looply-cli 0.0.0-stage → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +137 -3
- package/dist/.src-hash +1 -0
- package/dist/acceptance-observe.d.ts +108 -0
- package/dist/acceptance-observe.d.ts.map +1 -0
- package/dist/acceptance-observe.js +152 -0
- package/dist/acceptance-observe.js.map +1 -0
- package/dist/agent-cmd.d.ts +131 -0
- package/dist/agent-cmd.d.ts.map +1 -0
- package/dist/agent-cmd.js +154 -0
- package/dist/agent-cmd.js.map +1 -0
- package/dist/agent-contained.d.ts +114 -0
- package/dist/agent-contained.d.ts.map +1 -0
- package/dist/agent-contained.js +292 -0
- package/dist/agent-contained.js.map +1 -0
- package/dist/agent-driver.d.ts +130 -0
- package/dist/agent-driver.d.ts.map +1 -0
- package/dist/agent-driver.js +170 -0
- package/dist/agent-driver.js.map +1 -0
- package/dist/agent-envelope.d.ts +94 -0
- package/dist/agent-envelope.d.ts.map +1 -0
- package/dist/agent-envelope.js +214 -0
- package/dist/agent-envelope.js.map +1 -0
- package/dist/agent-exec.d.ts +182 -0
- package/dist/agent-exec.d.ts.map +1 -0
- package/dist/agent-exec.js +125 -0
- package/dist/agent-exec.js.map +1 -0
- package/dist/agent-runtime.d.ts +23 -0
- package/dist/agent-runtime.d.ts.map +1 -0
- package/dist/agent-runtime.js +143 -0
- package/dist/agent-runtime.js.map +1 -0
- package/dist/approval-gate-read.d.ts +66 -0
- package/dist/approval-gate-read.d.ts.map +1 -0
- package/dist/approval-gate-read.js +138 -0
- package/dist/approval-gate-read.js.map +1 -0
- package/dist/approval-resolution.d.ts +87 -0
- package/dist/approval-resolution.d.ts.map +1 -0
- package/dist/approval-resolution.js +100 -0
- package/dist/approval-resolution.js.map +1 -0
- package/dist/approval-resumes.d.ts +102 -0
- package/dist/approval-resumes.d.ts.map +1 -0
- package/dist/approval-resumes.js +167 -0
- package/dist/approval-resumes.js.map +1 -0
- package/dist/ask-brain.d.ts +167 -0
- package/dist/ask-brain.d.ts.map +1 -0
- package/dist/ask-brain.js +355 -0
- package/dist/ask-brain.js.map +1 -0
- package/dist/autonomy-authority.d.ts +80 -0
- package/dist/autonomy-authority.d.ts.map +1 -0
- package/dist/autonomy-authority.js +82 -0
- package/dist/autonomy-authority.js.map +1 -0
- package/dist/autonomy-controller.d.ts +321 -0
- package/dist/autonomy-controller.d.ts.map +1 -0
- package/dist/autonomy-controller.js +517 -0
- package/dist/autonomy-controller.js.map +1 -0
- package/dist/autonomy-store.d.ts +327 -0
- package/dist/autonomy-store.d.ts.map +1 -0
- package/dist/autonomy-store.js +581 -0
- package/dist/autonomy-store.js.map +1 -0
- package/dist/autonomy-tick.d.ts +257 -0
- package/dist/autonomy-tick.d.ts.map +1 -0
- package/dist/autonomy-tick.js +616 -0
- package/dist/autonomy-tick.js.map +1 -0
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +2727 -0
- package/dist/bin.js.map +1 -0
- package/dist/brain-advice.d.ts +21 -0
- package/dist/brain-advice.d.ts.map +1 -0
- package/dist/brain-advice.js +51 -0
- package/dist/brain-advice.js.map +1 -0
- package/dist/candidate-replay-runtime.d.ts +125 -0
- package/dist/candidate-replay-runtime.d.ts.map +1 -0
- package/dist/candidate-replay-runtime.js +188 -0
- package/dist/candidate-replay-runtime.js.map +1 -0
- package/dist/checkout-carry.d.ts +76 -0
- package/dist/checkout-carry.d.ts.map +1 -0
- package/dist/checkout-carry.js +125 -0
- package/dist/checkout-carry.js.map +1 -0
- package/dist/citation-readers.d.ts +26 -0
- package/dist/citation-readers.d.ts.map +1 -0
- package/dist/citation-readers.js +102 -0
- package/dist/citation-readers.js.map +1 -0
- package/dist/command-receipts.d.ts +79 -0
- package/dist/command-receipts.d.ts.map +1 -0
- package/dist/command-receipts.js +143 -0
- package/dist/command-receipts.js.map +1 -0
- package/dist/command-runner.d.ts +32 -0
- package/dist/command-runner.d.ts.map +1 -0
- package/dist/command-runner.js +108 -0
- package/dist/command-runner.js.map +1 -0
- package/dist/compatible-sets.d.ts +67 -0
- package/dist/compatible-sets.d.ts.map +1 -0
- package/dist/compatible-sets.js +81 -0
- package/dist/compatible-sets.js.map +1 -0
- package/dist/compile-check.d.ts +31 -0
- package/dist/compile-check.d.ts.map +1 -0
- package/dist/compile-check.js +34 -0
- package/dist/compile-check.js.map +1 -0
- package/dist/compile-store.d.ts +16 -0
- package/dist/compile-store.d.ts.map +1 -0
- package/dist/compile-store.js +21 -0
- package/dist/compile-store.js.map +1 -0
- package/dist/completion.d.ts +106 -0
- package/dist/completion.d.ts.map +1 -0
- package/dist/completion.js +131 -0
- package/dist/completion.js.map +1 -0
- package/dist/config.d.ts +549 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +763 -0
- package/dist/config.js.map +1 -0
- package/dist/control-file.d.ts +142 -0
- package/dist/control-file.d.ts.map +1 -0
- package/dist/control-file.js +144 -0
- package/dist/control-file.js.map +1 -0
- package/dist/coordinator-state.d.ts +131 -0
- package/dist/coordinator-state.d.ts.map +1 -0
- package/dist/coordinator-state.js +380 -0
- package/dist/coordinator-state.js.map +1 -0
- package/dist/coordinator.d.ts +95 -0
- package/dist/coordinator.d.ts.map +1 -0
- package/dist/coordinator.js +97 -0
- package/dist/coordinator.js.map +1 -0
- package/dist/cursor-store.d.ts +53 -0
- package/dist/cursor-store.d.ts.map +1 -0
- package/dist/cursor-store.js +98 -0
- package/dist/cursor-store.js.map +1 -0
- package/dist/daemon-cmd.d.ts +239 -0
- package/dist/daemon-cmd.d.ts.map +1 -0
- package/dist/daemon-cmd.js +1751 -0
- package/dist/daemon-cmd.js.map +1 -0
- package/dist/daemon-lock.d.ts +140 -0
- package/dist/daemon-lock.d.ts.map +1 -0
- package/dist/daemon-lock.js +352 -0
- package/dist/daemon-lock.js.map +1 -0
- package/dist/daemon-recovery.d.ts +78 -0
- package/dist/daemon-recovery.d.ts.map +1 -0
- package/dist/daemon-recovery.js +161 -0
- package/dist/daemon-recovery.js.map +1 -0
- package/dist/daemon.d.ts +368 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +601 -0
- package/dist/daemon.js.map +1 -0
- package/dist/declared-response-shape.d.ts +93 -0
- package/dist/declared-response-shape.d.ts.map +1 -0
- package/dist/declared-response-shape.js +200 -0
- package/dist/declared-response-shape.js.map +1 -0
- package/dist/declared-surfaces.d.ts +16 -0
- package/dist/declared-surfaces.d.ts.map +1 -0
- package/dist/declared-surfaces.js +19 -0
- package/dist/declared-surfaces.js.map +1 -0
- package/dist/depends-review.d.ts +113 -0
- package/dist/depends-review.d.ts.map +1 -0
- package/dist/depends-review.js +110 -0
- package/dist/depends-review.js.map +1 -0
- package/dist/doctor.d.ts +91 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +71 -0
- package/dist/doctor.js.map +1 -0
- package/dist/edge-approval.d.ts +105 -0
- package/dist/edge-approval.d.ts.map +1 -0
- package/dist/edge-approval.js +100 -0
- package/dist/edge-approval.js.map +1 -0
- package/dist/evidence-cache.d.ts +45 -0
- package/dist/evidence-cache.d.ts.map +1 -0
- package/dist/evidence-cache.js +90 -0
- package/dist/evidence-cache.js.map +1 -0
- package/dist/evidence-cmd.d.ts +133 -0
- package/dist/evidence-cmd.d.ts.map +1 -0
- package/dist/evidence-cmd.js +347 -0
- package/dist/evidence-cmd.js.map +1 -0
- package/dist/evidence-facts.d.ts +40 -0
- package/dist/evidence-facts.d.ts.map +1 -0
- package/dist/evidence-facts.js +114 -0
- package/dist/evidence-facts.js.map +1 -0
- package/dist/exclusive-lock.d.ts +52 -0
- package/dist/exclusive-lock.d.ts.map +1 -0
- package/dist/exclusive-lock.js +150 -0
- package/dist/exclusive-lock.js.map +1 -0
- package/dist/exec-domains.d.ts +140 -0
- package/dist/exec-domains.d.ts.map +1 -0
- package/dist/exec-domains.js +287 -0
- package/dist/exec-domains.js.map +1 -0
- package/dist/exemption-store.d.ts +197 -0
- package/dist/exemption-store.d.ts.map +1 -0
- package/dist/exemption-store.js +266 -0
- package/dist/exemption-store.js.map +1 -0
- package/dist/explicit-start-gate.d.ts +96 -0
- package/dist/explicit-start-gate.d.ts.map +1 -0
- package/dist/explicit-start-gate.js +103 -0
- package/dist/explicit-start-gate.js.map +1 -0
- package/dist/fs-trouble.d.ts +70 -0
- package/dist/fs-trouble.d.ts.map +1 -0
- package/dist/fs-trouble.js +98 -0
- package/dist/fs-trouble.js.map +1 -0
- package/dist/gate.d.ts +278 -0
- package/dist/gate.d.ts.map +1 -0
- package/dist/gate.js +278 -0
- package/dist/gate.js.map +1 -0
- package/dist/git-driver.d.ts +519 -0
- package/dist/git-driver.d.ts.map +1 -0
- package/dist/git-driver.js +900 -0
- package/dist/git-driver.js.map +1 -0
- package/dist/git-push-executor.d.ts +41 -0
- package/dist/git-push-executor.d.ts.map +1 -0
- package/dist/git-push-executor.js +142 -0
- package/dist/git-push-executor.js.map +1 -0
- package/dist/glob.d.ts +26 -0
- package/dist/glob.d.ts.map +1 -0
- package/dist/glob.js +93 -0
- package/dist/glob.js.map +1 -0
- package/dist/goal-adaptive.d.ts +295 -0
- package/dist/goal-adaptive.d.ts.map +1 -0
- package/dist/goal-adaptive.js +393 -0
- package/dist/goal-adaptive.js.map +1 -0
- package/dist/goal-compile.d.ts +342 -0
- package/dist/goal-compile.d.ts.map +1 -0
- package/dist/goal-compile.js +444 -0
- package/dist/goal-compile.js.map +1 -0
- package/dist/goal-depends-executor.d.ts +55 -0
- package/dist/goal-depends-executor.d.ts.map +1 -0
- package/dist/goal-depends-executor.js +202 -0
- package/dist/goal-depends-executor.js.map +1 -0
- package/dist/goal-execution-evidence.d.ts +135 -0
- package/dist/goal-execution-evidence.d.ts.map +1 -0
- package/dist/goal-execution-evidence.js +159 -0
- package/dist/goal-execution-evidence.js.map +1 -0
- package/dist/goal-gap.d.ts +140 -0
- package/dist/goal-gap.d.ts.map +1 -0
- package/dist/goal-gap.js +197 -0
- package/dist/goal-gap.js.map +1 -0
- package/dist/goal-met-target.d.ts +98 -0
- package/dist/goal-met-target.d.ts.map +1 -0
- package/dist/goal-met-target.js +92 -0
- package/dist/goal-met-target.js.map +1 -0
- package/dist/goal-ownership.d.ts +416 -0
- package/dist/goal-ownership.d.ts.map +1 -0
- package/dist/goal-ownership.js +576 -0
- package/dist/goal-ownership.js.map +1 -0
- package/dist/goal-runs.d.ts +82 -0
- package/dist/goal-runs.d.ts.map +1 -0
- package/dist/goal-runs.js +120 -0
- package/dist/goal-runs.js.map +1 -0
- package/dist/goal-store.d.ts +146 -0
- package/dist/goal-store.d.ts.map +1 -0
- package/dist/goal-store.js +294 -0
- package/dist/goal-store.js.map +1 -0
- package/dist/goal-view.d.ts +156 -0
- package/dist/goal-view.d.ts.map +1 -0
- package/dist/goal-view.js +499 -0
- package/dist/goal-view.js.map +1 -0
- package/dist/governed-approvals.d.ts +152 -0
- package/dist/governed-approvals.d.ts.map +1 -0
- package/dist/governed-approvals.js +246 -0
- package/dist/governed-approvals.js.map +1 -0
- package/dist/governed-broker.d.ts +169 -0
- package/dist/governed-broker.d.ts.map +1 -0
- package/dist/governed-broker.js +196 -0
- package/dist/governed-broker.js.map +1 -0
- package/dist/governed-run.d.ts +220 -0
- package/dist/governed-run.d.ts.map +1 -0
- package/dist/governed-run.js +406 -0
- package/dist/governed-run.js.map +1 -0
- package/dist/grant-reconcile.d.ts +63 -0
- package/dist/grant-reconcile.d.ts.map +1 -0
- package/dist/grant-reconcile.js +121 -0
- package/dist/grant-reconcile.js.map +1 -0
- package/dist/index-for-head.d.ts +56 -0
- package/dist/index-for-head.d.ts.map +1 -0
- package/dist/index-for-head.js +103 -0
- package/dist/index-for-head.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +55 -0
- package/dist/index.js.map +1 -0
- package/dist/init-detect.d.ts +39 -0
- package/dist/init-detect.d.ts.map +1 -0
- package/dist/init-detect.js +188 -0
- package/dist/init-detect.js.map +1 -0
- package/dist/integration-deps.d.ts +62 -0
- package/dist/integration-deps.d.ts.map +1 -0
- package/dist/integration-deps.js +251 -0
- package/dist/integration-deps.js.map +1 -0
- package/dist/integration-runtime.d.ts +458 -0
- package/dist/integration-runtime.d.ts.map +1 -0
- package/dist/integration-runtime.js +681 -0
- package/dist/integration-runtime.js.map +1 -0
- package/dist/integration.d.ts +45 -0
- package/dist/integration.d.ts.map +1 -0
- package/dist/integration.js +87 -0
- package/dist/integration.js.map +1 -0
- package/dist/integrator.d.ts +84 -0
- package/dist/integrator.d.ts.map +1 -0
- package/dist/integrator.js +193 -0
- package/dist/integrator.js.map +1 -0
- package/dist/lane-claims.d.ts +174 -0
- package/dist/lane-claims.d.ts.map +1 -0
- package/dist/lane-claims.js +218 -0
- package/dist/lane-claims.js.map +1 -0
- package/dist/lane-coverage.d.ts +87 -0
- package/dist/lane-coverage.d.ts.map +1 -0
- package/dist/lane-coverage.js +129 -0
- package/dist/lane-coverage.js.map +1 -0
- package/dist/ledger-replay.d.ts +115 -0
- package/dist/ledger-replay.d.ts.map +1 -0
- package/dist/ledger-replay.js +155 -0
- package/dist/ledger-replay.js.map +1 -0
- package/dist/ledger-store.d.ts +68 -0
- package/dist/ledger-store.d.ts.map +1 -0
- package/dist/ledger-store.js +111 -0
- package/dist/ledger-store.js.map +1 -0
- package/dist/loop-safety-observer.d.ts +132 -0
- package/dist/loop-safety-observer.d.ts.map +1 -0
- package/dist/loop-safety-observer.js +76 -0
- package/dist/loop-safety-observer.js.map +1 -0
- package/dist/loop-safety-store.d.ts +339 -0
- package/dist/loop-safety-store.d.ts.map +1 -0
- package/dist/loop-safety-store.js +800 -0
- package/dist/loop-safety-store.js.map +1 -0
- package/dist/machine-store.d.ts +54 -0
- package/dist/machine-store.d.ts.map +1 -0
- package/dist/machine-store.js +149 -0
- package/dist/machine-store.js.map +1 -0
- package/dist/mcp-main.d.ts +2 -0
- package/dist/mcp-main.d.ts.map +1 -0
- package/dist/mcp-main.js +116 -0
- package/dist/mcp-main.js.map +1 -0
- package/dist/mcp-server.d.ts +72 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +259 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/model-routing.d.ts +75 -0
- package/dist/model-routing.d.ts.map +1 -0
- package/dist/model-routing.js +108 -0
- package/dist/model-routing.js.map +1 -0
- package/dist/model-transport.d.ts +188 -0
- package/dist/model-transport.d.ts.map +1 -0
- package/dist/model-transport.js +625 -0
- package/dist/model-transport.js.map +1 -0
- package/dist/notify-cadence.d.ts +55 -0
- package/dist/notify-cadence.d.ts.map +1 -0
- package/dist/notify-cadence.js +68 -0
- package/dist/notify-cadence.js.map +1 -0
- package/dist/notify-channel.d.ts +69 -0
- package/dist/notify-channel.d.ts.map +1 -0
- package/dist/notify-channel.js +151 -0
- package/dist/notify-channel.js.map +1 -0
- package/dist/notify.d.ts +71 -0
- package/dist/notify.d.ts.map +1 -0
- package/dist/notify.js +125 -0
- package/dist/notify.js.map +1 -0
- package/dist/observation-inventory.d.ts +65 -0
- package/dist/observation-inventory.d.ts.map +1 -0
- package/dist/observation-inventory.js +139 -0
- package/dist/observation-inventory.js.map +1 -0
- package/dist/owned-children.d.ts +45 -0
- package/dist/owned-children.d.ts.map +1 -0
- package/dist/owned-children.js +64 -0
- package/dist/owned-children.js.map +1 -0
- package/dist/packet-for-goal.d.ts +19 -0
- package/dist/packet-for-goal.d.ts.map +1 -0
- package/dist/packet-for-goal.js +32 -0
- package/dist/packet-for-goal.js.map +1 -0
- package/dist/pair-cmd.d.ts +85 -0
- package/dist/pair-cmd.d.ts.map +1 -0
- package/dist/pair-cmd.js +205 -0
- package/dist/pair-cmd.js.map +1 -0
- package/dist/partial-asker.d.ts +96 -0
- package/dist/partial-asker.d.ts.map +1 -0
- package/dist/partial-asker.js +117 -0
- package/dist/partial-asker.js.map +1 -0
- package/dist/pdf-text-lines.d.ts +17 -0
- package/dist/pdf-text-lines.d.ts.map +1 -0
- package/dist/pdf-text-lines.js +70 -0
- package/dist/pdf-text-lines.js.map +1 -0
- package/dist/pdf-text-worker.d.ts +2 -0
- package/dist/pdf-text-worker.d.ts.map +1 -0
- package/dist/pdf-text-worker.js +81 -0
- package/dist/pdf-text-worker.js.map +1 -0
- package/dist/pdf-text.d.ts +56 -0
- package/dist/pdf-text.d.ts.map +1 -0
- package/dist/pdf-text.js +64 -0
- package/dist/pdf-text.js.map +1 -0
- package/dist/pending-action.d.ts +154 -0
- package/dist/pending-action.d.ts.map +1 -0
- package/dist/pending-action.js +148 -0
- package/dist/pending-action.js.map +1 -0
- package/dist/preemptor.d.ts +40 -0
- package/dist/preemptor.d.ts.map +1 -0
- package/dist/preemptor.js +49 -0
- package/dist/preemptor.js.map +1 -0
- package/dist/programme-mode.d.ts +29 -0
- package/dist/programme-mode.d.ts.map +1 -0
- package/dist/programme-mode.js +50 -0
- package/dist/programme-mode.js.map +1 -0
- package/dist/progress-view.d.ts +14 -0
- package/dist/progress-view.d.ts.map +1 -0
- package/dist/progress-view.js +114 -0
- package/dist/progress-view.js.map +1 -0
- package/dist/project-graph-builder.d.ts +81 -0
- package/dist/project-graph-builder.d.ts.map +1 -0
- package/dist/project-graph-builder.js +246 -0
- package/dist/project-graph-builder.js.map +1 -0
- package/dist/project-graph-runtime.d.ts +86 -0
- package/dist/project-graph-runtime.d.ts.map +1 -0
- package/dist/project-graph-runtime.js +112 -0
- package/dist/project-graph-runtime.js.map +1 -0
- package/dist/project-index-builder.d.ts +96 -0
- package/dist/project-index-builder.d.ts.map +1 -0
- package/dist/project-index-builder.js +298 -0
- package/dist/project-index-builder.js.map +1 -0
- package/dist/project-index-facts.d.ts +51 -0
- package/dist/project-index-facts.d.ts.map +1 -0
- package/dist/project-index-facts.js +117 -0
- package/dist/project-index-facts.js.map +1 -0
- package/dist/project-index-store.d.ts +97 -0
- package/dist/project-index-store.d.ts.map +1 -0
- package/dist/project-index-store.js +140 -0
- package/dist/project-index-store.js.map +1 -0
- package/dist/project-memory-store.d.ts +127 -0
- package/dist/project-memory-store.d.ts.map +1 -0
- package/dist/project-memory-store.js +302 -0
- package/dist/project-memory-store.js.map +1 -0
- package/dist/proposal-store.d.ts +14 -0
- package/dist/proposal-store.d.ts.map +1 -0
- package/dist/proposal-store.js +19 -0
- package/dist/proposal-store.js.map +1 -0
- package/dist/prover.d.ts +80 -0
- package/dist/prover.d.ts.map +1 -0
- package/dist/prover.js +137 -0
- package/dist/prover.js.map +1 -0
- package/dist/provider-identity-store.d.ts +34 -0
- package/dist/provider-identity-store.d.ts.map +1 -0
- package/dist/provider-identity-store.js +72 -0
- package/dist/provider-identity-store.js.map +1 -0
- package/dist/provider-identity.d.ts +104 -0
- package/dist/provider-identity.d.ts.map +1 -0
- package/dist/provider-identity.js +167 -0
- package/dist/provider-identity.js.map +1 -0
- package/dist/provider-limit.d.ts +79 -0
- package/dist/provider-limit.d.ts.map +1 -0
- package/dist/provider-limit.js +148 -0
- package/dist/provider-limit.js.map +1 -0
- package/dist/provider-preflight.d.ts +171 -0
- package/dist/provider-preflight.d.ts.map +1 -0
- package/dist/provider-preflight.js +395 -0
- package/dist/provider-preflight.js.map +1 -0
- package/dist/provider-state.d.ts +120 -0
- package/dist/provider-state.d.ts.map +1 -0
- package/dist/provider-state.js +182 -0
- package/dist/provider-state.js.map +1 -0
- package/dist/providers.d.ts +132 -0
- package/dist/providers.d.ts.map +1 -0
- package/dist/providers.js +161 -0
- package/dist/providers.js.map +1 -0
- package/dist/publication-recorder.d.ts +117 -0
- package/dist/publication-recorder.d.ts.map +1 -0
- package/dist/publication-recorder.js +124 -0
- package/dist/publication-recorder.js.map +1 -0
- package/dist/pursuit-delivery.d.ts +24 -0
- package/dist/pursuit-delivery.d.ts.map +1 -0
- package/dist/pursuit-delivery.js +38 -0
- package/dist/pursuit-delivery.js.map +1 -0
- package/dist/queue-store.d.ts +132 -0
- package/dist/queue-store.d.ts.map +1 -0
- package/dist/queue-store.js +185 -0
- package/dist/queue-store.js.map +1 -0
- package/dist/queue-summary.d.ts +14 -0
- package/dist/queue-summary.d.ts.map +1 -0
- package/dist/queue-summary.js +82 -0
- package/dist/queue-summary.js.map +1 -0
- package/dist/queue-view.d.ts +20 -0
- package/dist/queue-view.d.ts.map +1 -0
- package/dist/queue-view.js +163 -0
- package/dist/queue-view.js.map +1 -0
- package/dist/queue-write-lease.d.ts +106 -0
- package/dist/queue-write-lease.d.ts.map +1 -0
- package/dist/queue-write-lease.js +282 -0
- package/dist/queue-write-lease.js.map +1 -0
- package/dist/rails-home.d.ts +162 -0
- package/dist/rails-home.d.ts.map +1 -0
- package/dist/rails-home.js +452 -0
- package/dist/rails-home.js.map +1 -0
- package/dist/rails-migrations.d.ts +75 -0
- package/dist/rails-migrations.d.ts.map +1 -0
- package/dist/rails-migrations.js +199 -0
- package/dist/rails-migrations.js.map +1 -0
- package/dist/rails-stores.d.ts +49 -0
- package/dist/rails-stores.d.ts.map +1 -0
- package/dist/rails-stores.js +100 -0
- package/dist/rails-stores.js.map +1 -0
- package/dist/reaper.d.ts +69 -0
- package/dist/reaper.d.ts.map +1 -0
- package/dist/reaper.js +152 -0
- package/dist/reaper.js.map +1 -0
- package/dist/record-store.d.ts +36 -0
- package/dist/record-store.d.ts.map +1 -0
- package/dist/record-store.js +78 -0
- package/dist/record-store.js.map +1 -0
- package/dist/recovery-io.d.ts +50 -0
- package/dist/recovery-io.d.ts.map +1 -0
- package/dist/recovery-io.js +122 -0
- package/dist/recovery-io.js.map +1 -0
- package/dist/recovery.d.ts +146 -0
- package/dist/recovery.d.ts.map +1 -0
- package/dist/recovery.js +110 -0
- package/dist/recovery.js.map +1 -0
- package/dist/redraw.d.ts +34 -0
- package/dist/redraw.d.ts.map +1 -0
- package/dist/redraw.js +62 -0
- package/dist/redraw.js.map +1 -0
- package/dist/rejected-evidence.d.ts +255 -0
- package/dist/rejected-evidence.d.ts.map +1 -0
- package/dist/rejected-evidence.js +324 -0
- package/dist/rejected-evidence.js.map +1 -0
- package/dist/report-cmd.d.ts +32 -0
- package/dist/report-cmd.d.ts.map +1 -0
- package/dist/report-cmd.js +201 -0
- package/dist/report-cmd.js.map +1 -0
- package/dist/repos-cmd.d.ts +80 -0
- package/dist/repos-cmd.d.ts.map +1 -0
- package/dist/repos-cmd.js +240 -0
- package/dist/repos-cmd.js.map +1 -0
- package/dist/request-body-shape.d.ts +93 -0
- package/dist/request-body-shape.d.ts.map +1 -0
- package/dist/request-body-shape.js +407 -0
- package/dist/request-body-shape.js.map +1 -0
- package/dist/requirement-claims.d.ts +89 -0
- package/dist/requirement-claims.d.ts.map +1 -0
- package/dist/requirement-claims.js +92 -0
- package/dist/requirement-claims.js.map +1 -0
- package/dist/retention-apply-runtime.d.ts +105 -0
- package/dist/retention-apply-runtime.d.ts.map +1 -0
- package/dist/retention-apply-runtime.js +269 -0
- package/dist/retention-apply-runtime.js.map +1 -0
- package/dist/reverify.d.ts +41 -0
- package/dist/reverify.d.ts.map +1 -0
- package/dist/reverify.js +69 -0
- package/dist/reverify.js.map +1 -0
- package/dist/round-records.d.ts +65 -0
- package/dist/round-records.d.ts.map +1 -0
- package/dist/round-records.js +61 -0
- package/dist/round-records.js.map +1 -0
- package/dist/round-runner.d.ts +924 -0
- package/dist/round-runner.d.ts.map +1 -0
- package/dist/round-runner.js +1693 -0
- package/dist/round-runner.js.map +1 -0
- package/dist/run-approval.d.ts +180 -0
- package/dist/run-approval.d.ts.map +1 -0
- package/dist/run-approval.js +199 -0
- package/dist/run-approval.js.map +1 -0
- package/dist/run-cmd.d.ts +359 -0
- package/dist/run-cmd.d.ts.map +1 -0
- package/dist/run-cmd.js +4418 -0
- package/dist/run-cmd.js.map +1 -0
- package/dist/run-delivery.d.ts +71 -0
- package/dist/run-delivery.d.ts.map +1 -0
- package/dist/run-delivery.js +104 -0
- package/dist/run-delivery.js.map +1 -0
- package/dist/run-ended.d.ts +75 -0
- package/dist/run-ended.d.ts.map +1 -0
- package/dist/run-ended.js +27 -0
- package/dist/run-ended.js.map +1 -0
- package/dist/run-ending-locator.d.ts +125 -0
- package/dist/run-ending-locator.d.ts.map +1 -0
- package/dist/run-ending-locator.js +133 -0
- package/dist/run-ending-locator.js.map +1 -0
- package/dist/run-launcher.d.ts +459 -0
- package/dist/run-launcher.d.ts.map +1 -0
- package/dist/run-launcher.js +652 -0
- package/dist/run-launcher.js.map +1 -0
- package/dist/run-lease.d.ts +208 -0
- package/dist/run-lease.d.ts.map +1 -0
- package/dist/run-lease.js +301 -0
- package/dist/run-lease.js.map +1 -0
- package/dist/run-refusal-marks.d.ts +189 -0
- package/dist/run-refusal-marks.d.ts.map +1 -0
- package/dist/run-refusal-marks.js +249 -0
- package/dist/run-refusal-marks.js.map +1 -0
- package/dist/run-start-marks.d.ts +153 -0
- package/dist/run-start-marks.d.ts.map +1 -0
- package/dist/run-start-marks.js +269 -0
- package/dist/run-start-marks.js.map +1 -0
- package/dist/scan-cmd.d.ts +14 -0
- package/dist/scan-cmd.d.ts.map +1 -0
- package/dist/scan-cmd.js +270 -0
- package/dist/scan-cmd.js.map +1 -0
- package/dist/scan-events.d.ts +50 -0
- package/dist/scan-events.d.ts.map +1 -0
- package/dist/scan-events.js +91 -0
- package/dist/scan-events.js.map +1 -0
- package/dist/scan.d.ts +191 -0
- package/dist/scan.d.ts.map +1 -0
- package/dist/scan.js +417 -0
- package/dist/scan.js.map +1 -0
- package/dist/scope-rule.d.ts +148 -0
- package/dist/scope-rule.d.ts.map +1 -0
- package/dist/scope-rule.js +121 -0
- package/dist/scope-rule.js.map +1 -0
- package/dist/self-repo-id.d.ts +18 -0
- package/dist/self-repo-id.d.ts.map +1 -0
- package/dist/self-repo-id.js +70 -0
- package/dist/self-repo-id.js.map +1 -0
- package/dist/serve-cmd.d.ts +115 -0
- package/dist/serve-cmd.d.ts.map +1 -0
- package/dist/serve-cmd.js +505 -0
- package/dist/serve-cmd.js.map +1 -0
- package/dist/serve.d.ts +167 -0
- package/dist/serve.d.ts.map +1 -0
- package/dist/serve.js +336 -0
- package/dist/serve.js.map +1 -0
- package/dist/server-client.d.ts +766 -0
- package/dist/server-client.d.ts.map +1 -0
- package/dist/server-client.js +475 -0
- package/dist/server-client.js.map +1 -0
- package/dist/session-adapter-runtime.d.ts +195 -0
- package/dist/session-adapter-runtime.d.ts.map +1 -0
- package/dist/session-adapter-runtime.js +373 -0
- package/dist/session-adapter-runtime.js.map +1 -0
- package/dist/session-checkpoint-runtime.d.ts +62 -0
- package/dist/session-checkpoint-runtime.d.ts.map +1 -0
- package/dist/session-checkpoint-runtime.js +268 -0
- package/dist/session-checkpoint-runtime.js.map +1 -0
- package/dist/session-control-transport.d.ts +106 -0
- package/dist/session-control-transport.d.ts.map +1 -0
- package/dist/session-control-transport.js +232 -0
- package/dist/session-control-transport.js.map +1 -0
- package/dist/session-observation-store.d.ts +98 -0
- package/dist/session-observation-store.d.ts.map +1 -0
- package/dist/session-observation-store.js +155 -0
- package/dist/session-observation-store.js.map +1 -0
- package/dist/session-observe-runtime.d.ts +123 -0
- package/dist/session-observe-runtime.d.ts.map +1 -0
- package/dist/session-observe-runtime.js +317 -0
- package/dist/session-observe-runtime.js.map +1 -0
- package/dist/session-store.d.ts +98 -0
- package/dist/session-store.d.ts.map +1 -0
- package/dist/session-store.js +116 -0
- package/dist/session-store.js.map +1 -0
- package/dist/sessions-cmd.d.ts +202 -0
- package/dist/sessions-cmd.d.ts.map +1 -0
- package/dist/sessions-cmd.js +609 -0
- package/dist/sessions-cmd.js.map +1 -0
- package/dist/settings-overlay.d.ts +53 -0
- package/dist/settings-overlay.d.ts.map +1 -0
- package/dist/settings-overlay.js +175 -0
- package/dist/settings-overlay.js.map +1 -0
- package/dist/setup-prompt.d.ts +34 -0
- package/dist/setup-prompt.d.ts.map +1 -0
- package/dist/setup-prompt.js +92 -0
- package/dist/setup-prompt.js.map +1 -0
- package/dist/setup.d.ts +103 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/setup.js +283 -0
- package/dist/setup.js.map +1 -0
- package/dist/shared-grants.d.ts +164 -0
- package/dist/shared-grants.d.ts.map +1 -0
- package/dist/shared-grants.js +242 -0
- package/dist/shared-grants.js.map +1 -0
- package/dist/signals.d.ts +55 -0
- package/dist/signals.d.ts.map +1 -0
- package/dist/signals.js +85 -0
- package/dist/signals.js.map +1 -0
- package/dist/source-cmd.d.ts +201 -0
- package/dist/source-cmd.d.ts.map +1 -0
- package/dist/source-cmd.js +684 -0
- package/dist/source-cmd.js.map +1 -0
- package/dist/source-verdict.d.ts +99 -0
- package/dist/source-verdict.d.ts.map +1 -0
- package/dist/source-verdict.js +182 -0
- package/dist/source-verdict.js.map +1 -0
- package/dist/spend-ledger.d.ts +350 -0
- package/dist/spend-ledger.d.ts.map +1 -0
- package/dist/spend-ledger.js +546 -0
- package/dist/spend-ledger.js.map +1 -0
- package/dist/stale-run-sweep.d.ts +79 -0
- package/dist/stale-run-sweep.d.ts.map +1 -0
- package/dist/stale-run-sweep.js +116 -0
- package/dist/stale-run-sweep.js.map +1 -0
- package/dist/start-attempts.d.ts +385 -0
- package/dist/start-attempts.d.ts.map +1 -0
- package/dist/start-attempts.js +613 -0
- package/dist/start-attempts.js.map +1 -0
- package/dist/status-cmd.d.ts +28 -0
- package/dist/status-cmd.d.ts.map +1 -0
- package/dist/status-cmd.js +116 -0
- package/dist/status-cmd.js.map +1 -0
- package/dist/stop-follow-up.d.ts +107 -0
- package/dist/stop-follow-up.d.ts.map +1 -0
- package/dist/stop-follow-up.js +172 -0
- package/dist/stop-follow-up.js.map +1 -0
- package/dist/surface-lease.d.ts +118 -0
- package/dist/surface-lease.d.ts.map +1 -0
- package/dist/surface-lease.js +485 -0
- package/dist/surface-lease.js.map +1 -0
- package/dist/sync.d.ts +54 -0
- package/dist/sync.d.ts.map +1 -0
- package/dist/sync.js +93 -0
- package/dist/sync.js.map +1 -0
- package/dist/syncing-ledger.d.ts +45 -0
- package/dist/syncing-ledger.d.ts.map +1 -0
- package/dist/syncing-ledger.js +53 -0
- package/dist/syncing-ledger.js.map +1 -0
- package/dist/temp-fixtures.d.ts +68 -0
- package/dist/temp-fixtures.d.ts.map +1 -0
- package/dist/temp-fixtures.js +38 -0
- package/dist/temp-fixtures.js.map +1 -0
- package/dist/token-window.d.ts +84 -0
- package/dist/token-window.d.ts.map +1 -0
- package/dist/token-window.js +143 -0
- package/dist/token-window.js.map +1 -0
- package/dist/tool-bridge.d.ts +177 -0
- package/dist/tool-bridge.d.ts.map +1 -0
- package/dist/tool-bridge.js +329 -0
- package/dist/tool-bridge.js.map +1 -0
- package/dist/tool-call-record.d.ts +197 -0
- package/dist/tool-call-record.d.ts.map +1 -0
- package/dist/tool-call-record.js +276 -0
- package/dist/tool-call-record.js.map +1 -0
- package/dist/tool-protocol.d.ts +135 -0
- package/dist/tool-protocol.d.ts.map +1 -0
- package/dist/tool-protocol.js +104 -0
- package/dist/tool-protocol.js.map +1 -0
- package/dist/tool-worker.d.ts +3 -0
- package/dist/tool-worker.d.ts.map +1 -0
- package/dist/tool-worker.js +478 -0
- package/dist/tool-worker.js.map +1 -0
- package/dist/toolchain-mirror.d.ts +86 -0
- package/dist/toolchain-mirror.d.ts.map +1 -0
- package/dist/toolchain-mirror.js +307 -0
- package/dist/toolchain-mirror.js.map +1 -0
- package/dist/trusted-git.d.ts +243 -0
- package/dist/trusted-git.d.ts.map +1 -0
- package/dist/trusted-git.js +920 -0
- package/dist/trusted-git.js.map +1 -0
- package/dist/ui.d.ts +76 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +118 -0
- package/dist/ui.js.map +1 -0
- package/dist/untrusted-exec.d.ts +275 -0
- package/dist/untrusted-exec.d.ts.map +1 -0
- package/dist/untrusted-exec.js +479 -0
- package/dist/untrusted-exec.js.map +1 -0
- package/dist/untrusted-gate.d.ts +73 -0
- package/dist/untrusted-gate.d.ts.map +1 -0
- package/dist/untrusted-gate.js +226 -0
- package/dist/untrusted-gate.js.map +1 -0
- package/dist/uploader.d.ts +153 -0
- package/dist/uploader.d.ts.map +1 -0
- package/dist/uploader.js +204 -0
- package/dist/uploader.js.map +1 -0
- package/dist/verifier.d.ts +66 -0
- package/dist/verifier.d.ts.map +1 -0
- package/dist/verifier.js +170 -0
- package/dist/verifier.js.map +1 -0
- package/dist/verify-apply.d.ts +26 -0
- package/dist/verify-apply.d.ts.map +1 -0
- package/dist/verify-apply.js +36 -0
- package/dist/verify-apply.js.map +1 -0
- package/dist/verify-cmd.d.ts +44 -0
- package/dist/verify-cmd.d.ts.map +1 -0
- package/dist/verify-cmd.js +125 -0
- package/dist/verify-cmd.js.map +1 -0
- package/dist/verify-pass.d.ts +73 -0
- package/dist/verify-pass.d.ts.map +1 -0
- package/dist/verify-pass.js +103 -0
- package/dist/verify-pass.js.map +1 -0
- package/dist/welcome.d.ts +43 -0
- package/dist/welcome.d.ts.map +1 -0
- package/dist/welcome.js +116 -0
- package/dist/welcome.js.map +1 -0
- package/dist/workspace-provisioner.d.ts +65 -0
- package/dist/workspace-provisioner.d.ts.map +1 -0
- package/dist/workspace-provisioner.js +66 -0
- package/dist/workspace-provisioner.js.map +1 -0
- package/dist/workspace-quarantine.d.ts +64 -0
- package/dist/workspace-quarantine.d.ts.map +1 -0
- package/dist/workspace-quarantine.js +156 -0
- package/dist/workspace-quarantine.js.map +1 -0
- package/dist/workspace-residue-sweep.d.ts +113 -0
- package/dist/workspace-residue-sweep.d.ts.map +1 -0
- package/dist/workspace-residue-sweep.js +158 -0
- package/dist/workspace-residue-sweep.js.map +1 -0
- package/dist/workspace.d.ts +639 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +2026 -0
- package/dist/workspace.js.map +1 -0
- package/package.json +52 -4
- package/win/CredProbe.cs +64 -0
- package/win/FakeClaude.cs +56 -0
- package/win/HandleProbe.cs +116 -0
- package/win/TokenProbe.cs +53 -0
- package/win/appcontainer.ps1 +500 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { type AnyEvent, type RoundReport } from '@looply/core';
|
|
2
|
+
import { type RunRegistry } from './workspace';
|
|
3
|
+
/**
|
|
4
|
+
* EACH RUN OF A GOAL, FROM THE LEDGERS THIS MACHINE HOLDS (M5-4).
|
|
5
|
+
*
|
|
6
|
+
* A run writes its ledger where it ran: the project's own `.looply/state` for
|
|
7
|
+
* a run started in the main checkout, and a placed run's workspace for one the
|
|
8
|
+
* machine provisioned (M4). Nothing on the machine ever read those ledgers BY
|
|
9
|
+
* GOAL — `looply report` folds one file, and the goal view (M5-3) said "each
|
|
10
|
+
* round's account is in the run's own ledger". This file finds the ledgers,
|
|
11
|
+
* folds each run of one goal with the very fold `looply report` and the
|
|
12
|
+
* phone's run report use (core `runReport`), and names the runs whose ledger
|
|
13
|
+
* is no longer here.
|
|
14
|
+
*
|
|
15
|
+
* READ-ONLY, like the view it serves: it lists directories and reads files,
|
|
16
|
+
* and the spec pins that it does nothing else. It walks exactly two places —
|
|
17
|
+
* the project state and this project's checkouts under
|
|
18
|
+
* `~/.looply/workspaces` — never the rest of the disk.
|
|
19
|
+
*
|
|
20
|
+
* The fold is not re-implemented: a run's events are handed to `runReport`
|
|
21
|
+
* with the ledger's item events (titles), so the rounds, outcomes, totals and
|
|
22
|
+
* the implementer's note — M2-4's `touched:` account first — are the same
|
|
23
|
+
* text a person sees in `looply report`.
|
|
24
|
+
*/
|
|
25
|
+
export interface LedgerPlace {
|
|
26
|
+
/** The `events.jsonl` file. */
|
|
27
|
+
readonly path: string;
|
|
28
|
+
/** The state directory it sits in — what a `LedgerStore` or a replay is built on. */
|
|
29
|
+
readonly dir: string;
|
|
30
|
+
/** `retired`: the records the reaper moved to `<project state>/retired/<run>/` when it removed a died run's checkout (M4-4). */
|
|
31
|
+
readonly where: 'project' | 'workspace' | 'retired';
|
|
32
|
+
/** `project`, the checkout's path, or the retired records' path. */
|
|
33
|
+
readonly label: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The ledgers this machine holds for a project: the project's own, the records
|
|
37
|
+
* the reaper kept when it retired a died run's checkout, each registered run's,
|
|
38
|
+
* and every checkout under the project's workspaces root — de-duplicated by
|
|
39
|
+
* real path, so a registered run in a listed checkout is one ledger, not two.
|
|
40
|
+
* A path that does not exist is not a ledger.
|
|
41
|
+
*/
|
|
42
|
+
export declare function ledgersOn(projectStateDir: string, registry: RunRegistry, cwd: string, home?: string): LedgerPlace[];
|
|
43
|
+
export interface LedgerRead {
|
|
44
|
+
readonly place: LedgerPlace;
|
|
45
|
+
readonly events: readonly AnyEvent[];
|
|
46
|
+
/** Lines that were not events — counted, never guessed at. */
|
|
47
|
+
readonly badLines: number;
|
|
48
|
+
/** Set when the file could not be read at all; `events` is then empty. */
|
|
49
|
+
readonly unreadable?: string;
|
|
50
|
+
}
|
|
51
|
+
export declare function readLedgers(places: readonly LedgerPlace[]): LedgerRead[];
|
|
52
|
+
export interface GoalRun {
|
|
53
|
+
readonly runId: string;
|
|
54
|
+
readonly branch: string;
|
|
55
|
+
readonly startedAt: string;
|
|
56
|
+
readonly goalVersion: number | null;
|
|
57
|
+
readonly where: LedgerPlace['where'];
|
|
58
|
+
readonly label: string;
|
|
59
|
+
/** `null`: no `run.ended` on the ledger — still going, or the ledger was cut. */
|
|
60
|
+
readonly stopReason: string | null;
|
|
61
|
+
readonly rounds: readonly RoundReport[];
|
|
62
|
+
readonly totals: {
|
|
63
|
+
readonly rounds: number;
|
|
64
|
+
readonly committed: number;
|
|
65
|
+
readonly discarded: number;
|
|
66
|
+
readonly abandoned: number;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Every run of one goal across the ledgers read, oldest first. A run is its
|
|
71
|
+
* `run.started` naming the goal; its rounds are folded from its own events
|
|
72
|
+
* plus the ledger's item events (which carry the titles), by `runReport`.
|
|
73
|
+
*/
|
|
74
|
+
export declare function runsOf(ledgers: readonly LedgerRead[], goalId: string): GoalRun[];
|
|
75
|
+
export interface RetiredRun {
|
|
76
|
+
readonly runId: string;
|
|
77
|
+
readonly branch: string;
|
|
78
|
+
readonly workspace: string;
|
|
79
|
+
}
|
|
80
|
+
/** Registered runs whose ledger is not on this machine any more — a stated absence each, never a guess at what they did. */
|
|
81
|
+
export declare function retiredRunsOf(registry: RunRegistry): RetiredRun[];
|
|
82
|
+
//# sourceMappingURL=goal-runs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"goal-runs.d.ts","sourceRoot":"","sources":["../src/goal-runs.ts"],"names":[],"mappings":"AAGA,OAAO,EAAyB,KAAK,QAAQ,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAEtF,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,WAAW,WAAW;IAC1B,+BAA+B;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,qFAAqF;IACrF,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,gIAAgI;IAChI,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;IACpD,oEAAoE;IACpE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,eAAe,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,MAAkB,GAAG,WAAW,EAAE,CA2C9H;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,SAAS,QAAQ,EAAE,CAAC;IACrC,8DAA8D;IAC9D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,0EAA0E;IAC1E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,GAAG,UAAU,EAAE,CAWxE;AAED,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,iFAAiF;IACjF,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,CAAC;IACxC,QAAQ,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CAClI;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE,CAsBhF;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,4HAA4H;AAC5H,wBAAgB,aAAa,CAAC,QAAQ,EAAE,WAAW,GAAG,UAAU,EAAE,CAMjE"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ledgersOn = ledgersOn;
|
|
4
|
+
exports.readLedgers = readLedgers;
|
|
5
|
+
exports.runsOf = runsOf;
|
|
6
|
+
exports.retiredRunsOf = retiredRunsOf;
|
|
7
|
+
const node_fs_1 = require("node:fs");
|
|
8
|
+
const node_os_1 = require("node:os");
|
|
9
|
+
const node_path_1 = require("node:path");
|
|
10
|
+
const core_1 = require("@looply/core");
|
|
11
|
+
const git_driver_1 = require("./git-driver");
|
|
12
|
+
const workspace_1 = require("./workspace");
|
|
13
|
+
/**
|
|
14
|
+
* The ledgers this machine holds for a project: the project's own, the records
|
|
15
|
+
* the reaper kept when it retired a died run's checkout, each registered run's,
|
|
16
|
+
* and every checkout under the project's workspaces root — de-duplicated by
|
|
17
|
+
* real path, so a registered run in a listed checkout is one ledger, not two.
|
|
18
|
+
* A path that does not exist is not a ledger.
|
|
19
|
+
*/
|
|
20
|
+
function ledgersOn(projectStateDir, registry, cwd, home = (0, node_os_1.homedir)()) {
|
|
21
|
+
const seen = new Set();
|
|
22
|
+
const out = [];
|
|
23
|
+
const add = (dir, where, label) => {
|
|
24
|
+
const path = (0, node_path_1.join)(dir, 'events.jsonl');
|
|
25
|
+
if (!(0, node_fs_1.existsSync)(path))
|
|
26
|
+
return;
|
|
27
|
+
let key;
|
|
28
|
+
try {
|
|
29
|
+
key = (0, node_fs_1.realpathSync)(path).toLowerCase();
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
key = path.toLowerCase();
|
|
33
|
+
}
|
|
34
|
+
if (seen.has(key))
|
|
35
|
+
return;
|
|
36
|
+
seen.add(key);
|
|
37
|
+
out.push({ path, dir, where, label });
|
|
38
|
+
};
|
|
39
|
+
add(projectStateDir, 'project', 'project');
|
|
40
|
+
let kept;
|
|
41
|
+
try {
|
|
42
|
+
kept = (0, node_fs_1.readdirSync)((0, node_path_1.join)(projectStateDir, 'retired'));
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
kept = [];
|
|
46
|
+
}
|
|
47
|
+
for (const name of [...kept].sort()) {
|
|
48
|
+
const dir = (0, node_path_1.join)(projectStateDir, 'retired', name);
|
|
49
|
+
add(dir, 'retired', dir);
|
|
50
|
+
}
|
|
51
|
+
for (const live of registry.list()) {
|
|
52
|
+
if (!('record' in live))
|
|
53
|
+
continue;
|
|
54
|
+
add(live.record.stateDir, 'workspace', live.record.workspace);
|
|
55
|
+
}
|
|
56
|
+
const root = (0, workspace_1.workspacesRoot)(cwd, home);
|
|
57
|
+
let names;
|
|
58
|
+
try {
|
|
59
|
+
names = (0, node_fs_1.readdirSync)(root);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
names = [];
|
|
63
|
+
}
|
|
64
|
+
for (const name of [...names].sort()) {
|
|
65
|
+
const checkout = (0, node_path_1.join)(root, name);
|
|
66
|
+
add((0, node_path_1.join)(checkout, git_driver_1.STATE_DIR, 'state'), 'workspace', checkout);
|
|
67
|
+
}
|
|
68
|
+
return out;
|
|
69
|
+
}
|
|
70
|
+
function readLedgers(places) {
|
|
71
|
+
return places.map((place) => {
|
|
72
|
+
let text;
|
|
73
|
+
try {
|
|
74
|
+
text = (0, node_fs_1.readFileSync)(place.path, 'utf8');
|
|
75
|
+
}
|
|
76
|
+
catch (e) {
|
|
77
|
+
return { place, events: [], badLines: 0, unreadable: e.message };
|
|
78
|
+
}
|
|
79
|
+
const parsed = (0, core_1.parseLines)(text);
|
|
80
|
+
return { place, events: parsed.events, badLines: parsed.badLines.length };
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Every run of one goal across the ledgers read, oldest first. A run is its
|
|
85
|
+
* `run.started` naming the goal; its rounds are folded from its own events
|
|
86
|
+
* plus the ledger's item events (which carry the titles), by `runReport`.
|
|
87
|
+
*/
|
|
88
|
+
function runsOf(ledgers, goalId) {
|
|
89
|
+
const out = [];
|
|
90
|
+
for (const { place, events } of ledgers) {
|
|
91
|
+
for (const e of events) {
|
|
92
|
+
if (e.kind !== 'run.started' || e.data.goalId !== goalId)
|
|
93
|
+
continue;
|
|
94
|
+
const id = e.data.runId;
|
|
95
|
+
const own = events.filter((x) => x.runId === id || x.kind === 'item.created' || x.kind === 'item.verified');
|
|
96
|
+
const report = (0, core_1.runReport)(own);
|
|
97
|
+
out.push({
|
|
98
|
+
runId: id,
|
|
99
|
+
branch: e.data.branch,
|
|
100
|
+
startedAt: e.ts,
|
|
101
|
+
goalVersion: e.data.goalVersion ?? null,
|
|
102
|
+
where: place.where,
|
|
103
|
+
label: place.label,
|
|
104
|
+
stopReason: report.live ? null : report.stopReason,
|
|
105
|
+
rounds: report.rounds,
|
|
106
|
+
totals: report.totals,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return out.sort((a, b) => a.startedAt.localeCompare(b.startedAt) || a.runId.localeCompare(b.runId));
|
|
111
|
+
}
|
|
112
|
+
/** Registered runs whose ledger is not on this machine any more — a stated absence each, never a guess at what they did. */
|
|
113
|
+
function retiredRunsOf(registry) {
|
|
114
|
+
return registry
|
|
115
|
+
.list()
|
|
116
|
+
.flatMap((l) => ('record' in l ? [l.record] : []))
|
|
117
|
+
.filter((r) => !(0, node_fs_1.existsSync)((0, node_path_1.join)(r.stateDir, 'events.jsonl')))
|
|
118
|
+
.map((r) => ({ runId: r.runId, branch: r.branch, workspace: r.workspace }));
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=goal-runs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"goal-runs.js","sourceRoot":"","sources":["../src/goal-runs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { type Goal } from '@looply/core';
|
|
2
|
+
import type { LedgerFs } from './ledger-store';
|
|
3
|
+
/**
|
|
4
|
+
* What the server says this project's goals are — `goals.json` under the state dir.
|
|
5
|
+
*
|
|
6
|
+
* A MIRROR, not an authority. The server owns goal intent, this file is a copy,
|
|
7
|
+
* and nothing on the machine ever writes a goal back. That single fact settles
|
|
8
|
+
* most of the design questions a durable store usually raises: there is no
|
|
9
|
+
* merge, because there is no local edit; there is no conflict, because there is
|
|
10
|
+
* no second writer; and a whole-file replace is not a compromise but exactly
|
|
11
|
+
* right, because the server's answer IS the state.
|
|
12
|
+
*
|
|
13
|
+
* It is also why this is the first store here whose corrupt-file policy is
|
|
14
|
+
* DISCARD AND RE-PULL rather than a loud failure. `queue-store.ts` fails loudly
|
|
15
|
+
* because losing the queue loses curation somebody did by hand; every byte in
|
|
16
|
+
* this file costs one HTTP GET to rebuild, so killing an overnight daemon over
|
|
17
|
+
* it would be trading something valuable for something free. The policy in each
|
|
18
|
+
* store follows what its contents are worth, not a house preference.
|
|
19
|
+
*
|
|
20
|
+
* ONE WRITER: the daemon. These stores rewrite the whole file from an in-memory
|
|
21
|
+
* map, so a second writer does not race a row — it reverts the file to its own
|
|
22
|
+
* snapshot. Nothing else may call `replace`.
|
|
23
|
+
*/
|
|
24
|
+
/** Bumped only when the on-disk shape changes incompatibly. Read, not decorative. */
|
|
25
|
+
export declare const GOAL_STORE_SCHEMA = 1;
|
|
26
|
+
export interface GoalFile {
|
|
27
|
+
schema: number;
|
|
28
|
+
goals: Goal[];
|
|
29
|
+
}
|
|
30
|
+
/** Why a load produced nothing, so the caller can say which happened. */
|
|
31
|
+
export type GoalLoad = 'ok' | 'absent' | 'discarded';
|
|
32
|
+
/**
|
|
33
|
+
* What a locally-observed abandonment did to the mirror.
|
|
34
|
+
*
|
|
35
|
+
* Reported rather than swallowed so the daemon can say which happened, and so a
|
|
36
|
+
* test can tell "declined to move backwards" apart from "did nothing because it
|
|
37
|
+
* was already right".
|
|
38
|
+
*/
|
|
39
|
+
export type MirrorUpdate =
|
|
40
|
+
/** The row moved to abandoned at the command's version. */
|
|
41
|
+
'applied'
|
|
42
|
+
/** Already abandoned at that version or newer. */
|
|
43
|
+
| 'already'
|
|
44
|
+
/** The mirror holds a NEWER row; left alone rather than rewound. */
|
|
45
|
+
| 'ahead'
|
|
46
|
+
/** This mirror has never heard of the goal. Nothing invented. */
|
|
47
|
+
| 'absent';
|
|
48
|
+
export declare class GoalStore {
|
|
49
|
+
private readonly stateDir;
|
|
50
|
+
private readonly fs;
|
|
51
|
+
/** Optional: a discarded mirror is worth saying once, not silently. */
|
|
52
|
+
private readonly log?;
|
|
53
|
+
/** Distinguishes two writes from ONE process; the pid distinguishes processes. */
|
|
54
|
+
private static writes;
|
|
55
|
+
private goals;
|
|
56
|
+
private loaded;
|
|
57
|
+
constructor(stateDir: string, fs: LedgerFs,
|
|
58
|
+
/** Optional: a discarded mirror is worth saying once, not silently. */
|
|
59
|
+
log?: ((line: string) => void) | undefined);
|
|
60
|
+
private get path();
|
|
61
|
+
/**
|
|
62
|
+
* Read what is on disk.
|
|
63
|
+
*
|
|
64
|
+
* Anything unreadable, unparseable, wrongly shaped or of an unrecognised
|
|
65
|
+
* schema version is DISCARDED — treated as an empty mirror — and reported.
|
|
66
|
+
* Never a throw: this file is a cache of something the server can always be
|
|
67
|
+
* asked for again, and a daemon that dies over it has turned a free problem
|
|
68
|
+
* into an outage.
|
|
69
|
+
*
|
|
70
|
+
* An unknown `schema` is deliberately handled the same way. `cursor.json`
|
|
71
|
+
* declares a version field that nothing reads, so this is the first store
|
|
72
|
+
* where the field means anything; treating a future shape as corrupt lets an
|
|
73
|
+
* older build be downgraded onto a newer state dir and simply re-pull.
|
|
74
|
+
*/
|
|
75
|
+
load(): Promise<GoalLoad>;
|
|
76
|
+
private readIn;
|
|
77
|
+
/**
|
|
78
|
+
* What the mirror says RIGHT NOW, without adopting it.
|
|
79
|
+
*
|
|
80
|
+
* `get()` answers from an array this process loaded once, which is correct
|
|
81
|
+
* for the hundred cheap questions a run asks of it and wrong for the one
|
|
82
|
+
* expensive question asked after several minutes have passed. An adaptive
|
|
83
|
+
* Start spends up to eight minutes inside a goal evaluation; if a person
|
|
84
|
+
* amended or abandoned the goal in that window and the daemon has since
|
|
85
|
+
* written the new mirror, comparing the frozen snapshot against a value taken
|
|
86
|
+
* from that same snapshot compares a thing to itself and can only ever agree.
|
|
87
|
+
* That is not a re-check, and an adversarial review proved it was not
|
|
88
|
+
* behaving as one.
|
|
89
|
+
*
|
|
90
|
+
* So this reads the file again, and deliberately does NOT adopt what it
|
|
91
|
+
* finds: no `this.goals`, no `this.loaded`, no write, not even the discard
|
|
92
|
+
* rewrite that `load()` performs. It is a question, not a state change, and a
|
|
93
|
+
* run holding the lease must not quietly become the mirror's second writer
|
|
94
|
+
* on its way to asking one.
|
|
95
|
+
*
|
|
96
|
+
* ONE read, so what comes back is one whole state of the file rather than
|
|
97
|
+
* fields sampled across two of them.
|
|
98
|
+
*/
|
|
99
|
+
readFresh(): Promise<{
|
|
100
|
+
ok: true;
|
|
101
|
+
goals: Goal[];
|
|
102
|
+
} | {
|
|
103
|
+
ok: false;
|
|
104
|
+
because: string;
|
|
105
|
+
}>;
|
|
106
|
+
/**
|
|
107
|
+
* Take the server's answer as the new truth, whole.
|
|
108
|
+
*
|
|
109
|
+
* No merge and no diff: the argument IS the state. A goal the server no longer
|
|
110
|
+
* returns is gone from the mirror, which is what makes an abandoned goal
|
|
111
|
+
* disappear here without anything having to delete it.
|
|
112
|
+
*/
|
|
113
|
+
replace(goals: readonly Goal[]): Promise<void>;
|
|
114
|
+
private write;
|
|
115
|
+
/**
|
|
116
|
+
* Record that a goal has been given up on.
|
|
117
|
+
*
|
|
118
|
+
* Written when THIS machine carries out the release the abandonment produced,
|
|
119
|
+
* so a Start still in flight for the old version cannot resolve against
|
|
120
|
+
* `active` and adopt work back into a goal nobody is pursuing. The server
|
|
121
|
+
* remains authoritative — the next pull overwrites this with the real row,
|
|
122
|
+
* which says the same thing — but the machine must not need the server to
|
|
123
|
+
* remember something it has already been told.
|
|
124
|
+
*
|
|
125
|
+
* A goal the mirror has never heard of is left alone rather than invented:
|
|
126
|
+
* an absent goal can never resolve to `bound` anyway.
|
|
127
|
+
*/
|
|
128
|
+
markAbandoned(goalId: string, goalVersion: number): Promise<MirrorUpdate>;
|
|
129
|
+
private write1;
|
|
130
|
+
/** Everything the mirror holds, newest first as the server ordered it. */
|
|
131
|
+
all(): Goal[];
|
|
132
|
+
get(goalId: string): Goal | null;
|
|
133
|
+
/** Whether `load` has run. A store nobody loaded is empty for a different reason. */
|
|
134
|
+
isLoaded(): boolean;
|
|
135
|
+
size(): number;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Shape check for a goal off the wire or off disk.
|
|
139
|
+
*
|
|
140
|
+
* Deliberately structural and shallow, in the spirit of `isLooplyEvent`: it
|
|
141
|
+
* guards the fields the machine actually reads. A goal from a newer server with
|
|
142
|
+
* extra fields is kept — dropping it would make an older CLI go blind the day
|
|
143
|
+
* the server grows a column.
|
|
144
|
+
*/
|
|
145
|
+
export declare function isGoal(v: unknown): v is Goal;
|
|
146
|
+
//# sourceMappingURL=goal-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"goal-store.d.ts","sourceRoot":"","sources":["../src/goal-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,IAAI,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,qFAAqF;AACrF,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAEnC,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,IAAI,EAAE,CAAC;CACf;AAED,yEAAyE;AACzE,MAAM,MAAM,QAAQ,GAAG,IAAI,GAAG,QAAQ,GAAG,WAAW,CAAC;AAErD;;;;;;GAMG;AACH,MAAM,MAAM,YAAY;AACtB,2DAA2D;AACzD,SAAS;AACX,kDAAkD;GAChD,SAAS;AACX,oEAAoE;GAClE,OAAO;AACT,iEAAiE;GAC/D,QAAQ,CAAC;AAqCb,qBAAa,SAAS;IAQlB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,EAAE;IACnB,uEAAuE;IACvE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;IAVvB,kFAAkF;IAClF,OAAO,CAAC,MAAM,CAAC,MAAM,CAAK;IAE1B,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,MAAM,CAAS;gBAGJ,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,QAAQ;IAC7B,uEAAuE;IACtD,GAAG,CAAC,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,aAAA;IAG/C,OAAO,KAAK,IAAI,GAEf;IAED;;;;;;;;;;;;;OAaG;IACG,IAAI,IAAI,OAAO,CAAC,QAAQ,CAAC;YAiBjB,MAAM;IA4BpB;;;;;;;;;;;;;;;;;;;;;OAqBG;IACG,SAAS,IAAI,OAAO,CAAC;QAAE,EAAE,EAAE,IAAI,CAAC;QAAC,KAAK,EAAE,IAAI,EAAE,CAAA;KAAE,GAAG;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAexF;;;;;;OAMG;IACG,OAAO,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YAWtC,KAAK;IAenB;;;;;;;;;;;;OAYG;IACG,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;YAmCjE,MAAM;IAIpB,0EAA0E;IAC1E,GAAG,IAAI,IAAI,EAAE;IAIb,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAIhC,qFAAqF;IACrF,QAAQ,IAAI,OAAO;IAInB,IAAI,IAAI,MAAM;CAGf;AAED;;;;;;;GAOG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,IAAI,CAe5C"}
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GoalStore = exports.GOAL_STORE_SCHEMA = void 0;
|
|
4
|
+
exports.isGoal = isGoal;
|
|
5
|
+
const core_1 = require("@looply/core");
|
|
6
|
+
/**
|
|
7
|
+
* What the server says this project's goals are — `goals.json` under the state dir.
|
|
8
|
+
*
|
|
9
|
+
* A MIRROR, not an authority. The server owns goal intent, this file is a copy,
|
|
10
|
+
* and nothing on the machine ever writes a goal back. That single fact settles
|
|
11
|
+
* most of the design questions a durable store usually raises: there is no
|
|
12
|
+
* merge, because there is no local edit; there is no conflict, because there is
|
|
13
|
+
* no second writer; and a whole-file replace is not a compromise but exactly
|
|
14
|
+
* right, because the server's answer IS the state.
|
|
15
|
+
*
|
|
16
|
+
* It is also why this is the first store here whose corrupt-file policy is
|
|
17
|
+
* DISCARD AND RE-PULL rather than a loud failure. `queue-store.ts` fails loudly
|
|
18
|
+
* because losing the queue loses curation somebody did by hand; every byte in
|
|
19
|
+
* this file costs one HTTP GET to rebuild, so killing an overnight daemon over
|
|
20
|
+
* it would be trading something valuable for something free. The policy in each
|
|
21
|
+
* store follows what its contents are worth, not a house preference.
|
|
22
|
+
*
|
|
23
|
+
* ONE WRITER: the daemon. These stores rewrite the whole file from an in-memory
|
|
24
|
+
* map, so a second writer does not race a row — it reverts the file to its own
|
|
25
|
+
* snapshot. Nothing else may call `replace`.
|
|
26
|
+
*/
|
|
27
|
+
/** Bumped only when the on-disk shape changes incompatibly. Read, not decorative. */
|
|
28
|
+
exports.GOAL_STORE_SCHEMA = 1;
|
|
29
|
+
/**
|
|
30
|
+
* The mirror's bytes, checked. PURE, and shared by both readers.
|
|
31
|
+
*
|
|
32
|
+
* Extracted rather than duplicated because the two callers ask the same
|
|
33
|
+
* question for different reasons — one adopts the answer, one only looks — and
|
|
34
|
+
* two copies of a schema check are two copies that can disagree about what a
|
|
35
|
+
* valid mirror is.
|
|
36
|
+
*/
|
|
37
|
+
function parseMirror(text) {
|
|
38
|
+
let parsed;
|
|
39
|
+
try {
|
|
40
|
+
parsed = JSON.parse(text);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return { ok: false, because: 'the mirror is not readable JSON' };
|
|
44
|
+
}
|
|
45
|
+
const file = parsed;
|
|
46
|
+
if (typeof file !== 'object' || file === null || file.schema !== exports.GOAL_STORE_SCHEMA) {
|
|
47
|
+
return {
|
|
48
|
+
ok: false,
|
|
49
|
+
because: `the mirror is schema ${String(file?.schema)}, this build reads ${exports.GOAL_STORE_SCHEMA}`,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
if (!Array.isArray(file.goals))
|
|
53
|
+
return { ok: false, because: 'the mirror has no goals array' };
|
|
54
|
+
// Row-level rather than file-level: one malformed goal from a newer server
|
|
55
|
+
// should cost that goal, not the whole mirror. Anything the shape check
|
|
56
|
+
// rejects is simply not carried forward — and the next pull replaces the
|
|
57
|
+
// file wholesale anyway.
|
|
58
|
+
const kept = file.goals.filter(isGoal);
|
|
59
|
+
return { ok: true, goals: kept, dropped: file.goals.length - kept.length };
|
|
60
|
+
}
|
|
61
|
+
class GoalStore {
|
|
62
|
+
stateDir;
|
|
63
|
+
fs;
|
|
64
|
+
log;
|
|
65
|
+
/** Distinguishes two writes from ONE process; the pid distinguishes processes. */
|
|
66
|
+
static writes = 0;
|
|
67
|
+
goals = [];
|
|
68
|
+
loaded = false;
|
|
69
|
+
constructor(stateDir, fs,
|
|
70
|
+
/** Optional: a discarded mirror is worth saying once, not silently. */
|
|
71
|
+
log) {
|
|
72
|
+
this.stateDir = stateDir;
|
|
73
|
+
this.fs = fs;
|
|
74
|
+
this.log = log;
|
|
75
|
+
}
|
|
76
|
+
get path() {
|
|
77
|
+
return `${this.stateDir}/goals.json`;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Read what is on disk.
|
|
81
|
+
*
|
|
82
|
+
* Anything unreadable, unparseable, wrongly shaped or of an unrecognised
|
|
83
|
+
* schema version is DISCARDED — treated as an empty mirror — and reported.
|
|
84
|
+
* Never a throw: this file is a cache of something the server can always be
|
|
85
|
+
* asked for again, and a daemon that dies over it has turned a free problem
|
|
86
|
+
* into an outage.
|
|
87
|
+
*
|
|
88
|
+
* An unknown `schema` is deliberately handled the same way. `cursor.json`
|
|
89
|
+
* declares a version field that nothing reads, so this is the first store
|
|
90
|
+
* where the field means anything; treating a future shape as corrupt lets an
|
|
91
|
+
* older build be downgraded onto a newer state dir and simply re-pull.
|
|
92
|
+
*/
|
|
93
|
+
async load() {
|
|
94
|
+
const outcome = await this.readIn();
|
|
95
|
+
// "Discard and re-pull" has to be true of the DISK, not of a field nobody
|
|
96
|
+
// reads. Leaving the bad bytes in place meant a daemon that started corrupt
|
|
97
|
+
// and stayed offline kept them for ever, and the next process re-discovered
|
|
98
|
+
// the same damage — the invariant held in memory and nowhere else.
|
|
99
|
+
if (outcome === 'discarded') {
|
|
100
|
+
try {
|
|
101
|
+
await this.write([]);
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
// Best-effort. A mirror that cannot be rewritten is still discarded in
|
|
105
|
+
// memory, and the next successful pull replaces it wholesale anyway.
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return outcome;
|
|
109
|
+
}
|
|
110
|
+
async readIn() {
|
|
111
|
+
this.loaded = true;
|
|
112
|
+
let text;
|
|
113
|
+
try {
|
|
114
|
+
text = await this.fs.readFile(this.path);
|
|
115
|
+
}
|
|
116
|
+
catch (e) {
|
|
117
|
+
this.goals = [];
|
|
118
|
+
this.log?.(`goals : could not read the mirror (${e.message}) — will re-pull`);
|
|
119
|
+
return 'discarded';
|
|
120
|
+
}
|
|
121
|
+
if (text === null) {
|
|
122
|
+
this.goals = [];
|
|
123
|
+
return 'absent';
|
|
124
|
+
}
|
|
125
|
+
const parsed = parseMirror(text);
|
|
126
|
+
if (!parsed.ok) {
|
|
127
|
+
this.goals = [];
|
|
128
|
+
this.log?.(`goals : ${parsed.because} — discarding it and re-pulling`);
|
|
129
|
+
return 'discarded';
|
|
130
|
+
}
|
|
131
|
+
if (parsed.dropped > 0) {
|
|
132
|
+
this.log?.(`goals : ignored ${parsed.dropped} unreadable goal(s) in the mirror`);
|
|
133
|
+
}
|
|
134
|
+
this.goals = parsed.goals;
|
|
135
|
+
return 'ok';
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* What the mirror says RIGHT NOW, without adopting it.
|
|
139
|
+
*
|
|
140
|
+
* `get()` answers from an array this process loaded once, which is correct
|
|
141
|
+
* for the hundred cheap questions a run asks of it and wrong for the one
|
|
142
|
+
* expensive question asked after several minutes have passed. An adaptive
|
|
143
|
+
* Start spends up to eight minutes inside a goal evaluation; if a person
|
|
144
|
+
* amended or abandoned the goal in that window and the daemon has since
|
|
145
|
+
* written the new mirror, comparing the frozen snapshot against a value taken
|
|
146
|
+
* from that same snapshot compares a thing to itself and can only ever agree.
|
|
147
|
+
* That is not a re-check, and an adversarial review proved it was not
|
|
148
|
+
* behaving as one.
|
|
149
|
+
*
|
|
150
|
+
* So this reads the file again, and deliberately does NOT adopt what it
|
|
151
|
+
* finds: no `this.goals`, no `this.loaded`, no write, not even the discard
|
|
152
|
+
* rewrite that `load()` performs. It is a question, not a state change, and a
|
|
153
|
+
* run holding the lease must not quietly become the mirror's second writer
|
|
154
|
+
* on its way to asking one.
|
|
155
|
+
*
|
|
156
|
+
* ONE read, so what comes back is one whole state of the file rather than
|
|
157
|
+
* fields sampled across two of them.
|
|
158
|
+
*/
|
|
159
|
+
async readFresh() {
|
|
160
|
+
let text;
|
|
161
|
+
try {
|
|
162
|
+
text = await this.fs.readFile(this.path);
|
|
163
|
+
}
|
|
164
|
+
catch (e) {
|
|
165
|
+
return { ok: false, because: `the goal mirror could not be read (${e.message})` };
|
|
166
|
+
}
|
|
167
|
+
// Absent is NOT an empty mirror here. `load()` may treat it as one because
|
|
168
|
+
// a pull will fill it; a run asking whether its authority still stands must
|
|
169
|
+
// not read "the file is missing" as "nothing has changed".
|
|
170
|
+
if (text === null)
|
|
171
|
+
return { ok: false, because: 'there is no goal mirror on this machine' };
|
|
172
|
+
const parsed = parseMirror(text);
|
|
173
|
+
return parsed.ok ? { ok: true, goals: parsed.goals } : { ok: false, because: parsed.because };
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Take the server's answer as the new truth, whole.
|
|
177
|
+
*
|
|
178
|
+
* No merge and no diff: the argument IS the state. A goal the server no longer
|
|
179
|
+
* returns is gone from the mirror, which is what makes an abandoned goal
|
|
180
|
+
* disappear here without anything having to delete it.
|
|
181
|
+
*/
|
|
182
|
+
async replace(goals) {
|
|
183
|
+
const next = goals.filter(isGoal);
|
|
184
|
+
await this.write(next);
|
|
185
|
+
// Committed to memory only AFTER the durable write. The other order leaves
|
|
186
|
+
// this object ahead of the file when a write fails — the caller is told the
|
|
187
|
+
// mirror could not be written, while `all()` cheerfully returns the goals
|
|
188
|
+
// that never landed, and nothing can tell the two states apart afterwards.
|
|
189
|
+
this.goals = next;
|
|
190
|
+
this.loaded = true;
|
|
191
|
+
}
|
|
192
|
+
async write(goals) {
|
|
193
|
+
const body = { schema: exports.GOAL_STORE_SCHEMA, goals: [...goals] };
|
|
194
|
+
await this.fs.mkdir(this.stateDir);
|
|
195
|
+
// Temp-then-rename, like every other store here: a half-written mirror read
|
|
196
|
+
// by the next process is worse than no mirror, because it looks like data.
|
|
197
|
+
// The temp name is PRIVATE TO THIS WRITER. A shared `goals.json.tmp` is
|
|
198
|
+
// two processes writing one path: the second truncates and rewrites what
|
|
199
|
+
// the first is midway through, and then both rename it into place. The
|
|
200
|
+
// rename is atomic and the file it renames is a splice of two writes, and
|
|
201
|
+
// nothing downstream can tell.
|
|
202
|
+
const tmp = `${this.path}.${process.pid}.${(GoalStore.writes += 1)}.tmp`;
|
|
203
|
+
await this.fs.writeFile(tmp, JSON.stringify(body, null, 2) + '\n');
|
|
204
|
+
await this.fs.rename(tmp, this.path);
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Record that a goal has been given up on.
|
|
208
|
+
*
|
|
209
|
+
* Written when THIS machine carries out the release the abandonment produced,
|
|
210
|
+
* so a Start still in flight for the old version cannot resolve against
|
|
211
|
+
* `active` and adopt work back into a goal nobody is pursuing. The server
|
|
212
|
+
* remains authoritative — the next pull overwrites this with the real row,
|
|
213
|
+
* which says the same thing — but the machine must not need the server to
|
|
214
|
+
* remember something it has already been told.
|
|
215
|
+
*
|
|
216
|
+
* A goal the mirror has never heard of is left alone rather than invented:
|
|
217
|
+
* an absent goal can never resolve to `bound` anyway.
|
|
218
|
+
*/
|
|
219
|
+
async markAbandoned(goalId, goalVersion) {
|
|
220
|
+
const local = this.goals.find((g) => g.id === goalId);
|
|
221
|
+
// Never invented. An absent goal cannot resolve to `bound` anyway, so
|
|
222
|
+
// there is nothing to defend against and nothing to fabricate.
|
|
223
|
+
if (!local)
|
|
224
|
+
return 'absent';
|
|
225
|
+
if (local.version > goalVersion) {
|
|
226
|
+
// The mirror is AHEAD of what this command proves. A later server row has
|
|
227
|
+
// already been pulled, and writing this one over it would move the mirror
|
|
228
|
+
// backwards — turning a server-authoritative file into a guess. The goal
|
|
229
|
+
// is abandoned either way; the newer row already says so or says something
|
|
230
|
+
// truer.
|
|
231
|
+
return 'ahead';
|
|
232
|
+
}
|
|
233
|
+
if (local.version === goalVersion) {
|
|
234
|
+
// Same row. The command proves it is abandoned; anything else here is a
|
|
235
|
+
// mirror that disagrees with the transition that produced the command.
|
|
236
|
+
if (local.state === 'abandoned')
|
|
237
|
+
return 'already';
|
|
238
|
+
await this.write1(goalId, { state: 'abandoned', version: goalVersion });
|
|
239
|
+
return 'applied';
|
|
240
|
+
}
|
|
241
|
+
// Behind. The command is durable server-generated proof that the
|
|
242
|
+
// abandonment happened AT this version, so both fields move together — the
|
|
243
|
+
// one thing that must never happen is `abandoned` stamped against an older
|
|
244
|
+
// version, which is a row no server ever wrote and which every version
|
|
245
|
+
// comparison downstream would then read wrongly.
|
|
246
|
+
//
|
|
247
|
+
// Only these two fields move. Anything else on the row stays as the last
|
|
248
|
+
// real pull left it, and the next whole-file refresh replaces all of it.
|
|
249
|
+
await this.write1(goalId, { state: 'abandoned', version: goalVersion });
|
|
250
|
+
return 'applied';
|
|
251
|
+
}
|
|
252
|
+
async write1(goalId, fields) {
|
|
253
|
+
await this.replace(this.goals.map((g) => (g.id === goalId ? { ...g, ...fields } : g)));
|
|
254
|
+
}
|
|
255
|
+
/** Everything the mirror holds, newest first as the server ordered it. */
|
|
256
|
+
all() {
|
|
257
|
+
return [...this.goals];
|
|
258
|
+
}
|
|
259
|
+
get(goalId) {
|
|
260
|
+
return this.goals.find((g) => g.id === goalId) ?? null;
|
|
261
|
+
}
|
|
262
|
+
/** Whether `load` has run. A store nobody loaded is empty for a different reason. */
|
|
263
|
+
isLoaded() {
|
|
264
|
+
return this.loaded;
|
|
265
|
+
}
|
|
266
|
+
size() {
|
|
267
|
+
return this.goals.length;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
exports.GoalStore = GoalStore;
|
|
271
|
+
/**
|
|
272
|
+
* Shape check for a goal off the wire or off disk.
|
|
273
|
+
*
|
|
274
|
+
* Deliberately structural and shallow, in the spirit of `isLooplyEvent`: it
|
|
275
|
+
* guards the fields the machine actually reads. A goal from a newer server with
|
|
276
|
+
* extra fields is kept — dropping it would make an older CLI go blind the day
|
|
277
|
+
* the server grows a column.
|
|
278
|
+
*/
|
|
279
|
+
function isGoal(v) {
|
|
280
|
+
if (typeof v !== 'object' || v === null)
|
|
281
|
+
return false;
|
|
282
|
+
const g = v;
|
|
283
|
+
return (typeof g['id'] === 'string' &&
|
|
284
|
+
typeof g['projectId'] === 'string' &&
|
|
285
|
+
typeof g['text'] === 'string' &&
|
|
286
|
+
(0, core_1.isGoalState)(g['state']) &&
|
|
287
|
+
typeof g['version'] === 'number' &&
|
|
288
|
+
Number.isInteger(g['version']) &&
|
|
289
|
+
typeof g['clientRef'] === 'string' &&
|
|
290
|
+
typeof g['createdBy'] === 'string' &&
|
|
291
|
+
typeof g['createdAt'] === 'string' &&
|
|
292
|
+
typeof g['updatedAt'] === 'string');
|
|
293
|
+
}
|
|
294
|
+
//# sourceMappingURL=goal-store.js.map
|