claude-conversation-memory-mcp 0.6.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/README.md +53 -0
  2. package/dist/ConversationMemory.d.ts +151 -10
  3. package/dist/ConversationMemory.d.ts.map +1 -1
  4. package/dist/ConversationMemory.js +127 -10
  5. package/dist/ConversationMemory.js.map +1 -1
  6. package/dist/cache/QueryCache.d.ts +215 -0
  7. package/dist/cache/QueryCache.d.ts.map +1 -0
  8. package/dist/cache/QueryCache.js +294 -0
  9. package/dist/cache/QueryCache.js.map +1 -0
  10. package/dist/mcp-server.d.ts.map +1 -1
  11. package/dist/mcp-server.js +4 -1
  12. package/dist/mcp-server.js.map +1 -1
  13. package/dist/parsers/ConversationParser.d.ts +62 -3
  14. package/dist/parsers/ConversationParser.d.ts.map +1 -1
  15. package/dist/parsers/ConversationParser.js +50 -3
  16. package/dist/parsers/ConversationParser.js.map +1 -1
  17. package/dist/parsers/DecisionExtractor.d.ts +61 -3
  18. package/dist/parsers/DecisionExtractor.d.ts.map +1 -1
  19. package/dist/parsers/DecisionExtractor.js +47 -3
  20. package/dist/parsers/DecisionExtractor.js.map +1 -1
  21. package/dist/parsers/GitIntegrator.d.ts +88 -3
  22. package/dist/parsers/GitIntegrator.d.ts.map +1 -1
  23. package/dist/parsers/GitIntegrator.js +68 -3
  24. package/dist/parsers/GitIntegrator.js.map +1 -1
  25. package/dist/parsers/MistakeExtractor.d.ts +62 -3
  26. package/dist/parsers/MistakeExtractor.d.ts.map +1 -1
  27. package/dist/parsers/MistakeExtractor.js +50 -3
  28. package/dist/parsers/MistakeExtractor.js.map +1 -1
  29. package/dist/parsers/RequirementsExtractor.d.ts +95 -4
  30. package/dist/parsers/RequirementsExtractor.d.ts.map +1 -1
  31. package/dist/parsers/RequirementsExtractor.js +73 -4
  32. package/dist/parsers/RequirementsExtractor.js.map +1 -1
  33. package/dist/storage/BackupManager.d.ts +58 -0
  34. package/dist/storage/BackupManager.d.ts.map +1 -0
  35. package/dist/storage/BackupManager.js +213 -0
  36. package/dist/storage/BackupManager.js.map +1 -0
  37. package/dist/storage/ConversationStorage.d.ts +271 -2
  38. package/dist/storage/ConversationStorage.d.ts.map +1 -1
  39. package/dist/storage/ConversationStorage.js +356 -7
  40. package/dist/storage/ConversationStorage.js.map +1 -1
  41. package/dist/storage/DeletionService.d.ts +70 -0
  42. package/dist/storage/DeletionService.d.ts.map +1 -0
  43. package/dist/storage/DeletionService.js +198 -0
  44. package/dist/storage/DeletionService.js.map +1 -0
  45. package/dist/tools/ToolDefinitions.d.ts +26 -0
  46. package/dist/tools/ToolDefinitions.d.ts.map +1 -1
  47. package/dist/tools/ToolDefinitions.js +24 -0
  48. package/dist/tools/ToolDefinitions.js.map +1 -1
  49. package/dist/tools/ToolHandlers.d.ts +564 -16
  50. package/dist/tools/ToolHandlers.d.ts.map +1 -1
  51. package/dist/tools/ToolHandlers.js +664 -24
  52. package/dist/tools/ToolHandlers.js.map +1 -1
  53. package/dist/types/ToolTypes.d.ts +22 -0
  54. package/dist/types/ToolTypes.d.ts.map +1 -1
  55. package/dist/utils/Logger.d.ts +67 -0
  56. package/dist/utils/Logger.d.ts.map +1 -0
  57. package/dist/utils/Logger.js +119 -0
  58. package/dist/utils/Logger.js.map +1 -0
  59. package/dist/utils/constants.d.ts +75 -0
  60. package/dist/utils/constants.d.ts.map +1 -0
  61. package/dist/utils/constants.js +105 -0
  62. package/dist/utils/constants.js.map +1 -0
  63. package/package.json +1 -1
@@ -1,23 +1,88 @@
1
1
  /**
2
- * MCP Tool Handlers - Implementation of all 13 tools (including migration)
2
+ * MCP Tool Handlers - Implementation of all 13 tools for the conversation-memory MCP server.
3
+ *
4
+ * This class provides the implementation for all MCP (Model Context Protocol) tools
5
+ * that allow Claude to interact with conversation history and memory.
6
+ *
7
+ * Tools are organized into categories:
8
+ * - Indexing: index_conversations
9
+ * - Search: search_conversations, searchDecisions, search_mistakes
10
+ * - File Context: check_before_modify, get_file_evolution
11
+ * - History: get_tool_history, link_commits_to_conversations
12
+ * - Discovery: find_similar_sessions, get_requirements
13
+ * - Recall: recall_and_apply
14
+ * - Documentation: generate_documentation
15
+ * - Migration: discover_old_conversations, migrate_project
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * const handlers = new ToolHandlers(memory, db, '/path/to/projects');
20
+ * const result = await handlers.indexConversations({
21
+ * project_path: '/Users/me/my-project'
22
+ * });
23
+ * ```
3
24
  */
