@vpxa/kb 0.1.1 → 0.1.2
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/package.json +1 -1
- package/packages/analyzers/dist/blast-radius-analyzer.js +13 -114
- package/packages/analyzers/dist/dependency-analyzer.js +11 -425
- package/packages/analyzers/dist/diagram-generator.js +4 -86
- package/packages/analyzers/dist/entry-point-analyzer.js +5 -239
- package/packages/analyzers/dist/index.js +1 -23
- package/packages/analyzers/dist/knowledge-producer.js +24 -113
- package/packages/analyzers/dist/pattern-analyzer.js +5 -359
- package/packages/analyzers/dist/regex-call-graph.js +1 -428
- package/packages/analyzers/dist/structure-analyzer.js +4 -258
- package/packages/analyzers/dist/symbol-analyzer.js +13 -442
- package/packages/analyzers/dist/ts-call-graph.js +1 -160
- package/packages/analyzers/dist/types.js +0 -1
- package/packages/chunker/dist/call-graph-extractor.js +1 -90
- package/packages/chunker/dist/chunker-factory.js +1 -36
- package/packages/chunker/dist/chunker.interface.js +0 -1
- package/packages/chunker/dist/code-chunker.js +14 -134
- package/packages/chunker/dist/generic-chunker.js +5 -72
- package/packages/chunker/dist/index.js +1 -21
- package/packages/chunker/dist/markdown-chunker.js +7 -119
- package/packages/chunker/dist/treesitter-chunker.js +8 -234
- package/packages/cli/dist/commands/analyze.js +3 -112
- package/packages/cli/dist/commands/context-cmds.js +1 -155
- package/packages/cli/dist/commands/environment.js +2 -204
- package/packages/cli/dist/commands/execution.js +1 -137
- package/packages/cli/dist/commands/graph.js +7 -81
- package/packages/cli/dist/commands/init.js +9 -87
- package/packages/cli/dist/commands/knowledge.js +1 -139
- package/packages/cli/dist/commands/search.js +8 -267
- package/packages/cli/dist/commands/system.js +4 -241
- package/packages/cli/dist/commands/workspace.js +2 -388
- package/packages/cli/dist/context.js +1 -14
- package/packages/cli/dist/helpers.js +3 -458
- package/packages/cli/dist/index.js +3 -69
- package/packages/cli/dist/kb-init.js +1 -82
- package/packages/cli/dist/types.js +0 -1
- package/packages/core/dist/constants.js +1 -43
- package/packages/core/dist/content-detector.js +1 -79
- package/packages/core/dist/errors.js +1 -40
- package/packages/core/dist/index.js +1 -9
- package/packages/core/dist/logger.js +1 -34
- package/packages/core/dist/types.js +0 -1
- package/packages/embeddings/dist/embedder.interface.js +0 -1
- package/packages/embeddings/dist/index.js +1 -5
- package/packages/embeddings/dist/onnx-embedder.js +1 -82
- package/packages/indexer/dist/file-hasher.js +1 -13
- package/packages/indexer/dist/filesystem-crawler.js +1 -125
- package/packages/indexer/dist/graph-extractor.js +1 -111
- package/packages/indexer/dist/incremental-indexer.js +1 -278
- package/packages/indexer/dist/index.js +1 -14
- package/packages/server/dist/api.js +1 -9
- package/packages/server/dist/config.js +1 -75
- package/packages/server/dist/curated-manager.js +9 -356
- package/packages/server/dist/index.js +1 -134
- package/packages/server/dist/replay-interceptor.js +1 -38
- package/packages/server/dist/resources/resources.js +2 -40
- package/packages/server/dist/server.js +1 -247
- package/packages/server/dist/tools/analyze.tools.js +1 -288
- package/packages/server/dist/tools/forge.tools.js +11 -499
- package/packages/server/dist/tools/forget.tool.js +3 -39
- package/packages/server/dist/tools/graph.tool.js +5 -110
- package/packages/server/dist/tools/list.tool.js +5 -53
- package/packages/server/dist/tools/lookup.tool.js +8 -51
- package/packages/server/dist/tools/onboard.tool.js +2 -112
- package/packages/server/dist/tools/produce.tool.js +4 -74
- package/packages/server/dist/tools/read.tool.js +4 -47
- package/packages/server/dist/tools/reindex.tool.js +2 -70
- package/packages/server/dist/tools/remember.tool.js +3 -42
- package/packages/server/dist/tools/replay.tool.js +6 -88
- package/packages/server/dist/tools/search.tool.js +17 -327
- package/packages/server/dist/tools/status.tool.js +3 -68
- package/packages/server/dist/tools/toolkit.tools.js +20 -1673
- package/packages/server/dist/tools/update.tool.js +3 -39
- package/packages/server/dist/tools/utility.tools.js +19 -456
- package/packages/store/dist/graph-store.interface.js +0 -1
- package/packages/store/dist/index.js +1 -9
- package/packages/store/dist/lance-store.js +1 -258
- package/packages/store/dist/sqlite-graph-store.js +8 -309
- package/packages/store/dist/store-factory.js +1 -14
- package/packages/store/dist/store.interface.js +0 -1
- package/packages/tools/dist/batch.js +1 -45
- package/packages/tools/dist/changelog.js +2 -112
- package/packages/tools/dist/check.js +2 -59
- package/packages/tools/dist/checkpoint.js +2 -43
- package/packages/tools/dist/codemod.js +2 -69
- package/packages/tools/dist/compact.js +3 -60
- package/packages/tools/dist/data-transform.js +1 -124
- package/packages/tools/dist/dead-symbols.js +2 -71
- package/packages/tools/dist/delegate.js +3 -128
- package/packages/tools/dist/diff-parse.js +3 -153
- package/packages/tools/dist/digest.js +7 -242
- package/packages/tools/dist/encode.js +1 -46
- package/packages/tools/dist/env-info.js +1 -58
- package/packages/tools/dist/eval.js +3 -79
- package/packages/tools/dist/evidence-map.js +3 -203
- package/packages/tools/dist/file-summary.js +2 -106
- package/packages/tools/dist/file-walk.js +1 -75
- package/packages/tools/dist/find-examples.js +3 -48
- package/packages/tools/dist/find.js +1 -120
- package/packages/tools/dist/forge-classify.js +2 -319
- package/packages/tools/dist/forge-ground.js +1 -184
- package/packages/tools/dist/git-context.js +3 -46
- package/packages/tools/dist/graph-query.js +1 -194
- package/packages/tools/dist/health.js +1 -118
- package/packages/tools/dist/http-request.js +1 -58
- package/packages/tools/dist/index.js +1 -273
- package/packages/tools/dist/lane.js +7 -227
- package/packages/tools/dist/measure.js +2 -119
- package/packages/tools/dist/onboard.js +42 -1136
- package/packages/tools/dist/parse-output.js +2 -158
- package/packages/tools/dist/process-manager.js +1 -69
- package/packages/tools/dist/queue.js +2 -126
- package/packages/tools/dist/regex-test.js +1 -39
- package/packages/tools/dist/rename.js +2 -70
- package/packages/tools/dist/replay.js +6 -108
- package/packages/tools/dist/schema-validate.js +1 -141
- package/packages/tools/dist/scope-map.js +1 -72
- package/packages/tools/dist/snippet.js +1 -80
- package/packages/tools/dist/stash.js +2 -60
- package/packages/tools/dist/stratum-card.js +5 -238
- package/packages/tools/dist/symbol.js +3 -87
- package/packages/tools/dist/test-run.js +2 -55
- package/packages/tools/dist/text-utils.js +2 -31
- package/packages/tools/dist/time-utils.js +1 -135
- package/packages/tools/dist/trace.js +2 -114
- package/packages/tools/dist/truncation.js +10 -41
- package/packages/tools/dist/watch.js +1 -61
- package/packages/tools/dist/web-fetch.js +9 -244
- package/packages/tools/dist/web-search.js +1 -46
- package/packages/tools/dist/workset.js +2 -77
- package/packages/tui/dist/App.js +260 -52468
- package/packages/tui/dist/index.js +286 -54551
- package/packages/tui/dist/panels/CuratedPanel.js +211 -34291
- package/packages/tui/dist/panels/LogPanel.js +259 -51703
- package/packages/tui/dist/panels/SearchPanel.js +212 -34824
- package/packages/tui/dist/panels/StatusPanel.js +211 -34304
|
@@ -1,86 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
structureAnalyzer = new StructureAnalyzer();
|
|
6
|
-
dependencyAnalyzer = new DependencyAnalyzer();
|
|
7
|
-
async analyze(rootPath, options = {}) {
|
|
8
|
-
const { diagramType = "architecture" } = options;
|
|
9
|
-
const startTime = Date.now();
|
|
10
|
-
let output;
|
|
11
|
-
switch (diagramType) {
|
|
12
|
-
case "dependencies":
|
|
13
|
-
output = await this.generateDependencyDiagram(rootPath);
|
|
14
|
-
break;
|
|
15
|
-
default:
|
|
16
|
-
output = await this.generateArchitectureDiagram(rootPath);
|
|
17
|
-
break;
|
|
18
|
-
}
|
|
19
|
-
return {
|
|
20
|
-
output,
|
|
21
|
-
data: { diagramType },
|
|
22
|
-
meta: {
|
|
23
|
-
analyzedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
24
|
-
scope: rootPath,
|
|
25
|
-
fileCount: 0,
|
|
26
|
-
durationMs: Date.now() - startTime
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
async generateArchitectureDiagram(rootPath) {
|
|
31
|
-
const structResult = await this.structureAnalyzer.analyze(rootPath, {
|
|
32
|
-
format: "json",
|
|
33
|
-
maxDepth: 4
|
|
34
|
-
});
|
|
35
|
-
const tree = structResult.data.tree;
|
|
36
|
-
const depResult = await this.dependencyAnalyzer.analyze(rootPath, { format: "json" });
|
|
37
|
-
const depData = depResult.data;
|
|
38
|
-
const lines = ["```mermaid", "graph TB"];
|
|
39
|
-
const topDirs = (tree.children ?? []).filter((c) => c.type === "directory").slice(0, 15);
|
|
40
|
-
for (const dir of topDirs) {
|
|
41
|
-
const id = dir.name.replace(/[^a-zA-Z0-9]/g, "_");
|
|
42
|
-
const subDirs = (dir.children ?? []).filter((c) => c.type === "directory");
|
|
43
|
-
if (subDirs.length > 0) {
|
|
44
|
-
lines.push(` subgraph ${id}["${dir.name}/"]`);
|
|
45
|
-
for (const sub of subDirs.slice(0, 12)) {
|
|
46
|
-
const subId = `${id}_${sub.name.replace(/[^a-zA-Z0-9]/g, "_")}`;
|
|
47
|
-
const fileCount = Array.isArray(sub.children) ? sub.children.length : 0;
|
|
48
|
-
lines.push(` ${subId}["${sub.name}/ (${fileCount})"]`);
|
|
49
|
-
}
|
|
50
|
-
lines.push(" end");
|
|
51
|
-
} else {
|
|
52
|
-
const childCount = Array.isArray(dir.children) ? dir.children.length : 0;
|
|
53
|
-
lines.push(` ${id}["${dir.name}/ (${childCount} files)"]`);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
const addedEdges = /* @__PURE__ */ new Set();
|
|
57
|
-
if (depData.internal) {
|
|
58
|
-
for (const [file, imports] of Object.entries(depData.internal)) {
|
|
59
|
-
const fromDir = file.split("/")[0]?.replace(/[^a-zA-Z0-9]/g, "_");
|
|
60
|
-
for (const imp of imports) {
|
|
61
|
-
if (imp.startsWith(".")) continue;
|
|
62
|
-
const toDir = imp.split("/")[0]?.replace(/[^a-zA-Z0-9]/g, "_");
|
|
63
|
-
if (fromDir && toDir && fromDir !== toDir) {
|
|
64
|
-
const edgeKey = `${fromDir}->${toDir}`;
|
|
65
|
-
if (!addedEdges.has(edgeKey)) {
|
|
66
|
-
addedEdges.add(edgeKey);
|
|
67
|
-
lines.push(` ${fromDir} --> ${toDir}`);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
lines.push("```");
|
|
74
|
-
return lines.join("\n");
|
|
75
|
-
}
|
|
76
|
-
async generateDependencyDiagram(rootPath) {
|
|
77
|
-
const depResult = await this.dependencyAnalyzer.analyze(rootPath, { format: "mermaid" });
|
|
78
|
-
return `\`\`\`mermaid
|
|
79
|
-
${depResult.output}
|
|
80
|
-
\`\`\``;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
export {
|
|
84
|
-
DiagramGenerator
|
|
85
|
-
};
|
|
86
|
-
//# sourceMappingURL=diagram-generator.js.map
|
|
1
|
+
import{DependencyAnalyzer as u}from"./dependency-analyzer.js";import{StructureAnalyzer as g}from"./structure-analyzer.js";class D{name="diagrams";structureAnalyzer=new g;dependencyAnalyzer=new u;async analyze(r,d={}){const{diagramType:o="architecture"}=d,p=Date.now();let s;return o==="dependencies"?s=await this.generateDependencyDiagram(r):s=await this.generateArchitectureDiagram(r),{output:s,data:{diagramType:o},meta:{analyzedAt:new Date().toISOString(),scope:r,fileCount:0,durationMs:Date.now()-p}}}async generateArchitectureDiagram(r){const o=(await this.structureAnalyzer.analyze(r,{format:"json",maxDepth:4})).data.tree,s=(await this.dependencyAnalyzer.analyze(r,{format:"json"})).data,n=["```mermaid","graph TB"],y=(o.children??[]).filter(t=>t.type==="directory").slice(0,15);for(const t of y){const c=t.name.replace(/[^a-zA-Z0-9]/g,"_"),a=(t.children??[]).filter(e=>e.type==="directory");if(a.length>0){n.push(` subgraph ${c}["${t.name}/"]`);for(const e of a.slice(0,12)){const i=`${c}_${e.name.replace(/[^a-zA-Z0-9]/g,"_")}`,l=Array.isArray(e.children)?e.children.length:0;n.push(` ${i}["${e.name}/ (${l})"]`)}n.push(" end")}else{const e=Array.isArray(t.children)?t.children.length:0;n.push(` ${c}["${t.name}/ (${e} files)"]`)}}const m=new Set;if(s.internal)for(const[t,c]of Object.entries(s.internal)){const a=t.split("/")[0]?.replace(/[^a-zA-Z0-9]/g,"_");for(const e of c){if(e.startsWith("."))continue;const i=e.split("/")[0]?.replace(/[^a-zA-Z0-9]/g,"_");if(a&&i&&a!==i){const l=`${a}->${i}`;m.has(l)||(m.add(l),n.push(` ${a} --> ${i}`))}}}return n.push("```"),n.join(`
|
|
2
|
+
`)}async generateDependencyDiagram(r){return`\`\`\`mermaid
|
|
3
|
+
${(await this.dependencyAnalyzer.analyze(r,{format:"mermaid"})).output}
|
|
4
|
+
\`\`\``}}export{D as DiagramGenerator};
|
|
@@ -1,239 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
"dist",
|
|
7
|
-
"build",
|
|
8
|
-
"coverage",
|
|
9
|
-
".turbo",
|
|
10
|
-
".cache",
|
|
11
|
-
"cdk.out",
|
|
12
|
-
"__pycache__",
|
|
13
|
-
".venv",
|
|
14
|
-
"target",
|
|
15
|
-
"bin",
|
|
16
|
-
"obj",
|
|
17
|
-
".gradle",
|
|
18
|
-
"venv",
|
|
19
|
-
"env"
|
|
20
|
-
]);
|
|
21
|
-
const TEST_DIR_SEGMENTS = /* @__PURE__ */ new Set(["test", "tests", "__tests__", "spec", "specs", "test-utils"]);
|
|
22
|
-
const HANDLER_PATTERNS = [
|
|
23
|
-
// ── JS/TS ──
|
|
24
|
-
// Lambda: export const handler = ... (with optional type annotation)
|
|
25
|
-
/export\s+const\s+(handler|main)\s*(?::[^=]*)?\s*=/,
|
|
26
|
-
// Lambda: export async function handler
|
|
27
|
-
/export\s+(?:async\s+)?function\s+(handler|main)\s*\(/,
|
|
28
|
-
// Named handler exports: export const emailHandler = ... (with optional type annotation)
|
|
29
|
-
/export\s+const\s+(\w+Handler)\s*(?::[^=]*)?\s*=/,
|
|
30
|
-
// Express/Hono app: export default app
|
|
31
|
-
/export\s+default\s+app/,
|
|
32
|
-
// ── Python ──
|
|
33
|
-
// Flask/FastAPI app
|
|
34
|
-
/^app\s*=\s*(?:Flask|FastAPI)\s*\(/m,
|
|
35
|
-
// Django: urlpatterns
|
|
36
|
-
/^urlpatterns\s*=\s*\[/m,
|
|
37
|
-
// Python main guard
|
|
38
|
-
/^if\s+__name__\s*==\s*['"]__main__['"]:/m,
|
|
39
|
-
// ── Java ──
|
|
40
|
-
// Spring Boot main class
|
|
41
|
-
/public\s+static\s+void\s+main\s*\(\s*String/,
|
|
42
|
-
// Spring Boot Application annotation
|
|
43
|
-
/@SpringBootApplication/,
|
|
44
|
-
// ── Go ──
|
|
45
|
-
/^func\s+main\s*\(\s*\)/m
|
|
46
|
-
];
|
|
47
|
-
const TRIGGER_PATTERNS = [
|
|
48
|
-
{ regex: /SqsEventSource|SQSEvent|sqs/i, trigger: "SQS" },
|
|
49
|
-
{ regex: /SnsEventSource|SNSEvent|sns/i, trigger: "SNS" },
|
|
50
|
-
{ regex: /ApiGateway|APIGatewayEvent|httpApi|restApi/i, trigger: "API Gateway" },
|
|
51
|
-
{ regex: /ScheduleExpression|EventBridgeRule|schedule/i, trigger: "EventBridge Schedule" },
|
|
52
|
-
{ regex: /S3EventSource|S3Event|s3/i, trigger: "S3" },
|
|
53
|
-
{ regex: /DynamoEventSource|DynamoDBStream/i, trigger: "DynamoDB Stream" },
|
|
54
|
-
// Multi-language triggers
|
|
55
|
-
{ regex: /@RequestMapping|@GetMapping|@PostMapping/i, trigger: "HTTP Endpoint" },
|
|
56
|
-
{ regex: /http\.ListenAndServe|gin\.Default|echo\.New/i, trigger: "HTTP Server" },
|
|
57
|
-
{ regex: /app\.route\(|@app\.get|@app\.post|@router\./i, trigger: "HTTP Route" }
|
|
58
|
-
];
|
|
59
|
-
class EntryPointAnalyzer {
|
|
60
|
-
name = "entry-points";
|
|
61
|
-
async analyze(rootPath, _options = {}) {
|
|
62
|
-
const startTime = Date.now();
|
|
63
|
-
const entryPoints = [];
|
|
64
|
-
const pkgEntries = await this.fromPackageJson(rootPath);
|
|
65
|
-
entryPoints.push(...pkgEntries);
|
|
66
|
-
const handlerEntries = await this.fromHandlerExports(rootPath);
|
|
67
|
-
entryPoints.push(...handlerEntries);
|
|
68
|
-
const output = this.formatMarkdown(entryPoints, rootPath);
|
|
69
|
-
return {
|
|
70
|
-
output,
|
|
71
|
-
data: { entryPoints, total: entryPoints.length },
|
|
72
|
-
meta: {
|
|
73
|
-
analyzedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
74
|
-
scope: rootPath,
|
|
75
|
-
fileCount: entryPoints.length,
|
|
76
|
-
durationMs: Date.now() - startTime
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
async fromPackageJson(rootPath) {
|
|
81
|
-
const entries = [];
|
|
82
|
-
try {
|
|
83
|
-
const pkgPath = join(rootPath, "package.json");
|
|
84
|
-
await access(pkgPath);
|
|
85
|
-
const pkg = JSON.parse(await readFile(pkgPath, "utf-8"));
|
|
86
|
-
if (pkg.main) {
|
|
87
|
-
entries.push({
|
|
88
|
-
name: "main",
|
|
89
|
-
type: "main",
|
|
90
|
-
filePath: pkg.main
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
if (pkg.bin) {
|
|
94
|
-
const bins = typeof pkg.bin === "string" ? { [pkg.name ?? "cli"]: pkg.bin } : pkg.bin;
|
|
95
|
-
for (const [name, path] of Object.entries(bins)) {
|
|
96
|
-
entries.push({ name, type: "cli", filePath: path });
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
if (pkg.scripts?.start) {
|
|
100
|
-
entries.push({
|
|
101
|
-
name: "start",
|
|
102
|
-
type: "server",
|
|
103
|
-
filePath: pkg.scripts.start,
|
|
104
|
-
trigger: "npm start"
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
} catch {
|
|
108
|
-
}
|
|
109
|
-
return entries;
|
|
110
|
-
}
|
|
111
|
-
async fromHandlerExports(rootPath) {
|
|
112
|
-
const entries = [];
|
|
113
|
-
const files = await this.collectFiles(rootPath);
|
|
114
|
-
for (const filePath of files) {
|
|
115
|
-
try {
|
|
116
|
-
const content = await readFile(filePath, "utf-8");
|
|
117
|
-
const relPath = relative(rootPath, filePath).replace(/\\/g, "/");
|
|
118
|
-
const pathSegments = relPath.split("/");
|
|
119
|
-
if (pathSegments.some((seg) => TEST_DIR_SEGMENTS.has(seg))) continue;
|
|
120
|
-
for (const pattern of HANDLER_PATTERNS) {
|
|
121
|
-
const match = content.match(pattern);
|
|
122
|
-
if (match) {
|
|
123
|
-
let name = match[1] ?? this.inferNameFromFile(relPath);
|
|
124
|
-
if (name === "handler" || name === "main") {
|
|
125
|
-
name = this.deriveContextualName(relPath) ?? name;
|
|
126
|
-
}
|
|
127
|
-
const isSpringBoot = /@SpringBootApplication/.test(content);
|
|
128
|
-
const trigger = isSpringBoot ? "HTTP Server" : this.detectTrigger(content);
|
|
129
|
-
entries.push({
|
|
130
|
-
name,
|
|
131
|
-
type: this.inferEntryType(match[1] ?? name, relPath),
|
|
132
|
-
filePath: relPath,
|
|
133
|
-
trigger
|
|
134
|
-
});
|
|
135
|
-
break;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
} catch {
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
return entries;
|
|
142
|
-
}
|
|
143
|
-
/** Extract a meaningful name from the file path for non-JS entry points */
|
|
144
|
-
inferNameFromFile(relPath) {
|
|
145
|
-
const base = relPath.split(/[/\\]/).pop() ?? "default";
|
|
146
|
-
return base.replace(/\.\w+$/, "");
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Derive a contextual name from the directory path for generic handler/main files.
|
|
150
|
-
* E.g., "services/channels/email/delivery/src/handler.ts" → "email-delivery"
|
|
151
|
-
*/
|
|
152
|
-
deriveContextualName(relPath) {
|
|
153
|
-
const parts = relPath.split("/").filter((p) => p !== "src" && p !== "lib");
|
|
154
|
-
parts.pop();
|
|
155
|
-
if (parts.length === 0) return void 0;
|
|
156
|
-
const meaningful = parts.filter(
|
|
157
|
-
(p) => !["services", "functions", "lambdas", "handlers", "packages", "apps"].includes(p)
|
|
158
|
-
);
|
|
159
|
-
if (meaningful.length === 0) return void 0;
|
|
160
|
-
const last = meaningful.slice(-2);
|
|
161
|
-
if (last.length === 2 && last[1].startsWith(last[0])) {
|
|
162
|
-
return last[1];
|
|
163
|
-
}
|
|
164
|
-
return last.join("-");
|
|
165
|
-
}
|
|
166
|
-
inferEntryType(name, relPath) {
|
|
167
|
-
if (name === "handler" || name === "main") return "lambda-handler";
|
|
168
|
-
if (relPath.includes("handler")) return "lambda-handler";
|
|
169
|
-
if (/functions[/]/.test(relPath)) return "lambda-handler";
|
|
170
|
-
if (name.endsWith("Handler")) return "lambda-handler";
|
|
171
|
-
if (relPath.endsWith(".py") || relPath.endsWith(".go") || relPath.endsWith(".java")) {
|
|
172
|
-
return "main";
|
|
173
|
-
}
|
|
174
|
-
return "main";
|
|
175
|
-
}
|
|
176
|
-
detectTrigger(content) {
|
|
177
|
-
for (const tp of TRIGGER_PATTERNS) {
|
|
178
|
-
if (tp.regex.test(content)) return tp.trigger;
|
|
179
|
-
}
|
|
180
|
-
return void 0;
|
|
181
|
-
}
|
|
182
|
-
async collectFiles(rootPath) {
|
|
183
|
-
const files = [];
|
|
184
|
-
const codeExts = /* @__PURE__ */ new Set([
|
|
185
|
-
".ts",
|
|
186
|
-
".tsx",
|
|
187
|
-
".js",
|
|
188
|
-
".jsx",
|
|
189
|
-
".java",
|
|
190
|
-
".py",
|
|
191
|
-
".go",
|
|
192
|
-
".cs",
|
|
193
|
-
".kt",
|
|
194
|
-
".rb",
|
|
195
|
-
".rs",
|
|
196
|
-
".php",
|
|
197
|
-
".swift"
|
|
198
|
-
]);
|
|
199
|
-
const walk = async (dir, depth) => {
|
|
200
|
-
if (depth > 10) return;
|
|
201
|
-
const entries = await readdir(dir, { withFileTypes: true });
|
|
202
|
-
for (const entry of entries) {
|
|
203
|
-
if (DEFAULT_EXCLUDES.has(entry.name)) continue;
|
|
204
|
-
if (entry.name.startsWith(".")) continue;
|
|
205
|
-
const fullPath = join(dir, entry.name);
|
|
206
|
-
if (entry.isDirectory()) {
|
|
207
|
-
await walk(fullPath, depth + 1);
|
|
208
|
-
} else if (codeExts.has(extname(entry.name))) {
|
|
209
|
-
files.push(fullPath);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
};
|
|
213
|
-
await walk(rootPath, 0);
|
|
214
|
-
return files;
|
|
215
|
-
}
|
|
216
|
-
formatMarkdown(entryPoints, rootPath) {
|
|
217
|
-
const lines = [];
|
|
218
|
-
lines.push(`## Entry Points: ${rootPath}
|
|
219
|
-
`);
|
|
220
|
-
lines.push(
|
|
221
|
-
`**${entryPoints.length} entry ${entryPoints.length === 1 ? "point" : "points"}** found
|
|
222
|
-
`
|
|
223
|
-
);
|
|
224
|
-
if (entryPoints.length === 0) {
|
|
225
|
-
lines.push("No entry points detected.");
|
|
226
|
-
return lines.join("\n");
|
|
227
|
-
}
|
|
228
|
-
lines.push("| Name | Type | File | Trigger |");
|
|
229
|
-
lines.push("|------|------|------|---------|");
|
|
230
|
-
for (const ep of entryPoints) {
|
|
231
|
-
lines.push(`| ${ep.name} | ${ep.type} | ${ep.filePath} | ${ep.trigger ?? "\u2014"} |`);
|
|
232
|
-
}
|
|
233
|
-
return lines.join("\n");
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
export {
|
|
237
|
-
EntryPointAnalyzer
|
|
238
|
-
};
|
|
239
|
-
//# sourceMappingURL=entry-point-analyzer.js.map
|
|
1
|
+
import{access as f,readdir as m,readFile as g}from"node:fs/promises";import{extname as d,join as l,relative as h}from"node:path";const y=new Set(["node_modules",".git","dist","build","coverage",".turbo",".cache","cdk.out","__pycache__",".venv","target","bin","obj",".gradle","venv","env"]),S=new Set(["test","tests","__tests__","spec","specs","test-utils"]),E=[/export\s+const\s+(handler|main)\s*(?::[^=]*)?\s*=/,/export\s+(?:async\s+)?function\s+(handler|main)\s*\(/,/export\s+const\s+(\w+Handler)\s*(?::[^=]*)?\s*=/,/export\s+default\s+app/,/^app\s*=\s*(?:Flask|FastAPI)\s*\(/m,/^urlpatterns\s*=\s*\[/m,/^if\s+__name__\s*==\s*['"]__main__['"]:/m,/public\s+static\s+void\s+main\s*\(\s*String/,/@SpringBootApplication/,/^func\s+main\s*\(\s*\)/m],v=[{regex:/SqsEventSource|SQSEvent|sqs/i,trigger:"SQS"},{regex:/SnsEventSource|SNSEvent|sns/i,trigger:"SNS"},{regex:/ApiGateway|APIGatewayEvent|httpApi|restApi/i,trigger:"API Gateway"},{regex:/ScheduleExpression|EventBridgeRule|schedule/i,trigger:"EventBridge Schedule"},{regex:/S3EventSource|S3Event|s3/i,trigger:"S3"},{regex:/DynamoEventSource|DynamoDBStream/i,trigger:"DynamoDB Stream"},{regex:/@RequestMapping|@GetMapping|@PostMapping/i,trigger:"HTTP Endpoint"},{regex:/http\.ListenAndServe|gin\.Default|echo\.New/i,trigger:"HTTP Server"},{regex:/app\.route\(|@app\.get|@app\.post|@router\./i,trigger:"HTTP Route"}];class A{name="entry-points";async analyze(n,e={}){const r=Date.now(),t=[],s=await this.fromPackageJson(n);t.push(...s);const i=await this.fromHandlerExports(n);return t.push(...i),{output:this.formatMarkdown(t,n),data:{entryPoints:t,total:t.length},meta:{analyzedAt:new Date().toISOString(),scope:n,fileCount:t.length,durationMs:Date.now()-r}}}async fromPackageJson(n){const e=[];try{const r=l(n,"package.json");await f(r);const t=JSON.parse(await g(r,"utf-8"));if(t.main&&e.push({name:"main",type:"main",filePath:t.main}),t.bin){const s=typeof t.bin=="string"?{[t.name??"cli"]:t.bin}:t.bin;for(const[i,c]of Object.entries(s))e.push({name:i,type:"cli",filePath:c})}t.scripts?.start&&e.push({name:"start",type:"server",filePath:t.scripts.start,trigger:"npm start"})}catch{}return e}async fromHandlerExports(n){const e=[],r=await this.collectFiles(n);for(const t of r)try{const s=await g(t,"utf-8"),i=h(n,t).replace(/\\/g,"/");if(i.split("/").some(a=>S.has(a)))continue;for(const a of E){const o=s.match(a);if(o){let p=o[1]??this.inferNameFromFile(i);(p==="handler"||p==="main")&&(p=this.deriveContextualName(i)??p);const u=/@SpringBootApplication/.test(s)?"HTTP Server":this.detectTrigger(s);e.push({name:p,type:this.inferEntryType(o[1]??p,i),filePath:i,trigger:u});break}}}catch{}return e}inferNameFromFile(n){return(n.split(/[/\\]/).pop()??"default").replace(/\.\w+$/,"")}deriveContextualName(n){const e=n.split("/").filter(s=>s!=="src"&&s!=="lib");if(e.pop(),e.length===0)return;const r=e.filter(s=>!["services","functions","lambdas","handlers","packages","apps"].includes(s));if(r.length===0)return;const t=r.slice(-2);return t.length===2&&t[1].startsWith(t[0])?t[1]:t.join("-")}inferEntryType(n,e){return n==="handler"||n==="main"||e.includes("handler")||/functions[/]/.test(e)||n.endsWith("Handler")?"lambda-handler":(e.endsWith(".py")||e.endsWith(".go")||e.endsWith(".java"),"main")}detectTrigger(n){for(const e of v)if(e.regex.test(n))return e.trigger}async collectFiles(n){const e=[],r=new Set([".ts",".tsx",".js",".jsx",".java",".py",".go",".cs",".kt",".rb",".rs",".php",".swift"]),t=async(s,i)=>{if(i>10)return;const c=await m(s,{withFileTypes:!0});for(const a of c){if(y.has(a.name)||a.name.startsWith("."))continue;const o=l(s,a.name);a.isDirectory()?await t(o,i+1):r.has(d(a.name))&&e.push(o)}};return await t(n,0),e}formatMarkdown(n,e){const r=[];if(r.push(`## Entry Points: ${e}
|
|
2
|
+
`),r.push(`**${n.length} entry ${n.length===1?"point":"points"}** found
|
|
3
|
+
`),n.length===0)return r.push("No entry points detected."),r.join(`
|
|
4
|
+
`);r.push("| Name | Type | File | Trigger |"),r.push("|------|------|------|---------|");for(const t of n)r.push(`| ${t.name} | ${t.type} | ${t.filePath} | ${t.trigger??"\u2014"} |`);return r.join(`
|
|
5
|
+
`)}}export{A as EntryPointAnalyzer};
|
|
@@ -1,23 +1 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { DependencyAnalyzer } from "./dependency-analyzer.js";
|
|
3
|
-
import { DiagramGenerator } from "./diagram-generator.js";
|
|
4
|
-
import { EntryPointAnalyzer } from "./entry-point-analyzer.js";
|
|
5
|
-
import { KnowledgeProducer } from "./knowledge-producer.js";
|
|
6
|
-
import { PatternAnalyzer } from "./pattern-analyzer.js";
|
|
7
|
-
import { extractRegexCallGraph } from "./regex-call-graph.js";
|
|
8
|
-
import { StructureAnalyzer } from "./structure-analyzer.js";
|
|
9
|
-
import { SymbolAnalyzer } from "./symbol-analyzer.js";
|
|
10
|
-
import { extractTsCallGraph } from "./ts-call-graph.js";
|
|
11
|
-
export {
|
|
12
|
-
BlastRadiusAnalyzer,
|
|
13
|
-
DependencyAnalyzer,
|
|
14
|
-
DiagramGenerator,
|
|
15
|
-
EntryPointAnalyzer,
|
|
16
|
-
KnowledgeProducer,
|
|
17
|
-
PatternAnalyzer,
|
|
18
|
-
StructureAnalyzer,
|
|
19
|
-
SymbolAnalyzer,
|
|
20
|
-
extractRegexCallGraph,
|
|
21
|
-
extractTsCallGraph
|
|
22
|
-
};
|
|
23
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
import{BlastRadiusAnalyzer as t}from"./blast-radius-analyzer.js";import{DependencyAnalyzer as n}from"./dependency-analyzer.js";import{DiagramGenerator as l}from"./diagram-generator.js";import{EntryPointAnalyzer as s}from"./entry-point-analyzer.js";import{KnowledgeProducer as m}from"./knowledge-producer.js";import{PatternAnalyzer as x}from"./pattern-analyzer.js";import{extractRegexCallGraph as z}from"./regex-call-graph.js";import{StructureAnalyzer as c}from"./structure-analyzer.js";import{SymbolAnalyzer as u}from"./symbol-analyzer.js";import{extractTsCallGraph as O}from"./ts-call-graph.js";export{t as BlastRadiusAnalyzer,n as DependencyAnalyzer,l as DiagramGenerator,s as EntryPointAnalyzer,m as KnowledgeProducer,x as PatternAnalyzer,c as StructureAnalyzer,u as SymbolAnalyzer,z as extractRegexCallGraph,O as extractTsCallGraph};
|
|
@@ -1,113 +1,24 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (!analyzer) continue;
|
|
26
|
-
if (aspect === "diagrams") {
|
|
27
|
-
promises.push({
|
|
28
|
-
key: "diagrams",
|
|
29
|
-
promise: analyzer.analyze(scope, { diagramType: "architecture" })
|
|
30
|
-
});
|
|
31
|
-
} else {
|
|
32
|
-
promises.push({
|
|
33
|
-
key: aspect,
|
|
34
|
-
promise: analyzer.analyze(scope)
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
const results = await Promise.allSettled(
|
|
39
|
-
promises.map(async (p) => ({ key: p.key, result: await p.promise }))
|
|
40
|
-
);
|
|
41
|
-
for (const settled of results) {
|
|
42
|
-
if (settled.status !== "fulfilled") continue;
|
|
43
|
-
const { key, result } = settled.value;
|
|
44
|
-
if (key === "diagrams") {
|
|
45
|
-
baselines.diagrams = [result];
|
|
46
|
-
} else {
|
|
47
|
-
baselines[key] = result;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
return baselines;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Build synthesis instructions from baselines for the LLM.
|
|
54
|
-
*/
|
|
55
|
-
buildSynthesisInstructions(baselines, _aspects) {
|
|
56
|
-
const sections = [];
|
|
57
|
-
sections.push("## Knowledge Production Results\n");
|
|
58
|
-
sections.push("### Extraction Baselines (auto-generated)\n");
|
|
59
|
-
if (baselines.structure) {
|
|
60
|
-
sections.push("#### File Structure\n");
|
|
61
|
-
sections.push(baselines.structure.output);
|
|
62
|
-
sections.push("");
|
|
63
|
-
}
|
|
64
|
-
if (baselines.dependencies) {
|
|
65
|
-
sections.push("#### Dependencies\n");
|
|
66
|
-
sections.push(baselines.dependencies.output);
|
|
67
|
-
sections.push("");
|
|
68
|
-
}
|
|
69
|
-
if (baselines.symbols) {
|
|
70
|
-
sections.push("#### Symbols\n");
|
|
71
|
-
sections.push(baselines.symbols.output);
|
|
72
|
-
sections.push("");
|
|
73
|
-
}
|
|
74
|
-
if (baselines.patterns) {
|
|
75
|
-
sections.push("#### Detected Patterns\n");
|
|
76
|
-
sections.push(baselines.patterns.output);
|
|
77
|
-
sections.push("");
|
|
78
|
-
}
|
|
79
|
-
if (baselines.entryPoints) {
|
|
80
|
-
sections.push("#### Entry Points\n");
|
|
81
|
-
sections.push(baselines.entryPoints.output);
|
|
82
|
-
sections.push("");
|
|
83
|
-
}
|
|
84
|
-
if (baselines.diagrams && baselines.diagrams.length > 0) {
|
|
85
|
-
sections.push("#### Architecture Diagram\n");
|
|
86
|
-
for (const d of baselines.diagrams) {
|
|
87
|
-
sections.push(d.output);
|
|
88
|
-
}
|
|
89
|
-
sections.push("");
|
|
90
|
-
}
|
|
91
|
-
sections.push("### Your Task: Synthesize Knowledge\n");
|
|
92
|
-
sections.push("Based on the baselines above and your reading of the source files, produce");
|
|
93
|
-
sections.push("the following knowledge documents using `kb_remember`:\n");
|
|
94
|
-
sections.push(
|
|
95
|
-
"1. **Domain Overview** (category: `architecture`)\n - What this service does, boundary with other services\n - Key entities and their lifecycle\n"
|
|
96
|
-
);
|
|
97
|
-
sections.push(
|
|
98
|
-
"2. **Architecture Summary** (category: `architecture`)\n - Layer structure, dependency flow\n - Key design decisions\n"
|
|
99
|
-
);
|
|
100
|
-
sections.push(
|
|
101
|
-
"3. **Pattern Usage** (category: `patterns`)\n - Which patterns are used and why\n - Where to find examples\n"
|
|
102
|
-
);
|
|
103
|
-
sections.push(
|
|
104
|
-
"4. **Conventions** (category: `conventions`)\n - Naming conventions observed\n - File organization rules\n - Testing patterns\n"
|
|
105
|
-
);
|
|
106
|
-
sections.push("Store each as a separate `kb_remember` call with descriptive titles.\n");
|
|
107
|
-
return sections.join("\n");
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
export {
|
|
111
|
-
KnowledgeProducer
|
|
112
|
-
};
|
|
113
|
-
//# sourceMappingURL=knowledge-producer.js.map
|
|
1
|
+
const u={structure:"structure",dependencies:"dependencies",symbols:"symbols",patterns:"patterns","entry-points":"entryPoints",diagrams:"diagrams"},p=Object.keys(u);class l{constructor(t){this.analyzers=t}async runExtraction(t,o){const e=o.includes("all")?p:o,s={},i=[];for(const r of e){const a=u[r];if(!a)continue;const n=this.analyzers[a];n&&(r==="diagrams"?i.push({key:"diagrams",promise:n.analyze(t,{diagramType:"architecture"})}):i.push({key:r,promise:n.analyze(t)}))}const c=await Promise.allSettled(i.map(async r=>({key:r.key,result:await r.promise})));for(const r of c){if(r.status!=="fulfilled")continue;const{key:a,result:n}=r.value;a==="diagrams"?s.diagrams=[n]:s[a]=n}return s}buildSynthesisInstructions(t,o){const e=[];if(e.push(`## Knowledge Production Results
|
|
2
|
+
`),e.push(`### Extraction Baselines (auto-generated)
|
|
3
|
+
`),t.structure&&(e.push(`#### File Structure
|
|
4
|
+
`),e.push(t.structure.output),e.push("")),t.dependencies&&(e.push(`#### Dependencies
|
|
5
|
+
`),e.push(t.dependencies.output),e.push("")),t.symbols&&(e.push(`#### Symbols
|
|
6
|
+
`),e.push(t.symbols.output),e.push("")),t.patterns&&(e.push(`#### Detected Patterns
|
|
7
|
+
`),e.push(t.patterns.output),e.push("")),t.entryPoints&&(e.push(`#### Entry Points
|
|
8
|
+
`),e.push(t.entryPoints.output),e.push("")),t.diagrams&&t.diagrams.length>0){e.push(`#### Architecture Diagram
|
|
9
|
+
`);for(const s of t.diagrams)e.push(s.output);e.push("")}return e.push(`### Your Task: Synthesize Knowledge
|
|
10
|
+
`),e.push("Based on the baselines above and your reading of the source files, produce"),e.push("the following knowledge documents using `kb_remember`:\n"),e.push(`1. **Domain Overview** (category: \`architecture\`)
|
|
11
|
+
- What this service does, boundary with other services
|
|
12
|
+
- Key entities and their lifecycle
|
|
13
|
+
`),e.push(`2. **Architecture Summary** (category: \`architecture\`)
|
|
14
|
+
- Layer structure, dependency flow
|
|
15
|
+
- Key design decisions
|
|
16
|
+
`),e.push(`3. **Pattern Usage** (category: \`patterns\`)
|
|
17
|
+
- Which patterns are used and why
|
|
18
|
+
- Where to find examples
|
|
19
|
+
`),e.push(`4. **Conventions** (category: \`conventions\`)
|
|
20
|
+
- Naming conventions observed
|
|
21
|
+
- File organization rules
|
|
22
|
+
- Testing patterns
|
|
23
|
+
`),e.push("Store each as a separate `kb_remember` call with descriptive titles.\n"),e.join(`
|
|
24
|
+
`)}}export{l as KnowledgeProducer};
|