@memextend/claude-code 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.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pre-compact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pre-compact.d.ts","sourceRoot":"","sources":["../../src/hooks/pre-compact.ts"],"names":[],"mappings":""}
@@ -0,0 +1,303 @@
1
+ // packages/adapters/claude-code/src/hooks/pre-compact.ts
2
+ // Copyright (c) 2026 ZodTTD LLC. MIT License.
3
+ //
4
+ // PreCompact hook - Captures memories BEFORE context compaction occurs.
5
+ // This is critical for preserving important information that would otherwise
6
+ // be lost when Claude summarizes the conversation context.
7
+ import { createHash, randomUUID } from 'crypto';
8
+ import { existsSync } from 'fs';
9
+ import { readFile } from 'fs/promises';
10
+ import { join, basename } from 'path';
11
+ import { homedir } from 'os';
12
+ import { execSync } from 'child_process';
13
+ import { SQLiteStorage, LanceDBStorage, TranscriptParser, formatCaptureContent, isTextCapture, isToolCapture, createEmbedFunction, cosineSimilarity } from '@memextend/core';
14
+ import { log, logError } from './logger.js';
15
+ const MEMEXTEND_DIR = join(homedir(), '.memextend');
16
+ const CONFIG_PATH = join(MEMEXTEND_DIR, 'config.json');
17
+ const DB_PATH = join(MEMEXTEND_DIR, 'memextend.db');
18
+ const VECTORS_PATH = join(MEMEXTEND_DIR, 'vectors');
19
+ const MODELS_PATH = join(MEMEXTEND_DIR, 'models');
20
+ // Track what we've already captured to avoid duplicates
21
+ const CAPTURE_STATE_PATH = join(MEMEXTEND_DIR, 'capture-state.json');
22
+ async function loadCaptureState() {
23
+ try {
24
+ if (existsSync(CAPTURE_STATE_PATH)) {
25
+ const content = await readFile(CAPTURE_STATE_PATH, 'utf-8');
26
+ return JSON.parse(content);
27
+ }
28
+ }
29
+ catch {
30
+ // Ignore errors
31
+ }
32
+ return {};
33
+ }
34
+ async function saveCaptureState(state) {
35
+ const { writeFile } = await import('fs/promises');
36
+ await writeFile(CAPTURE_STATE_PATH, JSON.stringify(state, null, 2));
37
+ }
38
+ async function main() {
39
+ // Read input from stdin
40
+ const chunks = [];
41
+ for await (const chunk of process.stdin) {
42
+ chunks.push(chunk);
43
+ }
44
+ const input = JSON.parse(Buffer.concat(chunks).toString());
45
+ log('PreCompact', `Hook fired - ${input.trigger.toUpperCase()} compaction`, {
46
+ trigger: input.trigger,
47
+ session_id: input.session_id,
48
+ cwd: input.cwd,
49
+ has_transcript: !!input.transcript_path
50
+ });
51
+ try {
52
+ // Check if memextend is initialized
53
+ if (!existsSync(DB_PATH)) {
54
+ log('PreCompact', 'DB not found, skipping');
55
+ outputResult({ continue: true, suppressOutput: true });
56
+ return;
57
+ }
58
+ // Check if transcript exists
59
+ if (!input.transcript_path || !existsSync(input.transcript_path)) {
60
+ log('PreCompact', 'No transcript path, skipping');
61
+ outputResult({ continue: true, suppressOutput: true });
62
+ return;
63
+ }
64
+ // Load config
65
+ const config = await loadConfig();
66
+ // Load capture state to track what we've already captured
67
+ const captureState = await loadCaptureState();
68
+ const sessionState = captureState[input.session_id] || {
69
+ lastCapturedLine: 0,
70
+ capturedIds: []
71
+ };
72
+ // Read and parse transcript
73
+ const transcriptContent = await readFile(input.transcript_path, 'utf-8');
74
+ const lines = transcriptContent.split('\n').filter(l => l.trim());
75
+ // Only process lines we haven't seen yet
76
+ const newLines = lines.slice(sessionState.lastCapturedLine);
77
+ if (newLines.length === 0) {
78
+ log('PreCompact', 'No new lines to process');
79
+ outputResult({ continue: true, suppressOutput: true });
80
+ return;
81
+ }
82
+ log('PreCompact', 'Processing transcript', {
83
+ totalLines: lines.length,
84
+ newLines: newLines.length,
85
+ lastCapturedLine: sessionState.lastCapturedLine
86
+ });
87
+ const newTranscript = newLines.join('\n');
88
+ // By default: capture reasoning only, all tool capture disabled
89
+ // Users can enable individual tools via config.capture.tools: { Edit: true, Write: true, ... }
90
+ const parser = new TranscriptParser({
91
+ toolConfig: config.capture?.tools ?? {},
92
+ maxReasoningLength: config.capture?.maxReasoningLength ?? 10000,
93
+ maxToolOutputLength: config.capture?.maxToolOutputLength ?? 2000,
94
+ captureReasoning: config.capture?.captureReasoning ?? true
95
+ });
96
+ const captures = parser.parse(newTranscript);
97
+ if (captures.length === 0) {
98
+ log('PreCompact', 'No captures found in new lines');
99
+ // Update state even if no captures
100
+ sessionState.lastCapturedLine = lines.length;
101
+ captureState[input.session_id] = sessionState;
102
+ await saveCaptureState(captureState);
103
+ outputResult({ continue: true, suppressOutput: true });
104
+ return;
105
+ }
106
+ const reasoningCount = captures.filter(isTextCapture).length;
107
+ const toolCount = captures.filter(isToolCapture).length;
108
+ log('PreCompact', `Found ${captures.length} captures to save`, { reasoning: reasoningCount, tools: toolCount });
109
+ // Get project ID
110
+ const projectId = getProjectId(input.cwd);
111
+ // Initialize storage
112
+ const sqlite = new SQLiteStorage(DB_PATH);
113
+ const lancedb = await LanceDBStorage.create(VECTORS_PATH);
114
+ // Ensure project is registered
115
+ const project = sqlite.getProject(projectId);
116
+ if (!project) {
117
+ sqlite.insertProject({
118
+ id: projectId,
119
+ name: basename(input.cwd),
120
+ path: input.cwd,
121
+ createdAt: new Date().toISOString()
122
+ });
123
+ }
124
+ // Create embedding function (uses real model if available, fallback otherwise)
125
+ const embedder = await createEmbedFunction(MODELS_PATH);
126
+ // Save each capture as a memory
127
+ let capturedCount = 0;
128
+ for (const capture of captures) {
129
+ const content = formatCaptureContent(capture);
130
+ // Create a hash to detect duplicates
131
+ const contentHash = createHash('sha256').update(content).digest('hex').slice(0, 16);
132
+ if (sessionState.capturedIds.includes(contentHash)) {
133
+ continue; // Skip duplicate
134
+ }
135
+ const memoryId = randomUUID();
136
+ let memory;
137
+ if (isTextCapture(capture)) {
138
+ memory = {
139
+ id: memoryId,
140
+ projectId,
141
+ content,
142
+ type: 'reasoning',
143
+ sourceTool: null,
144
+ createdAt: new Date().toISOString(),
145
+ sessionId: input.session_id,
146
+ metadata: {
147
+ capturedAt: input.trigger === 'auto' ? 'auto-compact' : 'manual-compact'
148
+ }
149
+ };
150
+ }
151
+ else {
152
+ memory = {
153
+ id: memoryId,
154
+ projectId,
155
+ content,
156
+ type: 'tool_capture',
157
+ sourceTool: capture.tool,
158
+ createdAt: new Date().toISOString(),
159
+ sessionId: input.session_id,
160
+ metadata: {
161
+ input: capture.input,
162
+ outputPreview: capture.output.slice(0, 200),
163
+ capturedAt: input.trigger === 'auto' ? 'auto-compact' : 'manual-compact'
164
+ }
165
+ };
166
+ }
167
+ // Store in SQLite
168
+ sqlite.insertMemory(memory);
169
+ // Generate and store embedding
170
+ const vector = await embedder.embed(content);
171
+ await lancedb.insertVector(memoryId, vector);
172
+ sessionState.capturedIds.push(contentHash);
173
+ capturedCount++;
174
+ }
175
+ // Deduplicate highly similar memories to save space
176
+ const dedupeOnPrune = config.storage?.deduplicateOnPrune ?? true;
177
+ const dedupeThreshold = config.retrieval?.deduplicationThreshold ?? 0.85;
178
+ if (dedupeOnPrune) {
179
+ const dedupedIds = await deduplicateStoredMemories(sqlite, lancedb, projectId, dedupeThreshold);
180
+ if (dedupedIds.length > 0) {
181
+ log('PreCompact', `Deduplicated ${dedupedIds.length} similar memories`);
182
+ }
183
+ }
184
+ // Prune old memories if storage limits are configured
185
+ const maxPerProject = config.storage?.maxMemoriesPerProject ?? 500;
186
+ const maxTotal = config.storage?.maxTotalMemories ?? 5000;
187
+ if (maxPerProject > 0 || maxTotal > 0) {
188
+ const pruneResult = sqlite.pruneMemories({
189
+ maxPerProject,
190
+ maxTotal,
191
+ projectId
192
+ });
193
+ if (pruneResult.deleted > 0) {
194
+ log('PreCompact', `Pruned ${pruneResult.deleted} old memories to stay within limits`);
195
+ // Also delete from vector store
196
+ for (const id of pruneResult.deletedIds) {
197
+ await lancedb.deleteVector(id);
198
+ }
199
+ }
200
+ }
201
+ // Update capture state
202
+ sessionState.lastCapturedLine = lines.length;
203
+ captureState[input.session_id] = sessionState;
204
+ await saveCaptureState(captureState);
205
+ // Close storage and embedder
206
+ sqlite.close();
207
+ await lancedb.close();
208
+ await embedder.close();
209
+ // Log for debugging
210
+ if (capturedCount > 0) {
211
+ log('PreCompact', `SUCCESS: Captured ${capturedCount} memories before ${input.trigger} compaction`, {
212
+ capturedCount,
213
+ trigger: input.trigger
214
+ });
215
+ console.error(`[memextend] PreCompact: Captured ${capturedCount} memories before ${input.trigger} compaction`);
216
+ }
217
+ outputResult({ continue: true, suppressOutput: true });
218
+ }
219
+ catch (error) {
220
+ logError('PreCompact', error);
221
+ console.error('[memextend] PreCompact hook error:', error);
222
+ outputResult({ continue: true, suppressOutput: true });
223
+ }
224
+ }
225
+ function getProjectId(cwd) {
226
+ try {
227
+ const gitRoot = execSync('git rev-parse --show-toplevel', {
228
+ cwd,
229
+ encoding: 'utf-8',
230
+ stdio: ['pipe', 'pipe', 'pipe']
231
+ }).trim();
232
+ return createHash('sha256').update(gitRoot).digest('hex').slice(0, 16);
233
+ }
234
+ catch {
235
+ return createHash('sha256').update(cwd).digest('hex').slice(0, 16);
236
+ }
237
+ }
238
+ async function loadConfig() {
239
+ try {
240
+ if (existsSync(CONFIG_PATH)) {
241
+ const content = await readFile(CONFIG_PATH, 'utf-8');
242
+ return JSON.parse(content);
243
+ }
244
+ }
245
+ catch {
246
+ // Ignore config errors
247
+ }
248
+ return {};
249
+ }
250
+ function outputResult(result) {
251
+ console.log(JSON.stringify(result));
252
+ }
253
+ /**
254
+ * Deduplicate stored memories by removing older ones that are highly similar to newer ones.
255
+ * Uses cosine similarity on embeddings. Keeps the newest memory when duplicates found.
256
+ */
257
+ async function deduplicateStoredMemories(sqlite, lancedb, projectId, threshold) {
258
+ const deletedIds = [];
259
+ // Get all memories for this project, sorted by date (newest first)
260
+ const memories = sqlite.getRecentMemories(projectId, 0, 0); // 0 = unlimited
261
+ if (memories.length < 2)
262
+ return deletedIds;
263
+ // Get vectors for all memories
264
+ const memoryIds = memories.map(m => m.id);
265
+ const vectors = await lancedb.getVectorsByIds(memoryIds);
266
+ if (vectors.size < 2)
267
+ return deletedIds;
268
+ // Track which memories to keep (newest first wins)
269
+ const keepIds = new Set();
270
+ const keptVectors = [];
271
+ for (const memory of memories) {
272
+ const vector = vectors.get(memory.id);
273
+ if (!vector) {
274
+ keepIds.add(memory.id); // Keep if no vector
275
+ continue;
276
+ }
277
+ // Check if this memory is too similar to any kept memory
278
+ let isDuplicate = false;
279
+ for (const kept of keptVectors) {
280
+ const similarity = cosineSimilarity(vector, kept.vector);
281
+ if (similarity > threshold) {
282
+ isDuplicate = true;
283
+ break;
284
+ }
285
+ }
286
+ if (!isDuplicate) {
287
+ keepIds.add(memory.id);
288
+ keptVectors.push({ id: memory.id, vector });
289
+ }
290
+ else {
291
+ // Delete this duplicate
292
+ sqlite.deleteMemory(memory.id);
293
+ await lancedb.deleteVector(memory.id);
294
+ deletedIds.push(memory.id);
295
+ }
296
+ }
297
+ return deletedIds;
298
+ }
299
+ main().catch(error => {
300
+ console.error('[memextend] Fatal error:', error);
301
+ process.exit(0);
302
+ });
303
+ //# sourceMappingURL=pre-compact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pre-compact.js","sourceRoot":"","sources":["../../src/hooks/pre-compact.ts"],"names":[],"mappings":"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"}