* 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
* fix(hooks): collapse multi-line commands in bash audit logs
Add gsub("\\n"; " ") to jq filters in bash audit log and cost-tracker
hooks so multi-line commands produce single-line log entries, preventing
breakage in downstream line-based parsing.
Fixes#734
* fix: forward stdin to downstream hooks using echo pattern
Addresses review feedback: PostToolUse hooks now preserve stdin
for subsequent hooks by echoing $INPUT back to stdout after
processing. Changed ; to && for proper error propagation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: make stdin passthrough unconditional and broaden secret redaction
- Use semicolons instead of && so printf passthrough always runs
even if jq fails
- Add || true after jq to prevent non-zero exit on parse errors
- Use printf '%s\n' instead of echo for safe binary passthrough
- Fix Authorization pattern to handle 'Bearer <token>' with space
- Add ASIA (STS temp credentials) alongside AKIA redaction
- Add GitHub token patterns (ghp_, gho_, ghs_, github_pat_)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: use [: ]* instead of s* for Authorization whitespace matching
jq's ONIG regex engine interprets s* as literal 's' zero-or-more,
not \s* (whitespace). This caused 'Authorization: Bearer <token>'
to only redact 'Authorization:' and leak the actual token.
Using [: ]* avoids the JSON/jq double-escape issue entirely and
correctly matches both 'Authorization: Bearer xyz' and
'Authorization:xyz' patterns.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>
The script lives inside .kiro/, so SCRIPT_DIR already resolves to the .kiro directory. Appending /.kiro again produced an invalid path (.kiro/.kiro) causing the installer to find no source files to copy.
* 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>
* feat(commands): add santa-loop adversarial review command
Adds /santa-loop, a convergence loop command built on the santa-method
skill. Two independent reviewers (Claude Opus + external model) must
both return NICE before code ships. Supports Codex CLI (GPT-5.4),
Gemini CLI (3.1 Pro), or Claude-only fallback. Fixes are committed
per round and the loop repeats until convergence or escalation.
* fix: address all PR review findings for santa-loop command
- Add YAML frontmatter with description (coderabbit)
- Add Purpose, Usage, Output sections per CONTRIBUTING.md template (coderabbit)
- Fix literal <prompt> placeholder in Gemini CLI invocation (greptile P1)
- Use mktemp for unique temp file instead of fixed /tmp path (greptile P1, cubic P1)
- Use --sandbox read-only instead of --full-auto to prevent repo mutation (cubic P1)
- Use git push -u origin HEAD instead of bare git push (greptile P2, cubic P1)
- Clarify verdict protocol: reviewers return PASS/FAIL, gate maps to NICE/NAUGHTY (greptile P2, coderabbit)
- Specify parallel execution mechanism via Agent tool (coderabbit nitpick)
- Add escalation format for max-iterations case (coderabbit nitpick)
- Fix model IDs: gpt-5.4 for Codex, gemini-2.5-pro for Gemini
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>
Replace file glob probe order with `claude agents` as the primary
discovery mechanism so ECC marketplace plugin agents are included
automatically, regardless of install path or version.
Co-authored-by: lichangze <lichangze@uniontech.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
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): 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)
* fix(hooks): add WSL desktop notification support via PowerShell + BurntToast
Adds WSL (Windows Subsystem for Linux) desktop notification support to the
existing desktop-notify hook. The hook now detects WSL, finds available
PowerShell (7 or Windows PowerShell), checks for BurntToast module, and
sends Windows toast notifications.
New functions:
- isWSL(): detects WSL environment
- findPowerShell(): finds PowerShell 7 or Windows PowerShell on WSL
- isBurntToastAvailable(): checks if BurntToast module is installed
- notifyWindows(): sends Windows toast notification via BurntToast
If BurntToast is not installed, logs helpful tip for installation.
Falls back silently on non-WSL/non-macOS platforms.
* docs(hooks): update desktop-notify description to include WSL
Updates the hook description in hooks.json to reflect the newly
added WSL notification support alongside macOS.
* fix(hooks): capture stderr properly in notifyWindows
Change stdio to ['ignore', 'pipe', 'pipe'] so stderr is captured
and can be logged on errors. Without this, result.stderr is null
and error logs show 'undefined' instead of the actual error.
* fix(hooks): quote PowerShell path in install tip for shell safety
The PowerShell path contains spaces and needs to be quoted
when displayed as a copy-pasteable command.
* fix(hooks): remove external repo URL from tip message
BurntToast module is a well-known Microsoft module but per project
policy avoiding unvetted external links in user-facing output.
* fix(hooks): probe WSL interop PATH before hardcoded paths
Adds 'pwsh.exe' and 'powershell.exe' as candidates to leverage
WSL's Windows interop PATH resolution, making the hook work with
non-default WSL mount prefixes or Windows drives.
* perf(hooks): memoize isWSL detection at module load
Avoids reading /proc/version twice (once in run(), once in findPowerShell())
by computing the result once when the module loads.
* perf(hooks): reduce PowerShell spawns from 3 to 1 per notification
Merge findPowerShell version check and isBurntToastAvailable check
into a single notifyWindows call. Now just tries to send directly;
if it fails, tries next PowerShell path. Version field was unused.
Net effect: up to 3 spawns reduced to 1 in the happy path.
* fix(hooks): remove duplicate notifyWindows declaration
There were two notifyWindows function declarations due to incomplete
refactoring. Keeps only the version that returns true/false for the
call site. Node.js would throw SyntaxError with 'use strict'.
* fix(hooks): improve error handling and detection robustness
- Increase PowerShell detection timeout from 1s to 3s to avoid false
negatives on slower/cold WSL interop startup
- Return error reason from notifyWindows to distinguish BurntToast
module not found vs other PowerShell errors
- Log actionable error details instead of always showing install tip
---------
Co-authored-by: boss <boss@example.com>
On Git Bash (MINGW64), the native Windows Node.js binary receives a
POSIX path from $SCRIPT_DIR (e.g. /g/projects/everything-claude-code)
which Git Bash auto-converts to G:\g\projects\... — doubling the
drive letter prefix and producing MODULE_NOT_FOUND errors.
Fix: use `cygpath -w` when available to explicitly convert the POSIX
path to a proper Windows path before passing it to Node, falling back
to the original path on non-MSYS/Cygwin environments.
Adds omega-memory — persistent agent memory with semantic search,
multi-agent coordination, and knowledge graphs. Available on PyPI
as `omega-memory` (pip install omega-memory).
https://github.com/omega-memory/omega-memory
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Pin all GitHub Actions to commit SHAs instead of mutable version tags
across ci.yml, release.yml, maintenance.yml, and all reusable workflows.
This prevents supply-chain attacks via tag hijacking.
Add the required Skills section to CLAUDE.md mapping project files
(README.md, .github/workflows/*.yml) to their respective review skills.
The pre-push hook runs lint/typecheck/test/build checks on every push,
including `git push origin --delete <branch>`. Branch deletion does not
push any code, so verification checks are unnecessary and block the
delete operation.
Detect deletion pushes by reading stdin (local sha is all zeros for
deletes) and exit early.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>