kirograph 0.16.1 → 0.19.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/LICENSE +1 -1
- package/README.md +103 -1605
- package/dist/architecture/layers/dart.js +112 -0
- package/dist/architecture/layers/dart.js.map +7 -0
- package/dist/architecture/layers/index.js +3 -1
- package/dist/architecture/layers/index.js.map +2 -2
- package/dist/bin/banner.js +74 -6
- package/dist/bin/banner.js.map +2 -2
- package/dist/bin/commands/affected.js +40 -5
- package/dist/bin/commands/affected.js.map +2 -2
- package/dist/bin/commands/attack-surface.js +157 -0
- package/dist/bin/commands/attack-surface.js.map +7 -0
- package/dist/bin/commands/benchmark.js +206 -0
- package/dist/bin/commands/benchmark.js.map +7 -0
- package/dist/bin/commands/budget.js +70 -0
- package/dist/bin/commands/budget.js.map +7 -0
- package/dist/bin/commands/communities.js +77 -0
- package/dist/bin/commands/communities.js.map +7 -0
- package/dist/bin/commands/data.js +665 -0
- package/dist/bin/commands/data.js.map +7 -0
- package/dist/bin/commands/dep-confusion.js +119 -0
- package/dist/bin/commands/dep-confusion.js.map +7 -0
- package/dist/bin/commands/export.js +304 -10
- package/dist/bin/commands/export.js.map +2 -2
- package/dist/bin/commands/flows.js +97 -0
- package/dist/bin/commands/flows.js.map +7 -0
- package/dist/bin/commands/help.js +386 -100
- package/dist/bin/commands/help.js.map +2 -2
- package/dist/bin/commands/install.js +90 -8
- package/dist/bin/commands/install.js.map +2 -2
- package/dist/bin/commands/licenses.js +201 -0
- package/dist/bin/commands/licenses.js.map +7 -0
- package/dist/bin/commands/reachability.js +160 -0
- package/dist/bin/commands/reachability.js.map +7 -0
- package/dist/bin/commands/read.js +100 -0
- package/dist/bin/commands/read.js.map +7 -0
- package/dist/bin/commands/refactor.js +116 -0
- package/dist/bin/commands/refactor.js.map +7 -0
- package/dist/bin/commands/remediation.js +133 -0
- package/dist/bin/commands/remediation.js.map +7 -0
- package/dist/bin/commands/sbom.js +76 -0
- package/dist/bin/commands/sbom.js.map +7 -0
- package/dist/bin/commands/security-ci-report.js +267 -0
- package/dist/bin/commands/security-ci-report.js.map +7 -0
- package/dist/bin/commands/security-export.js +1349 -0
- package/dist/bin/commands/security-export.js.map +7 -0
- package/dist/bin/commands/security-flows.js +126 -0
- package/dist/bin/commands/security-flows.js.map +7 -0
- package/dist/bin/commands/security-secrets.js +170 -0
- package/dist/bin/commands/security-secrets.js.map +7 -0
- package/dist/bin/commands/security.js +193 -0
- package/dist/bin/commands/security.js.map +7 -0
- package/dist/bin/commands/staleness.js +144 -0
- package/dist/bin/commands/staleness.js.map +7 -0
- package/dist/bin/commands/status.js +102 -2
- package/dist/bin/commands/status.js.map +2 -2
- package/dist/bin/commands/supply-chain.js +138 -0
- package/dist/bin/commands/supply-chain.js.map +7 -0
- package/dist/bin/commands/uninit.js +109 -60
- package/dist/bin/commands/uninit.js.map +2 -2
- package/dist/bin/commands/vex.js +76 -0
- package/dist/bin/commands/vex.js.map +7 -0
- package/dist/bin/commands/vuln-suppress.js +95 -0
- package/dist/bin/commands/vuln-suppress.js.map +7 -0
- package/dist/bin/commands/vulns.js +382 -0
- package/dist/bin/commands/vulns.js.map +7 -0
- package/dist/bin/installer/auto-detect.js +125 -0
- package/dist/bin/installer/auto-detect.js.map +7 -0
- package/dist/bin/installer/cli-agent.js +28 -5
- package/dist/bin/installer/cli-agent.js.map +2 -2
- package/dist/bin/installer/common.js +47 -0
- package/dist/bin/installer/common.js.map +2 -2
- package/dist/bin/installer/config-prompt.js +39 -1
- package/dist/bin/installer/config-prompt.js.map +2 -2
- package/dist/bin/installer/detect.js +309 -0
- package/dist/bin/installer/detect.js.map +7 -0
- package/dist/bin/installer/index.js +36 -1
- package/dist/bin/installer/index.js.map +2 -2
- package/dist/bin/installer/instructions.js +195 -3
- package/dist/bin/installer/instructions.js.map +2 -2
- package/dist/bin/installer/steering.js +440 -0
- package/dist/bin/installer/steering.js.map +2 -2
- package/dist/bin/installer/targets/aider.js +3 -3
- package/dist/bin/installer/targets/aider.js.map +2 -2
- package/dist/bin/installer/targets/amp.js +3 -3
- package/dist/bin/installer/targets/amp.js.map +2 -2
- package/dist/bin/installer/targets/antigravity.js +35 -6
- package/dist/bin/installer/targets/antigravity.js.map +2 -2
- package/dist/bin/installer/targets/augment.js +3 -3
- package/dist/bin/installer/targets/augment.js.map +2 -2
- package/dist/bin/installer/targets/claude.js +49 -5
- package/dist/bin/installer/targets/claude.js.map +2 -2
- package/dist/bin/installer/targets/cline.js +32 -6
- package/dist/bin/installer/targets/cline.js.map +2 -2
- package/dist/bin/installer/targets/codex.js +64 -12
- package/dist/bin/installer/targets/codex.js.map +2 -2
- package/dist/bin/installer/targets/continue.js +2 -2
- package/dist/bin/installer/targets/continue.js.map +2 -2
- package/dist/bin/installer/targets/copilot-cli.js +101 -0
- package/dist/bin/installer/targets/copilot-cli.js.map +7 -0
- package/dist/bin/installer/targets/copilot.js +31 -5
- package/dist/bin/installer/targets/copilot.js.map +2 -2
- package/dist/bin/installer/targets/cursor.js +4 -4
- package/dist/bin/installer/targets/cursor.js.map +2 -2
- package/dist/bin/installer/targets/devin.js +2 -2
- package/dist/bin/installer/targets/devin.js.map +2 -2
- package/dist/bin/installer/targets/gemini-cli.js +2 -2
- package/dist/bin/installer/targets/gemini-cli.js.map +2 -2
- package/dist/bin/installer/targets/generic.js +2 -14
- package/dist/bin/installer/targets/generic.js.map +2 -2
- package/dist/bin/installer/targets/goose.js +3 -3
- package/dist/bin/installer/targets/goose.js.map +2 -2
- package/dist/bin/installer/targets/index.js +250 -0
- package/dist/bin/installer/targets/index.js.map +2 -2
- package/dist/bin/installer/targets/junie.js +2 -2
- package/dist/bin/installer/targets/junie.js.map +2 -2
- package/dist/bin/installer/targets/kilo.js +2 -2
- package/dist/bin/installer/targets/kilo.js.map +2 -2
- package/dist/bin/installer/targets/kiro.js +3 -3
- package/dist/bin/installer/targets/kiro.js.map +2 -2
- package/dist/bin/installer/targets/opencode.js +2 -2
- package/dist/bin/installer/targets/opencode.js.map +2 -2
- package/dist/bin/installer/targets/openhands.js +3 -3
- package/dist/bin/installer/targets/openhands.js.map +2 -2
- package/dist/bin/installer/targets/qoder.js +91 -0
- package/dist/bin/installer/targets/qoder.js.map +7 -0
- package/dist/bin/installer/targets/qwen.js +96 -0
- package/dist/bin/installer/targets/qwen.js.map +7 -0
- package/dist/bin/installer/targets/replit.js +3 -3
- package/dist/bin/installer/targets/replit.js.map +2 -2
- package/dist/bin/installer/targets/roo.js +2 -2
- package/dist/bin/installer/targets/roo.js.map +2 -2
- package/dist/bin/installer/targets/tabnine.js +3 -3
- package/dist/bin/installer/targets/tabnine.js.map +2 -2
- package/dist/bin/installer/targets/trae.js +5 -5
- package/dist/bin/installer/targets/trae.js.map +2 -2
- package/dist/bin/installer/targets/warp.js +2 -2
- package/dist/bin/installer/targets/warp.js.map +2 -2
- package/dist/bin/installer/targets/windsurf.js +35 -6
- package/dist/bin/installer/targets/windsurf.js.map +2 -2
- package/dist/bin/kirograph.js +74 -6
- package/dist/bin/kirograph.js.map +3 -3
- package/dist/bin/progress.js +30 -0
- package/dist/bin/progress.js.map +2 -2
- package/dist/compression/naive-cost.js +25 -0
- package/dist/compression/naive-cost.js.map +2 -2
- package/dist/compression/tracker.js +91 -2
- package/dist/compression/tracker.js.map +2 -2
- package/dist/compression/types.js.map +1 -1
- package/dist/config.js +126 -3
- package/dist/config.js.map +2 -2
- package/dist/core/pipeline.js +92 -4
- package/dist/core/pipeline.js.map +2 -2
- package/dist/data/filters.js +105 -0
- package/dist/data/filters.js.map +7 -0
- package/dist/data/indexer.js +225 -0
- package/dist/data/indexer.js.map +7 -0
- package/dist/data/linker.js +150 -0
- package/dist/data/linker.js.map +7 -0
- package/dist/data/lint.js +109 -0
- package/dist/data/lint.js.map +7 -0
- package/dist/data/parsers/csv.js +132 -0
- package/dist/data/parsers/csv.js.map +7 -0
- package/dist/data/parsers/excel.js +88 -0
- package/dist/data/parsers/excel.js.map +7 -0
- package/dist/data/parsers/index.js +79 -0
- package/dist/data/parsers/index.js.map +7 -0
- package/dist/data/parsers/json-array.js +89 -0
- package/dist/data/parsers/json-array.js.map +7 -0
- package/dist/data/parsers/jsonl.js +84 -0
- package/dist/data/parsers/jsonl.js.map +7 -0
- package/dist/data/parsers/parquet.js +95 -0
- package/dist/data/parsers/parquet.js.map +7 -0
- package/dist/data/profiler.js +182 -0
- package/dist/data/profiler.js.map +7 -0
- package/dist/data/queries.js +512 -0
- package/dist/data/queries.js.map +7 -0
- package/dist/data/types.js +17 -0
- package/dist/data/types.js.map +7 -0
- package/dist/db/data-schema.sql +61 -0
- package/dist/db/database.js +67 -5
- package/dist/db/database.js.map +2 -2
- package/dist/db/memory-schema.sql +5 -1
- package/dist/db/schema.sql +3 -1
- package/dist/db/security-schema.sql +72 -0
- package/dist/extraction/extractor.js +81 -0
- package/dist/extraction/extractor.js.map +2 -2
- package/dist/extraction/grammars.js +32 -8
- package/dist/extraction/grammars.js.map +2 -2
- package/dist/extraction/languages.js +43 -1
- package/dist/extraction/languages.js.map +2 -2
- package/dist/extraction/notebook.js +300 -0
- package/dist/extraction/notebook.js.map +7 -0
- package/dist/extraction/wasm/tree-sitter-astro.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-gdscript.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-julia.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-nix.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-perl.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-powershell.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-r.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-sql.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-verilog.wasm +0 -0
- package/dist/frameworks/flutter.js +130 -0
- package/dist/frameworks/flutter.js.map +7 -0
- package/dist/frameworks/index.js +7 -1
- package/dist/frameworks/index.js.map +3 -3
- package/dist/graph/communities.js +317 -0
- package/dist/graph/communities.js.map +7 -0
- package/dist/graph/flows.js +138 -0
- package/dist/graph/flows.js.map +7 -0
- package/dist/graph/refactor.js +155 -0
- package/dist/graph/refactor.js.map +7 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +2 -2
- package/dist/mcp/cache.js +172 -0
- package/dist/mcp/cache.js.map +7 -0
- package/dist/mcp/read-modes.js +295 -0
- package/dist/mcp/read-modes.js.map +7 -0
- package/dist/mcp/server.js +2 -1
- package/dist/mcp/server.js.map +2 -2
- package/dist/mcp/tool-names.js +29 -1
- package/dist/mcp/tool-names.js.map +2 -2
- package/dist/mcp/tools.js +1588 -6
- package/dist/mcp/tools.js.map +3 -3
- package/dist/memory/database.js +32 -2
- package/dist/memory/database.js.map +2 -2
- package/dist/memory/types.js.map +1 -1
- package/dist/resolution/bridges/android-rn.js +298 -0
- package/dist/resolution/bridges/android-rn.js.map +7 -0
- package/dist/resolution/bridges/expo-modules.js +155 -0
- package/dist/resolution/bridges/expo-modules.js.map +7 -0
- package/dist/resolution/bridges/flutter-channel.js +385 -0
- package/dist/resolution/bridges/flutter-channel.js.map +7 -0
- package/dist/resolution/bridges/index.js +80 -0
- package/dist/resolution/bridges/index.js.map +7 -0
- package/dist/resolution/bridges/native-events.js +188 -0
- package/dist/resolution/bridges/native-events.js.map +7 -0
- package/dist/resolution/bridges/native-views.js +244 -0
- package/dist/resolution/bridges/native-views.js.map +7 -0
- package/dist/resolution/bridges/react-native.js +161 -0
- package/dist/resolution/bridges/react-native.js.map +7 -0
- package/dist/resolution/bridges/swift-objc.js +227 -0
- package/dist/resolution/bridges/swift-objc.js.map +7 -0
- package/dist/resolution/bridges/turbomodules.js +216 -0
- package/dist/resolution/bridges/turbomodules.js.map +7 -0
- package/dist/resolution/index.js +61 -2
- package/dist/resolution/index.js.map +2 -2
- package/dist/security/attack-surface.js +164 -0
- package/dist/security/attack-surface.js.map +7 -0
- package/dist/security/context-warnings.js +123 -0
- package/dist/security/context-warnings.js.map +7 -0
- package/dist/security/context-warnings.test.js +300 -0
- package/dist/security/context-warnings.test.js.map +7 -0
- package/dist/security/data-flows.js +228 -0
- package/dist/security/data-flows.js.map +7 -0
- package/dist/security/dep-confusion.js +255 -0
- package/dist/security/dep-confusion.js.map +7 -0
- package/dist/security/errors.js +51 -0
- package/dist/security/errors.js.map +7 -0
- package/dist/security/export/fix-suggestions.js +58 -0
- package/dist/security/export/fix-suggestions.js.map +7 -0
- package/dist/security/export/fix-suggestions.test.js +74 -0
- package/dist/security/export/fix-suggestions.test.js.map +7 -0
- package/dist/security/export/sbom.js +230 -0
- package/dist/security/export/sbom.js.map +7 -0
- package/dist/security/export/sbom.test.js +288 -0
- package/dist/security/export/sbom.test.js.map +7 -0
- package/dist/security/export/serialization.js +142 -0
- package/dist/security/export/serialization.js.map +7 -0
- package/dist/security/export/serialization.test.js +310 -0
- package/dist/security/export/serialization.test.js.map +7 -0
- package/dist/security/export/vex.js +220 -0
- package/dist/security/export/vex.js.map +7 -0
- package/dist/security/export/vex.test.js +278 -0
- package/dist/security/export/vex.test.js.map +7 -0
- package/dist/security/index.js +67 -0
- package/dist/security/index.js.map +7 -0
- package/dist/security/integrator-transitives.test.js +359 -0
- package/dist/security/integrator-transitives.test.js.map +7 -0
- package/dist/security/integrator.js +491 -0
- package/dist/security/integrator.js.map +7 -0
- package/dist/security/integrator.test.js +237 -0
- package/dist/security/integrator.test.js.map +7 -0
- package/dist/security/license.js +70 -0
- package/dist/security/license.js.map +7 -0
- package/dist/security/manifest/adapter.js +243 -0
- package/dist/security/manifest/adapter.js.map +7 -0
- package/dist/security/manifest/adapter.test.js +272 -0
- package/dist/security/manifest/adapter.test.js.map +7 -0
- package/dist/security/manifest/parser.js +376 -0
- package/dist/security/manifest/parser.js.map +7 -0
- package/dist/security/manifest/parser.test.js +110 -0
- package/dist/security/manifest/parser.test.js.map +7 -0
- package/dist/security/manifest/plugins/cargo.js +233 -0
- package/dist/security/manifest/plugins/cargo.js.map +7 -0
- package/dist/security/manifest/plugins/cargo.test.js +304 -0
- package/dist/security/manifest/plugins/cargo.test.js.map +7 -0
- package/dist/security/manifest/plugins/composer.js +152 -0
- package/dist/security/manifest/plugins/composer.js.map +7 -0
- package/dist/security/manifest/plugins/go.js +146 -0
- package/dist/security/manifest/plugins/go.js.map +7 -0
- package/dist/security/manifest/plugins/go.test.js +341 -0
- package/dist/security/manifest/plugins/go.test.js.map +7 -0
- package/dist/security/manifest/plugins/gradle.js +159 -0
- package/dist/security/manifest/plugins/gradle.js.map +7 -0
- package/dist/security/manifest/plugins/hex.js +159 -0
- package/dist/security/manifest/plugins/hex.js.map +7 -0
- package/dist/security/manifest/plugins/maven.js +128 -0
- package/dist/security/manifest/plugins/maven.js.map +7 -0
- package/dist/security/manifest/plugins/maven.test.js +389 -0
- package/dist/security/manifest/plugins/maven.test.js.map +7 -0
- package/dist/security/manifest/plugins/npm.js +284 -0
- package/dist/security/manifest/plugins/npm.js.map +7 -0
- package/dist/security/manifest/plugins/npm.test.js +298 -0
- package/dist/security/manifest/plugins/npm.test.js.map +7 -0
- package/dist/security/manifest/plugins/nuget.js +186 -0
- package/dist/security/manifest/plugins/nuget.js.map +7 -0
- package/dist/security/manifest/plugins/pip.js +123 -0
- package/dist/security/manifest/plugins/pip.js.map +7 -0
- package/dist/security/manifest/plugins/pip.test.js +208 -0
- package/dist/security/manifest/plugins/pip.test.js.map +7 -0
- package/dist/security/manifest/plugins/pubspec.js +212 -0
- package/dist/security/manifest/plugins/pubspec.js.map +7 -0
- package/dist/security/manifest/plugins/pyproject.js +261 -0
- package/dist/security/manifest/plugins/pyproject.js.map +7 -0
- package/dist/security/manifest/plugins/rubygems.js +185 -0
- package/dist/security/manifest/plugins/rubygems.js.map +7 -0
- package/dist/security/manifest/plugins/swift.js +200 -0
- package/dist/security/manifest/plugins/swift.js.map +7 -0
- package/dist/security/owasp.js +104 -0
- package/dist/security/owasp.js.map +7 -0
- package/dist/security/pipeline.js +125 -0
- package/dist/security/pipeline.js.map +7 -0
- package/dist/security/reachability.js +276 -0
- package/dist/security/reachability.js.map +7 -0
- package/dist/security/reachability.test.js +394 -0
- package/dist/security/reachability.test.js.map +7 -0
- package/dist/security/remediation.js +126 -0
- package/dist/security/remediation.js.map +7 -0
- package/dist/security/secrets.js +176 -0
- package/dist/security/secrets.js.map +7 -0
- package/dist/security/staleness.js +231 -0
- package/dist/security/staleness.js.map +7 -0
- package/dist/security/supply-chain.js +301 -0
- package/dist/security/supply-chain.js.map +7 -0
- package/dist/security/suppressions.js +106 -0
- package/dist/security/suppressions.js.map +7 -0
- package/dist/security/types.js +17 -0
- package/dist/security/types.js.map +7 -0
- package/dist/security/vuln/client.js +355 -0
- package/dist/security/vuln/client.js.map +7 -0
- package/dist/security/vuln/client.test.js +288 -0
- package/dist/security/vuln/client.test.js.map +7 -0
- package/dist/security/vuln/epss-client.js +95 -0
- package/dist/security/vuln/epss-client.js.map +7 -0
- package/dist/security/vuln/index.js +29 -0
- package/dist/security/vuln/index.js.map +7 -0
- package/dist/security/vuln/osv-adapter.js +321 -0
- package/dist/security/vuln/osv-adapter.js.map +7 -0
- package/dist/security/vuln/osv-adapter.test.js +391 -0
- package/dist/security/vuln/osv-adapter.test.js.map +7 -0
- package/dist/security/vuln/types.js +17 -0
- package/dist/security/vuln/types.js.map +7 -0
- package/dist/types.js.map +2 -2
- package/package.json +5 -2
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var sbom_exports = {};
|
|
30
|
+
__export(sbom_exports, {
|
|
31
|
+
register: () => register
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(sbom_exports);
|
|
34
|
+
var fs = __toESM(require("fs"));
|
|
35
|
+
var path = __toESM(require("path"));
|
|
36
|
+
var import_config = require("../../config");
|
|
37
|
+
var import_ui = require("../ui");
|
|
38
|
+
function register(program) {
|
|
39
|
+
program.command("sbom [projectPath]").description("Export CycloneDX 1.5 SBOM (Software Bill of Materials)").option("--output <file>", "Write SBOM to file instead of stdout").action(async (projectPath, opts) => {
|
|
40
|
+
const target = path.resolve(projectPath ?? process.cwd());
|
|
41
|
+
const config = await (0, import_config.loadConfig)(target);
|
|
42
|
+
if (!config.enableSecurity) {
|
|
43
|
+
console.error(`
|
|
44
|
+
${"\x1B[33m"}\u26A0 Security analysis is disabled.${import_ui.reset}`);
|
|
45
|
+
console.error(` ${import_ui.dim}Enable it in .kirograph/config.json:${import_ui.reset} ${import_ui.violet}${import_ui.bold}"enableSecurity": true${import_ui.reset}`);
|
|
46
|
+
console.error(` ${import_ui.dim}Then re-run:${import_ui.reset} ${import_ui.violet}${import_ui.bold}kirograph index${import_ui.reset}
|
|
47
|
+
`);
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
const KiroGraph = (await Promise.resolve().then(() => require("../../index.js"))).default;
|
|
51
|
+
if (!KiroGraph.isInitialized(target)) {
|
|
52
|
+
console.error(" \u2716 KiroGraph not initialized. Run: kirograph init");
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
const cg = await KiroGraph.open(target);
|
|
56
|
+
const db = cg.getDatabase();
|
|
57
|
+
db.applySecuritySchema();
|
|
58
|
+
const { SBOMExporter } = await Promise.resolve().then(() => require("../../security/export/sbom.js"));
|
|
59
|
+
const exporter = new SBOMExporter(db, target);
|
|
60
|
+
const json = exporter.exportJSON();
|
|
61
|
+
if (opts.output) {
|
|
62
|
+
const outPath = path.resolve(opts.output);
|
|
63
|
+
fs.mkdirSync(path.dirname(outPath), { recursive: true });
|
|
64
|
+
fs.writeFileSync(outPath, json, "utf-8");
|
|
65
|
+
console.error(` ${import_ui.green}\u2713${import_ui.reset} SBOM written to ${import_ui.violet}${import_ui.bold}${outPath}${import_ui.reset}`);
|
|
66
|
+
} else {
|
|
67
|
+
process.stdout.write(json + "\n");
|
|
68
|
+
}
|
|
69
|
+
cg.close();
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
73
|
+
0 && (module.exports = {
|
|
74
|
+
register
|
|
75
|
+
});
|
|
76
|
+
//# sourceMappingURL=sbom.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/bin/commands/sbom.ts"],
|
|
4
|
+
"sourcesContent": ["import { Command } from 'commander';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { loadConfig } from '../../config';\nimport { dim, reset, violet, bold, green } from '../ui';\n\nexport function register(program: Command): void {\n program\n .command('sbom [projectPath]')\n .description('Export CycloneDX 1.5 SBOM (Software Bill of Materials)')\n .option('--output <file>', 'Write SBOM to file instead of stdout')\n .action(async (projectPath: string | undefined, opts: { output?: string }) => {\n const target = path.resolve(projectPath ?? process.cwd());\n const config = await loadConfig(target);\n\n if (!config.enableSecurity) {\n console.error(`\\n ${'\\x1b[33m'}\u26A0 Security analysis is disabled.${reset}`);\n console.error(` ${dim}Enable it in .kirograph/config.json:${reset} ${violet}${bold}\"enableSecurity\": true${reset}`);\n console.error(` ${dim}Then re-run:${reset} ${violet}${bold}kirograph index${reset}\\n`);\n process.exit(1);\n }\n\n const KiroGraph = (await Promise.resolve().then(() => require('../../index.js'))).default;\n if (!KiroGraph.isInitialized(target)) {\n console.error(' \u2716 KiroGraph not initialized. Run: kirograph init');\n process.exit(1);\n }\n\n const cg = await KiroGraph.open(target);\n const db = cg.getDatabase();\n db.applySecuritySchema();\n\n const { SBOMExporter } = await Promise.resolve().then(() => require('../../security/export/sbom.js'));\n const exporter = new SBOMExporter(db, target);\n const json = exporter.exportJSON();\n\n if (opts.output) {\n const outPath = path.resolve(opts.output);\n fs.mkdirSync(path.dirname(outPath), { recursive: true });\n fs.writeFileSync(outPath, json, 'utf-8');\n console.error(` ${green}\u2713${reset} SBOM written to ${violet}${bold}${outPath}${reset}`);\n } else {\n process.stdout.write(json + '\\n');\n }\n\n cg.close();\n });\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,SAAoB;AACpB,WAAsB;AACtB,oBAA2B;AAC3B,gBAAgD;AAEzC,SAAS,SAAS,SAAwB;AAC/C,UACG,QAAQ,oBAAoB,EAC5B,YAAY,wDAAwD,EACpE,OAAO,mBAAmB,sCAAsC,EAChE,OAAO,OAAO,aAAiC,SAA8B;AAC5E,UAAM,SAAS,KAAK,QAAQ,eAAe,QAAQ,IAAI,CAAC;AACxD,UAAM,SAAS,UAAM,0BAAW,MAAM;AAEtC,QAAI,CAAC,OAAO,gBAAgB;AAC1B,cAAQ,MAAM;AAAA,IAAO,UAAU,wCAAmC,eAAK,EAAE;AACzE,cAAQ,MAAM,KAAK,aAAG,uCAAuC,eAAK,IAAI,gBAAM,GAAG,cAAI,yBAAyB,eAAK,EAAE;AACnH,cAAQ,MAAM,KAAK,aAAG,eAAe,eAAK,IAAI,gBAAM,GAAG,cAAI,kBAAkB,eAAK;AAAA,CAAI;AACtF,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,aAAa,MAAM,QAAQ,QAAQ,EAAE,KAAK,MAAM,QAAQ,gBAAgB,CAAC,GAAG;AAClF,QAAI,CAAC,UAAU,cAAc,MAAM,GAAG;AACpC,cAAQ,MAAM,yDAAoD;AAClE,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,KAAK,MAAM,UAAU,KAAK,MAAM;AACtC,UAAM,KAAK,GAAG,YAAY;AAC1B,OAAG,oBAAoB;AAEvB,UAAM,EAAE,aAAa,IAAI,MAAM,QAAQ,QAAQ,EAAE,KAAK,MAAM,QAAQ,+BAA+B,CAAC;AACpG,UAAM,WAAW,IAAI,aAAa,IAAI,MAAM;AAC5C,UAAM,OAAO,SAAS,WAAW;AAEjC,QAAI,KAAK,QAAQ;AACf,YAAM,UAAU,KAAK,QAAQ,KAAK,MAAM;AACxC,SAAG,UAAU,KAAK,QAAQ,OAAO,GAAG,EAAE,WAAW,KAAK,CAAC;AACvD,SAAG,cAAc,SAAS,MAAM,OAAO;AACvC,cAAQ,MAAM,KAAK,eAAK,SAAI,eAAK,oBAAoB,gBAAM,GAAG,cAAI,GAAG,OAAO,GAAG,eAAK,EAAE;AAAA,IACxF,OAAO;AACL,cAAQ,OAAO,MAAM,OAAO,IAAI;AAAA,IAClC;AAEA,OAAG,MAAM;AAAA,EACX,CAAC;AACL;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var security_ci_report_exports = {};
|
|
30
|
+
__export(security_ci_report_exports, {
|
|
31
|
+
register: () => register
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(security_ci_report_exports);
|
|
34
|
+
var fs = __toESM(require("fs"));
|
|
35
|
+
var path = __toESM(require("path"));
|
|
36
|
+
var import_config = require("../../config");
|
|
37
|
+
var import_ui = require("../ui");
|
|
38
|
+
var import_owasp = require("../../security/owasp");
|
|
39
|
+
function severityToSarifLevel(score) {
|
|
40
|
+
if (score == null) return "note";
|
|
41
|
+
if (score >= 7) return "error";
|
|
42
|
+
if (score >= 4) return "warning";
|
|
43
|
+
return "note";
|
|
44
|
+
}
|
|
45
|
+
function computeMaxRisk(vulns) {
|
|
46
|
+
const scores = vulns.map((v) => v.riskScore ?? v.severityScore ?? 0);
|
|
47
|
+
return scores.length > 0 ? Math.max(...scores) : 0;
|
|
48
|
+
}
|
|
49
|
+
function collectOwaspCategories(vulns) {
|
|
50
|
+
const cats = new Set(vulns.map((v) => v.owaspCategory));
|
|
51
|
+
return Array.from(cats).sort();
|
|
52
|
+
}
|
|
53
|
+
function shouldFail(failOn, vulns) {
|
|
54
|
+
switch (failOn) {
|
|
55
|
+
case "affected":
|
|
56
|
+
return vulns.some((v) => v.verdict === "affected");
|
|
57
|
+
case "any":
|
|
58
|
+
return vulns.length > 0;
|
|
59
|
+
case "critical":
|
|
60
|
+
return vulns.some((v) => v.severityScore != null && v.severityScore >= 9);
|
|
61
|
+
default:
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function buildSarif(vulns, projectPath) {
|
|
66
|
+
const rulesMap = /* @__PURE__ */ new Map();
|
|
67
|
+
for (const v of vulns) {
|
|
68
|
+
const ruleId = v.cveId;
|
|
69
|
+
if (!rulesMap.has(ruleId)) {
|
|
70
|
+
const owasp = import_owasp.OWASP_TOP_10[v.owaspCategory];
|
|
71
|
+
rulesMap.set(ruleId, {
|
|
72
|
+
id: ruleId,
|
|
73
|
+
name: ruleId.replace(/-/g, ""),
|
|
74
|
+
shortDescription: { text: v.summary ?? ruleId },
|
|
75
|
+
fullDescription: { text: v.summary ?? ruleId },
|
|
76
|
+
helpUri: `https://osv.dev/vulnerability/${ruleId}`,
|
|
77
|
+
properties: {
|
|
78
|
+
tags: [
|
|
79
|
+
"security",
|
|
80
|
+
`owasp:${v.owaspCategory}`,
|
|
81
|
+
owasp ? owasp.name : ""
|
|
82
|
+
].filter(Boolean)
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const results = vulns.map((v) => {
|
|
88
|
+
const pkg = v.packageName ?? "unknown";
|
|
89
|
+
const ver = v.version ?? "?";
|
|
90
|
+
const msgText = `${v.cveId} in ${pkg}@${ver}` + (v.fixedVersion ? ` \u2014 fix available: ${v.fixedVersion}` : "") + (v.summary ? ` \u2014 ${v.summary}` : "");
|
|
91
|
+
return {
|
|
92
|
+
ruleId: v.cveId,
|
|
93
|
+
message: { text: msgText },
|
|
94
|
+
level: severityToSarifLevel(v.severityScore),
|
|
95
|
+
locations: [
|
|
96
|
+
{
|
|
97
|
+
physicalLocation: {
|
|
98
|
+
artifactLocation: {
|
|
99
|
+
uri: projectPath,
|
|
100
|
+
uriBaseId: "%SRCROOT%"
|
|
101
|
+
},
|
|
102
|
+
region: { startLine: 1 }
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
],
|
|
106
|
+
properties: {
|
|
107
|
+
verdict: v.verdict ?? "unknown",
|
|
108
|
+
owaspCategory: v.owaspCategory,
|
|
109
|
+
riskScore: v.riskScore,
|
|
110
|
+
severityScore: v.severityScore
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
});
|
|
114
|
+
return {
|
|
115
|
+
$schema: "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
|
|
116
|
+
version: "2.1.0",
|
|
117
|
+
runs: [
|
|
118
|
+
{
|
|
119
|
+
tool: {
|
|
120
|
+
driver: {
|
|
121
|
+
name: "kirograph",
|
|
122
|
+
version: "1.0",
|
|
123
|
+
informationUri: "https://github.com/eleva/kirograph",
|
|
124
|
+
rules: Array.from(rulesMap.values())
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
results
|
|
128
|
+
}
|
|
129
|
+
]
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
function renderText(vulns, exitCode) {
|
|
133
|
+
const lines = [];
|
|
134
|
+
for (const v of vulns) {
|
|
135
|
+
const pkg = v.packageName ? `${v.packageName}@${v.version ?? "?"}` : "unknown";
|
|
136
|
+
const score = v.severityScore != null ? v.severityScore.toFixed(1) : "?";
|
|
137
|
+
const verdict = v.verdict ?? "pending";
|
|
138
|
+
const risk = v.riskScore != null ? ` risk=${v.riskScore.toFixed(1)}` : "";
|
|
139
|
+
lines.push(`${v.cveId} | ${pkg} | cvss=${score}${risk} | ${verdict} | ${v.owaspCategory}`);
|
|
140
|
+
}
|
|
141
|
+
if (exitCode !== 0) {
|
|
142
|
+
lines.push(`EXIT_CODE=1`);
|
|
143
|
+
}
|
|
144
|
+
return lines.join("\n");
|
|
145
|
+
}
|
|
146
|
+
function register(program) {
|
|
147
|
+
program.command("ci-report [projectPath]").description("Generate a structured security report for CI/CD pipelines (JSON, SARIF, or text)").option("--format <fmt>", "Output format: json|sarif|text (default: json)", "json").option("--fail-on <condition>", "Exit 1 if condition is met: affected|any|critical", "affected").option("--output <file>", "Write report to file instead of stdout").action(async (projectPath, opts) => {
|
|
148
|
+
const target = path.resolve(projectPath ?? process.cwd());
|
|
149
|
+
const config = await (0, import_config.loadConfig)(target);
|
|
150
|
+
const validFormats = ["json", "sarif", "text"];
|
|
151
|
+
if (!validFormats.includes(opts.format)) {
|
|
152
|
+
console.error(` \u2716 Invalid --format value: ${opts.format}. Use: ${validFormats.join(", ")}`);
|
|
153
|
+
process.exit(1);
|
|
154
|
+
}
|
|
155
|
+
const validFailOns = ["affected", "any", "critical"];
|
|
156
|
+
if (!validFailOns.includes(opts.failOn)) {
|
|
157
|
+
console.error(` \u2716 Invalid --fail-on value: ${opts.failOn}. Use: ${validFailOns.join(", ")}`);
|
|
158
|
+
process.exit(1);
|
|
159
|
+
}
|
|
160
|
+
if (!config.enableSecurity) {
|
|
161
|
+
console.error(`
|
|
162
|
+
${"\x1B[33m"}\u26A0 Security analysis is disabled.${import_ui.reset}`);
|
|
163
|
+
console.error(` ${import_ui.dim}Enable it in .kirograph/config.json:${import_ui.reset} ${import_ui.violet}${import_ui.bold}"enableSecurity": true${import_ui.reset}`);
|
|
164
|
+
console.error(` ${import_ui.dim}Then re-run:${import_ui.reset} ${import_ui.violet}${import_ui.bold}kirograph index${import_ui.reset}
|
|
165
|
+
`);
|
|
166
|
+
process.exit(1);
|
|
167
|
+
}
|
|
168
|
+
const KiroGraph = (await Promise.resolve().then(() => require("../../index.js"))).default;
|
|
169
|
+
if (!KiroGraph.isInitialized(target)) {
|
|
170
|
+
console.error(" \u2716 KiroGraph not initialized. Run: kirograph init");
|
|
171
|
+
process.exit(1);
|
|
172
|
+
}
|
|
173
|
+
const cg = await KiroGraph.open(target);
|
|
174
|
+
const db = cg.getDatabase();
|
|
175
|
+
db.applySecuritySchema();
|
|
176
|
+
const rawDb = db.getRawDb();
|
|
177
|
+
const depCount = rawDb.get(
|
|
178
|
+
`SELECT COUNT(*) as count FROM sec_dependencies`
|
|
179
|
+
) ?? { count: 0 };
|
|
180
|
+
const vulnRows = rawDb.all(`
|
|
181
|
+
SELECT
|
|
182
|
+
v.cve_id,
|
|
183
|
+
d.package_name,
|
|
184
|
+
d.ecosystem,
|
|
185
|
+
d.resolved_version,
|
|
186
|
+
d.declared_constraint,
|
|
187
|
+
v.severity_score,
|
|
188
|
+
r.verdict,
|
|
189
|
+
v.risk_score,
|
|
190
|
+
v.summary,
|
|
191
|
+
v.fixed_version
|
|
192
|
+
FROM sec_vulnerabilities v
|
|
193
|
+
LEFT JOIN edges e ON e.target = v.node_id AND e.kind = 'has_vulnerability'
|
|
194
|
+
LEFT JOIN sec_dependencies d ON d.node_id = e.source
|
|
195
|
+
LEFT JOIN sec_reachability r ON r.vulnerability_node_id = v.node_id
|
|
196
|
+
ORDER BY v.risk_score DESC NULLS LAST, v.severity_score DESC NULLS LAST
|
|
197
|
+
`);
|
|
198
|
+
const vulns = vulnRows.map((row) => {
|
|
199
|
+
const owaspCat = (0, import_owasp.mapCveToOwasp)(row.summary ?? "", row.package_name ?? "");
|
|
200
|
+
return {
|
|
201
|
+
cveId: row.cve_id,
|
|
202
|
+
packageName: row.package_name,
|
|
203
|
+
ecosystem: row.ecosystem,
|
|
204
|
+
version: row.resolved_version ?? row.declared_constraint,
|
|
205
|
+
severityScore: row.severity_score,
|
|
206
|
+
verdict: row.verdict,
|
|
207
|
+
riskScore: row.risk_score,
|
|
208
|
+
owaspCategory: owaspCat,
|
|
209
|
+
owaspName: import_owasp.OWASP_TOP_10[owaspCat].name,
|
|
210
|
+
summary: row.summary,
|
|
211
|
+
fixedVersion: row.fixed_version
|
|
212
|
+
};
|
|
213
|
+
});
|
|
214
|
+
const willFail = shouldFail(opts.failOn, vulns);
|
|
215
|
+
const exitCode = willFail ? 1 : 0;
|
|
216
|
+
let output;
|
|
217
|
+
if (opts.format === "sarif") {
|
|
218
|
+
const sarif = buildSarif(vulns, target);
|
|
219
|
+
output = JSON.stringify(sarif, null, 2);
|
|
220
|
+
} else if (opts.format === "text") {
|
|
221
|
+
output = renderText(vulns, exitCode);
|
|
222
|
+
} else {
|
|
223
|
+
const affectedCount = vulns.filter((v) => v.verdict === "affected").length;
|
|
224
|
+
const maxRisk = parseFloat(computeMaxRisk(vulns).toFixed(1));
|
|
225
|
+
const report = {
|
|
226
|
+
version: "1.0",
|
|
227
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
228
|
+
project: path.basename(target),
|
|
229
|
+
summary: {
|
|
230
|
+
dependencies: depCount.count,
|
|
231
|
+
vulnerabilities: vulns.length,
|
|
232
|
+
affected: affectedCount,
|
|
233
|
+
riskScore: maxRisk,
|
|
234
|
+
secretsFound: 0,
|
|
235
|
+
// secrets scanning not yet wired
|
|
236
|
+
owaspCategories: collectOwaspCategories(vulns)
|
|
237
|
+
},
|
|
238
|
+
vulnerabilities: vulns,
|
|
239
|
+
secrets: [],
|
|
240
|
+
exitCode
|
|
241
|
+
};
|
|
242
|
+
output = JSON.stringify(report, null, 2);
|
|
243
|
+
}
|
|
244
|
+
if (opts.output) {
|
|
245
|
+
const outPath = path.resolve(opts.output);
|
|
246
|
+
fs.mkdirSync(path.dirname(outPath), { recursive: true });
|
|
247
|
+
fs.writeFileSync(outPath, output, "utf-8");
|
|
248
|
+
console.error(` ${import_ui.green}\u2713${import_ui.reset} Report written to ${import_ui.violet}${import_ui.bold}${outPath}${import_ui.reset}`);
|
|
249
|
+
} else {
|
|
250
|
+
process.stdout.write(output + "\n");
|
|
251
|
+
}
|
|
252
|
+
cg.close();
|
|
253
|
+
if (exitCode !== 0) {
|
|
254
|
+
const failLabel = opts.failOn;
|
|
255
|
+
console.error(
|
|
256
|
+
`
|
|
257
|
+
\x1B[31m\u2716\x1B[0m --fail-on ${failLabel}: condition met. Exiting with code 1.`
|
|
258
|
+
);
|
|
259
|
+
process.exit(1);
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
264
|
+
0 && (module.exports = {
|
|
265
|
+
register
|
|
266
|
+
});
|
|
267
|
+
//# sourceMappingURL=security-ci-report.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/bin/commands/security-ci-report.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * kirograph security ci-report\n *\n * Generates a structured security report for CI/CD pipelines.\n * Supports JSON, SARIF 2.1.0, and compact text output formats.\n */\n\nimport { Command } from 'commander';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { loadConfig } from '../../config';\nimport { dim, reset, violet, bold, green } from '../ui';\nimport { mapCveToOwasp, OWASP_TOP_10 } from '../../security/owasp';\n\n// \u2500\u2500 Report types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ninterface CiVulnEntry {\n cveId: string;\n packageName: string | null;\n ecosystem: string | null;\n version: string | null;\n severityScore: number | null;\n verdict: string | null;\n riskScore: number | null;\n owaspCategory: string;\n owaspName: string;\n summary: string | null;\n fixedVersion: string | null;\n}\n\ninterface CiReport {\n version: '1.0';\n timestamp: string;\n project: string;\n summary: {\n dependencies: number;\n vulnerabilities: number;\n affected: number;\n riskScore: number;\n secretsFound: number;\n owaspCategories: string[];\n };\n vulnerabilities: CiVulnEntry[];\n secrets: unknown[];\n exitCode: number;\n}\n\n// \u2500\u2500 SARIF types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ninterface SarifRule {\n id: string;\n name: string;\n shortDescription: { text: string };\n fullDescription: { text: string };\n helpUri: string;\n properties: { tags: string[] };\n}\n\ninterface SarifResult {\n ruleId: string;\n message: { text: string };\n level: 'error' | 'warning' | 'note';\n locations: Array<{\n physicalLocation: {\n artifactLocation: { uri: string; uriBaseId: string };\n region: { startLine: number };\n };\n }>;\n properties: Record<string, unknown>;\n}\n\ninterface SarifOutput {\n $schema: string;\n version: '2.1.0';\n runs: Array<{\n tool: {\n driver: {\n name: string;\n version: string;\n informationUri: string;\n rules: SarifRule[];\n };\n };\n results: SarifResult[];\n }>;\n}\n\n// \u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction severityToSarifLevel(score: number | null): 'error' | 'warning' | 'note' {\n if (score == null) return 'note';\n if (score >= 7.0) return 'error';\n if (score >= 4.0) return 'warning';\n return 'note';\n}\n\nfunction computeMaxRisk(vulns: CiVulnEntry[]): number {\n const scores = vulns.map((v) => v.riskScore ?? v.severityScore ?? 0);\n return scores.length > 0 ? Math.max(...scores) : 0;\n}\n\nfunction collectOwaspCategories(vulns: CiVulnEntry[]): string[] {\n const cats = new Set<string>(vulns.map((v) => v.owaspCategory));\n return Array.from(cats).sort();\n}\n\n// \u2500\u2500 Fail-on evaluation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction shouldFail(failOn: string, vulns: CiVulnEntry[]): boolean {\n switch (failOn) {\n case 'affected':\n return vulns.some((v) => v.verdict === 'affected');\n case 'any':\n return vulns.length > 0;\n case 'critical':\n return vulns.some((v) => v.severityScore != null && v.severityScore >= 9.0);\n default:\n return false;\n }\n}\n\n// \u2500\u2500 SARIF generation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction buildSarif(vulns: CiVulnEntry[], projectPath: string): SarifOutput {\n const rulesMap = new Map<string, SarifRule>();\n\n for (const v of vulns) {\n const ruleId = v.cveId;\n if (!rulesMap.has(ruleId)) {\n const owasp = OWASP_TOP_10[v.owaspCategory as keyof typeof OWASP_TOP_10];\n rulesMap.set(ruleId, {\n id: ruleId,\n name: ruleId.replace(/-/g, ''),\n shortDescription: { text: v.summary ?? ruleId },\n fullDescription: { text: v.summary ?? ruleId },\n helpUri: `https://osv.dev/vulnerability/${ruleId}`,\n properties: {\n tags: [\n 'security',\n `owasp:${v.owaspCategory}`,\n owasp ? owasp.name : '',\n ].filter(Boolean),\n },\n });\n }\n }\n\n const results: SarifResult[] = vulns.map((v) => {\n const pkg = v.packageName ?? 'unknown';\n const ver = v.version ?? '?';\n const msgText =\n `${v.cveId} in ${pkg}@${ver}` +\n (v.fixedVersion ? ` \u2014 fix available: ${v.fixedVersion}` : '') +\n (v.summary ? ` \u2014 ${v.summary}` : '');\n\n return {\n ruleId: v.cveId,\n message: { text: msgText },\n level: severityToSarifLevel(v.severityScore),\n locations: [\n {\n physicalLocation: {\n artifactLocation: {\n uri: projectPath,\n uriBaseId: '%SRCROOT%',\n },\n region: { startLine: 1 },\n },\n },\n ],\n properties: {\n verdict: v.verdict ?? 'unknown',\n owaspCategory: v.owaspCategory,\n riskScore: v.riskScore,\n severityScore: v.severityScore,\n },\n };\n });\n\n return {\n $schema: 'https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json',\n version: '2.1.0',\n runs: [\n {\n tool: {\n driver: {\n name: 'kirograph',\n version: '1.0',\n informationUri: 'https://github.com/eleva/kirograph',\n rules: Array.from(rulesMap.values()),\n },\n },\n results,\n },\n ],\n };\n}\n\n// \u2500\u2500 Text format \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction renderText(vulns: CiVulnEntry[], exitCode: number): string {\n const lines: string[] = [];\n for (const v of vulns) {\n const pkg = v.packageName ? `${v.packageName}@${v.version ?? '?'}` : 'unknown';\n const score = v.severityScore != null ? v.severityScore.toFixed(1) : '?';\n const verdict = v.verdict ?? 'pending';\n const risk = v.riskScore != null ? ` risk=${v.riskScore.toFixed(1)}` : '';\n lines.push(`${v.cveId} | ${pkg} | cvss=${score}${risk} | ${verdict} | ${v.owaspCategory}`);\n }\n if (exitCode !== 0) {\n lines.push(`EXIT_CODE=1`);\n }\n return lines.join('\\n');\n}\n\n// \u2500\u2500 Command registration \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function register(program: Command): void {\n program\n .command('ci-report [projectPath]')\n .description('Generate a structured security report for CI/CD pipelines (JSON, SARIF, or text)')\n .option('--format <fmt>', 'Output format: json|sarif|text (default: json)', 'json')\n .option('--fail-on <condition>', 'Exit 1 if condition is met: affected|any|critical', 'affected')\n .option('--output <file>', 'Write report to file instead of stdout')\n .action(async (\n projectPath: string | undefined,\n opts: { format: string; failOn: string; output?: string },\n ) => {\n const target = path.resolve(projectPath ?? process.cwd());\n const config = await loadConfig(target);\n\n // Validate --format\n const validFormats = ['json', 'sarif', 'text'];\n if (!validFormats.includes(opts.format)) {\n console.error(` \u2716 Invalid --format value: ${opts.format}. Use: ${validFormats.join(', ')}`);\n process.exit(1);\n }\n\n // Validate --fail-on\n const validFailOns = ['affected', 'any', 'critical'];\n if (!validFailOns.includes(opts.failOn)) {\n console.error(` \u2716 Invalid --fail-on value: ${opts.failOn}. Use: ${validFailOns.join(', ')}`);\n process.exit(1);\n }\n\n if (!config.enableSecurity) {\n console.error(`\\n ${'\\x1b[33m'}\u26A0 Security analysis is disabled.${reset}`);\n console.error(` ${dim}Enable it in .kirograph/config.json:${reset} ${violet}${bold}\"enableSecurity\": true${reset}`);\n console.error(` ${dim}Then re-run:${reset} ${violet}${bold}kirograph index${reset}\\n`);\n process.exit(1);\n }\n\n const KiroGraph = (await Promise.resolve().then(() => require('../../index.js'))).default;\n if (!KiroGraph.isInitialized(target)) {\n console.error(' \u2716 KiroGraph not initialized. Run: kirograph init');\n process.exit(1);\n }\n\n const cg = await KiroGraph.open(target);\n const db = cg.getDatabase();\n db.applySecuritySchema();\n const rawDb = db.getRawDb();\n\n // \u2500\u2500 Query data \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const depCount: { count: number } = rawDb.get(\n `SELECT COUNT(*) as count FROM sec_dependencies`,\n ) ?? { count: 0 };\n\n const vulnRows: Array<{\n cve_id: string;\n package_name: string | null;\n ecosystem: string | null;\n resolved_version: string | null;\n declared_constraint: string | null;\n severity_score: number | null;\n verdict: string | null;\n risk_score: number | null;\n summary: string | null;\n fixed_version: string | null;\n }> = rawDb.all(`\n SELECT\n v.cve_id,\n d.package_name,\n d.ecosystem,\n d.resolved_version,\n d.declared_constraint,\n v.severity_score,\n r.verdict,\n v.risk_score,\n v.summary,\n v.fixed_version\n FROM sec_vulnerabilities v\n LEFT JOIN edges e ON e.target = v.node_id AND e.kind = 'has_vulnerability'\n LEFT JOIN sec_dependencies d ON d.node_id = e.source\n LEFT JOIN sec_reachability r ON r.vulnerability_node_id = v.node_id\n ORDER BY v.risk_score DESC NULLS LAST, v.severity_score DESC NULLS LAST\n `);\n\n // \u2500\u2500 Build enriched vuln list with OWASP mapping \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const vulns: CiVulnEntry[] = vulnRows.map((row) => {\n const owaspCat = mapCveToOwasp(row.summary ?? '', row.package_name ?? '');\n return {\n cveId: row.cve_id,\n packageName: row.package_name,\n ecosystem: row.ecosystem,\n version: row.resolved_version ?? row.declared_constraint,\n severityScore: row.severity_score,\n verdict: row.verdict,\n riskScore: row.risk_score,\n owaspCategory: owaspCat,\n owaspName: OWASP_TOP_10[owaspCat].name,\n summary: row.summary,\n fixedVersion: row.fixed_version,\n };\n });\n\n // \u2500\u2500 Compute exit code \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const willFail = shouldFail(opts.failOn, vulns);\n const exitCode = willFail ? 1 : 0;\n\n // \u2500\u2500 Build and emit report \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n let output: string;\n\n if (opts.format === 'sarif') {\n const sarif = buildSarif(vulns, target);\n output = JSON.stringify(sarif, null, 2);\n } else if (opts.format === 'text') {\n output = renderText(vulns, exitCode);\n } else {\n // JSON\n const affectedCount = vulns.filter((v) => v.verdict === 'affected').length;\n const maxRisk = parseFloat(computeMaxRisk(vulns).toFixed(1));\n\n const report: CiReport = {\n version: '1.0',\n timestamp: new Date().toISOString(),\n project: path.basename(target),\n summary: {\n dependencies: depCount.count,\n vulnerabilities: vulns.length,\n affected: affectedCount,\n riskScore: maxRisk,\n secretsFound: 0, // secrets scanning not yet wired\n owaspCategories: collectOwaspCategories(vulns),\n },\n vulnerabilities: vulns,\n secrets: [],\n exitCode,\n };\n output = JSON.stringify(report, null, 2);\n }\n\n // \u2500\u2500 Write or print \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n if (opts.output) {\n const outPath = path.resolve(opts.output);\n fs.mkdirSync(path.dirname(outPath), { recursive: true });\n fs.writeFileSync(outPath, output, 'utf-8');\n console.error(` ${green}\u2713${reset} Report written to ${violet}${bold}${outPath}${reset}`);\n } else {\n process.stdout.write(output + '\\n');\n }\n\n cg.close();\n\n if (exitCode !== 0) {\n const failLabel = opts.failOn;\n console.error(\n `\\n \\x1b[31m\u2716\\x1b[0m --fail-on ${failLabel}: condition met. Exiting with code 1.`,\n );\n process.exit(1);\n }\n });\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|