@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,618 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* loop.ts — The M24 daemon operator.
|
|
3
|
+
*
|
|
4
|
+
* Exports:
|
|
5
|
+
* - tick(cfg, opts): one operator cycle — check guards, load backlog, dispatch
|
|
6
|
+
* sandboxed swarms, create PENDING inbox proposals, record spend + state.
|
|
7
|
+
* - runDaemon(cfg, opts): loop ticks on an interval (or once); REFUSES when
|
|
8
|
+
* nested; marks running state; stops on kill switch / budget exhaustion.
|
|
9
|
+
* - stopDaemon(): set kill switch + clear running state.
|
|
10
|
+
*
|
|
11
|
+
* NON-NEGOTIABLE GUARDRAILS (enforced here, grep-provable):
|
|
12
|
+
* 1. PROPOSAL-ONLY: this file has NO outward-action path whatsoever. Its ONLY
|
|
13
|
+
* inbox output is a PENDING proposal, produced indirectly by the swarm
|
|
14
|
+
* runner when this file passes { propose: true } to runSwarm. A PENDING
|
|
15
|
+
* proposal is applied LATER only by an explicit human inbox approve.
|
|
16
|
+
* This file imports no apply/push/PR/deploy primitive.
|
|
17
|
+
* 2. ENROLLMENT-ONLY: operates exclusively on listEnrolled() repos.
|
|
18
|
+
* DEFAULT EMPTY => the daemon does NOTHING.
|
|
19
|
+
* 3. SANDBOXED: every runSwarm call sets opts.sandbox = true so all
|
|
20
|
+
* swarm work runs in an isolated git-worktree (M21).
|
|
21
|
+
* 4. BOUNDED: hard daily USD cap + per-tick item cap + concurrency cap.
|
|
22
|
+
* Resets per calendar day. NO unbounded loop — every iteration
|
|
23
|
+
* re-checks kill switch + budget.
|
|
24
|
+
* 5. RE-ENTRANCY: runDaemon REFUSES if ASHLR_IN_DAEMON or ASHLR_IN_SWARM
|
|
25
|
+
* is already set (no daemon-inside-daemon / daemon-inside-swarm fork bomb).
|
|
26
|
+
* Sets ASHLR_IN_DAEMON=1 on this process so child spawns inherit it.
|
|
27
|
+
*
|
|
28
|
+
* No new runtime deps; node builtins only; never throws out of public API.
|
|
29
|
+
*/
|
|
30
|
+
import { killSwitchOn, setKill, listEnrolled } from '../sandbox/policy.js';
|
|
31
|
+
import { audit } from '../sandbox/audit.js';
|
|
32
|
+
import { buildBacklog } from '../portfolio/backlog.js';
|
|
33
|
+
import { loadDaemonState, saveDaemonState, resetDayIfNeeded } from './state.js';
|
|
34
|
+
import { nullSink } from '../run/streaming.js';
|
|
35
|
+
import { runSwarm } from '../swarm/runner.js';
|
|
36
|
+
import { pendingCount } from '../inbox/store.js';
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
// DaemonConfig defaults (conservative)
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
const DEFAULTS = {
|
|
41
|
+
dailyBudgetUsd: 1.0, // $1/day hard cap by default
|
|
42
|
+
perTickItems: 3, // at most 3 backlog items per tick
|
|
43
|
+
parallel: 2, // at most 2 concurrent sandboxed swarms per tick
|
|
44
|
+
intervalMs: 5 * 60_000, // 5-minute tick interval in loop mode
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Merge the hard-coded defaults with any partial overrides in cfg.daemon.
|
|
48
|
+
* cfg.daemon grants NO authority — it only tunes caps.
|
|
49
|
+
*/
|
|
50
|
+
function resolveCfg(cfg) {
|
|
51
|
+
const o = cfg.daemon ?? {};
|
|
52
|
+
return {
|
|
53
|
+
dailyBudgetUsd: typeof o.dailyBudgetUsd === 'number' && o.dailyBudgetUsd > 0
|
|
54
|
+
? o.dailyBudgetUsd
|
|
55
|
+
: DEFAULTS.dailyBudgetUsd,
|
|
56
|
+
perTickItems: typeof o.perTickItems === 'number' && o.perTickItems > 0
|
|
57
|
+
? Math.floor(o.perTickItems)
|
|
58
|
+
: DEFAULTS.perTickItems,
|
|
59
|
+
parallel: typeof o.parallel === 'number' && o.parallel > 0
|
|
60
|
+
? Math.min(Math.floor(o.parallel), 8) // hard upper bound at 8
|
|
61
|
+
: DEFAULTS.parallel,
|
|
62
|
+
intervalMs: typeof o.intervalMs === 'number' && o.intervalMs > 0
|
|
63
|
+
? o.intervalMs
|
|
64
|
+
: DEFAULTS.intervalMs,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
// Bounded concurrency helper
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
/**
|
|
71
|
+
* Run `tasks` with at most `limit` in flight at once.
|
|
72
|
+
* Returns all settled results in input order.
|
|
73
|
+
* Never throws — individual task errors are captured in the PromiseSettledResult.
|
|
74
|
+
*/
|
|
75
|
+
async function bounded(tasks, limit) {
|
|
76
|
+
const results = new Array(tasks.length);
|
|
77
|
+
let nextIdx = 0;
|
|
78
|
+
async function worker() {
|
|
79
|
+
while (nextIdx < tasks.length) {
|
|
80
|
+
const idx = nextIdx++;
|
|
81
|
+
const fn = tasks[idx];
|
|
82
|
+
if (fn === undefined)
|
|
83
|
+
break;
|
|
84
|
+
try {
|
|
85
|
+
results[idx] = { status: 'fulfilled', value: await fn() };
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
results[idx] = { status: 'rejected', reason: err };
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
const slots = Math.max(1, Math.min(limit, tasks.length));
|
|
93
|
+
await Promise.all(Array.from({ length: slots }, () => worker()));
|
|
94
|
+
return results;
|
|
95
|
+
}
|
|
96
|
+
// ---------------------------------------------------------------------------
|
|
97
|
+
// tick — one operator cycle
|
|
98
|
+
// ---------------------------------------------------------------------------
|
|
99
|
+
/**
|
|
100
|
+
* One operator cycle. In order:
|
|
101
|
+
* 1. Kill-switch check.
|
|
102
|
+
* 2. Load + resetDayIfNeeded state; budget exhaustion check.
|
|
103
|
+
* 3. Enrollment check (DEFAULT EMPTY => do nothing).
|
|
104
|
+
* 4. Build/load backlog for enrolled repos.
|
|
105
|
+
* 5. Select top-K items within remaining budget.
|
|
106
|
+
* 6a. dryRun: describe what WOULD be worked; create NO proposals.
|
|
107
|
+
* 6b. else: for each selected item (bounded concurrency):
|
|
108
|
+
* runSwarm({ sandbox:true, propose:true }) => a PENDING inbox proposal
|
|
109
|
+
* is produced by the runner + tally spend.
|
|
110
|
+
* 7. Persist updated state; return tick record.
|
|
111
|
+
*
|
|
112
|
+
* Has NO outward-action path (no apply, no push, no PR, no deploy).
|
|
113
|
+
* Never throws.
|
|
114
|
+
*/
|
|
115
|
+
export async function tick(cfg, opts) {
|
|
116
|
+
const now = new Date().toISOString();
|
|
117
|
+
const dcfg = resolveCfg(cfg);
|
|
118
|
+
// Append a tick record to persisted state so every operator cycle (including
|
|
119
|
+
// no-op reasons like kill-switch / no-enrolled-repos / dry-run) is visible to
|
|
120
|
+
// `daemon status`, the TUI, and the web dashboard. Never throws.
|
|
121
|
+
const recordTick = (t) => {
|
|
122
|
+
try {
|
|
123
|
+
let s = loadDaemonState();
|
|
124
|
+
s = resetDayIfNeeded(s);
|
|
125
|
+
s.lastTickAt = t.ts;
|
|
126
|
+
s.ticks = [...s.ticks, t];
|
|
127
|
+
saveDaemonState(s);
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
// persistence best-effort — never let observability crash a tick
|
|
131
|
+
}
|
|
132
|
+
return t;
|
|
133
|
+
};
|
|
134
|
+
// -------------------------------------------------------------------------
|
|
135
|
+
// 1. Kill-switch check.
|
|
136
|
+
// -------------------------------------------------------------------------
|
|
137
|
+
if (killSwitchOn()) {
|
|
138
|
+
audit({
|
|
139
|
+
action: 'daemon:tick',
|
|
140
|
+
repo: null,
|
|
141
|
+
sandboxId: null,
|
|
142
|
+
summary: 'tick skipped: kill switch is ON',
|
|
143
|
+
result: 'ok',
|
|
144
|
+
});
|
|
145
|
+
return recordTick({
|
|
146
|
+
ts: now,
|
|
147
|
+
itemsConsidered: 0,
|
|
148
|
+
proposalsCreated: 0,
|
|
149
|
+
spentUsd: 0,
|
|
150
|
+
reason: 'kill-switch',
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
// -------------------------------------------------------------------------
|
|
154
|
+
// 2. Load state + daily reset + budget exhaustion check.
|
|
155
|
+
// -------------------------------------------------------------------------
|
|
156
|
+
let state = loadDaemonState();
|
|
157
|
+
state = resetDayIfNeeded(state);
|
|
158
|
+
const remainingBudget = dcfg.dailyBudgetUsd - state.todaySpentUsd;
|
|
159
|
+
if (remainingBudget <= 0) {
|
|
160
|
+
saveDaemonState(state);
|
|
161
|
+
audit({
|
|
162
|
+
action: 'daemon:tick',
|
|
163
|
+
repo: null,
|
|
164
|
+
sandboxId: null,
|
|
165
|
+
summary: `tick skipped: daily budget exhausted ($${state.todaySpentUsd.toFixed(4)} >= $${dcfg.dailyBudgetUsd})`,
|
|
166
|
+
result: 'ok',
|
|
167
|
+
});
|
|
168
|
+
return recordTick({
|
|
169
|
+
ts: now,
|
|
170
|
+
itemsConsidered: 0,
|
|
171
|
+
proposalsCreated: 0,
|
|
172
|
+
spentUsd: 0,
|
|
173
|
+
reason: 'budget-exhausted',
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
// -------------------------------------------------------------------------
|
|
177
|
+
// 3. Enrollment check — NEVER touch non-enrolled repos.
|
|
178
|
+
// -------------------------------------------------------------------------
|
|
179
|
+
const enrolled = listEnrolled();
|
|
180
|
+
if (enrolled.length === 0) {
|
|
181
|
+
saveDaemonState(state);
|
|
182
|
+
audit({
|
|
183
|
+
action: 'daemon:tick',
|
|
184
|
+
repo: null,
|
|
185
|
+
sandboxId: null,
|
|
186
|
+
summary: 'tick skipped: no repos enrolled (DEFAULT EMPTY)',
|
|
187
|
+
result: 'ok',
|
|
188
|
+
});
|
|
189
|
+
return recordTick({
|
|
190
|
+
ts: now,
|
|
191
|
+
itemsConsidered: 0,
|
|
192
|
+
proposalsCreated: 0,
|
|
193
|
+
spentUsd: 0,
|
|
194
|
+
reason: 'no-enrolled-repos',
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
// -------------------------------------------------------------------------
|
|
198
|
+
// 4. Build / refresh backlog for ENROLLED repos only.
|
|
199
|
+
// -------------------------------------------------------------------------
|
|
200
|
+
let backlogItems = [];
|
|
201
|
+
try {
|
|
202
|
+
const backlog = await buildBacklog({ repos: enrolled });
|
|
203
|
+
backlogItems = backlog.items;
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
// buildBacklog never throws by contract; extra guard
|
|
207
|
+
backlogItems = [];
|
|
208
|
+
}
|
|
209
|
+
if (backlogItems.length === 0) {
|
|
210
|
+
saveDaemonState(state);
|
|
211
|
+
audit({
|
|
212
|
+
action: 'daemon:tick',
|
|
213
|
+
repo: null,
|
|
214
|
+
sandboxId: null,
|
|
215
|
+
summary: 'tick skipped: backlog is empty for enrolled repos',
|
|
216
|
+
result: 'ok',
|
|
217
|
+
});
|
|
218
|
+
return recordTick({
|
|
219
|
+
ts: now,
|
|
220
|
+
itemsConsidered: 0,
|
|
221
|
+
proposalsCreated: 0,
|
|
222
|
+
spentUsd: 0,
|
|
223
|
+
reason: 'no-backlog',
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
// -------------------------------------------------------------------------
|
|
227
|
+
// 5. Select top-K items within the per-tick cap and remaining budget.
|
|
228
|
+
// Items are already sorted highest-score-first by buildBacklog.
|
|
229
|
+
// The real controls are: (a) the perTickItems cap, (b) the remaining daily
|
|
230
|
+
// USD budget, which bounds how many items can each get a minimal slice, and
|
|
231
|
+
// (c) the swarm's own internal token budget (the hard per-item ceiling).
|
|
232
|
+
// We cap the selected count by how many MIN_PER_ITEM_USD slices fit in the
|
|
233
|
+
// remaining budget, so a near-exhausted budget selects fewer items rather
|
|
234
|
+
// than authorizing the full perTickItems against a tiny remaining headroom.
|
|
235
|
+
// -------------------------------------------------------------------------
|
|
236
|
+
const MIN_PER_ITEM_USD = 0.01; // floor on a per-item slice for selection math
|
|
237
|
+
const maxByBudget = Math.max(1, Math.floor(remainingBudget / MIN_PER_ITEM_USD));
|
|
238
|
+
const selectCount = Math.min(dcfg.perTickItems, maxByBudget, backlogItems.length);
|
|
239
|
+
const selected = backlogItems.slice(0, selectCount);
|
|
240
|
+
// -------------------------------------------------------------------------
|
|
241
|
+
// 6a. Dry-run mode: report what WOULD be worked; NO swarms, NO proposals.
|
|
242
|
+
// -------------------------------------------------------------------------
|
|
243
|
+
if (opts.dryRun) {
|
|
244
|
+
saveDaemonState(state);
|
|
245
|
+
audit({
|
|
246
|
+
action: 'daemon:tick',
|
|
247
|
+
repo: null,
|
|
248
|
+
sandboxId: null,
|
|
249
|
+
summary: `dry-run: would work ${selected.length} item(s): ${selected.map(i => i.title).join(', ')}`,
|
|
250
|
+
result: 'ok',
|
|
251
|
+
});
|
|
252
|
+
return recordTick({
|
|
253
|
+
ts: now,
|
|
254
|
+
itemsConsidered: selected.length,
|
|
255
|
+
proposalsCreated: 0,
|
|
256
|
+
spentUsd: 0,
|
|
257
|
+
reason: 'dry-run',
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
// -------------------------------------------------------------------------
|
|
261
|
+
// 6b. Live mode: for each selected item (bounded concurrency), run a
|
|
262
|
+
// sandboxed swarm that records a PENDING inbox proposal.
|
|
263
|
+
//
|
|
264
|
+
// GUARDRAIL: each swarm call uses opts.sandbox=true (M21 worktree) so
|
|
265
|
+
// swarm work NEVER touches the user's working tree, plus opts.propose=true
|
|
266
|
+
// so the runner records the captured diff as a PENDING inbox proposal.
|
|
267
|
+
// This file has NO outward-action primitive of any kind; a PENDING
|
|
268
|
+
// proposal is applied LATER only by an explicit human inbox approve.
|
|
269
|
+
// -------------------------------------------------------------------------
|
|
270
|
+
// Shared, mutable in-tick spend tally. Read+incremented by each concurrent
|
|
271
|
+
// task so later dispatches can short-circuit once cumulative realized spend
|
|
272
|
+
// reaches the remaining daily headroom (the USD daily cap is otherwise only
|
|
273
|
+
// enforced BETWEEN ticks — this keeps a single tick from overshooting it).
|
|
274
|
+
let tickSpent = 0;
|
|
275
|
+
// Per-item USD budget slice: divide remaining budget evenly across items.
|
|
276
|
+
const perItemUsdSlice = remainingBudget / selected.length;
|
|
277
|
+
// Convert USD slice to a rough token count for the swarm budget.
|
|
278
|
+
// Using a conservative $15/M-output estimate as the binding constraint.
|
|
279
|
+
// This is best-effort estimation — the daemon's HARD cap is the USD daily budget.
|
|
280
|
+
const usdPerMTokenOut = 15.0;
|
|
281
|
+
const perItemMaxTokens = Math.max(1000, Math.floor((perItemUsdSlice / usdPerMTokenOut) * 1_000_000));
|
|
282
|
+
// Count proposals by the ACTUAL change in the inbox's PENDING count across the
|
|
283
|
+
// whole batch — NOT by inferring from swarmRun.status==='done'. A swarm that
|
|
284
|
+
// finished but recorded no proposal (e.g. a strict-sandbox abort, or an empty
|
|
285
|
+
// diff) must NEVER be mis-counted as a proposal. pendingCount() is read-only.
|
|
286
|
+
let pendingBefore = 0;
|
|
287
|
+
try {
|
|
288
|
+
pendingBefore = pendingCount();
|
|
289
|
+
}
|
|
290
|
+
catch {
|
|
291
|
+
pendingBefore = 0;
|
|
292
|
+
}
|
|
293
|
+
const tasks = selected.map((item) => async () => {
|
|
294
|
+
// Re-check kill switch before each item dispatch.
|
|
295
|
+
if (killSwitchOn()) {
|
|
296
|
+
return { item, spentUsd: 0, dispatched: false };
|
|
297
|
+
}
|
|
298
|
+
// In-tick budget short-circuit: if cumulative realized spend has already
|
|
299
|
+
// reached the remaining daily headroom, do NOT dispatch further items.
|
|
300
|
+
if (tickSpent >= remainingBudget) {
|
|
301
|
+
return { item, spentUsd: 0, dispatched: false };
|
|
302
|
+
}
|
|
303
|
+
let swarmSpent = 0;
|
|
304
|
+
let dispatched = false;
|
|
305
|
+
// Snapshot ASHLR_IN_SWARM and restore it after the call. The swarm runner
|
|
306
|
+
// sets ASHLR_IN_SWARM=1 on THIS (long-lived) process and does not unwind it;
|
|
307
|
+
// without this restore, the 2nd..Kth runSwarm in a tick — and every tick
|
|
308
|
+
// after the first in loop mode — would hit the recursion guard and refuse,
|
|
309
|
+
// silently neutering the daemon. Restoring keeps each dispatch clean while
|
|
310
|
+
// the runner's own child-spawn inheritance still works during the call.
|
|
311
|
+
const prevInSwarm = process.env['ASHLR_IN_SWARM'];
|
|
312
|
+
try {
|
|
313
|
+
const sink = nullSink();
|
|
314
|
+
dispatched = true;
|
|
315
|
+
const swarmRun = await runSwarm({ goal: `${item.title}\n\n${item.detail}`.trim() }, cfg, {
|
|
316
|
+
sandbox: true, // M21: isolated git-worktree — NEVER user's tree
|
|
317
|
+
requireSandbox: true, // M24: sandbox is MANDATORY — abort (zero tasks) if it can't be created; NEVER touch the real tree
|
|
318
|
+
propose: true, // M24: swarm records its diff as a PENDING inbox proposal
|
|
319
|
+
project: item.repo,
|
|
320
|
+
budget: {
|
|
321
|
+
maxTokens: perItemMaxTokens,
|
|
322
|
+
maxSteps: 100,
|
|
323
|
+
allowCloud: false, // local-first; no cloud spend by default
|
|
324
|
+
},
|
|
325
|
+
parallel: 1, // inner swarm parallelism kept minimal
|
|
326
|
+
dryRun: false,
|
|
327
|
+
noCapture: true, // genome capture not needed for daemon proposals
|
|
328
|
+
}, sink);
|
|
329
|
+
// Estimate actual spend from swarm usage and add it to the shared tally
|
|
330
|
+
// so concurrent/subsequent items see the up-to-date headroom.
|
|
331
|
+
swarmSpent = swarmRun.usage?.estCostUsd ?? 0;
|
|
332
|
+
tickSpent += swarmSpent;
|
|
333
|
+
audit({
|
|
334
|
+
action: 'daemon:proposal-created',
|
|
335
|
+
repo: item.repo,
|
|
336
|
+
sandboxId: null,
|
|
337
|
+
summary: `swarm ${swarmRun.id} finished (status=${swarmRun.status}, spent=$${swarmSpent.toFixed(4)}) for "${item.title}"`,
|
|
338
|
+
result: 'ok',
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
catch (err) {
|
|
342
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
343
|
+
audit({
|
|
344
|
+
action: 'daemon:swarm-error',
|
|
345
|
+
repo: item.repo,
|
|
346
|
+
sandboxId: null,
|
|
347
|
+
summary: `swarm failed for "${item.title}": ${msg.slice(0, 200)}`,
|
|
348
|
+
result: 'error',
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
finally {
|
|
352
|
+
// Restore ASHLR_IN_SWARM so the next dispatch / next tick is not refused.
|
|
353
|
+
if (prevInSwarm === undefined)
|
|
354
|
+
delete process.env['ASHLR_IN_SWARM'];
|
|
355
|
+
else
|
|
356
|
+
process.env['ASHLR_IN_SWARM'] = prevInSwarm;
|
|
357
|
+
}
|
|
358
|
+
return { item, spentUsd: swarmSpent, dispatched };
|
|
359
|
+
});
|
|
360
|
+
const outcomes = await bounded(tasks, dcfg.parallel);
|
|
361
|
+
// itemsProcessed counts items whose swarm was actually dispatched (not those
|
|
362
|
+
// skipped by the kill switch or the in-tick budget short-circuit).
|
|
363
|
+
let dispatchedCount = 0;
|
|
364
|
+
for (const outcome of outcomes) {
|
|
365
|
+
if (outcome.status === 'fulfilled' && outcome.value.dispatched) {
|
|
366
|
+
dispatchedCount++;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
// Proposals actually recorded this tick = the PENDING-count delta (clamped >=0).
|
|
370
|
+
let proposalsCreated = 0;
|
|
371
|
+
try {
|
|
372
|
+
proposalsCreated = Math.max(0, pendingCount() - pendingBefore);
|
|
373
|
+
}
|
|
374
|
+
catch {
|
|
375
|
+
proposalsCreated = 0;
|
|
376
|
+
}
|
|
377
|
+
// -------------------------------------------------------------------------
|
|
378
|
+
// 7. Update + persist state with this tick's accounting.
|
|
379
|
+
// -------------------------------------------------------------------------
|
|
380
|
+
state = loadDaemonState(); // reload in case of concurrent writes
|
|
381
|
+
state = resetDayIfNeeded(state); // re-check day rollover after async work
|
|
382
|
+
state.todaySpentUsd += tickSpent;
|
|
383
|
+
state.itemsProcessed += dispatchedCount;
|
|
384
|
+
state.lastTickAt = now;
|
|
385
|
+
const tickRecord = {
|
|
386
|
+
ts: now,
|
|
387
|
+
itemsConsidered: selected.length,
|
|
388
|
+
proposalsCreated,
|
|
389
|
+
spentUsd: tickSpent,
|
|
390
|
+
reason: 'ok',
|
|
391
|
+
};
|
|
392
|
+
state.ticks = [...state.ticks, tickRecord];
|
|
393
|
+
saveDaemonState(state);
|
|
394
|
+
audit({
|
|
395
|
+
action: 'daemon:tick',
|
|
396
|
+
repo: null,
|
|
397
|
+
sandboxId: null,
|
|
398
|
+
summary: `tick ok: ${selected.length} item(s) considered, ${proposalsCreated} proposal(s) created, $${tickSpent.toFixed(4)} spent`,
|
|
399
|
+
result: 'ok',
|
|
400
|
+
});
|
|
401
|
+
return tickRecord;
|
|
402
|
+
}
|
|
403
|
+
// ---------------------------------------------------------------------------
|
|
404
|
+
// runDaemon — the operator loop
|
|
405
|
+
// ---------------------------------------------------------------------------
|
|
406
|
+
/**
|
|
407
|
+
* Start the daemon operator.
|
|
408
|
+
*
|
|
409
|
+
* REFUSES (returns unchanged state) if ASHLR_IN_DAEMON or ASHLR_IN_SWARM is
|
|
410
|
+
* set — prevents daemon-inside-daemon and daemon-inside-swarm fork bombs.
|
|
411
|
+
*
|
|
412
|
+
* Sets ASHLR_IN_DAEMON=1 on this process.env so all child spawns inherit it.
|
|
413
|
+
*
|
|
414
|
+
* opts.once = true => run exactly one tick then stop.
|
|
415
|
+
* opts.once = false => loop: tick → sleep intervalMs → tick → ... until kill
|
|
416
|
+
* switch is set OR daily budget is exhausted.
|
|
417
|
+
* NO unbounded loop — every iteration re-checks both.
|
|
418
|
+
*
|
|
419
|
+
* Never throws.
|
|
420
|
+
*/
|
|
421
|
+
export async function runDaemon(cfg, opts) {
|
|
422
|
+
// -------------------------------------------------------------------------
|
|
423
|
+
// RE-ENTRANCY GUARD — must be the very first check.
|
|
424
|
+
// -------------------------------------------------------------------------
|
|
425
|
+
if (process.env['ASHLR_IN_DAEMON'] || process.env['ASHLR_IN_SWARM']) {
|
|
426
|
+
// Refuse silently — do not start; return current state unchanged.
|
|
427
|
+
return loadDaemonState();
|
|
428
|
+
}
|
|
429
|
+
// -------------------------------------------------------------------------
|
|
430
|
+
// Set ASHLR_IN_DAEMON=1 on THIS process so all child engine spawns inherit it.
|
|
431
|
+
// Snapshot the prior value so it can be restored on exit — without this a
|
|
432
|
+
// second in-process runDaemon call (programmatic reuse / tests) would hit the
|
|
433
|
+
// re-entrancy guard above and silently refuse forever.
|
|
434
|
+
// -------------------------------------------------------------------------
|
|
435
|
+
const prevInDaemon = process.env['ASHLR_IN_DAEMON'];
|
|
436
|
+
process.env['ASHLR_IN_DAEMON'] = '1';
|
|
437
|
+
const dcfg = resolveCfg(cfg);
|
|
438
|
+
// -------------------------------------------------------------------------
|
|
439
|
+
// Mark daemon as running.
|
|
440
|
+
// -------------------------------------------------------------------------
|
|
441
|
+
let state = loadDaemonState();
|
|
442
|
+
state = resetDayIfNeeded(state);
|
|
443
|
+
state.running = true;
|
|
444
|
+
state.pid = process.pid;
|
|
445
|
+
state.startedAt = new Date().toISOString();
|
|
446
|
+
saveDaemonState(state);
|
|
447
|
+
audit({
|
|
448
|
+
action: 'daemon:start',
|
|
449
|
+
repo: null,
|
|
450
|
+
sandboxId: null,
|
|
451
|
+
summary: `daemon started: once=${opts.once}, dryRun=${opts.dryRun}, budget=$${dcfg.dailyBudgetUsd}, intervalMs=${dcfg.intervalMs}`,
|
|
452
|
+
result: 'ok',
|
|
453
|
+
});
|
|
454
|
+
// -------------------------------------------------------------------------
|
|
455
|
+
// H5 CHANGE 1 — WIRE THE ORPHAN SWEEP (crash-leftover reclaim).
|
|
456
|
+
// On daemon start, BEFORE the first tick, reclaim crash-leftover worktrees with
|
|
457
|
+
// a conservative staleMs GREATER than the max swarm wall-clock (ORPHAN_STALE_MS,
|
|
458
|
+
// shared from worktree.ts) so a LIVE in-flight worktree younger than staleMs is
|
|
459
|
+
// NEVER reclaimed — only genuine crash leftovers are swept. Inward cleanup only:
|
|
460
|
+
// sweepOrphanSandboxes routes every removal through removeSandbox, inheriting its
|
|
461
|
+
// containment guards verbatim (re-derived safe path + branch; a tampered/out-of-
|
|
462
|
+
// namespace entry falls through to local-dir cleanup only). It pushes nothing,
|
|
463
|
+
// opens no PR, applies no proposal — it is purely inward worktree reclaim. The
|
|
464
|
+
// worktree module is LAZY-imported so the daemon's STATIC outward-primitive
|
|
465
|
+
// grep-guards stay intact, and the whole thing is wrapped so a sweep failure
|
|
466
|
+
// NEVER throws out of runDaemon. Audited via the daemon:start surface.
|
|
467
|
+
//
|
|
468
|
+
// DRY-RUN = ZERO SIDE EFFECTS: the sweep performs real destructive on-disk git
|
|
469
|
+
// ops (`git worktree remove --force` / `git branch -D` via removeSandbox), so
|
|
470
|
+
// in dry-run mode we SKIP the actual reclaim and instead audit a PREVIEW of
|
|
471
|
+
// what WOULD be reclaimed (count only, via a guarded staleMs-eligible probe),
|
|
472
|
+
// honoring the strict 'dry-run mutates nothing' expectation that the rest of
|
|
473
|
+
// loop.ts upholds (it creates no proposals / makes no outward changes). A
|
|
474
|
+
// normal (non-dry) start reclaims for real. Documented in docs/contracts/CONTRACT-H5.md.
|
|
475
|
+
if (opts.dryRun) {
|
|
476
|
+
// Dry-run previews the loop WITHOUT mutating disk: skip the real reclaim and
|
|
477
|
+
// audit only the count that WOULD be reclaimed (a read-only listSandboxes()
|
|
478
|
+
// count; the actual liveness/age filtering happens for real on a non-dry
|
|
479
|
+
// start). This keeps `daemon start --dry-run` side-effect-free.
|
|
480
|
+
try {
|
|
481
|
+
const wt = await import('../sandbox/worktree.js');
|
|
482
|
+
const wouldConsider = wt.listSandboxes().length;
|
|
483
|
+
audit({
|
|
484
|
+
action: 'daemon:start',
|
|
485
|
+
repo: null,
|
|
486
|
+
sandboxId: null,
|
|
487
|
+
summary: `dry-run: orphan sweep skipped (${wouldConsider} sandbox(es) on disk; none swept)`,
|
|
488
|
+
result: 'ok',
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
catch {
|
|
492
|
+
// Best-effort: a preview failure must never crash daemon start.
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
else {
|
|
496
|
+
try {
|
|
497
|
+
const wt = await import('../sandbox/worktree.js');
|
|
498
|
+
const swept = wt.sweepOrphanSandboxes({ staleMs: wt.ORPHAN_STALE_MS });
|
|
499
|
+
audit({
|
|
500
|
+
action: 'daemon:start',
|
|
501
|
+
repo: null,
|
|
502
|
+
sandboxId: null,
|
|
503
|
+
summary: `orphan sweep reclaimed ${swept.length} sandbox(es)${swept.length ? `: ${swept.join(', ')}` : ''}`,
|
|
504
|
+
result: 'ok',
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
catch {
|
|
508
|
+
// Best-effort: a sweep failure must never crash daemon start.
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
try {
|
|
512
|
+
if (opts.once) {
|
|
513
|
+
// Single-tick mode.
|
|
514
|
+
await tick(cfg, { dryRun: opts.dryRun });
|
|
515
|
+
}
|
|
516
|
+
else {
|
|
517
|
+
// Loop mode: every iteration re-checks kill switch + budget. NOT unbounded.
|
|
518
|
+
while (true) {
|
|
519
|
+
// Kill switch check — halt immediately.
|
|
520
|
+
if (killSwitchOn())
|
|
521
|
+
break;
|
|
522
|
+
// Budget check — halt when daily cap exhausted.
|
|
523
|
+
const current = loadDaemonState();
|
|
524
|
+
const recheckCfg = resolveCfg(cfg);
|
|
525
|
+
if (current.todaySpentUsd >= recheckCfg.dailyBudgetUsd)
|
|
526
|
+
break;
|
|
527
|
+
// Run one tick.
|
|
528
|
+
await tick(cfg, { dryRun: opts.dryRun });
|
|
529
|
+
// Dry-run is inherently a one-shot PLAN: it records spentUsd:0 forever,
|
|
530
|
+
// so the budget break can never fire. Terminate after a single iteration
|
|
531
|
+
// (matching --once semantics) so a dry-run loop is BOUNDED, not endless.
|
|
532
|
+
if (opts.dryRun)
|
|
533
|
+
break;
|
|
534
|
+
// Re-check kill switch + budget after the tick before sleeping.
|
|
535
|
+
if (killSwitchOn())
|
|
536
|
+
break;
|
|
537
|
+
const afterTick = loadDaemonState();
|
|
538
|
+
if (afterTick.todaySpentUsd >= recheckCfg.dailyBudgetUsd)
|
|
539
|
+
break;
|
|
540
|
+
// Sleep between ticks using a bounded interval.
|
|
541
|
+
await sleep(dcfg.intervalMs);
|
|
542
|
+
// Final kill-switch check after sleep (in case stop() was called while sleeping).
|
|
543
|
+
if (killSwitchOn())
|
|
544
|
+
break;
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
catch {
|
|
549
|
+
// Unexpected error — swallow; still clean up running state below.
|
|
550
|
+
}
|
|
551
|
+
// -------------------------------------------------------------------------
|
|
552
|
+
// Clear running state on exit.
|
|
553
|
+
// -------------------------------------------------------------------------
|
|
554
|
+
state = loadDaemonState();
|
|
555
|
+
state.running = false;
|
|
556
|
+
state.pid = null;
|
|
557
|
+
saveDaemonState(state);
|
|
558
|
+
audit({
|
|
559
|
+
action: 'daemon:stop',
|
|
560
|
+
repo: null,
|
|
561
|
+
sandboxId: null,
|
|
562
|
+
summary: 'daemon stopped',
|
|
563
|
+
result: 'ok',
|
|
564
|
+
});
|
|
565
|
+
// Restore ASHLR_IN_DAEMON to its prior value so a fresh runDaemon can run
|
|
566
|
+
// again in the same process (a CLI process exits anyway; this matters for
|
|
567
|
+
// programmatic reuse / tests). Child spawns already inherited it during the run.
|
|
568
|
+
if (prevInDaemon === undefined)
|
|
569
|
+
delete process.env['ASHLR_IN_DAEMON'];
|
|
570
|
+
else
|
|
571
|
+
process.env['ASHLR_IN_DAEMON'] = prevInDaemon;
|
|
572
|
+
return loadDaemonState();
|
|
573
|
+
}
|
|
574
|
+
// ---------------------------------------------------------------------------
|
|
575
|
+
// stopDaemon — halt the operator
|
|
576
|
+
// ---------------------------------------------------------------------------
|
|
577
|
+
/**
|
|
578
|
+
* Set the kill switch (M21 ~/.ashlr/KILL) AND mark running=false, pid=null in
|
|
579
|
+
* persisted state. Idempotent; never throws. A running loop sees the kill
|
|
580
|
+
* switch on the next iteration and stops cleanly.
|
|
581
|
+
*/
|
|
582
|
+
export function stopDaemon() {
|
|
583
|
+
try {
|
|
584
|
+
setKill(true);
|
|
585
|
+
}
|
|
586
|
+
catch {
|
|
587
|
+
// setKill is idempotent + never throws by contract; extra guard
|
|
588
|
+
}
|
|
589
|
+
try {
|
|
590
|
+
const state = loadDaemonState();
|
|
591
|
+
state.running = false;
|
|
592
|
+
state.pid = null;
|
|
593
|
+
saveDaemonState(state);
|
|
594
|
+
}
|
|
595
|
+
catch {
|
|
596
|
+
// Persistence failure — swallow; kill switch was already set above
|
|
597
|
+
}
|
|
598
|
+
try {
|
|
599
|
+
audit({
|
|
600
|
+
action: 'daemon:stop',
|
|
601
|
+
repo: null,
|
|
602
|
+
sandboxId: null,
|
|
603
|
+
summary: 'stopDaemon() called: kill switch set + running=false',
|
|
604
|
+
result: 'ok',
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
catch {
|
|
608
|
+
// Audit best-effort
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
// ---------------------------------------------------------------------------
|
|
612
|
+
// Internal helpers
|
|
613
|
+
// ---------------------------------------------------------------------------
|
|
614
|
+
/** Promise-based sleep (bounded; never less than 0ms). */
|
|
615
|
+
function sleep(ms) {
|
|
616
|
+
return new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));
|
|
617
|
+
}
|
|
618
|
+
//# sourceMappingURL=loop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loop.js","sourceRoot":"","sources":["../../../src/core/daemon/loop.ts"],"names":[],"mappings":"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"}
|