c5e68a17c8
* Refactor code structure for improved readability and maintainability * Add test results for search API and related functionalities - Created test result files for various search-related functionalities, including: - test-11-search-server-changes.json - test-12-context-hook-changes.json - test-13-worker-service-changes.json - test-14-patterns.json - test-15-gotchas.json - test-16-discoveries.json - test-17-all-bugfixes.json - test-18-all-features.json - test-19-all-decisions.json - test-20-session-search.json - test-21-prompt-search.json - test-22-decisions-endpoint.json - test-23-changes-endpoint.json - test-24-how-it-works-endpoint.json - test-25-contextualize-endpoint.json - test-26-timeline-around-observation.json - test-27-multi-param-combo.json - test-28-file-type-combo.json - Each test result file captures specific search failures or outcomes, including issues with undefined properties and successful execution of search queries. - Enhanced documentation of search architecture and testing strategies, ensuring compliance with established guidelines and improving overall search functionality. * feat: Enhance unified search API with catch-all parameters and backward compatibility - Implemented a unified search API at /api/search that accepts catch-all parameters for filtering by type, observation type, concepts, and files. - Maintained backward compatibility by keeping granular endpoints functional while routing through the same infrastructure. - Completed comprehensive testing of search capabilities with real-world query scenarios. fix: Address missing debug output in search API query tests - Flushed PM2 logs and executed search queries to verify functionality. - Diagnosed absence of "Raw Chroma" debug messages in worker logs, indicating potential issues with logging or query processing. refactor: Improve build and deployment pipeline for claude-mem plugin - Successfully built and synced all hooks and services to the marketplace directory. - Ensured all dependencies are installed and up-to-date in the deployment location. feat: Implement hybrid search filters with 90-day recency window - Enhanced search server to apply a 90-day recency filter to Chroma results before categorizing by document type. fix: Correct parameter handling in searchUserPrompts method - Added support for filter-only queries and improved dual-path logic for clarity. refactor: Rename FTS5 method to clarify fallback status - Renamed escapeFTS5 to escapeFTS5_fallback_when_chroma_unavailable to indicate its temporary usage. feat: Introduce contextualize tool for comprehensive project overview - Added a new tool to fetch recent observations, sessions, and user prompts, providing a quick project overview. feat: Add semantic shortcut tools for common search patterns - Implemented 'decisions', 'changes', and 'how_it_works' tools for convenient access to frequently searched observation categories. feat: Unified timeline tool supports anchor and query modes - Combined get_context_timeline and get_timeline_by_query into a single interface for timeline exploration. feat: Unified search tool added to MCP server - New tool queries all memory types simultaneously, providing combined chronological results for improved search efficiency. * Refactor search functionality to clarify FTS5 fallback usage - Updated `worker-service.cjs` to replace FTS5 fallback function with a more descriptive name and improved error handling. - Enhanced documentation in `SKILL.md` to specify the unified API endpoint and clarify the behavior of the search engine, including the conditions under which FTS5 is used. - Modified `search-server.ts` to provide clearer logging and descriptions regarding the fallback to FTS5 when UVX/Python is unavailable. - Renamed and updated the `SessionSearch.ts` methods to reflect the conditions for using FTS5, emphasizing the lack of semantic understanding in fallback scenarios. * feat: Add ID-based fetch endpoints and simplify mem-search skill **Problem:** - Search returns IDs but no way to fetch by ID - Skill documentation was bloated with too many options - Claude wasn't using IDs because we didn't tell it how **Solution:** 1. Added three new HTTP endpoints: - GET /api/observation/:id - GET /api/session/:id - GET /api/prompt/:id 2. Completely rewrote SKILL.md: - Stripped complexity down to essentials - Clear 3-step prescriptive workflow: Search → Review IDs → Fetch by ID - Emphasized ID usage: "The IDs are there for a reason - USE THEM" - Removed confusing multi-endpoint documentation - Kept only unified search with filters **Impact:** - Token efficiency: Claude can now fetch full details only for relevant IDs - Clarity: One clear workflow instead of 10+ options to choose from - Usability: IDs are no longer wasted context - they're actionable 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: Move internal docs to private directory Moved POSTMORTEM and planning docs to ./private to exclude from PR reviews. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Remove experimental contextualize endpoint - Removed contextualize MCP tool from search-server (saves ~4KB) - Disabled FTS5 fallback paths in SessionSearch (now vector-first) - Cleaned up CLAUDE.md documentation - Removed contextualize-rewrite-plan.md doc Rationale: - Contextualize is better suited as a skill (LLM-powered) than an endpoint - Search API already provides vector search with configurable limits - Created issue #132 to track future contextualize skill implementation Changes: - src/servers/search-server.ts: Removed contextualize tool definition - src/services/sqlite/SessionSearch.ts: Disabled FTS5 fallback, added deprecation warnings - CLAUDE.md: Cleaned up outdated skill documentation - docs/: Removed contextualize plan document 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Complete FTS5 cleanup - remove all deprecated search code This completes the FTS5 cleanup work by removing all commented-out FTS5 search code while preserving database tables for backward compatibility. Changes: - Removed 200+ lines of commented FTS5 search code from SessionSearch.ts - Removed deprecated degraded_search_query__when_uvx_unavailable method - Updated all method documentation to clarify vector-first architecture - Updated class documentation to reflect filter-only query support - Updated CLAUDE.md to remove FTS5 search references - Clarified that FTS5 tables exist for backward compatibility only - Updated "Why SQLite FTS5" section to "Why Vector-First Search" Database impact: NONE - FTS5 tables remain intact for existing installations Search architecture: - ChromaDB: All text-based vector search queries - SQLite: Filter-only queries (date ranges, metadata, no query text) - FTS5 tables: Maintained but unused (backward compatibility) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: Remove all FTS5 fallback execution code from search-server Completes the FTS5 cleanup by removing all fallback execution paths that attempted to use FTS5 when ChromaDB was unavailable. Changes: - Removed all FTS5 fallback code execution paths - When ChromaDB fails or is unavailable, return empty results with helpful error messages - Updated all deprecated tool descriptions (search_observations, search_sessions, search_user_prompts) - Changed error messages to indicate FTS5 fallback has been removed - Added installation instructions for UVX/Python when vector search is unavailable - Updated comments from "hybrid search" to "vector-first search" - Removed ~100 lines of dead FTS5 fallback code Database impact: NONE - FTS5 tables remain intact (backward compatibility) Search behavior when ChromaDB unavailable: - Text queries: Return empty results with error explaining ChromaDB is required - Filter-only queries (no text): Continue to work via direct SQLite 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: Address PR 133 review feedback Critical fixes: - Remove contextualize endpoint from worker-service (route + handler) - Fix build script logging to show correct .cjs extension (was .mjs) Documentation improvements: - Add comprehensive FTS5 retention rationale documentation - Include v7.0.0 removal TODO for future cleanup Testing: - Build succeeds with correct output logging - Worker restarts successfully (30th restart) - Contextualize endpoint properly removed (404 response) - Search endpoint verified working This addresses all critical review feedback from PR 133. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
1 line
8.9 KiB
JSON
1 line
8.9 KiB
JSON
[{"type":"text","text":"## Add filter-only query path to searchUserPrompts method\n*Source: claude-mem://observation/10755*\n\n**Method accepts undefined query and handles dual-path logic with separate parameter arrays for clarity.**\n\nThe searchUserPrompts method has been enhanced with filter-only query support, completing the pattern established in searchObservations and searchSessions. The method signature now accepts optional query parameter. The implementation builds base filter conditions once for project and date range filters, then diverges into two paths. The filter-only path (when query is undefined) validates that at least some filters exist, then queries the user_prompts table directly with a WHERE clause, joining sdk_sessions for project filtering. The FTS5 path rebuilds filter conditions into a separate ftsParams array to avoid parameter ordering conflicts between the two paths. This dual-path approach enables both semantic/keyword search via FTS5 and pure metadata filtering via direct SQLite queries, completing the architectural pattern across all three search methods.\n\n---\nType: feature | Facts: searchUserPrompts signature changed to accept `query: string | undefined` at line 541; Filter conditions built once and shared between filter-only and FTS5 paths at lines 546-563; Filter-only path at lines 566-588 validates filters exist and queries user_prompts table directly; FTS5 path at lines 591-616 rebuilds filter conditions with separate ftsParams array to avoid parameter conflicts; Filter-only path joins sdk_sessions table for project filtering support; Documentation updated to clarify dual-mode operation matching searchObservations and searchSessions patterns | Concepts: what-changed, how-it-works, pattern, gotcha | Files: src/services/sqlite/SessionSearch.ts\n\n---\nDate: 11/17/2025, 11:50:08 PM\n\n---\n\n## searchUserPrompts Uses Custom ORDER BY Logic Instead of buildOrderClause\n*Source: claude-mem://observation/10754*\n\n**Unlike searchObservations, searchUserPrompts implements inline ORDER BY construction with hard-coded table aliases rather than using buildOrderClause helper.**\n\nThe searchUserPrompts method implements its ORDER BY logic inline rather than using the buildOrderClause helper method used by searchObservations and searchSessions. Lines 619-623 show a ternary expression that constructs the ORDER BY clause with hard-coded references to user_prompts_fts.rank for relevance ordering and up.created_at_epoch for date-based sorting. The main SQL query joins three tables: user_prompts, user_prompts_fts, and sdk_sessions, with the sdk_sessions join enabling project-based filtering. When implementing the filter-only path for this method, the code will need to construct a query that joins only user_prompts and sdk_sessions (skipping user_prompts_fts), and the ORDER BY logic will need to handle the absence of FTS5 rank data, defaulting to date-based ordering when query is undefined.\n\n---\nType: discovery | Facts: searchUserPrompts constructs ORDER BY clause inline at lines 619-623 instead of calling buildOrderClause; The inline ORDER BY uses hard-coded table alias user_prompts_fts.rank for relevance ordering; Date-based ordering uses up.created_at_epoch for both ascending and descending sorts; The SQL query joins user_prompts, user_prompts_fts, and sdk_sessions tables; searchUserPrompts will need filter-only path to query user_prompts without user_prompts_fts JOIN when query is undefined | Concepts: how-it-works, pattern | Files: src/services/sqlite/SessionSearch.ts\n\n---\nDate: 11/17/2025, 11:50:07 PM\n\n---\n\n## User Prompts Search Joins Three Tables for Filtering\n*Source: claude-mem://observation/10753*\n\n**searchUserPrompts method joins user_prompts, user_prompts_fts, and sdk_sessions tables to enable project-based filtering.**\n\nThe searchUserPrompts method demonstrates a more complex query structure than searchObservations or searchSessions due to the need for project filtering. Since user_prompts don't directly store project information, the method joins with the sdk_sessions table using claude_session_id as the key, which allows filtering by the project field from sdk_sessions. The query structure follows the same FTS5 pattern seen in other search methods: it joins the base table (user_prompts) with its FTS5 virtual table (user_prompts_fts) via rowid, uses the MATCH operator for full-text search, and orders by rank for relevance-based results. The default limit is set to 20 rather than 50, suggesting user prompts are typically returned in smaller batches. Like the other search methods, rank values are normalized to a 0-1 score scale where higher values indicate better matches, inverting FTS5's native lower-is-better ranking.\n\n---\nType: discovery | Facts: searchUserPrompts method joins three tables: user_prompts, user_prompts_fts, and sdk_sessions; sdk_sessions table joined via claude_session_id to enable project filtering on user prompts; user_prompts table aliased as 'up' and uses MATCH operator on user_prompts_fts virtual table; Default limit for user prompts is 20, compared to 50 for observations and sessions; Method supports dateRange filtering using created_at_epoch column from user_prompts table; Rank normalization converts FTS5 rank scores to 0-1 scale where higher values indicate better matches | Concepts: how-it-works, pattern | Files: /Users/alexnewman/Scripts/claude-mem/src/services/sqlite/SessionSearch.ts\n\n---\nDate: 11/17/2025, 11:49:42 PM\n\n---\n\n## Add filter-only query path to searchSessions method\n*Source: claude-mem://observation/10751*\n\n**Method now accepts undefined query and queries session_summaries table directly for metadata-only filtering.**\n\nThe searchSessions method in SessionSearch.ts has been enhanced to support filter-only queries without query text. The method signature now accepts `query: string | undefined`, enabling two distinct code paths. When query is undefined, a new filter-only path (lines 331-352) bypasses FTS5 entirely and queries the session_summaries table directly using metadata filters like project or date range. This path validates that at least some filters exist, throwing an error if both query and filters are missing. When query text is provided, the existing FTS5 search path executes as before. This dual-mode approach allows the system to handle both semantic/keyword search and pure metadata filtering, addressing the architectural requirement that filter-only queries skip text search mechanisms.\n\n---\nType: feature | Facts: searchSessions signature changed to accept `query: string | undefined` at line 327; New filter-only path added at lines 331-352 that bypasses FTS5 when query is undefined; Filter-only path throws error if neither query nor filters provided at line 336; Direct SQLite query on session_summaries table uses WHERE clause built from metadata filters; FTS5 path at line 355 only executes when query text exists; Documentation updated to clarify dual-mode operation: FTS5 fallback vs filter-only direct query | Concepts: what-changed, how-it-works, pattern | Files: src/services/sqlite/SessionSearch.ts\n\n---\nDate: 11/17/2025, 11:49:23 PM\n\n---\n\n## SessionSearch Methods Use FTS5 for Full-Text Search\n*Source: claude-mem://observation/10750*\n\n**Observed searchSessions method implementation showing FTS5 virtual table usage with rank-based relevance scoring.**\n\nThe SessionSearch.searchSessions method demonstrates the FTS5 full-text search implementation for session summaries. The method builds a SQL query that joins the session_summaries table with its corresponding session_summaries_fts virtual table, using the MATCH operator for full-text search. The query construction includes filter support (excluding type filters which aren't applicable to sessions), and adjusts column names to account for session_summaries using files_edited instead of files_modified. When orderBy is set to 'relevance', the query orders by session_summaries_fts.rank in ascending order, where lower rank values indicate better matches (FTS5 convention). The method then normalizes these ranks into 0-1 scores where higher is better. This pattern is consistent with searchObservations and searchUserPrompts methods, all using the same FTS5-based approach as a fallback when ChromaDB semantic search is unavailable.\n\n---\nType: discovery | Facts: searchSessions method in SessionSearch.ts performs FTS5 full-text search on session summaries; Method queries session_summaries_fts virtual table and joins with session_summaries table; FTS5 relevance ranking uses rank ASC ordering where lower rank values indicate better matches; Method supports three order modes: relevance (FTS5 rank), date_asc, and date_desc; Files_modified column name is replaced with files_edited for session_summaries table compatibility; Method uses escapeFTS5_fallback_when_chroma_unavailable to sanitize query input | Concepts: how-it-works, pattern | Files: /Users/alexnewman/Scripts/claude-mem/src/services/sqlite/SessionSearch.ts\n\n---\nDate: 11/17/2025, 11:49:09 PM"}] |