@ashlr/hub 2.2.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/CHANGELOG.md +1158 -0
- package/LICENSE +21 -0
- package/README.md +833 -0
- package/bin/ashlr +8 -0
- package/dist/api/core.d.ts +28 -0
- package/dist/api/core.js +42 -0
- package/dist/api/core.js.map +1 -0
- package/dist/api/index.d.ts +9 -0
- package/dist/api/index.js +9 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/plugin.d.ts +12 -0
- package/dist/api/plugin.js +13 -0
- package/dist/api/plugin.js.map +1 -0
- package/dist/api/types.d.ts +9 -0
- package/dist/api/types.js +9 -0
- package/dist/api/types.js.map +1 -0
- package/dist/cli/args.d.ts +20 -0
- package/dist/cli/args.js +23 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/ask.d.ts +22 -0
- package/dist/cli/ask.js +240 -0
- package/dist/cli/ask.js.map +1 -0
- package/dist/cli/audit.d.ts +26 -0
- package/dist/cli/audit.js +199 -0
- package/dist/cli/audit.js.map +1 -0
- package/dist/cli/backlog.d.ts +26 -0
- package/dist/cli/backlog.js +322 -0
- package/dist/cli/backlog.js.map +1 -0
- package/dist/cli/completions.d.ts +18 -0
- package/dist/cli/completions.js +156 -0
- package/dist/cli/completions.js.map +1 -0
- package/dist/cli/daemon.d.ts +31 -0
- package/dist/cli/daemon.js +334 -0
- package/dist/cli/daemon.js.map +1 -0
- package/dist/cli/demo-sandbox.d.ts +78 -0
- package/dist/cli/demo-sandbox.js +227 -0
- package/dist/cli/demo-sandbox.js.map +1 -0
- package/dist/cli/demo.d.ts +76 -0
- package/dist/cli/demo.js +285 -0
- package/dist/cli/demo.js.map +1 -0
- package/dist/cli/digest.d.ts +46 -0
- package/dist/cli/digest.js +352 -0
- package/dist/cli/digest.js.map +1 -0
- package/dist/cli/doctor-init.d.ts +28 -0
- package/dist/cli/doctor-init.js +335 -0
- package/dist/cli/doctor-init.js.map +1 -0
- package/dist/cli/genome.d.ts +62 -0
- package/dist/cli/genome.js +1061 -0
- package/dist/cli/genome.js.map +1 -0
- package/dist/cli/gh.d.ts +27 -0
- package/dist/cli/gh.js +322 -0
- package/dist/cli/gh.js.map +1 -0
- package/dist/cli/goals.d.ts +55 -0
- package/dist/cli/goals.js +667 -0
- package/dist/cli/goals.js.map +1 -0
- package/dist/cli/health.d.ts +56 -0
- package/dist/cli/health.js +407 -0
- package/dist/cli/health.js.map +1 -0
- package/dist/cli/help.d.ts +51 -0
- package/dist/cli/help.js +436 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/inbox.d.ts +28 -0
- package/dist/cli/inbox.js +589 -0
- package/dist/cli/inbox.js.map +1 -0
- package/dist/cli/index.d.ts +41 -0
- package/dist/cli/index.js +1208 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/knowledge.d.ts +33 -0
- package/dist/cli/knowledge.js +575 -0
- package/dist/cli/knowledge.js.map +1 -0
- package/dist/cli/mcp.d.ts +26 -0
- package/dist/cli/mcp.js +487 -0
- package/dist/cli/mcp.js.map +1 -0
- package/dist/cli/models.d.ts +26 -0
- package/dist/cli/models.js +435 -0
- package/dist/cli/models.js.map +1 -0
- package/dist/cli/new.d.ts +32 -0
- package/dist/cli/new.js +565 -0
- package/dist/cli/new.js.map +1 -0
- package/dist/cli/notify.d.ts +20 -0
- package/dist/cli/notify.js +188 -0
- package/dist/cli/notify.js.map +1 -0
- package/dist/cli/onboard.d.ts +85 -0
- package/dist/cli/onboard.js +305 -0
- package/dist/cli/onboard.js.map +1 -0
- package/dist/cli/open.d.ts +38 -0
- package/dist/cli/open.js +86 -0
- package/dist/cli/open.js.map +1 -0
- package/dist/cli/orient.d.ts +14 -0
- package/dist/cli/orient.js +110 -0
- package/dist/cli/orient.js.map +1 -0
- package/dist/cli/picker.d.ts +21 -0
- package/dist/cli/picker.js +177 -0
- package/dist/cli/picker.js.map +1 -0
- package/dist/cli/plugins.d.ts +21 -0
- package/dist/cli/plugins.js +394 -0
- package/dist/cli/plugins.js.map +1 -0
- package/dist/cli/preflight.d.ts +29 -0
- package/dist/cli/preflight.js +131 -0
- package/dist/cli/preflight.js.map +1 -0
- package/dist/cli/pulse.d.ts +26 -0
- package/dist/cli/pulse.js +482 -0
- package/dist/cli/pulse.js.map +1 -0
- package/dist/cli/reflect.d.ts +42 -0
- package/dist/cli/reflect.js +381 -0
- package/dist/cli/reflect.js.map +1 -0
- package/dist/cli/run.d.ts +29 -0
- package/dist/cli/run.js +687 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/cli/sandbox.d.ts +20 -0
- package/dist/cli/sandbox.js +345 -0
- package/dist/cli/sandbox.js.map +1 -0
- package/dist/cli/seams.d.ts +41 -0
- package/dist/cli/seams.js +167 -0
- package/dist/cli/seams.js.map +1 -0
- package/dist/cli/serve.d.ts +25 -0
- package/dist/cli/serve.js +249 -0
- package/dist/cli/serve.js.map +1 -0
- package/dist/cli/ship.d.ts +33 -0
- package/dist/cli/ship.js +433 -0
- package/dist/cli/ship.js.map +1 -0
- package/dist/cli/spec.d.ts +19 -0
- package/dist/cli/spec.js +478 -0
- package/dist/cli/spec.js.map +1 -0
- package/dist/cli/swarm.d.ts +42 -0
- package/dist/cli/swarm.js +1365 -0
- package/dist/cli/swarm.js.map +1 -0
- package/dist/cli/telemetry.d.ts +26 -0
- package/dist/cli/telemetry.js +364 -0
- package/dist/cli/telemetry.js.map +1 -0
- package/dist/cli/tui.d.ts +17 -0
- package/dist/cli/tui.js +52 -0
- package/dist/cli/tui.js.map +1 -0
- package/dist/cli/ui.d.ts +53 -0
- package/dist/cli/ui.js +66 -0
- package/dist/cli/ui.js.map +1 -0
- package/dist/cli/update.d.ts +38 -0
- package/dist/cli/update.js +682 -0
- package/dist/cli/update.js.map +1 -0
- package/dist/cli/vercel.d.ts +20 -0
- package/dist/cli/vercel.js +193 -0
- package/dist/cli/vercel.js.map +1 -0
- package/dist/cli/verify-safety.d.ts +96 -0
- package/dist/cli/verify-safety.js +509 -0
- package/dist/cli/verify-safety.js.map +1 -0
- package/dist/cli/wire.d.ts +22 -0
- package/dist/cli/wire.js +205 -0
- package/dist/cli/wire.js.map +1 -0
- package/dist/core/classify.d.ts +51 -0
- package/dist/core/classify.js +450 -0
- package/dist/core/classify.js.map +1 -0
- package/dist/core/config.d.ts +63 -0
- package/dist/core/config.js +474 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/daemon/loop.d.ts +74 -0
- package/dist/core/daemon/loop.js +618 -0
- package/dist/core/daemon/loop.js.map +1 -0
- package/dist/core/daemon/state.d.ts +66 -0
- package/dist/core/daemon/state.js +197 -0
- package/dist/core/daemon/state.js.map +1 -0
- package/dist/core/dashboard.d.ts +40 -0
- package/dist/core/dashboard.js +463 -0
- package/dist/core/dashboard.js.map +1 -0
- package/dist/core/digest/build.d.ts +51 -0
- package/dist/core/digest/build.js +230 -0
- package/dist/core/digest/build.js.map +1 -0
- package/dist/core/digest/deliver.d.ts +47 -0
- package/dist/core/digest/deliver.js +230 -0
- package/dist/core/digest/deliver.js.map +1 -0
- package/dist/core/digest/store.d.ts +57 -0
- package/dist/core/digest/store.js +223 -0
- package/dist/core/digest/store.js.map +1 -0
- package/dist/core/doctor-fix.d.ts +21 -0
- package/dist/core/doctor-fix.js +440 -0
- package/dist/core/doctor-fix.js.map +1 -0
- package/dist/core/doctor.d.ts +18 -0
- package/dist/core/doctor.js +806 -0
- package/dist/core/doctor.js.map +1 -0
- package/dist/core/env-bridge.d.ts +64 -0
- package/dist/core/env-bridge.js +103 -0
- package/dist/core/env-bridge.js.map +1 -0
- package/dist/core/genome/capture.d.ts +49 -0
- package/dist/core/genome/capture.js +352 -0
- package/dist/core/genome/capture.js.map +1 -0
- package/dist/core/genome/consolidate.d.ts +38 -0
- package/dist/core/genome/consolidate.js +426 -0
- package/dist/core/genome/consolidate.js.map +1 -0
- package/dist/core/genome/export.d.ts +29 -0
- package/dist/core/genome/export.js +102 -0
- package/dist/core/genome/export.js.map +1 -0
- package/dist/core/genome/playbook.d.ts +33 -0
- package/dist/core/genome/playbook.js +320 -0
- package/dist/core/genome/playbook.js.map +1 -0
- package/dist/core/genome/recall.d.ts +45 -0
- package/dist/core/genome/recall.js +293 -0
- package/dist/core/genome/recall.js.map +1 -0
- package/dist/core/genome/store.d.ts +62 -0
- package/dist/core/genome/store.js +711 -0
- package/dist/core/genome/store.js.map +1 -0
- package/dist/core/git.d.ts +34 -0
- package/dist/core/git.js +115 -0
- package/dist/core/git.js.map +1 -0
- package/dist/core/goals/advance.d.ts +82 -0
- package/dist/core/goals/advance.js +263 -0
- package/dist/core/goals/advance.js.map +1 -0
- package/dist/core/goals/planner.d.ts +58 -0
- package/dist/core/goals/planner.js +233 -0
- package/dist/core/goals/planner.js.map +1 -0
- package/dist/core/goals/store.d.ts +128 -0
- package/dist/core/goals/store.js +442 -0
- package/dist/core/goals/store.js.map +1 -0
- package/dist/core/inbox/apply.d.ts +36 -0
- package/dist/core/inbox/apply.js +407 -0
- package/dist/core/inbox/apply.js.map +1 -0
- package/dist/core/inbox/notify-proposal.d.ts +13 -0
- package/dist/core/inbox/notify-proposal.js +21 -0
- package/dist/core/inbox/notify-proposal.js.map +1 -0
- package/dist/core/inbox/store.d.ts +67 -0
- package/dist/core/inbox/store.js +258 -0
- package/dist/core/inbox/store.js.map +1 -0
- package/dist/core/index-engine.d.ts +62 -0
- package/dist/core/index-engine.js +486 -0
- package/dist/core/index-engine.js.map +1 -0
- package/dist/core/integrations/desktop-notify.d.ts +18 -0
- package/dist/core/integrations/desktop-notify.js +42 -0
- package/dist/core/integrations/desktop-notify.js.map +1 -0
- package/dist/core/integrations/editors.d.ts +50 -0
- package/dist/core/integrations/editors.js +216 -0
- package/dist/core/integrations/editors.js.map +1 -0
- package/dist/core/integrations/github.d.ts +66 -0
- package/dist/core/integrations/github.js +332 -0
- package/dist/core/integrations/github.js.map +1 -0
- package/dist/core/integrations/identity.d.ts +29 -0
- package/dist/core/integrations/identity.js +359 -0
- package/dist/core/integrations/identity.js.map +1 -0
- package/dist/core/integrations/notify.d.ts +23 -0
- package/dist/core/integrations/notify.js +96 -0
- package/dist/core/integrations/notify.js.map +1 -0
- package/dist/core/integrations/vercel.d.ts +37 -0
- package/dist/core/integrations/vercel.js +192 -0
- package/dist/core/integrations/vercel.js.map +1 -0
- package/dist/core/knowledge/ask.d.ts +34 -0
- package/dist/core/knowledge/ask.js +325 -0
- package/dist/core/knowledge/ask.js.map +1 -0
- package/dist/core/knowledge/graph.d.ts +51 -0
- package/dist/core/knowledge/graph.js +564 -0
- package/dist/core/knowledge/graph.js.map +1 -0
- package/dist/core/knowledge/index.d.ts +74 -0
- package/dist/core/knowledge/index.js +586 -0
- package/dist/core/knowledge/index.js.map +1 -0
- package/dist/core/learn/playbooks.d.ts +84 -0
- package/dist/core/learn/playbooks.js +241 -0
- package/dist/core/learn/playbooks.js.map +1 -0
- package/dist/core/learn/reflect.d.ts +87 -0
- package/dist/core/learn/reflect.js +435 -0
- package/dist/core/learn/reflect.js.map +1 -0
- package/dist/core/learn/store.d.ts +51 -0
- package/dist/core/learn/store.js +165 -0
- package/dist/core/learn/store.js.map +1 -0
- package/dist/core/learn/tuning.d.ts +48 -0
- package/dist/core/learn/tuning.js +201 -0
- package/dist/core/learn/tuning.js.map +1 -0
- package/dist/core/lifecycle/scaffold.d.ts +43 -0
- package/dist/core/lifecycle/scaffold.js +260 -0
- package/dist/core/lifecycle/scaffold.js.map +1 -0
- package/dist/core/lifecycle/ship.d.ts +48 -0
- package/dist/core/lifecycle/ship.js +513 -0
- package/dist/core/lifecycle/ship.js.map +1 -0
- package/dist/core/lifecycle/templates.d.ts +20 -0
- package/dist/core/lifecycle/templates.js +605 -0
- package/dist/core/lifecycle/templates.js.map +1 -0
- package/dist/core/mcp-gateway.d.ts +59 -0
- package/dist/core/mcp-gateway.js +385 -0
- package/dist/core/mcp-gateway.js.map +1 -0
- package/dist/core/mcp-native.d.ts +53 -0
- package/dist/core/mcp-native.js +507 -0
- package/dist/core/mcp-native.js.map +1 -0
- package/dist/core/mcp-registry.d.ts +36 -0
- package/dist/core/mcp-registry.js +180 -0
- package/dist/core/mcp-registry.js.map +1 -0
- package/dist/core/observability/budget-alert.d.ts +18 -0
- package/dist/core/observability/budget-alert.js +90 -0
- package/dist/core/observability/budget-alert.js.map +1 -0
- package/dist/core/observability/estimate.d.ts +27 -0
- package/dist/core/observability/estimate.js +188 -0
- package/dist/core/observability/estimate.js.map +1 -0
- package/dist/core/observability/forecast.d.ts +19 -0
- package/dist/core/observability/forecast.js +101 -0
- package/dist/core/observability/forecast.js.map +1 -0
- package/dist/core/observability/governance.d.ts +28 -0
- package/dist/core/observability/governance.js +101 -0
- package/dist/core/observability/governance.js.map +1 -0
- package/dist/core/observability/otlp.d.ts +88 -0
- package/dist/core/observability/otlp.js +217 -0
- package/dist/core/observability/otlp.js.map +1 -0
- package/dist/core/observability/rollup.d.ts +35 -0
- package/dist/core/observability/rollup.js +311 -0
- package/dist/core/observability/rollup.js.map +1 -0
- package/dist/core/observability/telemetry-sink.d.ts +63 -0
- package/dist/core/observability/telemetry-sink.js +350 -0
- package/dist/core/observability/telemetry-sink.js.map +1 -0
- package/dist/core/observability/usage-source.d.ts +60 -0
- package/dist/core/observability/usage-source.js +347 -0
- package/dist/core/observability/usage-source.js.map +1 -0
- package/dist/core/onboard.d.ts +27 -0
- package/dist/core/onboard.js +288 -0
- package/dist/core/onboard.js.map +1 -0
- package/dist/core/orient.d.ts +23 -0
- package/dist/core/orient.js +135 -0
- package/dist/core/orient.js.map +1 -0
- package/dist/core/phantom.d.ts +23 -0
- package/dist/core/phantom.js +279 -0
- package/dist/core/phantom.js.map +1 -0
- package/dist/core/plugins/host-api.d.ts +29 -0
- package/dist/core/plugins/host-api.js +113 -0
- package/dist/core/plugins/host-api.js.map +1 -0
- package/dist/core/plugins/integrity.d.ts +36 -0
- package/dist/core/plugins/integrity.js +73 -0
- package/dist/core/plugins/integrity.js.map +1 -0
- package/dist/core/plugins/manifest.d.ts +31 -0
- package/dist/core/plugins/manifest.js +316 -0
- package/dist/core/plugins/manifest.js.map +1 -0
- package/dist/core/plugins/registry.d.ts +87 -0
- package/dist/core/plugins/registry.js +415 -0
- package/dist/core/plugins/registry.js.map +1 -0
- package/dist/core/plugins/types.d.ts +182 -0
- package/dist/core/plugins/types.js +40 -0
- package/dist/core/plugins/types.js.map +1 -0
- package/dist/core/plugins/wrappers.d.ts +40 -0
- package/dist/core/plugins/wrappers.js +229 -0
- package/dist/core/plugins/wrappers.js.map +1 -0
- package/dist/core/portfolio/backlog.d.ts +40 -0
- package/dist/core/portfolio/backlog.js +177 -0
- package/dist/core/portfolio/backlog.js.map +1 -0
- package/dist/core/portfolio/scanners.d.ts +21 -0
- package/dist/core/portfolio/scanners.js +600 -0
- package/dist/core/portfolio/scanners.js.map +1 -0
- package/dist/core/providers.d.ts +34 -0
- package/dist/core/providers.js +250 -0
- package/dist/core/providers.js.map +1 -0
- package/dist/core/quality/conventions.d.ts +35 -0
- package/dist/core/quality/conventions.js +267 -0
- package/dist/core/quality/conventions.js.map +1 -0
- package/dist/core/quality/fixes.d.ts +56 -0
- package/dist/core/quality/fixes.js +209 -0
- package/dist/core/quality/fixes.js.map +1 -0
- package/dist/core/quality/health.d.ts +69 -0
- package/dist/core/quality/health.js +350 -0
- package/dist/core/quality/health.js.map +1 -0
- package/dist/core/quality/store.d.ts +56 -0
- package/dist/core/quality/store.js +195 -0
- package/dist/core/quality/store.js.map +1 -0
- package/dist/core/readiness.d.ts +112 -0
- package/dist/core/readiness.js +431 -0
- package/dist/core/readiness.js.map +1 -0
- package/dist/core/run/agent-loop.d.ts +40 -0
- package/dist/core/run/agent-loop.js +291 -0
- package/dist/core/run/agent-loop.js.map +1 -0
- package/dist/core/run/budget.d.ts +47 -0
- package/dist/core/run/budget.js +113 -0
- package/dist/core/run/budget.js.map +1 -0
- package/dist/core/run/engines.d.ts +75 -0
- package/dist/core/run/engines.js +199 -0
- package/dist/core/run/engines.js.map +1 -0
- package/dist/core/run/model-manager.d.ts +64 -0
- package/dist/core/run/model-manager.js +339 -0
- package/dist/core/run/model-manager.js.map +1 -0
- package/dist/core/run/orchestrator.d.ts +100 -0
- package/dist/core/run/orchestrator.js +1515 -0
- package/dist/core/run/orchestrator.js.map +1 -0
- package/dist/core/run/provider-client.d.ts +46 -0
- package/dist/core/run/provider-client.js +796 -0
- package/dist/core/run/provider-client.js.map +1 -0
- package/dist/core/run/retry.d.ts +19 -0
- package/dist/core/run/retry.js +68 -0
- package/dist/core/run/retry.js.map +1 -0
- package/dist/core/run/router.d.ts +50 -0
- package/dist/core/run/router.js +257 -0
- package/dist/core/run/router.js.map +1 -0
- package/dist/core/run/self-heal.d.ts +52 -0
- package/dist/core/run/self-heal.js +181 -0
- package/dist/core/run/self-heal.js.map +1 -0
- package/dist/core/run/streaming.d.ts +31 -0
- package/dist/core/run/streaming.js +122 -0
- package/dist/core/run/streaming.js.map +1 -0
- package/dist/core/run/verify.d.ts +30 -0
- package/dist/core/run/verify.js +204 -0
- package/dist/core/run/verify.js.map +1 -0
- package/dist/core/sandbox/audit.d.ts +31 -0
- package/dist/core/sandbox/audit.js +169 -0
- package/dist/core/sandbox/audit.js.map +1 -0
- package/dist/core/sandbox/policy.d.ts +61 -0
- package/dist/core/sandbox/policy.js +211 -0
- package/dist/core/sandbox/policy.js.map +1 -0
- package/dist/core/sandbox/worktree.d.ts +175 -0
- package/dist/core/sandbox/worktree.js +673 -0
- package/dist/core/sandbox/worktree.js.map +1 -0
- package/dist/core/seams/backlog.d.ts +47 -0
- package/dist/core/seams/backlog.js +47 -0
- package/dist/core/seams/backlog.js.map +1 -0
- package/dist/core/seams/daemon-coordinator.d.ts +72 -0
- package/dist/core/seams/daemon-coordinator.js +76 -0
- package/dist/core/seams/daemon-coordinator.js.map +1 -0
- package/dist/core/seams/genome.d.ts +45 -0
- package/dist/core/seams/genome.js +53 -0
- package/dist/core/seams/genome.js.map +1 -0
- package/dist/core/seams/identity.d.ts +40 -0
- package/dist/core/seams/identity.js +44 -0
- package/dist/core/seams/identity.js.map +1 -0
- package/dist/core/seams/inbox.d.ts +60 -0
- package/dist/core/seams/inbox.js +66 -0
- package/dist/core/seams/inbox.js.map +1 -0
- package/dist/core/seams/index.d.ts +20 -0
- package/dist/core/seams/index.js +21 -0
- package/dist/core/seams/index.js.map +1 -0
- package/dist/core/seams/portfolio.d.ts +50 -0
- package/dist/core/seams/portfolio.js +61 -0
- package/dist/core/seams/portfolio.js.map +1 -0
- package/dist/core/seams/registry.d.ts +42 -0
- package/dist/core/seams/registry.js +128 -0
- package/dist/core/seams/registry.js.map +1 -0
- package/dist/core/seams/run-swarm.d.ts +66 -0
- package/dist/core/seams/run-swarm.js +74 -0
- package/dist/core/seams/run-swarm.js.map +1 -0
- package/dist/core/seams/types.d.ts +123 -0
- package/dist/core/seams/types.js +35 -0
- package/dist/core/seams/types.js.map +1 -0
- package/dist/core/spec/spec-store.d.ts +62 -0
- package/dist/core/spec/spec-store.js +359 -0
- package/dist/core/spec/spec-store.js.map +1 -0
- package/dist/core/swarm/gate.d.ts +45 -0
- package/dist/core/swarm/gate.js +114 -0
- package/dist/core/swarm/gate.js.map +1 -0
- package/dist/core/swarm/planner.d.ts +32 -0
- package/dist/core/swarm/planner.js +293 -0
- package/dist/core/swarm/planner.js.map +1 -0
- package/dist/core/swarm/rollback.d.ts +56 -0
- package/dist/core/swarm/rollback.js +266 -0
- package/dist/core/swarm/rollback.js.map +1 -0
- package/dist/core/swarm/runner.d.ts +62 -0
- package/dist/core/swarm/runner.js +1263 -0
- package/dist/core/swarm/runner.js.map +1 -0
- package/dist/core/swarm/sign.d.ts +71 -0
- package/dist/core/swarm/sign.js +362 -0
- package/dist/core/swarm/sign.js.map +1 -0
- package/dist/core/swarm/store.d.ts +52 -0
- package/dist/core/swarm/store.js +195 -0
- package/dist/core/swarm/store.js.map +1 -0
- package/dist/core/tidy.d.ts +32 -0
- package/dist/core/tidy.js +354 -0
- package/dist/core/tidy.js.map +1 -0
- package/dist/core/tools-registry.d.ts +16 -0
- package/dist/core/tools-registry.js +308 -0
- package/dist/core/tools-registry.js.map +1 -0
- package/dist/core/types.d.ts +2545 -0
- package/dist/core/types.js +9 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/web/api.d.ts +53 -0
- package/dist/core/web/api.js +698 -0
- package/dist/core/web/api.js.map +1 -0
- package/dist/core/web/public/app.js +1906 -0
- package/dist/core/web/public/index.html +721 -0
- package/dist/core/web/public/styles.css +2007 -0
- package/dist/core/web/server.d.ts +18 -0
- package/dist/core/web/server.js +122 -0
- package/dist/core/web/server.js.map +1 -0
- package/dist/core/web/static.d.ts +18 -0
- package/dist/core/web/static.js +122 -0
- package/dist/core/web/static.js.map +1 -0
- package/dist/tui/app.d.ts +33 -0
- package/dist/tui/app.js +350 -0
- package/dist/tui/app.js.map +1 -0
- package/dist/tui/render.d.ts +20 -0
- package/dist/tui/render.js +558 -0
- package/dist/tui/render.js.map +1 -0
- package/package.json +80 -0
- package/schema/config.schema.json +223 -0
|
@@ -0,0 +1,564 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* graph.ts — Knowledge Graph + Impact analysis for enrolled repos.
|
|
3
|
+
*
|
|
4
|
+
* INVARIANTS (docs/contracts/CONTRACT-M25.md):
|
|
5
|
+
* 1. READ-ONLY: never modifies any enrolled repo; analysis only.
|
|
6
|
+
* 2. ENROLLMENT-SCOPED: default repos = listEnrolled() (DEFAULT EMPTY => empty graph).
|
|
7
|
+
* 3. BOUNDED: caps file walk depth, file count, and skips node_modules/.git/dist/binaries.
|
|
8
|
+
* 4. NEVER THROWS: all functions catch internally; callers get empty structures on error.
|
|
9
|
+
* 5. LOCAL-ONLY: no network calls; pure filesystem analysis.
|
|
10
|
+
* 6. NO SECRETS: skips .env/key files; does not emit secret-shaped content.
|
|
11
|
+
*
|
|
12
|
+
* buildGraph(repos?): construct KnowledgeGraph from persisted index + package.json manifests
|
|
13
|
+
* + import/require statements. Nodes: repos, key modules, shared deps.
|
|
14
|
+
* Edges: imports/depends/shared-dep. CrossRepo: same dep across repos, duplicated modules.
|
|
15
|
+
*
|
|
16
|
+
* impact(target, repos?): find all references to a file path or symbol across enrolled repos
|
|
17
|
+
* via the persisted index + grep-style scan. Returns ImpactResult with references + dependents.
|
|
18
|
+
*/
|
|
19
|
+
import fs from 'node:fs';
|
|
20
|
+
import path from 'node:path';
|
|
21
|
+
import { listEnrolled, isEnrolled } from '../sandbox/policy.js';
|
|
22
|
+
import { SECRET_PATTERNS, scrubSecrets as scrubSecretsParity } from './index.js';
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
// Constants — bounds
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
/** Max files to scan per repo during import analysis. */
|
|
27
|
+
const MAX_FILES_PER_REPO = 2000;
|
|
28
|
+
/** Max bytes to read from a single file for import extraction. */
|
|
29
|
+
const MAX_FILE_BYTES = 256 * 1024; // 256 KB
|
|
30
|
+
/** Max recursion depth during directory walk. */
|
|
31
|
+
const MAX_WALK_DEPTH = 10;
|
|
32
|
+
/** Max references to collect for an impact query (keeps output bounded). */
|
|
33
|
+
const MAX_REFERENCES = 500;
|
|
34
|
+
/** Directories to skip unconditionally. */
|
|
35
|
+
const SKIP_DIRS = new Set([
|
|
36
|
+
'node_modules', '.git', 'dist', '.next', '.turbo', 'coverage',
|
|
37
|
+
'__pycache__', 'build', 'out', '.cache', '.parcel-cache', 'vendor',
|
|
38
|
+
'.venv', 'venv', 'target', '.idea', '.vscode',
|
|
39
|
+
]);
|
|
40
|
+
/** File extensions considered source code (import-bearing). */
|
|
41
|
+
const SOURCE_EXTS = new Set([
|
|
42
|
+
'.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs',
|
|
43
|
+
'.py', '.rb', '.go', '.rs', '.java', '.kt',
|
|
44
|
+
]);
|
|
45
|
+
/** Binary / compiled extensions to skip entirely. */
|
|
46
|
+
const BINARY_EXTS = new Set([
|
|
47
|
+
'.png', '.jpg', '.jpeg', '.gif', '.webp', '.svg', '.ico',
|
|
48
|
+
'.woff', '.woff2', '.ttf', '.eot',
|
|
49
|
+
'.mp3', '.mp4', '.wav', '.ogg',
|
|
50
|
+
'.zip', '.tar', '.gz', '.bz2', '.rar',
|
|
51
|
+
'.bin', '.exe', '.dll', '.so', '.dylib',
|
|
52
|
+
'.lock', '.map',
|
|
53
|
+
]);
|
|
54
|
+
/** Secret-adjacent filenames to skip when reading. */
|
|
55
|
+
const SECRET_FILES = new Set([
|
|
56
|
+
'.env', '.env.local', '.env.production', '.env.development', '.env.test',
|
|
57
|
+
'.env.staging', '.envrc',
|
|
58
|
+
'credentials.json', 'secrets.json', 'secret.json',
|
|
59
|
+
'id_rsa', 'id_ed25519', 'id_ecdsa', 'id_dsa',
|
|
60
|
+
'.npmrc', '.netrc',
|
|
61
|
+
'service-account.json', 'serviceaccount.json',
|
|
62
|
+
]);
|
|
63
|
+
// ---------------------------------------------------------------------------
|
|
64
|
+
// Path helpers
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
/** Derive a stable short ID from an absolute path (basename). */
|
|
67
|
+
function repoId(absPath) {
|
|
68
|
+
return `repo:${path.basename(absPath)}`;
|
|
69
|
+
}
|
|
70
|
+
/** Returns true if the file should be skipped entirely (binary, secret, skip-dir). */
|
|
71
|
+
function shouldSkipFile(filePath) {
|
|
72
|
+
const base = path.basename(filePath);
|
|
73
|
+
if (SECRET_FILES.has(base))
|
|
74
|
+
return true;
|
|
75
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
76
|
+
if (BINARY_EXTS.has(ext))
|
|
77
|
+
return true;
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
/** Returns true if the directory entry should not be descended into. */
|
|
81
|
+
function shouldSkipDir(name) {
|
|
82
|
+
return SKIP_DIRS.has(name) || name.startsWith('.');
|
|
83
|
+
}
|
|
84
|
+
// ---------------------------------------------------------------------------
|
|
85
|
+
// Filesystem helpers — always safe, never throw
|
|
86
|
+
// ---------------------------------------------------------------------------
|
|
87
|
+
function safeReadFile(filePath) {
|
|
88
|
+
try {
|
|
89
|
+
if (shouldSkipFile(filePath))
|
|
90
|
+
return null;
|
|
91
|
+
const stat = fs.statSync(filePath);
|
|
92
|
+
if (!stat.isFile())
|
|
93
|
+
return null;
|
|
94
|
+
if (stat.size > MAX_FILE_BYTES)
|
|
95
|
+
return null;
|
|
96
|
+
return fs.readFileSync(filePath, 'utf8');
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function safeReaddir(dir) {
|
|
103
|
+
try {
|
|
104
|
+
return fs.readdirSync(dir, { withFileTypes: true });
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return [];
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// ---------------------------------------------------------------------------
|
|
111
|
+
// Directory walker — bounded, read-only, never throws
|
|
112
|
+
// ---------------------------------------------------------------------------
|
|
113
|
+
/**
|
|
114
|
+
* Walk a repo directory and collect all source file paths up to MAX_FILES_PER_REPO.
|
|
115
|
+
* Skips SKIP_DIRS, hidden dirs, binaries, and secret files.
|
|
116
|
+
*/
|
|
117
|
+
function walkSourceFiles(repoPath) {
|
|
118
|
+
const results = [];
|
|
119
|
+
function walk(dir, depth) {
|
|
120
|
+
if (depth > MAX_WALK_DEPTH)
|
|
121
|
+
return;
|
|
122
|
+
if (results.length >= MAX_FILES_PER_REPO)
|
|
123
|
+
return;
|
|
124
|
+
for (const dirent of safeReaddir(dir)) {
|
|
125
|
+
if (results.length >= MAX_FILES_PER_REPO)
|
|
126
|
+
return;
|
|
127
|
+
// Skip symlinks (files + dirs) so the walk cannot escape the repo boundary.
|
|
128
|
+
if (dirent.isSymbolicLink())
|
|
129
|
+
continue;
|
|
130
|
+
if (dirent.isDirectory()) {
|
|
131
|
+
if (shouldSkipDir(dirent.name))
|
|
132
|
+
continue;
|
|
133
|
+
walk(path.join(dir, dirent.name), depth + 1);
|
|
134
|
+
}
|
|
135
|
+
else if (dirent.isFile()) {
|
|
136
|
+
const filePath = path.join(dir, dirent.name);
|
|
137
|
+
if (shouldSkipFile(filePath))
|
|
138
|
+
continue;
|
|
139
|
+
const ext = path.extname(dirent.name).toLowerCase();
|
|
140
|
+
if (SOURCE_EXTS.has(ext)) {
|
|
141
|
+
results.push(filePath);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
try {
|
|
147
|
+
walk(repoPath, 0);
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
// bounded walk never propagates errors
|
|
151
|
+
}
|
|
152
|
+
return results;
|
|
153
|
+
}
|
|
154
|
+
function readPackageJson(repoPath) {
|
|
155
|
+
try {
|
|
156
|
+
const pkgPath = path.join(repoPath, 'package.json');
|
|
157
|
+
const raw = safeReadFile(pkgPath);
|
|
158
|
+
if (!raw)
|
|
159
|
+
return null;
|
|
160
|
+
return JSON.parse(raw);
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/** Collect all dependency names from a package.json. */
|
|
167
|
+
function collectDeps(pkg) {
|
|
168
|
+
return [
|
|
169
|
+
...Object.keys(pkg.dependencies ?? {}),
|
|
170
|
+
...Object.keys(pkg.devDependencies ?? {}),
|
|
171
|
+
...Object.keys(pkg.peerDependencies ?? {}),
|
|
172
|
+
];
|
|
173
|
+
}
|
|
174
|
+
// ---------------------------------------------------------------------------
|
|
175
|
+
// Import/require extraction — regex-based, fast, bounded
|
|
176
|
+
// ---------------------------------------------------------------------------
|
|
177
|
+
/**
|
|
178
|
+
* Extract import/require targets from a source file's text.
|
|
179
|
+
* Returns both external package names and relative path imports.
|
|
180
|
+
* Never throws.
|
|
181
|
+
*/
|
|
182
|
+
function extractImports(source) {
|
|
183
|
+
const imports = [];
|
|
184
|
+
try {
|
|
185
|
+
// ES module: import ... from 'target' / import 'target'
|
|
186
|
+
const esImportRe = /\bimport\s+(?:[^'"]*\s+from\s+)?['"]([^'"]+)['"]/g;
|
|
187
|
+
let m;
|
|
188
|
+
while ((m = esImportRe.exec(source)) !== null) {
|
|
189
|
+
if (m[1])
|
|
190
|
+
imports.push(m[1]);
|
|
191
|
+
}
|
|
192
|
+
// CommonJS: require('target')
|
|
193
|
+
const cjsRe = /\brequire\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
194
|
+
while ((m = cjsRe.exec(source)) !== null) {
|
|
195
|
+
if (m[1])
|
|
196
|
+
imports.push(m[1]);
|
|
197
|
+
}
|
|
198
|
+
// Dynamic import: import('target')
|
|
199
|
+
const dynRe = /\bimport\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
200
|
+
while ((m = dynRe.exec(source)) !== null) {
|
|
201
|
+
if (m[1])
|
|
202
|
+
imports.push(m[1]);
|
|
203
|
+
}
|
|
204
|
+
// Python: from target import / import target
|
|
205
|
+
const pyFromRe = /^from\s+([\w.]+)\s+import/gm;
|
|
206
|
+
while ((m = pyFromRe.exec(source)) !== null) {
|
|
207
|
+
if (m[1])
|
|
208
|
+
imports.push(m[1]);
|
|
209
|
+
}
|
|
210
|
+
const pyImportRe = /^import\s+([\w.,\s]+)/gm;
|
|
211
|
+
while ((m = pyImportRe.exec(source)) !== null) {
|
|
212
|
+
if (m[1]) {
|
|
213
|
+
for (const part of m[1].split(',')) {
|
|
214
|
+
const trimmed = part.trim().split(' ')[0];
|
|
215
|
+
if (trimmed)
|
|
216
|
+
imports.push(trimmed);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
catch {
|
|
222
|
+
// regex errors are non-fatal
|
|
223
|
+
}
|
|
224
|
+
return imports;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Classify an import string:
|
|
228
|
+
* - 'relative': starts with ./ or ../
|
|
229
|
+
* - 'package': external npm/pip package name
|
|
230
|
+
*/
|
|
231
|
+
function importKind(imp) {
|
|
232
|
+
return imp.startsWith('.') ? 'relative' : 'package';
|
|
233
|
+
}
|
|
234
|
+
/** Extract just the package name (before any slash for scoped/sub-path). */
|
|
235
|
+
function packageName(imp) {
|
|
236
|
+
if (imp.startsWith('@')) {
|
|
237
|
+
// scoped: @scope/name/sub => @scope/name
|
|
238
|
+
const parts = imp.split('/');
|
|
239
|
+
return parts.slice(0, 2).join('/');
|
|
240
|
+
}
|
|
241
|
+
return imp.split('/')[0] ?? imp;
|
|
242
|
+
}
|
|
243
|
+
// ---------------------------------------------------------------------------
|
|
244
|
+
// Secret-scrubbing helper (for display; not stored in graph)
|
|
245
|
+
// ---------------------------------------------------------------------------
|
|
246
|
+
// H6 (PART B.1 — scrub PARITY): graph.ts delegates to index.ts's full
|
|
247
|
+
// SECRET_PATTERNS set so the two scrubs are at PARITY. Previously this was the
|
|
248
|
+
// WEAKER scrub (H4 §6.8 FINDING) — ONE assignment-style regex that missed bare
|
|
249
|
+
// JWT / AKIA / base64 / hex blobs. graph.ts imports { SECRET_PATTERNS,
|
|
250
|
+
// scrubSecrets } from './index.js' and uses index's scrubSecrets at the
|
|
251
|
+
// `detail:` emit site, so graph.ts and index.ts redact the SAME shapes
|
|
252
|
+
// (JWT / AKIA / base64 / hex / Stripe sk_live_) — see
|
|
253
|
+
// docs/contracts/CONTRACT-H6.md §B.1. This flips the pinned H4 §6.8 assertions
|
|
254
|
+
// DELIBERATELY (§B.4): they now assert the bare blobs ARE redacted.
|
|
255
|
+
//
|
|
256
|
+
// PARITY DIRECTION (H6 review finding, §B.1): "parity" means graph.ts adopts
|
|
257
|
+
// index.ts's SUPERSET of high-entropy shapes (bare JWT / AKIA / base64 / hex /
|
|
258
|
+
// sk_live_). The OLD graph regex additionally matched bare LOW-entropy
|
|
259
|
+
// assignments like `token=abc123` / `auth=xyz`; index.ts's compound-name +
|
|
260
|
+
// high-entropy patterns intentionally do NOT, so those narrow shapes are
|
|
261
|
+
// dropped in this direction. This is safe because the ONLY string graph.ts
|
|
262
|
+
// scrubs is the structurally-constrained `detail` string
|
|
263
|
+
// `${dep} shared across N repos: basename@version` (dep names + repo@version,
|
|
264
|
+
// never free-form text), so a bare `token=…` literal cannot occur there.
|
|
265
|
+
//
|
|
266
|
+
// SECRET_PATTERNS is LOAD-BEARING here (not decorative): scrubSecrets() asserts
|
|
267
|
+
// the imported parity array is non-empty before delegating, so a wiped/empty
|
|
268
|
+
// upstream pattern set surfaces as a throw at the graph.ts call site rather than
|
|
269
|
+
// a silent no-op. `ashlr verify-safety` CHECK 4 pins the real `./index.js`
|
|
270
|
+
// parity import (scrubSecrets + SECRET_PATTERNS) — live code, not a vestigial
|
|
271
|
+
// assignment-regex string — see verify-safety.ts CHECK 4 + docs/contracts/CONTRACT-H6.md §B.1.
|
|
272
|
+
/** Parity scrub: delegates to index.ts's exported scrubSecrets over the shared
|
|
273
|
+
* SECRET_PATTERNS so graph.ts redacts the identical pattern set. The explicit
|
|
274
|
+
* SECRET_PATTERNS length guard makes the shared array load-bearing: an empty
|
|
275
|
+
* upstream pattern set throws here instead of silently passing raw text. */
|
|
276
|
+
function scrubSecrets(text) {
|
|
277
|
+
// Defense-in-depth: the shared pattern set must be non-empty for parity to
|
|
278
|
+
// hold. A zero-length array would mean index.ts's scrub silently became a
|
|
279
|
+
// no-op; refuse to emit an unscrubbed detail string in that case.
|
|
280
|
+
if (SECRET_PATTERNS.length === 0) {
|
|
281
|
+
throw new Error('graph.ts scrub parity broken: shared SECRET_PATTERNS is empty');
|
|
282
|
+
}
|
|
283
|
+
return scrubSecretsParity(text);
|
|
284
|
+
}
|
|
285
|
+
function analyseRepo(repoPath) {
|
|
286
|
+
const label = path.basename(repoPath);
|
|
287
|
+
const pkg = readPackageJson(repoPath);
|
|
288
|
+
const deps = pkg ? collectDeps(pkg) : [];
|
|
289
|
+
const moduleImports = new Map();
|
|
290
|
+
const sourceFiles = walkSourceFiles(repoPath);
|
|
291
|
+
for (const filePath of sourceFiles) {
|
|
292
|
+
const src = safeReadFile(filePath);
|
|
293
|
+
if (!src)
|
|
294
|
+
continue;
|
|
295
|
+
const relPath = path.relative(repoPath, filePath);
|
|
296
|
+
const pkgImports = new Set();
|
|
297
|
+
for (const imp of extractImports(src)) {
|
|
298
|
+
if (importKind(imp) === 'package') {
|
|
299
|
+
pkgImports.add(packageName(imp));
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
if (pkgImports.size > 0) {
|
|
303
|
+
moduleImports.set(relPath, pkgImports);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
return {
|
|
307
|
+
repoPath,
|
|
308
|
+
repoLabel: label,
|
|
309
|
+
packageName: pkg?.name ?? null,
|
|
310
|
+
deps,
|
|
311
|
+
moduleImports,
|
|
312
|
+
sourceFiles,
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
// ---------------------------------------------------------------------------
|
|
316
|
+
// buildGraph — public API
|
|
317
|
+
// ---------------------------------------------------------------------------
|
|
318
|
+
/**
|
|
319
|
+
* Build a KnowledgeGraph from enrolled repos (or the provided list).
|
|
320
|
+
*
|
|
321
|
+
* Nodes:
|
|
322
|
+
* - kind:'repo' — each enrolled repo
|
|
323
|
+
* - kind:'module' — key source files within a repo (those that import packages)
|
|
324
|
+
* - kind:'dep' — external dependencies (package names)
|
|
325
|
+
*
|
|
326
|
+
* Edges:
|
|
327
|
+
* - kind:'depends' — repo -> dep (from package.json)
|
|
328
|
+
* - kind:'imports' — module -> dep (from import statements)
|
|
329
|
+
* - kind:'shared-dep' — dep -> dep node (already in graph; used for cross-repo detection)
|
|
330
|
+
*
|
|
331
|
+
* CrossRepo:
|
|
332
|
+
* - kind:'shared-dep' when a dep appears in 2+ repos
|
|
333
|
+
* - kind:'duplicate-module' when the same relative module path exists in 2+ repos
|
|
334
|
+
*
|
|
335
|
+
* BOUNDED, READ-ONLY, NEVER THROWS.
|
|
336
|
+
*/
|
|
337
|
+
export function buildGraph(repos) {
|
|
338
|
+
const graph = { nodes: [], edges: [], crossRepo: [] };
|
|
339
|
+
try {
|
|
340
|
+
const targetRepos = repos ?? listEnrolled();
|
|
341
|
+
if (targetRepos.length === 0)
|
|
342
|
+
return graph;
|
|
343
|
+
const nodeIds = new Set();
|
|
344
|
+
const edgeKeys = new Set();
|
|
345
|
+
function addNode(id, kind, label) {
|
|
346
|
+
if (!nodeIds.has(id)) {
|
|
347
|
+
nodeIds.add(id);
|
|
348
|
+
graph.nodes.push({ id, kind, label });
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
function addEdge(from, to, kind) {
|
|
352
|
+
const key = `${from}||${to}||${kind}`;
|
|
353
|
+
if (!edgeKeys.has(key)) {
|
|
354
|
+
edgeKeys.add(key);
|
|
355
|
+
graph.edges.push({ from, to, kind });
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
// Analyse all repos
|
|
359
|
+
const analyses = [];
|
|
360
|
+
for (const repoPath of targetRepos) {
|
|
361
|
+
try {
|
|
362
|
+
// ENROLLMENT-SCOPED (docs/contracts/CONTRACT-M25.md invariant 3): only ever walk enrolled
|
|
363
|
+
// repos — an explicit repos list from the CLI (--repo / positional) is
|
|
364
|
+
// validated here so a non-enrolled directory is never read.
|
|
365
|
+
if (!isEnrolled(repoPath))
|
|
366
|
+
continue;
|
|
367
|
+
if (!fs.existsSync(repoPath))
|
|
368
|
+
continue;
|
|
369
|
+
const analysis = analyseRepo(repoPath);
|
|
370
|
+
analyses.push(analysis);
|
|
371
|
+
}
|
|
372
|
+
catch {
|
|
373
|
+
// one bad repo must not crash the whole graph
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
// dep name -> set of repo ids that declare it
|
|
377
|
+
const depToRepos = new Map();
|
|
378
|
+
// module relPath -> set of repo ids that have it
|
|
379
|
+
const moduleToRepos = new Map();
|
|
380
|
+
for (const analysis of analyses) {
|
|
381
|
+
const rId = repoId(analysis.repoPath);
|
|
382
|
+
addNode(rId, 'repo', analysis.repoLabel);
|
|
383
|
+
// Edges: repo -> declared dep (from package.json)
|
|
384
|
+
for (const dep of analysis.deps) {
|
|
385
|
+
const depId = `dep:${dep}`;
|
|
386
|
+
addNode(depId, 'dep', dep);
|
|
387
|
+
addEdge(rId, depId, 'depends');
|
|
388
|
+
if (!depToRepos.has(dep))
|
|
389
|
+
depToRepos.set(dep, new Set());
|
|
390
|
+
depToRepos.get(dep).add(rId);
|
|
391
|
+
}
|
|
392
|
+
// Edges: module -> imported package dep
|
|
393
|
+
for (const [relPath, pkgImports] of analysis.moduleImports) {
|
|
394
|
+
const moduleId = `module:${analysis.repoLabel}/${relPath}`;
|
|
395
|
+
addNode(moduleId, 'module', relPath);
|
|
396
|
+
addEdge(rId, moduleId, 'contains');
|
|
397
|
+
for (const imp of pkgImports) {
|
|
398
|
+
const depId = `dep:${imp}`;
|
|
399
|
+
addNode(depId, 'dep', imp);
|
|
400
|
+
addEdge(moduleId, depId, 'imports');
|
|
401
|
+
// Also track dep->repo for cross-repo detection
|
|
402
|
+
if (!depToRepos.has(imp))
|
|
403
|
+
depToRepos.set(imp, new Set());
|
|
404
|
+
depToRepos.get(imp).add(rId);
|
|
405
|
+
}
|
|
406
|
+
if (!moduleToRepos.has(relPath))
|
|
407
|
+
moduleToRepos.set(relPath, new Set());
|
|
408
|
+
moduleToRepos.get(relPath).add(rId);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
// Cross-repo: shared deps (appear in 2+ repos)
|
|
412
|
+
for (const [dep, repoSet] of depToRepos) {
|
|
413
|
+
if (repoSet.size >= 2) {
|
|
414
|
+
// Find the version strings for detail
|
|
415
|
+
const repoVersions = [];
|
|
416
|
+
for (const analysis of analyses) {
|
|
417
|
+
if (repoSet.has(repoId(analysis.repoPath))) {
|
|
418
|
+
const pkg = readPackageJson(analysis.repoPath);
|
|
419
|
+
const version = pkg?.dependencies?.[dep] ??
|
|
420
|
+
pkg?.devDependencies?.[dep] ??
|
|
421
|
+
pkg?.peerDependencies?.[dep] ??
|
|
422
|
+
'*';
|
|
423
|
+
repoVersions.push(`${path.basename(analysis.repoPath)}@${version}`);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
graph.crossRepo.push({
|
|
427
|
+
kind: 'shared-dep',
|
|
428
|
+
detail: scrubSecrets(`${dep} shared across ${repoSet.size} repos: ${repoVersions.join(', ')}`),
|
|
429
|
+
repos: Array.from(repoSet),
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
// Cross-repo: duplicate module paths (same relPath in 2+ repos)
|
|
434
|
+
for (const [relPath, repoSet] of moduleToRepos) {
|
|
435
|
+
if (repoSet.size >= 2) {
|
|
436
|
+
graph.crossRepo.push({
|
|
437
|
+
kind: 'duplicate-module',
|
|
438
|
+
detail: `Module path "${relPath}" exists in ${repoSet.size} repos`,
|
|
439
|
+
repos: Array.from(repoSet),
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
catch {
|
|
445
|
+
// top-level safety net: always return a valid (possibly partial) graph
|
|
446
|
+
}
|
|
447
|
+
return graph;
|
|
448
|
+
}
|
|
449
|
+
// ---------------------------------------------------------------------------
|
|
450
|
+
// impact — public API
|
|
451
|
+
// ---------------------------------------------------------------------------
|
|
452
|
+
/**
|
|
453
|
+
* Find all references to a file path or symbol across enrolled repos.
|
|
454
|
+
*
|
|
455
|
+
* For a file target: searches for import/require of that file (by basename and
|
|
456
|
+
* relative paths) and any text occurrence of the path.
|
|
457
|
+
* For a symbol target (no path separators, no extension): searches for usage
|
|
458
|
+
* occurrences in source files via text scan.
|
|
459
|
+
*
|
|
460
|
+
* Returns references (repo/file:line) and a list of dependent module names.
|
|
461
|
+
* BOUNDED (MAX_REFERENCES cap). READ-ONLY. NEVER THROWS.
|
|
462
|
+
*/
|
|
463
|
+
export function impact(target, repos) {
|
|
464
|
+
const result = { target, references: [], dependents: [] };
|
|
465
|
+
try {
|
|
466
|
+
if (!target || target.trim().length === 0)
|
|
467
|
+
return result;
|
|
468
|
+
const targetRepos = repos ?? listEnrolled();
|
|
469
|
+
if (targetRepos.length === 0)
|
|
470
|
+
return result;
|
|
471
|
+
const cleanTarget = target.trim();
|
|
472
|
+
// A target is a FILE PATH only when it has a path separator OR ends with a
|
|
473
|
+
// real file extension (.ts/.tsx/.js/.py/…). A bare dotted symbol like
|
|
474
|
+
// `React.useState` or `obj.method` has no path separator and no trailing
|
|
475
|
+
// file extension, so it falls through to word-boundary SYMBOL matching.
|
|
476
|
+
const FILE_EXT_RE = /\.[a-z0-9]{1,5}$/i;
|
|
477
|
+
const isFilePath = cleanTarget.includes('/') || cleanTarget.includes('\\') ||
|
|
478
|
+
FILE_EXT_RE.test(cleanTarget);
|
|
479
|
+
const targetBasename = path.basename(cleanTarget);
|
|
480
|
+
// For searching: strip extension for module-name matching
|
|
481
|
+
const targetNoExt = targetBasename.replace(/\.[^.]+$/, '');
|
|
482
|
+
const dependentSet = new Set();
|
|
483
|
+
for (const repoPath of targetRepos) {
|
|
484
|
+
try {
|
|
485
|
+
// ENROLLMENT-SCOPED (docs/contracts/CONTRACT-M25.md invariant 3): never walk a directory
|
|
486
|
+
// that is not enrolled, even if passed explicitly via --repo.
|
|
487
|
+
if (!isEnrolled(repoPath))
|
|
488
|
+
continue;
|
|
489
|
+
if (!fs.existsSync(repoPath))
|
|
490
|
+
continue;
|
|
491
|
+
const sourceFiles = walkSourceFiles(repoPath);
|
|
492
|
+
for (const filePath of sourceFiles) {
|
|
493
|
+
if (result.references.length >= MAX_REFERENCES)
|
|
494
|
+
break;
|
|
495
|
+
// Skip the target file itself if it's a file path
|
|
496
|
+
if (isFilePath) {
|
|
497
|
+
const absTarget = path.isAbsolute(cleanTarget)
|
|
498
|
+
? cleanTarget
|
|
499
|
+
: path.join(repoPath, cleanTarget);
|
|
500
|
+
if (filePath === absTarget)
|
|
501
|
+
continue;
|
|
502
|
+
}
|
|
503
|
+
const src = safeReadFile(filePath);
|
|
504
|
+
if (!src)
|
|
505
|
+
continue;
|
|
506
|
+
const lines = src.split('\n');
|
|
507
|
+
for (let i = 0; i < lines.length; i++) {
|
|
508
|
+
if (result.references.length >= MAX_REFERENCES)
|
|
509
|
+
break;
|
|
510
|
+
const line = lines[i];
|
|
511
|
+
if (!line)
|
|
512
|
+
continue;
|
|
513
|
+
let matched = false;
|
|
514
|
+
if (isFilePath) {
|
|
515
|
+
// File path target: look for imports that reference this file
|
|
516
|
+
// Match by basename (without ext) in import strings
|
|
517
|
+
if (line.includes(targetBasename) ||
|
|
518
|
+
(targetNoExt && line.includes(targetNoExt) &&
|
|
519
|
+
(line.includes('import') || line.includes('require') || line.includes('from')))) {
|
|
520
|
+
matched = true;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
else {
|
|
524
|
+
// Symbol target: look for usage of the symbol name in source
|
|
525
|
+
// Use word-boundary-style matching to avoid partial matches
|
|
526
|
+
const symbolRe = new RegExp(`\\b${escapeRegex(cleanTarget)}\\b`);
|
|
527
|
+
if (symbolRe.test(line)) {
|
|
528
|
+
matched = true;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
if (matched) {
|
|
532
|
+
const relFile = path.relative(repoPath, filePath);
|
|
533
|
+
const repo = path.basename(repoPath);
|
|
534
|
+
result.references.push({
|
|
535
|
+
repo,
|
|
536
|
+
file: relFile,
|
|
537
|
+
line: i + 1,
|
|
538
|
+
});
|
|
539
|
+
// Track this file as a dependent module
|
|
540
|
+
const modName = relFile.replace(/\.[^.]+$/, '');
|
|
541
|
+
dependentSet.add(`${repo}/${modName}`);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
catch {
|
|
547
|
+
// one bad repo must not crash the whole impact
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
result.dependents = Array.from(dependentSet);
|
|
551
|
+
}
|
|
552
|
+
catch {
|
|
553
|
+
// top-level safety net
|
|
554
|
+
}
|
|
555
|
+
return result;
|
|
556
|
+
}
|
|
557
|
+
// ---------------------------------------------------------------------------
|
|
558
|
+
// Internal utility
|
|
559
|
+
// ---------------------------------------------------------------------------
|
|
560
|
+
/** Escape a string for use in a RegExp. */
|
|
561
|
+
function escapeRegex(s) {
|
|
562
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
563
|
+
}
|
|
564
|
+
//# sourceMappingURL=graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../../../src/core/knowledge/graph.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* knowledge/index.ts — Portfolio Knowledge Index (M25)
|
|
3
|
+
*
|
|
4
|
+
* INVARIANTS (non-negotiable):
|
|
5
|
+
* 1. LOCAL-ONLY: embeddings run against local Ollama only. Never send chunks
|
|
6
|
+
* to a cloud endpoint — this file has no allowCloud path at all.
|
|
7
|
+
* 2. READ-ONLY: never mutates any enrolled repo. Writes go to knowledgeDir()
|
|
8
|
+
* only (~/.ashlr/knowledge/<repo-hash>/).
|
|
9
|
+
* 3. ENROLLMENT-SCOPED: default repo set is listEnrolled() (DEFAULT EMPTY →
|
|
10
|
+
* returns {repos:0, chunks:0}; never scans arbitrary paths).
|
|
11
|
+
* 4. BOUNDED: caps file count, total bytes read, and wall-clock time per repo;
|
|
12
|
+
* skips node_modules / .git / dist / build / binaries / lockfiles.
|
|
13
|
+
* 5. NO SECRETS: skips .env* / *.pem / *.key / *.p12 files outright; scrubs
|
|
14
|
+
* secret-shaped tokens from chunk text before storing or embedding.
|
|
15
|
+
* 6. INCREMENTAL: re-indexes only files whose mtime > last index timestamp.
|
|
16
|
+
* Never throws — all errors are silently swallowed per the contract.
|
|
17
|
+
*/
|
|
18
|
+
import type { KnowledgeChunk } from '../types.js';
|
|
19
|
+
/**
|
|
20
|
+
* Patterns for secret-shaped tokens: API keys, JWTs, long hex/base64 strings.
|
|
21
|
+
* Applied to chunk text before storing or embedding.
|
|
22
|
+
*
|
|
23
|
+
* EXPORTED (read-only) so the `ashlr verify-safety` self-check (H4) can run the
|
|
24
|
+
* REAL pattern set against a synthesized secret rather than a drifting private
|
|
25
|
+
* copy. Treat as a frozen constant — callers must never mutate it.
|
|
26
|
+
*/
|
|
27
|
+
export declare const SECRET_PATTERNS: RegExp[];
|
|
28
|
+
/**
|
|
29
|
+
* Scrub secret-shaped tokens from a chunk of text. Returns sanitized text.
|
|
30
|
+
*
|
|
31
|
+
* EXPORTED (pure, read-only) so the H4 `ashlr verify-safety` self-check can
|
|
32
|
+
* invoke the REAL redaction function — not a copy — against a synthesized
|
|
33
|
+
* secret, so any weakening of the function body (or its pattern set) is caught.
|
|
34
|
+
*/
|
|
35
|
+
export declare function scrubSecrets(text: string): string;
|
|
36
|
+
/** Root on-disk directory for the knowledge index: ~/.ashlr/knowledge */
|
|
37
|
+
export declare function knowledgeDir(): string;
|
|
38
|
+
/**
|
|
39
|
+
* Load persisted knowledge chunks, optionally scoped to one repo (absolute path).
|
|
40
|
+
* Returns [] when nothing is indexed or on any read error.
|
|
41
|
+
* NEVER scans repo source — reads only the persisted index under knowledgeDir().
|
|
42
|
+
*/
|
|
43
|
+
export declare function loadChunks(repo?: string): KnowledgeChunk[];
|
|
44
|
+
/**
|
|
45
|
+
* Build (or incrementally update) the knowledge index for enrolled repos.
|
|
46
|
+
*
|
|
47
|
+
* - `opts.repos`: explicit repo list; defaults to `listEnrolled()` (DEFAULT EMPTY).
|
|
48
|
+
* - `opts.allowCloud`: ignored here — this file is LOCAL-ONLY. Cloud flag is
|
|
49
|
+
* only meaningful in ask.ts for synthesis; indexing is always local.
|
|
50
|
+
*
|
|
51
|
+
* Guarantees:
|
|
52
|
+
* - Never mutates any enrolled repo (writes only to knowledgeDir()).
|
|
53
|
+
* - Skips secret files; scrubs secret tokens from chunk text.
|
|
54
|
+
* - Incremental: re-indexes only files changed since last run (by mtime).
|
|
55
|
+
* - Bounded: file count, byte, and time caps per repo.
|
|
56
|
+
* - Never throws.
|
|
57
|
+
*/
|
|
58
|
+
/** M32: per-repo progress event emitted by buildKnowledge (best-effort). */
|
|
59
|
+
export interface KnowledgeProgress {
|
|
60
|
+
repo: string;
|
|
61
|
+
repoIndex: number;
|
|
62
|
+
repoCount: number;
|
|
63
|
+
newChunks: number;
|
|
64
|
+
}
|
|
65
|
+
export declare function buildKnowledge(opts?: {
|
|
66
|
+
repos?: string[];
|
|
67
|
+
allowCloud?: boolean;
|
|
68
|
+
/** M32: called after each repo finishes indexing. Wrapped — a throwing
|
|
69
|
+
* callback can never violate buildKnowledge's never-throws contract. */
|
|
70
|
+
onProgress?: (ev: KnowledgeProgress) => void;
|
|
71
|
+
}): Promise<{
|
|
72
|
+
repos: number;
|
|
73
|
+
chunks: number;
|
|
74
|
+
}>;
|