claude-conversation-memory-mcp 0.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 (116) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +223 -0
  3. package/dist/ConversationMemory.d.ts +80 -0
  4. package/dist/ConversationMemory.d.ts.map +1 -0
  5. package/dist/ConversationMemory.js +203 -0
  6. package/dist/ConversationMemory.js.map +1 -0
  7. package/dist/documentation/CodeAnalyzer.d.ts +29 -0
  8. package/dist/documentation/CodeAnalyzer.d.ts.map +1 -0
  9. package/dist/documentation/CodeAnalyzer.js +122 -0
  10. package/dist/documentation/CodeAnalyzer.js.map +1 -0
  11. package/dist/documentation/ConversationAnalyzer.d.ts +19 -0
  12. package/dist/documentation/ConversationAnalyzer.d.ts.map +1 -0
  13. package/dist/documentation/ConversationAnalyzer.js +156 -0
  14. package/dist/documentation/ConversationAnalyzer.js.map +1 -0
  15. package/dist/documentation/CrossReferencer.d.ts +67 -0
  16. package/dist/documentation/CrossReferencer.d.ts.map +1 -0
  17. package/dist/documentation/CrossReferencer.js +247 -0
  18. package/dist/documentation/CrossReferencer.js.map +1 -0
  19. package/dist/documentation/DocumentationGenerator.d.ts +22 -0
  20. package/dist/documentation/DocumentationGenerator.d.ts.map +1 -0
  21. package/dist/documentation/DocumentationGenerator.js +57 -0
  22. package/dist/documentation/DocumentationGenerator.js.map +1 -0
  23. package/dist/documentation/MarkdownFormatter.d.ts +26 -0
  24. package/dist/documentation/MarkdownFormatter.d.ts.map +1 -0
  25. package/dist/documentation/MarkdownFormatter.js +301 -0
  26. package/dist/documentation/MarkdownFormatter.js.map +1 -0
  27. package/dist/documentation/types.d.ts +176 -0
  28. package/dist/documentation/types.d.ts.map +1 -0
  29. package/dist/documentation/types.js +5 -0
  30. package/dist/documentation/types.js.map +1 -0
  31. package/dist/embeddings/EmbeddingConfig.d.ts +39 -0
  32. package/dist/embeddings/EmbeddingConfig.d.ts.map +1 -0
  33. package/dist/embeddings/EmbeddingConfig.js +132 -0
  34. package/dist/embeddings/EmbeddingConfig.js.map +1 -0
  35. package/dist/embeddings/EmbeddingGenerator.d.ts +45 -0
  36. package/dist/embeddings/EmbeddingGenerator.d.ts.map +1 -0
  37. package/dist/embeddings/EmbeddingGenerator.js +129 -0
  38. package/dist/embeddings/EmbeddingGenerator.js.map +1 -0
  39. package/dist/embeddings/EmbeddingProvider.d.ts +34 -0
  40. package/dist/embeddings/EmbeddingProvider.d.ts.map +1 -0
  41. package/dist/embeddings/EmbeddingProvider.js +6 -0
  42. package/dist/embeddings/EmbeddingProvider.js.map +1 -0
  43. package/dist/embeddings/VectorStore.d.ts +75 -0
  44. package/dist/embeddings/VectorStore.d.ts.map +1 -0
  45. package/dist/embeddings/VectorStore.js +220 -0
  46. package/dist/embeddings/VectorStore.js.map +1 -0
  47. package/dist/embeddings/providers/OllamaEmbeddings.d.ts +38 -0
  48. package/dist/embeddings/providers/OllamaEmbeddings.d.ts.map +1 -0
  49. package/dist/embeddings/providers/OllamaEmbeddings.js +132 -0
  50. package/dist/embeddings/providers/OllamaEmbeddings.js.map +1 -0
  51. package/dist/embeddings/providers/OpenAIEmbeddings.d.ts +40 -0
  52. package/dist/embeddings/providers/OpenAIEmbeddings.d.ts.map +1 -0
  53. package/dist/embeddings/providers/OpenAIEmbeddings.js +128 -0
  54. package/dist/embeddings/providers/OpenAIEmbeddings.js.map +1 -0
  55. package/dist/embeddings/providers/TransformersEmbeddings.d.ts +38 -0
  56. package/dist/embeddings/providers/TransformersEmbeddings.d.ts.map +1 -0
  57. package/dist/embeddings/providers/TransformersEmbeddings.js +114 -0
  58. package/dist/embeddings/providers/TransformersEmbeddings.js.map +1 -0
  59. package/dist/index.d.ts +7 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.js +127 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/parsers/ConversationParser.d.ts +138 -0
  64. package/dist/parsers/ConversationParser.d.ts.map +1 -0
  65. package/dist/parsers/ConversationParser.js +325 -0
  66. package/dist/parsers/ConversationParser.js.map +1 -0
  67. package/dist/parsers/DecisionExtractor.d.ts +76 -0
  68. package/dist/parsers/DecisionExtractor.d.ts.map +1 -0
  69. package/dist/parsers/DecisionExtractor.js +305 -0
  70. package/dist/parsers/DecisionExtractor.js.map +1 -0
  71. package/dist/parsers/GitIntegrator.d.ts +71 -0
  72. package/dist/parsers/GitIntegrator.d.ts.map +1 -0
  73. package/dist/parsers/GitIntegrator.js +283 -0
  74. package/dist/parsers/GitIntegrator.js.map +1 -0
  75. package/dist/parsers/MistakeExtractor.d.ts +86 -0
  76. package/dist/parsers/MistakeExtractor.d.ts.map +1 -0
  77. package/dist/parsers/MistakeExtractor.js +341 -0
  78. package/dist/parsers/MistakeExtractor.js.map +1 -0
  79. package/dist/parsers/RequirementsExtractor.d.ts +70 -0
  80. package/dist/parsers/RequirementsExtractor.d.ts.map +1 -0
  81. package/dist/parsers/RequirementsExtractor.js +252 -0
  82. package/dist/parsers/RequirementsExtractor.js.map +1 -0
  83. package/dist/search/SemanticSearch.d.ts +90 -0
  84. package/dist/search/SemanticSearch.d.ts.map +1 -0
  85. package/dist/search/SemanticSearch.js +352 -0
  86. package/dist/search/SemanticSearch.js.map +1 -0
  87. package/dist/storage/ConversationStorage.d.ts +53 -0
  88. package/dist/storage/ConversationStorage.d.ts.map +1 -0
  89. package/dist/storage/ConversationStorage.js +249 -0
  90. package/dist/storage/ConversationStorage.js.map +1 -0
  91. package/dist/storage/SQLiteManager.d.ts +88 -0
  92. package/dist/storage/SQLiteManager.d.ts.map +1 -0
  93. package/dist/storage/SQLiteManager.js +281 -0
  94. package/dist/storage/SQLiteManager.js.map +1 -0
  95. package/dist/storage/migrations.d.ts +54 -0
  96. package/dist/storage/migrations.d.ts.map +1 -0
  97. package/dist/storage/migrations.js +153 -0
  98. package/dist/storage/migrations.js.map +1 -0
  99. package/dist/storage/schema.sql +321 -0
  100. package/dist/tools/ToolDefinitions.d.ts +265 -0
  101. package/dist/tools/ToolDefinitions.d.ts.map +1 -0
  102. package/dist/tools/ToolDefinitions.js +261 -0
  103. package/dist/tools/ToolDefinitions.js.map +1 -0
  104. package/dist/tools/ToolHandlers.d.ts +56 -0
  105. package/dist/tools/ToolHandlers.d.ts.map +1 -0
  106. package/dist/tools/ToolHandlers.js +431 -0
  107. package/dist/tools/ToolHandlers.js.map +1 -0
  108. package/dist/types/ToolTypes.d.ts +333 -0
  109. package/dist/types/ToolTypes.d.ts.map +1 -0
  110. package/dist/types/ToolTypes.js +6 -0
  111. package/dist/types/ToolTypes.js.map +1 -0
  112. package/dist/utils/sanitization.d.ts +35 -0
  113. package/dist/utils/sanitization.d.ts.map +1 -0
  114. package/dist/utils/sanitization.js +97 -0
  115. package/dist/utils/sanitization.js.map +1 -0
  116. package/package.json +87 -0
