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,268 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.STATE_SUBDIR = exports.DEFAULT_CHECKPOINT_LIMITS = void 0;
|
|
4
|
+
exports.measureWorkspace = measureWorkspace;
|
|
5
|
+
exports.writeCheckpoint = writeCheckpoint;
|
|
6
|
+
exports.reportCheckpoint = reportCheckpoint;
|
|
7
|
+
const node_child_process_1 = require("node:child_process");
|
|
8
|
+
const node_fs_1 = require("node:fs");
|
|
9
|
+
const node_path_1 = require("node:path");
|
|
10
|
+
const core_1 = require("@looply/core");
|
|
11
|
+
const trusted_git_1 = require("./trusted-git");
|
|
12
|
+
/**
|
|
13
|
+
* CAPTURING WHAT A SESSION LOOPLY COULD NOT ADOPT HAS ACTUALLY DONE.
|
|
14
|
+
*
|
|
15
|
+
* `session-checkpoint.ts` decides; this reads the tree and writes the export.
|
|
16
|
+
*
|
|
17
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
18
|
+
* 🔴 A MANIFEST IS NOT AN EXPORT, AND THE CHARTER ASKS FOR AN EXPORT.
|
|
19
|
+
*
|
|
20
|
+
* A record saying "src/a.ts is modified" is a list of names. The thing a person
|
|
21
|
+
* needs in order to start a managed run from this work is the WORK: the diff of
|
|
22
|
+
* what changed and the contents of what is new. Writing only the names would be
|
|
23
|
+
* the offer-with-nothing-behind-it again, one level in.
|
|
24
|
+
*
|
|
25
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
26
|
+
* 🔴 AN ABSOLUTE GIT PATH, NEVER THE BARE NAME. The cwd here is the workspace of
|
|
27
|
+
* a session this build REFUSED to adopt — the least trusted directory in the
|
|
28
|
+
* whole product — and on Windows the cwd is searched before PATH. A bare `git`
|
|
29
|
+
* would let that tree choose the program that reads it. This is the same defect
|
|
30
|
+
* a guard caught in the watcher, in a place where it would have been worse.
|
|
31
|
+
*
|
|
32
|
+
* ⚠️ AND THE CAPTURE IS BOUNDED. A session writes these files and is still
|
|
33
|
+
* writing them; an unbounded copy is this process doing unbounded work on the
|
|
34
|
+
* word of something it does not control. Hitting a bound is NAMED in the
|
|
35
|
+
* manifest, never silently truncated.
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* 🔴 THE FIRST LINK ON THE WAY TO A PATH, OR NULL.
|
|
39
|
+
*
|
|
40
|
+
* ⚠️ AND IT CHECKS EVERY ANCESTOR, NOT THE FILE. `git ls-files --others`
|
|
41
|
+
* WALKS THROUGH A JUNCTION: with a junction at `src/link`, it reports
|
|
42
|
+
* `src/link/secret.txt` — a path whose final component lstats as an ordinary
|
|
43
|
+
* file. A check on that component alone sees nothing wrong and copies a file
|
|
44
|
+
* from outside the workspace into an export labelled as this session's work.
|
|
45
|
+
*
|
|
46
|
+
* Measured, not assumed: `ls-files --others` on a checkout with a directory
|
|
47
|
+
* junction returned exactly that path, and `lstat` of the junction itself
|
|
48
|
+
* returned `isSymbolicLink() === true` — which is why the answer is to walk
|
|
49
|
+
* the prefixes rather than to trust the leaf.
|
|
50
|
+
*/
|
|
51
|
+
function linkOnTheWayTo(workspace, rel) {
|
|
52
|
+
// git reports forward slashes on every platform, so this splits on one.
|
|
53
|
+
const parts = rel.split('/').filter((p) => p !== '');
|
|
54
|
+
let at = (0, node_path_1.resolve)(workspace);
|
|
55
|
+
for (let i = 0; i < parts.length; i += 1) {
|
|
56
|
+
at = (0, node_path_1.join)(at, parts[i]);
|
|
57
|
+
try {
|
|
58
|
+
/**
|
|
59
|
+
* ⚠️ THE INDEX, NOT `indexOf`. A path can repeat a component
|
|
60
|
+
* (`src/x/src/y.ts`), and `indexOf` would name the FIRST occurrence -
|
|
61
|
+
* reporting a link at a place there is none while the real one goes
|
|
62
|
+
* unnamed.
|
|
63
|
+
*/
|
|
64
|
+
if ((0, node_fs_1.lstatSync)(at).isSymbolicLink())
|
|
65
|
+
return parts.slice(0, i + 1).join('/');
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
exports.DEFAULT_CHECKPOINT_LIMITS = {
|
|
74
|
+
maxDiffBytes: 4 * 1024 * 1024,
|
|
75
|
+
maxUntrackedFiles: 500,
|
|
76
|
+
maxFileBytes: 4 * 1024 * 1024,
|
|
77
|
+
};
|
|
78
|
+
function git(workspace, args) {
|
|
79
|
+
const bin = (0, trusted_git_1.gitBinary)();
|
|
80
|
+
if (bin === null)
|
|
81
|
+
return null;
|
|
82
|
+
try {
|
|
83
|
+
return (0, node_child_process_1.execFileSync)(bin, [...(0, trusted_git_1.trustedGitArgs)(), ...args], {
|
|
84
|
+
cwd: workspace,
|
|
85
|
+
env: (0, trusted_git_1.trustedGitEnv)(process.env, workspace),
|
|
86
|
+
encoding: 'utf8',
|
|
87
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
88
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* What this machine can establish about the workspace.
|
|
97
|
+
*
|
|
98
|
+
* ⚠️ EVERY FAILURE IS `null`, NEVER AN EMPTY LIST. `checkpointVerdict` answers
|
|
99
|
+
* `unmeasurable` for a null and would produce a clean-looking checkpoint from an
|
|
100
|
+
* empty one — which is the single most consequential thing this file could get
|
|
101
|
+
* wrong, so the distinction is made here rather than left to a caller.
|
|
102
|
+
*/
|
|
103
|
+
/**
|
|
104
|
+
* 🔴 LOOPLY'S OWN STATE DIRECTORY IS NOT THE SESSION'S WORK, AND A LIVE RUN
|
|
105
|
+
* PROVED WHY IT MATTERS.
|
|
106
|
+
*
|
|
107
|
+
* The checkpoint store lives at `<workspace>/.looply/state/checkpoints`, and
|
|
108
|
+
* `git ls-files --others` lists everything under it. So the FIRST checkpoint
|
|
109
|
+
* copied the session's work; the SECOND copied the session's work AND the first
|
|
110
|
+
* checkpoint; a third would have copied both. Measured: 5 untracked files became
|
|
111
|
+
* 12 on the second run. Each capture contained every capture before it.
|
|
112
|
+
*
|
|
113
|
+
* ⚠️ AND IT WAS ALSO MISLABELLED. `.looply/state/sessions.jsonl` is looply's
|
|
114
|
+
* own ledger, and it landed in a directory labelled "this session's untracked
|
|
115
|
+
* work" — a product's bookkeeping presented as somebody else's output.
|
|
116
|
+
*
|
|
117
|
+
* ⚠️ ONLY `state` IS EXCLUDED, NOT ALL OF `.looply`. A session that created
|
|
118
|
+
* `.looply/config.yaml` really did create it, and dropping that would be a guess
|
|
119
|
+
* about what counts as work. `state` is this product's runtime bookkeeping by
|
|
120
|
+
* construction, which is not a guess.
|
|
121
|
+
*/
|
|
122
|
+
exports.STATE_SUBDIR = '.looply/state';
|
|
123
|
+
function measureWorkspace(workspace, liveness, heldBy, stateSubdir = exports.STATE_SUBDIR) {
|
|
124
|
+
const revision = git(workspace, ['rev-parse', 'HEAD'])?.trim() ?? null;
|
|
125
|
+
/**
|
|
126
|
+
* ⚠️ `diff HEAD --name-only` AND NOT `diff --name-only`. The second omits
|
|
127
|
+
* anything already staged, and a session that ran `git add` would produce a
|
|
128
|
+
* checkpoint reporting its work as absent.
|
|
129
|
+
*/
|
|
130
|
+
const dirtyOut = git(workspace, ['diff', 'HEAD', '--name-only']);
|
|
131
|
+
const untrackedOut = git(workspace, ['ls-files', '--others', '--exclude-standard']);
|
|
132
|
+
const lines = (text) => text === null ? null : text.split(/\r?\n/).filter((l) => l.trim() !== '');
|
|
133
|
+
const allUntracked = lines(untrackedOut);
|
|
134
|
+
const prefix = stateSubdir.replace(/\/+$/, '');
|
|
135
|
+
const mine = (p) => p === prefix || p.startsWith(prefix + '/');
|
|
136
|
+
const excluded = allUntracked === null ? [] : allUntracked.filter(mine);
|
|
137
|
+
return {
|
|
138
|
+
liveness,
|
|
139
|
+
revision,
|
|
140
|
+
dirty: lines(dirtyOut),
|
|
141
|
+
untracked: allUntracked === null ? null : allUntracked.filter((p) => !mine(p)),
|
|
142
|
+
heldBy,
|
|
143
|
+
excluded,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
const atomicWrite = (path, body) => {
|
|
147
|
+
(0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(path), { recursive: true });
|
|
148
|
+
const tmp = `${path}.partial`;
|
|
149
|
+
const fd = (0, node_fs_1.openSync)(tmp, 'w');
|
|
150
|
+
try {
|
|
151
|
+
(0, node_fs_1.writeSync)(fd, body);
|
|
152
|
+
}
|
|
153
|
+
finally {
|
|
154
|
+
(0, node_fs_1.closeSync)(fd);
|
|
155
|
+
}
|
|
156
|
+
(0, node_fs_1.renameSync)(tmp, path);
|
|
157
|
+
};
|
|
158
|
+
/**
|
|
159
|
+
* Write the checkpoint: a manifest, the diff, and the untracked files.
|
|
160
|
+
*
|
|
161
|
+
* 🔴 THE MANIFEST IS WRITTEN LAST. Everything it names must already exist, or a
|
|
162
|
+
* crash mid-capture leaves a manifest describing an export that is not there —
|
|
163
|
+
* and a manifest is exactly what a later reader will trust.
|
|
164
|
+
*/
|
|
165
|
+
function writeCheckpoint(root, checkpoint, limits = exports.DEFAULT_CHECKPOINT_LIMITS) {
|
|
166
|
+
const dir = (0, node_path_1.join)(root, 'checkpoints', `${checkpoint.sessionId}-${checkpoint.takenAt.replace(/[:.]/g, '-')}`);
|
|
167
|
+
(0, node_fs_1.mkdirSync)(dir, { recursive: true });
|
|
168
|
+
const incomplete = [];
|
|
169
|
+
/* ── the diff of everything tracked, staged or not ─────────────────── */
|
|
170
|
+
let diffPath = null;
|
|
171
|
+
const diff = git(checkpoint.workspace, ['diff', 'HEAD']);
|
|
172
|
+
if (diff === null) {
|
|
173
|
+
incomplete.push('the diff could not be produced, so the tracked changes are named but not captured');
|
|
174
|
+
}
|
|
175
|
+
else if (diff.length > limits.maxDiffBytes) {
|
|
176
|
+
diffPath = (0, node_path_1.join)(dir, 'changes.patch');
|
|
177
|
+
atomicWrite(diffPath, diff.slice(0, limits.maxDiffBytes));
|
|
178
|
+
incomplete.push(`the diff is ${diff.length} bytes and was cut at ${limits.maxDiffBytes} — it is NOT a complete patch`);
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
diffPath = (0, node_path_1.join)(dir, 'changes.patch');
|
|
182
|
+
atomicWrite(diffPath, diff);
|
|
183
|
+
}
|
|
184
|
+
/* ── the untracked files, which no diff contains ───────────────────── */
|
|
185
|
+
let copied = 0;
|
|
186
|
+
for (const rel of checkpoint.untracked) {
|
|
187
|
+
if (copied >= limits.maxUntrackedFiles) {
|
|
188
|
+
incomplete.push(`${checkpoint.untracked.length - copied} untracked file(s) were not copied — ${limits.maxUntrackedFiles} is the limit`);
|
|
189
|
+
break;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* 🔴 THE LINK CHECK IS ON THE WHOLE PATH, NOT THE LEAF, AND A TEST
|
|
193
|
+
* FOUND OUT WHY. `git ls-files --others` walks THROUGH a junction: with one
|
|
194
|
+
* at `src/link` it reports `src/link/secret.txt`, whose final component is
|
|
195
|
+
* an ordinary file. Checking that component alone saw nothing wrong and
|
|
196
|
+
* copied a file from outside the workspace into an export labelled as this
|
|
197
|
+
* session's work.
|
|
198
|
+
*/
|
|
199
|
+
const link = linkOnTheWayTo(checkpoint.workspace, rel);
|
|
200
|
+
if (link !== null) {
|
|
201
|
+
incomplete.push(`${rel} is reached through the link ${link} and was not followed — what it points at is not this session's work`);
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
const from = (0, node_path_1.resolve)(checkpoint.workspace, rel);
|
|
205
|
+
let st;
|
|
206
|
+
try {
|
|
207
|
+
st = (0, node_fs_1.lstatSync)(from);
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
incomplete.push(`${rel} vanished between being listed and being read`);
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
if (st.isSymbolicLink()) {
|
|
214
|
+
incomplete.push(`${rel} is a link and was not followed — what it points at is not this session's work`);
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
if (!st.isFile())
|
|
218
|
+
continue;
|
|
219
|
+
if (st.size > limits.maxFileBytes) {
|
|
220
|
+
incomplete.push(`${rel} is ${st.size} bytes, past the ${limits.maxFileBytes}-byte limit — not copied`);
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
const to = (0, node_path_1.join)(dir, 'untracked', rel);
|
|
224
|
+
try {
|
|
225
|
+
(0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(to), { recursive: true });
|
|
226
|
+
(0, node_fs_1.copyFileSync)(from, to);
|
|
227
|
+
copied += 1;
|
|
228
|
+
}
|
|
229
|
+
catch (e) {
|
|
230
|
+
incomplete.push(`${rel} could not be copied: ${e.message}`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
const manifest = (0, node_path_1.join)(dir, 'CHECKPOINT.json');
|
|
234
|
+
atomicWrite(manifest, `${JSON.stringify({
|
|
235
|
+
...checkpoint,
|
|
236
|
+
export: {
|
|
237
|
+
diff: diffPath === null ? null : 'changes.patch',
|
|
238
|
+
untrackedCopied: copied,
|
|
239
|
+
untrackedListed: checkpoint.untracked.length,
|
|
240
|
+
},
|
|
241
|
+
/**
|
|
242
|
+
* 🔴 THE INCOMPLETENESS TRAVELS WITH THE THING. A reader who has to
|
|
243
|
+
* compare two lists to notice a truncated patch will not notice it.
|
|
244
|
+
*/
|
|
245
|
+
incomplete,
|
|
246
|
+
certifies: 'nothing. This records what was found in the workspace and when. It does not say the work is ' +
|
|
247
|
+
'correct, reviewed, complete or safe, and it does not adopt the session.',
|
|
248
|
+
}, null, 2)}\n`);
|
|
249
|
+
return { dir, manifest, diff: diffPath, copied, incomplete };
|
|
250
|
+
}
|
|
251
|
+
/** The lines a person reads, with what the export actually contains. */
|
|
252
|
+
function reportCheckpoint(written, checkpoint, out, excluded = []) {
|
|
253
|
+
for (const line of (0, core_1.describeCheckpoint)(checkpoint))
|
|
254
|
+
out(line);
|
|
255
|
+
/**
|
|
256
|
+
* ⚠️ SAID, NOT SILENT. Leaving files out of a capture is exactly the kind
|
|
257
|
+
* of thing that has to be visible: a reader counting files would otherwise
|
|
258
|
+
* find fewer than `git status` shows and have no way to know why.
|
|
259
|
+
*/
|
|
260
|
+
if (excluded.length > 0) {
|
|
261
|
+
out(` ${excluded.length} file(s) under ${exports.STATE_SUBDIR} left out — looply's own bookkeeping, not this session's work`);
|
|
262
|
+
}
|
|
263
|
+
out(` written to ${written.dir}`);
|
|
264
|
+
out(` ${written.diff === null ? 'no patch' : 'changes.patch'}, ${written.copied} untracked file(s) copied`);
|
|
265
|
+
for (const gap of written.incomplete)
|
|
266
|
+
out(` incomplete: ${gap}`);
|
|
267
|
+
}
|
|
268
|
+
//# sourceMappingURL=session-checkpoint-runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-checkpoint-runtime.js","sourceRoot":"","sources":["../src/session-checkpoint-runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { type ControlVerdict, type SessionControlGrant } from '@looply/core';
|
|
2
|
+
import { type AdapterPaths } from './session-adapter-runtime';
|
|
3
|
+
import type { ServerSessionGrant } from './server-client';
|
|
4
|
+
/**
|
|
5
|
+
* THE WIRE THAT TURNS F-14 ON.
|
|
6
|
+
*
|
|
7
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
8
|
+
* WHAT WAS SITTING UNCONNECTED. The fold, the grant table, the routes, the SDK
|
|
9
|
+
* reader, the adapter's two directories and the bounded watcher were all in
|
|
10
|
+
* place, and `sessions --offer` still printed *"this machine could not ask the
|
|
11
|
+
* server"* — because nothing in the CLI had ever asked it anything about a
|
|
12
|
+
* grant. `server.url` and `server.machine_token_file` were parsed by
|
|
13
|
+
* `config.ts` and read by NOBODY: a configuration block with no consumer, which
|
|
14
|
+
* is this codebase's most-named defect wearing different clothes.
|
|
15
|
+
*
|
|
16
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
17
|
+
* 🔴 THE TWO HALVES COME FROM DIFFERENT PLACES ON PURPOSE.
|
|
18
|
+
*
|
|
19
|
+
* the grant the SERVER's, because authority is not this machine's
|
|
20
|
+
* to mint and a local file cannot hold it
|
|
21
|
+
* the acknowledgement the SESSION's own channel, because provenance is the
|
|
22
|
+
* one thing a server cannot observe about a process on
|
|
23
|
+
* somebody else's machine
|
|
24
|
+
*
|
|
25
|
+
* Collapsing either into the other is the failure this whole feature is about.
|
|
26
|
+
* A grant read from a local file is a machine authorizing itself; an
|
|
27
|
+
* acknowledgement taken from the server alone is whoever last POSTed one.
|
|
28
|
+
*
|
|
29
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
30
|
+
* 🔴 `null` IS NOT `refused`, AND EVERY CALLER HERE HAS TO HANDLE BOTH.
|
|
31
|
+
*
|
|
32
|
+
* Unpaired, unregistered, unreachable — none of those is a decision anybody
|
|
33
|
+
* made about this session, and folding them into a refusal would put a
|
|
34
|
+
* plausible sentence on the screen where an absence of information belongs.
|
|
35
|
+
*/
|
|
36
|
+
export interface ControlTransportDeps {
|
|
37
|
+
/** This machine's identity, or null when it has not paired. */
|
|
38
|
+
machine(): {
|
|
39
|
+
readonly machineId: string;
|
|
40
|
+
readonly projectId: string;
|
|
41
|
+
} | null;
|
|
42
|
+
/** Grants for the project, or a throw. A throw is `null`, never a refusal. */
|
|
43
|
+
grants(projectId: string): Promise<readonly ServerSessionGrant[]>;
|
|
44
|
+
/** Record the acknowledgement on the server so its record matches this one. */
|
|
45
|
+
recordAck(projectId: string, grantId: string, ack: {
|
|
46
|
+
handshakeNonce: string;
|
|
47
|
+
sessionId: string;
|
|
48
|
+
workspace: string;
|
|
49
|
+
repositoryId: string;
|
|
50
|
+
scope: readonly string[];
|
|
51
|
+
via: 'adapter' | 'operator';
|
|
52
|
+
}): Promise<void>;
|
|
53
|
+
/** Where this session's inbox and outbox live. */
|
|
54
|
+
paths(sessionId: string): AdapterPaths;
|
|
55
|
+
supportedAdapters(): readonly string[];
|
|
56
|
+
now(): string;
|
|
57
|
+
/** Said out loud, because every one of these lines is a reason for observe-only. */
|
|
58
|
+
note(line: string): void;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* One coherent answer about control, from ONE read of the grants.
|
|
62
|
+
*
|
|
63
|
+
* 🔴 THE VERDICT, THE SCOPE AND THE EXPIRY ALL COME FROM THE SAME GRANT.
|
|
64
|
+
* Fetching them separately opens a window in which they describe different
|
|
65
|
+
* grants — a verb checked against a scope that was superseded between two
|
|
66
|
+
* calls — so `directionContextFor` and `serverControlFor` are both this one
|
|
67
|
+
* function, narrowed.
|
|
68
|
+
*/
|
|
69
|
+
export interface ControlSnapshot {
|
|
70
|
+
readonly verdict: ControlVerdict;
|
|
71
|
+
readonly scope: readonly string[];
|
|
72
|
+
readonly expiresAt: string;
|
|
73
|
+
}
|
|
74
|
+
export declare function controlSnapshotFor(deps: ControlTransportDeps): (sessionId: string) => Promise<ControlSnapshot | null>;
|
|
75
|
+
/**
|
|
76
|
+
* F40: THE OFFER REACHES THE SESSION, AND SO DOES THE REVOCATION.
|
|
77
|
+
*
|
|
78
|
+
* 🔴 MEASURED BEFORE LIVE-3: `offerFor` and `revocationFor` were called by tests and by nothing else, so
|
|
79
|
+
* every earlier proof had its test script put the handshake in the inbox — the script was the messenger,
|
|
80
|
+
* and the product could not establish control on its own. Delivered here, on the one read that already
|
|
81
|
+
* holds the live grant, into the session's inbox and NOWHERE ELSE: the note names the grant and its scope,
|
|
82
|
+
* never the nonce.
|
|
83
|
+
*
|
|
84
|
+
* ⚠️ ONCE PER GRANT. An offer already in the inbox is the same offer; a handshake acknowledged or spent
|
|
85
|
+
* is not offered again; an expired grant is not offered at all. A revocation is told once, so a
|
|
86
|
+
* cooperating session stops on its own — direction is refused by `mayDirect` either way.
|
|
87
|
+
*/
|
|
88
|
+
export declare function deliverControlNotice(paths: AdapterPaths, grant: SessionControlGrant, at: string, note: (line: string) => void): void;
|
|
89
|
+
/**
|
|
90
|
+
* What the server and the session's own channel say about directing this
|
|
91
|
+
* session — the verdict alone, for callers that need nothing else.
|
|
92
|
+
*/
|
|
93
|
+
export declare function serverControlFor(deps: ControlTransportDeps): (sessionId: string) => Promise<ControlVerdict | null>;
|
|
94
|
+
/**
|
|
95
|
+
* The same read, shaped for `mayDirect`.
|
|
96
|
+
*
|
|
97
|
+
* ⚠️ `null` HERE MEANS NOTHING WAS ESTABLISHED, and `mayDirect` turns that
|
|
98
|
+
* into `unmeasurable` rather than into an ending. An unreachable server is not
|
|
99
|
+
* a person withdrawing permission.
|
|
100
|
+
*/
|
|
101
|
+
export declare function directionContextFor(deps: ControlTransportDeps): (sessionId: string) => Promise<{
|
|
102
|
+
control: ControlVerdict;
|
|
103
|
+
scope: readonly string[];
|
|
104
|
+
expiresAt: string;
|
|
105
|
+
} | null>;
|
|
106
|
+
//# sourceMappingURL=session-control-transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-control-transport.d.ts","sourceRoot":"","sources":["../src/session-control-transport.ts"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,cAAc,EAEnB,KAAK,mBAAmB,EACzB,MAAM,cAAc,CAAC;AACtB,OAAO,EAA6E,KAAK,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzI,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,MAAM,WAAW,oBAAoB;IACnC,+DAA+D;IAC/D,OAAO,IAAI;QAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC7E,8EAA8E;IAC9E,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,kBAAkB,EAAE,CAAC,CAAC;IAClE,+EAA+E;IAC/E,SAAS,CACP,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,GAAG,EAAE;QACH,cAAc,EAAE,MAAM,CAAC;QACvB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,YAAY,EAAE,MAAM,CAAC;QACrB,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;QACzB,GAAG,EAAE,SAAS,GAAG,UAAU,CAAC;KAC7B,GACA,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,kDAAkD;IAClD,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,CAAC;IACvC,iBAAiB,IAAI,SAAS,MAAM,EAAE,CAAC;IACvC,GAAG,IAAI,MAAM,CAAC;IACd,oFAAoF;IACpF,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAuCD;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,oBAAoB,GAAG,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAgIrH;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,YAAY,EACnB,KAAK,EAAE,mBAAmB,EAC1B,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAC3B,IAAI,CAkBN;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,oBAAoB,GAAG,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAGlH;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,oBAAoB,GACzB,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;IAAE,OAAO,EAAE,cAAc,CAAC;IAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAMjH"}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.controlSnapshotFor = controlSnapshotFor;
|
|
4
|
+
exports.deliverControlNotice = deliverControlNotice;
|
|
5
|
+
exports.serverControlFor = serverControlFor;
|
|
6
|
+
exports.directionContextFor = directionContextFor;
|
|
7
|
+
const node_fs_1 = require("node:fs");
|
|
8
|
+
const node_path_1 = require("node:path");
|
|
9
|
+
const core_1 = require("@looply/core");
|
|
10
|
+
const session_adapter_runtime_1 = require("./session-adapter-runtime");
|
|
11
|
+
/**
|
|
12
|
+
* ⚠️ THE HIGHEST GENERATION WINS, AND EARLIER ONES ARE NOT CONSIDERED. A
|
|
13
|
+
* session that has been granted control twice has one live grant and a history;
|
|
14
|
+
* evaluating the history would let a spent generation answer for the current
|
|
15
|
+
* one, which is the shape `session-control.ts` calls "reviving a spent
|
|
16
|
+
* identity".
|
|
17
|
+
*/
|
|
18
|
+
function liveGrantFor(grants, sessionId) {
|
|
19
|
+
const mine = grants.filter((g) => g.sessionId === sessionId);
|
|
20
|
+
if (mine.length === 0)
|
|
21
|
+
return null;
|
|
22
|
+
return mine.reduce((best, g) => (g.generation > best.generation ? g : best));
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* ⚠️ `machineId` IS SUPPLIED BY THIS MACHINE, NEVER READ OFF THE WIRE. It is
|
|
26
|
+
* what `controlVerdict` compares the grant against, and a value the server
|
|
27
|
+
* chose would let the server tell a machine which machine it is.
|
|
28
|
+
*/
|
|
29
|
+
function asGrant(row, machineId) {
|
|
30
|
+
return {
|
|
31
|
+
id: row.id,
|
|
32
|
+
issuedBy: row.issuedBy,
|
|
33
|
+
machineId,
|
|
34
|
+
projectId: row.projectId,
|
|
35
|
+
repositoryId: row.repositoryId,
|
|
36
|
+
workspace: row.workspace,
|
|
37
|
+
sessionId: row.sessionId,
|
|
38
|
+
scope: row.scope,
|
|
39
|
+
handshakeNonce: row.handshakeNonce,
|
|
40
|
+
issuedAt: row.issuedAt,
|
|
41
|
+
expiresAt: row.expiresAt,
|
|
42
|
+
version: row.version,
|
|
43
|
+
state: row.state,
|
|
44
|
+
generation: row.generation,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function controlSnapshotFor(deps) {
|
|
48
|
+
return async (sessionId) => {
|
|
49
|
+
const identity = deps.machine();
|
|
50
|
+
if (identity === null) {
|
|
51
|
+
deps.note('this machine is not paired with a server, so nothing about control was established');
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
let rows;
|
|
55
|
+
try {
|
|
56
|
+
rows = await deps.grants(identity.projectId);
|
|
57
|
+
}
|
|
58
|
+
catch (e) {
|
|
59
|
+
deps.note(`the server could not be asked about control grants: ${e.message}`);
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
const row = liveGrantFor(rows, sessionId);
|
|
63
|
+
if (row === null) {
|
|
64
|
+
/**
|
|
65
|
+
* ⚠️ A REFUSAL STILL CARRIES A SCOPE AND AN EXPIRY, and they are empty
|
|
66
|
+
* and already-past on purpose: a caller that read them without looking at
|
|
67
|
+
* the verdict would find a grant that permits nothing and lapsed at the
|
|
68
|
+
* moment it asked. Failing closed in the shape as well as in the branch.
|
|
69
|
+
*/
|
|
70
|
+
return {
|
|
71
|
+
verdict: { kind: 'refused', because: `no control grant has ever been issued for ${sessionId}` },
|
|
72
|
+
scope: [],
|
|
73
|
+
expiresAt: deps.now(),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
const grant = asGrant(row, identity.machineId);
|
|
77
|
+
const at = deps.now();
|
|
78
|
+
const paths = deps.paths(sessionId);
|
|
79
|
+
/**
|
|
80
|
+
* 🔴 THE ACKNOWLEDGEMENT COMES FROM THE SESSION'S OWN OUTBOX, RULED BY THE
|
|
81
|
+
* FOLD. Nothing here decides whether a message is admissible; `ruleOnOutbox`
|
|
82
|
+
* does, inside `collectOutbox`, which is why the replay and identity rules
|
|
83
|
+
* are testable without a server.
|
|
84
|
+
*/
|
|
85
|
+
const collected = (0, session_adapter_runtime_1.collectOutbox)(paths, { grant, supportedAdapters: deps.supportedAdapters(), at });
|
|
86
|
+
if (!collected.present) {
|
|
87
|
+
// F40: a session that has never answered is exactly the one that needs the offer.
|
|
88
|
+
deliverControlNotice(paths, grant, at, deps.note);
|
|
89
|
+
return {
|
|
90
|
+
verdict: { kind: 'refused', because: `${sessionId} has no outbox, so it has not acknowledged through its adapter` },
|
|
91
|
+
scope: grant.scope,
|
|
92
|
+
expiresAt: grant.expiresAt,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
for (const blind of collected.unreadable)
|
|
96
|
+
deps.note(`outbox: ${blind}`);
|
|
97
|
+
let ack = null;
|
|
98
|
+
for (const { file, ruling } of collected.rulings) {
|
|
99
|
+
if (ruling.kind === 'accept') {
|
|
100
|
+
/**
|
|
101
|
+
* 🔴 SPENT BEFORE ANYTHING ACTS ON IT. A crash between acting and
|
|
102
|
+
* recording leaves a replayable handshake — the one thing the nonce
|
|
103
|
+
* exists to prevent, reachable by pulling a plug at the right moment.
|
|
104
|
+
* The cost of the other order is that a lost acknowledgement needs a
|
|
105
|
+
* re-issued grant, which is an inconvenience with a person in the loop.
|
|
106
|
+
*/
|
|
107
|
+
(0, session_adapter_runtime_1.markSpent)(paths, ruling.ack.handshakeNonce, at, `acknowledged ${ruling.ack.grantId} from ${file}`, ruling.ack);
|
|
108
|
+
(0, session_adapter_runtime_1.archive)(paths, file);
|
|
109
|
+
/**
|
|
110
|
+
* 🔴 AND IF THE SERVER CANNOT BE TOLD, NOTHING WAS ESTABLISHED. The
|
|
111
|
+
* handshake is already spent, so this acknowledgement cannot be
|
|
112
|
+
* presented again and the grant has to be re-issued — a real cost, paid
|
|
113
|
+
* deliberately. Returning `controlled` on a local decision the server
|
|
114
|
+
* has no record of would be two systems disagreeing about who may
|
|
115
|
+
* direct a session, with neither able to see the other's answer.
|
|
116
|
+
*/
|
|
117
|
+
try {
|
|
118
|
+
await deps.recordAck(identity.projectId, ruling.ack.grantId, {
|
|
119
|
+
handshakeNonce: ruling.ack.handshakeNonce,
|
|
120
|
+
sessionId: ruling.ack.sessionId,
|
|
121
|
+
workspace: ruling.ack.workspace,
|
|
122
|
+
repositoryId: ruling.ack.repositoryId,
|
|
123
|
+
scope: ruling.ack.scope,
|
|
124
|
+
via: ruling.ack.via,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
catch (e) {
|
|
128
|
+
deps.note(`the session acknowledged, and the server could not be told: ${e.message}. ` +
|
|
129
|
+
'That handshake is spent; a new grant is needed.');
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
ack = ruling.ack;
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* ⚠️ EVERY OTHER RULING IS SAID, NOT SWALLOWED. A declined grant, a
|
|
137
|
+
* replayed handshake and an unparseable file all leave the session at
|
|
138
|
+
* observe-only, and which one happened is the whole difference between
|
|
139
|
+
* "it said no", "somebody tried something" and "its adapter is broken".
|
|
140
|
+
*/
|
|
141
|
+
if (ruling.kind === 'declined')
|
|
142
|
+
deps.note(`${file}: the session declined — ${ruling.because}`);
|
|
143
|
+
else if (ruling.kind === 'refused')
|
|
144
|
+
deps.note(`${file}: not accepted — ${ruling.because}`);
|
|
145
|
+
else
|
|
146
|
+
deps.note(`${file}: nothing established — ${ruling.because}`);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* 🔴 AN ACKNOWLEDGEMENT ALREADY VALIDATED FOR THIS HANDSHAKE STILL COUNTS.
|
|
150
|
+
*
|
|
151
|
+
* A live run found this the hard way: `--offer` consumed the outbox message
|
|
152
|
+
* and archived it, and the next command answered "the session has not
|
|
153
|
+
* acknowledged this grant". Control lasted exactly one read. The
|
|
154
|
+
* acknowledgement is looked up by the LIVE grant's nonce, so a new grant
|
|
155
|
+
* still needs a new one — and the grant itself is re-read from the server
|
|
156
|
+
* every time, so revocation and expiry are unaffected.
|
|
157
|
+
*/
|
|
158
|
+
if (ack === null)
|
|
159
|
+
ack = (0, session_adapter_runtime_1.validatedAck)(paths, grant.handshakeNonce);
|
|
160
|
+
// F40: unanswered, it is offered; revoked, the session is told (see `deliverControlNotice`).
|
|
161
|
+
if (ack === null || grant.state === 'revoked')
|
|
162
|
+
deliverControlNotice(paths, grant, at, deps.note);
|
|
163
|
+
return {
|
|
164
|
+
verdict: (0, core_1.controlVerdict)({
|
|
165
|
+
grant,
|
|
166
|
+
ack,
|
|
167
|
+
at,
|
|
168
|
+
asking: { machineId: identity.machineId, projectId: identity.projectId },
|
|
169
|
+
}),
|
|
170
|
+
scope: grant.scope,
|
|
171
|
+
expiresAt: grant.expiresAt,
|
|
172
|
+
};
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* F40: THE OFFER REACHES THE SESSION, AND SO DOES THE REVOCATION.
|
|
177
|
+
*
|
|
178
|
+
* 🔴 MEASURED BEFORE LIVE-3: `offerFor` and `revocationFor` were called by tests and by nothing else, so
|
|
179
|
+
* every earlier proof had its test script put the handshake in the inbox — the script was the messenger,
|
|
180
|
+
* and the product could not establish control on its own. Delivered here, on the one read that already
|
|
181
|
+
* holds the live grant, into the session's inbox and NOWHERE ELSE: the note names the grant and its scope,
|
|
182
|
+
* never the nonce.
|
|
183
|
+
*
|
|
184
|
+
* ⚠️ ONCE PER GRANT. An offer already in the inbox is the same offer; a handshake acknowledged or spent
|
|
185
|
+
* is not offered again; an expired grant is not offered at all. A revocation is told once, so a
|
|
186
|
+
* cooperating session stops on its own — direction is refused by `mayDirect` either way.
|
|
187
|
+
*/
|
|
188
|
+
function deliverControlNotice(paths, grant, at, note) {
|
|
189
|
+
if (grant.state === 'authorized') {
|
|
190
|
+
if (Date.parse(grant.expiresAt) <= Date.parse(at))
|
|
191
|
+
return;
|
|
192
|
+
if ((0, session_adapter_runtime_1.validatedAck)(paths, grant.handshakeNonce) !== null)
|
|
193
|
+
return;
|
|
194
|
+
if ((0, session_adapter_runtime_1.spentHandshakes)(paths).includes(grant.handshakeNonce))
|
|
195
|
+
return;
|
|
196
|
+
if ((0, node_fs_1.existsSync)((0, node_path_1.join)(paths.inbox, `control-offered-${grant.id}.json`)))
|
|
197
|
+
return;
|
|
198
|
+
(0, session_adapter_runtime_1.deliver)(paths, (0, core_1.offerFor)(grant, at));
|
|
199
|
+
note(`offered control of ${grant.sessionId} through its inbox — grant ${grant.id}, scope ${grant.scope.join(', ')}, ` +
|
|
200
|
+
`until ${grant.expiresAt}; it has not acknowledged yet`);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
if (grant.state === 'revoked') {
|
|
204
|
+
if ((0, node_fs_1.existsSync)((0, node_path_1.join)(paths.inbox, `control-revoked-${grant.id}.json`)))
|
|
205
|
+
return;
|
|
206
|
+
(0, session_adapter_runtime_1.deliver)(paths, (0, core_1.revocationFor)(grant, at, 'the owner revoked this grant'));
|
|
207
|
+
note(`told ${grant.sessionId} through its inbox that grant ${grant.id} was revoked`);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* What the server and the session's own channel say about directing this
|
|
212
|
+
* session — the verdict alone, for callers that need nothing else.
|
|
213
|
+
*/
|
|
214
|
+
function serverControlFor(deps) {
|
|
215
|
+
const snapshot = controlSnapshotFor(deps);
|
|
216
|
+
return async (sessionId) => (await snapshot(sessionId))?.verdict ?? null;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* The same read, shaped for `mayDirect`.
|
|
220
|
+
*
|
|
221
|
+
* ⚠️ `null` HERE MEANS NOTHING WAS ESTABLISHED, and `mayDirect` turns that
|
|
222
|
+
* into `unmeasurable` rather than into an ending. An unreachable server is not
|
|
223
|
+
* a person withdrawing permission.
|
|
224
|
+
*/
|
|
225
|
+
function directionContextFor(deps) {
|
|
226
|
+
const snapshot = controlSnapshotFor(deps);
|
|
227
|
+
return async (sessionId) => {
|
|
228
|
+
const snap = await snapshot(sessionId);
|
|
229
|
+
return snap === null ? null : { control: snap.verdict, scope: snap.scope, expiresAt: snap.expiresAt };
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=session-control-transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-control-transport.js","sourceRoot":"","sources":["../src/session-control-transport.ts"],"names":[],"mappings":"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"}
|