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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mermaid.js","sourceRoot":"","sources":["../../src/shared/diagram/mermaid.ts"],"names":[],"mappings":"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","sourcesContent":["// Turns scan results into Mermaid flowchart source. Kept separate from the\n// UI so the exact same diagrams can be produced in Node (tests, exports)\n// and in the browser.\n\nimport { baseName, dirOf, topFolderOf } from '../analyzer/pathUtil.js';\nimport { factIndex, scanIndex } from '../analyzer/graph.js';\n\n// ---- theming ---------------------------------------------------------------\n// Every diagram embeds its own init directive, so exported SVGs carry the\n// theme too. The app flips `currentTheme`; Node tests can do the same.\n\nlet currentTheme = 'light';\n\nexport function setDiagramTheme(theme) {\n currentTheme = theme === 'dark' ? 'dark' : 'light';\n}\n\nexport function getDiagramTheme() {\n return currentTheme;\n}\n\nconst PALETTES = {\n light: {\n background: '#f7f4ed', node: '#fffdf7', border: '#3d3a33', text: '#2a2721',\n line: '#8a8577', cluster: '#efe9dc66', clusterBorder: '#8a8577',\n entry: 'fill:#dce8d8,stroke:#2e5d43,stroke-width:2px,color:#1d3a2a',\n hub: 'fill:#f3e3c8,stroke:#8a5a1d,stroke-width:2px,color:#5c3a10',\n cycle: 'fill:#f3d4c8,stroke:#a4442a,stroke-width:2px,color:#6e2c17',\n ghost: 'fill:#efe9dc,stroke:#b5ae9c,stroke-dasharray:4 3,color:#8a8577',\n self: 'fill:#dce8d8,stroke:#2e5d43,stroke-width:3px,color:#1d3a2a',\n ext: 'fill:#efe9dc,stroke:#b5ae9c,stroke-dasharray:4 3,color:#8a8577',\n blank: 'fill:transparent,stroke:transparent,color:transparent',\n note: 'fill:transparent,stroke:transparent,color:#8a8577',\n r0: 'fill:#dce8d8,stroke:#2e5d43,stroke-width:1.5px,color:#1d3a2a',\n r1: 'fill:#fffdf7,stroke:#8a8577,stroke-width:1px,color:#2a2721',\n r2: 'fill:#f3e3c8,stroke:#8a5a1d,stroke-width:1.5px,color:#5c3a10',\n r3: 'fill:#f3d4c8,stroke:#a4442a,stroke-width:2px,color:#6e2c17',\n },\n dark: {\n background: '#211e19', node: '#2b2721', border: '#b8b0a0', text: '#ece7db',\n line: '#8a8577', cluster: '#2b272166', clusterBorder: '#6b6558',\n entry: 'fill:#243d2c,stroke:#8fbd9f,stroke-width:2px,color:#cfe6d6',\n hub: 'fill:#463617,stroke:#d9a75f,stroke-width:2px,color:#f0d9ae',\n cycle: 'fill:#472418,stroke:#d97b5a,stroke-width:2px,color:#f3c4ae',\n ghost: 'fill:#2b2721,stroke:#6b6558,stroke-dasharray:4 3,color:#9b9484',\n self: 'fill:#243d2c,stroke:#8fbd9f,stroke-width:3px,color:#cfe6d6',\n ext: 'fill:#2b2721,stroke:#6b6558,stroke-dasharray:4 3,color:#9b9484',\n blank: 'fill:transparent,stroke:transparent,color:transparent',\n note: 'fill:transparent,stroke:transparent,color:#9b9484',\n r0: 'fill:#243d2c,stroke:#8fbd9f,stroke-width:1.5px,color:#cfe6d6',\n r1: 'fill:#2b2721,stroke:#8a8577,stroke-width:1px,color:#ece7db',\n r2: 'fill:#463617,stroke:#d9a75f,stroke-width:1.5px,color:#f0d9ae',\n r3: 'fill:#472418,stroke:#d97b5a,stroke-width:2px,color:#f3c4ae',\n },\n};\n\nfunction themeBlock() {\n const p = PALETTES[currentTheme];\n return `%%{init: {\n 'theme': 'base',\n 'themeVariables': {\n 'background': '${p.background}',\n 'primaryColor': '${p.node}',\n 'primaryBorderColor': '${p.border}',\n 'primaryTextColor': '${p.text}',\n 'lineColor': '${p.line}',\n 'secondaryColor': '${p.node}',\n 'tertiaryColor': '${p.node}',\n 'clusterBkg': '${p.cluster}',\n 'clusterBorder': '${p.clusterBorder}',\n 'edgeLabelBackground': '${p.background}',\n 'fontFamily': 'ui-monospace, SFMono-Regular, Menlo, monospace',\n 'fontSize': '13px'\n },\n 'flowchart': { 'curve': 'basis', 'htmlLabels': false, 'nodeSpacing': 42, 'rankSpacing': 52 }\n}}%%`;\n}\n\n// AI-generated diagrams get our theme injected after the fact, so a model's\n// sketch is indistinguishable from the hand-drawn ones.\nexport function diagramThemeBlock() {\n return themeBlock();\n}\n\nfunction classDefLines() {\n const p = PALETTES[currentTheme];\n return [\n ` classDef entry ${p.entry}`,\n ` classDef hub ${p.hub}`,\n ` classDef cycle ${p.cycle}`,\n ` classDef ghost ${p.ghost}`,\n ` classDef self ${p.self}`,\n ` classDef ext ${p.ext}`,\n ` classDef blank ${p.blank}`,\n ` classDef note ${p.note}`,\n ` classDef r0 ${p.r0}`,\n ` classDef r1 ${p.r1}`,\n ` classDef r2 ${p.r2}`,\n ` classDef r3 ${p.r3}`,\n ];\n}\n\nconst MAX_LABEL = 34;\n\nexport function overviewDiagram(scan, facts) {\n const lines = [themeBlock(), 'flowchart LR'];\n\n // Nodes: top-level folders, sized by parsed file count.\n const folderStats = new Map();\n for (const f of scan.files) {\n const top = topFolderOf(f.path);\n folderStats.set(top, (folderStats.get(top) || 0) + 1);\n }\n const entryFolders = new Set(facts.entries.map((p) => topFolderOf(p)));\n\n const ids = new Map();\n let n = 0;\n const sorted = [...folderStats.entries()].sort((a, b) => b[1] - a[1]);\n for (const [folder, count] of sorted) {\n const id = 'f' + n++;\n ids.set(folder, id);\n const isEntry = entryFolders.has(folder);\n const label = esc(folder === '(root)' ? '(repo root)' : folder + '/') + '\\\\n' + count + (count === 1 ? ' file' : ' files');\n if (isEntry) {\n lines.push(` ${id}([\"${label}\"]):::entry`);\n } else {\n lines.push(` ${id}[\"${label}\"]`);\n }\n }\n\n for (const fe of facts.folderEdges) {\n const a = ids.get(fe.from);\n const b = ids.get(fe.to);\n if (a === undefined || b === undefined) continue;\n lines.push(` ${a} -->|${fe.count}| ${b}`);\n }\n\n lines.push(...classDefLines());\n\n const nodes: Record<string, any> = {};\n for (const [folder, id] of ids) {\n nodes[id] = { kind: 'folder', path: folder === '(root)' ? '' : folder };\n }\n return { source: lines.join('\\n'), nodes };\n}\n\nexport function folderDiagram(scan, facts, folder, opts: Record<string, any> = {}) {\n const include = opts.include || (() => true);\n const here = scanIndex(scan).filesIn(folder).filter((f) => include(f.path));\n if (!here.length) return emptyDiagram('Nothing matches the filter in this folder.');\n\n const lines = [themeBlock(), 'flowchart LR'];\n const localSet = new Set(here.map((f) => f.path));\n const ids = idMapFor(here.map((f) => f.path));\n const fx = factIndex(facts);\n\n for (const f of here) {\n const id = ids.get(f.path);\n const fin = facts.fanIn[f.path] || 0;\n const isEntry = fx.entries.has(f.path);\n const inCycle = fx.inCycle.has(f.path);\n const cls = isEntry ? ':::entry' : inCycle ? ':::cycle' : fin >= 5 ? ':::hub' : '';\n lines.push(` ${id}[\"${esc(shortName(f.name))}\"]${cls}`);\n }\n\n // Edges between files in this folder; edges to elsewhere get ghost nodes.\n const ghosts = new Map(); // outside path -> id\n let g = 0;\n for (const e of scan.edges) {\n const fromIn = localSet.has(e.from);\n const toIn = localSet.has(e.to);\n if (fromIn && toIn) {\n lines.push(` ${ids.get(e.from)} --> ${ids.get(e.to)}`);\n } else if (fromIn && !toIn && include(e.to)) {\n const gid = ghostId(ghosts, e.to, () => 'g' + g++);\n lines.push(` ${ids.get(e.from)} -.-> ${gid}`);\n } else if (!fromIn && toIn && include(e.from)) {\n const gid = ghostId(ghosts, e.from, () => 'g' + g++);\n lines.push(` ${gid} -.-> ${ids.get(e.to)}`);\n }\n }\n for (const [p, gid] of ghosts) {\n lines.push(` ${gid}[\"${esc(shortName(baseName(p)))}\\\\n${esc(dirOf(p) || '(root)')}\"]:::ghost`);\n }\n\n lines.push(...classDefLines());\n\n const nodes: Record<string, any> = {};\n for (const [p, id] of ids) nodes[id] = { kind: 'file', path: p };\n for (const [p, id] of ghosts) nodes[id] = { kind: 'file', path: p };\n return { source: lines.join('\\n'), nodes };\n}\nexport function fileDetailDiagram(scan, facts, path) {\n const file = scanIndex(scan).fileAt(path);\n if (!file) return emptyDiagram('File not found in the scan.');\n\n const lines = [themeBlock(), 'flowchart LR'];\n const importers = (facts.importers[path] || []).slice(0, 8);\n const imports = (facts.importsOf[path] || []).slice(0, 8);\n const ext = scan.externals.filter((x) => x.usedBy.includes(path)).slice(0, 5);\n\n lines.push(` subgraph up[\"imported by\"]`);\n importers.forEach((p, i) => lines.push(` up${i}[\"${esc(shortName(baseName(p)))}\"]`));\n if (!importers.length) lines.push(` upnone[\" \"]:::blank`);\n lines.push(' end');\n\n lines.push(` self[\"${esc(shortName(file.name))}\"]:::self`);\n\n lines.push(` subgraph down[\"imports\"]`);\n imports.forEach((p, i) => lines.push(` dn${i}[\"${esc(shortName(baseName(p)))}\"]`));\n ext.forEach((x, i) => lines.push(` dx${i}[\"${esc(x.name)}\"]:::ext`));\n if (!imports.length && !ext.length) lines.push(` dnnone[\" \"]:::blank`);\n lines.push(' end');\n\n importers.forEach((p, i) => lines.push(` up${i} --> self`));\n imports.forEach((p, i) => lines.push(` self --> dn${i}`));\n ext.forEach((x, i) => lines.push(` self -.-> dx${i}`));\n\n lines.push(...classDefLines());\n\n const nodes = { self: { kind: 'file', path } };\n importers.forEach((p, i) => (nodes['up' + i] = { kind: 'file', path: p }));\n imports.forEach((p, i) => (nodes['dn' + i] = { kind: 'file', path: p }));\n return { source: lines.join('\\n'), nodes };\n}\n\nexport function callsDiagram(file) {\n if (!file?.calls?.length) return emptyDiagram('No internal call links we can see.');\n const lines = [themeBlock(), 'flowchart LR'];\n const names = new Set();\n for (const c of file.calls) {\n names.add(c.from);\n names.add(c.to);\n }\n const ids = idMapFor([...names]);\n for (const name of names) {\n lines.push(` ${ids.get(name)}[\"${esc(name)}()\"]`);\n }\n for (const c of file.calls) {\n lines.push(` ${ids.get(c.from)} --> ${ids.get(c.to)}`);\n }\n return { source: lines.join('\\n'), nodes: {} };\n}\n\nexport function servicesDiagram(scan, manifest) {\n if (!manifest?.services?.length) return emptyDiagram('No services detected.');\n const lines = [themeBlock(), 'flowchart LR'];\n manifest.services.forEach((s, i) => {\n const bits = [esc(s.name)];\n if (s.image) bits.push(esc(s.image));\n if (s.ports?.length) bits.push(esc(s.ports.join(', ')));\n if (s.command) bits.push(esc(shortName(s.command)));\n lines.push(` svc${i}([\"${bits.join('\\\\n')}\"])`);\n });\n // Link each service to the folder it builds from, when we can see one.\n manifest.services.forEach((s, i) => {\n if (!s.build) return;\n const dir = s.build.replace(/^\\.\\/?/, '').replace(/\\/$/, '');\n if (!dir || scan.folders.some((f) => f.path === dir)) {\n lines.push(` svc${i} -.->|\"${esc(dir || '.')}\"| root${i}[\"${esc(dir || '(repo root)')}\"]:::ghost`);\n }\n });\n lines.push(...classDefLines());\n return { source: lines.join('\\n'), nodes: {} };\n}\n\nexport function emptyDiagram(note) {\n const source = [themeBlock(), 'flowchart LR', ` empty[\"${esc(note)}\"]:::note`, ...classDefLines()].join('\\n');\n return { source, nodes: {} };\n}\n\n// The Patterns view: every file placed on its import depth — the longest\n// chain from an entry point — so the architecture's strata are visible at a\n// glance. Edges flow downward; anything horizontal or upward earns a look.\nexport function layersDiagram(scan, facts, layersInfo, opts: Record<string, any> = {}) {\n const include = opts.include || (() => true);\n const { layers, unreachable } = layersInfo;\n const MAX_PER_LAYER = 10;\n const MAX_EDGES = 70;\n\n const lines = [themeBlock(), 'flowchart TD'];\n const ids = new Map();\n const nodes: Record<string, any> = {};\n let n = 0;\n\n const fx = factIndex(facts);\n const clsFor = (p) =>\n fx.entries.has(p) ? ':::entry'\n : fx.inCycle.has(p) ? ':::cycle'\n : (facts.fanIn[p] || 0) >= 5 ? ':::hub'\n : '';\n\n layers.forEach((files, i) => {\n const shown = files.filter(include);\n if (!shown.length) return;\n const label = i === 0 ? 'the way in' : 'depth ' + i;\n lines.push(` subgraph L${i}[\"${label}\"]`);\n for (const p of shown.slice(0, MAX_PER_LAYER)) {\n const id = 'n' + n++;\n ids.set(p, id);\n nodes[id] = { kind: 'file', path: p };\n lines.push(` ${id}[\"${esc(shortName(baseName(p)))}\"]${clsFor(p)}`);\n }\n if (shown.length > MAX_PER_LAYER) {\n lines.push(` moreL${i}[\"+ ${shown.length - MAX_PER_LAYER} more\"]:::ghost`);\n }\n lines.push(' end');\n });\n\n const stray = unreachable.filter(include).slice(0, 6);\n if (stray.length) {\n lines.push(` subgraph LU[\"off the path\"]`);\n for (const p of stray) {\n const id = 'n' + n++;\n ids.set(p, id);\n nodes[id] = { kind: 'file', path: p };\n lines.push(` ${id}[\"${esc(shortName(baseName(p)))}\"]:::ghost`);\n }\n if (unreachable.length > stray.length) {\n lines.push(` moreLU[\"+ ${unreachable.length - stray.length} more\"]:::ghost`);\n }\n lines.push(' end');\n }\n\n let edgeCount = 0;\n for (const e of scan.edges) {\n if (edgeCount >= MAX_EDGES) break;\n if (!ids.has(e.from) || !ids.has(e.to)) continue;\n lines.push(` ${ids.get(e.from)} --> ${ids.get(e.to)}`);\n edgeCount++;\n }\n\n lines.push(...classDefLines());\n return { source: lines.join('\\n'), nodes };\n}\n\n// ---- helpers ---------------------------------------------------------------\n\nfunction idMapFor(paths) {\n const map = new Map();\n paths.forEach((p, i) => map.set(p, 'n' + i));\n return map;\n}\n\nfunction ghostId(ghosts, path, next) {\n if (!ghosts.has(path)) ghosts.set(path, next());\n return ghosts.get(path);\n}\n\n// Mermaid labels break on a handful of characters; keep them out.\nfunction esc(s) {\n return String(s)\n .replace(/[\"<>|{}[\\]()]/g, '')\n .replace(/&/g, 'and')\n .slice(0, 80);\n}\n\nfunction shortName(name) {\n return name.length > MAX_LABEL ? name.slice(0, MAX_LABEL - 1) + '…' : name;\n}\n\n// The Health view: the riskiest files as a heat map, colored by risk band and\n// wired with their import arrows, so the dangerous neighborhood reads at a\n// glance. Nodes stay clickable into the deep-dive.\nexport function healthDiagram(scan, facts, health, opts: Record<string, any> = {}) {\n const include = opts.include || (() => true);\n const MAX = 26;\n const top = health.perFile.filter((f) => include(f.path)).slice(0, MAX);\n const lines = [themeBlock(), 'flowchart TB', ...classDefLines()];\n const ids = new Map();\n const nodes: Record<string, any> = {};\n let n = 0;\n const band = (r) => (r >= 70 ? 'r3' : r >= 50 ? 'r2' : r >= 30 ? 'r1' : 'r0');\n\n for (const f of top) {\n const id = 'h' + n++;\n ids.set(f.path, id);\n nodes[id] = { kind: 'file', path: f.path };\n lines.push(` ${id}[\"${esc(shortName(baseName(f.path)))} · ${f.risk}\"]:::${band(f.risk)}`);\n }\n\n const set = new Set(top.map((f) => f.path));\n let drawn = 0;\n for (const e of scan.edges) {\n if (drawn >= 60) break;\n\n if (!set.has(e.from) || !set.has(e.to)) continue;\n lines.push(` ${ids.get(e.from)} --> ${ids.get(e.to)}`);\n drawn++;\n }\n if (!top.length) lines.push(' empty[\"Nothing stands out — this repo is in good shape.\"]:::note');\n return { source: lines.join('\\n'), nodes };\n}\n\n// The Security view: files carrying rule-engine findings, colored by their\n// worst severity (critical red → info green), wired with their import arrows.\nexport function securityDiagram(scan, facts, security, opts: Record<string, any> = {}) {\n const include = opts.include || (() => true);\n const MAX = 26;\n const sevClass = { critical: 'r3', high: 'r2', medium: 'r1', low: 'r0', info: 'r0' };\n const top = security.files.filter((f) => include(f.path)).slice(0, MAX);\n const lines = [themeBlock(), 'flowchart TB', ...classDefLines()];\n const ids = new Map();\n const nodes: Record<string, any> = {};\n let n = 0;\n for (const f of top) {\n const id = 's' + n++;\n ids.set(f.path, id);\n nodes[id] = { kind: 'file', path: f.path };\n lines.push(` ${id}[\"${esc(shortName(baseName(f.path)))} · ${f.count}\"]:::${sevClass[f.worst]}`);\n }\n const set = new Set(top.map((f) => f.path));\n let drawn = 0;\n for (const e of scan.edges) {\n if (drawn >= 60) break;\n if (!set.has(e.from) || !set.has(e.to)) continue;\n lines.push(` ${ids.get(e.from)} --> ${ids.get(e.to)}`);\n drawn++;\n }\n if (!top.length) lines.push(' clean[\"No findings — the rule engine found nothing to flag.\"]:::r0');\n return { source: lines.join('\\n'), nodes };\n}\n\n// The History view: the hotspot cross-tab — complexity × churn — as a heat\n// map. A file high here is both hard to change and changed constantly, which\n// is where a newcomer's caution (and a maintainer's tests) belong. Import\n// arrows are drawn between shown files so hot neighborhoods read at a glance.\n// No history (browser pick, tarball, not a checkout) says why instead of\n// drawing an empty chart.\nexport function historyDiagram(scan, facts, history, opts: Record<string, any> = {}) {\n if (!history?.available) {\n return emptyDiagram(history?.reason || 'No history available.');\n }\n const include = opts.include || (() => true);\n const MAX = 26;\n const band = (s) => (s >= 70 ? 'r3' : s >= 50 ? 'r2' : s >= 30 ? 'r1' : 'r0');\n const top = history.perFile.filter((f) => include(f.path)).slice(0, MAX);\n const lines = [themeBlock(), 'flowchart TB', ...classDefLines()];\n const ids = new Map();\n const nodes: Record<string, any> = {};\n let n = 0;\n for (const f of top) {\n const id = 't' + n++;\n ids.set(f.path, id);\n nodes[id] = { kind: 'file', path: f.path };\n lines.push(` ${id}[\"${esc(shortName(baseName(f.path)))} · ${f.hotspot}\"]:::${band(f.hotspot)}`);\n }\n const set = new Set(top.map((f) => f.path));\n let drawn = 0;\n for (const e of scan.edges) {\n if (drawn >= 60) break;\n if (!set.has(e.from) || !set.has(e.to)) continue;\n lines.push(` ${ids.get(e.from)} --> ${ids.get(e.to)}`);\n drawn++;\n }\n if (!top.length) lines.push(' quiet[\"No file in this repo has been touched in the recent window.\"]:::note');\n return { source: lines.join('\\n'), nodes };\n}\n\n"]}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
export type Severity = 'critical' | 'high' | 'medium' | 'low' | 'info';
|
|
2
|
+
export type ReviewProfile = 'focused' | 'balanced' | 'thorough';
|
|
3
|
+
export type ReviewMode = 'working' | 'staged' | 'range';
|
|
4
|
+
export interface PatchLine {
|
|
5
|
+
type: 'add' | 'del' | 'context';
|
|
6
|
+
text: string;
|
|
7
|
+
}
|
|
8
|
+
export interface PatchHunk {
|
|
9
|
+
header: string;
|
|
10
|
+
oldStart: number;
|
|
11
|
+
oldLines: number;
|
|
12
|
+
newStart: number;
|
|
13
|
+
newLines: number;
|
|
14
|
+
heading: string;
|
|
15
|
+
lines: PatchLine[];
|
|
16
|
+
}
|
|
17
|
+
export interface PatchFile {
|
|
18
|
+
oldPath: string;
|
|
19
|
+
newPath: string;
|
|
20
|
+
status: string;
|
|
21
|
+
additions: number;
|
|
22
|
+
deletions: number;
|
|
23
|
+
hunks: PatchHunk[];
|
|
24
|
+
binary?: boolean;
|
|
25
|
+
skipReason?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface GitDiff {
|
|
28
|
+
files: PatchFile[];
|
|
29
|
+
stats: {
|
|
30
|
+
filesChanged: number;
|
|
31
|
+
additions: number;
|
|
32
|
+
deletions: number;
|
|
33
|
+
};
|
|
34
|
+
raw: string;
|
|
35
|
+
base?: string;
|
|
36
|
+
head?: string;
|
|
37
|
+
mode?: ReviewMode;
|
|
38
|
+
untracked?: number;
|
|
39
|
+
}
|
|
40
|
+
export interface ReviewConfig {
|
|
41
|
+
profile: ReviewProfile;
|
|
42
|
+
exclude: string[];
|
|
43
|
+
instructions: {
|
|
44
|
+
path: string;
|
|
45
|
+
instruction: string;
|
|
46
|
+
}[];
|
|
47
|
+
}
|
|
48
|
+
export interface ReviewFinding {
|
|
49
|
+
id: string;
|
|
50
|
+
path: string;
|
|
51
|
+
line: number;
|
|
52
|
+
rule: string;
|
|
53
|
+
severity: Severity;
|
|
54
|
+
category: string;
|
|
55
|
+
message: string;
|
|
56
|
+
suggestion: string;
|
|
57
|
+
excerpt: string;
|
|
58
|
+
}
|
|
59
|
+
export interface ReviewFile {
|
|
60
|
+
path: string;
|
|
61
|
+
oldPath: string;
|
|
62
|
+
status: string;
|
|
63
|
+
additions: number;
|
|
64
|
+
deletions: number;
|
|
65
|
+
kind: string;
|
|
66
|
+
risk: 'high' | 'medium' | 'low';
|
|
67
|
+
findings: number;
|
|
68
|
+
instructions: string[];
|
|
69
|
+
skipped: string | null;
|
|
70
|
+
}
|
|
71
|
+
export interface ReviewCheck {
|
|
72
|
+
id: string;
|
|
73
|
+
label: string;
|
|
74
|
+
status: 'pass' | 'warn' | 'fail' | 'skip';
|
|
75
|
+
detail: string;
|
|
76
|
+
}
|
|
77
|
+
export interface ReviewReport {
|
|
78
|
+
fingerprint: string;
|
|
79
|
+
generatedAt: string;
|
|
80
|
+
mode: ReviewMode;
|
|
81
|
+
base: string;
|
|
82
|
+
head: string;
|
|
83
|
+
profile: ReviewProfile;
|
|
84
|
+
summary: string;
|
|
85
|
+
files: ReviewFile[];
|
|
86
|
+
findings: ReviewFinding[];
|
|
87
|
+
checks: ReviewCheck[];
|
|
88
|
+
stats: GitDiff['stats'];
|
|
89
|
+
coverage: {
|
|
90
|
+
reviewed: number;
|
|
91
|
+
skipped: number;
|
|
92
|
+
untracked: number;
|
|
93
|
+
limitations: string[];
|
|
94
|
+
};
|
|
95
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contracts.js","sourceRoot":"","sources":["../../src/shared/review/contracts.ts"],"names":[],"mappings":"","sourcesContent":["export type Severity = 'critical' | 'high' | 'medium' | 'low' | 'info';\nexport type ReviewProfile = 'focused' | 'balanced' | 'thorough';\nexport type ReviewMode = 'working' | 'staged' | 'range';\nexport interface PatchLine { type: 'add' | 'del' | 'context'; text: string }\nexport interface PatchHunk { header: string; oldStart: number; oldLines: number; newStart: number; newLines: number; heading: string; lines: PatchLine[] }\nexport interface PatchFile { oldPath: string; newPath: string; status: string; additions: number; deletions: number; hunks: PatchHunk[]; binary?: boolean; skipReason?: string }\nexport interface GitDiff { files: PatchFile[]; stats: { filesChanged: number; additions: number; deletions: number }; raw: string; base?: string; head?: string; mode?: ReviewMode; untracked?: number }\nexport interface ReviewConfig { profile: ReviewProfile; exclude: string[]; instructions: { path: string; instruction: string }[] }\nexport interface ReviewFinding { id: string; path: string; line: number; rule: string; severity: Severity; category: string; message: string; suggestion: string; excerpt: string }\nexport interface ReviewFile { path: string; oldPath: string; status: string; additions: number; deletions: number; kind: string; risk: 'high' | 'medium' | 'low'; findings: number; instructions: string[]; skipped: string | null }\nexport interface ReviewCheck { id: string; label: string; status: 'pass' | 'warn' | 'fail' | 'skip'; detail: string }\nexport interface ReviewReport { fingerprint: string; generatedAt: string; mode: ReviewMode; base: string; head: string; profile: ReviewProfile; summary: string; files: ReviewFile[]; findings: ReviewFinding[]; checks: ReviewCheck[]; stats: GitDiff['stats']; coverage: { reviewed: number; skipped: number; untracked: number; limitations: string[] } }\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { GitDiff, ReviewConfig, ReviewProfile, ReviewReport, Severity } from './contracts.js';
|
|
2
|
+
export declare const SEVERITY_RANK: Record<Severity, number>;
|
|
3
|
+
export declare const DEFAULT_REVIEW_CONFIG: ReviewConfig;
|
|
4
|
+
export declare function reviewProfile(value: unknown): ReviewProfile;
|
|
5
|
+
export declare function parseReviewConfig(value: unknown): ReviewConfig;
|
|
6
|
+
/** Small path glob vocabulary: * (one segment), ** (any depth), ? (one character). */
|
|
7
|
+
export declare function matchesReviewPath(path: string, pattern: string): boolean;
|
|
8
|
+
export declare function changeKind(path: string): string;
|
|
9
|
+
export declare function buildReview(diff: GitDiff, config?: ReviewConfig): ReviewReport;
|
|
10
|
+
export declare function reviewMarkdown(report: ReviewReport): string;
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { analyzeSecurityFile } from '../analyzer/security.js';
|
|
2
|
+
export const SEVERITY_RANK = { info: 0, low: 1, medium: 2, high: 3, critical: 4 };
|
|
3
|
+
export const DEFAULT_REVIEW_CONFIG = { profile: 'balanced', exclude: [], instructions: [] };
|
|
4
|
+
export function reviewProfile(value) {
|
|
5
|
+
if (value === 'focused' || value === 'balanced' || value === 'thorough')
|
|
6
|
+
return value;
|
|
7
|
+
throw new Error('Review profile must be focused, balanced, or thorough.');
|
|
8
|
+
}
|
|
9
|
+
export function parseReviewConfig(value) {
|
|
10
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
11
|
+
throw new Error('Review configuration must be a JSON object.');
|
|
12
|
+
const v = value;
|
|
13
|
+
if (Object.keys(v).some(k => !['profile', 'exclude', 'instructions'].includes(k)))
|
|
14
|
+
throw new Error('Unknown review configuration field. Use profile, exclude, and instructions.');
|
|
15
|
+
const exclude = v.exclude ?? [];
|
|
16
|
+
const instructions = v.instructions ?? [];
|
|
17
|
+
if (!Array.isArray(exclude) || exclude.length > 50 || exclude.some(p => typeof p !== 'string' || p.length > 200 || !p))
|
|
18
|
+
throw new Error('exclude must contain up to 50 path patterns.');
|
|
19
|
+
if (!Array.isArray(instructions) || instructions.length > 50)
|
|
20
|
+
throw new Error('instructions must contain up to 50 path guidelines.');
|
|
21
|
+
const rules = instructions.map((rule) => {
|
|
22
|
+
if (!rule || typeof rule !== 'object')
|
|
23
|
+
throw new Error('Each guideline needs a path and instruction.');
|
|
24
|
+
const r = rule;
|
|
25
|
+
if (typeof r.path !== 'string' || !r.path || r.path.length > 200 || typeof r.instruction !== 'string' || !r.instruction.trim() || r.instruction.length > 2000)
|
|
26
|
+
throw new Error('Each guideline needs a path pattern and an instruction of at most 2000 characters.');
|
|
27
|
+
return { path: r.path, instruction: r.instruction };
|
|
28
|
+
});
|
|
29
|
+
return { profile: v.profile === undefined ? 'balanced' : reviewProfile(v.profile), exclude, instructions: rules };
|
|
30
|
+
}
|
|
31
|
+
/** Small path glob vocabulary: * (one segment), ** (any depth), ? (one character). */
|
|
32
|
+
export function matchesReviewPath(path, pattern) {
|
|
33
|
+
// Dynamic programming avoids exponential regex backtracking on repository input.
|
|
34
|
+
const tokens = [];
|
|
35
|
+
for (let i = 0; i < pattern.length; i++) {
|
|
36
|
+
if (pattern[i] === '*' && pattern[i + 1] === '*') {
|
|
37
|
+
i++;
|
|
38
|
+
if (pattern[i + 1] === '/') {
|
|
39
|
+
tokens.push('directory');
|
|
40
|
+
i++;
|
|
41
|
+
}
|
|
42
|
+
else
|
|
43
|
+
tokens.push('all');
|
|
44
|
+
}
|
|
45
|
+
else
|
|
46
|
+
tokens.push(pattern[i] === '*' ? 'segment' : pattern[i] === '?' ? 'character' : 'literal:' + pattern[i]);
|
|
47
|
+
}
|
|
48
|
+
let dp = new Uint8Array(path.length + 1);
|
|
49
|
+
dp[0] = 1;
|
|
50
|
+
for (const token of tokens) {
|
|
51
|
+
const next = new Uint8Array(path.length + 1);
|
|
52
|
+
if (token === 'directory') {
|
|
53
|
+
let started = false;
|
|
54
|
+
for (let j = 0; j <= path.length; j++) {
|
|
55
|
+
if (dp[j]) {
|
|
56
|
+
next[j] = 1;
|
|
57
|
+
started = true;
|
|
58
|
+
}
|
|
59
|
+
if (j > 0 && started && path[j - 1] === '/')
|
|
60
|
+
next[j] = 1;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
else if (token === 'all' || token === 'segment') {
|
|
64
|
+
next[0] = dp[0];
|
|
65
|
+
for (let j = 1; j <= path.length; j++)
|
|
66
|
+
next[j] = dp[j] || (next[j - 1] && (token === 'all' || path[j - 1] !== '/') ? 1 : 0);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
for (let j = 0; j < path.length; j++)
|
|
70
|
+
if (dp[j] && (token === 'character' ? path[j] !== '/' : path[j] === token.slice(8)))
|
|
71
|
+
next[j + 1] = 1;
|
|
72
|
+
}
|
|
73
|
+
dp = next;
|
|
74
|
+
}
|
|
75
|
+
return Boolean(dp[path.length]);
|
|
76
|
+
}
|
|
77
|
+
function language(path) {
|
|
78
|
+
const ext = path.split('.').pop()?.toLowerCase();
|
|
79
|
+
return { js: 'javascript', jsx: 'javascript', ts: 'javascript', tsx: 'javascript', mjs: 'javascript', cjs: 'javascript', py: 'python', go: 'go', java: 'java', rs: 'rust', cs: 'csharp', php: 'php', rb: 'ruby', c: 'c', cpp: 'cpp', sh: 'shell' }[ext || ''] || 'generic';
|
|
80
|
+
}
|
|
81
|
+
export function changeKind(path) {
|
|
82
|
+
if (/(^|\/)(__tests__|tests?|specs?)(\/|\.)|[.-](test|spec)\.|_test\./i.test(path))
|
|
83
|
+
return 'Tests';
|
|
84
|
+
if (/\.(md|mdx|rst|txt)$|(^|\/)(docs?)\//i.test(path))
|
|
85
|
+
return 'Documentation';
|
|
86
|
+
if (/(^|\/)(package(-lock)?\.json|[^/]*lock[^/]*|requirements[^/]*|go\.(mod|sum)|Cargo\.toml)$/.test(path))
|
|
87
|
+
return 'Dependencies';
|
|
88
|
+
if (/(^|\/)(\.github|\.gitlab|Dockerfile|docker-compose|tsconfig)|\.(ya?ml|toml|ini)$/.test(path))
|
|
89
|
+
return 'Configuration';
|
|
90
|
+
return language(path) === 'generic' ? 'Other' : 'Source';
|
|
91
|
+
}
|
|
92
|
+
const suggestions = {
|
|
93
|
+
'hardcoded-secret': 'Remove the literal credential, rotate it if it was real, and load it from a secret store or environment variable.',
|
|
94
|
+
'aws-key': 'Remove this access key and rotate it if real. Use the platform credential provider.',
|
|
95
|
+
'jwt-secret': 'Remove the token and invalidate it if real. Load credentials at runtime.',
|
|
96
|
+
'private-key-block': 'Remove this private key from the change and rotate it if real.',
|
|
97
|
+
eval: 'Use a fixed operation lookup or a structured parser instead of executing input as code.',
|
|
98
|
+
'new-function': 'Replace dynamic code construction with a fixed function or an explicit operation lookup.',
|
|
99
|
+
'child-exec': 'Use execFile with a fixed executable and an argument array; validate untrusted arguments.',
|
|
100
|
+
'sql-concat': 'Bind values through the database parameter API rather than interpolating them into SQL.',
|
|
101
|
+
innerhtml: 'Use textContent for text. If markup is required, sanitize it with an established HTML sanitizer.',
|
|
102
|
+
'empty-catch': 'Handle the error, propagate it, or explain and log an intentionally recoverable failure.',
|
|
103
|
+
'loose-eq': 'Use strict equality and make any intended type conversion explicit.',
|
|
104
|
+
'var-keyword': 'Use const unless this binding is reassigned; otherwise use let.',
|
|
105
|
+
'console-log': 'Use the application logger with a suitable level and avoid logging credentials.',
|
|
106
|
+
debugger: 'Remove the debugger statement before shipping.',
|
|
107
|
+
};
|
|
108
|
+
export function buildReview(diff, config = DEFAULT_REVIEW_CONFIG) {
|
|
109
|
+
const findings = [];
|
|
110
|
+
const files = [];
|
|
111
|
+
const minSeverity = config.profile === 'focused' ? 2 : config.profile === 'balanced' ? 1 : 0;
|
|
112
|
+
let conflicts = 0;
|
|
113
|
+
for (const file of diff.files) {
|
|
114
|
+
const path = file.newPath || file.oldPath;
|
|
115
|
+
const kind = changeKind(path);
|
|
116
|
+
const excluded = config.exclude.some(p => matchesReviewPath(path, p));
|
|
117
|
+
const skipped = file.skipReason || (excluded ? 'Excluded by repository configuration' : file.binary ? 'Binary content' : file.status === 'deleted' ? 'Deleted file: no added lines to inspect' : !file.hunks.length ? 'Metadata-only change' : null);
|
|
118
|
+
const fileFindings = [];
|
|
119
|
+
if (!skipped) {
|
|
120
|
+
for (const hunk of file.hunks) {
|
|
121
|
+
let line = hunk.newStart;
|
|
122
|
+
const numbers = [];
|
|
123
|
+
const added = new Set();
|
|
124
|
+
const text = [];
|
|
125
|
+
for (const l of hunk.lines) {
|
|
126
|
+
if (l.type === 'del')
|
|
127
|
+
continue;
|
|
128
|
+
numbers.push(line);
|
|
129
|
+
text.push(l.text);
|
|
130
|
+
if (l.type === 'add') {
|
|
131
|
+
added.add(line);
|
|
132
|
+
if (/^(<{7}|={7}|>{7})(?:\s|$)/.test(l.text))
|
|
133
|
+
conflicts++;
|
|
134
|
+
}
|
|
135
|
+
line++;
|
|
136
|
+
}
|
|
137
|
+
const candidates = analyzeSecurityFile(text.join('\n'), language(path));
|
|
138
|
+
const secretLines = new Set(candidates.filter(f => f.category === 'secret').map(f => numbers[f.line - 1]));
|
|
139
|
+
for (const f of candidates) {
|
|
140
|
+
const actual = numbers[f.line - 1];
|
|
141
|
+
const severity = f.severity;
|
|
142
|
+
if (!added.has(actual) || SEVERITY_RANK[severity] < minSeverity)
|
|
143
|
+
continue;
|
|
144
|
+
const id = `${encodeURIComponent(path)}:${actual}:${f.rule}`;
|
|
145
|
+
if (fileFindings.some(x => x.id === id))
|
|
146
|
+
continue;
|
|
147
|
+
fileFindings.push({ id, path, line: actual, rule: f.rule, severity, category: f.category, message: f.message,
|
|
148
|
+
suggestion: suggestions[f.rule] || 'Check whether this pattern is safe in its actual calling context and use the safer API where appropriate.',
|
|
149
|
+
excerpt: secretLines.has(actual) ? '[credential content redacted]' : f.excerpt });
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
findings.push(...fileFindings);
|
|
154
|
+
const sensitive = /(^|\/)(auth|security|payments?|migrations?)(\/|\.)|(^|\/)\.github\//i.test(path);
|
|
155
|
+
const risk = fileFindings.some(f => SEVERITY_RANK[f.severity] >= 3) || sensitive || file.additions + file.deletions > 500 ? 'high' : fileFindings.length || kind === 'Dependencies' || file.additions + file.deletions > 100 ? 'medium' : 'low';
|
|
156
|
+
files.push({ path, oldPath: file.oldPath, status: file.status, additions: file.additions, deletions: file.deletions, kind, risk, findings: fileFindings.length,
|
|
157
|
+
instructions: config.instructions.filter(r => matchesReviewPath(path, r.path)).map(r => r.instruction), skipped });
|
|
158
|
+
}
|
|
159
|
+
findings.sort((a, b) => SEVERITY_RANK[b.severity] - SEVERITY_RANK[a.severity] || a.path.localeCompare(b.path) || a.line - b.line);
|
|
160
|
+
files.sort((a, b) => ({ high: 3, medium: 2, low: 1 }[b.risk] - { high: 3, medium: 2, low: 1 }[a.risk]) || b.findings - a.findings || a.path.localeCompare(b.path));
|
|
161
|
+
const blocking = findings.filter(f => SEVERITY_RANK[f.severity] >= 3).length;
|
|
162
|
+
const hasSource = files.some(f => f.kind === 'Source' && f.status !== 'deleted' && !f.skipped);
|
|
163
|
+
const hasTests = files.some(f => f.kind === 'Tests' && f.status !== 'deleted' && (f.additions || f.deletions));
|
|
164
|
+
const checks = [
|
|
165
|
+
{ id: 'security', label: 'High-severity patterns', status: blocking ? 'fail' : 'pass', detail: blocking ? `${blocking} high or critical patterns need human review.` : 'No high or critical patterns detected in reviewed added lines.' },
|
|
166
|
+
{ id: 'conflicts', label: 'Conflict markers', status: conflicts ? 'fail' : 'pass', detail: conflicts ? `${conflicts} added conflict markers found.` : 'No conflict markers in reviewed added lines.' },
|
|
167
|
+
{ id: 'tests', label: 'Test changes', status: !hasSource ? 'skip' : hasTests ? 'pass' : 'warn', detail: !hasSource ? 'No reviewed source changes.' : hasTests ? 'Test files changed. Execution and coverage have not been verified.' : 'Source changed without test-file changes. Confirm existing coverage or add tests.' },
|
|
168
|
+
{ id: 'size', label: 'Review size', status: diff.stats.additions + diff.stats.deletions > 1000 ? 'warn' : 'pass', detail: `${diff.stats.additions + diff.stats.deletions} changed lines. Large changes may benefit from separate reviews.` },
|
|
169
|
+
{ id: 'coverage', label: 'Review coverage', status: files.some(f => f.skipped && f.status !== 'deleted') ? 'warn' : 'pass', detail: `${files.filter(f => !f.skipped).length} files inspected; ${files.filter(f => f.skipped).length} skipped. See each file for its reason.` },
|
|
170
|
+
];
|
|
171
|
+
const groups = [...new Set(files.map(f => f.kind))].map(k => `${files.filter(f => f.kind === k).length} ${k.toLowerCase()}`).join(', ');
|
|
172
|
+
return { fingerprint: '', generatedAt: new Date().toISOString(), mode: diff.mode || 'working', base: diff.base || '', head: diff.head || '', profile: config.profile,
|
|
173
|
+
summary: files.length ? `${files.length} changed files (${groups}), with ${diff.stats.additions} additions and ${diff.stats.deletions} deletions. ${findings.length} patterns flagged on added lines.` : 'No changes in this comparison.', files, findings, checks, stats: diff.stats,
|
|
174
|
+
coverage: { reviewed: files.filter(f => !f.skipped).length, skipped: files.filter(f => f.skipped).length, untracked: diff.untracked || 0,
|
|
175
|
+
limitations: ['Local pattern checks inspect added lines with surrounding patch context; they are not a full semantic or vulnerability audit.', 'Tests are not executed. Test-change checks do not measure test coverage.', 'Risk is a heuristic based on findings, sensitive paths, and change size. Repository guidelines are prompts for human or optional AI review.'] } };
|
|
176
|
+
}
|
|
177
|
+
export function reviewMarkdown(report) {
|
|
178
|
+
const safe = (v) => v.replace(/[\r\n]/g, ' ').replace(/[`|<>]/g, '');
|
|
179
|
+
return ['# Onboarder change review', '', report.summary, '', `Comparison: ${report.mode}; base ${safe(report.base)}; head ${safe(report.head) || 'local changes'}.`, `Profile: ${report.profile}.`, '', '## Checks', '',
|
|
180
|
+
...report.checks.map(c => `- ${c.status.toUpperCase()}: ${c.label} — ${c.detail}`), '', '## Findings', '',
|
|
181
|
+
...(report.findings.length ? report.findings.map(f => `- **${f.severity}** — ${safe(f.path)}:${f.line}: ${f.message}\n ${f.suggestion}`) : ['No patterns detected in the reviewed added lines.']), '', '## Change walkthrough', '',
|
|
182
|
+
...report.files.map(f => `- ${safe(f.path)} — ${f.status}, +${f.additions}/-${f.deletions}, ${f.risk} risk.${f.skipped ? ' Skipped: ' + f.skipped + '.' : ''}${f.instructions.length ? ' Guidelines: ' + f.instructions.map(safe).join('; ') : ''}`), '', '## Scope', '', ...report.coverage.limitations.map(l => '- ' + l), '', 'Finding acknowledgements in the browser are local notes, not proof of a fix.', ''].join('\n');
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=review.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review.js","sourceRoot":"","sources":["../../src/shared/review/review.ts"],"names":[],"mappings":"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","sourcesContent":["import { analyzeSecurityFile } from '../analyzer/security.js';\nimport type { GitDiff, ReviewCheck, ReviewConfig, ReviewFile, ReviewFinding, ReviewProfile, ReviewReport, Severity } from './contracts.js';\n\nexport const SEVERITY_RANK: Record<Severity, number> = { info: 0, low: 1, medium: 2, high: 3, critical: 4 };\nexport const DEFAULT_REVIEW_CONFIG: ReviewConfig = { profile: 'balanced', exclude: [], instructions: [] };\nexport function reviewProfile(value: unknown): ReviewProfile {\n if (value === 'focused' || value === 'balanced' || value === 'thorough') return value;\n throw new Error('Review profile must be focused, balanced, or thorough.');\n}\nexport function parseReviewConfig(value: unknown): ReviewConfig {\n if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error('Review configuration must be a JSON object.');\n const v = value as Record<string, unknown>;\n if (Object.keys(v).some(k => !['profile', 'exclude', 'instructions'].includes(k))) throw new Error('Unknown review configuration field. Use profile, exclude, and instructions.');\n const exclude = v.exclude ?? [];\n const instructions = v.instructions ?? [];\n if (!Array.isArray(exclude) || exclude.length > 50 || exclude.some(p => typeof p !== 'string' || p.length > 200 || !p)) throw new Error('exclude must contain up to 50 path patterns.');\n if (!Array.isArray(instructions) || instructions.length > 50) throw new Error('instructions must contain up to 50 path guidelines.');\n const rules = instructions.map((rule: unknown) => {\n if (!rule || typeof rule !== 'object') throw new Error('Each guideline needs a path and instruction.');\n const r = rule as Record<string, unknown>;\n if (typeof r.path !== 'string' || !r.path || r.path.length > 200 || typeof r.instruction !== 'string' || !r.instruction.trim() || r.instruction.length > 2000) throw new Error('Each guideline needs a path pattern and an instruction of at most 2000 characters.');\n return { path: r.path, instruction: r.instruction };\n });\n return { profile: v.profile === undefined ? 'balanced' : reviewProfile(v.profile), exclude, instructions: rules };\n}\n/** Small path glob vocabulary: * (one segment), ** (any depth), ? (one character). */\nexport function matchesReviewPath(path: string, pattern: string): boolean {\n // Dynamic programming avoids exponential regex backtracking on repository input.\n const tokens: string[] = [];\n for (let i = 0; i < pattern.length; i++) {\n if (pattern[i] === '*' && pattern[i + 1] === '*') {\n i++;\n if (pattern[i + 1] === '/') { tokens.push('directory'); i++; } else tokens.push('all');\n } else tokens.push(pattern[i] === '*' ? 'segment' : pattern[i] === '?' ? 'character' : 'literal:' + pattern[i]);\n }\n let dp = new Uint8Array(path.length + 1); dp[0] = 1;\n for (const token of tokens) {\n const next = new Uint8Array(path.length + 1);\n if (token === 'directory') {\n let started = false;\n for (let j = 0; j <= path.length; j++) {\n if (dp[j]) { next[j] = 1; started = true; }\n if (j > 0 && started && path[j - 1] === '/') next[j] = 1;\n }\n } else if (token === 'all' || token === 'segment') {\n next[0] = dp[0];\n for (let j = 1; j <= path.length; j++) next[j] = dp[j] || (next[j - 1] && (token === 'all' || path[j - 1] !== '/') ? 1 : 0);\n } else {\n for (let j = 0; j < path.length; j++) if (dp[j] && (token === 'character' ? path[j] !== '/' : path[j] === token.slice(8))) next[j + 1] = 1;\n }\n dp = next;\n }\n return Boolean(dp[path.length]);\n}\nfunction language(path: string): string {\n const ext = path.split('.').pop()?.toLowerCase();\n return ({ js: 'javascript', jsx: 'javascript', ts: 'javascript', tsx: 'javascript', mjs: 'javascript', cjs: 'javascript', py: 'python', go: 'go', java: 'java', rs: 'rust', cs: 'csharp', php: 'php', rb: 'ruby', c: 'c', cpp: 'cpp', sh: 'shell' } as Record<string, string>)[ext || ''] || 'generic';\n}\nexport function changeKind(path: string): string {\n if (/(^|\\/)(__tests__|tests?|specs?)(\\/|\\.)|[.-](test|spec)\\.|_test\\./i.test(path)) return 'Tests';\n if (/\\.(md|mdx|rst|txt)$|(^|\\/)(docs?)\\//i.test(path)) return 'Documentation';\n if (/(^|\\/)(package(-lock)?\\.json|[^/]*lock[^/]*|requirements[^/]*|go\\.(mod|sum)|Cargo\\.toml)$/.test(path)) return 'Dependencies';\n if (/(^|\\/)(\\.github|\\.gitlab|Dockerfile|docker-compose|tsconfig)|\\.(ya?ml|toml|ini)$/.test(path)) return 'Configuration';\n return language(path) === 'generic' ? 'Other' : 'Source';\n}\nconst suggestions: Record<string, string> = {\n 'hardcoded-secret': 'Remove the literal credential, rotate it if it was real, and load it from a secret store or environment variable.',\n 'aws-key': 'Remove this access key and rotate it if real. Use the platform credential provider.',\n 'jwt-secret': 'Remove the token and invalidate it if real. Load credentials at runtime.',\n 'private-key-block': 'Remove this private key from the change and rotate it if real.',\n eval: 'Use a fixed operation lookup or a structured parser instead of executing input as code.',\n 'new-function': 'Replace dynamic code construction with a fixed function or an explicit operation lookup.',\n 'child-exec': 'Use execFile with a fixed executable and an argument array; validate untrusted arguments.',\n 'sql-concat': 'Bind values through the database parameter API rather than interpolating them into SQL.',\n innerhtml: 'Use textContent for text. If markup is required, sanitize it with an established HTML sanitizer.',\n 'empty-catch': 'Handle the error, propagate it, or explain and log an intentionally recoverable failure.',\n 'loose-eq': 'Use strict equality and make any intended type conversion explicit.',\n 'var-keyword': 'Use const unless this binding is reassigned; otherwise use let.',\n 'console-log': 'Use the application logger with a suitable level and avoid logging credentials.',\n debugger: 'Remove the debugger statement before shipping.',\n};\nexport function buildReview(diff: GitDiff, config = DEFAULT_REVIEW_CONFIG): ReviewReport {\n const findings: ReviewFinding[] = [];\n const files: ReviewFile[] = [];\n const minSeverity = config.profile === 'focused' ? 2 : config.profile === 'balanced' ? 1 : 0;\n let conflicts = 0;\n for (const file of diff.files) {\n const path = file.newPath || file.oldPath;\n const kind = changeKind(path);\n const excluded = config.exclude.some(p => matchesReviewPath(path, p));\n const skipped = file.skipReason || (excluded ? 'Excluded by repository configuration' : file.binary ? 'Binary content' : file.status === 'deleted' ? 'Deleted file: no added lines to inspect' : !file.hunks.length ? 'Metadata-only change' : null);\n const fileFindings: ReviewFinding[] = [];\n if (!skipped) {\n for (const hunk of file.hunks) {\n let line = hunk.newStart;\n const numbers: number[] = [];\n const added = new Set<number>();\n const text: string[] = [];\n for (const l of hunk.lines) {\n if (l.type === 'del') continue;\n numbers.push(line);\n text.push(l.text);\n if (l.type === 'add') { added.add(line); if (/^(<{7}|={7}|>{7})(?:\\s|$)/.test(l.text)) conflicts++; }\n line++;\n }\n const candidates = analyzeSecurityFile(text.join('\\n'), language(path));\n const secretLines = new Set(candidates.filter(f => f.category === 'secret').map(f => numbers[f.line - 1]));\n for (const f of candidates) {\n const actual = numbers[f.line - 1];\n const severity = f.severity as Severity;\n if (!added.has(actual) || SEVERITY_RANK[severity] < minSeverity) continue;\n const id = `${encodeURIComponent(path)}:${actual}:${f.rule}`;\n if (fileFindings.some(x => x.id === id)) continue;\n fileFindings.push({ id, path, line: actual, rule: f.rule, severity, category: f.category, message: f.message,\n suggestion: suggestions[f.rule] || 'Check whether this pattern is safe in its actual calling context and use the safer API where appropriate.',\n excerpt: secretLines.has(actual) ? '[credential content redacted]' : f.excerpt });\n }\n }\n }\n findings.push(...fileFindings);\n const sensitive = /(^|\\/)(auth|security|payments?|migrations?)(\\/|\\.)|(^|\\/)\\.github\\//i.test(path);\n const risk = fileFindings.some(f => SEVERITY_RANK[f.severity] >= 3) || sensitive || file.additions + file.deletions > 500 ? 'high' : fileFindings.length || kind === 'Dependencies' || file.additions + file.deletions > 100 ? 'medium' : 'low';\n files.push({ path, oldPath: file.oldPath, status: file.status, additions: file.additions, deletions: file.deletions, kind, risk, findings: fileFindings.length,\n instructions: config.instructions.filter(r => matchesReviewPath(path, r.path)).map(r => r.instruction), skipped });\n }\n findings.sort((a, b) => SEVERITY_RANK[b.severity] - SEVERITY_RANK[a.severity] || a.path.localeCompare(b.path) || a.line - b.line);\n files.sort((a, b) => ({ high: 3, medium: 2, low: 1 }[b.risk] - { high: 3, medium: 2, low: 1 }[a.risk]) || b.findings - a.findings || a.path.localeCompare(b.path));\n const blocking = findings.filter(f => SEVERITY_RANK[f.severity] >= 3).length;\n const hasSource = files.some(f => f.kind === 'Source' && f.status !== 'deleted' && !f.skipped);\n const hasTests = files.some(f => f.kind === 'Tests' && f.status !== 'deleted' && (f.additions || f.deletions));\n const checks: ReviewCheck[] = [\n { id: 'security', label: 'High-severity patterns', status: blocking ? 'fail' : 'pass', detail: blocking ? `${blocking} high or critical patterns need human review.` : 'No high or critical patterns detected in reviewed added lines.' },\n { id: 'conflicts', label: 'Conflict markers', status: conflicts ? 'fail' : 'pass', detail: conflicts ? `${conflicts} added conflict markers found.` : 'No conflict markers in reviewed added lines.' },\n { id: 'tests', label: 'Test changes', status: !hasSource ? 'skip' : hasTests ? 'pass' : 'warn', detail: !hasSource ? 'No reviewed source changes.' : hasTests ? 'Test files changed. Execution and coverage have not been verified.' : 'Source changed without test-file changes. Confirm existing coverage or add tests.' },\n { id: 'size', label: 'Review size', status: diff.stats.additions + diff.stats.deletions > 1000 ? 'warn' : 'pass', detail: `${diff.stats.additions + diff.stats.deletions} changed lines. Large changes may benefit from separate reviews.` },\n { id: 'coverage', label: 'Review coverage', status: files.some(f => f.skipped && f.status !== 'deleted') ? 'warn' : 'pass', detail: `${files.filter(f => !f.skipped).length} files inspected; ${files.filter(f => f.skipped).length} skipped. See each file for its reason.` },\n ];\n const groups = [...new Set(files.map(f => f.kind))].map(k => `${files.filter(f => f.kind === k).length} ${k.toLowerCase()}`).join(', ');\n return { fingerprint: '', generatedAt: new Date().toISOString(), mode: diff.mode || 'working', base: diff.base || '', head: diff.head || '', profile: config.profile,\n summary: files.length ? `${files.length} changed files (${groups}), with ${diff.stats.additions} additions and ${diff.stats.deletions} deletions. ${findings.length} patterns flagged on added lines.` : 'No changes in this comparison.', files, findings, checks, stats: diff.stats,\n coverage: { reviewed: files.filter(f => !f.skipped).length, skipped: files.filter(f => f.skipped).length, untracked: diff.untracked || 0,\n limitations: ['Local pattern checks inspect added lines with surrounding patch context; they are not a full semantic or vulnerability audit.', 'Tests are not executed. Test-change checks do not measure test coverage.', 'Risk is a heuristic based on findings, sensitive paths, and change size. Repository guidelines are prompts for human or optional AI review.'] } };\n}\nexport function reviewMarkdown(report: ReviewReport): string {\n const safe = (v: string) => v.replace(/[\\r\\n]/g, ' ').replace(/[`|<>]/g, '');\n return ['# Onboarder change review', '', report.summary, '', `Comparison: ${report.mode}; base ${safe(report.base)}; head ${safe(report.head) || 'local changes'}.`, `Profile: ${report.profile}.`, '', '## Checks', '',\n ...report.checks.map(c => `- ${c.status.toUpperCase()}: ${c.label} — ${c.detail}`), '', '## Findings', '',\n ...(report.findings.length ? report.findings.map(f => `- **${f.severity}** — ${safe(f.path)}:${f.line}: ${f.message}\\n ${f.suggestion}`) : ['No patterns detected in the reviewed added lines.']), '', '## Change walkthrough', '',\n ...report.files.map(f => `- ${safe(f.path)} — ${f.status}, +${f.additions}/-${f.deletions}, ${f.risk} risk.${f.skipped ? ' Skipped: ' + f.skipped + '.' : ''}${f.instructions.length ? ' Guidelines: ' + f.instructions.map(safe).join('; ') : ''}`), '', '## Scope', '', ...report.coverage.limitations.map(l => '- ' + l), '', 'Finding acknowledgements in the browser are local notes, not proof of a fix.', ''].join('\\n');\n}\n"]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export declare function parseQuery(raw: any, options?: Record<string, any>): {
|
|
2
|
+
raw: string;
|
|
3
|
+
clauses: any[];
|
|
4
|
+
terms: any[];
|
|
5
|
+
phrases: any[];
|
|
6
|
+
negatives: any[];
|
|
7
|
+
exts: any[];
|
|
8
|
+
paths: any[];
|
|
9
|
+
kinds: any[];
|
|
10
|
+
isTest: boolean;
|
|
11
|
+
isSource: boolean;
|
|
12
|
+
regex: any;
|
|
13
|
+
regexSource: string;
|
|
14
|
+
regexFlags: string;
|
|
15
|
+
regexGlobal: any;
|
|
16
|
+
caseSensitive: boolean;
|
|
17
|
+
error: any;
|
|
18
|
+
};
|
|
19
|
+
export declare function removeClause(raw: any, clause: any): string;
|
|
20
|
+
export declare function queryIsEmpty(parsed: any): boolean;
|
|
21
|
+
export declare function hasFilters(parsed: any): boolean;
|
|
22
|
+
export declare function isAdvanced(parsed: any): any;
|
|
23
|
+
export declare function matchesPathFilters(parsed: any, path: any): boolean;
|
|
24
|
+
export declare function scorePath(parsed: any, path: any): number;
|
|
25
|
+
export declare function scoreSymbol(parsed: any, name: any, kind: any): number;
|
|
26
|
+
export declare function scoreContent(parsed: any, text: any): {
|
|
27
|
+
score: number;
|
|
28
|
+
index: number;
|
|
29
|
+
};
|
|
30
|
+
export declare function highlightRanges(text: any, parsed: any): any[];
|
|
31
|
+
export declare function lineOfIndex(text: any, index: any): number;
|
|
32
|
+
export declare function snippetAt(text: any, index: any, maxLength?: number): any;
|