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,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WHAT A FRESH CHECKOUT NEEDS THAT GIT DOES NOT CARRY.
|
|
3
|
+
*
|
|
4
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
5
|
+
* 🔴 THE PRODUCT MAKES CHECKOUTS AND THEN GATES THEM, AND THEY HAD NO
|
|
6
|
+
* DEPENDENCIES.
|
|
7
|
+
*
|
|
8
|
+
* Two places create a checkout and immediately run the project's own gate in it:
|
|
9
|
+
*
|
|
10
|
+
* workspace.ts a second worker's tree (`run --new-workspace`)
|
|
11
|
+
* integration-runtime.ts the throwaway tree a candidate is checked in
|
|
12
|
+
*
|
|
13
|
+
* Both are `git worktree add`, so both contain exactly what git tracks — and
|
|
14
|
+
* `node_modules` is gitignored in every JavaScript project there has ever been.
|
|
15
|
+
* The contained gate runs with `network: 'none'` BY DESIGN, so it cannot install
|
|
16
|
+
* them either. The result is a gate that cannot pass for any project with a
|
|
17
|
+
* dependency, in a checkout the product made for the purpose of gating.
|
|
18
|
+
*
|
|
19
|
+
* MEASURED, on a TypeScript project whose gate is `tsc` + `node --test`:
|
|
20
|
+
* two workers, four rounds each, every round red on `tsc` with the SAME output
|
|
21
|
+
* digest (38faf4ea), 95–106 s per attempt; and the integration lane refusing
|
|
22
|
+
* both finished branches with "2 required check(s) failed against the
|
|
23
|
+
* candidate: tsc, test" — while the identical commit passed 8/8 in a checkout
|
|
24
|
+
* that happened to have `node_modules` in it.
|
|
25
|
+
*
|
|
26
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
27
|
+
* WHY A DECLARED LIST, AND NOT A CLEVERER ANSWER.
|
|
28
|
+
*
|
|
29
|
+
* `npm ci` is the obvious thought and it is wrong here twice: it needs the
|
|
30
|
+
* network the gate deliberately does not have, and it assumes a package manager
|
|
31
|
+
* this product does not otherwise care about. Guessing `node_modules` is wrong
|
|
32
|
+
* for a different reason — it is a guess, and a product that silently copies
|
|
33
|
+
* directories a person did not name is a product nobody can predict.
|
|
34
|
+
*
|
|
35
|
+
* So the person names them, in `run.carry_into_checkouts`, and absent means
|
|
36
|
+
* absent: an empty list copies nothing and every existing project behaves
|
|
37
|
+
* exactly as it did.
|
|
38
|
+
*
|
|
39
|
+
* ⚠️ A COPY, NEVER A LINK. A junction would be faster and is the one thing this
|
|
40
|
+
* must not do: both call sites DELETE their checkout when they are finished —
|
|
41
|
+
* `removeWorktree` then `rmSync(recursive)` — and a recursive delete walks a
|
|
42
|
+
* junction into the real directory behind it. The cost of getting that wrong is
|
|
43
|
+
* the project's own `node_modules`, and it is paid silently.
|
|
44
|
+
*/
|
|
45
|
+
export declare class CarryError extends Error {
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Names this will carry, and the rule is deliberately narrow: one plain
|
|
49
|
+
* top-level directory name, nothing else.
|
|
50
|
+
*
|
|
51
|
+
* ⚠️ NO SEPARATORS, NO `..`, NO ABSOLUTE PATHS, NO DOT NAMES. A carry list is
|
|
52
|
+
* read from `.looply/config.yaml`, which lives inside the worktree the model may
|
|
53
|
+
* edit. `..` or `C:\` would turn a convenience into a copy of somewhere else
|
|
54
|
+
* entirely, and a dot name would let `.git` or `.looply` be overwritten in the
|
|
55
|
+
* new checkout — the two directories whose contents decide what git executes
|
|
56
|
+
* and what the run believes about itself.
|
|
57
|
+
*/
|
|
58
|
+
export declare function carryNameTrouble(name: string): string | null;
|
|
59
|
+
export interface CarryResult {
|
|
60
|
+
readonly carried: readonly string[];
|
|
61
|
+
/** Named but not present in the project. Not an error: a project may not have built yet. */
|
|
62
|
+
readonly absent: readonly string[];
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Copy each named directory from the project into a checkout the product made.
|
|
66
|
+
*
|
|
67
|
+
* ⚠️ NEVER OVERWRITES. If the checkout already has the name — because somebody
|
|
68
|
+
* tracked it, or a previous carry ran — it is left exactly as it is. The tracked
|
|
69
|
+
* tree is what git says it is, and this must not quietly replace part of it.
|
|
70
|
+
*
|
|
71
|
+
* ⚠️ AND A FAILED CARRY IS A THROW, NOT A SHRUG. A checkout half-provisioned is
|
|
72
|
+
* a gate that fails for a reason nobody can see; the caller turns this into a
|
|
73
|
+
* refusal that names the directory.
|
|
74
|
+
*/
|
|
75
|
+
export declare function carryIntoCheckout(projectRoot: string, checkoutDir: string, names: readonly string[]): CarryResult;
|
|
76
|
+
//# sourceMappingURL=checkout-carry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkout-carry.d.ts","sourceRoot":"","sources":["../src/checkout-carry.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAEH,qBAAa,UAAW,SAAQ,KAAK;CAAG;AAExC;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAO5D;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,4FAA4F;IAC5F,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,SAAS,MAAM,EAAE,GACvB,WAAW,CAmCb"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CarryError = void 0;
|
|
4
|
+
exports.carryNameTrouble = carryNameTrouble;
|
|
5
|
+
exports.carryIntoCheckout = carryIntoCheckout;
|
|
6
|
+
const node_fs_1 = require("node:fs");
|
|
7
|
+
const node_path_1 = require("node:path");
|
|
8
|
+
/**
|
|
9
|
+
* WHAT A FRESH CHECKOUT NEEDS THAT GIT DOES NOT CARRY.
|
|
10
|
+
*
|
|
11
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
12
|
+
* 🔴 THE PRODUCT MAKES CHECKOUTS AND THEN GATES THEM, AND THEY HAD NO
|
|
13
|
+
* DEPENDENCIES.
|
|
14
|
+
*
|
|
15
|
+
* Two places create a checkout and immediately run the project's own gate in it:
|
|
16
|
+
*
|
|
17
|
+
* workspace.ts a second worker's tree (`run --new-workspace`)
|
|
18
|
+
* integration-runtime.ts the throwaway tree a candidate is checked in
|
|
19
|
+
*
|
|
20
|
+
* Both are `git worktree add`, so both contain exactly what git tracks — and
|
|
21
|
+
* `node_modules` is gitignored in every JavaScript project there has ever been.
|
|
22
|
+
* The contained gate runs with `network: 'none'` BY DESIGN, so it cannot install
|
|
23
|
+
* them either. The result is a gate that cannot pass for any project with a
|
|
24
|
+
* dependency, in a checkout the product made for the purpose of gating.
|
|
25
|
+
*
|
|
26
|
+
* MEASURED, on a TypeScript project whose gate is `tsc` + `node --test`:
|
|
27
|
+
* two workers, four rounds each, every round red on `tsc` with the SAME output
|
|
28
|
+
* digest (38faf4ea), 95–106 s per attempt; and the integration lane refusing
|
|
29
|
+
* both finished branches with "2 required check(s) failed against the
|
|
30
|
+
* candidate: tsc, test" — while the identical commit passed 8/8 in a checkout
|
|
31
|
+
* that happened to have `node_modules` in it.
|
|
32
|
+
*
|
|
33
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
34
|
+
* WHY A DECLARED LIST, AND NOT A CLEVERER ANSWER.
|
|
35
|
+
*
|
|
36
|
+
* `npm ci` is the obvious thought and it is wrong here twice: it needs the
|
|
37
|
+
* network the gate deliberately does not have, and it assumes a package manager
|
|
38
|
+
* this product does not otherwise care about. Guessing `node_modules` is wrong
|
|
39
|
+
* for a different reason — it is a guess, and a product that silently copies
|
|
40
|
+
* directories a person did not name is a product nobody can predict.
|
|
41
|
+
*
|
|
42
|
+
* So the person names them, in `run.carry_into_checkouts`, and absent means
|
|
43
|
+
* absent: an empty list copies nothing and every existing project behaves
|
|
44
|
+
* exactly as it did.
|
|
45
|
+
*
|
|
46
|
+
* ⚠️ A COPY, NEVER A LINK. A junction would be faster and is the one thing this
|
|
47
|
+
* must not do: both call sites DELETE their checkout when they are finished —
|
|
48
|
+
* `removeWorktree` then `rmSync(recursive)` — and a recursive delete walks a
|
|
49
|
+
* junction into the real directory behind it. The cost of getting that wrong is
|
|
50
|
+
* the project's own `node_modules`, and it is paid silently.
|
|
51
|
+
*/
|
|
52
|
+
class CarryError extends Error {
|
|
53
|
+
}
|
|
54
|
+
exports.CarryError = CarryError;
|
|
55
|
+
/**
|
|
56
|
+
* Names this will carry, and the rule is deliberately narrow: one plain
|
|
57
|
+
* top-level directory name, nothing else.
|
|
58
|
+
*
|
|
59
|
+
* ⚠️ NO SEPARATORS, NO `..`, NO ABSOLUTE PATHS, NO DOT NAMES. A carry list is
|
|
60
|
+
* read from `.looply/config.yaml`, which lives inside the worktree the model may
|
|
61
|
+
* edit. `..` or `C:\` would turn a convenience into a copy of somewhere else
|
|
62
|
+
* entirely, and a dot name would let `.git` or `.looply` be overwritten in the
|
|
63
|
+
* new checkout — the two directories whose contents decide what git executes
|
|
64
|
+
* and what the run believes about itself.
|
|
65
|
+
*/
|
|
66
|
+
function carryNameTrouble(name) {
|
|
67
|
+
if (name.length === 0)
|
|
68
|
+
return 'is empty';
|
|
69
|
+
if (name === '.' || name === '..')
|
|
70
|
+
return 'is a relative path, not a name';
|
|
71
|
+
if (/[\\/]/.test(name))
|
|
72
|
+
return 'contains a path separator — name one top-level directory';
|
|
73
|
+
if (name.startsWith('.'))
|
|
74
|
+
return 'starts with a dot — .git and .looply are not carriable';
|
|
75
|
+
if (/^[A-Za-z]:/.test(name))
|
|
76
|
+
return 'is an absolute path, not a name';
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Copy each named directory from the project into a checkout the product made.
|
|
81
|
+
*
|
|
82
|
+
* ⚠️ NEVER OVERWRITES. If the checkout already has the name — because somebody
|
|
83
|
+
* tracked it, or a previous carry ran — it is left exactly as it is. The tracked
|
|
84
|
+
* tree is what git says it is, and this must not quietly replace part of it.
|
|
85
|
+
*
|
|
86
|
+
* ⚠️ AND A FAILED CARRY IS A THROW, NOT A SHRUG. A checkout half-provisioned is
|
|
87
|
+
* a gate that fails for a reason nobody can see; the caller turns this into a
|
|
88
|
+
* refusal that names the directory.
|
|
89
|
+
*/
|
|
90
|
+
function carryIntoCheckout(projectRoot, checkoutDir, names) {
|
|
91
|
+
const carried = [];
|
|
92
|
+
const absent = [];
|
|
93
|
+
for (const name of names) {
|
|
94
|
+
const trouble = carryNameTrouble(name);
|
|
95
|
+
if (trouble !== null) {
|
|
96
|
+
throw new CarryError(`run.carry_into_checkouts: "${name}" ${trouble}`);
|
|
97
|
+
}
|
|
98
|
+
const from = (0, node_path_1.join)(projectRoot, name);
|
|
99
|
+
const to = (0, node_path_1.join)(checkoutDir, name);
|
|
100
|
+
if (!(0, node_fs_1.existsSync)(from)) {
|
|
101
|
+
absent.push(name);
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
if ((0, node_fs_1.existsSync)(to))
|
|
105
|
+
continue;
|
|
106
|
+
/**
|
|
107
|
+
* 🔴 THE SOURCE MUST BE A REAL DIRECTORY. If the project's own
|
|
108
|
+
* `node_modules` is itself a junction — which is how some monorepos are laid
|
|
109
|
+
* out — copying THROUGH it is still a copy, but `dereference: false` would
|
|
110
|
+
* reproduce the link in a checkout that is about to be deleted recursively.
|
|
111
|
+
* That is the hazard this file exists to avoid, reached from the other side.
|
|
112
|
+
*/
|
|
113
|
+
const st = (0, node_fs_1.lstatSync)(from);
|
|
114
|
+
if (st.isSymbolicLink()) {
|
|
115
|
+
throw new CarryError(`run.carry_into_checkouts: "${name}" is a link in this project, and copying a link into a checkout that is deleted recursively would delete what it points at`);
|
|
116
|
+
}
|
|
117
|
+
if (!st.isDirectory()) {
|
|
118
|
+
throw new CarryError(`run.carry_into_checkouts: "${name}" is not a directory`);
|
|
119
|
+
}
|
|
120
|
+
(0, node_fs_1.cpSync)(from, to, { recursive: true, dereference: false, errorOnExist: false, force: false });
|
|
121
|
+
carried.push(name);
|
|
122
|
+
}
|
|
123
|
+
return { carried, absent };
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=checkout-carry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkout-carry.js","sourceRoot":"","sources":["../src/checkout-carry.ts"],"names":[],"mappings":";;;AA6DA,4CAOC;AAmBD,8CAuCC;AA9HD,qCAAwD;AACxD,yCAAiC;AAEjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAEH,MAAa,UAAW,SAAQ,KAAK;CAAG;AAAxC,gCAAwC;AAExC;;;;;;;;;;GAUG;AACH,SAAgB,gBAAgB,CAAC,IAAY;IAC3C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,UAAU,CAAC;IACzC,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,gCAAgC,CAAC;IAC3E,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,0DAA0D,CAAC;IAC1F,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,wDAAwD,CAAC;IAC1F,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,iCAAiC,CAAC;IACtE,OAAO,IAAI,CAAC;AACd,CAAC;AAQD;;;;;;;;;;GAUG;AACH,SAAgB,iBAAiB,CAC/B,WAAmB,EACnB,WAAmB,EACnB,KAAwB;IAExB,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACrB,MAAM,IAAI,UAAU,CAAC,8BAA8B,IAAI,KAAK,OAAO,EAAE,CAAC,CAAC;QACzE,CAAC;QACD,MAAM,IAAI,GAAG,IAAA,gBAAI,EAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QACrC,MAAM,EAAE,GAAG,IAAA,gBAAI,EAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,IAAA,oBAAU,EAAC,IAAI,CAAC,EAAE,CAAC;YACtB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClB,SAAS;QACX,CAAC;QACD,IAAI,IAAA,oBAAU,EAAC,EAAE,CAAC;YAAE,SAAS;QAC7B;;;;;;WAMG;QACH,MAAM,EAAE,GAAG,IAAA,mBAAS,EAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC;YACxB,MAAM,IAAI,UAAU,CAClB,8BAA8B,IAAI,4HAA4H,CAC/J,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;YACtB,MAAM,IAAI,UAAU,CAAC,8BAA8B,IAAI,sBAAsB,CAAC,CAAC;QACjF,CAAC;QACD,IAAA,gBAAM,EAAC,IAAI,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QAC7F,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type GitExec } from './git-driver';
|
|
2
|
+
/**
|
|
3
|
+
* RE-READING WHAT A PROPOSAL OR A PLAN CITED — from the repository, git and
|
|
4
|
+
* the ledger.
|
|
5
|
+
*
|
|
6
|
+
* A proposal is not believed; it is checked. Each citation names something
|
|
7
|
+
* deterministic, and these readers fetch exactly that: a line of a file at the
|
|
8
|
+
* COMMITTED tree the question was asked at (not the working tree, which moves
|
|
9
|
+
* under a run), a file's presence there, the first line of it showing an
|
|
10
|
+
* excerpt, a commit by sha, a ledger event by sequence number, a gate step's
|
|
11
|
+
* last recorded result. `null` means "could not be read", which the judges
|
|
12
|
+
* treat as refuted — an unreadable citation is not a satisfied one.
|
|
13
|
+
*/
|
|
14
|
+
export interface CitationReaders {
|
|
15
|
+
/** `path:line <text>` at the tree, or null when the file or the line is not there. */
|
|
16
|
+
file(path: string, line: number, treeSha: string): Promise<string | null>;
|
|
17
|
+
/** `path <p> (<n> lines)` at the tree, or null when the file is not there. */
|
|
18
|
+
path(path: string, treeSha: string): Promise<string | null>;
|
|
19
|
+
/** `path:line <text>` of the first line showing the excerpt (whitespace aside), or null. */
|
|
20
|
+
find(path: string, excerpt: string, treeSha: string): Promise<string | null>;
|
|
21
|
+
commit(sha: string): Promise<string | null>;
|
|
22
|
+
event(seq: number): Promise<string | null>;
|
|
23
|
+
gate(step: string): Promise<string | null>;
|
|
24
|
+
}
|
|
25
|
+
export declare function nodeCitationReaders(cwd: string, stateDir: string, exec?: GitExec): CitationReaders;
|
|
26
|
+
//# sourceMappingURL=citation-readers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"citation-readers.d.ts","sourceRoot":"","sources":["../src/citation-readers.ts"],"names":[],"mappings":"AAGA,OAAO,EAA0B,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC;AAEpE;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,eAAe;IAC9B,sFAAsF;IACtF,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC1E,8EAA8E;IAC9E,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC5D,4FAA4F;IAC5F,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC7E,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC5C,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC3C,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC5C;AAmCD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,OAA0B,GAAG,eAAe,CAwDpH"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.nodeCitationReaders = nodeCitationReaders;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
const core_1 = require("@looply/core");
|
|
7
|
+
const git_driver_1 = require("./git-driver");
|
|
8
|
+
async function ledgerLines(stateDir) {
|
|
9
|
+
let text;
|
|
10
|
+
try {
|
|
11
|
+
text = await node_fs_1.promises.readFile((0, node_path_1.join)(stateDir, 'events.jsonl'), 'utf8');
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return [];
|
|
15
|
+
}
|
|
16
|
+
const out = [];
|
|
17
|
+
for (const line of text.split('\n')) {
|
|
18
|
+
if (line.trim() === '')
|
|
19
|
+
continue;
|
|
20
|
+
try {
|
|
21
|
+
const v = JSON.parse(line);
|
|
22
|
+
if (v !== null && typeof v === 'object')
|
|
23
|
+
out.push(v);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
/* a torn line is not an event */
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return out;
|
|
30
|
+
}
|
|
31
|
+
const linesOf = (text) => {
|
|
32
|
+
const lines = text.split('\n');
|
|
33
|
+
if (lines.length > 0 && lines[lines.length - 1] === '')
|
|
34
|
+
lines.pop();
|
|
35
|
+
return lines;
|
|
36
|
+
};
|
|
37
|
+
function nodeCitationReaders(cwd, stateDir, exec = (0, git_driver_1.nodeGitExec)(cwd)) {
|
|
38
|
+
const git = new git_driver_1.GitDriver(exec);
|
|
39
|
+
/** The file's text at the committed tree, or null when it is not there. */
|
|
40
|
+
const blobAt = async (path, treeSha) => {
|
|
41
|
+
try {
|
|
42
|
+
const entry = (await git.listTree(treeSha)).find((e) => e.path === path);
|
|
43
|
+
return entry === undefined ? null : await git.readBlob(entry.blobSha);
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
return {
|
|
50
|
+
async file(path, line, treeSha) {
|
|
51
|
+
const text = await blobAt(path, treeSha);
|
|
52
|
+
if (text === null || line < 1)
|
|
53
|
+
return null;
|
|
54
|
+
const found = text.split('\n')[line - 1];
|
|
55
|
+
return found === undefined ? null : `${path}:${line} ${found}`;
|
|
56
|
+
},
|
|
57
|
+
async path(path, treeSha) {
|
|
58
|
+
const text = await blobAt(path, treeSha);
|
|
59
|
+
if (text === null)
|
|
60
|
+
return null;
|
|
61
|
+
const n = linesOf(text).length;
|
|
62
|
+
return `path ${path} (${n} line${n === 1 ? '' : 's'})`;
|
|
63
|
+
},
|
|
64
|
+
async find(path, excerpt, treeSha) {
|
|
65
|
+
const q = (0, core_1.normaliseExcerpt)(excerpt);
|
|
66
|
+
if (q === '')
|
|
67
|
+
return null;
|
|
68
|
+
const text = await blobAt(path, treeSha);
|
|
69
|
+
if (text === null)
|
|
70
|
+
return null;
|
|
71
|
+
const lines = linesOf(text);
|
|
72
|
+
const i = lines.findIndex((l) => (0, core_1.normaliseExcerpt)(l).includes(q));
|
|
73
|
+
return i < 0 ? null : `${path}:${i + 1} ${lines[i]}`;
|
|
74
|
+
},
|
|
75
|
+
async commit(sha) {
|
|
76
|
+
const r = await exec(['log', '-1', '--format=%H %s', sha]);
|
|
77
|
+
const text = r.stdout.trim();
|
|
78
|
+
return r.code === 0 && text !== '' ? `commit ${text}` : null;
|
|
79
|
+
},
|
|
80
|
+
async event(seq) {
|
|
81
|
+
const hits = (await ledgerLines(stateDir)).filter((e) => e.seq === seq);
|
|
82
|
+
// A sequence number is per run; one that names two events is not a citation anybody can check.
|
|
83
|
+
if (hits.length !== 1)
|
|
84
|
+
return null;
|
|
85
|
+
const e = hits[0];
|
|
86
|
+
return `event ${seq} ${String(e.kind)} ${JSON.stringify(e.data ?? null)}`;
|
|
87
|
+
},
|
|
88
|
+
async gate(step) {
|
|
89
|
+
const gated = (await ledgerLines(stateDir)).filter((e) => e.kind === 'round.gated');
|
|
90
|
+
const last = gated[gated.length - 1];
|
|
91
|
+
if (last === undefined)
|
|
92
|
+
return null;
|
|
93
|
+
const data = (last.data ?? {});
|
|
94
|
+
const steps = (Array.isArray(data.steps) ? data.steps : Array.isArray(data.results) ? data.results : []);
|
|
95
|
+
const hit = steps.find((s) => s.step === step);
|
|
96
|
+
if (hit === undefined)
|
|
97
|
+
return null;
|
|
98
|
+
return `gate step ${step} ${hit.ok === true ? 'passed' : 'failed'}${hit.timedOut === true ? ' (timed out)' : ''}`;
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=citation-readers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"citation-readers.js","sourceRoot":"","sources":["../src/citation-readers.ts"],"names":[],"mappings":";;AA8DA,kDAwDC;AAtHD,qCAA0C;AAC1C,yCAAiC;AACjC,uCAAgD;AAChD,6CAAoE;AAiCpE,KAAK,UAAU,WAAW,CAAC,QAAgB;IACzC,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,kBAAG,CAAC,QAAQ,CAAC,IAAA,gBAAI,EAAC,QAAQ,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAC;IACpE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,GAAG,GAAiB,EAAE,CAAC;IAC7B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE;YAAE,SAAS;QACjC,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAY,CAAC;YACtC,IAAI,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ;gBAAE,GAAG,CAAC,IAAI,CAAC,CAAe,CAAC,CAAC;QACrE,CAAC;QAAC,MAAM,CAAC;YACP,iCAAiC;QACnC,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,OAAO,GAAG,CAAC,IAAY,EAAY,EAAE;IACzC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE;QAAE,KAAK,CAAC,GAAG,EAAE,CAAC;IACpE,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF,SAAgB,mBAAmB,CAAC,GAAW,EAAE,QAAgB,EAAE,OAAgB,IAAA,wBAAW,EAAC,GAAG,CAAC;IACjG,MAAM,GAAG,GAAG,IAAI,sBAAS,CAAC,IAAI,CAAC,CAAC;IAChC,2EAA2E;IAC3E,MAAM,MAAM,GAAG,KAAK,EAAE,IAAY,EAAE,OAAe,EAA0B,EAAE;QAC7E,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,CAAC,MAAM,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;YACzE,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACxE,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC,CAAC;IACF,OAAO;QACL,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO;YAC5B,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACzC,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,GAAG,CAAC;gBAAE,OAAO,IAAI,CAAC;YAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;YACzC,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,IAAI,IAAI,KAAK,EAAE,CAAC;QACjE,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO;YACtB,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACzC,IAAI,IAAI,KAAK,IAAI;gBAAE,OAAO,IAAI,CAAC;YAC/B,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;YAC/B,OAAO,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;QACzD,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO;YAC/B,MAAM,CAAC,GAAG,IAAA,uBAAgB,EAAC,OAAO,CAAC,CAAC;YACpC,IAAI,CAAC,KAAK,EAAE;gBAAE,OAAO,IAAI,CAAC;YAC1B,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACzC,IAAI,IAAI,KAAK,IAAI;gBAAE,OAAO,IAAI,CAAC;YAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;YAC5B,MAAM,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,uBAAgB,EAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;YAClE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QACvD,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,GAAG;YACd,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,GAAG,CAAC,CAAC,CAAC;YAC3D,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YAC7B,OAAO,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QAC/D,CAAC;QACD,KAAK,CAAC,KAAK,CAAC,GAAG;YACb,MAAM,IAAI,GAAG,CAAC,MAAM,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;YACxE,+FAA+F;YAC/F,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,IAAI,CAAC;YACnC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;YACnB,OAAO,SAAS,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;QAC5E,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,IAAI;YACb,MAAM,KAAK,GAAG,CAAC,MAAM,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,aAAa,CAAC,CAAC;YACpF,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACrC,IAAI,IAAI,KAAK,SAAS;gBAAE,OAAO,IAAI,CAAC;YACpC,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAA2C,CAAC;YACzE,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAA2D,CAAC;YACnK,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;YAC/C,IAAI,GAAG,KAAK,SAAS;gBAAE,OAAO,IAAI,CAAC;YACnC,OAAO,aAAa,IAAI,IAAI,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACpH,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { LedgerFs } from './ledger-store';
|
|
2
|
+
/**
|
|
3
|
+
* What this machine has already carried out — `commands.json` under the state dir.
|
|
4
|
+
*
|
|
5
|
+
* The run lease answers "is something running here *now*". It cannot answer
|
|
6
|
+
* "did I already do this", because it stops existing the moment the run ends.
|
|
7
|
+
* That gap is real and reachable: a `start-run` whose ack was lost redelivers
|
|
8
|
+
* for the whole hour-long window, and if the run it started has since finished,
|
|
9
|
+
* the lease is free and a second full run begins. The phone asked once.
|
|
10
|
+
*
|
|
11
|
+
* So a terminal disposition is written down. The guarantee this file exists to
|
|
12
|
+
* provide is the one Phase 0's redelivery made necessary:
|
|
13
|
+
*
|
|
14
|
+
* a command that reached a terminal outcome never executes again.
|
|
15
|
+
*
|
|
16
|
+
* Bounded on purpose. This is a dedupe window, not an audit log — the server
|
|
17
|
+
* holds the record of every command with its outcome. Keeping the newest few
|
|
18
|
+
* hundred covers a redelivery window measured in an hour; keeping all of them
|
|
19
|
+
* would grow a file on the append path of an overnight run for no benefit.
|
|
20
|
+
*/
|
|
21
|
+
/** One command this machine finished with. */
|
|
22
|
+
export interface CommandReceipt {
|
|
23
|
+
id: string;
|
|
24
|
+
kind: string;
|
|
25
|
+
outcome: 'done' | 'refused';
|
|
26
|
+
at: string;
|
|
27
|
+
/**
|
|
28
|
+
* Why it was refused, when it was.
|
|
29
|
+
*
|
|
30
|
+
* Kept because the receipt is what answers a REDELIVERY: a command whose ack
|
|
31
|
+
* was lost comes back, and the daemon replies from here rather than doing the
|
|
32
|
+
* work again. Without the reason stored, that second answer would be a
|
|
33
|
+
* strictly worse one than the first — the same refusal, stripped of the only
|
|
34
|
+
* part a person could act on.
|
|
35
|
+
*
|
|
36
|
+
* Optional, and only ever set alongside `outcome: 'refused'`. Receipts
|
|
37
|
+
* written by an older build simply do not have it.
|
|
38
|
+
*/
|
|
39
|
+
reason?: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* How many receipts to keep.
|
|
43
|
+
*
|
|
44
|
+
* Comfortably more than a redelivery window can hold: the server's window is
|
|
45
|
+
* one hour and the daemon polls every three seconds, so even a pathological
|
|
46
|
+
* burst cannot push a still-redeliverable id out of this range.
|
|
47
|
+
*/
|
|
48
|
+
export declare const MAX_RECEIPTS = 512;
|
|
49
|
+
export type ReceiptsState = 'ok' | 'unreadable';
|
|
50
|
+
export declare class CommandReceipts {
|
|
51
|
+
private readonly stateDir;
|
|
52
|
+
private readonly fs;
|
|
53
|
+
private readonly now;
|
|
54
|
+
/** Distinguishes two writes from ONE process; the pid distinguishes processes. */
|
|
55
|
+
private static writes;
|
|
56
|
+
private receipts;
|
|
57
|
+
private state;
|
|
58
|
+
private opened;
|
|
59
|
+
constructor(stateDir: string, fs: LedgerFs, now?: () => number);
|
|
60
|
+
private get path();
|
|
61
|
+
/** Read what is on disk. Never throws: an unreadable file is a state, not a crash. */
|
|
62
|
+
open(): Promise<ReceiptsState>;
|
|
63
|
+
/** Whether the file could be read. Callers decide what an unreadable one means. */
|
|
64
|
+
status(): ReceiptsState;
|
|
65
|
+
/** Has this exact command already reached a terminal outcome here? */
|
|
66
|
+
seen(id: string): CommandReceipt | undefined;
|
|
67
|
+
/**
|
|
68
|
+
* Write down that a command is finished with.
|
|
69
|
+
*
|
|
70
|
+
* Recorded after the handler acted and before the ack, so a crash between the
|
|
71
|
+
* two leaves the receipt rather than losing it — the redelivery that follows
|
|
72
|
+
* is then recognised instead of re-executed. The other order would make a
|
|
73
|
+
* lost ack indistinguishable from work never done.
|
|
74
|
+
*/
|
|
75
|
+
record(id: string, kind: string, outcome: 'done' | 'refused', reason?: string): Promise<void>;
|
|
76
|
+
private persist;
|
|
77
|
+
}
|
|
78
|
+
export declare function isRepeatable(kind: string): boolean;
|
|
79
|
+
//# sourceMappingURL=command-receipts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-receipts.d.ts","sourceRoot":"","sources":["../src/command-receipts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C;;;;;;;;;;;;;;;;;;GAkBG;AAEH,8CAA8C;AAC9C,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,MAAM,CAAC;AAEhC,MAAM,MAAM,aAAa,GAAG,IAAI,GAAG,YAAY,CAAC;AAEhD,qBAAa,eAAe;IASxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,EAAE;IACnB,OAAO,CAAC,QAAQ,CAAC,GAAG;IAVtB,kFAAkF;IAClF,OAAO,CAAC,MAAM,CAAC,MAAM,CAAK;IAE1B,OAAO,CAAC,QAAQ,CAAwB;IACxC,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,MAAM,CAAS;gBAGJ,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,QAAQ,EACZ,GAAG,GAAE,MAAM,MAAyB;IAGvD,OAAO,KAAK,IAAI,GAEf;IAED,sFAAsF;IAChF,IAAI,IAAI,OAAO,CAAC,aAAa,CAAC;IA+BpC,mFAAmF;IACnF,MAAM,IAAI,aAAa;IAIvB,sEAAsE;IACtE,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAI5C;;;;;;;OAOG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAuBrF,OAAO;CAatB;AAYD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAElD"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CommandReceipts = exports.MAX_RECEIPTS = void 0;
|
|
4
|
+
exports.isRepeatable = isRepeatable;
|
|
5
|
+
/**
|
|
6
|
+
* How many receipts to keep.
|
|
7
|
+
*
|
|
8
|
+
* Comfortably more than a redelivery window can hold: the server's window is
|
|
9
|
+
* one hour and the daemon polls every three seconds, so even a pathological
|
|
10
|
+
* burst cannot push a still-redeliverable id out of this range.
|
|
11
|
+
*/
|
|
12
|
+
exports.MAX_RECEIPTS = 512;
|
|
13
|
+
class CommandReceipts {
|
|
14
|
+
stateDir;
|
|
15
|
+
fs;
|
|
16
|
+
now;
|
|
17
|
+
/** Distinguishes two writes from ONE process; the pid distinguishes processes. */
|
|
18
|
+
static writes = 0;
|
|
19
|
+
receipts = [];
|
|
20
|
+
state = 'ok';
|
|
21
|
+
opened = false;
|
|
22
|
+
constructor(stateDir, fs, now = () => Date.now()) {
|
|
23
|
+
this.stateDir = stateDir;
|
|
24
|
+
this.fs = fs;
|
|
25
|
+
this.now = now;
|
|
26
|
+
}
|
|
27
|
+
get path() {
|
|
28
|
+
return `${this.stateDir}/commands.json`;
|
|
29
|
+
}
|
|
30
|
+
/** Read what is on disk. Never throws: an unreadable file is a state, not a crash. */
|
|
31
|
+
async open() {
|
|
32
|
+
this.opened = true;
|
|
33
|
+
let text;
|
|
34
|
+
try {
|
|
35
|
+
text = await this.fs.readFile(this.path);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
this.state = 'unreadable';
|
|
39
|
+
return this.state;
|
|
40
|
+
}
|
|
41
|
+
if (text === null) {
|
|
42
|
+
this.receipts = [];
|
|
43
|
+
this.state = 'ok';
|
|
44
|
+
return this.state;
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
const parsed = JSON.parse(text);
|
|
48
|
+
if (!Array.isArray(parsed)) {
|
|
49
|
+
this.state = 'unreadable';
|
|
50
|
+
return this.state;
|
|
51
|
+
}
|
|
52
|
+
this.receipts = parsed.filter(isReceipt);
|
|
53
|
+
this.state = 'ok';
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
// Written temp-then-rename, so a torn file should be impossible; garbage
|
|
57
|
+
// here is a fact about the machine rather than a race, and guessing
|
|
58
|
+
// "nothing has run" would re-open the duplicate-run window this closes.
|
|
59
|
+
this.state = 'unreadable';
|
|
60
|
+
}
|
|
61
|
+
return this.state;
|
|
62
|
+
}
|
|
63
|
+
/** Whether the file could be read. Callers decide what an unreadable one means. */
|
|
64
|
+
status() {
|
|
65
|
+
return this.state;
|
|
66
|
+
}
|
|
67
|
+
/** Has this exact command already reached a terminal outcome here? */
|
|
68
|
+
seen(id) {
|
|
69
|
+
return this.receipts.find((r) => r.id === id);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Write down that a command is finished with.
|
|
73
|
+
*
|
|
74
|
+
* Recorded after the handler acted and before the ack, so a crash between the
|
|
75
|
+
* two leaves the receipt rather than losing it — the redelivery that follows
|
|
76
|
+
* is then recognised instead of re-executed. The other order would make a
|
|
77
|
+
* lost ack indistinguishable from work never done.
|
|
78
|
+
*/
|
|
79
|
+
async record(id, kind, outcome, reason) {
|
|
80
|
+
if (!this.opened)
|
|
81
|
+
throw new Error('CommandReceipts.record before open()');
|
|
82
|
+
if (this.state === 'unreadable') {
|
|
83
|
+
// Refuse to rewrite a file we could not read: that would silently discard
|
|
84
|
+
// whatever it held, which is the history this whole file is.
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
this.receipts = this.receipts.filter((r) => r.id !== id);
|
|
88
|
+
this.receipts.push({
|
|
89
|
+
id,
|
|
90
|
+
kind,
|
|
91
|
+
outcome,
|
|
92
|
+
at: new Date(this.now()).toISOString(),
|
|
93
|
+
// Only on a refusal, and only if there is one. A `done` receipt with a
|
|
94
|
+
// reason attached is the stale-explanation bug written down.
|
|
95
|
+
...(outcome === 'refused' && reason !== undefined ? { reason } : {}),
|
|
96
|
+
});
|
|
97
|
+
if (this.receipts.length > exports.MAX_RECEIPTS) {
|
|
98
|
+
this.receipts = this.receipts.slice(this.receipts.length - exports.MAX_RECEIPTS);
|
|
99
|
+
}
|
|
100
|
+
await this.persist();
|
|
101
|
+
}
|
|
102
|
+
async persist() {
|
|
103
|
+
await this.fs.mkdir(this.stateDir);
|
|
104
|
+
// Same contract as every other store here: a reader in the daemon's next
|
|
105
|
+
// life must never catch half a file.
|
|
106
|
+
// The temp name is PRIVATE TO THIS WRITER. A shared `commands.json.tmp` is
|
|
107
|
+
// two processes writing one path: the second truncates and rewrites what
|
|
108
|
+
// the first is midway through, and then both rename it into place. The
|
|
109
|
+
// rename is atomic and the file it renames is a splice of two writes, and
|
|
110
|
+
// nothing downstream can tell.
|
|
111
|
+
const tmp = `${this.path}.${process.pid}.${(CommandReceipts.writes += 1)}.tmp`;
|
|
112
|
+
await this.fs.writeFile(tmp, JSON.stringify(this.receipts, null, 2) + '\n');
|
|
113
|
+
await this.fs.rename(tmp, this.path);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
exports.CommandReceipts = CommandReceipts;
|
|
117
|
+
/**
|
|
118
|
+
* Commands that may safely run again if their outcome was never recorded.
|
|
119
|
+
*
|
|
120
|
+
* Everything not listed here is treated as consequential: if we cannot prove it
|
|
121
|
+
* has not already been done, we refuse rather than do it twice. `start-run` and
|
|
122
|
+
* `scan` each spawn a process that mutates the repository; the others write a
|
|
123
|
+
* single control request whose effect is the same however many times it lands.
|
|
124
|
+
*/
|
|
125
|
+
const REPEATABLE = new Set(['pause', 'stop', 'resume']);
|
|
126
|
+
function isRepeatable(kind) {
|
|
127
|
+
return REPEATABLE.has(kind);
|
|
128
|
+
}
|
|
129
|
+
function isReceipt(v) {
|
|
130
|
+
if (typeof v !== 'object' || v === null)
|
|
131
|
+
return false;
|
|
132
|
+
const r = v;
|
|
133
|
+
// The OUTCOME is checked too, not just the identity. A receipt without one
|
|
134
|
+
// used to load through and be handed straight back as the disposition, which
|
|
135
|
+
// put `undefined` where the daemon expected 'done' or 'refused' — past the
|
|
136
|
+
// retry check, and on to the server as the outcome of a command. Anything
|
|
137
|
+
// that cannot say how it ended is not a receipt.
|
|
138
|
+
return (typeof r['id'] === 'string' &&
|
|
139
|
+
typeof r['kind'] === 'string' &&
|
|
140
|
+
(r['outcome'] === 'done' || r['outcome'] === 'refused') &&
|
|
141
|
+
(r['reason'] === undefined || typeof r['reason'] === 'string'));
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=command-receipts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-receipts.js","sourceRoot":"","sources":["../src/command-receipts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { CommandRunner } from './gate';
|
|
2
|
+
/**
|
|
3
|
+
* The real command runner behind the gate.
|
|
4
|
+
*
|
|
5
|
+
* Steps run through a shell (`npx --no-install jest --ci` is a shell line, not an
|
|
6
|
+
* argv), so the pid we hold is the shell's, not the tool's. The timeout therefore
|
|
7
|
+
* kills the whole process *group* — killing only the shell would orphan the actual
|
|
8
|
+
* hung jest, and the round would wait on it forever (DESIGN §12 case 5). Process
|
|
9
|
+
* creation and killing come through {@link CommandRunnerDeps}, so the timeout,
|
|
10
|
+
* settlement and output behaviour are all testable without spawning anything.
|
|
11
|
+
*/
|
|
12
|
+
/** The slice of a child process the runner needs; callbacks may fire in any order. */
|
|
13
|
+
export interface SpawnHandle {
|
|
14
|
+
pid: number | undefined;
|
|
15
|
+
/** `code` is null when the process died to a signal rather than exiting. */
|
|
16
|
+
onExit(cb: (code: number | null) => void): void;
|
|
17
|
+
/** Spawn-level failure: the shell itself could not start. */
|
|
18
|
+
onError(cb: (err: Error) => void): void;
|
|
19
|
+
/** Interleaved stdout + stderr, already decoded. */
|
|
20
|
+
onOutput(cb: (chunk: string) => void): void;
|
|
21
|
+
}
|
|
22
|
+
export interface CommandRunnerDeps {
|
|
23
|
+
spawn(cmd: string): SpawnHandle;
|
|
24
|
+
/** Must take down `pid` and every descendant, not just `pid`. */
|
|
25
|
+
killTree(pid: number): void;
|
|
26
|
+
}
|
|
27
|
+
export declare function makeCommandRunner(deps: CommandRunnerDeps): CommandRunner;
|
|
28
|
+
export declare function nodeSpawn(cmd: string): SpawnHandle;
|
|
29
|
+
export declare function nodeKillTree(pid: number): void;
|
|
30
|
+
/** The runner the gate executor should be handed in real use. */
|
|
31
|
+
export declare const nodeCommandRunner: CommandRunner;
|
|
32
|
+
//# sourceMappingURL=command-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-runner.d.ts","sourceRoot":"","sources":["../src/command-runner.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAiB,aAAa,EAAE,MAAM,QAAQ,CAAC;AAG3D;;;;;;;;;GASG;AAEH,sFAAsF;AACtF,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,4EAA4E;IAC5E,MAAM,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI,CAAC;IAChD,6DAA6D;IAC7D,OAAO,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC;IACxC,oDAAoD;IACpD,QAAQ,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;CAC7C;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAAC;IAChC,iEAAiE;IACjE,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,iBAAiB,GAAG,aAAa,CAmCxE;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAkBlD;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAmC9C;AAED,iEAAiE;AACjE,eAAO,MAAM,iBAAiB,EAAE,aAG9B,CAAC"}
|