Commit Graph

332 Commits

  • fix: remove unnecessary disk I/O + fix test cleanup
    - isChecked() no longer calls saveState() — read-only operation
      should not write to disk (was causing 3x writes per tool call)
    - Test cleanup uses fs.rmSync(recursive) instead of fs.rmdirSync
      which failed with ENOTEMPTY when .tmp files remained
    
    9/9 tests pass.
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
  • fix: P1 test state-file PID mismatch + P2 session key eviction
    P1 (cubic-dev-ai): Test process PID differs from spawned hook PID,
    so test was seeding/clearing wrong state file. Fix: pass fixed
    CLAUDE_SESSION_ID='gateguard-test-session' to spawned hooks.
    
    P2 (cubic-dev-ai): Pruning checked array could evict __bash_session__
    and other session keys, causing gates to re-fire mid-session. Fix:
    preserve __prefixed keys during pruning, only evict file-path entries.
    
    9/9 tests pass.
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
  • fix: session-scoped state to prevent cross-session race
    Addresses reviewer feedback from @affaan-m:
    
    1. State keyed by CLAUDE_SESSION_ID / ECC_SESSION_ID
       - Falls back to pid-based isolation when env vars absent
       - State file: state-{sessionId}.json (was .session_state.json)
    
    2. Atomic write+rename semantics
       - Write to temp file, then fs.renameSync to final path
       - Prevents partial reads from concurrent hooks
    
    3. Bounded checked list (MAX_CHECKED_ENTRIES = 500)
       - Prunes to last 500 entries when cap exceeded
       - Stale session files auto-deleted after 1 hour
    
    9/9 tests pass.
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
  • fix: allow destructive bash retry after facts presented
    Destructive bash gate previously denied every invocation with no
    isChecked call, creating an infinite deny loop. Now gates per-command
    on first attempt and allows retry after the model presents the required
    facts (targets, rollback plan, user instruction).
    
    Addresses greptile P1: "Destructive bash gate permanently blocks"
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
  • fix: address P2 review feedback (coderabbitai, cubic-dev-ai)
    - GATEGUARD_STATE_DIR env var for test isolation (hook + tests)
    - Exit code assertions on all 9 tests (no vacuous passes)
    - Non-vacuous allow-path assertions (verify pass-through preserves input)
    - Robust newline-injection assertion
    - clearState() now reports errors instead of swallowing
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
  • fix: address P1 review feedback from greptile bot
    1. Use run-with-flags.js wrapper (supports ECC_HOOK_PROFILE, ECC_DISABLED_HOOKS)
    2. Add session timeout (30min inactivity = state reset, fixes "once ever" bug)
    3. Add 9 integration tests (deny/allow/timeout/sanitize/disable)
    
    Refactored hook to module.exports.run() pattern for direct require() by
    run-with-flags.js (~50-100ms faster per invocation).
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
  • feat(opencode): add changed-files tree with change indicators (#815)
    * feat(opencode): add changed-files tree with change indicators
    
    * feat(opencode): address changed-files review feedback
    
    ---------
    
    Co-authored-by: Affaan Mustafa <me@affaanmustafa.com>
  • 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
  • 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: 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)