4
25
  import { sanitizeForLike } from "../utils/sanitization.js";
5
26
  import { DocumentationGenerator } from "../documentation/DocumentationGenerator.js";
6
27
  import { ProjectMigration } from "../utils/ProjectMigration.js";
7
28
  import { pathToProjectFolderName } from "../utils/sanitization.js";
29
+ import { DeletionService } from "../storage/DeletionService.js";
8
30
  import { readdirSync } from "fs";
9
31
  import { join } from "path";
32
+ /**
33
+ * Tool handlers for the conversation-memory MCP server.
34
+ *
35
+ * Provides methods for indexing, searching, and managing conversation history.
36
+ */
10
37
  export class ToolHandlers {
11
38
  memory;
12
39
  db;
13
40
  migration;
41
+ /**
42
+ * Create a new ToolHandlers instance.
43
+ *
44
+ * @param memory - ConversationMemory instance for core operations
45
+ * @param db - SQLiteManager for database access
46
+ * @param projectsDir - Optional directory for storing project data
47
+ */
14
48
  constructor(memory, db, projectsDir) {
15
49
  this.memory = memory;
16
50
  this.db = db;
17
51
  this.migration = new ProjectMigration(db, projectsDir);
18
52
  }
19
53
  /**
20
- * Tool 1: index_conversations
54
+ * Index conversation history for a project.
55
+ *
56
+ * Parses conversation files from Claude Code's conversation history, extracts
57
+ * decisions, mistakes, and requirements, links git commits, and generates
58
+ * semantic embeddings for search.
59
+ *
60
+ * @param args - Indexing arguments:
61
+ * - `project_path`: Path to the project (defaults to cwd)
62
+ * - `session_id`: Optional specific session to index
63
+ * - `include_thinking`: Include thinking blocks (default: false)
64
+ * - `enable_git`: Enable git integration (default: true)
65
+ * - `exclude_mcp_conversations`: Exclude MCP tool conversations (default: 'self-only')
66
+ * - `exclude_mcp_servers`: List of specific MCP servers to exclude
67
+ *
68
+ * @returns Result containing:
69
+ * - `success`: Whether indexing succeeded
70
+ * - `stats`: Counts of conversations, messages, decisions, etc.
71
+ * - `indexed_folders`: List of folders that were indexed
72
+ * - `database_path`: Path to the SQLite database
73
+ * - `embeddings_generated`: Whether embeddings were created
74
+ * - `embedding_error`: Error message if embeddings failed
75
+ * - `message`: Human-readable status message
76
+ *
77
+ * @example
78
+ * ```typescript
79
+ * const result = await handlers.indexConversations({
80
+ * project_path: '/Users/me/my-project',
81
+ * enable_git: true,
82
+ * exclude_mcp_conversations: 'self-only'
83
+ * });
84
+ * console.log(result.message); // "Indexed 5 conversation(s) with 245 messages..."
85
+ * ```
21
86
  */
22
87
  async indexConversations(args) {
23
88
  const typedArgs = args;
@@ -66,7 +131,39 @@ export class ToolHandlers {
66
131
  };
67
132
  }
68
133
  /**
69
- * Tool 2: search_conversations
134
+ * Search conversation history using natural language queries.
135
+ *
136
+ * Uses semantic search with embeddings if available, otherwise falls back
137
+ * to full-text search. Returns relevant messages with context and similarity scores.
138
+ *
139
+ * @param args - Search arguments:
140
+ * - `query`: Natural language search query (required)
141
+ * - `limit`: Maximum number of results (default: 10)
142
+ * - `date_range`: Optional [start_timestamp, end_timestamp] filter
143
+ *
144
+ * @returns Search results containing:
145
+ * - `query`: The search query used
146
+ * - `results`: Array of matching messages with:
147
+ * - `conversation_id`: Conversation containing the message
148
+ * - `message_id`: Message identifier
149
+ * - `timestamp`: When the message was created
150
+ * - `similarity`: Relevance score (0-1)
151
+ * - `snippet`: Text excerpt from the message
152
+ * - `git_branch`: Git branch at the time
153
+ * - `message_type`: Type of message
154
+ * - `role`: Message role (user/assistant)
155
+ * - `total_found`: Number of results returned
156
+ *
157
+ * @example
158
+ * ```typescript
159
+ * const result = await handlers.searchConversations({
160
+ * query: 'authentication bug fix',
161
+ * limit: 5
162
+ * });
163
+ * result.results.forEach(r => {
164
+ * console.log(`${r.similarity.toFixed(2)}: ${r.snippet}`);
165
+ * });
166
+ * ```
70
167
  */
71
168
  async searchConversations(args) {
72
169
  const typedArgs = args;
@@ -92,7 +189,45 @@ export class ToolHandlers {
92
189
  };
93
190
  }
94
191
  /**
95
- * Tool 3: get_decisions
192
+ * Find decisions made about a specific topic, file, or component.
193
+ *
194
+ * Searches through extracted decisions to find relevant architectural choices,
195
+ * technical decisions, and their rationale. Shows alternatives considered and
196
+ * rejected approaches.
197
+ *
198
+ * @param args - Decision search arguments:
199
+ * - `query`: Topic or keyword to search for (required)
200
+ * - `file_path`: Optional filter for decisions related to a specific file
201
+ * - `limit`: Maximum number of results (default: 10)
202
+ *
203
+ * @returns Decision search results containing:
204
+ * - `query`: The search query used
205
+ * - `file_path`: File filter if applied
206
+ * - `decisions`: Array of matching decisions with:
207
+ * - `decision_id`: Decision identifier
208
+ * - `decision_text`: The decision that was made
209
+ * - `rationale`: Why this decision was made
210
+ * - `alternatives_considered`: Other options that were considered
211
+ * - `rejected_reasons`: Why alternatives were rejected
212
+ * - `context`: Context in which the decision was made
213
+ * - `related_files`: Files affected by this decision
214
+ * - `related_commits`: Git commits implementing this decision
215
+ * - `timestamp`: When the decision was made
216
+ * - `similarity`: Relevance score
217
+ * - `total_found`: Number of decisions returned
218
+ *
219
+ * @example
220
+ * ```typescript
221
+ * const result = await handlers.getDecisions({
222
+ * query: 'database',
223
+ * file_path: 'src/storage/SQLiteManager.ts',
224
+ * limit: 5
225
+ * });
226
+ * result.decisions.forEach(d => {
227
+ * console.log(`Decision: ${d.decision_text}`);
228
+ * console.log(`Rationale: ${d.rationale}`);
229
+ * });
230
+ * ```
96
231
  */
97
232
  async getDecisions(args) {
98
233
  const typedArgs = args;
@@ -122,7 +257,33 @@ export class ToolHandlers {
122
257
  };
123
258
  }
124
259
  /**
125
- * Tool 4: check_before_modify
260
+ * Check important context before modifying a file.
261
+ *
262
+ * Shows recent changes, related decisions, commits, and past mistakes to avoid
263
+ * when working on a file. Use this before making significant changes to understand
264
+ * the file's history and context.
265
+ *
266
+ * @param args - Check arguments:
267
+ * - `file_path`: Path to the file you want to modify (required)
268
+ *
269
+ * @returns Context information containing:
270
+ * - `file_path`: The file being checked
271
+ * - `warning`: Warning message if important context found
272
+ * - `recent_changes`: Recent edits and commits to this file
273
+ * - `edits`: Recent file edits with timestamps and conversation IDs
274
+ * - `commits`: Recent git commits affecting this file
275
+ * - `related_decisions`: Decisions that affect this file
276
+ * - `mistakes_to_avoid`: Past mistakes related to this file
277
+ *
278
+ * @example
279
+ * ```typescript
280
+ * const context = await handlers.checkBeforeModify({
281
+ * file_path: 'src/storage/SQLiteManager.ts'
282
+ * });
283
+ * console.log(context.warning);
284
+ * console.log(`${context.related_decisions.length} decisions affect this file`);
285
+ * console.log(`${context.mistakes_to_avoid.length} mistakes to avoid`);
286
+ * ```
126
287
  */
127
288
  async checkBeforeModify(args) {
128
289
  const typedArgs = args;
@@ -162,7 +323,36 @@ export class ToolHandlers {
162
323
  };
163
324
  }
164
325
  /**
165
- * Tool 5: get_file_evolution
326
+ * Show complete timeline of changes to a file.
327
+ *
328
+ * Returns a chronological timeline of all edits, commits, and related decisions
329
+ * for a specific file across all conversations and git history.
330
+ *
331
+ * @param args - Evolution arguments:
332
+ * - `file_path`: Path to the file (required)
333
+ * - `include_decisions`: Include related decisions (default: true)
334
+ * - `include_commits`: Include git commits (default: true)
335
+ *
336
+ * @returns File evolution timeline containing:
337
+ * - `file_path`: The file being analyzed
338
+ * - `total_edits`: Total number of edits to this file
339
+ * - `timeline`: Chronological array of events (most recent first):
340
+ * - `type`: Event type ('edit', 'commit', or 'decision')
341
+ * - `timestamp`: When the event occurred
342
+ * - `data`: Event-specific data (conversation_id, commit hash, decision text, etc.)
343
+ *
344
+ * @example
345
+ * ```typescript
346
+ * const evolution = await handlers.getFileEvolution({
347
+ * file_path: 'src/index.ts',
348
+ * include_decisions: true,
349
+ * include_commits: true
350
+ * });
351
+ * console.log(`${evolution.total_edits} edits across ${evolution.timeline.length} events`);
352
+ * evolution.timeline.forEach(event => {
353
+ * console.log(`${event.timestamp}: ${event.type}`);
354
+ * });
355
+ * ```
166
356
  */
167
357
  async getFileEvolution(args) {
168
358
  const typedArgs = args;
@@ -213,7 +403,42 @@ export class ToolHandlers {
213
403
  };
214
404
  }
215
405
  /**
216
- * Tool 6: link_commits_to_conversations
406
+ * Link git commits to the conversations where they were made or discussed.
407
+ *
408
+ * Finds git commits that are associated with specific conversations, showing
409
+ * which code changes were made during which conversations. Helps answer "WHY
410
+ * was this code changed?"
411
+ *
412
+ * @param args - Link arguments:
413
+ * - `query`: Optional search query for commit messages
414
+ * - `conversation_id`: Optional filter for specific conversation
415
+ * - `limit`: Maximum number of commits (default: 20)
416
+ *
417
+ * @returns Commit links containing:
418
+ * - `query`: Search query if provided
419
+ * - `conversation_id`: Conversation filter if provided
420
+ * - `commits`: Array of linked commits with:
421
+ * - `hash`: Short commit hash (7 chars)
422
+ * - `full_hash`: Full commit hash
423
+ * - `message`: Commit message
424
+ * - `author`: Commit author
425
+ * - `timestamp`: When commit was made
426
+ * - `branch`: Git branch
427
+ * - `files_changed`: List of files changed
428
+ * - `conversation_id`: Conversation where this was discussed/made
429
+ * - `total_found`: Number of commits returned
430
+ *
431
+ * @example
432
+ * ```typescript
433
+ * const links = await handlers.linkCommitsToConversations({
434
+ * query: 'fix authentication',
435
+ * limit: 10
436
+ * });
437
+ * links.commits.forEach(c => {
438
+ * console.log(`${c.hash}: ${c.message}`);
439
+ * console.log(` Conversation: ${c.conversation_id}`);
440
+ * });
441
+ * ```
217
442
  */
218
443
  async linkCommitsToConversations(args) {
219
444
  const typedArgs = args;
@@ -248,7 +473,41 @@ export class ToolHandlers {
248
473
  };
249
474
  }
250
475
  /**
251
- * Tool 7: search_mistakes
476
+ * Find past mistakes to avoid repeating them.
477
+ *
478
+ * Searches through extracted mistakes to find documented errors, bugs, and
479
+ * wrong approaches. Shows what went wrong and how it was corrected.
480
+ *
481
+ * @param args - Mistake search arguments:
482
+ * - `query`: Search query for mistakes (required)
483
+ * - `mistake_type`: Optional filter by type (logic_error, wrong_approach, misunderstanding, tool_error, syntax_error)
484
+ * - `limit`: Maximum number of results (default: 10)
485
+ *
486
+ * @returns Mistake search results containing:
487
+ * - `query`: Search query used
488
+ * - `mistake_type`: Type filter if applied
489
+ * - `mistakes`: Array of matching mistakes with:
490
+ * - `mistake_id`: Mistake identifier
491
+ * - `mistake_type`: Type of mistake
492
+ * - `what_went_wrong`: Description of the mistake
493
+ * - `correction`: How it was fixed
494
+ * - `user_correction_message`: User's correction message if available
495
+ * - `files_affected`: List of files involved
496
+ * - `timestamp`: When the mistake occurred
497
+ * - `total_found`: Number of mistakes returned
498
+ *
499
+ * @example
500
+ * ```typescript
501
+ * const mistakes = await handlers.searchMistakes({
502
+ * query: 'database transaction',
503
+ * mistake_type: 'logic_error',
504
+ * limit: 5
505
+ * });
506
+ * mistakes.mistakes.forEach(m => {
507
+ * console.log(`${m.mistake_type}: ${m.what_went_wrong}`);
508
+ * console.log(`Fix: ${m.correction}`);
509
+ * });
510
+ * ```
252
511
  */
253
512
  async searchMistakes(args) {
254
513
  const typedArgs = args;
@@ -279,7 +538,38 @@ export class ToolHandlers {
279
538
  };
280
539
  }
281
540
  /**
282
- * Tool 8: get_requirements
541
+ * Look up requirements and constraints for a component or feature.
542
+ *
543
+ * Finds documented requirements, dependencies, performance constraints, and
544
+ * compatibility requirements that affect a component or feature.
545
+ *
546
+ * @param args - Requirements search arguments:
547
+ * - `component`: Component or feature name (required)
548
+ * - `type`: Optional filter by requirement type (dependency, performance, compatibility, business)
549
+ *
550
+ * @returns Requirements results containing:
551
+ * - `component`: Component searched
552
+ * - `type`: Type filter if applied
553
+ * - `requirements`: Array of matching requirements with:
554
+ * - `requirement_id`: Requirement identifier
555
+ * - `type`: Requirement type
556
+ * - `description`: Requirement description
557
+ * - `rationale`: Why this requirement exists
558
+ * - `affects_components`: List of affected components
559
+ * - `timestamp`: When requirement was documented
560
+ * - `total_found`: Number of requirements returned
561
+ *
562
+ * @example
563
+ * ```typescript
564
+ * const reqs = await handlers.getRequirements({
565
+ * component: 'authentication',
566
+ * type: 'security'
567
+ * });
568
+ * reqs.requirements.forEach(r => {
569
+ * console.log(`${r.type}: ${r.description}`);
570
+ * console.log(`Rationale: ${r.rationale}`);
571
+ * });
572
+ * ```
283
573
  */
284
574
  async getRequirements(args) {
285
575
  const typedArgs = args;
@@ -308,7 +598,43 @@ export class ToolHandlers {
308
598
  };
309
599
  }
310
600
  /**
311
- * Tool 9: get_tool_history
601
+ * Query history of tool uses (bash commands, file edits, reads, etc.).
602
+ *
603
+ * Shows what tools were used during conversations and their results. Useful
604
+ * for understanding what commands were run, what files were edited, and
605
+ * whether operations succeeded or failed.
606
+ *
607
+ * @param args - Tool history arguments:
608
+ * - `tool_name`: Optional filter by tool name (Bash, Edit, Write, Read)
609
+ * - `file_path`: Optional filter by file path
610
+ * - `limit`: Maximum number of results (default: 20)
611
+ *
612
+ * @returns Tool history containing:
613
+ * - `tool_name`: Tool filter if applied
614
+ * - `file_path`: File filter if applied
615
+ * - `tool_uses`: Array of tool uses with:
616
+ * - `tool_use_id`: Tool use identifier
617
+ * - `tool_name`: Name of the tool used
618
+ * - `tool_input`: Input parameters to the tool
619
+ * - `result`: Tool execution result with:
620
+ * - `content`: Result content
621
+ * - `is_error`: Whether the tool failed
622
+ * - `stdout`: Standard output (for Bash)
623
+ * - `stderr`: Standard error (for Bash)
624
+ * - `timestamp`: When the tool was used
625
+ * - `total_found`: Number of tool uses returned
626
+ *
627
+ * @example
628
+ * ```typescript
629
+ * const history = await handlers.getToolHistory({
630
+ * tool_name: 'Bash',
631
+ * limit: 10
632
+ * });
633
+ * history.tool_uses.forEach(t => {
634
+ * console.log(`${t.tool_name}: ${JSON.stringify(t.tool_input)}`);
635
+ * console.log(`Success: ${!t.result.is_error}`);
636
+ * });
637
+ * ```
312
638
  */
313
639
  async getToolHistory(args) {
314
640
  const typedArgs = args;
@@ -351,7 +677,39 @@ export class ToolHandlers {
351
677
  };
352
678
  }
353
679
  /**
354
- * Tool 10: find_similar_sessions
680
+ * Find conversations that dealt with similar topics or problems.
681
+ *
682
+ * Searches across all conversations to find ones that discussed similar topics,
683
+ * allowing you to learn from past work on similar problems.
684
+ *
685
+ * @param args - Similarity search arguments:
686
+ * - `query`: Description of the topic or problem (required)
687
+ * - `limit`: Maximum number of sessions (default: 5)
688
+ *
689
+ * @returns Similar sessions containing:
690
+ * - `query`: Search query used
691
+ * - `sessions`: Array of similar conversation sessions with:
692
+ * - `conversation_id`: Session identifier
693
+ * - `project_path`: Project path for this session
694
+ * - `first_message_at`: When the conversation started
695
+ * - `message_count`: Number of messages in the conversation
696
+ * - `git_branch`: Git branch at the time
697
+ * - `relevance_score`: Similarity score to the query
698
+ * - `relevant_messages`: Sample of relevant messages from this session
699
+ * - `total_found`: Number of sessions returned
700
+ *
701
+ * @example
702
+ * ```typescript
703
+ * const similar = await handlers.findSimilarSessions({
704
+ * query: 'implementing user authentication with JWT',
705
+ * limit: 3
706
+ * });
707
+ * similar.sessions.forEach(s => {
708
+ * console.log(`Session ${s.conversation_id} (${s.message_count} messages)`);
709
+ * console.log(`Relevance: ${s.relevance_score.toFixed(2)}`);
710
+ * console.log(`Messages: ${s.relevant_messages.length} relevant`);
711
+ * });
712
+ * ```
355
713
  */
356
714
  async findSimilarSessions(args) {
357
715
  const typedArgs = args;
@@ -391,8 +749,43 @@ export class ToolHandlers {
391
749
  };
392
750
  }
393
751
  /**
394
- * Tool 11: recall_and_apply
395
- * Recall relevant context and format for application to current work
752
+ * Recall relevant context and format for application to current work.
753
+ *
754
+ * This is a comprehensive context retrieval tool that searches across multiple
755
+ * data sources (conversations, decisions, mistakes, file changes, commits) and
756
+ * returns actionable suggestions for applying historical context to current work.
757
+ *
758
+ * @param args - Recall arguments:
759
+ * - `query`: What you're working on or need context for (required)
760
+ * - `context_types`: Types to recall (default: all types)
761
+ * - Options: "conversations", "decisions", "mistakes", "file_changes", "commits"
762
+ * - `file_path`: Optional filter for file-specific context
763
+ * - `date_range`: Optional [start_timestamp, end_timestamp] filter
764
+ * - `limit`: Maximum items per context type (default: 5)
765
+ *
766
+ * @returns Recalled context containing:
767
+ * - `query`: Search query used
768
+ * - `context_summary`: High-level summary of what was found
769
+ * - `recalled_context`: Structured context data:
770
+ * - `conversations`: Relevant past conversations
771
+ * - `decisions`: Related decisions with rationale
772
+ * - `mistakes`: Past mistakes to avoid
773
+ * - `file_changes`: File modification history
774
+ * - `commits`: Related git commits
775
+ * - `application_suggestions`: Actionable suggestions for applying this context
776
+ * - `total_items_found`: Total number of context items found
777
+ *
778
+ * @example
779
+ * ```typescript
780
+ * const context = await handlers.recallAndApply({
781
+ * query: 'refactoring database connection pooling',
782
+ * context_types: ['decisions', 'mistakes', 'commits'],
783
+ * file_path: 'src/database/pool.ts',
784
+ * limit: 5
785
+ * });
786
+ * console.log(context.context_summary);
787
+ * context.application_suggestions.forEach(s => console.log(`- ${s}`));
788
+ * ```
396
789
  */
397
790
  async recallAndApply(args) {
398
791
  const typedArgs = args;
@@ -422,22 +815,22 @@ export class ToolHandlers {
422
815
  if (context_types.includes("decisions")) {
423
816
  const decisions = this.db.getDatabase()
424
817
  .prepare(`
425
- SELECT decision_id, type, description, rationale, alternatives, rejected_approaches, affects_components, timestamp
818
+ SELECT id, decision_text, rationale, alternatives_considered, rejected_reasons, context, related_files, timestamp
426
819
  FROM decisions
427
- WHERE description LIKE ? ${file_path ? 'AND affects_components LIKE ?' : ''}
820
+ WHERE decision_text LIKE ? ${file_path ? 'AND related_files LIKE ?' : ''}
428
821
  ${date_range ? 'AND timestamp BETWEEN ? AND ?' : ''}
429
822
  ORDER BY timestamp DESC
430
823
  LIMIT ?
431
824
  `)
432
825
  .all(`%${sanitizeForLike(query)}%`, ...(file_path ? [`%${sanitizeForLike(file_path)}%`] : []), ...(date_range ? [date_range[0], date_range[1]] : []), limit);
433
826
  recalled.decisions = decisions.map(d => ({
434
- decision_id: d.decision_id,
435
- type: d.type,
436
- description: d.description,
827
+ decision_id: d.id,
828
+ type: d.context,
829
+ description: d.decision_text,
437
830
  rationale: d.rationale || undefined,
438
- alternatives: d.alternatives ? JSON.parse(d.alternatives) : undefined,
439
- rejected_approaches: d.rejected_approaches ? JSON.parse(d.rejected_approaches) : undefined,
440
- affects_components: JSON.parse(d.affects_components),
831
+ alternatives: d.alternatives_considered ? JSON.parse(d.alternatives_considered) : undefined,
832
+ rejected_approaches: d.rejected_reasons ? JSON.parse(d.rejected_reasons) : undefined,
833
+ affects_components: JSON.parse(d.related_files),
441
834
  timestamp: new Date(d.timestamp).toISOString(),
442
835
  }));
443
836
  totalItems += recalled.decisions.length;
@@ -559,7 +952,44 @@ export class ToolHandlers {
559
952
  };
560
953
  }
561
954
  /**
562
- * Tool 12: generate_documentation
955
+ * Generate comprehensive project documentation by combining codebase analysis
956
+ * with conversation history.
957
+ *
958
+ * Creates documentation that shows WHAT exists in the code (via CODE-GRAPH-RAG-MCP)
959
+ * and WHY it was built that way (via conversation history). Requires CODE-GRAPH-RAG-MCP
960
+ * to be indexed first.
961
+ *
962
+ * @param args - Documentation generation arguments:
963
+ * - `project_path`: Path to the project (defaults to cwd)
964
+ * - `session_id`: Optional specific session to include
965
+ * - `scope`: Documentation scope (default: 'full')
966
+ * - 'full': Everything (architecture, decisions, quality)
967
+ * - 'architecture': Module structure and dependencies
968
+ * - 'decisions': Decision log with rationale
969
+ * - 'quality': Code quality insights
970
+ * - `module_filter`: Optional filter for specific module path (e.g., 'src/auth')
971
+ *
972
+ * @returns Documentation result containing:
973
+ * - `success`: Whether generation succeeded
974
+ * - `project_path`: Project that was documented
975
+ * - `scope`: Scope of documentation generated
976
+ * - `documentation`: Generated markdown documentation
977
+ * - `statistics`: Summary statistics:
978
+ * - `modules`: Number of modules documented
979
+ * - `decisions`: Number of decisions included
980
+ * - `mistakes`: Number of mistakes documented
981
+ * - `commits`: Number of commits referenced
982
+ *
983
+ * @example
984
+ * ```typescript
985
+ * const doc = await handlers.generateDocumentation({
986
+ * project_path: '/Users/me/my-project',
987
+ * scope: 'full',
988
+ * module_filter: 'src/auth'
989
+ * });
990
+ * console.log(doc.documentation); // Markdown documentation
991
+ * console.log(`Documented ${doc.statistics.modules} modules`);
992
+ * ```
563
993
  */
564
994
  async generateDocumentation(args) {
565
995
  const typedArgs = args;
@@ -612,7 +1042,43 @@ export class ToolHandlers {
612
1042
  };
613
1043
  }
614
1044
  /**
615
- * Tool 12: discover_old_conversations
1045
+ * Discover old conversation folders that might contain conversation history
1046
+ * for the current project.
1047
+ *
1048
+ * Searches through stored conversation folders to find potential matches for
1049
+ * the current project path. Useful when project paths have changed (e.g., after
1050
+ * moving or renaming a project directory).
1051
+ *
1052
+ * @param args - Discovery arguments:
1053
+ * - `current_project_path`: Current project path (defaults to cwd)
1054
+ *
1055
+ * @returns Discovery results containing:
1056
+ * - `success`: Whether discovery succeeded
1057
+ * - `current_project_path`: Current project path searched for
1058
+ * - `candidates`: Array of potential matches sorted by score:
1059
+ * - `folder_name`: Name of the conversation folder
1060
+ * - `folder_path`: Full path to the folder
1061
+ * - `stored_project_path`: Original project path stored in conversations
1062
+ * - `score`: Match score (higher is better match)
1063
+ * - `stats`: Folder statistics:
1064
+ * - `conversations`: Number of conversations in folder
1065
+ * - `messages`: Number of messages in folder
1066
+ * - `files`: Number of .jsonl files
1067
+ * - `last_activity`: Timestamp of last activity
1068
+ * - `message`: Human-readable status message
1069
+ *
1070
+ * @example
1071
+ * ```typescript
1072
+ * const discovery = await handlers.discoverOldConversations({
1073
+ * current_project_path: '/Users/me/projects/my-app'
1074
+ * });
1075
+ * console.log(discovery.message);
1076
+ * discovery.candidates.forEach(c => {
1077
+ * console.log(`Score ${c.score}: ${c.folder_name}`);
1078
+ * console.log(` Original path: ${c.stored_project_path}`);
1079
+ * console.log(` Stats: ${c.stats.conversations} conversations, ${c.stats.files} files`);
1080
+ * });
1081
+ * ```
616
1082
  */
617
1083
  async discoverOldConversations(args) {
618
1084
  const typedArgs = args;
@@ -652,7 +1118,51 @@ export class ToolHandlers {
652
1118
  };
653
1119
  }
654
1120
  /**
655
- * Tool 13: migrate_project
1121
+ * Migrate or merge conversation history from an old project path to a new one.
1122
+ *
1123
+ * Use this when a project has been moved or renamed to bring the conversation
1124
+ * history along. Supports two modes: 'migrate' (move all files) or 'merge'
1125
+ * (combine with existing files).
1126
+ *
1127
+ * @param args - Migration arguments:
1128
+ * - `source_folder`: Source folder containing old conversations (required)
1129
+ * - `old_project_path`: Original project path in the conversations (required)
1130
+ * - `new_project_path`: New project path to update to (required)
1131
+ * - `dry_run`: Preview changes without applying them (default: false)
1132
+ * - `mode`: Migration mode (default: 'migrate')
1133
+ * - 'migrate': Move all files from source to target
1134
+ * - 'merge': Combine source files with existing target files
1135
+ *
1136
+ * @returns Migration result containing:
1137
+ * - `success`: Whether migration succeeded
1138
+ * - `source_folder`: Source folder path
1139
+ * - `target_folder`: Target folder path (where files were copied)
1140
+ * - `files_copied`: Number of files copied/migrated
1141
+ * - `database_updated`: Whether database was updated with new paths
1142
+ * - `backup_created`: Whether backup was created (always true for non-dry-run)
1143
+ * - `message`: Human-readable status message
1144
+ *
1145
+ * @example
1146
+ * ```typescript
1147
+ * // First, preview with dry run
1148
+ * const preview = await handlers.migrateProject({
1149
+ * source_folder: '/path/to/old/conversations',
1150
+ * old_project_path: '/old/path/to/project',
1151
+ * new_project_path: '/new/path/to/project',
1152
+ * dry_run: true
1153
+ * });
1154
+ * console.log(preview.message); // "Dry run: Would migrate X files..."
1155
+ *
1156
+ * // Then, execute the migration
1157
+ * const result = await handlers.migrateProject({
1158
+ * source_folder: '/path/to/old/conversations',
1159
+ * old_project_path: '/old/path/to/project',
1160
+ * new_project_path: '/new/path/to/project',
1161
+ * dry_run: false,
1162
+ * mode: 'migrate'
1163
+ * });
1164
+ * console.log(`Migrated ${result.files_copied} files`);
1165
+ * ```
656
1166
  */
657
1167
  async migrateProject(args) {
658
1168
  const typedArgs = args;
@@ -689,5 +1199,135 @@ export class ToolHandlers {
689
1199
  message
690
1200
  };
691
1201
  }
1202
+ /**
1203
+ * Forget conversations by topic/keywords.
1204
+ *
1205
+ * Searches for conversations matching the provided keywords and optionally deletes them.
1206
+ * Creates automatic backup before deletion.
1207
+ *
1208
+ * @param args - Arguments:
1209
+ * - `keywords`: Array of keywords/topics to search for
1210
+ * - `project_path`: Path to the project (defaults to cwd)
1211
+ * - `confirm`: Must be true to actually delete (default: false for preview)
1212
+ *
1213
+ * @returns Result containing:
1214
+ * - `success`: Whether operation succeeded
1215
+ * - `preview_mode`: Whether this was a preview (confirm=false)
1216
+ * - `conversations_found`: Number of conversations matching keywords
1217
+ * - `conversations_deleted`: Number of conversations actually deleted
1218
+ * - `messages_deleted`: Number of messages deleted
1219
+ * - `decisions_deleted`: Number of decisions deleted
1220
+ * - `mistakes_deleted`: Number of mistakes deleted
1221
+ * - `backup_path`: Path to backup file (if deletion occurred)
1222
+ * - `conversation_summaries`: List of conversations with basic info
1223
+ * - `message`: Human-readable status message
1224
+ *
1225
+ * @example
1226
+ * ```typescript
1227
+ * // Preview what would be deleted
1228
+ * const preview = await handlers.forgetByTopic({
1229
+ * keywords: ['authentication', 'redesign'],
1230
+ * confirm: false
1231
+ * });
1232
+ *
1233
+ * // Actually delete after reviewing preview
1234
+ * const result = await handlers.forgetByTopic({
1235
+ * keywords: ['authentication', 'redesign'],
1236
+ * confirm: true
1237
+ * });
1238
+ * ```
1239
+ */
1240
+ async forgetByTopic(args) {
1241
+ const typedArgs = args;
1242
+ const keywords = typedArgs.keywords || [];
1243
+ const projectPath = typedArgs.project_path || process.cwd();
1244
+ const confirm = typedArgs.confirm || false;
1245
+ if (keywords.length === 0) {
1246
+ return {
1247
+ success: false,
1248
+ preview_mode: true,
1249
+ conversations_found: 0,
1250
+ conversations_deleted: 0,
1251
+ messages_deleted: 0,
1252
+ decisions_deleted: 0,
1253
+ mistakes_deleted: 0,
1254
+ backup_path: null,
1255
+ conversation_summaries: [],
1256
+ message: "No keywords provided. Please specify keywords/topics to search for."
1257
+ };
1258
+ }
1259
+ try {
1260
+ // Create deletion service
1261
+ const storage = this.memory.getStorage();
1262
+ const semanticSearch = this.memory.getSemanticSearch();
1263
+ const deletionService = new DeletionService(this.db.getDatabase(), storage, semanticSearch);
1264
+ // Preview what would be deleted
1265
+ const preview = await deletionService.previewDeletionByTopic(keywords, projectPath);
1266
+ if (preview.conversationIds.length === 0) {
1267
+ return {
1268
+ success: true,
1269
+ preview_mode: true,
1270
+ conversations_found: 0,
1271
+ conversations_deleted: 0,
1272
+ messages_deleted: 0,
1273
+ decisions_deleted: 0,
1274
+ mistakes_deleted: 0,
1275
+ backup_path: null,
1276
+ conversation_summaries: [],
1277
+ message: preview.summary
1278
+ };
1279
+ }
1280
+ // Format conversation summaries for response
1281
+ const conversationSummaries = preview.conversations.map(conv => ({
1282
+ id: conv.id,
1283
+ session_id: conv.session_id,
1284
+ created_at: new Date(conv.created_at).toISOString(),
1285
+ message_count: conv.message_count
1286
+ }));
1287
+ // If not confirmed, return preview
1288
+ if (!confirm) {
1289
+ return {
1290
+ success: true,
1291
+ preview_mode: true,
1292
+ conversations_found: preview.conversationIds.length,
1293
+ conversations_deleted: 0,
1294
+ messages_deleted: 0,
1295
+ decisions_deleted: 0,
1296
+ mistakes_deleted: 0,
1297
+ backup_path: null,
1298
+ conversation_summaries: conversationSummaries,
1299
+ message: `${preview.summary}\n\nSet confirm=true to delete these conversations.`
1300
+ };
1301
+ }
1302
+ // Actually delete with backup
1303
+ const result = await deletionService.forgetByTopic(keywords, projectPath);
1304
+ return {
1305
+ success: true,
1306
+ preview_mode: false,
1307
+ conversations_found: result.deleted.conversations,
1308
+ conversations_deleted: result.deleted.conversations,
1309
+ messages_deleted: result.deleted.messages,
1310
+ decisions_deleted: result.deleted.decisions,
1311
+ mistakes_deleted: result.deleted.mistakes,
1312
+ backup_path: result.backup.backupPath,
1313
+ conversation_summaries: conversationSummaries,
1314
+ message: result.summary
1315
+ };
1316
+ }
1317
+ catch (error) {
1318
+ return {
1319
+ success: false,
1320
+ preview_mode: !confirm,
1321
+ conversations_found: 0,
1322
+ conversations_deleted: 0,
1323
+ messages_deleted: 0,
1324
+ decisions_deleted: 0,
1325
+ mistakes_deleted: 0,
1326
+ backup_path: null,
1327
+ conversation_summaries: [],
1328
+ message: `Error: ${error.message}`
1329
+ };
1330
+ }
1331
+ }
692
1332
  }
693
1333
  //# sourceMappingURL=ToolHandlers.js.map