cckb 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 (39) hide show
  1. package/README.md +247 -0
  2. package/dist/bin/cckb.d.ts +1 -0
  3. package/dist/bin/cckb.js +89 -0
  4. package/dist/bin/cckb.js.map +1 -0
  5. package/dist/chunk-GUB5D6EN.js +197 -0
  6. package/dist/chunk-GUB5D6EN.js.map +1 -0
  7. package/dist/chunk-K4W3KOBL.js +239 -0
  8. package/dist/chunk-K4W3KOBL.js.map +1 -0
  9. package/dist/chunk-TFFLX3YY.js +131 -0
  10. package/dist/chunk-TFFLX3YY.js.map +1 -0
  11. package/dist/chunk-XAY6TTXB.js +149 -0
  12. package/dist/chunk-XAY6TTXB.js.map +1 -0
  13. package/dist/chunk-Z3CJQKTH.js +547 -0
  14. package/dist/chunk-Z3CJQKTH.js.map +1 -0
  15. package/dist/hooks/notification.d.ts +3 -0
  16. package/dist/hooks/notification.js +132 -0
  17. package/dist/hooks/notification.js.map +1 -0
  18. package/dist/hooks/post-tool-use.d.ts +3 -0
  19. package/dist/hooks/post-tool-use.js +96 -0
  20. package/dist/hooks/post-tool-use.js.map +1 -0
  21. package/dist/hooks/session-start.d.ts +3 -0
  22. package/dist/hooks/session-start.js +57 -0
  23. package/dist/hooks/session-start.js.map +1 -0
  24. package/dist/hooks/stop.d.ts +3 -0
  25. package/dist/hooks/stop.js +80 -0
  26. package/dist/hooks/stop.js.map +1 -0
  27. package/dist/hooks/user-prompt.d.ts +3 -0
  28. package/dist/hooks/user-prompt.js +48 -0
  29. package/dist/hooks/user-prompt.js.map +1 -0
  30. package/dist/index.d.ts +145 -0
  31. package/dist/index.js +24 -0
  32. package/dist/index.js.map +1 -0
  33. package/package.json +47 -0
  34. package/templates/CLAUDE.md.tmpl +29 -0
  35. package/templates/settings.json.tmpl +44 -0
  36. package/templates/vault/INDEX.md +19 -0
  37. package/templates/vault/architecture.md +15 -0
  38. package/templates/vault/entities/INDEX.md +10 -0
  39. package/templates/vault/general-knowledge.md +15 -0
