kirograph 0.17.0 → 0.20.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 +105 -1822
- package/dist/architecture/layers/dart.d.ts +10 -0
- package/dist/architecture/layers/dart.d.ts.map +1 -0
- package/dist/architecture/layers/dart.js +112 -0
- package/dist/architecture/layers/dart.js.map +7 -0
- package/dist/architecture/layers/elixir.d.ts +6 -0
- package/dist/architecture/layers/elixir.d.ts.map +1 -0
- package/dist/architecture/layers/index.d.ts.map +1 -1
- package/dist/architecture/layers/index.js +3 -1
- package/dist/architecture/layers/index.js.map +2 -2
- package/dist/architecture/layers/ocaml.d.ts +6 -0
- package/dist/architecture/layers/ocaml.d.ts.map +1 -0
- package/dist/architecture/layers/scala.d.ts +6 -0
- package/dist/architecture/layers/scala.d.ts.map +1 -0
- package/dist/architecture/layers/solidity.d.ts +6 -0
- package/dist/architecture/layers/solidity.d.ts.map +1 -0
- package/dist/architecture/layers/vue.d.ts +6 -0
- package/dist/architecture/layers/vue.d.ts.map +1 -0
- package/dist/architecture/manifest/elm.d.ts +3 -0
- package/dist/architecture/manifest/elm.d.ts.map +1 -0
- package/dist/architecture/manifest/index.d.ts.map +1 -1
- package/dist/architecture/manifest/ocaml.d.ts +3 -0
- package/dist/architecture/manifest/ocaml.d.ts.map +1 -0
- package/dist/architecture/manifest/scala.d.ts +3 -0
- package/dist/architecture/manifest/scala.d.ts.map +1 -0
- package/dist/bin/banner.d.ts.map +1 -1
- package/dist/bin/banner.js +74 -6
- package/dist/bin/banner.js.map +2 -2
- package/dist/bin/commands/affected.d.ts.map +1 -1
- package/dist/bin/commands/attack-surface.d.ts +3 -0
- package/dist/bin/commands/attack-surface.d.ts.map +1 -0
- package/dist/bin/commands/attack-surface.js +164 -0
- package/dist/bin/commands/attack-surface.js.map +7 -0
- package/dist/bin/commands/benchmark.d.ts +9 -0
- package/dist/bin/commands/benchmark.d.ts.map +1 -0
- package/dist/bin/commands/benchmark.js +206 -0
- package/dist/bin/commands/benchmark.js.map +7 -0
- package/dist/bin/commands/budget.d.ts +6 -0
- package/dist/bin/commands/budget.d.ts.map +1 -0
- package/dist/bin/commands/budget.js +70 -0
- package/dist/bin/commands/budget.js.map +7 -0
- package/dist/bin/commands/caveman.d.ts +7 -0
- package/dist/bin/commands/caveman.d.ts.map +1 -0
- package/dist/bin/commands/communities.d.ts +3 -0
- package/dist/bin/commands/communities.d.ts.map +1 -0
- package/dist/bin/commands/communities.js +77 -0
- package/dist/bin/commands/communities.js.map +7 -0
- package/dist/bin/commands/compression.d.ts +7 -0
- package/dist/bin/commands/compression.d.ts.map +1 -0
- package/dist/bin/commands/context.d.ts.map +1 -1
- package/dist/bin/commands/data.d.ts +3 -0
- package/dist/bin/commands/data.d.ts.map +1 -0
- package/dist/bin/commands/dead-code.d.ts +3 -0
- package/dist/bin/commands/dead-code.d.ts.map +1 -0
- package/dist/bin/commands/dep-confusion.d.ts +3 -0
- package/dist/bin/commands/dep-confusion.d.ts.map +1 -0
- package/dist/bin/commands/dep-confusion.js +119 -0
- package/dist/bin/commands/dep-confusion.js.map +7 -0
- package/dist/bin/commands/docs.d.ts +3 -0
- package/dist/bin/commands/docs.d.ts.map +1 -0
- package/dist/bin/commands/exec.d.ts +11 -0
- package/dist/bin/commands/exec.d.ts.map +1 -0
- package/dist/bin/commands/export.d.ts +3 -0
- package/dist/bin/commands/export.d.ts.map +1 -0
- package/dist/bin/commands/export.js +304 -10
- package/dist/bin/commands/export.js.map +2 -2
- package/dist/bin/commands/flows.d.ts +3 -0
- package/dist/bin/commands/flows.d.ts.map +1 -0
- package/dist/bin/commands/flows.js +97 -0
- package/dist/bin/commands/flows.js.map +7 -0
- package/dist/bin/commands/gain.d.ts +6 -0
- package/dist/bin/commands/gain.d.ts.map +1 -0
- package/dist/bin/commands/help.d.ts +7 -0
- package/dist/bin/commands/help.d.ts.map +1 -1
- package/dist/bin/commands/help.js +399 -101
- package/dist/bin/commands/help.js.map +2 -2
- package/dist/bin/commands/hotspots.d.ts +3 -0
- package/dist/bin/commands/hotspots.d.ts.map +1 -0
- package/dist/bin/commands/hotspots.js +94 -1
- package/dist/bin/commands/hotspots.js.map +3 -3
- package/dist/bin/commands/install.d.ts.map +1 -1
- package/dist/bin/commands/install.js +90 -8
- package/dist/bin/commands/install.js.map +2 -2
- package/dist/bin/commands/licenses.d.ts +3 -0
- package/dist/bin/commands/licenses.d.ts.map +1 -0
- package/dist/bin/commands/licenses.js +201 -0
- package/dist/bin/commands/licenses.js.map +7 -0
- package/dist/bin/commands/memory.d.ts +16 -0
- package/dist/bin/commands/memory.d.ts.map +1 -0
- package/dist/bin/commands/memory.js +151 -4
- package/dist/bin/commands/memory.js.map +2 -2
- package/dist/bin/commands/path.d.ts +3 -0
- package/dist/bin/commands/path.d.ts.map +1 -0
- package/dist/bin/commands/pattern.d.ts +3 -0
- package/dist/bin/commands/pattern.d.ts.map +1 -0
- package/dist/bin/commands/pattern.js +592 -0
- package/dist/bin/commands/pattern.js.map +7 -0
- package/dist/bin/commands/query.d.ts.map +1 -1
- package/dist/bin/commands/reachability.d.ts +3 -0
- package/dist/bin/commands/reachability.d.ts.map +1 -0
- package/dist/bin/commands/reachability.js +160 -0
- package/dist/bin/commands/reachability.js.map +7 -0
- package/dist/bin/commands/read.d.ts +6 -0
- package/dist/bin/commands/read.d.ts.map +1 -0
- package/dist/bin/commands/read.js +100 -0
- package/dist/bin/commands/read.js.map +7 -0
- package/dist/bin/commands/refactor.d.ts +3 -0
- package/dist/bin/commands/refactor.d.ts.map +1 -0
- package/dist/bin/commands/refactor.js +116 -0
- package/dist/bin/commands/refactor.js.map +7 -0
- package/dist/bin/commands/remediation.d.ts +3 -0
- package/dist/bin/commands/remediation.d.ts.map +1 -0
- package/dist/bin/commands/remediation.js +133 -0
- package/dist/bin/commands/remediation.js.map +7 -0
- package/dist/bin/commands/sbom.d.ts +3 -0
- package/dist/bin/commands/sbom.d.ts.map +1 -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.d.ts +9 -0
- package/dist/bin/commands/security-ci-report.d.ts.map +1 -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.d.ts +2 -0
- package/dist/bin/commands/security-export.d.ts.map +1 -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.d.ts +3 -0
- package/dist/bin/commands/security-flows.d.ts.map +1 -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.d.ts +3 -0
- package/dist/bin/commands/security-secrets.d.ts.map +1 -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.d.ts +3 -0
- package/dist/bin/commands/security.d.ts.map +1 -0
- package/dist/bin/commands/security.js +208 -0
- package/dist/bin/commands/security.js.map +7 -0
- package/dist/bin/commands/snapshot.d.ts +3 -0
- package/dist/bin/commands/snapshot.d.ts.map +1 -0
- package/dist/bin/commands/staleness.d.ts +3 -0
- package/dist/bin/commands/staleness.d.ts.map +1 -0
- package/dist/bin/commands/staleness.js +144 -0
- package/dist/bin/commands/staleness.js.map +7 -0
- package/dist/bin/commands/status.d.ts.map +1 -1
- package/dist/bin/commands/status.js +129 -2
- package/dist/bin/commands/status.js.map +2 -2
- package/dist/bin/commands/supply-chain.d.ts +3 -0
- package/dist/bin/commands/supply-chain.d.ts.map +1 -0
- package/dist/bin/commands/supply-chain.js +138 -0
- package/dist/bin/commands/supply-chain.js.map +7 -0
- package/dist/bin/commands/surprising.d.ts +3 -0
- package/dist/bin/commands/surprising.d.ts.map +1 -0
- package/dist/bin/commands/sync.d.ts.map +1 -1
- package/dist/bin/commands/uninit.d.ts.map +1 -1
- package/dist/bin/commands/uninit.js +109 -60
- package/dist/bin/commands/uninit.js.map +2 -2
- package/dist/bin/commands/utils.d.ts +5 -0
- package/dist/bin/commands/utils.d.ts.map +1 -1
- package/dist/bin/commands/vex.d.ts +3 -0
- package/dist/bin/commands/vex.d.ts.map +1 -0
- package/dist/bin/commands/vex.js +76 -0
- package/dist/bin/commands/vex.js.map +7 -0
- package/dist/bin/commands/vuln-suppress.d.ts +3 -0
- package/dist/bin/commands/vuln-suppress.d.ts.map +1 -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.d.ts +3 -0
- package/dist/bin/commands/vulns.d.ts.map +1 -0
- package/dist/bin/commands/vulns.js +382 -0
- package/dist/bin/commands/vulns.js.map +7 -0
- package/dist/bin/installer/archive.d.ts +47 -0
- package/dist/bin/installer/archive.d.ts.map +1 -0
- package/dist/bin/installer/auto-detect.d.ts +16 -0
- package/dist/bin/installer/auto-detect.d.ts.map +1 -0
- package/dist/bin/installer/auto-detect.js +125 -0
- package/dist/bin/installer/auto-detect.js.map +7 -0
- package/dist/bin/installer/caveman.d.ts +12 -0
- package/dist/bin/installer/caveman.d.ts.map +1 -0
- package/dist/bin/installer/cli-agent.d.ts +7 -2
- package/dist/bin/installer/cli-agent.d.ts.map +1 -1
- package/dist/bin/installer/cli-agent.js +32 -5
- package/dist/bin/installer/cli-agent.js.map +2 -2
- package/dist/bin/installer/common.d.ts +36 -0
- package/dist/bin/installer/common.d.ts.map +1 -0
- package/dist/bin/installer/common.js +48 -0
- package/dist/bin/installer/common.js.map +2 -2
- package/dist/bin/installer/config-prompt.d.ts +1 -1
- package/dist/bin/installer/config-prompt.d.ts.map +1 -1
- package/dist/bin/installer/config-prompt.js +85 -2
- package/dist/bin/installer/config-prompt.js.map +2 -2
- package/dist/bin/installer/dashboard.d.ts.map +1 -1
- package/dist/bin/installer/detect.d.ts +30 -0
- package/dist/bin/installer/detect.d.ts.map +1 -0
- package/dist/bin/installer/detect.js +309 -0
- package/dist/bin/installer/detect.js.map +7 -0
- package/dist/bin/installer/hooks.d.ts +4 -1
- package/dist/bin/installer/hooks.d.ts.map +1 -1
- package/dist/bin/installer/hooks.js +34 -0
- package/dist/bin/installer/hooks.js.map +2 -2
- package/dist/bin/installer/index.d.ts +5 -4
- package/dist/bin/installer/index.d.ts.map +1 -1
- package/dist/bin/installer/index.js +46 -8
- package/dist/bin/installer/index.js.map +2 -2
- package/dist/bin/installer/instructions.d.ts +14 -0
- package/dist/bin/installer/instructions.d.ts.map +1 -0
- package/dist/bin/installer/instructions.js +209 -3
- package/dist/bin/installer/instructions.js.map +2 -2
- package/dist/bin/installer/mcp.d.ts.map +1 -1
- package/dist/bin/installer/prompts.d.ts +17 -0
- package/dist/bin/installer/prompts.d.ts.map +1 -1
- package/dist/bin/installer/qdrant-dashboard.d.ts.map +1 -1
- package/dist/bin/installer/steering.d.ts +14 -2
- package/dist/bin/installer/steering.d.ts.map +1 -1
- package/dist/bin/installer/steering.js +488 -0
- package/dist/bin/installer/steering.js.map +2 -2
- package/dist/bin/installer/targets/aider.d.ts +6 -0
- package/dist/bin/installer/targets/aider.d.ts.map +1 -0
- 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.d.ts +6 -0
- package/dist/bin/installer/targets/amp.d.ts.map +1 -0
- 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.d.ts +13 -0
- package/dist/bin/installer/targets/antigravity.d.ts.map +1 -0
- 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.d.ts +6 -0
- package/dist/bin/installer/targets/augment.d.ts.map +1 -0
- 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.d.ts +6 -0
- package/dist/bin/installer/targets/claude.d.ts.map +1 -0
- 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.d.ts +13 -0
- package/dist/bin/installer/targets/cline.d.ts.map +1 -0
- 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.d.ts +6 -0
- package/dist/bin/installer/targets/codex.d.ts.map +1 -0
- 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.d.ts +12 -0
- package/dist/bin/installer/targets/continue.d.ts.map +1 -0
- 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.d.ts +12 -0
- package/dist/bin/installer/targets/copilot-cli.d.ts.map +1 -0
- 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.d.ts +6 -0
- package/dist/bin/installer/targets/copilot.d.ts.map +1 -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.d.ts +6 -0
- package/dist/bin/installer/targets/cursor.d.ts.map +1 -0
- 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.d.ts +13 -0
- package/dist/bin/installer/targets/devin.d.ts.map +1 -0
- 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.d.ts +16 -0
- package/dist/bin/installer/targets/gemini-cli.d.ts.map +1 -0
- 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.d.ts +59 -0
- package/dist/bin/installer/targets/generic.d.ts.map +1 -0
- 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.d.ts +6 -0
- package/dist/bin/installer/targets/goose.d.ts.map +1 -0
- 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.d.ts +11 -0
- package/dist/bin/installer/targets/index.d.ts.map +1 -0
- 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.d.ts +13 -0
- package/dist/bin/installer/targets/junie.d.ts.map +1 -0
- 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.d.ts +12 -0
- package/dist/bin/installer/targets/kilo.d.ts.map +1 -0
- 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.d.ts +5 -0
- package/dist/bin/installer/targets/kiro.d.ts.map +1 -0
- package/dist/bin/installer/targets/kiro.js +4 -4
- package/dist/bin/installer/targets/kiro.js.map +2 -2
- package/dist/bin/installer/targets/opencode.d.ts +13 -0
- package/dist/bin/installer/targets/opencode.d.ts.map +1 -0
- 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.d.ts +6 -0
- package/dist/bin/installer/targets/openhands.d.ts.map +1 -0
- 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.d.ts +12 -0
- package/dist/bin/installer/targets/qoder.d.ts.map +1 -0
- 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.d.ts +12 -0
- package/dist/bin/installer/targets/qwen.d.ts.map +1 -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.d.ts +6 -0
- package/dist/bin/installer/targets/replit.d.ts.map +1 -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.d.ts +13 -0
- package/dist/bin/installer/targets/roo.d.ts.map +1 -0
- 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.d.ts +6 -0
- package/dist/bin/installer/targets/tabnine.d.ts.map +1 -0
- 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.d.ts +6 -0
- package/dist/bin/installer/targets/trae.d.ts.map +1 -0
- 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.d.ts +12 -0
- package/dist/bin/installer/targets/warp.d.ts.map +1 -0
- 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.d.ts +13 -0
- package/dist/bin/installer/targets/windsurf.d.ts.map +1 -0
- 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.d.ts +16 -1
- package/dist/bin/progress.d.ts.map +1 -1
- package/dist/compression/filters/aws.d.ts +9 -0
- package/dist/compression/filters/aws.d.ts.map +1 -0
- package/dist/compression/filters/docker.d.ts +6 -0
- package/dist/compression/filters/docker.d.ts.map +1 -0
- package/dist/compression/filters/files.d.ts +6 -0
- package/dist/compression/filters/files.d.ts.map +1 -0
- package/dist/compression/filters/generic.d.ts +7 -0
- package/dist/compression/filters/generic.d.ts.map +1 -0
- package/dist/compression/filters/git.d.ts +6 -0
- package/dist/compression/filters/git.d.ts.map +1 -0
- package/dist/compression/filters/github.d.ts +6 -0
- package/dist/compression/filters/github.d.ts.map +1 -0
- package/dist/compression/filters/lint.d.ts +6 -0
- package/dist/compression/filters/lint.d.ts.map +1 -0
- package/dist/compression/filters/misc.d.ts +6 -0
- package/dist/compression/filters/misc.d.ts.map +1 -0
- package/dist/compression/filters/package.d.ts +6 -0
- package/dist/compression/filters/package.d.ts.map +1 -0
- package/dist/compression/filters/test.d.ts +6 -0
- package/dist/compression/filters/test.d.ts.map +1 -0
- package/dist/compression/index.d.ts +29 -0
- package/dist/compression/index.d.ts.map +1 -0
- package/dist/compression/naive-cost.d.ts +26 -0
- package/dist/compression/naive-cost.d.ts.map +1 -0
- package/dist/compression/tracker.d.ts +155 -0
- package/dist/compression/tracker.d.ts.map +1 -0
- package/dist/compression/tracker.js +80 -0
- package/dist/compression/tracker.js.map +2 -2
- package/dist/compression/types.d.ts +49 -0
- package/dist/compression/types.d.ts.map +1 -0
- package/dist/config.d.ts +90 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +144 -3
- package/dist/config.js.map +2 -2
- package/dist/core/lock-manager.d.ts +2 -0
- package/dist/core/lock-manager.d.ts.map +1 -1
- package/dist/core/pipeline.d.ts +4 -1
- package/dist/core/pipeline.d.ts.map +1 -1
- package/dist/core/pipeline.js +78 -2
- package/dist/core/pipeline.js.map +2 -2
- package/dist/core/snapshot.d.ts +58 -0
- package/dist/core/snapshot.d.ts.map +1 -0
- package/dist/data/filters.d.ts +23 -0
- package/dist/data/filters.d.ts.map +1 -0
- package/dist/data/indexer.d.ts +25 -0
- package/dist/data/indexer.d.ts.map +1 -0
- package/dist/data/linker.d.ts +37 -0
- package/dist/data/linker.d.ts.map +1 -0
- package/dist/data/lint.d.ts +27 -0
- package/dist/data/lint.d.ts.map +1 -0
- package/dist/data/parsers/csv.d.ts +11 -0
- package/dist/data/parsers/csv.d.ts.map +1 -0
- package/dist/data/parsers/excel.d.ts +10 -0
- package/dist/data/parsers/excel.d.ts.map +1 -0
- package/dist/data/parsers/index.d.ts +28 -0
- package/dist/data/parsers/index.d.ts.map +1 -0
- package/dist/data/parsers/json-array.d.ts +9 -0
- package/dist/data/parsers/json-array.d.ts.map +1 -0
- package/dist/data/parsers/jsonl.d.ts +9 -0
- package/dist/data/parsers/jsonl.d.ts.map +1 -0
- package/dist/data/parsers/parquet.d.ts +10 -0
- package/dist/data/parsers/parquet.d.ts.map +1 -0
- package/dist/data/profiler.d.ts +29 -0
- package/dist/data/profiler.d.ts.map +1 -0
- package/dist/data/queries.d.ts +95 -0
- package/dist/data/queries.d.ts.map +1 -0
- package/dist/data/types.d.ts +103 -0
- package/dist/data/types.d.ts.map +1 -0
- package/dist/db/database.d.ts +57 -0
- package/dist/db/database.d.ts.map +1 -1
- package/dist/db/database.js +75 -5
- package/dist/db/database.js.map +2 -2
- package/dist/db/memory-schema.sql +5 -1
- package/dist/db/patterns-schema.sql +23 -0
- package/dist/db/schema.sql +3 -1
- package/dist/db/security-schema.sql +72 -0
- package/dist/docs/formats/asciidoc.d.ts +9 -0
- package/dist/docs/formats/asciidoc.d.ts.map +1 -0
- package/dist/docs/formats/html.d.ts +10 -0
- package/dist/docs/formats/html.d.ts.map +1 -0
- package/dist/docs/formats/index.d.ts +31 -0
- package/dist/docs/formats/index.d.ts.map +1 -0
- package/dist/docs/formats/markdown.d.ts +11 -0
- package/dist/docs/formats/markdown.d.ts.map +1 -0
- package/dist/docs/formats/openapi.d.ts +17 -0
- package/dist/docs/formats/openapi.d.ts.map +1 -0
- package/dist/docs/formats/org.d.ts +9 -0
- package/dist/docs/formats/org.d.ts.map +1 -0
- package/dist/docs/formats/plaintext.d.ts +11 -0
- package/dist/docs/formats/plaintext.d.ts.map +1 -0
- package/dist/docs/formats/rdoc.d.ts +10 -0
- package/dist/docs/formats/rdoc.d.ts.map +1 -0
- package/dist/docs/formats/rst.d.ts +11 -0
- package/dist/docs/formats/rst.d.ts.map +1 -0
- package/dist/docs/indexer.d.ts +49 -0
- package/dist/docs/indexer.d.ts.map +1 -0
- package/dist/docs/linker.d.ts +30 -0
- package/dist/docs/linker.d.ts.map +1 -0
- package/dist/docs/lint.d.ts +27 -0
- package/dist/docs/lint.d.ts.map +1 -0
- package/dist/docs/queries.d.ts +78 -0
- package/dist/docs/queries.d.ts.map +1 -0
- package/dist/docs/section-id.d.ts +48 -0
- package/dist/docs/section-id.d.ts.map +1 -0
- package/dist/docs/summarizer.d.ts +13 -0
- package/dist/docs/summarizer.d.ts.map +1 -0
- package/dist/docs/types.d.ts +71 -0
- package/dist/docs/types.d.ts.map +1 -0
- package/dist/docs/vectors.d.ts +54 -0
- package/dist/docs/vectors.d.ts.map +1 -0
- package/dist/extraction/extractor.d.ts +1 -1
- package/dist/extraction/extractor.d.ts.map +1 -1
- package/dist/extraction/extractor.js +81 -0
- package/dist/extraction/extractor.js.map +2 -2
- package/dist/extraction/grammars.d.ts +6 -0
- package/dist/extraction/grammars.d.ts.map +1 -1
- package/dist/extraction/grammars.js +32 -8
- package/dist/extraction/grammars.js.map +2 -2
- package/dist/extraction/languages.d.ts.map +1 -1
- package/dist/extraction/languages.js +43 -1
- package/dist/extraction/languages.js.map +2 -2
- package/dist/extraction/notebook.d.ts +14 -0
- package/dist/extraction/notebook.d.ts.map +1 -0
- 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/amplify.d.ts +9 -0
- package/dist/frameworks/amplify.d.ts.map +1 -0
- package/dist/frameworks/angular.d.ts +9 -0
- package/dist/frameworks/angular.d.ts.map +1 -0
- package/dist/frameworks/ansible.d.ts +8 -0
- package/dist/frameworks/ansible.d.ts.map +1 -0
- package/dist/frameworks/cloudformation.d.ts +9 -0
- package/dist/frameworks/cloudformation.d.ts.map +1 -0
- package/dist/frameworks/docker.d.ts +9 -0
- package/dist/frameworks/docker.d.ts.map +1 -0
- package/dist/frameworks/elixir.d.ts +6 -0
- package/dist/frameworks/elixir.d.ts.map +1 -0
- package/dist/frameworks/flutter.d.ts +12 -0
- package/dist/frameworks/flutter.d.ts.map +1 -0
- package/dist/frameworks/flutter.js +130 -0
- package/dist/frameworks/flutter.js.map +7 -0
- package/dist/frameworks/iac.d.ts +10 -0
- package/dist/frameworks/iac.d.ts.map +1 -0
- package/dist/frameworks/index.d.ts +14 -0
- package/dist/frameworks/index.d.ts.map +1 -1
- package/dist/frameworks/index.js +7 -1
- package/dist/frameworks/index.js.map +3 -3
- package/dist/frameworks/kubernetes.d.ts +9 -0
- package/dist/frameworks/kubernetes.d.ts.map +1 -0
- package/dist/frameworks/pulumi.d.ts +9 -0
- package/dist/frameworks/pulumi.d.ts.map +1 -0
- package/dist/frameworks/scala.d.ts +6 -0
- package/dist/frameworks/scala.d.ts.map +1 -0
- package/dist/frameworks/solidity.d.ts +6 -0
- package/dist/frameworks/solidity.d.ts.map +1 -0
- package/dist/frameworks/terraform.d.ts +14 -0
- package/dist/frameworks/terraform.d.ts.map +1 -0
- package/dist/frameworks/vue.d.ts +7 -0
- package/dist/frameworks/vue.d.ts.map +1 -0
- package/dist/graph/communities.d.ts +43 -0
- package/dist/graph/communities.d.ts.map +1 -0
- package/dist/graph/communities.js +317 -0
- package/dist/graph/communities.js.map +7 -0
- package/dist/graph/flows.d.ts +55 -0
- package/dist/graph/flows.d.ts.map +1 -0
- package/dist/graph/flows.js +138 -0
- package/dist/graph/flows.js.map +7 -0
- package/dist/graph/refactor.d.ts +43 -0
- package/dist/graph/refactor.d.ts.map +1 -0
- package/dist/graph/refactor.js +155 -0
- package/dist/graph/refactor.js.map +7 -0
- package/dist/index.d.ts +36 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +2 -2
- package/dist/mcp/cache.d.ts +69 -0
- package/dist/mcp/cache.d.ts.map +1 -0
- package/dist/mcp/cache.js +172 -0
- package/dist/mcp/cache.js.map +7 -0
- package/dist/mcp/read-modes.d.ts +31 -0
- package/dist/mcp/read-modes.d.ts.map +1 -0
- package/dist/mcp/read-modes.js +295 -0
- package/dist/mcp/read-modes.js.map +7 -0
- package/dist/mcp/server.d.ts +1 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +17 -3
- package/dist/mcp/server.js.map +2 -2
- package/dist/mcp/tool-names.d.ts +2 -0
- package/dist/mcp/tool-names.d.ts.map +1 -0
- package/dist/mcp/tool-names.js +24 -1
- package/dist/mcp/tool-names.js.map +2 -2
- package/dist/mcp/tools.d.ts +12 -0
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +1560 -4
- package/dist/mcp/tools.js.map +3 -3
- package/dist/memory/compress.d.ts +19 -0
- package/dist/memory/compress.d.ts.map +1 -0
- package/dist/memory/database.d.ts +92 -0
- package/dist/memory/database.d.ts.map +1 -0
- package/dist/memory/database.js +70 -2
- package/dist/memory/database.js.map +2 -2
- package/dist/memory/index.d.ts +71 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +12 -2
- package/dist/memory/index.js.map +2 -2
- package/dist/memory/symbols.d.ts +21 -0
- package/dist/memory/symbols.d.ts.map +1 -0
- package/dist/memory/types.d.ts +78 -0
- package/dist/memory/types.d.ts.map +1 -0
- package/dist/memory/types.js.map +1 -1
- package/dist/memory/vectors.d.ts +43 -0
- package/dist/memory/vectors.d.ts.map +1 -0
- package/dist/patterns/graph.d.ts +16 -0
- package/dist/patterns/graph.d.ts.map +1 -0
- package/dist/patterns/graph.js +45 -0
- package/dist/patterns/graph.js.map +7 -0
- package/dist/patterns/index.d.ts +4 -0
- package/dist/patterns/index.d.ts.map +1 -0
- package/dist/patterns/index.js +39 -0
- package/dist/patterns/index.js.map +7 -0
- package/dist/patterns/indexer.d.ts +15 -0
- package/dist/patterns/indexer.d.ts.map +1 -0
- package/dist/patterns/indexer.js +97 -0
- package/dist/patterns/indexer.js.map +7 -0
- package/dist/patterns/library/command-injection-go.yaml +11 -0
- package/dist/patterns/library/dangerous-eval-js.yaml +14 -0
- package/dist/patterns/library/dangerous-exec-py.yaml +13 -0
- package/dist/patterns/library/dangerous-reflection-java.yaml +8 -0
- package/dist/patterns/library/path-traversal-go.yaml +11 -0
- package/dist/patterns/library/path-traversal-py.yaml +12 -0
- package/dist/patterns/library/path-traversal-readfile-js.yaml +14 -0
- package/dist/patterns/library/prototype-pollution-js.yaml +12 -0
- package/dist/patterns/library/sql-injection-concat-js.yaml +12 -0
- package/dist/patterns/library/sql-injection-java.yaml +13 -0
- package/dist/patterns/library/sql-injection-py.yaml +12 -0
- package/dist/patterns/library/sql-injection-template-js.yaml +13 -0
- package/dist/patterns/library/weak-crypto-md5-js.yaml +13 -0
- package/dist/patterns/library/weak-crypto-py.yaml +13 -0
- package/dist/patterns/loader.d.ts +18 -0
- package/dist/patterns/loader.d.ts.map +1 -0
- package/dist/patterns/loader.js +277 -0
- package/dist/patterns/loader.js.map +7 -0
- package/dist/patterns/runner.d.ts +42 -0
- package/dist/patterns/runner.d.ts.map +1 -0
- package/dist/patterns/runner.js +277 -0
- package/dist/patterns/runner.js.map +7 -0
- package/dist/patterns/types.d.ts +27 -0
- package/dist/patterns/types.d.ts.map +1 -0
- package/dist/patterns/types.js +34 -0
- package/dist/patterns/types.js.map +7 -0
- package/dist/resolution/bridges/android-rn.d.ts +13 -0
- package/dist/resolution/bridges/android-rn.d.ts.map +1 -0
- 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.d.ts +10 -0
- package/dist/resolution/bridges/expo-modules.d.ts.map +1 -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.d.ts +14 -0
- package/dist/resolution/bridges/flutter-channel.d.ts.map +1 -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.d.ts +40 -0
- package/dist/resolution/bridges/index.d.ts.map +1 -0
- package/dist/resolution/bridges/index.js +80 -0
- package/dist/resolution/bridges/index.js.map +7 -0
- package/dist/resolution/bridges/native-events.d.ts +10 -0
- package/dist/resolution/bridges/native-events.d.ts.map +1 -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.d.ts +13 -0
- package/dist/resolution/bridges/native-views.d.ts.map +1 -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.d.ts +9 -0
- package/dist/resolution/bridges/react-native.d.ts.map +1 -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.d.ts +14 -0
- package/dist/resolution/bridges/swift-objc.d.ts.map +1 -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.d.ts +10 -0
- package/dist/resolution/bridges/turbomodules.d.ts.map +1 -0
- package/dist/resolution/bridges/turbomodules.js +216 -0
- package/dist/resolution/bridges/turbomodules.js.map +7 -0
- package/dist/resolution/index.d.ts +28 -3
- package/dist/resolution/index.d.ts.map +1 -1
- package/dist/resolution/index.js +61 -2
- package/dist/resolution/index.js.map +2 -2
- package/dist/security/attack-surface.d.ts +46 -0
- package/dist/security/attack-surface.d.ts.map +1 -0
- package/dist/security/attack-surface.js +206 -0
- package/dist/security/attack-surface.js.map +7 -0
- package/dist/security/context-warnings.d.ts +40 -0
- package/dist/security/context-warnings.d.ts.map +1 -0
- package/dist/security/context-warnings.js +123 -0
- package/dist/security/context-warnings.js.map +7 -0
- package/dist/security/data-flows.d.ts +33 -0
- package/dist/security/data-flows.d.ts.map +1 -0
- package/dist/security/data-flows.js +286 -0
- package/dist/security/data-flows.js.map +7 -0
- package/dist/security/dep-confusion.d.ts +23 -0
- package/dist/security/dep-confusion.d.ts.map +1 -0
- package/dist/security/dep-confusion.js +255 -0
- package/dist/security/dep-confusion.js.map +7 -0
- package/dist/security/errors.d.ts +16 -0
- package/dist/security/errors.d.ts.map +1 -0
- package/dist/security/errors.js +51 -0
- package/dist/security/errors.js.map +7 -0
- package/dist/security/export/fix-suggestions.d.ts +21 -0
- package/dist/security/export/fix-suggestions.d.ts.map +1 -0
- package/dist/security/export/fix-suggestions.js +58 -0
- package/dist/security/export/fix-suggestions.js.map +7 -0
- package/dist/security/export/sbom.d.ts +33 -0
- package/dist/security/export/sbom.d.ts.map +1 -0
- package/dist/security/export/sbom.js +230 -0
- package/dist/security/export/sbom.js.map +7 -0
- package/dist/security/export/serialization.d.ts +62 -0
- package/dist/security/export/serialization.d.ts.map +1 -0
- package/dist/security/export/serialization.js +142 -0
- package/dist/security/export/serialization.js.map +7 -0
- package/dist/security/export/vex.d.ts +58 -0
- package/dist/security/export/vex.d.ts.map +1 -0
- package/dist/security/export/vex.js +220 -0
- package/dist/security/export/vex.js.map +7 -0
- package/dist/security/index.d.ts +21 -0
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +67 -0
- package/dist/security/index.js.map +7 -0
- package/dist/security/integrator.d.ts +63 -0
- package/dist/security/integrator.d.ts.map +1 -0
- package/dist/security/integrator.js +491 -0
- package/dist/security/integrator.js.map +7 -0
- package/dist/security/license.d.ts +33 -0
- package/dist/security/license.d.ts.map +1 -0
- package/dist/security/license.js +70 -0
- package/dist/security/license.js.map +7 -0
- package/dist/security/manifest/adapter.d.ts +92 -0
- package/dist/security/manifest/adapter.d.ts.map +1 -0
- package/dist/security/manifest/adapter.js +243 -0
- package/dist/security/manifest/adapter.js.map +7 -0
- package/dist/security/manifest/parser.d.ts +73 -0
- package/dist/security/manifest/parser.d.ts.map +1 -0
- package/dist/security/manifest/parser.js +376 -0
- package/dist/security/manifest/parser.js.map +7 -0
- package/dist/security/manifest/plugins/cargo.d.ts +11 -0
- package/dist/security/manifest/plugins/cargo.d.ts.map +1 -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/composer.d.ts +11 -0
- package/dist/security/manifest/plugins/composer.d.ts.map +1 -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.d.ts +12 -0
- package/dist/security/manifest/plugins/go.d.ts.map +1 -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/gradle.d.ts +12 -0
- package/dist/security/manifest/plugins/gradle.d.ts.map +1 -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.d.ts +11 -0
- package/dist/security/manifest/plugins/hex.d.ts.map +1 -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.d.ts +11 -0
- package/dist/security/manifest/plugins/maven.d.ts.map +1 -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/npm.d.ts +11 -0
- package/dist/security/manifest/plugins/npm.d.ts.map +1 -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/nuget.d.ts +12 -0
- package/dist/security/manifest/plugins/nuget.d.ts.map +1 -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.d.ts +11 -0
- package/dist/security/manifest/plugins/pip.d.ts.map +1 -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/pubspec.d.ts +11 -0
- package/dist/security/manifest/plugins/pubspec.d.ts.map +1 -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.d.ts +3 -0
- package/dist/security/manifest/plugins/pyproject.d.ts.map +1 -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.d.ts +11 -0
- package/dist/security/manifest/plugins/rubygems.d.ts.map +1 -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.d.ts +11 -0
- package/dist/security/manifest/plugins/swift.d.ts.map +1 -0
- package/dist/security/manifest/plugins/swift.js +200 -0
- package/dist/security/manifest/plugins/swift.js.map +7 -0
- package/dist/security/owasp.d.ts +16 -0
- package/dist/security/owasp.d.ts.map +1 -0
- package/dist/security/owasp.js +104 -0
- package/dist/security/owasp.js.map +7 -0
- package/dist/security/pipeline.d.ts +37 -0
- package/dist/security/pipeline.d.ts.map +1 -0
- package/dist/security/pipeline.js +125 -0
- package/dist/security/pipeline.js.map +7 -0
- package/dist/security/reachability.d.ts +67 -0
- package/dist/security/reachability.d.ts.map +1 -0
- package/dist/security/reachability.js +276 -0
- package/dist/security/reachability.js.map +7 -0
- package/dist/security/remediation.d.ts +51 -0
- package/dist/security/remediation.d.ts.map +1 -0
- package/dist/security/remediation.js +126 -0
- package/dist/security/remediation.js.map +7 -0
- package/dist/security/secrets.d.ts +38 -0
- package/dist/security/secrets.d.ts.map +1 -0
- package/dist/security/secrets.js +176 -0
- package/dist/security/secrets.js.map +7 -0
- package/dist/security/staleness.d.ts +43 -0
- package/dist/security/staleness.d.ts.map +1 -0
- package/dist/security/staleness.js +231 -0
- package/dist/security/staleness.js.map +7 -0
- package/dist/security/supply-chain.d.ts +34 -0
- package/dist/security/supply-chain.d.ts.map +1 -0
- package/dist/security/supply-chain.js +301 -0
- package/dist/security/supply-chain.js.map +7 -0
- package/dist/security/suppressions.d.ts +18 -0
- package/dist/security/suppressions.d.ts.map +1 -0
- package/dist/security/suppressions.js +106 -0
- package/dist/security/suppressions.js.map +7 -0
- package/dist/security/types.d.ts +144 -0
- package/dist/security/types.d.ts.map +1 -0
- package/dist/security/types.js +17 -0
- package/dist/security/types.js.map +7 -0
- package/dist/security/vuln/client.d.ts +90 -0
- package/dist/security/vuln/client.d.ts.map +1 -0
- package/dist/security/vuln/client.js +355 -0
- package/dist/security/vuln/client.js.map +7 -0
- package/dist/security/vuln/epss-client.d.ts +26 -0
- package/dist/security/vuln/epss-client.d.ts.map +1 -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.d.ts +6 -0
- package/dist/security/vuln/index.d.ts.map +1 -0
- package/dist/security/vuln/index.js +29 -0
- package/dist/security/vuln/index.js.map +7 -0
- package/dist/security/vuln/osv-adapter.d.ts +58 -0
- package/dist/security/vuln/osv-adapter.d.ts.map +1 -0
- package/dist/security/vuln/osv-adapter.js +321 -0
- package/dist/security/vuln/osv-adapter.js.map +7 -0
- package/dist/security/vuln/types.d.ts +29 -0
- package/dist/security/vuln/types.d.ts.map +1 -0
- package/dist/security/vuln/types.js +17 -0
- package/dist/security/vuln/types.js.map +7 -0
- package/dist/sync/index.d.ts +4 -2
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/types.d.ts +10 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +2 -2
- package/dist/vectors/index.d.ts +11 -3
- package/dist/vectors/index.d.ts.map +1 -1
- package/dist/vectors/qdrant-index.d.ts +10 -3
- package/dist/vectors/qdrant-index.d.ts.map +1 -1
- package/dist/vectors/typesense-index.d.ts.map +1 -1
- package/dist/watchmen/index.js +83 -0
- package/dist/watchmen/index.js.map +7 -0
- package/dist/watchmen/synthesize.js +475 -0
- package/dist/watchmen/synthesize.js.map +7 -0
- package/package.json +6 -2
|
@@ -0,0 +1,176 @@
|
|
|
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 secrets_exports = {};
|
|
30
|
+
__export(secrets_exports, {
|
|
31
|
+
SecretsScanner: () => SecretsScanner
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(secrets_exports);
|
|
34
|
+
var fs = __toESM(require("fs"));
|
|
35
|
+
var path = __toESM(require("path"));
|
|
36
|
+
const SECRET_PATTERNS = [
|
|
37
|
+
{ name: "AWS Access Key ID", severity: "critical", pattern: /AKIA[0-9A-Z]{16}/ },
|
|
38
|
+
{ name: "AWS Secret Access Key", severity: "critical", pattern: /aws[_\-]secret[_\-]?(access[_\-]?)?key\s*[=:]\s*["']?([A-Za-z0-9\/+=]{40})["']?/i },
|
|
39
|
+
{ name: "GitHub Token", severity: "critical", pattern: /gh[pousr]_[A-Za-z0-9]{36,}/ },
|
|
40
|
+
{ name: "Stripe Secret Key", severity: "critical", pattern: /sk_(live|test)_[A-Za-z0-9]{24,}/ },
|
|
41
|
+
{ name: "Stripe Publishable Key", severity: "high", pattern: /pk_(live|test)_[A-Za-z0-9]{24,}/ },
|
|
42
|
+
{ name: "SendGrid API Key", severity: "critical", pattern: /SG\.[A-Za-z0-9_\-]{22}\.[A-Za-z0-9_\-]{43}/ },
|
|
43
|
+
{ name: "Twilio Account SID", severity: "high", pattern: /AC[a-z0-9]{32}/ },
|
|
44
|
+
{ name: "Slack Token", severity: "high", pattern: /xox[baprs]-[A-Za-z0-9-]{10,}/ },
|
|
45
|
+
{ name: "Private Key (PEM)", severity: "critical", pattern: /-----BEGIN (RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/ },
|
|
46
|
+
{ name: "JWT Token (hardcoded)", severity: "high", pattern: /eyJ[A-Za-z0-9+\/]{20,}\.[A-Za-z0-9+\/]{20,}\.[A-Za-z0-9+\/\-_]{20,}/ },
|
|
47
|
+
{ name: "Generic API Key", severity: "medium", pattern: /api[_\-]?key\s*[=:]\s*["']([A-Za-z0-9_\-]{20,})["']/i },
|
|
48
|
+
{ name: "Generic Secret", severity: "medium", pattern: /(?:secret|password|passwd|pwd)\s*[=:]\s*["']([^"'\s]{8,})["']/i },
|
|
49
|
+
{ name: "Bearer Token", severity: "medium", pattern: /bearer\s+[A-Za-z0-9+\/=]{20,}/i },
|
|
50
|
+
{ name: "Database URL", severity: "high", pattern: /(postgres|mysql|mongodb|redis):\/\/[^:]+:[^@]+@[^\/\s]+/ }
|
|
51
|
+
];
|
|
52
|
+
const SKIP_DIRS = ["node_modules", ".kirograph", "dist", "build"];
|
|
53
|
+
const TEST_PATTERNS = [
|
|
54
|
+
/\.test\.[tj]sx?$/,
|
|
55
|
+
/\.spec\.[tj]sx?$/,
|
|
56
|
+
/\/__tests__\//,
|
|
57
|
+
/\/test\//,
|
|
58
|
+
/\/tests\//
|
|
59
|
+
];
|
|
60
|
+
function isTestFile(filePath) {
|
|
61
|
+
return TEST_PATTERNS.some((p) => p.test(filePath));
|
|
62
|
+
}
|
|
63
|
+
function shouldSkipPath(filePath) {
|
|
64
|
+
const parts = filePath.split(path.sep);
|
|
65
|
+
return parts.some((p) => SKIP_DIRS.includes(p));
|
|
66
|
+
}
|
|
67
|
+
function redact(value) {
|
|
68
|
+
if (value.length <= 4) return value + "****";
|
|
69
|
+
return value.slice(0, 4) + "****";
|
|
70
|
+
}
|
|
71
|
+
class SecretsScanner {
|
|
72
|
+
constructor(db, projectRoot) {
|
|
73
|
+
this.db = db;
|
|
74
|
+
this.projectRoot = projectRoot;
|
|
75
|
+
}
|
|
76
|
+
async scan(options) {
|
|
77
|
+
const rawDb = this.db.getRawDb();
|
|
78
|
+
const includeTests = options?.includeTests ?? false;
|
|
79
|
+
const fileRows = rawDb.all(`SELECT path FROM files`);
|
|
80
|
+
const findings = [];
|
|
81
|
+
let filesScanned = 0;
|
|
82
|
+
for (const { path: relOrAbsPath } of fileRows) {
|
|
83
|
+
const absPath = path.isAbsolute(relOrAbsPath) ? relOrAbsPath : path.join(this.projectRoot, relOrAbsPath);
|
|
84
|
+
if (shouldSkipPath(absPath)) continue;
|
|
85
|
+
if (!includeTests && isTestFile(absPath)) continue;
|
|
86
|
+
let content;
|
|
87
|
+
try {
|
|
88
|
+
content = fs.readFileSync(absPath, "utf8");
|
|
89
|
+
} catch {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
filesScanned++;
|
|
93
|
+
const lines = content.split("\n");
|
|
94
|
+
for (let lineIdx = 0; lineIdx < lines.length; lineIdx++) {
|
|
95
|
+
const lineText = lines[lineIdx];
|
|
96
|
+
const lineNumber = lineIdx + 1;
|
|
97
|
+
for (const { name, severity, pattern } of SECRET_PATTERNS) {
|
|
98
|
+
const re = new RegExp(pattern.source, pattern.flags.includes("g") ? pattern.flags : pattern.flags + "g");
|
|
99
|
+
let match;
|
|
100
|
+
while ((match = re.exec(lineText)) !== null) {
|
|
101
|
+
const matchedValue = match[0];
|
|
102
|
+
const column = match.index + 1;
|
|
103
|
+
const { nodeId, nodeName } = this.findContainingNode(rawDb, absPath, lineNumber);
|
|
104
|
+
const entryPoints = nodeId ? this.findEntryPoints(rawDb, nodeId) : [];
|
|
105
|
+
findings.push({
|
|
106
|
+
filePath: absPath,
|
|
107
|
+
line: lineNumber,
|
|
108
|
+
column,
|
|
109
|
+
type: name,
|
|
110
|
+
severity,
|
|
111
|
+
snippet: redact(matchedValue),
|
|
112
|
+
nodeId,
|
|
113
|
+
nodeName,
|
|
114
|
+
reachableFromEntryPoints: entryPoints,
|
|
115
|
+
entryPointCount: entryPoints.length
|
|
116
|
+
});
|
|
117
|
+
if (match[0].length === 0) re.lastIndex++;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
const criticalCount = findings.filter((f) => f.severity === "critical").length;
|
|
123
|
+
const highCount = findings.filter((f) => f.severity === "high").length;
|
|
124
|
+
findings.sort((a, b) => {
|
|
125
|
+
const severityOrder = { critical: 0, high: 1, medium: 2, low: 3 };
|
|
126
|
+
const diff = severityOrder[a.severity] - severityOrder[b.severity];
|
|
127
|
+
if (diff !== 0) return diff;
|
|
128
|
+
if (a.filePath !== b.filePath) return a.filePath.localeCompare(b.filePath);
|
|
129
|
+
return a.line - b.line;
|
|
130
|
+
});
|
|
131
|
+
return {
|
|
132
|
+
findings,
|
|
133
|
+
filesScanned,
|
|
134
|
+
totalFindings: findings.length,
|
|
135
|
+
criticalCount,
|
|
136
|
+
highCount
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
// ── Private helpers ──────────────────────────────────────────────────────────
|
|
140
|
+
findContainingNode(rawDb, filePath, line) {
|
|
141
|
+
const row = rawDb.get(
|
|
142
|
+
`SELECT id, name FROM nodes
|
|
143
|
+
WHERE file_path = ? AND start_line <= ? AND end_line >= ?
|
|
144
|
+
AND kind IN ('function', 'method')
|
|
145
|
+
ORDER BY (end_line - start_line) ASC
|
|
146
|
+
LIMIT 1`,
|
|
147
|
+
[filePath, line, line]
|
|
148
|
+
);
|
|
149
|
+
if (!row) return {};
|
|
150
|
+
return { nodeId: row.id, nodeName: row.name };
|
|
151
|
+
}
|
|
152
|
+
findEntryPoints(rawDb, nodeId) {
|
|
153
|
+
const rows = rawDb.all(
|
|
154
|
+
`WITH RECURSIVE callers(node_id, depth) AS (
|
|
155
|
+
SELECT source, 1 FROM edges WHERE target = ? AND kind = 'calls'
|
|
156
|
+
UNION
|
|
157
|
+
SELECT e.source, c.depth + 1
|
|
158
|
+
FROM edges e
|
|
159
|
+
JOIN callers c ON e.target = c.node_id
|
|
160
|
+
WHERE c.depth < 5 AND e.kind = 'calls'
|
|
161
|
+
)
|
|
162
|
+
SELECT DISTINCT n.id, n.name
|
|
163
|
+
FROM callers c
|
|
164
|
+
JOIN nodes n ON n.id = c.node_id
|
|
165
|
+
WHERE n.kind IN ('route', 'function')
|
|
166
|
+
AND (n.name LIKE '%route%' OR n.name LIKE '%handler%' OR n.name LIKE '%controller%')`,
|
|
167
|
+
[nodeId]
|
|
168
|
+
);
|
|
169
|
+
return rows.map((r) => r.id);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
173
|
+
0 && (module.exports = {
|
|
174
|
+
SecretsScanner
|
|
175
|
+
});
|
|
176
|
+
//# sourceMappingURL=secrets.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/security/secrets.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * KiroGraph-Sec Secrets Scanner\n *\n * Regex-based secret detection that scans source files and enriches findings\n * with call graph context (containing function + reachability from entry points).\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport type { GraphDatabase } from '../db/database';\n\n// \u2500\u2500 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\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface SecretFinding {\n filePath: string;\n line: number;\n column: number;\n type: string;\n severity: 'critical' | 'high' | 'medium' | 'low';\n /** Redacted: first 4 chars of the matched value + \"****\" */\n snippet: string;\n nodeId?: string;\n nodeName?: string;\n reachableFromEntryPoints: string[];\n entryPointCount: number;\n}\n\nexport interface SecretsResult {\n findings: SecretFinding[];\n filesScanned: number;\n totalFindings: number;\n criticalCount: number;\n highCount: number;\n}\n\n// \u2500\u2500 Secret patterns \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 SecretPattern {\n name: string;\n severity: 'critical' | 'high' | 'medium' | 'low';\n pattern: RegExp;\n}\n\nconst SECRET_PATTERNS: SecretPattern[] = [\n { name: 'AWS Access Key ID', severity: 'critical', pattern: /AKIA[0-9A-Z]{16}/ },\n { name: 'AWS Secret Access Key', severity: 'critical', pattern: /aws[_\\-]secret[_\\-]?(access[_\\-]?)?key\\s*[=:]\\s*[\"']?([A-Za-z0-9\\/+=]{40})[\"']?/i },\n { name: 'GitHub Token', severity: 'critical', pattern: /gh[pousr]_[A-Za-z0-9]{36,}/ },\n { name: 'Stripe Secret Key', severity: 'critical', pattern: /sk_(live|test)_[A-Za-z0-9]{24,}/ },\n { name: 'Stripe Publishable Key', severity: 'high', pattern: /pk_(live|test)_[A-Za-z0-9]{24,}/ },\n { name: 'SendGrid API Key', severity: 'critical', pattern: /SG\\.[A-Za-z0-9_\\-]{22}\\.[A-Za-z0-9_\\-]{43}/ },\n { name: 'Twilio Account SID', severity: 'high', pattern: /AC[a-z0-9]{32}/ },\n { name: 'Slack Token', severity: 'high', pattern: /xox[baprs]-[A-Za-z0-9-]{10,}/ },\n { name: 'Private Key (PEM)', severity: 'critical', pattern: /-----BEGIN (RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/ },\n { name: 'JWT Token (hardcoded)', severity: 'high', pattern: /eyJ[A-Za-z0-9+\\/]{20,}\\.[A-Za-z0-9+\\/]{20,}\\.[A-Za-z0-9+\\/\\-_]{20,}/ },\n { name: 'Generic API Key', severity: 'medium', pattern: /api[_\\-]?key\\s*[=:]\\s*[\"']([A-Za-z0-9_\\-]{20,})[\"']/i },\n { name: 'Generic Secret', severity: 'medium', pattern: /(?:secret|password|passwd|pwd)\\s*[=:]\\s*[\"']([^\"'\\s]{8,})[\"']/i },\n { name: 'Bearer Token', severity: 'medium', pattern: /bearer\\s+[A-Za-z0-9+\\/=]{20,}/i },\n { name: 'Database URL', severity: 'high', pattern: /(postgres|mysql|mongodb|redis):\\/\\/[^:]+:[^@]+@[^\\/\\s]+/ },\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\nconst SKIP_DIRS = ['node_modules', '.kirograph', 'dist', 'build'];\nconst TEST_PATTERNS = [\n /\\.test\\.[tj]sx?$/,\n /\\.spec\\.[tj]sx?$/,\n /\\/__tests__\\//,\n /\\/test\\//,\n /\\/tests\\//,\n];\n\nfunction isTestFile(filePath: string): boolean {\n return TEST_PATTERNS.some(p => p.test(filePath));\n}\n\nfunction shouldSkipPath(filePath: string): boolean {\n const parts = filePath.split(path.sep);\n return parts.some(p => SKIP_DIRS.includes(p));\n}\n\n/**\n * Redact a matched string: show only the first 4 characters followed by \"****\".\n * If the match is shorter than 4 chars, show all of it + \"****\".\n */\nfunction redact(value: string): string {\n if (value.length <= 4) return value + '****';\n return value.slice(0, 4) + '****';\n}\n\n// \u2500\u2500 SecretsScanner \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 class SecretsScanner {\n constructor(\n private readonly db: GraphDatabase,\n private readonly projectRoot: string,\n ) {}\n\n async scan(options?: { includeTests?: boolean }): Promise<SecretsResult> {\n const rawDb = this.db.getRawDb();\n const includeTests = options?.includeTests ?? false;\n\n // 1. Collect all indexed files\n const fileRows: Array<{ path: string }> = rawDb.all(`SELECT path FROM files`);\n\n const findings: SecretFinding[] = [];\n let filesScanned = 0;\n\n for (const { path: relOrAbsPath } of fileRows) {\n // Resolve to absolute path\n const absPath = path.isAbsolute(relOrAbsPath)\n ? relOrAbsPath\n : path.join(this.projectRoot, relOrAbsPath);\n\n // Skip paths in blacklisted dirs\n if (shouldSkipPath(absPath)) continue;\n\n // Skip test files unless opted-in\n if (!includeTests && isTestFile(absPath)) continue;\n\n // Read file content\n let content: string;\n try {\n content = fs.readFileSync(absPath, 'utf8');\n } catch {\n // File might have been deleted since indexing \u2014 skip silently\n continue;\n }\n\n filesScanned++;\n const lines = content.split('\\n');\n\n for (let lineIdx = 0; lineIdx < lines.length; lineIdx++) {\n const lineText = lines[lineIdx];\n const lineNumber = lineIdx + 1;\n\n for (const { name, severity, pattern } of SECRET_PATTERNS) {\n // Clone regex to reset lastIndex between calls\n const re = new RegExp(pattern.source, pattern.flags.includes('g') ? pattern.flags : pattern.flags + 'g');\n let match: RegExpExecArray | null;\n\n while ((match = re.exec(lineText)) !== null) {\n const matchedValue = match[0];\n const column = match.index + 1;\n\n // Enrich with graph context\n const { nodeId, nodeName } = this.findContainingNode(rawDb, absPath, lineNumber);\n const entryPoints = nodeId\n ? this.findEntryPoints(rawDb, nodeId)\n : [];\n\n findings.push({\n filePath: absPath,\n line: lineNumber,\n column,\n type: name,\n severity,\n snippet: redact(matchedValue),\n nodeId,\n nodeName,\n reachableFromEntryPoints: entryPoints,\n entryPointCount: entryPoints.length,\n });\n\n // Avoid infinite loops on zero-width matches\n if (match[0].length === 0) re.lastIndex++;\n }\n }\n }\n }\n\n const criticalCount = findings.filter(f => f.severity === 'critical').length;\n const highCount = findings.filter(f => f.severity === 'high').length;\n\n // Sort: critical first, then high, then by file path + line\n findings.sort((a, b) => {\n const severityOrder = { critical: 0, high: 1, medium: 2, low: 3 };\n const diff = severityOrder[a.severity] - severityOrder[b.severity];\n if (diff !== 0) return diff;\n if (a.filePath !== b.filePath) return a.filePath.localeCompare(b.filePath);\n return a.line - b.line;\n });\n\n return {\n findings,\n filesScanned,\n totalFindings: findings.length,\n criticalCount,\n highCount,\n };\n }\n\n // \u2500\u2500 Private 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\n\n private findContainingNode(\n rawDb: any,\n filePath: string,\n line: number,\n ): { nodeId?: string; nodeName?: string } {\n const row: { id: string; name: string } | undefined = rawDb.get(\n `SELECT id, name FROM nodes\n WHERE file_path = ? AND start_line <= ? AND end_line >= ?\n AND kind IN ('function', 'method')\n ORDER BY (end_line - start_line) ASC\n LIMIT 1`,\n [filePath, line, line],\n );\n\n if (!row) return {};\n return { nodeId: row.id, nodeName: row.name };\n }\n\n private findEntryPoints(rawDb: any, nodeId: string): string[] {\n const rows: Array<{ id: string; name: string }> = rawDb.all(\n `WITH RECURSIVE callers(node_id, depth) AS (\n SELECT source, 1 FROM edges WHERE target = ? AND kind = 'calls'\n UNION\n SELECT e.source, c.depth + 1\n FROM edges e\n JOIN callers c ON e.target = c.node_id\n WHERE c.depth < 5 AND e.kind = 'calls'\n )\n SELECT DISTINCT n.id, n.name\n FROM callers c\n JOIN nodes n ON n.id = c.node_id\n WHERE n.kind IN ('route', 'function')\n AND (n.name LIKE '%route%' OR n.name LIKE '%handler%' OR n.name LIKE '%controller%')`,\n [nodeId],\n );\n\n return rows.map(r => r.id);\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dependency Staleness Checker
|
|
3
|
+
*
|
|
4
|
+
* Queries public package registries (npm, PyPI, crates.io, RubyGems, Packagist)
|
|
5
|
+
* to determine the latest published version and compute a staleness score for
|
|
6
|
+
* each dependency tracked in sec_dependencies.
|
|
7
|
+
*
|
|
8
|
+
* Score formula:
|
|
9
|
+
* score = min(majorVersionsBehind * 0.2, 0.6) // up to 0.6 for version lag
|
|
10
|
+
* + min(monthsSinceLatest / 36, 0.4) // up to 0.4 for time lag
|
|
11
|
+
* score = min(score, 1.0)
|
|
12
|
+
*/
|
|
13
|
+
import type { GraphDatabase } from '../db/database';
|
|
14
|
+
export interface StalenessResult {
|
|
15
|
+
packageName: string;
|
|
16
|
+
ecosystem: string;
|
|
17
|
+
resolvedVersion: string;
|
|
18
|
+
latestVersion: string;
|
|
19
|
+
latestPublished: number;
|
|
20
|
+
stalenessScore: number;
|
|
21
|
+
majorVersionsBehind: number;
|
|
22
|
+
monthsSinceLatest: number;
|
|
23
|
+
}
|
|
24
|
+
export declare class StalenessChecker {
|
|
25
|
+
private readonly db;
|
|
26
|
+
constructor(db: GraphDatabase);
|
|
27
|
+
/**
|
|
28
|
+
* Check all dependencies in sec_dependencies that have a supported ecosystem.
|
|
29
|
+
* Returns a summary of checked/stale counts and any errors encountered.
|
|
30
|
+
*/
|
|
31
|
+
checkAll(): Promise<{
|
|
32
|
+
checked: number;
|
|
33
|
+
stale: number;
|
|
34
|
+
errors: string[];
|
|
35
|
+
}>;
|
|
36
|
+
/**
|
|
37
|
+
* Check a single dependency by node_id. Returns null if the ecosystem is
|
|
38
|
+
* not supported or the dependency is not found.
|
|
39
|
+
*/
|
|
40
|
+
checkOne(nodeId: string): Promise<StalenessResult | null>;
|
|
41
|
+
private _checkRow;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=staleness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"staleness.d.ts","sourceRoot":"","sources":["../../src/security/staleness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAIpD,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAqJD,qBAAa,gBAAgB;IACf,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,aAAa;IAE9C;;;OAGG;IACG,QAAQ,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IA+B/E;;;OAGG;IACG,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;YAqBjD,SAAS;CAkDxB"}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var staleness_exports = {};
|
|
20
|
+
__export(staleness_exports, {
|
|
21
|
+
StalenessChecker: () => StalenessChecker
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(staleness_exports);
|
|
24
|
+
var import_parser = require("./manifest/parser");
|
|
25
|
+
var import_errors = require("../errors");
|
|
26
|
+
const TIMEOUT_MS = 1e4;
|
|
27
|
+
async function fetchJson(url, headers) {
|
|
28
|
+
const controller = new AbortController();
|
|
29
|
+
const timer = setTimeout(() => controller.abort(), TIMEOUT_MS);
|
|
30
|
+
try {
|
|
31
|
+
const resp = await fetch(url, {
|
|
32
|
+
signal: controller.signal,
|
|
33
|
+
headers: {
|
|
34
|
+
"Accept": "application/json",
|
|
35
|
+
...headers
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
|
|
39
|
+
return await resp.json();
|
|
40
|
+
} finally {
|
|
41
|
+
clearTimeout(timer);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
async function fetchNpm(name) {
|
|
45
|
+
const encoded = encodeURIComponent(name);
|
|
46
|
+
const data = await fetchJson(`https://registry.npmjs.org/${encoded}/latest`);
|
|
47
|
+
const version = data["version"];
|
|
48
|
+
const full = await fetchJson(`https://registry.npmjs.org/${encoded}`);
|
|
49
|
+
const time = full["time"] ?? {};
|
|
50
|
+
const publishedStr = time[version] ?? full["time"]?.["modified"] ?? "";
|
|
51
|
+
const latestPublished = publishedStr ? new Date(publishedStr).getTime() : Date.now();
|
|
52
|
+
return { latestVersion: version, latestPublished };
|
|
53
|
+
}
|
|
54
|
+
async function fetchPypi(name) {
|
|
55
|
+
const data = await fetchJson(`https://pypi.org/pypi/${encodeURIComponent(name)}/json`);
|
|
56
|
+
const info = data["info"];
|
|
57
|
+
const version = info["version"];
|
|
58
|
+
const releases = data["releases"] ?? {};
|
|
59
|
+
const files = releases[version] ?? [];
|
|
60
|
+
const uploadTime = files[0]?.["upload_time_iso_8601"] ?? "";
|
|
61
|
+
const latestPublished = uploadTime ? new Date(uploadTime).getTime() : Date.now();
|
|
62
|
+
return { latestVersion: version, latestPublished };
|
|
63
|
+
}
|
|
64
|
+
async function fetchCrates(name) {
|
|
65
|
+
const data = await fetchJson(
|
|
66
|
+
`https://crates.io/api/v1/crates/${encodeURIComponent(name)}`,
|
|
67
|
+
{ "User-Agent": "KiroGraph/1.0" }
|
|
68
|
+
);
|
|
69
|
+
const crate = data["crate"];
|
|
70
|
+
const version = crate["newest_version"];
|
|
71
|
+
const updatedAt = crate["updated_at"] ?? "";
|
|
72
|
+
const latestPublished = updatedAt ? new Date(updatedAt).getTime() : Date.now();
|
|
73
|
+
return { latestVersion: version, latestPublished };
|
|
74
|
+
}
|
|
75
|
+
async function fetchRubygems(name) {
|
|
76
|
+
const data = await fetchJson(`https://rubygems.org/api/v1/gems/${encodeURIComponent(name)}.json`);
|
|
77
|
+
const version = data["version"];
|
|
78
|
+
const createdAt = data["version_created_at"] ?? "";
|
|
79
|
+
const latestPublished = createdAt ? new Date(createdAt).getTime() : Date.now();
|
|
80
|
+
return { latestVersion: version, latestPublished };
|
|
81
|
+
}
|
|
82
|
+
async function fetchPackagist(name) {
|
|
83
|
+
const parts = name.split("/");
|
|
84
|
+
if (parts.length !== 2) throw new Error(`Invalid Composer package name: ${name}`);
|
|
85
|
+
const [vendor, pkg] = parts;
|
|
86
|
+
const data = await fetchJson(`https://repo.packagist.org/p2/${encodeURIComponent(vendor)}/${encodeURIComponent(pkg)}.json`);
|
|
87
|
+
const packages = data["packages"] ?? {};
|
|
88
|
+
const versions = packages[name] ?? [];
|
|
89
|
+
if (versions.length === 0) throw new Error(`No versions found for ${name}`);
|
|
90
|
+
let latestVersion = "";
|
|
91
|
+
let latestPublished = 0;
|
|
92
|
+
for (const v of versions) {
|
|
93
|
+
const versionStr = v["version"] ?? "";
|
|
94
|
+
if (versionStr.startsWith("dev-") || versionStr === "dev-master") continue;
|
|
95
|
+
if (!latestVersion || (0, import_parser.compareVersions)(versionStr, latestVersion) > 0) {
|
|
96
|
+
latestVersion = versionStr;
|
|
97
|
+
const timeStr = v["time"] ?? "";
|
|
98
|
+
latestPublished = timeStr ? new Date(timeStr).getTime() : 0;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (!latestVersion) throw new Error(`No stable versions found for ${name}`);
|
|
102
|
+
return { latestVersion, latestPublished: latestPublished || Date.now() };
|
|
103
|
+
}
|
|
104
|
+
async function fetchLatest(ecosystem, packageName) {
|
|
105
|
+
const eco = ecosystem.toLowerCase();
|
|
106
|
+
try {
|
|
107
|
+
switch (eco) {
|
|
108
|
+
case "npm":
|
|
109
|
+
return await fetchNpm(packageName);
|
|
110
|
+
case "pypi":
|
|
111
|
+
return await fetchPypi(packageName);
|
|
112
|
+
case "pip":
|
|
113
|
+
return await fetchPypi(packageName);
|
|
114
|
+
// alias
|
|
115
|
+
case "cargo":
|
|
116
|
+
return await fetchCrates(packageName);
|
|
117
|
+
case "rubygems":
|
|
118
|
+
return await fetchRubygems(packageName);
|
|
119
|
+
case "composer":
|
|
120
|
+
return await fetchPackagist(packageName);
|
|
121
|
+
default:
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
} catch (err) {
|
|
125
|
+
throw err;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
function getMajorVersion(version) {
|
|
129
|
+
const clean = version.startsWith("v") ? version.slice(1) : version;
|
|
130
|
+
const stripped = clean.replace(/^[~^>=<]+/, "");
|
|
131
|
+
const major = parseInt(stripped.split(".")[0] ?? "0", 10);
|
|
132
|
+
return isNaN(major) ? 0 : major;
|
|
133
|
+
}
|
|
134
|
+
function computeStaleness(resolvedVersion, latestVersion, latestPublished) {
|
|
135
|
+
const resolvedMajor = getMajorVersion(resolvedVersion);
|
|
136
|
+
const latestMajor = getMajorVersion(latestVersion);
|
|
137
|
+
const majorVersionsBehind = Math.max(0, latestMajor - resolvedMajor);
|
|
138
|
+
const monthsSinceLatest = Math.max(0, (Date.now() - latestPublished) / (1e3 * 60 * 60 * 24 * 30));
|
|
139
|
+
const versionScore = Math.min(majorVersionsBehind * 0.2, 0.6);
|
|
140
|
+
const timeScore = Math.min(monthsSinceLatest / 36, 0.4);
|
|
141
|
+
const score = Math.min(versionScore + timeScore, 1);
|
|
142
|
+
return { score, majorVersionsBehind, monthsSinceLatest: Math.round(monthsSinceLatest) };
|
|
143
|
+
}
|
|
144
|
+
class StalenessChecker {
|
|
145
|
+
constructor(db) {
|
|
146
|
+
this.db = db;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Check all dependencies in sec_dependencies that have a supported ecosystem.
|
|
150
|
+
* Returns a summary of checked/stale counts and any errors encountered.
|
|
151
|
+
*/
|
|
152
|
+
async checkAll() {
|
|
153
|
+
const rawDb = this.db.getRawDb();
|
|
154
|
+
const rows = rawDb.all(
|
|
155
|
+
`SELECT node_id, package_name, ecosystem, resolved_version, declared_constraint
|
|
156
|
+
FROM sec_dependencies`
|
|
157
|
+
);
|
|
158
|
+
let checked = 0;
|
|
159
|
+
let stale = 0;
|
|
160
|
+
const errors = [];
|
|
161
|
+
for (const row of rows) {
|
|
162
|
+
const result = await this._checkRow(row);
|
|
163
|
+
if (result === null) continue;
|
|
164
|
+
if (result instanceof Error) {
|
|
165
|
+
errors.push(`${row.package_name} (${row.ecosystem}): ${result.message}`);
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
checked++;
|
|
169
|
+
if (result.stalenessScore >= 0.3) stale++;
|
|
170
|
+
}
|
|
171
|
+
return { checked, stale, errors };
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Check a single dependency by node_id. Returns null if the ecosystem is
|
|
175
|
+
* not supported or the dependency is not found.
|
|
176
|
+
*/
|
|
177
|
+
async checkOne(nodeId) {
|
|
178
|
+
const rawDb = this.db.getRawDb();
|
|
179
|
+
const row = rawDb.get(
|
|
180
|
+
`SELECT node_id, package_name, ecosystem, resolved_version, declared_constraint
|
|
181
|
+
FROM sec_dependencies WHERE node_id = ?`,
|
|
182
|
+
[nodeId]
|
|
183
|
+
);
|
|
184
|
+
if (!row) return null;
|
|
185
|
+
const result = await this._checkRow(row);
|
|
186
|
+
if (result === null || result instanceof Error) return null;
|
|
187
|
+
return result;
|
|
188
|
+
}
|
|
189
|
+
async _checkRow(row) {
|
|
190
|
+
const resolvedVersion = row.resolved_version ?? row.declared_constraint;
|
|
191
|
+
let registryResult;
|
|
192
|
+
try {
|
|
193
|
+
registryResult = await fetchLatest(row.ecosystem, row.package_name);
|
|
194
|
+
} catch (err) {
|
|
195
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
196
|
+
(0, import_errors.logWarn)(`[staleness] Failed to fetch ${row.package_name} (${row.ecosystem}): ${msg}`);
|
|
197
|
+
return new Error(msg);
|
|
198
|
+
}
|
|
199
|
+
if (registryResult === null) {
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
const { latestVersion, latestPublished } = registryResult;
|
|
203
|
+
const { score, majorVersionsBehind, monthsSinceLatest } = computeStaleness(
|
|
204
|
+
resolvedVersion,
|
|
205
|
+
latestVersion,
|
|
206
|
+
latestPublished
|
|
207
|
+
);
|
|
208
|
+
const rawDb = this.db.getRawDb();
|
|
209
|
+
rawDb.run(
|
|
210
|
+
`UPDATE sec_dependencies
|
|
211
|
+
SET latest_version = ?, latest_published = ?, staleness_score = ?
|
|
212
|
+
WHERE node_id = ?`,
|
|
213
|
+
[latestVersion, latestPublished, score, row.node_id]
|
|
214
|
+
);
|
|
215
|
+
return {
|
|
216
|
+
packageName: row.package_name,
|
|
217
|
+
ecosystem: row.ecosystem,
|
|
218
|
+
resolvedVersion,
|
|
219
|
+
latestVersion,
|
|
220
|
+
latestPublished,
|
|
221
|
+
stalenessScore: score,
|
|
222
|
+
majorVersionsBehind,
|
|
223
|
+
monthsSinceLatest
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
228
|
+
0 && (module.exports = {
|
|
229
|
+
StalenessChecker
|
|
230
|
+
});
|
|
231
|
+
//# sourceMappingURL=staleness.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/security/staleness.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Dependency Staleness Checker\n *\n * Queries public package registries (npm, PyPI, crates.io, RubyGems, Packagist)\n * to determine the latest published version and compute a staleness score for\n * each dependency tracked in sec_dependencies.\n *\n * Score formula:\n * score = min(majorVersionsBehind * 0.2, 0.6) // up to 0.6 for version lag\n * + min(monthsSinceLatest / 36, 0.4) // up to 0.4 for time lag\n * score = min(score, 1.0)\n */\n\nimport { compareVersions } from './manifest/parser';\nimport { logWarn, logError } from '../errors';\nimport type { GraphDatabase } from '../db/database';\n\n// \u2500\u2500 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\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface StalenessResult {\n packageName: string;\n ecosystem: string;\n resolvedVersion: string;\n latestVersion: string;\n latestPublished: number; // epoch ms\n stalenessScore: number; // 0.0\u20131.0\n majorVersionsBehind: number;\n monthsSinceLatest: number;\n}\n\n// \u2500\u2500 Registry fetch 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\n\nconst TIMEOUT_MS = 10_000;\n\nasync function fetchJson(url: string, headers?: Record<string, string>): Promise<unknown> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), TIMEOUT_MS);\n try {\n const resp = await fetch(url, {\n signal: controller.signal,\n headers: {\n 'Accept': 'application/json',\n ...headers,\n },\n });\n if (!resp.ok) throw new Error(`HTTP ${resp.status}`);\n return await resp.json();\n } finally {\n clearTimeout(timer);\n }\n}\n\ninterface RegistryResult {\n latestVersion: string;\n latestPublished: number; // epoch ms\n}\n\nasync function fetchNpm(name: string): Promise<RegistryResult> {\n // Scoped packages: @scope/name \u2014 must be URL-encoded as %40scope%2Fname\n const encoded = encodeURIComponent(name);\n const data = await fetchJson(`https://registry.npmjs.org/${encoded}/latest`) as Record<string, unknown>;\n const version = data['version'] as string;\n // Fetch full metadata for publish time\n const full = await fetchJson(`https://registry.npmjs.org/${encoded}`) as Record<string, unknown>;\n const time = (full['time'] as Record<string, string>) ?? {};\n const publishedStr = time[version] ?? (full['time'] as Record<string, string>)?.['modified'] ?? '';\n const latestPublished = publishedStr ? new Date(publishedStr).getTime() : Date.now();\n return { latestVersion: version, latestPublished };\n}\n\nasync function fetchPypi(name: string): Promise<RegistryResult> {\n const data = await fetchJson(`https://pypi.org/pypi/${encodeURIComponent(name)}/json`) as Record<string, unknown>;\n const info = data['info'] as Record<string, unknown>;\n const version = info['version'] as string;\n const releases = (data['releases'] as Record<string, Array<Record<string, string>>>) ?? {};\n const files = releases[version] ?? [];\n const uploadTime = files[0]?.['upload_time_iso_8601'] ?? '';\n const latestPublished = uploadTime ? new Date(uploadTime).getTime() : Date.now();\n return { latestVersion: version, latestPublished };\n}\n\nasync function fetchCrates(name: string): Promise<RegistryResult> {\n const data = await fetchJson(\n `https://crates.io/api/v1/crates/${encodeURIComponent(name)}`,\n { 'User-Agent': 'KiroGraph/1.0' },\n ) as Record<string, unknown>;\n const crate = data['crate'] as Record<string, unknown>;\n const version = crate['newest_version'] as string;\n const updatedAt = (crate['updated_at'] as string) ?? '';\n const latestPublished = updatedAt ? new Date(updatedAt).getTime() : Date.now();\n return { latestVersion: version, latestPublished };\n}\n\nasync function fetchRubygems(name: string): Promise<RegistryResult> {\n const data = await fetchJson(`https://rubygems.org/api/v1/gems/${encodeURIComponent(name)}.json`) as Record<string, unknown>;\n const version = data['version'] as string;\n const createdAt = (data['version_created_at'] as string) ?? '';\n const latestPublished = createdAt ? new Date(createdAt).getTime() : Date.now();\n return { latestVersion: version, latestPublished };\n}\n\nasync function fetchPackagist(name: string): Promise<RegistryResult> {\n // name is expected to be \"vendor/package\"\n const parts = name.split('/');\n if (parts.length !== 2) throw new Error(`Invalid Composer package name: ${name}`);\n const [vendor, pkg] = parts;\n const data = await fetchJson(`https://repo.packagist.org/p2/${encodeURIComponent(vendor!)}/${encodeURIComponent(pkg!)}.json`) as Record<string, unknown>;\n const packages = (data['packages'] as Record<string, unknown[]>) ?? {};\n const versions = (packages[name] ?? []) as Array<Record<string, unknown>>;\n if (versions.length === 0) throw new Error(`No versions found for ${name}`);\n\n // Find highest non-dev version\n let latestVersion = '';\n let latestPublished = 0;\n for (const v of versions) {\n const versionStr = (v['version'] as string) ?? '';\n if (versionStr.startsWith('dev-') || versionStr === 'dev-master') continue;\n if (!latestVersion || compareVersions(versionStr, latestVersion) > 0) {\n latestVersion = versionStr;\n const timeStr = (v['time'] as string) ?? '';\n latestPublished = timeStr ? new Date(timeStr).getTime() : 0;\n }\n }\n if (!latestVersion) throw new Error(`No stable versions found for ${name}`);\n return { latestVersion, latestPublished: latestPublished || Date.now() };\n}\n\n// \u2500\u2500 Ecosystem dispatch \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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\nasync function fetchLatest(ecosystem: string, packageName: string): Promise<RegistryResult | null> {\n const eco = ecosystem.toLowerCase();\n try {\n switch (eco) {\n case 'npm': return await fetchNpm(packageName);\n case 'pypi': return await fetchPypi(packageName);\n case 'pip': return await fetchPypi(packageName); // alias\n case 'cargo': return await fetchCrates(packageName);\n case 'rubygems': return await fetchRubygems(packageName);\n case 'composer': return await fetchPackagist(packageName);\n default:\n // Maven, Go, NuGet, Swift, Pub, Hex, Gradle \u2014 skip\n return null;\n }\n } catch (err) {\n throw err; // let caller handle\n }\n}\n\n// \u2500\u2500 Score calculation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 getMajorVersion(version: string): number {\n const clean = version.startsWith('v') ? version.slice(1) : version;\n const stripped = clean.replace(/^[~^>=<]+/, '');\n const major = parseInt(stripped.split('.')[0] ?? '0', 10);\n return isNaN(major) ? 0 : major;\n}\n\nfunction computeStaleness(\n resolvedVersion: string,\n latestVersion: string,\n latestPublished: number,\n): { score: number; majorVersionsBehind: number; monthsSinceLatest: number } {\n const resolvedMajor = getMajorVersion(resolvedVersion);\n const latestMajor = getMajorVersion(latestVersion);\n const majorVersionsBehind = Math.max(0, latestMajor - resolvedMajor);\n\n const monthsSinceLatest = Math.max(0, (Date.now() - latestPublished) / (1000 * 60 * 60 * 24 * 30));\n\n const versionScore = Math.min(majorVersionsBehind * 0.2, 0.6);\n const timeScore = Math.min(monthsSinceLatest / 36, 0.4);\n const score = Math.min(versionScore + timeScore, 1.0);\n\n return { score, majorVersionsBehind, monthsSinceLatest: Math.round(monthsSinceLatest) };\n}\n\n// \u2500\u2500 StalenessChecker \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 class StalenessChecker {\n constructor(private readonly db: GraphDatabase) {}\n\n /**\n * Check all dependencies in sec_dependencies that have a supported ecosystem.\n * Returns a summary of checked/stale counts and any errors encountered.\n */\n async checkAll(): Promise<{ checked: number; stale: number; errors: string[] }> {\n const rawDb = this.db.getRawDb();\n const rows: Array<{\n node_id: string;\n package_name: string;\n ecosystem: string;\n resolved_version: string | null;\n declared_constraint: string;\n }> = rawDb.all(\n `SELECT node_id, package_name, ecosystem, resolved_version, declared_constraint\n FROM sec_dependencies`,\n );\n\n let checked = 0;\n let stale = 0;\n const errors: string[] = [];\n\n for (const row of rows) {\n const result = await this._checkRow(row);\n if (result === null) continue; // unsupported ecosystem \u2014 skip\n if (result instanceof Error) {\n errors.push(`${row.package_name} (${row.ecosystem}): ${result.message}`);\n continue;\n }\n checked++;\n if (result.stalenessScore >= 0.3) stale++;\n }\n\n return { checked, stale, errors };\n }\n\n /**\n * Check a single dependency by node_id. Returns null if the ecosystem is\n * not supported or the dependency is not found.\n */\n async checkOne(nodeId: string): Promise<StalenessResult | null> {\n const rawDb = this.db.getRawDb();\n const row: {\n node_id: string;\n package_name: string;\n ecosystem: string;\n resolved_version: string | null;\n declared_constraint: string;\n } | undefined = rawDb.get(\n `SELECT node_id, package_name, ecosystem, resolved_version, declared_constraint\n FROM sec_dependencies WHERE node_id = ?`,\n [nodeId],\n );\n\n if (!row) return null;\n\n const result = await this._checkRow(row);\n if (result === null || result instanceof Error) return null;\n return result;\n }\n\n private async _checkRow(row: {\n node_id: string;\n package_name: string;\n ecosystem: string;\n resolved_version: string | null;\n declared_constraint: string;\n }): Promise<StalenessResult | Error | null> {\n const resolvedVersion = row.resolved_version ?? row.declared_constraint;\n\n let registryResult: RegistryResult | null;\n try {\n registryResult = await fetchLatest(row.ecosystem, row.package_name);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n logWarn(`[staleness] Failed to fetch ${row.package_name} (${row.ecosystem}): ${msg}`);\n return new Error(msg);\n }\n\n if (registryResult === null) {\n // Unsupported ecosystem \u2014 skip silently\n return null;\n }\n\n const { latestVersion, latestPublished } = registryResult;\n const { score, majorVersionsBehind, monthsSinceLatest } = computeStaleness(\n resolvedVersion,\n latestVersion,\n latestPublished,\n );\n\n // Persist to sec_dependencies\n const rawDb = this.db.getRawDb();\n rawDb.run(\n `UPDATE sec_dependencies\n SET latest_version = ?, latest_published = ?, staleness_score = ?\n WHERE node_id = ?`,\n [latestVersion, latestPublished, score, row.node_id],\n );\n\n return {\n packageName: row.package_name,\n ecosystem: row.ecosystem,\n resolvedVersion,\n latestVersion,\n latestPublished,\n stalenessScore: score,\n majorVersionsBehind,\n monthsSinceLatest,\n };\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supply Chain Health Checker
|
|
3
|
+
*
|
|
4
|
+
* Queries OpenSSF Scorecard and registry APIs to assess the health of
|
|
5
|
+
* dependencies: maintenance activity, maintainer count, package age, and
|
|
6
|
+
* overall supply-chain risk level.
|
|
7
|
+
*/
|
|
8
|
+
import type { GraphDatabase } from '../db/database';
|
|
9
|
+
export interface SupplyChainRisk {
|
|
10
|
+
packageName: string;
|
|
11
|
+
ecosystem: string;
|
|
12
|
+
nodeId: string;
|
|
13
|
+
scorecardScore: number | null;
|
|
14
|
+
scorecardChecks: Record<string, number> | null;
|
|
15
|
+
daysSinceLastCommit: number | null;
|
|
16
|
+
isAbandoned: boolean;
|
|
17
|
+
maintainerCount: number | null;
|
|
18
|
+
isSingleMaintainer: boolean;
|
|
19
|
+
publishedAt: string | null;
|
|
20
|
+
isVeryNew: boolean;
|
|
21
|
+
riskLevel: 'critical' | 'high' | 'medium' | 'low' | 'unknown';
|
|
22
|
+
riskReasons: string[];
|
|
23
|
+
}
|
|
24
|
+
export declare class SupplyChainChecker {
|
|
25
|
+
private readonly db;
|
|
26
|
+
constructor(db: GraphDatabase);
|
|
27
|
+
checkAll(): Promise<{
|
|
28
|
+
results: SupplyChainRisk[];
|
|
29
|
+
errors: string[];
|
|
30
|
+
}>;
|
|
31
|
+
checkOne(packageName: string, ecosystem: string): Promise<SupplyChainRisk | null>;
|
|
32
|
+
private _check;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=supply-chain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supply-chain.d.ts","sourceRoot":"","sources":["../../src/security/supply-chain.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAIpD,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IAEf,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAE/C,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,WAAW,EAAE,OAAO,CAAC;IACrB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,kBAAkB,EAAE,OAAO,CAAC;IAE5B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,OAAO,CAAC;IAEnB,SAAS,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,CAAC;IAC9D,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAuQD,qBAAa,kBAAkB;IACjB,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,aAAa;IAExC,QAAQ,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,eAAe,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IA2BrE,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;YAUzE,MAAM;CAgErB"}
|