codebase-onboarder 0.5.0 → 0.7.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/README.md +196 -47
- package/bin/build-if-source.js +23 -0
- package/cli/commands.d.ts +26 -0
- package/cli/commands.js +836 -811
- package/cli/commands.js.map +1 -0
- package/cli/explorer/advanced.d.ts +14 -0
- package/cli/explorer/advanced.js +449 -0
- package/cli/explorer/advanced.js.map +1 -0
- package/cli/explorer/app.d.ts +1 -0
- package/cli/explorer/app.js +396 -229
- package/cli/explorer/app.js.map +1 -0
- package/cli/explorer/assistant.d.ts +9 -0
- package/cli/explorer/assistant.js +58 -0
- package/cli/explorer/assistant.js.map +1 -0
- package/cli/explorer/commands.d.ts +17 -0
- package/cli/explorer/commands.js +400 -162
- package/cli/explorer/commands.js.map +1 -0
- package/cli/explorer/featureViews.d.ts +124 -0
- package/cli/explorer/featureViews.js +179 -0
- package/cli/explorer/featureViews.js.map +1 -0
- package/cli/explorer/github.d.ts +21 -0
- package/cli/explorer/github.js +73 -0
- package/cli/explorer/github.js.map +1 -0
- package/cli/explorer/graphs.d.ts +7 -0
- package/cli/explorer/graphs.js +173 -0
- package/cli/explorer/graphs.js.map +1 -0
- package/cli/explorer/picker.d.ts +22 -0
- package/cli/explorer/picker.js +150 -0
- package/cli/explorer/picker.js.map +1 -0
- package/cli/explorer/report.d.ts +85 -0
- package/cli/explorer/report.js +60 -0
- package/cli/explorer/report.js.map +1 -0
- package/cli/explorer/session.d.ts +449 -0
- package/cli/explorer/session.js +184 -95
- package/cli/explorer/session.js.map +1 -0
- package/cli/explorer/views.d.ts +19 -0
- package/cli/explorer/views.js +496 -412
- package/cli/explorer/views.js.map +1 -0
- package/cli/explorer/wrap.d.ts +1 -0
- package/cli/explorer/wrap.js +33 -0
- package/cli/explorer/wrap.js.map +1 -0
- package/cli/main.d.ts +1 -0
- package/cli/main.js +235 -138
- package/cli/main.js.map +1 -0
- package/cli/prompt.d.ts +5 -0
- package/cli/prompt.js +84 -80
- package/cli/prompt.js.map +1 -0
- package/cli/scanOptions.d.ts +2 -0
- package/cli/scanOptions.js +11 -0
- package/cli/scanOptions.js.map +1 -0
- package/cli/ui.d.ts +33 -0
- package/cli/ui.js +55 -35
- package/cli/ui.js.map +1 -0
- package/cli/wizard.d.ts +187 -0
- package/cli/wizard.js +304 -284
- package/cli/wizard.js.map +1 -0
- package/package.json +15 -4
- package/public/app.d.ts +1 -0
- package/public/app.js +1057 -1009
- package/public/app.js.map +1 -0
- package/public/browser.d.ts +68 -0
- package/public/browser.js +2 -0
- package/public/browser.js.map +1 -0
- package/public/index.html +30 -13
- package/public/js/about.d.ts +6 -0
- package/public/js/about.js +165 -172
- package/public/js/about.js.map +1 -0
- package/public/js/aiDraft.d.ts +3 -0
- package/public/js/aiDraft.js +116 -124
- package/public/js/aiDraft.js.map +1 -0
- package/public/js/analysisPanel.d.ts +7 -0
- package/public/js/analysisPanel.js +166 -166
- package/public/js/analysisPanel.js.map +1 -0
- package/public/js/analysisReport.d.ts +38 -0
- package/public/js/analysisReport.js +105 -110
- package/public/js/analysisReport.js.map +1 -0
- package/public/js/api.d.ts +26 -0
- package/public/js/api.js +176 -167
- package/public/js/api.js.map +1 -0
- package/public/js/atlas.d.ts +6 -0
- package/public/js/atlas.js +50 -58
- package/public/js/atlas.js.map +1 -0
- package/public/js/blameView.d.ts +2 -0
- package/public/js/blameView.js +36 -37
- package/public/js/blameView.js.map +1 -0
- package/public/js/codeTab.d.ts +3 -0
- package/public/js/codeTab.js +175 -180
- package/public/js/codeTab.js.map +1 -0
- package/public/js/codeViewer.d.ts +5 -0
- package/public/js/codeViewer.js +162 -150
- package/public/js/codeViewer.js.map +1 -0
- package/public/js/components/FileChip.d.ts +9 -0
- package/public/js/components/FileChip.js +45 -49
- package/public/js/components/FileChip.js.map +1 -0
- package/public/js/components/MetricSparkline.d.ts +7 -0
- package/public/js/components/MetricSparkline.js +35 -44
- package/public/js/components/MetricSparkline.js.map +1 -0
- package/public/js/components/RiskBadge.d.ts +9 -0
- package/public/js/components/RiskBadge.js +55 -63
- package/public/js/components/RiskBadge.js.map +1 -0
- package/public/js/deepAnalysisView.d.ts +99 -0
- package/public/js/deepAnalysisView.js +282 -302
- package/public/js/deepAnalysisView.js.map +1 -0
- package/public/js/diagramPane.d.ts +8 -0
- package/public/js/diagramPane.js +133 -135
- package/public/js/diagramPane.js.map +1 -0
- package/public/js/diffView.d.ts +6 -0
- package/public/js/diffView.js +222 -209
- package/public/js/diffView.js.map +1 -0
- package/public/js/docsView.d.ts +2 -0
- package/public/js/docsView.js +441 -442
- package/public/js/docsView.js.map +1 -0
- package/public/js/dom.d.ts +189 -0
- package/public/js/dom.js +5 -0
- package/public/js/dom.js.map +1 -0
- package/public/js/fileSourceBrowser.d.ts +5 -0
- package/public/js/fileSourceBrowser.js +33 -41
- package/public/js/fileSourceBrowser.js.map +1 -0
- package/public/js/flameGraph.d.ts +5 -0
- package/public/js/flameGraph.js +62 -72
- package/public/js/flameGraph.js.map +1 -0
- package/public/js/forceGraph.d.ts +10 -0
- package/public/js/forceGraph.js +581 -556
- package/public/js/forceGraph.js.map +1 -0
- package/public/js/heatmap.d.ts +4 -0
- package/public/js/heatmap.js +142 -164
- package/public/js/heatmap.js.map +1 -0
- package/public/js/highlight.d.ts +2 -0
- package/public/js/highlight.js +116 -107
- package/public/js/highlight.js.map +1 -0
- package/public/js/html.d.ts +2 -0
- package/public/js/html.js +14 -44
- package/public/js/html.js.map +1 -0
- package/public/js/insightsView.d.ts +5 -0
- package/public/js/insightsView.js +93 -111
- package/public/js/insightsView.js.map +1 -0
- package/public/js/inspector.d.ts +37 -0
- package/public/js/inspector.js +416 -445
- package/public/js/inspector.js.map +1 -0
- package/public/js/llm.d.ts +113 -0
- package/public/js/llm.js +233 -272
- package/public/js/llm.js.map +1 -0
- package/public/js/mapView.d.ts +3 -0
- package/public/js/mapView.js +121 -120
- package/public/js/mapView.js.map +1 -0
- package/public/js/markdown.d.ts +3 -0
- package/public/js/markdown.js +84 -91
- package/public/js/markdown.js.map +1 -0
- package/public/js/mindmap.d.ts +32 -0
- package/public/js/mindmap.js +244 -259
- package/public/js/mindmap.js.map +1 -0
- package/public/js/mobilePanels.d.ts +5 -0
- package/public/js/mobilePanels.js +50 -0
- package/public/js/mobilePanels.js.map +1 -0
- package/public/js/repoFiles.d.ts +12 -0
- package/public/js/repoFiles.js +28 -27
- package/public/js/repoFiles.js.map +1 -0
- package/public/js/reviewView.d.ts +28 -0
- package/public/js/reviewView.js +256 -0
- package/public/js/reviewView.js.map +1 -0
- package/public/js/sbomView.d.ts +3 -0
- package/public/js/sbomView.js +59 -67
- package/public/js/sbomView.js.map +1 -0
- package/public/js/scanCache.d.ts +16 -0
- package/public/js/scanCache.js +67 -65
- package/public/js/scanCache.js.map +1 -0
- package/public/js/search.d.ts +7 -0
- package/public/js/search.js +868 -800
- package/public/js/search.js.map +1 -0
- package/public/js/searchLocal.d.ts +42 -0
- package/public/js/searchLocal.js +87 -0
- package/public/js/searchLocal.js.map +1 -0
- package/public/js/serverSettings.d.ts +5 -0
- package/public/js/serverSettings.js +153 -164
- package/public/js/serverSettings.js.map +1 -0
- package/public/js/state.d.ts +798 -0
- package/public/js/state.js +114 -122
- package/public/js/state.js.map +1 -0
- package/public/js/tour.d.ts +6 -0
- package/public/js/tour.js +5 -7
- package/public/js/tour.js.map +1 -0
- package/public/js/transitions.d.ts +2 -0
- package/public/js/transitions.js +9 -10
- package/public/js/transitions.js.map +1 -0
- package/public/js/tree.d.ts +12 -0
- package/public/js/tree.js +157 -154
- package/public/js/tree.js.map +1 -0
- package/public/js/workflowsView.d.ts +3 -0
- package/public/js/workflowsView.js +15 -22
- package/public/js/workflowsView.js.map +1 -0
- package/public/search.css +495 -0
- package/public/styles.css +163 -346
- package/public/workbench.css +166 -0
- package/server/apiAuth.d.ts +3 -0
- package/server/apiAuth.js +18 -20
- package/server/apiAuth.js.map +1 -0
- package/server/apiDiff.d.ts +2 -0
- package/server/apiDiff.js +20 -18
- package/server/apiDiff.js.map +1 -0
- package/server/apiDocs.d.ts +2 -0
- package/server/apiDocs.js +38 -40
- package/server/apiDocs.js.map +1 -0
- package/server/apiFile.d.ts +1 -0
- package/server/apiFile.js +14 -17
- package/server/apiFile.js.map +1 -0
- package/server/apiGitBlame.d.ts +2 -0
- package/server/apiGitBlame.js +50 -51
- package/server/apiGitBlame.js.map +1 -0
- package/server/apiMcp.d.ts +4 -0
- package/server/apiMcp.js +64 -66
- package/server/apiMcp.js.map +1 -0
- package/server/apiReview.d.ts +2 -0
- package/server/apiReview.js +45 -0
- package/server/apiReview.js.map +1 -0
- package/server/apiScan.d.ts +5 -0
- package/server/apiScan.js +90 -71
- package/server/apiScan.js.map +1 -0
- package/server/apiSearch.d.ts +33 -0
- package/server/apiSearch.js +184 -200
- package/server/apiSearch.js.map +1 -0
- package/server/apiSettings.d.ts +4 -0
- package/server/apiSettings.js +84 -85
- package/server/apiSettings.js.map +1 -0
- package/server/apiTools.d.ts +3 -0
- package/server/apiTools.js +55 -56
- package/server/apiTools.js.map +1 -0
- package/server/auth.d.ts +5 -0
- package/server/auth.js +54 -51
- package/server/auth.js.map +1 -0
- package/server/config.d.ts +42 -0
- package/server/config.js +189 -194
- package/server/config.js.map +1 -0
- package/server/daemon.d.ts +12 -0
- package/server/daemon.js +124 -114
- package/server/daemon.js.map +1 -0
- package/server/fileSourceNode.d.ts +2 -0
- package/server/fileSourceNode.js +34 -36
- package/server/fileSourceNode.js.map +1 -0
- package/server/gitClone.d.ts +9 -0
- package/server/gitClone.js +59 -61
- package/server/gitClone.js.map +1 -0
- package/server/gitDiff.d.ts +36 -0
- package/server/gitDiff.js +271 -169
- package/server/gitDiff.js.map +1 -0
- package/server/gitHistory.d.ts +12 -0
- package/server/gitHistory.js +80 -80
- package/server/gitHistory.js.map +1 -0
- package/server/gitRemote.d.ts +12 -0
- package/server/gitRemote.js +60 -0
- package/server/gitRemote.js.map +1 -0
- package/server/htmlText.d.ts +4 -0
- package/server/htmlText.js +16 -23
- package/server/htmlText.js.map +1 -0
- package/server/http.d.ts +5 -0
- package/server/http.js +27 -30
- package/server/http.js.map +1 -0
- package/server/httpGuards.d.ts +2 -0
- package/server/httpGuards.js +47 -43
- package/server/httpGuards.js.map +1 -0
- package/server/https.d.ts +34 -0
- package/server/https.js +121 -111
- package/server/https.js.map +1 -0
- package/server/index.d.ts +40 -0
- package/server/index.js +139 -147
- package/server/index.js.map +1 -0
- package/server/layout.d.ts +26 -0
- package/server/layout.js +59 -37
- package/server/layout.js.map +1 -0
- package/server/llmProxy.d.ts +3 -0
- package/server/llmProxy.js +137 -135
- package/server/llmProxy.js.map +1 -0
- package/server/logger.d.ts +38 -0
- package/server/logger.js +198 -211
- package/server/logger.js.map +1 -0
- package/server/mcp/analysis.d.ts +29 -0
- package/server/mcp/analysis.js +99 -120
- package/server/mcp/analysis.js.map +1 -0
- package/server/mcp/http.d.ts +9 -0
- package/server/mcp/http.js +128 -137
- package/server/mcp/http.js.map +1 -0
- package/server/mcp/runner.d.ts +68 -0
- package/server/mcp/runner.js +208 -218
- package/server/mcp/runner.js.map +1 -0
- package/server/mcp/server.d.ts +29 -0
- package/server/mcp/server.js +166 -179
- package/server/mcp/server.js.map +1 -0
- package/server/mcp/standalone.d.ts +1 -0
- package/server/mcp/standalone.js +8 -10
- package/server/mcp/standalone.js.map +1 -0
- package/server/mcp/tools.d.ts +2020 -0
- package/server/mcp/tools.js +523 -574
- package/server/mcp/tools.js.map +1 -0
- package/server/paths.d.ts +3 -0
- package/server/paths.js +17 -15
- package/server/paths.js.map +1 -0
- package/server/pidfile.d.ts +9 -0
- package/server/pidfile.js +43 -45
- package/server/pidfile.js.map +1 -0
- package/server/review.d.ts +5 -0
- package/server/review.js +35 -0
- package/server/review.js.map +1 -0
- package/server/router.d.ts +33 -0
- package/server/router.js +191 -197
- package/server/router.js.map +1 -0
- package/server/scanRequest.d.ts +3 -0
- package/server/scanRequest.js +36 -0
- package/server/scanRequest.js.map +1 -0
- package/server/searchIndex.d.ts +17 -0
- package/server/searchIndex.js +83 -80
- package/server/searchIndex.js.map +1 -0
- package/server/sessions.d.ts +14 -0
- package/server/sessions.js +62 -70
- package/server/sessions.js.map +1 -0
- package/server/startup.d.ts +118 -0
- package/server/startup.js +143 -148
- package/server/startup.js.map +1 -0
- package/server/static.d.ts +6 -0
- package/server/static.js +28 -31
- package/server/static.js.map +1 -0
- package/server/tools/install.d.ts +4 -0
- package/server/tools/install.js +176 -185
- package/server/tools/install.js.map +1 -0
- package/server/tools/parse.d.ts +8 -0
- package/server/tools/parse.js +112 -114
- package/server/tools/parse.js.map +1 -0
- package/server/tools/platform.d.ts +9 -0
- package/server/tools/platform.js +49 -47
- package/server/tools/platform.js.map +1 -0
- package/server/tools/registry.d.ts +137 -0
- package/server/tools/registry.js +173 -172
- package/server/tools/registry.js.map +1 -0
- package/server/tools/scan.d.ts +34 -0
- package/server/tools/scan.js +89 -98
- package/server/tools/scan.js.map +1 -0
- package/server/tools.d.ts +34 -0
- package/server/tools.js +94 -107
- package/server/tools.js.map +1 -0
- package/server/tunnel.d.ts +29 -0
- package/server/tunnel.js +61 -66
- package/server/tunnel.js.map +1 -0
- package/shared/analyzer/docs.d.ts +16 -0
- package/shared/analyzer/docs.js +99 -93
- package/shared/analyzer/docs.js.map +1 -0
- package/shared/analyzer/explainLocal.d.ts +4 -0
- package/shared/analyzer/explainLocal.js +122 -142
- package/shared/analyzer/explainLocal.js.map +1 -0
- package/shared/analyzer/github.d.ts +37 -0
- package/shared/analyzer/github.js +79 -0
- package/shared/analyzer/github.js.map +1 -0
- package/shared/analyzer/graph.d.ts +41 -0
- package/shared/analyzer/graph.js +393 -400
- package/shared/analyzer/graph.js.map +1 -0
- package/shared/analyzer/health.d.ts +33 -0
- package/shared/analyzer/health.js +197 -193
- package/shared/analyzer/health.js.map +1 -0
- package/shared/analyzer/history.d.ts +29 -0
- package/shared/analyzer/history.js +110 -111
- package/shared/analyzer/history.js.map +1 -0
- package/shared/analyzer/jsonConfig.d.ts +2 -0
- package/shared/analyzer/jsonConfig.js +61 -0
- package/shared/analyzer/jsonConfig.js.map +1 -0
- package/shared/analyzer/languages/csharp.d.ts +26 -0
- package/shared/analyzer/languages/csharp.js +83 -88
- package/shared/analyzer/languages/csharp.js.map +1 -0
- package/shared/analyzer/languages/generic.d.ts +23 -0
- package/shared/analyzer/languages/generic.js +94 -105
- package/shared/analyzer/languages/generic.js.map +1 -0
- package/shared/analyzer/languages/go.d.ts +24 -0
- package/shared/analyzer/languages/go.js +45 -54
- package/shared/analyzer/languages/go.js.map +1 -0
- package/shared/analyzer/languages/index.d.ts +6 -0
- package/shared/analyzer/languages/index.js +19 -20
- package/shared/analyzer/languages/index.js.map +1 -0
- package/shared/analyzer/languages/java.d.ts +20 -0
- package/shared/analyzer/languages/java.js +73 -78
- package/shared/analyzer/languages/java.js.map +1 -0
- package/shared/analyzer/languages/javascript.d.ts +12 -0
- package/shared/analyzer/languages/javascript.js +258 -209
- package/shared/analyzer/languages/javascript.js.map +1 -0
- package/shared/analyzer/languages/python.d.ts +23 -0
- package/shared/analyzer/languages/python.js +92 -100
- package/shared/analyzer/languages/python.js.map +1 -0
- package/shared/analyzer/languages/rust.d.ts +17 -0
- package/shared/analyzer/languages/rust.js +96 -98
- package/shared/analyzer/languages/rust.js.map +1 -0
- package/shared/analyzer/languages/typescript.d.ts +11 -0
- package/shared/analyzer/languages/typescript.js +117 -116
- package/shared/analyzer/languages/typescript.js.map +1 -0
- package/shared/analyzer/licenses.d.ts +18 -0
- package/shared/analyzer/licenses.js +130 -133
- package/shared/analyzer/licenses.js.map +1 -0
- package/shared/analyzer/metrics.d.ts +20 -0
- package/shared/analyzer/metrics.js +112 -104
- package/shared/analyzer/metrics.js.map +1 -0
- package/shared/analyzer/pathUtil.d.ts +10 -0
- package/shared/analyzer/pathUtil.js +29 -35
- package/shared/analyzer/pathUtil.js.map +1 -0
- package/shared/analyzer/patterns.d.ts +11 -0
- package/shared/analyzer/patterns.js +231 -253
- package/shared/analyzer/patterns.js.map +1 -0
- package/shared/analyzer/scan.d.ts +62 -0
- package/shared/analyzer/scan.js +451 -442
- package/shared/analyzer/scan.js.map +1 -0
- package/shared/analyzer/scanControl.d.ts +11 -0
- package/shared/analyzer/scanControl.js +62 -0
- package/shared/analyzer/scanControl.js.map +1 -0
- package/shared/analyzer/security.d.ts +18 -0
- package/shared/analyzer/security.js +159 -159
- package/shared/analyzer/security.js.map +1 -0
- package/shared/analyzer/services.d.ts +5 -0
- package/shared/analyzer/services.js +141 -138
- package/shared/analyzer/services.js.map +1 -0
- package/shared/analyzer/stack.d.ts +6 -0
- package/shared/analyzer/stack.js +134 -141
- package/shared/analyzer/stack.js.map +1 -0
- package/shared/analyzer/tour.d.ts +2 -0
- package/shared/analyzer/tour.js +45 -53
- package/shared/analyzer/tour.js.map +1 -0
- package/shared/analyzer/util.d.ts +8 -0
- package/shared/analyzer/util.js +130 -76
- package/shared/analyzer/util.js.map +1 -0
- package/shared/analyzer/workflows.d.ts +8 -0
- package/shared/analyzer/workflows.js +139 -134
- package/shared/analyzer/workflows.js.map +1 -0
- package/shared/contracts.d.ts +250 -0
- package/shared/contracts.js +2 -0
- package/shared/contracts.js.map +1 -0
- package/shared/diagram/aiFacts.d.ts +35 -0
- package/shared/diagram/aiFacts.js +102 -105
- package/shared/diagram/aiFacts.js.map +1 -0
- package/shared/diagram/aiMermaid.d.ts +5 -0
- package/shared/diagram/aiMermaid.js +46 -45
- package/shared/diagram/aiMermaid.js.map +1 -0
- package/shared/diagram/atlas.d.ts +16 -0
- package/shared/diagram/atlas.js +51 -60
- package/shared/diagram/atlas.js.map +1 -0
- package/shared/diagram/mermaid.d.ts +43 -0
- package/shared/diagram/mermaid.js +348 -370
- package/shared/diagram/mermaid.js.map +1 -0
- package/shared/review/contracts.d.ts +95 -0
- package/shared/review/contracts.js +2 -0
- package/shared/review/contracts.js.map +1 -0
- package/shared/review/review.d.ts +10 -0
- package/shared/review/review.js +184 -0
- package/shared/review/review.js.map +1 -0
- package/shared/search/query.d.ts +32 -0
- package/shared/search/query.js +395 -388
- package/shared/search/query.js.map +1 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
/** Portable contracts shared by the server, terminal app, and browser. */
|
|
2
|
+
export interface FileEntry {
|
|
3
|
+
name: string;
|
|
4
|
+
path: string;
|
|
5
|
+
type: 'file' | 'dir';
|
|
6
|
+
}
|
|
7
|
+
export interface FileSource {
|
|
8
|
+
kind: string;
|
|
9
|
+
root: string;
|
|
10
|
+
name: string;
|
|
11
|
+
list(directory: string): Promise<FileEntry[]>;
|
|
12
|
+
read(path: string): Promise<string>;
|
|
13
|
+
}
|
|
14
|
+
/** A structural signal keeps the engine independent of Node and browser imports. */
|
|
15
|
+
export interface ScanSignal {
|
|
16
|
+
readonly aborted: boolean;
|
|
17
|
+
readonly reason?: unknown;
|
|
18
|
+
addEventListener(type: 'abort', listener: () => void, options?: {
|
|
19
|
+
once?: boolean;
|
|
20
|
+
}): void;
|
|
21
|
+
removeEventListener(type: 'abort', listener: () => void): void;
|
|
22
|
+
}
|
|
23
|
+
export type ScanProgress = {
|
|
24
|
+
phase: 'clone';
|
|
25
|
+
url: string;
|
|
26
|
+
} | {
|
|
27
|
+
phase: 'walk';
|
|
28
|
+
found: number;
|
|
29
|
+
} | {
|
|
30
|
+
phase: 'parse';
|
|
31
|
+
done: number;
|
|
32
|
+
total: number;
|
|
33
|
+
} | {
|
|
34
|
+
phase: 'resolve';
|
|
35
|
+
done: number;
|
|
36
|
+
total: number;
|
|
37
|
+
} | {
|
|
38
|
+
phase: 'complete';
|
|
39
|
+
files: number;
|
|
40
|
+
edges: number;
|
|
41
|
+
};
|
|
42
|
+
export interface ScanOptions {
|
|
43
|
+
maxFiles?: number;
|
|
44
|
+
/** UTF-8 bytes, rather than JavaScript string length. */
|
|
45
|
+
maxFileSize?: number;
|
|
46
|
+
readConcurrency?: number;
|
|
47
|
+
signal?: ScanSignal;
|
|
48
|
+
onProgress?: (progress: ScanProgress) => void;
|
|
49
|
+
}
|
|
50
|
+
export interface ScanLimits {
|
|
51
|
+
maxFiles: number;
|
|
52
|
+
maxFileSize: number;
|
|
53
|
+
readConcurrency: number;
|
|
54
|
+
}
|
|
55
|
+
export interface ImportInfo {
|
|
56
|
+
spec: string;
|
|
57
|
+
line?: number;
|
|
58
|
+
symbols?: string[];
|
|
59
|
+
kind?: string;
|
|
60
|
+
local?: boolean;
|
|
61
|
+
static?: boolean;
|
|
62
|
+
typeOnly?: boolean;
|
|
63
|
+
reexport?: boolean;
|
|
64
|
+
packageName?: string;
|
|
65
|
+
}
|
|
66
|
+
export interface ImportEdge {
|
|
67
|
+
from: string;
|
|
68
|
+
to: string;
|
|
69
|
+
kind: string;
|
|
70
|
+
symbols: string[];
|
|
71
|
+
}
|
|
72
|
+
export interface Service {
|
|
73
|
+
name: string;
|
|
74
|
+
source: string;
|
|
75
|
+
command?: string;
|
|
76
|
+
build?: string;
|
|
77
|
+
image?: string;
|
|
78
|
+
ports?: string[];
|
|
79
|
+
dependsOn?: string[];
|
|
80
|
+
}
|
|
81
|
+
export interface Manifest {
|
|
82
|
+
entryPoints: string[];
|
|
83
|
+
services: Service[];
|
|
84
|
+
packageName: string;
|
|
85
|
+
scripts: string[];
|
|
86
|
+
workspaces: string[];
|
|
87
|
+
license?: string;
|
|
88
|
+
hasServerScript?: boolean;
|
|
89
|
+
composeFile?: string;
|
|
90
|
+
deps: {
|
|
91
|
+
npm: Record<string, string>;
|
|
92
|
+
dev: Record<string, string>;
|
|
93
|
+
pip: string[];
|
|
94
|
+
go: string[];
|
|
95
|
+
cargo: string[];
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
export interface ResolverContext {
|
|
99
|
+
hasDir?: (path: string) => boolean;
|
|
100
|
+
findDirEndingWith?: (suffix: string) => string | null;
|
|
101
|
+
findByName?: (name: string) => string | null;
|
|
102
|
+
modulePath?: string;
|
|
103
|
+
tsPaths?: {
|
|
104
|
+
baseUrl: string;
|
|
105
|
+
paths: Record<string, string[]>;
|
|
106
|
+
sourceRoot?: string;
|
|
107
|
+
outputRoot?: string;
|
|
108
|
+
} | null;
|
|
109
|
+
}
|
|
110
|
+
export interface ImportResolution {
|
|
111
|
+
path?: string;
|
|
112
|
+
packageDir?: string;
|
|
113
|
+
external?: string;
|
|
114
|
+
unresolved?: string;
|
|
115
|
+
}
|
|
116
|
+
export interface AccountSettings {
|
|
117
|
+
name: string;
|
|
118
|
+
email: string;
|
|
119
|
+
provider: string;
|
|
120
|
+
baseUrl: string;
|
|
121
|
+
model: string;
|
|
122
|
+
}
|
|
123
|
+
export interface Settings {
|
|
124
|
+
version: number;
|
|
125
|
+
mode: 'local' | 'self-hosted';
|
|
126
|
+
host: string;
|
|
127
|
+
port: number;
|
|
128
|
+
domain: string;
|
|
129
|
+
https: boolean;
|
|
130
|
+
accessKey: string;
|
|
131
|
+
autoOpen: boolean;
|
|
132
|
+
account: AccountSettings;
|
|
133
|
+
tunnel: {
|
|
134
|
+
cloudflare: boolean;
|
|
135
|
+
tailscale: boolean;
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
export interface SettingsInput {
|
|
139
|
+
version?: unknown;
|
|
140
|
+
mode?: unknown;
|
|
141
|
+
host?: unknown;
|
|
142
|
+
port?: unknown;
|
|
143
|
+
domain?: unknown;
|
|
144
|
+
https?: unknown;
|
|
145
|
+
accessKey?: unknown;
|
|
146
|
+
autoOpen?: unknown;
|
|
147
|
+
account?: Partial<Record<keyof AccountSettings, unknown>>;
|
|
148
|
+
tunnel?: {
|
|
149
|
+
cloudflare?: unknown;
|
|
150
|
+
tailscale?: unknown;
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
export interface ServerUrls {
|
|
154
|
+
local: string;
|
|
155
|
+
network?: string;
|
|
156
|
+
domain?: string;
|
|
157
|
+
}
|
|
158
|
+
export interface SymbolInfo {
|
|
159
|
+
name: string;
|
|
160
|
+
line?: number;
|
|
161
|
+
kind?: string;
|
|
162
|
+
calls?: string[];
|
|
163
|
+
async?: boolean;
|
|
164
|
+
exported?: boolean;
|
|
165
|
+
pub?: boolean;
|
|
166
|
+
genericArity?: number;
|
|
167
|
+
decorators?: string[];
|
|
168
|
+
annotations?: string[];
|
|
169
|
+
attributes?: string[];
|
|
170
|
+
}
|
|
171
|
+
export interface FileAnalysis {
|
|
172
|
+
imports: ImportInfo[];
|
|
173
|
+
exports: SymbolInfo[];
|
|
174
|
+
functions: SymbolInfo[];
|
|
175
|
+
classes: SymbolInfo[];
|
|
176
|
+
interfaces?: SymbolInfo[];
|
|
177
|
+
calls?: Array<{
|
|
178
|
+
from: string;
|
|
179
|
+
to: string;
|
|
180
|
+
}>;
|
|
181
|
+
hasMain?: boolean;
|
|
182
|
+
decorators?: string[];
|
|
183
|
+
annotations?: string[];
|
|
184
|
+
attributes?: string[];
|
|
185
|
+
packageName?: string;
|
|
186
|
+
namespace?: string;
|
|
187
|
+
}
|
|
188
|
+
export interface SecurityFinding {
|
|
189
|
+
rule: string;
|
|
190
|
+
severity: string;
|
|
191
|
+
category: string;
|
|
192
|
+
message: string;
|
|
193
|
+
line: number;
|
|
194
|
+
source?: string;
|
|
195
|
+
tool?: string;
|
|
196
|
+
}
|
|
197
|
+
export interface ScannedFile extends FileAnalysis {
|
|
198
|
+
path: string;
|
|
199
|
+
dir: string;
|
|
200
|
+
name: string;
|
|
201
|
+
ext: string;
|
|
202
|
+
lang: string;
|
|
203
|
+
size: number;
|
|
204
|
+
loc: number;
|
|
205
|
+
comment: number;
|
|
206
|
+
blank: number;
|
|
207
|
+
lines: number;
|
|
208
|
+
docRatio: number;
|
|
209
|
+
complexity: number;
|
|
210
|
+
findings?: SecurityFinding[];
|
|
211
|
+
cognitive?: number;
|
|
212
|
+
maintainability?: number;
|
|
213
|
+
}
|
|
214
|
+
export interface ScannedFolder {
|
|
215
|
+
path: string;
|
|
216
|
+
name: string;
|
|
217
|
+
depth: number;
|
|
218
|
+
fileCount: number;
|
|
219
|
+
loc: number;
|
|
220
|
+
comment: number;
|
|
221
|
+
blank: number;
|
|
222
|
+
size: number;
|
|
223
|
+
langs: Record<string, number>;
|
|
224
|
+
hasReadme: boolean;
|
|
225
|
+
docRatio?: number;
|
|
226
|
+
}
|
|
227
|
+
export interface LanguageAnalyzer {
|
|
228
|
+
id: string;
|
|
229
|
+
label: string;
|
|
230
|
+
short: string;
|
|
231
|
+
extensions: string[];
|
|
232
|
+
analyze(source: string, path: string): FileAnalysis;
|
|
233
|
+
resolveImport(spec: string, from: string, has: (path: string) => boolean, context?: ResolverContext, meta?: ImportInfo): ImportResolution;
|
|
234
|
+
}
|
|
235
|
+
export type ScanRequestOptions = Pick<ScanOptions, 'maxFiles' | 'maxFileSize' | 'readConcurrency'>;
|
|
236
|
+
export type ScanRequest = ({
|
|
237
|
+
path: string;
|
|
238
|
+
gitUrl?: never;
|
|
239
|
+
demo?: never;
|
|
240
|
+
} | {
|
|
241
|
+
gitUrl: string;
|
|
242
|
+
path?: never;
|
|
243
|
+
demo?: never;
|
|
244
|
+
} | {
|
|
245
|
+
demo: true;
|
|
246
|
+
path?: never;
|
|
247
|
+
gitUrl?: never;
|
|
248
|
+
}) & {
|
|
249
|
+
options?: ScanRequestOptions;
|
|
250
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contracts.js","sourceRoot":"","sources":["../src/shared/contracts.ts"],"names":[],"mappings":"","sourcesContent":["/** Portable contracts shared by the server, terminal app, and browser. */\nexport interface FileEntry {\n name: string;\n path: string;\n type: 'file' | 'dir';\n}\n\nexport interface FileSource {\n kind: string;\n root: string;\n name: string;\n list(directory: string): Promise<FileEntry[]>;\n read(path: string): Promise<string>;\n}\n\n/** A structural signal keeps the engine independent of Node and browser imports. */\nexport interface ScanSignal {\n readonly aborted: boolean;\n readonly reason?: unknown;\n addEventListener(type: 'abort', listener: () => void, options?: { once?: boolean }): void;\n removeEventListener(type: 'abort', listener: () => void): void;\n}\n\nexport type ScanProgress =\n | { phase: 'clone'; url: string }\n | { phase: 'walk'; found: number }\n | { phase: 'parse'; done: number; total: number }\n | { phase: 'resolve'; done: number; total: number }\n | { phase: 'complete'; files: number; edges: number };\n\nexport interface ScanOptions {\n maxFiles?: number;\n /** UTF-8 bytes, rather than JavaScript string length. */\n maxFileSize?: number;\n readConcurrency?: number;\n signal?: ScanSignal;\n onProgress?: (progress: ScanProgress) => void;\n}\n\nexport interface ScanLimits {\n maxFiles: number;\n maxFileSize: number;\n readConcurrency: number;\n}\n\nexport interface ImportInfo {\n spec: string;\n line?: number;\n symbols?: string[];\n kind?: string;\n local?: boolean;\n static?: boolean;\n typeOnly?: boolean;\n reexport?: boolean;\n packageName?: string;\n}\n\nexport interface ImportEdge {\n from: string;\n to: string;\n kind: string;\n symbols: string[];\n}\n\nexport interface Service {\n name: string;\n source: string;\n command?: string;\n build?: string;\n image?: string;\n ports?: string[];\n dependsOn?: string[];\n}\n\nexport interface Manifest {\n entryPoints: string[];\n services: Service[];\n packageName: string;\n scripts: string[];\n workspaces: string[];\n license?: string;\n hasServerScript?: boolean;\n composeFile?: string;\n deps: { npm: Record<string, string>; dev: Record<string, string>; pip: string[]; go: string[]; cargo: string[] };\n}\n\nexport interface ResolverContext {\n hasDir?: (path: string) => boolean;\n findDirEndingWith?: (suffix: string) => string | null;\n findByName?: (name: string) => string | null;\n modulePath?: string;\n tsPaths?: { baseUrl: string; paths: Record<string, string[]>; sourceRoot?: string; outputRoot?: string } | null;\n}\n\nexport interface ImportResolution {\n path?: string;\n packageDir?: string;\n external?: string;\n unresolved?: string;\n}\n\nexport interface AccountSettings {\n name: string;\n email: string;\n provider: string;\n baseUrl: string;\n model: string;\n}\n\nexport interface Settings {\n version: number;\n mode: 'local' | 'self-hosted';\n host: string;\n port: number;\n domain: string;\n https: boolean;\n accessKey: string;\n autoOpen: boolean;\n account: AccountSettings;\n tunnel: { cloudflare: boolean; tailscale: boolean };\n}\n\nexport interface SettingsInput {\n version?: unknown;\n mode?: unknown;\n host?: unknown;\n port?: unknown;\n domain?: unknown;\n https?: unknown;\n accessKey?: unknown;\n autoOpen?: unknown;\n account?: Partial<Record<keyof AccountSettings, unknown>>;\n tunnel?: { cloudflare?: unknown; tailscale?: unknown };\n}\n\nexport interface ServerUrls { local: string; network?: string; domain?: string }\n\nexport interface SymbolInfo {\n name: string;\n line?: number;\n kind?: string;\n calls?: string[];\n async?: boolean;\n exported?: boolean;\n pub?: boolean;\n genericArity?: number;\n decorators?: string[];\n annotations?: string[];\n attributes?: string[];\n}\n\nexport interface FileAnalysis {\n imports: ImportInfo[];\n exports: SymbolInfo[];\n functions: SymbolInfo[];\n classes: SymbolInfo[];\n interfaces?: SymbolInfo[];\n calls?: Array<{ from: string; to: string }>;\n hasMain?: boolean;\n decorators?: string[];\n annotations?: string[];\n attributes?: string[];\n packageName?: string;\n namespace?: string;\n}\n\nexport interface SecurityFinding {\n rule: string;\n severity: string;\n category: string;\n message: string;\n line: number;\n source?: string;\n tool?: string;\n}\n\nexport interface ScannedFile extends FileAnalysis {\n path: string;\n dir: string;\n name: string;\n ext: string;\n lang: string;\n size: number;\n loc: number;\n comment: number;\n blank: number;\n lines: number;\n docRatio: number;\n complexity: number;\n findings?: SecurityFinding[];\n cognitive?: number;\n maintainability?: number;\n}\n\nexport interface ScannedFolder {\n path: string;\n name: string;\n depth: number;\n fileCount: number;\n loc: number;\n comment: number;\n blank: number;\n size: number;\n langs: Record<string, number>;\n hasReadme: boolean;\n docRatio?: number;\n}\n\nexport interface LanguageAnalyzer {\n id: string;\n label: string;\n short: string;\n extensions: string[];\n analyze(source: string, path: string): FileAnalysis;\n resolveImport(spec: string, from: string, has: (path: string) => boolean, context?: ResolverContext, meta?: ImportInfo): ImportResolution;\n}\n\nexport type ScanRequestOptions = Pick<ScanOptions, 'maxFiles' | 'maxFileSize' | 'readConcurrency'>;\nexport type ScanRequest = (\n | { path: string; gitUrl?: never; demo?: never }\n | { gitUrl: string; path?: never; demo?: never }\n | { demo: true; path?: never; gitUrl?: never }\n) & { options?: ScanRequestOptions };\n"]}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export declare function diagramTarget(s: any): {
|
|
2
|
+
view: string;
|
|
3
|
+
path: any;
|
|
4
|
+
} | {
|
|
5
|
+
view: any;
|
|
6
|
+
path: string;
|
|
7
|
+
};
|
|
8
|
+
export declare function externalsFor(scan: any, path: any): any;
|
|
9
|
+
export declare function overviewFacts(scan: any, facts: any): {
|
|
10
|
+
kind: string;
|
|
11
|
+
facts: string[];
|
|
12
|
+
};
|
|
13
|
+
export declare function layersFacts(facts: any, patterns: any): {
|
|
14
|
+
kind: string;
|
|
15
|
+
facts: any[];
|
|
16
|
+
};
|
|
17
|
+
export declare function servicesFacts(scan: any, manifest: any): {
|
|
18
|
+
kind: string;
|
|
19
|
+
facts: string[];
|
|
20
|
+
};
|
|
21
|
+
export declare function fileFacts({ ctx, externals }: {
|
|
22
|
+
ctx: any;
|
|
23
|
+
externals: any;
|
|
24
|
+
}): {
|
|
25
|
+
kind: string;
|
|
26
|
+
facts: string[];
|
|
27
|
+
};
|
|
28
|
+
export declare function tourStopFacts({ ctx, externals, stop, index, total }: Record<string, any>): {
|
|
29
|
+
kind: string;
|
|
30
|
+
facts: string[];
|
|
31
|
+
};
|
|
32
|
+
export declare function folderFacts(scan: any, facts: any, folder: any): {
|
|
33
|
+
kind: string;
|
|
34
|
+
facts: string[];
|
|
35
|
+
};
|
|
@@ -9,137 +9,134 @@
|
|
|
9
9
|
//
|
|
10
10
|
// No DOM, no state import, no network: importable in Node, like everything
|
|
11
11
|
// under shared/.
|
|
12
|
-
|
|
13
12
|
import { topFolderOf } from '../analyzer/pathUtil.js';
|
|
14
13
|
import { scanIndex } from '../analyzer/graph.js';
|
|
15
|
-
|
|
16
14
|
// How much source text a file sheet may carry. Enough for the model to see the
|
|
17
15
|
// shape of a normal module; short enough to leave room for its answer.
|
|
18
16
|
const SOURCE_BUDGET = 9000;
|
|
19
|
-
|
|
20
17
|
// The repo-relative subject of the current view, and which sheet it wants.
|
|
21
18
|
// `view` here is the sheet's name, not the app's: an atlas card mirrors another
|
|
22
19
|
// view, and the files/deep-dive distinction becomes 'file' or 'folder'.
|
|
23
20
|
export function diagramTarget(s) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
21
|
+
if (s.view === 'atlas' && s.atlasOpen) {
|
|
22
|
+
const it = s.atlasOpen;
|
|
23
|
+
// A card shows exactly what its own view would show, so it asks for the
|
|
24
|
+
// same sheet. This used to be done by assigning to state.view, recursing,
|
|
25
|
+
// and putting the old values back in a `finally`.
|
|
26
|
+
if (it.kind === 'file')
|
|
27
|
+
return { view: 'file', path: it.path };
|
|
28
|
+
if (it.kind === 'folder')
|
|
29
|
+
return { view: 'folder', path: it.path };
|
|
30
|
+
if (it.kind === 'layers')
|
|
31
|
+
return { view: 'patterns', path: '' };
|
|
32
|
+
if (it.kind === 'overview')
|
|
33
|
+
return { view: 'map', path: '' };
|
|
34
|
+
return { view: it.kind, path: '' };
|
|
35
|
+
}
|
|
36
|
+
if (s.view === 'tour')
|
|
37
|
+
return { view: 'tour', path: s.tour.stops[s.tour.idx]?.path || '' };
|
|
38
|
+
if (s.view === 'map' || s.view === 'patterns' || s.view === 'services') {
|
|
39
|
+
return { view: s.view, path: '' };
|
|
40
|
+
}
|
|
41
|
+
// Everything else is the files view or one of its neighbours: a file if one
|
|
42
|
+
// is open in the deep-dive, otherwise the folder being shown.
|
|
43
|
+
return s.detail ? { view: 'file', path: s.detail } : { view: 'folder', path: s.folder };
|
|
42
44
|
}
|
|
43
|
-
|
|
44
45
|
// The third-party packages one file uses, by name.
|
|
45
46
|
export function externalsFor(scan, path) {
|
|
46
|
-
|
|
47
|
+
return (scan.externals || []).filter((x) => x.usedBy.includes(path)).map((x) => x.name);
|
|
47
48
|
}
|
|
48
|
-
|
|
49
49
|
export function overviewFacts(scan, facts) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
50
|
+
const counts = new Map();
|
|
51
|
+
for (const f of scan.files) {
|
|
52
|
+
const top = topFolderOf(f.path);
|
|
53
|
+
counts.set(top, (counts.get(top) || 0) + 1);
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
kind: 'overview map',
|
|
57
|
+
facts: [
|
|
58
|
+
'Top folders (parsed file count): ' + [...counts.entries()].map(([k, v]) => `${k} (${v})`).join(', '),
|
|
59
|
+
'Dependencies between folders (from -> to: edge count): ' + (facts.folderEdges.map((e) => `${e.from} -> ${e.to}: ${e.count}`).join('; ') || 'none'),
|
|
60
|
+
'Entry points: ' + (facts.entries.join(', ') || 'none found'),
|
|
61
|
+
'Most depended-on files (fan-in): ' + (facts.hubs.slice(0, 6).map((h) => `${h.path} (${h.fanIn})`).join(', ') || 'none'),
|
|
62
|
+
],
|
|
63
|
+
};
|
|
64
64
|
}
|
|
65
|
-
|
|
66
65
|
export function layersFacts(facts, patterns) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
66
|
+
const L = patterns.layersInfo;
|
|
67
|
+
return {
|
|
68
|
+
kind: 'architecture layers diagram',
|
|
69
|
+
facts: [
|
|
70
|
+
'Files grouped by import depth (longest chain from an entry point):',
|
|
71
|
+
...L.layers.map((l, i) => ` depth ${i}: ${l.slice(0, 14).join(', ')}${l.length > 14 ? ` …+${l.length - 14} more` : ''}`),
|
|
72
|
+
'Not reachable from any entry: ' + (L.unreachable.slice(0, 10).join(', ') || 'none'),
|
|
73
|
+
'Circular dependency loops: ' + (facts.cycles.map((c) => c.slice(0, 6).join(' <-> ')).join('; ') || 'none'),
|
|
74
|
+
'Hubs (fan-in): ' + (facts.hubs.slice(0, 6).map((h) => `${h.path} (${h.fanIn})`).join(', ') || 'none'),
|
|
75
|
+
],
|
|
76
|
+
};
|
|
78
77
|
}
|
|
79
|
-
|
|
80
78
|
export function servicesFacts(scan, manifest) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
79
|
+
return {
|
|
80
|
+
kind: 'services diagram',
|
|
81
|
+
facts: [
|
|
82
|
+
'Services (name | image | build | ports | command): ' +
|
|
83
|
+
((manifest.services || []).map((s) => [s.name, s.image, s.build, (s.ports || []).join('+'), s.command].filter(Boolean).join(' | ')).join('; ') || 'none detected'),
|
|
84
|
+
'Top folders: ' + scan.folders.filter((f) => f.depth === 1).slice(0, 8).map((f) => f.path).join(', '),
|
|
85
|
+
],
|
|
86
|
+
};
|
|
89
87
|
}
|
|
90
|
-
|
|
91
88
|
// The deep-dive sheet: one file, its neighbours, and its source if we have it.
|
|
92
89
|
export function fileFacts({ ctx, externals }) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
90
|
+
return {
|
|
91
|
+
kind: 'file deep-dive flowchart',
|
|
92
|
+
facts: [
|
|
93
|
+
`File: ${ctx.path} (role: ${ctx.role})`,
|
|
94
|
+
`Imported by ${ctx.fanIn} files: ${ctx.importers.join(', ') || 'none'}`,
|
|
95
|
+
`Imports ${ctx.fanOut} files: ${ctx.imports.join(', ') || 'none'}`,
|
|
96
|
+
`External packages: ${externals.join(', ') || 'none'}`,
|
|
97
|
+
ctx.functions?.length ? `Functions: ${ctx.functions.join(', ')}` : '',
|
|
98
|
+
ctx.source ? `Source, possibly truncated:\n${ctx.source.slice(0, SOURCE_BUDGET)}` : '(source unavailable)',
|
|
99
|
+
].filter(Boolean),
|
|
100
|
+
};
|
|
104
101
|
}
|
|
105
|
-
|
|
106
102
|
// The same file, but framed as a stop on the newcomer's tour: the model is told
|
|
107
103
|
// where it is in the sequence and why the guide stopped, which is what turns a
|
|
108
104
|
// dependency picture into an explanation.
|
|
109
105
|
export function tourStopFacts({ ctx, externals, stop, index, total }) {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
106
|
+
if (!stop)
|
|
107
|
+
return { kind: 'tour stop diagram', facts: ['No stop is selected.'] };
|
|
108
|
+
return {
|
|
109
|
+
kind: 'guided-tour stop diagram',
|
|
110
|
+
facts: [
|
|
111
|
+
`This is stop ${index + 1} of ${total} on a newcomer's guided tour of the repo.`,
|
|
112
|
+
`Why the guide stops here: ${stop.why}`,
|
|
113
|
+
`File: ${ctx.path} (role: ${ctx.role})`,
|
|
114
|
+
`Imported by ${ctx.fanIn} files: ${ctx.importers.join(', ') || 'none'}`,
|
|
115
|
+
`Imports ${ctx.fanOut} files: ${ctx.imports.join(', ') || 'none'}`,
|
|
116
|
+
`External packages: ${externals.join(', ') || 'none'}`,
|
|
117
|
+
ctx.functions?.length ? `Functions: ${ctx.functions.join(', ')}` : '',
|
|
118
|
+
ctx.source ? `Source, possibly truncated:\n${ctx.source.slice(0, SOURCE_BUDGET)}` : '(source unavailable)',
|
|
119
|
+
'Draw what a guide would point at: how this file connects to the repo around it, and the flow between its main parts.',
|
|
120
|
+
].filter(Boolean),
|
|
121
|
+
};
|
|
125
122
|
}
|
|
126
|
-
|
|
127
123
|
export function folderFacts(scan, facts, folder) {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
124
|
+
const here = scanIndex(scan).filesIn(folder);
|
|
125
|
+
const localSet = new Set(here.map((f) => f.path));
|
|
126
|
+
const internal = scan.edges.filter((e) => localSet.has(e.from) && localSet.has(e.to));
|
|
127
|
+
const outward = scan.edges.filter((e) => localSet.has(e.from) && !localSet.has(e.to));
|
|
128
|
+
const inward = scan.edges.filter((e) => !localSet.has(e.from) && localSet.has(e.to));
|
|
129
|
+
return {
|
|
130
|
+
kind: 'folder import graph',
|
|
131
|
+
facts: [
|
|
132
|
+
`Folder: ${folder || '(repo root)'} — ${here.length} parsed files`,
|
|
133
|
+
'Files (fan-in/fan-out): ' + here.map((f) => `${f.path} (${facts.fanIn[f.path] || 0}/${facts.fanOut[f.path] || 0})`).join(', '),
|
|
134
|
+
'Edges inside the folder: ' + (internal.map((e) => `${e.from} -> ${e.to}`).join('; ') || 'none'),
|
|
135
|
+
// Capped: a folder that everything imports would otherwise fill the
|
|
136
|
+
// prompt with edges and crowd out the rest of the sheet.
|
|
137
|
+
'Reaching out of it: ' + (outward.slice(0, 12).map((e) => `${e.from} -> ${e.to}`).join('; ') || 'none'),
|
|
138
|
+
'Pulled in from outside: ' + (inward.slice(0, 12).map((e) => `${e.from} -> ${e.to}`).join('; ') || 'none'),
|
|
139
|
+
],
|
|
140
|
+
};
|
|
145
141
|
}
|
|
142
|
+
//# sourceMappingURL=aiFacts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aiFacts.js","sourceRoot":"","sources":["../../src/shared/diagram/aiFacts.ts"],"names":[],"mappings":"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","sourcesContent":["// The fact sheets the AI draws from.\n//\n// Every \"AI draft\" of a diagram is a prompt plus a list of plain-English facts\n// pulled out of the graph. Keeping the sheets here, apart from the streaming and\n// the button states, has two payoffs: the wording is what the model actually\n// sees and can be read without a browser, and the fiddly question of *which*\n// sheet a given view wants — an opened atlas card borrows another view's — is a\n// pure function with a test rather than a temporary mutation of app state.\n//\n// No DOM, no state import, no network: importable in Node, like everything\n// under shared/.\n\nimport { topFolderOf } from '../analyzer/pathUtil.js';\nimport { scanIndex } from '../analyzer/graph.js';\n\n// How much source text a file sheet may carry. Enough for the model to see the\n// shape of a normal module; short enough to leave room for its answer.\nconst SOURCE_BUDGET = 9000;\n\n// The repo-relative subject of the current view, and which sheet it wants.\n// `view` here is the sheet's name, not the app's: an atlas card mirrors another\n// view, and the files/deep-dive distinction becomes 'file' or 'folder'.\nexport function diagramTarget(s) {\n if (s.view === 'atlas' && s.atlasOpen) {\n const it = s.atlasOpen;\n // A card shows exactly what its own view would show, so it asks for the\n // same sheet. This used to be done by assigning to state.view, recursing,\n // and putting the old values back in a `finally`.\n if (it.kind === 'file') return { view: 'file', path: it.path };\n if (it.kind === 'folder') return { view: 'folder', path: it.path };\n if (it.kind === 'layers') return { view: 'patterns', path: '' };\n if (it.kind === 'overview') return { view: 'map', path: '' };\n return { view: it.kind, path: '' };\n }\n if (s.view === 'tour') return { view: 'tour', path: s.tour.stops[s.tour.idx]?.path || '' };\n if (s.view === 'map' || s.view === 'patterns' || s.view === 'services') {\n return { view: s.view, path: '' };\n }\n // Everything else is the files view or one of its neighbours: a file if one\n // is open in the deep-dive, otherwise the folder being shown.\n return s.detail ? { view: 'file', path: s.detail } : { view: 'folder', path: s.folder };\n}\n\n// The third-party packages one file uses, by name.\nexport function externalsFor(scan, path) {\n return (scan.externals || []).filter((x) => x.usedBy.includes(path)).map((x) => x.name);\n}\n\nexport function overviewFacts(scan, facts) {\n const counts = new Map();\n for (const f of scan.files) {\n const top = topFolderOf(f.path);\n counts.set(top, (counts.get(top) || 0) + 1);\n }\n return {\n kind: 'overview map',\n facts: [\n 'Top folders (parsed file count): ' + [...counts.entries()].map(([k, v]) => `${k} (${v})`).join(', '),\n 'Dependencies between folders (from -> to: edge count): ' + (facts.folderEdges.map((e) => `${e.from} -> ${e.to}: ${e.count}`).join('; ') || 'none'),\n 'Entry points: ' + (facts.entries.join(', ') || 'none found'),\n 'Most depended-on files (fan-in): ' + (facts.hubs.slice(0, 6).map((h) => `${h.path} (${h.fanIn})`).join(', ') || 'none'),\n ],\n };\n}\n\nexport function layersFacts(facts, patterns) {\n const L = patterns.layersInfo;\n return {\n kind: 'architecture layers diagram',\n facts: [\n 'Files grouped by import depth (longest chain from an entry point):',\n ...L.layers.map((l, i) => ` depth ${i}: ${l.slice(0, 14).join(', ')}${l.length > 14 ? ` …+${l.length - 14} more` : ''}`),\n 'Not reachable from any entry: ' + (L.unreachable.slice(0, 10).join(', ') || 'none'),\n 'Circular dependency loops: ' + (facts.cycles.map((c) => c.slice(0, 6).join(' <-> ')).join('; ') || 'none'),\n 'Hubs (fan-in): ' + (facts.hubs.slice(0, 6).map((h) => `${h.path} (${h.fanIn})`).join(', ') || 'none'),\n ],\n };\n}\n\nexport function servicesFacts(scan, manifest) {\n return {\n kind: 'services diagram',\n facts: [\n 'Services (name | image | build | ports | command): ' +\n ((manifest.services || []).map((s) => [s.name, s.image, s.build, (s.ports || []).join('+'), s.command].filter(Boolean).join(' | ')).join('; ') || 'none detected'),\n 'Top folders: ' + scan.folders.filter((f) => f.depth === 1).slice(0, 8).map((f) => f.path).join(', '),\n ],\n };\n}\n\n// The deep-dive sheet: one file, its neighbours, and its source if we have it.\nexport function fileFacts({ ctx, externals }) {\n return {\n kind: 'file deep-dive flowchart',\n facts: [\n `File: ${ctx.path} (role: ${ctx.role})`,\n `Imported by ${ctx.fanIn} files: ${ctx.importers.join(', ') || 'none'}`,\n `Imports ${ctx.fanOut} files: ${ctx.imports.join(', ') || 'none'}`,\n `External packages: ${externals.join(', ') || 'none'}`,\n ctx.functions?.length ? `Functions: ${ctx.functions.join(', ')}` : '',\n ctx.source ? `Source, possibly truncated:\\n${ctx.source.slice(0, SOURCE_BUDGET)}` : '(source unavailable)',\n ].filter(Boolean),\n };\n}\n\n// The same file, but framed as a stop on the newcomer's tour: the model is told\n// where it is in the sequence and why the guide stopped, which is what turns a\n// dependency picture into an explanation.\nexport function tourStopFacts({ ctx, externals, stop, index, total }: Record<string, any>) {\n if (!stop) return { kind: 'tour stop diagram', facts: ['No stop is selected.'] };\n return {\n kind: 'guided-tour stop diagram',\n facts: [\n `This is stop ${index + 1} of ${total} on a newcomer's guided tour of the repo.`,\n `Why the guide stops here: ${stop.why}`,\n `File: ${ctx.path} (role: ${ctx.role})`,\n `Imported by ${ctx.fanIn} files: ${ctx.importers.join(', ') || 'none'}`,\n `Imports ${ctx.fanOut} files: ${ctx.imports.join(', ') || 'none'}`,\n `External packages: ${externals.join(', ') || 'none'}`,\n ctx.functions?.length ? `Functions: ${ctx.functions.join(', ')}` : '',\n ctx.source ? `Source, possibly truncated:\\n${ctx.source.slice(0, SOURCE_BUDGET)}` : '(source unavailable)',\n 'Draw what a guide would point at: how this file connects to the repo around it, and the flow between its main parts.',\n ].filter(Boolean),\n };\n}\n\nexport function folderFacts(scan, facts, folder) {\n const here = scanIndex(scan).filesIn(folder);\n const localSet = new Set(here.map((f) => f.path));\n const internal = scan.edges.filter((e) => localSet.has(e.from) && localSet.has(e.to));\n const outward = scan.edges.filter((e) => localSet.has(e.from) && !localSet.has(e.to));\n const inward = scan.edges.filter((e) => !localSet.has(e.from) && localSet.has(e.to));\n return {\n kind: 'folder import graph',\n facts: [\n `Folder: ${folder || '(repo root)'} — ${here.length} parsed files`,\n 'Files (fan-in/fan-out): ' + here.map((f) => `${f.path} (${facts.fanIn[f.path] || 0}/${facts.fanOut[f.path] || 0})`).join(', '),\n 'Edges inside the folder: ' + (internal.map((e) => `${e.from} -> ${e.to}`).join('; ') || 'none'),\n // Capped: a folder that everything imports would otherwise fill the\n // prompt with edges and crowd out the rest of the sheet.\n 'Reaching out of it: ' + (outward.slice(0, 12).map((e) => `${e.from} -> ${e.to}`).join('; ') || 'none'),\n 'Pulled in from outside: ' + (inward.slice(0, 12).map((e) => `${e.from} -> ${e.to}`).join('; ') || 'none'),\n ],\n };\n}\n"]}
|