@weavelogic/knowledge-graph-agent 0.10.6 → 0.10.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cultivation/deep-analyzer.d.ts +27 -28
- package/dist/cultivation/deep-analyzer.d.ts.map +1 -1
- package/dist/cultivation/deep-analyzer.js +214 -101
- package/dist/cultivation/deep-analyzer.js.map +1 -1
- package/dist/node_modules/@typescript-eslint/project-service/dist/index.js +1 -1
- 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/dist/node_modules/tinyglobby/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* DeepAnalyzer -
|
|
2
|
+
* DeepAnalyzer - Documentation Cultivation & Knowledge Graph Enhancement
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* -
|
|
6
|
-
* -
|
|
7
|
-
* -
|
|
8
|
-
* -
|
|
4
|
+
* Analyzes existing documentation to:
|
|
5
|
+
* - Understand the vision and requirements described
|
|
6
|
+
* - Identify documentation gaps and unclear areas
|
|
7
|
+
* - Guide the documentation process with research questions
|
|
8
|
+
* - Build knowledge graph connections
|
|
9
|
+
*
|
|
10
|
+
* This is NOT for code analysis - use analyze-codebase for that.
|
|
9
11
|
*
|
|
10
12
|
* @module cultivation/deep-analyzer
|
|
11
13
|
*/
|
|
@@ -21,11 +23,9 @@ export interface DeepAnalyzerOptions {
|
|
|
21
23
|
outputDir?: string;
|
|
22
24
|
/** Enable verbose logging */
|
|
23
25
|
verbose?: boolean;
|
|
24
|
-
/** Maximum
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
agentMode?: 'sequential' | 'parallel' | 'adaptive';
|
|
28
|
-
/** Timeout for each agent (ms) */
|
|
26
|
+
/** Maximum documents to analyze */
|
|
27
|
+
maxDocuments?: number;
|
|
28
|
+
/** Timeout for each analysis (ms) */
|
|
29
29
|
agentTimeout?: number;
|
|
30
30
|
/** Force use of API key even if CLI is available */
|
|
31
31
|
forceApiKey?: boolean;
|
|
@@ -61,12 +61,13 @@ export interface DeepAnalysisResult {
|
|
|
61
61
|
mode: 'cli' | 'anthropic' | 'gemini' | 'static';
|
|
62
62
|
}
|
|
63
63
|
/**
|
|
64
|
-
* DeepAnalyzer -
|
|
64
|
+
* DeepAnalyzer - Documentation cultivation with AI-powered analysis
|
|
65
65
|
*
|
|
66
|
-
*
|
|
67
|
-
* -
|
|
68
|
-
* -
|
|
69
|
-
* -
|
|
66
|
+
* Reads existing markdown documentation and provides:
|
|
67
|
+
* - Vision synthesis from requirements
|
|
68
|
+
* - Gap analysis identifying missing documentation
|
|
69
|
+
* - Research questions for unclear areas
|
|
70
|
+
* - Knowledge graph connection suggestions
|
|
70
71
|
*
|
|
71
72
|
* @example
|
|
72
73
|
* ```typescript
|
|
@@ -84,8 +85,7 @@ export declare class DeepAnalyzer {
|
|
|
84
85
|
private docsPath;
|
|
85
86
|
private outputDir;
|
|
86
87
|
private verbose;
|
|
87
|
-
private
|
|
88
|
-
private agentMode;
|
|
88
|
+
private maxDocuments;
|
|
89
89
|
private agentTimeout;
|
|
90
90
|
private forceApiKey;
|
|
91
91
|
private preferredProvider;
|
|
@@ -100,7 +100,6 @@ export declare class DeepAnalyzer {
|
|
|
100
100
|
private hasAnthropicApiKey;
|
|
101
101
|
/**
|
|
102
102
|
* Check if Google AI / Gemini API key is available
|
|
103
|
-
* Supports: GOOGLE_AI_API_KEY, GOOGLE_GEMINI_API_KEY, GEMINI_API_KEY, GOOGLE_API_KEY
|
|
104
103
|
*/
|
|
105
104
|
private hasGeminiApiKey;
|
|
106
105
|
/**
|
|
@@ -113,10 +112,6 @@ export declare class DeepAnalyzer {
|
|
|
113
112
|
private isCliAvailable;
|
|
114
113
|
/**
|
|
115
114
|
* Determine the best execution mode
|
|
116
|
-
*
|
|
117
|
-
* Priority: API keys > CLI (CLI often hangs in various contexts)
|
|
118
|
-
* - Prefer API when available for reliability
|
|
119
|
-
* - Fall back to CLI only when no API key is available
|
|
120
115
|
*/
|
|
121
116
|
private detectExecutionMode;
|
|
122
117
|
/**
|
|
@@ -130,6 +125,14 @@ export declare class DeepAnalyzer {
|
|
|
130
125
|
available: boolean;
|
|
131
126
|
reason: string;
|
|
132
127
|
}>;
|
|
128
|
+
/**
|
|
129
|
+
* Scan documentation directory for markdown files
|
|
130
|
+
*/
|
|
131
|
+
private scanDocumentation;
|
|
132
|
+
/**
|
|
133
|
+
* Read full content of key documents
|
|
134
|
+
*/
|
|
135
|
+
private readKeyDocuments;
|
|
133
136
|
/**
|
|
134
137
|
* Run deep analysis
|
|
135
138
|
*/
|
|
@@ -139,13 +142,9 @@ export declare class DeepAnalyzer {
|
|
|
139
142
|
*/
|
|
140
143
|
private executeAgent;
|
|
141
144
|
/**
|
|
142
|
-
* Build context-aware prompt for
|
|
145
|
+
* Build context-aware prompt for documentation cultivation
|
|
143
146
|
*/
|
|
144
147
|
private buildPrompt;
|
|
145
|
-
/**
|
|
146
|
-
* Gather project context for analysis
|
|
147
|
-
*/
|
|
148
|
-
private gatherProjectContext;
|
|
149
148
|
/**
|
|
150
149
|
* Run analysis using Claude CLI
|
|
151
150
|
*/
|
|
@@ -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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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { execFileSync, execSync } from "child_process";
|
|
2
|
-
import { existsSync, mkdirSync, writeFileSync,
|
|
3
|
-
import { resolve, join } from "path";
|
|
2
|
+
import { existsSync, readFileSync, mkdirSync, writeFileSync, readdirSync, statSync } from "fs";
|
|
3
|
+
import { resolve, join, extname, relative, basename } from "path";
|
|
4
4
|
import { createLogger } from "../utils/logger.js";
|
|
5
5
|
const logger = createLogger("deep-analyzer");
|
|
6
6
|
class DeepAnalyzer {
|
|
@@ -8,8 +8,7 @@ class DeepAnalyzer {
|
|
|
8
8
|
docsPath;
|
|
9
9
|
outputDir;
|
|
10
10
|
verbose;
|
|
11
|
-
|
|
12
|
-
agentMode;
|
|
11
|
+
maxDocuments;
|
|
13
12
|
agentTimeout;
|
|
14
13
|
forceApiKey;
|
|
15
14
|
preferredProvider;
|
|
@@ -18,8 +17,7 @@ class DeepAnalyzer {
|
|
|
18
17
|
this.docsPath = options.docsPath || "docs";
|
|
19
18
|
this.outputDir = options.outputDir || join(this.projectRoot, this.docsPath, "analysis");
|
|
20
19
|
this.verbose = options.verbose || false;
|
|
21
|
-
this.
|
|
22
|
-
this.agentMode = options.agentMode || "adaptive";
|
|
20
|
+
this.maxDocuments = options.maxDocuments || 50;
|
|
23
21
|
this.agentTimeout = options.agentTimeout || 12e4;
|
|
24
22
|
this.forceApiKey = options.forceApiKey || false;
|
|
25
23
|
this.preferredProvider = options.preferredProvider || "anthropic";
|
|
@@ -38,7 +36,6 @@ class DeepAnalyzer {
|
|
|
38
36
|
}
|
|
39
37
|
/**
|
|
40
38
|
* Check if Google AI / Gemini API key is available
|
|
41
|
-
* Supports: GOOGLE_AI_API_KEY, GOOGLE_GEMINI_API_KEY, GEMINI_API_KEY, GOOGLE_API_KEY
|
|
42
39
|
*/
|
|
43
40
|
hasGeminiApiKey() {
|
|
44
41
|
return !!(process.env.GOOGLE_AI_API_KEY || process.env.GOOGLE_GEMINI_API_KEY || process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY);
|
|
@@ -66,10 +63,6 @@ class DeepAnalyzer {
|
|
|
66
63
|
}
|
|
67
64
|
/**
|
|
68
65
|
* Determine the best execution mode
|
|
69
|
-
*
|
|
70
|
-
* Priority: API keys > CLI (CLI often hangs in various contexts)
|
|
71
|
-
* - Prefer API when available for reliability
|
|
72
|
-
* - Fall back to CLI only when no API key is available
|
|
73
66
|
*/
|
|
74
67
|
detectExecutionMode() {
|
|
75
68
|
const insideClaudeCode = this.isInsideClaudeCode();
|
|
@@ -86,7 +79,7 @@ class DeepAnalyzer {
|
|
|
86
79
|
if (hasGeminiKey) {
|
|
87
80
|
return { mode: "gemini", reason: "Using Gemini API (forced, fallback)" };
|
|
88
81
|
}
|
|
89
|
-
return { mode: "unavailable", reason: "No API key found
|
|
82
|
+
return { mode: "unavailable", reason: "No API key found. Set ANTHROPIC_API_KEY or GOOGLE_AI_API_KEY." };
|
|
90
83
|
}
|
|
91
84
|
if (this.preferredProvider === "gemini" && hasGeminiKey) {
|
|
92
85
|
return { mode: "gemini", reason: "Using Gemini API (preferred)" };
|
|
@@ -100,7 +93,7 @@ class DeepAnalyzer {
|
|
|
100
93
|
if (insideClaudeCode) {
|
|
101
94
|
return {
|
|
102
95
|
mode: "unavailable",
|
|
103
|
-
reason: "Cannot run
|
|
96
|
+
reason: "Cannot run inside Claude Code without an API key. Set ANTHROPIC_API_KEY or GOOGLE_AI_API_KEY."
|
|
104
97
|
};
|
|
105
98
|
}
|
|
106
99
|
if (cliAvailable) {
|
|
@@ -108,7 +101,7 @@ class DeepAnalyzer {
|
|
|
108
101
|
}
|
|
109
102
|
return {
|
|
110
103
|
mode: "unavailable",
|
|
111
|
-
reason: "No execution method available. Set ANTHROPIC_API_KEY or GOOGLE_AI_API_KEY
|
|
104
|
+
reason: "No execution method available. Set ANTHROPIC_API_KEY or GOOGLE_AI_API_KEY."
|
|
112
105
|
};
|
|
113
106
|
}
|
|
114
107
|
/**
|
|
@@ -128,6 +121,85 @@ class DeepAnalyzer {
|
|
|
128
121
|
reason: mode.reason
|
|
129
122
|
};
|
|
130
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* Scan documentation directory for markdown files
|
|
126
|
+
*/
|
|
127
|
+
scanDocumentation() {
|
|
128
|
+
const docsDir = join(this.projectRoot, this.docsPath);
|
|
129
|
+
if (!existsSync(docsDir)) {
|
|
130
|
+
return [];
|
|
131
|
+
}
|
|
132
|
+
const documents = [];
|
|
133
|
+
const scan = (dir) => {
|
|
134
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
135
|
+
for (const entry of entries) {
|
|
136
|
+
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "analysis") {
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
const fullPath = join(dir, entry.name);
|
|
140
|
+
if (entry.isDirectory()) {
|
|
141
|
+
scan(fullPath);
|
|
142
|
+
} else if (entry.isFile() && extname(entry.name) === ".md") {
|
|
143
|
+
try {
|
|
144
|
+
const content = readFileSync(fullPath, "utf-8");
|
|
145
|
+
const stats = statSync(fullPath);
|
|
146
|
+
const relPath = relative(docsDir, fullPath);
|
|
147
|
+
const titleMatch = content.match(/^#\s+(.+)$/m);
|
|
148
|
+
const title = titleMatch ? titleMatch[1] : basename(entry.name, ".md");
|
|
149
|
+
let type = "general";
|
|
150
|
+
if (relPath.includes("concepts/")) type = "concept";
|
|
151
|
+
else if (relPath.includes("components/")) type = "component";
|
|
152
|
+
else if (relPath.includes("services/")) type = "service";
|
|
153
|
+
else if (relPath.includes("features/")) type = "feature";
|
|
154
|
+
else if (relPath.includes("guides/")) type = "guide";
|
|
155
|
+
else if (relPath.includes("standards/")) type = "standard";
|
|
156
|
+
else if (relPath.includes("references/")) type = "reference";
|
|
157
|
+
else if (relPath.includes("integrations/")) type = "integration";
|
|
158
|
+
else if (entry.name.includes("requirement")) type = "requirement";
|
|
159
|
+
else if (entry.name.includes("spec")) type = "specification";
|
|
160
|
+
const preview = content.slice(0, 2e3).replace(/^#.+\n/, "").trim().slice(0, 500);
|
|
161
|
+
documents.push({
|
|
162
|
+
path: relPath,
|
|
163
|
+
title,
|
|
164
|
+
type,
|
|
165
|
+
size: stats.size,
|
|
166
|
+
preview
|
|
167
|
+
});
|
|
168
|
+
} catch {
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
scan(docsDir);
|
|
174
|
+
return documents.slice(0, this.maxDocuments);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Read full content of key documents
|
|
178
|
+
*/
|
|
179
|
+
readKeyDocuments() {
|
|
180
|
+
const docsDir = join(this.projectRoot, this.docsPath);
|
|
181
|
+
const keyDocs = /* @__PURE__ */ new Map();
|
|
182
|
+
const priorityFiles = [
|
|
183
|
+
"README.md",
|
|
184
|
+
"MOC.md",
|
|
185
|
+
"PRIMITIVES.md",
|
|
186
|
+
"original_specs.md",
|
|
187
|
+
"business_requirements_document.md",
|
|
188
|
+
"technical_requirements.md",
|
|
189
|
+
"test_strategy.md"
|
|
190
|
+
];
|
|
191
|
+
for (const file of priorityFiles) {
|
|
192
|
+
const filePath = join(docsDir, file);
|
|
193
|
+
if (existsSync(filePath)) {
|
|
194
|
+
try {
|
|
195
|
+
const content = readFileSync(filePath, "utf-8");
|
|
196
|
+
keyDocs.set(file, content.slice(0, 15e3));
|
|
197
|
+
} catch {
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return keyDocs;
|
|
202
|
+
}
|
|
131
203
|
/**
|
|
132
204
|
* Run deep analysis
|
|
133
205
|
*/
|
|
@@ -150,39 +222,52 @@ class DeepAnalyzer {
|
|
|
150
222
|
logger.error("Deep analysis unavailable", new Error(executionMode.reason));
|
|
151
223
|
return result;
|
|
152
224
|
}
|
|
153
|
-
logger.info(`Starting
|
|
225
|
+
logger.info(`Starting documentation cultivation`, { mode: executionMode.mode, reason: executionMode.reason });
|
|
154
226
|
if (!existsSync(this.outputDir)) {
|
|
155
227
|
mkdirSync(this.outputDir, { recursive: true });
|
|
156
228
|
}
|
|
229
|
+
const documents = this.scanDocumentation();
|
|
230
|
+
const keyDocs = this.readKeyDocuments();
|
|
231
|
+
if (documents.length === 0) {
|
|
232
|
+
result.errors.push("No markdown documents found in docs directory");
|
|
233
|
+
result.duration = Date.now() - startTime;
|
|
234
|
+
return result;
|
|
235
|
+
}
|
|
236
|
+
logger.info("Found documentation", { documents: documents.length, keyDocs: keyDocs.size });
|
|
157
237
|
const agents = [
|
|
158
238
|
{
|
|
159
|
-
name: "
|
|
160
|
-
type: "
|
|
161
|
-
task: "
|
|
162
|
-
outputFile: "
|
|
239
|
+
name: "Vision Synthesizer",
|
|
240
|
+
type: "vision",
|
|
241
|
+
task: "Synthesize the project vision, goals, and core value proposition from the documentation",
|
|
242
|
+
outputFile: "vision-synthesis.md"
|
|
163
243
|
},
|
|
164
244
|
{
|
|
165
|
-
name: "
|
|
166
|
-
type: "
|
|
167
|
-
task: "Identify
|
|
168
|
-
outputFile: "
|
|
245
|
+
name: "Gap Analyst",
|
|
246
|
+
type: "gaps",
|
|
247
|
+
task: "Identify documentation gaps, missing sections, and areas that need more detail",
|
|
248
|
+
outputFile: "documentation-gaps.md"
|
|
169
249
|
},
|
|
170
250
|
{
|
|
171
|
-
name: "
|
|
172
|
-
type: "
|
|
173
|
-
task: "
|
|
174
|
-
outputFile: "
|
|
251
|
+
name: "Research Guide",
|
|
252
|
+
type: "research",
|
|
253
|
+
task: "Generate research questions and areas that need further investigation or clarification",
|
|
254
|
+
outputFile: "research-questions.md"
|
|
175
255
|
},
|
|
176
256
|
{
|
|
177
|
-
name: "
|
|
178
|
-
type: "
|
|
179
|
-
task: "
|
|
180
|
-
outputFile: "
|
|
257
|
+
name: "Connection Mapper",
|
|
258
|
+
type: "connections",
|
|
259
|
+
task: "Identify relationships between concepts and suggest knowledge graph connections",
|
|
260
|
+
outputFile: "knowledge-connections.md"
|
|
181
261
|
}
|
|
182
262
|
];
|
|
183
|
-
logger.info("Executing
|
|
263
|
+
logger.info("Executing cultivation agents", { agents: agents.length, mode: "sequential" });
|
|
184
264
|
for (const agent of agents) {
|
|
185
|
-
const agentResult = await this.executeAgent(
|
|
265
|
+
const agentResult = await this.executeAgent(
|
|
266
|
+
agent,
|
|
267
|
+
executionMode.mode,
|
|
268
|
+
documents,
|
|
269
|
+
keyDocs
|
|
270
|
+
);
|
|
186
271
|
result.results.push(agentResult);
|
|
187
272
|
}
|
|
188
273
|
result.agentsSpawned = result.results.length;
|
|
@@ -195,7 +280,7 @@ class DeepAnalyzer {
|
|
|
195
280
|
result.errors.push(`${agentResult.name}: ${agentResult.error}`);
|
|
196
281
|
}
|
|
197
282
|
}
|
|
198
|
-
logger.info("
|
|
283
|
+
logger.info("Documentation cultivation complete", {
|
|
199
284
|
success: result.success,
|
|
200
285
|
insights: result.insightsCount,
|
|
201
286
|
documents: result.documentsCreated,
|
|
@@ -206,7 +291,7 @@ class DeepAnalyzer {
|
|
|
206
291
|
/**
|
|
207
292
|
* Execute a single agent
|
|
208
293
|
*/
|
|
209
|
-
async executeAgent(agent, mode) {
|
|
294
|
+
async executeAgent(agent, mode, documents, keyDocs) {
|
|
210
295
|
const startTime = Date.now();
|
|
211
296
|
const outputPath = join(this.outputDir, agent.outputFile);
|
|
212
297
|
const result = {
|
|
@@ -219,7 +304,7 @@ class DeepAnalyzer {
|
|
|
219
304
|
};
|
|
220
305
|
try {
|
|
221
306
|
logger.info(`Executing agent: ${agent.name}`, { type: agent.type, mode });
|
|
222
|
-
const prompt = this.buildPrompt(agent);
|
|
307
|
+
const prompt = this.buildPrompt(agent, documents, keyDocs);
|
|
223
308
|
let output;
|
|
224
309
|
if (mode === "cli") {
|
|
225
310
|
output = await this.runWithCli(prompt);
|
|
@@ -243,61 +328,95 @@ class DeepAnalyzer {
|
|
|
243
328
|
return result;
|
|
244
329
|
}
|
|
245
330
|
/**
|
|
246
|
-
* Build context-aware prompt for
|
|
331
|
+
* Build context-aware prompt for documentation cultivation
|
|
247
332
|
*/
|
|
248
|
-
buildPrompt(agent) {
|
|
249
|
-
const
|
|
250
|
-
|
|
333
|
+
buildPrompt(agent, documents, keyDocs) {
|
|
334
|
+
const inventory = documents.map((d) => `- ${d.path} (${d.type}): ${d.title}`).join("\n");
|
|
335
|
+
const keyContent = Array.from(keyDocs.entries()).map(([name, content]) => `### ${name}
|
|
251
336
|
|
|
252
|
-
${
|
|
337
|
+
${content}`).join("\n\n---\n\n");
|
|
338
|
+
let specificInstructions = "";
|
|
339
|
+
switch (agent.type) {
|
|
340
|
+
case "vision":
|
|
341
|
+
specificInstructions = `
|
|
342
|
+
Focus on:
|
|
343
|
+
1. What is the core purpose/goal of this project?
|
|
344
|
+
2. What problem does it solve?
|
|
345
|
+
3. What is the target audience/user?
|
|
346
|
+
4. What are the key success metrics?
|
|
347
|
+
5. What is the overall architecture vision?
|
|
253
348
|
|
|
254
|
-
|
|
349
|
+
Provide a clear, concise synthesis of the project vision with references to specific documentation.`;
|
|
350
|
+
break;
|
|
351
|
+
case "gaps":
|
|
352
|
+
specificInstructions = `
|
|
353
|
+
Identify:
|
|
354
|
+
1. Missing documentation (what topics are mentioned but not explained?)
|
|
355
|
+
2. Incomplete sections (what areas need more detail?)
|
|
356
|
+
3. Outdated information (anything that seems inconsistent?)
|
|
357
|
+
4. Missing examples or use cases
|
|
358
|
+
5. Unclear terminology or concepts that need definitions
|
|
255
359
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
360
|
+
For each gap, specify:
|
|
361
|
+
- What is missing
|
|
362
|
+
- Where it should be documented
|
|
363
|
+
- Why it's important`;
|
|
364
|
+
break;
|
|
365
|
+
case "research":
|
|
366
|
+
specificInstructions = `
|
|
367
|
+
Generate research questions in these categories:
|
|
368
|
+
1. Technical questions (how should X be implemented?)
|
|
369
|
+
2. Design decisions (why this approach vs alternatives?)
|
|
370
|
+
3. Integration questions (how does X connect to Y?)
|
|
371
|
+
4. Validation questions (how do we verify X works?)
|
|
372
|
+
5. Scalability questions (will this work at scale?)
|
|
260
373
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
}
|
|
281
|
-
try {
|
|
282
|
-
const entries = readdirSync(this.projectRoot, { withFileTypes: true });
|
|
283
|
-
const dirs = entries.filter((e) => e.isDirectory() && !e.name.startsWith(".") && e.name !== "node_modules").map((e) => e.name).slice(0, 10);
|
|
284
|
-
if (dirs.length > 0) {
|
|
285
|
-
lines.push(`Project structure: ${dirs.join(", ")}`);
|
|
286
|
-
}
|
|
287
|
-
} catch {
|
|
288
|
-
}
|
|
289
|
-
const configFiles = [
|
|
290
|
-
"tsconfig.json",
|
|
291
|
-
"vite.config.ts",
|
|
292
|
-
"vitest.config.ts",
|
|
293
|
-
".eslintrc.js",
|
|
294
|
-
"Dockerfile"
|
|
295
|
-
];
|
|
296
|
-
const foundConfigs = configFiles.filter((f) => existsSync(join(this.projectRoot, f)));
|
|
297
|
-
if (foundConfigs.length > 0) {
|
|
298
|
-
lines.push(`Config files: ${foundConfigs.join(", ")}`);
|
|
374
|
+
For each question:
|
|
375
|
+
- State the question clearly
|
|
376
|
+
- Explain why answering it is important
|
|
377
|
+
- Suggest where to look for answers`;
|
|
378
|
+
break;
|
|
379
|
+
case "connections":
|
|
380
|
+
specificInstructions = `
|
|
381
|
+
Identify relationships between documented concepts:
|
|
382
|
+
1. Dependencies (X requires Y)
|
|
383
|
+
2. Extensions (X extends Y)
|
|
384
|
+
3. Alternatives (X is an alternative to Y)
|
|
385
|
+
4. Compositions (X is made up of Y and Z)
|
|
386
|
+
5. References (X references Y for details)
|
|
387
|
+
|
|
388
|
+
Suggest knowledge graph nodes and edges in this format:
|
|
389
|
+
- [Node A] --relationship--> [Node B]: description
|
|
390
|
+
|
|
391
|
+
Also identify concepts that should be linked but aren't currently.`;
|
|
392
|
+
break;
|
|
299
393
|
}
|
|
300
|
-
return
|
|
394
|
+
return `You are a documentation analyst helping to cultivate a knowledge graph.
|
|
395
|
+
|
|
396
|
+
## Your Task
|
|
397
|
+
${agent.task}
|
|
398
|
+
|
|
399
|
+
## Documentation Inventory
|
|
400
|
+
The following markdown documents exist in this project:
|
|
401
|
+
${inventory}
|
|
402
|
+
|
|
403
|
+
## Key Document Contents
|
|
404
|
+
|
|
405
|
+
${keyContent}
|
|
406
|
+
|
|
407
|
+
## Instructions
|
|
408
|
+
${specificInstructions}
|
|
409
|
+
|
|
410
|
+
## Output Format
|
|
411
|
+
Provide your analysis in markdown format with:
|
|
412
|
+
1. Clear section headings
|
|
413
|
+
2. Specific observations (prefix with "Observation:")
|
|
414
|
+
3. Specific recommendations (prefix with "Recommendation:")
|
|
415
|
+
4. Key findings (prefix with "Finding:")
|
|
416
|
+
5. Research questions where applicable (prefix with "Question:")
|
|
417
|
+
|
|
418
|
+
Reference specific documents using [[document-name]] wiki-link format where relevant.
|
|
419
|
+
Be specific and actionable in your analysis.`;
|
|
301
420
|
}
|
|
302
421
|
/**
|
|
303
422
|
* Run analysis using Claude CLI
|
|
@@ -310,7 +429,6 @@ Be specific and actionable in your analysis.`;
|
|
|
310
429
|
encoding: "utf8",
|
|
311
430
|
timeout: this.agentTimeout,
|
|
312
431
|
maxBuffer: 10 * 1024 * 1024
|
|
313
|
-
// 10MB buffer
|
|
314
432
|
});
|
|
315
433
|
return result;
|
|
316
434
|
} catch (error) {
|
|
@@ -341,12 +459,7 @@ Be specific and actionable in your analysis.`;
|
|
|
341
459
|
const response = await client.messages.create({
|
|
342
460
|
model: "claude-sonnet-4-20250514",
|
|
343
461
|
max_tokens: 4096,
|
|
344
|
-
messages: [
|
|
345
|
-
{
|
|
346
|
-
role: "user",
|
|
347
|
-
content: prompt
|
|
348
|
-
}
|
|
349
|
-
]
|
|
462
|
+
messages: [{ role: "user", content: prompt }]
|
|
350
463
|
});
|
|
351
464
|
const textBlock = response.content.find((block) => block.type === "text");
|
|
352
465
|
if (textBlock && textBlock.type === "text") {
|
|
@@ -366,7 +479,7 @@ Be specific and actionable in your analysis.`;
|
|
|
366
479
|
async runWithGemini(prompt) {
|
|
367
480
|
const apiKey = this.getGeminiApiKey();
|
|
368
481
|
if (!apiKey) {
|
|
369
|
-
throw new Error("GOOGLE_AI_API_KEY
|
|
482
|
+
throw new Error("GOOGLE_AI_API_KEY not set");
|
|
370
483
|
}
|
|
371
484
|
try {
|
|
372
485
|
const { GoogleGenerativeAI } = await import("../node_modules/@google/generative-ai/dist/index.js");
|
|
@@ -392,9 +505,9 @@ Be specific and actionable in your analysis.`;
|
|
|
392
505
|
extractInsights(output) {
|
|
393
506
|
const insights = [];
|
|
394
507
|
const patterns = [
|
|
395
|
-
/[-*]?\s*(?:insight|finding|observation|recommendation):\s*(.+)/gi,
|
|
396
|
-
/##\s*(?:insight|finding|observation|recommendation):\s*(.+)/gi,
|
|
397
|
-
/(?:key\s+)?(?:insight|finding|observation|recommendation):\s*(.+)/gi
|
|
508
|
+
/[-*]?\s*(?:insight|finding|observation|recommendation|question):\s*(.+)/gi,
|
|
509
|
+
/##\s*(?:insight|finding|observation|recommendation|question):\s*(.+)/gi,
|
|
510
|
+
/(?:key\s+)?(?:insight|finding|observation|recommendation|question):\s*(.+)/gi
|
|
398
511
|
];
|
|
399
512
|
for (const pattern of patterns) {
|
|
400
513
|
const matches = output.matchAll(pattern);
|
|
@@ -412,19 +525,19 @@ Be specific and actionable in your analysis.`;
|
|
|
412
525
|
formatOutput(agent, output, mode) {
|
|
413
526
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
414
527
|
return `---
|
|
415
|
-
title: "${agent.name}
|
|
416
|
-
type: analysis
|
|
528
|
+
title: "${agent.name}"
|
|
529
|
+
type: cultivation-analysis
|
|
417
530
|
generator: deep-analyzer
|
|
418
531
|
agent: ${agent.type}
|
|
419
532
|
provider: ${mode}
|
|
420
533
|
created: ${timestamp}
|
|
421
534
|
---
|
|
422
535
|
|
|
423
|
-
# ${agent.name}
|
|
536
|
+
# ${agent.name}
|
|
424
537
|
|
|
425
|
-
> Generated by DeepAnalyzer
|
|
538
|
+
> Generated by DeepAnalyzer for documentation cultivation
|
|
426
539
|
|
|
427
|
-
##
|
|
540
|
+
## Purpose
|
|
428
541
|
|
|
429
542
|
${agent.task}
|
|
430
543
|
|
|
@@ -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 * - 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 * Supports: GOOGLE_AI_API_KEY, GOOGLE_GEMINI_API_KEY, GEMINI_API_KEY, GOOGLE_API_KEY\n */\n private hasGeminiApiKey(): boolean {\n return !!(\n process.env.GOOGLE_AI_API_KEY ||\n process.env.GOOGLE_GEMINI_API_KEY ||\n process.env.GEMINI_API_KEY ||\n process.env.GOOGLE_API_KEY\n );\n }\n\n /**\n * Get the Gemini API key from available env vars\n */\n private getGeminiApiKey(): string | undefined {\n return (\n process.env.GOOGLE_AI_API_KEY ||\n process.env.GOOGLE_GEMINI_API_KEY ||\n process.env.GEMINI_API_KEY ||\n process.env.GOOGLE_API_KEY\n );\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 * Priority: API keys > CLI (CLI often hangs in various contexts)\n * - Prefer API when available for reliability\n * - Fall back to CLI only when no API key is available\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 // Prefer API keys for reliability (CLI can hang in various contexts)\n // Check preferred provider first\n if (this.preferredProvider === 'gemini' && hasGeminiKey) {\n return { mode: 'gemini', reason: 'Using Gemini API (preferred)' };\n }\n if (hasAnthropicKey) {\n return { mode: 'anthropic', reason: 'Using Anthropic API' };\n }\n if (hasGeminiKey) {\n return { mode: 'gemini', reason: 'Using Gemini API' };\n }\n\n // No API keys - try CLI as last resort (only works reliably in regular terminal)\n if (insideClaudeCode) {\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.',\n };\n }\n\n if (cliAvailable) {\n return { mode: 'cli', reason: 'Using Claude CLI (no API key found)' };\n }\n\n return {\n mode: 'unavailable',\n reason: 'No execution method available. Set ANTHROPIC_API_KEY or GOOGLE_AI_API_KEY, ' +\n 'or install Claude Code (https://claude.ai/code).',\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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"}
|
|
1
|
+
{"version":3,"file":"deep-analyzer.js","sources":["../../src/cultivation/deep-analyzer.ts"],"sourcesContent":["/**\n * DeepAnalyzer - Documentation Cultivation & Knowledge Graph Enhancement\n *\n * Analyzes existing documentation to:\n * - Understand the vision and requirements described\n * - Identify documentation gaps and unclear areas\n * - Guide the documentation process with research questions\n * - Build knowledge graph connections\n *\n * This is NOT for code analysis - use analyze-codebase for that.\n *\n * @module cultivation/deep-analyzer\n */\n\nimport { execFileSync, execSync } from 'child_process';\nimport { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync, statSync } from 'fs';\nimport { join, resolve, relative, basename, extname } from 'path';\nimport { createLogger } from '../utils/index.js';\n\nconst logger = createLogger('deep-analyzer');\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 documents to analyze */\n maxDocuments?: number;\n /** Timeout for each analysis (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: string;\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 * Document metadata for analysis\n */\ninterface DocMetadata {\n path: string;\n title: string;\n type: string;\n size: number;\n preview: string;\n}\n\n/**\n * DeepAnalyzer - Documentation cultivation with AI-powered analysis\n *\n * Reads existing markdown documentation and provides:\n * - Vision synthesis from requirements\n * - Gap analysis identifying missing documentation\n * - Research questions for unclear areas\n * - Knowledge graph connection suggestions\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 maxDocuments: number;\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.maxDocuments = options.maxDocuments || 50;\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 !!(\n process.env.GOOGLE_AI_API_KEY ||\n process.env.GOOGLE_GEMINI_API_KEY ||\n process.env.GEMINI_API_KEY ||\n process.env.GOOGLE_API_KEY\n );\n }\n\n /**\n * Get the Gemini API key from available env vars\n */\n private getGeminiApiKey(): string | undefined {\n return (\n process.env.GOOGLE_AI_API_KEY ||\n process.env.GOOGLE_GEMINI_API_KEY ||\n process.env.GEMINI_API_KEY ||\n process.env.GOOGLE_API_KEY\n );\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 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. Set ANTHROPIC_API_KEY or GOOGLE_AI_API_KEY.' };\n }\n\n // Prefer API keys for reliability\n if (this.preferredProvider === 'gemini' && hasGeminiKey) {\n return { mode: 'gemini', reason: 'Using Gemini API (preferred)' };\n }\n if (hasAnthropicKey) {\n return { mode: 'anthropic', reason: 'Using Anthropic API' };\n }\n if (hasGeminiKey) {\n return { mode: 'gemini', reason: 'Using Gemini API' };\n }\n\n // No API keys - try CLI as last resort\n if (insideClaudeCode) {\n return {\n mode: 'unavailable',\n reason: 'Cannot run inside Claude Code without an API key. Set ANTHROPIC_API_KEY or GOOGLE_AI_API_KEY.',\n };\n }\n\n if (cliAvailable) {\n return { mode: 'cli', reason: 'Using Claude CLI (no API key found)' };\n }\n\n return {\n mode: 'unavailable',\n reason: 'No execution method available. 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 * Scan documentation directory for markdown files\n */\n private scanDocumentation(): DocMetadata[] {\n const docsDir = join(this.projectRoot, this.docsPath);\n if (!existsSync(docsDir)) {\n return [];\n }\n\n const documents: DocMetadata[] = [];\n const scan = (dir: string) => {\n const entries = readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.name.startsWith('.') || entry.name === 'node_modules' || entry.name === 'analysis') {\n continue;\n }\n\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n scan(fullPath);\n } else if (entry.isFile() && extname(entry.name) === '.md') {\n try {\n const content = readFileSync(fullPath, 'utf-8');\n const stats = statSync(fullPath);\n const relPath = relative(docsDir, fullPath);\n\n // Extract title from first heading or filename\n const titleMatch = content.match(/^#\\s+(.+)$/m);\n const title = titleMatch ? titleMatch[1] : basename(entry.name, '.md');\n\n // Determine document type from path or frontmatter\n let type = 'general';\n if (relPath.includes('concepts/')) type = 'concept';\n else if (relPath.includes('components/')) type = 'component';\n else if (relPath.includes('services/')) type = 'service';\n else if (relPath.includes('features/')) type = 'feature';\n else if (relPath.includes('guides/')) type = 'guide';\n else if (relPath.includes('standards/')) type = 'standard';\n else if (relPath.includes('references/')) type = 'reference';\n else if (relPath.includes('integrations/')) type = 'integration';\n else if (entry.name.includes('requirement')) type = 'requirement';\n else if (entry.name.includes('spec')) type = 'specification';\n\n // Get preview (first 500 chars after title)\n const preview = content.slice(0, 2000).replace(/^#.+\\n/, '').trim().slice(0, 500);\n\n documents.push({\n path: relPath,\n title,\n type,\n size: stats.size,\n preview,\n });\n } catch {\n // Skip files that can't be read\n }\n }\n }\n };\n\n scan(docsDir);\n return documents.slice(0, this.maxDocuments);\n }\n\n /**\n * Read full content of key documents\n */\n private readKeyDocuments(): Map<string, string> {\n const docsDir = join(this.projectRoot, this.docsPath);\n const keyDocs = new Map<string, string>();\n\n // Priority documents to read in full\n const priorityFiles = [\n 'README.md',\n 'MOC.md',\n 'PRIMITIVES.md',\n 'original_specs.md',\n 'business_requirements_document.md',\n 'technical_requirements.md',\n 'test_strategy.md',\n ];\n\n for (const file of priorityFiles) {\n const filePath = join(docsDir, file);\n if (existsSync(filePath)) {\n try {\n const content = readFileSync(filePath, 'utf-8');\n // Limit to 15KB per document to fit in context\n keyDocs.set(file, content.slice(0, 15000));\n } catch {\n // Skip\n }\n }\n }\n\n return keyDocs;\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 documentation cultivation`, { 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 // Scan existing documentation\n const documents = this.scanDocumentation();\n const keyDocs = this.readKeyDocuments();\n\n if (documents.length === 0) {\n result.errors.push('No markdown documents found in docs directory');\n result.duration = Date.now() - startTime;\n return result;\n }\n\n logger.info('Found documentation', { documents: documents.length, keyDocs: keyDocs.size });\n\n // Define documentation cultivation agents\n const agents: AgentConfig[] = [\n {\n name: 'Vision Synthesizer',\n type: 'vision',\n task: 'Synthesize the project vision, goals, and core value proposition from the documentation',\n outputFile: 'vision-synthesis.md',\n },\n {\n name: 'Gap Analyst',\n type: 'gaps',\n task: 'Identify documentation gaps, missing sections, and areas that need more detail',\n outputFile: 'documentation-gaps.md',\n },\n {\n name: 'Research Guide',\n type: 'research',\n task: 'Generate research questions and areas that need further investigation or clarification',\n outputFile: 'research-questions.md',\n },\n {\n name: 'Connection Mapper',\n type: 'connections',\n task: 'Identify relationships between concepts and suggest knowledge graph connections',\n outputFile: 'knowledge-connections.md',\n },\n ];\n\n logger.info('Executing cultivation agents', { agents: agents.length, mode: 'sequential' });\n\n // Execute agents sequentially\n for (const agent of agents) {\n const agentResult = await this.executeAgent(\n agent,\n executionMode.mode as 'cli' | 'anthropic' | 'gemini',\n documents,\n keyDocs\n );\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);\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('Documentation cultivation 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(\n agent: AgentConfig,\n mode: 'cli' | 'anthropic' | 'gemini',\n documents: DocMetadata[],\n keyDocs: Map<string, string>\n ): 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, documents, keyDocs);\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 documentation cultivation\n */\n private buildPrompt(agent: AgentConfig, documents: DocMetadata[], keyDocs: Map<string, string>): string {\n // Build document inventory\n const inventory = documents.map(d => `- ${d.path} (${d.type}): ${d.title}`).join('\\n');\n\n // Build key document content\n const keyContent = Array.from(keyDocs.entries())\n .map(([name, content]) => `### ${name}\\n\\n${content}`)\n .join('\\n\\n---\\n\\n');\n\n // Agent-specific instructions\n let specificInstructions = '';\n switch (agent.type) {\n case 'vision':\n specificInstructions = `\nFocus on:\n1. What is the core purpose/goal of this project?\n2. What problem does it solve?\n3. What is the target audience/user?\n4. What are the key success metrics?\n5. What is the overall architecture vision?\n\nProvide a clear, concise synthesis of the project vision with references to specific documentation.`;\n break;\n\n case 'gaps':\n specificInstructions = `\nIdentify:\n1. Missing documentation (what topics are mentioned but not explained?)\n2. Incomplete sections (what areas need more detail?)\n3. Outdated information (anything that seems inconsistent?)\n4. Missing examples or use cases\n5. Unclear terminology or concepts that need definitions\n\nFor each gap, specify:\n- What is missing\n- Where it should be documented\n- Why it's important`;\n break;\n\n case 'research':\n specificInstructions = `\nGenerate research questions in these categories:\n1. Technical questions (how should X be implemented?)\n2. Design decisions (why this approach vs alternatives?)\n3. Integration questions (how does X connect to Y?)\n4. Validation questions (how do we verify X works?)\n5. Scalability questions (will this work at scale?)\n\nFor each question:\n- State the question clearly\n- Explain why answering it is important\n- Suggest where to look for answers`;\n break;\n\n case 'connections':\n specificInstructions = `\nIdentify relationships between documented concepts:\n1. Dependencies (X requires Y)\n2. Extensions (X extends Y)\n3. Alternatives (X is an alternative to Y)\n4. Compositions (X is made up of Y and Z)\n5. References (X references Y for details)\n\nSuggest knowledge graph nodes and edges in this format:\n- [Node A] --relationship--> [Node B]: description\n\nAlso identify concepts that should be linked but aren't currently.`;\n break;\n }\n\n return `You are a documentation analyst helping to cultivate a knowledge graph.\n\n## Your Task\n${agent.task}\n\n## Documentation Inventory\nThe following markdown documents exist in this project:\n${inventory}\n\n## Key Document Contents\n\n${keyContent}\n\n## Instructions\n${specificInstructions}\n\n## Output Format\nProvide your analysis in markdown format with:\n1. Clear section headings\n2. Specific observations (prefix with \"Observation:\")\n3. Specific recommendations (prefix with \"Recommendation:\")\n4. Key findings (prefix with \"Finding:\")\n5. Research questions where applicable (prefix with \"Question:\")\n\nReference specific documents using [[document-name]] wiki-link format where relevant.\nBe specific and actionable in your analysis.`;\n }\n\n /**\n * Run analysis using Claude CLI\n */\n private async runWithCli(prompt: string): Promise<string> {\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,\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 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 const { default: Anthropic } = await import('@anthropic-ai/sdk');\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: [{ role: 'user', content: prompt }],\n });\n\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 not set');\n }\n\n try {\n const { GoogleGenerativeAI } = await import('@google/generative-ai');\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 const patterns = [\n /[-*]?\\s*(?:insight|finding|observation|recommendation|question):\\s*(.+)/gi,\n /##\\s*(?:insight|finding|observation|recommendation|question):\\s*(.+)/gi,\n /(?:key\\s+)?(?:insight|finding|observation|recommendation|question):\\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 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}\"\ntype: cultivation-analysis\ngenerator: deep-analyzer\nagent: ${agent.type}\nprovider: ${mode}\ncreated: ${timestamp}\n---\n\n# ${agent.name}\n\n> Generated by DeepAnalyzer for documentation cultivation\n\n## Purpose\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,4 +1,4 @@
|
|
|
1
|
-
import { __exports as dist } from "../../../../_virtual/
|
|
1
|
+
import { __exports as dist } from "../../../../_virtual/index8.js";
|
|
2
2
|
import { __require as requireCreateProjectService } from "./createProjectService.js";
|
|
3
3
|
var hasRequiredDist;
|
|
4
4
|
function requireDist() {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __exports as dist } from "../../../../_virtual/
|
|
1
|
+
import { __exports as dist } from "../../../../_virtual/index6.js";
|
|
2
2
|
import { __require as requireAstSpec } from "./generated/ast-spec.js";
|
|
3
3
|
import { __require as requireLib } from "./lib.js";
|
|
4
4
|
import { __require as requireParserOptions } from "./parser-options.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __exports as dist } from "../../../../_virtual/
|
|
1
|
+
import { __exports as dist } from "../../../../_virtual/index5.js";
|
|
2
2
|
import { __require as requireGetKeys } from "./get-keys.js";
|
|
3
3
|
import { __require as requireVisitorKeys } from "./visitor-keys.js";
|
|
4
4
|
var hasRequiredDist;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weavelogic/knowledge-graph-agent",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.7",
|
|
4
4
|
"description": "Knowledge graph agent for Claude Code - generates knowledge graphs, initializes docs, and integrates with claude-flow",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|