cckb 0.1.5 → 0.1.7

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,10 +2,10 @@
2
2
  import {
3
3
  discover,
4
4
  install
5
- } from "../chunk-XOV27B2L.js";
6
- import "../chunk-TB2GPCQP.js";
7
- import "../chunk-4IQV2TQE.js";
8
- import "../chunk-FRETJBP5.js";
5
+ } from "../chunk-JTHQRYKF.js";
6
+ import "../chunk-AJ2AVV5V.js";
7
+ import "../chunk-NEHPNFRM.js";
8
+ import "../chunk-I4GLPRZ2.js";
9
9
 
10
10
  // src/bin/cckb.ts
11
11
  var args = process.argv.slice(2);
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  IndexManager
3
- } from "./chunk-4IQV2TQE.js";
3
+ } from "./chunk-NEHPNFRM.js";
4
4
  import {
5
5
  appendToFile,
6
6
  ensureDir,
7
7
  fileExists,
8
8
  readTextFile,
9
9
  writeTextFile
10
- } from "./chunk-FRETJBP5.js";
10
+ } from "./chunk-I4GLPRZ2.js";
11
11
 
12
12
  // src/core/entity-detector.ts
13
13
  var EntityDetector = class {
@@ -355,4 +355,4 @@ export {
355
355
  spawnClaudeAgent,
356
356
  isClaudeAvailable
357
357
  };
358
- //# sourceMappingURL=chunk-TB2GPCQP.js.map
358
+ //# sourceMappingURL=chunk-AJ2AVV5V.js.map
@@ -13,7 +13,7 @@ import {
13
13
  readTextFile,
14
14
  writeJSON,
15
15
  writeTextFile
16
- } from "./chunk-FRETJBP5.js";
16
+ } from "./chunk-I4GLPRZ2.js";
17
17
 
18
18
  // src/core/conversation-manager.ts
19
19
  import * as path from "path";
@@ -236,4 +236,4 @@ ${entry.content}
236
236
  export {
237
237
  ConversationManager
238
238
  };
239
- //# sourceMappingURL=chunk-HP5YVMZ6.js.map
239
+ //# sourceMappingURL=chunk-EXDIJANL.js.map
@@ -88,7 +88,8 @@ var DEFAULT_CONFIG = {
88
88
  },
