Commit Graph

247 Commits

  • Merge pull request #1384 from KeWang0622/fix/lint-md028-eqeqeq
    fix: resolve markdownlint MD028 + ESLint eqeqeq lint failures
  • Merge pull request #1385 from KeWang0622/fix/block-no-verify-hook
    fix: route block-no-verify hook through run-with-flags.js
  • fix: harden release surface version and packaging sync (#1388)
    * fix: keep ecc release surfaces version-synced
    
    * fix: keep lockfile release version in sync
    
    * fix: remove release version drift from locks and tests
    
    * fix: keep root release metadata version-synced
    
    * fix: keep codex marketplace metadata version-synced
    
    * fix: gate release workflows on full metadata sync
    
    * fix: ship all versioned release metadata
    
    * fix: harden manual release path
    
    * fix: keep localized release docs version-synced
    
    * fix: sync install architecture version examples
    
    * test: cover shipped plugin metadata in npm pack
    
    * fix: verify final npm payload in release script
    
    * fix: ship opencode lockfile in npm package
    
    * docs: sync localized release highlights
    
    * fix: stabilize windows ci portability
    
    * fix: tighten release script version sync
    
    * fix: prefer repo-relative hook file paths
    
    * fix: make npm pack test shell-safe on windows
  • fix: detach ecc2 background session runners (#1387)
    * fix: detach ecc2 background session runners
    
    * fix: stabilize windows ci portability
    
    * fix: persist detached runner startup stderr
    
    * fix: prefer repo-relative hook file paths
    
    * fix: make npm pack test shell-safe on windows
  • fix: address PR review comments on block-no-verify hook
    - Add `minimal` profile so the security hook runs in all profiles
    - Scope -n/--no-verify flag check to the detected subcommand region,
      preventing false positives on chained commands (e.g. `git log -n 10`)
    - Guard stdin listeners with `require.main === module` so require()
      from run-with-flags.js does not register unnecessary listeners
    - Verify subcommand token is preceded only by flags/flag-args after
      "git", preventing misclassification of argument values as subcommands
    - Add integration tests for block-no-verify hook
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
  • fix: route block-no-verify hook through run-with-flags.js
    Replace inline `npx block-no-verify@1.1.2` with a standalone Node.js
    script routed through `run-with-flags.js`, matching every other hook.
    
    Fixes two bugs:
    1. npx inherits the project cwd and triggers EBADDEVENGINES in
       pnpm-only projects that set devEngines.packageManager.onFail=error.
    2. The hook bypassed run-with-flags.js so ECC_DISABLED_HOOKS had no
       effect — the isHookEnabled() check never ran.
    
    The new script replicates the full block-no-verify@1.1.2 detection
    logic (--no-verify, -n shorthand for commit, core.hooksPath override)
    with zero external dependencies.
    
    Closes #1378
  • fix: resolve markdownlint MD028 and ESLint eqeqeq warnings
    Fix two lint issues that cause `npm run lint` to exit non-zero:
    
    1. README.md (MD028): Two consecutive blockquotes separated by a bare
       blank line. Markdownlint treats this as one blockquote with an
       illegal blank line inside. Replace the blank line with a `>`
       continuation so both paragraphs stay in the same blockquote.
    
    2. session-activity-tracker.js (eqeqeq): Three instances of `== null`
       replaced with explicit `=== null || === undefined` guards to satisfy
       the repo's `eqeqeq: warn` ESLint rule.
    
    Closes #1366
  • perf(hooks): batch format+typecheck at Stop instead of per Edit (#746)
    * perf(hooks): batch format+typecheck at Stop instead of per Edit
    
    Fixes #735. The per-edit post:edit:format and post:edit:typecheck hooks
    ran synchronously after every Edit call, adding 15-30s of latency per
    file — up to 7.5 minutes for a 10-file refactor.
    
    New approach:
    - post-edit-accumulator.js (PostToolUse/Edit): lightweight hook that
      records each edited JS/TS path to a session-scoped temp file in
      os.tmpdir(). No formatters, no tsc — exits in microseconds.
    - stop-format-typecheck.js (Stop): reads the accumulator once per
      response, groups files by project root and runs the formatter in
      one batched invocation per root, then groups .ts/.tsx files by
      tsconfig dir and runs tsc once per tsconfig. Clears the accumulator
      immediately on read so repeated Stop calls don't double-process.
    
    For a 10-file refactor: was 10 × (15s + 30s) = 7.5 min overhead,
    now 1 × (batch format + batch tsc) = ~5-30s total.
    
    * fix(hooks): address race condition, spawn timeout, and Windows path guard
    
    Three issues raised in code review:
    
    1. Race condition: switched accumulator from non-atomic JSON
       read-modify-write to appendFileSync (one path per line). Concurrent
       Edit hook processes each append independently without clobbering each
       other. Deduplication moved to the Stop hook at read time.
    
    2. Effective timeout: added run() export to stop-format-typecheck.js so
       run-with-flags.js uses the direct require() path instead of falling
       through to spawnSync (which has a hardcoded 30s cap). The 120s
       timeout in hooks.json now governs the full batch as intended.
    
    3. Windows path guard: added spaces and parentheses to UNSAFE_PATH_CHARS
       so paths like "C:\Users\John Doe\project\file.ts" are caught before
       being passed to cmd.exe with shell: true.
    
    * fix(hooks): fix session fallback, stale comment, trim verbose comments
    
    - Replace 'default' session ID fallback with a cwd-based sha1 hash so
      concurrent sessions in different projects don't share the same
      accumulator file when CLAUDE_SESSION_ID is unset
    - Remove stale "JSON file" reference in accumulator header (format is
      now newline-delimited plain text)
    - Remove redundant/verbose inline comments throughout both files
    
    * fix(hooks): sanitize session ID, fix Windows tsc, proportional timeouts
    
    - Sanitize CLAUDE_SESSION_ID with /[^a-zA-Z0-9_-]/g before embedding in
      the temp filename so crafted separators or '..' sequences cannot escape
      os.tmpdir() (cubic P1)
    - Fix typecheckBatch on Windows: npx.cmd requires shell:true like
      formatBatch already does; use spawnSync and extract stdout/stderr from
      the result object (coderabbit P1)
    - Proportional per-batch timeouts: divide 270s budget across all format
      and typecheck batches so sequential runs in monorepos stay within the
      Stop hook wall-clock limit (greptile P2)
    - Raise Stop hook timeout from 120s to 300s to give large monorepos
      adequate headroom (cubic P2)
    
    * fix(hooks): extend accumulator to Write|MultiEdit, fix tests
    
    - Extend matcher from Edit to Edit|Write|MultiEdit so files created with
      Write and all files in a MultiEdit batch are included in the Stop-time
      format+typecheck pass (cubic P1)
    - Handle tool_input.edits[] array in accumulator for MultiEdit support
    - Rename misleading 'concurrent writes' test to clarify it tests append
      preservation, not true concurrency (cubic P2)
    - Add Stop hook dedup test: writes duplicate paths to accumulator and
      verifies the hook clears it cleanly (cubic P2)
    - Add Write and MultiEdit accumulation tests
    
    * fix(hooks): move timeout to command level, add dedup unit tests
    
    - Move timeout: 300 from the matcher object to the hook command object
      where it is actually enforced; the previous position was a no-op
      (cubic P2)
    - Extract parseAccumulator() and export it so tests can assert dedup
      behavior directly without relying only on side effects (cubic P2)
    - Add two unit tests for parseAccumulator: deduplication and blank-line
      handling; rename the integration test to match its scope
    
    * fix(hooks): replace removed format/typecheck hooks with accumulator in cursor adapter
  • feat(install): add CodeBuddy(Tencent) adaptation with installation scripts (#1038)
    * feat(install): add CodeBuddy(Tencent) adaptation with installation scripts
    
    * fix: add codebuddy to SUPPORTED_INSTALL_TARGETS
    
    * fix(codebuddy): resolve installer path issues, unused vars, and uninstall safety
  • feat: add GAN-style generator-evaluator harness (#1029)
    Implements Anthropic's March 2026 harness design pattern — a multi-agent
    architecture that separates generation from evaluation, creating an
    adversarial feedback loop that produces production-quality applications.
    
    Components:
    - 3 agent definitions (planner, generator, evaluator)
    - 1 skill with full documentation (skills/gan-style-harness/)
    - 2 commands (gan-build for full apps, gan-design for frontend)
    - 1 shell orchestrator (scripts/gan-harness.sh)
    - Examples and configuration reference
    
    Based on: https://www.anthropic.com/engineering/harness-design-long-running-apps
    
    Co-authored-by: Hao Chen <haochen806@gmail.com>
  • fix: filter session-start injection by cwd/project to prevent cross-project contamination (#1054)
    * fix: filter session-start injection by cwd/project to prevent cross-project contamination
    
    The SessionStart hook previously selected the most recent session file
    purely by timestamp, ignoring the current working directory. This caused
    Claude to receive a previous project's session context when switching
    between projects, leading to incorrect file reads and project analysis.
    
    session-end.js already writes **Project:** and **Worktree:** header
    fields into each session file. This commit adds selectMatchingSession()
    which uses those fields with the following priority:
    
    1. Exact worktree (cwd) match — most recent
    2. Same project name match — most recent
    3. Fallback to overall most recent (preserves backward compatibility)
    
    No new dependencies. Gracefully falls back to original behavior when
    no matching session exists.
    
    * fix: address review feedback — eliminate duplicate I/O, add null guards, improve docstrings
    
    - Return { session, content, matchReason } from selectMatchingSession()
      to avoid reading the same file twice (coderabbitai, greptile P2)
    - Add empty array guard: return null when sessions.length === 0 (coderabbitai)
    - Stop mutating input objects — no more session._matchReason (coderabbitai)
    - Add null check on result before accessing properties (coderabbitai)
    - Only log "selected" after confirming content is readable (cubic-dev-ai P3)
    - Add full JSDoc with @param/@returns (docstring coverage)
    
    * fix: track fallback session object to prevent session/content mismatch
    
    When sessions[0] is unreadable, fallbackContent came from a later
    session (e.g. sessions[1]) while the returned session object still
    pointed to sessions[0]. This caused misleading logs and injected
    content from the wrong session — the exact problem this PR fixes.
    
    Now tracks fallbackSession alongside fallbackContent so the returned
    pair is always consistent.
    
    Addresses greptile-apps P1 review feedback.
    
    * fix: normalize worktree paths to handle symlinks and case differences
    
    On macOS /var is a symlink to /private/var, and on Windows paths may
    differ in casing (C:\repo vs c:\repo). Use fs.realpathSync() to
    resolve both sides before comparison so worktree matching is reliable
    across symlinked and case-insensitive filesystems.
    
    cwd is normalized once outside the loop to avoid repeated syscalls.
    
    Addresses coderabbitai Major review feedback.
    
    ---------
    
    Co-authored-by: kuqili <kuqili@tencent.com>
  • fix: extract inline SessionStart bootstrap to separate file (#1035)
    Inline `node -e "..."` in hooks.json contained `!` characters (e.g.
    `!org.isDirectory()`) that bash history expansion in certain shell
    environments would misinterpret, producing syntax errors and the
    "SessionStart:startup hook error" banner in the Claude Code CLI header.
    
    Extract the bootstrap logic to `scripts/hooks/session-start-bootstrap.js`
    so the shell never sees the JS source. Behaviour is identical: the script
    reads stdin, resolves the ECC plugin root via CLAUDE_PLUGIN_ROOT or a set
    of well-known fallback paths, then delegates to run-with-flags.js.
    
    Update the test that asserted the old inline pattern to verify the new
    file-based approach instead.
    
    Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
  • fix(hooks): pass phase argument from hook ID to observe.sh (#1042)
    The shell wrapper run-with-flags-shell.sh was not extracting the phase
    prefix from the hook ID (e.g., "pre:observe" -> "pre") and passing it
    as $1 to the invoked script. This caused observe.sh to always default
    to "post", recording all observations as tool_complete events with no
    tool_start events captured.
    
    Fixes #1018
    
    Co-authored-by: Millectable <noreply@github.com>
    Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
  • fix: CI fixes, security audit, remotion skill, lead-intelligence, npm audit (#1039)
    * fix(ci): resolve cross-platform test failures
    
    - Sanity check script (check-codex-global-state.sh) now falls back to
      grep -E when ripgrep is not available, fixing the codex-hooks sync
      test on all CI platforms. Patterns converted to POSIX ERE for
      portability.
    - Unicode safety test accepts both / and \ path separators so the
      executable-file assertion passes on Windows.
    - Gacha test sets PYTHONUTF8=1 so Python uses UTF-8 stdout encoding on
      Windows instead of cp1252, preventing UnicodeEncodeError on box-drawing
      characters.
    - Quoted-hook-path test skipped on Windows where NTFS disallows
      double-quote characters in filenames.
    
    * feat: port remotion-video-creation skill (29 rules), restore missing files
    
    New skill:
    - remotion-video-creation: 29 domain-specific Remotion rules covering 3D/Three.js,
      animations, audio, captions, charts, compositions, fonts, GIFs, Lottie,
      measuring, sequencing, tailwind, text animations, timing, transitions,
      trimming, and video embedding. Ported from personal skills.
    
    Restored:
    - autonomous-agent-harness/SKILL.md (was in commit but missing from worktree)
    - lead-intelligence/ (full directory restored from branch commit)
    
    Updated:
    - manifests/install-modules.json: added remotion-video-creation to media-generation
    - README.md + AGENTS.md: synced counts to 139 skills
    
    Catalog validates: 30 agents, 60 commands, 139 skills.
    
    * fix(security): pin MCP server versions, add dependabot, pin github-script SHA
    
    Critical:
    - Pin all npx -y MCP server packages to specific versions in .mcp.json
      to prevent supply chain attacks via version hijacking:
      - @modelcontextprotocol/server-github@2025.4.8
      - @modelcontextprotocol/server-memory@2026.1.26
      - @modelcontextprotocol/server-sequential-thinking@2025.12.18
      - @playwright/mcp@0.0.69 (was 0.0.68)
    
    Medium:
    - Add .github/dependabot.yml for weekly npm + github-actions updates
      with grouped minor/patch PRs
    - Pin actions/github-script to SHA (was @v7 tag, now pinned to commit)
    
    * feat: add social-graph-ranker skill — weighted network proximity scoring
    
    New skill: social-graph-ranker
    - Weighted social graph traversal with exponential decay across hops
    - Bridge Score: B(m) = Σ w(t) · λ^(d(m,t)-1) ranks mutuals by target proximity
    - Extended Score incorporates 2nd-order network (mutual-of-mutual connections)
    - Final ranking includes engagement bonus for responsive connections
    - Runs in parallel with lead-intelligence skill for combined warm+cold outreach
    - Supports X API + LinkedIn CSV for graph harvesting
    - Outputs tiered action list: warm intros, direct outreach, network gap analysis
    
    Added to business-content install module. Catalog validates: 30/60/140.
    
    * fix(security): npm audit fix — resolve all dependency vulnerabilities
    
    Applied npm audit fix --force to resolve:
    - minimatch ReDoS (3 vulnerabilities, HIGH)
    - smol-toml DoS (MODERATE)
    - brace-expansion memory exhaustion (MODERATE)
    - markdownlint-cli upgraded from 0.47.0 to 0.48.0
    
    npm audit now reports 0 vulnerabilities.
    
    * fix: resolve markdown lint and yarn lockfile sync
    
    - MD047: ensure single trailing newline on all remotion rule files
    - MD012: remove consecutive blank lines in lottie, measuring-dom-nodes, trimming
    - MD034: wrap bare URLs in angle brackets (tailwind, transcribe-captions)
    - yarn.lock: regenerated to sync with npm audit changes in package.json
    
    * fix: replace unicode arrows in lead-intelligence (CI unicode safety check)