cckb 0.1.10 → 0.1.11

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/dist/bin/cckb.js CHANGED
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  discover,
4
4
  install
5
- } from "../chunk-OVZRLGW3.js";
6
- import "../chunk-C4DKNWDW.js";
5
+ } from "../chunk-W7IAOG27.js";
6
+ import "../chunk-6P6BBEGR.js";
7
7
  import "../chunk-NEHPNFRM.js";
8
8
  import "../chunk-I4GLPRZ2.js";
9
9
 
@@ -321,9 +321,17 @@ function spawnClaudeAgentWithHandle(prompt, options) {
321
321
  console.error(`[Claude SDK] [${elapsed}s] ${event.type}: ${event.message}`);
322
322
  }
323
323
  };
324
- const child = spawn("claude", ["--print", "-p", prompt], {
324
+ const child = spawn("claude", ["--print"], {
325
325
  stdio: ["pipe", "pipe", "pipe"]
326
326
  });
327
+ if (child.stdin) {
328
+ child.stdin.write(prompt);
329
+ child.stdin.end();
330
+ }
331
+ const promptPreview = prompt.length > 200 ? prompt.substring(0, 200) + "..." : prompt;
332
+ console.error(`[Claude SDK] Spawning: claude --print (prompt via stdin)`);
333
+ console.error(`[Claude SDK] Prompt length: ${prompt.length} chars`);
334
+ console.error(`[Claude SDK] Prompt preview: ${promptPreview.replace(/\n/g, "\\n")}`);
327
335
  emit({ type: "started", message: `Claude process spawned (PID: ${child.pid})` });
328
336
  const heartbeatInterval = setInterval(() => {
329
337
  if (!timedOut && !aborted) {
@@ -426,4 +434,4 @@ export {
426
434
  spawnClaudeAgent,
427
435
  isClaudeAvailable
428
436
  };
429
- //# sourceMappingURL=chunk-C4DKNWDW.js.map
437
+ //# sourceMappingURL=chunk-6P6BBEGR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/entity-detector.ts","../src/core/vault-integrator.ts","../src/utils/claude-sdk.ts"],"sourcesContent":["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","import { spawn, type ChildProcess } from \"node:child_process\";\n\nexport interface ClaudeAgentOptions {\n timeout?: number; // milliseconds, default 5 minutes\n onProgress?: (event: ProgressEvent) => void; // Progress callback\n onStderr?: (data: string) => void; // Real-time stderr streaming\n verbose?: boolean; // Log all activity to stderr\n}\n\nexport interface ProgressEvent {\n type: \"started\" | \"activity\" | \"stdout\" | \"stderr\" | \"heartbeat\" | \"complete\" | \"error\";\n message: string;\n timestamp: number;\n elapsed?: number; // ms since start\n bytesReceived?: number; // total bytes received so far\n}\n\nexport interface ClaudeAgentHandle {\n promise: Promise<string>;\n process: ChildProcess;\n abort: () => void;\n}\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 *\n * Returns a handle with:\n * - promise: The result promise\n * - process: The child process (for advanced control)\n * - abort: Function to cancel the operation\n */\nexport function spawnClaudeAgentWithHandle(\n prompt: string,\n options?: ClaudeAgentOptions\n): ClaudeAgentHandle {\n const timeout = options?.timeout ?? 300000; // 5 minutes default\n const startTime = Date.now();\n let totalBytesReceived = 0;\n let lastActivityTime = startTime;\n let timedOut = false;\n let aborted = false;\n\n const emit = (event: Omit<ProgressEvent, \"timestamp\" | \"elapsed\">) => {\n if (options?.onProgress) {\n options.onProgress({\n ...event,\n timestamp: Date.now(),\n elapsed: Date.now() - startTime,\n bytesReceived: totalBytesReceived,\n });\n }\n if (options?.verbose) {\n const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);\n console.error(`[Claude SDK] [${elapsed}s] ${event.type}: ${event.message}`);\n }\n };\n\n // Use claude CLI with --print flag, sending prompt via stdin\n // Note: Passing prompt as argument doesn't work - Claude expects stdin input\n const child = spawn(\"claude\", [\"--print\"], {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n\n // Send prompt via stdin (this is how Claude CLI expects input)\n if (child.stdin) {\n child.stdin.write(prompt);\n child.stdin.end();\n }\n\n // Log the command being executed for debugging\n const promptPreview = prompt.length > 200 ? prompt.substring(0, 200) + \"...\" : prompt;\n console.error(`[Claude SDK] Spawning: claude --print (prompt via stdin)`);\n console.error(`[Claude SDK] Prompt length: ${prompt.length} chars`);\n console.error(`[Claude SDK] Prompt preview: ${promptPreview.replace(/\\n/g, \"\\\\n\")}`);\n\n emit({ type: \"started\", message: `Claude process spawned (PID: ${child.pid})` });\n\n // Heartbeat interval - shows we're still alive even with no output\n const heartbeatInterval = setInterval(() => {\n if (!timedOut && !aborted) {\n const silentFor = Date.now() - lastActivityTime;\n emit({\n type: \"heartbeat\",\n message: `Waiting for response... (silent for ${(silentFor / 1000).toFixed(0)}s)`\n });\n }\n }, 10000); // Every 10 seconds\n\n const promise = new Promise<string>((resolve, reject) => {\n let stdout = \"\";\n let stderr = \"\";\n\n // Manual timeout since spawn timeout doesn't always work\n const timeoutId = setTimeout(() => {\n timedOut = true;\n child.kill(\"SIGTERM\");\n emit({ type: \"error\", message: `Timed out after ${timeout / 1000}s` });\n reject(new Error(`Claude agent timed out after ${timeout / 1000}s`));\n }, timeout);\n\n const cleanup = () => {\n clearTimeout(timeoutId);\n clearInterval(heartbeatInterval);\n };\n\n child.stdout?.on(\"data\", (data) => {\n const chunk = data.toString();\n stdout += chunk;\n totalBytesReceived += data.length;\n lastActivityTime = Date.now();\n\n emit({\n type: \"stdout\",\n message: `Received ${data.length} bytes (total: ${totalBytesReceived})`\n });\n });\n\n child.stderr?.on(\"data\", (data) => {\n const chunk = data.toString();\n stderr += chunk;\n totalBytesReceived += data.length;\n lastActivityTime = Date.now();\n\n // Stream stderr in real-time\n if (options?.onStderr) {\n options.onStderr(chunk);\n }\n\n emit({\n type: \"stderr\",\n message: chunk.trim().substring(0, 200) // First 200 chars\n });\n });\n\n child.on(\"close\", (code) => {\n cleanup();\n if (timedOut || aborted) return;\n\n if (code === 0) {\n emit({\n type: \"complete\",\n message: `Success - received ${stdout.length} chars in ${((Date.now() - startTime) / 1000).toFixed(1)}s`\n });\n resolve(stdout.trim());\n } else {\n emit({ type: \"error\", message: `Exit code ${code}: ${stderr || \"(no stderr)\"}` });\n reject(new Error(`Claude agent failed with code ${code}: ${stderr || \"(no stderr)\"}`));\n }\n });\n\n child.on(\"error\", (error) => {\n cleanup();\n emit({ type: \"error\", message: error.message });\n reject(error);\n });\n });\n\n const abort = () => {\n if (!timedOut && !aborted) {\n aborted = true;\n clearInterval(heartbeatInterval); // Clean up heartbeat on abort\n child.kill(\"SIGTERM\");\n emit({ type: \"error\", message: \"Aborted by user\" });\n }\n };\n\n return { promise, process: child, abort };\n}\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 *\n * This is the simple async version. For more control, use spawnClaudeAgentWithHandle.\n */\nexport async function spawnClaudeAgent(\n prompt: string,\n options?: ClaudeAgentOptions\n): Promise<string> {\n const handle = spawnClaudeAgentWithHandle(prompt, options);\n return handle.promise;\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"],"mappings":"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","names":[]}
@@ -2,7 +2,7 @@ import {
2
2
  VaultIntegrator,
3
3
  isClaudeAvailable,
4
4
  spawnClaudeAgent
5
- } from "./chunk-C4DKNWDW.js";
5
+ } from "./chunk-6P6BBEGR.js";
6
6
  import {
7
7
  DEFAULT_CONFIG,
8
8
  ensureDir,
@@ -972,4 +972,4 @@ export {
972
972
  AutoDiscover,
973
973
  discover
974
974
  };
975
- //# sourceMappingURL=chunk-OVZRLGW3.js.map
975
+ //# sourceMappingURL=chunk-W7IAOG27.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  spawnClaudeAgent
3
- } from "./chunk-C4DKNWDW.js";
3
+ } from "./chunk-6P6BBEGR.js";
4
4
  import {
5
5
  getConversationsPath,
6
6
  loadConfig,
@@ -276,4 +276,4 @@ ${content}`);
276
276
  export {
277
277
  CompactionEngine
278
278
  };
279
- //# sourceMappingURL=chunk-NPO2T25V.js.map
279
+ //# sourceMappingURL=chunk-XLRXDBQZ.js.map
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  CompactionEngine
3
- } from "../chunk-NPO2T25V.js";
3
+ } from "../chunk-XLRXDBQZ.js";
4
4
  import {
5
5
  VaultIntegrator
6
- } from "../chunk-C4DKNWDW.js";
6
+ } from "../chunk-6P6BBEGR.js";
7
7
  import {
8
8
  ConversationManager
9
9
  } from "../chunk-EXDIJANL.js";
package/dist/index.js CHANGED
@@ -4,17 +4,17 @@ import {
4
4
  FileCollector,
5
5
  discover,
6
6
  install
7
- } from "./chunk-OVZRLGW3.js";
7
+ } from "./chunk-W7IAOG27.js";
8
8
  import {
9
9
  CompactionEngine
10
- } from "./chunk-NPO2T25V.js";
10
+ } from "./chunk-XLRXDBQZ.js";
11
11
  import {
12
12
  EntityDetector,
13
13
  VaultIntegrator,
14
14
  isClaudeAvailable,
15
15
  spawnClaudeAgent,
16
16
  spawnClaudeAgentWithHandle
17
- } from "./chunk-C4DKNWDW.js";
17
+ } from "./chunk-6P6BBEGR.js";
18
18
  import {
19
19
  ConversationManager
20
20
  } from "./chunk-EXDIJANL.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cckb",
3
- "version": "0.1.10",
3
+ "version": "0.1.11",
4
4
  "description": "Claude Code Knowledge Base - Automatic project knowledge capture for Claude Code",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/entity-detector.ts","../src/core/vault-integrator.ts","../src/utils/claude-sdk.ts"],"sourcesContent":["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","import { spawn, type ChildProcess } from \"node:child_process\";\n\nexport interface ClaudeAgentOptions {\n timeout?: number; // milliseconds, default 5 minutes\n onProgress?: (event: ProgressEvent) => void; // Progress callback\n onStderr?: (data: string) => void; // Real-time stderr streaming\n verbose?: boolean; // Log all activity to stderr\n}\n\nexport interface ProgressEvent {\n type: \"started\" | \"activity\" | \"stdout\" | \"stderr\" | \"heartbeat\" | \"complete\" | \"error\";\n message: string;\n timestamp: number;\n elapsed?: number; // ms since start\n bytesReceived?: number; // total bytes received so far\n}\n\nexport interface ClaudeAgentHandle {\n promise: Promise<string>;\n process: ChildProcess;\n abort: () => void;\n}\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 *\n * Returns a handle with:\n * - promise: The result promise\n * - process: The child process (for advanced control)\n * - abort: Function to cancel the operation\n */\nexport function spawnClaudeAgentWithHandle(\n prompt: string,\n options?: ClaudeAgentOptions\n): ClaudeAgentHandle {\n const timeout = options?.timeout ?? 300000; // 5 minutes default\n const startTime = Date.now();\n let totalBytesReceived = 0;\n let lastActivityTime = startTime;\n let timedOut = false;\n let aborted = false;\n\n const emit = (event: Omit<ProgressEvent, \"timestamp\" | \"elapsed\">) => {\n if (options?.onProgress) {\n options.onProgress({\n ...event,\n timestamp: Date.now(),\n elapsed: Date.now() - startTime,\n bytesReceived: totalBytesReceived,\n });\n }\n if (options?.verbose) {\n const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);\n console.error(`[Claude SDK] [${elapsed}s] ${event.type}: ${event.message}`);\n }\n };\n\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 });\n\n emit({ type: \"started\", message: `Claude process spawned (PID: ${child.pid})` });\n\n // Heartbeat interval - shows we're still alive even with no output\n const heartbeatInterval = setInterval(() => {\n if (!timedOut && !aborted) {\n const silentFor = Date.now() - lastActivityTime;\n emit({\n type: \"heartbeat\",\n message: `Waiting for response... (silent for ${(silentFor / 1000).toFixed(0)}s)`\n });\n }\n }, 10000); // Every 10 seconds\n\n const promise = new Promise<string>((resolve, reject) => {\n let stdout = \"\";\n let stderr = \"\";\n\n // Manual timeout since spawn timeout doesn't always work\n const timeoutId = setTimeout(() => {\n timedOut = true;\n child.kill(\"SIGTERM\");\n emit({ type: \"error\", message: `Timed out after ${timeout / 1000}s` });\n reject(new Error(`Claude agent timed out after ${timeout / 1000}s`));\n }, timeout);\n\n const cleanup = () => {\n clearTimeout(timeoutId);\n clearInterval(heartbeatInterval);\n };\n\n child.stdout?.on(\"data\", (data) => {\n const chunk = data.toString();\n stdout += chunk;\n totalBytesReceived += data.length;\n lastActivityTime = Date.now();\n\n emit({\n type: \"stdout\",\n message: `Received ${data.length} bytes (total: ${totalBytesReceived})`\n });\n });\n\n child.stderr?.on(\"data\", (data) => {\n const chunk = data.toString();\n stderr += chunk;\n totalBytesReceived += data.length;\n lastActivityTime = Date.now();\n\n // Stream stderr in real-time\n if (options?.onStderr) {\n options.onStderr(chunk);\n }\n\n emit({\n type: \"stderr\",\n message: chunk.trim().substring(0, 200) // First 200 chars\n });\n });\n\n child.on(\"close\", (code) => {\n cleanup();\n if (timedOut || aborted) return;\n\n if (code === 0) {\n emit({\n type: \"complete\",\n message: `Success - received ${stdout.length} chars in ${((Date.now() - startTime) / 1000).toFixed(1)}s`\n });\n resolve(stdout.trim());\n } else {\n emit({ type: \"error\", message: `Exit code ${code}: ${stderr || \"(no stderr)\"}` });\n reject(new Error(`Claude agent failed with code ${code}: ${stderr || \"(no stderr)\"}`));\n }\n });\n\n child.on(\"error\", (error) => {\n cleanup();\n emit({ type: \"error\", message: error.message });\n reject(error);\n });\n });\n\n const abort = () => {\n if (!timedOut && !aborted) {\n aborted = true;\n clearInterval(heartbeatInterval); // Clean up heartbeat on abort\n child.kill(\"SIGTERM\");\n emit({ type: \"error\", message: \"Aborted by user\" });\n }\n };\n\n return { promise, process: child, abort };\n}\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 *\n * This is the simple async version. For more control, use spawnClaudeAgentWithHandle.\n */\nexport async function spawnClaudeAgent(\n prompt: string,\n options?: ClaudeAgentOptions\n): Promise<string> {\n const handle = spawnClaudeAgentWithHandle(prompt, options);\n return handle.promise;\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"],"mappings":"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","names":[]}