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.
- package/LICENSE +21 -0
- package/README.md +349 -0
- package/dist/ConversationMemory.d.ts +231 -0
- package/dist/ConversationMemory.d.ts.map +1 -0
- package/dist/ConversationMemory.js +357 -0
- package/dist/ConversationMemory.js.map +1 -0
- package/dist/cache/QueryCache.d.ts +215 -0
- package/dist/cache/QueryCache.d.ts.map +1 -0
- package/dist/cache/QueryCache.js +294 -0
- package/dist/cache/QueryCache.js.map +1 -0
- package/dist/cli/commands.d.ts +9 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +954 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/help.d.ts +16 -0
- package/dist/cli/help.d.ts.map +1 -0
- package/dist/cli/help.js +361 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/index.d.ts +30 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +111 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/context/ContextInjector.d.ts +38 -0
- package/dist/context/ContextInjector.d.ts.map +1 -0
- package/dist/context/ContextInjector.js +235 -0
- package/dist/context/ContextInjector.js.map +1 -0
- package/dist/documentation/CodeAnalyzer.d.ts +29 -0
- package/dist/documentation/CodeAnalyzer.d.ts.map +1 -0
- package/dist/documentation/CodeAnalyzer.js +122 -0
- package/dist/documentation/CodeAnalyzer.js.map +1 -0
- package/dist/documentation/ConversationAnalyzer.d.ts +19 -0
- package/dist/documentation/ConversationAnalyzer.d.ts.map +1 -0
- package/dist/documentation/ConversationAnalyzer.js +157 -0
- package/dist/documentation/ConversationAnalyzer.js.map +1 -0
- package/dist/documentation/CrossReferencer.d.ts +67 -0
- package/dist/documentation/CrossReferencer.d.ts.map +1 -0
- package/dist/documentation/CrossReferencer.js +247 -0
- package/dist/documentation/CrossReferencer.js.map +1 -0
- package/dist/documentation/DocumentationGenerator.d.ts +22 -0
- package/dist/documentation/DocumentationGenerator.d.ts.map +1 -0
- package/dist/documentation/DocumentationGenerator.js +57 -0
- package/dist/documentation/DocumentationGenerator.js.map +1 -0
- package/dist/documentation/MarkdownFormatter.d.ts +26 -0
- package/dist/documentation/MarkdownFormatter.d.ts.map +1 -0
- package/dist/documentation/MarkdownFormatter.js +301 -0
- package/dist/documentation/MarkdownFormatter.js.map +1 -0
- package/dist/documentation/types.d.ts +176 -0
- package/dist/documentation/types.d.ts.map +1 -0
- package/dist/documentation/types.js +5 -0
- package/dist/documentation/types.js.map +1 -0
- package/dist/embeddings/ConfigManager.d.ts +46 -0
- package/dist/embeddings/ConfigManager.d.ts.map +1 -0
- package/dist/embeddings/ConfigManager.js +177 -0
- package/dist/embeddings/ConfigManager.js.map +1 -0
- package/dist/embeddings/EmbeddingConfig.d.ts +39 -0
- package/dist/embeddings/EmbeddingConfig.d.ts.map +1 -0
- package/dist/embeddings/EmbeddingConfig.js +132 -0
- package/dist/embeddings/EmbeddingConfig.js.map +1 -0
- package/dist/embeddings/EmbeddingGenerator.d.ts +51 -0
- package/dist/embeddings/EmbeddingGenerator.d.ts.map +1 -0
- package/dist/embeddings/EmbeddingGenerator.js +157 -0
- package/dist/embeddings/EmbeddingGenerator.js.map +1 -0
- package/dist/embeddings/EmbeddingProvider.d.ts +34 -0
- package/dist/embeddings/EmbeddingProvider.d.ts.map +1 -0
- package/dist/embeddings/EmbeddingProvider.js +6 -0
- package/dist/embeddings/EmbeddingProvider.js.map +1 -0
- package/dist/embeddings/ModelRegistry.d.ts +48 -0
- package/dist/embeddings/ModelRegistry.d.ts.map +1 -0
- package/dist/embeddings/ModelRegistry.js +170 -0
- package/dist/embeddings/ModelRegistry.js.map +1 -0
- package/dist/embeddings/VectorStore.d.ts +114 -0
- package/dist/embeddings/VectorStore.d.ts.map +1 -0
- package/dist/embeddings/VectorStore.js +393 -0
- package/dist/embeddings/VectorStore.js.map +1 -0
- package/dist/embeddings/providers/OllamaEmbeddings.d.ts +38 -0
- package/dist/embeddings/providers/OllamaEmbeddings.d.ts.map +1 -0
- package/dist/embeddings/providers/OllamaEmbeddings.js +125 -0
- package/dist/embeddings/providers/OllamaEmbeddings.js.map +1 -0
- package/dist/embeddings/providers/OpenAIEmbeddings.d.ts +40 -0
- package/dist/embeddings/providers/OpenAIEmbeddings.d.ts.map +1 -0
- package/dist/embeddings/providers/OpenAIEmbeddings.js +129 -0
- package/dist/embeddings/providers/OpenAIEmbeddings.js.map +1 -0
- package/dist/embeddings/providers/TransformersEmbeddings.d.ts +38 -0
- package/dist/embeddings/providers/TransformersEmbeddings.d.ts.map +1 -0
- package/dist/embeddings/providers/TransformersEmbeddings.js +115 -0
- package/dist/embeddings/providers/TransformersEmbeddings.js.map +1 -0
- package/dist/handoff/SessionHandoffStore.d.ts +80 -0
- package/dist/handoff/SessionHandoffStore.d.ts.map +1 -0
- package/dist/handoff/SessionHandoffStore.js +314 -0
- package/dist/handoff/SessionHandoffStore.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +115 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server.d.ts +27 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +157 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/memory/WorkingMemoryStore.d.ts +83 -0
- package/dist/memory/WorkingMemoryStore.d.ts.map +1 -0
- package/dist/memory/WorkingMemoryStore.js +318 -0
- package/dist/memory/WorkingMemoryStore.js.map +1 -0
- package/dist/memory/types.d.ts +192 -0
- package/dist/memory/types.d.ts.map +1 -0
- package/dist/memory/types.js +8 -0
- package/dist/memory/types.js.map +1 -0
- package/dist/parsers/CodexConversationParser.d.ts +51 -0
- package/dist/parsers/CodexConversationParser.d.ts.map +1 -0
- package/dist/parsers/CodexConversationParser.js +301 -0
- package/dist/parsers/CodexConversationParser.js.map +1 -0
- package/dist/parsers/ConversationParser.d.ts +286 -0
- package/dist/parsers/ConversationParser.d.ts.map +1 -0
- package/dist/parsers/ConversationParser.js +795 -0
- package/dist/parsers/ConversationParser.js.map +1 -0
- package/dist/parsers/DecisionExtractor.d.ts +144 -0
- package/dist/parsers/DecisionExtractor.d.ts.map +1 -0
- package/dist/parsers/DecisionExtractor.js +434 -0
- package/dist/parsers/DecisionExtractor.js.map +1 -0
- package/dist/parsers/GitIntegrator.d.ts +156 -0
- package/dist/parsers/GitIntegrator.d.ts.map +1 -0
- package/dist/parsers/GitIntegrator.js +348 -0
- package/dist/parsers/GitIntegrator.js.map +1 -0
- package/dist/parsers/MistakeExtractor.d.ts +151 -0
- package/dist/parsers/MistakeExtractor.d.ts.map +1 -0
- package/dist/parsers/MistakeExtractor.js +460 -0
- package/dist/parsers/MistakeExtractor.js.map +1 -0
- package/dist/parsers/RequirementsExtractor.d.ts +166 -0
- package/dist/parsers/RequirementsExtractor.d.ts.map +1 -0
- package/dist/parsers/RequirementsExtractor.js +338 -0
- package/dist/parsers/RequirementsExtractor.js.map +1 -0
- package/dist/realtime/ConversationWatcher.d.ts +87 -0
- package/dist/realtime/ConversationWatcher.d.ts.map +1 -0
- package/dist/realtime/ConversationWatcher.js +204 -0
- package/dist/realtime/ConversationWatcher.js.map +1 -0
- package/dist/realtime/IncrementalParser.d.ts +83 -0
- package/dist/realtime/IncrementalParser.d.ts.map +1 -0
- package/dist/realtime/IncrementalParser.js +232 -0
- package/dist/realtime/IncrementalParser.js.map +1 -0
- package/dist/realtime/LiveExtractor.d.ts +72 -0
- package/dist/realtime/LiveExtractor.d.ts.map +1 -0
- package/dist/realtime/LiveExtractor.js +288 -0
- package/dist/realtime/LiveExtractor.js.map +1 -0
- package/dist/search/SemanticSearch.d.ts +121 -0
- package/dist/search/SemanticSearch.d.ts.map +1 -0
- package/dist/search/SemanticSearch.js +823 -0
- package/dist/search/SemanticSearch.js.map +1 -0
- package/dist/storage/BackupManager.d.ts +58 -0
- package/dist/storage/BackupManager.d.ts.map +1 -0
- package/dist/storage/BackupManager.js +223 -0
- package/dist/storage/BackupManager.js.map +1 -0
- package/dist/storage/ConversationStorage.d.ts +341 -0
- package/dist/storage/ConversationStorage.d.ts.map +1 -0
- package/dist/storage/ConversationStorage.js +792 -0
- package/dist/storage/ConversationStorage.js.map +1 -0
- package/dist/storage/DeletionService.d.ts +70 -0
- package/dist/storage/DeletionService.d.ts.map +1 -0
- package/dist/storage/DeletionService.js +253 -0
- package/dist/storage/DeletionService.js.map +1 -0
- package/dist/storage/GlobalIndex.d.ts +133 -0
- package/dist/storage/GlobalIndex.d.ts.map +1 -0
- package/dist/storage/GlobalIndex.js +310 -0
- package/dist/storage/GlobalIndex.js.map +1 -0
- package/dist/storage/SQLiteManager.d.ts +114 -0
- package/dist/storage/SQLiteManager.d.ts.map +1 -0
- package/dist/storage/SQLiteManager.js +636 -0
- package/dist/storage/SQLiteManager.js.map +1 -0
- package/dist/storage/migrations.d.ts +54 -0
- package/dist/storage/migrations.d.ts.map +1 -0
- package/dist/storage/migrations.js +285 -0
- package/dist/storage/migrations.js.map +1 -0
- package/dist/storage/schema.sql +436 -0
- package/dist/tools/ToolDefinitions.d.ts +946 -0
- package/dist/tools/ToolDefinitions.d.ts.map +1 -0
- package/dist/tools/ToolDefinitions.js +937 -0
- package/dist/tools/ToolDefinitions.js.map +1 -0
- package/dist/tools/ToolHandlers.d.ts +791 -0
- package/dist/tools/ToolHandlers.d.ts.map +1 -0
- package/dist/tools/ToolHandlers.js +3262 -0
- package/dist/tools/ToolHandlers.js.map +1 -0
- package/dist/types/ToolTypes.d.ts +824 -0
- package/dist/types/ToolTypes.d.ts.map +1 -0
- package/dist/types/ToolTypes.js +6 -0
- package/dist/types/ToolTypes.js.map +1 -0
- package/dist/utils/Logger.d.ts +70 -0
- package/dist/utils/Logger.d.ts.map +1 -0
- package/dist/utils/Logger.js +131 -0
- package/dist/utils/Logger.js.map +1 -0
- package/dist/utils/McpConfig.d.ts +54 -0
- package/dist/utils/McpConfig.d.ts.map +1 -0
- package/dist/utils/McpConfig.js +136 -0
- package/dist/utils/McpConfig.js.map +1 -0
- package/dist/utils/ProjectMigration.d.ts +82 -0
- package/dist/utils/ProjectMigration.d.ts.map +1 -0
- package/dist/utils/ProjectMigration.js +416 -0
- package/dist/utils/ProjectMigration.js.map +1 -0
- package/dist/utils/constants.d.ts +75 -0
- package/dist/utils/constants.d.ts.map +1 -0
- package/dist/utils/constants.js +105 -0
- package/dist/utils/constants.js.map +1 -0
- package/dist/utils/safeJson.d.ts +37 -0
- package/dist/utils/safeJson.d.ts.map +1 -0
- package/dist/utils/safeJson.js +48 -0
- package/dist/utils/safeJson.js.map +1 -0
- package/dist/utils/sanitization.d.ts +45 -0
- package/dist/utils/sanitization.d.ts.map +1 -0
- package/dist/utils/sanitization.js +153 -0
- package/dist/utils/sanitization.js.map +1 -0
- package/dist/utils/worktree.d.ts +15 -0
- package/dist/utils/worktree.d.ts.map +1 -0
- package/dist/utils/worktree.js +86 -0
- package/dist/utils/worktree.js.map +1 -0
- package/package.json +98 -0
- package/scripts/changelog-check.sh +62 -0
- package/scripts/check-node.js +17 -0
- package/scripts/dev-config.js +56 -0
- package/scripts/postinstall.js +117 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Incremental Parser
|
|
3
|
+
*
|
|
4
|
+
* Parses new lines from Claude conversation JSONL files as they are appended.
|
|
5
|
+
* Maintains file positions to only process new content.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Parsed message from a JSONL file
|
|
9
|
+
*/
|
|
10
|
+
export interface ParsedMessage {
|
|
11
|
+
type: "user" | "assistant" | "system";
|
|
12
|
+
content: string;
|
|
13
|
+
timestamp?: number;
|
|
14
|
+
toolUse?: {
|
|
15
|
+
name: string;
|
|
16
|
+
input: Record<string, unknown>;
|
|
17
|
+
};
|
|
18
|
+
toolResult?: {
|
|
19
|
+
name: string;
|
|
20
|
+
output: string;
|
|
21
|
+
isError?: boolean;
|
|
22
|
+
};
|
|
23
|
+
thinkingContent?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* File tracking info
|
|
27
|
+
*/
|
|
28
|
+
interface FileInfo {
|
|
29
|
+
path: string;
|
|
30
|
+
lastPosition: number;
|
|
31
|
+
lastModified: number;
|
|
32
|
+
lineCount: number;
|
|
33
|
+
}
|
|
34
|
+
export declare class IncrementalParser {
|
|
35
|
+
private filePositions;
|
|
36
|
+
constructor();
|
|
37
|
+
/**
|
|
38
|
+
* Parse new content from a file since last read
|
|
39
|
+
*/
|
|
40
|
+
parseNewContent(filePath: string): ParsedMessage[];
|
|
41
|
+
/**
|
|
42
|
+
* Parse a single JSONL line
|
|
43
|
+
*/
|
|
44
|
+
private parseLine;
|
|
45
|
+
/**
|
|
46
|
+
* Extract message from parsed JSON data
|
|
47
|
+
*/
|
|
48
|
+
private extractMessage;
|
|
49
|
+
/**
|
|
50
|
+
* Extract text content from various content formats
|
|
51
|
+
*/
|
|
52
|
+
private extractContent;
|
|
53
|
+
/**
|
|
54
|
+
* Extract tool use information
|
|
55
|
+
*/
|
|
56
|
+
private extractToolUse;
|
|
57
|
+
/**
|
|
58
|
+
* Extract tool result information
|
|
59
|
+
*/
|
|
60
|
+
private extractToolResult;
|
|
61
|
+
/**
|
|
62
|
+
* Extract thinking/reasoning content
|
|
63
|
+
*/
|
|
64
|
+
private extractThinking;
|
|
65
|
+
/**
|
|
66
|
+
* Reset tracking for a specific file
|
|
67
|
+
*/
|
|
68
|
+
resetFile(filePath: string): void;
|
|
69
|
+
/**
|
|
70
|
+
* Reset all tracking
|
|
71
|
+
*/
|
|
72
|
+
resetAll(): void;
|
|
73
|
+
/**
|
|
74
|
+
* Get current tracking info for a file
|
|
75
|
+
*/
|
|
76
|
+
getFileInfo(filePath: string): FileInfo | undefined;
|
|
77
|
+
/**
|
|
78
|
+
* Get all tracked files
|
|
79
|
+
*/
|
|
80
|
+
getTrackedFiles(): string[];
|
|
81
|
+
}
|
|
82
|
+
export {};
|
|
83
|
+
//# sourceMappingURL=IncrementalParser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IncrementalParser.d.ts","sourceRoot":"","sources":["../../src/realtime/IncrementalParser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAChC,CAAC;IACF,UAAU,CAAC,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC;IACF,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,UAAU,QAAQ;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,aAAa,CAAoC;;IAMzD;;OAEG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,EAAE;IAwClD;;OAEG;IACH,OAAO,CAAC,SAAS;IAUjB;;OAEG;IACH,OAAO,CAAC,cAAc;IAuEtB;;OAEG;IACH,OAAO,CAAC,cAAc;IAyBtB;;OAEG;IACH,OAAO,CAAC,cAAc;IAqBtB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAsBzB;;OAEG;IACH,OAAO,CAAC,eAAe;IAevB;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAIjC;;OAEG;IACH,QAAQ,IAAI,IAAI;IAIhB;;OAEG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS;IAInD;;OAEG;IACH,eAAe,IAAI,MAAM,EAAE;CAG5B"}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Incremental Parser
|
|
3
|
+
*
|
|
4
|
+
* Parses new lines from Claude conversation JSONL files as they are appended.
|
|
5
|
+
* Maintains file positions to only process new content.
|
|
6
|
+
*/
|
|
7
|
+
import { readFileSync, statSync, existsSync } from "fs";
|
|
8
|
+
export class IncrementalParser {
|
|
9
|
+
filePositions = new Map();
|
|
10
|
+
constructor() {
|
|
11
|
+
// No initialization needed - file positions are initialized inline
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Parse new content from a file since last read
|
|
15
|
+
*/
|
|
16
|
+
parseNewContent(filePath) {
|
|
17
|
+
if (!existsSync(filePath)) {
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
const stats = statSync(filePath);
|
|
21
|
+
const fileInfo = this.filePositions.get(filePath);
|
|
22
|
+
// Check if file has been modified
|
|
23
|
+
if (fileInfo && stats.mtimeMs <= fileInfo.lastModified) {
|
|
24
|
+
return []; // No changes
|
|
25
|
+
}
|
|
26
|
+
// Read file content
|
|
27
|
+
const content = readFileSync(filePath, "utf-8");
|
|
28
|
+
const lines = content.split("\n").filter((line) => line.trim());
|
|
29
|
+
// Determine where to start parsing
|
|
30
|
+
const startLine = fileInfo ? fileInfo.lineCount : 0;
|
|
31
|
+
// Parse new lines
|
|
32
|
+
const messages = [];
|
|
33
|
+
for (let i = startLine; i < lines.length; i++) {
|
|
34
|
+
const parsed = this.parseLine(lines[i]);
|
|
35
|
+
if (parsed) {
|
|
36
|
+
messages.push(parsed);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// Update tracking info
|
|
40
|
+
this.filePositions.set(filePath, {
|
|
41
|
+
path: filePath,
|
|
42
|
+
lastPosition: content.length,
|
|
43
|
+
lastModified: stats.mtimeMs,
|
|
44
|
+
lineCount: lines.length,
|
|
45
|
+
});
|
|
46
|
+
return messages;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Parse a single JSONL line
|
|
50
|
+
*/
|
|
51
|
+
parseLine(line) {
|
|
52
|
+
try {
|
|
53
|
+
const data = JSON.parse(line);
|
|
54
|
+
return this.extractMessage(data);
|
|
55
|
+
}
|
|
56
|
+
catch (_error) {
|
|
57
|
+
// Invalid JSON - skip
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Extract message from parsed JSON data
|
|
63
|
+
*/
|
|
64
|
+
extractMessage(data) {
|
|
65
|
+
// Handle different Claude message formats
|
|
66
|
+
// Standard message format
|
|
67
|
+
if (data.type === "message" || data.role) {
|
|
68
|
+
const role = (data.role || data.type);
|
|
69
|
+
let messageType = "user";
|
|
70
|
+
if (role === "assistant" || role === "model") {
|
|
71
|
+
messageType = "assistant";
|
|
72
|
+
}
|
|
73
|
+
else if (role === "system") {
|
|
74
|
+
messageType = "system";
|
|
75
|
+
}
|
|
76
|
+
const message = {
|
|
77
|
+
type: messageType,
|
|
78
|
+
content: this.extractContent(data.content),
|
|
79
|
+
timestamp: typeof data.timestamp === "number" ? data.timestamp : Date.now(),
|
|
80
|
+
};
|
|
81
|
+
// Extract tool use if present
|
|
82
|
+
const toolUse = this.extractToolUse(data);
|
|
83
|
+
if (toolUse) {
|
|
84
|
+
message.toolUse = toolUse;
|
|
85
|
+
}
|
|
86
|
+
// Extract tool result if present
|
|
87
|
+
const toolResult = this.extractToolResult(data);
|
|
88
|
+
if (toolResult) {
|
|
89
|
+
message.toolResult = toolResult;
|
|
90
|
+
}
|
|
91
|
+
// Extract thinking content
|
|
92
|
+
const thinking = this.extractThinking(data);
|
|
93
|
+
if (thinking) {
|
|
94
|
+
message.thinkingContent = thinking;
|
|
95
|
+
}
|
|
96
|
+
return message;
|
|
97
|
+
}
|
|
98
|
+
// Tool use block format
|
|
99
|
+
if (data.type === "tool_use") {
|
|
100
|
+
return {
|
|
101
|
+
type: "assistant",
|
|
102
|
+
content: "",
|
|
103
|
+
toolUse: {
|
|
104
|
+
name: typeof data.name === "string" ? data.name : "unknown",
|
|
105
|
+
input: (data.input || {}),
|
|
106
|
+
},
|
|
107
|
+
timestamp: Date.now(),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
// Tool result format
|
|
111
|
+
if (data.type === "tool_result") {
|
|
112
|
+
return {
|
|
113
|
+
type: "user",
|
|
114
|
+
content: "",
|
|
115
|
+
toolResult: {
|
|
116
|
+
name: typeof data.tool_use_id === "string" ? data.tool_use_id : "unknown",
|
|
117
|
+
output: this.extractContent(data.content),
|
|
118
|
+
isError: data.is_error === true,
|
|
119
|
+
},
|
|
120
|
+
timestamp: Date.now(),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Extract text content from various content formats
|
|
127
|
+
*/
|
|
128
|
+
extractContent(content) {
|
|
129
|
+
if (typeof content === "string") {
|
|
130
|
+
return content;
|
|
131
|
+
}
|
|
132
|
+
if (Array.isArray(content)) {
|
|
133
|
+
return content
|
|
134
|
+
.map((block) => {
|
|
135
|
+
if (typeof block === "string") {
|
|
136
|
+
return block;
|
|
137
|
+
}
|
|
138
|
+
if (typeof block === "object" && block !== null) {
|
|
139
|
+
const b = block;
|
|
140
|
+
if (b.type === "text" && typeof b.text === "string") {
|
|
141
|
+
return b.text;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return "";
|
|
145
|
+
})
|
|
146
|
+
.join("\n");
|
|
147
|
+
}
|
|
148
|
+
return "";
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Extract tool use information
|
|
152
|
+
*/
|
|
153
|
+
extractToolUse(data) {
|
|
154
|
+
// Check content array for tool_use blocks
|
|
155
|
+
if (Array.isArray(data.content)) {
|
|
156
|
+
for (const block of data.content) {
|
|
157
|
+
if (typeof block === "object" && block !== null) {
|
|
158
|
+
const b = block;
|
|
159
|
+
if (b.type === "tool_use" && typeof b.name === "string") {
|
|
160
|
+
return {
|
|
161
|
+
name: b.name,
|
|
162
|
+
input: (b.input || {}),
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Extract tool result information
|
|
172
|
+
*/
|
|
173
|
+
extractToolResult(data) {
|
|
174
|
+
// Check content array for tool_result blocks
|
|
175
|
+
if (Array.isArray(data.content)) {
|
|
176
|
+
for (const block of data.content) {
|
|
177
|
+
if (typeof block === "object" && block !== null) {
|
|
178
|
+
const b = block;
|
|
179
|
+
if (b.type === "tool_result") {
|
|
180
|
+
return {
|
|
181
|
+
name: typeof b.tool_use_id === "string" ? b.tool_use_id : "unknown",
|
|
182
|
+
output: this.extractContent(b.content),
|
|
183
|
+
isError: b.is_error === true,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Extract thinking/reasoning content
|
|
193
|
+
*/
|
|
194
|
+
extractThinking(data) {
|
|
195
|
+
if (Array.isArray(data.content)) {
|
|
196
|
+
for (const block of data.content) {
|
|
197
|
+
if (typeof block === "object" && block !== null) {
|
|
198
|
+
const b = block;
|
|
199
|
+
if (b.type === "thinking" && typeof b.thinking === "string") {
|
|
200
|
+
return b.thinking;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Reset tracking for a specific file
|
|
209
|
+
*/
|
|
210
|
+
resetFile(filePath) {
|
|
211
|
+
this.filePositions.delete(filePath);
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Reset all tracking
|
|
215
|
+
*/
|
|
216
|
+
resetAll() {
|
|
217
|
+
this.filePositions.clear();
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Get current tracking info for a file
|
|
221
|
+
*/
|
|
222
|
+
getFileInfo(filePath) {
|
|
223
|
+
return this.filePositions.get(filePath);
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Get all tracked files
|
|
227
|
+
*/
|
|
228
|
+
getTrackedFiles() {
|
|
229
|
+
return Array.from(this.filePositions.keys());
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=IncrementalParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IncrementalParser.js","sourceRoot":"","sources":["../../src/realtime/IncrementalParser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live Extractor
|
|
3
|
+
*
|
|
4
|
+
* Extracts decisions, file operations, and errors from parsed messages
|
|
5
|
+
* in real-time and stores them in working memory.
|
|
6
|
+
*/
|
|
7
|
+
import type { Database } from "better-sqlite3";
|
|
8
|
+
import type { ParsedMessage } from "./IncrementalParser.js";
|
|
9
|
+
import type { RealtimeConfig } from "../memory/types.js";
|
|
10
|
+
import { WorkingMemoryStore } from "../memory/WorkingMemoryStore.js";
|
|
11
|
+
/**
|
|
12
|
+
* Result of extraction processing
|
|
13
|
+
*/
|
|
14
|
+
export interface ExtractionResult {
|
|
15
|
+
messagesProcessed: number;
|
|
16
|
+
decisionsExtracted: number;
|
|
17
|
+
filesTracked: number;
|
|
18
|
+
errorsDetected: number;
|
|
19
|
+
memoryItemsCreated: number;
|
|
20
|
+
}
|
|
21
|
+
export declare class LiveExtractor {
|
|
22
|
+
private memoryStore;
|
|
23
|
+
private config;
|
|
24
|
+
private decisionPatterns;
|
|
25
|
+
private errorPatterns;
|
|
26
|
+
constructor(db: Database, config?: Partial<RealtimeConfig>);
|
|
27
|
+
/**
|
|
28
|
+
* Process a batch of messages and extract relevant information
|
|
29
|
+
*/
|
|
30
|
+
processMessages(filePath: string, messages: ParsedMessage[]): Promise<ExtractionResult>;
|
|
31
|
+
/**
|
|
32
|
+
* Extract project path from file path
|
|
33
|
+
*/
|
|
34
|
+
private extractProjectPath;
|
|
35
|
+
/**
|
|
36
|
+
* Extract decisions from message content
|
|
37
|
+
*/
|
|
38
|
+
private extractDecisions;
|
|
39
|
+
/**
|
|
40
|
+
* Calculate confidence score for a decision
|
|
41
|
+
*/
|
|
42
|
+
private calculateDecisionConfidence;
|
|
43
|
+
/**
|
|
44
|
+
* Deduplicate similar decisions
|
|
45
|
+
*/
|
|
46
|
+
private deduplicateDecisions;
|
|
47
|
+
/**
|
|
48
|
+
* Extract file operation from tool use
|
|
49
|
+
*/
|
|
50
|
+
private extractFileOperation;
|
|
51
|
+
/**
|
|
52
|
+
* Extract errors from content
|
|
53
|
+
*/
|
|
54
|
+
private extractErrors;
|
|
55
|
+
/**
|
|
56
|
+
* Store a detected decision in working memory
|
|
57
|
+
*/
|
|
58
|
+
private storeDecision;
|
|
59
|
+
/**
|
|
60
|
+
* Store a file operation in working memory
|
|
61
|
+
*/
|
|
62
|
+
private storeFileOperation;
|
|
63
|
+
/**
|
|
64
|
+
* Store an error in working memory
|
|
65
|
+
*/
|
|
66
|
+
private storeError;
|
|
67
|
+
/**
|
|
68
|
+
* Get the working memory store for direct access
|
|
69
|
+
*/
|
|
70
|
+
getMemoryStore(): WorkingMemoryStore;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=LiveExtractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LiveExtractor.d.ts","sourceRoot":"","sources":["../../src/realtime/LiveExtractor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAIrE;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAoBD,qBAAa,aAAa;IACxB,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,MAAM,CAAiB;IAG/B,OAAO,CAAC,gBAAgB,CAKtB;IAGF,OAAO,CAAC,aAAa,CAMnB;gBAEU,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC;IAgB1D;;OAEG;IACG,eAAe,CACnB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,aAAa,EAAE,GACxB,OAAO,CAAC,gBAAgB,CAAC;IAsD5B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAgB1B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IA8BxB;;OAEG;IACH,OAAO,CAAC,2BAA2B;IA+BnC;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAe5B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAiD5B;;OAEG;IACH,OAAO,CAAC,aAAa;IAkBrB;;OAEG;IACH,OAAO,CAAC,aAAa;IAarB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAa1B;;OAEG;IACH,OAAO,CAAC,UAAU;IAYlB;;OAEG;IACH,cAAc,IAAI,kBAAkB;CAGrC"}
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live Extractor
|
|
3
|
+
*
|
|
4
|
+
* Extracts decisions, file operations, and errors from parsed messages
|
|
5
|
+
* in real-time and stores them in working memory.
|
|
6
|
+
*/
|
|
7
|
+
import { WorkingMemoryStore } from "../memory/WorkingMemoryStore.js";
|
|
8
|
+
import { dirname } from "path";
|
|
9
|
+
import { getCanonicalProjectPath } from "../utils/worktree.js";
|
|
10
|
+
export class LiveExtractor {
|
|
11
|
+
memoryStore;
|
|
12
|
+
config;
|
|
13
|
+
// Decision detection patterns
|
|
14
|
+
decisionPatterns = [
|
|
15
|
+
/(?:I'll|I will|Let's|We should|I've decided to|Going to) ([^.]+)/gi,
|
|
16
|
+
/(?:decided|choosing|opting|selecting) (?:to )?([^.]+)/gi,
|
|
17
|
+
/(?:using|implementing|adopting) ([^.]+?) (?:for|because|since)/gi,
|
|
18
|
+
/(?:the (?:best|right|correct) (?:approach|solution|way) is) ([^.]+)/gi,
|
|
19
|
+
];
|
|
20
|
+
// Error detection patterns
|
|
21
|
+
errorPatterns = [
|
|
22
|
+
/error[:\s]+(.+)/gi,
|
|
23
|
+
/failed[:\s]+(.+)/gi,
|
|
24
|
+
/exception[:\s]+(.+)/gi,
|
|
25
|
+
/cannot (.+)/gi,
|
|
26
|
+
/unable to (.+)/gi,
|
|
27
|
+
];
|
|
28
|
+
constructor(db, config) {
|
|
29
|
+
this.memoryStore = new WorkingMemoryStore(db);
|
|
30
|
+
this.config = {
|
|
31
|
+
enabled: true,
|
|
32
|
+
watchPaths: [],
|
|
33
|
+
extractionInterval: 1000,
|
|
34
|
+
checkpointInterval: 60000,
|
|
35
|
+
autoRemember: {
|
|
36
|
+
decisions: true,
|
|
37
|
+
fileEdits: true,
|
|
38
|
+
errors: true,
|
|
39
|
+
},
|
|
40
|
+
...config,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Process a batch of messages and extract relevant information
|
|
45
|
+
*/
|
|
46
|
+
async processMessages(filePath, messages) {
|
|
47
|
+
const projectPath = this.extractProjectPath(filePath);
|
|
48
|
+
const result = {
|
|
49
|
+
messagesProcessed: messages.length,
|
|
50
|
+
decisionsExtracted: 0,
|
|
51
|
+
filesTracked: 0,
|
|
52
|
+
errorsDetected: 0,
|
|
53
|
+
memoryItemsCreated: 0,
|
|
54
|
+
};
|
|
55
|
+
for (const message of messages) {
|
|
56
|
+
// Process assistant messages for decisions
|
|
57
|
+
if (message.type === "assistant" && this.config.autoRemember.decisions) {
|
|
58
|
+
const decisions = this.extractDecisions(message.content);
|
|
59
|
+
for (const decision of decisions) {
|
|
60
|
+
if (decision.confidence > 0.5) {
|
|
61
|
+
this.storeDecision(projectPath, decision);
|
|
62
|
+
result.decisionsExtracted++;
|
|
63
|
+
result.memoryItemsCreated++;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Process tool uses for file operations
|
|
68
|
+
if (message.toolUse && this.config.autoRemember.fileEdits) {
|
|
69
|
+
const fileOp = this.extractFileOperation(message.toolUse);
|
|
70
|
+
if (fileOp) {
|
|
71
|
+
this.storeFileOperation(projectPath, fileOp);
|
|
72
|
+
result.filesTracked++;
|
|
73
|
+
result.memoryItemsCreated++;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// Process tool results for errors
|
|
77
|
+
if (message.toolResult?.isError && this.config.autoRemember.errors) {
|
|
78
|
+
this.storeError(projectPath, message.toolResult.output);
|
|
79
|
+
result.errorsDetected++;
|
|
80
|
+
result.memoryItemsCreated++;
|
|
81
|
+
}
|
|
82
|
+
// Also check content for errors
|
|
83
|
+
if (this.config.autoRemember.errors) {
|
|
84
|
+
const errors = this.extractErrors(message.content);
|
|
85
|
+
for (const error of errors) {
|
|
86
|
+
this.storeError(projectPath, error);
|
|
87
|
+
result.errorsDetected++;
|
|
88
|
+
result.memoryItemsCreated++;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return result;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Extract project path from file path
|
|
96
|
+
*/
|
|
97
|
+
extractProjectPath(filePath) {
|
|
98
|
+
// Claude conversation paths are typically:
|
|
99
|
+
// ~/.claude/projects/-Users-name-project/.../conversation.jsonl
|
|
100
|
+
// We want to extract the actual project path
|
|
101
|
+
const match = filePath.match(/projects\/(.+?)\//);
|
|
102
|
+
if (match) {
|
|
103
|
+
// Convert the encoded path back to real path
|
|
104
|
+
const encoded = match[1];
|
|
105
|
+
const decodedPath = "/" + encoded.replace(/-/g, "/").replace(/\/\//g, "-");
|
|
106
|
+
return getCanonicalProjectPath(decodedPath).canonicalPath;
|
|
107
|
+
}
|
|
108
|
+
return getCanonicalProjectPath(dirname(filePath)).canonicalPath;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Extract decisions from message content
|
|
112
|
+
*/
|
|
113
|
+
extractDecisions(content) {
|
|
114
|
+
const decisions = [];
|
|
115
|
+
for (const pattern of this.decisionPatterns) {
|
|
116
|
+
// Reset regex lastIndex
|
|
117
|
+
pattern.lastIndex = 0;
|
|
118
|
+
let match;
|
|
119
|
+
while ((match = pattern.exec(content)) !== null) {
|
|
120
|
+
const decisionText = match[1].trim();
|
|
121
|
+
// Skip if too short or too long
|
|
122
|
+
if (decisionText.length < 10 || decisionText.length > 200) {
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
// Calculate confidence based on context
|
|
126
|
+
const confidence = this.calculateDecisionConfidence(decisionText, content);
|
|
127
|
+
decisions.push({
|
|
128
|
+
text: decisionText,
|
|
129
|
+
confidence,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// Deduplicate similar decisions
|
|
134
|
+
return this.deduplicateDecisions(decisions);
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Calculate confidence score for a decision
|
|
138
|
+
*/
|
|
139
|
+
calculateDecisionConfidence(decision, context) {
|
|
140
|
+
let confidence = 0.5;
|
|
141
|
+
// Higher confidence if it mentions specific tech/patterns
|
|
142
|
+
const techPatterns = [
|
|
143
|
+
/typescript|javascript|python|rust|go/i,
|
|
144
|
+
/react|vue|angular|svelte/i,
|
|
145
|
+
/sqlite|postgres|mongodb|redis/i,
|
|
146
|
+
/api|rest|graphql|grpc/i,
|
|
147
|
+
/pattern|architecture|design/i,
|
|
148
|
+
];
|
|
149
|
+
for (const pattern of techPatterns) {
|
|
150
|
+
if (pattern.test(decision)) {
|
|
151
|
+
confidence += 0.1;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// Higher confidence if in a longer context
|
|
155
|
+
if (context.length > 500) {
|
|
156
|
+
confidence += 0.1;
|
|
157
|
+
}
|
|
158
|
+
// Lower confidence if it looks like a question
|
|
159
|
+
if (decision.includes("?")) {
|
|
160
|
+
confidence -= 0.2;
|
|
161
|
+
}
|
|
162
|
+
return Math.min(1, Math.max(0, confidence));
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Deduplicate similar decisions
|
|
166
|
+
*/
|
|
167
|
+
deduplicateDecisions(decisions) {
|
|
168
|
+
const seen = new Set();
|
|
169
|
+
const unique = [];
|
|
170
|
+
for (const decision of decisions) {
|
|
171
|
+
const normalized = decision.text.toLowerCase().replace(/\s+/g, " ");
|
|
172
|
+
if (!seen.has(normalized)) {
|
|
173
|
+
seen.add(normalized);
|
|
174
|
+
unique.push(decision);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return unique;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Extract file operation from tool use
|
|
181
|
+
*/
|
|
182
|
+
extractFileOperation(toolUse) {
|
|
183
|
+
const { name, input } = toolUse;
|
|
184
|
+
let filePath;
|
|
185
|
+
let action = "read";
|
|
186
|
+
switch (name) {
|
|
187
|
+
case "Read":
|
|
188
|
+
filePath = input.file_path;
|
|
189
|
+
action = "read";
|
|
190
|
+
break;
|
|
191
|
+
case "Edit":
|
|
192
|
+
filePath = input.file_path;
|
|
193
|
+
action = "edit";
|
|
194
|
+
break;
|
|
195
|
+
case "Write":
|
|
196
|
+
filePath = input.file_path;
|
|
197
|
+
action = "create";
|
|
198
|
+
break;
|
|
199
|
+
case "Bash": {
|
|
200
|
+
// Try to extract file paths from bash commands
|
|
201
|
+
const cmd = input.command;
|
|
202
|
+
if (cmd) {
|
|
203
|
+
if (cmd.includes("rm ") || cmd.includes("rm -")) {
|
|
204
|
+
const rmMatch = cmd.match(/rm\s+(?:-\w+\s+)*(\S+)/);
|
|
205
|
+
if (rmMatch) {
|
|
206
|
+
filePath = rmMatch[1];
|
|
207
|
+
action = "delete";
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (filePath) {
|
|
215
|
+
return {
|
|
216
|
+
path: filePath,
|
|
217
|
+
action,
|
|
218
|
+
timestamp: Date.now(),
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Extract errors from content
|
|
225
|
+
*/
|
|
226
|
+
extractErrors(content) {
|
|
227
|
+
const errors = [];
|
|
228
|
+
for (const pattern of this.errorPatterns) {
|
|
229
|
+
pattern.lastIndex = 0;
|
|
230
|
+
let match;
|
|
231
|
+
while ((match = pattern.exec(content)) !== null) {
|
|
232
|
+
const errorText = match[1].trim();
|
|
233
|
+
if (errorText.length > 5 && errorText.length < 500) {
|
|
234
|
+
errors.push(errorText);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return errors.slice(0, 5); // Limit to 5 errors per message
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Store a detected decision in working memory
|
|
242
|
+
*/
|
|
243
|
+
storeDecision(projectPath, decision) {
|
|
244
|
+
const key = `decision_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
245
|
+
this.memoryStore.remember({
|
|
246
|
+
key,
|
|
247
|
+
value: decision.text,
|
|
248
|
+
context: decision.rationale,
|
|
249
|
+
tags: ["decision", "auto-extracted"],
|
|
250
|
+
projectPath,
|
|
251
|
+
ttl: 86400 * 7, // 7 days
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Store a file operation in working memory
|
|
256
|
+
*/
|
|
257
|
+
storeFileOperation(projectPath, fileOp) {
|
|
258
|
+
// Use a stable key for the file to update rather than create new entries
|
|
259
|
+
const key = `file_${fileOp.path.replace(/[^a-zA-Z0-9]/g, "_")}`;
|
|
260
|
+
this.memoryStore.remember({
|
|
261
|
+
key,
|
|
262
|
+
value: `${fileOp.action}: ${fileOp.path}`,
|
|
263
|
+
tags: ["file", fileOp.action, "auto-extracted"],
|
|
264
|
+
projectPath,
|
|
265
|
+
ttl: 86400, // 1 day
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Store an error in working memory
|
|
270
|
+
*/
|
|
271
|
+
storeError(projectPath, error) {
|
|
272
|
+
const key = `error_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
273
|
+
this.memoryStore.remember({
|
|
274
|
+
key,
|
|
275
|
+
value: error,
|
|
276
|
+
tags: ["error", "auto-extracted"],
|
|
277
|
+
projectPath,
|
|
278
|
+
ttl: 86400 * 3, // 3 days
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Get the working memory store for direct access
|
|
283
|
+
*/
|
|
284
|
+
getMemoryStore() {
|
|
285
|
+
return this.memoryStore;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
//# sourceMappingURL=LiveExtractor.js.map
|