11 Commits

  • fix: sanitize getExecCommand args, escape regex in getCommandPattern, clean up readStdinJson timeout, add 10 tests
    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.
  • fix: add input validation, date range checks, and security hardening
    - validate-agents.js: reject invalid model names in agent frontmatter
    - package-manager.js: validate script/binary names against shell injection
    - session-manager.js: reject impossible month/day values in filenames
    - utils.js: support options.all for replaceInFile string patterns
    - strategic-compact/SKILL.md: fix hook matcher syntax and script reference
    - install.sh: warn when overwriting existing rule customizations
    - Add 24 new tests covering all validation and edge cases
  • fix: Windows path support, error handling, and dedup in validators
    - 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
  • fix: 6 bugs fixed, 67 tests added for session-manager and session-aliases
    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
  • fix: improve error handling, fix bugs, and optimize core libraries
    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: eliminate child process spawns during session startup (#162)
    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.
  • fix: resolve ESLint errors and update tests for project-name fallback
    - 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.
  • feat: cross-platform support with Node.js scripts
    - Rewrite all bash hooks to Node.js for Windows/macOS/Linux compatibility
    - Add package manager auto-detection (npm, pnpm, yarn, bun)
    - Add scripts/lib/ with cross-platform utilities
    - Add /setup-pm command for package manager configuration
    - Add comprehensive test suite (62 tests)
    
    Co-authored-by: zerx-lab