Commit Graph

29 Commits

Author SHA1 Message Date
Alex Newman
309e8a7139 Implement hybrid search: Chroma semantic + SQLite temporal
Core implementation:
- Added Chroma MCP client integration to search-server.ts
- Implemented queryChroma() helper with Python dict parsing
- Added VECTOR_DB_DIR constant to paths.ts
- Added SessionStore.getObservationsByIds() method

Search handlers updated:
- search_observations: Semantic-first with 90-day temporal filter
- find_by_concept/type/file: Metadata-first, semantic-enhanced ranking
- All handlers fall back to FTS5 if Chroma unavailable

Technical details:
- Direct MCP client usage (no abstractions)
- Regex parsing of Chroma Python dict responses
- Semantic ranking preserved in final results
- Graceful degradation to FTS5-only search

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-31 23:00:04 -04:00
Alex Newman
df44bd8fd3 Fix double shebang: remove shebang from TS source files (esbuild adds it) 2025-10-26 00:01:04 -04:00
Alex Newman
e9c0ec45db Consolidate hooks: merge bin/hooks and hooks into single hooks/ directory
- Removed bin/hooks/ wrapper layer
- Moved all hook logic into consolidated hooks/*-hook.ts files
- Each hook now handles its own stdin/stdout/JSON wrapping
- Removed ALL try-catch blocks from context-hook (let errors surface)
- Updated build script to reference new src/hooks/ paths
- Reduced from 12+ files to 6 hook files

This simplifies the architecture and makes debugging actually possible.
2025-10-25 23:59:43 -04:00
Alex Newman
81fdf28347 Fix critical bug: getSessionById missing claude_session_id
Critical bugfix for NOT NULL constraint violation.

Problem:
- Worker service calls getSessionById(sessionDbId) to fetch session data
- Worker then uses dbSession.claude_session_id to create ActiveSession
- But getSessionById was NOT selecting claude_session_id from database
- Result: claudeSessionId = undefined in worker
- Caused: "NOT NULL constraint failed: sdk_sessions.claude_session_id" errors
- Impact: Observations and summaries couldn't be stored

Root cause:
- SessionStore.getSessionById() SQL query missing claude_session_id column
- Line 710-713: "SELECT id, sdk_session_id, project, user_prompt"
- Should be: "SELECT id, claude_session_id, sdk_session_id, project, user_prompt"

Fix:
- Added claude_session_id to SELECT query in getSessionById
- Updated return type to include claude_session_id: string
- Now worker correctly receives claude_session_id from database
- Session ID from hook flows properly through entire system

Files changed:
- src/services/sqlite/SessionStore.ts (getSessionById method)

Testing:
- Build succeeded
- Ready for PM2 restart and live testing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-24 22:18:03 -04:00
Alex Newman
0adbf38c39 fix: update getDirname function to support both ESM and CJS contexts 2025-10-23 23:03:48 -04:00
Alex Newman
15362d1aed Refactor getDirname function to only return __dirname for CJS context 2025-10-23 23:00:34 -04:00
Alex Newman
3042de1093 feat(SessionStore): update SDK session creation to include sdk_session_id 2025-10-21 22:16:06 -04:00
Alex Newman
f7f62ef3f3 feat(SessionStore): auto-create session records if missing
- Added functionality to automatically create a session record in the database if it does not exist when storing observations or session summaries.
- Updated `storeObservation` and `storeSummary` methods to include checks for existing session records and insert new records as needed.
- Added logging for auto-created session records for better traceability.
2025-10-21 22:13:13 -04:00
Alex Newman
726f167ebf feat: Implement full-text search for user prompts
- Added functionality to save raw user prompts for full-text search in the newHook function.
- Introduced new search endpoint 'search_user_prompts' to retrieve user prompts using FTS5.
- Created UserPromptRow and UserPromptSearchResult types for handling user prompt data.
- Implemented searchUserPrompts method in SessionSearch class to perform FTS5 queries.
- Created user_prompts table with FTS5 support and necessary triggers for data synchronization.
- Updated SessionStore to include methods for saving user prompts and managing the new table.
2025-10-21 22:02:06 -04:00
Alex Newman
c27f07023c fix: Remove all session validation to prevent continuation errors after /exit
Root cause: Hooks provide session_id as the source of truth. We were adding
unnecessary validation (checking if sessions exist, checking status, etc.)
which caused 409 conflicts when continuing sessions after /exit.

Changes:
1. worker-service.ts: Removed 409 "Session already exists" check in handleInit
2. SessionStore.ts: Made createSDKSession idempotent using INSERT OR IGNORE
3. new-hook.ts: Simplified to just call createSDKSession - no findActiveSDKSession,
   no reactivateSession logic, no status management
4. save-hook.ts: Removed session validation, use fixed port instead of session.worker_port
5. summary-hook.ts: Removed session validation, use fixed port instead of session.worker_port

Philosophy: Hooks manage lifecycle, we just save data with whatever session_id
they give us. No validation, no status checks, no guessing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-21 21:44:58 -04:00
Alex Newman
ef572ec032 Refactor summary generation from session-level to request-level
Changed summary prompts to generate discrete per-request summaries instead of cumulative session summaries. This provides better chronological memory where each summary is a clean unit representing one request/response cycle.

Changes:
- Renamed buildFinalizePrompt() to buildSummaryPrompt() in src/sdk/prompts.ts
- Updated prompt text to focus on "THIS REQUEST" rather than "this session"
- Updated all import and function call sites in worker-service.ts and worker.ts
- Added IMPORTANT warning to emphasize request-level scope

Expected behavior: Each summary will now describe only what happened during that specific request, eliminating cumulative recaps.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-21 17:27:14 -04:00
Alex Newman
df0f3fd96c Enhance context hook output formatting and add file aggregation for sessions
- Updated contextHook to support colorized output for terminal and JSON format for hooks.
- Introduced ANSI color codes for improved readability in terminal output.
- Modified the output structure to include session details with color formatting.
- Added a new method in SessionStore to aggregate files read and modified from observations for a session.
- Improved error handling for JSON parsing of file data in the new method.
2025-10-21 16:37:16 -04:00
Alex Newman
651989c423 refactor: Replace TypeScript bootstrap with bash dependency checks
Simplified dependency installation by moving from TypeScript runtime bootstrap to bash-based checks in plugin manifest. This reduces complexity and code size while maintaining the same functionality.

Changes:
- Added bash conditional dependency checks to all 5 hooks in hooks.json
- Check runs before each hook: [ ! -d "${CLAUDE_PLUGIN_ROOT}/scripts/node_modules" ] && cd "${CLAUDE_PLUGIN_ROOT}/scripts" && npm install || true
- Reverted all hook TypeScript files to use simple static imports (removed dynamic imports)
- Removed src/shared/bootstrap.ts (44 lines)
- Removed ensureDependencies() calls from all hook entry points

Benefits:
- Simpler architecture using native bash instead of TypeScript
- Net reduction of 157 lines of code
- No runtime overhead when dependencies already installed
- Uses plugin manifest's command hook feature as intended
- Faster and more efficient

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-20 17:01:24 -04:00
Alex Newman
9dd8b180ac fix: Use dynamic imports in hooks to fix better-sqlite3 loading
Changed all hook entry points to use dynamic imports after bootstrap runs. This ensures that better-sqlite3 is installed before Node.js attempts to resolve the import.

Changes:
- Modified src/bin/hooks/*.ts to call ensureDependencies() before dynamic import
- Moved from static `import { hook } from '...'` to `const { hook } = await import('...')`
- This delays module resolution until after npm install completes
- Bumped version to 4.0.6

The previous approach failed because static imports are resolved at module link time, before any runtime code (including ensureDependencies) executes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-20 16:54:28 -04:00
Alex Newman
6fb9570291 feat: Release v4.0.5 - Auto-install dependencies via bootstrap hooks
Fixed better-sqlite3 distribution by implementing self-bootstrapping hooks
that auto-install dependencies on first run. This eliminates the need for
users to have native compilation tools or manually install dependencies.

## Solution

Instead of bundling 25MB of better-sqlite3 binaries in git or requiring
manual npm install, hooks now bootstrap themselves on first execution:

1. Created `src/shared/bootstrap.ts` with `ensureDependencies()` function
2. Added bootstrap calls to all hook entry points (context, new, save, summary, cleanup)
3. Created `plugin/scripts/package.json` declaring better-sqlite3 dependency
4. Bootstrap checks if `node_modules` exists, runs `npm install` if missing
5. npm automatically downloads prebuilt better-sqlite3 binary for user's platform

## Changes

**Core Bootstrap System:**
- Added src/shared/bootstrap.ts: Auto-install dependencies using npm
- Modified all hooks (context, new, save, summary, cleanup) to call ensureDependencies()
- Created plugin/scripts/package.json with better-sqlite3 dependency

**Build & Distribution:**
- Removed node_modules copying logic from build script
- Build output is now compact (hooks + package.json, no binaries)
- Updated marketplace.json to point to GitHub for direct installation

**Documentation:**
- Updated README: GitHub Marketplace installation is now recommended method
- Installation instructions emphasize no compilation needed
- Version bumped to 4.0.5 throughout

## Benefits

-  No git bloat (repo stays small, no 25MB binaries committed)
-  No compilation needed (npm downloads prebuilt binaries)
-  Works on all platforms (npm handles platform-specific binaries)
-  Zero manual steps (hooks bootstrap themselves automatically)
-  Idempotent (skips install if dependencies already exist)

Installation now works via simple:
```
/plugin marketplace add https://github.com/thedotmack/claude-mem
/plugin install claude-mem
```

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-20 16:44:26 -04:00
Alex Newman
f849a69506 fix: Move ensureWorkerRunning to start of hooks to prevent race condition
All hooks now call ensureWorkerRunning() BEFORE querying the database. This
ensures the worker's orphaned session cleanup runs before hooks check for
active sessions, preventing 404 errors when hooks try to use sessions that
don't exist in worker memory after a restart.

Hook order now:
1. ensureWorkerRunning() - starts worker, runs cleanup
2. Query DB - cleanup already marked orphaned sessions as failed
3. Use session - only valid sessions are processed

Fixed in:
- new-hook: Line 26, before DB queries
- save-hook: Line 37, before DB queries
- summary-hook: Line 24, before DB queries
- cleanup-hook: Line 50, before DB queries

This prevents the race condition where hooks would read session status before
cleanup ran, then get 404 from worker after cleanup marked sessions failed.
2025-10-19 02:01:11 -04:00
Alex Newman
daf368e343 Refactor code structure for improved readability and maintainability 2025-10-19 01:45:51 -04:00
Alex Newman
7ff611feb5 Refactor hooks and worker service for improved error handling and initialization
- Removed try-catch blocks in new-hook, save-hook, and summary-hook for cleaner flow.
- Enhanced error handling in save and summary hooks to throw errors instead of logging and returning.
- Introduced ensureWorkerRunning utility to manage worker service lifecycle and health checks.
- Replaced dynamic port allocation with a fixed port for the worker service.
- Simplified path management and removed unused port allocator utility.
- Added database schema initialization for fresh installations and improved migration handling.
2025-10-19 00:57:49 -04:00
Alex Newman
002f7a94b8 feat: Release v4.0.0 - Plugin data directory and auto-starting worker
BREAKING CHANGES:
- Data directory moved from ~/.claude-mem/ to ${CLAUDE_PLUGIN_ROOT}/data/
- Fresh start required - no migration from v3.x databases
- Worker service now auto-starts on SessionStart hook

New Features:
- MCP Search Server with 6 specialized search tools
- FTS5 full-text search across observations and sessions
- Auto-starting worker service in SessionStart hook
- Citation support for search results (claude-mem:// URIs)

Changes:
- Updated paths.ts to use CLAUDE_PLUGIN_ROOT for data directory
- Added worker auto-start logic to context hook
- Updated worker service to write port file to plugin data dir
- Bumped version to 4.0.0 in package.json and plugin.json
- Created comprehensive CHANGELOG.md documenting v4.0.0 changes
- Updated README.md with v4.0.0 breaking changes and features
- Rebuilt all hooks and worker service

Technical Improvements:
- Improved error handling and graceful degradation
- Structured logging across all components
- Enhanced plugin integration with Claude Code

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-19 00:05:56 -04:00
Alex Newman
115270c35e feat: Implement session management and search functionality
- Added SDK session, observation, and summary types to types.ts.
- Refactored worker-service to use SessionStore for session management.
- Created SessionSearch class for FTS5 full-text search and structured queries.
- Implemented SessionStore for CRUD operations on SDK sessions, observations, and summaries.
- Added migrations for database schema updates, including new columns and constraints.
- Enhanced search capabilities with filters for projects, types, concepts, and date ranges.
2025-10-18 20:15:55 -04:00
Alex Newman
c27682c799 Refactor summary and session retrieval logic in HooksDatabase
- Updated SQL queries in summary-hook.js and HooksDatabase.ts to improve performance and clarity.
- Introduced a subquery for fetching recent sessions with status, ensuring correct ordering and grouping.
- Enhanced logging functionality for better debugging and error tracking.
- Added comprehensive documentation in README.md to outline the new features and usage instructions.
2025-10-18 19:44:14 -04:00
Alex Newman
1fbba55aa3 Refactor summary and context handling in hooks
- Updated `summary-hook.js` to improve logging and session handling.
- Modified `context.ts` to fetch recent sessions with status and summary info, enhancing output formatting.
- Added new methods in `HooksDatabase.ts` for retrieving recent sessions and their summaries.
- Improved observation retrieval logic in `context.ts` to display relevant information for active sessions.
- Enhanced prompt documentation in `prompts.ts` to clarify output expectations.
- Refactored logger methods in `logger.ts` to instance methods for better encapsulation.
2025-10-18 19:29:45 -04:00
Alex Newman
05f3889deb feat(logging): Implement structured logging across the application
- Introduced a new Logger utility to standardize logging with correlation IDs and structured context.
- Replaced console.error and console.log statements with logger methods in various modules including save.ts, summary.ts, parser.ts, HooksDatabase.ts, and worker-service.ts.
- Enhanced error handling and logging for better traceability of observations and summaries.
- Made observations.text nullable in the database schema to support structured fields.
- Added correlation IDs for tracking observations through the processing pipeline.
2025-10-18 19:15:52 -04:00
Alex Newman
874815770a fix: Add missing process.exit(0) calls in hook entry points
All 4 hook entry point scripts were missing process.exit(0) after successful
execution, causing Node processes to hang indefinitely instead of returning
control to Claude Code with exit code 0.

Root cause: In commit 6f62a56, process.exit(0) calls were removed from the
hook functions but were never added to the entry point scripts that wrap them.

Fixed files:
- src/bin/hooks/save-hook.ts (PostToolUse)
- src/bin/hooks/new-hook.ts (UserPromptSubmit)
- src/bin/hooks/summary-hook.ts (Stop)
- src/bin/hooks/context-hook.ts (SessionStart)

This restores proper hook exit behavior and prevents Claude Code from waiting
indefinitely for hook completion.
2025-10-18 18:49:11 -04:00
Alex Newman
81101ef1a6 feat: Enhance observation and summary structures in hooks
- Updated observation schema to include hierarchical fields: title, subtitle, facts, narrative, concepts, files_read, and files_modified.
- Modified the save-hook and summary-hook scripts to accommodate the new observation structure.
- Added migration logic to the HooksDatabase for adding new fields to the observations table.
- Refactored the parser to extract new fields from XML formatted observations.
- Adjusted prompt generation to reflect the new observation format and requirements.
- Updated worker service to handle new observation and summary structures.
2025-10-18 17:34:24 -04:00
Alex Newman
015b38c763 Refactor database hooks to add new session tracking features
- Introduced `getSessionById` method in HooksDatabase to retrieve session details by ID.
- Updated context, new, save, and summary hooks to utilize the new `getSessionById` method.
- Enhanced session management by adding `worker_port` and `prompt_counter` columns to relevant tables.
- Improved logging in WorkerService to provide clearer output during session initialization and processing.
- Removed redundant error logging in favor of more informative console logs.
2025-10-17 16:42:23 -04:00
Alex Newman
be936d8413 Enhance HooksDatabase and WorkerService functionality
- Updated save-hook.js and summary-hook.js to include new database columns for tracking worker ports and prompt numbers.
- Implemented migration logic to remove UNIQUE constraints from session_summaries table and added necessary indices.
- Modified HooksDatabase methods to return boolean values indicating success or failure of updates.
- Changed logging from error to info level in WorkerService for better clarity on session management and initialization.
2025-10-17 16:32:20 -04:00
Alex Newman
d4a71c994d feat: Enhance session management with prompt tracking
- Added prompt_number to observations and session summaries for better tracking.
- Implemented prompt counter in SDK sessions to manage user prompts effectively.
- Updated database schema to include prompt tracking columns and removed unique constraints on session summaries.
- Modified hooks to utilize prompt_number in observations and summaries.
- Changed worker service to handle summarize requests instead of finalize, keeping the SDK agent active.
- Improved logging for better debugging and tracking of prompt numbers across sessions.
2025-10-17 16:23:11 -04:00
Alex Newman
372854948c feat: Implement Worker Service with session management and SDK integration
- Added WorkerService to handle long-running HTTP service with session management.
- Implemented endpoints for initializing, observing, finalizing, checking status, and deleting sessions.
- Integrated with Claude SDK for processing observations and generating responses.
- Added port allocator utility to dynamically find available ports for the service.
- Configured TypeScript settings for the project.
2025-10-17 15:59:36 -04:00