@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,227 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/cli/demo-sandbox.ts — H8 shared isolation module for `ashlr demo`.
|
|
3
|
+
*
|
|
4
|
+
* MILESTONE H8 "Harden & Prove" (FINAL). This module factors the
|
|
5
|
+
* DISPOSABLE-repo + ISOLATED-tmp-`~/.ashlr` setup/teardown out of `demo.ts`
|
|
6
|
+
* (and away from `test/`) so the demo applies the EXACT same isolation discipline
|
|
7
|
+
* the H1 testkit encodes (`test/helpers/h1-fixture.ts:makeFixture`) — but as a
|
|
8
|
+
* shippable CLI helper rather than a test-only one. See
|
|
9
|
+
* docs/contracts/CONTRACT-H8.md (BUILD ITEM 1).
|
|
10
|
+
*
|
|
11
|
+
* ───────────────────────────────────────────────────────────────────────────
|
|
12
|
+
* ABSOLUTE SAFETY RULES (paramount — encoded directly in these helpers):
|
|
13
|
+
* - HOME is relocated to a FRESH os.tmpdir() dir so every state read/write
|
|
14
|
+
* resolves to an ISOLATED ~/.ashlr — NEVER the real one. The real portfolio
|
|
15
|
+
* (~/.ashlr/enrollment.json = { repos: [] }) is NEVER touched. The prior
|
|
16
|
+
* HOME + re-entrancy env (ASHLR_IN_DAEMON / ASHLR_IN_SWARM) are snapshotted
|
|
17
|
+
* and RESTORED on dispose().
|
|
18
|
+
* - A sanity guard asserts homedir() resolves to the tmp HOME before the demo
|
|
19
|
+
* proceeds; if relocation did not take effect it RESTORES + ABORTS rather
|
|
20
|
+
* than risk mutating the real ~/.ashlr (mirrors makeFixture's guard).
|
|
21
|
+
* - The throwaway repo is a real git repo under os.tmpdir(), seeded with a
|
|
22
|
+
* `// TODO:` marker so the backlog scan finds work. dispose() unenrolls it,
|
|
23
|
+
* sweeps its sandboxes, rm -rf's the repo + the tmp HOME, and restores env.
|
|
24
|
+
* - dispose() is IDEMPOTENT and NEVER throws (best-effort teardown), so the
|
|
25
|
+
* demo's try/finally + signal handler can always clean up safely.
|
|
26
|
+
*
|
|
27
|
+
* IMPLEMENTATION NOTE: this module encodes the SAME disposable-repo + TODO-seed
|
|
28
|
+
* isolation discipline the H1 testkit (`test/helpers/h1-fixture.ts`) uses, but
|
|
29
|
+
* SELF-CONTAINED in `src/` — a shipped CLI module cannot import from `test/`
|
|
30
|
+
* (the build's `rootDir` is `src/`). The handful of git/seed primitives are tiny
|
|
31
|
+
* and use node builtins + git only, so duplicating them here (rather than
|
|
32
|
+
* importing a test helper) is the correct seam per docs/contracts/CONTRACT-H8.md ("factors them
|
|
33
|
+
* out of `test/` into a shippable module"). No new runtime dep is added.
|
|
34
|
+
*/
|
|
35
|
+
import { execFileSync } from 'node:child_process';
|
|
36
|
+
import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync, } from 'node:fs';
|
|
37
|
+
import { homedir, tmpdir } from 'node:os';
|
|
38
|
+
import { dirname, join, resolve } from 'node:path';
|
|
39
|
+
import { unenroll } from '../core/sandbox/policy.js';
|
|
40
|
+
import { sweepRepoSandboxes } from '../core/sandbox/worktree.js';
|
|
41
|
+
/**
|
|
42
|
+
* Create an ISOLATED demo context: snapshot + relocate `process.env.HOME` to a
|
|
43
|
+
* fresh os.tmpdir() dir, clear the re-entrancy env, ASSERT homedir() now
|
|
44
|
+
* resolves to the tmp HOME (else restore + throw), then create a DISPOSABLE git
|
|
45
|
+
* repo seeded with a `// TODO:` marker.
|
|
46
|
+
*
|
|
47
|
+
* The returned context's `dispose()` performs the guaranteed auto-cleanup. The
|
|
48
|
+
* caller MUST invoke it in a `try/finally` (and from a SIGINT/SIGTERM handler)
|
|
49
|
+
* so the tmp state is always reclaimed.
|
|
50
|
+
*
|
|
51
|
+
* @throws if HOME relocation does not take effect (isolation broken) — fails
|
|
52
|
+
* loudly rather than risk touching the real ~/.ashlr.
|
|
53
|
+
*/
|
|
54
|
+
export function makeDemoContext(opts) {
|
|
55
|
+
const keep = opts?.keep === true;
|
|
56
|
+
// 1. Snapshot the prior HOME + re-entrancy env so dispose() can restore them
|
|
57
|
+
// EXACTLY as found (an undefined var must be re-deleted, not set to '').
|
|
58
|
+
const prevHome = process.env.HOME;
|
|
59
|
+
const prevInDaemon = process.env.ASHLR_IN_DAEMON;
|
|
60
|
+
const prevInSwarm = process.env.ASHLR_IN_SWARM;
|
|
61
|
+
// 2. Relocate HOME to a fresh tmp dir; clear the re-entrancy guard so a
|
|
62
|
+
// daemon tick is not refused by the recursion check.
|
|
63
|
+
// PID in the prefix so concurrent processes (e.g. vitest's parallel forks)
|
|
64
|
+
// never collide in the shared os.tmpdir() and a prefix-scoped sweep can target
|
|
65
|
+
// only its own process's dirs. Real-world hygiene + race-free test cleanup.
|
|
66
|
+
const home = mkdtempSync(join(tmpdir(), `ashlr-h8-demo-home-${process.pid}-`));
|
|
67
|
+
process.env.HOME = home;
|
|
68
|
+
delete process.env.ASHLR_IN_DAEMON;
|
|
69
|
+
delete process.env.ASHLR_IN_SWARM;
|
|
70
|
+
// Restore env to EXACTLY the snapshotted state. Shared by the abort guard and
|
|
71
|
+
// dispose() so isolation is symmetric and never leaks a cleared var.
|
|
72
|
+
const restoreEnv = () => {
|
|
73
|
+
if (prevHome === undefined)
|
|
74
|
+
delete process.env.HOME;
|
|
75
|
+
else
|
|
76
|
+
process.env.HOME = prevHome;
|
|
77
|
+
if (prevInDaemon === undefined)
|
|
78
|
+
delete process.env.ASHLR_IN_DAEMON;
|
|
79
|
+
else
|
|
80
|
+
process.env.ASHLR_IN_DAEMON = prevInDaemon;
|
|
81
|
+
if (prevInSwarm === undefined)
|
|
82
|
+
delete process.env.ASHLR_IN_SWARM;
|
|
83
|
+
else
|
|
84
|
+
process.env.ASHLR_IN_SWARM = prevInSwarm;
|
|
85
|
+
};
|
|
86
|
+
// 3. SANITY GUARD: homedir() must now resolve to the tmp HOME, otherwise
|
|
87
|
+
// isolation is broken on this platform and we MUST NOT proceed (it would
|
|
88
|
+
// risk the real ~/.ashlr). Restore env + rm the tmp dir + fail loudly —
|
|
89
|
+
// exactly as the H1 fixture's guard does.
|
|
90
|
+
if (resolve(homedir()) !== resolve(home)) {
|
|
91
|
+
restoreEnv();
|
|
92
|
+
try {
|
|
93
|
+
rmSync(home, { recursive: true, force: true });
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
/* idempotent — never throw from the abort path */
|
|
97
|
+
}
|
|
98
|
+
throw new Error('ashlr demo: HOME relocation did not take effect (homedir() != tmp HOME); ' +
|
|
99
|
+
'refusing to run to avoid touching the real ~/.ashlr');
|
|
100
|
+
}
|
|
101
|
+
// 4. Create a DISPOSABLE git repo seeded with a `// TODO:` marker so the
|
|
102
|
+
// backlog scan finds REAL work (same discipline as the H1 testkit's
|
|
103
|
+
// makeDisposableRepo/todoSeedFiles, self-contained here).
|
|
104
|
+
let repoDir;
|
|
105
|
+
try {
|
|
106
|
+
repoDir = seedDisposableRepo();
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
// Repo creation failed (e.g. git missing) — tear the tmp HOME back down and
|
|
110
|
+
// restore env before re-throwing so we never strand isolated state.
|
|
111
|
+
restoreEnv();
|
|
112
|
+
try {
|
|
113
|
+
rmSync(home, { recursive: true, force: true });
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
/* idempotent */
|
|
117
|
+
}
|
|
118
|
+
throw err;
|
|
119
|
+
}
|
|
120
|
+
// Once dispose() restores the REAL HOME, a second dispose() must be a TRUE
|
|
121
|
+
// no-op — a repeat unenroll()/sweep would write into the REAL ~/.ashlr (policy
|
|
122
|
+
// emits audit() on every enroll/unenroll since H6). This flag enforces genuine
|
|
123
|
+
// idempotence so a double-dispose never leaks state to the real home.
|
|
124
|
+
let disposed = false;
|
|
125
|
+
const dispose = () => {
|
|
126
|
+
if (disposed)
|
|
127
|
+
return;
|
|
128
|
+
disposed = true;
|
|
129
|
+
// a. Unenroll the tmp repo + sweep its sandboxes (the rollback) — STILL
|
|
130
|
+
// under the isolated HOME, so this writes only into the tmp ~/.ashlr.
|
|
131
|
+
try {
|
|
132
|
+
unenroll(repoDir);
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
/* best-effort — never throw from teardown */
|
|
136
|
+
}
|
|
137
|
+
try {
|
|
138
|
+
sweepRepoSandboxes(repoDir);
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
/* best-effort */
|
|
142
|
+
}
|
|
143
|
+
// b. rm -rf the tmp repo + tmp HOME (unless --no-cleanup keeps them).
|
|
144
|
+
if (!keep) {
|
|
145
|
+
try {
|
|
146
|
+
rmSync(repoDir, { recursive: true, force: true });
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
/* idempotent */
|
|
150
|
+
}
|
|
151
|
+
try {
|
|
152
|
+
if (existsSync(home))
|
|
153
|
+
rmSync(home, { recursive: true, force: true });
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
/* idempotent */
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// c. Restore HOME + re-entrancy env LAST, so (a)/(b) ran isolated.
|
|
160
|
+
restoreEnv();
|
|
161
|
+
};
|
|
162
|
+
return {
|
|
163
|
+
home,
|
|
164
|
+
ashlrDir: join(home, '.ashlr'),
|
|
165
|
+
repoDir,
|
|
166
|
+
dispose,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
// ---------------------------------------------------------------------------
|
|
170
|
+
// seedDisposableRepo — a real git repo under os.tmpdir(), seeded with a
|
|
171
|
+
// `// TODO:` marker + an initial commit so HEAD resolves and the backlog scan
|
|
172
|
+
// finds work. Self-contained (node builtins + git only) — the same discipline
|
|
173
|
+
// the H1 testkit's makeDisposableRepo/todoSeedFiles encode, inlined so a shipped
|
|
174
|
+
// src/ module never imports from test/.
|
|
175
|
+
// ---------------------------------------------------------------------------
|
|
176
|
+
const GIT_TIMEOUT = 30_000;
|
|
177
|
+
// HERMETIC git env: pin global/system config to /dev/null so the disposable
|
|
178
|
+
// repo never inherits the ambient (or the relocated tmp) HOME's `.gitconfig`,
|
|
179
|
+
// and never reads /etc git config. Without this the demo's HOME relocation
|
|
180
|
+
// (process.env.HOME → fresh tmp dir) makes git resolve config against a dir that
|
|
181
|
+
// can differ between back-to-back demo runs in one process, which intermittently
|
|
182
|
+
// breaks repo detection mid-sequence ("fatal: not in a git directory"). Pinning
|
|
183
|
+
// both config sources + an explicit cwd makes seeding fully deterministic and
|
|
184
|
+
// independent of any leaked/relocated git state. Mirrors the H1 testkit.
|
|
185
|
+
const GIT_ENV = {
|
|
186
|
+
...process.env,
|
|
187
|
+
GIT_CONFIG_GLOBAL: '/dev/null',
|
|
188
|
+
GIT_CONFIG_SYSTEM: '/dev/null',
|
|
189
|
+
GIT_TERMINAL_PROMPT: '0',
|
|
190
|
+
};
|
|
191
|
+
function git(dir, args) {
|
|
192
|
+
execFileSync('git', ['-C', dir, ...args], {
|
|
193
|
+
cwd: dir,
|
|
194
|
+
env: GIT_ENV,
|
|
195
|
+
timeout: GIT_TIMEOUT,
|
|
196
|
+
stdio: 'pipe',
|
|
197
|
+
encoding: 'utf8',
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
function seedDisposableRepo() {
|
|
201
|
+
const dir = mkdtempSync(join(tmpdir(), `ashlr-h8-demo-repo-${process.pid}-`));
|
|
202
|
+
// Self-contained git identity so commits never depend on global config, and
|
|
203
|
+
// gpgsign off so CI signing config can't interfere (mirrors the H1 testkit).
|
|
204
|
+
// `--local` pins every write to this repo's own config regardless of ambient
|
|
205
|
+
// state (the GIT_ENV above already neutralises global/system config).
|
|
206
|
+
git(dir, ['init', '--initial-branch=main', '.']);
|
|
207
|
+
git(dir, ['config', '--local', 'user.email', 'demo@ashlr.local']);
|
|
208
|
+
git(dir, ['config', '--local', 'user.name', 'Ashlr Demo']);
|
|
209
|
+
git(dir, ['config', '--local', 'commit.gpgsign', 'false']);
|
|
210
|
+
// A README so HEAD/docs are well-formed + one source file carrying a single
|
|
211
|
+
// `// TODO:` so `scanTodos` (buildBacklog) discovers exactly one work item.
|
|
212
|
+
const files = {
|
|
213
|
+
'README.md': '# disposable demo repo\n',
|
|
214
|
+
'src/todo-0.ts': 'export function f0(): number {\n' +
|
|
215
|
+
' // TODO: implement f0 (deterministic discovery signal)\n' +
|
|
216
|
+
' return 0;\n}\n',
|
|
217
|
+
};
|
|
218
|
+
for (const [rel, content] of Object.entries(files)) {
|
|
219
|
+
const full = join(dir, rel);
|
|
220
|
+
mkdirSync(dirname(full), { recursive: true });
|
|
221
|
+
writeFileSync(full, content, 'utf8');
|
|
222
|
+
}
|
|
223
|
+
git(dir, ['add', '-A']);
|
|
224
|
+
git(dir, ['commit', '--no-verify', '-m', 'init']);
|
|
225
|
+
return dir;
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=demo-sandbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"demo-sandbox.js","sourceRoot":"","sources":["../../src/cli/demo-sandbox.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI handler for `ashlr demo` — a WATCHABLE, reproducible run of the FULL
|
|
3
|
+
* autonomous chain on a DISPOSABLE repo so Mason can SEE it before trusting it.
|
|
4
|
+
* See docs/contracts/CONTRACT-H8.md (BUILD ITEM 1).
|
|
5
|
+
*
|
|
6
|
+
* MILESTONE H8 "Harden & Prove" (FINAL). The demo adds NO new outward
|
|
7
|
+
* capability: it is the ONLY new runtime surface, and it is
|
|
8
|
+
* sandboxed/proposal-only/local + DISPOSABLE-repo-only with GUARANTEED
|
|
9
|
+
* auto-cleanup.
|
|
10
|
+
*
|
|
11
|
+
* H8 ABSOLUTE RULES (proven by test/h8.demo.test.ts + test/h8.no-new-outward.test.ts):
|
|
12
|
+
* - DEMO-DISPOSABLE-ONLY: the demo runs in an ISOLATED context (its OWN tmp
|
|
13
|
+
* ~/.ashlr via a relocated process.env.HOME) and enrolls/works ONLY a
|
|
14
|
+
* throwaway git repo under os.tmpdir(). It NEVER enrolls or touches the real
|
|
15
|
+
* portfolio or the real ~/.ashlr/enrollment.json ({repos:[]}).
|
|
16
|
+
* - DEMO-AUTO-CLEANS: the tmp repo + tmp ~/.ashlr are removed on success, on
|
|
17
|
+
* error, AND on interrupt (try/finally + a SIGINT/SIGTERM handler). Cleanup
|
|
18
|
+
* is idempotent + never throws. `--no-cleanup` keeps the tmp dir (still under
|
|
19
|
+
* os.tmpdir()) for inspection and prints its path.
|
|
20
|
+
* - DEMO-NEVER-APPLIES: the demo creates only a PENDING proposal; it NEVER
|
|
21
|
+
* approves/applies a proposal, NEVER pushes/PRs/deploys, and NEVER runs
|
|
22
|
+
* against a real repo. It imports NO apply/push/PR/deploy primitive — it
|
|
23
|
+
* points the human at `ashlr inbox` exactly as the daemon does.
|
|
24
|
+
* - DETERMINISTIC, NO LIVE MODEL REQUIRED: the demo works end-to-end with NO
|
|
25
|
+
* local model. When a local model IS reachable it MAY run a real sandboxed
|
|
26
|
+
* PROPOSAL-ONLY swarm (via the daemon's existing `tick({dryRun:false})`,
|
|
27
|
+
* which imports no apply/push/PR/deploy primitive); otherwise it runs the
|
|
28
|
+
* daemon tick dry-run + a deterministic stub PENDING proposal so a proposal
|
|
29
|
+
* always appears.
|
|
30
|
+
* - No new runtime deps; node builtins + existing modules only.
|
|
31
|
+
*
|
|
32
|
+
* Wiring: BUILD/INTEGRATION adds `case 'demo'` + a `loadDemoCmd` lazy loader in
|
|
33
|
+
* src/cli/index.ts + a cmdHelp entry.
|
|
34
|
+
*/
|
|
35
|
+
/**
|
|
36
|
+
* Print one narrated demo step. Exported so a test can assert the chain narrates
|
|
37
|
+
* each stage (enroll → backlog → tick → PENDING → inbox → cleanup) in order.
|
|
38
|
+
*/
|
|
39
|
+
export declare function narrateStep(n: number, title: string, detail?: string): void;
|
|
40
|
+
/** @internal options consumed only by tests — see test/h8.demo.test.ts. */
|
|
41
|
+
export interface DemoInternalOptions {
|
|
42
|
+
/**
|
|
43
|
+
* Injected just before the inbox-review step (step 7). When provided and it
|
|
44
|
+
* throws, the demo MUST still run its try/finally cleanup (tmp gone, HOME
|
|
45
|
+
* restored) — the DEMO-AUTO-CLEANS error-path proof.
|
|
46
|
+
*/
|
|
47
|
+
beforeInbox?: () => void;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* `ashlr demo` — watch the FULL autonomous chain run, safely.
|
|
51
|
+
*
|
|
52
|
+
* Walks + narrates each step on a DISPOSABLE repo inside an ISOLATED tmp
|
|
53
|
+
* ~/.ashlr (see {@link import('./demo-sandbox.js').makeDemoContext}):
|
|
54
|
+
* 1. isolate — relocate HOME to a fresh os.tmpdir() dir (assert it took effect)
|
|
55
|
+
* 2. seed — create a throwaway git repo with a `// TODO:` so work exists
|
|
56
|
+
* 3. enroll — enroll(tmpRepo) (the explicit gate — on the DISPOSABLE repo only)
|
|
57
|
+
* 4. backlog — buildBacklog({repos:[tmpRepo]}) (narrate the discovered TODO)
|
|
58
|
+
* 5. tick — tick(cfg,{dryRun}) [real proposal-only swarm IF a local model is
|
|
59
|
+
* up, else dry-run + a deterministic stub PENDING proposal]
|
|
60
|
+
* 6. pending — listProposals({status:'pending'}) (show the proposal — NOT applied)
|
|
61
|
+
* 7. inbox — cmdInbox (review only — the human gate; the demo NEVER approves)
|
|
62
|
+
* 8. rollback — unenroll + sweepRepoSandboxes (narrated; performed by dispose())
|
|
63
|
+
* 9. cleanup — FINALLY: dispose() the tmp context (rm -rf unless --no-cleanup)
|
|
64
|
+
*
|
|
65
|
+
* Flags:
|
|
66
|
+
* --no-cleanup keep the tmp dir (still under os.tmpdir()) for inspection.
|
|
67
|
+
* --json emit a structured trace of the steps instead of narration.
|
|
68
|
+
*
|
|
69
|
+
* GUARANTEED auto-cleanup: the whole chain runs inside a try/finally that calls
|
|
70
|
+
* dispose(), and a SIGINT/SIGTERM handler is installed so an interrupt also
|
|
71
|
+
* cleans up. Returns 0 on success, non-zero on error (after cleanup ran).
|
|
72
|
+
*
|
|
73
|
+
* @param args CLI args (`--no-cleanup`, `--json`).
|
|
74
|
+
* @param internal @internal test-only injection seam (never passed by the CLI).
|
|
75
|
+
*/
|
|
76
|
+
export declare function cmdDemo(args: string[], internal?: DemoInternalOptions): Promise<number>;
|
package/dist/cli/demo.js
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI handler for `ashlr demo` — a WATCHABLE, reproducible run of the FULL
|
|
3
|
+
* autonomous chain on a DISPOSABLE repo so Mason can SEE it before trusting it.
|
|
4
|
+
* See docs/contracts/CONTRACT-H8.md (BUILD ITEM 1).
|
|
5
|
+
*
|
|
6
|
+
* MILESTONE H8 "Harden & Prove" (FINAL). The demo adds NO new outward
|
|
7
|
+
* capability: it is the ONLY new runtime surface, and it is
|
|
8
|
+
* sandboxed/proposal-only/local + DISPOSABLE-repo-only with GUARANTEED
|
|
9
|
+
* auto-cleanup.
|
|
10
|
+
*
|
|
11
|
+
* H8 ABSOLUTE RULES (proven by test/h8.demo.test.ts + test/h8.no-new-outward.test.ts):
|
|
12
|
+
* - DEMO-DISPOSABLE-ONLY: the demo runs in an ISOLATED context (its OWN tmp
|
|
13
|
+
* ~/.ashlr via a relocated process.env.HOME) and enrolls/works ONLY a
|
|
14
|
+
* throwaway git repo under os.tmpdir(). It NEVER enrolls or touches the real
|
|
15
|
+
* portfolio or the real ~/.ashlr/enrollment.json ({repos:[]}).
|
|
16
|
+
* - DEMO-AUTO-CLEANS: the tmp repo + tmp ~/.ashlr are removed on success, on
|
|
17
|
+
* error, AND on interrupt (try/finally + a SIGINT/SIGTERM handler). Cleanup
|
|
18
|
+
* is idempotent + never throws. `--no-cleanup` keeps the tmp dir (still under
|
|
19
|
+
* os.tmpdir()) for inspection and prints its path.
|
|
20
|
+
* - DEMO-NEVER-APPLIES: the demo creates only a PENDING proposal; it NEVER
|
|
21
|
+
* approves/applies a proposal, NEVER pushes/PRs/deploys, and NEVER runs
|
|
22
|
+
* against a real repo. It imports NO apply/push/PR/deploy primitive — it
|
|
23
|
+
* points the human at `ashlr inbox` exactly as the daemon does.
|
|
24
|
+
* - DETERMINISTIC, NO LIVE MODEL REQUIRED: the demo works end-to-end with NO
|
|
25
|
+
* local model. When a local model IS reachable it MAY run a real sandboxed
|
|
26
|
+
* PROPOSAL-ONLY swarm (via the daemon's existing `tick({dryRun:false})`,
|
|
27
|
+
* which imports no apply/push/PR/deploy primitive); otherwise it runs the
|
|
28
|
+
* daemon tick dry-run + a deterministic stub PENDING proposal so a proposal
|
|
29
|
+
* always appears.
|
|
30
|
+
* - No new runtime deps; node builtins + existing modules only.
|
|
31
|
+
*
|
|
32
|
+
* Wiring: BUILD/INTEGRATION adds `case 'demo'` + a `loadDemoCmd` lazy loader in
|
|
33
|
+
* src/cli/index.ts + a cmdHelp entry.
|
|
34
|
+
*/
|
|
35
|
+
import { makeColors, isTty } from './ui.js';
|
|
36
|
+
import { makeDemoContext } from './demo-sandbox.js';
|
|
37
|
+
import { enroll, listEnrolled } from '../core/sandbox/policy.js';
|
|
38
|
+
import { buildBacklog } from '../core/portfolio/backlog.js';
|
|
39
|
+
import { tick } from '../core/daemon/loop.js';
|
|
40
|
+
import { probeEndpoint } from '../core/providers.js';
|
|
41
|
+
import { listProposals, createProposal } from '../core/inbox/store.js';
|
|
42
|
+
import { cmdInbox } from './inbox.js';
|
|
43
|
+
const { bold, dim, red, green, yellow, cyan } = makeColors(isTty());
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
// Narration helper — every demo step prints a numbered, colorized line so the
|
|
46
|
+
// human can WATCH the chain. Kept tiny + side-effect-only (console.log).
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
/**
|
|
49
|
+
* Print one narrated demo step. Exported so a test can assert the chain narrates
|
|
50
|
+
* each stage (enroll → backlog → tick → PENDING → inbox → cleanup) in order.
|
|
51
|
+
*/
|
|
52
|
+
export function narrateStep(n, title, detail) {
|
|
53
|
+
const head = ` ${cyan(String(n))}. ${bold(title)}`;
|
|
54
|
+
console.log(detail ? `${head} ${dim(detail)}` : head);
|
|
55
|
+
}
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
// cmdDemo — the dispatcher entry point
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
/**
|
|
60
|
+
* `ashlr demo` — watch the FULL autonomous chain run, safely.
|
|
61
|
+
*
|
|
62
|
+
* Walks + narrates each step on a DISPOSABLE repo inside an ISOLATED tmp
|
|
63
|
+
* ~/.ashlr (see {@link import('./demo-sandbox.js').makeDemoContext}):
|
|
64
|
+
* 1. isolate — relocate HOME to a fresh os.tmpdir() dir (assert it took effect)
|
|
65
|
+
* 2. seed — create a throwaway git repo with a `// TODO:` so work exists
|
|
66
|
+
* 3. enroll — enroll(tmpRepo) (the explicit gate — on the DISPOSABLE repo only)
|
|
67
|
+
* 4. backlog — buildBacklog({repos:[tmpRepo]}) (narrate the discovered TODO)
|
|
68
|
+
* 5. tick — tick(cfg,{dryRun}) [real proposal-only swarm IF a local model is
|
|
69
|
+
* up, else dry-run + a deterministic stub PENDING proposal]
|
|
70
|
+
* 6. pending — listProposals({status:'pending'}) (show the proposal — NOT applied)
|
|
71
|
+
* 7. inbox — cmdInbox (review only — the human gate; the demo NEVER approves)
|
|
72
|
+
* 8. rollback — unenroll + sweepRepoSandboxes (narrated; performed by dispose())
|
|
73
|
+
* 9. cleanup — FINALLY: dispose() the tmp context (rm -rf unless --no-cleanup)
|
|
74
|
+
*
|
|
75
|
+
* Flags:
|
|
76
|
+
* --no-cleanup keep the tmp dir (still under os.tmpdir()) for inspection.
|
|
77
|
+
* --json emit a structured trace of the steps instead of narration.
|
|
78
|
+
*
|
|
79
|
+
* GUARANTEED auto-cleanup: the whole chain runs inside a try/finally that calls
|
|
80
|
+
* dispose(), and a SIGINT/SIGTERM handler is installed so an interrupt also
|
|
81
|
+
* cleans up. Returns 0 on success, non-zero on error (after cleanup ran).
|
|
82
|
+
*
|
|
83
|
+
* @param args CLI args (`--no-cleanup`, `--json`).
|
|
84
|
+
* @param internal @internal test-only injection seam (never passed by the CLI).
|
|
85
|
+
*/
|
|
86
|
+
export async function cmdDemo(args, internal) {
|
|
87
|
+
const noCleanup = args.includes('--no-cleanup');
|
|
88
|
+
const asJson = args.includes('--json');
|
|
89
|
+
const steps = [];
|
|
90
|
+
let stepNo = 0;
|
|
91
|
+
// Record + narrate one step. In --json mode we stay quiet on stdout (the
|
|
92
|
+
// transcript is emitted once at the end) but still track the step.
|
|
93
|
+
const step = (name, title, detail) => {
|
|
94
|
+
stepNo += 1;
|
|
95
|
+
steps.push({ n: stepNo, step: name, detail });
|
|
96
|
+
if (!asJson)
|
|
97
|
+
narrateStep(stepNo, title, detail);
|
|
98
|
+
};
|
|
99
|
+
if (!asJson) {
|
|
100
|
+
console.log('');
|
|
101
|
+
console.log(bold('ashlr demo') +
|
|
102
|
+
dim(' — watch the full autonomous chain on a DISPOSABLE repo (proposal-only, auto-cleans)'));
|
|
103
|
+
console.log('');
|
|
104
|
+
}
|
|
105
|
+
// ── Step 1: isolate. Relocate HOME to a fresh tmp dir; assert it took effect.
|
|
106
|
+
// makeDemoContext throws (after restoring) if isolation did not engage, so
|
|
107
|
+
// we NEVER risk the real ~/.ashlr.
|
|
108
|
+
let ctx;
|
|
109
|
+
try {
|
|
110
|
+
ctx = makeDemoContext({ keep: noCleanup });
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
// Isolation failed BEFORE any state was touched — report + bail (exit 1).
|
|
114
|
+
if (!asJson) {
|
|
115
|
+
console.error(red('demo: could not establish an isolated tmp context: ' + String(err)));
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
console.log(JSON.stringify({ ok: false, error: String(err) }));
|
|
119
|
+
}
|
|
120
|
+
return 1;
|
|
121
|
+
}
|
|
122
|
+
// Install a signal handler so an interrupt (Ctrl-C / SIGTERM) ALSO cleans up.
|
|
123
|
+
// Declared here so the finally can remove it; INSTALLED inside the try below so
|
|
124
|
+
// that ANY throw after makeDemoContext() (which has already relocated HOME to
|
|
125
|
+
// the tmp dir) routes through the dispose() finally and never leaks tmp state.
|
|
126
|
+
let signalled = false;
|
|
127
|
+
const onSignal = () => {
|
|
128
|
+
signalled = true;
|
|
129
|
+
try {
|
|
130
|
+
ctx.dispose();
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
/* dispose is best-effort + idempotent */
|
|
134
|
+
}
|
|
135
|
+
// STOP the chain. process.once(...) suppresses Node's default
|
|
136
|
+
// terminate-on-signal, so we MUST exit ourselves — otherwise the awaited
|
|
137
|
+
// body would RESUME after dispose() restored the REAL HOME and the remaining
|
|
138
|
+
// steps (tick / createProposal / inbox / audit) would write into the REAL
|
|
139
|
+
// ~/.ashlr. Exiting here makes that impossible.
|
|
140
|
+
process.exit(130);
|
|
141
|
+
};
|
|
142
|
+
let liveModel = false;
|
|
143
|
+
let ok = false;
|
|
144
|
+
try {
|
|
145
|
+
// Narrate the first two (already-completed) steps + install the signal
|
|
146
|
+
// handler INSIDE the try, so any throw from here on — including from these
|
|
147
|
+
// narration calls or the listener install — routes through the dispose()
|
|
148
|
+
// finally with HOME still relocated to the tmp dir.
|
|
149
|
+
step('isolate', 'Isolate', `tmp HOME at ${ctx.home} (NOT your real ~/.ashlr)`);
|
|
150
|
+
step('seed', 'Seed disposable repo', `${ctx.repoDir} (a throwaway git repo with a // TODO:)`);
|
|
151
|
+
process.once('SIGINT', onSignal);
|
|
152
|
+
process.once('SIGTERM', onSignal);
|
|
153
|
+
// ── Step 3: enroll the DISPOSABLE repo (the explicit gate). Resolves state
|
|
154
|
+
// via homedir() at call time, so it writes ONLY into the isolated tmp
|
|
155
|
+
// ~/.ashlr and targets ONLY the throwaway repo — never a real path.
|
|
156
|
+
enroll(ctx.repoDir);
|
|
157
|
+
step('enroll', 'Enroll', `enrolled 1 disposable repo (${listEnrolled().length} total — NOT your portfolio)`);
|
|
158
|
+
// ── Step 4: backlog scan. Re-runs the REAL scanners over the tmp repo's
|
|
159
|
+
// working tree and finds the seeded // TODO:.
|
|
160
|
+
const backlog = await buildBacklog({ repos: [ctx.repoDir] });
|
|
161
|
+
const titles = backlog.items.map((i) => i.title);
|
|
162
|
+
step('backlog', 'Backlog scan', `discovered ${backlog.items.length} work item(s)` +
|
|
163
|
+
(titles.length > 0 ? `: ${titles.slice(0, 3).join('; ')}` : ''));
|
|
164
|
+
// ── Step 5: daemon tick. Determine the path by probing for a LOCAL model.
|
|
165
|
+
// probeEndpoint is local-only, 2s, never throws. With a model up we run
|
|
166
|
+
// the daemon's existing PROPOSAL-ONLY swarm (tick {dryRun:false}); with
|
|
167
|
+
// NO model we run the dry-run tick + synthesize a deterministic stub
|
|
168
|
+
// PENDING proposal so a proposal ALWAYS appears (the deterministic path
|
|
169
|
+
// the tests force).
|
|
170
|
+
const cfg = demoCfg();
|
|
171
|
+
const [lm, ol] = await Promise.all([
|
|
172
|
+
probeEndpoint('lmstudio', cfg.models.lmstudio),
|
|
173
|
+
probeEndpoint('ollama', cfg.models.ollama),
|
|
174
|
+
]);
|
|
175
|
+
liveModel = lm.up || ol.up;
|
|
176
|
+
if (liveModel) {
|
|
177
|
+
// Real sandboxed PROPOSAL-ONLY swarm — tick imports no apply/push/PR/deploy
|
|
178
|
+
// primitive (H1/H4 grep-guarded); the most it can do is emit a PENDING
|
|
179
|
+
// proposal. NEVER applies.
|
|
180
|
+
await tick(cfg, { dryRun: false });
|
|
181
|
+
step('tick', 'Daemon tick (LIVE swarm)', `local model reachable (${lm.up ? 'lmstudio' : 'ollama'}) → sandboxed PROPOSAL-ONLY swarm`);
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
// Deterministic no-model path: dry-run tick (touches nothing) + a stub
|
|
185
|
+
// PENDING proposal so the human still sees the inbox half of the chain.
|
|
186
|
+
await tick(cfg, { dryRun: true });
|
|
187
|
+
const seedTitle = titles[0] ?? 'demo: address the seeded TODO';
|
|
188
|
+
createProposal({
|
|
189
|
+
repo: ctx.repoDir,
|
|
190
|
+
origin: 'swarm',
|
|
191
|
+
kind: 'note',
|
|
192
|
+
title: `[demo] ${seedTitle}`,
|
|
193
|
+
summary: 'Deterministic demo stub: no local model was reachable, so the demo ' +
|
|
194
|
+
'synthesizes a single PENDING proposal to show the inbox-review + ' +
|
|
195
|
+
'rollback half of the chain. It is NEVER applied.',
|
|
196
|
+
});
|
|
197
|
+
step('tick', 'Daemon tick (no-model stub)', 'no local model reachable → dry-run tick + a deterministic stub PENDING proposal');
|
|
198
|
+
}
|
|
199
|
+
// ── Step 6: show the PENDING proposal — NOT applied.
|
|
200
|
+
const pending = listProposals({ status: 'pending' });
|
|
201
|
+
step('pending', 'PENDING proposal', `${pending.length} pending proposal(s) — ` +
|
|
202
|
+
(pending[0] ? `"${pending[0].title}" ` : '') +
|
|
203
|
+
green('NOT applied'));
|
|
204
|
+
// Test seam: inject a failure right before the inbox-review step to prove
|
|
205
|
+
// the try/finally ALWAYS cleans up. Never set by the CLI.
|
|
206
|
+
if (internal?.beforeInbox)
|
|
207
|
+
internal.beforeInbox();
|
|
208
|
+
// ── Step 7: inbox review (the human gate). cmdInbox renders against the
|
|
209
|
+
// ISOLATED inbox; the demo NEVER approves.
|
|
210
|
+
if (!asJson) {
|
|
211
|
+
console.log('');
|
|
212
|
+
console.log(' ' +
|
|
213
|
+
yellow('This is the human gate.') +
|
|
214
|
+
dim(' In real use YOU review + approve here. The demo NEVER approves.'));
|
|
215
|
+
await cmdInbox([]);
|
|
216
|
+
console.log('');
|
|
217
|
+
}
|
|
218
|
+
step('inbox', 'Inbox review', 'the human gate — in real use YOU approve here; the demo NEVER approves/applies');
|
|
219
|
+
// ── Step 8: narrate the rollback (performed by dispose() in the finally).
|
|
220
|
+
step('rollback', 'Rollback / cleanup', 'unenroll the tmp repo + sweep its sandboxes, then remove the tmp repo + tmp HOME');
|
|
221
|
+
ok = true;
|
|
222
|
+
}
|
|
223
|
+
finally {
|
|
224
|
+
// ── Step 9: GUARANTEED auto-cleanup — runs on success, on error, AND on a
|
|
225
|
+
// forced mid-run throw. dispose() is idempotent + never throws.
|
|
226
|
+
process.removeListener('SIGINT', onSignal);
|
|
227
|
+
process.removeListener('SIGTERM', onSignal);
|
|
228
|
+
if (!signalled) {
|
|
229
|
+
try {
|
|
230
|
+
ctx.dispose();
|
|
231
|
+
}
|
|
232
|
+
catch {
|
|
233
|
+
/* dispose is best-effort + idempotent */
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
// ── Final report.
|
|
238
|
+
if (asJson) {
|
|
239
|
+
const transcript = {
|
|
240
|
+
ok,
|
|
241
|
+
liveModel,
|
|
242
|
+
repoDir: ctx.repoDir,
|
|
243
|
+
kept: noCleanup,
|
|
244
|
+
steps,
|
|
245
|
+
};
|
|
246
|
+
console.log(JSON.stringify(transcript, null, 2));
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
console.log('');
|
|
250
|
+
if (noCleanup) {
|
|
251
|
+
console.log(' ' +
|
|
252
|
+
yellow('--no-cleanup:') +
|
|
253
|
+
` kept the tmp dir for inspection (still under os.tmpdir()): ${ctx.repoDir}`);
|
|
254
|
+
console.log(' ' + dim('(remove it yourself when done — it is a throwaway repo)'));
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
console.log(' ' + green('done') + dim(' — tmp repo + tmp ~/.ashlr removed; your real portfolio was never touched'));
|
|
258
|
+
}
|
|
259
|
+
console.log('');
|
|
260
|
+
}
|
|
261
|
+
return ok ? 0 : 1;
|
|
262
|
+
}
|
|
263
|
+
// ---------------------------------------------------------------------------
|
|
264
|
+
// demoCfg — a minimal, deterministic in-memory AshlrConfig for the demo tick.
|
|
265
|
+
// Conservative caps; constructed in memory (NOT loadConfig) so it never depends
|
|
266
|
+
// on config.ts's module-load CONFIG_DIR — keeping the demo isolated regardless
|
|
267
|
+
// of import order, exactly like the H1 fixture's makeCfg().
|
|
268
|
+
// ---------------------------------------------------------------------------
|
|
269
|
+
function demoCfg() {
|
|
270
|
+
return {
|
|
271
|
+
version: 1,
|
|
272
|
+
daemon: {
|
|
273
|
+
dailyBudgetUsd: 0.5,
|
|
274
|
+
perTickItems: 1,
|
|
275
|
+
parallel: 1,
|
|
276
|
+
intervalMs: 100,
|
|
277
|
+
},
|
|
278
|
+
models: {
|
|
279
|
+
lmstudio: 'http://localhost:1234',
|
|
280
|
+
ollama: 'http://localhost:11434',
|
|
281
|
+
providerChain: ['lmstudio', 'ollama'],
|
|
282
|
+
},
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
//# sourceMappingURL=demo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"demo.js","sourceRoot":"","sources":["../../src/cli/demo.ts"],"names":[],"mappings":"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"}
|