codebase-onboarder 0.6.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 +174 -46
- 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 +321 -329
- package/cli/explorer/advanced.js.map +1 -0
- package/cli/explorer/app.d.ts +1 -0
- package/cli/explorer/app.js +384 -313
- 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 +368 -302
- 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 +42 -44
- package/cli/explorer/github.js.map +1 -0
- package/cli/explorer/graphs.d.ts +7 -0
- package/cli/explorer/graphs.js +90 -95
- 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 +143 -144
- package/cli/explorer/session.js.map +1 -0
- package/cli/explorer/views.d.ts +19 -0
- package/cli/explorer/views.js +465 -482
- package/cli/explorer/views.js.map +1 -0
- package/cli/explorer/wrap.d.ts +1 -0
- package/cli/explorer/wrap.js +28 -44
- package/cli/explorer/wrap.js.map +1 -0
- package/cli/main.d.ts +1 -0
- package/cli/main.js +214 -161
- 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 +35 -44
- 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 +152 -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 +37 -38
- 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 -64
- 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 +41 -43
- 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
package/public/js/llm.js
CHANGED
|
@@ -1,292 +1,257 @@
|
|
|
1
1
|
// LLM settings and prompt assembly. The key lives in localStorage and only
|
|
2
2
|
// ever travels to the local server, which forwards it to whatever
|
|
3
3
|
// OpenAI-compatible endpoint the user pointed at.
|
|
4
|
-
|
|
5
4
|
const STORE_KEY = 'onboarder.llm.v1';
|
|
6
|
-
|
|
7
5
|
// No endpoint, model, or key ships with the repo. Anything saved in the
|
|
8
6
|
// API-key drawer overrides these empty defaults (localStorage wins); without
|
|
9
7
|
// a saved endpoint the app stays on the offline graph explanations.
|
|
10
8
|
export const DEFAULT_SETTINGS = {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
baseUrl: '',
|
|
10
|
+
apiKey: '',
|
|
11
|
+
model: '',
|
|
14
12
|
};
|
|
15
|
-
|
|
16
13
|
export function getSettings() {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
try {
|
|
15
|
+
return { ...DEFAULT_SETTINGS, ...JSON.parse(localStorage.getItem(STORE_KEY) || '{}') };
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return { ...DEFAULT_SETTINGS };
|
|
19
|
+
}
|
|
22
20
|
}
|
|
23
|
-
|
|
24
21
|
export function saveSettings(settings) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
22
|
+
localStorage.setItem(STORE_KEY, JSON.stringify({
|
|
23
|
+
baseUrl: (settings.baseUrl || '').trim().replace(/\/+$/, ''),
|
|
24
|
+
apiKey: settings.apiKey || '',
|
|
25
|
+
model: (settings.model || '').trim(),
|
|
26
|
+
}));
|
|
30
27
|
}
|
|
31
|
-
|
|
32
28
|
export function isConfigured() {
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
const s = getSettings();
|
|
30
|
+
return Boolean(s.baseUrl && s.model);
|
|
35
31
|
}
|
|
36
|
-
|
|
37
32
|
// Azure OpenAI speaks a slightly different dialect than the rest: api-key
|
|
38
33
|
// header (handled server-side) and no `reasoning` request parameter.
|
|
39
34
|
export function isAzureHost(baseUrl) {
|
|
40
|
-
|
|
35
|
+
return /\.openai\.azure\.com|\.cognitiveservices\.azure\.com/i.test(baseUrl || '');
|
|
41
36
|
}
|
|
42
|
-
|
|
43
37
|
const SYSTEM_PROMPT = [
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
38
|
+
'You are a senior engineer walking a new teammate through a codebase they have never seen.',
|
|
39
|
+
'Write like a person, not a product page: plain sentences, concrete names, no hype, no bullet-point cosplay unless a list is genuinely clearer.',
|
|
40
|
+
'Keep it under 180 words. Refer to files and functions by their real names in backticks.',
|
|
41
|
+
'If something looks risky to change, say so plainly.',
|
|
48
42
|
].join(' ');
|
|
49
|
-
|
|
50
43
|
export function fileMessages({ repoName, overview, path, role, fanIn, fanOut, importers, imports, functions, exports_, source }) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
{ role: 'user', content: user },
|
|
69
|
-
];
|
|
44
|
+
const context = [
|
|
45
|
+
`Repository: ${repoName}`,
|
|
46
|
+
overview ? `Big picture: ${overview}` : '',
|
|
47
|
+
'',
|
|
48
|
+
`File: ${path} (role: ${role})`,
|
|
49
|
+
`Imported by ${fanIn} files: ${importers.slice(0, 8).join(', ') || 'none'}`,
|
|
50
|
+
`Imports ${fanOut} files: ${imports.slice(0, 8).join(', ') || 'none'}`,
|
|
51
|
+
functions?.length ? `Functions: ${functions.slice(0, 14).join(', ')}` : '',
|
|
52
|
+
exports_?.length ? `Exports: ${exports_.slice(0, 10).join(', ')}` : '',
|
|
53
|
+
].filter(Boolean).join('\n');
|
|
54
|
+
const user = source
|
|
55
|
+
? `${context}\n\nHere is the source, possibly truncated:\n\`\`\`\n${source.slice(0, 12000)}\n\`\`\`\n\nExplain what this file does, how it fits into the repo, and what breaks if it is deleted.`
|
|
56
|
+
: `${context}\n\n(Source was not available.) Explain what this file most likely does, how it fits into the repo, and what breaks if it is deleted. Say what you are inferring versus what the graph proves.`;
|
|
57
|
+
return [
|
|
58
|
+
{ role: 'system', content: SYSTEM_PROMPT },
|
|
59
|
+
{ role: 'user', content: user },
|
|
60
|
+
];
|
|
70
61
|
}
|
|
71
|
-
|
|
72
62
|
export function overviewMessages({ repoName, overview, entries, hubs, services, cycles, orphans, languages }) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
];
|
|
63
|
+
const user = [
|
|
64
|
+
`Repository: ${repoName}`,
|
|
65
|
+
`Languages: ${languages}`,
|
|
66
|
+
overview ? `Static notes: ${overview}` : '',
|
|
67
|
+
entries?.length ? `Entry points: ${entries.slice(0, 5).join(', ')}` : '',
|
|
68
|
+
hubs?.length ? `Most-depended-on files: ${hubs.slice(0, 5).map((h) => h.path + ' (' + h.fanIn + ')').join(', ')}` : '',
|
|
69
|
+
services?.length ? `Services: ${services.map((s) => s.name).join(', ')}` : '',
|
|
70
|
+
cycles?.length ? `${cycles.length} circular dependencies` : '',
|
|
71
|
+
orphans?.length ? `${orphans.length} files imported by nothing` : '',
|
|
72
|
+
'',
|
|
73
|
+
'Give a new teammate the orientation you would give on their first day: what this thing is, where to start reading, and which files to treat with respect.',
|
|
74
|
+
].filter(Boolean).join('\n');
|
|
75
|
+
return [
|
|
76
|
+
{ role: 'system', content: SYSTEM_PROMPT },
|
|
77
|
+
{ role: 'user', content: user },
|
|
78
|
+
];
|
|
90
79
|
}
|
|
91
|
-
|
|
92
80
|
// Diagram generation prompts. The model gets compact graph facts and returns
|
|
93
81
|
// a Mermaid flowchart with a caption; the theme is injected by us afterwards
|
|
94
82
|
// so AI drafts look exactly like the hand-drawn ones.
|
|
95
|
-
|
|
96
83
|
const DIAGRAM_PROMPT = [
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
84
|
+
'You turn codebase facts into Mermaid flowcharts that teach.',
|
|
85
|
+
'Output format, exactly: first line `%% caption: <one honest sentence about what the diagram shows>`, then the flowchart source. Nothing else — no fences, no commentary, no sign-off.',
|
|
86
|
+
'Rules: start with `flowchart LR` or `flowchart TD` on its own line; use short alphanumeric ids (a1, b2); put every label in "double quotes"; at most 36 nodes; group with subgraphs where it helps; A --> B means A depends on B; no click, style or linkStyle statements.',
|
|
87
|
+
'Where you can infer what a group of files is FOR, name the cluster by its purpose instead of repeating folder names.',
|
|
101
88
|
].join(' ');
|
|
102
|
-
|
|
103
89
|
export function diagramMessages({ repoName, kind, facts }) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
];
|
|
90
|
+
const user = [
|
|
91
|
+
`Repository: ${repoName}`,
|
|
92
|
+
`Diagram to draw: ${kind}`,
|
|
93
|
+
'Facts:',
|
|
94
|
+
facts.join('\n'),
|
|
95
|
+
'',
|
|
96
|
+
`Draw the most useful ${kind} for someone who has never seen this codebase.`,
|
|
97
|
+
].join('\n');
|
|
98
|
+
return [
|
|
99
|
+
{ role: 'system', content: DIAGRAM_PROMPT },
|
|
100
|
+
{ role: 'user', content: user },
|
|
101
|
+
];
|
|
117
102
|
}
|
|
118
|
-
|
|
119
103
|
// ---- documentation prompts -------------------------------------------------
|
|
120
|
-
|
|
121
104
|
const DOC_SYSTEM = [
|
|
122
|
-
|
|
123
|
-
|
|
105
|
+
'You write documentation for a codebase as a senior engineer would: concrete, calm, specific.',
|
|
106
|
+
'Plain sentences. Real names. No hype, no filler, no "this file plays a crucial role".',
|
|
124
107
|
].join(' ');
|
|
125
|
-
|
|
126
108
|
// Detailed reference notes for one file or folder, opened as a tab in Docs.
|
|
127
109
|
const FILE_DOC_SYSTEM = [
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
110
|
+
'You write detailed reference notes for one file in a codebase, as a senior engineer would for a new teammate.',
|
|
111
|
+
'Concrete and specific: real names, real numbers, no filler. Answer in Markdown with exactly these sections, in this order:',
|
|
112
|
+
'## Purpose',
|
|
113
|
+
'## How it fits',
|
|
114
|
+
'## Key parts',
|
|
115
|
+
'## Handle with care',
|
|
116
|
+
'Keep "Key parts" a short bullet list of the functions or exports that matter. Under 350 words total. If a section honestly has nothing to say, one line saying so.',
|
|
135
117
|
].join('\n');
|
|
136
|
-
|
|
137
118
|
const FOLDER_DOC_SYSTEM = [
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
119
|
+
'You write detailed reference notes for one folder in a codebase, as a senior engineer would for a new teammate.',
|
|
120
|
+
'Concrete and specific: real names, no filler. Answer in Markdown with exactly these sections, in this order:',
|
|
121
|
+
'## Purpose',
|
|
122
|
+
'## How the parts cooperate',
|
|
123
|
+
'## The files that matter',
|
|
124
|
+
'## Handle with care',
|
|
125
|
+
'Under 300 words total. Say what you infer from names and import facts versus what you know.',
|
|
145
126
|
].join('\n');
|
|
146
|
-
|
|
147
127
|
export function fileDocMessages({ repoName, overview, file }) {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
128
|
+
const blocks = [
|
|
129
|
+
`Repository: ${repoName}`,
|
|
130
|
+
overview ? `Big picture: ${overview}` : '',
|
|
131
|
+
`File: ${file.path} (role: ${file.role})`,
|
|
132
|
+
`Imported by ${file.fanIn} files: ${file.importers.slice(0, 8).join(', ') || 'none'}`,
|
|
133
|
+
`Imports ${file.fanOut} files: ${file.imports.slice(0, 8).join(', ') || 'none'}`,
|
|
134
|
+
file.functions?.length ? `Functions: ${file.functions.slice(0, 14).join(', ')}` : '',
|
|
135
|
+
file.exports_?.length ? `Exports: ${file.exports_.slice(0, 10).join(', ')}` : '',
|
|
136
|
+
file.source
|
|
137
|
+
? `Source, possibly truncated:\n\`\`\`\n${file.source.slice(0, 12000)}\n\`\`\``
|
|
138
|
+
: '(Source unavailable — write from the graph facts and say what you are inferring.)',
|
|
139
|
+
].filter(Boolean);
|
|
140
|
+
return [
|
|
141
|
+
{ role: 'system', content: FILE_DOC_SYSTEM },
|
|
142
|
+
{ role: 'user', content: blocks.join('\n') },
|
|
143
|
+
];
|
|
164
144
|
}
|
|
165
|
-
|
|
166
145
|
export function folderDocDetailedMessages({ repoName, folder, subfolders, files }) {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
'
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
{ role: 'user', content: user },
|
|
182
|
-
];
|
|
146
|
+
const lines = files.map((f) => `- ${f.name} — ${f.fanIn} dependents, pulls in ${f.fanOut}` +
|
|
147
|
+
(f.role !== 'module' ? `, role: ${f.role}` : '') +
|
|
148
|
+
(f.functions.length ? `, functions: ${f.functions.slice(0, 5).join(', ')}` : ''));
|
|
149
|
+
const user = [
|
|
150
|
+
`Repository: ${repoName}`,
|
|
151
|
+
`Folder: ${folder || '(repo root)'}`,
|
|
152
|
+
subfolders?.length ? `Subfolders: ${subfolders.join(', ')}` : '',
|
|
153
|
+
'Files with import-graph facts:',
|
|
154
|
+
lines.join('\n') || '(no files directly here)',
|
|
155
|
+
].filter(Boolean).join('\n');
|
|
156
|
+
return [
|
|
157
|
+
{ role: 'system', content: FOLDER_DOC_SYSTEM },
|
|
158
|
+
{ role: 'user', content: user },
|
|
159
|
+
];
|
|
183
160
|
}
|
|
184
|
-
|
|
185
161
|
export function repoDocMessages({ repoName, overview, readmeExcerpt, entries, hubs }) {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
];
|
|
162
|
+
const user = [
|
|
163
|
+
`Repository: ${repoName}`,
|
|
164
|
+
overview ? `Static analysis notes: ${overview}` : '',
|
|
165
|
+
entries?.length ? `Entry points: ${entries.slice(0, 5).join(', ')}` : '',
|
|
166
|
+
hubs?.length ? `Most depended-on files: ${hubs.slice(0, 5).map((h) => h.path + ' (' + h.fanIn + ')').join(', ')}` : '',
|
|
167
|
+
readmeExcerpt ? `The project's own README begins:\n"""\n${readmeExcerpt.slice(0, 1500)}\n"""` : '(No README found.)',
|
|
168
|
+
'',
|
|
169
|
+
'Write 3–4 sentences of high-level overview for a brand-new teammate: what this project is, how it is organized at the top level, and where to start reading. Plain prose only — no headings, no bullets.',
|
|
170
|
+
].filter(Boolean).join('\n');
|
|
171
|
+
return [
|
|
172
|
+
{ role: 'system', content: DOC_SYSTEM },
|
|
173
|
+
{ role: 'user', content: user },
|
|
174
|
+
];
|
|
200
175
|
}
|
|
201
|
-
|
|
202
176
|
export function folderDocMessages({ repoName, folder, subfolders, files }) {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
177
|
+
const fileLines = files.map((f) => {
|
|
178
|
+
if (!f.parsed)
|
|
179
|
+
return `- ${f.name} — not parsed (asset or data)`;
|
|
180
|
+
const bits = [`${f.fanIn} dependents`, `pulls in ${f.fanOut}`];
|
|
181
|
+
if (f.role !== 'module')
|
|
182
|
+
bits.push('role: ' + f.role);
|
|
183
|
+
if (f.functions.length)
|
|
184
|
+
bits.push('functions: ' + f.functions.slice(0, 5).join(', '));
|
|
185
|
+
return `- ${f.name} — ${bits.join(', ')}`;
|
|
186
|
+
});
|
|
187
|
+
const user = [
|
|
188
|
+
`Repository: ${repoName}`,
|
|
189
|
+
`Folder under review: ${folder || '(repo root)'}`,
|
|
190
|
+
subfolders?.length ? `Subfolders inside it: ${subfolders.join(', ')}` : '',
|
|
191
|
+
'Files (with import-graph facts):',
|
|
192
|
+
fileLines.join('\n') || '(no files directly here)',
|
|
193
|
+
'',
|
|
194
|
+
'Write complete documentation for this folder, in exactly this format, no preamble, no fences:',
|
|
195
|
+
'FOLDER: <3-5 sentences — what lives here, why it exists, how the parts cooperate, and what a newcomer should read first>',
|
|
196
|
+
...files.filter((f) => f.parsed).map((f) => `FILE: ${f.name}: <2-3 sentences — what this file is for, who it talks to, and what to handle with care>`),
|
|
197
|
+
].filter(Boolean).join('\n');
|
|
198
|
+
return [
|
|
199
|
+
{ role: 'system', content: DOC_SYSTEM },
|
|
200
|
+
{ role: 'user', content: user },
|
|
201
|
+
];
|
|
227
202
|
}
|
|
228
|
-
|
|
229
203
|
const QUESTION_PROMPT = [
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
204
|
+
'You are a senior engineer answering a teammate\'s question about a codebase.',
|
|
205
|
+
'Answer directly and concretely, citing real file and function names in backticks.',
|
|
206
|
+
'If the answer is not in the graph facts or source you were given, say so plainly and name the file you would open next to find out.',
|
|
207
|
+
'Keep it under 200 words unless the question genuinely needs more.',
|
|
234
208
|
].join(' ');
|
|
235
|
-
|
|
236
209
|
// A free-form question. When the user has a file selected, its facts and
|
|
237
210
|
// source ride along; otherwise the model reasons from the repo overview.
|
|
238
211
|
export function questionMessages({ repoName, overview, question, file }) {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
blocks.push('(Source for that file was not available — answer from the graph facts and say so.)');
|
|
212
|
+
const blocks = [
|
|
213
|
+
`Repository: ${repoName}`,
|
|
214
|
+
overview ? `Big picture: ${overview}` : '',
|
|
215
|
+
];
|
|
216
|
+
if (file) {
|
|
217
|
+
blocks.push(`The user is currently looking at: ${file.path} (role: ${file.role})`, `Imported by ${file.fanIn} files: ${file.importers.slice(0, 8).join(', ') || 'none'}`, `Imports ${file.fanOut} files: ${file.imports.slice(0, 8).join(', ') || 'none'}`);
|
|
218
|
+
if (file.functions?.length)
|
|
219
|
+
blocks.push(`Functions: ${file.functions.slice(0, 14).join(', ')}`);
|
|
220
|
+
if (file.exports_?.length)
|
|
221
|
+
blocks.push(`Exports: ${file.exports_.slice(0, 10).join(', ')}`);
|
|
222
|
+
if (file.source) {
|
|
223
|
+
blocks.push(`Source of ${file.path}, possibly truncated:\n\`\`\`\n${file.source.slice(0, 12000)}\n\`\`\``);
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
blocks.push('(Source for that file was not available — answer from the graph facts and say so.)');
|
|
227
|
+
}
|
|
256
228
|
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
{ role: 'system', content: QUESTION_PROMPT },
|
|
263
|
-
{ role: 'user', content: blocks.filter(Boolean).join('\n') },
|
|
264
|
-
];
|
|
229
|
+
blocks.push(`Question: ${question}`);
|
|
230
|
+
return [
|
|
231
|
+
{ role: 'system', content: QUESTION_PROMPT },
|
|
232
|
+
{ role: 'user', content: blocks.filter(Boolean).join('\n') },
|
|
233
|
+
];
|
|
265
234
|
}
|
|
266
|
-
|
|
267
|
-
|
|
268
235
|
// Used by the About tab to summarize a detected framework/library: the model
|
|
269
236
|
// reasons from the official docs excerpt (when fetched) plus the repo's own
|
|
270
237
|
// context. docsText may be empty — the prompt says so and falls back to
|
|
271
238
|
// general knowledge.
|
|
272
239
|
export function stackSummaryMessages({ repoName, item, docsText, repoNote }) {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
return [{ role: 'system', content: system }, { role: 'user', content: user }];
|
|
240
|
+
const system = 'You are a senior developer writing compact field notes for a codebase onboarding tool. Be specific and honest; distinguish between what the docs state and what you infer. No headings, no "Sure" / "Absolutely" openers, no filler.';
|
|
241
|
+
const declared = item.version
|
|
242
|
+
? `The project declares ${item.name} ${item.version} (${item.category}, ${item.lang}${item.dev ? ', dev dependency' : ''}).`
|
|
243
|
+
: `The project uses ${item.name} (${item.category}, ${item.lang}).`;
|
|
244
|
+
const user = [
|
|
245
|
+
`Repository: ${repoName}.`,
|
|
246
|
+
declared,
|
|
247
|
+
`Repo context: ${repoNote}`,
|
|
248
|
+
docsText
|
|
249
|
+
? `Official docs excerpt:\n${docsText}`
|
|
250
|
+
: 'No official docs could be fetched for this dependency — rely on your own knowledge and say so in one short clause.',
|
|
251
|
+
'In 2-4 sentences: what this is, why the project likely chose it, and anything a new teammate should know about using it here.',
|
|
252
|
+
].join('\n\n');
|
|
253
|
+
return [{ role: 'system', content: system }, { role: 'user', content: user }];
|
|
288
254
|
}
|
|
289
|
-
|
|
290
255
|
// The Deep Analysis report, read back by the model. Two jobs in one builder: a
|
|
291
256
|
// report is either *explained* (no question — prioritize what to fix) or asked
|
|
292
257
|
// about ("is the eval finding actually reachable?"). The engine list is part of
|
|
@@ -294,52 +259,48 @@ export function stackSummaryMessages({ repoName, item, docsText, repoNote }) {
|
|
|
294
259
|
// answer, and a model that does not know a tool was missing will invent
|
|
295
260
|
// confidence it has not earned.
|
|
296
261
|
const ANALYSIS_SYSTEM = [
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
262
|
+
'You are a senior engineer walking the owner of a codebase through a static-analysis report.',
|
|
263
|
+
'Be concrete and calm. Name real files, rules and line numbers in backticks.',
|
|
264
|
+
'Prioritize: what must be fixed now, what can wait, and what is noise. Say plainly when a finding looks like a false positive and why.',
|
|
265
|
+
'Never invent a finding that is not in the list you were given. If the list is empty, say so — and say what that does and does not prove.',
|
|
266
|
+
'If some engines did not run or are not installed, say what that leaves unchecked.',
|
|
267
|
+
'Keep it under 220 words unless the question genuinely needs more.',
|
|
303
268
|
].join(' ');
|
|
304
|
-
|
|
305
269
|
export function analysisMessages({ repoName, grade, score, counts, engines, findings, question }) {
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
{ role: 'user', content: user },
|
|
335
|
-
];
|
|
270
|
+
const engineLines = (engines || []).map((e) => {
|
|
271
|
+
if (e.ran)
|
|
272
|
+
return `- ${e.label}: ran, ${e.findings} finding(s) in ${e.ms}ms`;
|
|
273
|
+
if (e.failed)
|
|
274
|
+
return `- ${e.label}: ran but failed — ${e.failure || 'no reason given'}`;
|
|
275
|
+
if (e.available)
|
|
276
|
+
return `- ${e.label}: installed but not run`;
|
|
277
|
+
return `- ${e.label}: NOT INSTALLED (${e.reason || 'unknown'})`;
|
|
278
|
+
});
|
|
279
|
+
const findingLines = (findings || []).slice(0, 40).map((f) => `- [${f.severity}] ${f.path}:${f.line} — ${f.message} (${f.tool} · ${f.rule})`);
|
|
280
|
+
const user = [
|
|
281
|
+
`Repository: ${repoName}`,
|
|
282
|
+
grade ? `Built-in security grade: ${grade} (${score}/100)` : '',
|
|
283
|
+
counts
|
|
284
|
+
? `Findings: ${counts.total} total — ${counts.critical} critical, ${counts.high} high, ${counts.medium} medium, ${counts.low} low. ${counts.external} came from external engines, ${counts.builtin} from the built-in scanner.`
|
|
285
|
+
: '',
|
|
286
|
+
engineLines.length ? `Engines:\n${engineLines.join('\n')}` : '',
|
|
287
|
+
findingLines.length
|
|
288
|
+
? `Findings, worst first:\n${findingLines.join('\n')}`
|
|
289
|
+
: 'No findings were reported by anything.',
|
|
290
|
+
question
|
|
291
|
+
? `Question: ${question}`
|
|
292
|
+
: 'Explain this report: what matters most, what to fix first, and what the engines could not see.',
|
|
293
|
+
].filter(Boolean).join('\n\n');
|
|
294
|
+
return [
|
|
295
|
+
{ role: 'system', content: ANALYSIS_SYSTEM },
|
|
296
|
+
{ role: 'user', content: user },
|
|
297
|
+
];
|
|
336
298
|
}
|
|
337
|
-
|
|
338
299
|
export async function streamTokens(container, text) {
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
300
|
+
container.innerHTML = '';
|
|
301
|
+
for (let i = 0; i < text.length; i++) {
|
|
302
|
+
container.innerHTML += text[i];
|
|
303
|
+
await new Promise(r => setTimeout(r, 10));
|
|
304
|
+
}
|
|
344
305
|
}
|
|
345
|
-
|
|
306
|
+
//# sourceMappingURL=llm.js.map
|