Move three complex inline hooks from hooks.json into proper external
scripts in scripts/hooks/:
- post-edit-format.js: Prettier auto-formatting (was 1 minified line)
- post-edit-typecheck.js: TypeScript check (was 1 minified line with
unbounded directory traversal, now capped at 20 levels)
- post-edit-console-warn.js: console.log warnings (was 1 minified line)
Benefits:
- Readable, documented, and properly error-handled
- Testable independently via stdin
- Consistent with other hooks (all use external scripts now)
- Adds timeouts to Prettier (15s) and tsc (30s) to prevent hangs
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)
getAvailablePackageManagers() spawned where.exe/which for each package
manager (npm, pnpm, yarn, bun). During SessionStart hooks, these 4+
child processes combined with Bun's own initialization exceeded the
spawn limit on Windows, freezing the terminal.
Fix: Remove process spawning from the hot path. Steps 1-5 of detection
(env var, project config, package.json, lock file, global config) already
cover all file-based detection. If none match, default to npm without
spawning. Also fix getSelectionPrompt() to list supported PMs without
checking availability.
session-end.js: Extract meaningful summaries from CLAUDE_TRANSCRIPT_PATH
instead of writing blank template files. Pulls user messages, tools used,
and files modified from the session transcript JSONL.
session-start.js: Output the latest session summary to stdout (via the
output() helper) so it gets injected into Claude's conversation context,
instead of only logging to stderr which just shows briefly in the terminal.
Add a new /sessions command to manage Claude Code session history with
alias support for quick access to previous sessions.
Features:
- List sessions with pagination and filtering (by date, ID)
- Load and view session content and metadata
- Create memorable aliases for sessions
- Remove aliases
- Display session statistics (lines, items, size)
- List all aliases
New libraries:
- scripts/lib/session-manager.js - Core session CRUD operations
- scripts/lib/session-aliases.js - Alias management with atomic saves
New command:
- commands/sessions.md - Complete command with embedded scripts
Modified:
- scripts/lib/utils.js - Add getAliasesPath() export
- scripts/hooks/session-start.js - Show available aliases on session start
Session format support:
- Old: YYYY-MM-DD-session.tmp
- New: YYYY-MM-DD-<short-id>-session.tmp
Aliases are stored in ~/.claude/session-aliases.json with Windows-
compatible atomic writes and backup support.
Co-authored-by: 王志坚 <wangzhijian10@bgyfw.com>
Co-authored-by: Claude <noreply@anthropic.com>
- 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.
- fix(utils.js): prevent command injection in commandExists() by using
spawnSync instead of execSync with string interpolation, and validate
input to only allow alphanumeric chars, dash, underscore, dot (#42)
- fix(utils.js): add security documentation to runCommand() warning
against passing user-controlled input
- fix(setup-package-manager.js): replace <script> and <binary> with
[script-name] and [binary-name] to avoid XSS scanner false positives (#43)
- fix(doc-updater.md): replace invalid 'npx ts-morph' with correct
'npx tsx scripts/codemaps/generate.ts' since ts-morph is a library,
not a CLI tool (#51)
Fixes#42, #43, #51