- hooks.json: add \b word boundary anchors to dev server blocking regex
to prevent false positives matching "npm run develop", "npm run devtools" etc.
- skill-create-output.js: guard box() horizontal repeat with Math.max(0, ...)
to prevent RangeError when title exceeds container width
- Add 13 tests for setup-package-manager.js CLI argument parsing
- Add 14 tests for skill-create-output.js SkillCreateOutput class
- All 333 tests passing
On Windows, os.homedir() uses USERPROFILE env var instead of HOME.
Tests that override HOME to a temp dir must also set USERPROFILE for
the session-manager, session-aliases, and session-start hook tests
to find files in the correct directory.
The validator was matching example/template content inside fenced code
blocks as real cross-references, causing false positives for evolve.md
(example /new-table command and debugger agent).
- Strip ``` blocks before running cross-reference checks
- Change evolve.md examples to use bold instead of backtick formatting
for hypothetical outputs
All 261 tests pass.
Docker Compose for local dev, networking, volume strategies, container
security hardening, debugging commands, and anti-patterns.
Complements the existing deployment-patterns skill which covers CI/CD
and production Dockerfiles.
Closes#121
When installed via `npm install ecc-universal`, the `ecc-install` bin
entry creates a symlink from the package manager's bin directory to
install.sh. The old `$(dirname "$0")` resolved to the bin directory
instead of the actual package directory, causing `cp` to fail with
"cannot stat '.../rules/common/.'".
Now follows the symlink chain with readlink before resolving SCRIPT_DIR.
Fixes#199
The package.json test script listed individual test files, which fell
out of sync when session-manager.test.js and session-aliases.test.js
were added to tests/run-all.js but not to package.json. Now npm test
delegates to run-all.js so new test files are automatically included.
- hooks.schema.json: add async (boolean) and timeout (number) properties
to hookItem definition, matching fields used in hooks.json
- validate-hooks.js: validate async and timeout types when present
- hooks.test.js: add SessionEnd to required event types check
- session-manager.js: fix getSessionStats path detection to handle
Windows paths (C:\...) in addition to Unix paths (/)
- package-manager.js: add try-catch to setPreferredPackageManager for
consistent error handling with setProjectPackageManager
- validate-hooks.js: extract duplicated hook entry validation into
reusable validateHookEntry() helper
- Update .d.ts JSDoc for both fixes
Bug fixes:
- utils.js: prevent duplicate 'g' flag in countInFile regex construction
- validate-agents.js: handle CRLF line endings in frontmatter parsing
- validate-hooks.js: handle \t and \\ escape sequences in inline JS validation
- session-aliases.js: prevent NaN in date sort when timestamps are missing
- session-aliases.js: persist rollback on rename failure instead of silent loss
- session-manager.js: require absolute paths in getSessionStats to prevent
content strings ending with .tmp from being treated as file paths
New tests (164 total, up from 97):
- session-manager.test.js: 27 tests covering parseSessionFilename,
parseSessionMetadata, getSessionStats, CRUD operations, getSessionSize,
getSessionTitle, edge cases (null input, non-existent files, directories)
- session-aliases.test.js: 40 tests covering loadAliases (corrupted JSON,
invalid structure), setAlias (validation, reserved names), resolveAlias,
listAliases (sort, search, limit), deleteAlias, renameAlias, updateAliasTitle,
resolveSessionAlias, getAliasesForSession, cleanupAliases, atomic write
Also includes hook-generated improvements:
- utils.d.ts: document that readStdinJson never rejects
- session-aliases.d.ts: fix updateAliasTitle type to accept null
- package-manager.js: add try-catch to setProjectPackageManager writeFile
Windows pipes raise EOF instead of EPIPE when the child process
exits before stdin finishes flushing. Added EOF to the ignored
error codes in runHookWithInput.
Integration tests were still passing CLAUDE_TRANSCRIPT_PATH as an env
var, but evaluate-session.js now reads transcript_path from stdin JSON.
Also improves strategic-compact skill with decision guide and survival table.
- 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
- Replace raw fs.readFileSync with readFile() from utils in
check-console-log.js and post-edit-console-warn.js to eliminate
TOCTOU race conditions (file deleted between existsSync and read)
- Remove redundant existsSync in post-edit-format.js (exec already
handles missing files via its catch block)
- Resolve path upfront in post-edit-typecheck.js before tsconfig walk
- Add type guard in getGitModifiedFiles() to skip non-string and
empty patterns before regex compilation
- New skills: api-design, database-migrations, deployment-patterns
- validate-hooks.js: validate inline JS syntax in node -e hook commands
- utils.test.js: edge case tests for findFiles with null/undefined inputs
- README: update skill count to 35, add new skills to directory tree
- Guard findFiles() against null/undefined dir and pattern parameters
(previously crashed with TypeError on .replace() or fs.existsSync())
- Wrap countInFile() and grepFile() regex construction in try-catch to
handle invalid regex strings like '(unclosed' (previously crashed with
SyntaxError: Invalid regular expression)
- Add try-catch to replaceInFile() with descriptive error logging
- Add 1MB size limit to readStdinJson() matching the PostToolUse hooks
(previously had unbounded stdin accumulation)
- Improve ensureDir() error message to include the directory path
- Add 128-char length limit to setAlias() to prevent oversized alias
names from inflating the JSON store
- Update utils.d.ts with new maxSize option on ReadStdinJsonOptions
- Wrap JSON.parse in try-catch for all 6 inline hooks in hooks.json
(dev-server blocker, tmux reminder, git-push reminder, doc blocker,
PR create logger, build analysis) — previously unguarded JSON.parse
would crash on empty/malformed stdin, preventing data passthrough
- Add config parse error logging to evaluate-session.js
- Fix plugin.schema.json: author can be string or {name,url} object,
add version (semver pattern), homepage, keywords, skills, agents
- Fix package-manager.schema.json: add setAt (date-time) field and
make packageManager required to match actual code behavior
- 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
- Validate language names in install.sh to prevent path traversal via
malicious args like ../../etc (only allow [a-zA-Z0-9_-])
- Replace silent catch in check-console-log.js with stderr logging so
hook failures are visible to the user for debugging
- Escape backticks in session-end.js user messages to prevent markdown
structure corruption in session files
- 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