codebase-onboarder 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +196 -47
- package/bin/build-if-source.js +23 -0
- package/cli/commands.d.ts +26 -0
- package/cli/commands.js +836 -811
- package/cli/commands.js.map +1 -0
- package/cli/explorer/advanced.d.ts +14 -0
- package/cli/explorer/advanced.js +449 -0
- package/cli/explorer/advanced.js.map +1 -0
- package/cli/explorer/app.d.ts +1 -0
- package/cli/explorer/app.js +396 -229
- package/cli/explorer/app.js.map +1 -0
- package/cli/explorer/assistant.d.ts +9 -0
- package/cli/explorer/assistant.js +58 -0
- package/cli/explorer/assistant.js.map +1 -0
- package/cli/explorer/commands.d.ts +17 -0
- package/cli/explorer/commands.js +400 -162
- package/cli/explorer/commands.js.map +1 -0
- package/cli/explorer/featureViews.d.ts +124 -0
- package/cli/explorer/featureViews.js +179 -0
- package/cli/explorer/featureViews.js.map +1 -0
- package/cli/explorer/github.d.ts +21 -0
- package/cli/explorer/github.js +73 -0
- package/cli/explorer/github.js.map +1 -0
- package/cli/explorer/graphs.d.ts +7 -0
- package/cli/explorer/graphs.js +173 -0
- package/cli/explorer/graphs.js.map +1 -0
- package/cli/explorer/picker.d.ts +22 -0
- package/cli/explorer/picker.js +150 -0
- package/cli/explorer/picker.js.map +1 -0
- package/cli/explorer/report.d.ts +85 -0
- package/cli/explorer/report.js +60 -0
- package/cli/explorer/report.js.map +1 -0
- package/cli/explorer/session.d.ts +449 -0
- package/cli/explorer/session.js +184 -95
- package/cli/explorer/session.js.map +1 -0
- package/cli/explorer/views.d.ts +19 -0
- package/cli/explorer/views.js +496 -412
- package/cli/explorer/views.js.map +1 -0
- package/cli/explorer/wrap.d.ts +1 -0
- package/cli/explorer/wrap.js +33 -0
- package/cli/explorer/wrap.js.map +1 -0
- package/cli/main.d.ts +1 -0
- package/cli/main.js +235 -138
- package/cli/main.js.map +1 -0
- package/cli/prompt.d.ts +5 -0
- package/cli/prompt.js +84 -80
- package/cli/prompt.js.map +1 -0
- package/cli/scanOptions.d.ts +2 -0
- package/cli/scanOptions.js +11 -0
- package/cli/scanOptions.js.map +1 -0
- package/cli/ui.d.ts +33 -0
- package/cli/ui.js +55 -35
- package/cli/ui.js.map +1 -0
- package/cli/wizard.d.ts +187 -0
- package/cli/wizard.js +304 -284
- package/cli/wizard.js.map +1 -0
- package/package.json +15 -4
- package/public/app.d.ts +1 -0
- package/public/app.js +1057 -1009
- package/public/app.js.map +1 -0
- package/public/browser.d.ts +68 -0
- package/public/browser.js +2 -0
- package/public/browser.js.map +1 -0
- package/public/index.html +30 -13
- package/public/js/about.d.ts +6 -0
- package/public/js/about.js +165 -172
- package/public/js/about.js.map +1 -0
- package/public/js/aiDraft.d.ts +3 -0
- package/public/js/aiDraft.js +116 -124
- package/public/js/aiDraft.js.map +1 -0
- package/public/js/analysisPanel.d.ts +7 -0
- package/public/js/analysisPanel.js +166 -166
- package/public/js/analysisPanel.js.map +1 -0
- package/public/js/analysisReport.d.ts +38 -0
- package/public/js/analysisReport.js +105 -110
- package/public/js/analysisReport.js.map +1 -0
- package/public/js/api.d.ts +26 -0
- package/public/js/api.js +176 -167
- package/public/js/api.js.map +1 -0
- package/public/js/atlas.d.ts +6 -0
- package/public/js/atlas.js +50 -58
- package/public/js/atlas.js.map +1 -0
- package/public/js/blameView.d.ts +2 -0
- package/public/js/blameView.js +36 -37
- package/public/js/blameView.js.map +1 -0
- package/public/js/codeTab.d.ts +3 -0
- package/public/js/codeTab.js +175 -180
- package/public/js/codeTab.js.map +1 -0
- package/public/js/codeViewer.d.ts +5 -0
- package/public/js/codeViewer.js +162 -150
- package/public/js/codeViewer.js.map +1 -0
- package/public/js/components/FileChip.d.ts +9 -0
- package/public/js/components/FileChip.js +45 -49
- package/public/js/components/FileChip.js.map +1 -0
- package/public/js/components/MetricSparkline.d.ts +7 -0
- package/public/js/components/MetricSparkline.js +35 -44
- package/public/js/components/MetricSparkline.js.map +1 -0
- package/public/js/components/RiskBadge.d.ts +9 -0
- package/public/js/components/RiskBadge.js +55 -63
- package/public/js/components/RiskBadge.js.map +1 -0
- package/public/js/deepAnalysisView.d.ts +99 -0
- package/public/js/deepAnalysisView.js +282 -302
- package/public/js/deepAnalysisView.js.map +1 -0
- package/public/js/diagramPane.d.ts +8 -0
- package/public/js/diagramPane.js +133 -135
- package/public/js/diagramPane.js.map +1 -0
- package/public/js/diffView.d.ts +6 -0
- package/public/js/diffView.js +222 -209
- package/public/js/diffView.js.map +1 -0
- package/public/js/docsView.d.ts +2 -0
- package/public/js/docsView.js +441 -442
- package/public/js/docsView.js.map +1 -0
- package/public/js/dom.d.ts +189 -0
- package/public/js/dom.js +5 -0
- package/public/js/dom.js.map +1 -0
- package/public/js/fileSourceBrowser.d.ts +5 -0
- package/public/js/fileSourceBrowser.js +33 -41
- package/public/js/fileSourceBrowser.js.map +1 -0
- package/public/js/flameGraph.d.ts +5 -0
- package/public/js/flameGraph.js +62 -72
- package/public/js/flameGraph.js.map +1 -0
- package/public/js/forceGraph.d.ts +10 -0
- package/public/js/forceGraph.js +581 -556
- package/public/js/forceGraph.js.map +1 -0
- package/public/js/heatmap.d.ts +4 -0
- package/public/js/heatmap.js +142 -164
- package/public/js/heatmap.js.map +1 -0
- package/public/js/highlight.d.ts +2 -0
- package/public/js/highlight.js +116 -107
- package/public/js/highlight.js.map +1 -0
- package/public/js/html.d.ts +2 -0
- package/public/js/html.js +14 -44
- package/public/js/html.js.map +1 -0
- package/public/js/insightsView.d.ts +5 -0
- package/public/js/insightsView.js +93 -111
- package/public/js/insightsView.js.map +1 -0
- package/public/js/inspector.d.ts +37 -0
- package/public/js/inspector.js +416 -445
- package/public/js/inspector.js.map +1 -0
- package/public/js/llm.d.ts +113 -0
- package/public/js/llm.js +233 -272
- package/public/js/llm.js.map +1 -0
- package/public/js/mapView.d.ts +3 -0
- package/public/js/mapView.js +121 -120
- package/public/js/mapView.js.map +1 -0
- package/public/js/markdown.d.ts +3 -0
- package/public/js/markdown.js +84 -91
- package/public/js/markdown.js.map +1 -0
- package/public/js/mindmap.d.ts +32 -0
- package/public/js/mindmap.js +244 -259
- package/public/js/mindmap.js.map +1 -0
- package/public/js/mobilePanels.d.ts +5 -0
- package/public/js/mobilePanels.js +50 -0
- package/public/js/mobilePanels.js.map +1 -0
- package/public/js/repoFiles.d.ts +12 -0
- package/public/js/repoFiles.js +28 -27
- package/public/js/repoFiles.js.map +1 -0
- package/public/js/reviewView.d.ts +28 -0
- package/public/js/reviewView.js +256 -0
- package/public/js/reviewView.js.map +1 -0
- package/public/js/sbomView.d.ts +3 -0
- package/public/js/sbomView.js +59 -67
- package/public/js/sbomView.js.map +1 -0
- package/public/js/scanCache.d.ts +16 -0
- package/public/js/scanCache.js +67 -65
- package/public/js/scanCache.js.map +1 -0
- package/public/js/search.d.ts +7 -0
- package/public/js/search.js +868 -800
- package/public/js/search.js.map +1 -0
- package/public/js/searchLocal.d.ts +42 -0
- package/public/js/searchLocal.js +87 -0
- package/public/js/searchLocal.js.map +1 -0
- package/public/js/serverSettings.d.ts +5 -0
- package/public/js/serverSettings.js +153 -164
- package/public/js/serverSettings.js.map +1 -0
- package/public/js/state.d.ts +798 -0
- package/public/js/state.js +114 -122
- package/public/js/state.js.map +1 -0
- package/public/js/tour.d.ts +6 -0
- package/public/js/tour.js +5 -7
- package/public/js/tour.js.map +1 -0
- package/public/js/transitions.d.ts +2 -0
- package/public/js/transitions.js +9 -10
- package/public/js/transitions.js.map +1 -0
- package/public/js/tree.d.ts +12 -0
- package/public/js/tree.js +157 -154
- package/public/js/tree.js.map +1 -0
- package/public/js/workflowsView.d.ts +3 -0
- package/public/js/workflowsView.js +15 -22
- package/public/js/workflowsView.js.map +1 -0
- package/public/search.css +495 -0
- package/public/styles.css +163 -346
- package/public/workbench.css +166 -0
- package/server/apiAuth.d.ts +3 -0
- package/server/apiAuth.js +18 -20
- package/server/apiAuth.js.map +1 -0
- package/server/apiDiff.d.ts +2 -0
- package/server/apiDiff.js +20 -18
- package/server/apiDiff.js.map +1 -0
- package/server/apiDocs.d.ts +2 -0
- package/server/apiDocs.js +38 -40
- package/server/apiDocs.js.map +1 -0
- package/server/apiFile.d.ts +1 -0
- package/server/apiFile.js +14 -17
- package/server/apiFile.js.map +1 -0
- package/server/apiGitBlame.d.ts +2 -0
- package/server/apiGitBlame.js +50 -51
- package/server/apiGitBlame.js.map +1 -0
- package/server/apiMcp.d.ts +4 -0
- package/server/apiMcp.js +64 -66
- package/server/apiMcp.js.map +1 -0
- package/server/apiReview.d.ts +2 -0
- package/server/apiReview.js +45 -0
- package/server/apiReview.js.map +1 -0
- package/server/apiScan.d.ts +5 -0
- package/server/apiScan.js +90 -71
- package/server/apiScan.js.map +1 -0
- package/server/apiSearch.d.ts +33 -0
- package/server/apiSearch.js +184 -200
- package/server/apiSearch.js.map +1 -0
- package/server/apiSettings.d.ts +4 -0
- package/server/apiSettings.js +84 -85
- package/server/apiSettings.js.map +1 -0
- package/server/apiTools.d.ts +3 -0
- package/server/apiTools.js +55 -56
- package/server/apiTools.js.map +1 -0
- package/server/auth.d.ts +5 -0
- package/server/auth.js +54 -51
- package/server/auth.js.map +1 -0
- package/server/config.d.ts +42 -0
- package/server/config.js +189 -194
- package/server/config.js.map +1 -0
- package/server/daemon.d.ts +12 -0
- package/server/daemon.js +124 -114
- package/server/daemon.js.map +1 -0
- package/server/fileSourceNode.d.ts +2 -0
- package/server/fileSourceNode.js +34 -36
- package/server/fileSourceNode.js.map +1 -0
- package/server/gitClone.d.ts +9 -0
- package/server/gitClone.js +59 -61
- package/server/gitClone.js.map +1 -0
- package/server/gitDiff.d.ts +36 -0
- package/server/gitDiff.js +271 -169
- package/server/gitDiff.js.map +1 -0
- package/server/gitHistory.d.ts +12 -0
- package/server/gitHistory.js +80 -80
- package/server/gitHistory.js.map +1 -0
- package/server/gitRemote.d.ts +12 -0
- package/server/gitRemote.js +60 -0
- package/server/gitRemote.js.map +1 -0
- package/server/htmlText.d.ts +4 -0
- package/server/htmlText.js +16 -23
- package/server/htmlText.js.map +1 -0
- package/server/http.d.ts +5 -0
- package/server/http.js +27 -30
- package/server/http.js.map +1 -0
- package/server/httpGuards.d.ts +2 -0
- package/server/httpGuards.js +47 -43
- package/server/httpGuards.js.map +1 -0
- package/server/https.d.ts +34 -0
- package/server/https.js +121 -111
- package/server/https.js.map +1 -0
- package/server/index.d.ts +40 -0
- package/server/index.js +139 -147
- package/server/index.js.map +1 -0
- package/server/layout.d.ts +26 -0
- package/server/layout.js +59 -37
- package/server/layout.js.map +1 -0
- package/server/llmProxy.d.ts +3 -0
- package/server/llmProxy.js +137 -135
- package/server/llmProxy.js.map +1 -0
- package/server/logger.d.ts +38 -0
- package/server/logger.js +198 -211
- package/server/logger.js.map +1 -0
- package/server/mcp/analysis.d.ts +29 -0
- package/server/mcp/analysis.js +99 -120
- package/server/mcp/analysis.js.map +1 -0
- package/server/mcp/http.d.ts +9 -0
- package/server/mcp/http.js +128 -137
- package/server/mcp/http.js.map +1 -0
- package/server/mcp/runner.d.ts +68 -0
- package/server/mcp/runner.js +208 -218
- package/server/mcp/runner.js.map +1 -0
- package/server/mcp/server.d.ts +29 -0
- package/server/mcp/server.js +166 -179
- package/server/mcp/server.js.map +1 -0
- package/server/mcp/standalone.d.ts +1 -0
- package/server/mcp/standalone.js +8 -10
- package/server/mcp/standalone.js.map +1 -0
- package/server/mcp/tools.d.ts +2020 -0
- package/server/mcp/tools.js +523 -574
- package/server/mcp/tools.js.map +1 -0
- package/server/paths.d.ts +3 -0
- package/server/paths.js +17 -15
- package/server/paths.js.map +1 -0
- package/server/pidfile.d.ts +9 -0
- package/server/pidfile.js +43 -45
- package/server/pidfile.js.map +1 -0
- package/server/review.d.ts +5 -0
- package/server/review.js +35 -0
- package/server/review.js.map +1 -0
- package/server/router.d.ts +33 -0
- package/server/router.js +191 -197
- package/server/router.js.map +1 -0
- package/server/scanRequest.d.ts +3 -0
- package/server/scanRequest.js +36 -0
- package/server/scanRequest.js.map +1 -0
- package/server/searchIndex.d.ts +17 -0
- package/server/searchIndex.js +83 -80
- package/server/searchIndex.js.map +1 -0
- package/server/sessions.d.ts +14 -0
- package/server/sessions.js +62 -70
- package/server/sessions.js.map +1 -0
- package/server/startup.d.ts +118 -0
- package/server/startup.js +143 -148
- package/server/startup.js.map +1 -0
- package/server/static.d.ts +6 -0
- package/server/static.js +28 -31
- package/server/static.js.map +1 -0
- package/server/tools/install.d.ts +4 -0
- package/server/tools/install.js +176 -185
- package/server/tools/install.js.map +1 -0
- package/server/tools/parse.d.ts +8 -0
- package/server/tools/parse.js +112 -114
- package/server/tools/parse.js.map +1 -0
- package/server/tools/platform.d.ts +9 -0
- package/server/tools/platform.js +49 -47
- package/server/tools/platform.js.map +1 -0
- package/server/tools/registry.d.ts +137 -0
- package/server/tools/registry.js +173 -172
- package/server/tools/registry.js.map +1 -0
- package/server/tools/scan.d.ts +34 -0
- package/server/tools/scan.js +89 -98
- package/server/tools/scan.js.map +1 -0
- package/server/tools.d.ts +34 -0
- package/server/tools.js +94 -107
- package/server/tools.js.map +1 -0
- package/server/tunnel.d.ts +29 -0
- package/server/tunnel.js +61 -66
- package/server/tunnel.js.map +1 -0
- package/shared/analyzer/docs.d.ts +16 -0
- package/shared/analyzer/docs.js +99 -93
- package/shared/analyzer/docs.js.map +1 -0
- package/shared/analyzer/explainLocal.d.ts +4 -0
- package/shared/analyzer/explainLocal.js +122 -142
- package/shared/analyzer/explainLocal.js.map +1 -0
- package/shared/analyzer/github.d.ts +37 -0
- package/shared/analyzer/github.js +79 -0
- package/shared/analyzer/github.js.map +1 -0
- package/shared/analyzer/graph.d.ts +41 -0
- package/shared/analyzer/graph.js +393 -400
- package/shared/analyzer/graph.js.map +1 -0
- package/shared/analyzer/health.d.ts +33 -0
- package/shared/analyzer/health.js +197 -193
- package/shared/analyzer/health.js.map +1 -0
- package/shared/analyzer/history.d.ts +29 -0
- package/shared/analyzer/history.js +110 -111
- package/shared/analyzer/history.js.map +1 -0
- package/shared/analyzer/jsonConfig.d.ts +2 -0
- package/shared/analyzer/jsonConfig.js +61 -0
- package/shared/analyzer/jsonConfig.js.map +1 -0
- package/shared/analyzer/languages/csharp.d.ts +26 -0
- package/shared/analyzer/languages/csharp.js +83 -88
- package/shared/analyzer/languages/csharp.js.map +1 -0
- package/shared/analyzer/languages/generic.d.ts +23 -0
- package/shared/analyzer/languages/generic.js +94 -105
- package/shared/analyzer/languages/generic.js.map +1 -0
- package/shared/analyzer/languages/go.d.ts +24 -0
- package/shared/analyzer/languages/go.js +45 -54
- package/shared/analyzer/languages/go.js.map +1 -0
- package/shared/analyzer/languages/index.d.ts +6 -0
- package/shared/analyzer/languages/index.js +19 -20
- package/shared/analyzer/languages/index.js.map +1 -0
- package/shared/analyzer/languages/java.d.ts +20 -0
- package/shared/analyzer/languages/java.js +73 -78
- package/shared/analyzer/languages/java.js.map +1 -0
- package/shared/analyzer/languages/javascript.d.ts +12 -0
- package/shared/analyzer/languages/javascript.js +258 -209
- package/shared/analyzer/languages/javascript.js.map +1 -0
- package/shared/analyzer/languages/python.d.ts +23 -0
- package/shared/analyzer/languages/python.js +92 -100
- package/shared/analyzer/languages/python.js.map +1 -0
- package/shared/analyzer/languages/rust.d.ts +17 -0
- package/shared/analyzer/languages/rust.js +96 -98
- package/shared/analyzer/languages/rust.js.map +1 -0
- package/shared/analyzer/languages/typescript.d.ts +11 -0
- package/shared/analyzer/languages/typescript.js +117 -116
- package/shared/analyzer/languages/typescript.js.map +1 -0
- package/shared/analyzer/licenses.d.ts +18 -0
- package/shared/analyzer/licenses.js +130 -133
- package/shared/analyzer/licenses.js.map +1 -0
- package/shared/analyzer/metrics.d.ts +20 -0
- package/shared/analyzer/metrics.js +112 -104
- package/shared/analyzer/metrics.js.map +1 -0
- package/shared/analyzer/pathUtil.d.ts +10 -0
- package/shared/analyzer/pathUtil.js +29 -35
- package/shared/analyzer/pathUtil.js.map +1 -0
- package/shared/analyzer/patterns.d.ts +11 -0
- package/shared/analyzer/patterns.js +231 -253
- package/shared/analyzer/patterns.js.map +1 -0
- package/shared/analyzer/scan.d.ts +62 -0
- package/shared/analyzer/scan.js +451 -442
- package/shared/analyzer/scan.js.map +1 -0
- package/shared/analyzer/scanControl.d.ts +11 -0
- package/shared/analyzer/scanControl.js +62 -0
- package/shared/analyzer/scanControl.js.map +1 -0
- package/shared/analyzer/security.d.ts +18 -0
- package/shared/analyzer/security.js +159 -159
- package/shared/analyzer/security.js.map +1 -0
- package/shared/analyzer/services.d.ts +5 -0
- package/shared/analyzer/services.js +141 -138
- package/shared/analyzer/services.js.map +1 -0
- package/shared/analyzer/stack.d.ts +6 -0
- package/shared/analyzer/stack.js +134 -141
- package/shared/analyzer/stack.js.map +1 -0
- package/shared/analyzer/tour.d.ts +2 -0
- package/shared/analyzer/tour.js +45 -53
- package/shared/analyzer/tour.js.map +1 -0
- package/shared/analyzer/util.d.ts +8 -0
- package/shared/analyzer/util.js +130 -76
- package/shared/analyzer/util.js.map +1 -0
- package/shared/analyzer/workflows.d.ts +8 -0
- package/shared/analyzer/workflows.js +139 -134
- package/shared/analyzer/workflows.js.map +1 -0
- package/shared/contracts.d.ts +250 -0
- package/shared/contracts.js +2 -0
- package/shared/contracts.js.map +1 -0
- package/shared/diagram/aiFacts.d.ts +35 -0
- package/shared/diagram/aiFacts.js +102 -105
- package/shared/diagram/aiFacts.js.map +1 -0
- package/shared/diagram/aiMermaid.d.ts +5 -0
- package/shared/diagram/aiMermaid.js +46 -45
- package/shared/diagram/aiMermaid.js.map +1 -0
- package/shared/diagram/atlas.d.ts +16 -0
- package/shared/diagram/atlas.js +51 -60
- package/shared/diagram/atlas.js.map +1 -0
- package/shared/diagram/mermaid.d.ts +43 -0
- package/shared/diagram/mermaid.js +348 -370
- package/shared/diagram/mermaid.js.map +1 -0
- package/shared/review/contracts.d.ts +95 -0
- package/shared/review/contracts.js +2 -0
- package/shared/review/contracts.js.map +1 -0
- package/shared/review/review.d.ts +10 -0
- package/shared/review/review.js +184 -0
- package/shared/review/review.js.map +1 -0
- package/shared/search/query.d.ts +32 -0
- package/shared/search/query.js +395 -388
- package/shared/search/query.js.map +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security.js","sourceRoot":"","sources":["../../src/shared/analyzer/security.ts"],"names":[],"mappings":"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","sourcesContent":["// A built-in vulnerability & code-quality rule engine — a Semgrep-lite that\n// runs entirely locally, no external binary. Rules are regex/line based,\n// language-scoped, each with a severity and a category. Per-file findings are\n// attached during the scan; summarizeSecurity rolls them into a repo grade.\n\nimport { lineCounter } from './util.js';\n\nexport const SEVERITIES = ['info', 'low', 'medium', 'high', 'critical'];\nexport const sevRank = (s) => SEVERITIES.indexOf(s);\n\n// Each rule: id, severity, category, message, rx. `byLine` rules test each\n// line (and report the line number); others test the whole source once.\nconst RULES = [\n { id: 'hardcoded-secret', severity: 'critical', category: 'secret',\n message: 'Hardcoded credential — move it to env/config.',\n rx: /\\b(api[_-]?key|apikey|secret|client[_-]?secret|password|passwd|access[_-]?token|auth[_-]?token|private[_-]?key)\\b\\s*[:=]\\s*['\"`][^'\"`\\s]{8,}['\"`]/i, byLine: true },\n { id: 'aws-key', severity: 'critical', category: 'secret',\n message: 'Looks like an AWS access key id.',\n rx: /\\b(AKIA|ASIA)[0-9A-Z]{16}\\b/, byLine: true },\n { id: 'private-key-block', severity: 'critical', category: 'secret',\n message: 'A private key is committed to the source.',\n rx: /-----BEGIN (RSA|EC|DSA|OPENSSH|PGP) PRIVATE KEY-----/ },\n { id: 'eval', severity: 'high', category: 'injection', langs: ['javascript'],\n message: 'eval() executes strings as code — classic injection sink.',\n rx: /\\beval\\s*\\(/, byLine: true },\n { id: 'new-function', severity: 'high', category: 'injection', langs: ['javascript'],\n message: 'new Function() is eval in a trench coat.',\n rx: /\\bnew Function\\s*\\(/, byLine: true },\n { id: 'child-exec', severity: 'high', category: 'injection', langs: ['javascript'],\n message: 'Shelling out — if any argument is user input, this is command injection.',\n rx: /\\b(child_process\\.(exec|spawn)|execSync|spawnSync)\\s*\\(/, byLine: true },\n { id: 'os-system', severity: 'high', category: 'injection', langs: ['python'],\n message: 'os.system / shell=True runs a shell — sanitize any input reaching it.',\n rx: /\\bos\\.system\\s*\\(|shell\\s*=\\s*True/, byLine: true },\n { id: 'sql-concat', severity: 'high', category: 'injection',\n message: 'SQL built by string concatenation/formatting — use parameterized queries.',\n rx: /\\b(execute|query|exec|raw)\\s*\\(\\s*[^)]*(\\+|\\$\\{|\\.format\\(|f[\"'])/, byLine: true },\n { id: 'innerhtml', severity: 'medium', category: 'xss', langs: ['javascript'],\n message: 'Writing raw HTML — if the value is user-controlled, this is XSS.',\n rx: /\\b(innerHTML|outerHTML)\\s*=|dangerouslySetInnerHTML|document\\.write\\s*\\(/, byLine: true,\n ignore: /\\b(innerHTML|outerHTML)\\s*=\\s*(['\"`])\\2\\s*;?\\s*$/ },\n { id: 'weak-hash', severity: 'medium', category: 'crypto',\n message: 'MD5/SHA-1 are broken — use SHA-256+, and bcrypt/argon2 for passwords.',\n rx: /\\b(md5|sha1)\\s*\\(|createHash\\(\\s*['\"](md5|sha1)['\"]/, byLine: true },\n { id: 'math-random', severity: 'low', category: 'crypto', langs: ['javascript'],\n message: 'Math.random() is not cryptographically secure.',\n rx: /\\bMath\\.random\\s*\\(/, byLine: true },\n { id: 'insecure-deser', severity: 'high', category: 'deserialization',\n message: 'Insecure deserialization — untrusted data here is remote code execution.',\n rx: /\\b(pickle\\.loads?|yaml\\.load\\s*\\((?![^)]*SafeLoader)|unserialize\\s*\\(|ObjectInputStream)/, byLine: true },\n { id: 'open-redirect', severity: 'medium', category: 'redirect',\n message: 'Redirect target comes from the request — open-redirect risk.',\n rx: /\\b(res\\.redirect|redirect)\\s*\\(\\s*(req\\.|request\\.)/, byLine: true },\n { id: 'localhost-url', severity: 'low', category: 'config',\n message: 'Hardcoded localhost/127.0.0.1 — will break outside this machine.',\n rx: /['\"`](https?:\\/\\/(localhost|127\\.0\\.0\\.1)|localhost:\\d|127\\.0\\.0\\.1)/, byLine: true },\n { id: 'debugger', severity: 'low', category: 'debug', langs: ['javascript'],\n message: 'A debugger statement is left in.',\n rx: /\\bdebugger\\s*;?/, byLine: true },\n { id: 'console-log', severity: 'info', category: 'debug', langs: ['javascript'],\n message: 'console.log — fine locally, noise in production.',\n rx: /\\bconsole\\.(log|debug|info)\\s*\\(/, byLine: true },\n { id: 'print-stmt', severity: 'info', category: 'debug', langs: ['python'],\n message: 'print() — use the logger in production code.',\n rx: /^\\s*print\\s*\\(/, byLine: true },\n { id: 'todo', severity: 'info', category: 'quality',\n message: 'TODO/FIXME left in the source.',\n rx: /\\b(TODO|FIXME|XXX|HACK)\\b/, byLine: true },\n { id: 'loose-eq', severity: 'low', category: 'quality', langs: ['javascript'],\n message: 'Loose equality (==) coerces types — prefer ===.',\n rx: /[^=!<>]==[^=]/, byLine: true },\n { id: 'var-keyword', severity: 'low', category: 'quality', langs: ['javascript'],\n message: 'var is function-scoped and hoisted — prefer let/const.',\n rx: /\\bvar\\s+[A-Za-z_$]/, byLine: true },\n { id: 'empty-catch', severity: 'medium', category: 'quality',\n message: 'Swallowed exception — errors vanish silently here.',\n rx: /(catch\\s*\\([^)]*\\)\\s*\\{\\s*\\}|except\\s*\\w*\\s*:\\s*pass\\b)/, byLine: true },\n // JSON Web Tokens start with a base64-encoded header that is always\n // `eyJ…` (\"{\"). A line that contains one and treats it as a literal\n // string — rather than reading it from a vault — is the same shape of\n // mistake as a hardcoded API key. Three base64 segments separated by\n // dots is the JWT signature; we only require the first segment to keep\n // the rule cheap.\n { id: 'jwt-secret', severity: 'critical', category: 'secret',\n message: 'Looks like a hardcoded JWT — treat it like a credential, not a string.',\n rx: /['\"`](eyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,})['\"`]/, byLine: true },\n // The `os-system` rule already catches `os.system` and `shell=True` on\n // subprocess calls, but `subprocess.Popen(..., shell=True)` and\n // `subprocess.run(..., shell=True)` are the modern Python way to do\n // the same thing, and a regex on `shell=True` alone matches both\n // without the false-positive rate. A separate rule for Popen keeps the\n // message specific and the langs filter honest.\n { id: 'subprocess-shell', severity: 'high', category: 'injection', langs: ['python'],\n message: 'subprocess.* with shell=True runs a shell — sanitize any input reaching it.',\n rx: /\\bsubprocess\\.(Popen|run|call|check_output|check_call)\\s*\\([^)]*shell\\s*=\\s*True/, byLine: true },\n // Go's `http.ListenAndServe` defaults to binding all interfaces when\n // given a `\":port\"` address (the colon makes it a wildcard), and a\n // literal `0.0.0.0` does the same. That is fine inside a container with\n // a tight network policy and a bug everywhere else: the dev box, the\n // staging cluster, the CI runner, the laptop on coffee-shop Wi-Fi. The\n // rule does not distinguish \"0.0.0.0\" from \"127.0.0.1\" because the\n // safer pattern is always `127.0.0.1:<port>`, so the finding is a\n // nudge rather than an alarm.\n { id: 'go-public-listen', severity: 'medium', category: 'config', langs: ['go'],\n message: 'Go listener binds all interfaces (\":port\" or \"0.0.0.0\") — bind 127.0.0.1 explicitly.',\n rx: /(ListenAndServe|Listen|TLS\\s*\\.\\s*Listen|ListenAndServeTLS)\\s*\\(\\s*[\"'](:[0-9]+|0\\.0\\.0\\.0(?::[0-9]+)?|::)[\"']/, byLine: true },\n];\n\n// Findings for one file, run at scan time while the source is in hand.\nexport function analyzeSecurityFile(source, lang) {\n const findings = [];\n const text = String(source);\n const lines = text.split('\\n');\n // Whole-file rules report a byte offset and need it as a line number. Built\n // once and lazily: most files trip none of these rules and never build it.\n const lineAt = lineCounter(text);\n for (const rule of RULES) {\n if (rule.langs && !rule.langs.includes(lang)) continue;\n if (rule.byLine) {\n for (let i = 0; i < lines.length; i++) {\n if (rule.ignore && rule.ignore.test(lines[i])) continue;\n const m = lines[i].match(rule.rx);\n if (m) {\n findings.push({ rule: rule.id, severity: rule.severity, category: rule.category, message: rule.message, line: i + 1, excerpt: lines[i].trim().slice(0, 90) });\n }\n }\n } else {\n const m = text.match(rule.rx);\n if (m) {\n findings.push({ rule: rule.id, severity: rule.severity, category: rule.category, message: rule.message, line: lineAt(m.index), excerpt: (m[0] || '').slice(0, 90) });\n }\n }\n }\n return findings;\n}\n\n// Repo-level roll-up: counts by severity and category, the files carrying\n// findings (worst-first), and a 0–100 score + grade.\nexport function summarizeSecurity(scan) {\n const counts = { critical: 0, high: 0, medium: 0, low: 0, info: 0 };\n const byCat: Record<string, any> = {};\n const files = [];\n for (const f of scan.files) {\n const finds = f.findings || [];\n if (!finds.length) continue;\n let worst = 'info';\n for (const x of finds) {\n counts[x.severity]++;\n byCat[x.category] = (byCat[x.category] || 0) + 1;\n if (sevRank(x.severity) > sevRank(worst)) worst = x.severity;\n }\n files.push({ path: f.path, name: f.name, findings: finds, worst, count: finds.length });\n }\n files.sort((a, b) => sevRank(b.worst) - sevRank(a.worst) || b.count - a.count);\n\n let score = 100;\n score -= counts.critical * 15;\n score -= counts.high * 6;\n score -= counts.medium * 2;\n score -= Math.min(10, counts.low);\n score = Math.max(0, Math.round(score));\n const grade = score >= 90 ? 'A' : score >= 75 ? 'B' : score >= 60 ? 'C' : score >= 45 ? 'D' : 'F';\n\n return { counts, byCat, files, score, grade, total: files.reduce((s, f) => s + f.count, 0) };\n}\n\n// Fold an external engine's findings into the scan, in place, so the security\n// view — which reads `scan.files[].findings` and re-summarizes — sees one list.\n// Dedup is on (path, line, rule): two engines flagging the same line for the\n// same reason are one problem. This is the shared, pure half of the merge; the\n// fetching and spawning live on the server.\nexport function mergeFindingsIntoScan(scan, external) {\n if (!scan || !Array.isArray(external) || !external.length) return 0;\n const byPath = new Map<string, { findings?: any[] }>(scan.files.map((f) => [f.path, f]));\n let added = 0;\n for (const finding of external) {\n const file = byPath.get(finding.path);\n if (!file) continue; // a path the scanner never accepted is not ours to show\n const list = file.findings || (file.findings = []);\n const dupe = list.some((x) => x.line === finding.line && x.rule === finding.rule);\n if (dupe) continue;\n list.push(finding);\n added++;\n }\n return added;\n}\n\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { FileSource, Manifest } from '../contracts.js';
|
|
2
|
+
export declare function detectManifest(source: FileSource): Promise<Manifest>;
|
|
3
|
+
export declare function parseRequirements(text: any): string[];
|
|
4
|
+
export declare function parseGoRequires(text: any): string[];
|
|
5
|
+
export declare function parseCargoDeps(text: any): any[];
|
|
@@ -1,157 +1,160 @@
|
|
|
1
1
|
// Service and manifest detection: docker-compose services, package.json
|
|
2
2
|
// (workspaces, scripts, entry points), Procfile. Regex/JSON based — a YAML
|
|
3
3
|
// parser would be overkill for what is a navigational aid.
|
|
4
|
-
|
|
5
4
|
export async function detectManifest(source) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
5
|
+
const manifest = { entryPoints: [], services: [], packageName: '', scripts: [], workspaces: [], deps: { npm: {}, dev: {}, pip: [], go: [], cargo: [] } };
|
|
6
|
+
// package.json
|
|
7
|
+
try {
|
|
8
|
+
const pkg = JSON.parse(await source.read('package.json'));
|
|
9
|
+
manifest.packageName = pkg.name || '';
|
|
10
|
+
manifest.license = pkg.license || '';
|
|
11
|
+
manifest.scripts = Object.keys(pkg.scripts || {});
|
|
12
|
+
manifest.deps.npm = pkg.dependencies || {};
|
|
13
|
+
manifest.deps.dev = pkg.devDependencies || {};
|
|
14
|
+
if (pkg.main)
|
|
15
|
+
manifest.entryPoints.push(pkg.main.replace(/^\.\//, ''));
|
|
16
|
+
if (pkg.bin) {
|
|
17
|
+
for (const p of Object.values(typeof pkg.bin === 'string' ? { bin: pkg.bin } : pkg.bin)) {
|
|
18
|
+
manifest.entryPoints.push(String(p).replace(/^\.\//, ''));
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const ws = pkg.workspaces;
|
|
22
|
+
const list = Array.isArray(ws) ? ws : ws?.packages || [];
|
|
23
|
+
manifest.workspaces = list.map((w) => w.replace(/\/$/, ''));
|
|
24
|
+
if (manifest.scripts.some((s) => /start|serve|dev/.test(s))) {
|
|
25
|
+
manifest.hasServerScript = true;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
/* no package.json or unreadable — fine */
|
|
30
|
+
}
|
|
31
|
+
// requirements.txt
|
|
32
|
+
try {
|
|
33
|
+
manifest.deps.pip = parseRequirements(await source.read('requirements.txt'));
|
|
34
|
+
}
|
|
35
|
+
catch { /* none */ }
|
|
36
|
+
// go.mod
|
|
37
|
+
try {
|
|
38
|
+
manifest.deps.go = parseGoRequires(await source.read('go.mod'));
|
|
20
39
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
40
|
+
catch { /* none */ }
|
|
41
|
+
// Cargo.toml
|
|
42
|
+
try {
|
|
43
|
+
manifest.deps.cargo = parseCargoDeps(await source.read('Cargo.toml'));
|
|
44
|
+
}
|
|
45
|
+
catch { /* none */ }
|
|
46
|
+
// docker-compose.yml / docker-compose.yaml / compose.yml
|
|
47
|
+
for (const name of ['docker-compose.yml', 'docker-compose.yaml', 'compose.yml', 'compose.yaml']) {
|
|
48
|
+
let text;
|
|
49
|
+
try {
|
|
50
|
+
text = await source.read(name);
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
manifest.composeFile = name;
|
|
56
|
+
manifest.services = parseComposeServices(text);
|
|
57
|
+
break;
|
|
26
58
|
}
|
|
27
|
-
|
|
28
|
-
/* no package.json or unreadable — fine */
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// requirements.txt
|
|
32
|
-
try {
|
|
33
|
-
manifest.deps.pip = parseRequirements(await source.read('requirements.txt'));
|
|
34
|
-
} catch { /* none */ }
|
|
35
|
-
|
|
36
|
-
// go.mod
|
|
37
|
-
try {
|
|
38
|
-
manifest.deps.go = parseGoRequires(await source.read('go.mod'));
|
|
39
|
-
} catch { /* none */ }
|
|
40
|
-
|
|
41
|
-
// Cargo.toml
|
|
42
|
-
try {
|
|
43
|
-
manifest.deps.cargo = parseCargoDeps(await source.read('Cargo.toml'));
|
|
44
|
-
} catch { /* none */ }
|
|
45
|
-
|
|
46
|
-
// docker-compose.yml / docker-compose.yaml / compose.yml
|
|
47
|
-
for (const name of ['docker-compose.yml', 'docker-compose.yaml', 'compose.yml', 'compose.yaml']) {
|
|
48
|
-
let text;
|
|
59
|
+
// Procfile
|
|
49
60
|
try {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
61
|
+
const text = await source.read('Procfile');
|
|
62
|
+
for (const line of text.split('\n')) {
|
|
63
|
+
const m = line.match(/^([\w-]+):\s*(.+)$/);
|
|
64
|
+
if (m)
|
|
65
|
+
manifest.services.push({ name: m[1], command: m[2].trim(), source: 'Procfile' });
|
|
66
|
+
}
|
|
53
67
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
break;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Procfile
|
|
60
|
-
try {
|
|
61
|
-
const text = await source.read('Procfile');
|
|
62
|
-
for (const line of text.split('\n')) {
|
|
63
|
-
const m = line.match(/^([\w-]+):\s*(.+)$/);
|
|
64
|
-
if (m) manifest.services.push({ name: m[1], command: m[2].trim(), source: 'Procfile' });
|
|
68
|
+
catch {
|
|
69
|
+
/* none */
|
|
65
70
|
}
|
|
66
|
-
|
|
67
|
-
/* none */
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return manifest;
|
|
71
|
+
return manifest;
|
|
71
72
|
}
|
|
72
|
-
|
|
73
73
|
export function parseRequirements(text) {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
74
|
+
return String(text)
|
|
75
|
+
.split('\n')
|
|
76
|
+
.map((l) => l.split('#')[0].trim())
|
|
77
|
+
.filter(Boolean)
|
|
78
|
+
.map((l) => l.split(/[<>=!~;\[ ]/)[0].replace(/["']/g, '').trim())
|
|
79
|
+
.filter(Boolean);
|
|
80
80
|
}
|
|
81
|
-
|
|
82
81
|
export function parseGoRequires(text) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
82
|
+
const s = String(text);
|
|
83
|
+
const names = new Set();
|
|
84
|
+
const block = s.match(/require\s*\(([\s\S]*?)\)/);
|
|
85
|
+
const scoped = block ? block[1] : '';
|
|
86
|
+
const single = (s.match(/require\s+([\w./-]+)(?:\s+v[\w.\-+]+)?(?:\n|$)/) || [, ''])[1];
|
|
87
|
+
if (single)
|
|
88
|
+
names.add(single);
|
|
89
|
+
for (const [, name] of (scoped.matchAll(/^\s*([\w./-]+)\s+v?[\w.\-+]*/gm) || []))
|
|
90
|
+
if (name)
|
|
91
|
+
names.add(name);
|
|
92
|
+
const lines = scoped.length ? scoped.split('\n') : s.split('\n').filter((l) => l.trim().startsWith('require'));
|
|
93
|
+
for (const line of lines) {
|
|
94
|
+
const m = line.match(/\b([\w./-]+)\s+v[\w.\-+]+/);
|
|
95
|
+
if (m)
|
|
96
|
+
names.add(m[1]);
|
|
97
|
+
}
|
|
98
|
+
// drop the standard library pseudo module
|
|
99
|
+
names.delete('.');
|
|
100
|
+
return [...names].sort();
|
|
98
101
|
}
|
|
99
|
-
|
|
100
102
|
export function parseCargoDeps(text) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
103
|
+
const s = String(text);
|
|
104
|
+
const sec = s.match(/\[dependencies\]([\s\S]*?)(?=\n\[|$)/);
|
|
105
|
+
const body = sec ? sec[1] : '';
|
|
106
|
+
const names = [];
|
|
107
|
+
for (const line of body.split('\n')) {
|
|
108
|
+
const m = line.match(/^([A-Za-z0-9_-]+)\s*(?:=\s*[^{]|\{)/);
|
|
109
|
+
if (m)
|
|
110
|
+
names.push(m[1]);
|
|
111
|
+
}
|
|
112
|
+
return [...new Set(names)];
|
|
110
113
|
}
|
|
111
|
-
|
|
112
114
|
function parseComposeServices(text) {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
115
|
+
const lines = text.split('\n');
|
|
116
|
+
const services = [];
|
|
117
|
+
let inServices = false;
|
|
118
|
+
let servicesIndent = 0;
|
|
119
|
+
let current = null;
|
|
120
|
+
let currentIndent = 0;
|
|
121
|
+
for (const line of lines) {
|
|
122
|
+
if (/^\s*#/.test(line) || line.trim() === '')
|
|
123
|
+
continue;
|
|
124
|
+
const indent = line.length - line.trimStart().length;
|
|
125
|
+
const trimmed = line.trim();
|
|
126
|
+
if (!inServices) {
|
|
127
|
+
if (/^services:\s*$/.test(trimmed)) {
|
|
128
|
+
inServices = true;
|
|
129
|
+
servicesIndent = indent;
|
|
130
|
+
}
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
if (indent <= servicesIndent && !/^services:/.test(trimmed))
|
|
134
|
+
break; // left the block
|
|
135
|
+
const svcMatch = trimmed.match(/^([\w.-]+):\s*$/);
|
|
136
|
+
if (svcMatch && indent === servicesIndent + 2) {
|
|
137
|
+
current = { name: svcMatch[1], source: 'compose', ports: [], dependsOn: [] };
|
|
138
|
+
currentIndent = indent;
|
|
139
|
+
services.push(current);
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
if (!current || indent <= currentIndent)
|
|
143
|
+
continue;
|
|
144
|
+
let m;
|
|
145
|
+
if ((m = trimmed.match(/^build:\s*(.+)$/))) {
|
|
146
|
+
current.build = m[1].trim();
|
|
147
|
+
}
|
|
148
|
+
else if ((m = trimmed.match(/^image:\s*(.+)$/))) {
|
|
149
|
+
current.image = m[1].trim();
|
|
150
|
+
}
|
|
151
|
+
else if ((m = trimmed.match(/^-\s*["']?(\d+):(\d+)/))) {
|
|
152
|
+
current.ports.push(m[1] + ':' + m[2]);
|
|
153
|
+
}
|
|
154
|
+
else if ((m = trimmed.match(/^context:\s*(.+)$/))) {
|
|
155
|
+
current.build = m[1].trim();
|
|
156
|
+
}
|
|
154
157
|
}
|
|
155
|
-
|
|
156
|
-
return services;
|
|
158
|
+
return services;
|
|
157
159
|
}
|
|
160
|
+
//# sourceMappingURL=services.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"services.js","sourceRoot":"","sources":["../../src/shared/analyzer/services.ts"],"names":[],"mappings":"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","sourcesContent":["import type { FileSource, Manifest, Service } from '../contracts.js';\n// Service and manifest detection: docker-compose services, package.json\n// (workspaces, scripts, entry points), Procfile. Regex/JSON based — a YAML\n// parser would be overkill for what is a navigational aid.\n\nexport async function detectManifest(source: FileSource): Promise<Manifest> {\n const manifest: Manifest = { entryPoints: [], services: [], packageName: '', scripts: [], workspaces: [], deps: { npm: {}, dev: {}, pip: [], go: [], cargo: [] } };\n\n // package.json\n try {\n const pkg = JSON.parse(await source.read('package.json'));\n manifest.packageName = pkg.name || '';\n manifest.license = pkg.license || '';\n manifest.scripts = Object.keys(pkg.scripts || {});\n manifest.deps.npm = pkg.dependencies || {};\n manifest.deps.dev = pkg.devDependencies || {};\n if (pkg.main) manifest.entryPoints.push(pkg.main.replace(/^\\.\\//, ''));\n if (pkg.bin) {\n for (const p of Object.values(typeof pkg.bin === 'string' ? { bin: pkg.bin } : pkg.bin)) {\n manifest.entryPoints.push(String(p).replace(/^\\.\\//, ''));\n }\n }\n const ws = pkg.workspaces;\n const list = Array.isArray(ws) ? ws : ws?.packages || [];\n manifest.workspaces = list.map((w) => w.replace(/\\/$/, ''));\n if (manifest.scripts.some((s) => /start|serve|dev/.test(s))) {\n manifest.hasServerScript = true;\n }\n } catch {\n /* no package.json or unreadable — fine */\n }\n\n // requirements.txt\n try {\n manifest.deps.pip = parseRequirements(await source.read('requirements.txt'));\n } catch { /* none */ }\n\n // go.mod\n try {\n manifest.deps.go = parseGoRequires(await source.read('go.mod'));\n } catch { /* none */ }\n\n // Cargo.toml\n try {\n manifest.deps.cargo = parseCargoDeps(await source.read('Cargo.toml'));\n } catch { /* none */ }\n\n // docker-compose.yml / docker-compose.yaml / compose.yml\n for (const name of ['docker-compose.yml', 'docker-compose.yaml', 'compose.yml', 'compose.yaml']) {\n let text;\n try {\n text = await source.read(name);\n } catch {\n continue;\n }\n manifest.composeFile = name;\n manifest.services = parseComposeServices(text);\n break;\n }\n\n // Procfile\n try {\n const text = await source.read('Procfile');\n for (const line of text.split('\\n')) {\n const m = line.match(/^([\\w-]+):\\s*(.+)$/);\n if (m) manifest.services.push({ name: m[1], command: m[2].trim(), source: 'Procfile' });\n }\n } catch {\n /* none */\n }\n\n return manifest;\n}\n\nexport function parseRequirements(text) {\n return String(text)\n .split('\\n')\n .map((l) => l.split('#')[0].trim())\n .filter(Boolean)\n .map((l) => l.split(/[<>=!~;\\[ ]/)[0].replace(/[\"']/g, '').trim())\n .filter(Boolean);\n}\n\nexport function parseGoRequires(text) {\n const s = String(text);\n const names = new Set<string>();\n const block = s.match(/require\\s*\\(([\\s\\S]*?)\\)/);\n const scoped = block ? block[1] : '';\n const single = (s.match(/require\\s+([\\w./-]+)(?:\\s+v[\\w.\\-+]+)?(?:\\n|$)/) || [, ''])[1];\n if (single) names.add(single);\n for (const [, name] of (scoped.matchAll(/^\\s*([\\w./-]+)\\s+v?[\\w.\\-+]*/gm) || [])) if (name) names.add(name);\n const lines = scoped.length ? scoped.split('\\n') : s.split('\\n').filter((l) => l.trim().startsWith('require'));\n for (const line of lines) {\n const m = line.match(/\\b([\\w./-]+)\\s+v[\\w.\\-+]+/);\n if (m) names.add(m[1]);\n }\n // drop the standard library pseudo module\n names.delete('.');\n return [...names].sort();\n}\n\nexport function parseCargoDeps(text) {\n const s = String(text);\n const sec = s.match(/\\[dependencies\\]([\\s\\S]*?)(?=\\n\\[|$)/);\n const body = sec ? sec[1] : '';\n const names = [];\n for (const line of body.split('\\n')) {\n const m = line.match(/^([A-Za-z0-9_-]+)\\s*(?:=\\s*[^{]|\\{)/);\n if (m) names.push(m[1]);\n }\n return [...new Set(names)];\n}\n\nfunction parseComposeServices(text) {\n const lines = text.split('\\n');\n const services: Service[] = [];\n let inServices = false;\n let servicesIndent = 0;\n let current: Service | null = null;\n let currentIndent = 0;\n\n for (const line of lines) {\n if (/^\\s*#/.test(line) || line.trim() === '') continue;\n const indent = line.length - line.trimStart().length;\n const trimmed = line.trim();\n\n if (!inServices) {\n if (/^services:\\s*$/.test(trimmed)) {\n inServices = true;\n servicesIndent = indent;\n }\n continue;\n }\n\n if (indent <= servicesIndent && !/^services:/.test(trimmed)) break; // left the block\n\n const svcMatch = trimmed.match(/^([\\w.-]+):\\s*$/);\n if (svcMatch && indent === servicesIndent + 2) {\n current = { name: svcMatch[1], source: 'compose', ports: [], dependsOn: [] };\n currentIndent = indent;\n services.push(current);\n continue;\n }\n\n if (!current || indent <= currentIndent) continue;\n\n let m;\n if ((m = trimmed.match(/^build:\\s*(.+)$/))) {\n current.build = m[1].trim();\n } else if ((m = trimmed.match(/^image:\\s*(.+)$/))) {\n current.image = m[1].trim();\n } else if ((m = trimmed.match(/^-\\s*[\"']?(\\d+):(\\d+)/))) {\n current.ports.push(m[1] + ':' + m[2]);\n } else if ((m = trimmed.match(/^context:\\s*(.+)$/))) {\n current.build = m[1].trim();\n }\n }\n return services;\n}\n"]}
|