18 Commits

  • fix: use local-time Date constructor in session-manager to prevent timezone day shift
    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.
  • fix: clamp getAllSessions pagination params, add cleanupAliases success field, add 10 tests
    - session-manager: clamp offset/limit to safe non-negative integers to
      prevent negative offset counting from end and NaN returning empty results
    - session-aliases: add success field to cleanupAliases return value for
      API contract consistency with setAlias/deleteAlias/renameAlias
  • fix: calendar-accurate date validation in parseSessionFilename, add 22 tests
    - Fix parseSessionFilename to reject impossible dates (Feb 31, Apr 31,
      Feb 29 non-leap) using Date constructor month/day roundtrip check
    - Add 6 session-manager tests for calendar date validation edge cases
    - Add 3 session-manager tests for code blocks/special chars in getSessionStats
    - Add 10 package-manager tests for PM-specific command formats (getRunCommand
      and getExecCommand for pnpm, yarn, bun, npm)
    - Add 3 integration tests for session-end transcript parsing (mixed JSONL
      formats, malformed lines, nested user messages)
  • 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: renameAlias data corruption, empty sessionId match, NaN threshold
    - 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
  • fix: harden error handling, fix TOCTOU races, and improve test accuracy
    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
  • 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)
  • feat: add /sessions command for session history management (#142)
    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>