89
89
  discover: {
90
90
  maxFiles: 100,
91
- maxChunkSize: 5e4,
91
+ maxChunkSize: 15e3,
92
+ // ~3750 tokens, creates ~10 smaller chunks
92
93
  excludePatterns: [
93
94
  "*.min.js",
94
95
  "*.bundle.js",
@@ -151,4 +152,4 @@ export {
151
152
  getVaultPath,
152
153
  getStatePath
153
154
  };
154
- //# sourceMappingURL=chunk-FRETJBP5.js.map
155
+ //# sourceMappingURL=chunk-I4GLPRZ2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/file-utils.ts","../src/utils/config.ts"],"sourcesContent":["import * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\n\nexport async function ensureDir(dirPath: string): Promise<void> {\n await fs.mkdir(dirPath, { recursive: true });\n}\n\nexport async function fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function readJSON<T>(filePath: string): Promise<T | null> {\n try {\n const content = await fs.readFile(filePath, \"utf-8\");\n return JSON.parse(content) as T;\n } catch {\n return null;\n }\n}\n\nexport async function writeJSON(\n filePath: string,\n data: unknown,\n pretty = true\n): Promise<void> {\n await ensureDir(path.dirname(filePath));\n const content = pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);\n await fs.writeFile(filePath, content);\n}\n\nexport async function appendToFile(\n filePath: string,\n content: string\n): Promise<void> {\n await ensureDir(path.dirname(filePath));\n await fs.appendFile(filePath, content);\n}\n\nexport async function readTextFile(filePath: string): Promise<string | null> {\n try {\n return await fs.readFile(filePath, \"utf-8\");\n } catch {\n return null;\n }\n}\n\nexport async function writeTextFile(\n filePath: string,\n content: string\n): Promise<void> {\n await ensureDir(path.dirname(filePath));\n await fs.writeFile(filePath, content);\n}\n\nexport async function copyFile(src: string, dest: string): Promise<void> {\n await ensureDir(path.dirname(dest));\n await fs.copyFile(src, dest);\n}\n\nexport async function listDir(dirPath: string): Promise<string[]> {\n try {\n return await fs.readdir(dirPath);\n } catch {\n return [];\n }\n}\n\nexport async function getFileSize(filePath: string): Promise<number> {\n try {\n const stats = await fs.stat(filePath);\n return stats.size;\n } catch {\n return 0;\n }\n}\n\nexport function generateSessionId(): string {\n const timestamp = Date.now().toString(36);\n const random = Math.random().toString(36).substring(2, 8);\n return `${timestamp}-${random}`;\n}\n\nexport function getCurrentTimestamp(): string {\n return new Date().toISOString();\n}\n","import * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\n\nexport interface CCKBConfig {\n compaction: {\n trigger: \"session_end\" | \"size\" | \"messages\" | \"manual\";\n sizeThresholdKB: number;\n messageThreshold: number;\n cleanupAfterSummary: \"keep\" | \"archive\" | \"delete\";\n };\n capture: {\n tools: string[];\n maxContentLength: number;\n };\n vault: {\n autoIntegrate: boolean;\n maxDepth: number;\n };\n feedback: {\n enabled: boolean;\n contextDepth: number;\n };\n discover: {\n maxFiles: number;\n maxChunkSize: number;\n excludePatterns: string[];\n priorityPatterns: string[];\n supportedLanguages: string[];\n };\n}\n\nexport const DEFAULT_CONFIG: CCKBConfig = {\n compaction: {\n trigger: \"session_end\",\n sizeThresholdKB: 50,\n messageThreshold: 100,\n cleanupAfterSummary: \"keep\",\n },\n capture: {\n tools: [\"Write\", \"Edit\", \"MultiEdit\", \"Bash\", \"Task\"],\n maxContentLength: 500,\n },\n vault: {\n autoIntegrate: true,\n maxDepth: 5,\n },\n feedback: {\n enabled: true,\n contextDepth: 2,\n },\n discover: {\n maxFiles: 100,\n maxChunkSize: 15000, // ~3750 tokens, creates ~10 smaller chunks\n excludePatterns: [\n \"*.min.js\",\n \"*.bundle.js\",\n \"*.map\",\n \"coverage/**\",\n \".next/**\",\n \"build/**\",\n \"dist/**\",\n ],\n priorityPatterns: [\n \"**/index.{ts,js,tsx,jsx}\",\n \"**/main.{ts,js,py,go,rs}\",\n \"**/app.{ts,js,py}\",\n \"**/models/**\",\n \"**/entities/**\",\n \"**/services/**\",\n ],\n supportedLanguages: [\"typescript\", \"javascript\", \"python\", \"go\", \"rust\"],\n },\n};\n\nexport async function loadConfig(projectPath: string): Promise<CCKBConfig> {\n const configPath = path.join(\n projectPath,\n \"cc-knowledge-base\",\n \".cckb-config.json\"\n );\n\n try {\n const content = await fs.readFile(configPath, \"utf-8\");\n const userConfig = JSON.parse(content);\n return { ...DEFAULT_CONFIG, ...userConfig };\n } catch {\n return DEFAULT_CONFIG;\n }\n}\n\nexport async function saveConfig(\n projectPath: string,\n config: CCKBConfig\n): Promise<void> {\n const configPath = path.join(\n projectPath,\n \"cc-knowledge-base\",\n \".cckb-config.json\"\n );\n\n await fs.writeFile(configPath, JSON.stringify(config, null, 2));\n}\n\nexport function getKnowledgeBasePath(projectPath: string): string {\n return path.join(projectPath, \"cc-knowledge-base\");\n}\n\nexport function getConversationsPath(projectPath: string): string {\n return path.join(projectPath, \"cc-knowledge-base\", \"conversations\");\n}\n\nexport function getVaultPath(projectPath: string): string {\n return path.join(projectPath, \"cc-knowledge-base\", \"vault\");\n}\n\nexport function getStatePath(projectPath: string): string {\n return path.join(projectPath, \"cc-knowledge-base\", \".cckb-state\");\n}\n"],"mappings":"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","names":["fs","path"]}
@@ -2,7 +2,7 @@ import {
2
2
  VaultIntegrator,
3
3
  isClaudeAvailable,
4
4
  spawnClaudeAgent
5
- } from "./chunk-TB2GPCQP.js";
5
+ } from "./chunk-AJ2AVV5V.js";
6
6
  import {
7
7
  DEFAULT_CONFIG,
8
8
  ensureDir,
@@ -12,7 +12,7 @@ import {
12
12
  readTextFile,
13
13
  writeJSON,
14
14
  writeTextFile
15
- } from "./chunk-FRETJBP5.js";
15
+ } from "./chunk-I4GLPRZ2.js";
16
16
 
17
17
  // src/cli/install.ts
18
18
  import * as fs from "fs/promises";
@@ -630,7 +630,8 @@ var AutoDiscover = class {
630
630
  const partialSummaries = [];
631
631
  let chunksProcessed = 0;
632
632
  for (const chunk of chunks) {
633
- this.log(` [${chunk.index + 1}/${chunk.totalChunks}] Analyzing ${chunk.files.length} files...`);
633
+ const chunkKB = Math.round(chunk.content.length / 1024);
634
+ this.log(` [${chunk.index + 1}/${chunk.totalChunks}] Analyzing ${chunk.files.length} files (~${chunkKB}KB, ~${chunk.estimatedTokens} tokens)...`);
634
635
  try {
635
636
  const summary = await this.analyzeChunk(chunk, collection);
636
637
  partialSummaries.push(summary);
@@ -675,11 +676,13 @@ Discovery complete (${(duration / 1e3).toFixed(1)}s)`);
675
676
  async analyzeChunk(chunk, collection) {
676
677
  const prompt = DISCOVERY_PROMPT.replace("{languages}", collection.languages.join(", ")).replace("{projectType}", collection.projectType).replace("{fileContents}", chunk.content);
677
678
  const response = await this.runWithProgressIndicators(
678
- () => spawnClaudeAgent(prompt, { timeout: 3e5 }),
679
- // 5 minutes
679
+ () => spawnClaudeAgent(prompt, { timeout: 6e5 }),
680
+ // 10 minutes
680
681
  [
681
682
  { at: 6e4, message: " Still analyzing... (1 min)" },
682
- { at: 18e4, message: " Still working... (3 min)" }
683
+ { at: 18e4, message: " Still working... (3 min)" },
684
+ { at: 3e5, message: " Still working... (5 min)" },
685
+ { at: 48e4, message: " Almost timing out... (8 min)" }
683
686
  ]
684
687
  );
685
688
  return this.parseResponse(response, chunk);
@@ -966,4 +969,4 @@ export {
966
969
  AutoDiscover,
967
970
  discover
968
971
  };
969
- //# sourceMappingURL=chunk-XOV27B2L.js.map
972
+ //# sourceMappingURL=chunk-JTHQRYKF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/install.ts","../src/core/file-collector.ts","../src/core/chunk-manager.ts","../src/core/auto-discover.ts","../src/cli/discover.ts"],"sourcesContent":["import * as fs from \"node:fs/promises\";\nimport * as fsSync from \"node:fs\";\nimport * as path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n ensureDir,\n fileExists,\n readJSON,\n writeJSON,\n readTextFile,\n writeTextFile,\n} from \"../utils/file-utils.js\";\nimport { DEFAULT_CONFIG } from \"../utils/config.js\";\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\n// Find package root by looking for package.json\nfunction findPackageRoot(): string {\n let dir = __dirname;\n for (let i = 0; i < 5; i++) {\n const packageJson = path.join(dir, \"package.json\");\n if (fsSync.existsSync(packageJson)) {\n return dir;\n }\n dir = path.dirname(dir);\n }\n // Fallback to relative from __dirname\n return path.resolve(__dirname, \"../..\");\n}\n\nconst PACKAGE_ROOT = findPackageRoot();\nconst TEMPLATES_DIR = path.join(PACKAGE_ROOT, \"templates\");\n\nexport interface InstallOptions {\n force?: boolean;\n}\n\nexport async function install(\n targetPath: string,\n options: InstallOptions = {}\n): Promise<void> {\n const resolvedPath = path.resolve(targetPath);\n\n console.log(`Installing CCKB to: ${resolvedPath}`);\n\n // Pre-flight checks\n await validateTargetPath(resolvedPath);\n await checkExistingInstallation(resolvedPath, options.force);\n\n // Create directory structure\n await createDirectoryStructure(resolvedPath);\n\n // Copy template files\n await copyTemplateFiles(resolvedPath);\n\n // Create config file\n await createConfigFile(resolvedPath);\n\n // Install hooks configuration\n await installHooks(resolvedPath);\n\n // Update CLAUDE.md\n await updateClaudeMd(resolvedPath);\n\n // Update .gitignore\n await updateGitignore(resolvedPath);\n\n console.log(\"\\nCCKB installed successfully!\");\n console.log(\"\\nNext steps:\");\n console.log(\" 1. Review cc-knowledge-base/vault/ structure\");\n console.log(\" 2. Check .claude/settings.json for hook configuration\");\n console.log(\" 3. Start a new Claude Code session to begin capturing knowledge\");\n}\n\nasync function validateTargetPath(targetPath: string): Promise<void> {\n const exists = await fileExists(targetPath);\n if (!exists) {\n throw new Error(`Target path does not exist: ${targetPath}`);\n }\n\n const stats = await fs.stat(targetPath);\n if (!stats.isDirectory()) {\n throw new Error(`Target path is not a directory: ${targetPath}`);\n }\n}\n\nasync function checkExistingInstallation(\n targetPath: string,\n force?: boolean\n): Promise<void> {\n const kbPath = path.join(targetPath, \"cc-knowledge-base\");\n const exists = await fileExists(kbPath);\n\n if (exists && !force) {\n throw new Error(\n \"CCKB is already installed in this project. Use --force to reinstall.\"\n );\n }\n}\n\nasync function createDirectoryStructure(targetPath: string): Promise<void> {\n const directories = [\n \"cc-knowledge-base\",\n \"cc-knowledge-base/conversations\",\n \"cc-knowledge-base/vault\",\n \"cc-knowledge-base/vault/entities\",\n \"cc-knowledge-base/vault/apps\",\n \"cc-knowledge-base/vault/modules\",\n \"cc-knowledge-base/.cckb-state\",\n ];\n\n for (const dir of directories) {\n await ensureDir(path.join(targetPath, dir));\n }\n\n console.log(\" Created directory structure\");\n}\n\nasync function copyTemplateFiles(targetPath: string): Promise<void> {\n const vaultFiles = [\n { src: \"vault/INDEX.md\", dest: \"cc-knowledge-base/vault/INDEX.md\" },\n {\n src: \"vault/architecture.md\",\n dest: \"cc-knowledge-base/vault/architecture.md\",\n },\n {\n src: \"vault/general-knowledge.md\",\n dest: \"cc-knowledge-base/vault/general-knowledge.md\",\n },\n {\n src: \"vault/entities/INDEX.md\",\n dest: \"cc-knowledge-base/vault/entities/INDEX.md\",\n },\n {\n src: \"vault/apps/INDEX.md\",\n dest: \"cc-knowledge-base/vault/apps/INDEX.md\",\n },\n {\n src: \"vault/modules/INDEX.md\",\n dest: \"cc-knowledge-base/vault/modules/INDEX.md\",\n },\n ];\n\n for (const file of vaultFiles) {\n const srcPath = path.join(TEMPLATES_DIR, file.src);\n const destPath = path.join(targetPath, file.dest);\n\n const content = await readTextFile(srcPath);\n if (content) {\n await writeTextFile(destPath, content);\n }\n }\n\n // Create .gitkeep for conversations\n await writeTextFile(\n path.join(targetPath, \"cc-knowledge-base/conversations/.gitkeep\"),\n \"\"\n );\n\n console.log(\" Copied vault template files\");\n}\n\nasync function createConfigFile(targetPath: string): Promise<void> {\n const configPath = path.join(\n targetPath,\n \"cc-knowledge-base\",\n \".cckb-config.json\"\n );\n\n await writeJSON(configPath, DEFAULT_CONFIG);\n\n console.log(\" Created configuration file\");\n}\n\nasync function installHooks(targetPath: string): Promise<void> {\n const claudeDir = path.join(targetPath, \".claude\");\n const settingsPath = path.join(claudeDir, \"settings.json\");\n\n await ensureDir(claudeDir);\n\n // Load existing settings or create new\n let settings: Record<string, unknown> =\n (await readJSON<Record<string, unknown>>(settingsPath)) || {};\n\n // Load hook template\n const templatePath = path.join(TEMPLATES_DIR, \"settings.json.tmpl\");\n const hookSettings = await readJSON<{ hooks: Record<string, unknown> }>(\n templatePath\n );\n\n if (!hookSettings) {\n throw new Error(\"Failed to load hook template\");\n }\n\n // Merge hooks (CCKB hooks take precedence for its own hook types)\n const existingHooks = (settings.hooks as Record<string, unknown[]>) || {};\n const newHooks = hookSettings.hooks as Record<string, unknown[]>;\n\n settings.hooks = mergeHooks(existingHooks, newHooks);\n\n await writeJSON(settingsPath, settings);\n\n console.log(\" Installed hook configuration\");\n}\n\nfunction mergeHooks(\n existing: Record<string, unknown[]>,\n incoming: Record<string, unknown[]>\n): Record<string, unknown[]> {\n const merged = { ...existing };\n\n for (const [hookType, hooks] of Object.entries(incoming)) {\n if (!merged[hookType]) {\n merged[hookType] = [];\n }\n\n // Add incoming hooks, avoiding duplicates based on command\n for (const hook of hooks) {\n const hookObj = hook as Record<string, unknown>;\n const command = hookObj.command as string | undefined;\n\n if (command?.includes(\"cckb\")) {\n // Remove any existing CCKB hooks for this type\n merged[hookType] = merged[hookType].filter((h) => {\n const existingCmd = (h as Record<string, unknown>).command as\n | string\n | undefined;\n return !existingCmd?.includes(\"cckb\");\n });\n }\n\n merged[hookType].push(hook);\n }\n }\n\n return merged;\n}\n\nasync function updateClaudeMd(targetPath: string): Promise<void> {\n const claudeMdPath = path.join(targetPath, \"CLAUDE.md\");\n const templatePath = path.join(TEMPLATES_DIR, \"CLAUDE.md.tmpl\");\n\n const template = await readTextFile(templatePath);\n if (!template) {\n throw new Error(\"Failed to load CLAUDE.md template\");\n }\n\n const marker = \"## Project Knowledge Base (CCKB)\";\n\n let existing = await readTextFile(claudeMdPath);\n\n if (existing) {\n // Check if CCKB section already exists\n if (existing.includes(marker)) {\n // Replace existing CCKB section\n const regex = /## Project Knowledge Base \\(CCKB\\)[\\s\\S]*?(?=\\n## |$)/;\n existing = existing.replace(regex, template.trim());\n } else {\n // Append CCKB section\n existing = existing.trimEnd() + \"\\n\\n\" + template;\n }\n await writeTextFile(claudeMdPath, existing);\n } else {\n // Create new CLAUDE.md with CCKB section\n await writeTextFile(claudeMdPath, template);\n }\n\n console.log(\" Updated CLAUDE.md with vault directives\");\n}\n\nasync function updateGitignore(targetPath: string): Promise<void> {\n const gitignorePath = path.join(targetPath, \".gitignore\");\n\n const entries = [\n \"\",\n \"# CCKB state files\",\n \"cc-knowledge-base/.cckb-state/\",\n ];\n\n let existing = (await readTextFile(gitignorePath)) || \"\";\n\n // Check if already added\n if (existing.includes(\"cc-knowledge-base/.cckb-state/\")) {\n return;\n }\n\n existing = existing.trimEnd() + \"\\n\" + entries.join(\"\\n\") + \"\\n\";\n await writeTextFile(gitignorePath, existing);\n\n console.log(\" Updated .gitignore\");\n}\n","import * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { readTextFile, fileExists } from \"../utils/file-utils.js\";\nimport { loadConfig } from \"../utils/config.js\";\n\n// Language detection from manifest files\nconst MANIFEST_LANGUAGE_MAP: Record<string, { language: string; projectType: string }> = {\n \"package.json\": { language: \"typescript\", projectType: \"node\" },\n \"tsconfig.json\": { language: \"typescript\", projectType: \"node\" },\n \"Cargo.toml\": { language: \"rust\", projectType: \"rust\" },\n \"go.mod\": { language: \"go\", projectType: \"go\" },\n \"requirements.txt\": { language: \"python\", projectType: \"python\" },\n \"pyproject.toml\": { language: \"python\", projectType: \"python\" },\n \"setup.py\": { language: \"python\", projectType: \"python\" },\n \"pom.xml\": { language: \"java\", projectType: \"java\" },\n \"build.gradle\": { language: \"java\", projectType: \"java\" },\n \"*.csproj\": { language: \"csharp\", projectType: \"dotnet\" },\n \"Gemfile\": { language: \"ruby\", projectType: \"ruby\" },\n \"composer.json\": { language: \"php\", projectType: \"php\" },\n};\n\n// Extension to language mapping\nconst EXTENSION_LANGUAGE_MAP: Record<string, string> = {\n \".ts\": \"typescript\",\n \".tsx\": \"typescript\",\n \".js\": \"javascript\",\n \".jsx\": \"javascript\",\n \".mjs\": \"javascript\",\n \".cjs\": \"javascript\",\n \".py\": \"python\",\n \".go\": \"go\",\n \".rs\": \"rust\",\n \".java\": \"java\",\n \".cs\": \"csharp\",\n \".rb\": \"ruby\",\n \".php\": \"php\",\n};\n\n// File categories for prioritization\ntype FileCategory = \"entry\" | \"model\" | \"service\" | \"util\" | \"config\" | \"test\" | \"other\";\n\nexport interface CollectedFile {\n path: string; // Relative to project root\n absolutePath: string;\n language: string;\n category: FileCategory;\n size: number;\n priority: number;\n}\n\nexport interface CollectionResult {\n files: CollectedFile[];\n languages: string[];\n projectType: string;\n totalFilesScanned: number;\n}\n\nexport interface CollectOptions {\n maxFiles?: number;\n excludePatterns?: string[];\n priorityPatterns?: string[];\n supportedLanguages?: string[];\n}\n\nexport class FileCollector {\n private projectPath: string;\n\n constructor(projectPath: string) {\n this.projectPath = projectPath;\n }\n\n async collect(options?: CollectOptions): Promise<CollectionResult> {\n const config = await loadConfig(this.projectPath);\n const mergedOptions = {\n maxFiles: options?.maxFiles ?? config.discover.maxFiles,\n excludePatterns: options?.excludePatterns ?? config.discover.excludePatterns,\n supportedLanguages: options?.supportedLanguages ?? config.discover.supportedLanguages,\n };\n\n // Detect project languages\n const { languages, projectType } = await this.detectLanguages();\n\n // Load ignore patterns\n const ignorePatterns = await this.loadIgnorePatterns(mergedOptions.excludePatterns);\n\n // Collect all source files\n const allFiles: CollectedFile[] = [];\n let totalScanned = 0;\n\n await this.walkDirectory(\n this.projectPath,\n async (filePath, stats) => {\n totalScanned++;\n const relativePath = path.relative(this.projectPath, filePath);\n\n // Skip if matches ignore pattern\n if (this.shouldIgnore(relativePath, ignorePatterns)) {\n return;\n }\n\n const ext = path.extname(filePath);\n const language = EXTENSION_LANGUAGE_MAP[ext];\n\n // Skip unsupported languages\n if (!language || !mergedOptions.supportedLanguages.includes(language)) {\n return;\n }\n\n const category = this.categorizeFile(relativePath);\n const priority = this.calculatePriority(relativePath, category, stats.size);\n\n allFiles.push({\n path: relativePath,\n absolutePath: filePath,\n language,\n category,\n size: stats.size,\n priority,\n });\n }\n );\n\n // Sort by priority (descending) and limit\n allFiles.sort((a, b) => b.priority - a.priority);\n const limitedFiles = allFiles.slice(0, mergedOptions.maxFiles);\n\n return {\n files: limitedFiles,\n languages,\n projectType,\n totalFilesScanned: totalScanned,\n };\n }\n\n async detectLanguages(): Promise<{ languages: string[]; projectType: string }> {\n const detected = new Set<string>();\n let projectType = \"unknown\";\n\n // Check for manifest files\n for (const [manifest, info] of Object.entries(MANIFEST_LANGUAGE_MAP)) {\n if (manifest.startsWith(\"*\")) {\n // Glob pattern - skip for now\n continue;\n }\n const manifestPath = path.join(this.projectPath, manifest);\n if (await fileExists(manifestPath)) {\n detected.add(info.language);\n if (projectType === \"unknown\") {\n projectType = info.projectType;\n }\n }\n }\n\n // If package.json exists, check for TypeScript\n const packageJsonPath = path.join(this.projectPath, \"package.json\");\n if (await fileExists(packageJsonPath)) {\n const content = await readTextFile(packageJsonPath);\n if (content) {\n try {\n const pkg = JSON.parse(content);\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n if (deps.typescript || await fileExists(path.join(this.projectPath, \"tsconfig.json\"))) {\n detected.add(\"typescript\");\n } else {\n detected.add(\"javascript\");\n }\n } catch {\n detected.add(\"javascript\");\n }\n }\n }\n\n return {\n languages: Array.from(detected),\n projectType,\n };\n }\n\n private async loadIgnorePatterns(additionalPatterns: string[]): Promise<string[]> {\n const patterns: string[] = [\n // Default ignores\n \"node_modules/**\",\n \".git/**\",\n \"dist/**\",\n \"build/**\",\n \"coverage/**\",\n \"*.log\",\n \".env*\",\n \"__pycache__/**\",\n \"*.pyc\",\n \"target/**\", // Rust\n \"vendor/**\", // Go\n \".venv/**\",\n \"venv/**\",\n ];\n\n // Load .gitignore\n const gitignorePath = path.join(this.projectPath, \".gitignore\");\n const gitignore = await readTextFile(gitignorePath);\n if (gitignore) {\n const lines = gitignore\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line && !line.startsWith(\"#\"));\n patterns.push(...lines);\n }\n\n // Add user-configured excludes\n patterns.push(...additionalPatterns);\n\n return patterns;\n }\n\n private shouldIgnore(relativePath: string, patterns: string[]): boolean {\n const normalizedPath = relativePath.replace(/\\\\/g, \"/\");\n\n for (const pattern of patterns) {\n if (this.matchPattern(normalizedPath, pattern)) {\n return true;\n }\n }\n return false;\n }\n\n private matchPattern(filePath: string, pattern: string): boolean {\n // Simple glob matching - supports *, **, and basic patterns\n const normalizedPattern = pattern.replace(/\\\\/g, \"/\");\n\n // Handle negation patterns\n if (normalizedPattern.startsWith(\"!\")) {\n return false; // Negation patterns don't cause ignore\n }\n\n // Convert glob to regex\n let regex = normalizedPattern\n .replace(/\\./g, \"\\\\.\")\n .replace(/\\*\\*/g, \"{{GLOBSTAR}}\")\n .replace(/\\*/g, \"[^/]*\")\n .replace(/{{GLOBSTAR}}/g, \".*\")\n .replace(/\\?/g, \".\");\n\n // Handle patterns that should match from start or anywhere\n if (!regex.startsWith(\"/\") && !regex.startsWith(\".*\")) {\n regex = \"(^|/)\" + regex;\n }\n\n // Handle trailing slash (directory match)\n if (regex.endsWith(\"/\")) {\n regex = regex + \".*\";\n }\n\n try {\n const re = new RegExp(regex);\n return re.test(filePath);\n } catch {\n // Invalid regex, do simple includes check\n return filePath.includes(pattern.replace(/\\*/g, \"\"));\n }\n }\n\n private categorizeFile(relativePath: string): FileCategory {\n const lowerPath = relativePath.toLowerCase();\n const fileName = path.basename(lowerPath);\n\n // Test files\n if (\n /\\.(test|spec)\\.[^/]+$/.test(lowerPath) ||\n /\\/__tests__\\//.test(lowerPath) ||\n /\\/test\\//.test(lowerPath) ||\n /\\/tests\\//.test(lowerPath)\n ) {\n return \"test\";\n }\n\n // Entry points\n if (\n /^(index|main|app|server)\\.[^/]+$/.test(fileName) ||\n /\\/src\\/(index|main|app)\\.[^/]+$/.test(lowerPath)\n ) {\n return \"entry\";\n }\n\n // Models/Entities\n if (\n /\\/(models?|entities|domain|types|schemas?)\\//i.test(lowerPath) ||\n /\\.(model|entity|type)\\.[^/]+$/.test(lowerPath)\n ) {\n return \"model\";\n }\n\n // Services\n if (\n /\\/(services?|controllers?|handlers?|api|routes?)\\//i.test(lowerPath) ||\n /\\.(service|controller|handler)\\.[^/]+$/.test(lowerPath)\n ) {\n return \"service\";\n }\n\n // Config files\n if (\n /\\.(config|conf)\\.[^/]+$/.test(lowerPath) ||\n /\\/config\\//i.test(lowerPath) ||\n fileName.startsWith(\".\")\n ) {\n return \"config\";\n }\n\n // Utilities\n if (\n /\\/(utils?|helpers?|lib|common|shared)\\//i.test(lowerPath) ||\n /\\.(util|helper)\\.[^/]+$/.test(lowerPath)\n ) {\n return \"util\";\n }\n\n return \"other\";\n }\n\n private calculatePriority(\n relativePath: string,\n category: FileCategory,\n size: number\n ): number {\n let score = 0;\n\n // Category-based scoring\n const categoryScores: Record<FileCategory, number> = {\n entry: 100,\n model: 80,\n service: 70,\n util: 30,\n config: 20,\n other: 10,\n test: -50,\n };\n score += categoryScores[category];\n\n // Depth penalty (shallower files are usually more important)\n const depth = relativePath.split(\"/\").length;\n score -= depth * 2;\n\n // Size preferences\n if (size < 5000) score += 10; // Small, focused files\n if (size > 50000) score -= 20; // Very large files\n if (size > 100000) score -= 30; // Huge files\n\n // Bonus for src directory\n if (/^src\\//.test(relativePath)) score += 15;\n\n return score;\n }\n\n private async walkDirectory(\n dir: string,\n callback: (filePath: string, stats: { size: number }) => Promise<void>\n ): Promise<void> {\n try {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n // Skip common non-source directories early\n if (\n entry.name === \"node_modules\" ||\n entry.name === \".git\" ||\n entry.name === \"dist\" ||\n entry.name === \"build\" ||\n entry.name === \"__pycache__\" ||\n entry.name === \"target\" ||\n entry.name === \"vendor\" ||\n entry.name === \".venv\" ||\n entry.name === \"venv\"\n ) {\n continue;\n }\n await this.walkDirectory(fullPath, callback);\n } else if (entry.isFile()) {\n try {\n const stats = await fs.stat(fullPath);\n await callback(fullPath, { size: stats.size });\n } catch {\n // Skip files we can't stat\n }\n }\n }\n } catch {\n // Skip directories we can't read\n }\n }\n}\n","import { readTextFile } from \"../utils/file-utils.js\";\nimport type { CollectedFile } from \"./file-collector.js\";\n\nexport interface FileChunk {\n files: CollectedFile[];\n content: string;\n estimatedTokens: number;\n index: number;\n totalChunks: number;\n}\n\nexport interface ChunkOptions {\n maxChunkSize?: number; // Max characters per chunk (default: 50000)\n}\n\nconst DEFAULT_MAX_CHUNK_SIZE = 50000;\n\n// Rough token estimation (avg ~4 chars per token for code)\nfunction estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n\nexport class ChunkManager {\n private files: CollectedFile[];\n private maxChunkSize: number;\n private chunks: FileChunk[] | null = null;\n\n constructor(files: CollectedFile[], options?: ChunkOptions) {\n this.files = files;\n this.maxChunkSize = options?.maxChunkSize ?? DEFAULT_MAX_CHUNK_SIZE;\n }\n\n async prepareChunks(): Promise<FileChunk[]> {\n if (this.chunks) {\n return this.chunks;\n }\n\n const chunks: FileChunk[] = [];\n let currentChunk: CollectedFile[] = [];\n let currentContent = \"\";\n let currentSize = 0;\n\n for (const file of this.files) {\n const content = await readTextFile(file.absolutePath);\n if (!content) continue;\n\n // Format file content with path header\n const formattedContent = this.formatFileContent(file.path, content);\n const contentSize = formattedContent.length;\n\n // If single file exceeds max size, truncate it\n if (contentSize > this.maxChunkSize) {\n // If we have pending content, save current chunk first\n if (currentChunk.length > 0) {\n chunks.push(this.createChunk(currentChunk, currentContent, chunks.length));\n currentChunk = [];\n currentContent = \"\";\n currentSize = 0;\n }\n\n // Add truncated file as its own chunk\n const truncatedContent = this.truncateContent(formattedContent, this.maxChunkSize);\n chunks.push(this.createChunk([file], truncatedContent, chunks.length));\n continue;\n }\n\n // If adding this file would exceed max size, start new chunk\n if (currentSize + contentSize > this.maxChunkSize && currentChunk.length > 0) {\n chunks.push(this.createChunk(currentChunk, currentContent, chunks.length));\n currentChunk = [];\n currentContent = \"\";\n currentSize = 0;\n }\n\n // Add file to current chunk\n currentChunk.push(file);\n currentContent += formattedContent + \"\\n\\n\";\n currentSize += contentSize;\n }\n\n // Don't forget the last chunk\n if (currentChunk.length > 0) {\n chunks.push(this.createChunk(currentChunk, currentContent, chunks.length));\n }\n\n // Update totalChunks in all chunks\n for (const chunk of chunks) {\n chunk.totalChunks = chunks.length;\n }\n\n this.chunks = chunks;\n return chunks;\n }\n\n private createChunk(\n files: CollectedFile[],\n content: string,\n index: number\n ): FileChunk {\n return {\n files,\n content: content.trim(),\n estimatedTokens: estimateTokens(content),\n index,\n totalChunks: 0, // Will be updated after all chunks are created\n };\n }\n\n private formatFileContent(filePath: string, content: string): string {\n // Add clear file boundaries for Claude to parse\n return `===== FILE: ${filePath} =====\n${content}\n===== END: ${filePath} =====`;\n }\n\n private truncateContent(content: string, maxSize: number): string {\n if (content.length <= maxSize) {\n return content;\n }\n\n // Try to truncate at a reasonable point\n const truncateAt = maxSize - 100; // Leave room for truncation message\n const lastNewline = content.lastIndexOf(\"\\n\", truncateAt);\n const cutPoint = lastNewline > truncateAt * 0.5 ? lastNewline : truncateAt;\n\n return content.slice(0, cutPoint) + \"\\n\\n[... TRUNCATED - file too large ...]\";\n }\n\n getTotalChunks(): number {\n if (!this.chunks) {\n throw new Error(\"Chunks not prepared. Call prepareChunks() first.\");\n }\n return this.chunks.length;\n }\n\n getChunkSummary(): string {\n if (!this.chunks) {\n return \"Chunks not yet prepared\";\n }\n\n const totalFiles = this.chunks.reduce((sum, c) => sum + c.files.length, 0);\n const totalTokens = this.chunks.reduce((sum, c) => sum + c.estimatedTokens, 0);\n\n return `${totalFiles} files in ${this.chunks.length} chunks (~${totalTokens} tokens)`;\n }\n\n // Async generator for processing chunks one at a time\n async *iterateChunks(): AsyncGenerator<FileChunk> {\n const chunks = await this.prepareChunks();\n for (const chunk of chunks) {\n yield chunk;\n }\n }\n}\n","import { FileCollector, type CollectionResult } from \"./file-collector.js\";\nimport { ChunkManager, type FileChunk } from \"./chunk-manager.js\";\nimport { VaultIntegrator } from \"./vault-integrator.js\";\nimport { spawnClaudeAgent, isClaudeAvailable } from \"../utils/claude-sdk.js\";\nimport { loadConfig } from \"../utils/config.js\";\nimport type {\n Summary,\n ExtractedEntity,\n ArchitectureItem,\n ServiceItem,\n KnowledgeItem,\n} from \"./compaction-engine.js\";\n\nconst DISCOVERY_PROMPT = `You are a technical knowledge extractor analyzing a codebase. Extract information for a project knowledge base.\n\nPROJECT CONTEXT:\n- Language(s): {languages}\n- Project Type: {projectType}\n\nANALYZE THESE SOURCE FILES:\n\n{fileContents}\n\nExtract and format the following:\n\n## Entities\nFor each domain entity (data model, type, class, interface):\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 (e.g., MVC, Repository, Factory, Singleton, etc.)\n- **Description**: Brief explanation of how it's used\n- **Affected Files**: Relevant file paths\n\n## Services\nFor each service or component:\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 discovered:\n- **Topic**: What it's about\n- **Details**: The actual information\n\nGuidelines:\n- Only include sections that have content\n- Be concise but complete\n- Use exact file paths as shown\n- Focus on domain logic, not framework boilerplate\n- Identify patterns from code structure, not just naming\n`;\n\nexport interface DiscoverOptions {\n maxFiles?: number;\n maxChunkSize?: number;\n verbose?: boolean;\n}\n\nexport interface DiscoveryResult {\n summary: Summary;\n filesAnalyzed: number;\n chunksProcessed: number;\n duration: number;\n integrated: boolean;\n}\n\nexport class AutoDiscover {\n private projectPath: string;\n private verbose: boolean;\n\n constructor(projectPath: string, verbose = false) {\n this.projectPath = projectPath;\n this.verbose = verbose;\n }\n\n async discover(options?: DiscoverOptions): Promise<DiscoveryResult> {\n const startTime = Date.now();\n const config = await loadConfig(this.projectPath);\n\n const maxFiles = options?.maxFiles ?? config.discover.maxFiles;\n const maxChunkSize = options?.maxChunkSize ?? config.discover.maxChunkSize;\n\n this.log(\"Discovering codebase...\\n\");\n\n // Step 1: Collect files\n const collector = new FileCollector(this.projectPath);\n const collection = await collector.collect({ maxFiles });\n\n this.log(`Detected: ${collection.languages.join(\", \")} (${collection.projectType} project)`);\n this.log(`Collected: ${collection.totalFilesScanned} files → ${collection.files.length} prioritized`);\n\n if (collection.files.length === 0) {\n this.log(\"No source files found to analyze.\");\n return this.createEmptyResult(startTime);\n }\n\n // Step 2: Check Claude availability\n const claudeAvailable = await isClaudeAvailable();\n if (!claudeAvailable) {\n this.log(\"Claude CLI not available. Using fallback analysis...\");\n return this.fallbackDiscovery(collection, startTime);\n }\n\n // Step 3: Prepare chunks\n const chunkManager = new ChunkManager(collection.files, { maxChunkSize });\n const chunks = await chunkManager.prepareChunks();\n\n this.log(`Grouped into ${chunks.length} chunks\\n`);\n this.log(\"Analyzing with Claude...\");\n\n // Step 4: Analyze each chunk with Claude\n const partialSummaries: Summary[] = [];\n let chunksProcessed = 0;\n\n for (const chunk of chunks) {\n const chunkKB = Math.round(chunk.content.length / 1024);\n this.log(` [${chunk.index + 1}/${chunk.totalChunks}] Analyzing ${chunk.files.length} files (~${chunkKB}KB, ~${chunk.estimatedTokens} tokens)...`);\n\n try {\n const summary = await this.analyzeChunk(chunk, collection);\n partialSummaries.push(summary);\n chunksProcessed++;\n\n // Rate limiting between chunks\n if (chunk.index < chunks.length - 1) {\n await this.delay(1500);\n }\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n this.log(` Warning: Chunk ${chunk.index + 1} analysis failed: ${errorMsg}`);\n // Continue with other chunks\n }\n }\n\n if (partialSummaries.length === 0) {\n this.log(\"\\nNo successful analyses. Using fallback...\");\n return this.fallbackDiscovery(collection, startTime);\n }\n\n // Step 5: Merge summaries\n const mergedSummary = this.mergeSummaries(partialSummaries);\n\n // Step 6: Integrate into vault\n this.log(\"\\nIntegrating into vault...\");\n let integrated = false;\n\n try {\n const integrator = new VaultIntegrator(this.projectPath);\n await integrator.integrate(mergedSummary);\n integrated = true;\n\n this.log(` ${mergedSummary.entities.length} entities`);\n this.log(` ${mergedSummary.architecture.length} patterns`);\n this.log(` ${mergedSummary.services.length} services`);\n this.log(` ${mergedSummary.knowledge.length} knowledge items`);\n } catch (error) {\n this.log(` Warning: Vault integration failed: ${error}`);\n }\n\n const duration = Date.now() - startTime;\n this.log(`\\nDiscovery complete (${(duration / 1000).toFixed(1)}s)`);\n\n return {\n summary: mergedSummary,\n filesAnalyzed: collection.files.length,\n chunksProcessed,\n duration,\n integrated,\n };\n }\n\n private async analyzeChunk(\n chunk: FileChunk,\n collection: CollectionResult\n ): Promise<Summary> {\n const prompt = DISCOVERY_PROMPT\n .replace(\"{languages}\", collection.languages.join(\", \"))\n .replace(\"{projectType}\", collection.projectType)\n .replace(\"{fileContents}\", chunk.content);\n\n const response = await this.runWithProgressIndicators(\n () => spawnClaudeAgent(prompt, { timeout: 600000 }), // 10 minutes\n [\n { at: 60000, message: \" Still analyzing... (1 min)\" },\n { at: 180000, message: \" Still working... (3 min)\" },\n { at: 300000, message: \" Still working... (5 min)\" },\n { at: 480000, message: \" Almost timing out... (8 min)\" },\n ]\n );\n\n return this.parseResponse(response, chunk);\n }\n\n private async runWithProgressIndicators<T>(\n task: () => Promise<T>,\n indicators: { at: number; message: string }[]\n ): Promise<T> {\n const timers: NodeJS.Timeout[] = [];\n\n // Set up progress indicators\n for (const indicator of indicators) {\n const timer = setTimeout(() => {\n this.log(indicator.message);\n }, indicator.at);\n timers.push(timer);\n }\n\n try {\n const result = await task();\n return result;\n } finally {\n // Clean up timers\n for (const timer of timers) {\n clearTimeout(timer);\n }\n }\n }\n\n private parseResponse(response: string, _chunk: FileChunk): Summary {\n const summary: Summary = {\n sessionId: `discover-${Date.now()}`,\n content: response,\n entities: [],\n architecture: [],\n services: [],\n knowledge: [],\n };\n\n // Parse entities\n const entitiesMatch = response.match(/## Entities\\n([\\s\\S]*?)(?=\\n## |$)/);\n if (entitiesMatch) {\n summary.entities = this.parseEntities(entitiesMatch[1]);\n }\n\n // Parse architecture\n const archMatch = response.match(/## Architecture\\n([\\s\\S]*?)(?=\\n## |$)/);\n if (archMatch) {\n summary.architecture = this.parseArchitecture(archMatch[1]);\n }\n\n // Parse services\n const servicesMatch = response.match(/## Services\\n([\\s\\S]*?)(?=\\n## |$)/);\n if (servicesMatch) {\n summary.services = this.parseServices(servicesMatch[1]);\n }\n\n // Parse knowledge\n const knowledgeMatch = response.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 mergeSummaries(summaries: Summary[]): Summary {\n const merged: Summary = {\n sessionId: `discover-${Date.now()}`,\n content: summaries.map((s) => s.content).join(\"\\n\\n---\\n\\n\"),\n entities: [],\n architecture: [],\n services: [],\n knowledge: [],\n };\n\n // Merge and deduplicate by name\n const entityMap = new Map<string, ExtractedEntity>();\n const archMap = new Map<string, ArchitectureItem>();\n const serviceMap = new Map<string, ServiceItem>();\n const knowledgeMap = new Map<string, KnowledgeItem>();\n\n for (const summary of summaries) {\n for (const entity of summary.entities) {\n const key = entity.name.toLowerCase();\n if (!entityMap.has(key)) {\n entityMap.set(key, entity);\n }\n }\n\n for (const arch of summary.architecture) {\n const key = arch.pattern.toLowerCase();\n if (!archMap.has(key)) {\n archMap.set(key, arch);\n }\n }\n\n for (const service of summary.services) {\n const key = service.name.toLowerCase();\n if (!serviceMap.has(key)) {\n serviceMap.set(key, service);\n }\n }\n\n for (const knowledge of summary.knowledge) {\n const key = knowledge.topic.toLowerCase();\n if (!knowledgeMap.has(key)) {\n knowledgeMap.set(key, knowledge);\n }\n }\n }\n\n merged.entities = Array.from(entityMap.values());\n merged.architecture = Array.from(archMap.values());\n merged.services = Array.from(serviceMap.values());\n merged.knowledge = Array.from(knowledgeMap.values());\n\n return merged;\n }\n\n private async fallbackDiscovery(\n collection: CollectionResult,\n startTime: number\n ): Promise<DiscoveryResult> {\n // Basic discovery without Claude - just catalog files\n const summary: Summary = {\n sessionId: `discover-fallback-${Date.now()}`,\n content: \"Fallback discovery - Claude unavailable\",\n entities: [],\n architecture: [],\n services: [],\n knowledge: [\n {\n topic: \"Project Languages\",\n details: collection.languages.join(\", \"),\n },\n {\n topic: \"Project Type\",\n details: collection.projectType,\n },\n {\n topic: \"Source Files Discovered\",\n details: `${collection.files.length} files categorized by type`,\n },\n ],\n };\n\n // Group files by category\n const categories = new Map<string, string[]>();\n for (const file of collection.files) {\n if (!categories.has(file.category)) {\n categories.set(file.category, []);\n }\n categories.get(file.category)!.push(file.path);\n }\n\n for (const [category, files] of categories) {\n if (category !== \"other\" && category !== \"test\") {\n summary.knowledge.push({\n topic: `${category.charAt(0).toUpperCase() + category.slice(1)} Files`,\n details: files.slice(0, 10).join(\", \") + (files.length > 10 ? ` (+${files.length - 10} more)` : \"\"),\n });\n }\n }\n\n // Try to integrate\n let integrated = false;\n try {\n const integrator = new VaultIntegrator(this.projectPath);\n await integrator.integrate(summary);\n integrated = true;\n this.log(\"\\nFallback discovery integrated into vault\");\n } catch {\n this.log(\"\\nFallback discovery completed (vault integration failed)\");\n }\n\n return {\n summary,\n filesAnalyzed: collection.files.length,\n chunksProcessed: 0,\n duration: Date.now() - startTime,\n integrated,\n };\n }\n\n private createEmptyResult(startTime: number): DiscoveryResult {\n return {\n summary: {\n sessionId: `discover-empty-${Date.now()}`,\n content: \"\",\n entities: [],\n architecture: [],\n services: [],\n knowledge: [],\n },\n filesAnalyzed: 0,\n chunksProcessed: 0,\n duration: Date.now() - startTime,\n integrated: false,\n };\n }\n\n private log(message: string): void {\n if (this.verbose) {\n console.log(message);\n }\n }\n\n private delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","import * as path from \"node:path\";\nimport { fileExists } from \"../utils/file-utils.js\";\nimport { AutoDiscover } from \"../core/auto-discover.js\";\n\nexport interface DiscoverCommandOptions {\n targetPath?: string;\n verbose?: boolean;\n}\n\nexport async function discover(options: DiscoverCommandOptions = {}): Promise<void> {\n const targetPath = path.resolve(options.targetPath || process.cwd());\n const verbose = options.verbose ?? true; // Default to verbose for CLI\n\n // Validate target path\n const exists = await fileExists(targetPath);\n if (!exists) {\n console.error(`Error: Target path does not exist: ${targetPath}`);\n process.exit(1);\n }\n\n // Check if CCKB is installed\n const kbPath = path.join(targetPath, \"cc-knowledge-base\");\n const kbExists = await fileExists(kbPath);\n if (!kbExists) {\n console.error(\"Error: CCKB is not installed in this project.\");\n console.error(\"Run 'cckb init' first to install CCKB.\");\n process.exit(1);\n }\n\n try {\n const autoDiscover = new AutoDiscover(targetPath, verbose);\n const result = await autoDiscover.discover();\n\n if (!result.integrated) {\n console.error(\"\\nWarning: Vault integration failed. Check the logs above.\");\n process.exit(1);\n }\n\n console.log(`\\nVault populated at: ${kbPath}/vault/`);\n } catch (error) {\n console.error(\"Discovery failed:\", error);\n process.exit(1);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAAA,YAAY,QAAQ;AACpB,YAAY,YAAY;AACxB,YAAY,UAAU;AACtB,SAAS,qBAAqB;AAW9B,IAAM,YAAiB,aAAQ,cAAc,YAAY,GAAG,CAAC;AAG7D,SAAS,kBAA0B;AACjC,MAAI,MAAM;AACV,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAM,cAAmB,UAAK,KAAK,cAAc;AACjD,QAAW,kBAAW,WAAW,GAAG;AAClC,aAAO;AAAA,IACT;AACA,UAAW,aAAQ,GAAG;AAAA,EACxB;AAEA,SAAY,aAAQ,WAAW,OAAO;AACxC;AAEA,IAAM,eAAe,gBAAgB;AACrC,IAAM,gBAAqB,UAAK,cAAc,WAAW;AAMzD,eAAsB,QACpB,YACA,UAA0B,CAAC,GACZ;AACf,QAAM,eAAoB,aAAQ,UAAU;AAE5C,UAAQ,IAAI,uBAAuB,YAAY,EAAE;AAGjD,QAAM,mBAAmB,YAAY;AACrC,QAAM,0BAA0B,cAAc,QAAQ,KAAK;AAG3D,QAAM,yBAAyB,YAAY;AAG3C,QAAM,kBAAkB,YAAY;AAGpC,QAAM,iBAAiB,YAAY;AAGnC,QAAM,aAAa,YAAY;AAG/B,QAAM,eAAe,YAAY;AAGjC,QAAM,gBAAgB,YAAY;AAElC,UAAQ,IAAI,gCAAgC;AAC5C,UAAQ,IAAI,eAAe;AAC3B,UAAQ,IAAI,gDAAgD;AAC5D,UAAQ,IAAI,yDAAyD;AACrE,UAAQ,IAAI,mEAAmE;AACjF;AAEA,eAAe,mBAAmB,YAAmC;AACnE,QAAM,SAAS,MAAM,WAAW,UAAU;AAC1C,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,+BAA+B,UAAU,EAAE;AAAA,EAC7D;AAEA,QAAM,QAAQ,MAAS,QAAK,UAAU;AACtC,MAAI,CAAC,MAAM,YAAY,GAAG;AACxB,UAAM,IAAI,MAAM,mCAAmC,UAAU,EAAE;AAAA,EACjE;AACF;AAEA,eAAe,0BACb,YACA,OACe;AACf,QAAM,SAAc,UAAK,YAAY,mBAAmB;AACxD,QAAM,SAAS,MAAM,WAAW,MAAM;AAEtC,MAAI,UAAU,CAAC,OAAO;AACpB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAe,yBAAyB,YAAmC;AACzE,QAAM,cAAc;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,aAAW,OAAO,aAAa;AAC7B,UAAM,UAAe,UAAK,YAAY,GAAG,CAAC;AAAA,EAC5C;AAEA,UAAQ,IAAI,+BAA+B;AAC7C;AAEA,eAAe,kBAAkB,YAAmC;AAClE,QAAM,aAAa;AAAA,IACjB,EAAE,KAAK,kBAAkB,MAAM,mCAAmC;AAAA,IAClE;AAAA,MACE,KAAK;AAAA,MACL,MAAM;AAAA,IACR;AAAA,IACA;AAAA,MACE,KAAK;AAAA,MACL,MAAM;AAAA,IACR;AAAA,IACA;AAAA,MACE,KAAK;AAAA,MACL,MAAM;AAAA,IACR;AAAA,IACA;AAAA,MACE,KAAK;AAAA,MACL,MAAM;AAAA,IACR;AAAA,IACA;AAAA,MACE,KAAK;AAAA,MACL,MAAM;AAAA,IACR;AAAA,EACF;AAEA,aAAW,QAAQ,YAAY;AAC7B,UAAM,UAAe,UAAK,eAAe,KAAK,GAAG;AACjD,UAAM,WAAgB,UAAK,YAAY,KAAK,IAAI;AAEhD,UAAM,UAAU,MAAM,aAAa,OAAO;AAC1C,QAAI,SAAS;AACX,YAAM,cAAc,UAAU,OAAO;AAAA,IACvC;AAAA,EACF;AAGA,QAAM;AAAA,IACC,UAAK,YAAY,0CAA0C;AAAA,IAChE;AAAA,EACF;AAEA,UAAQ,IAAI,+BAA+B;AAC7C;AAEA,eAAe,iBAAiB,YAAmC;AACjE,QAAM,aAAkB;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,UAAU,YAAY,cAAc;AAE1C,UAAQ,IAAI,8BAA8B;AAC5C;AAEA,eAAe,aAAa,YAAmC;AAC7D,QAAM,YAAiB,UAAK,YAAY,SAAS;AACjD,QAAM,eAAoB,UAAK,WAAW,eAAe;AAEzD,QAAM,UAAU,SAAS;AAGzB,MAAI,WACD,MAAM,SAAkC,YAAY,KAAM,CAAC;AAG9D,QAAM,eAAoB,UAAK,eAAe,oBAAoB;AAClE,QAAM,eAAe,MAAM;AAAA,IACzB;AAAA,EACF;AAEA,MAAI,CAAC,cAAc;AACjB,UAAM,IAAI,MAAM,8BAA8B;AAAA,EAChD;AAGA,QAAM,gBAAiB,SAAS,SAAuC,CAAC;AACxE,QAAM,WAAW,aAAa;AAE9B,WAAS,QAAQ,WAAW,eAAe,QAAQ;AAEnD,QAAM,UAAU,cAAc,QAAQ;AAEtC,UAAQ,IAAI,gCAAgC;AAC9C;AAEA,SAAS,WACP,UACA,UAC2B;AAC3B,QAAM,SAAS,EAAE,GAAG,SAAS;AAE7B,aAAW,CAAC,UAAU,KAAK,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACxD,QAAI,CAAC,OAAO,QAAQ,GAAG;AACrB,aAAO,QAAQ,IAAI,CAAC;AAAA,IACtB;AAGA,eAAW,QAAQ,OAAO;AACxB,YAAM,UAAU;AAChB,YAAM,UAAU,QAAQ;AAExB,UAAI,SAAS,SAAS,MAAM,GAAG;AAE7B,eAAO,QAAQ,IAAI,OAAO,QAAQ,EAAE,OAAO,CAAC,MAAM;AAChD,gBAAM,cAAe,EAA8B;AAGnD,iBAAO,CAAC,aAAa,SAAS,MAAM;AAAA,QACtC,CAAC;AAAA,MACH;AAEA,aAAO,QAAQ,EAAE,KAAK,IAAI;AAAA,IAC5B;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAe,eAAe,YAAmC;AAC/D,QAAM,eAAoB,UAAK,YAAY,WAAW;AACtD,QAAM,eAAoB,UAAK,eAAe,gBAAgB;AAE9D,QAAM,WAAW,MAAM,aAAa,YAAY;AAChD,MAAI,CAAC,UAAU;AACb,UAAM,IAAI,MAAM,mCAAmC;AAAA,EACrD;AAEA,QAAM,SAAS;AAEf,MAAI,WAAW,MAAM,aAAa,YAAY;AAE9C,MAAI,UAAU;AAEZ,QAAI,SAAS,SAAS,MAAM,GAAG;AAE7B,YAAM,QAAQ;AACd,iBAAW,SAAS,QAAQ,OAAO,SAAS,KAAK,CAAC;AAAA,IACpD,OAAO;AAEL,iBAAW,SAAS,QAAQ,IAAI,SAAS;AAAA,IAC3C;AACA,UAAM,cAAc,cAAc,QAAQ;AAAA,EAC5C,OAAO;AAEL,UAAM,cAAc,cAAc,QAAQ;AAAA,EAC5C;AAEA,UAAQ,IAAI,2CAA2C;AACzD;AAEA,eAAe,gBAAgB,YAAmC;AAChE,QAAM,gBAAqB,UAAK,YAAY,YAAY;AAExD,QAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,WAAY,MAAM,aAAa,aAAa,KAAM;AAGtD,MAAI,SAAS,SAAS,gCAAgC,GAAG;AACvD;AAAA,EACF;AAEA,aAAW,SAAS,QAAQ,IAAI,OAAO,QAAQ,KAAK,IAAI,IAAI;AAC5D,QAAM,cAAc,eAAe,QAAQ;AAE3C,UAAQ,IAAI,sBAAsB;AACpC;;;AClSA,YAAYA,SAAQ;AACpB,YAAYC,WAAU;AAKtB,IAAM,wBAAmF;AAAA,EACvF,gBAAgB,EAAE,UAAU,cAAc,aAAa,OAAO;AAAA,EAC9D,iBAAiB,EAAE,UAAU,cAAc,aAAa,OAAO;AAAA,EAC/D,cAAc,EAAE,UAAU,QAAQ,aAAa,OAAO;AAAA,EACtD,UAAU,EAAE,UAAU,MAAM,aAAa,KAAK;AAAA,EAC9C,oBAAoB,EAAE,UAAU,UAAU,aAAa,SAAS;AAAA,EAChE,kBAAkB,EAAE,UAAU,UAAU,aAAa,SAAS;AAAA,EAC9D,YAAY,EAAE,UAAU,UAAU,aAAa,SAAS;AAAA,EACxD,WAAW,EAAE,UAAU,QAAQ,aAAa,OAAO;AAAA,EACnD,gBAAgB,EAAE,UAAU,QAAQ,aAAa,OAAO;AAAA,EACxD,YAAY,EAAE,UAAU,UAAU,aAAa,SAAS;AAAA,EACxD,WAAW,EAAE,UAAU,QAAQ,aAAa,OAAO;AAAA,EACnD,iBAAiB,EAAE,UAAU,OAAO,aAAa,MAAM;AACzD;AAGA,IAAM,yBAAiD;AAAA,EACrD,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,SAAS;AAAA,EACT,OAAO;AAAA,EACP,OAAO;AAAA,EACP,QAAQ;AACV;AA4BO,IAAM,gBAAN,MAAoB;AAAA,EACjB;AAAA,EAER,YAAY,aAAqB;AAC/B,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,MAAM,QAAQ,SAAqD;AACjE,UAAM,SAAS,MAAM,WAAW,KAAK,WAAW;AAChD,UAAM,gBAAgB;AAAA,MACpB,UAAU,SAAS,YAAY,OAAO,SAAS;AAAA,MAC/C,iBAAiB,SAAS,mBAAmB,OAAO,SAAS;AAAA,MAC7D,oBAAoB,SAAS,sBAAsB,OAAO,SAAS;AAAA,IACrE;AAGA,UAAM,EAAE,WAAW,YAAY,IAAI,MAAM,KAAK,gBAAgB;AAG9D,UAAM,iBAAiB,MAAM,KAAK,mBAAmB,cAAc,eAAe;AAGlF,UAAM,WAA4B,CAAC;AACnC,QAAI,eAAe;AAEnB,UAAM,KAAK;AAAA,MACT,KAAK;AAAA,MACL,OAAO,UAAU,UAAU;AACzB;AACA,cAAM,eAAoB,eAAS,KAAK,aAAa,QAAQ;AAG7D,YAAI,KAAK,aAAa,cAAc,cAAc,GAAG;AACnD;AAAA,QACF;AAEA,cAAM,MAAW,cAAQ,QAAQ;AACjC,cAAM,WAAW,uBAAuB,GAAG;AAG3C,YAAI,CAAC,YAAY,CAAC,cAAc,mBAAmB,SAAS,QAAQ,GAAG;AACrE;AAAA,QACF;AAEA,cAAM,WAAW,KAAK,eAAe,YAAY;AACjD,cAAM,WAAW,KAAK,kBAAkB,cAAc,UAAU,MAAM,IAAI;AAE1E,iBAAS,KAAK;AAAA,UACZ,MAAM;AAAA,UACN,cAAc;AAAA,UACd;AAAA,UACA;AAAA,UACA,MAAM,MAAM;AAAA,UACZ;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAGA,aAAS,KAAK,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ;AAC/C,UAAM,eAAe,SAAS,MAAM,GAAG,cAAc,QAAQ;AAE7D,WAAO;AAAA,MACL,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA,mBAAmB;AAAA,IACrB;AAAA,EACF;AAAA,EAEA,MAAM,kBAAyE;AAC7E,UAAM,WAAW,oBAAI,IAAY;AACjC,QAAI,cAAc;AAGlB,eAAW,CAAC,UAAU,IAAI,KAAK,OAAO,QAAQ,qBAAqB,GAAG;AACpE,UAAI,SAAS,WAAW,GAAG,GAAG;AAE5B;AAAA,MACF;AACA,YAAM,eAAoB,WAAK,KAAK,aAAa,QAAQ;AACzD,UAAI,MAAM,WAAW,YAAY,GAAG;AAClC,iBAAS,IAAI,KAAK,QAAQ;AAC1B,YAAI,gBAAgB,WAAW;AAC7B,wBAAc,KAAK;AAAA,QACrB;AAAA,MACF;AAAA,IACF;AAGA,UAAM,kBAAuB,WAAK,KAAK,aAAa,cAAc;AAClE,QAAI,MAAM,WAAW,eAAe,GAAG;AACrC,YAAM,UAAU,MAAM,aAAa,eAAe;AAClD,UAAI,SAAS;AACX,YAAI;AACF,gBAAM,MAAM,KAAK,MAAM,OAAO;AAC9B,gBAAM,OAAO,EAAE,GAAG,IAAI,cAAc,GAAG,IAAI,gBAAgB;AAC3D,cAAI,KAAK,cAAc,MAAM,WAAgB,WAAK,KAAK,aAAa,eAAe,CAAC,GAAG;AACrF,qBAAS,IAAI,YAAY;AAAA,UAC3B,OAAO;AACL,qBAAS,IAAI,YAAY;AAAA,UAC3B;AAAA,QACF,QAAQ;AACN,mBAAS,IAAI,YAAY;AAAA,QAC3B;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,WAAW,MAAM,KAAK,QAAQ;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,mBAAmB,oBAAiD;AAChF,UAAM,WAAqB;AAAA;AAAA,MAEzB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAGA,UAAM,gBAAqB,WAAK,KAAK,aAAa,YAAY;AAC9D,UAAM,YAAY,MAAM,aAAa,aAAa;AAClD,QAAI,WAAW;AACb,YAAM,QAAQ,UACX,MAAM,IAAI,EACV,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,EACzB,OAAO,CAAC,SAAS,QAAQ,CAAC,KAAK,WAAW,GAAG,CAAC;AACjD,eAAS,KAAK,GAAG,KAAK;AAAA,IACxB;AAGA,aAAS,KAAK,GAAG,kBAAkB;AAEnC,WAAO;AAAA,EACT;AAAA,EAEQ,aAAa,cAAsB,UAA6B;AACtE,UAAM,iBAAiB,aAAa,QAAQ,OAAO,GAAG;AAEtD,eAAW,WAAW,UAAU;AAC9B,UAAI,KAAK,aAAa,gBAAgB,OAAO,GAAG;AAC9C,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,aAAa,UAAkB,SAA0B;AAE/D,UAAM,oBAAoB,QAAQ,QAAQ,OAAO,GAAG;AAGpD,QAAI,kBAAkB,WAAW,GAAG,GAAG;AACrC,aAAO;AAAA,IACT;AAGA,QAAI,QAAQ,kBACT,QAAQ,OAAO,KAAK,EACpB,QAAQ,SAAS,cAAc,EAC/B,QAAQ,OAAO,OAAO,EACtB,QAAQ,iBAAiB,IAAI,EAC7B,QAAQ,OAAO,GAAG;AAGrB,QAAI,CAAC,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,WAAW,IAAI,GAAG;AACrD,cAAQ,UAAU;AAAA,IACpB;AAGA,QAAI,MAAM,SAAS,GAAG,GAAG;AACvB,cAAQ,QAAQ;AAAA,IAClB;AAEA,QAAI;AACF,YAAM,KAAK,IAAI,OAAO,KAAK;AAC3B,aAAO,GAAG,KAAK,QAAQ;AAAA,IACzB,QAAQ;AAEN,aAAO,SAAS,SAAS,QAAQ,QAAQ,OAAO,EAAE,CAAC;AAAA,IACrD;AAAA,EACF;AAAA,EAEQ,eAAe,cAAoC;AACzD,UAAM,YAAY,aAAa,YAAY;AAC3C,UAAM,WAAgB,eAAS,SAAS;AAGxC,QACE,wBAAwB,KAAK,SAAS,KACtC,gBAAgB,KAAK,SAAS,KAC9B,WAAW,KAAK,SAAS,KACzB,YAAY,KAAK,SAAS,GAC1B;AACA,aAAO;AAAA,IACT;AAGA,QACE,mCAAmC,KAAK,QAAQ,KAChD,kCAAkC,KAAK,SAAS,GAChD;AACA,aAAO;AAAA,IACT;AAGA,QACE,gDAAgD,KAAK,SAAS,KAC9D,gCAAgC,KAAK,SAAS,GAC9C;AACA,aAAO;AAAA,IACT;AAGA,QACE,sDAAsD,KAAK,SAAS,KACpE,yCAAyC,KAAK,SAAS,GACvD;AACA,aAAO;AAAA,IACT;AAGA,QACE,0BAA0B,KAAK,SAAS,KACxC,cAAc,KAAK,SAAS,KAC5B,SAAS,WAAW,GAAG,GACvB;AACA,aAAO;AAAA,IACT;AAGA,QACE,2CAA2C,KAAK,SAAS,KACzD,0BAA0B,KAAK,SAAS,GACxC;AACA,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,kBACN,cACA,UACA,MACQ;AACR,QAAI,QAAQ;AAGZ,UAAM,iBAA+C;AAAA,MACnD,OAAO;AAAA,MACP,OAAO;AAAA,MACP,SAAS;AAAA,MACT,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,MAAM;AAAA,IACR;AACA,aAAS,eAAe,QAAQ;AAGhC,UAAM,QAAQ,aAAa,MAAM,GAAG,EAAE;AACtC,aAAS,QAAQ;AAGjB,QAAI,OAAO,IAAM,UAAS;AAC1B,QAAI,OAAO,IAAO,UAAS;AAC3B,QAAI,OAAO,IAAQ,UAAS;AAG5B,QAAI,SAAS,KAAK,YAAY,EAAG,UAAS;AAE1C,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,cACZ,KACA,UACe;AACf,QAAI;AACF,YAAM,UAAU,MAAS,YAAQ,KAAK,EAAE,eAAe,KAAK,CAAC;AAE7D,iBAAW,SAAS,SAAS;AAC3B,cAAM,WAAgB,WAAK,KAAK,MAAM,IAAI;AAE1C,YAAI,MAAM,YAAY,GAAG;AAEvB,cACE,MAAM,SAAS,kBACf,MAAM,SAAS,UACf,MAAM,SAAS,UACf,MAAM,SAAS,WACf,MAAM,SAAS,iBACf,MAAM,SAAS,YACf,MAAM,SAAS,YACf,MAAM,SAAS,WACf,MAAM,SAAS,QACf;AACA;AAAA,UACF;AACA,gBAAM,KAAK,cAAc,UAAU,QAAQ;AAAA,QAC7C,WAAW,MAAM,OAAO,GAAG;AACzB,cAAI;AACF,kBAAM,QAAQ,MAAS,SAAK,QAAQ;AACpC,kBAAM,SAAS,UAAU,EAAE,MAAM,MAAM,KAAK,CAAC;AAAA,UAC/C,QAAQ;AAAA,UAER;AAAA,QACF;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AACF;;;ACxXA,IAAM,yBAAyB;AAG/B,SAAS,eAAe,MAAsB;AAC5C,SAAO,KAAK,KAAK,KAAK,SAAS,CAAC;AAClC;AAEO,IAAM,eAAN,MAAmB;AAAA,EAChB;AAAA,EACA;AAAA,EACA,SAA6B;AAAA,EAErC,YAAY,OAAwB,SAAwB;AAC1D,SAAK,QAAQ;AACb,SAAK,eAAe,SAAS,gBAAgB;AAAA,EAC/C;AAAA,EAEA,MAAM,gBAAsC;AAC1C,QAAI,KAAK,QAAQ;AACf,aAAO,KAAK;AAAA,IACd;AAEA,UAAM,SAAsB,CAAC;AAC7B,QAAI,eAAgC,CAAC;AACrC,QAAI,iBAAiB;AACrB,QAAI,cAAc;AAElB,eAAW,QAAQ,KAAK,OAAO;AAC7B,YAAM,UAAU,MAAM,aAAa,KAAK,YAAY;AACpD,UAAI,CAAC,QAAS;AAGd,YAAM,mBAAmB,KAAK,kBAAkB,KAAK,MAAM,OAAO;AAClE,YAAM,cAAc,iBAAiB;AAGrC,UAAI,cAAc,KAAK,cAAc;AAEnC,YAAI,aAAa,SAAS,GAAG;AAC3B,iBAAO,KAAK,KAAK,YAAY,cAAc,gBAAgB,OAAO,MAAM,CAAC;AACzE,yBAAe,CAAC;AAChB,2BAAiB;AACjB,wBAAc;AAAA,QAChB;AAGA,cAAM,mBAAmB,KAAK,gBAAgB,kBAAkB,KAAK,YAAY;AACjF,eAAO,KAAK,KAAK,YAAY,CAAC,IAAI,GAAG,kBAAkB,OAAO,MAAM,CAAC;AACrE;AAAA,MACF;AAGA,UAAI,cAAc,cAAc,KAAK,gBAAgB,aAAa,SAAS,GAAG;AAC5E,eAAO,KAAK,KAAK,YAAY,cAAc,gBAAgB,OAAO,MAAM,CAAC;AACzE,uBAAe,CAAC;AAChB,yBAAiB;AACjB,sBAAc;AAAA,MAChB;AAGA,mBAAa,KAAK,IAAI;AACtB,wBAAkB,mBAAmB;AACrC,qBAAe;AAAA,IACjB;AAGA,QAAI,aAAa,SAAS,GAAG;AAC3B,aAAO,KAAK,KAAK,YAAY,cAAc,gBAAgB,OAAO,MAAM,CAAC;AAAA,IAC3E;AAGA,eAAW,SAAS,QAAQ;AAC1B,YAAM,cAAc,OAAO;AAAA,IAC7B;AAEA,SAAK,SAAS;AACd,WAAO;AAAA,EACT;AAAA,EAEQ,YACN,OACA,SACA,OACW;AACX,WAAO;AAAA,MACL;AAAA,MACA,SAAS,QAAQ,KAAK;AAAA,MACtB,iBAAiB,eAAe,OAAO;AAAA,MACvC;AAAA,MACA,aAAa;AAAA;AAAA,IACf;AAAA,EACF;AAAA,EAEQ,kBAAkB,UAAkB,SAAyB;AAEnE,WAAO,eAAe,QAAQ;AAAA,EAChC,OAAO;AAAA,aACI,QAAQ;AAAA,EACnB;AAAA,EAEQ,gBAAgB,SAAiB,SAAyB;AAChE,QAAI,QAAQ,UAAU,SAAS;AAC7B,aAAO;AAAA,IACT;AAGA,UAAM,aAAa,UAAU;AAC7B,UAAM,cAAc,QAAQ,YAAY,MAAM,UAAU;AACxD,UAAM,WAAW,cAAc,aAAa,MAAM,cAAc;AAEhE,WAAO,QAAQ,MAAM,GAAG,QAAQ,IAAI;AAAA,EACtC;AAAA,EAEA,iBAAyB;AACvB,QAAI,CAAC,KAAK,QAAQ;AAChB,YAAM,IAAI,MAAM,kDAAkD;AAAA,IACpE;AACA,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEA,kBAA0B;AACxB,QAAI,CAAC,KAAK,QAAQ;AAChB,aAAO;AAAA,IACT;AAEA,UAAM,aAAa,KAAK,OAAO,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,MAAM,QAAQ,CAAC;AACzE,UAAM,cAAc,KAAK,OAAO,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,iBAAiB,CAAC;AAE7E,WAAO,GAAG,UAAU,aAAa,KAAK,OAAO,MAAM,aAAa,WAAW;AAAA,EAC7E;AAAA;AAAA,EAGA,OAAO,gBAA2C;AAChD,UAAM,SAAS,MAAM,KAAK,cAAc;AACxC,eAAW,SAAS,QAAQ;AAC1B,YAAM;AAAA,IACR;AAAA,EACF;AACF;;;AC5IA,IAAM,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2DlB,IAAM,eAAN,MAAmB;AAAA,EAChB;AAAA,EACA;AAAA,EAER,YAAY,aAAqB,UAAU,OAAO;AAChD,SAAK,cAAc;AACnB,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,MAAM,SAAS,SAAqD;AAClE,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,SAAS,MAAM,WAAW,KAAK,WAAW;AAEhD,UAAM,WAAW,SAAS,YAAY,OAAO,SAAS;AACtD,UAAM,eAAe,SAAS,gBAAgB,OAAO,SAAS;AAE9D,SAAK,IAAI,2BAA2B;AAGpC,UAAM,YAAY,IAAI,cAAc,KAAK,WAAW;AACpD,UAAM,aAAa,MAAM,UAAU,QAAQ,EAAE,SAAS,CAAC;AAEvD,SAAK,IAAI,aAAa,WAAW,UAAU,KAAK,IAAI,CAAC,KAAK,WAAW,WAAW,WAAW;AAC3F,SAAK,IAAI,cAAc,WAAW,iBAAiB,iBAAY,WAAW,MAAM,MAAM,cAAc;AAEpG,QAAI,WAAW,MAAM,WAAW,GAAG;AACjC,WAAK,IAAI,mCAAmC;AAC5C,aAAO,KAAK,kBAAkB,SAAS;AAAA,IACzC;AAGA,UAAM,kBAAkB,MAAM,kBAAkB;AAChD,QAAI,CAAC,iBAAiB;AACpB,WAAK,IAAI,sDAAsD;AAC/D,aAAO,KAAK,kBAAkB,YAAY,SAAS;AAAA,IACrD;AAGA,UAAM,eAAe,IAAI,aAAa,WAAW,OAAO,EAAE,aAAa,CAAC;AACxE,UAAM,SAAS,MAAM,aAAa,cAAc;AAEhD,SAAK,IAAI,gBAAgB,OAAO,MAAM;AAAA,CAAW;AACjD,SAAK,IAAI,0BAA0B;AAGnC,UAAM,mBAA8B,CAAC;AACrC,QAAI,kBAAkB;AAEtB,eAAW,SAAS,QAAQ;AAC1B,YAAM,UAAU,KAAK,MAAM,MAAM,QAAQ,SAAS,IAAI;AACtD,WAAK,IAAI,MAAM,MAAM,QAAQ,CAAC,IAAI,MAAM,WAAW,eAAe,MAAM,MAAM,MAAM,YAAY,OAAO,QAAQ,MAAM,eAAe,aAAa;AAEjJ,UAAI;AACF,cAAM,UAAU,MAAM,KAAK,aAAa,OAAO,UAAU;AACzD,yBAAiB,KAAK,OAAO;AAC7B;AAGA,YAAI,MAAM,QAAQ,OAAO,SAAS,GAAG;AACnC,gBAAM,KAAK,MAAM,IAAI;AAAA,QACvB;AAAA,MACF,SAAS,OAAO;AACd,cAAM,WAAW,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACtE,aAAK,IAAI,sBAAsB,MAAM,QAAQ,CAAC,qBAAqB,QAAQ,EAAE;AAAA,MAE/E;AAAA,IACF;AAEA,QAAI,iBAAiB,WAAW,GAAG;AACjC,WAAK,IAAI,6CAA6C;AACtD,aAAO,KAAK,kBAAkB,YAAY,SAAS;AAAA,IACrD;AAGA,UAAM,gBAAgB,KAAK,eAAe,gBAAgB;AAG1D,SAAK,IAAI,6BAA6B;AACtC,QAAI,aAAa;AAEjB,QAAI;AACF,YAAM,aAAa,IAAI,gBAAgB,KAAK,WAAW;AACvD,YAAM,WAAW,UAAU,aAAa;AACxC,mBAAa;AAEb,WAAK,IAAI,KAAK,cAAc,SAAS,MAAM,WAAW;AACtD,WAAK,IAAI,KAAK,cAAc,aAAa,MAAM,WAAW;AAC1D,WAAK,IAAI,KAAK,cAAc,SAAS,MAAM,WAAW;AACtD,WAAK,IAAI,KAAK,cAAc,UAAU,MAAM,kBAAkB;AAAA,IAChE,SAAS,OAAO;AACd,WAAK,IAAI,wCAAwC,KAAK,EAAE;AAAA,IAC1D;AAEA,UAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,SAAK,IAAI;AAAA,uBAA0B,WAAW,KAAM,QAAQ,CAAC,CAAC,IAAI;AAElE,WAAO;AAAA,MACL,SAAS;AAAA,MACT,eAAe,WAAW,MAAM;AAAA,MAChC;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,aACZ,OACA,YACkB;AAClB,UAAM,SAAS,iBACZ,QAAQ,eAAe,WAAW,UAAU,KAAK,IAAI,CAAC,EACtD,QAAQ,iBAAiB,WAAW,WAAW,EAC/C,QAAQ,kBAAkB,MAAM,OAAO;AAE1C,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B,MAAM,iBAAiB,QAAQ,EAAE,SAAS,IAAO,CAAC;AAAA;AAAA,MAClD;AAAA,QACE,EAAE,IAAI,KAAO,SAAS,mCAAmC;AAAA,QACzD,EAAE,IAAI,MAAQ,SAAS,iCAAiC;AAAA,QACxD,EAAE,IAAI,KAAQ,SAAS,iCAAiC;AAAA,QACxD,EAAE,IAAI,MAAQ,SAAS,qCAAqC;AAAA,MAC9D;AAAA,IACF;AAEA,WAAO,KAAK,cAAc,UAAU,KAAK;AAAA,EAC3C;AAAA,EAEA,MAAc,0BACZ,MACA,YACY;AACZ,UAAM,SAA2B,CAAC;AAGlC,eAAW,aAAa,YAAY;AAClC,YAAM,QAAQ,WAAW,MAAM;AAC7B,aAAK,IAAI,UAAU,OAAO;AAAA,MAC5B,GAAG,UAAU,EAAE;AACf,aAAO,KAAK,KAAK;AAAA,IACnB;AAEA,QAAI;AACF,YAAM,SAAS,MAAM,KAAK;AAC1B,aAAO;AAAA,IACT,UAAE;AAEA,iBAAW,SAAS,QAAQ;AAC1B,qBAAa,KAAK;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,cAAc,UAAkB,QAA4B;AAClE,UAAM,UAAmB;AAAA,MACvB,WAAW,YAAY,KAAK,IAAI,CAAC;AAAA,MACjC,SAAS;AAAA,MACT,UAAU,CAAC;AAAA,MACX,cAAc,CAAC;AAAA,MACf,UAAU,CAAC;AAAA,MACX,WAAW,CAAC;AAAA,IACd;AAGA,UAAM,gBAAgB,SAAS,MAAM,oCAAoC;AACzE,QAAI,eAAe;AACjB,cAAQ,WAAW,KAAK,cAAc,cAAc,CAAC,CAAC;AAAA,IACxD;AAGA,UAAM,YAAY,SAAS,MAAM,wCAAwC;AACzE,QAAI,WAAW;AACb,cAAQ,eAAe,KAAK,kBAAkB,UAAU,CAAC,CAAC;AAAA,IAC5D;AAGA,UAAM,gBAAgB,SAAS,MAAM,oCAAoC;AACzE,QAAI,eAAe;AACjB,cAAQ,WAAW,KAAK,cAAc,cAAc,CAAC,CAAC;AAAA,IACxD;AAGA,UAAM,iBAAiB,SAAS,MAAM,qCAAqC;AAC3E,QAAI,gBAAgB;AAClB,cAAQ,YAAY,KAAK,eAAe,eAAe,CAAC,CAAC;AAAA,IAC3D;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,cAAc,SAAoC;AACxD,UAAM,WAA8B,CAAC;AACrC,UAAM,SAAS,QAAQ,MAAM,uBAAuB;AAEpD,eAAW,SAAS,QAAQ;AAC1B,UAAI,CAAC,MAAM,KAAK,EAAG;AAEnB,YAAM,YAAY,MAAM,MAAM,sBAAsB;AACpD,YAAM,gBAAgB,MAAM,MAAM,0BAA0B;AAC5D,YAAM,kBAAkB,MAAM,MAAM,4BAA4B;AAChE,YAAM,iBAAiB,MAAM,MAAM,2BAA2B;AAE9D,UAAI,WAAW;AACb,iBAAS,KAAK;AAAA,UACZ,MAAM,UAAU,CAAC,EAAE,KAAK;AAAA,UACxB,UAAU,gBAAgB,CAAC,EAAE,KAAK;AAAA,UAClC,YAAY,kBAAkB,CAAC,EAAE,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC;AAAA,UACrE,WAAW,iBAAiB,CAAC,EAAE,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC;AAAA,QACrE,CAAC;AAAA,MACH;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,kBAAkB,SAAqC;AAC7D,UAAM,QAA4B,CAAC;AACnC,UAAM,SAAS,QAAQ,MAAM,0BAA0B;AAEvD,eAAW,SAAS,QAAQ;AAC1B,UAAI,CAAC,MAAM,KAAK,EAAG;AAEnB,YAAM,eAAe,MAAM,MAAM,yBAAyB;AAC1D,YAAM,YAAY,MAAM,MAAM,6BAA6B;AAC3D,YAAM,aAAa,MAAM,MAAM,gCAAgC;AAE/D,UAAI,cAAc;AAChB,cAAM,KAAK;AAAA,UACT,SAAS,aAAa,CAAC,EAAE,KAAK;AAAA,UAC9B,aAAa,YAAY,CAAC,EAAE,KAAK,KAAK;AAAA,UACtC,eAAe,aAAa,CAAC,EAAE,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC;AAAA,QACrE,CAAC;AAAA,MACH;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,cAAc,SAAgC;AACpD,UAAM,QAAuB,CAAC;AAC9B,UAAM,SAAS,QAAQ,MAAM,uBAAuB;AAEpD,eAAW,SAAS,QAAQ;AAC1B,UAAI,CAAC,MAAM,KAAK,EAAG;AAEnB,YAAM,YAAY,MAAM,MAAM,sBAAsB;AACpD,YAAM,gBAAgB,MAAM,MAAM,0BAA0B;AAC5D,YAAM,eAAe,MAAM,MAAM,yBAAyB;AAC1D,YAAM,eAAe,MAAM,MAAM,yBAAyB;AAE1D,UAAI,WAAW;AACb,cAAM,KAAK;AAAA,UACT,MAAM,UAAU,CAAC,EAAE,KAAK;AAAA,UACxB,UAAU,gBAAgB,CAAC,EAAE,KAAK;AAAA,UAClC,SAAS,eAAe,CAAC,EAAE,KAAK,KAAK;AAAA,UACrC,SAAS,eAAe,CAAC,EAAE,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC;AAAA,QACjE,CAAC;AAAA,MACH;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,eAAe,SAAkC;AACvD,UAAM,QAAyB,CAAC;AAChC,UAAM,SAAS,QAAQ,MAAM,wBAAwB;AAErD,eAAW,SAAS,QAAQ;AAC1B,UAAI,CAAC,MAAM,KAAK,EAAG;AAEnB,YAAM,aAAa,MAAM,MAAM,uBAAuB;AACtD,YAAM,eAAe,MAAM,MAAM,yBAAyB;AAE1D,UAAI,YAAY;AACd,cAAM,KAAK;AAAA,UACT,OAAO,WAAW,CAAC,EAAE,KAAK;AAAA,UAC1B,SAAS,eAAe,CAAC,EAAE,KAAK,KAAK;AAAA,QACvC,CAAC;AAAA,MACH;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,eAAe,WAA+B;AACpD,UAAM,SAAkB;AAAA,MACtB,WAAW,YAAY,KAAK,IAAI,CAAC;AAAA,MACjC,SAAS,UAAU,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,aAAa;AAAA,MAC3D,UAAU,CAAC;AAAA,MACX,cAAc,CAAC;AAAA,MACf,UAAU,CAAC;AAAA,MACX,WAAW,CAAC;AAAA,IACd;AAGA,UAAM,YAAY,oBAAI,IAA6B;AACnD,UAAM,UAAU,oBAAI,IAA8B;AAClD,UAAM,aAAa,oBAAI,IAAyB;AAChD,UAAM,eAAe,oBAAI,IAA2B;AAEpD,eAAW,WAAW,WAAW;AAC/B,iBAAW,UAAU,QAAQ,UAAU;AACrC,cAAM,MAAM,OAAO,KAAK,YAAY;AACpC,YAAI,CAAC,UAAU,IAAI,GAAG,GAAG;AACvB,oBAAU,IAAI,KAAK,MAAM;AAAA,QAC3B;AAAA,MACF;AAEA,iBAAW,QAAQ,QAAQ,cAAc;AACvC,cAAM,MAAM,KAAK,QAAQ,YAAY;AACrC,YAAI,CAAC,QAAQ,IAAI,GAAG,GAAG;AACrB,kBAAQ,IAAI,KAAK,IAAI;AAAA,QACvB;AAAA,MACF;AAEA,iBAAW,WAAW,QAAQ,UAAU;AACtC,cAAM,MAAM,QAAQ,KAAK,YAAY;AACrC,YAAI,CAAC,WAAW,IAAI,GAAG,GAAG;AACxB,qBAAW,IAAI,KAAK,OAAO;AAAA,QAC7B;AAAA,MACF;AAEA,iBAAW,aAAa,QAAQ,WAAW;AACzC,cAAM,MAAM,UAAU,MAAM,YAAY;AACxC,YAAI,CAAC,aAAa,IAAI,GAAG,GAAG;AAC1B,uBAAa,IAAI,KAAK,SAAS;AAAA,QACjC;AAAA,MACF;AAAA,IACF;AAEA,WAAO,WAAW,MAAM,KAAK,UAAU,OAAO,CAAC;AAC/C,WAAO,eAAe,MAAM,KAAK,QAAQ,OAAO,CAAC;AACjD,WAAO,WAAW,MAAM,KAAK,WAAW,OAAO,CAAC;AAChD,WAAO,YAAY,MAAM,KAAK,aAAa,OAAO,CAAC;AAEnD,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,kBACZ,YACA,WAC0B;AAE1B,UAAM,UAAmB;AAAA,MACvB,WAAW,qBAAqB,KAAK,IAAI,CAAC;AAAA,MAC1C,SAAS;AAAA,MACT,UAAU,CAAC;AAAA,MACX,cAAc,CAAC;AAAA,MACf,UAAU,CAAC;AAAA,MACX,WAAW;AAAA,QACT;AAAA,UACE,OAAO;AAAA,UACP,SAAS,WAAW,UAAU,KAAK,IAAI;AAAA,QACzC;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,SAAS,WAAW;AAAA,QACtB;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,SAAS,GAAG,WAAW,MAAM,MAAM;AAAA,QACrC;AAAA,MACF;AAAA,IACF;AAGA,UAAM,aAAa,oBAAI,IAAsB;AAC7C,eAAW,QAAQ,WAAW,OAAO;AACnC,UAAI,CAAC,WAAW,IAAI,KAAK,QAAQ,GAAG;AAClC,mBAAW,IAAI,KAAK,UAAU,CAAC,CAAC;AAAA,MAClC;AACA,iBAAW,IAAI,KAAK,QAAQ,EAAG,KAAK,KAAK,IAAI;AAAA,IAC/C;AAEA,eAAW,CAAC,UAAU,KAAK,KAAK,YAAY;AAC1C,UAAI,aAAa,WAAW,aAAa,QAAQ;AAC/C,gBAAQ,UAAU,KAAK;AAAA,UACrB,OAAO,GAAG,SAAS,OAAO,CAAC,EAAE,YAAY,IAAI,SAAS,MAAM,CAAC,CAAC;AAAA,UAC9D,SAAS,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,IAAI,KAAK,MAAM,SAAS,KAAK,MAAM,MAAM,SAAS,EAAE,WAAW;AAAA,QAClG,CAAC;AAAA,MACH;AAAA,IACF;AAGA,QAAI,aAAa;AACjB,QAAI;AACF,YAAM,aAAa,IAAI,gBAAgB,KAAK,WAAW;AACvD,YAAM,WAAW,UAAU,OAAO;AAClC,mBAAa;AACb,WAAK,IAAI,4CAA4C;AAAA,IACvD,QAAQ;AACN,WAAK,IAAI,2DAA2D;AAAA,IACtE;AAEA,WAAO;AAAA,MACL;AAAA,MACA,eAAe,WAAW,MAAM;AAAA,MAChC,iBAAiB;AAAA,MACjB,UAAU,KAAK,IAAI,IAAI;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,kBAAkB,WAAoC;AAC5D,WAAO;AAAA,MACL,SAAS;AAAA,QACP,WAAW,kBAAkB,KAAK,IAAI,CAAC;AAAA,QACvC,SAAS;AAAA,QACT,UAAU,CAAC;AAAA,QACX,cAAc,CAAC;AAAA,QACf,UAAU,CAAC;AAAA,QACX,WAAW,CAAC;AAAA,MACd;AAAA,MACA,eAAe;AAAA,MACf,iBAAiB;AAAA,MACjB,UAAU,KAAK,IAAI,IAAI;AAAA,MACvB,YAAY;AAAA,IACd;AAAA,EACF;AAAA,EAEQ,IAAI,SAAuB;AACjC,QAAI,KAAK,SAAS;AAChB,cAAQ,IAAI,OAAO;AAAA,IACrB;AAAA,EACF;AAAA,EAEQ,MAAM,IAA2B;AACvC,WAAO,IAAI,QAAQ,CAACC,aAAY,WAAWA,UAAS,EAAE,CAAC;AAAA,EACzD;AACF;;;ACpfA,YAAYC,WAAU;AAStB,eAAsB,SAAS,UAAkC,CAAC,GAAkB;AAClF,QAAM,aAAkB,cAAQ,QAAQ,cAAc,QAAQ,IAAI,CAAC;AACnE,QAAM,UAAU,QAAQ,WAAW;AAGnC,QAAM,SAAS,MAAM,WAAW,UAAU;AAC1C,MAAI,CAAC,QAAQ;AACX,YAAQ,MAAM,sCAAsC,UAAU,EAAE;AAChE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,SAAc,WAAK,YAAY,mBAAmB;AACxD,QAAM,WAAW,MAAM,WAAW,MAAM;AACxC,MAAI,CAAC,UAAU;AACb,YAAQ,MAAM,+CAA+C;AAC7D,YAAQ,MAAM,wCAAwC;AACtD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI;AACF,UAAM,eAAe,IAAI,aAAa,YAAY,OAAO;AACzD,UAAM,SAAS,MAAM,aAAa,SAAS;AAE3C,QAAI,CAAC,OAAO,YAAY;AACtB,cAAQ,MAAM,4DAA4D;AAC1E,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,YAAQ,IAAI;AAAA,sBAAyB,MAAM,SAAS;AAAA,EACtD,SAAS,OAAO;AACd,YAAQ,MAAM,qBAAqB,KAAK;AACxC,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;","names":["fs","path","resolve","path"]}
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  spawnClaudeAgent
3
- } from "./chunk-TB2GPCQP.js";
3
+ } from "./chunk-AJ2AVV5V.js";
4
4
  import {
5
5
  getConversationsPath,
6
6
  loadConfig,
7
7
  readTextFile,
8
8
  writeTextFile
9
- } from "./chunk-FRETJBP5.js";
9
+ } from "./chunk-I4GLPRZ2.js";
10
10
 
11
11
  // src/core/compaction-engine.ts
12
12
  import * as path from "path";
@@ -273,4 +273,4 @@ ${content}`);
273
273
  export {
274
274
  CompactionEngine
275
275
  };
276
- //# sourceMappingURL=chunk-C6NR36YP.js.map
276
+ //# sourceMappingURL=chunk-KZ2I74VT.js.map
@@ -4,7 +4,7 @@ import {
4
4
  listDir,
5
5
  readTextFile,
6
6
  writeTextFile
7
- } from "./chunk-FRETJBP5.js";
7
+ } from "./chunk-I4GLPRZ2.js";
8
8
 
9
9
  // src/core/index-manager.ts
10
10
  import * as path from "path";
@@ -146,4 +146,4 @@ _Last updated: ${(/* @__PURE__ */ new Date()).toISOString()}_
146
146
  export {
147
147
  IndexManager
148
148
  };
149
- //# sourceMappingURL=chunk-4IQV2TQE.js.map
149
+ //# sourceMappingURL=chunk-NEHPNFRM.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  IndexManager
3
- } from "../chunk-4IQV2TQE.js";
3
+ } from "../chunk-NEHPNFRM.js";
4
4
  import {
5
5
  fileExists,
6
6
  getStatePath,
@@ -8,7 +8,7 @@ import {
8
8
  loadConfig,
9
9
  readJSON,
10
10
  writeJSON
11
- } from "../chunk-FRETJBP5.js";
11
+ } from "../chunk-I4GLPRZ2.js";
12
12
 
13
13
  // src/hooks/notification.ts
14
14
  import * as path from "path";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  ConversationManager
3
- } from "../chunk-HP5YVMZ6.js";
3
+ } from "../chunk-EXDIJANL.js";
4
4
  import {
5
5
  loadConfig
6
- } from "../chunk-FRETJBP5.js";
6
+ } from "../chunk-I4GLPRZ2.js";
7
7
 
8
8
  // src/hooks/post-tool-use.ts
9
9
  async function handlePostToolUse() {
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  ConversationManager
3
- } from "../chunk-HP5YVMZ6.js";
3
+ } from "../chunk-EXDIJANL.js";
4
4
  import {
5
5
  IndexManager
6
- } from "../chunk-4IQV2TQE.js";
6
+ } from "../chunk-NEHPNFRM.js";
7
7
  import {
8
8
  getVaultPath
9
- } from "../chunk-FRETJBP5.js";
9
+ } from "../chunk-I4GLPRZ2.js";
10
10
 
11
11
  // src/hooks/session-start.ts
12
12
  async function handleSessionStart() {
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  CompactionEngine
3
- } from "../chunk-C6NR36YP.js";
3
+ } from "../chunk-KZ2I74VT.js";
4
4
  import {
5
5
  VaultIntegrator
6
- } from "../chunk-TB2GPCQP.js";
6
+ } from "../chunk-AJ2AVV5V.js";
7
7
  import {
8
8
  ConversationManager
9
- } from "../chunk-HP5YVMZ6.js";
10
- import "../chunk-4IQV2TQE.js";
9
+ } from "../chunk-EXDIJANL.js";
10
+ import "../chunk-NEHPNFRM.js";
11
11
  import {
12
12
  getVaultPath,
13
13
  loadConfig
14
- } from "../chunk-FRETJBP5.js";
14
+ } from "../chunk-I4GLPRZ2.js";
15
15
 
16
16
  // src/hooks/stop.ts
17
17
  async function handleStop() {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  ConversationManager
3
- } from "../chunk-HP5YVMZ6.js";
4
- import "../chunk-FRETJBP5.js";
3
+ } from "../chunk-EXDIJANL.js";
4
+ import "../chunk-I4GLPRZ2.js";
5
5
 
6
6
  // src/hooks/user-prompt.ts
7
7
  async function handleUserPrompt() {
package/dist/index.js CHANGED
@@ -4,21 +4,21 @@ import {
4
4
  FileCollector,
5
5
  discover,
6
6
  install
7
- } from "./chunk-XOV27B2L.js";
7
+ } from "./chunk-JTHQRYKF.js";
8
8
  import {
9
9
  CompactionEngine
10
- } from "./chunk-C6NR36YP.js";
10
+ } from "./chunk-KZ2I74VT.js";
11
11
  import {
12
12
  EntityDetector,
13
13
  VaultIntegrator
14
- } from "./chunk-TB2GPCQP.js";
14
+ } from "./chunk-AJ2AVV5V.js";
15
15
  import {
16
16
  ConversationManager
17
- } from "./chunk-HP5YVMZ6.js";
17
+ } from "./chunk-EXDIJANL.js";
18
18
  import {
19
19
  IndexManager
20
- } from "./chunk-4IQV2TQE.js";
21
- import "./chunk-FRETJBP5.js";
20
+ } from "./chunk-NEHPNFRM.js";
21
+ import "./chunk-I4GLPRZ2.js";
22
22
  export {
23
23
  AutoDiscover,
24
24
  ChunkManager,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cckb",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
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/utils/file-utils.ts","../src/utils/config.ts"],"sourcesContent":["import * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\n\nexport async function ensureDir(dirPath: string): Promise<void> {\n await fs.mkdir(dirPath, { recursive: true });\n}\n\nexport async function fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function readJSON<T>(filePath: string): Promise<T | null> {\n try {\n const content = await fs.readFile(filePath, \"utf-8\");\n return JSON.parse(content) as T;\n } catch {\n return null;\n }\n}\n\nexport async function writeJSON(\n filePath: string,\n data: unknown,\n pretty = true\n): Promise<void> {\n await ensureDir(path.dirname(filePath));\n const content = pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);\n await fs.writeFile(filePath, content);\n}\n\nexport async function appendToFile(\n filePath: string,\n content: string\n): Promise<void> {\n await ensureDir(path.dirname(filePath));\n await fs.appendFile(filePath, content);\n}\n\nexport async function readTextFile(filePath: string): Promise<string | null> {\n try {\n return await fs.readFile(filePath, \"utf-8\");\n } catch {\n return null;\n }\n}\n\nexport async function writeTextFile(\n filePath: string,\n content: string\n): Promise<void> {\n await ensureDir(path.dirname(filePath));\n await fs.writeFile(filePath, content);\n}\n\nexport async function copyFile(src: string, dest: string): Promise<void> {\n await ensureDir(path.dirname(dest));\n await fs.copyFile(src, dest);\n}\n\nexport async function listDir(dirPath: string): Promise<string[]> {\n try {\n return await fs.readdir(dirPath);\n } catch {\n return [];\n }\n}\n\nexport async function getFileSize(filePath: string): Promise<number> {\n try {\n const stats = await fs.stat(filePath);\n return stats.size;\n } catch {\n return 0;\n }\n}\n\nexport function generateSessionId(): string {\n const timestamp = Date.now().toString(36);\n const random = Math.random().toString(36).substring(2, 8);\n return `${timestamp}-${random}`;\n}\n\nexport function getCurrentTimestamp(): string {\n return new Date().toISOString();\n}\n","import * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\n\nexport interface CCKBConfig {\n compaction: {\n trigger: \"session_end\" | \"size\" | \"messages\" | \"manual\";\n sizeThresholdKB: number;\n messageThreshold: number;\n cleanupAfterSummary: \"keep\" | \"archive\" | \"delete\";\n };\n capture: {\n tools: string[];\n maxContentLength: number;\n };\n vault: {\n autoIntegrate: boolean;\n maxDepth: number;\n };\n feedback: {\n enabled: boolean;\n contextDepth: number;\n };\n discover: {\n maxFiles: number;\n maxChunkSize: number;\n excludePatterns: string[];\n priorityPatterns: string[];\n supportedLanguages: string[];\n };\n}\n\nexport const DEFAULT_CONFIG: CCKBConfig = {\n compaction: {\n trigger: \"session_end\",\n sizeThresholdKB: 50,\n messageThreshold: 100,\n cleanupAfterSummary: \"keep\",\n },\n capture: {\n tools: [\"Write\", \"Edit\", \"MultiEdit\", \"Bash\", \"Task\"],\n maxContentLength: 500,\n },\n vault: {\n autoIntegrate: true,\n maxDepth: 5,\n },\n feedback: {\n enabled: true,\n contextDepth: 2,\n },\n discover: {\n maxFiles: 100,\n maxChunkSize: 50000,\n excludePatterns: [\n \"*.min.js\",\n \"*.bundle.js\",\n \"*.map\",\n \"coverage/**\",\n \".next/**\",\n \"build/**\",\n \"dist/**\",\n ],\n priorityPatterns: [\n \"**/index.{ts,js,tsx,jsx}\",\n \"**/main.{ts,js,py,go,rs}\",\n \"**/app.{ts,js,py}\",\n \"**/models/**\",\n \"**/entities/**\",\n \"**/services/**\",\n ],\n supportedLanguages: [\"typescript\", \"javascript\", \"python\", \"go\", \"rust\"],\n },\n};\n\nexport async function loadConfig(projectPath: string): Promise<CCKBConfig> {\n const configPath = path.join(\n projectPath,\n \"cc-knowledge-base\",\n \".cckb-config.json\"\n );\n\n try {\n const content = await fs.readFile(configPath, \"utf-8\");\n const userConfig = JSON.parse(content);\n return { ...DEFAULT_CONFIG, ...userConfig };\n } catch {\n return DEFAULT_CONFIG;\n }\n}\n\nexport async function saveConfig(\n projectPath: string,\n config: CCKBConfig\n): Promise<void> {\n const configPath = path.join(\n projectPath,\n \"cc-knowledge-base\",\n \".cckb-config.json\"\n );\n\n await fs.writeFile(configPath, JSON.stringify(config, null, 2));\n}\n\nexport function getKnowledgeBasePath(projectPath: string): string {\n return path.join(projectPath, \"cc-knowledge-base\");\n}\n\nexport function getConversationsPath(projectPath: string): string {\n return path.join(projectPath, \"cc-knowledge-base\", \"conversations\");\n}\n\nexport function getVaultPath(projectPath: string): string {\n return path.join(projectPath, \"cc-knowledge-base\", \"vault\");\n}\n\nexport function getStatePath(projectPath: string): string {\n return path.join(projectPath, \"cc-knowledge-base\", \".cckb-state\");\n}\n"],"mappings":"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","names":["fs","path"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/cli/install.ts","../src/core/file-collector.ts","../src/core/chunk-manager.ts","../src/core/auto-discover.ts","../src/cli/discover.ts"],"sourcesContent":["import * as fs from \"node:fs/promises\";\nimport * as fsSync from \"node:fs\";\nimport * as path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n ensureDir,\n fileExists,\n readJSON,\n writeJSON,\n readTextFile,\n writeTextFile,\n} from \"../utils/file-utils.js\";\nimport { DEFAULT_CONFIG } from \"../utils/config.js\";\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\n// Find package root by looking for package.json\nfunction findPackageRoot(): string {\n let dir = __dirname;\n for (let i = 0; i < 5; i++) {\n const packageJson = path.join(dir, \"package.json\");\n if (fsSync.existsSync(packageJson)) {\n return dir;\n }\n dir = path.dirname(dir);\n }\n // Fallback to relative from __dirname\n return path.resolve(__dirname, \"../..\");\n}\n\nconst PACKAGE_ROOT = findPackageRoot();\nconst TEMPLATES_DIR = path.join(PACKAGE_ROOT, \"templates\");\n\nexport interface InstallOptions {\n force?: boolean;\n}\n\nexport async function install(\n targetPath: string,\n options: InstallOptions = {}\n): Promise<void> {\n const resolvedPath = path.resolve(targetPath);\n\n console.log(`Installing CCKB to: ${resolvedPath}`);\n\n // Pre-flight checks\n await validateTargetPath(resolvedPath);\n await checkExistingInstallation(resolvedPath, options.force);\n\n // Create directory structure\n await createDirectoryStructure(resolvedPath);\n\n // Copy template files\n await copyTemplateFiles(resolvedPath);\n\n // Create config file\n await createConfigFile(resolvedPath);\n\n // Install hooks configuration\n await installHooks(resolvedPath);\n\n // Update CLAUDE.md\n await updateClaudeMd(resolvedPath);\n\n // Update .gitignore\n await updateGitignore(resolvedPath);\n\n console.log(\"\\nCCKB installed successfully!\");\n console.log(\"\\nNext steps:\");\n console.log(\" 1. Review cc-knowledge-base/vault/ structure\");\n console.log(\" 2. Check .claude/settings.json for hook configuration\");\n console.log(\" 3. Start a new Claude Code session to begin capturing knowledge\");\n}\n\nasync function validateTargetPath(targetPath: string): Promise<void> {\n const exists = await fileExists(targetPath);\n if (!exists) {\n throw new Error(`Target path does not exist: ${targetPath}`);\n }\n\n const stats = await fs.stat(targetPath);\n if (!stats.isDirectory()) {\n throw new Error(`Target path is not a directory: ${targetPath}`);\n }\n}\n\nasync function checkExistingInstallation(\n targetPath: string,\n force?: boolean\n): Promise<void> {\n const kbPath = path.join(targetPath, \"cc-knowledge-base\");\n const exists = await fileExists(kbPath);\n\n if (exists && !force) {\n throw new Error(\n \"CCKB is already installed in this project. Use --force to reinstall.\"\n );\n }\n}\n\nasync function createDirectoryStructure(targetPath: string): Promise<void> {\n const directories = [\n \"cc-knowledge-base\",\n \"cc-knowledge-base/conversations\",\n \"cc-knowledge-base/vault\",\n \"cc-knowledge-base/vault/entities\",\n \"cc-knowledge-base/vault/apps\",\n \"cc-knowledge-base/vault/modules\",\n \"cc-knowledge-base/.cckb-state\",\n ];\n\n for (const dir of directories) {\n await ensureDir(path.join(targetPath, dir));\n }\n\n console.log(\" Created directory structure\");\n}\n\nasync function copyTemplateFiles(targetPath: string): Promise<void> {\n const vaultFiles = [\n { src: \"vault/INDEX.md\", dest: \"cc-knowledge-base/vault/INDEX.md\" },\n {\n src: \"vault/architecture.md\",\n dest: \"cc-knowledge-base/vault/architecture.md\",\n },\n {\n src: \"vault/general-knowledge.md\",\n dest: \"cc-knowledge-base/vault/general-knowledge.md\",\n },\n {\n src: \"vault/entities/INDEX.md\",\n dest: \"cc-knowledge-base/vault/entities/INDEX.md\",\n },\n {\n src: \"vault/apps/INDEX.md\",\n dest: \"cc-knowledge-base/vault/apps/INDEX.md\",\n },\n {\n src: \"vault/modules/INDEX.md\",\n dest: \"cc-knowledge-base/vault/modules/INDEX.md\",\n },\n ];\n\n for (const file of vaultFiles) {\n const srcPath = path.join(TEMPLATES_DIR, file.src);\n const destPath = path.join(targetPath, file.dest);\n\n const content = await readTextFile(srcPath);\n if (content) {\n await writeTextFile(destPath, content);\n }\n }\n\n // Create .gitkeep for conversations\n await writeTextFile(\n path.join(targetPath, \"cc-knowledge-base/conversations/.gitkeep\"),\n \"\"\n );\n\n console.log(\" Copied vault template files\");\n}\n\nasync function createConfigFile(targetPath: string): Promise<void> {\n const configPath = path.join(\n targetPath,\n \"cc-knowledge-base\",\n \".cckb-config.json\"\n );\n\n await writeJSON(configPath, DEFAULT_CONFIG);\n\n console.log(\" Created configuration file\");\n}\n\nasync function installHooks(targetPath: string): Promise<void> {\n const claudeDir = path.join(targetPath, \".claude\");\n const settingsPath = path.join(claudeDir, \"settings.json\");\n\n await ensureDir(claudeDir);\n\n // Load existing settings or create new\n let settings: Record<string, unknown> =\n (await readJSON<Record<string, unknown>>(settingsPath)) || {};\n\n // Load hook template\n const templatePath = path.join(TEMPLATES_DIR, \"settings.json.tmpl\");\n const hookSettings = await readJSON<{ hooks: Record<string, unknown> }>(\n templatePath\n );\n\n if (!hookSettings) {\n throw new Error(\"Failed to load hook template\");\n }\n\n // Merge hooks (CCKB hooks take precedence for its own hook types)\n const existingHooks = (settings.hooks as Record<string, unknown[]>) || {};\n const newHooks = hookSettings.hooks as Record<string, unknown[]>;\n\n settings.hooks = mergeHooks(existingHooks, newHooks);\n\n await writeJSON(settingsPath, settings);\n\n console.log(\" Installed hook configuration\");\n}\n\nfunction mergeHooks(\n existing: Record<string, unknown[]>,\n incoming: Record<string, unknown[]>\n): Record<string, unknown[]> {\n const merged = { ...existing };\n\n for (const [hookType, hooks] of Object.entries(incoming)) {\n if (!merged[hookType]) {\n merged[hookType] = [];\n }\n\n // Add incoming hooks, avoiding duplicates based on command\n for (const hook of hooks) {\n const hookObj = hook as Record<string, unknown>;\n const command = hookObj.command as string | undefined;\n\n if (command?.includes(\"cckb\")) {\n // Remove any existing CCKB hooks for this type\n merged[hookType] = merged[hookType].filter((h) => {\n const existingCmd = (h as Record<string, unknown>).command as\n | string\n | undefined;\n return !existingCmd?.includes(\"cckb\");\n });\n }\n\n merged[hookType].push(hook);\n }\n }\n\n return merged;\n}\n\nasync function updateClaudeMd(targetPath: string): Promise<void> {\n const claudeMdPath = path.join(targetPath, \"CLAUDE.md\");\n const templatePath = path.join(TEMPLATES_DIR, \"CLAUDE.md.tmpl\");\n\n const template = await readTextFile(templatePath);\n if (!template) {\n throw new Error(\"Failed to load CLAUDE.md template\");\n }\n\n const marker = \"## Project Knowledge Base (CCKB)\";\n\n let existing = await readTextFile(claudeMdPath);\n\n if (existing) {\n // Check if CCKB section already exists\n if (existing.includes(marker)) {\n // Replace existing CCKB section\n const regex = /## Project Knowledge Base \\(CCKB\\)[\\s\\S]*?(?=\\n## |$)/;\n existing = existing.replace(regex, template.trim());\n } else {\n // Append CCKB section\n existing = existing.trimEnd() + \"\\n\\n\" + template;\n }\n await writeTextFile(claudeMdPath, existing);\n } else {\n // Create new CLAUDE.md with CCKB section\n await writeTextFile(claudeMdPath, template);\n }\n\n console.log(\" Updated CLAUDE.md with vault directives\");\n}\n\nasync function updateGitignore(targetPath: string): Promise<void> {\n const gitignorePath = path.join(targetPath, \".gitignore\");\n\n const entries = [\n \"\",\n \"# CCKB state files\",\n \"cc-knowledge-base/.cckb-state/\",\n ];\n\n let existing = (await readTextFile(gitignorePath)) || \"\";\n\n // Check if already added\n if (existing.includes(\"cc-knowledge-base/.cckb-state/\")) {\n return;\n }\n\n existing = existing.trimEnd() + \"\\n\" + entries.join(\"\\n\") + \"\\n\";\n await writeTextFile(gitignorePath, existing);\n\n console.log(\" Updated .gitignore\");\n}\n","import * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { readTextFile, fileExists } from \"../utils/file-utils.js\";\nimport { loadConfig } from \"../utils/config.js\";\n\n// Language detection from manifest files\nconst MANIFEST_LANGUAGE_MAP: Record<string, { language: string; projectType: string }> = {\n \"package.json\": { language: \"typescript\", projectType: \"node\" },\n \"tsconfig.json\": { language: \"typescript\", projectType: \"node\" },\n \"Cargo.toml\": { language: \"rust\", projectType: \"rust\" },\n \"go.mod\": { language: \"go\", projectType: \"go\" },\n \"requirements.txt\": { language: \"python\", projectType: \"python\" },\n \"pyproject.toml\": { language: \"python\", projectType: \"python\" },\n \"setup.py\": { language: \"python\", projectType: \"python\" },\n \"pom.xml\": { language: \"java\", projectType: \"java\" },\n \"build.gradle\": { language: \"java\", projectType: \"java\" },\n \"*.csproj\": { language: \"csharp\", projectType: \"dotnet\" },\n \"Gemfile\": { language: \"ruby\", projectType: \"ruby\" },\n \"composer.json\": { language: \"php\", projectType: \"php\" },\n};\n\n// Extension to language mapping\nconst EXTENSION_LANGUAGE_MAP: Record<string, string> = {\n \".ts\": \"typescript\",\n \".tsx\": \"typescript\",\n \".js\": \"javascript\",\n \".jsx\": \"javascript\",\n \".mjs\": \"javascript\",\n \".cjs\": \"javascript\",\n \".py\": \"python\",\n \".go\": \"go\",\n \".rs\": \"rust\",\n \".java\": \"java\",\n \".cs\": \"csharp\",\n \".rb\": \"ruby\",\n \".php\": \"php\",\n};\n\n// File categories for prioritization\ntype FileCategory = \"entry\" | \"model\" | \"service\" | \"util\" | \"config\" | \"test\" | \"other\";\n\nexport interface CollectedFile {\n path: string; // Relative to project root\n absolutePath: string;\n language: string;\n category: FileCategory;\n size: number;\n priority: number;\n}\n\nexport interface CollectionResult {\n files: CollectedFile[];\n languages: string[];\n projectType: string;\n totalFilesScanned: number;\n}\n\nexport interface CollectOptions {\n maxFiles?: number;\n excludePatterns?: string[];\n priorityPatterns?: string[];\n supportedLanguages?: string[];\n}\n\nexport class FileCollector {\n private projectPath: string;\n\n constructor(projectPath: string) {\n this.projectPath = projectPath;\n }\n\n async collect(options?: CollectOptions): Promise<CollectionResult> {\n const config = await loadConfig(this.projectPath);\n const mergedOptions = {\n maxFiles: options?.maxFiles ?? config.discover.maxFiles,\n excludePatterns: options?.excludePatterns ?? config.discover.excludePatterns,\n supportedLanguages: options?.supportedLanguages ?? config.discover.supportedLanguages,\n };\n\n // Detect project languages\n const { languages, projectType } = await this.detectLanguages();\n\n // Load ignore patterns\n const ignorePatterns = await this.loadIgnorePatterns(mergedOptions.excludePatterns);\n\n // Collect all source files\n const allFiles: CollectedFile[] = [];\n let totalScanned = 0;\n\n await this.walkDirectory(\n this.projectPath,\n async (filePath, stats) => {\n totalScanned++;\n const relativePath = path.relative(this.projectPath, filePath);\n\n // Skip if matches ignore pattern\n if (this.shouldIgnore(relativePath, ignorePatterns)) {\n return;\n }\n\n const ext = path.extname(filePath);\n const language = EXTENSION_LANGUAGE_MAP[ext];\n\n // Skip unsupported languages\n if (!language || !mergedOptions.supportedLanguages.includes(language)) {\n return;\n }\n\n const category = this.categorizeFile(relativePath);\n const priority = this.calculatePriority(relativePath, category, stats.size);\n\n allFiles.push({\n path: relativePath,\n absolutePath: filePath,\n language,\n category,\n size: stats.size,\n priority,\n });\n }\n );\n\n // Sort by priority (descending) and limit\n allFiles.sort((a, b) => b.priority - a.priority);\n const limitedFiles = allFiles.slice(0, mergedOptions.maxFiles);\n\n return {\n files: limitedFiles,\n languages,\n projectType,\n totalFilesScanned: totalScanned,\n };\n }\n\n async detectLanguages(): Promise<{ languages: string[]; projectType: string }> {\n const detected = new Set<string>();\n let projectType = \"unknown\";\n\n // Check for manifest files\n for (const [manifest, info] of Object.entries(MANIFEST_LANGUAGE_MAP)) {\n if (manifest.startsWith(\"*\")) {\n // Glob pattern - skip for now\n continue;\n }\n const manifestPath = path.join(this.projectPath, manifest);\n if (await fileExists(manifestPath)) {\n detected.add(info.language);\n if (projectType === \"unknown\") {\n projectType = info.projectType;\n }\n }\n }\n\n // If package.json exists, check for TypeScript\n const packageJsonPath = path.join(this.projectPath, \"package.json\");\n if (await fileExists(packageJsonPath)) {\n const content = await readTextFile(packageJsonPath);\n if (content) {\n try {\n const pkg = JSON.parse(content);\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n if (deps.typescript || await fileExists(path.join(this.projectPath, \"tsconfig.json\"))) {\n detected.add(\"typescript\");\n } else {\n detected.add(\"javascript\");\n }\n } catch {\n detected.add(\"javascript\");\n }\n }\n }\n\n return {\n languages: Array.from(detected),\n projectType,\n };\n }\n\n private async loadIgnorePatterns(additionalPatterns: string[]): Promise<string[]> {\n const patterns: string[] = [\n // Default ignores\n \"node_modules/**\",\n \".git/**\",\n \"dist/**\",\n \"build/**\",\n \"coverage/**\",\n \"*.log\",\n \".env*\",\n \"__pycache__/**\",\n \"*.pyc\",\n \"target/**\", // Rust\n \"vendor/**\", // Go\n \".venv/**\",\n \"venv/**\",\n ];\n\n // Load .gitignore\n const gitignorePath = path.join(this.projectPath, \".gitignore\");\n const gitignore = await readTextFile(gitignorePath);\n if (gitignore) {\n const lines = gitignore\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line && !line.startsWith(\"#\"));\n patterns.push(...lines);\n }\n\n // Add user-configured excludes\n patterns.push(...additionalPatterns);\n\n return patterns;\n }\n\n private shouldIgnore(relativePath: string, patterns: string[]): boolean {\n const normalizedPath = relativePath.replace(/\\\\/g, \"/\");\n\n for (const pattern of patterns) {\n if (this.matchPattern(normalizedPath, pattern)) {\n return true;\n }\n }\n return false;\n }\n\n private matchPattern(filePath: string, pattern: string): boolean {\n // Simple glob matching - supports *, **, and basic patterns\n const normalizedPattern = pattern.replace(/\\\\/g, \"/\");\n\n // Handle negation patterns\n if (normalizedPattern.startsWith(\"!\")) {\n return false; // Negation patterns don't cause ignore\n }\n\n // Convert glob to regex\n let regex = normalizedPattern\n .replace(/\\./g, \"\\\\.\")\n .replace(/\\*\\*/g, \"{{GLOBSTAR}}\")\n .replace(/\\*/g, \"[^/]*\")\n .replace(/{{GLOBSTAR}}/g, \".*\")\n .replace(/\\?/g, \".\");\n\n // Handle patterns that should match from start or anywhere\n if (!regex.startsWith(\"/\") && !regex.startsWith(\".*\")) {\n regex = \"(^|/)\" + regex;\n }\n\n // Handle trailing slash (directory match)\n if (regex.endsWith(\"/\")) {\n regex = regex + \".*\";\n }\n\n try {\n const re = new RegExp(regex);\n return re.test(filePath);\n } catch {\n // Invalid regex, do simple includes check\n return filePath.includes(pattern.replace(/\\*/g, \"\"));\n }\n }\n\n private categorizeFile(relativePath: string): FileCategory {\n const lowerPath = relativePath.toLowerCase();\n const fileName = path.basename(lowerPath);\n\n // Test files\n if (\n /\\.(test|spec)\\.[^/]+$/.test(lowerPath) ||\n /\\/__tests__\\//.test(lowerPath) ||\n /\\/test\\//.test(lowerPath) ||\n /\\/tests\\//.test(lowerPath)\n ) {\n return \"test\";\n }\n\n // Entry points\n if (\n /^(index|main|app|server)\\.[^/]+$/.test(fileName) ||\n /\\/src\\/(index|main|app)\\.[^/]+$/.test(lowerPath)\n ) {\n return \"entry\";\n }\n\n // Models/Entities\n if (\n /\\/(models?|entities|domain|types|schemas?)\\//i.test(lowerPath) ||\n /\\.(model|entity|type)\\.[^/]+$/.test(lowerPath)\n ) {\n return \"model\";\n }\n\n // Services\n if (\n /\\/(services?|controllers?|handlers?|api|routes?)\\//i.test(lowerPath) ||\n /\\.(service|controller|handler)\\.[^/]+$/.test(lowerPath)\n ) {\n return \"service\";\n }\n\n // Config files\n if (\n /\\.(config|conf)\\.[^/]+$/.test(lowerPath) ||\n /\\/config\\//i.test(lowerPath) ||\n fileName.startsWith(\".\")\n ) {\n return \"config\";\n }\n\n // Utilities\n if (\n /\\/(utils?|helpers?|lib|common|shared)\\//i.test(lowerPath) ||\n /\\.(util|helper)\\.[^/]+$/.test(lowerPath)\n ) {\n return \"util\";\n }\n\n return \"other\";\n }\n\n private calculatePriority(\n relativePath: string,\n category: FileCategory,\n size: number\n ): number {\n let score = 0;\n\n // Category-based scoring\n const categoryScores: Record<FileCategory, number> = {\n entry: 100,\n model: 80,\n service: 70,\n util: 30,\n config: 20,\n other: 10,\n test: -50,\n };\n score += categoryScores[category];\n\n // Depth penalty (shallower files are usually more important)\n const depth = relativePath.split(\"/\").length;\n score -= depth * 2;\n\n // Size preferences\n if (size < 5000) score += 10; // Small, focused files\n if (size > 50000) score -= 20; // Very large files\n if (size > 100000) score -= 30; // Huge files\n\n // Bonus for src directory\n if (/^src\\//.test(relativePath)) score += 15;\n\n return score;\n }\n\n private async walkDirectory(\n dir: string,\n callback: (filePath: string, stats: { size: number }) => Promise<void>\n ): Promise<void> {\n try {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n // Skip common non-source directories early\n if (\n entry.name === \"node_modules\" ||\n entry.name === \".git\" ||\n entry.name === \"dist\" ||\n entry.name === \"build\" ||\n entry.name === \"__pycache__\" ||\n entry.name === \"target\" ||\n entry.name === \"vendor\" ||\n entry.name === \".venv\" ||\n entry.name === \"venv\"\n ) {\n continue;\n }\n await this.walkDirectory(fullPath, callback);\n } else if (entry.isFile()) {\n try {\n const stats = await fs.stat(fullPath);\n await callback(fullPath, { size: stats.size });\n } catch {\n // Skip files we can't stat\n }\n }\n }\n } catch {\n // Skip directories we can't read\n }\n }\n}\n","import { readTextFile } from \"../utils/file-utils.js\";\nimport type { CollectedFile } from \"./file-collector.js\";\n\nexport interface FileChunk {\n files: CollectedFile[];\n content: string;\n estimatedTokens: number;\n index: number;\n totalChunks: number;\n}\n\nexport interface ChunkOptions {\n maxChunkSize?: number; // Max characters per chunk (default: 50000)\n}\n\nconst DEFAULT_MAX_CHUNK_SIZE = 50000;\n\n// Rough token estimation (avg ~4 chars per token for code)\nfunction estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n\nexport class ChunkManager {\n private files: CollectedFile[];\n private maxChunkSize: number;\n private chunks: FileChunk[] | null = null;\n\n constructor(files: CollectedFile[], options?: ChunkOptions) {\n this.files = files;\n this.maxChunkSize = options?.maxChunkSize ?? DEFAULT_MAX_CHUNK_SIZE;\n }\n\n async prepareChunks(): Promise<FileChunk[]> {\n if (this.chunks) {\n return this.chunks;\n }\n\n const chunks: FileChunk[] = [];\n let currentChunk: CollectedFile[] = [];\n let currentContent = \"\";\n let currentSize = 0;\n\n for (const file of this.files) {\n const content = await readTextFile(file.absolutePath);\n if (!content) continue;\n\n // Format file content with path header\n const formattedContent = this.formatFileContent(file.path, content);\n const contentSize = formattedContent.length;\n\n // If single file exceeds max size, truncate it\n if (contentSize > this.maxChunkSize) {\n // If we have pending content, save current chunk first\n if (currentChunk.length > 0) {\n chunks.push(this.createChunk(currentChunk, currentContent, chunks.length));\n currentChunk = [];\n currentContent = \"\";\n currentSize = 0;\n }\n\n // Add truncated file as its own chunk\n const truncatedContent = this.truncateContent(formattedContent, this.maxChunkSize);\n chunks.push(this.createChunk([file], truncatedContent, chunks.length));\n continue;\n }\n\n // If adding this file would exceed max size, start new chunk\n if (currentSize + contentSize > this.maxChunkSize && currentChunk.length > 0) {\n chunks.push(this.createChunk(currentChunk, currentContent, chunks.length));\n currentChunk = [];\n currentContent = \"\";\n currentSize = 0;\n }\n\n // Add file to current chunk\n currentChunk.push(file);\n currentContent += formattedContent + \"\\n\\n\";\n currentSize += contentSize;\n }\n\n // Don't forget the last chunk\n if (currentChunk.length > 0) {\n chunks.push(this.createChunk(currentChunk, currentContent, chunks.length));\n }\n\n // Update totalChunks in all chunks\n for (const chunk of chunks) {\n chunk.totalChunks = chunks.length;\n }\n\n this.chunks = chunks;\n return chunks;\n }\n\n private createChunk(\n files: CollectedFile[],\n content: string,\n index: number\n ): FileChunk {\n return {\n files,\n content: content.trim(),\n estimatedTokens: estimateTokens(content),\n index,\n totalChunks: 0, // Will be updated after all chunks are created\n };\n }\n\n private formatFileContent(filePath: string, content: string): string {\n // Add clear file boundaries for Claude to parse\n return `===== FILE: ${filePath} =====\n${content}\n===== END: ${filePath} =====`;\n }\n\n private truncateContent(content: string, maxSize: number): string {\n if (content.length <= maxSize) {\n return content;\n }\n\n // Try to truncate at a reasonable point\n const truncateAt = maxSize - 100; // Leave room for truncation message\n const lastNewline = content.lastIndexOf(\"\\n\", truncateAt);\n const cutPoint = lastNewline > truncateAt * 0.5 ? lastNewline : truncateAt;\n\n return content.slice(0, cutPoint) + \"\\n\\n[... TRUNCATED - file too large ...]\";\n }\n\n getTotalChunks(): number {\n if (!this.chunks) {\n throw new Error(\"Chunks not prepared. Call prepareChunks() first.\");\n }\n return this.chunks.length;\n }\n\n getChunkSummary(): string {\n if (!this.chunks) {\n return \"Chunks not yet prepared\";\n }\n\n const totalFiles = this.chunks.reduce((sum, c) => sum + c.files.length, 0);\n const totalTokens = this.chunks.reduce((sum, c) => sum + c.estimatedTokens, 0);\n\n return `${totalFiles} files in ${this.chunks.length} chunks (~${totalTokens} tokens)`;\n }\n\n // Async generator for processing chunks one at a time\n async *iterateChunks(): AsyncGenerator<FileChunk> {\n const chunks = await this.prepareChunks();\n for (const chunk of chunks) {\n yield chunk;\n }\n }\n}\n","import { FileCollector, type CollectionResult } from \"./file-collector.js\";\nimport { ChunkManager, type FileChunk } from \"./chunk-manager.js\";\nimport { VaultIntegrator } from \"./vault-integrator.js\";\nimport { spawnClaudeAgent, isClaudeAvailable } from \"../utils/claude-sdk.js\";\nimport { loadConfig } from \"../utils/config.js\";\nimport type {\n Summary,\n ExtractedEntity,\n ArchitectureItem,\n ServiceItem,\n KnowledgeItem,\n} from \"./compaction-engine.js\";\n\nconst DISCOVERY_PROMPT = `You are a technical knowledge extractor analyzing a codebase. Extract information for a project knowledge base.\n\nPROJECT CONTEXT:\n- Language(s): {languages}\n- Project Type: {projectType}\n\nANALYZE THESE SOURCE FILES:\n\n{fileContents}\n\nExtract and format the following:\n\n## Entities\nFor each domain entity (data model, type, class, interface):\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 (e.g., MVC, Repository, Factory, Singleton, etc.)\n- **Description**: Brief explanation of how it's used\n- **Affected Files**: Relevant file paths\n\n## Services\nFor each service or component:\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 discovered:\n- **Topic**: What it's about\n- **Details**: The actual information\n\nGuidelines:\n- Only include sections that have content\n- Be concise but complete\n- Use exact file paths as shown\n- Focus on domain logic, not framework boilerplate\n- Identify patterns from code structure, not just naming\n`;\n\nexport interface DiscoverOptions {\n maxFiles?: number;\n maxChunkSize?: number;\n verbose?: boolean;\n}\n\nexport interface DiscoveryResult {\n summary: Summary;\n filesAnalyzed: number;\n chunksProcessed: number;\n duration: number;\n integrated: boolean;\n}\n\nexport class AutoDiscover {\n private projectPath: string;\n private verbose: boolean;\n\n constructor(projectPath: string, verbose = false) {\n this.projectPath = projectPath;\n this.verbose = verbose;\n }\n\n async discover(options?: DiscoverOptions): Promise<DiscoveryResult> {\n const startTime = Date.now();\n const config = await loadConfig(this.projectPath);\n\n const maxFiles = options?.maxFiles ?? config.discover.maxFiles;\n const maxChunkSize = options?.maxChunkSize ?? config.discover.maxChunkSize;\n\n this.log(\"Discovering codebase...\\n\");\n\n // Step 1: Collect files\n const collector = new FileCollector(this.projectPath);\n const collection = await collector.collect({ maxFiles });\n\n this.log(`Detected: ${collection.languages.join(\", \")} (${collection.projectType} project)`);\n this.log(`Collected: ${collection.totalFilesScanned} files → ${collection.files.length} prioritized`);\n\n if (collection.files.length === 0) {\n this.log(\"No source files found to analyze.\");\n return this.createEmptyResult(startTime);\n }\n\n // Step 2: Check Claude availability\n const claudeAvailable = await isClaudeAvailable();\n if (!claudeAvailable) {\n this.log(\"Claude CLI not available. Using fallback analysis...\");\n return this.fallbackDiscovery(collection, startTime);\n }\n\n // Step 3: Prepare chunks\n const chunkManager = new ChunkManager(collection.files, { maxChunkSize });\n const chunks = await chunkManager.prepareChunks();\n\n this.log(`Grouped into ${chunks.length} chunks\\n`);\n this.log(\"Analyzing with Claude...\");\n\n // Step 4: Analyze each chunk with Claude\n const partialSummaries: Summary[] = [];\n let chunksProcessed = 0;\n\n for (const chunk of chunks) {\n this.log(` [${chunk.index + 1}/${chunk.totalChunks}] Analyzing ${chunk.files.length} files...`);\n\n try {\n const summary = await this.analyzeChunk(chunk, collection);\n partialSummaries.push(summary);\n chunksProcessed++;\n\n // Rate limiting between chunks\n if (chunk.index < chunks.length - 1) {\n await this.delay(1500);\n }\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n this.log(` Warning: Chunk ${chunk.index + 1} analysis failed: ${errorMsg}`);\n // Continue with other chunks\n }\n }\n\n if (partialSummaries.length === 0) {\n this.log(\"\\nNo successful analyses. Using fallback...\");\n return this.fallbackDiscovery(collection, startTime);\n }\n\n // Step 5: Merge summaries\n const mergedSummary = this.mergeSummaries(partialSummaries);\n\n // Step 6: Integrate into vault\n this.log(\"\\nIntegrating into vault...\");\n let integrated = false;\n\n try {\n const integrator = new VaultIntegrator(this.projectPath);\n await integrator.integrate(mergedSummary);\n integrated = true;\n\n this.log(` ${mergedSummary.entities.length} entities`);\n this.log(` ${mergedSummary.architecture.length} patterns`);\n this.log(` ${mergedSummary.services.length} services`);\n this.log(` ${mergedSummary.knowledge.length} knowledge items`);\n } catch (error) {\n this.log(` Warning: Vault integration failed: ${error}`);\n }\n\n const duration = Date.now() - startTime;\n this.log(`\\nDiscovery complete (${(duration / 1000).toFixed(1)}s)`);\n\n return {\n summary: mergedSummary,\n filesAnalyzed: collection.files.length,\n chunksProcessed,\n duration,\n integrated,\n };\n }\n\n private async analyzeChunk(\n chunk: FileChunk,\n collection: CollectionResult\n ): Promise<Summary> {\n const prompt = DISCOVERY_PROMPT\n .replace(\"{languages}\", collection.languages.join(\", \"))\n .replace(\"{projectType}\", collection.projectType)\n .replace(\"{fileContents}\", chunk.content);\n\n const response = await this.runWithProgressIndicators(\n () => spawnClaudeAgent(prompt, { timeout: 300000 }), // 5 minutes\n [\n { at: 60000, message: \" Still analyzing... (1 min)\" },\n { at: 180000, message: \" Still working... (3 min)\" },\n ]\n );\n\n return this.parseResponse(response, chunk);\n }\n\n private async runWithProgressIndicators<T>(\n task: () => Promise<T>,\n indicators: { at: number; message: string }[]\n ): Promise<T> {\n const timers: NodeJS.Timeout[] = [];\n\n // Set up progress indicators\n for (const indicator of indicators) {\n const timer = setTimeout(() => {\n this.log(indicator.message);\n }, indicator.at);\n timers.push(timer);\n }\n\n try {\n const result = await task();\n return result;\n } finally {\n // Clean up timers\n for (const timer of timers) {\n clearTimeout(timer);\n }\n }\n }\n\n private parseResponse(response: string, _chunk: FileChunk): Summary {\n const summary: Summary = {\n sessionId: `discover-${Date.now()}`,\n content: response,\n entities: [],\n architecture: [],\n services: [],\n knowledge: [],\n };\n\n // Parse entities\n const entitiesMatch = response.match(/## Entities\\n([\\s\\S]*?)(?=\\n## |$)/);\n if (entitiesMatch) {\n summary.entities = this.parseEntities(entitiesMatch[1]);\n }\n\n // Parse architecture\n const archMatch = response.match(/## Architecture\\n([\\s\\S]*?)(?=\\n## |$)/);\n if (archMatch) {\n summary.architecture = this.parseArchitecture(archMatch[1]);\n }\n\n // Parse services\n const servicesMatch = response.match(/## Services\\n([\\s\\S]*?)(?=\\n## |$)/);\n if (servicesMatch) {\n summary.services = this.parseServices(servicesMatch[1]);\n }\n\n // Parse knowledge\n const knowledgeMatch = response.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 mergeSummaries(summaries: Summary[]): Summary {\n const merged: Summary = {\n sessionId: `discover-${Date.now()}`,\n content: summaries.map((s) => s.content).join(\"\\n\\n---\\n\\n\"),\n entities: [],\n architecture: [],\n services: [],\n knowledge: [],\n };\n\n // Merge and deduplicate by name\n const entityMap = new Map<string, ExtractedEntity>();\n const archMap = new Map<string, ArchitectureItem>();\n const serviceMap = new Map<string, ServiceItem>();\n const knowledgeMap = new Map<string, KnowledgeItem>();\n\n for (const summary of summaries) {\n for (const entity of summary.entities) {\n const key = entity.name.toLowerCase();\n if (!entityMap.has(key)) {\n entityMap.set(key, entity);\n }\n }\n\n for (const arch of summary.architecture) {\n const key = arch.pattern.toLowerCase();\n if (!archMap.has(key)) {\n archMap.set(key, arch);\n }\n }\n\n for (const service of summary.services) {\n const key = service.name.toLowerCase();\n if (!serviceMap.has(key)) {\n serviceMap.set(key, service);\n }\n }\n\n for (const knowledge of summary.knowledge) {\n const key = knowledge.topic.toLowerCase();\n if (!knowledgeMap.has(key)) {\n knowledgeMap.set(key, knowledge);\n }\n }\n }\n\n merged.entities = Array.from(entityMap.values());\n merged.architecture = Array.from(archMap.values());\n merged.services = Array.from(serviceMap.values());\n merged.knowledge = Array.from(knowledgeMap.values());\n\n return merged;\n }\n\n private async fallbackDiscovery(\n collection: CollectionResult,\n startTime: number\n ): Promise<DiscoveryResult> {\n // Basic discovery without Claude - just catalog files\n const summary: Summary = {\n sessionId: `discover-fallback-${Date.now()}`,\n content: \"Fallback discovery - Claude unavailable\",\n entities: [],\n architecture: [],\n services: [],\n knowledge: [\n {\n topic: \"Project Languages\",\n details: collection.languages.join(\", \"),\n },\n {\n topic: \"Project Type\",\n details: collection.projectType,\n },\n {\n topic: \"Source Files Discovered\",\n details: `${collection.files.length} files categorized by type`,\n },\n ],\n };\n\n // Group files by category\n const categories = new Map<string, string[]>();\n for (const file of collection.files) {\n if (!categories.has(file.category)) {\n categories.set(file.category, []);\n }\n categories.get(file.category)!.push(file.path);\n }\n\n for (const [category, files] of categories) {\n if (category !== \"other\" && category !== \"test\") {\n summary.knowledge.push({\n topic: `${category.charAt(0).toUpperCase() + category.slice(1)} Files`,\n details: files.slice(0, 10).join(\", \") + (files.length > 10 ? ` (+${files.length - 10} more)` : \"\"),\n });\n }\n }\n\n // Try to integrate\n let integrated = false;\n try {\n const integrator = new VaultIntegrator(this.projectPath);\n await integrator.integrate(summary);\n integrated = true;\n this.log(\"\\nFallback discovery integrated into vault\");\n } catch {\n this.log(\"\\nFallback discovery completed (vault integration failed)\");\n }\n\n return {\n summary,\n filesAnalyzed: collection.files.length,\n chunksProcessed: 0,\n duration: Date.now() - startTime,\n integrated,\n };\n }\n\n private createEmptyResult(startTime: number): DiscoveryResult {\n return {\n summary: {\n sessionId: `discover-empty-${Date.now()}`,\n content: \"\",\n entities: [],\n architecture: [],\n services: [],\n knowledge: [],\n },\n filesAnalyzed: 0,\n chunksProcessed: 0,\n duration: Date.now() - startTime,\n integrated: false,\n };\n }\n\n private log(message: string): void {\n if (this.verbose) {\n console.log(message);\n }\n }\n\n private delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","import * as path from \"node:path\";\nimport { fileExists } from \"../utils/file-utils.js\";\nimport { AutoDiscover } from \"../core/auto-discover.js\";\n\nexport interface DiscoverCommandOptions {\n targetPath?: string;\n verbose?: boolean;\n}\n\nexport async function discover(options: DiscoverCommandOptions = {}): Promise<void> {\n const targetPath = path.resolve(options.targetPath || process.cwd());\n const verbose = options.verbose ?? true; // Default to verbose for CLI\n\n // Validate target path\n const exists = await fileExists(targetPath);\n if (!exists) {\n console.error(`Error: Target path does not exist: ${targetPath}`);\n process.exit(1);\n }\n\n // Check if CCKB is installed\n const kbPath = path.join(targetPath, \"cc-knowledge-base\");\n const kbExists = await fileExists(kbPath);\n if (!kbExists) {\n console.error(\"Error: CCKB is not installed in this project.\");\n console.error(\"Run 'cckb init' first to install CCKB.\");\n process.exit(1);\n }\n\n try {\n const autoDiscover = new AutoDiscover(targetPath, verbose);\n const result = await autoDiscover.discover();\n\n if (!result.integrated) {\n console.error(\"\\nWarning: Vault integration failed. Check the logs above.\");\n process.exit(1);\n }\n\n console.log(`\\nVault populated at: ${kbPath}/vault/`);\n } catch (error) {\n console.error(\"Discovery failed:\", error);\n process.exit(1);\n }\n}\n"],"mappings":"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","names":["fs","path","resolve","path"]}