cccmemory 1.8.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 (216) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +349 -0
  3. package/dist/ConversationMemory.d.ts +231 -0
  4. package/dist/ConversationMemory.d.ts.map +1 -0
  5. package/dist/ConversationMemory.js +357 -0
  6. package/dist/ConversationMemory.js.map +1 -0
  7. package/dist/cache/QueryCache.d.ts +215 -0
  8. package/dist/cache/QueryCache.d.ts.map +1 -0
  9. package/dist/cache/QueryCache.js +294 -0
  10. package/dist/cache/QueryCache.js.map +1 -0
  11. package/dist/cli/commands.d.ts +9 -0
  12. package/dist/cli/commands.d.ts.map +1 -0
  13. package/dist/cli/commands.js +954 -0
  14. package/dist/cli/commands.js.map +1 -0
  15. package/dist/cli/help.d.ts +16 -0
  16. package/dist/cli/help.d.ts.map +1 -0
  17. package/dist/cli/help.js +361 -0
  18. package/dist/cli/help.js.map +1 -0
  19. package/dist/cli/index.d.ts +30 -0
  20. package/dist/cli/index.d.ts.map +1 -0
  21. package/dist/cli/index.js +111 -0
  22. package/dist/cli/index.js.map +1 -0
  23. package/dist/context/ContextInjector.d.ts +38 -0
  24. package/dist/context/ContextInjector.d.ts.map +1 -0
  25. package/dist/context/ContextInjector.js +235 -0
  26. package/dist/context/ContextInjector.js.map +1 -0
  27. package/dist/documentation/CodeAnalyzer.d.ts +29 -0
  28. package/dist/documentation/CodeAnalyzer.d.ts.map +1 -0
  29. package/dist/documentation/CodeAnalyzer.js +122 -0
  30. package/dist/documentation/CodeAnalyzer.js.map +1 -0
  31. package/dist/documentation/ConversationAnalyzer.d.ts +19 -0
  32. package/dist/documentation/ConversationAnalyzer.d.ts.map +1 -0
  33. package/dist/documentation/ConversationAnalyzer.js +157 -0
  34. package/dist/documentation/ConversationAnalyzer.js.map +1 -0
  35. package/dist/documentation/CrossReferencer.d.ts +67 -0
  36. package/dist/documentation/CrossReferencer.d.ts.map +1 -0
  37. package/dist/documentation/CrossReferencer.js +247 -0
  38. package/dist/documentation/CrossReferencer.js.map +1 -0
  39. package/dist/documentation/DocumentationGenerator.d.ts +22 -0
  40. package/dist/documentation/DocumentationGenerator.d.ts.map +1 -0
  41. package/dist/documentation/DocumentationGenerator.js +57 -0
  42. package/dist/documentation/DocumentationGenerator.js.map +1 -0
  43. package/dist/documentation/MarkdownFormatter.d.ts +26 -0
  44. package/dist/documentation/MarkdownFormatter.d.ts.map +1 -0
  45. package/dist/documentation/MarkdownFormatter.js +301 -0
  46. package/dist/documentation/MarkdownFormatter.js.map +1 -0
  47. package/dist/documentation/types.d.ts +176 -0
  48. package/dist/documentation/types.d.ts.map +1 -0
  49. package/dist/documentation/types.js +5 -0
  50. package/dist/documentation/types.js.map +1 -0
  51. package/dist/embeddings/ConfigManager.d.ts +46 -0
  52. package/dist/embeddings/ConfigManager.d.ts.map +1 -0
  53. package/dist/embeddings/ConfigManager.js +177 -0
  54. package/dist/embeddings/ConfigManager.js.map +1 -0
  55. package/dist/embeddings/EmbeddingConfig.d.ts +39 -0
  56. package/dist/embeddings/EmbeddingConfig.d.ts.map +1 -0
  57. package/dist/embeddings/EmbeddingConfig.js +132 -0
  58. package/dist/embeddings/EmbeddingConfig.js.map +1 -0
  59. package/dist/embeddings/EmbeddingGenerator.d.ts +51 -0
  60. package/dist/embeddings/EmbeddingGenerator.d.ts.map +1 -0
  61. package/dist/embeddings/EmbeddingGenerator.js +157 -0
  62. package/dist/embeddings/EmbeddingGenerator.js.map +1 -0
  63. package/dist/embeddings/EmbeddingProvider.d.ts +34 -0
  64. package/dist/embeddings/EmbeddingProvider.d.ts.map +1 -0
  65. package/dist/embeddings/EmbeddingProvider.js +6 -0
  66. package/dist/embeddings/EmbeddingProvider.js.map +1 -0
  67. package/dist/embeddings/ModelRegistry.d.ts +48 -0
  68. package/dist/embeddings/ModelRegistry.d.ts.map +1 -0
  69. package/dist/embeddings/ModelRegistry.js +170 -0
  70. package/dist/embeddings/ModelRegistry.js.map +1 -0
  71. package/dist/embeddings/VectorStore.d.ts +114 -0
  72. package/dist/embeddings/VectorStore.d.ts.map +1 -0
  73. package/dist/embeddings/VectorStore.js +393 -0
  74. package/dist/embeddings/VectorStore.js.map +1 -0
  75. package/dist/embeddings/providers/OllamaEmbeddings.d.ts +38 -0
  76. package/dist/embeddings/providers/OllamaEmbeddings.d.ts.map +1 -0
  77. package/dist/embeddings/providers/OllamaEmbeddings.js +125 -0
  78. package/dist/embeddings/providers/OllamaEmbeddings.js.map +1 -0
  79. package/dist/embeddings/providers/OpenAIEmbeddings.d.ts +40 -0
  80. package/dist/embeddings/providers/OpenAIEmbeddings.d.ts.map +1 -0
  81. package/dist/embeddings/providers/OpenAIEmbeddings.js +129 -0
  82. package/dist/embeddings/providers/OpenAIEmbeddings.js.map +1 -0
  83. package/dist/embeddings/providers/TransformersEmbeddings.d.ts +38 -0
  84. package/dist/embeddings/providers/TransformersEmbeddings.d.ts.map +1 -0
  85. package/dist/embeddings/providers/TransformersEmbeddings.js +115 -0
  86. package/dist/embeddings/providers/TransformersEmbeddings.js.map +1 -0
  87. package/dist/handoff/SessionHandoffStore.d.ts +80 -0
  88. package/dist/handoff/SessionHandoffStore.d.ts.map +1 -0
  89. package/dist/handoff/SessionHandoffStore.js +314 -0
  90. package/dist/handoff/SessionHandoffStore.js.map +1 -0
  91. package/dist/index.d.ts +7 -0
  92. package/dist/index.d.ts.map +1 -0
  93. package/dist/index.js +115 -0
  94. package/dist/index.js.map +1 -0
  95. package/dist/mcp-server.d.ts +27 -0
  96. package/dist/mcp-server.d.ts.map +1 -0
  97. package/dist/mcp-server.js +157 -0
  98. package/dist/mcp-server.js.map +1 -0
  99. package/dist/memory/WorkingMemoryStore.d.ts +83 -0
  100. package/dist/memory/WorkingMemoryStore.d.ts.map +1 -0
  101. package/dist/memory/WorkingMemoryStore.js +318 -0
  102. package/dist/memory/WorkingMemoryStore.js.map +1 -0
  103. package/dist/memory/types.d.ts +192 -0
  104. package/dist/memory/types.d.ts.map +1 -0
  105. package/dist/memory/types.js +8 -0
  106. package/dist/memory/types.js.map +1 -0
  107. package/dist/parsers/CodexConversationParser.d.ts +51 -0
  108. package/dist/parsers/CodexConversationParser.d.ts.map +1 -0
  109. package/dist/parsers/CodexConversationParser.js +301 -0
  110. package/dist/parsers/CodexConversationParser.js.map +1 -0
  111. package/dist/parsers/ConversationParser.d.ts +286 -0
  112. package/dist/parsers/ConversationParser.d.ts.map +1 -0
  113. package/dist/parsers/ConversationParser.js +795 -0
  114. package/dist/parsers/ConversationParser.js.map +1 -0
  115. package/dist/parsers/DecisionExtractor.d.ts +144 -0
  116. package/dist/parsers/DecisionExtractor.d.ts.map +1 -0
  117. package/dist/parsers/DecisionExtractor.js +434 -0
  118. package/dist/parsers/DecisionExtractor.js.map +1 -0
  119. package/dist/parsers/GitIntegrator.d.ts +156 -0
  120. package/dist/parsers/GitIntegrator.d.ts.map +1 -0
  121. package/dist/parsers/GitIntegrator.js +348 -0
  122. package/dist/parsers/GitIntegrator.js.map +1 -0
  123. package/dist/parsers/MistakeExtractor.d.ts +151 -0
  124. package/dist/parsers/MistakeExtractor.d.ts.map +1 -0
  125. package/dist/parsers/MistakeExtractor.js +460 -0
  126. package/dist/parsers/MistakeExtractor.js.map +1 -0
  127. package/dist/parsers/RequirementsExtractor.d.ts +166 -0
  128. package/dist/parsers/RequirementsExtractor.d.ts.map +1 -0
  129. package/dist/parsers/RequirementsExtractor.js +338 -0
  130. package/dist/parsers/RequirementsExtractor.js.map +1 -0
  131. package/dist/realtime/ConversationWatcher.d.ts +87 -0
  132. package/dist/realtime/ConversationWatcher.d.ts.map +1 -0
  133. package/dist/realtime/ConversationWatcher.js +204 -0
  134. package/dist/realtime/ConversationWatcher.js.map +1 -0
  135. package/dist/realtime/IncrementalParser.d.ts +83 -0
  136. package/dist/realtime/IncrementalParser.d.ts.map +1 -0
  137. package/dist/realtime/IncrementalParser.js +232 -0
  138. package/dist/realtime/IncrementalParser.js.map +1 -0
  139. package/dist/realtime/LiveExtractor.d.ts +72 -0
  140. package/dist/realtime/LiveExtractor.d.ts.map +1 -0
  141. package/dist/realtime/LiveExtractor.js +288 -0
  142. package/dist/realtime/LiveExtractor.js.map +1 -0
  143. package/dist/search/SemanticSearch.d.ts +121 -0
  144. package/dist/search/SemanticSearch.d.ts.map +1 -0
  145. package/dist/search/SemanticSearch.js +823 -0
  146. package/dist/search/SemanticSearch.js.map +1 -0
  147. package/dist/storage/BackupManager.d.ts +58 -0
  148. package/dist/storage/BackupManager.d.ts.map +1 -0
  149. package/dist/storage/BackupManager.js +223 -0
  150. package/dist/storage/BackupManager.js.map +1 -0
  151. package/dist/storage/ConversationStorage.d.ts +341 -0
  152. package/dist/storage/ConversationStorage.d.ts.map +1 -0
  153. package/dist/storage/ConversationStorage.js +792 -0
  154. package/dist/storage/ConversationStorage.js.map +1 -0
  155. package/dist/storage/DeletionService.d.ts +70 -0
  156. package/dist/storage/DeletionService.d.ts.map +1 -0
  157. package/dist/storage/DeletionService.js +253 -0
  158. package/dist/storage/DeletionService.js.map +1 -0
  159. package/dist/storage/GlobalIndex.d.ts +133 -0
  160. package/dist/storage/GlobalIndex.d.ts.map +1 -0
  161. package/dist/storage/GlobalIndex.js +310 -0
  162. package/dist/storage/GlobalIndex.js.map +1 -0
  163. package/dist/storage/SQLiteManager.d.ts +114 -0
  164. package/dist/storage/SQLiteManager.d.ts.map +1 -0
  165. package/dist/storage/SQLiteManager.js +636 -0
  166. package/dist/storage/SQLiteManager.js.map +1 -0
  167. package/dist/storage/migrations.d.ts +54 -0
  168. package/dist/storage/migrations.d.ts.map +1 -0
  169. package/dist/storage/migrations.js +285 -0
  170. package/dist/storage/migrations.js.map +1 -0
  171. package/dist/storage/schema.sql +436 -0
  172. package/dist/tools/ToolDefinitions.d.ts +946 -0
  173. package/dist/tools/ToolDefinitions.d.ts.map +1 -0
  174. package/dist/tools/ToolDefinitions.js +937 -0
  175. package/dist/tools/ToolDefinitions.js.map +1 -0
  176. package/dist/tools/ToolHandlers.d.ts +791 -0
  177. package/dist/tools/ToolHandlers.d.ts.map +1 -0
  178. package/dist/tools/ToolHandlers.js +3262 -0
  179. package/dist/tools/ToolHandlers.js.map +1 -0
  180. package/dist/types/ToolTypes.d.ts +824 -0
  181. package/dist/types/ToolTypes.d.ts.map +1 -0
  182. package/dist/types/ToolTypes.js +6 -0
  183. package/dist/types/ToolTypes.js.map +1 -0
  184. package/dist/utils/Logger.d.ts +70 -0
  185. package/dist/utils/Logger.d.ts.map +1 -0
  186. package/dist/utils/Logger.js +131 -0
  187. package/dist/utils/Logger.js.map +1 -0
  188. package/dist/utils/McpConfig.d.ts +54 -0
  189. package/dist/utils/McpConfig.d.ts.map +1 -0
  190. package/dist/utils/McpConfig.js +136 -0
  191. package/dist/utils/McpConfig.js.map +1 -0
  192. package/dist/utils/ProjectMigration.d.ts +82 -0
  193. package/dist/utils/ProjectMigration.d.ts.map +1 -0
  194. package/dist/utils/ProjectMigration.js +416 -0
  195. package/dist/utils/ProjectMigration.js.map +1 -0
  196. package/dist/utils/constants.d.ts +75 -0
  197. package/dist/utils/constants.d.ts.map +1 -0
  198. package/dist/utils/constants.js +105 -0
  199. package/dist/utils/constants.js.map +1 -0
  200. package/dist/utils/safeJson.d.ts +37 -0
  201. package/dist/utils/safeJson.d.ts.map +1 -0
  202. package/dist/utils/safeJson.js +48 -0
  203. package/dist/utils/safeJson.js.map +1 -0
  204. package/dist/utils/sanitization.d.ts +45 -0
  205. package/dist/utils/sanitization.d.ts.map +1 -0
  206. package/dist/utils/sanitization.js +153 -0
  207. package/dist/utils/sanitization.js.map +1 -0
  208. package/dist/utils/worktree.d.ts +15 -0
  209. package/dist/utils/worktree.d.ts.map +1 -0
  210. package/dist/utils/worktree.js +86 -0
  211. package/dist/utils/worktree.js.map +1 -0
  212. package/package.json +98 -0
  213. package/scripts/changelog-check.sh +62 -0
  214. package/scripts/check-node.js +17 -0
  215. package/scripts/dev-config.js +56 -0
  216. package/scripts/postinstall.js +117 -0
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Git Integrator - Links git commits to conversations based on temporal and contextual analysis.
3
+ *
4
+ * This integrator connects git repository history with conversation history by:
5
+ * - Parsing git log to extract commits
6
+ * - Matching commits to conversations using multiple signals:
7
+ * - Temporal proximity (commit time vs conversation time)
8
+ * - File overlap (files changed in commit vs files edited in conversation)
9
+ * - Branch matching (git branch in commit vs conversation metadata)
10
+ * - Decision matching (commit message mentions decisions from conversation)
11
+ *
12
+ * Provides confidence scores (0-1) for each linkage based on:
13
+ * - Exact timestamp match (highest confidence)
14
+ * - File overlap percentage
15
+ * - Branch name match
16
+ * - Decision keyword presence
17
+ *
18
+ * Helps answer "WHY was this code changed?" by linking code changes to their
19
+ * discussion context.
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * const integrator = new GitIntegrator('/path/to/project');
24
+ * const linkedCommits = await integrator.linkCommitsToConversations(
25
+ * conversations,
26
+ * fileEdits,
27
+ * decisions
28
+ * );
29
+ * console.error(`Linked ${linkedCommits.filter(c => c.conversation_id).length} commits`);
30
+ * ```
31
+ */
32
+ import type { Conversation, FileEdit } from "./ConversationParser.js";
33
+ import type { Decision } from "./DecisionExtractor.js";
34
+ /**
35
+ * Represents a git commit with conversation linkage.
36
+ */
37
+ export interface GitCommit {
38
+ /** Short commit hash (7 chars) or full hash */
39
+ hash: string;
40
+ /** Commit message */
41
+ message: string;
42
+ /** Commit author */
43
+ author?: string;
44
+ /** Commit timestamp */
45
+ timestamp: number;
46
+ /** Git branch name */
47
+ branch?: string;
48
+ /** Files modified in this commit */
49
+ files_changed: string[];
50
+ /** Linked conversation ID (if matched) */
51
+ conversation_id?: string;
52
+ /** Related message ID within the conversation */
53
+ related_message_id?: string;
54
+ /** Additional commit metadata */
55
+ metadata: Record<string, unknown>;
56
+ }
57
+ /**
58
+ * Represents a commit-to-conversation linkage with confidence score.
59
+ * @internal
60
+ */
61
+ export interface CommitLinkage {
62
+ /** The git commit */
63
+ commit: GitCommit;
64
+ /** The matched conversation */
65
+ conversation: Conversation;
66
+ /** Confidence score (0-1) of the match */
67
+ confidence: number;
68
+ /** Reasons why this match was made */
69
+ reasons: string[];
70
+ }
71
+ /**
72
+ * Integrates git repository history with conversation history.
73
+ *
74
+ * Links commits to conversations using temporal and contextual analysis.
75
+ */
76
+ export declare class GitIntegrator {
77
+ private git;
78
+ /**
79
+ * Create a new GitIntegrator.
80
+ *
81
+ * @param projectPath - Path to the git repository
82
+ * @throws {Error} If the directory is not a git repository
83
+ */
84
+ constructor(projectPath: string);
85
+ /**
86
+ * Parse git history and link commits to conversations.
87
+ *
88
+ * Analyzes git log and matches commits to conversations using multiple signals:
89
+ * - Temporal proximity (commits made during conversation timeframe)
90
+ * - File overlap (files changed in commit match files edited in conversation)
91
+ * - Branch matching (git branch matches conversation metadata)
92
+ * - Decision context (commit message references decisions from conversation)
93
+ *
94
+ * Only creates links with confidence > 0.3 to avoid false positives.
95
+ *
96
+ * @param conversations - Array of conversations to match against
97
+ * @param fileEdits - Array of file edits from conversations
98
+ * @param decisions - Array of decisions that may be referenced in commits
99
+ * @returns Array of GitCommit objects with conversation_id set for matches
100
+ *
101
+ * @example
102
+ * ```typescript
103
+ * const integrator = new GitIntegrator('/path/to/project');
104
+ * const commits = await integrator.linkCommitsToConversations(
105
+ * conversations,
106
+ * fileEdits,
107
+ * decisions
108
+ * );
109
+ *
110
+ * // Find commits linked to a specific conversation
111
+ * const convCommits = commits.filter(c => c.conversation_id === 'conv-123');
112
+ * console.error(`${convCommits.length} commits for this conversation`);
113
+ * ```
114
+ */
115
+ linkCommitsToConversations(conversations: Conversation[], fileEdits: FileEdit[], decisions: Decision[]): Promise<GitCommit[]>;
116
+ /**
117
+ * Parse git history
118
+ */
119
+ private parseGitHistory;
120
+ /**
121
+ * Get files changed in a commit
122
+ */
123
+ private getChangedFiles;
124
+ /**
125
+ * Find best conversation match for a commit
126
+ */
127
+ private findBestConversationMatch;
128
+ /**
129
+ * Score how well a commit matches a conversation
130
+ */
131
+ private scoreCommitConversationMatch;
132
+ /**
133
+ * Score based on timestamp proximity
134
+ * Returns 0-3 points
135
+ */
136
+ private scoreTimestampProximity;
137
+ /**
138
+ * Score based on file overlap
139
+ * Returns 0-4 points
140
+ */
141
+ private scoreFileOverlap;
142
+ /**
143
+ * Score based on commit message keywords
144
+ * Returns 0-2 points
145
+ */
146
+ private scoreCommitMessageKeywords;
147
+ /**
148
+ * Get recent commits (last N days)
149
+ */
150
+ getRecentCommits(days?: number): Promise<GitCommit[]>;
151
+ /**
152
+ * Get commits affecting a specific file
153
+ */
154
+ getCommitsForFile(filePath: string): Promise<GitCommit[]>;
155
+ }
156
+ //# sourceMappingURL=GitIntegrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GitIntegrator.d.ts","sourceRoot":"","sources":["../../src/parsers/GitIntegrator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAEvD;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,qBAAqB;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,oBAAoB;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uBAAuB;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,sBAAsB;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oCAAoC;IACpC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,0CAA0C;IAC1C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iDAAiD;IACjD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,qBAAqB;IACrB,MAAM,EAAE,SAAS,CAAC;IAClB,+BAA+B;IAC/B,YAAY,EAAE,YAAY,CAAC;IAC3B,0CAA0C;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;GAIG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,GAAG,CAAY;IAEvB;;;;;OAKG;gBACS,WAAW,EAAE,MAAM;IAI/B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACG,0BAA0B,CAC9B,aAAa,EAAE,YAAY,EAAE,EAC7B,SAAS,EAAE,QAAQ,EAAE,EACrB,SAAS,EAAE,QAAQ,EAAE,GACpB,OAAO,CAAC,SAAS,EAAE,CAAC;IAqCvB;;OAEG;YACW,eAAe;IA4C7B;;OAEG;YACW,eAAe;IAgB7B;;OAEG;IACH,OAAO,CAAC,yBAAyB;IA0BjC;;OAEG;IACH,OAAO,CAAC,4BAA4B;IAiDpC;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAkC/B;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IA0BxB;;;OAGG;IACH,OAAO,CAAC,0BAA0B;IAyClC;;OAEG;IACG,gBAAgB,CAAC,IAAI,GAAE,MAAW,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAkC/D;;OAEG;IACG,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;CAsBhE"}
@@ -0,0 +1,348 @@
1
+ /**
2
+ * Git Integrator - Links git commits to conversations based on temporal and contextual analysis.
3
+ *
4
+ * This integrator connects git repository history with conversation history by:
5
+ * - Parsing git log to extract commits
6
+ * - Matching commits to conversations using multiple signals:
7
+ * - Temporal proximity (commit time vs conversation time)
8
+ * - File overlap (files changed in commit vs files edited in conversation)
9
+ * - Branch matching (git branch in commit vs conversation metadata)
10
+ * - Decision matching (commit message mentions decisions from conversation)
11
+ *
12
+ * Provides confidence scores (0-1) for each linkage based on:
13
+ * - Exact timestamp match (highest confidence)
14
+ * - File overlap percentage
15
+ * - Branch name match
16
+ * - Decision keyword presence
17
+ *
18
+ * Helps answer "WHY was this code changed?" by linking code changes to their
19
+ * discussion context.
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * const integrator = new GitIntegrator('/path/to/project');
24
+ * const linkedCommits = await integrator.linkCommitsToConversations(
25
+ * conversations,
26
+ * fileEdits,
27
+ * decisions
28
+ * );
29
+ * console.error(`Linked ${linkedCommits.filter(c => c.conversation_id).length} commits`);
30
+ * ```
31
+ */
32
+ import simpleGit from "simple-git";
33
+ /**
34
+ * Integrates git repository history with conversation history.
35
+ *
36
+ * Links commits to conversations using temporal and contextual analysis.
37
+ */
38
+ export class GitIntegrator {
39
+ git;
40
+ /**
41
+ * Create a new GitIntegrator.
42
+ *
43
+ * @param projectPath - Path to the git repository
44
+ * @throws {Error} If the directory is not a git repository
45
+ */
46
+ constructor(projectPath) {
47
+ this.git = simpleGit(projectPath);
48
+ }
49
+ /**
50
+ * Parse git history and link commits to conversations.
51
+ *
52
+ * Analyzes git log and matches commits to conversations using multiple signals:
53
+ * - Temporal proximity (commits made during conversation timeframe)
54
+ * - File overlap (files changed in commit match files edited in conversation)
55
+ * - Branch matching (git branch matches conversation metadata)
56
+ * - Decision context (commit message references decisions from conversation)
57
+ *
58
+ * Only creates links with confidence > 0.3 to avoid false positives.
59
+ *
60
+ * @param conversations - Array of conversations to match against
61
+ * @param fileEdits - Array of file edits from conversations
62
+ * @param decisions - Array of decisions that may be referenced in commits
63
+ * @returns Array of GitCommit objects with conversation_id set for matches
64
+ *
65
+ * @example
66
+ * ```typescript
67
+ * const integrator = new GitIntegrator('/path/to/project');
68
+ * const commits = await integrator.linkCommitsToConversations(
69
+ * conversations,
70
+ * fileEdits,
71
+ * decisions
72
+ * );
73
+ *
74
+ * // Find commits linked to a specific conversation
75
+ * const convCommits = commits.filter(c => c.conversation_id === 'conv-123');
76
+ * console.error(`${convCommits.length} commits for this conversation`);
77
+ * ```
78
+ */
79
+ async linkCommitsToConversations(conversations, fileEdits, decisions) {
80
+ console.error("Parsing git history...");
81
+ // Get git log
82
+ const commits = await this.parseGitHistory();
83
+ console.error(`Found ${commits.length} commits`);
84
+ // Link commits to conversations
85
+ const linkedCommits = [];
86
+ for (const commit of commits) {
87
+ const linkage = this.findBestConversationMatch(commit, conversations, fileEdits, decisions);
88
+ if (linkage && linkage.confidence > 0.3) {
89
+ commit.conversation_id = linkage.conversation.id;
90
+ console.error(`Linked commit ${commit.hash.substring(0, 7)} to conversation (confidence: ${(linkage.confidence * 100).toFixed(0)}%)`);
91
+ console.error(` Reasons: ${linkage.reasons.join(", ")}`);
92
+ }
93
+ linkedCommits.push(commit);
94
+ }
95
+ console.error(`Linked ${linkedCommits.filter((c) => c.conversation_id).length} commits to conversations`);
96
+ return linkedCommits;
97
+ }
98
+ /**
99
+ * Parse git history
100
+ */
101
+ async parseGitHistory() {
102
+ try {
103
+ const log = await this.git.log({
104
+ "--all": null,
105
+ "--name-only": null,
106
+ });
107
+ const commits = [];
108
+ for (const entry of log.all) {
109
+ // Get current branch (if available)
110
+ let branch;
111
+ try {
112
+ const branches = await this.git.branch(["--contains", entry.hash]);
113
+ branch = branches.current || branches.all[0];
114
+ }
115
+ catch (_e) {
116
+ // Branch info not available
117
+ }
118
+ // Parse changed files from diff
119
+ const files = await this.getChangedFiles(entry.hash);
120
+ commits.push({
121
+ hash: entry.hash,
122
+ message: entry.message,
123
+ author: entry.author_name,
124
+ timestamp: new Date(entry.date).getTime(),
125
+ branch,
126
+ files_changed: files,
127
+ metadata: {
128
+ author_email: entry.author_email,
129
+ refs: entry.refs,
130
+ body: entry.body,
131
+ },
132
+ });
133
+ }
134
+ return commits;
135
+ }
136
+ catch (error) {
137
+ console.error("Error parsing git history:", error);
138
+ return [];
139
+ }
140
+ }
141
+ /**
142
+ * Get files changed in a commit
143
+ */
144
+ async getChangedFiles(commitHash) {
145
+ try {
146
+ const diff = await this.git.show([
147
+ "--name-only",
148
+ "--format=",
149
+ commitHash,
150
+ ]);
151
+ return diff
152
+ .split("\n")
153
+ .map((f) => f.trim())
154
+ .filter((f) => f.length > 0);
155
+ }
156
+ catch (_error) {
157
+ return [];
158
+ }
159
+ }
160
+ /**
161
+ * Find best conversation match for a commit
162
+ */
163
+ findBestConversationMatch(commit, conversations, fileEdits, decisions) {
164
+ let bestMatch = null;
165
+ let highestConfidence = 0;
166
+ for (const conversation of conversations) {
167
+ const linkage = this.scoreCommitConversationMatch(commit, conversation, fileEdits, decisions);
168
+ if (linkage.confidence > highestConfidence) {
169
+ highestConfidence = linkage.confidence;
170
+ bestMatch = linkage;
171
+ }
172
+ }
173
+ return bestMatch;
174
+ }
175
+ /**
176
+ * Score how well a commit matches a conversation
177
+ */
178
+ scoreCommitConversationMatch(commit, conversation, fileEdits, decisions) {
179
+ let score = 0;
180
+ const reasons = [];
181
+ const maxScore = 10; // Total possible points
182
+ // 1. Timestamp proximity (3 points max)
183
+ const timestampScore = this.scoreTimestampProximity(commit, conversation);
184
+ score += timestampScore;
185
+ if (timestampScore > 0) {
186
+ reasons.push(`timestamp proximity (${timestampScore.toFixed(1)}/3)`);
187
+ }
188
+ // 2. File overlap (4 points max)
189
+ const fileScore = this.scoreFileOverlap(commit, conversation, fileEdits);
190
+ score += fileScore;
191
+ if (fileScore > 0) {
192
+ reasons.push(`file overlap (${fileScore.toFixed(1)}/4)`);
193
+ }
194
+ // 3. Branch match (1 point)
195
+ if (commit.branch && commit.branch === conversation.git_branch) {
196
+ score += 1;
197
+ reasons.push("branch match");
198
+ }
199
+ // 4. Commit message keywords (2 points max)
200
+ const keywordScore = this.scoreCommitMessageKeywords(commit, conversation, decisions);
201
+ score += keywordScore;
202
+ if (keywordScore > 0) {
203
+ reasons.push(`message keywords (${keywordScore.toFixed(1)}/2)`);
204
+ }
205
+ return {
206
+ commit,
207
+ conversation,
208
+ confidence: score / maxScore,
209
+ reasons,
210
+ };
211
+ }
212
+ /**
213
+ * Score based on timestamp proximity
214
+ * Returns 0-3 points
215
+ */
216
+ scoreTimestampProximity(commit, conversation) {
217
+ const { first_message_at, last_message_at } = conversation;
218
+ // Check if commit is within conversation timespan
219
+ if (commit.timestamp >= first_message_at &&
220
+ commit.timestamp <= last_message_at) {
221
+ return 3; // Perfect match
222
+ }
223
+ // Check if commit is within 5 minutes before/after conversation
224
+ const fiveMinutes = 5 * 60 * 1000;
225
+ const timeDelta = Math.min(Math.abs(commit.timestamp - first_message_at), Math.abs(commit.timestamp - last_message_at));
226
+ if (timeDelta < fiveMinutes) {
227
+ return 2; // Very close
228
+ }
229
+ // Check if commit is within 1 hour
230
+ const oneHour = 60 * 60 * 1000;
231
+ if (timeDelta < oneHour) {
232
+ return 1; // Somewhat close
233
+ }
234
+ return 0; // Too far away
235
+ }
236
+ /**
237
+ * Score based on file overlap
238
+ * Returns 0-4 points
239
+ */
240
+ scoreFileOverlap(commit, conversation, fileEdits) {
241
+ // Get files discussed in conversation
242
+ const conversationFiles = fileEdits
243
+ .filter((edit) => edit.conversation_id === conversation.id)
244
+ .map((edit) => edit.file_path);
245
+ if (conversationFiles.length === 0) {
246
+ return 0;
247
+ }
248
+ // Calculate overlap
249
+ const commitFilesSet = new Set(commit.files_changed);
250
+ const overlappingFiles = conversationFiles.filter((file) => commitFilesSet.has(file));
251
+ const overlapRatio = overlappingFiles.length /
252
+ Math.max(commit.files_changed.length, conversationFiles.length);
253
+ // 4 points for 100% overlap, scaling down
254
+ return overlapRatio * 4;
255
+ }
256
+ /**
257
+ * Score based on commit message keywords
258
+ * Returns 0-2 points
259
+ */
260
+ scoreCommitMessageKeywords(commit, conversation, decisions) {
261
+ const commitMessage = commit.message.toLowerCase();
262
+ // Get keywords from conversation decisions
263
+ const conversationDecisions = decisions.filter((d) => d.conversation_id === conversation.id);
264
+ if (conversationDecisions.length === 0) {
265
+ return 0;
266
+ }
267
+ // Extract keywords from decisions
268
+ const keywords = new Set();
269
+ for (const decision of conversationDecisions) {
270
+ // Extract significant words (3+ characters)
271
+ const words = decision.decision_text
272
+ .toLowerCase()
273
+ .split(/\s+/)
274
+ .filter((w) => w.length >= 3);
275
+ words.forEach((w) => keywords.add(w));
276
+ if (decision.context) {
277
+ keywords.add(decision.context.toLowerCase());
278
+ }
279
+ }
280
+ // Count keyword matches
281
+ let matches = 0;
282
+ for (const keyword of keywords) {
283
+ if (commitMessage.includes(keyword)) {
284
+ matches++;
285
+ }
286
+ }
287
+ // 2 points for 3+ matches, scaling down
288
+ return Math.min(matches / 3, 1) * 2;
289
+ }
290
+ /**
291
+ * Get recent commits (last N days)
292
+ */
293
+ async getRecentCommits(days = 30) {
294
+ const sinceDate = new Date();
295
+ sinceDate.setDate(sinceDate.getDate() - days);
296
+ try {
297
+ const log = await this.git.log({
298
+ "--since": sinceDate.toISOString(),
299
+ });
300
+ const commits = [];
301
+ for (const entry of log.all) {
302
+ const files = await this.getChangedFiles(entry.hash);
303
+ commits.push({
304
+ hash: entry.hash,
305
+ message: entry.message,
306
+ author: entry.author_name,
307
+ timestamp: new Date(entry.date).getTime(),
308
+ files_changed: files,
309
+ metadata: {
310
+ author_email: entry.author_email,
311
+ refs: entry.refs,
312
+ },
313
+ });
314
+ }
315
+ return commits;
316
+ }
317
+ catch (error) {
318
+ console.error("Error getting recent commits:", error);
319
+ return [];
320
+ }
321
+ }
322
+ /**
323
+ * Get commits affecting a specific file
324
+ */
325
+ async getCommitsForFile(filePath) {
326
+ try {
327
+ const log = await this.git.log({
328
+ file: filePath,
329
+ });
330
+ return log.all.map((entry) => ({
331
+ hash: entry.hash,
332
+ message: entry.message,
333
+ author: entry.author_name,
334
+ timestamp: new Date(entry.date).getTime(),
335
+ files_changed: [filePath],
336
+ metadata: {
337
+ author_email: entry.author_email,
338
+ refs: entry.refs,
339
+ },
340
+ }));
341
+ }
342
+ catch (error) {
343
+ console.error(`Error getting commits for ${filePath}:`, error);
344
+ return [];
345
+ }
346
+ }
347
+ }
348
+ //# sourceMappingURL=GitIntegrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GitIntegrator.js","sourceRoot":"","sources":["../../src/parsers/GitIntegrator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Mistake Extractor - Identifies errors and how they were corrected.
3
+ *
4
+ * This extractor analyzes conversation messages and tool results to identify
5
+ * mistakes made during development and how they were corrected. It helps prevent
6
+ * repeating the same errors by documenting:
7
+ * - What went wrong
8
+ * - How it was corrected
9
+ * - Files affected
10
+ * - Type of mistake (logic error, wrong approach, etc.)
11
+ *
12
+ * Sources of mistakes:
13
+ * - Tool execution errors (failed commands, syntax errors)
14
+ * - User corrections ("that's wrong", "don't do that")
15
+ * - Error discussions (debugging conversations)
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * const extractor = new MistakeExtractor();
20
+ * const mistakes = extractor.extractMistakes(messages, toolResults);
21
+ * console.log(`Found ${mistakes.length} mistakes`);
22
+ * mistakes.forEach(m => {
23
+ * console.log(`${m.mistake_type}: ${m.what_went_wrong}`);
24
+ * if (m.correction) console.log(`Fixed by: ${m.correction}`);
25
+ * });
26
+ * ```
27
+ */
28
+ import type { Message, ToolResult } from "./ConversationParser.js";
29
+ /**
30
+ * Represents a mistake made during development and how it was corrected.
31
+ */
32
+ export interface Mistake {
33
+ /** Unique mistake identifier */
34
+ id: string;
35
+ /** Conversation where the mistake occurred */
36
+ conversation_id: string;
37
+ /** Message containing or referencing the mistake */
38
+ message_id: string;
39
+ /** Category of mistake */
40
+ mistake_type: "logic_error" | "wrong_approach" | "misunderstanding" | "tool_error" | "syntax_error";
41
+ /** Description of what went wrong */
42
+ what_went_wrong: string;
43
+ /** How the mistake was corrected */
44
+ correction?: string;
45
+ /** User's message correcting the mistake */
46
+ user_correction_message?: string;
47
+ /** Files affected by this mistake */
48
+ files_affected: string[];
49
+ /** When the mistake occurred */
50
+ timestamp: number;
51
+ }
52
+ /**
53
+ * Extracts mistakes and corrections from conversation history.
54
+ *
55
+ * Analyzes tool errors, user corrections, and error discussions to document
56
+ * mistakes and prevent repetition.
57
+ */
58
+ export declare class MistakeExtractor {
59
+ private readonly MIN_SEVERITY_SCORE;
60
+ private readonly NOISE_PATTERNS;
61
+ private readonly CORRECTION_INDICATORS;
62
+ private readonly ERROR_INDICATORS;
63
+ private readonly MISTAKE_PATTERNS;
64
+ /**
65
+ * Extract mistakes from messages and tool results.
66
+ *
67
+ * Analyzes three sources to identify mistakes:
68
+ * 1. Tool execution errors (failed commands, syntax errors)
69
+ * 2. User corrections (explicit corrections by the user)
70
+ * 3. Error discussions (conversations about bugs and fixes)
71
+ *
72
+ * @param messages - Array of conversation messages
73
+ * @param toolResults - Array of tool execution results
74
+ * @returns Array of extracted Mistake objects, deduplicated
75
+ *
76
+ * @example
77
+ * ```typescript
78
+ * const extractor = new MistakeExtractor();
79
+ * const mistakes = extractor.extractMistakes(messages, toolResults);
80
+ *
81
+ * // Find logic errors
82
+ * const logicErrors = mistakes.filter(m => m.mistake_type === 'logic_error');
83
+ * ```
84
+ */
85
+ extractMistakes(messages: Message[], toolResults: ToolResult[]): Mistake[];
86
+ /**
87
+ * Check if content is noise that should be filtered out
88
+ */
89
+ private isNoiseContent;
90
+ /**
91
+ * Extract mistakes from tool execution errors
92
+ */
93
+ private extractToolErrors;
94
+ /**
95
+ * Extract mistakes from user corrections
96
+ */
97
+ private extractUserCorrections;
98
+ /**
99
+ * Extract mistakes from error discussions in messages
100
+ */
101
+ private extractErrorDiscussions;
102
+ /**
103
+ * Classify the type of mistake
104
+ */
105
+ private classifyMistakeType;
106
+ /**
107
+ * Summarize error message - find the most descriptive error line
108
+ */
109
+ private summarizeError;
110
+ /**
111
+ * Find correction in subsequent messages
112
+ */
113
+ private findCorrection;
114
+ /**
115
+ * Extract files mentioned in error
116
+ */
117
+ private extractFilesFromError;
118
+ /**
119
+ * Extract files from message metadata
120
+ */
121
+ private extractFilesFromMessage;
122
+ /**
123
+ * Find previous assistant message
124
+ */
125
+ private findPreviousAssistantMessage;
126
+ /**
127
+ * Extract what went wrong from correction message
128
+ */
129
+ private extractWhatWentWrong;
130
+ /**
131
+ * Extract correction from user message
132
+ */
133
+ private extractCorrection;
134
+ /**
135
+ * Extract error discussion from message
136
+ */
137
+ private extractErrorDiscussion;
138
+ /**
139
+ * Extract solution from same message that discusses error
140
+ */
141
+ private extractSolutionFromSameMessage;
142
+ /**
143
+ * Deduplicate similar mistakes
144
+ */
145
+ private deduplicateMistakes;
146
+ /**
147
+ * Score mistake severity (for prioritization)
148
+ */
149
+ scoreMistakeSeverity(mistake: Mistake): number;
150
+ }
151
+ //# sourceMappingURL=MistakeExtractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MistakeExtractor.d.ts","sourceRoot":"","sources":["../../src/parsers/MistakeExtractor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,gCAAgC;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,8CAA8C;IAC9C,eAAe,EAAE,MAAM,CAAC;IACxB,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,0BAA0B;IAC1B,YAAY,EAAE,aAAa,GAAG,gBAAgB,GAAG,kBAAkB,GAAG,YAAY,GAAG,cAAc,CAAC;IACpG,qCAAqC;IACrC,eAAe,EAAE,MAAM,CAAC;IACxB,oCAAoC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,qCAAqC;IACrC,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,qBAAa,gBAAgB;IAG3B,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAK;IAGxC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAM7B;IAGF,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAWpC;IAGF,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAS/B;IAGF,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAa/B;IAEF;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,eAAe,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,OAAO,EAAE;IAyB1E;;OAEG;IACH,OAAO,CAAC,cAAc;IAKtB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAqCzB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAyC9B;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAsC/B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAkB3B;;OAEG;IACH,OAAO,CAAC,cAAc;IAyCtB;;OAEG;IACH,OAAO,CAAC,cAAc;IAqBtB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAc7B;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAgB/B;;OAEG;IACH,OAAO,CAAC,4BAA4B;IAYpC;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAgB5B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAezB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAa9B;;OAEG;IACH,OAAO,CAAC,8BAA8B;IAQtC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAmB3B;;OAEG;IACH,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM;CA8B/C"}