Adds npx block-no-verify@1.1.2 as a PreToolUse Bash hook in hooks/hooks.json
and a beforeShellExecution hook in .cursor/hooks.json to prevent AI agents
from bypassing git hooks via the hook-bypass flag.
This closes the last enforcement gap in the ECC security stack — the bypass
flag silently skips pre-commit, commit-msg, and pre-push hooks.
Closes#648
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Changes based on CodeRabbit review feedback:
1. Remove entire .cursor/ directory — it was an identical copy of the
main skills/commands/agents/rules, causing maintenance drift.
Users of Cursor can reference the canonical files directly.
2. Use explicit `is not None` checks instead of truthiness for
parsed['input'] and parsed['output']. Empty strings or empty
dicts are valid values that should be preserved.
The observe.sh script receives "pre" or "post" as $1 from the hook
config, but the Python code was looking for a "hook_type" field in
the stdin JSON. Claude Code does NOT include "hook_type" in the
JSON payload passed to hooks, so it always defaulted to "unknown",
causing all observations to be recorded as "tool_complete" —
PreToolUse events were never distinguished from PostToolUse.
Fix: capture $1 as HOOK_PHASE and pass it to Python via env var.
This also fixes TIMESTAMP export in the .cursor copy where inline
`VAR=val cmd` syntax didn't propagate to the python subprocess.
New community skills: content-hash-cache-pattern, cost-aware-llm-pipeline,
regex-vs-llm-structured-text, swift-actor-persistence, swift-protocol-di-testing
Comprehensive coding standards for modern C++ (C++17/20/23) derived
from isocpp.github.io/CppCoreGuidelines. Covers philosophy, functions,
classes, resource management, expressions, error handling, immutability,
concurrency, templates, standard library, enumerations, naming, and
performance with DO/DON'T examples and a pre-commit checklist.
The .cursor copy had diverged from scripts/hooks/suggest-compact.js:
- Fixed interval calculation: count % 25 → (count - threshold) % 25
so suggestions fire relative to the configured threshold
- Added upper bound clamp (<=1000000) to prevent counter corruption
from large values converting to scientific notation strings
- Removed unreliable String(process.ppid) fallback for session ID
The observer agent creates instinct files as .md with YAML frontmatter,
but load_all_instincts() only globbed *.yaml and *.yml. Add *.md to the
glob so instinct-cli status discovers all instinct files.
- Load both .yaml and .yml files in load_all_instincts() (#216)
The *.yaml-only glob missed .yml files, causing 'No instincts found'
- Implement evolve --generate to create skill/command/agent files (#217)
Previously printed a stub message. Now generates SKILL.md, command .md,
and agent .md files from the clustering analysis into ~/.claude/homunculus/evolved/
- Migrate session-end.js and evaluate-session.js from CLAUDE_TRANSCRIPT_PATH
env var to stdin JSON transcript_path (correct hook input mechanism)
- Remove duplicate main() calls that ran before stdin was read, causing
session files to be created with empty data
- Add range validation (1-10000) on COMPACT_THRESHOLD in suggest-compact.js
to prevent negative or absurdly large thresholds
- Add integration/hooks.test.js to tests/run-all.js so CI runs all 97 tests
- Update evaluate-session.sh to parse transcript_path from stdin JSON
- Update hooks.test.js to pass transcript_path via stdin instead of env var
- Sync .cursor/ copies
- Fix renameAlias() leaving orphaned newAlias key on save failure,
causing in-memory data corruption with both old and new keys present
- Add sessionPath validation to setAlias() to reject empty/null paths
- Guard getSessionById() against empty string matching all sessions
(startsWith('') is always true in JavaScript)
- Fix suggest-compact.js NaN comparison when COMPACT_THRESHOLD env var
is set to a non-numeric value — falls back to 50 instead of silently
disabling the threshold check
- Sync suggest-compact.js to .cursor/ copy
- Add try-catch around readFileSync in validate-agents, validate-commands,
validate-skills to handle TOCTOU races and file read errors
- Add validate-hooks.js and all test suites to package.json test script
(was only running 4/5 validators and 0/4 test files)
- Fix shell variable injection in observe.sh: use os.environ instead of
interpolating $timestamp/$OBSERVATIONS_FILE into Python string literals
- Fix $? always being 0 in start-observer.sh: capture exit code before
conditional since `if !` inverts the status
- Add OLD_VERSION validation in release.sh and use pipe delimiter in sed
to avoid issues with slash-containing values
- Add jq dependency check in evaluate-session.sh before parsing config
- Sync .cursor/ copies of all modified shell scripts
- Remove duplicate getAliasesPath() from utils.js (only used in
session-aliases.js which has its own copy)
- session-aliases.js: validate cleanupAliases param is a function,
check saveAliases return value, guard resolveAlias against empty input
- Sync .cursor/skills/strategic-compact/suggest-compact.sh with the
fixed main version (CLAUDE_SESSION_ID instead of $$)
Core library fixes:
- session-manager.js: wrap all statSync calls in try-catch to prevent
TOCTOU crashes when files are deleted between readdir and stat
- session-manager.js: use birthtime||ctime fallback for Linux compat
- session-manager.js: remove redundant existsSync before readFile
- utils.js: fix findFiles TOCTOU race on statSync inside readdir loop
Hook improvements:
- Add 1MB stdin buffer limits to all PostToolUse hooks to prevent
unbounded memory growth from large payloads
- suggest-compact.js: use fd-based atomic read+write for counter file
to reduce race window between concurrent invocations
- session-end.js: log when transcript file is missing, check
replaceInFile return value for failed timestamp updates
- start-observer.sh: log claude CLI failures instead of silently
swallowing them, check observations file exists before analysis
Test fixes:
- Fix blocking hook tests to send matching input (dev server command)
and expect correct exit code 2 instead of 1
- Sync .cursor/observe.sh with corrected main version (use stdin pipe
instead of broken heredoc json.loads pattern)
- Fix suggest-compact.sh to use CLAUDE_SESSION_ID instead of $$ which
gives a new PID per invocation, preventing counter from incrementing
Add complete .cursor/ directory with rules, agents, skills, commands,
and MCP config adapted for Cursor's format. This makes ecc-universal
a truly cross-IDE package supporting Claude Code, Cursor, and OpenCode.
- 27 rule files with YAML frontmatter (description, globs, alwaysApply)
- 13 agent files with full model IDs and readonly flags
- 30 skill directories (identical Agent Skills standard, no translation)
- 31 command files (5 multi-* stubbed for missing codeagent-wrapper)
- MCP config with Cursor env interpolation syntax
- README.md and MIGRATION.md documentation
- install.sh --target cursor flag for project-scoped installation
- package.json updated with .cursor/ in files and cursor keywords