Commit Graph

303 Commits

  • fix(commands): resolve active plugin root in /instinct-status (#2037)
    The `/instinct-status` slash command template expanded
    `${CLAUDE_PLUGIN_ROOT}` directly and documented a manual-install
    fallback to `~/.claude/skills/continuous-learning-v2/scripts/instinct-cli.py`.
    When users had both an active plugin install (under
    `~/.claude/plugins/cache/<slug>/<org>/<version>/`) and a legacy
    `~/.claude/skills/continuous-learning-v2/` directory left over from a
    previous manual install, an empty `CLAUDE_PLUGIN_ROOT` (which Claude
    Code does not always populate in slash-command shell contexts) silently
    made the command read the stale legacy install while the active plugin
    hooks and observer wrote to the new XDG path. The user saw "No
    instincts found" while the system was actively learning — exactly the
    divergence the bug reporter spent hours diagnosing.
    
    Replace the brittle two-block template with the same inline resolver
    pattern that `hooks/hooks.json` and `/sessions` / `/skill-health`
    already use: env var → standard install → known plugin roots → plugin
    cache walk → fallback. The resolver is the canonical `INLINE_RESOLVE`
    constant from `scripts/lib/resolve-ecc-root.js`, so no new code is
    introduced — just consistent adoption of the existing pattern.
    
    Apply the same fix to all five copies of the command:
      - commands/instinct-status.md (canonical)
      - .opencode/commands/instinct-status.md
      - docs/zh-CN/commands/instinct-status.md
      - docs/ja-JP/commands/instinct-status.md
      - docs/tr/commands/instinct-status.md
    
    Extend tests/lib/command-plugin-root.test.js with an assertion that the
    canonical instinct-status.md uses the inline resolver and no longer
    hard-codes the legacy `~/.claude/skills/...` fallback (regression
    guard).
    
    zh-CN copy: polish the Chinese phrasing per LanguageTool feedback
    (`使用与 ... 相同的解析器` → `以与 ... 相同的解析器`) so the verb is
    introduced by an explicit preposition instead of reading as an awkward
    verb-object construction.
  • fix: warn when populated legacy ~/.claude/homunculus exists (#2036)
    After the XDG migration the CLI reads from
    $XDG_DATA_HOME/ecc-homunculus/ (default ~/.local/share/ecc-homunculus/),
    but installs that retained an older manual copy at ~/.claude/homunculus/
    saw observations land in the new location while `instinct-cli.py status`
    silently continued to look at the new directory only. The reporter
    spent hours tracing the divergence because nothing surfaced the legacy
    tree.
    
    Add `_detect_legacy_homunculus_dir()` which returns the legacy path
    when ~/.claude/homunculus/ contains real ECC state (projects/,
    instincts/, evolved/, or observations.jsonl) and the active
    HOMUNCULUS_DIR is different. `cmd_status` calls it at the bottom of
    its output and prints a one-time, scoped warning that names both
    paths and points at the existing migrate-homunculus.sh script.
    
    Empty placeholder directories (just ~/.claude/homunculus/ with no
    content) are ignored so users who have already migrated and left the
    empty shell behind don't get nagged on every status call.
    
    Tests cover three branches: populated legacy dir triggers the warning,
    absent legacy dir stays silent, and empty placeholder legacy dir stays
    silent.
  • fix(continuous-learning): bump observer MAX_TURNS default to 50 (#2035)
    The observer's MAX_TURNS default of 20 was systematically insufficient
    for the MAX_ANALYSIS_LINES default of 500. First-cycle analysis on a
    fresh project consistently failed with "Reached max turns (20)", forcing
    users to either raise ECC_OBSERVER_MAX_TURNS or lower
    ECC_OBSERVER_MAX_ANALYSIS_LINES before the observer became useful.
    
    Pair the defaults so the out-of-the-box experience succeeds: bump
    MAX_TURNS to 50 (the value the reporter empirically settled on for the
    500-line default). The safety floor (turns < 4 falls back to default) is
    preserved.
    
    Test asserting the default constant is updated alongside the source.
  • 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)
  • Merge pull request #831 from dani-mezei/fix/clv2-subdirectory-project-detection
    fix(clv2): resolve cwd to git root before project detection
  • fix: audit consumer projects from cwd (#1014)
    * fix: audit consumer projects from cwd
    
    * fix: unblock unicode safety CI lint
    
    * fix: unblock shared CI regressions
    
    * test: isolate package-manager dependent hooks and formatter tests
  • fix: harden Trae install ownership (#1013)
    * fix: harden trae install ownership
    
    * fix: unblock unicode safety CI lint
    
    * fix: unblock shared CI regressions
    
    * test: isolate package-manager dependent hooks and formatter tests
  • fix: unblock unicode safety CI lint (#1017)
    * fix: unblock unicode safety CI lint
    
    * fix: unblock shared CI regressions
  • Merge pull request #1011 from affaan-m/fix/stop-hook-and-mcp-schema
    fix: harden lifecycle hook launchers and mcp schema
  • Merge pull request #926 from xingzihai/feature/pre-commit-quality-hook
    feat(hooks): add pre-commit quality check hook
  • refactor: address reviewer feedback
    - Add options={} parameter to run() to match run-with-flags.js contract
    - Remove case-insensitive flag from extension pre-filter for consistency
      with ADHOC_FILENAMES regex (both now case-sensitive)
    - Expand warning text to list more structured paths
    - Add test cases for uppercase extensions (TODO.MD, NOTES.TXT)
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
    
    Signed-off-by: Lidang-Jiang <lidangjiang@gmail.com>
  • fix(hooks): port doc-file-warning denylist policy to current hook runtime
    Replace the broad allowlist approach with a targeted denylist that only
    warns on known ad-hoc filenames (NOTES, TODO, SCRATCH, TEMP, DRAFT,
    BRAINSTORM, SPIKE, DEBUG, WIP) outside structured directories. This
    eliminates false positives for legitimate markdown-heavy workflows while
    still catching impulse documentation files.
    
    Closes #988
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
    
    Signed-off-by: Lidang-Jiang <lidangjiang@gmail.com>
  • 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 #960 from senoldogann/feat/codex-plugin-manifest
    feat(codex): add Codex native plugin manifest and fix Claude plugin.json
  • feat(codex): add Codex native plugin manifest and fix Claude plugin.json
    - Add .codex-plugin/plugin.json — Codex-native plugin manifest with
      skills reference and MCP server config pointer
    - Add .codex-plugin/.mcp.json — standalone MCP server config bundle
      (github, context7, exa, memory, playwright, sequential-thinking)
    - Add .codex-plugin/README.md — installation guide and server reference
    - Fix .claude-plugin/plugin.json — add missing agents[] (28 explicit
      file paths per validator rules), skills[], and commands[] arrays;
      remove hooks field (auto-loaded by Claude Code v2.1+ convention)
    - Add tests/plugin-manifest.test.js — 16 CI tests enforcing
      PLUGIN_SCHEMA_NOTES.md rules (no hooks, arrays throughout, explicit
      agent paths, version required, .mcp.json structural checks)
    - Update package.json: add .codex-plugin/ to files[], add plugin
      manifest test to npm test chain
    
    Refs: .claude-plugin/PLUGIN_SCHEMA_NOTES.md
  • Merge pull request #964 from affaan-m/fix/claude-hooks-settings-merge-safe
    fix(installer): preserve existing Claude hook settings
  • fix(observer): clean up prompt_file early and fix test for analysis_relpath
    - Remove prompt_file immediately after shell expansion into -p arg,
      avoiding stale temp files during long analysis windows (greptile feedback)
    - Update test assertion to check analysis_relpath instead of analysis_file,
      matching the cross-platform relative path change from earlier commits
    
    Signed-off-by: Lidang-Jiang <lidangjiang@gmail.com>