@@ -0,0 +1,547 @@
1
+ import {
2
+ IndexManager
3
+ } from "./chunk-XAY6TTXB.js";
4
+ import {
5
+ appendToFile,
6
+ ensureDir,
7
+ fileExists,
8
+ getConversationsPath,
9
+ readTextFile,
10
+ writeTextFile
11
+ } from "./chunk-TFFLX3YY.js";
12
+
13
+ // src/core/compaction-engine.ts
14
+ import * as path from "path";
15
+
16
+ // src/utils/claude-sdk.ts
17
+ import { spawn } from "child_process";
18
+ async function spawnClaudeAgent(prompt) {
19
+ return new Promise((resolve, reject) => {
20
+ const child = spawn("claude", ["--print", "-p", prompt], {
21
+ stdio: ["pipe", "pipe", "pipe"],
22
+ timeout: 12e4
23
+ // 2 minute timeout
24
+ });
25
+ let stdout = "";
26
+ let stderr = "";
27
+ child.stdout?.on("data", (data) => {
28
+ stdout += data.toString();
29
+ });
30
+ child.stderr?.on("data", (data) => {
31
+ stderr += data.toString();
32
+ });
33
+ child.on("close", (code) => {
34
+ if (code === 0) {
35
+ resolve(stdout.trim());
36
+ } else {
37
+ reject(new Error(`Claude agent failed with code ${code}: ${stderr}`));
38
+ }
39
+ });
40
+ child.on("error", (error) => {
41
+ reject(error);
42
+ });
43
+ });
44
+ }
45
+
46
+ // src/core/compaction-engine.ts
47
+ var SUMMARIZATION_PROMPT = `You are a technical knowledge extractor. Analyze this conversation log and extract key information for a project knowledge base.
48
+
49
+ Extract and format the following:
50
+
51
+ ## Entities
52
+ For each domain entity (data model, type, class) created or modified:
53
+ - **Name**: Entity name
54
+ - **Location**: File path
55
+ - **Attributes**: Key fields/properties
56
+ - **Relations**: Related entities
57
+
58
+ ## Architecture
59
+ For each architectural pattern or design decision:
60
+ - **Pattern**: Name of pattern
61
+ - **Description**: Brief explanation
62
+ - **Affected Files**: Relevant file paths
63
+
64
+ ## Services
65
+ For each service or component created:
66
+ - **Name**: Service name
67
+ - **Location**: File path
68
+ - **Purpose**: Brief description
69
+ - **Methods**: Key methods/functions
70
+
71
+ ## Knowledge
72
+ For each convention, rule, or important context:
73
+ - **Topic**: What it's about
74
+ - **Details**: The actual information
75
+
76
+ Only include sections that have content. Be concise but complete.
77
+ Use file paths exactly as shown in the conversation.
78
+
79
+ CONVERSATION LOG:
80
+ `;
81
+ var CompactionEngine = class {
82
+ projectPath;
83
+ constructor(projectPath) {
84
+ this.projectPath = projectPath;
85
+ }
86
+ async compact(sessionId, conversation) {
87
+ try {
88
+ const summaryContent = await this.generateSummary(conversation);
89
+ if (!summaryContent) {
90
+ return null;
91
+ }
92
+ const summary = this.parseSummary(sessionId, summaryContent);
93
+ await this.writeSummary(sessionId, summaryContent);
94
+ return summary;
95
+ } catch (error) {
96
+ console.error("Compaction failed:", error);
97
+ return null;
98
+ }
99
+ }
100
+ async generateSummary(conversation) {
101
+ const prompt = SUMMARIZATION_PROMPT + conversation;
102
+ try {
103
+ const result = await spawnClaudeAgent(prompt);
104
+ return result;
105
+ } catch (error) {
106
+ return this.fallbackExtraction(conversation);
107
+ }
108
+ }
109
+ fallbackExtraction(conversation) {
110
+ const lines = conversation.split("\n");
111
+ const files = [];
112
+ const actions = [];
113
+ for (const line of lines) {
114
+ const fileMatch = line.match(/(?:Created|Modified|Edited).*?:\s*(.+\.(?:ts|js|tsx|jsx|md))/i);
115
+ if (fileMatch) {
116
+ files.push(fileMatch[1]);
117
+ }
118
+ if (line.includes("[TOOL:")) {
119
+ actions.push(line);
120
+ }
121
+ }
122
+ let summary = "# Session Summary\n\n";
123
+ if (files.length > 0) {
124
+ summary += "## Files Modified\n";
125
+ for (const file of [...new Set(files)]) {
126
+ summary += `- ${file}
127
+ `;
128
+ }
129
+ summary += "\n";
130
+ }
131
+ if (actions.length > 0) {
132
+ summary += "## Actions\n";
133
+ for (const action of actions.slice(0, 20)) {
134
+ summary += `- ${action}
135
+ `;
136
+ }
137
+ }
138
+ return summary;
139
+ }
140
+ parseSummary(sessionId, content) {
141
+ const summary = {
142
+ sessionId,
143
+ content,
144
+ entities: [],
145
+ architecture: [],
146
+ services: [],
147
+ knowledge: []
148
+ };
149
+ const entitiesMatch = content.match(/## Entities\n([\s\S]*?)(?=\n## |$)/);
150
+ if (entitiesMatch) {
151
+ summary.entities = this.parseEntities(entitiesMatch[1]);
152
+ }
153
+ const archMatch = content.match(/## Architecture\n([\s\S]*?)(?=\n## |$)/);
154
+ if (archMatch) {
155
+ summary.architecture = this.parseArchitecture(archMatch[1]);
156
+ }
157
+ const servicesMatch = content.match(/## Services\n([\s\S]*?)(?=\n## |$)/);
158
+ if (servicesMatch) {
159
+ summary.services = this.parseServices(servicesMatch[1]);
160
+ }
161
+ const knowledgeMatch = content.match(/## Knowledge\n([\s\S]*?)(?=\n## |$)/);
162
+ if (knowledgeMatch) {
163
+ summary.knowledge = this.parseKnowledge(knowledgeMatch[1]);
164
+ }
165
+ return summary;
166
+ }
167
+ parseEntities(section) {
168
+ const entities = [];
169
+ const blocks = section.split(/\n(?=- \*\*Name\*\*:)/);
170
+ for (const block of blocks) {
171
+ if (!block.trim()) continue;
172
+ const nameMatch = block.match(/\*\*Name\*\*:\s*(.+)/);
173
+ const locationMatch = block.match(/\*\*Location\*\*:\s*(.+)/);
174
+ const attributesMatch = block.match(/\*\*Attributes\*\*:\s*(.+)/);
175
+ const relationsMatch = block.match(/\*\*Relations\*\*:\s*(.+)/);
176
+ if (nameMatch) {
177
+ entities.push({
178
+ name: nameMatch[1].trim(),
179
+ location: locationMatch?.[1].trim(),
180
+ attributes: attributesMatch?.[1].split(",").map((a) => a.trim()) || [],
181
+ relations: relationsMatch?.[1].split(",").map((r) => r.trim()) || []
182
+ });
183
+ }
184
+ }
185
+ return entities;
186
+ }
187
+ parseArchitecture(section) {
188
+ const items = [];
189
+ const blocks = section.split(/\n(?=- \*\*Pattern\*\*:)/);
190
+ for (const block of blocks) {
191
+ if (!block.trim()) continue;
192
+ const patternMatch = block.match(/\*\*Pattern\*\*:\s*(.+)/);
193
+ const descMatch = block.match(/\*\*Description\*\*:\s*(.+)/);
194
+ const filesMatch = block.match(/\*\*Affected Files\*\*:\s*(.+)/);
195
+ if (patternMatch) {
196
+ items.push({
197
+ pattern: patternMatch[1].trim(),
198
+ description: descMatch?.[1].trim() || "",
199
+ affectedFiles: filesMatch?.[1].split(",").map((f) => f.trim()) || []
200
+ });
201
+ }
202
+ }
203
+ return items;
204
+ }
205
+ parseServices(section) {
206
+ const items = [];
207
+ const blocks = section.split(/\n(?=- \*\*Name\*\*:)/);
208
+ for (const block of blocks) {
209
+ if (!block.trim()) continue;
210
+ const nameMatch = block.match(/\*\*Name\*\*:\s*(.+)/);
211
+ const locationMatch = block.match(/\*\*Location\*\*:\s*(.+)/);
212
+ const purposeMatch = block.match(/\*\*Purpose\*\*:\s*(.+)/);
213
+ const methodsMatch = block.match(/\*\*Methods\*\*:\s*(.+)/);
214
+ if (nameMatch) {
215
+ items.push({
216
+ name: nameMatch[1].trim(),
217
+ location: locationMatch?.[1].trim(),
218
+ purpose: purposeMatch?.[1].trim() || "",
219
+ methods: methodsMatch?.[1].split(",").map((m) => m.trim()) || []
220
+ });
221
+ }
222
+ }
223
+ return items;
224
+ }
225
+ parseKnowledge(section) {
226
+ const items = [];
227
+ const blocks = section.split(/\n(?=- \*\*Topic\*\*:)/);
228
+ for (const block of blocks) {
229
+ if (!block.trim()) continue;
230
+ const topicMatch = block.match(/\*\*Topic\*\*:\s*(.+)/);
231
+ const detailsMatch = block.match(/\*\*Details\*\*:\s*(.+)/);
232
+ if (topicMatch) {
233
+ items.push({
234
+ topic: topicMatch[1].trim(),
235
+ details: detailsMatch?.[1].trim() || ""
236
+ });
237
+ }
238
+ }
239
+ return items;
240
+ }
241
+ async writeSummary(sessionId, content) {
242
+ const conversationsPath = getConversationsPath(this.projectPath);
243
+ const summaryPath = path.join(conversationsPath, sessionId, "summary.md");
244
+ const fullContent = `# Session Summary: ${sessionId}
245
+ Generated: ${(/* @__PURE__ */ new Date()).toISOString()}
246
+
247
+ ${content}
248
+ `;
249
+ await writeTextFile(summaryPath, fullContent);
250
+ }
251
+ };
252
+
253
+ // src/core/entity-detector.ts
254
+ var EntityDetector = class {
255
+ /**
256
+ * Analyzes a summary and determines what should be added to the vault.
257
+ */
258
+ detect(summary) {
259
+ const items = [];
260
+ for (const entity of summary.entities) {
261
+ items.push(this.createEntityItem(entity));
262
+ const relatedServices = summary.services.filter(
263
+ (s) => s.name.toLowerCase().includes(entity.name.toLowerCase()) || s.location?.toLowerCase().includes(entity.name.toLowerCase())
264
+ );
265
+ for (const service of relatedServices) {
266
+ items.push(this.createServiceItem(entity.name, service));
267
+ }
268
+ }
269
+ const processedServiceNames = /* @__PURE__ */ new Set();
270
+ for (const entity of summary.entities) {
271
+ for (const service of summary.services) {
272
+ if (service.name.toLowerCase().includes(entity.name.toLowerCase()) || service.location?.toLowerCase().includes(entity.name.toLowerCase())) {
273
+ processedServiceNames.add(service.name);
274
+ }
275
+ }
276
+ }
277
+ for (const service of summary.services) {
278
+ if (!processedServiceNames.has(service.name)) {
279
+ items.push(this.createStandaloneServiceItem(service));
280
+ }
281
+ }
282
+ for (const arch of summary.architecture) {
283
+ items.push(this.createArchitectureItem(arch));
284
+ }
285
+ for (const knowledge of summary.knowledge) {
286
+ items.push(this.createKnowledgeItem(knowledge));
287
+ }
288
+ return items;
289
+ }
290
+ createEntityItem(entity) {
291
+ const content = this.formatEntityContent(entity);
292
+ return {
293
+ type: "entity",
294
+ name: entity.name,
295
+ data: entity,
296
+ vaultPath: `entities/${entity.name.toLowerCase()}`,
297
+ content
298
+ };
299
+ }
300
+ createServiceItem(entityName, service) {
301
+ const content = this.formatServiceContent(service);
302
+ const serviceName = service.name.toLowerCase().replace(entityName.toLowerCase(), "").trim();
303
+ const fileName = serviceName || "service";
304
+ return {
305
+ type: "service",
306
+ name: service.name,
307
+ data: service,
308
+ vaultPath: `entities/${entityName.toLowerCase()}/services/${fileName}`,
309
+ content
310
+ };
311
+ }
312
+ createStandaloneServiceItem(service) {
313
+ const content = this.formatServiceContent(service);
314
+ return {
315
+ type: "service",
316
+ name: service.name,
317
+ data: service,
318
+ vaultPath: `services/${service.name.toLowerCase()}`,
319
+ content
320
+ };
321
+ }
322
+ createArchitectureItem(arch) {
323
+ const content = `## ${arch.pattern}
324
+
325
+ ${arch.description}
326
+
327
+ ### Affected Files
328
+ ${arch.affectedFiles.map((f) => `- ${f}`).join("\n")}
329
+ `;
330
+ return {
331
+ type: "pattern",
332
+ name: arch.pattern,
333
+ data: arch,
334
+ vaultPath: "architecture",
335
+ content
336
+ };
337
+ }
338
+ createKnowledgeItem(knowledge) {
339
+ const content = `## ${knowledge.topic}
340
+
341
+ ${knowledge.details}
342
+ `;
343
+ return {
344
+ type: "knowledge",
345
+ name: knowledge.topic,
346
+ data: knowledge,
347
+ vaultPath: "general-knowledge",
348
+ content
349
+ };
350
+ }
351
+ formatEntityContent(entity) {
352
+ let content = `# ${entity.name}
353
+
354
+ `;
355
+ if (entity.location) {
356
+ content += `**Location**: ${entity.location}
357
+
358
+ `;
359
+ }
360
+ if (entity.attributes.length > 0) {
361
+ content += `## Attributes
362
+
363
+ `;
364
+ for (const attr of entity.attributes) {
365
+ content += `- ${attr}
366
+ `;
367
+ }
368
+ content += "\n";
369
+ }
370
+ if (entity.relations.length > 0) {
371
+ content += `## Relations
372
+
373
+ `;
374
+ for (const rel of entity.relations) {
375
+ content += `- ${rel}
376
+ `;
377
+ }
378
+ content += "\n";
379
+ }
380
+ return content;
381
+ }
382
+ formatServiceContent(service) {
383
+ let content = `# ${service.name}
384
+
385
+ `;
386
+ if (service.location) {
387
+ content += `**Location**: ${service.location}
388
+
389
+ `;
390
+ }
391
+ if (service.purpose) {
392
+ content += `## Purpose
393
+
394
+ ${service.purpose}
395
+
396
+ `;
397
+ }
398
+ if (service.methods.length > 0) {
399
+ content += `## Methods
400
+
401
+ `;
402
+ for (const method of service.methods) {
403
+ content += `- ${method}
404
+ `;
405
+ }
406
+ content += "\n";
407
+ }
408
+ return content;
409
+ }
410
+ };
411
+
412
+ // src/core/vault-integrator.ts
413
+ import * as path2 from "path";
414
+ var VaultIntegrator = class {
415
+ vaultPath;
416
+ indexManager;
417
+ entityDetector;
418
+ constructor(vaultPath) {
419
+ this.vaultPath = vaultPath;
420
+ this.indexManager = new IndexManager(vaultPath);
421
+ this.entityDetector = new EntityDetector();
422
+ }
423
+ async integrate(summary) {
424
+ const items = this.entityDetector.detect(summary);
425
+ if (items.length === 0) {
426
+ return;
427
+ }
428
+ for (const item of items) {
429
+ await this.processItem(item);
430
+ }
431
+ await this.updateRootIndex();
432
+ }
433
+ async processItem(item) {
434
+ switch (item.type) {
435
+ case "entity":
436
+ await this.processEntity(item);
437
+ break;
438
+ case "service":
439
+ await this.processService(item);
440
+ break;
441
+ case "pattern":
442
+ await this.processPattern(item);
443
+ break;
444
+ case "knowledge":
445
+ await this.processKnowledge(item);
446
+ break;
447
+ }
448
+ }
449
+ async processEntity(item) {
450
+ const entityPath = await this.indexManager.ensureEntityFolder(item.name);
451
+ const fullPath = path2.join(this.vaultPath, entityPath);
452
+ const attributesPath = path2.join(fullPath, "attributes.md");
453
+ await writeTextFile(attributesPath, item.content);
454
+ await this.indexManager.addEntry(entityPath, {
455
+ name: "attributes",
456
+ path: "./attributes.md",
457
+ description: `Attributes of ${item.name}`,
458
+ type: "file"
459
+ });
460
+ }
461
+ async processService(item) {
462
+ const pathParts = item.vaultPath.split("/");
463
+ const fileName = pathParts.pop() + ".md";
464
+ const folderPath = pathParts.join("/");
465
+ const fullFolderPath = path2.join(this.vaultPath, folderPath);
466
+ await ensureDir(fullFolderPath);
467
+ const filePath = path2.join(fullFolderPath, fileName);
468
+ await writeTextFile(filePath, item.content);
469
+ const parentIndexPath = path2.join(fullFolderPath, "INDEX.md");
470
+ if (!await fileExists(parentIndexPath)) {
471
+ await this.indexManager.createIndex(folderPath, []);
472
+ }
473
+ await this.indexManager.addEntry(folderPath, {
474
+ name: item.name,
475
+ path: `./${fileName}`,
476
+ description: item.data.purpose || `${item.name} service`,
477
+ type: "file"
478
+ });
479
+ if (folderPath.startsWith("entities/") && folderPath.includes("/services")) {
480
+ const entityFolder = folderPath.split("/").slice(0, 2).join("/");
481
+ await this.indexManager.addEntry(entityFolder, {
482
+ name: "services",
483
+ path: "./services/INDEX.md",
484
+ description: "Service layer documentation",
485
+ type: "folder"
486
+ });
487
+ }
488
+ }
489
+ async processPattern(item) {
490
+ const archPath = path2.join(this.vaultPath, "architecture.md");
491
+ const existing = await readTextFile(archPath);
492
+ if (!existing) {
493
+ await writeTextFile(archPath, `# Architecture
494
+
495
+ ${item.content}`);
496
+ return;
497
+ }
498
+ if (existing.includes(`## ${item.name}`)) {
499
+ const regex = new RegExp(`## ${item.name}[\\s\\S]*?(?=\\n## |$)`);
500
+ const updated = existing.replace(regex, item.content);
501
+ await writeTextFile(archPath, updated);
502
+ } else {
503
+ await appendToFile(archPath, `
504
+ ${item.content}`);
505
+ }
506
+ }
507
+ async processKnowledge(item) {
508
+ const knowledgePath = path2.join(this.vaultPath, "general-knowledge.md");
509
+ const existing = await readTextFile(knowledgePath);
510
+ if (!existing) {
511
+ await writeTextFile(knowledgePath, `# General Knowledge
512
+
513
+ ${item.content}`);
514
+ return;
515
+ }
516
+ if (existing.includes(`## ${item.name}`)) {
517
+ const regex = new RegExp(`## ${item.name}[\\s\\S]*?(?=\\n## |$)`);
518
+ const updated = existing.replace(regex, item.content);
519
+ await writeTextFile(knowledgePath, updated);
520
+ } else {
521
+ await appendToFile(knowledgePath, `
522
+ ${item.content}`);
523
+ }
524
+ }
525
+ async updateRootIndex() {
526
+ const indexPath = path2.join(this.vaultPath, "INDEX.md");
527
+ const content = await readTextFile(indexPath);
528
+ if (!content) {
529
+ return;
530
+ }
531
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
532
+ const updated = content.replace(
533
+ /## Last Updated[\s\S]*$/,
534
+ `## Last Updated
535
+
536
+ ${timestamp}`
537
+ );
538
+ await writeTextFile(indexPath, updated);
539
+ }
540
+ };
541
+
542
+ export {
543
+ CompactionEngine,
544
+ EntityDetector,
545
+ VaultIntegrator
546
+ };
547
+ //# sourceMappingURL=chunk-Z3CJQKTH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/compaction-engine.ts","../src/utils/claude-sdk.ts","../src/core/entity-detector.ts","../src/core/vault-integrator.ts"],"sourcesContent":["import * as path from \"node:path\";\nimport { writeTextFile } from \"../utils/file-utils.js\";\nimport { getConversationsPath } from \"../utils/config.js\";\nimport { spawnClaudeAgent } from \"../utils/claude-sdk.js\";\n\nconst SUMMARIZATION_PROMPT = `You are a technical knowledge extractor. Analyze this conversation log and extract key information for a project knowledge base.\n\nExtract and format the following:\n\n## Entities\nFor each domain entity (data model, type, class) created or modified:\n- **Name**: Entity name\n- **Location**: File path\n- **Attributes**: Key fields/properties\n- **Relations**: Related entities\n\n## Architecture\nFor each architectural pattern or design decision:\n- **Pattern**: Name of pattern\n- **Description**: Brief explanation\n- **Affected Files**: Relevant file paths\n\n## Services\nFor each service or component created:\n- **Name**: Service name\n- **Location**: File path\n- **Purpose**: Brief description\n- **Methods**: Key methods/functions\n\n## Knowledge\nFor each convention, rule, or important context:\n- **Topic**: What it's about\n- **Details**: The actual information\n\nOnly include sections that have content. Be concise but complete.\nUse file paths exactly as shown in the conversation.\n\nCONVERSATION LOG:\n`;\n\nexport interface Summary {\n sessionId: string;\n content: string;\n entities: ExtractedEntity[];\n architecture: ArchitectureItem[];\n services: ServiceItem[];\n knowledge: KnowledgeItem[];\n}\n\nexport interface ExtractedEntity {\n name: string;\n location?: string;\n attributes: string[];\n relations: string[];\n}\n\nexport interface ArchitectureItem {\n pattern: string;\n description: string;\n affectedFiles: string[];\n}\n\nexport interface ServiceItem {\n name: string;\n location?: string;\n purpose: string;\n methods: string[];\n}\n\nexport interface KnowledgeItem {\n topic: string;\n details: string;\n}\n\nexport class CompactionEngine {\n private projectPath: string;\n\n constructor(projectPath: string) {\n this.projectPath = projectPath;\n }\n\n async compact(sessionId: string, conversation: string): Promise<Summary | null> {\n try {\n // Use Claude SDK to generate summary\n const summaryContent = await this.generateSummary(conversation);\n\n if (!summaryContent) {\n return null;\n }\n\n // Parse the summary to extract structured data\n const summary = this.parseSummary(sessionId, summaryContent);\n\n // Write summary to conversation folder\n await this.writeSummary(sessionId, summaryContent);\n\n return summary;\n } catch (error) {\n console.error(\"Compaction failed:\", error);\n return null;\n }\n }\n\n private async generateSummary(conversation: string): Promise<string | null> {\n const prompt = SUMMARIZATION_PROMPT + conversation;\n\n try {\n const result = await spawnClaudeAgent(prompt);\n return result;\n } catch (error) {\n // Fallback to basic extraction if Claude SDK fails\n return this.fallbackExtraction(conversation);\n }\n }\n\n private fallbackExtraction(conversation: string): string {\n // Basic extraction without AI - just capture file paths and actions\n const lines = conversation.split(\"\\n\");\n const files: string[] = [];\n const actions: string[] = [];\n\n for (const line of lines) {\n // Extract file paths\n const fileMatch = line.match(/(?:Created|Modified|Edited).*?:\\s*(.+\\.(?:ts|js|tsx|jsx|md))/i);\n if (fileMatch) {\n files.push(fileMatch[1]);\n }\n\n // Extract tool actions\n if (line.includes(\"[TOOL:\")) {\n actions.push(line);\n }\n }\n\n let summary = \"# Session Summary\\n\\n\";\n\n if (files.length > 0) {\n summary += \"## Files Modified\\n\";\n for (const file of [...new Set(files)]) {\n summary += `- ${file}\\n`;\n }\n summary += \"\\n\";\n }\n\n if (actions.length > 0) {\n summary += \"## Actions\\n\";\n for (const action of actions.slice(0, 20)) {\n summary += `- ${action}\\n`;\n }\n }\n\n return summary;\n }\n\n private parseSummary(sessionId: string, content: string): Summary {\n const summary: Summary = {\n sessionId,\n content,\n entities: [],\n architecture: [],\n services: [],\n knowledge: [],\n };\n\n // Parse entities section\n const entitiesMatch = content.match(/## Entities\\n([\\s\\S]*?)(?=\\n## |$)/);\n if (entitiesMatch) {\n summary.entities = this.parseEntities(entitiesMatch[1]);\n }\n\n // Parse architecture section\n const archMatch = content.match(/## Architecture\\n([\\s\\S]*?)(?=\\n## |$)/);\n if (archMatch) {\n summary.architecture = this.parseArchitecture(archMatch[1]);\n }\n\n // Parse services section\n const servicesMatch = content.match(/## Services\\n([\\s\\S]*?)(?=\\n## |$)/);\n if (servicesMatch) {\n summary.services = this.parseServices(servicesMatch[1]);\n }\n\n // Parse knowledge section\n const knowledgeMatch = content.match(/## Knowledge\\n([\\s\\S]*?)(?=\\n## |$)/);\n if (knowledgeMatch) {\n summary.knowledge = this.parseKnowledge(knowledgeMatch[1]);\n }\n\n return summary;\n }\n\n private parseEntities(section: string): ExtractedEntity[] {\n const entities: ExtractedEntity[] = [];\n const blocks = section.split(/\\n(?=- \\*\\*Name\\*\\*:)/);\n\n for (const block of blocks) {\n if (!block.trim()) continue;\n\n const nameMatch = block.match(/\\*\\*Name\\*\\*:\\s*(.+)/);\n const locationMatch = block.match(/\\*\\*Location\\*\\*:\\s*(.+)/);\n const attributesMatch = block.match(/\\*\\*Attributes\\*\\*:\\s*(.+)/);\n const relationsMatch = block.match(/\\*\\*Relations\\*\\*:\\s*(.+)/);\n\n if (nameMatch) {\n entities.push({\n name: nameMatch[1].trim(),\n location: locationMatch?.[1].trim(),\n attributes: attributesMatch?.[1].split(\",\").map((a) => a.trim()) || [],\n relations: relationsMatch?.[1].split(\",\").map((r) => r.trim()) || [],\n });\n }\n }\n\n return entities;\n }\n\n private parseArchitecture(section: string): ArchitectureItem[] {\n const items: ArchitectureItem[] = [];\n const blocks = section.split(/\\n(?=- \\*\\*Pattern\\*\\*:)/);\n\n for (const block of blocks) {\n if (!block.trim()) continue;\n\n const patternMatch = block.match(/\\*\\*Pattern\\*\\*:\\s*(.+)/);\n const descMatch = block.match(/\\*\\*Description\\*\\*:\\s*(.+)/);\n const filesMatch = block.match(/\\*\\*Affected Files\\*\\*:\\s*(.+)/);\n\n if (patternMatch) {\n items.push({\n pattern: patternMatch[1].trim(),\n description: descMatch?.[1].trim() || \"\",\n affectedFiles: filesMatch?.[1].split(\",\").map((f) => f.trim()) || [],\n });\n }\n }\n\n return items;\n }\n\n private parseServices(section: string): ServiceItem[] {\n const items: ServiceItem[] = [];\n const blocks = section.split(/\\n(?=- \\*\\*Name\\*\\*:)/);\n\n for (const block of blocks) {\n if (!block.trim()) continue;\n\n const nameMatch = block.match(/\\*\\*Name\\*\\*:\\s*(.+)/);\n const locationMatch = block.match(/\\*\\*Location\\*\\*:\\s*(.+)/);\n const purposeMatch = block.match(/\\*\\*Purpose\\*\\*:\\s*(.+)/);\n const methodsMatch = block.match(/\\*\\*Methods\\*\\*:\\s*(.+)/);\n\n if (nameMatch) {\n items.push({\n name: nameMatch[1].trim(),\n location: locationMatch?.[1].trim(),\n purpose: purposeMatch?.[1].trim() || \"\",\n methods: methodsMatch?.[1].split(\",\").map((m) => m.trim()) || [],\n });\n }\n }\n\n return items;\n }\n\n private parseKnowledge(section: string): KnowledgeItem[] {\n const items: KnowledgeItem[] = [];\n const blocks = section.split(/\\n(?=- \\*\\*Topic\\*\\*:)/);\n\n for (const block of blocks) {\n if (!block.trim()) continue;\n\n const topicMatch = block.match(/\\*\\*Topic\\*\\*:\\s*(.+)/);\n const detailsMatch = block.match(/\\*\\*Details\\*\\*:\\s*(.+)/);\n\n if (topicMatch) {\n items.push({\n topic: topicMatch[1].trim(),\n details: detailsMatch?.[1].trim() || \"\",\n });\n }\n }\n\n return items;\n }\n\n private async writeSummary(sessionId: string, content: string): Promise<void> {\n const conversationsPath = getConversationsPath(this.projectPath);\n const summaryPath = path.join(conversationsPath, sessionId, \"summary.md\");\n\n const fullContent = `# Session Summary: ${sessionId}\nGenerated: ${new Date().toISOString()}\n\n${content}\n`;\n\n await writeTextFile(summaryPath, fullContent);\n }\n}\n","import { spawn } from \"node:child_process\";\n\n/**\n * Spawns a Claude Code subagent to process a prompt.\n * Uses the Claude Code CLI with the --print flag to get output.\n */\nexport async function spawnClaudeAgent(prompt: string): Promise<string> {\n return new Promise((resolve, reject) => {\n // Use claude CLI with --print to get output without interactive mode\n const child = spawn(\"claude\", [\"--print\", \"-p\", prompt], {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n timeout: 120000, // 2 minute timeout\n });\n\n let stdout = \"\";\n let stderr = \"\";\n\n child.stdout?.on(\"data\", (data) => {\n stdout += data.toString();\n });\n\n child.stderr?.on(\"data\", (data) => {\n stderr += data.toString();\n });\n\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve(stdout.trim());\n } else {\n reject(new Error(`Claude agent failed with code ${code}: ${stderr}`));\n }\n });\n\n child.on(\"error\", (error) => {\n reject(error);\n });\n });\n}\n\n/**\n * Checks if Claude CLI is available.\n */\nexport async function isClaudeAvailable(): Promise<boolean> {\n return new Promise((resolve) => {\n const child = spawn(\"claude\", [\"--version\"], {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n\n child.on(\"close\", (code) => {\n resolve(code === 0);\n });\n\n child.on(\"error\", () => {\n resolve(false);\n });\n });\n}\n","import type { Summary, ExtractedEntity, ServiceItem } from \"./compaction-engine.js\";\n\nexport interface DetectedItem {\n type: \"entity\" | \"service\" | \"pattern\" | \"knowledge\";\n name: string;\n data: unknown;\n vaultPath: string;\n content: string;\n}\n\nexport class EntityDetector {\n /**\n * Analyzes a summary and determines what should be added to the vault.\n */\n detect(summary: Summary): DetectedItem[] {\n const items: DetectedItem[] = [];\n\n // Detect entities\n for (const entity of summary.entities) {\n items.push(this.createEntityItem(entity));\n\n // Also create service entries for entity-related services\n const relatedServices = summary.services.filter(\n (s) =>\n s.name.toLowerCase().includes(entity.name.toLowerCase()) ||\n s.location?.toLowerCase().includes(entity.name.toLowerCase())\n );\n\n for (const service of relatedServices) {\n items.push(this.createServiceItem(entity.name, service));\n }\n }\n\n // Detect standalone services\n const processedServiceNames = new Set<string>();\n for (const entity of summary.entities) {\n for (const service of summary.services) {\n if (\n service.name.toLowerCase().includes(entity.name.toLowerCase()) ||\n service.location?.toLowerCase().includes(entity.name.toLowerCase())\n ) {\n processedServiceNames.add(service.name);\n }\n }\n }\n\n for (const service of summary.services) {\n if (!processedServiceNames.has(service.name)) {\n items.push(this.createStandaloneServiceItem(service));\n }\n }\n\n // Detect architecture patterns\n for (const arch of summary.architecture) {\n items.push(this.createArchitectureItem(arch));\n }\n\n // Detect general knowledge\n for (const knowledge of summary.knowledge) {\n items.push(this.createKnowledgeItem(knowledge));\n }\n\n return items;\n }\n\n private createEntityItem(entity: ExtractedEntity): DetectedItem {\n const content = this.formatEntityContent(entity);\n\n return {\n type: \"entity\",\n name: entity.name,\n data: entity,\n vaultPath: `entities/${entity.name.toLowerCase()}`,\n content,\n };\n }\n\n private createServiceItem(\n entityName: string,\n service: ServiceItem\n ): DetectedItem {\n const content = this.formatServiceContent(service);\n const serviceName = service.name.toLowerCase().replace(entityName.toLowerCase(), \"\").trim();\n const fileName = serviceName || \"service\";\n\n return {\n type: \"service\",\n name: service.name,\n data: service,\n vaultPath: `entities/${entityName.toLowerCase()}/services/${fileName}`,\n content,\n };\n }\n\n private createStandaloneServiceItem(service: ServiceItem): DetectedItem {\n const content = this.formatServiceContent(service);\n\n return {\n type: \"service\",\n name: service.name,\n data: service,\n vaultPath: `services/${service.name.toLowerCase()}`,\n content,\n };\n }\n\n private createArchitectureItem(arch: {\n pattern: string;\n description: string;\n affectedFiles: string[];\n }): DetectedItem {\n const content = `## ${arch.pattern}\n\n${arch.description}\n\n### Affected Files\n${arch.affectedFiles.map((f) => `- ${f}`).join(\"\\n\")}\n`;\n\n return {\n type: \"pattern\",\n name: arch.pattern,\n data: arch,\n vaultPath: \"architecture\",\n content,\n };\n }\n\n private createKnowledgeItem(knowledge: {\n topic: string;\n details: string;\n }): DetectedItem {\n const content = `## ${knowledge.topic}\n\n${knowledge.details}\n`;\n\n return {\n type: \"knowledge\",\n name: knowledge.topic,\n data: knowledge,\n vaultPath: \"general-knowledge\",\n content,\n };\n }\n\n private formatEntityContent(entity: ExtractedEntity): string {\n let content = `# ${entity.name}\\n\\n`;\n\n if (entity.location) {\n content += `**Location**: ${entity.location}\\n\\n`;\n }\n\n if (entity.attributes.length > 0) {\n content += `## Attributes\\n\\n`;\n for (const attr of entity.attributes) {\n content += `- ${attr}\\n`;\n }\n content += \"\\n\";\n }\n\n if (entity.relations.length > 0) {\n content += `## Relations\\n\\n`;\n for (const rel of entity.relations) {\n content += `- ${rel}\\n`;\n }\n content += \"\\n\";\n }\n\n return content;\n }\n\n private formatServiceContent(service: ServiceItem): string {\n let content = `# ${service.name}\\n\\n`;\n\n if (service.location) {\n content += `**Location**: ${service.location}\\n\\n`;\n }\n\n if (service.purpose) {\n content += `## Purpose\\n\\n${service.purpose}\\n\\n`;\n }\n\n if (service.methods.length > 0) {\n content += `## Methods\\n\\n`;\n for (const method of service.methods) {\n content += `- ${method}\\n`;\n }\n content += \"\\n\";\n }\n\n return content;\n }\n}\n","import * as path from \"node:path\";\nimport {\n readTextFile,\n writeTextFile,\n appendToFile,\n ensureDir,\n fileExists,\n} from \"../utils/file-utils.js\";\nimport { IndexManager } from \"./index-manager.js\";\nimport { EntityDetector, type DetectedItem } from \"./entity-detector.js\";\nimport type { Summary } from \"./compaction-engine.js\";\n\nexport class VaultIntegrator {\n private vaultPath: string;\n private indexManager: IndexManager;\n private entityDetector: EntityDetector;\n\n constructor(vaultPath: string) {\n this.vaultPath = vaultPath;\n this.indexManager = new IndexManager(vaultPath);\n this.entityDetector = new EntityDetector();\n }\n\n async integrate(summary: Summary): Promise<void> {\n // Detect items from summary\n const items = this.entityDetector.detect(summary);\n\n if (items.length === 0) {\n return;\n }\n\n // Process each detected item\n for (const item of items) {\n await this.processItem(item);\n }\n\n // Update root INDEX.md with timestamp\n await this.updateRootIndex();\n }\n\n private async processItem(item: DetectedItem): Promise<void> {\n switch (item.type) {\n case \"entity\":\n await this.processEntity(item);\n break;\n case \"service\":\n await this.processService(item);\n break;\n case \"pattern\":\n await this.processPattern(item);\n break;\n case \"knowledge\":\n await this.processKnowledge(item);\n break;\n }\n }\n\n private async processEntity(item: DetectedItem): Promise<void> {\n const entityPath = await this.indexManager.ensureEntityFolder(item.name);\n const fullPath = path.join(this.vaultPath, entityPath);\n\n // Write attributes.md\n const attributesPath = path.join(fullPath, \"attributes.md\");\n await writeTextFile(attributesPath, item.content);\n\n // Update entity INDEX.md\n await this.indexManager.addEntry(entityPath, {\n name: \"attributes\",\n path: \"./attributes.md\",\n description: `Attributes of ${item.name}`,\n type: \"file\",\n });\n }\n\n private async processService(item: DetectedItem): Promise<void> {\n const pathParts = item.vaultPath.split(\"/\");\n const fileName = pathParts.pop() + \".md\";\n const folderPath = pathParts.join(\"/\");\n const fullFolderPath = path.join(this.vaultPath, folderPath);\n\n await ensureDir(fullFolderPath);\n\n // Write service file\n const filePath = path.join(fullFolderPath, fileName);\n await writeTextFile(filePath, item.content);\n\n // Ensure parent has INDEX.md\n const parentIndexPath = path.join(fullFolderPath, \"INDEX.md\");\n if (!(await fileExists(parentIndexPath))) {\n await this.indexManager.createIndex(folderPath, []);\n }\n\n // Update parent INDEX.md\n await this.indexManager.addEntry(folderPath, {\n name: item.name,\n path: `./${fileName}`,\n description: (item.data as { purpose?: string }).purpose || `${item.name} service`,\n type: \"file\",\n });\n\n // Update entity INDEX if this is an entity service\n if (folderPath.startsWith(\"entities/\") && folderPath.includes(\"/services\")) {\n const entityFolder = folderPath.split(\"/\").slice(0, 2).join(\"/\");\n await this.indexManager.addEntry(entityFolder, {\n name: \"services\",\n path: \"./services/INDEX.md\",\n description: \"Service layer documentation\",\n type: \"folder\",\n });\n }\n }\n\n private async processPattern(item: DetectedItem): Promise<void> {\n const archPath = path.join(this.vaultPath, \"architecture.md\");\n const existing = await readTextFile(archPath);\n\n if (!existing) {\n await writeTextFile(archPath, `# Architecture\\n\\n${item.content}`);\n return;\n }\n\n // Check if pattern already exists\n if (existing.includes(`## ${item.name}`)) {\n // Replace existing section\n const regex = new RegExp(`## ${item.name}[\\\\s\\\\S]*?(?=\\\\n## |$)`);\n const updated = existing.replace(regex, item.content);\n await writeTextFile(archPath, updated);\n } else {\n // Append new pattern\n await appendToFile(archPath, `\\n${item.content}`);\n }\n }\n\n private async processKnowledge(item: DetectedItem): Promise<void> {\n const knowledgePath = path.join(this.vaultPath, \"general-knowledge.md\");\n const existing = await readTextFile(knowledgePath);\n\n if (!existing) {\n await writeTextFile(knowledgePath, `# General Knowledge\\n\\n${item.content}`);\n return;\n }\n\n // Check if topic already exists\n if (existing.includes(`## ${item.name}`)) {\n // Replace existing section\n const regex = new RegExp(`## ${item.name}[\\\\s\\\\S]*?(?=\\\\n## |$)`);\n const updated = existing.replace(regex, item.content);\n await writeTextFile(knowledgePath, updated);\n } else {\n // Append new knowledge\n await appendToFile(knowledgePath, `\\n${item.content}`);\n }\n }\n\n private async updateRootIndex(): Promise<void> {\n const indexPath = path.join(this.vaultPath, \"INDEX.md\");\n const content = await readTextFile(indexPath);\n\n if (!content) {\n return;\n }\n\n // Update the \"Last Updated\" line\n const timestamp = new Date().toISOString();\n const updated = content.replace(\n /## Last Updated[\\s\\S]*$/,\n `## Last Updated\\n\\n${timestamp}`\n );\n\n await writeTextFile(indexPath, updated);\n }\n}\n"],"mappings":"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","names":["path"]}
@@ -0,0 +1,3 @@
1
+ declare function handleNotification(): Promise<void>;
2
+
3
+ export { handleNotification };