kirograph 0.17.0 → 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 -1822
- 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/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/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 +382 -101
- 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 +12 -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 +9 -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 +407 -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 +72 -6
- package/dist/bin/kirograph.js.map +3 -3
- package/dist/compression/tracker.js +80 -0
- package/dist/compression/tracker.js.map +2 -2
- package/dist/config.js +90 -3
- package/dist/config.js.map +2 -2
- package/dist/core/pipeline.js +36 -2
- package/dist/core/pipeline.js.map +2 -2
- package/dist/db/database.js +56 -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 +21 -1
- package/dist/mcp/tool-names.js.map +2 -2
- package/dist/mcp/tools.js +1160 -1
- 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 +2 -1
|
@@ -0,0 +1,112 @@
|
|
|
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 dart_exports = {};
|
|
30
|
+
__export(dart_exports, {
|
|
31
|
+
dartLayerDetector: () => dartLayerDetector
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(dart_exports);
|
|
34
|
+
var import_picomatch = __toESM(require("picomatch"));
|
|
35
|
+
const LAYER_PATTERNS = [
|
|
36
|
+
// UI layer
|
|
37
|
+
["ui", "**/lib/screens/**", 0.9],
|
|
38
|
+
["ui", "**/lib/pages/**", 0.9],
|
|
39
|
+
["ui", "**/lib/views/**", 0.85],
|
|
40
|
+
["ui", "**/lib/widgets/**", 0.9],
|
|
41
|
+
["ui", "**/lib/components/**", 0.85],
|
|
42
|
+
// Service / Business logic layer
|
|
43
|
+
["service", "**/lib/services/**", 0.9],
|
|
44
|
+
["service", "**/lib/providers/**", 0.85],
|
|
45
|
+
["service", "**/lib/blocs/**", 0.9],
|
|
46
|
+
["service", "**/lib/cubits/**", 0.9],
|
|
47
|
+
["service", "**/lib/notifiers/**", 0.85],
|
|
48
|
+
// Data layer
|
|
49
|
+
["data", "**/lib/repositories/**", 0.9],
|
|
50
|
+
["data", "**/lib/data/**", 0.85],
|
|
51
|
+
["data", "**/lib/datasources/**", 0.9],
|
|
52
|
+
["data", "**/lib/models/**", 0.85],
|
|
53
|
+
["data", "**/lib/entities/**", 0.85],
|
|
54
|
+
["data", "**/lib/domain/**", 0.8],
|
|
55
|
+
// Shared / Infrastructure layer
|
|
56
|
+
["shared", "**/lib/core/**", 0.85],
|
|
57
|
+
["shared", "**/lib/utils/**", 0.85],
|
|
58
|
+
["shared", "**/lib/helpers/**", 0.85],
|
|
59
|
+
["shared", "**/lib/extensions/**", 0.85],
|
|
60
|
+
["shared", "**/lib/constants/**", 0.8],
|
|
61
|
+
// API / Navigation layer
|
|
62
|
+
["api", "**/lib/routes/**", 0.9],
|
|
63
|
+
["api", "**/lib/navigation/**", 0.85],
|
|
64
|
+
["api", "**/lib/router/**", 0.85],
|
|
65
|
+
["api", "**/lib/main.dart", 0.8],
|
|
66
|
+
["api", "**/lib/app.dart", 0.8]
|
|
67
|
+
];
|
|
68
|
+
const TEST_PATTERN = (0, import_picomatch.default)("**/test/**");
|
|
69
|
+
const dartLayerDetector = {
|
|
70
|
+
language: "dart",
|
|
71
|
+
async detect(files, _projectRoot, configLayers) {
|
|
72
|
+
const results = [];
|
|
73
|
+
const configMatchers = _buildConfigMatchers(configLayers ?? {});
|
|
74
|
+
for (const file of files) {
|
|
75
|
+
if (!file.endsWith(".dart")) continue;
|
|
76
|
+
if (TEST_PATTERN(file)) continue;
|
|
77
|
+
const configMatch = _matchConfig(file, configMatchers);
|
|
78
|
+
if (configMatch) {
|
|
79
|
+
results.push({ ...configMatch, filePath: file });
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
let best = null;
|
|
83
|
+
for (const [layerName, pattern, confidence] of LAYER_PATTERNS) {
|
|
84
|
+
if ((0, import_picomatch.default)(pattern)(file)) {
|
|
85
|
+
if (!best || confidence > best.confidence) {
|
|
86
|
+
best = { layerName, filePath: file, confidence, matchedPattern: pattern };
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (best) results.push(best);
|
|
91
|
+
}
|
|
92
|
+
return results;
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
function _buildConfigMatchers(configLayers) {
|
|
96
|
+
return Object.entries(configLayers).flatMap(
|
|
97
|
+
([layerName, patterns]) => patterns.map(
|
|
98
|
+
(pattern) => [layerName, (0, import_picomatch.default)(pattern), pattern]
|
|
99
|
+
)
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
function _matchConfig(file, matchers) {
|
|
103
|
+
for (const [layerName, matcher, pattern] of matchers) {
|
|
104
|
+
if (matcher(file)) return { layerName, confidence: 1, matchedPattern: `config:${pattern}` };
|
|
105
|
+
}
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
109
|
+
0 && (module.exports = {
|
|
110
|
+
dartLayerDetector
|
|
111
|
+
});
|
|
112
|
+
//# sourceMappingURL=dart.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/architecture/layers/dart.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Layer detector for Dart / Flutter projects.\n *\n * Detects: api, service, data, ui, shared layers based on\n * directory names common in Flutter projects under lib/.\n * Files in test/ are skipped (return no match).\n */\nimport type { LayerDetector, ArchLayerMatch } from '../types';\nimport picomatch from 'picomatch';\n\n// Pattern definitions: each entry is [layerName, glob, confidence]\nconst LAYER_PATTERNS: Array<[string, string, number]> = [\n // UI layer\n ['ui', '**/lib/screens/**', 0.9],\n ['ui', '**/lib/pages/**', 0.9],\n ['ui', '**/lib/views/**', 0.85],\n ['ui', '**/lib/widgets/**', 0.9],\n ['ui', '**/lib/components/**', 0.85],\n\n // Service / Business logic layer\n ['service', '**/lib/services/**', 0.9],\n ['service', '**/lib/providers/**', 0.85],\n ['service', '**/lib/blocs/**', 0.9],\n ['service', '**/lib/cubits/**', 0.9],\n ['service', '**/lib/notifiers/**', 0.85],\n\n // Data layer\n ['data', '**/lib/repositories/**', 0.9],\n ['data', '**/lib/data/**', 0.85],\n ['data', '**/lib/datasources/**', 0.9],\n ['data', '**/lib/models/**', 0.85],\n ['data', '**/lib/entities/**', 0.85],\n ['data', '**/lib/domain/**', 0.8],\n\n // Shared / Infrastructure layer\n ['shared', '**/lib/core/**', 0.85],\n ['shared', '**/lib/utils/**', 0.85],\n ['shared', '**/lib/helpers/**', 0.85],\n ['shared', '**/lib/extensions/**', 0.85],\n ['shared', '**/lib/constants/**', 0.8],\n\n // API / Navigation layer\n ['api', '**/lib/routes/**', 0.9],\n ['api', '**/lib/navigation/**', 0.85],\n ['api', '**/lib/router/**', 0.85],\n ['api', '**/lib/main.dart', 0.8],\n ['api', '**/lib/app.dart', 0.8],\n];\n\nconst TEST_PATTERN = picomatch('**/test/**');\n\nexport const dartLayerDetector: LayerDetector = {\n language: 'dart',\n\n async detect(files: string[], _projectRoot: string, configLayers?: Record<string, string[]>): Promise<ArchLayerMatch[]> {\n const results: ArchLayerMatch[] = [];\n const configMatchers = _buildConfigMatchers(configLayers ?? {});\n\n for (const file of files) {\n if (!file.endsWith('.dart')) continue;\n\n // Skip test files\n if (TEST_PATTERN(file)) continue;\n\n const configMatch = _matchConfig(file, configMatchers);\n if (configMatch) {\n results.push({ ...configMatch, filePath: file });\n continue;\n }\n\n let best: ArchLayerMatch | null = null;\n for (const [layerName, pattern, confidence] of LAYER_PATTERNS) {\n if (picomatch(pattern)(file)) {\n if (!best || confidence > best.confidence) {\n best = { layerName, filePath: file, confidence, matchedPattern: pattern };\n }\n }\n }\n if (best) results.push(best);\n }\n\n return results;\n },\n};\n\nfunction _buildConfigMatchers(configLayers: Record<string, string[]>): Array<[string, ReturnType<typeof picomatch>, string]> {\n return Object.entries(configLayers).flatMap(([layerName, patterns]) =>\n patterns.map((pattern): [string, ReturnType<typeof picomatch>, string] =>\n [layerName, picomatch(pattern), pattern]\n )\n );\n}\n\nfunction _matchConfig(\n file: string,\n matchers: Array<[string, ReturnType<typeof picomatch>, string]>\n): Omit<ArchLayerMatch, 'filePath'> | null {\n for (const [layerName, matcher, pattern] of matchers) {\n if (matcher(file)) return { layerName, confidence: 1.0, matchedPattern: `config:${pattern}` };\n }\n return null;\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA,uBAAsB;AAGtB,MAAM,iBAAkD;AAAA;AAAA,EAEtD,CAAC,MAAM,qBAAqB,GAAG;AAAA,EAC/B,CAAC,MAAM,mBAAmB,GAAG;AAAA,EAC7B,CAAC,MAAM,mBAAmB,IAAI;AAAA,EAC9B,CAAC,MAAM,qBAAqB,GAAG;AAAA,EAC/B,CAAC,MAAM,wBAAwB,IAAI;AAAA;AAAA,EAGnC,CAAC,WAAW,sBAAsB,GAAG;AAAA,EACrC,CAAC,WAAW,uBAAuB,IAAI;AAAA,EACvC,CAAC,WAAW,mBAAmB,GAAG;AAAA,EAClC,CAAC,WAAW,oBAAoB,GAAG;AAAA,EACnC,CAAC,WAAW,uBAAuB,IAAI;AAAA;AAAA,EAGvC,CAAC,QAAQ,0BAA0B,GAAG;AAAA,EACtC,CAAC,QAAQ,kBAAkB,IAAI;AAAA,EAC/B,CAAC,QAAQ,yBAAyB,GAAG;AAAA,EACrC,CAAC,QAAQ,oBAAoB,IAAI;AAAA,EACjC,CAAC,QAAQ,sBAAsB,IAAI;AAAA,EACnC,CAAC,QAAQ,oBAAoB,GAAG;AAAA;AAAA,EAGhC,CAAC,UAAU,kBAAkB,IAAI;AAAA,EACjC,CAAC,UAAU,mBAAmB,IAAI;AAAA,EAClC,CAAC,UAAU,qBAAqB,IAAI;AAAA,EACpC,CAAC,UAAU,wBAAwB,IAAI;AAAA,EACvC,CAAC,UAAU,uBAAuB,GAAG;AAAA;AAAA,EAGrC,CAAC,OAAO,oBAAoB,GAAG;AAAA,EAC/B,CAAC,OAAO,wBAAwB,IAAI;AAAA,EACpC,CAAC,OAAO,oBAAoB,IAAI;AAAA,EAChC,CAAC,OAAO,oBAAoB,GAAG;AAAA,EAC/B,CAAC,OAAO,mBAAmB,GAAG;AAChC;AAEA,MAAM,mBAAe,iBAAAA,SAAU,YAAY;AAEpC,MAAM,oBAAmC;AAAA,EAC9C,UAAU;AAAA,EAEV,MAAM,OAAO,OAAiB,cAAsB,cAAoE;AACtH,UAAM,UAA4B,CAAC;AACnC,UAAM,iBAAiB,qBAAqB,gBAAgB,CAAC,CAAC;AAE9D,eAAW,QAAQ,OAAO;AACxB,UAAI,CAAC,KAAK,SAAS,OAAO,EAAG;AAG7B,UAAI,aAAa,IAAI,EAAG;AAExB,YAAM,cAAc,aAAa,MAAM,cAAc;AACrD,UAAI,aAAa;AACf,gBAAQ,KAAK,EAAE,GAAG,aAAa,UAAU,KAAK,CAAC;AAC/C;AAAA,MACF;AAEA,UAAI,OAA8B;AAClC,iBAAW,CAAC,WAAW,SAAS,UAAU,KAAK,gBAAgB;AAC7D,gBAAI,iBAAAA,SAAU,OAAO,EAAE,IAAI,GAAG;AAC5B,cAAI,CAAC,QAAQ,aAAa,KAAK,YAAY;AACzC,mBAAO,EAAE,WAAW,UAAU,MAAM,YAAY,gBAAgB,QAAQ;AAAA,UAC1E;AAAA,QACF;AAAA,MACF;AACA,UAAI,KAAM,SAAQ,KAAK,IAAI;AAAA,IAC7B;AAEA,WAAO;AAAA,EACT;AACF;AAEA,SAAS,qBAAqB,cAA+F;AAC3H,SAAO,OAAO,QAAQ,YAAY,EAAE;AAAA,IAAQ,CAAC,CAAC,WAAW,QAAQ,MAC/D,SAAS;AAAA,MAAI,CAAC,YACZ,CAAC,eAAW,iBAAAA,SAAU,OAAO,GAAG,OAAO;AAAA,IACzC;AAAA,EACF;AACF;AAEA,SAAS,aACP,MACA,UACyC;AACzC,aAAW,CAAC,WAAW,SAAS,OAAO,KAAK,UAAU;AACpD,QAAI,QAAQ,IAAI,EAAG,QAAO,EAAE,WAAW,YAAY,GAAK,gBAAgB,UAAU,OAAO,GAAG;AAAA,EAC9F;AACA,SAAO;AACT;",
|
|
6
|
+
"names": ["picomatch"]
|
|
7
|
+
}
|
|
@@ -36,6 +36,7 @@ var import_scala = require("./scala");
|
|
|
36
36
|
var import_vue = require("./vue");
|
|
37
37
|
var import_solidity = require("./solidity");
|
|
38
38
|
var import_ocaml = require("./ocaml");
|
|
39
|
+
var import_dart = require("./dart");
|
|
39
40
|
const LAYER_DETECTORS = [
|
|
40
41
|
import_typescript.typescriptLayerDetector,
|
|
41
42
|
import_python.pythonLayerDetector,
|
|
@@ -48,7 +49,8 @@ const LAYER_DETECTORS = [
|
|
|
48
49
|
import_scala.scalaLayerDetector,
|
|
49
50
|
import_vue.vueLayerDetector,
|
|
50
51
|
import_solidity.solidityLayerDetector,
|
|
51
|
-
import_ocaml.ocamlLayerDetector
|
|
52
|
+
import_ocaml.ocamlLayerDetector,
|
|
53
|
+
import_dart.dartLayerDetector
|
|
52
54
|
];
|
|
53
55
|
function getAllLayerDetectors() {
|
|
54
56
|
return LAYER_DETECTORS;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/architecture/layers/index.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Layer Detector Registry\n *\n * Dispatches layer detection to language-specific detectors.\n * Config-defined layers always win over auto-detection.\n */\nimport type { LayerDetector, ArchLayerMatch, ArchLayer } from '../types';\nimport { typescriptLayerDetector } from './typescript';\nimport { pythonLayerDetector } from './python';\nimport { goLayerDetector } from './go';\nimport { javaLayerDetector } from './java';\nimport { rubyLayerDetector } from './ruby';\nimport { rustLayerDetector } from './rust';\nimport { csharpLayerDetector } from './csharp';\nimport { elixirLayerDetector } from './elixir';\nimport { scalaLayerDetector } from './scala';\nimport { vueLayerDetector } from './vue';\nimport { solidityLayerDetector } from './solidity';\nimport { ocamlLayerDetector } from './ocaml';\n\nconst LAYER_DETECTORS: LayerDetector[] = [\n typescriptLayerDetector,\n pythonLayerDetector,\n goLayerDetector,\n javaLayerDetector,\n rubyLayerDetector,\n rustLayerDetector,\n csharpLayerDetector,\n elixirLayerDetector,\n scalaLayerDetector,\n vueLayerDetector,\n solidityLayerDetector,\n ocamlLayerDetector,\n];\n\nexport function getAllLayerDetectors(): LayerDetector[] {\n return LAYER_DETECTORS;\n}\n\nexport function registerLayerDetector(detector: LayerDetector): void {\n const idx = LAYER_DETECTORS.findIndex(d => d.language === detector.language && d.framework === detector.framework);\n if (idx >= 0) LAYER_DETECTORS[idx] = detector;\n else LAYER_DETECTORS.push(detector);\n}\n\nexport interface FileLayerAssignment {\n filePath: string;\n layerName: string;\n confidence: number;\n matchedPattern: string;\n}\n\n/**\n * Run all language-specific layer detectors against the file list.\n * Each file gets at most one layer assignment (highest confidence wins).\n * Config-defined layers (confidence=1.0) always beat auto-detected ones.\n *\n * @param files - relative file paths (from project root)\n * @param projectRoot - absolute project root path\n * @param configLayers - user-defined layer\u2192glob overrides from config\n */\nexport async function detectAllLayers(\n files: string[],\n projectRoot: string,\n configLayers?: Record<string, string[]>\n): Promise<FileLayerAssignment[]> {\n // Collect all matches from all detectors\n const allMatches: ArchLayerMatch[] = [];\n for (const detector of LAYER_DETECTORS) {\n const matches = await detector.detect(files, projectRoot, configLayers);\n allMatches.push(...matches);\n }\n\n // Per file, keep the highest-confidence match\n const best = new Map<string, ArchLayerMatch>();\n for (const match of allMatches) {\n const existing = best.get(match.filePath);\n if (!existing || match.confidence > existing.confidence) {\n best.set(match.filePath, match);\n }\n }\n\n return [...best.values()].map(m => ({\n filePath: m.filePath,\n layerName: m.layerName,\n confidence: m.confidence,\n matchedPattern: m.matchedPattern,\n }));\n}\n\n/**\n * From a list of FileLayerAssignment, derive the unique ArchLayer records.\n */\nexport function buildArchLayers(\n assignments: FileLayerAssignment[],\n configLayers?: Record<string, string[]>\n): ArchLayer[] {\n const layerMap = new Map<string, ArchLayer>();\n\n for (const a of assignments) {\n if (!layerMap.has(a.layerName)) {\n const isConfig = configLayers && a.layerName in configLayers;\n layerMap.set(a.layerName, {\n id: `layer:${a.layerName}`,\n name: a.layerName,\n source: isConfig ? 'config' : 'auto',\n patterns: [],\n updatedAt: Date.now(),\n });\n }\n const layer = layerMap.get(a.layerName)!;\n if (!layer.patterns.includes(a.matchedPattern)) {\n layer.patterns.push(a.matchedPattern);\n }\n }\n\n return [...layerMap.values()];\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,wBAAwC;AACxC,oBAAoC;AACpC,gBAAgC;AAChC,kBAAkC;AAClC,kBAAkC;AAClC,kBAAkC;AAClC,oBAAoC;AACpC,oBAAoC;AACpC,mBAAmC;AACnC,iBAAiC;AACjC,sBAAsC;AACtC,mBAAmC;
|
|
4
|
+
"sourcesContent": ["/**\n * Layer Detector Registry\n *\n * Dispatches layer detection to language-specific detectors.\n * Config-defined layers always win over auto-detection.\n */\nimport type { LayerDetector, ArchLayerMatch, ArchLayer } from '../types';\nimport { typescriptLayerDetector } from './typescript';\nimport { pythonLayerDetector } from './python';\nimport { goLayerDetector } from './go';\nimport { javaLayerDetector } from './java';\nimport { rubyLayerDetector } from './ruby';\nimport { rustLayerDetector } from './rust';\nimport { csharpLayerDetector } from './csharp';\nimport { elixirLayerDetector } from './elixir';\nimport { scalaLayerDetector } from './scala';\nimport { vueLayerDetector } from './vue';\nimport { solidityLayerDetector } from './solidity';\nimport { ocamlLayerDetector } from './ocaml';\nimport { dartLayerDetector } from './dart';\n\nconst LAYER_DETECTORS: LayerDetector[] = [\n typescriptLayerDetector,\n pythonLayerDetector,\n goLayerDetector,\n javaLayerDetector,\n rubyLayerDetector,\n rustLayerDetector,\n csharpLayerDetector,\n elixirLayerDetector,\n scalaLayerDetector,\n vueLayerDetector,\n solidityLayerDetector,\n ocamlLayerDetector,\n dartLayerDetector,\n];\n\nexport function getAllLayerDetectors(): LayerDetector[] {\n return LAYER_DETECTORS;\n}\n\nexport function registerLayerDetector(detector: LayerDetector): void {\n const idx = LAYER_DETECTORS.findIndex(d => d.language === detector.language && d.framework === detector.framework);\n if (idx >= 0) LAYER_DETECTORS[idx] = detector;\n else LAYER_DETECTORS.push(detector);\n}\n\nexport interface FileLayerAssignment {\n filePath: string;\n layerName: string;\n confidence: number;\n matchedPattern: string;\n}\n\n/**\n * Run all language-specific layer detectors against the file list.\n * Each file gets at most one layer assignment (highest confidence wins).\n * Config-defined layers (confidence=1.0) always beat auto-detected ones.\n *\n * @param files - relative file paths (from project root)\n * @param projectRoot - absolute project root path\n * @param configLayers - user-defined layer\u2192glob overrides from config\n */\nexport async function detectAllLayers(\n files: string[],\n projectRoot: string,\n configLayers?: Record<string, string[]>\n): Promise<FileLayerAssignment[]> {\n // Collect all matches from all detectors\n const allMatches: ArchLayerMatch[] = [];\n for (const detector of LAYER_DETECTORS) {\n const matches = await detector.detect(files, projectRoot, configLayers);\n allMatches.push(...matches);\n }\n\n // Per file, keep the highest-confidence match\n const best = new Map<string, ArchLayerMatch>();\n for (const match of allMatches) {\n const existing = best.get(match.filePath);\n if (!existing || match.confidence > existing.confidence) {\n best.set(match.filePath, match);\n }\n }\n\n return [...best.values()].map(m => ({\n filePath: m.filePath,\n layerName: m.layerName,\n confidence: m.confidence,\n matchedPattern: m.matchedPattern,\n }));\n}\n\n/**\n * From a list of FileLayerAssignment, derive the unique ArchLayer records.\n */\nexport function buildArchLayers(\n assignments: FileLayerAssignment[],\n configLayers?: Record<string, string[]>\n): ArchLayer[] {\n const layerMap = new Map<string, ArchLayer>();\n\n for (const a of assignments) {\n if (!layerMap.has(a.layerName)) {\n const isConfig = configLayers && a.layerName in configLayers;\n layerMap.set(a.layerName, {\n id: `layer:${a.layerName}`,\n name: a.layerName,\n source: isConfig ? 'config' : 'auto',\n patterns: [],\n updatedAt: Date.now(),\n });\n }\n const layer = layerMap.get(a.layerName)!;\n if (!layer.patterns.includes(a.matchedPattern)) {\n layer.patterns.push(a.matchedPattern);\n }\n }\n\n return [...layerMap.values()];\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,wBAAwC;AACxC,oBAAoC;AACpC,gBAAgC;AAChC,kBAAkC;AAClC,kBAAkC;AAClC,kBAAkC;AAClC,oBAAoC;AACpC,oBAAoC;AACpC,mBAAmC;AACnC,iBAAiC;AACjC,sBAAsC;AACtC,mBAAmC;AACnC,kBAAkC;AAElC,MAAM,kBAAmC;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,SAAS,uBAAwC;AACtD,SAAO;AACT;AAEO,SAAS,sBAAsB,UAA+B;AACnE,QAAM,MAAM,gBAAgB,UAAU,OAAK,EAAE,aAAa,SAAS,YAAY,EAAE,cAAc,SAAS,SAAS;AACjH,MAAI,OAAO,EAAG,iBAAgB,GAAG,IAAI;AAAA,MAChC,iBAAgB,KAAK,QAAQ;AACpC;AAkBA,eAAsB,gBACpB,OACA,aACA,cACgC;AAEhC,QAAM,aAA+B,CAAC;AACtC,aAAW,YAAY,iBAAiB;AACtC,UAAM,UAAU,MAAM,SAAS,OAAO,OAAO,aAAa,YAAY;AACtE,eAAW,KAAK,GAAG,OAAO;AAAA,EAC5B;AAGA,QAAM,OAAO,oBAAI,IAA4B;AAC7C,aAAW,SAAS,YAAY;AAC9B,UAAM,WAAW,KAAK,IAAI,MAAM,QAAQ;AACxC,QAAI,CAAC,YAAY,MAAM,aAAa,SAAS,YAAY;AACvD,WAAK,IAAI,MAAM,UAAU,KAAK;AAAA,IAChC;AAAA,EACF;AAEA,SAAO,CAAC,GAAG,KAAK,OAAO,CAAC,EAAE,IAAI,QAAM;AAAA,IAClC,UAAU,EAAE;AAAA,IACZ,WAAW,EAAE;AAAA,IACb,YAAY,EAAE;AAAA,IACd,gBAAgB,EAAE;AAAA,EACpB,EAAE;AACJ;AAKO,SAAS,gBACd,aACA,cACa;AACb,QAAM,WAAW,oBAAI,IAAuB;AAE5C,aAAW,KAAK,aAAa;AAC3B,QAAI,CAAC,SAAS,IAAI,EAAE,SAAS,GAAG;AAC9B,YAAM,WAAW,gBAAgB,EAAE,aAAa;AAChD,eAAS,IAAI,EAAE,WAAW;AAAA,QACxB,IAAI,SAAS,EAAE,SAAS;AAAA,QACxB,MAAM,EAAE;AAAA,QACR,QAAQ,WAAW,WAAW;AAAA,QAC9B,UAAU,CAAC;AAAA,QACX,WAAW,KAAK,IAAI;AAAA,MACtB,CAAC;AAAA,IACH;AACA,UAAM,QAAQ,SAAS,IAAI,EAAE,SAAS;AACtC,QAAI,CAAC,MAAM,SAAS,SAAS,EAAE,cAAc,GAAG;AAC9C,YAAM,SAAS,KAAK,EAAE,cAAc;AAAA,IACtC;AAAA,EACF;AAEA,SAAO,CAAC,GAAG,SAAS,OAAO,CAAC;AAC9B;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/bin/banner.js
CHANGED
|
@@ -33,6 +33,7 @@ const c = {
|
|
|
33
33
|
white: "\x1B[97m"
|
|
34
34
|
};
|
|
35
35
|
const TIPS = [
|
|
36
|
+
// Core graph
|
|
36
37
|
`Run ${c.cyan}kirograph context "your task"${c.reset} to get relevant code
|
|
37
38
|
in one shot \u2014 no file scanning needed.`,
|
|
38
39
|
`Use ${c.cyan}kirograph query <name>${c.reset} instead of grep.
|
|
@@ -41,14 +42,81 @@ const TIPS = [
|
|
|
41
42
|
that depends on a changed file \u2014 great for CI.`,
|
|
42
43
|
`${c.cyan}kirograph files --format grouped${c.reset} shows your project
|
|
43
44
|
structure grouped by language from the index.`,
|
|
44
|
-
`${c.cyan}kirograph
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
`${c.cyan}kirograph path LoginController DatabasePool${c.reset}
|
|
46
|
+
finds the shortest connection between any two symbols.`,
|
|
47
|
+
`${c.cyan}kirograph hotspots${c.reset} ranks symbols by edge degree \u2014
|
|
48
|
+
the top results are the riskiest to change.`,
|
|
49
|
+
`${c.cyan}kirograph surprising${c.reset} surfaces hidden cross-module coupling
|
|
50
|
+
you didn't know existed.`,
|
|
51
|
+
`${c.cyan}kirograph dead-code${c.reset} lists unexported symbols with zero
|
|
52
|
+
incoming references \u2014 safe candidates for deletion.`,
|
|
53
|
+
`${c.cyan}kirograph snapshot save pre-refactor${c.reset} then
|
|
54
|
+
${c.cyan}kirograph snapshot diff pre-refactor${c.reset} after \u2014 structural changelog.`,
|
|
55
|
+
`Pipe git diff into kirograph:
|
|
56
|
+
${c.cyan}git diff --name-only | kirograph affected --stdin${c.reset}`,
|
|
57
|
+
// Indexing
|
|
48
58
|
`${c.cyan}kirograph sync${c.reset} is incremental \u2014 it only re-parses
|
|
49
59
|
files whose content has changed since last index.`,
|
|
50
|
-
|
|
51
|
-
|
|
60
|
+
`${c.cyan}kirograph sync-if-dirty${c.reset} is safe to call on every agent stop \u2014
|
|
61
|
+
it's a no-op when nothing changed.`,
|
|
62
|
+
`Run ${c.cyan}kirograph install${c.reset} once per workspace to wire up
|
|
63
|
+
MCP, auto-sync hooks, and steering automatically.`,
|
|
64
|
+
// Architecture
|
|
65
|
+
`${c.cyan}kirograph coupling --sort instability${c.reset} shows which packages
|
|
66
|
+
are most volatile and risky to depend on.`,
|
|
67
|
+
`${c.cyan}kirograph architecture${c.reset} detects packages and layers (api/service/
|
|
68
|
+
data/ui/shared) without any config \u2014 just enable it.`,
|
|
69
|
+
`${c.cyan}kirograph package src/auth${c.reset} shows incoming dependents,
|
|
70
|
+
outgoing deps, and files in one call.`,
|
|
71
|
+
// Security
|
|
72
|
+
`${c.cyan}kirograph security${c.reset} gives an instant vulnerability overview \u2014
|
|
73
|
+
dep count, CVEs, verdict breakdown, stale warnings.`,
|
|
74
|
+
`${c.cyan}kirograph vulns --verdict affected${c.reset} filters to only CVEs
|
|
75
|
+
with a confirmed reachable call path from your entry points.`,
|
|
76
|
+
`${c.cyan}kirograph vulns --epss 0.5${c.reset} shows only vulnerabilities
|
|
77
|
+
with >= 50% exploitation probability \u2014 EPSS beats CVSS for triage.`,
|
|
78
|
+
`${c.cyan}kirograph reachability CVE-2024-1234${c.reset} shows the exact
|
|
79
|
+
call path from your entry points to the vulnerable dependency.`,
|
|
80
|
+
`${c.cyan}kirograph licenses --policy${c.reset} flags dependencies that violate
|
|
81
|
+
your configured SPDX license policy (deny/warn lists).`,
|
|
82
|
+
`${c.cyan}kirograph staleness --threshold 0.7${c.reset} identifies dependencies
|
|
83
|
+
that are significantly behind their latest published version.`,
|
|
84
|
+
`${c.cyan}kirograph sbom --output sbom.json${c.reset} exports a CycloneDX 1.5
|
|
85
|
+
SBOM \u2014 parent directory is created automatically if missing.`,
|
|
86
|
+
`${c.cyan}kirograph vex --output vex.json${c.reset} exports a VEX document
|
|
87
|
+
with reachability-derived analysis states for each CVE.`,
|
|
88
|
+
// Memory
|
|
89
|
+
`${c.cyan}kirograph mem search "auth decision"${c.reset} recalls past observations
|
|
90
|
+
using hybrid FTS + vector search across all sessions.`,
|
|
91
|
+
`${c.cyan}kirograph mem store "..." --kind decision${c.reset} saves an observation
|
|
92
|
+
linked to relevant code symbols automatically.`,
|
|
93
|
+
`${c.cyan}kirograph mem timeline${c.reset} shows recent sessions and what
|
|
94
|
+
the agent observed \u2014 great for onboarding after a break.`,
|
|
95
|
+
// Docs & Data
|
|
96
|
+
`${c.cyan}kirograph docs search "authentication"${c.reset} searches indexed
|
|
97
|
+
documentation sections \u2014 faster than reading full files.`,
|
|
98
|
+
`${c.cyan}kirograph data describe orders${c.reset} gives full schema profile
|
|
99
|
+
without loading a single data row into context.`,
|
|
100
|
+
`${c.cyan}kirograph data aggregate orders --group-by region --metric sum:amount${c.reset}
|
|
101
|
+
runs GROUP BY server-side \u2014 only results enter context.`,
|
|
102
|
+
// Export & token tools
|
|
103
|
+
`${c.cyan}kirograph export start${c.reset} opens an interactive graph dashboard
|
|
104
|
+
in your browser \u2014 search, path-find, cluster, heat map.`,
|
|
105
|
+
`${c.cyan}kirograph exec "npm test"${c.reset} compresses test output by 80-90% \u2014
|
|
106
|
+
you get pass/fail and errors, not thousands of lines of noise.`,
|
|
107
|
+
`${c.cyan}kirograph gain --graph${c.reset} shows your cumulative token savings
|
|
108
|
+
from graph tools and shell compression over time.`,
|
|
109
|
+
// Workflow files
|
|
110
|
+
`Type ${c.cyan}/kirograph-security${c.reset} in Kiro to activate a step-by-step
|
|
111
|
+
security audit workflow with CVE triage and EPSS guidance.`,
|
|
112
|
+
`Type ${c.cyan}/kirograph-review${c.reset} in Kiro for a structured code review:
|
|
113
|
+
blast radius, test coverage, surprising coupling.`,
|
|
114
|
+
`Type ${c.cyan}/kirograph-refactor${c.reset} in Kiro before any major refactor \u2014
|
|
115
|
+
it guides you through blast radius, rename preview, and diff verify.`,
|
|
116
|
+
`Type ${c.cyan}/kirograph-debug${c.reset} in Kiro to trace a bug systematically:
|
|
117
|
+
callers, callees, recent diff, root cause analysis.`,
|
|
118
|
+
`Type ${c.cyan}/kirograph-architecture${c.reset} in Kiro for a full architecture
|
|
119
|
+
exploration: packages, layers, coupling, hidden cycles.`
|
|
52
120
|
];
|
|
53
121
|
function pickTip() {
|
|
54
122
|
const idx = Math.floor(Date.now() / 864e5) % TIPS.length;
|
package/dist/bin/banner.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/bin/banner.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * KiroGraph CLI Banner\n * Displays the KIROGRAPH ASCII art header and a rotating \"Did you know?\" tip.\n */\n\n// eslint-disable-next-line @typescript-eslint/no-require-imports\nconst figlet = require('figlet');\n\n// ANSI color helpers (no external deps)\nconst c = {\n reset: '\\x1b[0m',\n bold: '\\x1b[1m',\n dim: '\\x1b[2m',\n purple: '\\x1b[38;5;135m',\n violet: '\\x1b[38;5;99m',\n cyan: '\\x1b[38;5;117m',\n gray: '\\x1b[90m',\n white: '\\x1b[97m',\n};\n\nconst TIPS = [\n `Run ${c.cyan}kirograph context \"your task\"${c.reset} to get relevant code\\n in one shot \u2014 no file scanning needed.`,\n `Use ${c.cyan}kirograph query <name>${c.reset} instead of grep.\\n It searches the symbol index instantly.`,\n `${c.cyan}kirograph affected src/foo.ts${c.reset} finds every test file\\n that depends on a changed file \u2014 great for CI.`,\n `${c.cyan}kirograph files --format grouped${c.reset} shows your project\\n structure grouped by language from the index.`,\n `${c.cyan}kirograph
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,MAAM,SAAS,QAAQ,QAAQ;AAG/B,MAAM,IAAI;AAAA,EACR,OAAQ;AAAA,EACR,MAAQ;AAAA,EACR,KAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,MAAQ;AAAA,EACR,MAAQ;AAAA,EACR,OAAQ;AACV;AAEA,MAAM,OAAO;AAAA,
|
|
4
|
+
"sourcesContent": ["/**\n * KiroGraph CLI Banner\n * Displays the KIROGRAPH ASCII art header and a rotating \"Did you know?\" tip.\n */\n\n// eslint-disable-next-line @typescript-eslint/no-require-imports\nconst figlet = require('figlet');\n\n// ANSI color helpers (no external deps)\nconst c = {\n reset: '\\x1b[0m',\n bold: '\\x1b[1m',\n dim: '\\x1b[2m',\n purple: '\\x1b[38;5;135m',\n violet: '\\x1b[38;5;99m',\n cyan: '\\x1b[38;5;117m',\n gray: '\\x1b[90m',\n white: '\\x1b[97m',\n};\n\nconst TIPS = [\n // Core graph\n `Run ${c.cyan}kirograph context \"your task\"${c.reset} to get relevant code\\n in one shot \u2014 no file scanning needed.`,\n `Use ${c.cyan}kirograph query <name>${c.reset} instead of grep.\\n It searches the symbol index instantly.`,\n `${c.cyan}kirograph affected src/foo.ts${c.reset} finds every test file\\n that depends on a changed file \u2014 great for CI.`,\n `${c.cyan}kirograph files --format grouped${c.reset} shows your project\\n structure grouped by language from the index.`,\n `${c.cyan}kirograph path LoginController DatabasePool${c.reset}\\n finds the shortest connection between any two symbols.`,\n `${c.cyan}kirograph hotspots${c.reset} ranks symbols by edge degree \u2014\\n the top results are the riskiest to change.`,\n `${c.cyan}kirograph surprising${c.reset} surfaces hidden cross-module coupling\\n you didn't know existed.`,\n `${c.cyan}kirograph dead-code${c.reset} lists unexported symbols with zero\\n incoming references \u2014 safe candidates for deletion.`,\n `${c.cyan}kirograph snapshot save pre-refactor${c.reset} then\\n ${c.cyan}kirograph snapshot diff pre-refactor${c.reset} after \u2014 structural changelog.`,\n `Pipe git diff into kirograph:\\n ${c.cyan}git diff --name-only | kirograph affected --stdin${c.reset}`,\n // Indexing\n `${c.cyan}kirograph sync${c.reset} is incremental \u2014 it only re-parses\\n files whose content has changed since last index.`,\n `${c.cyan}kirograph sync-if-dirty${c.reset} is safe to call on every agent stop \u2014\\n it's a no-op when nothing changed.`,\n `Run ${c.cyan}kirograph install${c.reset} once per workspace to wire up\\n MCP, auto-sync hooks, and steering automatically.`,\n // Architecture\n `${c.cyan}kirograph coupling --sort instability${c.reset} shows which packages\\n are most volatile and risky to depend on.`,\n `${c.cyan}kirograph architecture${c.reset} detects packages and layers (api/service/\\n data/ui/shared) without any config \u2014 just enable it.`,\n `${c.cyan}kirograph package src/auth${c.reset} shows incoming dependents,\\n outgoing deps, and files in one call.`,\n // Security\n `${c.cyan}kirograph security${c.reset} gives an instant vulnerability overview \u2014\\n dep count, CVEs, verdict breakdown, stale warnings.`,\n `${c.cyan}kirograph vulns --verdict affected${c.reset} filters to only CVEs\\n with a confirmed reachable call path from your entry points.`,\n `${c.cyan}kirograph vulns --epss 0.5${c.reset} shows only vulnerabilities\\n with >= 50% exploitation probability \u2014 EPSS beats CVSS for triage.`,\n `${c.cyan}kirograph reachability CVE-2024-1234${c.reset} shows the exact\\n call path from your entry points to the vulnerable dependency.`,\n `${c.cyan}kirograph licenses --policy${c.reset} flags dependencies that violate\\n your configured SPDX license policy (deny/warn lists).`,\n `${c.cyan}kirograph staleness --threshold 0.7${c.reset} identifies dependencies\\n that are significantly behind their latest published version.`,\n `${c.cyan}kirograph sbom --output sbom.json${c.reset} exports a CycloneDX 1.5\\n SBOM \u2014 parent directory is created automatically if missing.`,\n `${c.cyan}kirograph vex --output vex.json${c.reset} exports a VEX document\\n with reachability-derived analysis states for each CVE.`,\n // Memory\n `${c.cyan}kirograph mem search \"auth decision\"${c.reset} recalls past observations\\n using hybrid FTS + vector search across all sessions.`,\n `${c.cyan}kirograph mem store \"...\" --kind decision${c.reset} saves an observation\\n linked to relevant code symbols automatically.`,\n `${c.cyan}kirograph mem timeline${c.reset} shows recent sessions and what\\n the agent observed \u2014 great for onboarding after a break.`,\n // Docs & Data\n `${c.cyan}kirograph docs search \"authentication\"${c.reset} searches indexed\\n documentation sections \u2014 faster than reading full files.`,\n `${c.cyan}kirograph data describe orders${c.reset} gives full schema profile\\n without loading a single data row into context.`,\n `${c.cyan}kirograph data aggregate orders --group-by region --metric sum:amount${c.reset}\\n runs GROUP BY server-side \u2014 only results enter context.`,\n // Export & token tools\n `${c.cyan}kirograph export start${c.reset} opens an interactive graph dashboard\\n in your browser \u2014 search, path-find, cluster, heat map.`,\n `${c.cyan}kirograph exec \"npm test\"${c.reset} compresses test output by 80-90% \u2014\\n you get pass/fail and errors, not thousands of lines of noise.`,\n `${c.cyan}kirograph gain --graph${c.reset} shows your cumulative token savings\\n from graph tools and shell compression over time.`,\n // Workflow files\n `Type ${c.cyan}/kirograph-security${c.reset} in Kiro to activate a step-by-step\\n security audit workflow with CVE triage and EPSS guidance.`,\n `Type ${c.cyan}/kirograph-review${c.reset} in Kiro for a structured code review:\\n blast radius, test coverage, surprising coupling.`,\n `Type ${c.cyan}/kirograph-refactor${c.reset} in Kiro before any major refactor \u2014\\n it guides you through blast radius, rename preview, and diff verify.`,\n `Type ${c.cyan}/kirograph-debug${c.reset} in Kiro to trace a bug systematically:\\n callers, callees, recent diff, root cause analysis.`,\n `Type ${c.cyan}/kirograph-architecture${c.reset} in Kiro for a full architecture\\n exploration: packages, layers, coupling, hidden cycles.`,\n];\n\nfunction pickTip(): string {\n // Rotate daily so it feels fresh but is deterministic\n const idx = Math.floor(Date.now() / 86_400_000) % TIPS.length;\n return TIPS[idx];\n}\n\nfunction boxed(text: string, width = 70): string {\n const lines = text.split('\\n');\n const top = `${c.gray}\u250C${'\u2500'.repeat(width - 2)}\u2510${c.reset}`;\n const bottom = `${c.gray}\u2514${'\u2500'.repeat(width - 2)}\u2518${c.reset}`;\n const padded = lines.map(l => {\n // Strip ANSI for length calculation\n const plain = l.replace(/\\x1b\\[[0-9;]*m/g, '');\n const pad = Math.max(0, width - 4 - plain.length);\n return `${c.gray}\u2502${c.reset} ${l}${' '.repeat(pad)} ${c.gray}\u2502${c.reset}`;\n });\n return [top, ...padded, bottom].join('\\n');\n}\n\nexport function printBanner(): void {\n // ASCII art title\n const art: string = figlet.textSync('KIROGRAPH', { font: 'ANSI Shadow' });\n\n // Colorize each line of the art in purple/violet gradient\n const artLines = art.split('\\n');\n const colored = artLines.map((line, i) => {\n const color = i < artLines.length / 2 ? c.purple : c.violet;\n return `${color}${line}${c.reset}`;\n }).join('\\n');\n\n console.log('\\n' + colored);\n\n // Subtitle\n console.log(`${c.dim} Semantic code knowledge graph for Kiro \u2014 100% local${c.reset}`);\n console.log(`${c.dim} Inspired by CodeGraph \u2014 original idea by ${c.reset}${c.violet}github.com/colbymchenry${c.reset}\\n`);\n\n // Did you know box\n const label = `${c.gray}\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 ${c.reset}${c.bold}${c.white}Did you know?${c.reset}${c.gray} \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500${c.reset}`;\n console.log(label);\n console.log(boxed(pickTip()));\n console.log();\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,157 @@
|
|
|
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 attack_surface_exports = {};
|
|
30
|
+
__export(attack_surface_exports, {
|
|
31
|
+
register: () => register
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(attack_surface_exports);
|
|
34
|
+
var path = __toESM(require("path"));
|
|
35
|
+
var import_config = require("../../config");
|
|
36
|
+
var import_ui = require("../ui");
|
|
37
|
+
const red = "\x1B[31m";
|
|
38
|
+
const yellow = "\x1B[33m";
|
|
39
|
+
function register(program) {
|
|
40
|
+
program.command("attack-surface [projectPath]").description("Map HTTP routes to reachable vulnerable dependencies").option("--limit <n>", "Max routes to show (default: 20)", "20").option("--public-only", "Show only public/unauthenticated routes").option("--format <fmt>", "Output format: text, json (default: text)", "text").action(async (projectPath, opts) => {
|
|
41
|
+
const target = path.resolve(projectPath ?? process.cwd());
|
|
42
|
+
const config = await (0, import_config.loadConfig)(target);
|
|
43
|
+
if (!config.enableSecurity) {
|
|
44
|
+
console.error(`
|
|
45
|
+
${yellow}\u26A0 Security analysis is disabled.${import_ui.reset}`);
|
|
46
|
+
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}`);
|
|
47
|
+
console.error(` ${import_ui.dim}Then re-run:${import_ui.reset} ${import_ui.violet}${import_ui.bold}kirograph index${import_ui.reset}
|
|
48
|
+
`);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
const limit = parseInt(opts.limit, 10);
|
|
52
|
+
if (isNaN(limit) || limit < 1) {
|
|
53
|
+
console.error(` \u2716 Invalid --limit value: ${opts.limit}. Must be a positive integer.`);
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
const validFormats = ["text", "json"];
|
|
57
|
+
if (!validFormats.includes(opts.format)) {
|
|
58
|
+
console.error(` \u2716 Invalid --format value: ${opts.format}. Use: text, json`);
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
const KiroGraph = (await Promise.resolve().then(() => require("../../index.js"))).default;
|
|
62
|
+
if (!KiroGraph.isInitialized(target)) {
|
|
63
|
+
console.error(" \u2716 KiroGraph not initialized. Run: kirograph init");
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
const cg = await KiroGraph.open(target);
|
|
67
|
+
const db = cg.getDatabase();
|
|
68
|
+
db.applySecuritySchema();
|
|
69
|
+
const { AttackSurfaceAnalyzer } = await Promise.resolve().then(() => require("../../security/attack-surface.js"));
|
|
70
|
+
const analyzer = new AttackSurfaceAnalyzer(db);
|
|
71
|
+
const result = await analyzer.analyze();
|
|
72
|
+
cg.close();
|
|
73
|
+
let routes = opts.publicOnly ? result.allRoutes.filter((r) => r.exposureLevel === "public") : result.allRoutes;
|
|
74
|
+
const limited = routes.slice(0, limit);
|
|
75
|
+
if (opts.format === "json") {
|
|
76
|
+
console.log(JSON.stringify(
|
|
77
|
+
{
|
|
78
|
+
totalRoutes: result.totalRoutes,
|
|
79
|
+
publicRoutes: result.publicRoutes,
|
|
80
|
+
authenticatedRoutes: result.authenticatedRoutes,
|
|
81
|
+
routesWithVulns: result.routesWithVulns,
|
|
82
|
+
criticalPaths: result.criticalPaths,
|
|
83
|
+
routes: limited
|
|
84
|
+
},
|
|
85
|
+
null,
|
|
86
|
+
2
|
|
87
|
+
));
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const totalLabel = result.totalRoutes === 1 ? "route" : "routes";
|
|
91
|
+
console.log(
|
|
92
|
+
`
|
|
93
|
+
${(0, import_ui.section)("Attack Surface")} ${import_ui.dim}(${result.totalRoutes} ${totalLabel} total: ${result.publicRoutes} public, ${result.authenticatedRoutes} authenticated)${import_ui.reset}
|
|
94
|
+
`
|
|
95
|
+
);
|
|
96
|
+
if (result.criticalPaths.length === 0) {
|
|
97
|
+
console.log(` ${import_ui.dim}No routes reaching vulnerable dependencies found.${import_ui.reset}
|
|
98
|
+
`);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
console.log(` ${import_ui.violet}${import_ui.bold}\u25CF Critical paths${import_ui.reset} ${import_ui.dim}(routes reaching affected vulnerabilities)${import_ui.reset}
|
|
102
|
+
`);
|
|
103
|
+
const criticalToShow = result.criticalPaths.slice(0, limit);
|
|
104
|
+
for (const entry of criticalToShow) {
|
|
105
|
+
printRouteEntry(entry);
|
|
106
|
+
}
|
|
107
|
+
if (!opts.publicOnly) {
|
|
108
|
+
const cleanCount = result.totalRoutes - result.routesWithVulns;
|
|
109
|
+
if (cleanCount > 0) {
|
|
110
|
+
console.log(` ${import_ui.dim}+ ${cleanCount} clean route${cleanCount === 1 ? "" : "s"} (no reachable vulnerabilities)${import_ui.reset}
|
|
111
|
+
`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
function printRouteEntry(entry) {
|
|
117
|
+
const isPublicVuln = entry.exposureLevel === "public" && entry.vulnerableDeps.length > 0;
|
|
118
|
+
const isAuthVuln = (entry.exposureLevel === "authenticated" || entry.exposureLevel === "internal") && entry.vulnerableDeps.length > 0;
|
|
119
|
+
const routeColor = isPublicVuln ? red : isAuthVuln ? yellow : import_ui.dim;
|
|
120
|
+
const riskLabel = entry.riskScore > 0 ? `${entry.riskScore.toFixed(1)}` : "?";
|
|
121
|
+
const exposureBadge = (() => {
|
|
122
|
+
switch (entry.exposureLevel) {
|
|
123
|
+
case "public":
|
|
124
|
+
return `${red}public${import_ui.reset} `;
|
|
125
|
+
case "authenticated":
|
|
126
|
+
return `${yellow}authenticated${import_ui.reset}`;
|
|
127
|
+
case "internal":
|
|
128
|
+
return `${import_ui.dim}internal${import_ui.reset} `;
|
|
129
|
+
default:
|
|
130
|
+
return `${import_ui.dim}unknown${import_ui.reset} `;
|
|
131
|
+
}
|
|
132
|
+
})();
|
|
133
|
+
const topVuln = entry.vulnerableDeps.reduce(
|
|
134
|
+
(best, v) => {
|
|
135
|
+
if (!best) return v;
|
|
136
|
+
if ((v.riskScore ?? 0) > (best.riskScore ?? 0)) return v;
|
|
137
|
+
return best;
|
|
138
|
+
},
|
|
139
|
+
null
|
|
140
|
+
);
|
|
141
|
+
let vulnSuffix = "";
|
|
142
|
+
if (topVuln) {
|
|
143
|
+
const hopWord = topVuln.hopCount === 1 ? "1 hop" : `${topVuln.hopCount} hops`;
|
|
144
|
+
vulnSuffix = ` ${import_ui.dim}\u2192${import_ui.reset} ${import_ui.violet}${topVuln.packageName}${import_ui.reset} ${import_ui.dim}${topVuln.cveId}${import_ui.reset} ${import_ui.dim}(${hopWord})${import_ui.reset}`;
|
|
145
|
+
if (entry.vulnerableDeps.length > 1) {
|
|
146
|
+
vulnSuffix += ` ${import_ui.dim}+${entry.vulnerableDeps.length - 1} more${import_ui.reset}`;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
console.log(
|
|
150
|
+
` ${routeColor}[${riskLabel}]${import_ui.reset} ${import_ui.bold}${entry.route.padEnd(30)}${import_ui.reset} ${exposureBadge}${vulnSuffix}`
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
154
|
+
0 && (module.exports = {
|
|
155
|
+
register
|
|
156
|
+
});
|
|
157
|
+
//# sourceMappingURL=attack-surface.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/bin/commands/attack-surface.ts"],
|
|
4
|
+
"sourcesContent": ["import { Command } from 'commander';\nimport * as path from 'path';\nimport { loadConfig } from '../../config';\nimport { dim, reset, violet, bold, section } from '../ui';\nimport type { AttackSurfaceEntry } from '../../security/attack-surface';\n\nconst red = '\\x1b[31m';\nconst yellow = '\\x1b[33m';\n\nexport function register(program: Command): void {\n program\n .command('attack-surface [projectPath]')\n .description('Map HTTP routes to reachable vulnerable dependencies')\n .option('--limit <n>', 'Max routes to show (default: 20)', '20')\n .option('--public-only', 'Show only public/unauthenticated routes')\n .option('--format <fmt>', 'Output format: text, json (default: text)', 'text')\n .action(async (\n projectPath: string | undefined,\n opts: { limit: string; publicOnly?: boolean; format: string },\n ) => {\n const target = path.resolve(projectPath ?? process.cwd());\n const config = await loadConfig(target);\n\n if (!config.enableSecurity) {\n console.error(`\\n ${yellow}\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 limit = parseInt(opts.limit, 10);\n if (isNaN(limit) || limit < 1) {\n console.error(` \u2716 Invalid --limit value: ${opts.limit}. Must be a positive integer.`);\n process.exit(1);\n }\n\n const validFormats = ['text', 'json'];\n if (!validFormats.includes(opts.format)) {\n console.error(` \u2716 Invalid --format value: ${opts.format}. Use: text, json`);\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 { AttackSurfaceAnalyzer } = await Promise.resolve().then(() => require('../../security/attack-surface.js'));\n const analyzer = new AttackSurfaceAnalyzer(db);\n const result = await analyzer.analyze();\n\n cg.close();\n\n // Apply --public-only filter\n let routes = opts.publicOnly\n ? result.allRoutes.filter(r => r.exposureLevel === 'public')\n : result.allRoutes;\n\n // Apply limit\n const limited = routes.slice(0, limit);\n\n // \u2500\u2500 JSON output \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 if (opts.format === 'json') {\n console.log(JSON.stringify(\n {\n totalRoutes: result.totalRoutes,\n publicRoutes: result.publicRoutes,\n authenticatedRoutes: result.authenticatedRoutes,\n routesWithVulns: result.routesWithVulns,\n criticalPaths: result.criticalPaths,\n routes: limited,\n },\n null,\n 2,\n ));\n return;\n }\n\n // \u2500\u2500 Text output \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 const totalLabel = result.totalRoutes === 1 ? 'route' : 'routes';\n console.log(\n `\\n ${section('Attack Surface')} ` +\n `${dim}(${result.totalRoutes} ${totalLabel} total: ${result.publicRoutes} public, ${result.authenticatedRoutes} authenticated)${reset}\\n`,\n );\n\n if (result.criticalPaths.length === 0) {\n console.log(` ${dim}No routes reaching vulnerable dependencies found.${reset}\\n`);\n return;\n }\n\n // Critical paths section\n console.log(` ${violet}${bold}\u25CF Critical paths${reset} ${dim}(routes reaching affected vulnerabilities)${reset}\\n`);\n\n const criticalToShow = result.criticalPaths.slice(0, limit);\n\n for (const entry of criticalToShow) {\n printRouteEntry(entry);\n }\n\n // If public-only was not set, also show clean routes summary\n if (!opts.publicOnly) {\n const cleanCount = result.totalRoutes - result.routesWithVulns;\n if (cleanCount > 0) {\n console.log(` ${dim}+ ${cleanCount} clean route${cleanCount === 1 ? '' : 's'} (no reachable vulnerabilities)${reset}\\n`);\n }\n }\n });\n}\n\nfunction printRouteEntry(entry: AttackSurfaceEntry): void {\n const isPublicVuln = entry.exposureLevel === 'public' && entry.vulnerableDeps.length > 0;\n const isAuthVuln = (entry.exposureLevel === 'authenticated' || entry.exposureLevel === 'internal') && entry.vulnerableDeps.length > 0;\n\n const routeColor = isPublicVuln ? red : isAuthVuln ? yellow : dim;\n const riskLabel = entry.riskScore > 0 ? `${entry.riskScore.toFixed(1)}` : '?';\n\n // Exposure badge\n const exposureBadge = (() => {\n switch (entry.exposureLevel) {\n case 'public': return `${red}public${reset} `;\n case 'authenticated': return `${yellow}authenticated${reset}`;\n case 'internal': return `${dim}internal${reset} `;\n default: return `${dim}unknown${reset} `;\n }\n })();\n\n // Pick the top vuln by riskScore to show inline\n const topVuln = entry.vulnerableDeps.reduce<AttackSurfaceEntry['vulnerableDeps'][0] | null>(\n (best, v) => {\n if (!best) return v;\n if ((v.riskScore ?? 0) > (best.riskScore ?? 0)) return v;\n return best;\n },\n null,\n );\n\n let vulnSuffix = '';\n if (topVuln) {\n const hopWord = topVuln.hopCount === 1 ? '1 hop' : `${topVuln.hopCount} hops`;\n vulnSuffix = ` ${dim}\u2192${reset} ${violet}${topVuln.packageName}${reset} ${dim}${topVuln.cveId}${reset} ${dim}(${hopWord})${reset}`;\n if (entry.vulnerableDeps.length > 1) {\n vulnSuffix += ` ${dim}+${entry.vulnerableDeps.length - 1} more${reset}`;\n }\n }\n\n console.log(\n ` ${routeColor}[${riskLabel}]${reset} ${bold}${entry.route.padEnd(30)}${reset} ${exposureBadge}${vulnSuffix}`,\n );\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|