- parseSessionMetadata: blank line within Completed section truncates items
due to regex lookahead (?=###|\n\n|$) stopping at \n\n boundary
- grepFile: sticky (y) flag not stripped like g flag, causing stateful
.test() behavior that misses matching lines
- getExecCommand: object args bypass SAFE_ARGS_REGEX (typeof !== 'string')
but coerce to "[object Object]" in command string
- detectFromPackageJson with scoped package name (@scope/pkg@version)
returns null because split('@')[0] yields empty string
- getPackageManager skips empty string CLAUDE_PACKAGE_MANAGER via
falsy short-circuit (distinct from unknown PM name test)
- session-end buildSummarySection includes Tools Used but omits
Files Modified when transcript has only Read/Grep tools
Total tests: 842
- Test countInFile returns 0 for object pattern type (non-string non-RegExp)
- Test getSessionStats treats Windows UNC path as content (not file path)
- Test detectFromPackageJson returns null for empty string packageManager field
Total tests: 836
- Test getCommandPattern('') produces valid regex for empty action string
- Test detectFromPackageJson returns null for whitespace-only packageManager
- Test getSessionStats treats mixed Windows path separators as file path
Total tests: 833
- loadAliases resets to defaults when aliases field is a truthy non-object (string)
- detectFromPackageJson returns null for empty (0-byte) package.json
- evaluate-session uses learned_skills_path config override with ~ expansion
Round 80: Three previously untested conditional branches:
- session-end.js: entry.message?.role === 'user' third OR condition
(fires when type is not 'user' but message.role is)
- package-manager.js: getExecCommand with truthy non-string args
(typeof check short-circuits, value still appended via ternary)
- validate-hooks.js: legacy array format parsing path (lines 115-135)
with 'Hook N' error labels instead of 'EventType[N]'
- utils.test.js: replaceInFile returns false on read-only file (catch block)
- session-manager.test.js: getAllSessions returns empty when sessions dir missing
- package-manager.test.js: getPackageManager falls through corrupted global config to npm default
788 tests total, all passing.
When --global or --project was followed by another flag (e.g., --global --project),
the flag was treated as a package manager name. Added pmName.startsWith('-') check
to both handlers. Added 20 tests across 4 test files covering argument validation,
ensureDir error propagation, runCommand stderr handling, and saveAliases failure paths.
new Date('YYYY-MM-DD') creates UTC midnight, which in negative UTC offset
timezones (e.g., Hawaii) causes getDate() to return the previous day.
Replaced with new Date(year, month - 1, day) for correct local-time behavior.
Added 15 tests: session-manager datetime verification and edge cases (7),
package-manager getCommandPattern special characters (4), and
validators model/skill-reference validation (4). Tests: 651 → 666.
Validate args parameter in getExecCommand() against SAFE_ARGS_REGEX to
prevent command injection when returned string is passed to a shell.
Escape regex metacharacters in getCommandPattern() generic action branch
to prevent malformed patterns and unintended matching. Clean up stdin
listeners in readStdinJson() timeout path to prevent process hanging.
- Test valid project-config detection (.claude/package-manager.json)
- Test priority order: project-config > package.json > lock-file
- Test package.json > lock-file priority
- Test default fallback to npm
- Test setPreferredPackageManager success case
- Test getCommandPattern for test and build actions
The prompt no longer lists "Available package managers" (which required
spawning processes) — it now shows "Supported package managers" and
mentions lock file detection as a configuration option.
All 69 tests pass.
- 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.