@weavelogic/knowledge-graph-agent 0.10.4 ā 0.10.5
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/cli/commands/cultivate.d.ts.map +1 -1
- package/dist/cli/commands/cultivate.js +1 -0
- package/dist/cli/commands/cultivate.js.map +1 -1
- package/dist/cultivation/deep-analyzer.d.ts +25 -4
- package/dist/cultivation/deep-analyzer.d.ts.map +1 -1
- package/dist/cultivation/deep-analyzer.js +79 -17
- package/dist/cultivation/deep-analyzer.js.map +1 -1
- package/dist/node_modules/@google/generative-ai/dist/index.js +1256 -0
- package/dist/node_modules/@google/generative-ai/dist/index.js.map +1 -0
- package/dist/node_modules/@typescript-eslint/types/dist/index.js +1 -1
- package/dist/node_modules/@typescript-eslint/visitor-keys/dist/index.js +1 -1
- package/package.json +3 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cultivate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/cultivate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgCpC;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,
|
|
1
|
+
{"version":3,"file":"cultivate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/cultivate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgCpC;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CA+PhD"}
|
|
@@ -136,6 +136,7 @@ function createCultivateCommand() {
|
|
|
136
136
|
console.log(chalk.gray(" Options:"));
|
|
137
137
|
console.log(chalk.gray(" 1. Run from a regular terminal (outside Claude Code)"));
|
|
138
138
|
console.log(chalk.gray(" 2. Set ANTHROPIC_API_KEY environment variable"));
|
|
139
|
+
console.log(chalk.gray(" 3. Set GOOGLE_AI_API_KEY for Gemini fallback"));
|
|
139
140
|
result.warnings.push(`Deep analysis unavailable: ${availability.reason}`);
|
|
140
141
|
} else {
|
|
141
142
|
console.log(chalk.gray(` Mode: ${availability.reason}`));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cultivate.js","sources":["../../../src/cli/commands/cultivate.ts"],"sourcesContent":["/**\n * Cultivate Command - Systematically enhance the knowledge graph\n *\n * This command provides cultivation tasks:\n * - Seed primitives from codebase analysis\n * - Deep analysis with claude-flow integration\n * - Graph enhancement and optimization\n *\n * @module cli/commands/cultivate\n */\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport { resolve, join, relative } from 'path';\nimport { existsSync, mkdirSync, readFileSync, readdirSync, statSync } from 'fs';\nimport { SeedGenerator } from '../../cultivation/seed-generator.js';\nimport { ShadowCache, loadShadowCache } from '../../core/cache.js';\nimport type { CultivationOptions, Ecosystem, SeedAnalysis } from '../../cultivation/types.js';\n\n/**\n * Cultivation result\n */\ninterface CultivationResult {\n success: boolean;\n seed: {\n created: number;\n documents: Array<{ title: string; path: string; type: string }>;\n };\n analysis: {\n filesProcessed: number;\n dependenciesFound: number;\n servicesFound: number;\n };\n cache: {\n updated: number;\n hits: number;\n misses: number;\n };\n duration: number;\n warnings: string[];\n errors: string[];\n}\n\n/**\n * Create cultivate command\n */\nexport function createCultivateCommand(): Command {\n return new Command('cultivate')\n .description('Systematically cultivate and enhance the knowledge graph')\n .argument('[path]', 'Directory to cultivate (defaults to current directory)', '.')\n .option('--dry-run', 'Preview changes without executing', false)\n .option('-d, --docs <path>', 'Documentation path', 'docs')\n .option('-v, --verbose', 'Verbose output', false)\n .option('--seed', 'Bootstrap vault with primitives from codebase analysis', false)\n .option('--deep-analysis', 'Use claude-flow agents for deep analysis', false)\n .option('--cache', 'Use shadow cache for incremental updates', true)\n .option('--ecosystem <ecosystems>', 'Filter to specific ecosystems (comma-separated)', undefined)\n .option('--include-dev', 'Include dev dependencies', false)\n .option('--major-only', 'Only process major dependencies', false)\n .option('--refresh-cache', 'Force refresh the shadow cache', false)\n .action(async (targetPath: string, options: {\n dryRun?: boolean;\n docs?: string;\n verbose?: boolean;\n seed?: boolean;\n deepAnalysis?: boolean;\n cache?: boolean;\n ecosystem?: string;\n includeDev?: boolean;\n majorOnly?: boolean;\n refreshCache?: boolean;\n }) => {\n const projectRoot = resolve(targetPath);\n const docsPath = options.docs || 'docs';\n const verbose = options.verbose || false;\n const dryRun = options.dryRun || false;\n\n console.log(chalk.bold.green('\\nš± Knowledge Graph Cultivator\\n'));\n console.log(` Project: ${projectRoot}`);\n console.log(` Docs: ${docsPath}`);\n if (dryRun) {\n console.log(` Mode: ${chalk.yellow('Dry Run')}`);\n }\n console.log('');\n\n // Determine tasks\n const tasks = {\n seed: options.seed || false,\n deepAnalysis: options.deepAnalysis || false,\n };\n\n // If no tasks selected, show help\n if (!tasks.seed && !tasks.deepAnalysis) {\n console.log(chalk.yellow('š” No tasks selected. Use one or more of:'));\n console.log(' --seed Bootstrap vault with primitives from codebase');\n console.log(' --deep-analysis Use claude-flow for deep codebase analysis');\n console.log('');\n console.log(chalk.gray('Options:'));\n console.log(' --dry-run Preview without writing files');\n console.log(' --cache Use shadow cache for incremental updates (default: true)');\n console.log(' --refresh-cache Force refresh the shadow cache');\n console.log(' --ecosystem Filter to ecosystems (nodejs,python,rust,go,php,java)');\n console.log(' --include-dev Include dev dependencies');\n console.log(' --major-only Only process major dependencies');\n console.log('');\n console.log('Run \"kg cultivate --help\" for more options');\n return;\n }\n\n const startTime = Date.now();\n const result: CultivationResult = {\n success: true,\n seed: { created: 0, documents: [] },\n analysis: { filesProcessed: 0, dependenciesFound: 0, servicesFound: 0 },\n cache: { updated: 0, hits: 0, misses: 0 },\n duration: 0,\n warnings: [],\n errors: [],\n };\n\n try {\n // Initialize shadow cache\n let cache: ShadowCache | undefined;\n if (options.cache !== false) {\n console.log(chalk.cyan('š¦ Initializing shadow cache...'));\n cache = await loadShadowCache(projectRoot);\n\n if (options.refreshCache) {\n cache.clear();\n console.log(chalk.gray(' Cache cleared (refresh mode)'));\n }\n\n const stats = cache.getStats();\n console.log(chalk.gray(` Entries: ${stats.totalEntries}, Hit rate: ${(stats.hitRate * 100).toFixed(1)}%`));\n console.log('');\n }\n\n // Task 1: Seed primitives\n if (tasks.seed) {\n console.log(chalk.cyan('š± Seeding primitives from codebase...\\n'));\n\n // Parse ecosystem filter\n let ecosystems: Ecosystem[] | undefined;\n if (options.ecosystem) {\n ecosystems = options.ecosystem.split(',').map(e => e.trim() as Ecosystem);\n console.log(chalk.gray(` Ecosystems: ${ecosystems.join(', ')}`));\n }\n\n // Create generator\n const generator = await SeedGenerator.create(projectRoot, docsPath);\n\n // Analyze\n console.log(chalk.gray(' Analyzing codebase...'));\n const analysis = await generator.analyze();\n\n result.analysis = {\n filesProcessed: analysis.metadata.filesScanned,\n dependenciesFound: analysis.dependencies.length,\n servicesFound: analysis.services.length,\n };\n\n // Display analysis\n console.log(`\\n ${chalk.bold('Analysis Results:')}`);\n console.log(` Languages: ${analysis.languages.join(', ') || 'none'}`);\n console.log(` Dependencies: ${analysis.dependencies.length}`);\n console.log(` Frameworks: ${analysis.frameworks.length}`);\n console.log(` Services: ${analysis.services.length}`);\n console.log(` Deployments: ${analysis.deployments.length}`);\n\n if (verbose) {\n displayDetailedAnalysis(analysis);\n }\n\n console.log('');\n\n // Generate primitives\n console.log(chalk.gray(' Generating primitive nodes...'));\n const documents = await generator.generatePrimitives(analysis);\n\n if (dryRun) {\n console.log(`\\n ${chalk.yellow('[DRY RUN]')} Would create ${documents.length} primitives:`);\n for (const doc of documents.slice(0, 10)) {\n console.log(` - ${doc.frontmatter.type}: ${doc.title}`);\n }\n if (documents.length > 10) {\n console.log(` ... and ${documents.length - 10} more`);\n }\n result.seed.documents = documents.map(d => ({\n title: d.title,\n path: d.path,\n type: d.frontmatter.type || 'unknown',\n }));\n } else {\n const writeResult = await generator.writePrimitives(documents);\n result.seed.created = writeResult.documentsGenerated.length;\n result.seed.documents = writeResult.documentsGenerated;\n\n console.log(`\\n ${chalk.green('ā')} Created ${writeResult.documentsGenerated.length} primitives`);\n\n if (writeResult.warnings.length > 0) {\n result.warnings.push(...writeResult.warnings);\n if (verbose) {\n console.log(chalk.yellow(` Warnings: ${writeResult.warnings.length}`));\n }\n }\n\n if (writeResult.errors.length > 0) {\n result.errors.push(...writeResult.errors);\n console.log(chalk.red(` Errors: ${writeResult.errors.length}`));\n }\n }\n\n console.log('');\n }\n\n // Task 2: Deep Analysis\n if (tasks.deepAnalysis) {\n console.log(chalk.cyan('š§ Running deep analysis...\\n'));\n\n // Import and check DeepAnalyzer availability\n const { DeepAnalyzer } = await import('../../cultivation/deep-analyzer.js');\n const analyzer = new DeepAnalyzer({\n projectRoot,\n docsPath,\n verbose,\n });\n\n const availability = await analyzer.getAvailabilityStatus();\n\n if (!availability.available) {\n console.log(chalk.yellow(' ā ļø Deep analysis unavailable'));\n console.log(chalk.gray(` ${availability.reason}`));\n console.log('');\n console.log(chalk.gray(' Options:'));\n console.log(chalk.gray(' 1. Run from a regular terminal (outside Claude Code)'));\n console.log(chalk.gray(' 2. Set ANTHROPIC_API_KEY environment variable'));\n result.warnings.push(`Deep analysis unavailable: ${availability.reason}`);\n } else {\n console.log(chalk.gray(` Mode: ${availability.reason}`));\n\n if (dryRun) {\n console.log(chalk.yellow('\\n [DRY RUN] Would run analysis agents:'));\n console.log(' - Pattern Researcher: Analyze codebase architecture');\n console.log(' - Code Analyst: Identify quality issues');\n console.log(' - Implementation Reviewer: Review code patterns');\n console.log(' - Test Analyzer: Analyze test coverage');\n } else {\n try {\n const deepResult = await analyzer.analyze();\n\n if (deepResult.success) {\n console.log(`\\n ${chalk.green('ā')} Deep analysis complete`);\n console.log(` Agents spawned: ${deepResult.agentsSpawned}`);\n console.log(` Insights generated: ${deepResult.insightsCount}`);\n console.log(` Documentation created: ${deepResult.documentsCreated}`);\n console.log(` Mode: ${deepResult.mode}`);\n } else {\n console.log(`\\n ${chalk.yellow('ā ')} Deep analysis completed with issues`);\n console.log(` Agents spawned: ${deepResult.agentsSpawned}`);\n console.log(` Insights generated: ${deepResult.insightsCount}`);\n if (deepResult.errors.length > 0) {\n for (const err of deepResult.errors.slice(0, 3)) {\n console.log(chalk.gray(` - ${err}`));\n }\n }\n result.warnings.push(...deepResult.errors);\n }\n } catch (error) {\n result.errors.push(`Deep analysis failed: ${error instanceof Error ? error.message : String(error)}`);\n console.log(chalk.red(` ā Deep analysis failed: ${error instanceof Error ? error.message : String(error)}`));\n }\n }\n }\n\n console.log('');\n }\n\n // Update cache\n if (cache) {\n const stats = cache.getStats();\n result.cache = {\n updated: stats.totalEntries,\n hits: stats.hitCount,\n misses: stats.missCount,\n };\n\n await cache.save();\n }\n\n result.duration = Date.now() - startTime;\n result.success = result.errors.length === 0;\n\n // Final summary\n displaySummary(result, dryRun);\n\n } catch (error) {\n console.error(chalk.red('\\nā Cultivation failed:'), error);\n process.exit(1);\n }\n });\n}\n\n/**\n * Display detailed analysis output\n */\nfunction displayDetailedAnalysis(analysis: SeedAnalysis): void {\n if (analysis.frameworks.length > 0) {\n console.log(`\\n ${chalk.gray('Frameworks:')}`);\n for (const fw of analysis.frameworks) {\n console.log(` - ${fw.name} (${fw.ecosystem}) v${fw.version}`);\n }\n }\n\n if (analysis.services.length > 0) {\n console.log(`\\n ${chalk.gray('Services:')}`);\n for (const svc of analysis.services) {\n console.log(` - ${svc.name}: ${svc.type} (${svc.technology})`);\n }\n }\n\n if (analysis.deployments.length > 0) {\n console.log(`\\n ${chalk.gray('Deployments:')}`);\n for (const dep of analysis.deployments) {\n console.log(` - ${dep}`);\n }\n }\n}\n\n/**\n * Display cultivation summary\n */\nfunction displaySummary(result: CultivationResult, dryRun: boolean): void {\n console.log(chalk.bold.blue('š Cultivation Summary\\n'));\n\n if (dryRun) {\n console.log(chalk.yellow('[DRY RUN] No changes were made\\n'));\n }\n\n console.log(' Analysis:');\n console.log(` Files processed: ${result.analysis.filesProcessed}`);\n console.log(` Dependencies: ${result.analysis.dependenciesFound}`);\n console.log(` Services: ${result.analysis.servicesFound}`);\n\n if (result.seed.created > 0 || result.seed.documents.length > 0) {\n console.log('\\n Seed:');\n console.log(` Primitives ${dryRun ? 'would create' : 'created'}: ${dryRun ? result.seed.documents.length : result.seed.created}`);\n }\n\n if (result.cache.updated > 0) {\n console.log('\\n Cache:');\n console.log(` Entries: ${result.cache.updated}`);\n const hitRate = result.cache.hits + result.cache.misses > 0\n ? (result.cache.hits / (result.cache.hits + result.cache.misses) * 100).toFixed(1)\n : 0;\n console.log(` Hit rate: ${hitRate}%`);\n }\n\n console.log(`\\n Duration: ${(result.duration / 1000).toFixed(2)}s`);\n\n if (result.warnings.length > 0) {\n console.log(chalk.yellow(`\\n ā ļø Warnings: ${result.warnings.length}`));\n for (const warning of result.warnings.slice(0, 5)) {\n console.log(chalk.gray(` - ${warning}`));\n }\n }\n\n if (result.errors.length > 0) {\n console.log(chalk.red(`\\n ā Errors: ${result.errors.length}`));\n for (const error of result.errors.slice(0, 5)) {\n console.log(chalk.gray(` - ${error}`));\n }\n }\n\n if (result.success && !dryRun) {\n console.log(chalk.bold.green('\\n⨠Cultivation complete!\\n'));\n } else if (!result.success) {\n console.log(chalk.yellow('\\nā ļø Cultivation completed with errors\\n'));\n } else {\n console.log(chalk.gray('\\nRun without --dry-run to apply changes\\n'));\n }\n}\n\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cultivate.js","sources":["../../../src/cli/commands/cultivate.ts"],"sourcesContent":["/**\n * Cultivate Command - Systematically enhance the knowledge graph\n *\n * This command provides cultivation tasks:\n * - Seed primitives from codebase analysis\n * - Deep analysis with claude-flow integration\n * - Graph enhancement and optimization\n *\n * @module cli/commands/cultivate\n */\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport { resolve, join, relative } from 'path';\nimport { existsSync, mkdirSync, readFileSync, readdirSync, statSync } from 'fs';\nimport { SeedGenerator } from '../../cultivation/seed-generator.js';\nimport { ShadowCache, loadShadowCache } from '../../core/cache.js';\nimport type { CultivationOptions, Ecosystem, SeedAnalysis } from '../../cultivation/types.js';\n\n/**\n * Cultivation result\n */\ninterface CultivationResult {\n success: boolean;\n seed: {\n created: number;\n documents: Array<{ title: string; path: string; type: string }>;\n };\n analysis: {\n filesProcessed: number;\n dependenciesFound: number;\n servicesFound: number;\n };\n cache: {\n updated: number;\n hits: number;\n misses: number;\n };\n duration: number;\n warnings: string[];\n errors: string[];\n}\n\n/**\n * Create cultivate command\n */\nexport function createCultivateCommand(): Command {\n return new Command('cultivate')\n .description('Systematically cultivate and enhance the knowledge graph')\n .argument('[path]', 'Directory to cultivate (defaults to current directory)', '.')\n .option('--dry-run', 'Preview changes without executing', false)\n .option('-d, --docs <path>', 'Documentation path', 'docs')\n .option('-v, --verbose', 'Verbose output', false)\n .option('--seed', 'Bootstrap vault with primitives from codebase analysis', false)\n .option('--deep-analysis', 'Use claude-flow agents for deep analysis', false)\n .option('--cache', 'Use shadow cache for incremental updates', true)\n .option('--ecosystem <ecosystems>', 'Filter to specific ecosystems (comma-separated)', undefined)\n .option('--include-dev', 'Include dev dependencies', false)\n .option('--major-only', 'Only process major dependencies', false)\n .option('--refresh-cache', 'Force refresh the shadow cache', false)\n .action(async (targetPath: string, options: {\n dryRun?: boolean;\n docs?: string;\n verbose?: boolean;\n seed?: boolean;\n deepAnalysis?: boolean;\n cache?: boolean;\n ecosystem?: string;\n includeDev?: boolean;\n majorOnly?: boolean;\n refreshCache?: boolean;\n }) => {\n const projectRoot = resolve(targetPath);\n const docsPath = options.docs || 'docs';\n const verbose = options.verbose || false;\n const dryRun = options.dryRun || false;\n\n console.log(chalk.bold.green('\\nš± Knowledge Graph Cultivator\\n'));\n console.log(` Project: ${projectRoot}`);\n console.log(` Docs: ${docsPath}`);\n if (dryRun) {\n console.log(` Mode: ${chalk.yellow('Dry Run')}`);\n }\n console.log('');\n\n // Determine tasks\n const tasks = {\n seed: options.seed || false,\n deepAnalysis: options.deepAnalysis || false,\n };\n\n // If no tasks selected, show help\n if (!tasks.seed && !tasks.deepAnalysis) {\n console.log(chalk.yellow('š” No tasks selected. Use one or more of:'));\n console.log(' --seed Bootstrap vault with primitives from codebase');\n console.log(' --deep-analysis Use claude-flow for deep codebase analysis');\n console.log('');\n console.log(chalk.gray('Options:'));\n console.log(' --dry-run Preview without writing files');\n console.log(' --cache Use shadow cache for incremental updates (default: true)');\n console.log(' --refresh-cache Force refresh the shadow cache');\n console.log(' --ecosystem Filter to ecosystems (nodejs,python,rust,go,php,java)');\n console.log(' --include-dev Include dev dependencies');\n console.log(' --major-only Only process major dependencies');\n console.log('');\n console.log('Run \"kg cultivate --help\" for more options');\n return;\n }\n\n const startTime = Date.now();\n const result: CultivationResult = {\n success: true,\n seed: { created: 0, documents: [] },\n analysis: { filesProcessed: 0, dependenciesFound: 0, servicesFound: 0 },\n cache: { updated: 0, hits: 0, misses: 0 },\n duration: 0,\n warnings: [],\n errors: [],\n };\n\n try {\n // Initialize shadow cache\n let cache: ShadowCache | undefined;\n if (options.cache !== false) {\n console.log(chalk.cyan('š¦ Initializing shadow cache...'));\n cache = await loadShadowCache(projectRoot);\n\n if (options.refreshCache) {\n cache.clear();\n console.log(chalk.gray(' Cache cleared (refresh mode)'));\n }\n\n const stats = cache.getStats();\n console.log(chalk.gray(` Entries: ${stats.totalEntries}, Hit rate: ${(stats.hitRate * 100).toFixed(1)}%`));\n console.log('');\n }\n\n // Task 1: Seed primitives\n if (tasks.seed) {\n console.log(chalk.cyan('š± Seeding primitives from codebase...\\n'));\n\n // Parse ecosystem filter\n let ecosystems: Ecosystem[] | undefined;\n if (options.ecosystem) {\n ecosystems = options.ecosystem.split(',').map(e => e.trim() as Ecosystem);\n console.log(chalk.gray(` Ecosystems: ${ecosystems.join(', ')}`));\n }\n\n // Create generator\n const generator = await SeedGenerator.create(projectRoot, docsPath);\n\n // Analyze\n console.log(chalk.gray(' Analyzing codebase...'));\n const analysis = await generator.analyze();\n\n result.analysis = {\n filesProcessed: analysis.metadata.filesScanned,\n dependenciesFound: analysis.dependencies.length,\n servicesFound: analysis.services.length,\n };\n\n // Display analysis\n console.log(`\\n ${chalk.bold('Analysis Results:')}`);\n console.log(` Languages: ${analysis.languages.join(', ') || 'none'}`);\n console.log(` Dependencies: ${analysis.dependencies.length}`);\n console.log(` Frameworks: ${analysis.frameworks.length}`);\n console.log(` Services: ${analysis.services.length}`);\n console.log(` Deployments: ${analysis.deployments.length}`);\n\n if (verbose) {\n displayDetailedAnalysis(analysis);\n }\n\n console.log('');\n\n // Generate primitives\n console.log(chalk.gray(' Generating primitive nodes...'));\n const documents = await generator.generatePrimitives(analysis);\n\n if (dryRun) {\n console.log(`\\n ${chalk.yellow('[DRY RUN]')} Would create ${documents.length} primitives:`);\n for (const doc of documents.slice(0, 10)) {\n console.log(` - ${doc.frontmatter.type}: ${doc.title}`);\n }\n if (documents.length > 10) {\n console.log(` ... and ${documents.length - 10} more`);\n }\n result.seed.documents = documents.map(d => ({\n title: d.title,\n path: d.path,\n type: d.frontmatter.type || 'unknown',\n }));\n } else {\n const writeResult = await generator.writePrimitives(documents);\n result.seed.created = writeResult.documentsGenerated.length;\n result.seed.documents = writeResult.documentsGenerated;\n\n console.log(`\\n ${chalk.green('ā')} Created ${writeResult.documentsGenerated.length} primitives`);\n\n if (writeResult.warnings.length > 0) {\n result.warnings.push(...writeResult.warnings);\n if (verbose) {\n console.log(chalk.yellow(` Warnings: ${writeResult.warnings.length}`));\n }\n }\n\n if (writeResult.errors.length > 0) {\n result.errors.push(...writeResult.errors);\n console.log(chalk.red(` Errors: ${writeResult.errors.length}`));\n }\n }\n\n console.log('');\n }\n\n // Task 2: Deep Analysis\n if (tasks.deepAnalysis) {\n console.log(chalk.cyan('š§ Running deep analysis...\\n'));\n\n // Import and check DeepAnalyzer availability\n const { DeepAnalyzer } = await import('../../cultivation/deep-analyzer.js');\n const analyzer = new DeepAnalyzer({\n projectRoot,\n docsPath,\n verbose,\n });\n\n const availability = await analyzer.getAvailabilityStatus();\n\n if (!availability.available) {\n console.log(chalk.yellow(' ā ļø Deep analysis unavailable'));\n console.log(chalk.gray(` ${availability.reason}`));\n console.log('');\n console.log(chalk.gray(' Options:'));\n console.log(chalk.gray(' 1. Run from a regular terminal (outside Claude Code)'));\n console.log(chalk.gray(' 2. Set ANTHROPIC_API_KEY environment variable'));\n console.log(chalk.gray(' 3. Set GOOGLE_AI_API_KEY for Gemini fallback'));\n result.warnings.push(`Deep analysis unavailable: ${availability.reason}`);\n } else {\n console.log(chalk.gray(` Mode: ${availability.reason}`));\n\n if (dryRun) {\n console.log(chalk.yellow('\\n [DRY RUN] Would run analysis agents:'));\n console.log(' - Pattern Researcher: Analyze codebase architecture');\n console.log(' - Code Analyst: Identify quality issues');\n console.log(' - Implementation Reviewer: Review code patterns');\n console.log(' - Test Analyzer: Analyze test coverage');\n } else {\n try {\n const deepResult = await analyzer.analyze();\n\n if (deepResult.success) {\n console.log(`\\n ${chalk.green('ā')} Deep analysis complete`);\n console.log(` Agents spawned: ${deepResult.agentsSpawned}`);\n console.log(` Insights generated: ${deepResult.insightsCount}`);\n console.log(` Documentation created: ${deepResult.documentsCreated}`);\n console.log(` Mode: ${deepResult.mode}`);\n } else {\n console.log(`\\n ${chalk.yellow('ā ')} Deep analysis completed with issues`);\n console.log(` Agents spawned: ${deepResult.agentsSpawned}`);\n console.log(` Insights generated: ${deepResult.insightsCount}`);\n if (deepResult.errors.length > 0) {\n for (const err of deepResult.errors.slice(0, 3)) {\n console.log(chalk.gray(` - ${err}`));\n }\n }\n result.warnings.push(...deepResult.errors);\n }\n } catch (error) {\n result.errors.push(`Deep analysis failed: ${error instanceof Error ? error.message : String(error)}`);\n console.log(chalk.red(` ā Deep analysis failed: ${error instanceof Error ? error.message : String(error)}`));\n }\n }\n }\n\n console.log('');\n }\n\n // Update cache\n if (cache) {\n const stats = cache.getStats();\n result.cache = {\n updated: stats.totalEntries,\n hits: stats.hitCount,\n misses: stats.missCount,\n };\n\n await cache.save();\n }\n\n result.duration = Date.now() - startTime;\n result.success = result.errors.length === 0;\n\n // Final summary\n displaySummary(result, dryRun);\n\n } catch (error) {\n console.error(chalk.red('\\nā Cultivation failed:'), error);\n process.exit(1);\n }\n });\n}\n\n/**\n * Display detailed analysis output\n */\nfunction displayDetailedAnalysis(analysis: SeedAnalysis): void {\n if (analysis.frameworks.length > 0) {\n console.log(`\\n ${chalk.gray('Frameworks:')}`);\n for (const fw of analysis.frameworks) {\n console.log(` - ${fw.name} (${fw.ecosystem}) v${fw.version}`);\n }\n }\n\n if (analysis.services.length > 0) {\n console.log(`\\n ${chalk.gray('Services:')}`);\n for (const svc of analysis.services) {\n console.log(` - ${svc.name}: ${svc.type} (${svc.technology})`);\n }\n }\n\n if (analysis.deployments.length > 0) {\n console.log(`\\n ${chalk.gray('Deployments:')}`);\n for (const dep of analysis.deployments) {\n console.log(` - ${dep}`);\n }\n }\n}\n\n/**\n * Display cultivation summary\n */\nfunction displaySummary(result: CultivationResult, dryRun: boolean): void {\n console.log(chalk.bold.blue('š Cultivation Summary\\n'));\n\n if (dryRun) {\n console.log(chalk.yellow('[DRY RUN] No changes were made\\n'));\n }\n\n console.log(' Analysis:');\n console.log(` Files processed: ${result.analysis.filesProcessed}`);\n console.log(` Dependencies: ${result.analysis.dependenciesFound}`);\n console.log(` Services: ${result.analysis.servicesFound}`);\n\n if (result.seed.created > 0 || result.seed.documents.length > 0) {\n console.log('\\n Seed:');\n console.log(` Primitives ${dryRun ? 'would create' : 'created'}: ${dryRun ? result.seed.documents.length : result.seed.created}`);\n }\n\n if (result.cache.updated > 0) {\n console.log('\\n Cache:');\n console.log(` Entries: ${result.cache.updated}`);\n const hitRate = result.cache.hits + result.cache.misses > 0\n ? (result.cache.hits / (result.cache.hits + result.cache.misses) * 100).toFixed(1)\n : 0;\n console.log(` Hit rate: ${hitRate}%`);\n }\n\n console.log(`\\n Duration: ${(result.duration / 1000).toFixed(2)}s`);\n\n if (result.warnings.length > 0) {\n console.log(chalk.yellow(`\\n ā ļø Warnings: ${result.warnings.length}`));\n for (const warning of result.warnings.slice(0, 5)) {\n console.log(chalk.gray(` - ${warning}`));\n }\n }\n\n if (result.errors.length > 0) {\n console.log(chalk.red(`\\n ā Errors: ${result.errors.length}`));\n for (const error of result.errors.slice(0, 5)) {\n console.log(chalk.gray(` - ${error}`));\n }\n }\n\n if (result.success && !dryRun) {\n console.log(chalk.bold.green('\\n⨠Cultivation complete!\\n'));\n } else if (!result.success) {\n console.log(chalk.yellow('\\nā ļø Cultivation completed with errors\\n'));\n } else {\n console.log(chalk.gray('\\nRun without --dry-run to apply changes\\n'));\n }\n}\n\n"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
* Provides comprehensive codebase analysis using:
|
|
5
5
|
* - Claude CLI (`claude -p`) when running outside Claude Code
|
|
6
6
|
* - Direct Anthropic API when ANTHROPIC_API_KEY is available
|
|
7
|
-
* -
|
|
7
|
+
* - Google Gemini API when GOOGLE_AI_API_KEY is available (fallback)
|
|
8
|
+
* - Clear error messaging when no option is available
|
|
8
9
|
*
|
|
9
10
|
* @module cultivation/deep-analyzer
|
|
10
11
|
*/
|
|
@@ -28,6 +29,8 @@ export interface DeepAnalyzerOptions {
|
|
|
28
29
|
agentTimeout?: number;
|
|
29
30
|
/** Force use of API key even if CLI is available */
|
|
30
31
|
forceApiKey?: boolean;
|
|
32
|
+
/** Preferred provider when multiple are available */
|
|
33
|
+
preferredProvider?: 'anthropic' | 'gemini';
|
|
31
34
|
}
|
|
32
35
|
/**
|
|
33
36
|
* Analysis result from an agent
|
|
@@ -55,11 +58,16 @@ export interface DeepAnalysisResult {
|
|
|
55
58
|
results: AgentResult[];
|
|
56
59
|
duration: number;
|
|
57
60
|
errors: string[];
|
|
58
|
-
mode: 'cli' | '
|
|
61
|
+
mode: 'cli' | 'anthropic' | 'gemini' | 'static';
|
|
59
62
|
}
|
|
60
63
|
/**
|
|
61
64
|
* DeepAnalyzer - Deep codebase analysis with multiple execution modes
|
|
62
65
|
*
|
|
66
|
+
* Supports multiple providers:
|
|
67
|
+
* - Claude CLI (uses OAuth session, no API key needed)
|
|
68
|
+
* - Anthropic API (requires ANTHROPIC_API_KEY)
|
|
69
|
+
* - Google Gemini API (requires GOOGLE_AI_API_KEY or GEMINI_API_KEY)
|
|
70
|
+
*
|
|
63
71
|
* @example
|
|
64
72
|
* ```typescript
|
|
65
73
|
* const analyzer = new DeepAnalyzer({
|
|
@@ -80,6 +88,7 @@ export declare class DeepAnalyzer {
|
|
|
80
88
|
private agentMode;
|
|
81
89
|
private agentTimeout;
|
|
82
90
|
private forceApiKey;
|
|
91
|
+
private preferredProvider;
|
|
83
92
|
constructor(options: DeepAnalyzerOptions);
|
|
84
93
|
/**
|
|
85
94
|
* Check if running inside a Claude Code session
|
|
@@ -88,7 +97,15 @@ export declare class DeepAnalyzer {
|
|
|
88
97
|
/**
|
|
89
98
|
* Check if Anthropic API key is available
|
|
90
99
|
*/
|
|
91
|
-
private
|
|
100
|
+
private hasAnthropicApiKey;
|
|
101
|
+
/**
|
|
102
|
+
* Check if Google AI / Gemini API key is available
|
|
103
|
+
*/
|
|
104
|
+
private hasGeminiApiKey;
|
|
105
|
+
/**
|
|
106
|
+
* Get the Gemini API key from available env vars
|
|
107
|
+
*/
|
|
108
|
+
private getGeminiApiKey;
|
|
92
109
|
/**
|
|
93
110
|
* Check if Claude CLI is available
|
|
94
111
|
*/
|
|
@@ -131,7 +148,11 @@ export declare class DeepAnalyzer {
|
|
|
131
148
|
/**
|
|
132
149
|
* Run analysis using Anthropic API directly
|
|
133
150
|
*/
|
|
134
|
-
private
|
|
151
|
+
private runWithAnthropic;
|
|
152
|
+
/**
|
|
153
|
+
* Run analysis using Google Gemini API
|
|
154
|
+
*/
|
|
155
|
+
private runWithGemini;
|
|
135
156
|
/**
|
|
136
157
|
* Extract insights from agent output
|
|
137
158
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deep-analyzer.d.ts","sourceRoot":"","sources":["../../src/cultivation/deep-analyzer.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"deep-analyzer.d.ts","sourceRoot":"","sources":["../../src/cultivation/deep-analyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,6 +12,7 @@ class DeepAnalyzer {
|
|
|
12
12
|
agentMode;
|
|
13
13
|
agentTimeout;
|
|
14
14
|
forceApiKey;
|
|
15
|
+
preferredProvider;
|
|
15
16
|
constructor(options) {
|
|
16
17
|
this.projectRoot = resolve(options.projectRoot);
|
|
17
18
|
this.docsPath = options.docsPath || "docs";
|
|
@@ -21,6 +22,7 @@ class DeepAnalyzer {
|
|
|
21
22
|
this.agentMode = options.agentMode || "adaptive";
|
|
22
23
|
this.agentTimeout = options.agentTimeout || 12e4;
|
|
23
24
|
this.forceApiKey = options.forceApiKey || false;
|
|
25
|
+
this.preferredProvider = options.preferredProvider || "anthropic";
|
|
24
26
|
}
|
|
25
27
|
/**
|
|
26
28
|
* Check if running inside a Claude Code session
|
|
@@ -31,9 +33,21 @@ class DeepAnalyzer {
|
|
|
31
33
|
/**
|
|
32
34
|
* Check if Anthropic API key is available
|
|
33
35
|
*/
|
|
34
|
-
|
|
36
|
+
hasAnthropicApiKey() {
|
|
35
37
|
return !!process.env.ANTHROPIC_API_KEY;
|
|
36
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Check if Google AI / Gemini API key is available
|
|
41
|
+
*/
|
|
42
|
+
hasGeminiApiKey() {
|
|
43
|
+
return !!(process.env.GOOGLE_AI_API_KEY || process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get the Gemini API key from available env vars
|
|
47
|
+
*/
|
|
48
|
+
getGeminiApiKey() {
|
|
49
|
+
return process.env.GOOGLE_AI_API_KEY || process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY;
|
|
50
|
+
}
|
|
37
51
|
/**
|
|
38
52
|
* Check if Claude CLI is available
|
|
39
53
|
*/
|
|
@@ -54,32 +68,51 @@ class DeepAnalyzer {
|
|
|
54
68
|
*/
|
|
55
69
|
detectExecutionMode() {
|
|
56
70
|
const insideClaudeCode = this.isInsideClaudeCode();
|
|
57
|
-
const
|
|
71
|
+
const hasAnthropicKey = this.hasAnthropicApiKey();
|
|
72
|
+
const hasGeminiKey = this.hasGeminiApiKey();
|
|
58
73
|
const cliAvailable = this.isCliAvailable();
|
|
59
74
|
if (this.forceApiKey) {
|
|
60
|
-
if (
|
|
61
|
-
return { mode: "
|
|
75
|
+
if (this.preferredProvider === "gemini" && hasGeminiKey) {
|
|
76
|
+
return { mode: "gemini", reason: "Using Gemini API (forced, preferred)" };
|
|
62
77
|
}
|
|
63
|
-
|
|
78
|
+
if (hasAnthropicKey) {
|
|
79
|
+
return { mode: "anthropic", reason: "Using Anthropic API (forced)" };
|
|
80
|
+
}
|
|
81
|
+
if (hasGeminiKey) {
|
|
82
|
+
return { mode: "gemini", reason: "Using Gemini API (forced, fallback)" };
|
|
83
|
+
}
|
|
84
|
+
return { mode: "unavailable", reason: "No API key found (required when forceApiKey=true). Set ANTHROPIC_API_KEY or GOOGLE_AI_API_KEY." };
|
|
64
85
|
}
|
|
65
86
|
if (insideClaudeCode) {
|
|
66
|
-
if (
|
|
67
|
-
return { mode: "
|
|
87
|
+
if (this.preferredProvider === "gemini" && hasGeminiKey) {
|
|
88
|
+
return { mode: "gemini", reason: "Using Gemini API (inside Claude Code, preferred)" };
|
|
89
|
+
}
|
|
90
|
+
if (hasAnthropicKey) {
|
|
91
|
+
return { mode: "anthropic", reason: "Using Anthropic API (inside Claude Code)" };
|
|
92
|
+
}
|
|
93
|
+
if (hasGeminiKey) {
|
|
94
|
+
return { mode: "gemini", reason: "Using Gemini API (inside Claude Code, fallback)" };
|
|
68
95
|
}
|
|
69
96
|
return {
|
|
70
97
|
mode: "unavailable",
|
|
71
|
-
reason: "Cannot run deep analysis inside Claude Code session without
|
|
98
|
+
reason: "Cannot run deep analysis inside Claude Code session without an API key. Set ANTHROPIC_API_KEY or GOOGLE_AI_API_KEY, or run from a regular terminal."
|
|
72
99
|
};
|
|
73
100
|
}
|
|
74
101
|
if (cliAvailable) {
|
|
75
102
|
return { mode: "cli", reason: "Using Claude CLI" };
|
|
76
103
|
}
|
|
77
|
-
if (
|
|
78
|
-
return { mode: "
|
|
104
|
+
if (this.preferredProvider === "gemini" && hasGeminiKey) {
|
|
105
|
+
return { mode: "gemini", reason: "Using Gemini API (CLI not available, preferred)" };
|
|
106
|
+
}
|
|
107
|
+
if (hasAnthropicKey) {
|
|
108
|
+
return { mode: "anthropic", reason: "Using Anthropic API (CLI not available)" };
|
|
109
|
+
}
|
|
110
|
+
if (hasGeminiKey) {
|
|
111
|
+
return { mode: "gemini", reason: "Using Gemini API (CLI not available)" };
|
|
79
112
|
}
|
|
80
113
|
return {
|
|
81
114
|
mode: "unavailable",
|
|
82
|
-
reason: "
|
|
115
|
+
reason: "No execution method available. Install Claude Code (https://claude.ai/code), or set ANTHROPIC_API_KEY or GOOGLE_AI_API_KEY."
|
|
83
116
|
};
|
|
84
117
|
}
|
|
85
118
|
/**
|
|
@@ -194,11 +227,13 @@ class DeepAnalyzer {
|
|
|
194
227
|
let output;
|
|
195
228
|
if (mode === "cli") {
|
|
196
229
|
output = await this.runWithCli(prompt);
|
|
230
|
+
} else if (mode === "anthropic") {
|
|
231
|
+
output = await this.runWithAnthropic(prompt);
|
|
197
232
|
} else {
|
|
198
|
-
output = await this.
|
|
233
|
+
output = await this.runWithGemini(prompt);
|
|
199
234
|
}
|
|
200
235
|
result.insights = this.extractInsights(output);
|
|
201
|
-
writeFileSync(outputPath, this.formatOutput(agent, output));
|
|
236
|
+
writeFileSync(outputPath, this.formatOutput(agent, output, mode));
|
|
202
237
|
result.documents.push({ path: outputPath, title: agent.name });
|
|
203
238
|
result.success = true;
|
|
204
239
|
if (this.verbose) {
|
|
@@ -299,7 +334,7 @@ Be specific and actionable in your analysis.`;
|
|
|
299
334
|
/**
|
|
300
335
|
* Run analysis using Anthropic API directly
|
|
301
336
|
*/
|
|
302
|
-
async
|
|
337
|
+
async runWithAnthropic(prompt) {
|
|
303
338
|
const apiKey = process.env.ANTHROPIC_API_KEY;
|
|
304
339
|
if (!apiKey) {
|
|
305
340
|
throw new Error("ANTHROPIC_API_KEY not set");
|
|
@@ -324,7 +359,33 @@ Be specific and actionable in your analysis.`;
|
|
|
324
359
|
throw new Error("No text content in API response");
|
|
325
360
|
} catch (error) {
|
|
326
361
|
if (error instanceof Error) {
|
|
327
|
-
throw new Error(`API call failed: ${error.message}`);
|
|
362
|
+
throw new Error(`Anthropic API call failed: ${error.message}`);
|
|
363
|
+
}
|
|
364
|
+
throw error;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Run analysis using Google Gemini API
|
|
369
|
+
*/
|
|
370
|
+
async runWithGemini(prompt) {
|
|
371
|
+
const apiKey = this.getGeminiApiKey();
|
|
372
|
+
if (!apiKey) {
|
|
373
|
+
throw new Error("GOOGLE_AI_API_KEY, GEMINI_API_KEY, or GOOGLE_API_KEY not set");
|
|
374
|
+
}
|
|
375
|
+
try {
|
|
376
|
+
const { GoogleGenerativeAI } = await import("../node_modules/@google/generative-ai/dist/index.js");
|
|
377
|
+
const genAI = new GoogleGenerativeAI(apiKey);
|
|
378
|
+
const model = genAI.getGenerativeModel({ model: "gemini-2.0-flash" });
|
|
379
|
+
const result = await model.generateContent(prompt);
|
|
380
|
+
const response = result.response;
|
|
381
|
+
const text = response.text();
|
|
382
|
+
if (!text) {
|
|
383
|
+
throw new Error("No text content in Gemini response");
|
|
384
|
+
}
|
|
385
|
+
return text;
|
|
386
|
+
} catch (error) {
|
|
387
|
+
if (error instanceof Error) {
|
|
388
|
+
throw new Error(`Gemini API call failed: ${error.message}`);
|
|
328
389
|
}
|
|
329
390
|
throw error;
|
|
330
391
|
}
|
|
@@ -352,19 +413,20 @@ Be specific and actionable in your analysis.`;
|
|
|
352
413
|
/**
|
|
353
414
|
* Format output for documentation
|
|
354
415
|
*/
|
|
355
|
-
formatOutput(agent, output) {
|
|
416
|
+
formatOutput(agent, output, mode) {
|
|
356
417
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
357
418
|
return `---
|
|
358
419
|
title: "${agent.name} Analysis"
|
|
359
420
|
type: analysis
|
|
360
421
|
generator: deep-analyzer
|
|
361
422
|
agent: ${agent.type}
|
|
423
|
+
provider: ${mode}
|
|
362
424
|
created: ${timestamp}
|
|
363
425
|
---
|
|
364
426
|
|
|
365
427
|
# ${agent.name} Analysis
|
|
366
428
|
|
|
367
|
-
> Generated by DeepAnalyzer
|
|
429
|
+
> Generated by DeepAnalyzer using ${mode === "cli" ? "Claude CLI" : mode === "anthropic" ? "Anthropic API" : "Gemini API"}
|
|
368
430
|
|
|
369
431
|
## Overview
|
|
370
432
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deep-analyzer.js","sources":["../../src/cultivation/deep-analyzer.ts"],"sourcesContent":["/**\n * DeepAnalyzer - Deep Codebase Analysis\n *\n * Provides comprehensive codebase analysis using:\n * - Claude CLI (`claude -p`) when running outside Claude Code\n * - Direct Anthropic API when ANTHROPIC_API_KEY is available\n * - Clear error messaging when neither option is available\n *\n * @module cultivation/deep-analyzer\n */\n\nimport { execFileSync, execSync } from 'child_process';\nimport { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync } from 'fs';\nimport { join, resolve, relative } from 'path';\nimport { createLogger } from '../utils/index.js';\n\nconst logger = createLogger('deep-analyzer');\n\n/**\n * Valid agent types for analysis\n */\nconst VALID_AGENT_TYPES = new Set([\n 'researcher',\n 'architect',\n 'analyst',\n 'coder',\n 'tester',\n 'reviewer',\n 'documenter',\n]);\n\n/**\n * Deep analyzer options\n */\nexport interface DeepAnalyzerOptions {\n /** Project root directory */\n projectRoot: string;\n /** Documentation path (relative to project root) */\n docsPath?: string;\n /** Output directory for analysis results */\n outputDir?: string;\n /** Enable verbose logging */\n verbose?: boolean;\n /** Maximum agents to spawn */\n maxAgents?: number;\n /** Agent execution mode */\n agentMode?: 'sequential' | 'parallel' | 'adaptive';\n /** Timeout for each agent (ms) */\n agentTimeout?: number;\n /** Force use of API key even if CLI is available */\n forceApiKey?: boolean;\n}\n\n/**\n * Analysis result from an agent\n */\nexport interface AgentResult {\n name: string;\n type: string;\n success: boolean;\n insights: string[];\n documents: Array<{ path: string; title: string }>;\n duration: number;\n error?: string;\n}\n\n/**\n * Deep analysis result\n */\nexport interface DeepAnalysisResult {\n success: boolean;\n agentsSpawned: number;\n insightsCount: number;\n documentsCreated: number;\n results: AgentResult[];\n duration: number;\n errors: string[];\n mode: 'cli' | 'api' | 'static';\n}\n\n/**\n * Agent configuration\n */\ninterface AgentConfig {\n name: string;\n type: 'researcher' | 'analyst' | 'coder' | 'tester' | 'reviewer';\n task: string;\n outputFile: string;\n}\n\n/**\n * Execution mode detection result\n */\ninterface ExecutionMode {\n mode: 'cli' | 'api' | 'unavailable';\n reason: string;\n}\n\n/**\n * DeepAnalyzer - Deep codebase analysis with multiple execution modes\n *\n * @example\n * ```typescript\n * const analyzer = new DeepAnalyzer({\n * projectRoot: '/my/project',\n * docsPath: 'docs',\n * });\n *\n * const result = await analyzer.analyze();\n * console.log(`Generated ${result.insightsCount} insights`);\n * ```\n */\nexport class DeepAnalyzer {\n private projectRoot: string;\n private docsPath: string;\n private outputDir: string;\n private verbose: boolean;\n private maxAgents: number;\n private agentMode: 'sequential' | 'parallel' | 'adaptive';\n private agentTimeout: number;\n private forceApiKey: boolean;\n\n constructor(options: DeepAnalyzerOptions) {\n this.projectRoot = resolve(options.projectRoot);\n this.docsPath = options.docsPath || 'docs';\n this.outputDir = options.outputDir || join(this.projectRoot, this.docsPath, 'analysis');\n this.verbose = options.verbose || false;\n this.maxAgents = options.maxAgents || 5;\n this.agentMode = options.agentMode || 'adaptive';\n // Default timeout of 2 minutes (120 seconds)\n this.agentTimeout = options.agentTimeout || 120000;\n this.forceApiKey = options.forceApiKey || false;\n }\n\n /**\n * Check if running inside a Claude Code session\n */\n private isInsideClaudeCode(): boolean {\n return process.env.CLAUDECODE === '1' || process.env.CLAUDE_CODE === '1';\n }\n\n /**\n * Check if Anthropic API key is available\n */\n private hasApiKey(): boolean {\n return !!process.env.ANTHROPIC_API_KEY;\n }\n\n /**\n * Check if Claude CLI is available\n */\n private isCliAvailable(): boolean {\n try {\n execFileSync('claude', ['--version'], {\n stdio: 'pipe',\n timeout: 5000,\n windowsHide: true,\n });\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Determine the best execution mode\n */\n private detectExecutionMode(): ExecutionMode {\n const insideClaudeCode = this.isInsideClaudeCode();\n const hasApiKey = this.hasApiKey();\n const cliAvailable = this.isCliAvailable();\n\n // If forced to use API key\n if (this.forceApiKey) {\n if (hasApiKey) {\n return { mode: 'api', reason: 'Using API key (forced)' };\n }\n return { mode: 'unavailable', reason: 'ANTHROPIC_API_KEY not set (required when forceApiKey=true)' };\n }\n\n // Inside Claude Code session - CLI doesn't work due to resource contention\n if (insideClaudeCode) {\n if (hasApiKey) {\n return { mode: 'api', reason: 'Using API key (inside Claude Code session)' };\n }\n return {\n mode: 'unavailable',\n reason: 'Cannot run deep analysis inside Claude Code session without ANTHROPIC_API_KEY. ' +\n 'Either set ANTHROPIC_API_KEY environment variable, or run this command from a regular terminal.',\n };\n }\n\n // Outside Claude Code - prefer CLI for OAuth session support\n if (cliAvailable) {\n return { mode: 'cli', reason: 'Using Claude CLI' };\n }\n\n // CLI not available, try API key\n if (hasApiKey) {\n return { mode: 'api', reason: 'Using API key (CLI not available)' };\n }\n\n return {\n mode: 'unavailable',\n reason: 'Claude CLI not found. Install Claude Code (https://claude.ai/code) or set ANTHROPIC_API_KEY.',\n };\n }\n\n /**\n * Check if analysis is available\n */\n async isAvailable(): Promise<boolean> {\n const mode = this.detectExecutionMode();\n return mode.mode !== 'unavailable';\n }\n\n /**\n * Get availability status with reason\n */\n async getAvailabilityStatus(): Promise<{ available: boolean; reason: string }> {\n const mode = this.detectExecutionMode();\n return {\n available: mode.mode !== 'unavailable',\n reason: mode.reason,\n };\n }\n\n /**\n * Run deep analysis\n */\n async analyze(): Promise<DeepAnalysisResult> {\n const startTime = Date.now();\n const executionMode = this.detectExecutionMode();\n\n const result: DeepAnalysisResult = {\n success: false,\n agentsSpawned: 0,\n insightsCount: 0,\n documentsCreated: 0,\n results: [],\n duration: 0,\n errors: [],\n mode: executionMode.mode === 'unavailable' ? 'static' : executionMode.mode,\n };\n\n // Check availability\n if (executionMode.mode === 'unavailable') {\n result.errors.push(executionMode.reason);\n result.duration = Date.now() - startTime;\n logger.error('Deep analysis unavailable', new Error(executionMode.reason));\n return result;\n }\n\n logger.info(`Starting deep analysis`, { mode: executionMode.mode, reason: executionMode.reason });\n\n // Ensure output directory exists\n if (!existsSync(this.outputDir)) {\n mkdirSync(this.outputDir, { recursive: true });\n }\n\n // Define agents\n const agents: AgentConfig[] = [\n {\n name: 'Pattern Researcher',\n type: 'researcher',\n task: 'Analyze codebase architecture, patterns, and design decisions',\n outputFile: 'architecture-patterns.md',\n },\n {\n name: 'Code Analyst',\n type: 'analyst',\n task: 'Identify code quality issues, complexity hotspots, and improvement opportunities',\n outputFile: 'code-analysis.md',\n },\n {\n name: 'Implementation Reviewer',\n type: 'coder',\n task: 'Review implementation patterns, naming conventions, and code style',\n outputFile: 'implementation-review.md',\n },\n {\n name: 'Test Analyzer',\n type: 'tester',\n task: 'Analyze test coverage, testing patterns, and testing gaps',\n outputFile: 'testing-analysis.md',\n },\n ];\n\n logger.info('Executing analysis agents', { agents: agents.length, mode: 'sequential' });\n\n // Execute agents sequentially\n for (const agent of agents) {\n const agentResult = await this.executeAgent(agent, executionMode.mode as 'cli' | 'api');\n result.results.push(agentResult);\n }\n\n // Calculate totals\n result.agentsSpawned = result.results.length;\n result.insightsCount = result.results.reduce((sum, r) => sum + r.insights.length, 0);\n result.documentsCreated = result.results.reduce((sum, r) => sum + r.documents.length, 0);\n result.success = result.results.some(r => r.success); // Success if at least one agent succeeded\n result.duration = Date.now() - startTime;\n\n // Collect errors\n for (const agentResult of result.results) {\n if (agentResult.error) {\n result.errors.push(`${agentResult.name}: ${agentResult.error}`);\n }\n }\n\n logger.info('Deep analysis complete', {\n success: result.success,\n insights: result.insightsCount,\n documents: result.documentsCreated,\n duration: result.duration,\n });\n\n return result;\n }\n\n /**\n * Execute a single agent\n */\n private async executeAgent(agent: AgentConfig, mode: 'cli' | 'api'): Promise<AgentResult> {\n const startTime = Date.now();\n const outputPath = join(this.outputDir, agent.outputFile);\n\n const result: AgentResult = {\n name: agent.name,\n type: agent.type,\n success: false,\n insights: [],\n documents: [],\n duration: 0,\n };\n\n try {\n logger.info(`Executing agent: ${agent.name}`, { type: agent.type, mode });\n\n const prompt = this.buildPrompt(agent);\n let output: string;\n\n if (mode === 'cli') {\n output = await this.runWithCli(prompt);\n } else {\n output = await this.runWithApi(prompt);\n }\n\n // Parse output for insights\n result.insights = this.extractInsights(output);\n\n // Write output to file\n writeFileSync(outputPath, this.formatOutput(agent, output));\n result.documents.push({ path: outputPath, title: agent.name });\n\n result.success = true;\n\n if (this.verbose) {\n logger.debug(`Agent completed: ${agent.name}`, { insights: result.insights.length });\n }\n } catch (error) {\n result.error = error instanceof Error ? error.message : String(error);\n logger.error(`Agent failed: ${agent.name}`, error instanceof Error ? error : new Error(String(error)));\n }\n\n result.duration = Date.now() - startTime;\n return result;\n }\n\n /**\n * Build context-aware prompt for analysis\n */\n private buildPrompt(agent: AgentConfig): string {\n // Gather project context\n const context = this.gatherProjectContext();\n\n return `You are analyzing a codebase. Here is the project context:\n\n${context}\n\nTask: ${agent.task}\n\nProvide your findings in markdown format with:\n1. Key observations (prefix with \"Observation:\")\n2. Specific recommendations (prefix with \"Recommendation:\")\n3. Any potential issues found (prefix with \"Finding:\")\n\nBe specific and actionable in your analysis.`;\n }\n\n /**\n * Gather project context for analysis\n */\n private gatherProjectContext(): string {\n const lines: string[] = [];\n\n // Check for package.json\n const packageJsonPath = join(this.projectRoot, 'package.json');\n if (existsSync(packageJsonPath)) {\n try {\n const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n lines.push(`Project: ${pkg.name || 'Unknown'} v${pkg.version || '0.0.0'}`);\n lines.push(`Description: ${pkg.description || 'No description'}`);\n\n if (pkg.dependencies) {\n const deps = Object.keys(pkg.dependencies).slice(0, 10);\n lines.push(`Key dependencies: ${deps.join(', ')}`);\n }\n } catch {\n // Ignore parse errors\n }\n }\n\n // List top-level directories\n try {\n const entries = readdirSync(this.projectRoot, { withFileTypes: true });\n const dirs = entries\n .filter(e => e.isDirectory() && !e.name.startsWith('.') && e.name !== 'node_modules')\n .map(e => e.name)\n .slice(0, 10);\n\n if (dirs.length > 0) {\n lines.push(`Project structure: ${dirs.join(', ')}`);\n }\n } catch {\n // Ignore errors\n }\n\n // Check for common config files\n const configFiles = [\n 'tsconfig.json',\n 'vite.config.ts',\n 'vitest.config.ts',\n '.eslintrc.js',\n 'Dockerfile',\n ];\n\n const foundConfigs = configFiles.filter(f => existsSync(join(this.projectRoot, f)));\n if (foundConfigs.length > 0) {\n lines.push(`Config files: ${foundConfigs.join(', ')}`);\n }\n\n return lines.join('\\n');\n }\n\n /**\n * Run analysis using Claude CLI\n */\n private async runWithCli(prompt: string): Promise<string> {\n // Sanitize prompt - escape double quotes and remove dangerous chars\n const sanitizedPrompt = prompt\n .replace(/\"/g, '\\\\\"')\n .replace(/[`$]/g, '');\n\n try {\n const result = execSync(`claude -p \"${sanitizedPrompt}\"`, {\n cwd: this.projectRoot,\n encoding: 'utf8',\n timeout: this.agentTimeout,\n maxBuffer: 10 * 1024 * 1024, // 10MB buffer\n });\n return result;\n } catch (error) {\n if (error instanceof Error) {\n const execError = error as { stderr?: string; stdout?: string; killed?: boolean };\n if (execError.killed) {\n // Timeout - return partial output if available\n if (execError.stdout && execError.stdout.length > 100) {\n return execError.stdout;\n }\n throw new Error(`Claude CLI timed out after ${this.agentTimeout / 1000}s`);\n }\n throw new Error(execError.stderr || error.message);\n }\n throw error;\n }\n }\n\n /**\n * Run analysis using Anthropic API directly\n */\n private async runWithApi(prompt: string): Promise<string> {\n const apiKey = process.env.ANTHROPIC_API_KEY;\n if (!apiKey) {\n throw new Error('ANTHROPIC_API_KEY not set');\n }\n\n try {\n // Dynamic import to avoid bundling issues\n const { default: Anthropic } = await import('@anthropic-ai/sdk');\n\n const client = new Anthropic({ apiKey });\n\n const response = await client.messages.create({\n model: 'claude-sonnet-4-20250514',\n max_tokens: 4096,\n messages: [\n {\n role: 'user',\n content: prompt,\n },\n ],\n });\n\n // Extract text from response\n const textBlock = response.content.find(block => block.type === 'text');\n if (textBlock && textBlock.type === 'text') {\n return textBlock.text;\n }\n\n throw new Error('No text content in API response');\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`API call failed: ${error.message}`);\n }\n throw error;\n }\n }\n\n /**\n * Extract insights from agent output\n */\n private extractInsights(output: string): string[] {\n const insights: string[] = [];\n\n // Look for patterns like \"- Insight:\", \"Observation:\", \"Finding:\", \"Recommendation:\"\n const patterns = [\n /[-*]?\\s*(?:insight|finding|observation|recommendation):\\s*(.+)/gi,\n /##\\s*(?:insight|finding|observation|recommendation):\\s*(.+)/gi,\n /(?:key\\s+)?(?:insight|finding|observation|recommendation):\\s*(.+)/gi,\n ];\n\n for (const pattern of patterns) {\n const matches = output.matchAll(pattern);\n for (const match of matches) {\n if (match[1]) {\n insights.push(match[1].trim());\n }\n }\n }\n\n // Deduplicate\n return [...new Set(insights)];\n }\n\n /**\n * Format output for documentation\n */\n private formatOutput(agent: AgentConfig, output: string): string {\n const timestamp = new Date().toISOString();\n\n return `---\ntitle: \"${agent.name} Analysis\"\ntype: analysis\ngenerator: deep-analyzer\nagent: ${agent.type}\ncreated: ${timestamp}\n---\n\n# ${agent.name} Analysis\n\n> Generated by DeepAnalyzer\n\n## Overview\n\n${agent.task}\n\n## Analysis\n\n${output}\n\n---\n\n*Generated on ${new Date().toLocaleString()}*\n`;\n }\n}\n\n/**\n * Create a deep analyzer instance\n */\nexport function createDeepAnalyzer(options: DeepAnalyzerOptions): DeepAnalyzer {\n return new DeepAnalyzer(options);\n}\n\n/**\n * Run deep analysis on a project\n */\nexport async function analyzeDeep(\n projectRoot: string,\n docsPath?: string\n): Promise<DeepAnalysisResult> {\n const analyzer = new DeepAnalyzer({ projectRoot, docsPath });\n return analyzer.analyze();\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"deep-analyzer.js","sources":["../../src/cultivation/deep-analyzer.ts"],"sourcesContent":["/**\n * DeepAnalyzer - Deep Codebase Analysis\n *\n * Provides comprehensive codebase analysis using:\n * - Claude CLI (`claude -p`) when running outside Claude Code\n * - Direct Anthropic API when ANTHROPIC_API_KEY is available\n * - Google Gemini API when GOOGLE_AI_API_KEY is available (fallback)\n * - Clear error messaging when no option is available\n *\n * @module cultivation/deep-analyzer\n */\n\nimport { execFileSync, execSync } from 'child_process';\nimport { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync } from 'fs';\nimport { join, resolve, relative } from 'path';\nimport { createLogger } from '../utils/index.js';\n\nconst logger = createLogger('deep-analyzer');\n\n/**\n * Valid agent types for analysis\n */\nconst VALID_AGENT_TYPES = new Set([\n 'researcher',\n 'architect',\n 'analyst',\n 'coder',\n 'tester',\n 'reviewer',\n 'documenter',\n]);\n\n/**\n * Deep analyzer options\n */\nexport interface DeepAnalyzerOptions {\n /** Project root directory */\n projectRoot: string;\n /** Documentation path (relative to project root) */\n docsPath?: string;\n /** Output directory for analysis results */\n outputDir?: string;\n /** Enable verbose logging */\n verbose?: boolean;\n /** Maximum agents to spawn */\n maxAgents?: number;\n /** Agent execution mode */\n agentMode?: 'sequential' | 'parallel' | 'adaptive';\n /** Timeout for each agent (ms) */\n agentTimeout?: number;\n /** Force use of API key even if CLI is available */\n forceApiKey?: boolean;\n /** Preferred provider when multiple are available */\n preferredProvider?: 'anthropic' | 'gemini';\n}\n\n/**\n * Analysis result from an agent\n */\nexport interface AgentResult {\n name: string;\n type: string;\n success: boolean;\n insights: string[];\n documents: Array<{ path: string; title: string }>;\n duration: number;\n error?: string;\n}\n\n/**\n * Deep analysis result\n */\nexport interface DeepAnalysisResult {\n success: boolean;\n agentsSpawned: number;\n insightsCount: number;\n documentsCreated: number;\n results: AgentResult[];\n duration: number;\n errors: string[];\n mode: 'cli' | 'anthropic' | 'gemini' | 'static';\n}\n\n/**\n * Agent configuration\n */\ninterface AgentConfig {\n name: string;\n type: 'researcher' | 'analyst' | 'coder' | 'tester' | 'reviewer';\n task: string;\n outputFile: string;\n}\n\n/**\n * Execution mode detection result\n */\ninterface ExecutionMode {\n mode: 'cli' | 'anthropic' | 'gemini' | 'unavailable';\n reason: string;\n}\n\n/**\n * DeepAnalyzer - Deep codebase analysis with multiple execution modes\n *\n * Supports multiple providers:\n * - Claude CLI (uses OAuth session, no API key needed)\n * - Anthropic API (requires ANTHROPIC_API_KEY)\n * - Google Gemini API (requires GOOGLE_AI_API_KEY or GEMINI_API_KEY)\n *\n * @example\n * ```typescript\n * const analyzer = new DeepAnalyzer({\n * projectRoot: '/my/project',\n * docsPath: 'docs',\n * });\n *\n * const result = await analyzer.analyze();\n * console.log(`Generated ${result.insightsCount} insights`);\n * ```\n */\nexport class DeepAnalyzer {\n private projectRoot: string;\n private docsPath: string;\n private outputDir: string;\n private verbose: boolean;\n private maxAgents: number;\n private agentMode: 'sequential' | 'parallel' | 'adaptive';\n private agentTimeout: number;\n private forceApiKey: boolean;\n private preferredProvider: 'anthropic' | 'gemini';\n\n constructor(options: DeepAnalyzerOptions) {\n this.projectRoot = resolve(options.projectRoot);\n this.docsPath = options.docsPath || 'docs';\n this.outputDir = options.outputDir || join(this.projectRoot, this.docsPath, 'analysis');\n this.verbose = options.verbose || false;\n this.maxAgents = options.maxAgents || 5;\n this.agentMode = options.agentMode || 'adaptive';\n // Default timeout of 2 minutes (120 seconds)\n this.agentTimeout = options.agentTimeout || 120000;\n this.forceApiKey = options.forceApiKey || false;\n this.preferredProvider = options.preferredProvider || 'anthropic';\n }\n\n /**\n * Check if running inside a Claude Code session\n */\n private isInsideClaudeCode(): boolean {\n return process.env.CLAUDECODE === '1' || process.env.CLAUDE_CODE === '1';\n }\n\n /**\n * Check if Anthropic API key is available\n */\n private hasAnthropicApiKey(): boolean {\n return !!process.env.ANTHROPIC_API_KEY;\n }\n\n /**\n * Check if Google AI / Gemini API key is available\n */\n private hasGeminiApiKey(): boolean {\n return !!(process.env.GOOGLE_AI_API_KEY || process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY);\n }\n\n /**\n * Get the Gemini API key from available env vars\n */\n private getGeminiApiKey(): string | undefined {\n return process.env.GOOGLE_AI_API_KEY || process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY;\n }\n\n /**\n * Check if Claude CLI is available\n */\n private isCliAvailable(): boolean {\n try {\n execFileSync('claude', ['--version'], {\n stdio: 'pipe',\n timeout: 5000,\n windowsHide: true,\n });\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Determine the best execution mode\n */\n private detectExecutionMode(): ExecutionMode {\n const insideClaudeCode = this.isInsideClaudeCode();\n const hasAnthropicKey = this.hasAnthropicApiKey();\n const hasGeminiKey = this.hasGeminiApiKey();\n const cliAvailable = this.isCliAvailable();\n\n // If forced to use API key\n if (this.forceApiKey) {\n // Check preferred provider first\n if (this.preferredProvider === 'gemini' && hasGeminiKey) {\n return { mode: 'gemini', reason: 'Using Gemini API (forced, preferred)' };\n }\n if (hasAnthropicKey) {\n return { mode: 'anthropic', reason: 'Using Anthropic API (forced)' };\n }\n if (hasGeminiKey) {\n return { mode: 'gemini', reason: 'Using Gemini API (forced, fallback)' };\n }\n return { mode: 'unavailable', reason: 'No API key found (required when forceApiKey=true). Set ANTHROPIC_API_KEY or GOOGLE_AI_API_KEY.' };\n }\n\n // Inside Claude Code session - CLI doesn't work due to resource contention\n if (insideClaudeCode) {\n // Check preferred provider first\n if (this.preferredProvider === 'gemini' && hasGeminiKey) {\n return { mode: 'gemini', reason: 'Using Gemini API (inside Claude Code, preferred)' };\n }\n if (hasAnthropicKey) {\n return { mode: 'anthropic', reason: 'Using Anthropic API (inside Claude Code)' };\n }\n if (hasGeminiKey) {\n return { mode: 'gemini', reason: 'Using Gemini API (inside Claude Code, fallback)' };\n }\n return {\n mode: 'unavailable',\n reason: 'Cannot run deep analysis inside Claude Code session without an API key. ' +\n 'Set ANTHROPIC_API_KEY or GOOGLE_AI_API_KEY, or run from a regular terminal.',\n };\n }\n\n // Outside Claude Code - prefer CLI for OAuth session support\n if (cliAvailable) {\n return { mode: 'cli', reason: 'Using Claude CLI' };\n }\n\n // CLI not available, try API keys\n if (this.preferredProvider === 'gemini' && hasGeminiKey) {\n return { mode: 'gemini', reason: 'Using Gemini API (CLI not available, preferred)' };\n }\n if (hasAnthropicKey) {\n return { mode: 'anthropic', reason: 'Using Anthropic API (CLI not available)' };\n }\n if (hasGeminiKey) {\n return { mode: 'gemini', reason: 'Using Gemini API (CLI not available)' };\n }\n\n return {\n mode: 'unavailable',\n reason: 'No execution method available. Install Claude Code (https://claude.ai/code), ' +\n 'or set ANTHROPIC_API_KEY or GOOGLE_AI_API_KEY.',\n };\n }\n\n /**\n * Check if analysis is available\n */\n async isAvailable(): Promise<boolean> {\n const mode = this.detectExecutionMode();\n return mode.mode !== 'unavailable';\n }\n\n /**\n * Get availability status with reason\n */\n async getAvailabilityStatus(): Promise<{ available: boolean; reason: string }> {\n const mode = this.detectExecutionMode();\n return {\n available: mode.mode !== 'unavailable',\n reason: mode.reason,\n };\n }\n\n /**\n * Run deep analysis\n */\n async analyze(): Promise<DeepAnalysisResult> {\n const startTime = Date.now();\n const executionMode = this.detectExecutionMode();\n\n const result: DeepAnalysisResult = {\n success: false,\n agentsSpawned: 0,\n insightsCount: 0,\n documentsCreated: 0,\n results: [],\n duration: 0,\n errors: [],\n mode: executionMode.mode === 'unavailable' ? 'static' : executionMode.mode,\n };\n\n // Check availability\n if (executionMode.mode === 'unavailable') {\n result.errors.push(executionMode.reason);\n result.duration = Date.now() - startTime;\n logger.error('Deep analysis unavailable', new Error(executionMode.reason));\n return result;\n }\n\n logger.info(`Starting deep analysis`, { mode: executionMode.mode, reason: executionMode.reason });\n\n // Ensure output directory exists\n if (!existsSync(this.outputDir)) {\n mkdirSync(this.outputDir, { recursive: true });\n }\n\n // Define agents\n const agents: AgentConfig[] = [\n {\n name: 'Pattern Researcher',\n type: 'researcher',\n task: 'Analyze codebase architecture, patterns, and design decisions',\n outputFile: 'architecture-patterns.md',\n },\n {\n name: 'Code Analyst',\n type: 'analyst',\n task: 'Identify code quality issues, complexity hotspots, and improvement opportunities',\n outputFile: 'code-analysis.md',\n },\n {\n name: 'Implementation Reviewer',\n type: 'coder',\n task: 'Review implementation patterns, naming conventions, and code style',\n outputFile: 'implementation-review.md',\n },\n {\n name: 'Test Analyzer',\n type: 'tester',\n task: 'Analyze test coverage, testing patterns, and testing gaps',\n outputFile: 'testing-analysis.md',\n },\n ];\n\n logger.info('Executing analysis agents', { agents: agents.length, mode: 'sequential' });\n\n // Execute agents sequentially\n for (const agent of agents) {\n const agentResult = await this.executeAgent(agent, executionMode.mode as 'cli' | 'anthropic' | 'gemini');\n result.results.push(agentResult);\n }\n\n // Calculate totals\n result.agentsSpawned = result.results.length;\n result.insightsCount = result.results.reduce((sum, r) => sum + r.insights.length, 0);\n result.documentsCreated = result.results.reduce((sum, r) => sum + r.documents.length, 0);\n result.success = result.results.some(r => r.success); // Success if at least one agent succeeded\n result.duration = Date.now() - startTime;\n\n // Collect errors\n for (const agentResult of result.results) {\n if (agentResult.error) {\n result.errors.push(`${agentResult.name}: ${agentResult.error}`);\n }\n }\n\n logger.info('Deep analysis complete', {\n success: result.success,\n insights: result.insightsCount,\n documents: result.documentsCreated,\n duration: result.duration,\n });\n\n return result;\n }\n\n /**\n * Execute a single agent\n */\n private async executeAgent(agent: AgentConfig, mode: 'cli' | 'anthropic' | 'gemini'): Promise<AgentResult> {\n const startTime = Date.now();\n const outputPath = join(this.outputDir, agent.outputFile);\n\n const result: AgentResult = {\n name: agent.name,\n type: agent.type,\n success: false,\n insights: [],\n documents: [],\n duration: 0,\n };\n\n try {\n logger.info(`Executing agent: ${agent.name}`, { type: agent.type, mode });\n\n const prompt = this.buildPrompt(agent);\n let output: string;\n\n if (mode === 'cli') {\n output = await this.runWithCli(prompt);\n } else if (mode === 'anthropic') {\n output = await this.runWithAnthropic(prompt);\n } else {\n output = await this.runWithGemini(prompt);\n }\n\n // Parse output for insights\n result.insights = this.extractInsights(output);\n\n // Write output to file\n writeFileSync(outputPath, this.formatOutput(agent, output, mode));\n result.documents.push({ path: outputPath, title: agent.name });\n\n result.success = true;\n\n if (this.verbose) {\n logger.debug(`Agent completed: ${agent.name}`, { insights: result.insights.length });\n }\n } catch (error) {\n result.error = error instanceof Error ? error.message : String(error);\n logger.error(`Agent failed: ${agent.name}`, error instanceof Error ? error : new Error(String(error)));\n }\n\n result.duration = Date.now() - startTime;\n return result;\n }\n\n /**\n * Build context-aware prompt for analysis\n */\n private buildPrompt(agent: AgentConfig): string {\n // Gather project context\n const context = this.gatherProjectContext();\n\n return `You are analyzing a codebase. Here is the project context:\n\n${context}\n\nTask: ${agent.task}\n\nProvide your findings in markdown format with:\n1. Key observations (prefix with \"Observation:\")\n2. Specific recommendations (prefix with \"Recommendation:\")\n3. Any potential issues found (prefix with \"Finding:\")\n\nBe specific and actionable in your analysis.`;\n }\n\n /**\n * Gather project context for analysis\n */\n private gatherProjectContext(): string {\n const lines: string[] = [];\n\n // Check for package.json\n const packageJsonPath = join(this.projectRoot, 'package.json');\n if (existsSync(packageJsonPath)) {\n try {\n const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n lines.push(`Project: ${pkg.name || 'Unknown'} v${pkg.version || '0.0.0'}`);\n lines.push(`Description: ${pkg.description || 'No description'}`);\n\n if (pkg.dependencies) {\n const deps = Object.keys(pkg.dependencies).slice(0, 10);\n lines.push(`Key dependencies: ${deps.join(', ')}`);\n }\n } catch {\n // Ignore parse errors\n }\n }\n\n // List top-level directories\n try {\n const entries = readdirSync(this.projectRoot, { withFileTypes: true });\n const dirs = entries\n .filter(e => e.isDirectory() && !e.name.startsWith('.') && e.name !== 'node_modules')\n .map(e => e.name)\n .slice(0, 10);\n\n if (dirs.length > 0) {\n lines.push(`Project structure: ${dirs.join(', ')}`);\n }\n } catch {\n // Ignore errors\n }\n\n // Check for common config files\n const configFiles = [\n 'tsconfig.json',\n 'vite.config.ts',\n 'vitest.config.ts',\n '.eslintrc.js',\n 'Dockerfile',\n ];\n\n const foundConfigs = configFiles.filter(f => existsSync(join(this.projectRoot, f)));\n if (foundConfigs.length > 0) {\n lines.push(`Config files: ${foundConfigs.join(', ')}`);\n }\n\n return lines.join('\\n');\n }\n\n /**\n * Run analysis using Claude CLI\n */\n private async runWithCli(prompt: string): Promise<string> {\n // Sanitize prompt - escape double quotes and remove dangerous chars\n const sanitizedPrompt = prompt\n .replace(/\"/g, '\\\\\"')\n .replace(/[`$]/g, '');\n\n try {\n const result = execSync(`claude -p \"${sanitizedPrompt}\"`, {\n cwd: this.projectRoot,\n encoding: 'utf8',\n timeout: this.agentTimeout,\n maxBuffer: 10 * 1024 * 1024, // 10MB buffer\n });\n return result;\n } catch (error) {\n if (error instanceof Error) {\n const execError = error as { stderr?: string; stdout?: string; killed?: boolean };\n if (execError.killed) {\n // Timeout - return partial output if available\n if (execError.stdout && execError.stdout.length > 100) {\n return execError.stdout;\n }\n throw new Error(`Claude CLI timed out after ${this.agentTimeout / 1000}s`);\n }\n throw new Error(execError.stderr || error.message);\n }\n throw error;\n }\n }\n\n /**\n * Run analysis using Anthropic API directly\n */\n private async runWithAnthropic(prompt: string): Promise<string> {\n const apiKey = process.env.ANTHROPIC_API_KEY;\n if (!apiKey) {\n throw new Error('ANTHROPIC_API_KEY not set');\n }\n\n try {\n // Dynamic import to avoid bundling issues\n const { default: Anthropic } = await import('@anthropic-ai/sdk');\n\n const client = new Anthropic({ apiKey });\n\n const response = await client.messages.create({\n model: 'claude-sonnet-4-20250514',\n max_tokens: 4096,\n messages: [\n {\n role: 'user',\n content: prompt,\n },\n ],\n });\n\n // Extract text from response\n const textBlock = response.content.find(block => block.type === 'text');\n if (textBlock && textBlock.type === 'text') {\n return textBlock.text;\n }\n\n throw new Error('No text content in API response');\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Anthropic API call failed: ${error.message}`);\n }\n throw error;\n }\n }\n\n /**\n * Run analysis using Google Gemini API\n */\n private async runWithGemini(prompt: string): Promise<string> {\n const apiKey = this.getGeminiApiKey();\n if (!apiKey) {\n throw new Error('GOOGLE_AI_API_KEY, GEMINI_API_KEY, or GOOGLE_API_KEY not set');\n }\n\n try {\n // Dynamic import to avoid bundling issues\n const { GoogleGenerativeAI } = await import('@google/generative-ai');\n\n const genAI = new GoogleGenerativeAI(apiKey);\n const model = genAI.getGenerativeModel({ model: 'gemini-2.0-flash' });\n\n const result = await model.generateContent(prompt);\n const response = result.response;\n const text = response.text();\n\n if (!text) {\n throw new Error('No text content in Gemini response');\n }\n\n return text;\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Gemini API call failed: ${error.message}`);\n }\n throw error;\n }\n }\n\n /**\n * Extract insights from agent output\n */\n private extractInsights(output: string): string[] {\n const insights: string[] = [];\n\n // Look for patterns like \"- Insight:\", \"Observation:\", \"Finding:\", \"Recommendation:\"\n const patterns = [\n /[-*]?\\s*(?:insight|finding|observation|recommendation):\\s*(.+)/gi,\n /##\\s*(?:insight|finding|observation|recommendation):\\s*(.+)/gi,\n /(?:key\\s+)?(?:insight|finding|observation|recommendation):\\s*(.+)/gi,\n ];\n\n for (const pattern of patterns) {\n const matches = output.matchAll(pattern);\n for (const match of matches) {\n if (match[1]) {\n insights.push(match[1].trim());\n }\n }\n }\n\n // Deduplicate\n return [...new Set(insights)];\n }\n\n /**\n * Format output for documentation\n */\n private formatOutput(agent: AgentConfig, output: string, mode: string): string {\n const timestamp = new Date().toISOString();\n\n return `---\ntitle: \"${agent.name} Analysis\"\ntype: analysis\ngenerator: deep-analyzer\nagent: ${agent.type}\nprovider: ${mode}\ncreated: ${timestamp}\n---\n\n# ${agent.name} Analysis\n\n> Generated by DeepAnalyzer using ${mode === 'cli' ? 'Claude CLI' : mode === 'anthropic' ? 'Anthropic API' : 'Gemini API'}\n\n## Overview\n\n${agent.task}\n\n## Analysis\n\n${output}\n\n---\n\n*Generated on ${new Date().toLocaleString()}*\n`;\n }\n}\n\n/**\n * Create a deep analyzer instance\n */\nexport function createDeepAnalyzer(options: DeepAnalyzerOptions): DeepAnalyzer {\n return new DeepAnalyzer(options);\n}\n\n/**\n * Run deep analysis on a project\n */\nexport async function analyzeDeep(\n projectRoot: string,\n docsPath?: string\n): Promise<DeepAnalysisResult> {\n const analyzer = new DeepAnalyzer({ projectRoot, docsPath });\n return analyzer.analyze();\n}\n"],"names":[],"mappings":"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"}
|