22 Commits

  • fix: add plugin cache health check (#2249)
    * fix: add plugin cache health check
    
    * fix: harden plugin cache diagnostics
    
    * fix: reject escaping plugin cache refs
    
    * test: remove unused plugin cache fixture
  • fix: stability batch — hook stdin truncation, Codex exa TOML, Stop hook JSON, GateGuard repetition (#2227)
    * fix(hooks): fail open on oversized stdin instead of echoing truncated JSON (#2222)
    
    run-with-flags.js capped stdin at 1MB but every fallthrough path still
    echoed the truncated string to stdout. The harness parses hook stdout as
    JSON, got a document cut mid-stream, and blocked the tool call — so any
    Edit/Write with a >1MB hook payload was permanently blocked by every
    registered pre-write hook, before ECC_HOOK_PROFILE / ECC_DISABLED_HOOKS
    gating could run.
    
    - Exit 0 with empty stdout (no opinion) when the stdin cap trips, before
      any echo or gating logic.
    - Flush stdout via write callback before process.exit: exiting right
      after stdout.write() dropped everything past the ~64KB pipe buffer,
      cutting even sub-cap pass-through payloads mid-JSON.
    
    Regression tests cover the enabled, disabled, and missing-arg paths for
    oversized payloads plus full echo of sub-cap >64KB payloads.
    
    * fix(codex): stop emitting invalid exa url entry, align merge with connector policy (#2224)
    
    The Codex MCP merge declared exa with a url key, but Codex's
    [mcp_servers.*] TOML schema is stdio-only — the url key makes the
    entire config.toml fail to load, bricking both the codex CLI and the
    desktop app. Every install/update re-injected the line because the
    urlEntry branch treated the broken entry as present.
    
    - ECC_SERVERS now emits only the current default set per
      docs/MCP-CONNECTOR-POLICY.md: chrome-devtools (stdio, command/args).
      Retired servers (supabase, playwright, context7, exa, github, memory,
      sequential-thinking) are never re-emitted; existing user-managed
      entries are untouched.
    - The merge now repairs the exact ECC-emitted broken form (url-only
      exa entry) on every run so re-running the installer fixes broken
      configs instead of preserving them. User stdio exa entries
      (command + mcp-remote) are left alone.
    - check-codex-global-state.sh requires chrome-devtools instead of the
      retired set, and flags url-only exa entries with a repair hint.
    
    Tests cover repair, re-run idempotence, stdio-entry preservation, and
    no-retired-server emission in add, update, dry-run, and disabled modes.
    
    * fix(hooks): never echo truncated stdin from Stop hooks (#2090)
    
    Stop hooks follow the ECC pass-through convention (echo stdin on
    stdout), but every echoing Stop hook capped stdin and echoed the capped
    string. The Stop payload carries last_assistant_message, so a long
    final assistant message produced a JSON document cut mid-stream on
    stdout, which the harness reports as 'Stop hook error: JSON validation
    failed' across the whole Stop chain.
    
    Reproduced: a Stop payload with a >64KB last_assistant_message run
    through run-with-flags + cost-tracker emitted exactly 65536 bytes of
    invalid JSON (cost-tracker capped stdin at 64KB — far below realistic
    Stop payloads).
    
    - cost-tracker: raise the cap to 1MB (matching all other hooks) and
      suppress the pass-through echo when stdin was truncated.
    - check-console-log, stop-format-typecheck, desktop-notify: suppress
      the echo when stdin was truncated; flush stdout before process.exit
      so sub-cap payloads are not cut at the ~64KB pipe buffer.
    - All hooks keep exiting 0 (fail-open); diagnostics go to stderr.
    
    New stop-hooks-stdout test asserts the contract for every registered
    Stop hook: stdout is empty or valid JSON, exit code 0 — for realistic
    100KB payloads and oversized >1MB payloads, via the production runner
    and via direct invocation. Updated the old hooks.test.js case that
    codified the truncated-echo behavior.
    
    * fix(hooks): dampen GateGuard fact-force repetition in long sessions (#2142)
    
    In long autonomous sessions the fact-force gate produced 10+
    near-identical 'state facts -> blocked -> restate -> retry' blocks in
    one context window, which measurably raises the odds of the model
    collapsing into a degenerate single-token repetition loop.
    
    - Track a per-session fact_force_denials counter in GateGuard state
      (merged max across concurrent writers, reset with the session, robust
      to malformed on-disk values).
    - The first GATEGUARD_FACT_FORCE_FULL_DENIALS denials (default 3) keep
      the full four-fact block; later denials emit a condensed single-line
      message that carries the denial ordinal, so consecutive denials are
      structurally different and never textually identical.
    - True retries of the same target remain allowed without re-prompting
      (unchanged). Destructive-Bash and routine-Bash gates are unchanged,
      as are the ECC_GATEGUARD=off / ECC_DISABLED_HOOKS escape hatches.
    
    Eight new tests cover budget counting, condensed format, ordinal
    advancement, retry pass-through, env tuning, malformed state, MultiEdit
    dampening, and destructive-gate exemption.
    
    * fix(hooks): keep security hooks able to block on oversized stdin (#2222)
    
    Refine the truncation fail-open: instead of skipping the hook entirely,
    the runner now suppresses only its own raw-echo when stdin was
    truncated. The hook still executes and receives the truncated flag
    (run() context / ECC_HOOK_INPUT_TRUNCATED), so config-protection keeps
    blocking truncated protected-config payloads (its test requires exit 2)
    while pass-through hooks fail open with empty stdout as before.
    
    * style: apply repo formatter to touched hook files
  • 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)
  • Merge pull request #892 from chris-yyau/fix/remove-redundant-skill-sync
    fix: remove redundant skill copy from sync-ecc-to-codex.sh
  • Merge pull request #974 from Lidang-Jiang/fix/codex-sanity-check-persistent-instructions
    fix(codex): add persistent_instructions to baseline and relax sanity check
  • fix(codex): align context7-mcp package specifier with config.toml
    Add @latest suffix to '@upstash/context7-mcp' in ECC_SERVERS so the
    generated merge spec matches .codex/config.toml exactly, preventing
    configDiffers from flagging false drift on --update-mcp runs.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    Signed-off-by: Lidang-Jiang <lidangjiang@gmail.com>
  • fix(codex): allow leading whitespace in persistent_instructions regex
    The rg pattern anchored at line start (^persistent_instructions) would
    miss indented TOML entries. Use ^\s* prefix to match both top-level and
    indented configurations.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    Signed-off-by: Lidang-Jiang <lidangjiang@gmail.com>
  • fix(codex): add persistent_instructions to baseline and relax sanity check
    The global sanity check (check-codex-global-state.sh) hard-fails when
    persistent_instructions is missing from ~/.codex/config.toml, but neither
    the baseline .codex/config.toml nor the sync script ever define this field.
    This causes a clean install to report a failing sanity check even though the
    sync otherwise succeeds (#967).
    
    - Add persistent_instructions to the baseline .codex/config.toml so that
      users who cp the config get a working default.
    - Downgrade the sanity check from fail to warn, since persistent_instructions
      is additive and optional — users who rely solely on AGENTS.md should not be
      blocked.
    
    Fixes #967 (persistent_instructions part; context7 naming addressed by #970)
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    Signed-off-by: Lidang-Jiang <lidangjiang@gmail.com>
  • fix(codex): sync startup_timeout_sec into merge-mcp-config.js ECC_SERVERS
    Reviewers identified that merge-mcp-config.js --update-mcp would
    silently strip the startup_timeout_sec from config.toml because the
    ECC_SERVERS spec did not include it. Add startup_timeout_sec = 30 to
    playwright, context7-mcp, github, memory, and sequential-thinking.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    Signed-off-by: Lidang-Jiang <lidangjiang@gmail.com>
  • fix: add execute permissions to codex sync shell scripts
    Three .sh files were committed without the execute bit, causing
    `install-global-git-hooks.sh` to fail with "Permission denied"
    when invoked by `sync-ecc-to-codex.sh`.
    
    Generated with [Claude Code](https://claude.ai/code)
    via [Happy](https://happy.engineering)
    
    Co-Authored-By: Claude <noreply@anthropic.com>
    Co-Authored-By: Happy <yesreply@happy.engineering>
  • fix: remove redundant skill copy from sync-ecc-to-codex.sh
    Codex CLI reads skills natively from ~/.agents/skills/ (installed by
    ECC installer / npx skills). The sync script was redundantly copying
    the same skills from .agents/skills/ to ~/.codex/skills/.
    
    Changes:
    - Remove skill copy loop, variables, and path validation from sync script
    - Update sanity checker to validate ~/.agents/skills/ instead of
      ~/.codex/skills/, downgrade missing skills from FAIL to WARN
    - Update test assertions to verify skill sync removal
    
    Generated with [Claude Code](https://claude.ai/code)
    via [Happy](https://happy.engineering)
    
    Co-Authored-By: Claude <noreply@anthropic.com>
    Co-Authored-By: Happy <yesreply@happy.engineering>
  • fix: safe Codex config sync — merge AGENTS.md + add-only MCP servers (#723)
    * fix: replace bash TOML surgery with Node add-only MCP merge
    
    The old sync script used awk/sed to remove and re-append MCP server
    sections in config.toml, causing credential extraction races, duplicate
    TOML tables, and 3 fragile code paths with 9 remove_section_inplace
    calls each.
    
    Replace with a Node script (scripts/codex/merge-mcp-config.js) that
    uses @iarna/toml to parse the config, then appends only missing ECC
    servers — preserving all existing content byte-for-byte. Warns on
    config drift, supports legacy aliases (context7 → context7-mcp), and
    adds --update-mcp flag for explicit refresh.
    
    Generated with [Claude Code](https://claude.ai/code)
    via [Happy](https://happy.engineering)
    
    Co-Authored-By: Claude <noreply@anthropic.com>
    Co-Authored-By: Happy <yesreply@happy.engineering>
    
    * fix: address PR #723 review findings for Codex MCP merge
    
    - Use package-manager abstraction (scripts/lib/package-manager.js)
      instead of hardcoding pnpm — respects CLAUDE_PACKAGE_MANAGER,
      lock files, and project config
    - Add Yarn 1.x fallback to npx (yarn dlx unsupported in classic)
    - Add missing exa server to match .codex/config.toml baseline
    - Wire up findSubSections for --update-mcp nested subtable removal
      (fixes Greptile P1: Object.keys only returned top-level keys)
    - Fix resolvedLabel to prefer canonical entry over legacy alias
      when both exist (fixes context7/context7-mcp spurious warning)
    - Fix removeSectionFromText to handle inline TOML comments
    - Fix dry-run + --update-mcp to show removals before early return
    - Update README parity table: 4 → 7 servers, TOML-parser-based
    - Add non-npm install variants to README Codex quick start
    - Update package-lock.json for @iarna/toml
    
    Generated with [Claude Code](https://claude.ai/code)
    via [Happy](https://happy.engineering)
    
    Co-Authored-By: Claude <noreply@anthropic.com>
    Co-Authored-By: Happy <yesreply@happy.engineering>
    
    * fix: address PR #723 review comments (preflight, marker validation)
    
    - Add Node.js and merge-mcp-config.js to preflight checks so the
      script fails fast before partial writes (CodeRabbit)
    - Validate marker counts: require exactly 1 BEGIN + 1 END in correct
      order for clean replacement (CodeRabbit)
    - Corrupted markers: strip all marker lines and re-append fresh block,
      preserving user content outside markers instead of overwriting
    - Move MCP_MERGE_SCRIPT to preflight section, remove duplicate
    
    Generated with [Claude Code](https://claude.ai/code)
    via [Happy](https://happy.engineering)
    
    Co-Authored-By: Claude <noreply@anthropic.com>
    Co-Authored-By: Happy <yesreply@happy.engineering>
    
    ---------
    
    Co-authored-by: Claude <noreply@anthropic.com>
    Co-authored-by: Happy <yesreply@happy.engineering>
  • feat: add Codex CLI customization scripts (#336)
    * chore(codex): add global ecc sync script and pnpm mcp config
    
    * chore(codex): include codex supplement when syncing agents
    
    * feat(codex): add global git safety hooks and QA/rule prompt packs
    
    * feat(codex): add global regression sanity check command
    
    ---------
    
    Co-authored-by: TGreen87 <your-email@example.com>