looply-cli 0.0.0-stage → 0.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/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 +2719 -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/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 +54 -6
- 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,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.recordObservedPublication = recordObservedPublication;
|
|
4
|
+
exports.nodeRevisionOf = nodeRevisionOf;
|
|
5
|
+
exports.nodePublicationRecorder = nodePublicationRecorder;
|
|
6
|
+
const core_1 = require("@looply/core");
|
|
7
|
+
const compatible_sets_1 = require("./compatible-sets");
|
|
8
|
+
const git_driver_1 = require("./git-driver");
|
|
9
|
+
const integration_1 = require("./integration");
|
|
10
|
+
const ledger_store_1 = require("./ledger-store");
|
|
11
|
+
const self_repo_id_1 = require("./self-repo-id");
|
|
12
|
+
/**
|
|
13
|
+
* Offer one observed publication to the ruling, and write the record only if it
|
|
14
|
+
* says to.
|
|
15
|
+
*
|
|
16
|
+
* The order matters and is the ruling's, not this function's: what makes the
|
|
17
|
+
* recording the WRONG ACT first, then drift, then whether it is already down.
|
|
18
|
+
* The one check that lives here is the last one, because it is about the
|
|
19
|
+
* OBSERVATION rather than about the set.
|
|
20
|
+
*/
|
|
21
|
+
async function recordObservedPublication(deps, observed) {
|
|
22
|
+
const declared = deps.declared();
|
|
23
|
+
const records = await deps.records();
|
|
24
|
+
const setId = (0, compatible_sets_1.newestSetId)(records);
|
|
25
|
+
const set = setId === null ? null : (0, compatible_sets_1.setFrom)(records, setId);
|
|
26
|
+
const current = new Map();
|
|
27
|
+
for (const r of declared) {
|
|
28
|
+
const at = await deps.revisionOf(r);
|
|
29
|
+
if (at !== null)
|
|
30
|
+
current.set(r.id, at.sha);
|
|
31
|
+
}
|
|
32
|
+
const ruling = (0, core_1.publicationRuling)({
|
|
33
|
+
declared: declared.map((d) => d.id),
|
|
34
|
+
set,
|
|
35
|
+
current,
|
|
36
|
+
repo: observed.repo,
|
|
37
|
+
});
|
|
38
|
+
if (ruling.kind !== 'record') {
|
|
39
|
+
return { ruling, recorded: false, line: (0, core_1.describePublicationRuling)(ruling) };
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* 🔴 THE RECEIPT HAS TO BE ABOUT THE OPERATION THAT WAS OBSERVED.
|
|
43
|
+
*
|
|
44
|
+
* Everything above is about the SET: does it exist, does it name this
|
|
45
|
+
* repository, has anything drifted. None of that notices that the ref moved
|
|
46
|
+
* AGAIN between the tick and this call — another lane, another run, a person
|
|
47
|
+
* with a shell. The set could still hold and the record would still be true
|
|
48
|
+
* about the world, and it would name an operation that is not why the world
|
|
49
|
+
* looks like that. "Only observed authorized operations create receipts"
|
|
50
|
+
* means this one, not a later one that happens to agree.
|
|
51
|
+
*/
|
|
52
|
+
const here = current.get(observed.repo);
|
|
53
|
+
if (here !== observed.to) {
|
|
54
|
+
const because = `the tick left ${observed.ref} at ${observed.to.slice(0, 7)} and it is at ` +
|
|
55
|
+
`${here === undefined ? 'a revision that could not be read' : here.slice(0, 7)} now — ` +
|
|
56
|
+
'nothing was recorded, because the receipt would name an operation that is not why it is there';
|
|
57
|
+
return { ruling: { kind: 'refused', because }, recorded: false, line: `refusing — ${because}` };
|
|
58
|
+
}
|
|
59
|
+
await deps.append({
|
|
60
|
+
id: (0, compatible_sets_1.publishedId)(ruling.setId, ruling.repo),
|
|
61
|
+
kind: 'published',
|
|
62
|
+
setId: ruling.setId,
|
|
63
|
+
at: deps.now(),
|
|
64
|
+
repo: ruling.repo,
|
|
65
|
+
});
|
|
66
|
+
return { ruling, recorded: true, line: (0, core_1.describePublicationRuling)(ruling) };
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Where a repository is now, on this machine.
|
|
70
|
+
*
|
|
71
|
+
* ⚠️ ONE IMPLEMENTATION, TWO CALLERS — `looply repos` and the daemon's
|
|
72
|
+
* integrator. Two copies of "where is this repository" are two copies that can
|
|
73
|
+
* disagree, and the one that disagrees is the one deciding whether a set has
|
|
74
|
+
* drifted.
|
|
75
|
+
*/
|
|
76
|
+
async function nodeRevisionOf(repo) {
|
|
77
|
+
try {
|
|
78
|
+
const git = new git_driver_1.GitDriver((0, git_driver_1.nodeGitExec)(repo.path));
|
|
79
|
+
// `listBranches` answers "does it exist" and "what is it at" in one call.
|
|
80
|
+
// It prefix-matches, so the name is compared exactly: a
|
|
81
|
+
// `looply/integration-old` lying around must not be read as the
|
|
82
|
+
// integration ref of this repository.
|
|
83
|
+
const branches = await git.listBranches(integration_1.INTEGRATION_BRANCH);
|
|
84
|
+
const integration = branches.find((b) => b.name === integration_1.INTEGRATION_BRANCH);
|
|
85
|
+
if (integration !== undefined)
|
|
86
|
+
return { sha: integration.sha, from: integration_1.INTEGRATION_BRANCH };
|
|
87
|
+
return { sha: await git.headSha(), from: 'HEAD' };
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
// 🔴 NULL, NEVER A GUESS. See `PublicationRecorderDeps.revisionOf`.
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* The daemon's recorder, or nothing at all.
|
|
96
|
+
*
|
|
97
|
+
* ⚠️ NOTHING is the right answer for most projects. A project that declares
|
|
98
|
+
* no sibling repositories has no compatible set to publish against, and a
|
|
99
|
+
* checkout that is not one of the declared repositories cannot say which one
|
|
100
|
+
* published — in both cases the honest thing is to have no recorder rather
|
|
101
|
+
* than one that refuses every tick into the log.
|
|
102
|
+
*/
|
|
103
|
+
function nodePublicationRecorder(cwd, projectState, declared) {
|
|
104
|
+
const self = (0, self_repo_id_1.selfRepoId)(declared, cwd);
|
|
105
|
+
if (declared.length === 0 || self === null)
|
|
106
|
+
return undefined;
|
|
107
|
+
const store = new compatible_sets_1.CompatibleSetStore(projectState, ledger_store_1.nodeLedgerFs);
|
|
108
|
+
let opened = false;
|
|
109
|
+
return async (observed) => {
|
|
110
|
+
if (!opened) {
|
|
111
|
+
await store.open();
|
|
112
|
+
opened = true;
|
|
113
|
+
}
|
|
114
|
+
const out = await recordObservedPublication({
|
|
115
|
+
declared: () => declared,
|
|
116
|
+
revisionOf: nodeRevisionOf,
|
|
117
|
+
records: async () => store.all(),
|
|
118
|
+
append: async (record) => store.append(record),
|
|
119
|
+
now: () => new Date().toISOString(),
|
|
120
|
+
}, { ...observed, repo: self });
|
|
121
|
+
return out.line;
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=publication-recorder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publication-recorder.js","sourceRoot":"","sources":["../src/publication-recorder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { RunDelivery, RunRefusalMark } from './run-refusal-marks';
|
|
2
|
+
/**
|
|
3
|
+
* What key 2 confirmed for a pursuit that ended `satisfied`, or null (L4b).
|
|
4
|
+
*
|
|
5
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
6
|
+
* 🔴 READ AT SETTLE TIME, BESIDE THE DECISION, AND NOT THROUGH IT.
|
|
7
|
+
*
|
|
8
|
+
* The reducer that decides a pursuit is over (`autonomy-controller.ts`) is
|
|
9
|
+
* deliberately goal-blind and decision-only; threading a commit and a set of
|
|
10
|
+
* gate outcomes through it would give it facts it has no business holding. The
|
|
11
|
+
* facts already sit in the refusal marks, keyed by each Start's id, so the one
|
|
12
|
+
* place that SENDS the ending can look them up itself — the decision stays
|
|
13
|
+
* exactly where it was, and only the report gains its evidence.
|
|
14
|
+
*
|
|
15
|
+
* Every Start of a grant is `autonomyStartId(controllerId, n)` for n in
|
|
16
|
+
* 1..MAX_AUTONOMOUS_STARTS, so the search is bounded and exact. The newest
|
|
17
|
+
* `goal_satisfied` mark that carries a delivery wins: it is the refusal that
|
|
18
|
+
* ended the pursuit.
|
|
19
|
+
*
|
|
20
|
+
* Null is an honest answer — an older run wrote no delivery, or key 2 never
|
|
21
|
+
* answered — and the settle then goes out exactly as before.
|
|
22
|
+
*/
|
|
23
|
+
export declare function deliveryForPursuit(find: (requestId: string) => RunRefusalMark | null, controllerId: string, maxOrdinal?: number): RunDelivery | null;
|
|
24
|
+
//# sourceMappingURL=pursuit-delivery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pursuit-delivery.d.ts","sourceRoot":"","sources":["../src/pursuit-delivery.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAEvE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,cAAc,GAAG,IAAI,EAClD,YAAY,EAAE,MAAM,EACpB,UAAU,GAAE,MAA8B,GACzC,WAAW,GAAG,IAAI,CAQpB"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deliveryForPursuit = deliveryForPursuit;
|
|
4
|
+
const core_1 = require("@looply/core");
|
|
5
|
+
const autonomy_store_1 = require("./autonomy-store");
|
|
6
|
+
/**
|
|
7
|
+
* What key 2 confirmed for a pursuit that ended `satisfied`, or null (L4b).
|
|
8
|
+
*
|
|
9
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
10
|
+
* 🔴 READ AT SETTLE TIME, BESIDE THE DECISION, AND NOT THROUGH IT.
|
|
11
|
+
*
|
|
12
|
+
* The reducer that decides a pursuit is over (`autonomy-controller.ts`) is
|
|
13
|
+
* deliberately goal-blind and decision-only; threading a commit and a set of
|
|
14
|
+
* gate outcomes through it would give it facts it has no business holding. The
|
|
15
|
+
* facts already sit in the refusal marks, keyed by each Start's id, so the one
|
|
16
|
+
* place that SENDS the ending can look them up itself — the decision stays
|
|
17
|
+
* exactly where it was, and only the report gains its evidence.
|
|
18
|
+
*
|
|
19
|
+
* Every Start of a grant is `autonomyStartId(controllerId, n)` for n in
|
|
20
|
+
* 1..MAX_AUTONOMOUS_STARTS, so the search is bounded and exact. The newest
|
|
21
|
+
* `goal_satisfied` mark that carries a delivery wins: it is the refusal that
|
|
22
|
+
* ended the pursuit.
|
|
23
|
+
*
|
|
24
|
+
* Null is an honest answer — an older run wrote no delivery, or key 2 never
|
|
25
|
+
* answered — and the settle then goes out exactly as before.
|
|
26
|
+
*/
|
|
27
|
+
function deliveryForPursuit(find, controllerId, maxOrdinal = core_1.MAX_AUTONOMOUS_STARTS) {
|
|
28
|
+
let best = null;
|
|
29
|
+
for (let n = 1; n <= maxOrdinal; n++) {
|
|
30
|
+
const mark = find((0, autonomy_store_1.autonomyStartId)(controllerId, n));
|
|
31
|
+
if (mark === null || mark.code !== 'goal_satisfied' || mark.delivery === undefined)
|
|
32
|
+
continue;
|
|
33
|
+
if (best === null || mark.at > best.at)
|
|
34
|
+
best = mark;
|
|
35
|
+
}
|
|
36
|
+
return best?.delivery ?? null;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=pursuit-delivery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pursuit-delivery.js","sourceRoot":"","sources":["../src/pursuit-delivery.ts"],"names":[],"mappings":";;AAyBA,gDAYC;AArCD,uCAAqD;AACrD,qDAAmD;AAGnD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,SAAgB,kBAAkB,CAChC,IAAkD,EAClD,YAAoB,EACpB,aAAqB,4BAAqB;IAE1C,IAAI,IAAI,GAA0B,IAAI,CAAC;IACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAA,gCAAe,EAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC;QACpD,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,gBAAgB,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS;YAAE,SAAS;QAC7F,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE;YAAE,IAAI,GAAG,IAAI,CAAC;IACtD,CAAC;IACD,OAAO,IAAI,EAAE,QAAQ,IAAI,IAAI,CAAC;AAChC,CAAC"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import type { Item } from '@looply/core';
|
|
2
|
+
import type { LedgerFs } from './ledger-store';
|
|
3
|
+
/**
|
|
4
|
+
* The queue store — `queue.json` under the state dir, holding every item with its
|
|
5
|
+
* id, state, evidence, attempts and version (DESIGN §5, §13 row 7).
|
|
6
|
+
*
|
|
7
|
+
* Unlike `status.json`, the queue file is not a projection: it *is* the truth for
|
|
8
|
+
* curation. Two writers race over it — the loop marking an item `in_progress` and
|
|
9
|
+
* a phone PATCH reordering or blocking it — so every write is optimistic on the
|
|
10
|
+
* item's version. A write against a stale version is rejected with the current
|
|
11
|
+
* version, never silently applied (DESIGN §12 case 22).
|
|
12
|
+
*
|
|
13
|
+
* Reuses {@link LedgerFs} so the same in-memory double drives both stores' tests.
|
|
14
|
+
*/
|
|
15
|
+
/** Everything a caller may change. Id is identity; version is the store's token. */
|
|
16
|
+
export type ItemPatch = Partial<Omit<Item, 'id' | 'version'>>;
|
|
17
|
+
export type QueueWriteResult = {
|
|
18
|
+
ok: true;
|
|
19
|
+
item: Item;
|
|
20
|
+
} | {
|
|
21
|
+
ok: false;
|
|
22
|
+
reason: 'not-found';
|
|
23
|
+
} | {
|
|
24
|
+
ok: false;
|
|
25
|
+
reason: 'stale-version';
|
|
26
|
+
currentVersion: number;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Outcome of {@link QueueStore.insertAll}.
|
|
30
|
+
*
|
|
31
|
+
* `alreadyPresent` is not a failure. A caller that derives its ids from
|
|
32
|
+
* something stable — rather than minting a fresh one per attempt — will hand
|
|
33
|
+
* the same batch over again after a crash or a redelivery, and the honest
|
|
34
|
+
* answer to "insert this" for something already inserted is "it is already
|
|
35
|
+
* there", not an exception. Reported rather than swallowed, so a caller can
|
|
36
|
+
* tell a fresh batch from a repeat and say so.
|
|
37
|
+
*/
|
|
38
|
+
export type BatchInsertResult = {
|
|
39
|
+
ok: true;
|
|
40
|
+
inserted: Item[];
|
|
41
|
+
alreadyPresent: string[];
|
|
42
|
+
}
|
|
43
|
+
/** The same id twice in ONE batch. That is a caller bug, not a repeat. */
|
|
44
|
+
| {
|
|
45
|
+
ok: false;
|
|
46
|
+
reason: 'duplicate-id';
|
|
47
|
+
id: string;
|
|
48
|
+
};
|
|
49
|
+
/** All-or-nothing outcome of {@link QueueStore.patchAll}. */
|
|
50
|
+
export type BatchWriteResult = {
|
|
51
|
+
ok: true;
|
|
52
|
+
items: Item[];
|
|
53
|
+
} | {
|
|
54
|
+
ok: false;
|
|
55
|
+
reason: 'duplicate-id';
|
|
56
|
+
} | {
|
|
57
|
+
ok: false;
|
|
58
|
+
reason: 'not-found';
|
|
59
|
+
id: string;
|
|
60
|
+
} | {
|
|
61
|
+
ok: false;
|
|
62
|
+
reason: 'stale-version';
|
|
63
|
+
id: string;
|
|
64
|
+
currentVersion: number;
|
|
65
|
+
};
|
|
66
|
+
export declare class QueueStore {
|
|
67
|
+
private readonly stateDir;
|
|
68
|
+
private readonly fs;
|
|
69
|
+
/** Distinguishes two writes from ONE process; the pid distinguishes processes. */
|
|
70
|
+
private static writes;
|
|
71
|
+
private items;
|
|
72
|
+
private opened;
|
|
73
|
+
constructor(stateDir: string, fs: LedgerFs);
|
|
74
|
+
private get queuePath();
|
|
75
|
+
/**
|
|
76
|
+
* Load whatever is on disk. A missing file is an empty queue; a corrupt file is
|
|
77
|
+
* a loud failure. The file only ever lands whole (temp-then-rename), so corrupt
|
|
78
|
+
* means something outside this store touched it — starting empty here would
|
|
79
|
+
* silently discard every item a night of scanning produced.
|
|
80
|
+
*/
|
|
81
|
+
open(): Promise<Item[]>;
|
|
82
|
+
/** All items, in stored order. Callers sort by `orderKey` when order matters. */
|
|
83
|
+
list(): Item[];
|
|
84
|
+
get(id: string): Item | undefined;
|
|
85
|
+
/** New items enter at version 1; the store owns the concurrency token. */
|
|
86
|
+
insert(input: Omit<Item, 'version'>): Promise<Item>;
|
|
87
|
+
/**
|
|
88
|
+
* Apply `patch` only if the caller saw the current version. On success the
|
|
89
|
+
* version bumps, so the loser of a race gets `stale-version` with the number
|
|
90
|
+
* it must refetch — the rejection is the feature, not the error path.
|
|
91
|
+
*/
|
|
92
|
+
update(id: string, expectedVersion: number, patch: ItemPatch): Promise<QueueWriteResult>;
|
|
93
|
+
/**
|
|
94
|
+
* Apply several patches as ONE durable write, or apply none of them.
|
|
95
|
+
*
|
|
96
|
+
* `update` in a loop is not this: it persists after each item, so a crash
|
|
97
|
+
* halfway leaves the queue in a state no caller asked for and no reader can
|
|
98
|
+
* name — half a set of items moved, half not. Every check runs first, then
|
|
99
|
+
* every change, then a single temp-then-rename. There is no window in which
|
|
100
|
+
* the file on disk holds a partial batch.
|
|
101
|
+
*
|
|
102
|
+
* Deliberately says nothing about WHY a caller wants several items changed
|
|
103
|
+
* together. It takes patches; what they mean is the caller's business.
|
|
104
|
+
*/
|
|
105
|
+
patchAll(patches: readonly {
|
|
106
|
+
id: string;
|
|
107
|
+
expectedVersion: number;
|
|
108
|
+
patch: ItemPatch;
|
|
109
|
+
}[]): Promise<BatchWriteResult>;
|
|
110
|
+
private assertOpened;
|
|
111
|
+
/**
|
|
112
|
+
* Add several items as ONE durable write, or add none of them.
|
|
113
|
+
*
|
|
114
|
+
* `insert` in a loop is not this: it persists after each item, so a process
|
|
115
|
+
* that dies partway leaves an arbitrary PREFIX of the batch on disk. For a
|
|
116
|
+
* batch that means something as a whole — a compiled plan, say — a prefix is
|
|
117
|
+
* a shape nobody asked for and nothing records which part landed.
|
|
118
|
+
*
|
|
119
|
+
* An id the store already holds is SKIPPED, not refused. That is what makes
|
|
120
|
+
* a retry converge: re-offering a batch whose ids are derived from something
|
|
121
|
+
* stable inserts only what is missing, and re-offering it complete inserts
|
|
122
|
+
* nothing at all. `insert` still throws on a duplicate, because a single
|
|
123
|
+
* insert naming an existing id really is a mistake.
|
|
124
|
+
*
|
|
125
|
+
* Deliberately says nothing about WHY a caller wants several items added
|
|
126
|
+
* together. It takes items; what they mean is the caller's business.
|
|
127
|
+
*/
|
|
128
|
+
insertAll(inputs: readonly Omit<Item, 'version'>[]): Promise<BatchInsertResult>;
|
|
129
|
+
private persist;
|
|
130
|
+
private writeList;
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=queue-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue-store.d.ts","sourceRoot":"","sources":["../src/queue-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C;;;;;;;;;;;GAWG;AAEH,oFAAoF;AACpF,MAAM,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC;AAE9D,MAAM,MAAM,gBAAgB,GACxB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GACxB;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAE,GAClC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,eAAe,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnE;;;;;;;;;GASG;AACH,MAAM,MAAM,iBAAiB,GACzB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,IAAI,EAAE,CAAC;IAAC,cAAc,EAAE,MAAM,EAAE,CAAA;CAAE;AAC1D,0EAA0E;GACxE;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,cAAc,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtD,6DAA6D;AAC7D,MAAM,MAAM,gBAAgB,GACxB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,GAC3B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,cAAc,CAAA;CAAE,GACrC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,WAAW,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC9C;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,eAAe,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/E,qBAAa,UAAU;IAQnB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,EAAE;IARrB,kFAAkF;IAClF,OAAO,CAAC,MAAM,CAAC,MAAM,CAAK;IAE1B,OAAO,CAAC,KAAK,CAA2B;IACxC,OAAO,CAAC,MAAM,CAAS;gBAGJ,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,QAAQ;IAG/B,OAAO,KAAK,SAAS,GAEpB;IAED;;;;;OAKG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;IAW7B,iFAAiF;IACjF,IAAI,IAAI,IAAI,EAAE;IAId,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAIjC,0EAA0E;IACpE,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAWzD;;;;OAIG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAa9F;;;;;;;;;;;OAWG;IACG,QAAQ,CACZ,OAAO,EAAE,SAAS;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,SAAS,CAAA;KAAE,EAAE,GAC5E,OAAO,CAAC,gBAAgB,CAAC;IA2B5B,OAAO,CAAC,YAAY;IAOpB;;;;;;;;;;;;;;;;OAgBG;IACG,SAAS,CAAC,MAAM,EAAE,SAAS,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC;YAoCvE,OAAO;YAIP,SAAS;CAcxB"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.QueueStore = void 0;
|
|
4
|
+
class QueueStore {
|
|
5
|
+
stateDir;
|
|
6
|
+
fs;
|
|
7
|
+
/** Distinguishes two writes from ONE process; the pid distinguishes processes. */
|
|
8
|
+
static writes = 0;
|
|
9
|
+
items = new Map();
|
|
10
|
+
opened = false;
|
|
11
|
+
constructor(stateDir, fs) {
|
|
12
|
+
this.stateDir = stateDir;
|
|
13
|
+
this.fs = fs;
|
|
14
|
+
}
|
|
15
|
+
get queuePath() {
|
|
16
|
+
return `${this.stateDir}/queue.json`;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Load whatever is on disk. A missing file is an empty queue; a corrupt file is
|
|
20
|
+
* a loud failure. The file only ever lands whole (temp-then-rename), so corrupt
|
|
21
|
+
* means something outside this store touched it — starting empty here would
|
|
22
|
+
* silently discard every item a night of scanning produced.
|
|
23
|
+
*/
|
|
24
|
+
async open() {
|
|
25
|
+
await this.fs.mkdir(this.stateDir);
|
|
26
|
+
const text = await this.fs.readFile(this.queuePath);
|
|
27
|
+
if (text !== null) {
|
|
28
|
+
const parsed = JSON.parse(text);
|
|
29
|
+
this.items = new Map(parsed.map((i) => [i.id, i]));
|
|
30
|
+
}
|
|
31
|
+
this.opened = true;
|
|
32
|
+
return this.list();
|
|
33
|
+
}
|
|
34
|
+
/** All items, in stored order. Callers sort by `orderKey` when order matters. */
|
|
35
|
+
list() {
|
|
36
|
+
return [...this.items.values()];
|
|
37
|
+
}
|
|
38
|
+
get(id) {
|
|
39
|
+
return this.items.get(id);
|
|
40
|
+
}
|
|
41
|
+
/** New items enter at version 1; the store owns the concurrency token. */
|
|
42
|
+
async insert(input) {
|
|
43
|
+
this.assertOpened();
|
|
44
|
+
if (this.items.has(input.id)) {
|
|
45
|
+
throw new Error(`queue: duplicate item id ${input.id}`);
|
|
46
|
+
}
|
|
47
|
+
const item = { ...input, version: 1 };
|
|
48
|
+
this.items.set(item.id, item);
|
|
49
|
+
await this.persist();
|
|
50
|
+
return item;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Apply `patch` only if the caller saw the current version. On success the
|
|
54
|
+
* version bumps, so the loser of a race gets `stale-version` with the number
|
|
55
|
+
* it must refetch — the rejection is the feature, not the error path.
|
|
56
|
+
*/
|
|
57
|
+
async update(id, expectedVersion, patch) {
|
|
58
|
+
this.assertOpened();
|
|
59
|
+
const current = this.items.get(id);
|
|
60
|
+
if (current === undefined)
|
|
61
|
+
return { ok: false, reason: 'not-found' };
|
|
62
|
+
if (current.version !== expectedVersion) {
|
|
63
|
+
return { ok: false, reason: 'stale-version', currentVersion: current.version };
|
|
64
|
+
}
|
|
65
|
+
const next = { ...current, ...patch, id: current.id, version: current.version + 1 };
|
|
66
|
+
this.items.set(id, next);
|
|
67
|
+
await this.persist();
|
|
68
|
+
return { ok: true, item: next };
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Apply several patches as ONE durable write, or apply none of them.
|
|
72
|
+
*
|
|
73
|
+
* `update` in a loop is not this: it persists after each item, so a crash
|
|
74
|
+
* halfway leaves the queue in a state no caller asked for and no reader can
|
|
75
|
+
* name — half a set of items moved, half not. Every check runs first, then
|
|
76
|
+
* every change, then a single temp-then-rename. There is no window in which
|
|
77
|
+
* the file on disk holds a partial batch.
|
|
78
|
+
*
|
|
79
|
+
* Deliberately says nothing about WHY a caller wants several items changed
|
|
80
|
+
* together. It takes patches; what they mean is the caller's business.
|
|
81
|
+
*/
|
|
82
|
+
async patchAll(patches) {
|
|
83
|
+
this.assertOpened();
|
|
84
|
+
// The same id twice would make the second patch race the first through one
|
|
85
|
+
// map, and the caller almost certainly did not mean it.
|
|
86
|
+
const ids = new Set(patches.map((p) => p.id));
|
|
87
|
+
if (ids.size !== patches.length)
|
|
88
|
+
return { ok: false, reason: 'duplicate-id' };
|
|
89
|
+
const next = [];
|
|
90
|
+
for (const p of patches) {
|
|
91
|
+
const current = this.items.get(p.id);
|
|
92
|
+
if (current === undefined)
|
|
93
|
+
return { ok: false, reason: 'not-found', id: p.id };
|
|
94
|
+
if (current.version !== p.expectedVersion) {
|
|
95
|
+
return { ok: false, reason: 'stale-version', id: p.id, currentVersion: current.version };
|
|
96
|
+
}
|
|
97
|
+
next.push({ ...current, ...p.patch, id: current.id, version: current.version + 1 });
|
|
98
|
+
}
|
|
99
|
+
// Nothing above mutated anything, so a refusal leaves the store untouched
|
|
100
|
+
// in memory as well as on disk.
|
|
101
|
+
for (const item of next)
|
|
102
|
+
this.items.set(item.id, item);
|
|
103
|
+
// An empty batch is a legitimate no-op — "adopt nothing new" is a real
|
|
104
|
+
// request — and rewriting the file to prove it would be a write for nothing.
|
|
105
|
+
if (next.length)
|
|
106
|
+
await this.persist();
|
|
107
|
+
return { ok: true, items: next };
|
|
108
|
+
}
|
|
109
|
+
assertOpened() {
|
|
110
|
+
if (!this.opened) {
|
|
111
|
+
// Writing before replay would clobber the on-disk queue with an empty one.
|
|
112
|
+
throw new Error('queue: write before open() — would overwrite the queue on disk');
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Add several items as ONE durable write, or add none of them.
|
|
117
|
+
*
|
|
118
|
+
* `insert` in a loop is not this: it persists after each item, so a process
|
|
119
|
+
* that dies partway leaves an arbitrary PREFIX of the batch on disk. For a
|
|
120
|
+
* batch that means something as a whole — a compiled plan, say — a prefix is
|
|
121
|
+
* a shape nobody asked for and nothing records which part landed.
|
|
122
|
+
*
|
|
123
|
+
* An id the store already holds is SKIPPED, not refused. That is what makes
|
|
124
|
+
* a retry converge: re-offering a batch whose ids are derived from something
|
|
125
|
+
* stable inserts only what is missing, and re-offering it complete inserts
|
|
126
|
+
* nothing at all. `insert` still throws on a duplicate, because a single
|
|
127
|
+
* insert naming an existing id really is a mistake.
|
|
128
|
+
*
|
|
129
|
+
* Deliberately says nothing about WHY a caller wants several items added
|
|
130
|
+
* together. It takes items; what they mean is the caller's business.
|
|
131
|
+
*/
|
|
132
|
+
async insertAll(inputs) {
|
|
133
|
+
this.assertOpened();
|
|
134
|
+
// Checked across the WHOLE batch before anything is decided, so a refusal
|
|
135
|
+
// leaves the store exactly as it was.
|
|
136
|
+
const seen = new Set();
|
|
137
|
+
for (const input of inputs) {
|
|
138
|
+
if (seen.has(input.id))
|
|
139
|
+
return { ok: false, reason: 'duplicate-id', id: input.id };
|
|
140
|
+
seen.add(input.id);
|
|
141
|
+
}
|
|
142
|
+
const inserted = [];
|
|
143
|
+
const alreadyPresent = [];
|
|
144
|
+
for (const input of inputs) {
|
|
145
|
+
if (this.items.has(input.id)) {
|
|
146
|
+
alreadyPresent.push(input.id);
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
inserted.push({ ...input, version: 1 });
|
|
150
|
+
}
|
|
151
|
+
// Nothing new is a legitimate no-op — a fully repeated batch is the normal
|
|
152
|
+
// shape of a retry — and rewriting the file to prove it would be a write
|
|
153
|
+
// for nothing.
|
|
154
|
+
if (inserted.length) {
|
|
155
|
+
// Written from a computed list, then committed to memory, in that order.
|
|
156
|
+
// The other way round leaves this object claiming items the file does not
|
|
157
|
+
// have when the write fails — and the caller is told the write failed
|
|
158
|
+
// while `list()` cheerfully returns them.
|
|
159
|
+
const next = [...this.items.values(), ...inserted];
|
|
160
|
+
await this.writeList(next);
|
|
161
|
+
for (const item of inserted)
|
|
162
|
+
this.items.set(item.id, item);
|
|
163
|
+
}
|
|
164
|
+
return { ok: true, inserted, alreadyPresent };
|
|
165
|
+
}
|
|
166
|
+
async persist() {
|
|
167
|
+
await this.writeList(this.list());
|
|
168
|
+
}
|
|
169
|
+
async writeList(items) {
|
|
170
|
+
// Temp-then-rename, same contract as status.json: a concurrent reader
|
|
171
|
+
// (`looply queue`, the daemon) never sees half a file. It is also what
|
|
172
|
+
// makes a batch all-or-nothing — a process that dies before the rename
|
|
173
|
+
// leaves an orphaned temp file and a queue.json nobody touched.
|
|
174
|
+
// The temp name is PRIVATE TO THIS WRITER. A shared `queue.json.tmp` is
|
|
175
|
+
// two processes writing one path: the second truncates and rewrites what
|
|
176
|
+
// the first is midway through, and then both rename it into place. The
|
|
177
|
+
// rename is atomic and the file it renames is a splice of two writes, and
|
|
178
|
+
// nothing downstream can tell.
|
|
179
|
+
const tmp = `${this.queuePath}.${process.pid}.${(QueueStore.writes += 1)}.tmp`;
|
|
180
|
+
await this.fs.writeFile(tmp, JSON.stringify(items, null, 2) + '\n');
|
|
181
|
+
await this.fs.rename(tmp, this.queuePath);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
exports.QueueStore = QueueStore;
|
|
185
|
+
//# sourceMappingURL=queue-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue-store.js","sourceRoot":"","sources":["../src/queue-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Item, ItemState } from '@looply/core';
|
|
2
|
+
export interface StateCount {
|
|
3
|
+
state: ItemState;
|
|
4
|
+
count: number;
|
|
5
|
+
}
|
|
6
|
+
/** Counts per state, in triage order. States with no items are left out. */
|
|
7
|
+
export declare function countByState(items: readonly Pick<Item, 'state'>[]): StateCount[];
|
|
8
|
+
/**
|
|
9
|
+
* One line explaining an unpickable queue. Always opens with `no ready items`
|
|
10
|
+
* — `scripts/cli-audit.sh` asserts that phrase, and it is the fact the run
|
|
11
|
+
* refused on.
|
|
12
|
+
*/
|
|
13
|
+
export declare function describeNoReady(items: readonly Pick<Item, 'state'>[]): string;
|
|
14
|
+
//# sourceMappingURL=queue-summary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue-summary.d.ts","sourceRoot":"","sources":["../src/queue-summary.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AA+BpD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,SAAS,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,4EAA4E;AAC5E,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,GAAG,UAAU,EAAE,CAOhF;AA8BD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,GAAG,MAAM,CAS7E"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.countByState = countByState;
|
|
4
|
+
exports.describeNoReady = describeNoReady;
|
|
5
|
+
/**
|
|
6
|
+
* Why the run found nothing to pick.
|
|
7
|
+
*
|
|
8
|
+
* `looply run` picks items in exactly one state (`ready`), and every item a
|
|
9
|
+
* scan writes starts as `draft` — a claim about the code until a verify pass
|
|
10
|
+
* confirms it. So the commonest state right after a scan is a queue full of
|
|
11
|
+
* work the run refuses to touch, and saying only "no ready items" there reads
|
|
12
|
+
* as "the scan found nothing", which is the opposite of the truth. Name what
|
|
13
|
+
* is actually in the queue, and name what would make one of them pickable.
|
|
14
|
+
*
|
|
15
|
+
* Pure: the caller owns the queue file and the terminal.
|
|
16
|
+
*/
|
|
17
|
+
/** Triage order: what someone can act on first, what is settled last. */
|
|
18
|
+
const STATE_ORDER = [
|
|
19
|
+
'ready',
|
|
20
|
+
'draft',
|
|
21
|
+
'verifying',
|
|
22
|
+
'in_progress',
|
|
23
|
+
'blocked',
|
|
24
|
+
'stale',
|
|
25
|
+
'duplicate',
|
|
26
|
+
'split',
|
|
27
|
+
'done',
|
|
28
|
+
'closed',
|
|
29
|
+
];
|
|
30
|
+
const STATE_LABEL = { in_progress: 'in progress' };
|
|
31
|
+
/** Counts per state, in triage order. States with no items are left out. */
|
|
32
|
+
function countByState(items) {
|
|
33
|
+
const counts = new Map();
|
|
34
|
+
for (const item of items)
|
|
35
|
+
counts.set(item.state, (counts.get(item.state) ?? 0) + 1);
|
|
36
|
+
return STATE_ORDER.filter((state) => counts.has(state)).map((state) => ({
|
|
37
|
+
state,
|
|
38
|
+
count: counts.get(state),
|
|
39
|
+
}));
|
|
40
|
+
}
|
|
41
|
+
function has(counts, state) {
|
|
42
|
+
return counts.some((c) => c.state === state && c.count > 0);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* The one thing worth doing next. Ordered by which state is actually holding
|
|
46
|
+
* the run up, not by how many items are in it: a single unverified draft is a
|
|
47
|
+
* more useful thing to say than fifty closed ones.
|
|
48
|
+
*/
|
|
49
|
+
function nextStep(counts) {
|
|
50
|
+
if (has(counts, 'draft') || has(counts, 'verifying')) {
|
|
51
|
+
// This used to send people to the app, which predates `looply verify`.
|
|
52
|
+
// Marking an item ready by hand skips the very check that makes it
|
|
53
|
+
// pickable, so pointing at the app was wrong advice as well as remote.
|
|
54
|
+
return 'Run `looply verify` to check them against the code — a run does the same pass itself before picking.';
|
|
55
|
+
}
|
|
56
|
+
if (has(counts, 'in_progress')) {
|
|
57
|
+
// The advice used to be "reset it from the app", which was never possible:
|
|
58
|
+
// the phone patches the server's item table and nothing carries that back
|
|
59
|
+
// down to the queue this run picks from. The next run now recovers it.
|
|
60
|
+
return 'An item is still marked in progress, so a previous run did not finish it. Start a run and it will put the item back — or say why it cannot.';
|
|
61
|
+
}
|
|
62
|
+
if (has(counts, 'blocked')) {
|
|
63
|
+
return 'Every item is blocked. `looply queue` says why each one is; unblock one from the app, or run `looply scan` to find other work.';
|
|
64
|
+
}
|
|
65
|
+
return 'Everything in the queue is settled. Run `looply scan` to find more work.';
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* One line explaining an unpickable queue. Always opens with `no ready items`
|
|
69
|
+
* — `scripts/cli-audit.sh` asserts that phrase, and it is the fact the run
|
|
70
|
+
* refused on.
|
|
71
|
+
*/
|
|
72
|
+
function describeNoReady(items) {
|
|
73
|
+
const counts = countByState(items);
|
|
74
|
+
if (!counts.length) {
|
|
75
|
+
return 'no ready items: the queue is empty. Run `looply scan` to find work, or add an item from the app.';
|
|
76
|
+
}
|
|
77
|
+
const inventory = counts
|
|
78
|
+
.map(({ state, count }) => `${count} ${STATE_LABEL[state] ?? state}`)
|
|
79
|
+
.join(', ');
|
|
80
|
+
return `no ready items: the queue holds ${inventory}. ${nextStep(counts)}`;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=queue-summary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue-summary.js","sourceRoot":"","sources":["../src/queue-summary.ts"],"names":[],"mappings":";;AAqCA,oCAOC;AAmCD,0CASC;AAtFD;;;;;;;;;;;GAWG;AAEH,yEAAyE;AACzE,MAAM,WAAW,GAAyB;IACxC,OAAO;IACP,OAAO;IACP,WAAW;IACX,aAAa;IACb,SAAS;IACT,OAAO;IACP,WAAW;IACX,OAAO;IACP,MAAM;IACN,QAAQ;CACT,CAAC;AAEF,MAAM,WAAW,GAAuC,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC;AAOvF,4EAA4E;AAC5E,SAAgB,YAAY,CAAC,KAAqC;IAChE,MAAM,MAAM,GAAG,IAAI,GAAG,EAAqB,CAAC;IAC5C,KAAK,MAAM,IAAI,IAAI,KAAK;QAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACpF,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACtE,KAAK;QACL,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAE;KAC1B,CAAC,CAAC,CAAC;AACN,CAAC;AAED,SAAS,GAAG,CAAC,MAA6B,EAAE,KAAgB;IAC1D,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED;;;;GAIG;AACH,SAAS,QAAQ,CAAC,MAA6B;IAC7C,IAAI,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,CAAC;QACrD,uEAAuE;QACvE,mEAAmE;QACnE,uEAAuE;QACvE,OAAO,sGAAsG,CAAC;IAChH,CAAC;IACD,IAAI,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,EAAE,CAAC;QAC/B,2EAA2E;QAC3E,0EAA0E;QAC1E,uEAAuE;QACvE,OAAO,6IAA6I,CAAC;IACvJ,CAAC;IACD,IAAI,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,CAAC;QAC3B,OAAO,gIAAgI,CAAC;IAC1I,CAAC;IACD,OAAO,0EAA0E,CAAC;AACpF,CAAC;AAED;;;;GAIG;AACH,SAAgB,eAAe,CAAC,KAAqC;IACnE,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACnC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACnB,OAAO,kGAAkG,CAAC;IAC5G,CAAC;IACD,MAAM,SAAS,GAAG,MAAM;SACrB,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,GAAG,KAAK,IAAI,WAAW,CAAC,KAAK,CAAC,IAAI,KAAK,EAAE,CAAC;SACpE,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,OAAO,mCAAmC,SAAS,KAAK,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;AAC7E,CAAC"}
|