spec-gen-cli 1.0.0
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/LICENSE +21 -0
- package/README.md +1078 -0
- package/dist/api/analyze.d.ts +17 -0
- package/dist/api/analyze.d.ts.map +1 -0
- package/dist/api/analyze.js +109 -0
- package/dist/api/analyze.js.map +1 -0
- package/dist/api/drift.d.ts +21 -0
- package/dist/api/drift.d.ts.map +1 -0
- package/dist/api/drift.js +145 -0
- package/dist/api/drift.js.map +1 -0
- package/dist/api/generate.d.ts +18 -0
- package/dist/api/generate.d.ts.map +1 -0
- package/dist/api/generate.js +251 -0
- package/dist/api/generate.js.map +1 -0
- package/dist/api/index.d.ts +39 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +32 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/init.d.ts +18 -0
- package/dist/api/init.d.ts.map +1 -0
- package/dist/api/init.js +82 -0
- package/dist/api/init.js.map +1 -0
- package/dist/api/run.d.ts +19 -0
- package/dist/api/run.d.ts.map +1 -0
- package/dist/api/run.js +291 -0
- package/dist/api/run.js.map +1 -0
- package/dist/api/specs.d.ts +49 -0
- package/dist/api/specs.d.ts.map +1 -0
- package/dist/api/specs.js +136 -0
- package/dist/api/specs.js.map +1 -0
- package/dist/api/types.d.ts +176 -0
- package/dist/api/types.d.ts.map +1 -0
- package/dist/api/types.js +9 -0
- package/dist/api/types.js.map +1 -0
- package/dist/api/verify.d.ts +20 -0
- package/dist/api/verify.d.ts.map +1 -0
- package/dist/api/verify.js +117 -0
- package/dist/api/verify.js.map +1 -0
- package/dist/cli/commands/analyze.d.ts +27 -0
- package/dist/cli/commands/analyze.d.ts.map +1 -0
- package/dist/cli/commands/analyze.js +485 -0
- package/dist/cli/commands/analyze.js.map +1 -0
- package/dist/cli/commands/drift.d.ts +9 -0
- package/dist/cli/commands/drift.d.ts.map +1 -0
- package/dist/cli/commands/drift.js +540 -0
- package/dist/cli/commands/drift.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +9 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/generate.js +633 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/cli/commands/init.d.ts +9 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +171 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/mcp.d.ts +638 -0
- package/dist/cli/commands/mcp.d.ts.map +1 -0
- package/dist/cli/commands/mcp.js +574 -0
- package/dist/cli/commands/mcp.js.map +1 -0
- package/dist/cli/commands/run.d.ts +24 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +546 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/verify.d.ts +9 -0
- package/dist/cli/commands/verify.d.ts.map +1 -0
- package/dist/cli/commands/verify.js +417 -0
- package/dist/cli/commands/verify.js.map +1 -0
- package/dist/cli/commands/view.d.ts +9 -0
- package/dist/cli/commands/view.d.ts.map +1 -0
- package/dist/cli/commands/view.js +511 -0
- package/dist/cli/commands/view.js.map +1 -0
- package/dist/cli/index.d.ts +9 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +83 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/analyzer/architecture-writer.d.ts +67 -0
- package/dist/core/analyzer/architecture-writer.d.ts.map +1 -0
- package/dist/core/analyzer/architecture-writer.js +209 -0
- package/dist/core/analyzer/architecture-writer.js.map +1 -0
- package/dist/core/analyzer/artifact-generator.d.ts +222 -0
- package/dist/core/analyzer/artifact-generator.d.ts.map +1 -0
- package/dist/core/analyzer/artifact-generator.js +726 -0
- package/dist/core/analyzer/artifact-generator.js.map +1 -0
- package/dist/core/analyzer/call-graph.d.ts +83 -0
- package/dist/core/analyzer/call-graph.d.ts.map +1 -0
- package/dist/core/analyzer/call-graph.js +827 -0
- package/dist/core/analyzer/call-graph.js.map +1 -0
- package/dist/core/analyzer/code-shaper.d.ts +33 -0
- package/dist/core/analyzer/code-shaper.d.ts.map +1 -0
- package/dist/core/analyzer/code-shaper.js +149 -0
- package/dist/core/analyzer/code-shaper.js.map +1 -0
- package/dist/core/analyzer/dependency-graph.d.ts +179 -0
- package/dist/core/analyzer/dependency-graph.d.ts.map +1 -0
- package/dist/core/analyzer/dependency-graph.js +574 -0
- package/dist/core/analyzer/dependency-graph.js.map +1 -0
- package/dist/core/analyzer/duplicate-detector.d.ts +52 -0
- package/dist/core/analyzer/duplicate-detector.d.ts.map +1 -0
- package/dist/core/analyzer/duplicate-detector.js +279 -0
- package/dist/core/analyzer/duplicate-detector.js.map +1 -0
- package/dist/core/analyzer/embedding-service.d.ts +50 -0
- package/dist/core/analyzer/embedding-service.d.ts.map +1 -0
- package/dist/core/analyzer/embedding-service.js +104 -0
- package/dist/core/analyzer/embedding-service.js.map +1 -0
- package/dist/core/analyzer/file-walker.d.ts +78 -0
- package/dist/core/analyzer/file-walker.d.ts.map +1 -0
- package/dist/core/analyzer/file-walker.js +531 -0
- package/dist/core/analyzer/file-walker.js.map +1 -0
- package/dist/core/analyzer/import-parser.d.ts +91 -0
- package/dist/core/analyzer/import-parser.d.ts.map +1 -0
- package/dist/core/analyzer/import-parser.js +720 -0
- package/dist/core/analyzer/import-parser.js.map +1 -0
- package/dist/core/analyzer/index.d.ts +10 -0
- package/dist/core/analyzer/index.d.ts.map +1 -0
- package/dist/core/analyzer/index.js +10 -0
- package/dist/core/analyzer/index.js.map +1 -0
- package/dist/core/analyzer/refactor-analyzer.d.ts +80 -0
- package/dist/core/analyzer/refactor-analyzer.d.ts.map +1 -0
- package/dist/core/analyzer/refactor-analyzer.js +339 -0
- package/dist/core/analyzer/refactor-analyzer.js.map +1 -0
- package/dist/core/analyzer/repository-mapper.d.ts +150 -0
- package/dist/core/analyzer/repository-mapper.d.ts.map +1 -0
- package/dist/core/analyzer/repository-mapper.js +731 -0
- package/dist/core/analyzer/repository-mapper.js.map +1 -0
- package/dist/core/analyzer/signature-extractor.d.ts +31 -0
- package/dist/core/analyzer/signature-extractor.d.ts.map +1 -0
- package/dist/core/analyzer/signature-extractor.js +387 -0
- package/dist/core/analyzer/signature-extractor.js.map +1 -0
- package/dist/core/analyzer/significance-scorer.d.ts +79 -0
- package/dist/core/analyzer/significance-scorer.d.ts.map +1 -0
- package/dist/core/analyzer/significance-scorer.js +407 -0
- package/dist/core/analyzer/significance-scorer.js.map +1 -0
- package/dist/core/analyzer/subgraph-extractor.d.ts +43 -0
- package/dist/core/analyzer/subgraph-extractor.d.ts.map +1 -0
- package/dist/core/analyzer/subgraph-extractor.js +129 -0
- package/dist/core/analyzer/subgraph-extractor.js.map +1 -0
- package/dist/core/analyzer/vector-index.d.ts +63 -0
- package/dist/core/analyzer/vector-index.d.ts.map +1 -0
- package/dist/core/analyzer/vector-index.js +169 -0
- package/dist/core/analyzer/vector-index.js.map +1 -0
- package/dist/core/drift/drift-detector.d.ts +102 -0
- package/dist/core/drift/drift-detector.d.ts.map +1 -0
- package/dist/core/drift/drift-detector.js +597 -0
- package/dist/core/drift/drift-detector.js.map +1 -0
- package/dist/core/drift/git-diff.d.ts +55 -0
- package/dist/core/drift/git-diff.d.ts.map +1 -0
- package/dist/core/drift/git-diff.js +356 -0
- package/dist/core/drift/git-diff.js.map +1 -0
- package/dist/core/drift/index.d.ts +12 -0
- package/dist/core/drift/index.d.ts.map +1 -0
- package/dist/core/drift/index.js +9 -0
- package/dist/core/drift/index.js.map +1 -0
- package/dist/core/drift/spec-mapper.d.ts +73 -0
- package/dist/core/drift/spec-mapper.d.ts.map +1 -0
- package/dist/core/drift/spec-mapper.js +353 -0
- package/dist/core/drift/spec-mapper.js.map +1 -0
- package/dist/core/generator/adr-generator.d.ts +32 -0
- package/dist/core/generator/adr-generator.d.ts.map +1 -0
- package/dist/core/generator/adr-generator.js +192 -0
- package/dist/core/generator/adr-generator.js.map +1 -0
- package/dist/core/generator/index.d.ts +9 -0
- package/dist/core/generator/index.d.ts.map +1 -0
- package/dist/core/generator/index.js +12 -0
- package/dist/core/generator/index.js.map +1 -0
- package/dist/core/generator/mapping-generator.d.ts +54 -0
- package/dist/core/generator/mapping-generator.d.ts.map +1 -0
- package/dist/core/generator/mapping-generator.js +239 -0
- package/dist/core/generator/mapping-generator.js.map +1 -0
- package/dist/core/generator/openspec-compat.d.ts +160 -0
- package/dist/core/generator/openspec-compat.d.ts.map +1 -0
- package/dist/core/generator/openspec-compat.js +523 -0
- package/dist/core/generator/openspec-compat.js.map +1 -0
- package/dist/core/generator/openspec-format-generator.d.ts +111 -0
- package/dist/core/generator/openspec-format-generator.d.ts.map +1 -0
- package/dist/core/generator/openspec-format-generator.js +817 -0
- package/dist/core/generator/openspec-format-generator.js.map +1 -0
- package/dist/core/generator/openspec-writer.d.ts +131 -0
- package/dist/core/generator/openspec-writer.d.ts.map +1 -0
- package/dist/core/generator/openspec-writer.js +379 -0
- package/dist/core/generator/openspec-writer.js.map +1 -0
- package/dist/core/generator/prompts.d.ts +35 -0
- package/dist/core/generator/prompts.d.ts.map +1 -0
- package/dist/core/generator/prompts.js +212 -0
- package/dist/core/generator/prompts.js.map +1 -0
- package/dist/core/generator/spec-pipeline.d.ts +94 -0
- package/dist/core/generator/spec-pipeline.d.ts.map +1 -0
- package/dist/core/generator/spec-pipeline.js +474 -0
- package/dist/core/generator/spec-pipeline.js.map +1 -0
- package/dist/core/generator/stages/stage1-survey.d.ts +19 -0
- package/dist/core/generator/stages/stage1-survey.d.ts.map +1 -0
- package/dist/core/generator/stages/stage1-survey.js +105 -0
- package/dist/core/generator/stages/stage1-survey.js.map +1 -0
- package/dist/core/generator/stages/stage2-entities.d.ts +11 -0
- package/dist/core/generator/stages/stage2-entities.d.ts.map +1 -0
- package/dist/core/generator/stages/stage2-entities.js +67 -0
- package/dist/core/generator/stages/stage2-entities.js.map +1 -0
- package/dist/core/generator/stages/stage3-services.d.ts +11 -0
- package/dist/core/generator/stages/stage3-services.d.ts.map +1 -0
- package/dist/core/generator/stages/stage3-services.js +75 -0
- package/dist/core/generator/stages/stage3-services.js.map +1 -0
- package/dist/core/generator/stages/stage4-api.d.ts +11 -0
- package/dist/core/generator/stages/stage4-api.d.ts.map +1 -0
- package/dist/core/generator/stages/stage4-api.js +65 -0
- package/dist/core/generator/stages/stage4-api.js.map +1 -0
- package/dist/core/generator/stages/stage5-architecture.d.ts +10 -0
- package/dist/core/generator/stages/stage5-architecture.d.ts.map +1 -0
- package/dist/core/generator/stages/stage5-architecture.js +62 -0
- package/dist/core/generator/stages/stage5-architecture.js.map +1 -0
- package/dist/core/generator/stages/stage6-adr.d.ts +8 -0
- package/dist/core/generator/stages/stage6-adr.d.ts.map +1 -0
- package/dist/core/generator/stages/stage6-adr.js +41 -0
- package/dist/core/generator/stages/stage6-adr.js.map +1 -0
- package/dist/core/services/chat-agent.d.ts +45 -0
- package/dist/core/services/chat-agent.d.ts.map +1 -0
- package/dist/core/services/chat-agent.js +310 -0
- package/dist/core/services/chat-agent.js.map +1 -0
- package/dist/core/services/chat-tools.d.ts +32 -0
- package/dist/core/services/chat-tools.d.ts.map +1 -0
- package/dist/core/services/chat-tools.js +270 -0
- package/dist/core/services/chat-tools.js.map +1 -0
- package/dist/core/services/config-manager.d.ts +61 -0
- package/dist/core/services/config-manager.d.ts.map +1 -0
- package/dist/core/services/config-manager.js +143 -0
- package/dist/core/services/config-manager.js.map +1 -0
- package/dist/core/services/gitignore-manager.d.ts +29 -0
- package/dist/core/services/gitignore-manager.d.ts.map +1 -0
- package/dist/core/services/gitignore-manager.js +106 -0
- package/dist/core/services/gitignore-manager.js.map +1 -0
- package/dist/core/services/index.d.ts +8 -0
- package/dist/core/services/index.d.ts.map +1 -0
- package/dist/core/services/index.js +8 -0
- package/dist/core/services/index.js.map +1 -0
- package/dist/core/services/llm-service.d.ts +336 -0
- package/dist/core/services/llm-service.d.ts.map +1 -0
- package/dist/core/services/llm-service.js +1155 -0
- package/dist/core/services/llm-service.js.map +1 -0
- package/dist/core/services/mcp-handlers/analysis.d.ts +42 -0
- package/dist/core/services/mcp-handlers/analysis.d.ts.map +1 -0
- package/dist/core/services/mcp-handlers/analysis.js +300 -0
- package/dist/core/services/mcp-handlers/analysis.js.map +1 -0
- package/dist/core/services/mcp-handlers/graph.d.ts +65 -0
- package/dist/core/services/mcp-handlers/graph.d.ts.map +1 -0
- package/dist/core/services/mcp-handlers/graph.js +509 -0
- package/dist/core/services/mcp-handlers/graph.js.map +1 -0
- package/dist/core/services/mcp-handlers/semantic.d.ts +38 -0
- package/dist/core/services/mcp-handlers/semantic.d.ts.map +1 -0
- package/dist/core/services/mcp-handlers/semantic.js +172 -0
- package/dist/core/services/mcp-handlers/semantic.js.map +1 -0
- package/dist/core/services/mcp-handlers/utils.d.ts +21 -0
- package/dist/core/services/mcp-handlers/utils.d.ts.map +1 -0
- package/dist/core/services/mcp-handlers/utils.js +62 -0
- package/dist/core/services/mcp-handlers/utils.js.map +1 -0
- package/dist/core/services/project-detector.d.ts +32 -0
- package/dist/core/services/project-detector.d.ts.map +1 -0
- package/dist/core/services/project-detector.js +111 -0
- package/dist/core/services/project-detector.js.map +1 -0
- package/dist/core/verifier/index.d.ts +5 -0
- package/dist/core/verifier/index.d.ts.map +1 -0
- package/dist/core/verifier/index.js +5 -0
- package/dist/core/verifier/index.js.map +1 -0
- package/dist/core/verifier/verification-engine.d.ts +226 -0
- package/dist/core/verifier/verification-engine.d.ts.map +1 -0
- package/dist/core/verifier/verification-engine.js +681 -0
- package/dist/core/verifier/verification-engine.js.map +1 -0
- package/dist/types/index.d.ts +252 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/pipeline.d.ts +148 -0
- package/dist/types/pipeline.d.ts.map +1 -0
- package/dist/types/pipeline.js +5 -0
- package/dist/types/pipeline.js.map +1 -0
- package/dist/utils/errors.d.ts +51 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +128 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/logger.d.ts +149 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +331 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/progress.d.ts +142 -0
- package/dist/utils/progress.d.ts.map +1 -0
- package/dist/utils/progress.js +280 -0
- package/dist/utils/progress.js.map +1 -0
- package/dist/utils/prompts.d.ts +53 -0
- package/dist/utils/prompts.d.ts.map +1 -0
- package/dist/utils/prompts.js +199 -0
- package/dist/utils/prompts.js.map +1 -0
- package/dist/utils/shutdown.d.ts +89 -0
- package/dist/utils/shutdown.d.ts.map +1 -0
- package/dist/utils/shutdown.js +237 -0
- package/dist/utils/shutdown.js.map +1 -0
- package/package.json +114 -0
- package/src/viewer/InteractiveGraphViewer.jsx +1486 -0
- package/src/viewer/app/index.html +17 -0
- package/src/viewer/app/main.jsx +13 -0
- package/src/viewer/components/ArchitectureView.jsx +177 -0
- package/src/viewer/components/ChatPanel.jsx +448 -0
- package/src/viewer/components/ClusterGraph.jsx +441 -0
- package/src/viewer/components/FilterBar.jsx +179 -0
- package/src/viewer/components/FlatGraph.jsx +275 -0
- package/src/viewer/components/MicroComponents.jsx +83 -0
- package/src/viewer/hooks/usePanZoom.js +79 -0
- package/src/viewer/utils/constants.js +47 -0
- package/src/viewer/utils/graph-helpers.js +291 -0
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File Significance Scorer
|
|
3
|
+
*
|
|
4
|
+
* Ranks files by their likely importance to understanding system architecture.
|
|
5
|
+
* This determines what gets sent to the LLM and what gets skipped.
|
|
6
|
+
*
|
|
7
|
+
* Scoring algorithm: 0-100 points per file
|
|
8
|
+
* - Name-based scoring: 0-30 points
|
|
9
|
+
* - Path-based scoring: 0-25 points
|
|
10
|
+
* - Structure-based scoring: 0-25 points
|
|
11
|
+
* - Connectivity scoring: 0-20 points
|
|
12
|
+
*/
|
|
13
|
+
import { readFile } from 'node:fs/promises';
|
|
14
|
+
import { basename } from 'node:path';
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// NAME-BASED SCORING (0-30 points)
|
|
17
|
+
// ============================================================================
|
|
18
|
+
const HIGH_VALUE_NAMES = {
|
|
19
|
+
// Schema/model files (+25)
|
|
20
|
+
schema: 25,
|
|
21
|
+
model: 25,
|
|
22
|
+
entity: 25,
|
|
23
|
+
types: 25,
|
|
24
|
+
interfaces: 25,
|
|
25
|
+
// Auth files (+25)
|
|
26
|
+
auth: 25,
|
|
27
|
+
authentication: 25,
|
|
28
|
+
authorization: 25,
|
|
29
|
+
// API files (+25)
|
|
30
|
+
api: 25,
|
|
31
|
+
routes: 25,
|
|
32
|
+
endpoints: 25,
|
|
33
|
+
controller: 25,
|
|
34
|
+
controllers: 25,
|
|
35
|
+
// Database files (+25)
|
|
36
|
+
database: 25,
|
|
37
|
+
db: 25,
|
|
38
|
+
repository: 25,
|
|
39
|
+
store: 25,
|
|
40
|
+
// Config files (+20)
|
|
41
|
+
config: 20,
|
|
42
|
+
configuration: 20,
|
|
43
|
+
settings: 20,
|
|
44
|
+
// Middleware (+20)
|
|
45
|
+
middleware: 20,
|
|
46
|
+
interceptor: 20,
|
|
47
|
+
guard: 20,
|
|
48
|
+
// Services (+15)
|
|
49
|
+
service: 15,
|
|
50
|
+
provider: 15,
|
|
51
|
+
manager: 15,
|
|
52
|
+
// Utilities (+5)
|
|
53
|
+
utils: 5,
|
|
54
|
+
util: 5,
|
|
55
|
+
helpers: 5,
|
|
56
|
+
helper: 5,
|
|
57
|
+
common: 5,
|
|
58
|
+
};
|
|
59
|
+
const NEGATIVE_NAMES = {
|
|
60
|
+
// Test files (-10)
|
|
61
|
+
test: -10,
|
|
62
|
+
spec: -10,
|
|
63
|
+
mock: -10,
|
|
64
|
+
stub: -10,
|
|
65
|
+
fake: -10,
|
|
66
|
+
// Fixtures (-10)
|
|
67
|
+
fixture: -10,
|
|
68
|
+
fixtures: -10,
|
|
69
|
+
snapshot: -10,
|
|
70
|
+
snapshots: -10,
|
|
71
|
+
// Examples (-5)
|
|
72
|
+
example: -5,
|
|
73
|
+
examples: -5,
|
|
74
|
+
sample: -5,
|
|
75
|
+
samples: -5,
|
|
76
|
+
demo: -5,
|
|
77
|
+
// Deprecated (-15)
|
|
78
|
+
backup: -15,
|
|
79
|
+
old: -15,
|
|
80
|
+
deprecated: -15,
|
|
81
|
+
legacy: -15,
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Calculate name-based score for a file
|
|
85
|
+
*/
|
|
86
|
+
function calculateNameScore(fileName, config) {
|
|
87
|
+
const nameLower = fileName.toLowerCase();
|
|
88
|
+
const nameWithoutExt = basename(nameLower, nameLower.substring(nameLower.lastIndexOf('.')));
|
|
89
|
+
let score = 0;
|
|
90
|
+
// Check high-value names
|
|
91
|
+
const highValueNames = { ...HIGH_VALUE_NAMES, ...config?.highValueNames };
|
|
92
|
+
for (const [pattern, points] of Object.entries(highValueNames)) {
|
|
93
|
+
if (nameWithoutExt.includes(pattern)) {
|
|
94
|
+
score = Math.max(score, points);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Check negative names
|
|
98
|
+
const negativeNames = { ...NEGATIVE_NAMES, ...config?.negativeNames };
|
|
99
|
+
for (const [pattern, points] of Object.entries(negativeNames)) {
|
|
100
|
+
if (nameWithoutExt.includes(pattern)) {
|
|
101
|
+
score += points; // Negative values
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Clamp to valid range
|
|
105
|
+
return Math.max(0, Math.min(30, score));
|
|
106
|
+
}
|
|
107
|
+
// ============================================================================
|
|
108
|
+
// PATH-BASED SCORING (0-25 points)
|
|
109
|
+
// ============================================================================
|
|
110
|
+
const HIGH_VALUE_PATHS = {
|
|
111
|
+
'src/': 10,
|
|
112
|
+
'lib/': 10,
|
|
113
|
+
'core/': 15,
|
|
114
|
+
'domain/': 15,
|
|
115
|
+
'models/': 15,
|
|
116
|
+
'api/': 15,
|
|
117
|
+
'routes/': 15,
|
|
118
|
+
'controllers/': 15,
|
|
119
|
+
'config/': 10,
|
|
120
|
+
'configs/': 10,
|
|
121
|
+
'services/': 10,
|
|
122
|
+
'schemas/': 15,
|
|
123
|
+
};
|
|
124
|
+
/**
|
|
125
|
+
* Calculate path-based score for a file
|
|
126
|
+
*/
|
|
127
|
+
function calculatePathScore(relativePath, depth, config) {
|
|
128
|
+
let score = 0;
|
|
129
|
+
// Root directory bonus
|
|
130
|
+
if (depth === 0) {
|
|
131
|
+
score += 15;
|
|
132
|
+
}
|
|
133
|
+
// Check high-value paths
|
|
134
|
+
const highValuePaths = { ...HIGH_VALUE_PATHS, ...config?.highValuePaths };
|
|
135
|
+
for (const [pattern, points] of Object.entries(highValuePaths)) {
|
|
136
|
+
if (relativePath.startsWith(pattern) || relativePath.includes('/' + pattern)) {
|
|
137
|
+
score = Math.max(score, points);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// Penalty for deeply nested files
|
|
141
|
+
if (depth > 5) {
|
|
142
|
+
score -= 10;
|
|
143
|
+
}
|
|
144
|
+
// Penalty for deeply nested utils/helpers
|
|
145
|
+
const pathLower = relativePath.toLowerCase();
|
|
146
|
+
if ((pathLower.includes('utils/') || pathLower.includes('helpers/')) && depth > 3) {
|
|
147
|
+
score -= 5;
|
|
148
|
+
}
|
|
149
|
+
// Clamp to valid range
|
|
150
|
+
return Math.max(0, Math.min(25, score));
|
|
151
|
+
}
|
|
152
|
+
// ============================================================================
|
|
153
|
+
// STRUCTURE-BASED SCORING (0-25 points)
|
|
154
|
+
// ============================================================================
|
|
155
|
+
/**
|
|
156
|
+
* Quick content analysis patterns
|
|
157
|
+
*/
|
|
158
|
+
const STRUCTURE_PATTERNS = {
|
|
159
|
+
hasClass: /\bclass\s+\w+/,
|
|
160
|
+
hasInterface: /\b(interface|type)\s+\w+\s*[={<]/,
|
|
161
|
+
hasExport: /\bexport\s+(default\s+)?(class|function|const|let|var|interface|type|enum)/,
|
|
162
|
+
hasDecorator: /@\w+\s*\(/,
|
|
163
|
+
importStatement: /\bimport\s+.*from\s+['"][^'"]+['"]/g,
|
|
164
|
+
};
|
|
165
|
+
/**
|
|
166
|
+
* Calculate structure-based score from file content
|
|
167
|
+
*/
|
|
168
|
+
async function calculateStructureScore(absolutePath, lines) {
|
|
169
|
+
let score = 0;
|
|
170
|
+
try {
|
|
171
|
+
const content = await readFile(absolutePath, 'utf-8');
|
|
172
|
+
// Has class definitions (+10)
|
|
173
|
+
if (STRUCTURE_PATTERNS.hasClass.test(content)) {
|
|
174
|
+
score += 10;
|
|
175
|
+
}
|
|
176
|
+
// Has interface/type definitions (+15)
|
|
177
|
+
if (STRUCTURE_PATTERNS.hasInterface.test(content)) {
|
|
178
|
+
score += 15;
|
|
179
|
+
}
|
|
180
|
+
// Has export statements (+5)
|
|
181
|
+
if (STRUCTURE_PATTERNS.hasExport.test(content)) {
|
|
182
|
+
score += 5;
|
|
183
|
+
}
|
|
184
|
+
// Has decorators (+15)
|
|
185
|
+
if (STRUCTURE_PATTERNS.hasDecorator.test(content)) {
|
|
186
|
+
score += 15;
|
|
187
|
+
}
|
|
188
|
+
// Count import statements
|
|
189
|
+
const imports = content.match(STRUCTURE_PATTERNS.importStatement);
|
|
190
|
+
if (imports && imports.length > 10) {
|
|
191
|
+
score += 10; // Many imports = integration point
|
|
192
|
+
}
|
|
193
|
+
// File size scoring
|
|
194
|
+
if (lines >= 50 && lines <= 500) {
|
|
195
|
+
score += 5; // Sweet spot
|
|
196
|
+
}
|
|
197
|
+
else if (lines > 1000) {
|
|
198
|
+
score -= 5; // Probably generated or data file
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
// File read error, return 0 for structure score
|
|
203
|
+
return 0;
|
|
204
|
+
}
|
|
205
|
+
// Clamp to valid range
|
|
206
|
+
return Math.max(0, Math.min(25, score));
|
|
207
|
+
}
|
|
208
|
+
// ============================================================================
|
|
209
|
+
// CONNECTIVITY SCORING (0-20 points)
|
|
210
|
+
// ============================================================================
|
|
211
|
+
/**
|
|
212
|
+
* Build file relationships from import analysis
|
|
213
|
+
*/
|
|
214
|
+
export function buildFileRelationships(files) {
|
|
215
|
+
const relationships = new Map();
|
|
216
|
+
// Initialize all files
|
|
217
|
+
for (const file of files) {
|
|
218
|
+
relationships.set(file.path, {
|
|
219
|
+
filePath: file.path,
|
|
220
|
+
imports: [],
|
|
221
|
+
importedBy: [],
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
return relationships;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Calculate connectivity score based on import relationships
|
|
228
|
+
*/
|
|
229
|
+
function calculateConnectivityScore(filePath, relationships) {
|
|
230
|
+
const rel = relationships.get(filePath);
|
|
231
|
+
if (!rel) {
|
|
232
|
+
return 0;
|
|
233
|
+
}
|
|
234
|
+
let score = 0;
|
|
235
|
+
// Imported by many files
|
|
236
|
+
const importedByCount = rel.importedBy.length;
|
|
237
|
+
if (importedByCount >= 5) {
|
|
238
|
+
score += 20;
|
|
239
|
+
}
|
|
240
|
+
else if (importedByCount >= 2) {
|
|
241
|
+
score += 10;
|
|
242
|
+
}
|
|
243
|
+
// Imports many local files
|
|
244
|
+
const importsCount = rel.imports.length;
|
|
245
|
+
if (importsCount >= 5) {
|
|
246
|
+
score += 10;
|
|
247
|
+
}
|
|
248
|
+
// Orphan penalty
|
|
249
|
+
if (importsCount === 0 && importedByCount === 0) {
|
|
250
|
+
score -= 10;
|
|
251
|
+
}
|
|
252
|
+
// Clamp to valid range
|
|
253
|
+
return Math.max(0, Math.min(20, score));
|
|
254
|
+
}
|
|
255
|
+
// ============================================================================
|
|
256
|
+
// TAGGING
|
|
257
|
+
// ============================================================================
|
|
258
|
+
/**
|
|
259
|
+
* Generate tags for a scored file
|
|
260
|
+
*/
|
|
261
|
+
function generateTags(file, scoreBreakdown) {
|
|
262
|
+
const tags = [];
|
|
263
|
+
// Entry point tag
|
|
264
|
+
if (file.isEntryPoint) {
|
|
265
|
+
tags.push('entry-point');
|
|
266
|
+
}
|
|
267
|
+
// Config tag
|
|
268
|
+
if (file.isConfig) {
|
|
269
|
+
tags.push('config');
|
|
270
|
+
}
|
|
271
|
+
// Test tag
|
|
272
|
+
if (file.isTest) {
|
|
273
|
+
tags.push('test');
|
|
274
|
+
}
|
|
275
|
+
// Generated tag
|
|
276
|
+
if (file.isGenerated) {
|
|
277
|
+
tags.push('generated');
|
|
278
|
+
}
|
|
279
|
+
// Schema/model tag
|
|
280
|
+
const nameLower = file.name.toLowerCase();
|
|
281
|
+
if (nameLower.includes('schema') ||
|
|
282
|
+
nameLower.includes('model') ||
|
|
283
|
+
nameLower.includes('entity')) {
|
|
284
|
+
tags.push('schema');
|
|
285
|
+
}
|
|
286
|
+
// API/route tag
|
|
287
|
+
if (nameLower.includes('api') ||
|
|
288
|
+
nameLower.includes('route') ||
|
|
289
|
+
nameLower.includes('controller')) {
|
|
290
|
+
tags.push('api');
|
|
291
|
+
}
|
|
292
|
+
// Service tag
|
|
293
|
+
if (nameLower.includes('service') || nameLower.includes('provider')) {
|
|
294
|
+
tags.push('service');
|
|
295
|
+
}
|
|
296
|
+
// High name score tag
|
|
297
|
+
if (scoreBreakdown.name >= 20) {
|
|
298
|
+
tags.push('high-value-name');
|
|
299
|
+
}
|
|
300
|
+
// High connectivity tag
|
|
301
|
+
if (scoreBreakdown.connectivity >= 15) {
|
|
302
|
+
tags.push('high-connectivity');
|
|
303
|
+
}
|
|
304
|
+
return tags;
|
|
305
|
+
}
|
|
306
|
+
// ============================================================================
|
|
307
|
+
// MAIN SCORER CLASS
|
|
308
|
+
// ============================================================================
|
|
309
|
+
/**
|
|
310
|
+
* File Significance Scorer
|
|
311
|
+
*/
|
|
312
|
+
export class SignificanceScorer {
|
|
313
|
+
config;
|
|
314
|
+
relationships;
|
|
315
|
+
constructor(config = {}) {
|
|
316
|
+
this.config = config;
|
|
317
|
+
this.relationships = new Map();
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Set file relationships for connectivity scoring
|
|
321
|
+
*/
|
|
322
|
+
setRelationships(relationships) {
|
|
323
|
+
this.relationships = relationships;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Score a single file
|
|
327
|
+
*/
|
|
328
|
+
async scoreFile(file) {
|
|
329
|
+
const nameScore = calculateNameScore(file.name, this.config);
|
|
330
|
+
const pathScore = calculatePathScore(file.path, file.depth, this.config);
|
|
331
|
+
const structureScore = await calculateStructureScore(file.absolutePath, file.lines);
|
|
332
|
+
const connectivityScore = calculateConnectivityScore(file.path, this.relationships);
|
|
333
|
+
const totalScore = nameScore + pathScore + structureScore + connectivityScore;
|
|
334
|
+
const scoreBreakdown = {
|
|
335
|
+
name: nameScore,
|
|
336
|
+
path: pathScore,
|
|
337
|
+
structure: structureScore,
|
|
338
|
+
connectivity: connectivityScore,
|
|
339
|
+
};
|
|
340
|
+
const tags = generateTags(file, scoreBreakdown);
|
|
341
|
+
return {
|
|
342
|
+
...file,
|
|
343
|
+
score: Math.max(0, Math.min(100, totalScore)),
|
|
344
|
+
scoreBreakdown,
|
|
345
|
+
tags,
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Score all files
|
|
350
|
+
*/
|
|
351
|
+
async scoreFiles(files) {
|
|
352
|
+
const scoredFiles = [];
|
|
353
|
+
for (const file of files) {
|
|
354
|
+
const scored = await this.scoreFile(file);
|
|
355
|
+
// Apply minimum score filter if configured
|
|
356
|
+
if (this.config.minScore === undefined || scored.score >= this.config.minScore) {
|
|
357
|
+
scoredFiles.push(scored);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
// Sort by score descending
|
|
361
|
+
scoredFiles.sort((a, b) => b.score - a.score);
|
|
362
|
+
return scoredFiles;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
// ============================================================================
|
|
366
|
+
// UTILITY FUNCTIONS
|
|
367
|
+
// ============================================================================
|
|
368
|
+
/**
|
|
369
|
+
* Get top N files by score
|
|
370
|
+
*/
|
|
371
|
+
export function getTopFiles(files, n) {
|
|
372
|
+
return [...files].sort((a, b) => b.score - a.score).slice(0, n);
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Get files matching a specific tag
|
|
376
|
+
*/
|
|
377
|
+
export function getFilesByTag(files, tag) {
|
|
378
|
+
return files.filter((file) => file.tags.includes(tag));
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Get files with score above threshold
|
|
382
|
+
*/
|
|
383
|
+
export function getFilesAboveThreshold(files, threshold) {
|
|
384
|
+
return files.filter((file) => file.score >= threshold);
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Group files by tag
|
|
388
|
+
*/
|
|
389
|
+
export function groupFilesByTag(files) {
|
|
390
|
+
const groups = new Map();
|
|
391
|
+
for (const file of files) {
|
|
392
|
+
for (const tag of file.tags) {
|
|
393
|
+
const group = groups.get(tag) ?? [];
|
|
394
|
+
group.push(file);
|
|
395
|
+
groups.set(tag, group);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
return groups;
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Convenience function to score files
|
|
402
|
+
*/
|
|
403
|
+
export async function scoreFiles(files, config) {
|
|
404
|
+
const scorer = new SignificanceScorer(config);
|
|
405
|
+
return scorer.scoreFiles(files);
|
|
406
|
+
}
|
|
407
|
+
//# sourceMappingURL=significance-scorer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"significance-scorer.js","sourceRoot":"","sources":["../../../src/core/analyzer/significance-scorer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AA0BrC,+EAA+E;AAC/E,mCAAmC;AACnC,+EAA+E;AAE/E,MAAM,gBAAgB,GAA2B;IAC/C,2BAA2B;IAC3B,MAAM,EAAE,EAAE;IACV,KAAK,EAAE,EAAE;IACT,MAAM,EAAE,EAAE;IACV,KAAK,EAAE,EAAE;IACT,UAAU,EAAE,EAAE;IACd,mBAAmB;IACnB,IAAI,EAAE,EAAE;IACR,cAAc,EAAE,EAAE;IAClB,aAAa,EAAE,EAAE;IACjB,kBAAkB;IAClB,GAAG,EAAE,EAAE;IACP,MAAM,EAAE,EAAE;IACV,SAAS,EAAE,EAAE;IACb,UAAU,EAAE,EAAE;IACd,WAAW,EAAE,EAAE;IACf,uBAAuB;IACvB,QAAQ,EAAE,EAAE;IACZ,EAAE,EAAE,EAAE;IACN,UAAU,EAAE,EAAE;IACd,KAAK,EAAE,EAAE;IACT,qBAAqB;IACrB,MAAM,EAAE,EAAE;IACV,aAAa,EAAE,EAAE;IACjB,QAAQ,EAAE,EAAE;IACZ,mBAAmB;IACnB,UAAU,EAAE,EAAE;IACd,WAAW,EAAE,EAAE;IACf,KAAK,EAAE,EAAE;IACT,iBAAiB;IACjB,OAAO,EAAE,EAAE;IACX,QAAQ,EAAE,EAAE;IACZ,OAAO,EAAE,EAAE;IACX,iBAAiB;IACjB,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;IACP,OAAO,EAAE,CAAC;IACV,MAAM,EAAE,CAAC;IACT,MAAM,EAAE,CAAC;CACV,CAAC;AAEF,MAAM,cAAc,GAA2B;IAC7C,mBAAmB;IACnB,IAAI,EAAE,CAAC,EAAE;IACT,IAAI,EAAE,CAAC,EAAE;IACT,IAAI,EAAE,CAAC,EAAE;IACT,IAAI,EAAE,CAAC,EAAE;IACT,IAAI,EAAE,CAAC,EAAE;IACT,iBAAiB;IACjB,OAAO,EAAE,CAAC,EAAE;IACZ,QAAQ,EAAE,CAAC,EAAE;IACb,QAAQ,EAAE,CAAC,EAAE;IACb,SAAS,EAAE,CAAC,EAAE;IACd,gBAAgB;IAChB,OAAO,EAAE,CAAC,CAAC;IACX,QAAQ,EAAE,CAAC,CAAC;IACZ,MAAM,EAAE,CAAC,CAAC;IACV,OAAO,EAAE,CAAC,CAAC;IACX,IAAI,EAAE,CAAC,CAAC;IACR,mBAAmB;IACnB,MAAM,EAAE,CAAC,EAAE;IACX,GAAG,EAAE,CAAC,EAAE;IACR,UAAU,EAAE,CAAC,EAAE;IACf,MAAM,EAAE,CAAC,EAAE;CACZ,CAAC;AAEF;;GAEG;AACH,SAAS,kBAAkB,CAAC,QAAgB,EAAE,MAAsB;IAClE,MAAM,SAAS,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IACzC,MAAM,cAAc,GAAG,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAE5F,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,yBAAyB;IACzB,MAAM,cAAc,GAAG,EAAE,GAAG,gBAAgB,EAAE,GAAG,MAAM,EAAE,cAAc,EAAE,CAAC;IAC1E,KAAK,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;QAC/D,IAAI,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACrC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED,uBAAuB;IACvB,MAAM,aAAa,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,MAAM,EAAE,aAAa,EAAE,CAAC;IACtE,KAAK,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;QAC9D,IAAI,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACrC,KAAK,IAAI,MAAM,CAAC,CAAC,kBAAkB;QACrC,CAAC;IACH,CAAC;IAED,uBAAuB;IACvB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED,+EAA+E;AAC/E,mCAAmC;AACnC,+EAA+E;AAE/E,MAAM,gBAAgB,GAA2B;IAC/C,MAAM,EAAE,EAAE;IACV,MAAM,EAAE,EAAE;IACV,OAAO,EAAE,EAAE;IACX,SAAS,EAAE,EAAE;IACb,SAAS,EAAE,EAAE;IACb,MAAM,EAAE,EAAE;IACV,SAAS,EAAE,EAAE;IACb,cAAc,EAAE,EAAE;IAClB,SAAS,EAAE,EAAE;IACb,UAAU,EAAE,EAAE;IACd,WAAW,EAAE,EAAE;IACf,UAAU,EAAE,EAAE;CACf,CAAC;AAEF;;GAEG;AACH,SAAS,kBAAkB,CACzB,YAAoB,EACpB,KAAa,EACb,MAAsB;IAEtB,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,uBAAuB;IACvB,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;QAChB,KAAK,IAAI,EAAE,CAAC;IACd,CAAC;IAED,yBAAyB;IACzB,MAAM,cAAc,GAAG,EAAE,GAAG,gBAAgB,EAAE,GAAG,MAAM,EAAE,cAAc,EAAE,CAAC;IAC1E,KAAK,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;QAC/D,IAAI,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,YAAY,CAAC,QAAQ,CAAC,GAAG,GAAG,OAAO,CAAC,EAAE,CAAC;YAC7E,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED,kCAAkC;IAClC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACd,KAAK,IAAI,EAAE,CAAC;IACd,CAAC;IAED,0CAA0C;IAC1C,MAAM,SAAS,GAAG,YAAY,CAAC,WAAW,EAAE,CAAC;IAC7C,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QAClF,KAAK,IAAI,CAAC,CAAC;IACb,CAAC;IAED,uBAAuB;IACvB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED,+EAA+E;AAC/E,wCAAwC;AACxC,+EAA+E;AAE/E;;GAEG;AACH,MAAM,kBAAkB,GAAG;IACzB,QAAQ,EAAE,eAAe;IACzB,YAAY,EAAE,kCAAkC;IAChD,SAAS,EAAE,4EAA4E;IACvF,YAAY,EAAE,WAAW;IACzB,eAAe,EAAE,qCAAqC;CACvD,CAAC;AAEF;;GAEG;AACH,KAAK,UAAU,uBAAuB,CACpC,YAAoB,EACpB,KAAa;IAEb,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAEtD,8BAA8B;QAC9B,IAAI,kBAAkB,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAC9C,KAAK,IAAI,EAAE,CAAC;QACd,CAAC;QAED,uCAAuC;QACvC,IAAI,kBAAkB,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAClD,KAAK,IAAI,EAAE,CAAC;QACd,CAAC;QAED,6BAA6B;QAC7B,IAAI,kBAAkB,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/C,KAAK,IAAI,CAAC,CAAC;QACb,CAAC;QAED,uBAAuB;QACvB,IAAI,kBAAkB,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAClD,KAAK,IAAI,EAAE,CAAC;QACd,CAAC;QAED,0BAA0B;QAC1B,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,eAAe,CAAC,CAAC;QAClE,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;YACnC,KAAK,IAAI,EAAE,CAAC,CAAC,mCAAmC;QAClD,CAAC;QAED,oBAAoB;QACpB,IAAI,KAAK,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;YAChC,KAAK,IAAI,CAAC,CAAC,CAAC,aAAa;QAC3B,CAAC;aAAM,IAAI,KAAK,GAAG,IAAI,EAAE,CAAC;YACxB,KAAK,IAAI,CAAC,CAAC,CAAC,kCAAkC;QAChD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,gDAAgD;QAChD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,uBAAuB;IACvB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED,+EAA+E;AAC/E,qCAAqC;AACrC,+EAA+E;AAE/E;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAAqB;IAC1D,MAAM,aAAa,GAAG,IAAI,GAAG,EAA4B,CAAC;IAE1D,uBAAuB;IACvB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE;YAC3B,QAAQ,EAAE,IAAI,CAAC,IAAI;YACnB,OAAO,EAAE,EAAE;YACX,UAAU,EAAE,EAAE;SACf,CAAC,CAAC;IACL,CAAC;IAED,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,SAAS,0BAA0B,CACjC,QAAgB,EAChB,aAA4C;IAE5C,MAAM,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACxC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,yBAAyB;IACzB,MAAM,eAAe,GAAG,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;IAC9C,IAAI,eAAe,IAAI,CAAC,EAAE,CAAC;QACzB,KAAK,IAAI,EAAE,CAAC;IACd,CAAC;SAAM,IAAI,eAAe,IAAI,CAAC,EAAE,CAAC;QAChC,KAAK,IAAI,EAAE,CAAC;IACd,CAAC;IAED,2BAA2B;IAC3B,MAAM,YAAY,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC;IACxC,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;QACtB,KAAK,IAAI,EAAE,CAAC;IACd,CAAC;IAED,iBAAiB;IACjB,IAAI,YAAY,KAAK,CAAC,IAAI,eAAe,KAAK,CAAC,EAAE,CAAC;QAChD,KAAK,IAAI,EAAE,CAAC;IACd,CAAC;IAED,uBAAuB;IACvB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED,+EAA+E;AAC/E,UAAU;AACV,+EAA+E;AAE/E;;GAEG;AACH,SAAS,YAAY,CACnB,IAAkB,EAClB,cAA4C;IAE5C,MAAM,IAAI,GAAa,EAAE,CAAC;IAE1B,kBAAkB;IAClB,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC3B,CAAC;IAED,aAAa;IACb,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACtB,CAAC;IAED,WAAW;IACX,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACpB,CAAC;IAED,gBAAgB;IAChB,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACzB,CAAC;IAED,mBAAmB;IACnB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;IAC1C,IACE,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC5B,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC;QAC3B,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAC5B,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACtB,CAAC;IAED,gBAAgB;IAChB,IACE,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC;QACzB,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC;QAC3B,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,EAChC,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnB,CAAC;IAED,cAAc;IACd,IAAI,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QACpE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACvB,CAAC;IAED,sBAAsB;IACtB,IAAI,cAAc,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAC/B,CAAC;IAED,wBAAwB;IACxB,IAAI,cAAc,CAAC,YAAY,IAAI,EAAE,EAAE,CAAC;QACtC,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IACjC,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,+EAA+E;AAC/E,oBAAoB;AACpB,+EAA+E;AAE/E;;GAEG;AACH,MAAM,OAAO,kBAAkB;IACrB,MAAM,CAAgB;IACtB,aAAa,CAAgC;IAErD,YAAY,SAAwB,EAAE;QACpC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,aAAa,GAAG,IAAI,GAAG,EAAE,CAAC;IACjC,CAAC;IAED;;OAEG;IACH,gBAAgB,CAAC,aAA4C;QAC3D,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;IACrC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,SAAS,CAAC,IAAkB;QAChC,MAAM,SAAS,GAAG,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAC7D,MAAM,SAAS,GAAG,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACzE,MAAM,cAAc,GAAG,MAAM,uBAAuB,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QACpF,MAAM,iBAAiB,GAAG,0BAA0B,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAEpF,MAAM,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,cAAc,GAAG,iBAAiB,CAAC;QAE9E,MAAM,cAAc,GAAG;YACrB,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,SAAS;YACf,SAAS,EAAE,cAAc;YACzB,YAAY,EAAE,iBAAiB;SAChC,CAAC;QAEF,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;QAEhD,OAAO;YACL,GAAG,IAAI;YACP,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;YAC7C,cAAc;YACd,IAAI;SACL,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,KAAqB;QACpC,MAAM,WAAW,GAAiB,EAAE,CAAC;QAErC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAE1C,2CAA2C;YAC3C,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,KAAK,SAAS,IAAI,MAAM,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;gBAC/E,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC;QAED,2BAA2B;QAC3B,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;QAE9C,OAAO,WAAW,CAAC;IACrB,CAAC;CACF;AAED,+EAA+E;AAC/E,oBAAoB;AACpB,+EAA+E;AAE/E;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,KAAmB,EAAE,CAAS;IACxD,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAClE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,KAAmB,EAAE,GAAW;IAC5D,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;AACzD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAAmB,EAAE,SAAiB;IAC3E,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,SAAS,CAAC,CAAC;AACzD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,KAAmB;IACjD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAwB,CAAC;IAE/C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;YACpC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,KAAqB,EACrB,MAAsB;IAEtB,MAAM,MAAM,GAAG,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC9C,OAAO,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subgraph Extractor
|
|
3
|
+
*
|
|
4
|
+
* For files that are too large to send as raw source to the LLM,
|
|
5
|
+
* extracts a compact call-graph neighborhood around "god functions"
|
|
6
|
+
* (high fan-out) and formats it as a structured prompt section.
|
|
7
|
+
*
|
|
8
|
+
* This dramatically reduces token usage while preserving structural
|
|
9
|
+
* information about complex orchestration code.
|
|
10
|
+
*/
|
|
11
|
+
import type { SerializedCallGraph, FunctionNode } from './call-graph.js';
|
|
12
|
+
import type { FileSignatureMap } from './signature-extractor.js';
|
|
13
|
+
export interface SubGraphNode {
|
|
14
|
+
name: string;
|
|
15
|
+
file: string;
|
|
16
|
+
fanIn: number;
|
|
17
|
+
fanOut: number;
|
|
18
|
+
}
|
|
19
|
+
export interface SubGraph {
|
|
20
|
+
root: SubGraphNode;
|
|
21
|
+
/** Callee nodes reachable within MAX_DEPTH */
|
|
22
|
+
nodes: SubGraphNode[];
|
|
23
|
+
/** [callerName, calleeName] pairs */
|
|
24
|
+
edges: Array<[string, string]>;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Return all god functions (fanOut >= threshold) defined in a given file.
|
|
28
|
+
* Normalises path separators for cross-platform matching.
|
|
29
|
+
*/
|
|
30
|
+
export declare function getFileGodFunctions(callGraph: SerializedCallGraph, filePath: string, fanOutThreshold?: number): FunctionNode[];
|
|
31
|
+
/**
|
|
32
|
+
* Extract a depth-limited subgraph around a root node.
|
|
33
|
+
* Only follows outgoing (callee) edges.
|
|
34
|
+
*/
|
|
35
|
+
export declare function extractSubgraph(callGraph: SerializedCallGraph, root: FunctionNode): SubGraph;
|
|
36
|
+
/**
|
|
37
|
+
* Build a graph-based prompt section for a large file.
|
|
38
|
+
*
|
|
39
|
+
* Returns null if no call-graph data is available for the file,
|
|
40
|
+
* signalling the caller to fall back to raw source chunking.
|
|
41
|
+
*/
|
|
42
|
+
export declare function buildGraphPromptSection(callGraph: SerializedCallGraph | undefined, signatures: FileSignatureMap[] | undefined, filePath: string): string | null;
|
|
43
|
+
//# sourceMappingURL=subgraph-extractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subgraph-extractor.d.ts","sourceRoot":"","sources":["../../../src/core/analyzer/subgraph-extractor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAajE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,YAAY,CAAC;IACnB,8CAA8C;IAC9C,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,qCAAqC;IACrC,KAAK,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAChC;AAMD;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,mBAAmB,EAC9B,QAAQ,EAAE,MAAM,EAChB,eAAe,SAAuB,GACrC,YAAY,EAAE,CAKhB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,mBAAmB,EAC9B,IAAI,EAAE,YAAY,GACjB,QAAQ,CA0CV;AA+BD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,mBAAmB,GAAG,SAAS,EAC1C,UAAU,EAAE,gBAAgB,EAAE,GAAG,SAAS,EAC1C,QAAQ,EAAE,MAAM,GACf,MAAM,GAAG,IAAI,CAiCf"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subgraph Extractor
|
|
3
|
+
*
|
|
4
|
+
* For files that are too large to send as raw source to the LLM,
|
|
5
|
+
* extracts a compact call-graph neighborhood around "god functions"
|
|
6
|
+
* (high fan-out) and formats it as a structured prompt section.
|
|
7
|
+
*
|
|
8
|
+
* This dramatically reduces token usage while preserving structural
|
|
9
|
+
* information about complex orchestration code.
|
|
10
|
+
*/
|
|
11
|
+
// Fan-out threshold for god-function detection (matches refactor-analyzer.ts)
|
|
12
|
+
const GOD_FANOUT_THRESHOLD = 8;
|
|
13
|
+
// Max graph depth and nodes per subgraph to avoid prompt explosion
|
|
14
|
+
const MAX_DEPTH = 2;
|
|
15
|
+
const MAX_NODES = 30;
|
|
16
|
+
// ============================================================================
|
|
17
|
+
// CORE FUNCTIONS
|
|
18
|
+
// ============================================================================
|
|
19
|
+
/**
|
|
20
|
+
* Return all god functions (fanOut >= threshold) defined in a given file.
|
|
21
|
+
* Normalises path separators for cross-platform matching.
|
|
22
|
+
*/
|
|
23
|
+
export function getFileGodFunctions(callGraph, filePath, fanOutThreshold = GOD_FANOUT_THRESHOLD) {
|
|
24
|
+
const normalised = filePath.replace(/\\/g, '/');
|
|
25
|
+
return callGraph.nodes.filter(n => n.filePath.replace(/\\/g, '/').endsWith(normalised) && n.fanOut >= fanOutThreshold);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Extract a depth-limited subgraph around a root node.
|
|
29
|
+
* Only follows outgoing (callee) edges.
|
|
30
|
+
*/
|
|
31
|
+
export function extractSubgraph(callGraph, root) {
|
|
32
|
+
const nodeMap = new Map(callGraph.nodes.map(n => [n.id, n]));
|
|
33
|
+
const visited = new Set();
|
|
34
|
+
const resultNodes = [];
|
|
35
|
+
const edges = [];
|
|
36
|
+
function visit(nodeId, depth) {
|
|
37
|
+
if (visited.has(nodeId) || depth > MAX_DEPTH || visited.size >= MAX_NODES)
|
|
38
|
+
return;
|
|
39
|
+
visited.add(nodeId);
|
|
40
|
+
const outgoing = callGraph.edges.filter(e => e.callerId === nodeId && e.calleeId);
|
|
41
|
+
for (const edge of outgoing) {
|
|
42
|
+
const callerNode = nodeMap.get(edge.callerId);
|
|
43
|
+
const calleeNode = nodeMap.get(edge.calleeId);
|
|
44
|
+
if (!callerNode || !calleeNode)
|
|
45
|
+
continue;
|
|
46
|
+
edges.push([callerNode.name, calleeNode.name]);
|
|
47
|
+
if (!visited.has(edge.calleeId)) {
|
|
48
|
+
resultNodes.push({
|
|
49
|
+
name: calleeNode.name,
|
|
50
|
+
file: calleeNode.filePath,
|
|
51
|
+
fanIn: calleeNode.fanIn,
|
|
52
|
+
fanOut: calleeNode.fanOut,
|
|
53
|
+
});
|
|
54
|
+
visit(edge.calleeId, depth + 1);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
visit(root.id, 0);
|
|
59
|
+
return {
|
|
60
|
+
root: {
|
|
61
|
+
name: root.name,
|
|
62
|
+
file: root.filePath,
|
|
63
|
+
fanIn: root.fanIn,
|
|
64
|
+
fanOut: root.fanOut,
|
|
65
|
+
},
|
|
66
|
+
nodes: resultNodes,
|
|
67
|
+
edges,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Format a single subgraph as a compact ASCII block for LLM prompts.
|
|
72
|
+
*
|
|
73
|
+
* Example output:
|
|
74
|
+
* run (fanIn=0, fanOut=12)
|
|
75
|
+
* → runStage1, runStage2, runStage3 ...
|
|
76
|
+
*/
|
|
77
|
+
function formatSubgraph(sub) {
|
|
78
|
+
const lines = [];
|
|
79
|
+
lines.push(`${sub.root.name} (fanIn=${sub.root.fanIn}, fanOut=${sub.root.fanOut})`);
|
|
80
|
+
// Direct callees of root
|
|
81
|
+
const directCallees = sub.edges
|
|
82
|
+
.filter(([from]) => from === sub.root.name)
|
|
83
|
+
.map(([, to]) => to);
|
|
84
|
+
if (directCallees.length > 0) {
|
|
85
|
+
lines.push(` → ${directCallees.join(', ')}`);
|
|
86
|
+
}
|
|
87
|
+
// Second-level callees
|
|
88
|
+
const secondLevel = sub.edges.filter(([from]) => from !== sub.root.name);
|
|
89
|
+
for (const [from, to] of secondLevel) {
|
|
90
|
+
lines.push(` ${from} → ${to}`);
|
|
91
|
+
}
|
|
92
|
+
return lines.join('\n');
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Build a graph-based prompt section for a large file.
|
|
96
|
+
*
|
|
97
|
+
* Returns null if no call-graph data is available for the file,
|
|
98
|
+
* signalling the caller to fall back to raw source chunking.
|
|
99
|
+
*/
|
|
100
|
+
export function buildGraphPromptSection(callGraph, signatures, filePath) {
|
|
101
|
+
if (!callGraph)
|
|
102
|
+
return null;
|
|
103
|
+
const godFunctions = getFileGodFunctions(callGraph, filePath);
|
|
104
|
+
// No god functions means the graph adds little value; let caller chunk normally
|
|
105
|
+
if (godFunctions.length === 0)
|
|
106
|
+
return null;
|
|
107
|
+
const lines = [
|
|
108
|
+
`[Graph-based analysis — file too large to include full source]`,
|
|
109
|
+
'',
|
|
110
|
+
];
|
|
111
|
+
// Signatures for this file (from signature-extractor)
|
|
112
|
+
const sigMap = signatures?.find(s => s.path.replace(/\\/g, '/').endsWith(filePath.replace(/\\/g, '/')));
|
|
113
|
+
if (sigMap && sigMap.entries.length > 0) {
|
|
114
|
+
lines.push('Signatures:');
|
|
115
|
+
for (const entry of sigMap.entries) {
|
|
116
|
+
const doc = entry.docstring ? ` // ${entry.docstring}` : '';
|
|
117
|
+
lines.push(` ${entry.signature}${doc}`);
|
|
118
|
+
}
|
|
119
|
+
lines.push('');
|
|
120
|
+
}
|
|
121
|
+
// Subgraphs for each god function
|
|
122
|
+
lines.push(`High-complexity functions (fanOut >= ${GOD_FANOUT_THRESHOLD}):`);
|
|
123
|
+
for (const godFn of godFunctions) {
|
|
124
|
+
const sub = extractSubgraph(callGraph, godFn);
|
|
125
|
+
lines.push(formatSubgraph(sub));
|
|
126
|
+
}
|
|
127
|
+
return lines.join('\n');
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=subgraph-extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subgraph-extractor.js","sourceRoot":"","sources":["../../../src/core/analyzer/subgraph-extractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VectorIndex
|
|
3
|
+
*
|
|
4
|
+
* Builds and queries a LanceDB vector index over the call graph functions.
|
|
5
|
+
* Each function is represented by a document combining its signature, docstring,
|
|
6
|
+
* file path, language, and topological metadata (fanIn/fanOut, hub, entry point).
|
|
7
|
+
*
|
|
8
|
+
* Storage: <outputDir>/vector-index/ (LanceDB database folder)
|
|
9
|
+
* Table name: "functions"
|
|
10
|
+
*
|
|
11
|
+
* Usage:
|
|
12
|
+
* // Build (after spec-gen analyze --embed)
|
|
13
|
+
* await VectorIndex.build(outputDir, nodes, signatures, hubIds, entryPointIds, embedSvc);
|
|
14
|
+
*
|
|
15
|
+
* // Search
|
|
16
|
+
* const results = await VectorIndex.search(outputDir, "authenticate user with JWT", embedSvc);
|
|
17
|
+
*/
|
|
18
|
+
import type { FunctionNode } from './call-graph.js';
|
|
19
|
+
import type { FileSignatureMap } from './signature-extractor.js';
|
|
20
|
+
import type { EmbeddingService } from './embedding-service.js';
|
|
21
|
+
export interface FunctionRecord {
|
|
22
|
+
id: string;
|
|
23
|
+
name: string;
|
|
24
|
+
filePath: string;
|
|
25
|
+
className: string;
|
|
26
|
+
language: string;
|
|
27
|
+
signature: string;
|
|
28
|
+
docstring: string;
|
|
29
|
+
fanIn: number;
|
|
30
|
+
fanOut: number;
|
|
31
|
+
isHub: boolean;
|
|
32
|
+
isEntryPoint: boolean;
|
|
33
|
+
/** Concatenated text used for embedding */
|
|
34
|
+
text: string;
|
|
35
|
+
/** Embedding vector */
|
|
36
|
+
vector: number[];
|
|
37
|
+
}
|
|
38
|
+
export interface SearchResult {
|
|
39
|
+
record: Omit<FunctionRecord, 'vector'>;
|
|
40
|
+
/** Distance score (lower = more similar) */
|
|
41
|
+
score: number;
|
|
42
|
+
}
|
|
43
|
+
export declare class VectorIndex {
|
|
44
|
+
/**
|
|
45
|
+
* Build (or rebuild) the vector index from call graph nodes + signatures.
|
|
46
|
+
* Overwrites any existing index.
|
|
47
|
+
*/
|
|
48
|
+
static build(outputDir: string, nodes: FunctionNode[], signatures: FileSignatureMap[], hubIds: Set<string>, entryPointIds: Set<string>, embedSvc: EmbeddingService): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Semantic search over the index.
|
|
51
|
+
* Returns up to `limit` results sorted by similarity (closest first).
|
|
52
|
+
*/
|
|
53
|
+
static search(outputDir: string, query: string, embedSvc: EmbeddingService, opts?: {
|
|
54
|
+
limit?: number;
|
|
55
|
+
language?: string;
|
|
56
|
+
minFanIn?: number;
|
|
57
|
+
}): Promise<SearchResult[]>;
|
|
58
|
+
/**
|
|
59
|
+
* Returns true if a vector index has been built for this output directory.
|
|
60
|
+
*/
|
|
61
|
+
static exists(outputDir: string): boolean;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=vector-index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vector-index.d.ts","sourceRoot":"","sources":["../../../src/core/analyzer/vector-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAM/D,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,YAAY,EAAE,OAAO,CAAC;IACtB,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;IACvC,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;CACf;AAiED,qBAAa,WAAW;IACtB;;;OAGG;WACU,KAAK,CAChB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,YAAY,EAAE,EACrB,UAAU,EAAE,gBAAgB,EAAE,EAC9B,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,EACnB,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,EAC1B,QAAQ,EAAE,gBAAgB,GACzB,OAAO,CAAC,IAAI,CAAC;IAkDhB;;;OAGG;WACU,MAAM,CACjB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,gBAAgB,EAC1B,IAAI,GAAE;QACJ,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACd,GACL,OAAO,CAAC,YAAY,EAAE,CAAC;IAmD1B;;OAEG;IACH,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;CAG1C"}
|