@amalgm/shell 0.1.164-preview.36072132286 → 0.1.164-preview.36809057014
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/PURPOSE.md +642 -128
- package/README.md +10 -8
- package/dist/accepted-tail.d.ts +26 -0
- package/dist/accepted-tail.js +37 -0
- package/dist/accepted-tail.js.map +1 -0
- package/dist/agent-execution.d.ts +16 -1
- package/dist/agent-execution.js +13 -5
- package/dist/agent-execution.js.map +1 -1
- package/dist/apply-cleanup.d.ts +28 -0
- package/dist/apply-cleanup.js +166 -0
- package/dist/apply-cleanup.js.map +1 -0
- package/dist/apply-recovery.d.ts +47 -0
- package/dist/apply-recovery.js +99 -0
- package/dist/apply-recovery.js.map +1 -0
- package/dist/apply-rows.d.ts +72 -0
- package/dist/apply-rows.js +150 -0
- package/dist/apply-rows.js.map +1 -0
- package/dist/apply-saves.d.ts +85 -0
- package/dist/apply-saves.js +238 -0
- package/dist/apply-saves.js.map +1 -0
- package/dist/boot.js +2 -1
- package/dist/boot.js.map +1 -1
- package/dist/capture-work.d.ts +8 -0
- package/dist/capture-work.js +67 -0
- package/dist/capture-work.js.map +1 -0
- package/dist/cargo-group.d.ts +45 -0
- package/dist/cargo-group.js +88 -0
- package/dist/cargo-group.js.map +1 -0
- package/dist/channel-session.d.ts +4 -2
- package/dist/channel-session.js +4 -3
- package/dist/channel-session.js.map +1 -1
- package/dist/chat-composition.d.ts +2 -0
- package/dist/chat-composition.js +1 -0
- package/dist/chat-composition.js.map +1 -1
- package/dist/cli.js +20 -1
- package/dist/cli.js.map +1 -1
- package/dist/construct-apply-host.d.ts +4 -2
- package/dist/construct-apply-host.js +8 -3
- package/dist/construct-apply-host.js.map +1 -1
- package/dist/construct-door.js +1 -1
- package/dist/construct-door.js.map +1 -1
- package/dist/construct-ledger.d.ts +6 -1
- package/dist/construct-ledger.js +21 -33
- package/dist/construct-ledger.js.map +1 -1
- package/dist/content-cache-collection.d.ts +18 -0
- package/dist/content-cache-collection.js +99 -0
- package/dist/content-cache-collection.js.map +1 -0
- package/dist/content-cache-host.d.ts +83 -17
- package/dist/content-cache-host.js +335 -95
- package/dist/content-cache-host.js.map +1 -1
- package/dist/content-cache-namespace.d.ts +59 -0
- package/dist/content-cache-namespace.js +210 -0
- package/dist/content-cache-namespace.js.map +1 -0
- package/dist/content-cache-ownership.d.ts +13 -0
- package/dist/content-cache-ownership.js +75 -0
- package/dist/content-cache-ownership.js.map +1 -0
- package/dist/content-cache-retention.d.ts +23 -0
- package/dist/content-cache-retention.js +195 -0
- package/dist/content-cache-retention.js.map +1 -0
- package/dist/content-capture-pool.d.ts +287 -0
- package/dist/content-capture-pool.js +461 -0
- package/dist/content-capture-pool.js.map +1 -0
- package/dist/content-capture-worker.d.ts +8 -0
- package/dist/content-capture-worker.js +109 -0
- package/dist/content-capture-worker.js.map +1 -0
- package/dist/content-clock.d.ts +42 -0
- package/dist/content-clock.js +166 -0
- package/dist/content-clock.js.map +1 -0
- package/dist/content-direct.d.ts +2 -0
- package/dist/content-direct.js +12 -0
- package/dist/content-direct.js.map +1 -1
- package/dist/content-failure.d.ts +18 -0
- package/dist/content-failure.js +38 -0
- package/dist/content-failure.js.map +1 -0
- package/dist/content-stream-thread.d.ts +60 -0
- package/dist/content-stream-thread.js +95 -0
- package/dist/content-stream-thread.js.map +1 -0
- package/dist/content-stream-worker.d.ts +7 -0
- package/dist/content-stream-worker.js +52 -0
- package/dist/content-stream-worker.js.map +1 -0
- package/dist/declaration-absorption.d.ts +37 -0
- package/dist/declaration-absorption.js +119 -0
- package/dist/declaration-absorption.js.map +1 -0
- package/dist/declaration-chain.d.ts +36 -0
- package/dist/declaration-chain.js +96 -0
- package/dist/declaration-chain.js.map +1 -0
- package/dist/declaration-commit.d.ts +31 -0
- package/dist/declaration-commit.js +49 -0
- package/dist/declaration-commit.js.map +1 -0
- package/dist/declaration-hold.d.ts +22 -0
- package/dist/declaration-hold.js +24 -0
- package/dist/declaration-hold.js.map +1 -0
- package/dist/declaration-journal.d.ts +62 -0
- package/dist/declaration-journal.js +99 -0
- package/dist/declaration-journal.js.map +1 -0
- package/dist/declaration-save.d.ts +31 -0
- package/dist/declaration-save.js +134 -0
- package/dist/declaration-save.js.map +1 -0
- package/dist/detection/accepted-result.d.ts +19 -1
- package/dist/detection/accepted-result.js +36 -5
- package/dist/detection/accepted-result.js.map +1 -1
- package/dist/detection/admission-save.d.ts +55 -0
- package/dist/detection/admission-save.js +48 -0
- package/dist/detection/admission-save.js.map +1 -0
- package/dist/detection/admission-units.d.ts +66 -0
- package/dist/detection/admission-units.js +322 -0
- package/dist/detection/admission-units.js.map +1 -0
- package/dist/detection/alias-discovery.d.ts +12 -0
- package/dist/detection/alias-discovery.js +80 -0
- package/dist/detection/alias-discovery.js.map +1 -0
- package/dist/detection/alias-examination.d.ts +30 -0
- package/dist/detection/alias-examination.js +49 -0
- package/dist/detection/alias-examination.js.map +1 -0
- package/dist/detection/apply-ownership.d.ts +81 -0
- package/dist/detection/apply-ownership.js +232 -0
- package/dist/detection/apply-ownership.js.map +1 -0
- package/dist/detection/basis-advanced.d.ts +11 -0
- package/dist/detection/basis-advanced.js +26 -0
- package/dist/detection/basis-advanced.js.map +1 -0
- package/dist/detection/capture-outcome.d.ts +16 -0
- package/dist/detection/capture-outcome.js +92 -0
- package/dist/detection/capture-outcome.js.map +1 -0
- package/dist/detection/container-membership.d.ts +32 -0
- package/dist/detection/container-membership.js +49 -0
- package/dist/detection/container-membership.js.map +1 -0
- package/dist/detection/detect-cancelled.d.ts +6 -0
- package/dist/detection/detect-cancelled.js +10 -0
- package/dist/detection/detect-cancelled.js.map +1 -0
- package/dist/detection/directory-proof.d.ts +47 -0
- package/dist/detection/directory-proof.js +77 -0
- package/dist/detection/directory-proof.js.map +1 -0
- package/dist/detection/disposition-rows.d.ts +18 -0
- package/dist/detection/disposition-rows.js +29 -0
- package/dist/detection/disposition-rows.js.map +1 -0
- package/dist/detection/dispositions.d.ts +130 -0
- package/dist/detection/dispositions.js +248 -0
- package/dist/detection/dispositions.js.map +1 -0
- package/dist/detection/git-notice.d.ts +88 -0
- package/dist/detection/git-notice.js +444 -0
- package/dist/detection/git-notice.js.map +1 -0
- package/dist/detection/ground-proof.d.ts +130 -0
- package/dist/detection/ground-proof.js +274 -0
- package/dist/detection/ground-proof.js.map +1 -0
- package/dist/detection/ground-reader.d.ts +29 -0
- package/dist/detection/ground-reader.js +102 -0
- package/dist/detection/ground-reader.js.map +1 -0
- package/dist/detection/held-territory.d.ts +51 -0
- package/dist/detection/held-territory.js +205 -0
- package/dist/detection/held-territory.js.map +1 -0
- package/dist/detection/identity-discovery.d.ts +45 -0
- package/dist/detection/identity-discovery.js +287 -0
- package/dist/detection/identity-discovery.js.map +1 -0
- package/dist/detection/maintenance-sweep.d.ts +108 -0
- package/dist/detection/maintenance-sweep.js +325 -0
- package/dist/detection/maintenance-sweep.js.map +1 -0
- package/dist/detection/name-reach.d.ts +12 -0
- package/dist/detection/name-reach.js +28 -0
- package/dist/detection/name-reach.js.map +1 -0
- package/dist/detection/notebook-basis.d.ts +5 -7
- package/dist/detection/notebook-basis.js +6 -7
- package/dist/detection/notebook-basis.js.map +1 -1
- package/dist/detection/owed-selection.d.ts +51 -0
- package/dist/detection/owed-selection.js +169 -0
- package/dist/detection/owed-selection.js.map +1 -0
- package/dist/detection/portable.d.ts +34 -34
- package/dist/detection/portable.js +67 -93
- package/dist/detection/portable.js.map +1 -1
- package/dist/detection/reconciliation-coverage.d.ts +7 -0
- package/dist/detection/reconciliation-coverage.js +16 -0
- package/dist/detection/reconciliation-coverage.js.map +1 -0
- package/dist/detection/repository-publication.d.ts +20 -0
- package/dist/detection/repository-publication.js +79 -0
- package/dist/detection/repository-publication.js.map +1 -0
- package/dist/detection/repository-routes.d.ts +43 -0
- package/dist/detection/repository-routes.js +97 -0
- package/dist/detection/repository-routes.js.map +1 -0
- package/dist/detection/root-examination.d.ts +94 -0
- package/dist/detection/root-examination.js +523 -0
- package/dist/detection/root-examination.js.map +1 -0
- package/dist/detection/runtime.d.ts +131 -64
- package/dist/detection/runtime.js +808 -1103
- package/dist/detection/runtime.js.map +1 -1
- package/dist/detection/scoped-identity-port.d.ts +34 -0
- package/dist/detection/scoped-identity-port.js +81 -0
- package/dist/detection/scoped-identity-port.js.map +1 -0
- package/dist/detection/seal-law.d.ts +66 -0
- package/dist/detection/seal-law.js +116 -0
- package/dist/detection/seal-law.js.map +1 -0
- package/dist/detection/sharing-policy.d.ts +11 -0
- package/dist/detection/sharing-policy.js +32 -0
- package/dist/detection/sharing-policy.js.map +1 -0
- package/dist/detection/thread-database.d.ts +4 -0
- package/dist/detection/thread-database.js +30 -0
- package/dist/detection/thread-database.js.map +1 -0
- package/dist/detection/unreadable.d.ts +11 -0
- package/dist/detection/unreadable.js +9 -0
- package/dist/detection/unreadable.js.map +1 -0
- package/dist/detection/verified-content.d.ts +6 -0
- package/dist/detection/verified-content.js +12 -0
- package/dist/detection/verified-content.js.map +1 -0
- package/dist/detection/walk-law.d.ts +34 -0
- package/dist/detection/walk-law.js +55 -0
- package/dist/detection/walk-law.js.map +1 -0
- package/dist/development/fly-guest.js +2 -1
- package/dist/development/fly-guest.js.map +1 -1
- package/dist/entity-apply-host.d.ts +29 -13
- package/dist/entity-apply-host.js +1426 -461
- package/dist/entity-apply-host.js.map +1 -1
- package/dist/entity-apply-store.d.ts +77 -30
- package/dist/entity-apply-store.js +221 -516
- package/dist/entity-apply-store.js.map +1 -1
- package/dist/entity-record-observability.js +2 -0
- package/dist/entity-record-observability.js.map +1 -1
- package/dist/entity-record-saves.d.ts +20 -0
- package/dist/entity-record-saves.js +91 -0
- package/dist/entity-record-saves.js.map +1 -0
- package/dist/entity-record-store.d.ts +15 -7
- package/dist/entity-record-store.js +57 -117
- package/dist/entity-record-store.js.map +1 -1
- package/dist/files-register-host.d.ts +22 -3
- package/dist/files-register-host.js +70 -31
- package/dist/files-register-host.js.map +1 -1
- package/dist/filesystem.js +3 -2
- package/dist/filesystem.js.map +1 -1
- package/dist/git-binding.d.ts +65 -0
- package/dist/git-binding.js +220 -0
- package/dist/git-binding.js.map +1 -0
- package/dist/git-capture.d.ts +39 -0
- package/dist/git-capture.js +86 -0
- package/dist/git-capture.js.map +1 -0
- package/dist/git-card.d.ts +12 -0
- package/dist/git-card.js +123 -0
- package/dist/git-card.js.map +1 -0
- package/dist/git-checkpoint-construction.d.ts +41 -0
- package/dist/git-checkpoint-construction.js +96 -0
- package/dist/git-checkpoint-construction.js.map +1 -0
- package/dist/git-checkpoint-preparation.d.ts +37 -0
- package/dist/git-checkpoint-preparation.js +145 -0
- package/dist/git-checkpoint-preparation.js.map +1 -0
- package/dist/git-command.d.ts +61 -8
- package/dist/git-command.js +217 -63
- package/dist/git-command.js.map +1 -1
- package/dist/git-configuration.d.ts +40 -0
- package/dist/git-configuration.js +217 -0
- package/dist/git-configuration.js.map +1 -0
- package/dist/git-evidence.d.ts +61 -0
- package/dist/git-evidence.js +181 -0
- package/dist/git-evidence.js.map +1 -0
- package/dist/git-index-entries.d.ts +15 -0
- package/dist/git-index-entries.js +44 -0
- package/dist/git-index-entries.js.map +1 -0
- package/dist/git-index-format.d.ts +35 -0
- package/dist/git-index-format.js +293 -0
- package/dist/git-index-format.js.map +1 -0
- package/dist/git-index-witness.d.ts +33 -0
- package/dist/git-index-witness.js +69 -0
- package/dist/git-index-witness.js.map +1 -0
- package/dist/git-literal-host.d.ts +82 -0
- package/dist/git-literal-host.js +172 -0
- package/dist/git-literal-host.js.map +1 -0
- package/dist/git-literal-read.d.ts +88 -0
- package/dist/git-literal-read.js +170 -0
- package/dist/git-literal-read.js.map +1 -0
- package/dist/git-literal-replay.d.ts +33 -0
- package/dist/git-literal-replay.js +268 -0
- package/dist/git-literal-replay.js.map +1 -0
- package/dist/git-native-file.d.ts +42 -0
- package/dist/git-native-file.js +145 -0
- package/dist/git-native-file.js.map +1 -0
- package/dist/git-native-index.d.ts +21 -0
- package/dist/git-native-index.js +44 -0
- package/dist/git-native-index.js.map +1 -0
- package/dist/git-operation-host.d.ts +48 -0
- package/dist/git-operation-host.js +127 -0
- package/dist/git-operation-host.js.map +1 -0
- package/dist/git-private-index.d.ts +11 -0
- package/dist/git-private-index.js +42 -0
- package/dist/git-private-index.js.map +1 -0
- package/dist/git-private-repository.d.ts +4 -0
- package/dist/git-private-repository.js +69 -0
- package/dist/git-private-repository.js.map +1 -0
- package/dist/git-private-view.d.ts +39 -0
- package/dist/git-private-view.js +162 -0
- package/dist/git-private-view.js.map +1 -0
- package/dist/git-ref-store.d.ts +12 -0
- package/dist/git-ref-store.js +68 -0
- package/dist/git-ref-store.js.map +1 -0
- package/dist/git-registration-host.d.ts +20 -30
- package/dist/git-registration-host.js +86 -249
- package/dist/git-registration-host.js.map +1 -1
- package/dist/git-repository-host.d.ts +148 -22
- package/dist/git-repository-host.js +633 -650
- package/dist/git-repository-host.js.map +1 -1
- package/dist/git-worktree-host.d.ts +2 -0
- package/dist/git-worktree-host.js +16 -0
- package/dist/git-worktree-host.js.map +1 -0
- package/dist/graph-publication.d.ts +75 -0
- package/dist/graph-publication.js +203 -0
- package/dist/graph-publication.js.map +1 -0
- package/dist/ground-basis.d.ts +242 -0
- package/dist/ground-basis.js +1023 -0
- package/dist/ground-basis.js.map +1 -0
- package/dist/ground-checkpoint-worker.d.ts +1 -0
- package/dist/ground-checkpoint-worker.js +84 -0
- package/dist/ground-checkpoint-worker.js.map +1 -0
- package/dist/ground-checkpoints.d.ts +16 -0
- package/dist/ground-checkpoints.js +45 -0
- package/dist/ground-checkpoints.js.map +1 -0
- package/dist/ground-coordination.d.ts +107 -3
- package/dist/ground-coordination.js +249 -24
- package/dist/ground-coordination.js.map +1 -1
- package/dist/ground-database.d.ts +42 -0
- package/dist/ground-database.js +290 -0
- package/dist/ground-database.js.map +1 -0
- package/dist/ground-differences.d.ts +23 -0
- package/dist/ground-differences.js +47 -0
- package/dist/ground-differences.js.map +1 -0
- package/dist/ground-holders.d.ts +4 -0
- package/dist/ground-holders.js +15 -0
- package/dist/ground-holders.js.map +1 -0
- package/dist/ground-initialization-worker.d.ts +1 -0
- package/dist/ground-initialization-worker.js +20 -0
- package/dist/ground-initialization-worker.js.map +1 -0
- package/dist/ground-initialization.d.ts +35 -0
- package/dist/ground-initialization.js +102 -0
- package/dist/ground-initialization.js.map +1 -0
- package/dist/ground-install-saves.d.ts +63 -0
- package/dist/ground-install-saves.js +139 -0
- package/dist/ground-install-saves.js.map +1 -0
- package/dist/ground-inventory-schema.d.ts +18 -0
- package/dist/ground-inventory-schema.js +168 -0
- package/dist/ground-inventory-schema.js.map +1 -0
- package/dist/ground-profile.d.ts +7 -0
- package/dist/ground-profile.js +52 -0
- package/dist/ground-profile.js.map +1 -0
- package/dist/ground-root-index.d.ts +2 -1
- package/dist/ground-root-index.js +16 -14
- package/dist/ground-root-index.js.map +1 -1
- package/dist/ground-row.d.ts +62 -0
- package/dist/ground-row.js +70 -0
- package/dist/ground-row.js.map +1 -0
- package/dist/ground-save-ops.d.ts +44 -0
- package/dist/ground-save-ops.js +41 -0
- package/dist/ground-save-ops.js.map +1 -0
- package/dist/ground-saver-worker.d.ts +1 -0
- package/dist/ground-saver-worker.js +156 -0
- package/dist/ground-saver-worker.js.map +1 -0
- package/dist/ground-saver.d.ts +75 -0
- package/dist/ground-saver.js +216 -0
- package/dist/ground-saver.js.map +1 -0
- package/dist/ground-store.d.ts +84 -0
- package/dist/ground-store.js +473 -0
- package/dist/ground-store.js.map +1 -0
- package/dist/ground-territory.d.ts +130 -0
- package/dist/ground-territory.js +511 -0
- package/dist/ground-territory.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/dist/installation/ownership.d.ts +0 -2
- package/dist/installation/ownership.js +3 -15
- package/dist/installation/ownership.js.map +1 -1
- package/dist/machine-host.d.ts +3 -2
- package/dist/machine-host.js +28 -16
- package/dist/machine-host.js.map +1 -1
- package/dist/materialized-graph.d.ts +7 -7
- package/dist/materialized-graph.js +11 -23
- package/dist/materialized-graph.js.map +1 -1
- package/dist/module-thread.d.ts +9 -0
- package/dist/module-thread.js +10 -0
- package/dist/module-thread.js.map +1 -0
- package/dist/native/fsevents-stream.node +0 -0
- package/dist/physical-path-witness.d.ts +64 -0
- package/dist/physical-path-witness.js +168 -0
- package/dist/physical-path-witness.js.map +1 -0
- package/dist/register-upload-fusion.d.ts +5 -4
- package/dist/register-upload-fusion.js +9 -6
- package/dist/register-upload-fusion.js.map +1 -1
- package/dist/registry-graph.d.ts +3 -2
- package/dist/registry-graph.js +9 -6
- package/dist/registry-graph.js.map +1 -1
- package/dist/registry-page-cache.d.ts +5 -2
- package/dist/registry-page-cache.js.map +1 -1
- package/dist/repository-identity-steps.d.ts +5 -0
- package/dist/repository-identity-steps.js +33 -0
- package/dist/repository-identity-steps.js.map +1 -0
- package/dist/runtime-node-flags.d.ts +10 -0
- package/dist/runtime-node-flags.js +11 -0
- package/dist/runtime-node-flags.js.map +1 -0
- package/dist/service/adapter.d.ts +1 -1
- package/dist/service/adapter.js +1 -1
- package/dist/service/adapter.js.map +1 -1
- package/dist/service/cli.js +16 -20
- package/dist/service/cli.js.map +1 -1
- package/dist/service/control.d.ts +2 -2
- package/dist/service/keepalive.d.ts +4 -11
- package/dist/service/keepalive.js +65 -118
- package/dist/service/keepalive.js.map +1 -1
- package/dist/service/policy.d.ts +36 -0
- package/dist/service/policy.js +25 -0
- package/dist/service/policy.js.map +1 -0
- package/dist/service/portable.d.ts +1 -1
- package/dist/service/portable.js +1 -1
- package/dist/service/portable.js.map +1 -1
- package/dist/service/recovery.d.ts +10 -9
- package/dist/service/recovery.js +29 -19
- package/dist/service/recovery.js.map +1 -1
- package/dist/service/windows-action.d.ts +5 -3
- package/dist/service/windows-action.js +6 -9
- package/dist/service/windows-action.js.map +1 -1
- package/dist/service/windows-task.js +5 -5
- package/dist/service/windows-task.js.map +1 -1
- package/dist/sharing-admission.d.ts +17 -0
- package/dist/sharing-admission.js +128 -0
- package/dist/sharing-admission.js.map +1 -0
- package/dist/snapshot-delivery-baseline.d.ts +12 -3
- package/dist/snapshot-delivery-baseline.js +41 -42
- package/dist/snapshot-delivery-baseline.js.map +1 -1
- package/dist/source-proof.d.ts +36 -0
- package/dist/source-proof.js +70 -0
- package/dist/source-proof.js.map +1 -0
- package/dist/source-signature.d.ts +56 -0
- package/dist/source-signature.js +56 -0
- package/dist/source-signature.js.map +1 -0
- package/dist/source-witness.d.ts +15 -0
- package/dist/source-witness.js +29 -0
- package/dist/source-witness.js.map +1 -0
- package/dist/sqlite-durability.d.ts +31 -0
- package/dist/sqlite-durability.js +28 -0
- package/dist/sqlite-durability.js.map +1 -0
- package/dist/sqlite.d.ts +8 -2
- package/dist/sqlite.js +27 -4
- package/dist/sqlite.js.map +1 -1
- package/dist/sync-address.d.ts +19 -0
- package/dist/sync-address.js +52 -0
- package/dist/sync-address.js.map +1 -0
- package/dist/sync-setting.d.ts +15 -0
- package/dist/sync-setting.js +13 -0
- package/dist/sync-setting.js.map +1 -1
- package/dist/turns.d.ts +42 -0
- package/dist/turns.js +112 -0
- package/dist/turns.js.map +1 -0
- package/dist/updates/bootstrap.d.ts +53 -7
- package/dist/updates/bootstrap.js +224 -137
- package/dist/updates/bootstrap.js.map +1 -1
- package/dist/updates/controller.d.ts +8 -0
- package/dist/updates/controller.js +27 -3
- package/dist/updates/controller.js.map +1 -1
- package/dist/updates/store.d.ts +3 -0
- package/dist/updates/store.js +12 -0
- package/dist/updates/store.js.map +1 -1
- package/dist/user-ground-host.d.ts +364 -69
- package/dist/user-ground-host.js +5231 -3366
- package/dist/user-ground-host.js.map +1 -1
- package/dist/watching/fsevents.d.ts +52 -1
- package/dist/watching/fsevents.js +60 -25
- package/dist/watching/fsevents.js.map +1 -1
- package/dist/watching/host.d.ts +129 -5
- package/dist/watching/host.js +433 -80
- package/dist/watching/host.js.map +1 -1
- package/dist/watching/index.d.ts +1 -1
- package/dist/wire-binary.d.ts +3 -2
- package/dist/wire-binary.js +10 -8
- package/dist/wire-binary.js.map +1 -1
- package/dist/wire-client.d.ts +3 -4
- package/dist/wire-client.js +18 -44
- package/dist/wire-client.js.map +1 -1
- package/dist/wire-outbox.d.ts +34 -0
- package/dist/wire-outbox.js +127 -0
- package/dist/wire-outbox.js.map +1 -0
- package/dist/workspace-host.d.ts +4 -0
- package/dist/workspace-host.js +12 -1
- package/dist/workspace-host.js.map +1 -1
- package/examinations/fixtures/private-wire-authority.js +133 -10
- package/npm-shrinkwrap.json +43 -56
- package/package.json +26 -13
package/README.md
CHANGED
|
@@ -131,14 +131,16 @@ or terminal. Use `amalgm service status --user EMAIL` to inspect its controller,
|
|
|
131
131
|
runtime phase, recovery attempts and last failure. `service stop` drains it;
|
|
132
132
|
`service start` resumes the registered service.
|
|
133
133
|
|
|
134
|
-
The
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
134
|
+
The runtime is always on: only `service stop` and `service uninstall` end it.
|
|
135
|
+
Every other exit — failed launch, startup timeout, lost IPC health, premature
|
|
136
|
+
exit — restarts it after a delay that doubles from one second and stops growing
|
|
137
|
+
at five minutes, forever. The streak is committed to SQLite before each launch
|
|
138
|
+
and counts from the last failure, so controller replacement, logout/login and
|
|
139
|
+
reboot neither reset it nor repeat time already waited. A ready runtime that
|
|
140
|
+
answers IPC health for 30 seconds resets it. A slow runtime is alive: any late
|
|
141
|
+
answer proves life, and only about two minutes of silence replaces it. Run
|
|
142
|
+
`amalgm service retry --user EMAIL` to restart a failing runtime now instead of
|
|
143
|
+
waiting out its delay. A failed update returns to the last good release.
|
|
142
144
|
Portable mode needs an external foreground owner; it does not install an OS service.
|
|
143
145
|
|
|
144
146
|
Managed npm delivery uses `.github/workflows/publish-package.yml` after the
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The accepted tail: the latest authority-accepted result of every entity
|
|
3
|
+
* delivered in (M, N], read in one SQLite transaction together with the local
|
|
4
|
+
* delivery cursor N and its history floor.
|
|
5
|
+
*
|
|
6
|
+
* The Inbox holds every authority record above the floor through the cursor.
|
|
7
|
+
* A tail may begin only at or above that floor: below it this machine never
|
|
8
|
+
* received the records a snapshot adoption skipped, and an Inbox read there
|
|
9
|
+
* would silently omit accepted results. Such a read fails closed.
|
|
10
|
+
*/
|
|
11
|
+
import type Database from "better-sqlite3";
|
|
12
|
+
import { type CloudEntityRecord } from "@amalgm/live";
|
|
13
|
+
export declare class AcceptedHistoryUnavailableError extends Error {
|
|
14
|
+
readonly after: number;
|
|
15
|
+
readonly floor: number;
|
|
16
|
+
constructor(after: number, floor: number);
|
|
17
|
+
}
|
|
18
|
+
export interface AcceptedTail {
|
|
19
|
+
/** M: the base the tail folds onto. */
|
|
20
|
+
readonly after: number;
|
|
21
|
+
/** N: the local gap-free authority cursor the tail runs through. */
|
|
22
|
+
readonly through: number;
|
|
23
|
+
/** The latest accepted result per entity in (after, through]. */
|
|
24
|
+
readonly results: readonly CloudEntityRecord[];
|
|
25
|
+
}
|
|
26
|
+
export declare function readAcceptedTail(database: Database.Database, authorityId: string, after: number): AcceptedTail;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { decodeAcceptedEntityRecord } from "@amalgm/live";
|
|
2
|
+
export class AcceptedHistoryUnavailableError extends Error {
|
|
3
|
+
after;
|
|
4
|
+
floor;
|
|
5
|
+
constructor(after, floor) {
|
|
6
|
+
super(`accepted history after delivery ${after} is unavailable below local floor ${floor}`);
|
|
7
|
+
this.after = after;
|
|
8
|
+
this.floor = floor;
|
|
9
|
+
this.name = "AcceptedHistoryUnavailableError";
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export function readAcceptedTail(database, authorityId, after) {
|
|
13
|
+
return database.transaction(() => {
|
|
14
|
+
const cursor = database.prepare(`
|
|
15
|
+
SELECT received_through AS through, history_floor AS floor
|
|
16
|
+
FROM authority_delivery_cursors WHERE authority_id = ?
|
|
17
|
+
`).get(authorityId);
|
|
18
|
+
const through = cursor?.through ?? 0;
|
|
19
|
+
const floor = cursor?.floor ?? 0;
|
|
20
|
+
if (through < after) {
|
|
21
|
+
throw new Error("local delivery cursor is behind the active snapshot watermark");
|
|
22
|
+
}
|
|
23
|
+
if (floor > after)
|
|
24
|
+
throw new AcceptedHistoryUnavailableError(after, floor);
|
|
25
|
+
const latest = new Map();
|
|
26
|
+
for (const { recordJson } of database.prepare(`
|
|
27
|
+
SELECT record_json AS recordJson FROM record_inbox
|
|
28
|
+
WHERE authority_id = ? AND delivery_sequence > ? AND delivery_sequence <= ?
|
|
29
|
+
ORDER BY delivery_sequence
|
|
30
|
+
`).iterate(authorityId, after, through)) {
|
|
31
|
+
const accepted = decodeAcceptedEntityRecord(recordJson);
|
|
32
|
+
latest.set(accepted.entityId, accepted.change.result);
|
|
33
|
+
}
|
|
34
|
+
return { after, through, results: [...latest.values()] };
|
|
35
|
+
})();
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=accepted-tail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accepted-tail.js","sourceRoot":"","sources":["../src/accepted-tail.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,0BAA0B,EAA0B,MAAM,cAAc,CAAC;AAElF,MAAM,OAAO,+BAAgC,SAAQ,KAAK;IACnC;IAAwB;IAA7C,YAAqB,KAAa,EAAW,KAAa;QACxD,KAAK,CAAC,mCAAmC,KAAK,qCAAqC,KAAK,EAAE,CAAC,CAAC;QADzE,UAAK,GAAL,KAAK,CAAQ;QAAW,UAAK,GAAL,KAAK,CAAQ;QAExD,IAAI,CAAC,IAAI,GAAG,iCAAiC,CAAC;IAChD,CAAC;CACF;AAWD,MAAM,UAAU,gBAAgB,CAC9B,QAA2B,EAC3B,WAAmB,EACnB,KAAa;IAEb,OAAO,QAAQ,CAAC,WAAW,CAAC,GAAiB,EAAE;QAC7C,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC;;;KAG/B,CAAC,CAAC,GAAG,CAAC,WAAW,CAAmD,CAAC;QACtE,MAAM,OAAO,GAAG,MAAM,EAAE,OAAO,IAAI,CAAC,CAAC;QACrC,MAAM,KAAK,GAAG,MAAM,EAAE,KAAK,IAAI,CAAC,CAAC;QACjC,IAAI,OAAO,GAAG,KAAK,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;QACnF,CAAC;QACD,IAAI,KAAK,GAAG,KAAK;YAAE,MAAM,IAAI,+BAA+B,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC3E,MAAM,MAAM,GAAG,IAAI,GAAG,EAA6B,CAAC;QACpD,KAAK,MAAM,EAAE,UAAU,EAAE,IAAI,QAAQ,CAAC,OAAO,CAAC;;;;KAI7C,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,EAAE,OAAO,CAAqC,EAAE,CAAC;YAC5E,MAAM,QAAQ,GAAG,0BAA0B,CAAC,UAAU,CAAC,CAAC;YACxD,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACxD,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;IAC3D,CAAC,CAAC,EAAE,CAAC;AACP,CAAC"}
|
|
@@ -7,7 +7,21 @@ export interface AgentExecutionContext {
|
|
|
7
7
|
readonly computerId: string;
|
|
8
8
|
readonly stateDir: string;
|
|
9
9
|
readonly amalgmDir?: string;
|
|
10
|
+
readonly workspaces?: WorkspaceScope;
|
|
10
11
|
}
|
|
12
|
+
/** The Workspaces folder: where a run starts when nothing else is chosen. */
|
|
13
|
+
export interface WorkspaceScope {
|
|
14
|
+
readonly root: string;
|
|
15
|
+
/** Every registered folder outside the root, read when a run starts. */
|
|
16
|
+
folders(): readonly string[];
|
|
17
|
+
}
|
|
18
|
+
/** A run in the Workspaces folder also reaches every registered folder. */
|
|
19
|
+
export declare function workspaceCwd(options: AgentExecutionContext, path: string): {
|
|
20
|
+
workspaceId: null;
|
|
21
|
+
materializationRevision: null;
|
|
22
|
+
additionalDirectories?: string[] | undefined;
|
|
23
|
+
path: string;
|
|
24
|
+
};
|
|
11
25
|
export declare function resolveAgentRun(options: AgentExecutionContext, installationId: string, selection?: {
|
|
12
26
|
modelId?: string;
|
|
13
27
|
}): Readonly<{
|
|
@@ -47,9 +61,10 @@ export declare function resolveAgentRun(options: AgentExecutionContext, installa
|
|
|
47
61
|
toolIds: string[];
|
|
48
62
|
};
|
|
49
63
|
cwd: {
|
|
50
|
-
path: string;
|
|
51
64
|
workspaceId: null;
|
|
52
65
|
materializationRevision: null;
|
|
66
|
+
additionalDirectories?: string[] | undefined;
|
|
67
|
+
path: string;
|
|
53
68
|
};
|
|
54
69
|
permissionMode: "ask" | "full_access";
|
|
55
70
|
computerId: string;
|
package/dist/agent-execution.js
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/** A run in the Workspaces folder also reaches every registered folder. */
|
|
2
|
+
export function workspaceCwd(options, path) {
|
|
3
|
+
const additionalDirectories = options.workspaces && path === options.workspaces.root
|
|
4
|
+
? options.workspaces.folders().filter(folder => folder !== path)
|
|
5
|
+
: [];
|
|
6
|
+
return {
|
|
7
|
+
path,
|
|
8
|
+
...(additionalDirectories.length ? { additionalDirectories } : {}),
|
|
9
|
+
workspaceId: null,
|
|
10
|
+
materializationRevision: null,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
1
13
|
export function resolveAgentRun(options, installationId, selection = {}) {
|
|
2
14
|
const record = options.agents.getAgent(installationId);
|
|
3
15
|
if (!record)
|
|
@@ -33,11 +45,7 @@ export function resolveAgentRun(options, installationId, selection = {}) {
|
|
|
33
45
|
toolIds: tools,
|
|
34
46
|
...(definition.toolbox.exposure ? { exposure: definition.toolbox.exposure } : {}),
|
|
35
47
|
},
|
|
36
|
-
cwd:
|
|
37
|
-
path: definition.workspace.cwd || options.amalgmDir || options.stateDir,
|
|
38
|
-
workspaceId: null,
|
|
39
|
-
materializationRevision: null,
|
|
40
|
-
},
|
|
48
|
+
cwd: workspaceCwd(options, definition.workspace.cwd || options.workspaces?.root || options.amalgmDir || options.stateDir),
|
|
41
49
|
permissionMode: definition.metadata["permissionMode"] === "ask" ? "ask" : "full_access",
|
|
42
50
|
computerId: options.computerId,
|
|
43
51
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-execution.js","sourceRoot":"","sources":["../src/agent-execution.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"agent-execution.js","sourceRoot":"","sources":["../src/agent-execution.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface ApplyCleanupBinding {
|
|
2
|
+
readonly path: string;
|
|
3
|
+
/** Exact `device:inode`. */
|
|
4
|
+
readonly physical: string;
|
|
5
|
+
}
|
|
6
|
+
interface CleanupObject extends ApplyCleanupBinding {
|
|
7
|
+
readonly kind: "file" | "link" | "directory";
|
|
8
|
+
readonly value: string | null;
|
|
9
|
+
readonly mode: number;
|
|
10
|
+
readonly signature: string;
|
|
11
|
+
}
|
|
12
|
+
export interface ApplyCleanupDescription {
|
|
13
|
+
readonly contract: "amalgm.apply-cleanup@2";
|
|
14
|
+
readonly root: ApplyCleanupBinding;
|
|
15
|
+
readonly control: string;
|
|
16
|
+
/** Parents precede children. All paths are relative to control. */
|
|
17
|
+
readonly objects: readonly CleanupObject[];
|
|
18
|
+
}
|
|
19
|
+
/** Called only after retained versions and joint namespace effects were proved.
|
|
20
|
+
* Capture uses bounded buffers and never interprets Git or follows symlinks. */
|
|
21
|
+
export declare function describeApplyCleanup(root: ApplyCleanupBinding, control: string): Promise<ApplyCleanupDescription>;
|
|
22
|
+
/** Close the original private read after the logical disposition proof.
|
|
23
|
+
* Later bytes may not be substituted for the versions that proof authorized. */
|
|
24
|
+
export declare function assertApplyCleanupUnchanged(description: ApplyCleanupDescription): void;
|
|
25
|
+
/** Missing authorized objects mean partial progress; changed or unexpected
|
|
26
|
+
* survivors keep this same terminal responsibility visibly unfinished. */
|
|
27
|
+
export declare function finishApplyCleanup(description: ApplyCleanupDescription): Promise<void>;
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/** Finite machine-local cleanup authority, committed with the Apply outcome.
|
|
2
|
+
* It names exact private objects; it never authorizes changing live ground. */
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
import { closeSync, constants, fsyncSync, lstatSync, openSync, readdirSync, readlinkSync, rmdirSync, unlinkSync, } from "node:fs";
|
|
5
|
+
import { dirname, isAbsolute, join } from "node:path";
|
|
6
|
+
import { open } from "node:fs/promises";
|
|
7
|
+
import { physicalKey, sameSource, sourceSignature, sourceUnchanged } from "./source-signature.js";
|
|
8
|
+
function stat(path) {
|
|
9
|
+
try {
|
|
10
|
+
return lstatSync(path, { bigint: true });
|
|
11
|
+
}
|
|
12
|
+
catch (error) {
|
|
13
|
+
if (error.code === "ENOENT")
|
|
14
|
+
return null;
|
|
15
|
+
throw error;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
async function digest(path, expected) {
|
|
19
|
+
const hash = createHash("sha256"), size = Number(expected.size);
|
|
20
|
+
const same = (current) => current !== null && current.isFile() && sameSource(current, expected);
|
|
21
|
+
const file = await open(path, constants.O_RDONLY | constants.O_NONBLOCK | (constants.O_NOFOLLOW ?? 0));
|
|
22
|
+
try {
|
|
23
|
+
if (!same(await file.stat({ bigint: true })))
|
|
24
|
+
throw new Error("Apply cleanup file changed before its read");
|
|
25
|
+
const buffer = Buffer.allocUnsafe(Math.min(256 * 1024, size));
|
|
26
|
+
for (let offset = 0; offset < size;) {
|
|
27
|
+
const { bytesRead } = await file.read(buffer, 0, Math.min(buffer.length, size - offset), offset);
|
|
28
|
+
if (!bytesRead)
|
|
29
|
+
throw new Error("Apply cleanup file changed length during its read");
|
|
30
|
+
hash.update(buffer.subarray(0, bytesRead));
|
|
31
|
+
offset += bytesRead;
|
|
32
|
+
}
|
|
33
|
+
if (!same(await file.stat({ bigint: true })) || !same(stat(path)))
|
|
34
|
+
throw new Error("Apply cleanup file changed during its read");
|
|
35
|
+
return hash.digest("hex");
|
|
36
|
+
}
|
|
37
|
+
finally {
|
|
38
|
+
await file.close();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function kind(stats) {
|
|
42
|
+
if (stats.isSymbolicLink())
|
|
43
|
+
return "link";
|
|
44
|
+
if (stats.isFile())
|
|
45
|
+
return "file";
|
|
46
|
+
if (stats.isDirectory())
|
|
47
|
+
return "directory";
|
|
48
|
+
throw new Error("Apply cleanup encountered an unsupported private object");
|
|
49
|
+
}
|
|
50
|
+
async function value(path, type, before) {
|
|
51
|
+
return type === "file" ? digest(path, before) : type === "link" ? readlinkSync(path) : null;
|
|
52
|
+
}
|
|
53
|
+
function sameIdentity(stats, expected) {
|
|
54
|
+
return stats !== null && physicalKey(stats) === expected.physical;
|
|
55
|
+
}
|
|
56
|
+
async function matches(path, expected) {
|
|
57
|
+
const before = stat(path);
|
|
58
|
+
if (!sameIdentity(before, expected) || kind(before) !== expected.kind || Number(before.mode) !== expected.mode)
|
|
59
|
+
return false;
|
|
60
|
+
const observed = await value(path, expected.kind, before), after = stat(path);
|
|
61
|
+
return sameIdentity(after, expected) && after.mode === before.mode && observed === expected.value
|
|
62
|
+
&& (expected.kind === "directory" || sameSource(before, after));
|
|
63
|
+
}
|
|
64
|
+
/** Called only after retained versions and joint namespace effects were proved.
|
|
65
|
+
* Capture uses bounded buffers and never interprets Git or follows symlinks. */
|
|
66
|
+
export async function describeApplyCleanup(root, control) {
|
|
67
|
+
if (!sameIdentity(stat(root.path), root))
|
|
68
|
+
throw new Error("Apply recovery root is missing or replaced");
|
|
69
|
+
const objects = [];
|
|
70
|
+
const visit = async (relativePath) => {
|
|
71
|
+
const path = join(control, relativePath), before = stat(path);
|
|
72
|
+
if (!before)
|
|
73
|
+
throw new Error("Apply private cleanup changed during its proof");
|
|
74
|
+
const type = kind(before), expected = { path: relativePath, physical: physicalKey(before),
|
|
75
|
+
kind: type, value: await value(path, type, before), mode: Number(before.mode), signature: sourceSignature(before) };
|
|
76
|
+
const after = stat(path);
|
|
77
|
+
if (!after || !sourceUnchanged(expected.signature, after)) {
|
|
78
|
+
throw new Error("Apply private cleanup changed during its proof");
|
|
79
|
+
}
|
|
80
|
+
objects.push(expected);
|
|
81
|
+
if (type === "directory")
|
|
82
|
+
for (const name of readdirSync(path).sort())
|
|
83
|
+
await visit(relativePath ? `${relativePath}/${name}` : name);
|
|
84
|
+
};
|
|
85
|
+
if (stat(control))
|
|
86
|
+
await visit("");
|
|
87
|
+
return { contract: "amalgm.apply-cleanup@2", root, control, objects };
|
|
88
|
+
}
|
|
89
|
+
/** Close the original private read after the logical disposition proof.
|
|
90
|
+
* Later bytes may not be substituted for the versions that proof authorized. */
|
|
91
|
+
export function assertApplyCleanupUnchanged(description) {
|
|
92
|
+
if (!sameIdentity(stat(description.root.path), description.root))
|
|
93
|
+
throw new Error("Apply cleanup root changed before commitment");
|
|
94
|
+
if (description.objects.length === 0 && stat(description.control))
|
|
95
|
+
throw new Error("Apply control appeared during retirement proof");
|
|
96
|
+
for (const object of description.objects) {
|
|
97
|
+
const current = stat(join(description.control, object.path));
|
|
98
|
+
if (!current || !sourceUnchanged(object.signature, current)) {
|
|
99
|
+
throw new Error("Apply cleanup changed during retirement proof");
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/** Missing authorized objects mean partial progress; changed or unexpected
|
|
104
|
+
* survivors keep this same terminal responsibility visibly unfinished. */
|
|
105
|
+
export async function finishApplyCleanup(description) {
|
|
106
|
+
if (description.contract !== "amalgm.apply-cleanup@2" || !isAbsolute(description.control)
|
|
107
|
+
|| !isAbsolute(description.root.path))
|
|
108
|
+
throw new Error("Invalid Apply cleanup description");
|
|
109
|
+
if (!sameIdentity(stat(description.root.path), description.root))
|
|
110
|
+
throw new Error("Apply cleanup root is missing or replaced");
|
|
111
|
+
const expected = new Map(description.objects.map(object => [object.path, object]));
|
|
112
|
+
if (expected.size !== description.objects.length || description.objects.some(object => isAbsolute(object.path)
|
|
113
|
+
|| object.path.split("/").some(part => part === "." || part === ".."))) {
|
|
114
|
+
throw new Error("Apply cleanup has an invalid private address");
|
|
115
|
+
}
|
|
116
|
+
const flushed = new Set();
|
|
117
|
+
const visit = async (relativePath) => {
|
|
118
|
+
const path = join(description.control, relativePath), observed = stat(path);
|
|
119
|
+
if (!observed)
|
|
120
|
+
return;
|
|
121
|
+
const object = expected.get(relativePath);
|
|
122
|
+
if (!object || !await matches(path, object))
|
|
123
|
+
throw new Error("Apply cleanup retains an unexpected or changed private object");
|
|
124
|
+
if (object.kind === "directory") {
|
|
125
|
+
for (const name of readdirSync(path))
|
|
126
|
+
await visit(relativePath ? `${relativePath}/${name}` : name);
|
|
127
|
+
if (!sameIdentity(stat(path), object))
|
|
128
|
+
throw new Error("Apply cleanup directory was replaced");
|
|
129
|
+
rmdirSync(path);
|
|
130
|
+
}
|
|
131
|
+
else
|
|
132
|
+
unlinkSync(path);
|
|
133
|
+
flushed.add(dirname(path));
|
|
134
|
+
};
|
|
135
|
+
await visit("");
|
|
136
|
+
if (stat(description.control))
|
|
137
|
+
throw new Error("Apply cleanup left an unexplained control tree");
|
|
138
|
+
// Flush the first surviving parent even after a prior process removed the
|
|
139
|
+
// entire control tree but stopped before the SQL acknowledgment.
|
|
140
|
+
flushed.add(dirname(description.control));
|
|
141
|
+
const owners = new Set();
|
|
142
|
+
for (let directory of flushed) {
|
|
143
|
+
while (!stat(directory)) {
|
|
144
|
+
const parent = dirname(directory);
|
|
145
|
+
if (parent === directory)
|
|
146
|
+
throw new Error("Apply cleanup has no surviving deletion owner");
|
|
147
|
+
directory = parent;
|
|
148
|
+
}
|
|
149
|
+
const physical = stat(directory);
|
|
150
|
+
if (!physical?.isDirectory() || physical.isSymbolicLink()) {
|
|
151
|
+
throw new Error("Apply cleanup deletion owner is not a physical directory");
|
|
152
|
+
}
|
|
153
|
+
owners.add(directory);
|
|
154
|
+
}
|
|
155
|
+
if (process.platform !== "win32")
|
|
156
|
+
for (const directory of owners) {
|
|
157
|
+
const fd = openSync(directory, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0));
|
|
158
|
+
try {
|
|
159
|
+
fsyncSync(fd);
|
|
160
|
+
}
|
|
161
|
+
finally {
|
|
162
|
+
closeSync(fd);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=apply-cleanup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply-cleanup.js","sourceRoot":"","sources":["../src/apply-cleanup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type CloudEntityRecord, type EntityApplyIntent, type RepoIdentityEntry } from "@amalgm/live";
|
|
2
|
+
import type { ApplyCleanupBinding } from "./apply-cleanup.js";
|
|
3
|
+
export interface ApplyPreimage {
|
|
4
|
+
readonly path: string;
|
|
5
|
+
readonly rows: readonly {
|
|
6
|
+
readonly path: string;
|
|
7
|
+
readonly record: CloudEntityRecord;
|
|
8
|
+
/** Exact `device:inode` of the root and every container. */
|
|
9
|
+
readonly physical: string | null;
|
|
10
|
+
}[];
|
|
11
|
+
}
|
|
12
|
+
export interface ApplyRecovery {
|
|
13
|
+
readonly contract: "amalgm.apply-recovery@6";
|
|
14
|
+
readonly intent: EntityApplyIntent;
|
|
15
|
+
readonly target: CloudEntityRecord;
|
|
16
|
+
readonly targetPath: string;
|
|
17
|
+
readonly binding: ApplyCleanupBinding;
|
|
18
|
+
readonly source: ApplyPreimage | null;
|
|
19
|
+
readonly moves: readonly {
|
|
20
|
+
readonly uuid: string;
|
|
21
|
+
readonly source: ApplyPreimage;
|
|
22
|
+
readonly destination: string;
|
|
23
|
+
}[];
|
|
24
|
+
readonly relocated: readonly {
|
|
25
|
+
readonly uuid: string;
|
|
26
|
+
readonly source: ApplyPreimage;
|
|
27
|
+
}[];
|
|
28
|
+
/** Source preimage paths this intent keeps in place: local ground policy
|
|
29
|
+
* excludes and sharing never held, frozen before any effect. Verify
|
|
30
|
+
* accounts for exactly these extras. */
|
|
31
|
+
readonly remainder: readonly string[];
|
|
32
|
+
}
|
|
33
|
+
/** The frozen remainder as identity entries relative to the source root. */
|
|
34
|
+
export declare function applyRecoveryRemainder(recovery: ApplyRecovery): RepoIdentityEntry[];
|
|
35
|
+
export declare function applyPreimageRoot(preimage: ApplyPreimage): {
|
|
36
|
+
physical: string;
|
|
37
|
+
path: string;
|
|
38
|
+
record: CloudEntityRecord;
|
|
39
|
+
};
|
|
40
|
+
/** Each receipt lives in its binding's reserved control tree, so the
|
|
41
|
+
* binding it serves is known before the receipt can be read. */
|
|
42
|
+
export declare const applyControlDirectory: (root: string, intent: EntityApplyIntent) => string;
|
|
43
|
+
/** The binding root whose control tree holds `control`. */
|
|
44
|
+
export declare const applyControlRoot: (control: string) => string;
|
|
45
|
+
export declare function readApplyRecovery(control: string, intent: EntityApplyIntent): ApplyRecovery | null;
|
|
46
|
+
/** The caller flushes this exact file and control directory before any effect. */
|
|
47
|
+
export declare function writeApplyRecovery(control: string, value: ApplyRecovery): void;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/** Immutable preimages for one existing Apply intent, beneath its control tree.
|
|
2
|
+
* These are recovery evidence, never a second entity inventory or shared state. */
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { dirname, isAbsolute, join } from "node:path";
|
|
5
|
+
import { assertApplyIntent, assertRecord, } from "@amalgm/live";
|
|
6
|
+
import { atomicJson } from "./filesystem.js";
|
|
7
|
+
/** The frozen remainder as identity entries relative to the source root. */
|
|
8
|
+
export function applyRecoveryRemainder(recovery) {
|
|
9
|
+
const kept = new Set(recovery.remainder);
|
|
10
|
+
return (recovery.source?.rows ?? []).filter(row => kept.has(row.path)).map(row => ({
|
|
11
|
+
path: row.path, uuid: row.record.uuid, type: row.record.type, payloadVersion: row.record.payloadVersion,
|
|
12
|
+
}));
|
|
13
|
+
}
|
|
14
|
+
export function applyPreimageRoot(preimage) {
|
|
15
|
+
const root = preimage.rows.find(row => row.path === "");
|
|
16
|
+
if (!root?.physical)
|
|
17
|
+
throw new Error("Apply preimage lacks its original root association");
|
|
18
|
+
return { ...root, physical: root.physical };
|
|
19
|
+
}
|
|
20
|
+
const physicalKeyValid = (key) => typeof key === "string" && /^\d+:\d+$/.test(key);
|
|
21
|
+
function validatePreimage(value) {
|
|
22
|
+
if (!value || !isAbsolute(value.path) || !Array.isArray(value.rows) || value.rows.length === 0) {
|
|
23
|
+
throw new Error("Apply recovery has no complete preimage");
|
|
24
|
+
}
|
|
25
|
+
const paths = new Set();
|
|
26
|
+
for (const row of value.rows) {
|
|
27
|
+
if (typeof row.path !== "string" || row.path.startsWith("/")
|
|
28
|
+
|| row.path.split("/").some((part) => part === "." || part === "..") || paths.has(row.path)) {
|
|
29
|
+
throw new Error("Apply recovery has an invalid preimage address");
|
|
30
|
+
}
|
|
31
|
+
assertRecord(row.record);
|
|
32
|
+
if (row.record.status !== "active")
|
|
33
|
+
throw new Error("Apply recovery preimage is not active");
|
|
34
|
+
const associated = row.path === "" || ["workspace", "folder", "repo.git"].includes(row.record.type);
|
|
35
|
+
if (associated ? !physicalKeyValid(row.physical) : row.physical !== null) {
|
|
36
|
+
throw new Error("Apply recovery preimage lacks its physical association");
|
|
37
|
+
}
|
|
38
|
+
paths.add(row.path);
|
|
39
|
+
}
|
|
40
|
+
if (!paths.has(""))
|
|
41
|
+
throw new Error("Apply recovery lacks its source identity");
|
|
42
|
+
}
|
|
43
|
+
/** Each receipt lives in its binding's reserved control tree, so the
|
|
44
|
+
* binding it serves is known before the receipt can be read. */
|
|
45
|
+
export const applyControlDirectory = (root, intent) => join(root, ".amalgm", "apply", `${intent.entityId}-${intent.throughSequence}`);
|
|
46
|
+
/** The binding root whose control tree holds `control`. */
|
|
47
|
+
export const applyControlRoot = (control) => dirname(dirname(dirname(control)));
|
|
48
|
+
export function readApplyRecovery(control, intent) {
|
|
49
|
+
let encoded;
|
|
50
|
+
try {
|
|
51
|
+
encoded = readFileSync(join(control, "preimage.json"), "utf8");
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
if (error.code === "ENOENT")
|
|
55
|
+
return null;
|
|
56
|
+
throw error;
|
|
57
|
+
}
|
|
58
|
+
const value = JSON.parse(encoded);
|
|
59
|
+
if (value.contract !== "amalgm.apply-recovery@6")
|
|
60
|
+
throw new Error("Unsupported Apply recovery contract");
|
|
61
|
+
assertApplyIntent(value.intent);
|
|
62
|
+
for (const field of ["attemptId", "authorityId", "entityId", "fromSequence", "throughSequence", "targetState", "targetMutationId", "targetType", "createdAt"]) {
|
|
63
|
+
if (value.intent[field] !== intent[field])
|
|
64
|
+
throw new Error("Apply recovery belongs to another intent");
|
|
65
|
+
}
|
|
66
|
+
assertRecord(value.target);
|
|
67
|
+
if (value.target.uuid !== intent.entityId || value.target.version !== intent.targetState
|
|
68
|
+
|| !isAbsolute(value.targetPath) || !Array.isArray(value.relocated) || !Array.isArray(value.moves)
|
|
69
|
+
|| value.target.type !== intent.targetType
|
|
70
|
+
|| !value.binding || !isAbsolute(value.binding.path)
|
|
71
|
+
|| !physicalKeyValid(value.binding.physical)) {
|
|
72
|
+
throw new Error("Apply recovery has a different accepted target");
|
|
73
|
+
}
|
|
74
|
+
if (value.source !== null)
|
|
75
|
+
validatePreimage(value.source);
|
|
76
|
+
const sourcePaths = new Set(value.source?.rows.map(row => row.path) ?? []);
|
|
77
|
+
if (!Array.isArray(value.remainder) || new Set(value.remainder).size !== value.remainder.length
|
|
78
|
+
|| value.remainder.some(path => path === "" || !sourcePaths.has(path))) {
|
|
79
|
+
throw new Error("Apply recovery remainder is not part of its source preimage");
|
|
80
|
+
}
|
|
81
|
+
for (const move of value.moves) {
|
|
82
|
+
validatePreimage(move.source);
|
|
83
|
+
if (!isAbsolute(move.destination) || applyPreimageRoot(move.source).record.uuid !== move.uuid)
|
|
84
|
+
throw new Error("Invalid Apply recovery move");
|
|
85
|
+
}
|
|
86
|
+
for (const relocation of value.relocated) {
|
|
87
|
+
validatePreimage(relocation.source);
|
|
88
|
+
if (relocation.source.rows.find((row) => row.path === "")?.record.uuid !== relocation.uuid) {
|
|
89
|
+
throw new Error("Apply recovery relocation has a different identity");
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return value;
|
|
93
|
+
}
|
|
94
|
+
/** The caller flushes this exact file and control directory before any effect. */
|
|
95
|
+
export function writeApplyRecovery(control, value) {
|
|
96
|
+
atomicJson(join(control, "preimage.json"), value);
|
|
97
|
+
readApplyRecovery(control, value.intent);
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=apply-recovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply-recovery.js","sourceRoot":"","sources":["../src/apply-recovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/** The Apply tables' one reading of intents, terminal dispositions, history
|
|
2
|
+
* resolution and newer local work. The store reads these answers on the main
|
|
3
|
+
* thread; its saves (apply-saves.ts) read the same answers inside their
|
|
4
|
+
* savepoint on the saver thread. */
|
|
5
|
+
import { type AcceptedEntityRecord, type EntityApplyIntent, type EntityApplyRetirement } from "@amalgm/live";
|
|
6
|
+
import type Database from "better-sqlite3";
|
|
7
|
+
import type { ApplyCleanupDescription } from "./apply-cleanup.js";
|
|
8
|
+
export type CleanupDisposition = ApplyCleanupDescription | {
|
|
9
|
+
readonly contract: "amalgm.apply-no-ground@1";
|
|
10
|
+
};
|
|
11
|
+
export interface ApplyStateRow {
|
|
12
|
+
readonly resolvedThrough: number;
|
|
13
|
+
readonly materializedSequence: number | null;
|
|
14
|
+
readonly materializedRecordJson: string | null;
|
|
15
|
+
}
|
|
16
|
+
export interface ApplyRetirementRow {
|
|
17
|
+
readonly retirement: EntityApplyRetirement;
|
|
18
|
+
readonly cleanup: CleanupDisposition;
|
|
19
|
+
}
|
|
20
|
+
export declare const sameIntent: (left: EntityApplyIntent, right: EntityApplyIntent) => boolean;
|
|
21
|
+
export declare function readIntent(database: Database.Database, entityId: string, authorityId?: string): EntityApplyIntent | null;
|
|
22
|
+
export declare function recoveryLocation(database: Database.Database, intent: EntityApplyIntent): string | null;
|
|
23
|
+
export declare function readRetirement(database: Database.Database, intent: EntityApplyIntent): ApplyRetirementRow | null;
|
|
24
|
+
export declare function requireIntent(database: Database.Database, intent: EntityApplyIntent): EntityApplyIntent;
|
|
25
|
+
/** The terminal disposition a cleanup acknowledgement or description names. */
|
|
26
|
+
export declare function ownedCleanup(database: Database.Database, retirement: EntityApplyRetirement): CleanupDisposition;
|
|
27
|
+
export declare const applyState: (database: Database.Database, authorityId: string, entityId: string) => ApplyStateRow | undefined;
|
|
28
|
+
/** Where one entity's Apply history stands. Without a state row, an installed
|
|
29
|
+
* snapshot already resolved every record it contained, so the entity's first
|
|
30
|
+
* Inbox record after that watermark follows its earlier dense sequences.
|
|
31
|
+
* Selection and terminal commit both read this one answer. */
|
|
32
|
+
export declare function applyResolution(database: Database.Database, authorityId: string, entityId: string): {
|
|
33
|
+
readonly state: ApplyStateRow | undefined;
|
|
34
|
+
readonly resolvedThrough: number;
|
|
35
|
+
readonly rows: ReadonlyArray<{
|
|
36
|
+
readonly recordJson: string;
|
|
37
|
+
readonly deliverySequence: number;
|
|
38
|
+
}>;
|
|
39
|
+
};
|
|
40
|
+
/** Live's local-work gate over this entity's Outbox rows: one the authority
|
|
41
|
+
* has not sequenced yet (a pending row carries no sequence), or one it
|
|
42
|
+
* sequenced after the target. Each is its own seek into the entity's channel
|
|
43
|
+
* index; one disjunction would walk the entity's retained receipts. */
|
|
44
|
+
export declare function hasLocalWorkAfter(database: Database.Database, authorityId: string, entityId: string, targetSequence: number): boolean;
|
|
45
|
+
export interface OwnPublication {
|
|
46
|
+
readonly authorityId: string;
|
|
47
|
+
readonly entityId: string;
|
|
48
|
+
/** Where the selecting Apply work found this entity's history resolved. */
|
|
49
|
+
readonly resolvedThrough: number;
|
|
50
|
+
readonly globalSequence: number;
|
|
51
|
+
readonly mutationId: string;
|
|
52
|
+
}
|
|
53
|
+
/** This computer's own exact publication, when it alone can resolve the
|
|
54
|
+
* entity's open history: no intent, Inbox still starts where the work saw it
|
|
55
|
+
* and ends at this record, the retained Outbox receipt is its exact own
|
|
56
|
+
* acceptance, no local work follows it, and the sharing basis holds its
|
|
57
|
+
* result. Null otherwise; then the ordinary Apply journey decides. */
|
|
58
|
+
export declare function ownPublication(database: Database.Database, input: OwnPublication): {
|
|
59
|
+
readonly after: number;
|
|
60
|
+
readonly prior: ApplyStateRow | undefined;
|
|
61
|
+
readonly accepted: AcceptedEntityRecord;
|
|
62
|
+
} | null;
|
|
63
|
+
/** What an installed snapshot watermark resolves: each entity's retained
|
|
64
|
+
* history at or below it, and each intent whose target it already holds. */
|
|
65
|
+
export declare function snapshotHistory(database: Database.Database): {
|
|
66
|
+
readonly rows: ReadonlyArray<{
|
|
67
|
+
readonly authorityId: string;
|
|
68
|
+
readonly entityId: string;
|
|
69
|
+
readonly resolvedThrough: number;
|
|
70
|
+
}>;
|
|
71
|
+
readonly intents: readonly EntityApplyIntent[];
|
|
72
|
+
};
|