cckb 0.1.4 → 0.1.6
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 +4 -4
- package/dist/{chunk-HP5YVMZ6.js → chunk-2USUMNE7.js} +2 -2
- package/dist/{chunk-EPZCT4Y2.js → chunk-C7H3GIXY.js} +3 -3
- package/dist/{chunk-P7O44DI3.js → chunk-CGTH2E5W.js} +34 -6
- package/dist/chunk-CGTH2E5W.js.map +1 -0
- package/dist/{chunk-4IQV2TQE.js → chunk-D753AA36.js} +2 -2
- package/dist/{chunk-ZZDG5UWP.js → chunk-FEXOQA6H.js} +16 -8
- package/dist/{chunk-ZZDG5UWP.js.map → chunk-FEXOQA6H.js.map} +1 -1
- package/dist/{chunk-FRETJBP5.js → chunk-V6LRQYKA.js} +3 -2
- package/dist/chunk-V6LRQYKA.js.map +1 -0
- package/dist/hooks/notification.js +2 -2
- package/dist/hooks/post-tool-use.js +2 -2
- package/dist/hooks/session-start.js +3 -3
- package/dist/hooks/stop.js +5 -5
- package/dist/hooks/user-prompt.js +2 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +6 -6
- package/package.json +1 -1
- package/dist/chunk-FRETJBP5.js.map +0 -1
- package/dist/chunk-P7O44DI3.js.map +0 -1
- /package/dist/{chunk-HP5YVMZ6.js.map → chunk-2USUMNE7.js.map} +0 -0
- /package/dist/{chunk-EPZCT4Y2.js.map → chunk-C7H3GIXY.js.map} +0 -0
- /package/dist/{chunk-4IQV2TQE.js.map → chunk-D753AA36.js.map} +0 -0
package/dist/bin/cckb.js
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
discover,
|
|
4
4
|
install
|
|
5
|
-
} from "../chunk-
|
|
6
|
-
import "../chunk-
|
|
7
|
-
import "../chunk-
|
|
8
|
-
import "../chunk-
|
|
5
|
+
} from "../chunk-CGTH2E5W.js";
|
|
6
|
+
import "../chunk-FEXOQA6H.js";
|
|
7
|
+
import "../chunk-D753AA36.js";
|
|
8
|
+
import "../chunk-V6LRQYKA.js";
|
|
9
9
|
|
|
10
10
|
// src/bin/cckb.ts
|
|
11
11
|
var args = process.argv.slice(2);
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
readTextFile,
|
|
14
14
|
writeJSON,
|
|
15
15
|
writeTextFile
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-V6LRQYKA.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-
|
|
239
|
+
//# sourceMappingURL=chunk-2USUMNE7.js.map
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
spawnClaudeAgent
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-FEXOQA6H.js";
|
|
4
4
|
import {
|
|
5
5
|
getConversationsPath,
|
|
6
6
|
loadConfig,
|
|
7
7
|
readTextFile,
|
|
8
8
|
writeTextFile
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-V6LRQYKA.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-
|
|
276
|
+
//# sourceMappingURL=chunk-C7H3GIXY.js.map
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
VaultIntegrator,
|
|
3
3
|
isClaudeAvailable,
|
|
4
4
|
spawnClaudeAgent
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-FEXOQA6H.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-
|
|
15
|
+
} from "./chunk-V6LRQYKA.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
|
-
|
|
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);
|
|
@@ -639,7 +640,8 @@ var AutoDiscover = class {
|
|
|
639
640
|
await this.delay(1500);
|
|
640
641
|
}
|
|
641
642
|
} catch (error) {
|
|
642
|
-
|
|
643
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
644
|
+
this.log(` Warning: Chunk ${chunk.index + 1} analysis failed: ${errorMsg}`);
|
|
643
645
|
}
|
|
644
646
|
}
|
|
645
647
|
if (partialSummaries.length === 0) {
|
|
@@ -673,9 +675,35 @@ Discovery complete (${(duration / 1e3).toFixed(1)}s)`);
|
|
|
673
675
|
}
|
|
674
676
|
async analyzeChunk(chunk, collection) {
|
|
675
677
|
const prompt = DISCOVERY_PROMPT.replace("{languages}", collection.languages.join(", ")).replace("{projectType}", collection.projectType).replace("{fileContents}", chunk.content);
|
|
676
|
-
const response = await
|
|
678
|
+
const response = await this.runWithProgressIndicators(
|
|
679
|
+
() => spawnClaudeAgent(prompt, { timeout: 6e5 }),
|
|
680
|
+
// 10 minutes
|
|
681
|
+
[
|
|
682
|
+
{ at: 6e4, message: " Still analyzing... (1 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)" }
|
|
686
|
+
]
|
|
687
|
+
);
|
|
677
688
|
return this.parseResponse(response, chunk);
|
|
678
689
|
}
|
|
690
|
+
async runWithProgressIndicators(task, indicators) {
|
|
691
|
+
const timers = [];
|
|
692
|
+
for (const indicator of indicators) {
|
|
693
|
+
const timer = setTimeout(() => {
|
|
694
|
+
this.log(indicator.message);
|
|
695
|
+
}, indicator.at);
|
|
696
|
+
timers.push(timer);
|
|
697
|
+
}
|
|
698
|
+
try {
|
|
699
|
+
const result = await task();
|
|
700
|
+
return result;
|
|
701
|
+
} finally {
|
|
702
|
+
for (const timer of timers) {
|
|
703
|
+
clearTimeout(timer);
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
}
|
|
679
707
|
parseResponse(response, _chunk) {
|
|
680
708
|
const summary = {
|
|
681
709
|
sessionId: `discover-${Date.now()}`,
|
|
@@ -941,4 +969,4 @@ export {
|
|
|
941
969
|
AutoDiscover,
|
|
942
970
|
discover
|
|
943
971
|
};
|
|
944
|
-
//# sourceMappingURL=chunk-
|
|
972
|
+
//# sourceMappingURL=chunk-CGTH2E5W.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":"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","names":["fs","path","resolve","path"]}
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
listDir,
|
|
5
5
|
readTextFile,
|
|
6
6
|
writeTextFile
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-V6LRQYKA.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-
|
|
149
|
+
//# sourceMappingURL=chunk-D753AA36.js.map
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
IndexManager
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-D753AA36.js";
|
|
4
4
|
import {
|
|
5
5
|
appendToFile,
|
|
6
6
|
ensureDir,
|
|
7
7
|
fileExists,
|
|
8
8
|
readTextFile,
|
|
9
9
|
writeTextFile
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-V6LRQYKA.js";
|
|
11
11
|
|
|
12
12
|
// src/core/entity-detector.ts
|
|
13
13
|
var EntityDetector = class {
|
|
@@ -300,15 +300,20 @@ ${timestamp}`
|
|
|
300
300
|
|
|
301
301
|
// src/utils/claude-sdk.ts
|
|
302
302
|
import { spawn } from "child_process";
|
|
303
|
-
async function spawnClaudeAgent(prompt) {
|
|
303
|
+
async function spawnClaudeAgent(prompt, options) {
|
|
304
|
+
const timeout = options?.timeout ?? 3e5;
|
|
304
305
|
return new Promise((resolve, reject) => {
|
|
305
306
|
const child = spawn("claude", ["--print", "-p", prompt], {
|
|
306
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
307
|
-
timeout: 12e4
|
|
308
|
-
// 2 minute timeout
|
|
307
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
309
308
|
});
|
|
310
309
|
let stdout = "";
|
|
311
310
|
let stderr = "";
|
|
311
|
+
let timedOut = false;
|
|
312
|
+
const timeoutId = setTimeout(() => {
|
|
313
|
+
timedOut = true;
|
|
314
|
+
child.kill("SIGTERM");
|
|
315
|
+
reject(new Error(`Claude agent timed out after ${timeout / 1e3}s`));
|
|
316
|
+
}, timeout);
|
|
312
317
|
child.stdout?.on("data", (data) => {
|
|
313
318
|
stdout += data.toString();
|
|
314
319
|
});
|
|
@@ -316,13 +321,16 @@ async function spawnClaudeAgent(prompt) {
|
|
|
316
321
|
stderr += data.toString();
|
|
317
322
|
});
|
|
318
323
|
child.on("close", (code) => {
|
|
324
|
+
clearTimeout(timeoutId);
|
|
325
|
+
if (timedOut) return;
|
|
319
326
|
if (code === 0) {
|
|
320
327
|
resolve(stdout.trim());
|
|
321
328
|
} else {
|
|
322
|
-
reject(new Error(`Claude agent failed with code ${code}: ${stderr}`));
|
|
329
|
+
reject(new Error(`Claude agent failed with code ${code}: ${stderr || "(no stderr)"}`));
|
|
323
330
|
}
|
|
324
331
|
});
|
|
325
332
|
child.on("error", (error) => {
|
|
333
|
+
clearTimeout(timeoutId);
|
|
326
334
|
reject(error);
|
|
327
335
|
});
|
|
328
336
|
});
|
|
@@ -347,4 +355,4 @@ export {
|
|
|
347
355
|
spawnClaudeAgent,
|
|
348
356
|
isClaudeAvailable
|
|
349
357
|
};
|
|
350
|
-
//# sourceMappingURL=chunk-
|
|
358
|
+
//# sourceMappingURL=chunk-FEXOQA6H.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/entity-detector.ts","../src/core/vault-integrator.ts","../src/utils/claude-sdk.ts"],"sourcesContent":["import type { Summary, ExtractedEntity, ServiceItem } from \"./compaction-engine.js\";\n\nexport interface DetectedItem {\n type: \"entity\" | \"service\" | \"pattern\" | \"knowledge\";\n name: string;\n data: unknown;\n vaultPath: string;\n content: string;\n}\n\nexport class EntityDetector {\n /**\n * Analyzes a summary and determines what should be added to the vault.\n */\n detect(summary: Summary): DetectedItem[] {\n const items: DetectedItem[] = [];\n\n // Detect entities\n for (const entity of summary.entities) {\n items.push(this.createEntityItem(entity));\n\n // Also create service entries for entity-related services\n const relatedServices = summary.services.filter(\n (s) =>\n s.name.toLowerCase().includes(entity.name.toLowerCase()) ||\n s.location?.toLowerCase().includes(entity.name.toLowerCase())\n );\n\n for (const service of relatedServices) {\n items.push(this.createServiceItem(entity.name, service));\n }\n }\n\n // Detect standalone services\n const processedServiceNames = new Set<string>();\n for (const entity of summary.entities) {\n for (const service of summary.services) {\n if (\n service.name.toLowerCase().includes(entity.name.toLowerCase()) ||\n service.location?.toLowerCase().includes(entity.name.toLowerCase())\n ) {\n processedServiceNames.add(service.name);\n }\n }\n }\n\n for (const service of summary.services) {\n if (!processedServiceNames.has(service.name)) {\n items.push(this.createStandaloneServiceItem(service));\n }\n }\n\n // Detect architecture patterns\n for (const arch of summary.architecture) {\n items.push(this.createArchitectureItem(arch));\n }\n\n // Detect general knowledge\n for (const knowledge of summary.knowledge) {\n items.push(this.createKnowledgeItem(knowledge));\n }\n\n return items;\n }\n\n private createEntityItem(entity: ExtractedEntity): DetectedItem {\n const content = this.formatEntityContent(entity);\n\n return {\n type: \"entity\",\n name: entity.name,\n data: entity,\n vaultPath: `entities/${entity.name.toLowerCase()}`,\n content,\n };\n }\n\n private createServiceItem(\n entityName: string,\n service: ServiceItem\n ): DetectedItem {\n const content = this.formatServiceContent(service);\n const serviceName = service.name.toLowerCase().replace(entityName.toLowerCase(), \"\").trim();\n const fileName = serviceName || \"service\";\n\n return {\n type: \"service\",\n name: service.name,\n data: service,\n vaultPath: `entities/${entityName.toLowerCase()}/services/${fileName}`,\n content,\n };\n }\n\n private createStandaloneServiceItem(service: ServiceItem): DetectedItem {\n const content = this.formatServiceContent(service);\n\n return {\n type: \"service\",\n name: service.name,\n data: service,\n vaultPath: `services/${service.name.toLowerCase()}`,\n content,\n };\n }\n\n private createArchitectureItem(arch: {\n pattern: string;\n description: string;\n affectedFiles: string[];\n }): DetectedItem {\n const content = `## ${arch.pattern}\n\n${arch.description}\n\n### Affected Files\n${arch.affectedFiles.map((f) => `- ${f}`).join(\"\\n\")}\n`;\n\n return {\n type: \"pattern\",\n name: arch.pattern,\n data: arch,\n vaultPath: \"architecture\",\n content,\n };\n }\n\n private createKnowledgeItem(knowledge: {\n topic: string;\n details: string;\n }): DetectedItem {\n const content = `## ${knowledge.topic}\n\n${knowledge.details}\n`;\n\n return {\n type: \"knowledge\",\n name: knowledge.topic,\n data: knowledge,\n vaultPath: \"general-knowledge\",\n content,\n };\n }\n\n private formatEntityContent(entity: ExtractedEntity): string {\n let content = `# ${entity.name}\\n\\n`;\n\n if (entity.location) {\n content += `**Location**: ${entity.location}\\n\\n`;\n }\n\n if (entity.attributes.length > 0) {\n content += `## Attributes\\n\\n`;\n for (const attr of entity.attributes) {\n content += `- ${attr}\\n`;\n }\n content += \"\\n\";\n }\n\n if (entity.relations.length > 0) {\n content += `## Relations\\n\\n`;\n for (const rel of entity.relations) {\n content += `- ${rel}\\n`;\n }\n content += \"\\n\";\n }\n\n return content;\n }\n\n private formatServiceContent(service: ServiceItem): string {\n let content = `# ${service.name}\\n\\n`;\n\n if (service.location) {\n content += `**Location**: ${service.location}\\n\\n`;\n }\n\n if (service.purpose) {\n content += `## Purpose\\n\\n${service.purpose}\\n\\n`;\n }\n\n if (service.methods.length > 0) {\n content += `## Methods\\n\\n`;\n for (const method of service.methods) {\n content += `- ${method}\\n`;\n }\n content += \"\\n\";\n }\n\n return content;\n }\n}\n","import * as path from \"node:path\";\nimport {\n readTextFile,\n writeTextFile,\n appendToFile,\n ensureDir,\n fileExists,\n} from \"../utils/file-utils.js\";\nimport { IndexManager } from \"./index-manager.js\";\nimport { EntityDetector, type DetectedItem } from \"./entity-detector.js\";\nimport type { Summary } from \"./compaction-engine.js\";\n\nexport class VaultIntegrator {\n private vaultPath: string;\n private indexManager: IndexManager;\n private entityDetector: EntityDetector;\n\n constructor(vaultPath: string) {\n this.vaultPath = vaultPath;\n this.indexManager = new IndexManager(vaultPath);\n this.entityDetector = new EntityDetector();\n }\n\n async integrate(summary: Summary): Promise<void> {\n // Detect items from summary\n const items = this.entityDetector.detect(summary);\n\n if (items.length === 0) {\n return;\n }\n\n // Process each detected item\n for (const item of items) {\n await this.processItem(item);\n }\n\n // Update root INDEX.md with timestamp\n await this.updateRootIndex();\n }\n\n private async processItem(item: DetectedItem): Promise<void> {\n switch (item.type) {\n case \"entity\":\n await this.processEntity(item);\n break;\n case \"service\":\n await this.processService(item);\n break;\n case \"pattern\":\n await this.processPattern(item);\n break;\n case \"knowledge\":\n await this.processKnowledge(item);\n break;\n }\n }\n\n private async processEntity(item: DetectedItem): Promise<void> {\n const entityPath = await this.indexManager.ensureEntityFolder(item.name);\n const fullPath = path.join(this.vaultPath, entityPath);\n\n // Write attributes.md\n const attributesPath = path.join(fullPath, \"attributes.md\");\n await writeTextFile(attributesPath, item.content);\n\n // Update entity INDEX.md\n await this.indexManager.addEntry(entityPath, {\n name: \"attributes\",\n path: \"./attributes.md\",\n description: `Attributes of ${item.name}`,\n type: \"file\",\n });\n }\n\n private async processService(item: DetectedItem): Promise<void> {\n const pathParts = item.vaultPath.split(\"/\");\n const fileName = pathParts.pop() + \".md\";\n const folderPath = pathParts.join(\"/\");\n const fullFolderPath = path.join(this.vaultPath, folderPath);\n\n await ensureDir(fullFolderPath);\n\n // Write service file\n const filePath = path.join(fullFolderPath, fileName);\n await writeTextFile(filePath, item.content);\n\n // Ensure parent has INDEX.md\n const parentIndexPath = path.join(fullFolderPath, \"INDEX.md\");\n if (!(await fileExists(parentIndexPath))) {\n await this.indexManager.createIndex(folderPath, []);\n }\n\n // Update parent INDEX.md\n await this.indexManager.addEntry(folderPath, {\n name: item.name,\n path: `./${fileName}`,\n description: (item.data as { purpose?: string }).purpose || `${item.name} service`,\n type: \"file\",\n });\n\n // Update entity INDEX if this is an entity service\n if (folderPath.startsWith(\"entities/\") && folderPath.includes(\"/services\")) {\n const entityFolder = folderPath.split(\"/\").slice(0, 2).join(\"/\");\n await this.indexManager.addEntry(entityFolder, {\n name: \"services\",\n path: \"./services/INDEX.md\",\n description: \"Service layer documentation\",\n type: \"folder\",\n });\n }\n }\n\n private async processPattern(item: DetectedItem): Promise<void> {\n const archPath = path.join(this.vaultPath, \"architecture.md\");\n const existing = await readTextFile(archPath);\n\n if (!existing) {\n await writeTextFile(archPath, `# Architecture\\n\\n${item.content}`);\n return;\n }\n\n // Check if pattern already exists\n if (existing.includes(`## ${item.name}`)) {\n // Replace existing section\n const regex = new RegExp(`## ${item.name}[\\\\s\\\\S]*?(?=\\\\n## |$)`);\n const updated = existing.replace(regex, item.content);\n await writeTextFile(archPath, updated);\n } else {\n // Append new pattern\n await appendToFile(archPath, `\\n${item.content}`);\n }\n }\n\n private async processKnowledge(item: DetectedItem): Promise<void> {\n const knowledgePath = path.join(this.vaultPath, \"general-knowledge.md\");\n const existing = await readTextFile(knowledgePath);\n\n if (!existing) {\n await writeTextFile(knowledgePath, `# General Knowledge\\n\\n${item.content}`);\n return;\n }\n\n // Check if topic already exists\n if (existing.includes(`## ${item.name}`)) {\n // Replace existing section\n const regex = new RegExp(`## ${item.name}[\\\\s\\\\S]*?(?=\\\\n## |$)`);\n const updated = existing.replace(regex, item.content);\n await writeTextFile(knowledgePath, updated);\n } else {\n // Append new knowledge\n await appendToFile(knowledgePath, `\\n${item.content}`);\n }\n }\n\n private async updateRootIndex(): Promise<void> {\n const indexPath = path.join(this.vaultPath, \"INDEX.md\");\n const content = await readTextFile(indexPath);\n\n if (!content) {\n return;\n }\n\n // Update the \"Last Updated\" line\n const timestamp = new Date().toISOString();\n const updated = content.replace(\n /## Last Updated[\\s\\S]*$/,\n `## Last Updated\\n\\n${timestamp}`\n );\n\n await writeTextFile(indexPath, updated);\n }\n}\n","import { spawn } from \"node:child_process\";\n\n/**\n * Spawns a Claude Code subagent to process a prompt.\n * Uses the Claude Code CLI with the --print flag to get output.\n */\nexport async function spawnClaudeAgent(prompt: string): Promise<string> {\n return new Promise((resolve, reject) => {\n // Use claude CLI with --print to get output without interactive mode\n const child = spawn(\"claude\", [\"--print\", \"-p\", prompt], {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n timeout: 120000, // 2 minute timeout\n });\n\n let stdout = \"\";\n let stderr = \"\";\n\n child.stdout?.on(\"data\", (data) => {\n stdout += data.toString();\n });\n\n child.stderr?.on(\"data\", (data) => {\n stderr += data.toString();\n });\n\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve(stdout.trim());\n } else {\n reject(new Error(`Claude agent failed with code ${code}: ${stderr}`));\n }\n });\n\n child.on(\"error\", (error) => {\n reject(error);\n });\n });\n}\n\n/**\n * Checks if Claude CLI is available.\n */\nexport async function isClaudeAvailable(): Promise<boolean> {\n return new Promise((resolve) => {\n const child = spawn(\"claude\", [\"--version\"], {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n\n child.on(\"close\", (code) => {\n resolve(code === 0);\n });\n\n child.on(\"error\", () => {\n resolve(false);\n });\n });\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/core/entity-detector.ts","../src/core/vault-integrator.ts","../src/utils/claude-sdk.ts"],"sourcesContent":["import type { Summary, ExtractedEntity, ServiceItem } from \"./compaction-engine.js\";\n\nexport interface DetectedItem {\n type: \"entity\" | \"service\" | \"pattern\" | \"knowledge\";\n name: string;\n data: unknown;\n vaultPath: string;\n content: string;\n}\n\nexport class EntityDetector {\n /**\n * Analyzes a summary and determines what should be added to the vault.\n */\n detect(summary: Summary): DetectedItem[] {\n const items: DetectedItem[] = [];\n\n // Detect entities\n for (const entity of summary.entities) {\n items.push(this.createEntityItem(entity));\n\n // Also create service entries for entity-related services\n const relatedServices = summary.services.filter(\n (s) =>\n s.name.toLowerCase().includes(entity.name.toLowerCase()) ||\n s.location?.toLowerCase().includes(entity.name.toLowerCase())\n );\n\n for (const service of relatedServices) {\n items.push(this.createServiceItem(entity.name, service));\n }\n }\n\n // Detect standalone services\n const processedServiceNames = new Set<string>();\n for (const entity of summary.entities) {\n for (const service of summary.services) {\n if (\n service.name.toLowerCase().includes(entity.name.toLowerCase()) ||\n service.location?.toLowerCase().includes(entity.name.toLowerCase())\n ) {\n processedServiceNames.add(service.name);\n }\n }\n }\n\n for (const service of summary.services) {\n if (!processedServiceNames.has(service.name)) {\n items.push(this.createStandaloneServiceItem(service));\n }\n }\n\n // Detect architecture patterns\n for (const arch of summary.architecture) {\n items.push(this.createArchitectureItem(arch));\n }\n\n // Detect general knowledge\n for (const knowledge of summary.knowledge) {\n items.push(this.createKnowledgeItem(knowledge));\n }\n\n return items;\n }\n\n private createEntityItem(entity: ExtractedEntity): DetectedItem {\n const content = this.formatEntityContent(entity);\n\n return {\n type: \"entity\",\n name: entity.name,\n data: entity,\n vaultPath: `entities/${entity.name.toLowerCase()}`,\n content,\n };\n }\n\n private createServiceItem(\n entityName: string,\n service: ServiceItem\n ): DetectedItem {\n const content = this.formatServiceContent(service);\n const serviceName = service.name.toLowerCase().replace(entityName.toLowerCase(), \"\").trim();\n const fileName = serviceName || \"service\";\n\n return {\n type: \"service\",\n name: service.name,\n data: service,\n vaultPath: `entities/${entityName.toLowerCase()}/services/${fileName}`,\n content,\n };\n }\n\n private createStandaloneServiceItem(service: ServiceItem): DetectedItem {\n const content = this.formatServiceContent(service);\n\n return {\n type: \"service\",\n name: service.name,\n data: service,\n vaultPath: `services/${service.name.toLowerCase()}`,\n content,\n };\n }\n\n private createArchitectureItem(arch: {\n pattern: string;\n description: string;\n affectedFiles: string[];\n }): DetectedItem {\n const content = `## ${arch.pattern}\n\n${arch.description}\n\n### Affected Files\n${arch.affectedFiles.map((f) => `- ${f}`).join(\"\\n\")}\n`;\n\n return {\n type: \"pattern\",\n name: arch.pattern,\n data: arch,\n vaultPath: \"architecture\",\n content,\n };\n }\n\n private createKnowledgeItem(knowledge: {\n topic: string;\n details: string;\n }): DetectedItem {\n const content = `## ${knowledge.topic}\n\n${knowledge.details}\n`;\n\n return {\n type: \"knowledge\",\n name: knowledge.topic,\n data: knowledge,\n vaultPath: \"general-knowledge\",\n content,\n };\n }\n\n private formatEntityContent(entity: ExtractedEntity): string {\n let content = `# ${entity.name}\\n\\n`;\n\n if (entity.location) {\n content += `**Location**: ${entity.location}\\n\\n`;\n }\n\n if (entity.attributes.length > 0) {\n content += `## Attributes\\n\\n`;\n for (const attr of entity.attributes) {\n content += `- ${attr}\\n`;\n }\n content += \"\\n\";\n }\n\n if (entity.relations.length > 0) {\n content += `## Relations\\n\\n`;\n for (const rel of entity.relations) {\n content += `- ${rel}\\n`;\n }\n content += \"\\n\";\n }\n\n return content;\n }\n\n private formatServiceContent(service: ServiceItem): string {\n let content = `# ${service.name}\\n\\n`;\n\n if (service.location) {\n content += `**Location**: ${service.location}\\n\\n`;\n }\n\n if (service.purpose) {\n content += `## Purpose\\n\\n${service.purpose}\\n\\n`;\n }\n\n if (service.methods.length > 0) {\n content += `## Methods\\n\\n`;\n for (const method of service.methods) {\n content += `- ${method}\\n`;\n }\n content += \"\\n\";\n }\n\n return content;\n }\n}\n","import * as path from \"node:path\";\nimport {\n readTextFile,\n writeTextFile,\n appendToFile,\n ensureDir,\n fileExists,\n} from \"../utils/file-utils.js\";\nimport { IndexManager } from \"./index-manager.js\";\nimport { EntityDetector, type DetectedItem } from \"./entity-detector.js\";\nimport type { Summary } from \"./compaction-engine.js\";\n\nexport class VaultIntegrator {\n private vaultPath: string;\n private indexManager: IndexManager;\n private entityDetector: EntityDetector;\n\n constructor(vaultPath: string) {\n this.vaultPath = vaultPath;\n this.indexManager = new IndexManager(vaultPath);\n this.entityDetector = new EntityDetector();\n }\n\n async integrate(summary: Summary): Promise<void> {\n // Detect items from summary\n const items = this.entityDetector.detect(summary);\n\n if (items.length === 0) {\n return;\n }\n\n // Process each detected item\n for (const item of items) {\n await this.processItem(item);\n }\n\n // Update root INDEX.md with timestamp\n await this.updateRootIndex();\n }\n\n private async processItem(item: DetectedItem): Promise<void> {\n switch (item.type) {\n case \"entity\":\n await this.processEntity(item);\n break;\n case \"service\":\n await this.processService(item);\n break;\n case \"pattern\":\n await this.processPattern(item);\n break;\n case \"knowledge\":\n await this.processKnowledge(item);\n break;\n }\n }\n\n private async processEntity(item: DetectedItem): Promise<void> {\n const entityPath = await this.indexManager.ensureEntityFolder(item.name);\n const fullPath = path.join(this.vaultPath, entityPath);\n\n // Write attributes.md\n const attributesPath = path.join(fullPath, \"attributes.md\");\n await writeTextFile(attributesPath, item.content);\n\n // Update entity INDEX.md\n await this.indexManager.addEntry(entityPath, {\n name: \"attributes\",\n path: \"./attributes.md\",\n description: `Attributes of ${item.name}`,\n type: \"file\",\n });\n }\n\n private async processService(item: DetectedItem): Promise<void> {\n const pathParts = item.vaultPath.split(\"/\");\n const fileName = pathParts.pop() + \".md\";\n const folderPath = pathParts.join(\"/\");\n const fullFolderPath = path.join(this.vaultPath, folderPath);\n\n await ensureDir(fullFolderPath);\n\n // Write service file\n const filePath = path.join(fullFolderPath, fileName);\n await writeTextFile(filePath, item.content);\n\n // Ensure parent has INDEX.md\n const parentIndexPath = path.join(fullFolderPath, \"INDEX.md\");\n if (!(await fileExists(parentIndexPath))) {\n await this.indexManager.createIndex(folderPath, []);\n }\n\n // Update parent INDEX.md\n await this.indexManager.addEntry(folderPath, {\n name: item.name,\n path: `./${fileName}`,\n description: (item.data as { purpose?: string }).purpose || `${item.name} service`,\n type: \"file\",\n });\n\n // Update entity INDEX if this is an entity service\n if (folderPath.startsWith(\"entities/\") && folderPath.includes(\"/services\")) {\n const entityFolder = folderPath.split(\"/\").slice(0, 2).join(\"/\");\n await this.indexManager.addEntry(entityFolder, {\n name: \"services\",\n path: \"./services/INDEX.md\",\n description: \"Service layer documentation\",\n type: \"folder\",\n });\n }\n }\n\n private async processPattern(item: DetectedItem): Promise<void> {\n const archPath = path.join(this.vaultPath, \"architecture.md\");\n const existing = await readTextFile(archPath);\n\n if (!existing) {\n await writeTextFile(archPath, `# Architecture\\n\\n${item.content}`);\n return;\n }\n\n // Check if pattern already exists\n if (existing.includes(`## ${item.name}`)) {\n // Replace existing section\n const regex = new RegExp(`## ${item.name}[\\\\s\\\\S]*?(?=\\\\n## |$)`);\n const updated = existing.replace(regex, item.content);\n await writeTextFile(archPath, updated);\n } else {\n // Append new pattern\n await appendToFile(archPath, `\\n${item.content}`);\n }\n }\n\n private async processKnowledge(item: DetectedItem): Promise<void> {\n const knowledgePath = path.join(this.vaultPath, \"general-knowledge.md\");\n const existing = await readTextFile(knowledgePath);\n\n if (!existing) {\n await writeTextFile(knowledgePath, `# General Knowledge\\n\\n${item.content}`);\n return;\n }\n\n // Check if topic already exists\n if (existing.includes(`## ${item.name}`)) {\n // Replace existing section\n const regex = new RegExp(`## ${item.name}[\\\\s\\\\S]*?(?=\\\\n## |$)`);\n const updated = existing.replace(regex, item.content);\n await writeTextFile(knowledgePath, updated);\n } else {\n // Append new knowledge\n await appendToFile(knowledgePath, `\\n${item.content}`);\n }\n }\n\n private async updateRootIndex(): Promise<void> {\n const indexPath = path.join(this.vaultPath, \"INDEX.md\");\n const content = await readTextFile(indexPath);\n\n if (!content) {\n return;\n }\n\n // Update the \"Last Updated\" line\n const timestamp = new Date().toISOString();\n const updated = content.replace(\n /## Last Updated[\\s\\S]*$/,\n `## Last Updated\\n\\n${timestamp}`\n );\n\n await writeTextFile(indexPath, updated);\n }\n}\n","import { spawn } from \"node:child_process\";\n\nexport interface ClaudeAgentOptions {\n timeout?: number; // milliseconds, default 5 minutes\n}\n\n/**\n * Spawns a Claude Code subagent to process a prompt.\n * Uses the Claude Code CLI with the --print flag to get output.\n */\nexport async function spawnClaudeAgent(\n prompt: string,\n options?: ClaudeAgentOptions\n): Promise<string> {\n const timeout = options?.timeout ?? 300000; // 5 minutes default\n\n return new Promise((resolve, reject) => {\n // Use claude CLI with --print to get output without interactive mode\n const child = spawn(\"claude\", [\"--print\", \"-p\", prompt], {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n\n let stdout = \"\";\n let stderr = \"\";\n let timedOut = false;\n\n // Manual timeout since spawn timeout doesn't always work\n const timeoutId = setTimeout(() => {\n timedOut = true;\n child.kill(\"SIGTERM\");\n reject(new Error(`Claude agent timed out after ${timeout / 1000}s`));\n }, timeout);\n\n child.stdout?.on(\"data\", (data) => {\n stdout += data.toString();\n });\n\n child.stderr?.on(\"data\", (data) => {\n stderr += data.toString();\n });\n\n child.on(\"close\", (code) => {\n clearTimeout(timeoutId);\n if (timedOut) return; // Already rejected\n\n if (code === 0) {\n resolve(stdout.trim());\n } else {\n reject(new Error(`Claude agent failed with code ${code}: ${stderr || \"(no stderr)\"}`));\n }\n });\n\n child.on(\"error\", (error) => {\n clearTimeout(timeoutId);\n reject(error);\n });\n });\n}\n\n/**\n * Checks if Claude CLI is available.\n */\nexport async function isClaudeAvailable(): Promise<boolean> {\n return new Promise((resolve) => {\n const child = spawn(\"claude\", [\"--version\"], {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n\n child.on(\"close\", (code) => {\n resolve(code === 0);\n });\n\n child.on(\"error\", () => {\n resolve(false);\n });\n });\n}\n"],"mappings":"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","names":[]}
|
|
@@ -88,7 +88,8 @@ var DEFAULT_CONFIG = {
|
|
|
88
88
|
},
|
|
89
89
|
discover: {
|
|
90
90
|
maxFiles: 100,
|
|
91
|
-
maxChunkSize:
|
|
91
|
+
maxChunkSize: 3e4,
|
|
92
|
+
// ~7500 tokens, safer for Claude
|
|
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-
|
|
155
|
+
//# sourceMappingURL=chunk-V6LRQYKA.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: 30000, // ~7500 tokens, safer for Claude\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,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
IndexManager
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-D753AA36.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-
|
|
11
|
+
} from "../chunk-V6LRQYKA.js";
|
|
12
12
|
|
|
13
13
|
// src/hooks/notification.ts
|
|
14
14
|
import * as path from "path";
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ConversationManager
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-2USUMNE7.js";
|
|
4
4
|
import {
|
|
5
5
|
IndexManager
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-D753AA36.js";
|
|
7
7
|
import {
|
|
8
8
|
getVaultPath
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-V6LRQYKA.js";
|
|
10
10
|
|
|
11
11
|
// src/hooks/session-start.ts
|
|
12
12
|
async function handleSessionStart() {
|
package/dist/hooks/stop.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CompactionEngine
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-C7H3GIXY.js";
|
|
4
4
|
import {
|
|
5
5
|
VaultIntegrator
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-FEXOQA6H.js";
|
|
7
7
|
import {
|
|
8
8
|
ConversationManager
|
|
9
|
-
} from "../chunk-
|
|
10
|
-
import "../chunk-
|
|
9
|
+
} from "../chunk-2USUMNE7.js";
|
|
10
|
+
import "../chunk-D753AA36.js";
|
|
11
11
|
import {
|
|
12
12
|
getVaultPath,
|
|
13
13
|
loadConfig
|
|
14
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-V6LRQYKA.js";
|
|
15
15
|
|
|
16
16
|
// src/hooks/stop.ts
|
|
17
17
|
async function handleStop() {
|
package/dist/index.d.ts
CHANGED
|
@@ -149,6 +149,7 @@ declare class AutoDiscover {
|
|
|
149
149
|
constructor(projectPath: string, verbose?: boolean);
|
|
150
150
|
discover(options?: DiscoverOptions): Promise<DiscoveryResult>;
|
|
151
151
|
private analyzeChunk;
|
|
152
|
+
private runWithProgressIndicators;
|
|
152
153
|
private parseResponse;
|
|
153
154
|
private parseEntities;
|
|
154
155
|
private parseArchitecture;
|
package/dist/index.js
CHANGED
|
@@ -4,21 +4,21 @@ import {
|
|
|
4
4
|
FileCollector,
|
|
5
5
|
discover,
|
|
6
6
|
install
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-CGTH2E5W.js";
|
|
8
8
|
import {
|
|
9
9
|
CompactionEngine
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-C7H3GIXY.js";
|
|
11
11
|
import {
|
|
12
12
|
EntityDetector,
|
|
13
13
|
VaultIntegrator
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-FEXOQA6H.js";
|
|
15
15
|
import {
|
|
16
16
|
ConversationManager
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-2USUMNE7.js";
|
|
18
18
|
import {
|
|
19
19
|
IndexManager
|
|
20
|
-
} from "./chunk-
|
|
21
|
-
import "./chunk-
|
|
20
|
+
} from "./chunk-D753AA36.js";
|
|
21
|
+
import "./chunk-V6LRQYKA.js";
|
|
22
22
|
export {
|
|
23
23
|
AutoDiscover,
|
|
24
24
|
ChunkManager,
|
package/package.json
CHANGED
|
@@ -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":";AAAA,YAAY,QAAQ;AACpB,YAAY,UAAU;AAEtB,eAAsB,UAAU,SAAgC;AAC9D,QAAS,SAAM,SAAS,EAAE,WAAW,KAAK,CAAC;AAC7C;AAEA,eAAsB,WAAW,UAAoC;AACnE,MAAI;AACF,UAAS,UAAO,QAAQ;AACxB,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,SAAY,UAAqC;AACrE,MAAI;AACF,UAAM,UAAU,MAAS,YAAS,UAAU,OAAO;AACnD,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,UACpB,UACA,MACA,SAAS,MACM;AACf,QAAM,UAAe,aAAQ,QAAQ,CAAC;AACtC,QAAM,UAAU,SAAS,KAAK,UAAU,MAAM,MAAM,CAAC,IAAI,KAAK,UAAU,IAAI;AAC5E,QAAS,aAAU,UAAU,OAAO;AACtC;AAEA,eAAsB,aACpB,UACA,SACe;AACf,QAAM,UAAe,aAAQ,QAAQ,CAAC;AACtC,QAAS,cAAW,UAAU,OAAO;AACvC;AAEA,eAAsB,aAAa,UAA0C;AAC3E,MAAI;AACF,WAAO,MAAS,YAAS,UAAU,OAAO;AAAA,EAC5C,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,cACpB,UACA,SACe;AACf,QAAM,UAAe,aAAQ,QAAQ,CAAC;AACtC,QAAS,aAAU,UAAU,OAAO;AACtC;AAOA,eAAsB,QAAQ,SAAoC;AAChE,MAAI;AACF,WAAO,MAAS,WAAQ,OAAO;AAAA,EACjC,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEA,eAAsB,YAAY,UAAmC;AACnE,MAAI;AACF,UAAM,QAAQ,MAAS,QAAK,QAAQ;AACpC,WAAO,MAAM;AAAA,EACf,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,oBAA4B;AAC1C,QAAM,YAAY,KAAK,IAAI,EAAE,SAAS,EAAE;AACxC,QAAM,SAAS,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,UAAU,GAAG,CAAC;AACxD,SAAO,GAAG,SAAS,IAAI,MAAM;AAC/B;AAEO,SAAS,sBAA8B;AAC5C,UAAO,oBAAI,KAAK,GAAE,YAAY;AAChC;;;ACzFA,YAAYA,SAAQ;AACpB,YAAYC,WAAU;AA8Bf,IAAM,iBAA6B;AAAA,EACxC,YAAY;AAAA,IACV,SAAS;AAAA,IACT,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,qBAAqB;AAAA,EACvB;AAAA,EACA,SAAS;AAAA,IACP,OAAO,CAAC,SAAS,QAAQ,aAAa,QAAQ,MAAM;AAAA,IACpD,kBAAkB;AAAA,EACpB;AAAA,EACA,OAAO;AAAA,IACL,eAAe;AAAA,IACf,UAAU;AAAA,EACZ;AAAA,EACA,UAAU;AAAA,IACR,SAAS;AAAA,IACT,cAAc;AAAA,EAChB;AAAA,EACA,UAAU;AAAA,IACR,UAAU;AAAA,IACV,cAAc;AAAA,IACd,iBAAiB;AAAA,MACf;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,kBAAkB;AAAA,MAChB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,oBAAoB,CAAC,cAAc,cAAc,UAAU,MAAM,MAAM;AAAA,EACzE;AACF;AAEA,eAAsB,WAAW,aAA0C;AACzE,QAAM,aAAkB;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI;AACF,UAAM,UAAU,MAAS,aAAS,YAAY,OAAO;AACrD,UAAM,aAAa,KAAK,MAAM,OAAO;AACrC,WAAO,EAAE,GAAG,gBAAgB,GAAG,WAAW;AAAA,EAC5C,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAmBO,SAAS,qBAAqB,aAA6B;AAChE,SAAY,WAAK,aAAa,qBAAqB,eAAe;AACpE;AAEO,SAAS,aAAa,aAA6B;AACxD,SAAY,WAAK,aAAa,qBAAqB,OAAO;AAC5D;AAEO,SAAS,aAAa,aAA6B;AACxD,SAAY,WAAK,aAAa,qBAAqB,aAAa;AAClE;","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 this.log(` Warning: Chunk ${chunk.index + 1} analysis failed`);\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 spawnClaudeAgent(prompt);\n\n return this.parseResponse(response, chunk);\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"]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|