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
|
@@ -23,58 +23,57 @@
|
|
|
23
23
|
// both surfaces explain that instead of pretending.
|
|
24
24
|
// * Findings merge into the same shape the built-in scanner uses, with
|
|
25
25
|
// `source: 'builtin'|'external'` kept, so the attribution stays visible.
|
|
26
|
-
|
|
27
26
|
import { escapeHtml } from './html.js';
|
|
28
27
|
import { fetchToolsStatus, runAnalysisTools, streamToolInstall } from './api.js';
|
|
29
28
|
import { state } from './state.js';
|
|
30
29
|
import { engineRows, engineSummary } from './analysisReport.js';
|
|
31
30
|
import { mergeFindingsIntoScan, summarizeSecurity } from '/shared/analyzer/security.js';
|
|
32
|
-
|
|
33
31
|
// ---- the store -------------------------------------------------------------
|
|
34
|
-
|
|
35
32
|
// Who wants to know when a run starts, finishes or fails. The inspector panel
|
|
36
33
|
// and the Deep Analysis view both subscribe; neither polls.
|
|
37
34
|
const listeners = new Set();
|
|
38
|
-
|
|
39
35
|
export function subscribeAnalysis(listener) {
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
listeners.add(listener);
|
|
37
|
+
return () => listeners.delete(listener);
|
|
42
38
|
}
|
|
43
|
-
|
|
44
39
|
function notify() {
|
|
45
|
-
|
|
40
|
+
for (const listener of listeners)
|
|
41
|
+
listener();
|
|
46
42
|
}
|
|
47
|
-
|
|
48
43
|
// Which engines are installed. Asked once per repo and cached on the session —
|
|
49
44
|
// detection spawns `which`, and the answer does not change mid-scan.
|
|
50
45
|
export async function ensureToolsStatus(force = false) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (status) state.tools.status = status;
|
|
59
|
-
} finally {
|
|
60
|
-
state.tools.loading = false;
|
|
46
|
+
if (state.tools.running)
|
|
47
|
+
return state.tools.status;
|
|
48
|
+
if (state.tools.status && !force)
|
|
49
|
+
return state.tools.status;
|
|
50
|
+
if (state.tools.loading)
|
|
51
|
+
return state.tools.status;
|
|
52
|
+
state.tools.loading = true;
|
|
61
53
|
notify();
|
|
62
|
-
|
|
63
|
-
|
|
54
|
+
try {
|
|
55
|
+
const status = await fetchToolsStatus();
|
|
56
|
+
if (status)
|
|
57
|
+
state.tools.status = status;
|
|
58
|
+
}
|
|
59
|
+
finally {
|
|
60
|
+
state.tools.loading = false;
|
|
61
|
+
notify();
|
|
62
|
+
}
|
|
63
|
+
return state.tools.status;
|
|
64
64
|
}
|
|
65
|
-
|
|
66
65
|
// The per-engine option values the Configure panels hold, shaped for the API:
|
|
67
66
|
// only engines that have a form contribute, and every run gets the full set —
|
|
68
67
|
// the server picks out what its `tools`/`kinds` filter selected.
|
|
69
68
|
function collectToolOptions() {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
69
|
+
const out = {};
|
|
70
|
+
const status = state.tools.status || {};
|
|
71
|
+
for (const id of Object.keys(status)) {
|
|
72
|
+
if ((status[id].options || []).length)
|
|
73
|
+
out[id] = state.tools.options[id] || {};
|
|
74
|
+
}
|
|
75
|
+
return out;
|
|
76
76
|
}
|
|
77
|
-
|
|
78
77
|
// Run the engines. `kinds` narrows by purpose (security / dead-code), `tools`
|
|
79
78
|
// to named engines — the view offers all three scopes.
|
|
80
79
|
//
|
|
@@ -83,181 +82,182 @@ function collectToolOptions() {
|
|
|
83
82
|
// (it dedups on path+line+rule), so re-running a subset after a full run adds
|
|
84
83
|
// nothing twice.
|
|
85
84
|
export async function runDeepAnalysis(options = {}) {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
try {
|
|
94
|
-
const report = await runAnalysisTools(state.scanId, { ...options, options: collectToolOptions() });
|
|
95
|
-
state.tools.report = report;
|
|
96
|
-
state.tools.findings = report.findings || [];
|
|
97
|
-
state.tools.merged = mergeFindingsIntoScan(state.scan, state.tools.findings);
|
|
98
|
-
state.security = summarizeSecurity(state.scan);
|
|
99
|
-
return report;
|
|
100
|
-
} catch (err) {
|
|
101
|
-
state.tools.error = err.message;
|
|
102
|
-
return null;
|
|
103
|
-
} finally {
|
|
104
|
-
state.tools.running = false;
|
|
85
|
+
if (state.tools.running)
|
|
86
|
+
return null;
|
|
87
|
+
if (!state.scanId)
|
|
88
|
+
return null;
|
|
89
|
+
state.tools.running = true;
|
|
90
|
+
state.tools.error = null;
|
|
105
91
|
notify();
|
|
106
|
-
|
|
92
|
+
try {
|
|
93
|
+
const report = await runAnalysisTools(state.scanId, { ...options, options: collectToolOptions() });
|
|
94
|
+
state.tools.report = report;
|
|
95
|
+
state.tools.findings = report.findings || [];
|
|
96
|
+
state.tools.merged = mergeFindingsIntoScan(state.scan, state.tools.findings);
|
|
97
|
+
state.security = summarizeSecurity(state.scan);
|
|
98
|
+
return report;
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
state.tools.error = err.message;
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
finally {
|
|
105
|
+
state.tools.running = false;
|
|
106
|
+
notify();
|
|
107
|
+
}
|
|
107
108
|
}
|
|
108
|
-
|
|
109
109
|
// Install a missing engine without leaving the GUI. The server streams log
|
|
110
110
|
// lines, which collect on `state.tools.install[id]` so both surfaces can show
|
|
111
111
|
// a live console; on success the status is re-fetched (the install cleared
|
|
112
112
|
// the server's detection cache) and the card flips from "not installed" to
|
|
113
113
|
// "ready" without a restart.
|
|
114
114
|
export async function installEngine(id) {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
try {
|
|
121
|
-
const done = await streamToolInstall(id, (event) => {
|
|
122
|
-
const slot = state.tools.install[id];
|
|
123
|
-
if (event.type === 'log') slot.log.push(event.line);
|
|
124
|
-
if (slot.log.length > 400) slot.log.splice(0, slot.log.length - 400);
|
|
125
|
-
notify();
|
|
126
|
-
});
|
|
127
|
-
const slot = state.tools.install[id];
|
|
128
|
-
slot.running = false;
|
|
129
|
-
slot.ok = !!done.ok;
|
|
130
|
-
slot.error = done.ok ? null : (done.error || 'The install did not finish.');
|
|
131
|
-
if (done.ok) await ensureToolsStatus(true);
|
|
132
|
-
notify();
|
|
133
|
-
return done;
|
|
134
|
-
} catch (err) {
|
|
135
|
-
state.tools.install[id] = { running: false, log: state.tools.install[id].log, ok: false, error: err.message };
|
|
115
|
+
const entry = state.tools.install[id];
|
|
116
|
+
if (entry && entry.running)
|
|
117
|
+
return null;
|
|
118
|
+
state.tools.install[id] = { running: true, log: [], ok: null, error: null };
|
|
136
119
|
notify();
|
|
137
|
-
|
|
138
|
-
|
|
120
|
+
try {
|
|
121
|
+
const done = await streamToolInstall(id, (event) => {
|
|
122
|
+
const slot = state.tools.install[id];
|
|
123
|
+
if (event.type === 'log')
|
|
124
|
+
slot.log.push(event.line);
|
|
125
|
+
if (slot.log.length > 400)
|
|
126
|
+
slot.log.splice(0, slot.log.length - 400);
|
|
127
|
+
notify();
|
|
128
|
+
});
|
|
129
|
+
const slot = state.tools.install[id];
|
|
130
|
+
slot.running = false;
|
|
131
|
+
slot.ok = !!done.ok;
|
|
132
|
+
slot.error = done.ok ? null : (done.error || 'The install did not finish.');
|
|
133
|
+
if (done.ok)
|
|
134
|
+
await ensureToolsStatus(true);
|
|
135
|
+
notify();
|
|
136
|
+
return done;
|
|
137
|
+
}
|
|
138
|
+
catch (err) {
|
|
139
|
+
state.tools.install[id] = { running: false, log: state.tools.install[id].log, ok: false, error: err.message };
|
|
140
|
+
notify();
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
139
143
|
}
|
|
140
|
-
|
|
141
144
|
// A sentence for whoever pressed the button. Kept out of the store proper —
|
|
142
145
|
// toasting is the caller's business, and the store has no hooks.
|
|
143
146
|
export function runOutcomeMessage(report) {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
147
|
+
if (!report)
|
|
148
|
+
return 'Deep analysis did not finish.';
|
|
149
|
+
if (!report.ranCount) {
|
|
150
|
+
return report.unavailable && report.unavailable.length
|
|
151
|
+
? 'No engine is installed — see the list for what to install.'
|
|
152
|
+
: 'No engine managed to run.';
|
|
153
|
+
}
|
|
154
|
+
const n = (report.findings || []).length;
|
|
155
|
+
return `${report.ranCount} engine${report.ranCount === 1 ? '' : 's'} ran — ${n} finding${n === 1 ? '' : 's'} merged.`;
|
|
152
156
|
}
|
|
153
|
-
|
|
154
157
|
// ---- the inspector panel ---------------------------------------------------
|
|
155
|
-
|
|
156
158
|
let host = null;
|
|
157
|
-
let hooks = { onToast: () => {}, onOpenFile: () => {} };
|
|
158
|
-
|
|
159
|
+
let hooks = { onToast: (..._args) => { }, onOpenFile: (..._args) => { } };
|
|
159
160
|
export function initAnalysisPanel(options) {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
161
|
+
host = options.host;
|
|
162
|
+
hooks = { ...hooks, ...options };
|
|
163
|
+
host.addEventListener('click', (event) => {
|
|
164
|
+
const install = event.target.closest('[data-engine-install]');
|
|
165
|
+
if (install) {
|
|
166
|
+
installEngine(install.dataset.engineInstall).then((done) => {
|
|
167
|
+
if (done && done.ok)
|
|
168
|
+
hooks.onToast(`${install.dataset.engineInstall} installed — it is ready to run.`);
|
|
169
|
+
else if (done && done.error)
|
|
170
|
+
hooks.onToast(done.error);
|
|
171
|
+
});
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
const run = event.target.closest('[data-run-tools]');
|
|
175
|
+
if (run) {
|
|
176
|
+
const scope = run.dataset.runTools;
|
|
177
|
+
runTools(scope ? { tools: [scope] } : {});
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
const kind = event.target.closest('[data-run-kind]');
|
|
181
|
+
if (kind)
|
|
182
|
+
runTools({ kinds: [kind.dataset.runKind] });
|
|
183
|
+
});
|
|
184
|
+
subscribeAnalysis(() => paint());
|
|
183
185
|
}
|
|
184
|
-
|
|
185
186
|
async function runTools(options) {
|
|
186
|
-
|
|
187
|
-
|
|
187
|
+
const report = await runDeepAnalysis(options);
|
|
188
|
+
hooks.onToast(runOutcomeMessage(report));
|
|
188
189
|
}
|
|
189
|
-
|
|
190
190
|
// Renders into the security view's inspector. Also the place the "not a
|
|
191
191
|
// server-side scan" case is explained, since that is a property of the repo.
|
|
192
192
|
export function renderAnalysisPanel() {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
193
|
+
if (!host)
|
|
194
|
+
return;
|
|
195
|
+
if (!state.scanId) {
|
|
196
|
+
host.innerHTML = `<div class="tools-note">Deep analysis runs on a scanned folder or clone. A folder picked in the browser never leaves this tab, so there is nothing on the server for an external engine to read — the built-in scan is the whole story for this repo.</div>`;
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
if (!state.tools.status && !state.tools.loading)
|
|
200
|
+
void ensureToolsStatus();
|
|
201
|
+
paint();
|
|
200
202
|
}
|
|
201
|
-
|
|
202
203
|
// The panel is the summary; the Deep Analysis view is where you go to read the
|
|
203
204
|
// whole report. So this stays tight: the engines, one button, and an outcome
|
|
204
205
|
// line — no findings table here.
|
|
205
206
|
function paint() {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
207
|
+
if (!host)
|
|
208
|
+
return;
|
|
209
|
+
const { status, report, running, loading, error } = state.tools;
|
|
210
|
+
const rows = engineRows(status, report);
|
|
211
|
+
const head = `<div class="tools-head">
|
|
211
212
|
<h4>Deep analysis <span class="tools-sub">external engines</span></h4>
|
|
212
213
|
<button class="btn btn-ghost tools-run" data-run-tools ${running ? 'disabled' : ''}>
|
|
213
214
|
${running ? 'Running…' : 'Run deep analysis'}
|
|
214
215
|
</button>
|
|
215
216
|
</div>`;
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
host.innerHTML = head + body;
|
|
217
|
+
let body = '';
|
|
218
|
+
if (error)
|
|
219
|
+
body += `<div class="tools-err">${escapeHtml(error)}</div>`;
|
|
220
|
+
if (!rows.length) {
|
|
221
|
+
body += `<div class="tools-note">${loading ? 'Checking which engines are available…' : 'No engine table yet.'}</div>`;
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
body += '<ul class="tools-list">' + rows.map(engineCard).join('') + '</ul>';
|
|
225
|
+
}
|
|
226
|
+
const summary = engineSummary(report, rows);
|
|
227
|
+
if (report || rows.length) {
|
|
228
|
+
body += `<div class="tools-summary is-${escapeHtml(summary.tone)}">${escapeHtml(summary.text)}</div>`;
|
|
229
|
+
}
|
|
230
|
+
if (rows.some((r) => r.ran)) {
|
|
231
|
+
body += '<div class="tools-more">Every finding, with links to the file and line, is in the <b>Deep Analysis</b> tab.</div>';
|
|
232
|
+
}
|
|
233
|
+
host.innerHTML = head + body;
|
|
236
234
|
}
|
|
237
|
-
|
|
238
235
|
// One engine card. The badge is the whole story at a glance: did it run, what
|
|
239
236
|
// did it find, and if it could not run, why not. A missing engine gets an
|
|
240
237
|
// Install button — the person stays in the GUI, and the log lands in the Deep
|
|
241
238
|
// Analysis view's console.
|
|
242
239
|
function engineCard(engine) {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
240
|
+
const installing = state.tools.install[engine.id];
|
|
241
|
+
let badge;
|
|
242
|
+
if (installing && installing.running)
|
|
243
|
+
badge = '<span class="tools-badge is-running">installing…</span>';
|
|
244
|
+
else if (!engine.available)
|
|
245
|
+
badge = '<span class="tools-badge is-missing">not installed</span>';
|
|
246
|
+
else if (state.tools.running)
|
|
247
|
+
badge = '<span class="tools-badge is-running">running…</span>';
|
|
248
|
+
else if (engine.ran)
|
|
249
|
+
badge = `<span class="tools-badge is-ran">${engine.findings} · ${engine.ms}ms</span>`;
|
|
250
|
+
else if (engine.failed)
|
|
251
|
+
badge = '<span class="tools-badge is-failed">failed</span>';
|
|
252
|
+
else
|
|
253
|
+
badge = `<span class="tools-badge is-ready">ready${engine.how ? ' · ' + escapeHtml(engine.how) : ''}</span>`;
|
|
254
|
+
const note = !engine.available && engine.reason
|
|
255
|
+
? `<span class="tools-reason">${escapeHtml(engine.reason)}</span>`
|
|
256
|
+
: (engine.failure ? `<span class="tools-reason">${escapeHtml(engine.failure)}</span>` : '');
|
|
257
|
+
const installBtn = !engine.available && engine.installable
|
|
258
|
+
? `<button class="btn btn-ghost btn-sm" data-engine-install="${escapeHtml(engine.id)}" ${installing && installing.running ? 'disabled' : ''}>${installing && installing.running ? 'Installing…' : 'Install'}</button>`
|
|
259
|
+
: '';
|
|
260
|
+
return `<li class="tools-item${engine.available ? '' : ' is-missing'}">
|
|
261
261
|
<div class="tools-item-main">
|
|
262
262
|
<span class="tools-name">${escapeHtml(engine.label)}</span>
|
|
263
263
|
${badge}
|
|
@@ -267,4 +267,4 @@ function engineCard(engine) {
|
|
|
267
267
|
${note}
|
|
268
268
|
</li>`;
|
|
269
269
|
}
|
|
270
|
-
|
|
270
|
+
//# sourceMappingURL=analysisPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analysisPanel.js","sourceRoot":"","sources":["../../src/public/js/analysisPanel.ts"],"names":[],"mappings":"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","sourcesContent":["// The deep-analysis store, and the panel the Security view draws from it.\n//\n// Onboarder's built-in scanner is a fast, zero-dependency first pass. This is\n// the second pass — it runs the real analyzers the machine has (Semgrep,\n// Gitleaks, Knip, Vulture, Depcheck) through the server, and merges what they\n// find into the scan so the security grade includes them.\n//\n// Two consumers now share one store: this file's panel in the Security view's\n// inspector, and the full Deep Analysis view\n// (`deepAnalysisView.js`). Putting the run in one place is what keeps them\n// from disagreeing — a run started from either surface lands in\n// `state.tools`, merges identically, and notifies both to repaint. The\n// alternative (each surface calling the API itself) is how you end up with two\n// buttons that produce two different grades.\n//\n// The contract, in three lines:\n//\n// * Nothing is required. Both surfaces render with zero engines installed and\n// say which to install — \"no deep analysis\" and \"no findings\" are never the\n// same sentence.\n// * Server-side scans only. A browser-picked folder never touches the disk\n// from the server's point of view, so there is no root to point a tool at;\n// both surfaces explain that instead of pretending.\n// * Findings merge into the same shape the built-in scanner uses, with\n// `source: 'builtin'|'external'` kept, so the attribution stays visible.\n\nimport { escapeHtml } from './html.js';\nimport { fetchToolsStatus, runAnalysisTools, streamToolInstall } from './api.js';\nimport { state } from './state.js';\nimport { engineRows, engineSummary } from './analysisReport.js';\nimport { mergeFindingsIntoScan, summarizeSecurity } from '/shared/analyzer/security.js';\n\n// ---- the store -------------------------------------------------------------\n\n// Who wants to know when a run starts, finishes or fails. The inspector panel\n// and the Deep Analysis view both subscribe; neither polls.\nconst listeners = new Set<() => void>();\n\nexport function subscribeAnalysis(listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n}\n\nfunction notify() {\n for (const listener of listeners) listener();\n}\n\n// Which engines are installed. Asked once per repo and cached on the session —\n// detection spawns `which`, and the answer does not change mid-scan.\nexport async function ensureToolsStatus(force = false) {\n if (state.tools.running) return state.tools.status;\n if (state.tools.status && !force) return state.tools.status;\n if (state.tools.loading) return state.tools.status;\n state.tools.loading = true;\n notify();\n try {\n const status = await fetchToolsStatus();\n if (status) state.tools.status = status;\n } finally {\n state.tools.loading = false;\n notify();\n }\n return state.tools.status;\n}\n\n// The per-engine option values the Configure panels hold, shaped for the API:\n// only engines that have a form contribute, and every run gets the full set —\n// the server picks out what its `tools`/`kinds` filter selected.\nfunction collectToolOptions() {\n const out: Record<string, any> = {};\n const status = state.tools.status || {};\n for (const id of Object.keys(status)) {\n if ((status[id].options || []).length) out[id] = state.tools.options[id] || {};\n }\n return out;\n}\n\n// Run the engines. `kinds` narrows by purpose (security / dead-code), `tools`\n// to named engines — the view offers all three scopes.\n//\n// The merge happens here rather than in either caller, so the grade can never\n// depend on which button was pressed. `mergeFindingsIntoScan` is idempotent\n// (it dedups on path+line+rule), so re-running a subset after a full run adds\n// nothing twice.\nexport async function runDeepAnalysis(options: Record<string, any> = {}) {\n if (state.tools.running) return null;\n if (!state.scanId) return null;\n\n state.tools.running = true;\n state.tools.error = null;\n notify();\n\n try {\n const report = await runAnalysisTools(state.scanId, { ...options, options: collectToolOptions() });\n state.tools.report = report;\n state.tools.findings = report.findings || [];\n state.tools.merged = mergeFindingsIntoScan(state.scan, state.tools.findings);\n state.security = summarizeSecurity(state.scan);\n return report;\n } catch (err) {\n state.tools.error = err.message;\n return null;\n } finally {\n state.tools.running = false;\n notify();\n }\n}\n\n// Install a missing engine without leaving the GUI. The server streams log\n// lines, which collect on `state.tools.install[id]` so both surfaces can show\n// a live console; on success the status is re-fetched (the install cleared\n// the server's detection cache) and the card flips from \"not installed\" to\n// \"ready\" without a restart.\nexport async function installEngine(id) {\n const entry = state.tools.install[id];\n if (entry && entry.running) return null;\n state.tools.install[id] = { running: true, log: [], ok: null, error: null };\n notify();\n\n try {\n const done = await streamToolInstall(id, (event) => {\n const slot = state.tools.install[id];\n if (event.type === 'log') slot.log.push(event.line);\n if (slot.log.length > 400) slot.log.splice(0, slot.log.length - 400);\n notify();\n });\n const slot = state.tools.install[id];\n slot.running = false;\n slot.ok = !!done.ok;\n slot.error = done.ok ? null : (done.error || 'The install did not finish.');\n if (done.ok) await ensureToolsStatus(true);\n notify();\n return done;\n } catch (err) {\n state.tools.install[id] = { running: false, log: state.tools.install[id].log, ok: false, error: err.message };\n notify();\n return null;\n }\n}\n\n// A sentence for whoever pressed the button. Kept out of the store proper —\n// toasting is the caller's business, and the store has no hooks.\nexport function runOutcomeMessage(report) {\n if (!report) return 'Deep analysis did not finish.';\n if (!report.ranCount) {\n return report.unavailable && report.unavailable.length\n ? 'No engine is installed — see the list for what to install.'\n : 'No engine managed to run.';\n }\n const n = (report.findings || []).length;\n return `${report.ranCount} engine${report.ranCount === 1 ? '' : 's'} ran — ${n} finding${n === 1 ? '' : 's'} merged.`;\n}\n\n// ---- the inspector panel ---------------------------------------------------\n\nlet host = null;\nlet hooks = { onToast: (..._args: unknown[]) => {}, onOpenFile: (..._args: unknown[]) => {} };\n\nexport function initAnalysisPanel(options) {\n host = options.host;\n hooks = { ...hooks, ...options };\n\n host.addEventListener('click', (event) => {\n const install = event.target.closest('[data-engine-install]');\n if (install) {\n installEngine(install.dataset.engineInstall).then((done) => {\n if (done && done.ok) hooks.onToast(`${install.dataset.engineInstall} installed — it is ready to run.`);\n else if (done && done.error) hooks.onToast(done.error);\n });\n return;\n }\n const run = event.target.closest('[data-run-tools]');\n if (run) {\n const scope = run.dataset.runTools;\n runTools(scope ? { tools: [scope] } : {});\n return;\n }\n const kind = event.target.closest('[data-run-kind]');\n if (kind) runTools({ kinds: [kind.dataset.runKind] });\n });\n\n subscribeAnalysis(() => paint());\n}\n\nasync function runTools(options) {\n const report = await runDeepAnalysis(options);\n hooks.onToast(runOutcomeMessage(report));\n}\n\n// Renders into the security view's inspector. Also the place the \"not a\n// server-side scan\" case is explained, since that is a property of the repo.\nexport function renderAnalysisPanel() {\n if (!host) return;\n if (!state.scanId) {\n host.innerHTML = `<div class=\"tools-note\">Deep analysis runs on a scanned folder or clone. A folder picked in the browser never leaves this tab, so there is nothing on the server for an external engine to read — the built-in scan is the whole story for this repo.</div>`;\n return;\n }\n if (!state.tools.status && !state.tools.loading) void ensureToolsStatus();\n paint();\n}\n\n// The panel is the summary; the Deep Analysis view is where you go to read the\n// whole report. So this stays tight: the engines, one button, and an outcome\n// line — no findings table here.\nfunction paint() {\n if (!host) return;\n const { status, report, running, loading, error } = state.tools;\n const rows = engineRows(status, report);\n\n const head = `<div class=\"tools-head\">\n <h4>Deep analysis <span class=\"tools-sub\">external engines</span></h4>\n <button class=\"btn btn-ghost tools-run\" data-run-tools ${running ? 'disabled' : ''}>\n ${running ? 'Running…' : 'Run deep analysis'}\n </button>\n </div>`;\n\n let body = '';\n if (error) body += `<div class=\"tools-err\">${escapeHtml(error)}</div>`;\n\n if (!rows.length) {\n body += `<div class=\"tools-note\">${loading ? 'Checking which engines are available…' : 'No engine table yet.'}</div>`;\n } else {\n body += '<ul class=\"tools-list\">' + rows.map(engineCard).join('') + '</ul>';\n }\n\n const summary = engineSummary(report, rows);\n if (report || rows.length) {\n body += `<div class=\"tools-summary is-${escapeHtml(summary.tone)}\">${escapeHtml(summary.text)}</div>`;\n }\n\n if (rows.some((r) => r.ran)) {\n body += '<div class=\"tools-more\">Every finding, with links to the file and line, is in the <b>Deep Analysis</b> tab.</div>';\n }\n\n host.innerHTML = head + body;\n}\n\n// One engine card. The badge is the whole story at a glance: did it run, what\n// did it find, and if it could not run, why not. A missing engine gets an\n// Install button — the person stays in the GUI, and the log lands in the Deep\n// Analysis view's console.\nfunction engineCard(engine) {\n const installing = state.tools.install[engine.id];\n let badge;\n if (installing && installing.running) badge = '<span class=\"tools-badge is-running\">installing…</span>';\n else if (!engine.available) badge = '<span class=\"tools-badge is-missing\">not installed</span>';\n else if (state.tools.running) badge = '<span class=\"tools-badge is-running\">running…</span>';\n else if (engine.ran) badge = `<span class=\"tools-badge is-ran\">${engine.findings} · ${engine.ms}ms</span>`;\n else if (engine.failed) badge = '<span class=\"tools-badge is-failed\">failed</span>';\n else badge = `<span class=\"tools-badge is-ready\">ready${engine.how ? ' · ' + escapeHtml(engine.how) : ''}</span>`;\n\n const note = !engine.available && engine.reason\n ? `<span class=\"tools-reason\">${escapeHtml(engine.reason)}</span>`\n : (engine.failure ? `<span class=\"tools-reason\">${escapeHtml(engine.failure)}</span>` : '');\n\n const installBtn = !engine.available && engine.installable\n ? `<button class=\"btn btn-ghost btn-sm\" data-engine-install=\"${escapeHtml(engine.id)}\" ${installing && installing.running ? 'disabled' : ''}>${installing && installing.running ? 'Installing…' : 'Install'}</button>`\n : '';\n\n return `<li class=\"tools-item${engine.available ? '' : ' is-missing'}\">\n <div class=\"tools-item-main\">\n <span class=\"tools-name\">${escapeHtml(engine.label)}</span>\n ${badge}\n ${installBtn}\n <span class=\"tools-purpose\">${escapeHtml(engine.purpose)}</span>\n </div>\n ${note}\n </li>`;\n}\n\n"]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export declare const SEV_ORDER: string[];
|
|
2
|
+
export declare function sevRank(severity: any): number;
|
|
3
|
+
export declare const BUILTIN_TOOL = "built-in";
|
|
4
|
+
export declare function findingsFromSecurity(security: any): any[];
|
|
5
|
+
export declare function tabulate(rows: any): {
|
|
6
|
+
total: any;
|
|
7
|
+
bySeverity: Record<string, any>;
|
|
8
|
+
byTool: Record<string, any>;
|
|
9
|
+
byCategory: Record<string, any>;
|
|
10
|
+
external: any;
|
|
11
|
+
builtin: number;
|
|
12
|
+
critical: any;
|
|
13
|
+
high: any;
|
|
14
|
+
medium: any;
|
|
15
|
+
low: any;
|
|
16
|
+
};
|
|
17
|
+
export declare function filterFindings(rows: any, { severity, tool, q }?: Record<string, any>): any;
|
|
18
|
+
export declare function engineRows(status: any, report: any): {
|
|
19
|
+
id: string;
|
|
20
|
+
label: any;
|
|
21
|
+
kind: any;
|
|
22
|
+
purpose: any;
|
|
23
|
+
available: boolean;
|
|
24
|
+
how: any;
|
|
25
|
+
reason: any;
|
|
26
|
+
options: any;
|
|
27
|
+
defaults: any;
|
|
28
|
+
installable: boolean;
|
|
29
|
+
ran: boolean;
|
|
30
|
+
failed: boolean;
|
|
31
|
+
findings: any;
|
|
32
|
+
ms: any;
|
|
33
|
+
failure: any;
|
|
34
|
+
}[];
|
|
35
|
+
export declare function engineSummary(report: any, rows: any): {
|
|
36
|
+
tone: string;
|
|
37
|
+
text: string;
|
|
38
|
+
};
|