@@ -0,0 +1,341 @@
1
+ /**
2
+ * Mistake Extractor
3
+ * Identifies errors and how they were corrected to prevent repetition
4
+ */
5
+ import { nanoid } from "nanoid";
6
+ export class MistakeExtractor {
7
+ // User correction indicators
8
+ CORRECTION_INDICATORS = [
9
+ /^no[,\s]/i,
10
+ /that'?s?\s+(?:wrong|incorrect|not right|a mistake)/i,
11
+ /(?:you|that)\s+(?:made|caused|introduced)\s+(?:a|an)\s+(?:error|bug|mistake)/i,
12
+ /don't\s+do\s+(?:that|this)/i,
13
+ /(?:should not|shouldn't|must not|mustn't)\s+(?:have\s+)?(?:done|used)/i,
14
+ /(?:fix|correct|change)\s+(?:that|this)/i,
15
+ ];
16
+ // Error indicators in assistant messages
17
+ ERROR_INDICATORS = [
18
+ /error:/i,
19
+ /failed:/i,
20
+ /exception:/i,
21
+ /(?:this|that)\s+(?:didn't|doesn't|won't)\s+work/i,
22
+ /(?:broke|breaking|broken)/i,
23
+ /(?:issue|problem|bug)/i,
24
+ ];
25
+ // Mistake type patterns
26
+ MISTAKE_PATTERNS = {
27
+ logic_error: [/logic\s+error/i, /incorrect\s+logic/i, /wrong\s+condition/i],
28
+ wrong_approach: [
29
+ /wrong\s+approach/i,
30
+ /better\s+way/i,
31
+ /should\s+(?:have\s+)?use(?:d)?/i,
32
+ ],
33
+ misunderstanding: [
34
+ /misunderstood/i,
35
+ /(?:didn't|don't)\s+understand/i,
36
+ /confused\s+about/i,
37
+ ],
38
+ syntax_error: [/syntax\s+error/i, /parse\s+error/i, /invalid\s+syntax/i],
39
+ };
40
+ /**
41
+ * Extract mistakes from messages and tool results
42
+ */
43
+ extractMistakes(messages, toolResults) {
44
+ const mistakes = [];
45
+ // Extract from tool errors
46
+ const toolErrors = this.extractToolErrors(toolResults, messages);
47
+ mistakes.push(...toolErrors);
48
+ // Extract from user corrections
49
+ const userCorrections = this.extractUserCorrections(messages);
50
+ mistakes.push(...userCorrections);
51
+ // Extract from error discussions
52
+ const errorDiscussions = this.extractErrorDiscussions(messages);
53
+ mistakes.push(...errorDiscussions);
54
+ return this.deduplicateMistakes(mistakes);
55
+ }
56
+ /**
57
+ * Extract mistakes from tool execution errors
58
+ */
59
+ extractToolErrors(toolResults, messages) {
60
+ const mistakes = [];
61
+ for (const result of toolResults) {
62
+ if (!result.is_error) {
63
+ continue;
64
+ }
65
+ const message = messages.find((m) => m.id === result.message_id);
66
+ if (!message) {
67
+ continue;
68
+ }
69
+ // Extract error details
70
+ const errorContent = result.stderr || result.content || "";
71
+ const mistakeType = this.classifyMistakeType(errorContent);
72
+ mistakes.push({
73
+ id: nanoid(),
74
+ conversation_id: message.conversation_id,
75
+ message_id: message.id,
76
+ mistake_type: mistakeType || "tool_error",
77
+ what_went_wrong: this.summarizeError(errorContent),
78
+ correction: this.findCorrection(message, messages),
79
+ files_affected: this.extractFilesFromError(errorContent),
80
+ timestamp: result.timestamp,
81
+ });
82
+ }
83
+ return mistakes;
84
+ }
85
+ /**
86
+ * Extract mistakes from user corrections
87
+ */
88
+ extractUserCorrections(messages) {
89
+ const mistakes = [];
90
+ for (let i = 0; i < messages.length; i++) {
91
+ const message = messages[i];
92
+ if (message.role !== "user" || !message.content) {
93
+ continue;
94
+ }
95
+ const content = message.content;
96
+ // Check if this is a correction
97
+ const isCorrection = this.CORRECTION_INDICATORS.some((pattern) => pattern.test(content));
98
+ if (!isCorrection) {
99
+ continue;
100
+ }
101
+ // Find the previous assistant message
102
+ const previousAssistant = this.findPreviousAssistantMessage(messages, i);
103
+ if (!previousAssistant) {
104
+ continue;
105
+ }
106
+ const mistakeType = this.classifyMistakeType(message.content);
107
+ mistakes.push({
108
+ id: nanoid(),
109
+ conversation_id: message.conversation_id,
110
+ message_id: previousAssistant.id,
111
+ mistake_type: mistakeType || "misunderstanding",
112
+ what_went_wrong: this.extractWhatWentWrong(message.content),
113
+ correction: this.extractCorrection(message.content),
114
+ user_correction_message: message.content,
115
+ files_affected: this.extractFilesFromMessage(message),
116
+ timestamp: message.timestamp,
117
+ });
118
+ }
119
+ return mistakes;
120
+ }
121
+ /**
122
+ * Extract mistakes from error discussions in messages
123
+ */
124
+ extractErrorDiscussions(messages) {
125
+ const mistakes = [];
126
+ for (const message of messages) {
127
+ if (message.role !== "assistant" || !message.content) {
128
+ continue;
129
+ }
130
+ const content = message.content;
131
+ // Check if message discusses an error
132
+ const hasErrorDiscussion = this.ERROR_INDICATORS.some((pattern) => pattern.test(content));
133
+ if (!hasErrorDiscussion) {
134
+ continue;
135
+ }
136
+ // Extract error discussion
137
+ const errorText = this.extractErrorDiscussion(message.content);
138
+ if (!errorText) {
139
+ continue;
140
+ }
141
+ const mistakeType = this.classifyMistakeType(errorText);
142
+ mistakes.push({
143
+ id: nanoid(),
144
+ conversation_id: message.conversation_id,
145
+ message_id: message.id,
146
+ mistake_type: mistakeType || "logic_error",
147
+ what_went_wrong: errorText,
148
+ correction: this.extractSolutionFromSameMessage(message.content),
149
+ files_affected: this.extractFilesFromMessage(message),
150
+ timestamp: message.timestamp,
151
+ });
152
+ }
153
+ return mistakes;
154
+ }
155
+ /**
156
+ * Classify the type of mistake
157
+ */
158
+ classifyMistakeType(text) {
159
+ for (const [type, patterns] of Object.entries(this.MISTAKE_PATTERNS)) {
160
+ for (const pattern of patterns) {
161
+ if (pattern.test(text)) {
162
+ return type;
163
+ }
164
+ }
165
+ }
166
+ return null;
167
+ }
168
+ /**
169
+ * Summarize error message
170
+ */
171
+ summarizeError(errorText) {
172
+ // Take first line or first 200 characters
173
+ const firstLine = errorText.split("\n")[0];
174
+ return firstLine.length > 200
175
+ ? firstLine.substring(0, 200) + "..."
176
+ : firstLine;
177
+ }
178
+ /**
179
+ * Find correction in subsequent messages
180
+ */
181
+ findCorrection(errorMessage, allMessages) {
182
+ const index = allMessages.findIndex((m) => m.id === errorMessage.id);
183
+ if (index === -1) {
184
+ return undefined;
185
+ }
186
+ // Look at next few messages for a fix
187
+ const nextMessages = allMessages.slice(index + 1, index + 5);
188
+ for (const msg of nextMessages) {
189
+ if (msg.role === "assistant" && msg.content) {
190
+ // Look for fix indicators
191
+ if (/(?:fixed|resolved|corrected|solved)/i.test(msg.content)) {
192
+ return msg.content.substring(0, 500);
193
+ }
194
+ }
195
+ }
196
+ return undefined;
197
+ }
198
+ /**
199
+ * Extract files mentioned in error
200
+ */
201
+ extractFilesFromError(errorText) {
202
+ const files = [];
203
+ // Common file path patterns
204
+ const filePathPattern = /(?:\/|\.\/|\.\.\/)?(?:[\w-]+\/)*[\w-]+\.[\w]+/g;
205
+ const matches = errorText.match(filePathPattern);
206
+ if (matches) {
207
+ files.push(...matches);
208
+ }
209
+ return [...new Set(files)];
210
+ }
211
+ /**
212
+ * Extract files from message metadata
213
+ */
214
+ extractFilesFromMessage(message) {
215
+ const files = [];
216
+ if (message.metadata) {
217
+ const metadataStr = JSON.stringify(message.metadata);
218
+ const filePathPattern = /(?:\/[\w-]+)+\.[\w]+/g;
219
+ const matches = metadataStr.match(filePathPattern);
220
+ if (matches) {
221
+ files.push(...matches);
222
+ }
223
+ }
224
+ return [...new Set(files)];
225
+ }
226
+ /**
227
+ * Find previous assistant message
228
+ */
229
+ findPreviousAssistantMessage(messages, currentIndex) {
230
+ for (let i = currentIndex - 1; i >= 0; i--) {
231
+ if (messages[i].role === "assistant") {
232
+ return messages[i];
233
+ }
234
+ }
235
+ return undefined;
236
+ }
237
+ /**
238
+ * Extract what went wrong from correction message
239
+ */
240
+ extractWhatWentWrong(correctionText) {
241
+ // Remove correction indicators
242
+ let cleaned = correctionText;
243
+ for (const pattern of this.CORRECTION_INDICATORS) {
244
+ cleaned = cleaned.replace(pattern, "");
245
+ }
246
+ // Take first sentence or up to 300 characters
247
+ const sentences = cleaned.split(/\.|!|\?/);
248
+ const firstSentence = sentences[0]?.trim();
249
+ return firstSentence && firstSentence.length > 0
250
+ ? firstSentence.substring(0, 300)
251
+ : cleaned.substring(0, 300);
252
+ }
253
+ /**
254
+ * Extract correction from user message
255
+ */
256
+ extractCorrection(correctionText) {
257
+ // Look for "instead" or "should" patterns
258
+ const insteadMatch = correctionText.match(/instead[,\s]+(.+?)(?:\.|$)/i);
259
+ if (insteadMatch) {
260
+ return insteadMatch[1].trim();
261
+ }
262
+ const shouldMatch = correctionText.match(/should\s+(?:have\s+)?(.+?)(?:\.|$)/i);
263
+ if (shouldMatch) {
264
+ return shouldMatch[1].trim();
265
+ }
266
+ return undefined;
267
+ }
268
+ /**
269
+ * Extract error discussion from message
270
+ */
271
+ extractErrorDiscussion(content) {
272
+ // Find sentences containing error indicators
273
+ const sentences = content.split(/\.|!|\?/);
274
+ for (const sentence of sentences) {
275
+ if (this.ERROR_INDICATORS.some((pattern) => pattern.test(sentence))) {
276
+ return sentence.trim();
277
+ }
278
+ }
279
+ return undefined;
280
+ }
281
+ /**
282
+ * Extract solution from same message that discusses error
283
+ */
284
+ extractSolutionFromSameMessage(content) {
285
+ // Look for solution indicators
286
+ const solutionPattern = /(?:to fix|solution|resolved by|corrected by|fixed by)\s+(.+?)(?:\.|$)/i;
287
+ const match = content.match(solutionPattern);
288
+ return match?.[1]?.trim();
289
+ }
290
+ /**
291
+ * Deduplicate similar mistakes
292
+ */
293
+ deduplicateMistakes(mistakes) {
294
+ const unique = [];
295
+ const seen = new Set();
296
+ for (const mistake of mistakes) {
297
+ // Create signature
298
+ const signature = `${mistake.what_went_wrong.substring(0, 100)}_${mistake.timestamp}`;
299
+ if (!seen.has(signature)) {
300
+ seen.add(signature);
301
+ unique.push(mistake);
302
+ }
303
+ }
304
+ return unique;
305
+ }
306
+ /**
307
+ * Score mistake severity (for prioritization)
308
+ */
309
+ scoreMistakeSeverity(mistake) {
310
+ let score = 0;
311
+ // Has correction
312
+ if (mistake.correction) {
313
+ score += 2;
314
+ }
315
+ // User explicitly corrected
316
+ if (mistake.user_correction_message) {
317
+ score += 3;
318
+ }
319
+ // Affects files
320
+ if (mistake.files_affected.length > 0) {
321
+ score += 2;
322
+ }
323
+ // Type-based severity
324
+ switch (mistake.mistake_type) {
325
+ case "logic_error":
326
+ score += 3;
327
+ break;
328
+ case "wrong_approach":
329
+ score += 2;
330
+ break;
331
+ case "syntax_error":
332
+ score += 1;
333
+ break;
334
+ case "tool_error":
335
+ score += 1;
336
+ break;
337
+ }
338
+ return score;
339
+ }
340
+ }
341
+ //# sourceMappingURL=MistakeExtractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MistakeExtractor.js","sourceRoot":"","sources":["../../src/parsers/MistakeExtractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Requirements and Validations Extractor
3
+ * Tracks constraints, dependencies, and testing context
4
+ */
5
+ import type { Message, ToolUse, ToolResult } from "./ConversationParser.js";
6
+ export interface Requirement {
7
+ id: string;
8
+ type: "dependency" | "performance" | "compatibility" | "business";
9
+ description: string;
10
+ rationale?: string;
11
+ affects_components: string[];
12
+ conversation_id: string;
13
+ message_id: string;
14
+ timestamp: number;
15
+ }
16
+ export interface Validation {
17
+ id: string;
18
+ conversation_id: string;
19
+ what_was_tested: string;
20
+ test_command?: string;
21
+ result: "passed" | "failed" | "error";
22
+ performance_data?: Record<string, unknown>;
23
+ files_tested: string[];
24
+ timestamp: number;
25
+ }
26
+ export declare class RequirementsExtractor {
27
+ private readonly REQUIREMENT_PATTERNS;
28
+ private readonly TEST_PATTERNS;
29
+ /**
30
+ * Extract requirements from messages
31
+ */
32
+ extractRequirements(messages: Message[]): Requirement[];
33
+ /**
34
+ * Extract validations from tool uses
35
+ */
36
+ extractValidations(toolUses: ToolUse[], toolResults: ToolResult[], messages: Message[]): Validation[];
37
+ /**
38
+ * Parse a requirement from pattern match
39
+ */
40
+ private parseRequirement;
41
+ /**
42
+ * Extract rationale from requirement text
43
+ */
44
+ private extractRationale;
45
+ /**
46
+ * Extract affected components from message metadata
47
+ */
48
+ private extractAffectedComponents;
49
+ /**
50
+ * Extract what was tested from command and result
51
+ */
52
+ private extractWhatWasTested;
53
+ /**
54
+ * Determine test result from tool result
55
+ */
56
+ private determineTestResult;
57
+ /**
58
+ * Extract performance data from test results
59
+ */
60
+ private extractPerformanceData;
61
+ /**
62
+ * Extract files that were tested
63
+ */
64
+ private extractTestedFiles;
65
+ /**
66
+ * Deduplicate similar requirements
67
+ */
68
+ private deduplicateRequirements;
69
+ }
70
+ //# sourceMappingURL=RequirementsExtractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RequirementsExtractor.d.ts","sourceRoot":"","sources":["../../src/parsers/RequirementsExtractor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAE5E,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,YAAY,GAAG,aAAa,GAAG,eAAe,GAAG,UAAU,CAAC;IAClE,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;IACtC,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,qBAAqB;IAEhC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAmBnC;IAGF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAQ5B;IAEF;;OAEG;IACH,mBAAmB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,WAAW,EAAE;IA8BvD;;OAEG;IACH,kBAAkB,CAChB,QAAQ,EAAE,OAAO,EAAE,EACnB,WAAW,EAAE,UAAU,EAAE,EACzB,QAAQ,EAAE,OAAO,EAAE,GAClB,UAAU,EAAE;IAuCf;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAgCxB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAuBxB;;OAEG;IACH,OAAO,CAAC,yBAAyB;IA0BjC;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAqB5B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IA6B3B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA6B9B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAe1B;;OAEG;IACH,OAAO,CAAC,uBAAuB;CAchC"}
@@ -0,0 +1,252 @@
1
+ /**
2
+ * Requirements and Validations Extractor
3
+ * Tracks constraints, dependencies, and testing context
4
+ */
5
+ import { nanoid } from "nanoid";
6
+ export class RequirementsExtractor {
7
+ // Requirement indicators
8
+ REQUIREMENT_PATTERNS = {
9
+ dependency: [
10
+ /(?:need|require|must use|depends on)\s+(.+?)\s+(?:library|package|module|dependency)/gi,
11
+ /(?:install|add)\s+(.+?)\s+(?:for|to)/gi,
12
+ ],
13
+ performance: [
14
+ /(?:must|should|need to)\s+(?:be|run)\s+(?:faster|slower|within|under)\s+(.+)/gi,
15
+ /response time\s+(?:must|should)\s+(?:be\s+)?(?:under|less than|within)\s+(.+)/gi,
16
+ /(?:latency|throughput|performance)\s+requirement:\s*(.+)/gi,
17
+ ],
18
+ compatibility: [
19
+ /(?:must|should|need to)\s+(?:support|work with|be compatible with)\s+(.+)/gi,
20
+ /(?:requires?|needs?)\s+(.+?)\s+(?:version|or higher|or later)/gi,
21
+ ],
22
+ business: [
23
+ /business requirement:\s*(.+)/gi,
24
+ /(?:must|cannot|can't)\s+(?:exceed|violate|break)\s+(.+)/gi,
25
+ /(?:constraint|limitation):\s*(.+)/gi,
26
+ ],
27
+ };
28
+ // Test/validation indicators
29
+ TEST_PATTERNS = [
30
+ /(?:npm|yarn|pnpm)\s+test/,
31
+ /(?:npm|yarn|pnpm)\s+run\s+test/,
32
+ /pytest/,
33
+ /jest/,
34
+ /mocha/,
35
+ /cargo\s+test/,
36
+ /go\s+test/,
37
+ ];
38
+ /**
39
+ * Extract requirements from messages
40
+ */
41
+ extractRequirements(messages) {
42
+ const requirements = [];
43
+ for (const message of messages) {
44
+ if (!message.content) {
45
+ continue;
46
+ }
47
+ // Check each requirement type
48
+ for (const [type, patterns] of Object.entries(this.REQUIREMENT_PATTERNS)) {
49
+ for (const pattern of patterns) {
50
+ const matches = Array.from(message.content.matchAll(pattern));
51
+ for (const match of matches) {
52
+ const requirement = this.parseRequirement(type, match, message);
53
+ if (requirement) {
54
+ requirements.push(requirement);
55
+ }
56
+ }
57
+ }
58
+ }
59
+ }
60
+ return this.deduplicateRequirements(requirements);
61
+ }
62
+ /**
63
+ * Extract validations from tool uses
64
+ */
65
+ extractValidations(toolUses, toolResults, messages) {
66
+ const validations = [];
67
+ for (const toolUse of toolUses) {
68
+ // Check if this is a test command
69
+ if (toolUse.tool_name === "Bash") {
70
+ const command = toolUse.tool_input.command;
71
+ if (!command || typeof command !== "string") {
72
+ continue;
73
+ }
74
+ const isTest = this.TEST_PATTERNS.some((pattern) => pattern.test(command));
75
+ if (isTest) {
76
+ // Find corresponding result
77
+ const result = toolResults.find((r) => r.tool_use_id === toolUse.id);
78
+ const message = messages.find((m) => m.id === toolUse.message_id);
79
+ if (result && message) {
80
+ validations.push({
81
+ id: nanoid(),
82
+ conversation_id: message.conversation_id,
83
+ what_was_tested: this.extractWhatWasTested(command, result),
84
+ test_command: command,
85
+ result: this.determineTestResult(result),
86
+ performance_data: this.extractPerformanceData(result),
87
+ files_tested: this.extractTestedFiles(result),
88
+ timestamp: toolUse.timestamp,
89
+ });
90
+ }
91
+ }
92
+ }
93
+ }
94
+ return validations;
95
+ }
96
+ /**
97
+ * Parse a requirement from pattern match
98
+ */
99
+ parseRequirement(type, match, message) {
100
+ const description = match[1]?.trim();
101
+ if (!description) {
102
+ return null;
103
+ }
104
+ if (!message.content) {
105
+ return null;
106
+ }
107
+ // Extract rationale from message context
108
+ const rationale = this.extractRationale(match[0], message.content);
109
+ // Extract affected components
110
+ const components = this.extractAffectedComponents(message);
111
+ return {
112
+ id: nanoid(),
113
+ type,
114
+ description,
115
+ rationale,
116
+ affects_components: components,
117
+ conversation_id: message.conversation_id,
118
+ message_id: message.id,
119
+ timestamp: message.timestamp,
120
+ };
121
+ }
122
+ /**
123
+ * Extract rationale from requirement text
124
+ */
125
+ extractRationale(requirementText, fullContent) {
126
+ // Look for "because", "since", "for" explanations
127
+ const rationaleMatch = requirementText.match(/(?:because|since|for|due to)\s+(.+?)(?:\.|$)/i);
128
+ if (rationaleMatch) {
129
+ return rationaleMatch[1].trim();
130
+ }
131
+ // Look in surrounding context
132
+ const contextMatch = fullContent.match(new RegExp(`${requirementText.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}[^.]*?(?:because|since|for|due to)\\s+(.+?)(?:\\.|$)`, "i"));
133
+ return contextMatch?.[1]?.trim();
134
+ }
135
+ /**
136
+ * Extract affected components from message metadata
137
+ */
138
+ extractAffectedComponents(message) {
139
+ const components = [];
140
+ // Common component keywords
141
+ const componentKeywords = [
142
+ "frontend",
143
+ "backend",
144
+ "api",
145
+ "database",
146
+ "auth",
147
+ "ui",
148
+ "server",
149
+ "client",
150
+ ];
151
+ const content = message.content?.toLowerCase() || "";
152
+ for (const keyword of componentKeywords) {
153
+ if (content.includes(keyword)) {
154
+ components.push(keyword);
155
+ }
156
+ }
157
+ return [...new Set(components)];
158
+ }
159
+ /**
160
+ * Extract what was tested from command and result
161
+ */
162
+ extractWhatWasTested(command, result) {
163
+ // Try to extract test file/suite name
164
+ const fileMatch = command.match(/test[/\\](.+?)(?:\s|$)/);
165
+ if (fileMatch) {
166
+ return fileMatch[1];
167
+ }
168
+ // Try to extract from result
169
+ const resultContent = result.stdout || result.content || "";
170
+ const suiteMatch = resultContent.match(/(?:Test Suite|Describe):\s*(.+)/i);
171
+ if (suiteMatch) {
172
+ return suiteMatch[1].trim();
173
+ }
174
+ // Fallback to command
175
+ return command;
176
+ }
177
+ /**
178
+ * Determine test result from tool result
179
+ */
180
+ determineTestResult(result) {
181
+ if (result.is_error) {
182
+ return "error";
183
+ }
184
+ const output = (result.stdout || result.content || "").toLowerCase();
185
+ // Check for pass indicators
186
+ if (/(?:all tests? passed|✓|✔|success)/i.test(output) ||
187
+ /(?:\d+\s+passed,\s+0\s+failed)/i.test(output)) {
188
+ return "passed";
189
+ }
190
+ // Check for fail indicators
191
+ if (/(?:test failed|✗|✘|failure|failed)/i.test(output) ||
192
+ /(?:\d+\s+failed)/i.test(output)) {
193
+ return "failed";
194
+ }
195
+ // Default to passed if no errors
196
+ return result.is_error ? "error" : "passed";
197
+ }
198
+ /**
199
+ * Extract performance data from test results
200
+ */
201
+ extractPerformanceData(result) {
202
+ const output = result.stdout || result.content || "";
203
+ const data = {};
204
+ // Extract timing information
205
+ const timeMatch = output.match(/(\d+(?:\.\d+)?)\s*(ms|s|seconds?|milliseconds?)/i);
206
+ if (timeMatch) {
207
+ const value = parseFloat(timeMatch[1]);
208
+ const unit = timeMatch[2].toLowerCase();
209
+ data.duration_ms = unit.startsWith("s") ? value * 1000 : value;
210
+ }
211
+ // Extract test counts
212
+ const passedMatch = output.match(/(\d+)\s+passed/i);
213
+ if (passedMatch) {
214
+ data.tests_passed = parseInt(passedMatch[1]);
215
+ }
216
+ const failedMatch = output.match(/(\d+)\s+failed/i);
217
+ if (failedMatch) {
218
+ data.tests_failed = parseInt(failedMatch[1]);
219
+ }
220
+ return Object.keys(data).length > 0 ? data : undefined;
221
+ }
222
+ /**
223
+ * Extract files that were tested
224
+ */
225
+ extractTestedFiles(result) {
226
+ const output = result.stdout || result.content || "";
227
+ const files = [];
228
+ // Look for file paths
229
+ const filePattern = /(?:PASS|FAIL|ERROR)\s+([\w/.-]+\.(?:test|spec)\.[\w]+)/gi;
230
+ const matches = Array.from(output.matchAll(filePattern));
231
+ for (const match of matches) {
232
+ files.push(match[1]);
233
+ }
234
+ return [...new Set(files)];
235
+ }
236
+ /**
237
+ * Deduplicate similar requirements
238
+ */
239
+ deduplicateRequirements(requirements) {
240
+ const unique = [];
241
+ const seen = new Set();
242
+ for (const req of requirements) {
243
+ const signature = `${req.type}_${req.description.substring(0, 50)}`;
244
+ if (!seen.has(signature)) {
245
+ seen.add(signature);
246
+ unique.push(req);
247
+ }
248
+ }
249
+ return unique;
250
+ }
251
+ }
252
+ //# sourceMappingURL=RequirementsExtractor.js.map