- 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
- 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
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
utils.js:
- Fix countInFile: enforce global flag on regex to prevent silent
under-counting (match() without /g returns only first match)
- Add 5s timeout to readStdinJson to prevent hooks hanging forever
- Handle EEXIST race condition in ensureDir
- Pre-compile regex patterns in getGitModifiedFiles to avoid N*M
compilations and catch invalid patterns before filtering
- Add JSDoc documentation to all improved functions
session-manager.js:
- Fix getSessionById triple file read: pass pre-read content to
getSessionStats instead of re-reading from disk
- Allow getSessionStats to accept content string directly
session-aliases.js:
- Wrap temp file cleanup in try/catch to prevent cascading errors
check-console-log.js:
- Refactor to use shared utils (isGitRepo, getGitModifiedFiles, log)
instead of raw execSync calls
- Add exclusion patterns for test files, config files, and scripts/
where console.log is intentional
session-end.js:
- Log count of skipped unparseable transcript lines for diagnostics
suggest-compact.js:
- Guard against NaN from corrupted counter files
package-manager.js:
- Remove dead fallbackOrder parameter (unused after #162 fix)
- Fix 16 ESLint no-unused-vars errors across hook scripts and tests
- Add eslint-disable comment for intentional control-regex in ANSI stripper
- Update session file test to use getSessionIdShort() instead of hardcoded 'default'
(reflects PR #110's project-name fallback behavior)
- Add marketing/ to .gitignore (local drafts)
- Add skill-create-output.js (terminal output formatter)
All 69 tests now pass. CI should be green.
Fixes#78
## Problem
The Stop hook used inline JavaScript code with `node -e`, which caused
shell syntax errors on macOS/zsh due to special characters (parentheses,
braces, arrow functions) being misinterpreted by the shell.
Error message:
/bin/sh: -c: line 0: syntax error near unexpected token \`('
## Solution
- Created scripts/hooks/check-console-log.js with the hook logic
- Updated hooks/hooks.json to reference the external script
- This follows the same pattern as other hooks in the plugin
## Benefits
- Fixes shell compatibility issues across different environments
- Improves code maintainability (separate, well-documented script)
- Follows plugin's own best practices
- Makes the code easier to test and debug
## Testing
Tested on macOS with zsh - no more syntax errors.
The hook still functions correctly to detect console.log statements.