@mysten-incubation/devstack 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -3
- package/dashboard-ui/assets/grpc-a4usE3Nk.js +3 -0
- package/dashboard-ui/assets/index-B82Bh84P.css +1 -0
- package/dashboard-ui/assets/index-CRYJ4pru.js +1277 -0
- package/dashboard-ui/index.html +2 -2
- package/dist/api/define-capabilities.d.mts +1 -20
- package/dist/api/define-capabilities.mjs +15 -22
- package/dist/api/define-capabilities.mjs.map +1 -1
- package/dist/api/define-devstack-with.d.mts +7 -1
- package/dist/api/define-devstack-with.mjs.map +1 -1
- package/dist/api/define-devstack.mjs.map +1 -1
- package/dist/api/define-plugin.d.mts +2 -1
- package/dist/api/inference-network.d.mts +31 -17
- package/dist/api/inference-network.mjs +40 -43
- package/dist/api/inference-network.mjs.map +1 -1
- package/dist/api/load-config.mjs +88 -0
- package/dist/api/load-config.mjs.map +1 -0
- package/dist/api/mode-narrowed-factory.d.mts +1 -1
- package/dist/api/mode-narrowed-factory.mjs.map +1 -1
- package/dist/api/run-stack-internal.mjs +202 -0
- package/dist/api/run-stack-internal.mjs.map +1 -0
- package/dist/api/run-stack.d.mts +82 -31
- package/dist/api/run-stack.mjs +22 -141
- package/dist/api/run-stack.mjs.map +1 -1
- package/dist/build-integrations/dapp-kit/index.d.mts +61 -0
- package/dist/build-integrations/dapp-kit/index.mjs +58 -0
- package/dist/build-integrations/dapp-kit/index.mjs.map +1 -0
- package/dist/build-integrations/playwright/config.d.mts +1 -30
- package/dist/build-integrations/playwright/config.mjs +1 -27
- package/dist/build-integrations/playwright/config.mjs.map +1 -1
- package/dist/build-integrations/playwright/errors.d.mts +4 -7
- package/dist/build-integrations/playwright/errors.mjs.map +1 -1
- package/dist/build-integrations/playwright/global-setup.d.mts +42 -71
- package/dist/build-integrations/playwright/global-setup.mjs +142 -218
- package/dist/build-integrations/playwright/global-setup.mjs.map +1 -1
- package/dist/build-integrations/playwright/index.d.mts +2 -2
- package/dist/build-integrations/playwright/index.mjs +2 -2
- package/dist/build-integrations/playwright/stack-context.d.mts +3 -1
- package/dist/build-integrations/playwright/stack-context.mjs +4 -2
- package/dist/build-integrations/playwright/stack-context.mjs.map +1 -1
- package/dist/build-integrations/playwright/wallet-context.mjs +44 -19
- package/dist/build-integrations/playwright/wallet-context.mjs.map +1 -1
- package/dist/build-integrations/runtime/cold-start-url.mjs.map +1 -1
- package/dist/build-integrations/runtime/conventional-routes.mjs.map +1 -1
- package/dist/build-integrations/runtime/dapp-kit-slot.mjs.map +1 -1
- package/dist/build-integrations/runtime/discover.d.mts +6 -4
- package/dist/build-integrations/runtime/discover.mjs +15 -4
- package/dist/build-integrations/runtime/discover.mjs.map +1 -1
- package/dist/build-integrations/runtime/endpoint-registry.mjs.map +1 -1
- package/dist/build-integrations/runtime/errors.mjs.map +1 -1
- package/dist/build-integrations/runtime/read-stack-context.mjs +3 -3
- package/dist/build-integrations/runtime/read-stack-context.mjs.map +1 -1
- package/dist/build-integrations/runtime/resolve-discovery-env.d.mts +23 -7
- package/dist/build-integrations/runtime/resolve-discovery-env.mjs +25 -12
- package/dist/build-integrations/runtime/resolve-discovery-env.mjs.map +1 -1
- package/dist/build-integrations/runtime/stack-context.d.mts +2 -2
- package/dist/build-integrations/vite/index.d.mts +84 -19
- package/dist/build-integrations/vite/index.mjs +203 -28
- package/dist/build-integrations/vite/index.mjs.map +1 -1
- package/dist/build-integrations/vitest/config.d.mts +20 -2
- package/dist/build-integrations/vitest/config.mjs +16 -4
- package/dist/build-integrations/vitest/config.mjs.map +1 -1
- package/dist/build-integrations/vitest/env.d.mts +18 -10
- package/dist/build-integrations/vitest/env.mjs +11 -10
- package/dist/build-integrations/vitest/env.mjs.map +1 -1
- package/dist/build-integrations/vitest/errors.d.mts +7 -11
- package/dist/build-integrations/vitest/errors.mjs +3 -4
- package/dist/build-integrations/vitest/errors.mjs.map +1 -1
- package/dist/build-integrations/vitest/global-setup.d.mts +35 -0
- package/dist/build-integrations/vitest/global-setup.mjs +156 -0
- package/dist/build-integrations/vitest/global-setup.mjs.map +1 -0
- package/dist/build-integrations/vitest/index.d.mts +3 -2
- package/dist/build-integrations/vitest/index.mjs +3 -2
- package/dist/build-integrations/vitest/setup.mjs +2 -2
- package/dist/build-integrations/vitest/setup.mjs.map +1 -1
- package/dist/build-integrations/vitest/stack-context.d.mts +5 -3
- package/dist/build-integrations/vitest/stack-context.mjs +3 -2
- package/dist/build-integrations/vitest/stack-context.mjs.map +1 -1
- package/dist/cli/bail.mjs.map +1 -1
- package/dist/cli/doctor-probes.mjs +1 -3
- package/dist/cli/doctor-probes.mjs.map +1 -1
- package/dist/cli/main.d.mts +23 -1
- package/dist/cli/main.mjs +63 -8
- package/dist/cli/main.mjs.map +1 -1
- package/dist/cli/prune-direct.mjs.map +1 -1
- package/dist/cli/snapshot-reader.mjs.map +1 -1
- package/dist/cli/up-lifecycle.mjs.map +1 -1
- package/dist/cli/wirings/apply.mjs +28 -21
- package/dist/cli/wirings/apply.mjs.map +1 -1
- package/dist/cli/wirings/codegen.mjs +108 -0
- package/dist/cli/wirings/codegen.mjs.map +1 -0
- package/dist/cli/wirings/config-loader.mjs +12 -62
- package/dist/cli/wirings/config-loader.mjs.map +1 -1
- package/dist/cli/wirings/dump-ids.mjs +86 -0
- package/dist/cli/wirings/dump-ids.mjs.map +1 -0
- package/dist/cli/wirings/engine-command.mjs +1 -1
- package/dist/cli/wirings/engine-command.mjs.map +1 -1
- package/dist/cli/wirings/identity.mjs +2 -2
- package/dist/cli/wirings/identity.mjs.map +1 -1
- package/dist/cli/wirings/provide-file-system.mjs.map +1 -1
- package/dist/cli/wirings/read-devstack-version.mjs +17 -0
- package/dist/cli/wirings/read-devstack-version.mjs.map +1 -0
- package/dist/cli/wirings/snapshot.mjs +27 -34
- package/dist/cli/wirings/snapshot.mjs.map +1 -1
- package/dist/cli/wirings/up-ipc.mjs +147 -0
- package/dist/cli/wirings/up-ipc.mjs.map +1 -0
- package/dist/cli/wirings/up.mjs +218 -198
- package/dist/cli/wirings/up.mjs.map +1 -1
- package/dist/cli/wirings/wipe.mjs +1 -1
- package/dist/cli/wirings/wipe.mjs.map +1 -1
- package/dist/contracts/chain-probe.d.mts +1 -1
- package/dist/contracts/chain-probe.mjs +1 -1
- package/dist/contracts/chain-probe.mjs.map +1 -1
- package/dist/contracts/codegenable.d.mts +60 -6
- package/dist/contracts/codegenable.mjs +28 -0
- package/dist/contracts/codegenable.mjs.map +1 -0
- package/dist/contracts/config-bindings.mjs +162 -0
- package/dist/contracts/config-bindings.mjs.map +1 -0
- package/dist/contracts/container-runtime.d.mts +23 -17
- package/dist/contracts/plugin-expander.mjs.map +1 -1
- package/dist/contracts/snapshotable.d.mts +5 -7
- package/dist/contracts/wallet-protocol.d.mts +2 -5
- package/dist/contracts/wallet-protocol.mjs +2 -5
- package/dist/contracts/wallet-protocol.mjs.map +1 -1
- package/dist/index.d.mts +21 -26
- package/dist/index.mjs +8 -9
- package/dist/orchestrators/boot.d.mts +28 -0
- package/dist/orchestrators/boot.mjs +440 -0
- package/dist/orchestrators/boot.mjs.map +1 -0
- package/dist/orchestrators/codegen/bindings.d.mts +13 -1
- package/dist/orchestrators/codegen/bindings.mjs +23 -9
- package/dist/orchestrators/codegen/bindings.mjs.map +1 -1
- package/dist/orchestrators/codegen/config-runtime.mjs +208 -0
- package/dist/orchestrators/codegen/config-runtime.mjs.map +1 -0
- package/dist/orchestrators/codegen/emit.mjs +1 -1
- package/dist/orchestrators/codegen/emit.mjs.map +1 -1
- package/dist/orchestrators/codegen/errors.mjs +21 -1
- package/dist/orchestrators/codegen/errors.mjs.map +1 -1
- package/dist/orchestrators/codegen/format.mjs +2 -0
- package/dist/orchestrators/codegen/format.mjs.map +1 -1
- package/dist/orchestrators/codegen/gitignore.mjs +30 -11
- package/dist/orchestrators/codegen/gitignore.mjs.map +1 -1
- package/dist/orchestrators/codegen/id-config.mjs +107 -0
- package/dist/orchestrators/codegen/id-config.mjs.map +1 -0
- package/dist/orchestrators/codegen/output-location.mjs +23 -32
- package/dist/orchestrators/codegen/output-location.mjs.map +1 -1
- package/dist/orchestrators/codegen/paths.mjs +8 -1
- package/dist/orchestrators/codegen/paths.mjs.map +1 -1
- package/dist/orchestrators/codegen/permissions.mjs.map +1 -1
- package/dist/orchestrators/codegen/service.mjs +286 -58
- package/dist/orchestrators/codegen/service.mjs.map +1 -1
- package/dist/orchestrators/layers.mjs +31 -0
- package/dist/orchestrators/layers.mjs.map +1 -0
- package/dist/orchestrators/lifecycle-prune/errors.mjs.map +1 -1
- package/dist/orchestrators/lifecycle-prune/index.mjs +8 -10
- package/dist/orchestrators/lifecycle-prune/index.mjs.map +1 -1
- package/dist/orchestrators/network-options.d.mts +52 -0
- package/dist/orchestrators/network-options.mjs +43 -0
- package/dist/orchestrators/network-options.mjs.map +1 -0
- package/dist/orchestrators/router/cleanup.mjs.map +1 -1
- package/dist/orchestrators/router/cors.mjs.map +1 -1
- package/dist/orchestrators/router/entrypoints.mjs.map +1 -1
- package/dist/orchestrators/router/errors.mjs.map +1 -1
- package/dist/orchestrators/router/file-provider.mjs.map +1 -1
- package/dist/orchestrators/router/hostname.mjs.map +1 -1
- package/dist/orchestrators/router/profile.mjs +1 -1
- package/dist/orchestrators/router/profile.mjs.map +1 -1
- package/dist/orchestrators/router/service.d.mts +2 -2
- package/dist/orchestrators/router/service.mjs +12 -27
- package/dist/orchestrators/router/service.mjs.map +1 -1
- package/dist/orchestrators/router/traefik-container.mjs +1 -1
- package/dist/orchestrators/router/traefik-container.mjs.map +1 -1
- package/dist/orchestrators/snapshot/capture.mjs +171 -195
- package/dist/orchestrators/snapshot/capture.mjs.map +1 -1
- package/dist/orchestrators/snapshot/descriptor.d.mts +1 -1
- package/dist/orchestrators/snapshot/descriptor.mjs +53 -11
- package/dist/orchestrators/snapshot/descriptor.mjs.map +1 -1
- package/dist/orchestrators/snapshot/identity-guard.mjs +3 -5
- package/dist/orchestrators/snapshot/identity-guard.mjs.map +1 -1
- package/dist/orchestrators/snapshot/image-bundle-tags.mjs +32 -101
- package/dist/orchestrators/snapshot/image-bundle-tags.mjs.map +1 -1
- package/dist/orchestrators/snapshot/index.mjs +1 -4
- package/dist/orchestrators/snapshot/integrity.mjs.map +1 -1
- package/dist/orchestrators/snapshot/interrupted-restore.mjs +116 -0
- package/dist/orchestrators/snapshot/interrupted-restore.mjs.map +1 -0
- package/dist/orchestrators/snapshot/phase-error.mjs.map +1 -1
- package/dist/orchestrators/snapshot/prune.mjs +40 -31
- package/dist/orchestrators/snapshot/prune.mjs.map +1 -1
- package/dist/orchestrators/snapshot/restore.mjs +221 -196
- package/dist/orchestrators/snapshot/restore.mjs.map +1 -1
- package/dist/orchestrators/snapshot/service.mjs +72 -62
- package/dist/orchestrators/snapshot/service.mjs.map +1 -1
- package/dist/orchestrators/snapshot/wipe.mjs +67 -56
- package/dist/orchestrators/snapshot/wipe.mjs.map +1 -1
- package/dist/plugins/account/codegen.mjs +3 -0
- package/dist/plugins/account/codegen.mjs.map +1 -1
- package/dist/plugins/account/errors.d.mts +2 -2
- package/dist/plugins/account/errors.mjs +1 -4
- package/dist/plugins/account/errors.mjs.map +1 -1
- package/dist/plugins/account/funding.mjs +3 -27
- package/dist/plugins/account/funding.mjs.map +1 -1
- package/dist/plugins/account/index.d.mts +3 -8
- package/dist/plugins/account/index.mjs +71 -35
- package/dist/plugins/account/index.mjs.map +1 -1
- package/dist/plugins/account/keypair.d.mts +8 -7
- package/dist/plugins/account/keypair.mjs +5 -18
- package/dist/plugins/account/keypair.mjs.map +1 -1
- package/dist/plugins/account/lease.mjs.map +1 -1
- package/dist/plugins/account/registry.d.mts +1 -46
- package/dist/plugins/account/registry.mjs.map +1 -1
- package/dist/plugins/account/service.d.mts +43 -34
- package/dist/plugins/account/service.mjs +9 -54
- package/dist/plugins/account/service.mjs.map +1 -1
- package/dist/plugins/account/snapshot.mjs.map +1 -1
- package/dist/plugins/account/variants/ephemeral.mjs.map +1 -1
- package/dist/plugins/account/variants/impersonate.mjs.map +1 -1
- package/dist/plugins/account/variants/signer.mjs.map +1 -1
- package/dist/plugins/action/discriminator.mjs.map +1 -1
- package/dist/plugins/action/errors.mjs +1 -4
- package/dist/plugins/action/errors.mjs.map +1 -1
- package/dist/plugins/action/execute.mjs +3 -4
- package/dist/plugins/action/execute.mjs.map +1 -1
- package/dist/plugins/action/index.d.mts +2 -2
- package/dist/plugins/action/index.mjs +7 -11
- package/dist/plugins/action/index.mjs.map +1 -1
- package/dist/plugins/action/service.d.mts +5 -7
- package/dist/plugins/action/service.mjs +2 -16
- package/dist/plugins/action/service.mjs.map +1 -1
- package/dist/plugins/coin/address-resolution.mjs.map +1 -1
- package/dist/plugins/coin/codegen.mjs +97 -16
- package/dist/plugins/coin/codegen.mjs.map +1 -1
- package/dist/plugins/coin/discovery.mjs.map +1 -1
- package/dist/plugins/coin/errors.mjs +1 -4
- package/dist/plugins/coin/errors.mjs.map +1 -1
- package/dist/plugins/coin/index.d.mts +4 -34
- package/dist/plugins/coin/index.mjs +47 -28
- package/dist/plugins/coin/index.mjs.map +1 -1
- package/dist/plugins/coin/metadata.d.mts +1 -0
- package/dist/plugins/coin/metadata.mjs +8 -9
- package/dist/plugins/coin/metadata.mjs.map +1 -1
- package/dist/plugins/coin/mint.mjs +7 -21
- package/dist/plugins/coin/mint.mjs.map +1 -1
- package/dist/plugins/coin/registry.mjs +33 -20
- package/dist/plugins/coin/registry.mjs.map +1 -1
- package/dist/plugins/coin/service.d.mts +1 -1
- package/dist/plugins/coin/service.mjs +1 -8
- package/dist/plugins/coin/service.mjs.map +1 -1
- package/dist/plugins/coin/snapshot.mjs.map +1 -1
- package/dist/plugins/coin/type-strings.mjs.map +1 -1
- package/dist/plugins/dashboard/domain.mjs +106 -167
- package/dist/plugins/dashboard/domain.mjs.map +1 -1
- package/dist/plugins/dashboard/index.mjs +13 -13
- package/dist/plugins/dashboard/index.mjs.map +1 -1
- package/dist/plugins/dashboard/origin-policy.mjs +3 -3
- package/dist/plugins/dashboard/origin-policy.mjs.map +1 -1
- package/dist/plugins/dashboard/routable.mjs.map +1 -1
- package/dist/plugins/dashboard/schema/builder.mjs.map +1 -1
- package/dist/plugins/dashboard/schema/enums.mjs.map +1 -1
- package/dist/plugins/dashboard/schema/root.mjs +23 -44
- package/dist/plugins/dashboard/schema/root.mjs.map +1 -1
- package/dist/plugins/dashboard/schema/types.mjs +37 -91
- package/dist/plugins/dashboard/schema/types.mjs.map +1 -1
- package/dist/plugins/dashboard/schema.mjs.map +1 -1
- package/dist/plugins/dashboard/server.mjs.map +1 -1
- package/dist/plugins/deepbook/codegen.d.mts +12 -11
- package/dist/plugins/deepbook/codegen.mjs +108 -11
- package/dist/plugins/deepbook/codegen.mjs.map +1 -1
- package/dist/plugins/deepbook/deploy.mjs +7 -14
- package/dist/plugins/deepbook/deploy.mjs.map +1 -1
- package/dist/plugins/deepbook/errors.mjs +4 -2
- package/dist/plugins/deepbook/errors.mjs.map +1 -1
- package/dist/plugins/deepbook/faucet-strategy.mjs +4 -10
- package/dist/plugins/deepbook/faucet-strategy.mjs.map +1 -1
- package/dist/plugins/deepbook/hash.mjs.map +1 -1
- package/dist/plugins/deepbook/index.d.mts +38 -34
- package/dist/plugins/deepbook/index.mjs +133 -64
- package/dist/plugins/deepbook/index.mjs.map +1 -1
- package/dist/plugins/deepbook/plugin-key.mjs.map +1 -1
- package/dist/plugins/deepbook/pyth/index.mjs +4 -8
- package/dist/plugins/deepbook/pyth/index.mjs.map +1 -1
- package/dist/plugins/deepbook/snapshot.mjs +0 -1
- package/dist/plugins/deepbook/snapshot.mjs.map +1 -1
- package/dist/plugins/deepbook/type-strings.mjs.map +1 -1
- package/dist/plugins/deepbook/types.d.mts +2 -1
- package/dist/plugins/deepbook/types.mjs.map +1 -1
- package/dist/plugins/faucet/dispatcher.d.mts +3 -3
- package/dist/plugins/faucet/dispatcher.mjs.map +1 -1
- package/dist/plugins/faucet/errors.mjs.map +1 -1
- package/dist/plugins/faucet/http.mjs +2 -10
- package/dist/plugins/faucet/http.mjs.map +1 -1
- package/dist/plugins/faucet/index.mjs +0 -1
- package/dist/plugins/faucet/index.mjs.map +1 -1
- package/dist/plugins/host-service/errors.d.mts +1 -3
- package/dist/plugins/host-service/errors.mjs +1 -2
- package/dist/plugins/host-service/errors.mjs.map +1 -1
- package/dist/plugins/host-service/index.d.mts +1 -2
- package/dist/plugins/host-service/index.mjs +11 -11
- package/dist/plugins/host-service/index.mjs.map +1 -1
- package/dist/plugins/host-service/routable.mjs.map +1 -1
- package/dist/plugins/host-service/service.mjs +13 -13
- package/dist/plugins/host-service/service.mjs.map +1 -1
- package/dist/plugins/internal/acquire-on-chain-artifact.mjs.map +1 -1
- package/dist/plugins/internal/codegen-helpers.mjs +2 -0
- package/dist/plugins/internal/codegen-helpers.mjs.map +1 -1
- package/dist/plugins/internal/funding-failure-error.mjs.map +1 -1
- package/dist/plugins/{postgres → internal/postgres-sidecar}/connection.mjs +1 -1
- package/dist/plugins/internal/postgres-sidecar/connection.mjs.map +1 -0
- package/dist/plugins/{postgres → internal/postgres-sidecar}/db-ensure.mjs +30 -16
- package/dist/plugins/internal/postgres-sidecar/db-ensure.mjs.map +1 -0
- package/dist/plugins/internal/postgres-sidecar/errors.mjs +21 -0
- package/dist/plugins/internal/postgres-sidecar/errors.mjs.map +1 -0
- package/dist/{substrate/runtime/scoped-multimap → plugins/internal/postgres-sidecar}/index.mjs +1 -0
- package/dist/plugins/internal/postgres-sidecar/service.mjs +121 -0
- package/dist/plugins/internal/postgres-sidecar/service.mjs.map +1 -0
- package/dist/plugins/package/build.mjs +2 -2
- package/dist/plugins/package/build.mjs.map +1 -1
- package/dist/plugins/package/codegen.d.mts +7 -14
- package/dist/plugins/package/codegen.mjs +187 -59
- package/dist/plugins/package/codegen.mjs.map +1 -1
- package/dist/plugins/package/dep-resolution.mjs +51 -3
- package/dist/plugins/package/dep-resolution.mjs.map +1 -1
- package/dist/plugins/package/errors.mjs +1 -4
- package/dist/plugins/package/errors.mjs.map +1 -1
- package/dist/plugins/package/git-source.d.mts +18 -0
- package/dist/plugins/package/git-source.mjs +119 -0
- package/dist/plugins/package/git-source.mjs.map +1 -0
- package/dist/plugins/package/index.d.mts +28 -19
- package/dist/plugins/package/index.mjs +107 -32
- package/dist/plugins/package/index.mjs.map +1 -1
- package/dist/plugins/package/mode-known.mjs +2 -2
- package/dist/plugins/package/mode-known.mjs.map +1 -1
- package/dist/plugins/package/mode-local.mjs +18 -35
- package/dist/plugins/package/mode-local.mjs.map +1 -1
- package/dist/plugins/package/publish-executor.mjs +13 -8
- package/dist/plugins/package/publish-executor.mjs.map +1 -1
- package/dist/plugins/package/publish-output.d.mts +1 -11
- package/dist/plugins/package/publish-output.mjs +1 -9
- package/dist/plugins/package/publish-output.mjs.map +1 -1
- package/dist/plugins/package/registry.d.mts +1 -1
- package/dist/plugins/package/registry.mjs +26 -14
- package/dist/plugins/package/registry.mjs.map +1 -1
- package/dist/plugins/package/service.mjs.map +1 -1
- package/dist/plugins/package/snapshot.mjs.map +1 -1
- package/dist/plugins/router-entrypoints.mjs +1 -3
- package/dist/plugins/router-entrypoints.mjs.map +1 -1
- package/dist/plugins/seal/bootstrap-assets/cargo-image.mjs +1 -2
- package/dist/plugins/seal/bootstrap-assets/cargo-image.mjs.map +1 -1
- package/dist/plugins/seal/bootstrap-assets/source-fetch.mjs +1 -6
- package/dist/plugins/seal/bootstrap-assets/source-fetch.mjs.map +1 -1
- package/dist/plugins/seal/codegen.d.mts +1 -5
- package/dist/plugins/seal/codegen.mjs +83 -12
- package/dist/plugins/seal/codegen.mjs.map +1 -1
- package/dist/plugins/seal/config-render.mjs +2 -6
- package/dist/plugins/seal/config-render.mjs.map +1 -1
- package/dist/plugins/seal/deploy.mjs +18 -29
- package/dist/plugins/seal/deploy.mjs.map +1 -1
- package/dist/plugins/seal/errors.d.mts +4 -5
- package/dist/plugins/seal/errors.mjs +1 -8
- package/dist/plugins/seal/errors.mjs.map +1 -1
- package/dist/plugins/seal/index.d.mts +7 -28
- package/dist/plugins/seal/index.mjs +69 -47
- package/dist/plugins/seal/index.mjs.map +1 -1
- package/dist/plugins/seal/key-manager.mjs.map +1 -1
- package/dist/plugins/seal/key-server.mjs +1 -6
- package/dist/plugins/seal/key-server.mjs.map +1 -1
- package/dist/plugins/seal/keygen.mjs +2 -3
- package/dist/plugins/seal/keygen.mjs.map +1 -1
- package/dist/plugins/seal/mode/fork-known.mjs.map +1 -1
- package/dist/plugins/seal/mode/live.mjs +1 -1
- package/dist/plugins/seal/mode/live.mjs.map +1 -1
- package/dist/plugins/seal/mode/local-keygen.mjs +4 -10
- package/dist/plugins/seal/mode/local-keygen.mjs.map +1 -1
- package/dist/plugins/seal/plugin-key.mjs.map +1 -1
- package/dist/plugins/seal/registry-publish.mjs.map +1 -1
- package/dist/plugins/seal/routable.mjs.map +1 -1
- package/dist/plugins/seal/service.mjs.map +1 -1
- package/dist/plugins/seal/snapshot.mjs +1 -2
- package/dist/plugins/seal/snapshot.mjs.map +1 -1
- package/dist/plugins/sui/auto-tick.mjs +5 -5
- package/dist/plugins/sui/auto-tick.mjs.map +1 -1
- package/dist/plugins/sui/chain-build-container.mjs +2 -2
- package/dist/plugins/sui/chain-build-container.mjs.map +1 -1
- package/dist/plugins/sui/chain-probe.mjs +4 -4
- package/dist/plugins/sui/chain-probe.mjs.map +1 -1
- package/dist/plugins/sui/codegen.d.mts +9 -7
- package/dist/plugins/sui/codegen.mjs +49 -46
- package/dist/plugins/sui/codegen.mjs.map +1 -1
- package/dist/plugins/sui/errors.d.mts +1 -1
- package/dist/plugins/sui/errors.mjs +1 -9
- package/dist/plugins/sui/errors.mjs.map +1 -1
- package/dist/{substrate/runtime/sui-execute → plugins/sui/exec}/index.d.mts +1 -1
- package/dist/{substrate/runtime/sui-execute → plugins/sui/exec}/index.mjs +3 -7
- package/dist/plugins/sui/exec/index.mjs.map +1 -0
- package/dist/{substrate/runtime/sui-execute → plugins/sui/exec}/sign-and-dispatch.mjs +1 -1
- package/dist/plugins/sui/exec/sign-and-dispatch.mjs.map +1 -0
- package/dist/plugins/sui/fork-faucet-strategy.mjs +2 -6
- package/dist/plugins/sui/fork-faucet-strategy.mjs.map +1 -1
- package/dist/plugins/sui/fork-orchestration.mjs +13 -23
- package/dist/plugins/sui/fork-orchestration.mjs.map +1 -1
- package/dist/plugins/sui/fork-transaction.mjs.map +1 -1
- package/dist/plugins/sui/index.d.mts +34 -83
- package/dist/plugins/sui/index.mjs +200 -68
- package/dist/plugins/sui/index.mjs.map +1 -1
- package/dist/{substrate/runtime/sui-ledger → plugins/sui/ledger}/object-ref.mjs +1 -1
- package/dist/plugins/sui/ledger/object-ref.mjs.map +1 -0
- package/dist/plugins/sui/local-faucet-strategy.mjs +1 -5
- package/dist/plugins/sui/local-faucet-strategy.mjs.map +1 -1
- package/dist/plugins/sui/log-attrs.mjs +11 -0
- package/dist/plugins/sui/log-attrs.mjs.map +1 -0
- package/dist/plugins/sui/mode/external.mjs +4 -12
- package/dist/plugins/sui/mode/external.mjs.map +1 -1
- package/dist/plugins/sui/mode/fork.mjs +19 -16
- package/dist/plugins/sui/mode/fork.mjs.map +1 -1
- package/dist/plugins/sui/mode/live.mjs +4 -17
- package/dist/plugins/sui/mode/live.mjs.map +1 -1
- package/dist/plugins/sui/mode/local.d.mts +1 -0
- package/dist/plugins/sui/mode/local.mjs +203 -61
- package/dist/plugins/sui/mode/local.mjs.map +1 -1
- package/dist/plugins/sui/mode/shared-boot.mjs +18 -23
- package/dist/plugins/sui/mode/shared-boot.mjs.map +1 -1
- package/dist/plugins/sui/mode/shared.d.mts +6 -7
- package/dist/plugins/sui/mode/shared.mjs.map +1 -1
- package/dist/plugins/sui/mode/spec.d.mts +23 -6
- package/dist/{substrate/runtime/sui-move-build → plugins/sui/move}/index.mjs +28 -30
- package/dist/plugins/sui/move/index.mjs.map +1 -0
- package/dist/plugins/sui/move-summary-runner.mjs +8 -4
- package/dist/plugins/sui/move-summary-runner.mjs.map +1 -1
- package/dist/{substrate/network.d.mts → plugins/sui/network-config.d.mts} +11 -10
- package/dist/plugins/sui/network-resolver.d.mts +6 -6
- package/dist/plugins/sui/routable.mjs.map +1 -1
- package/dist/plugins/sui/service.mjs +10 -6
- package/dist/plugins/sui/service.mjs.map +1 -1
- package/dist/plugins/sui/snapshot.mjs +10 -5
- package/dist/plugins/sui/snapshot.mjs.map +1 -1
- package/dist/plugins/wallet/codegen.d.mts +8 -6
- package/dist/plugins/wallet/codegen.mjs +4 -10
- package/dist/plugins/wallet/codegen.mjs.map +1 -1
- package/dist/plugins/wallet/errors.mjs +1 -4
- package/dist/plugins/wallet/errors.mjs.map +1 -1
- package/dist/plugins/wallet/index.d.mts +3 -6
- package/dist/plugins/wallet/index.mjs +16 -21
- package/dist/plugins/wallet/index.mjs.map +1 -1
- package/dist/plugins/wallet/origin-policy.mjs +3 -3
- package/dist/plugins/wallet/origin-policy.mjs.map +1 -1
- package/dist/plugins/wallet/pairing.mjs +6 -24
- package/dist/plugins/wallet/pairing.mjs.map +1 -1
- package/dist/plugins/wallet/protocol.mjs.map +1 -1
- package/dist/plugins/wallet/routable.mjs.map +1 -1
- package/dist/plugins/wallet/server.mjs +17 -24
- package/dist/plugins/wallet/server.mjs.map +1 -1
- package/dist/plugins/wallet/service.d.mts +2 -2
- package/dist/plugins/wallet/service.mjs +4 -15
- package/dist/plugins/wallet/service.mjs.map +1 -1
- package/dist/plugins/wallet/snapshot.mjs.map +1 -1
- package/dist/plugins/walrus/bootstrap-assets/cargo-image.mjs +1 -5
- package/dist/plugins/walrus/bootstrap-assets/cargo-image.mjs.map +1 -1
- package/dist/plugins/walrus/codegen.d.mts +2 -13
- package/dist/plugins/walrus/codegen.mjs +93 -28
- package/dist/plugins/walrus/codegen.mjs.map +1 -1
- package/dist/plugins/walrus/deploy-paths.mjs +2 -3
- package/dist/plugins/walrus/deploy-paths.mjs.map +1 -1
- package/dist/plugins/walrus/deploy.mjs +26 -19
- package/dist/plugins/walrus/deploy.mjs.map +1 -1
- package/dist/plugins/walrus/errors.mjs +1 -8
- package/dist/plugins/walrus/errors.mjs.map +1 -1
- package/dist/plugins/walrus/faucet-strategy.mjs +15 -1
- package/dist/plugins/walrus/faucet-strategy.mjs.map +1 -1
- package/dist/plugins/walrus/index.d.mts +13 -44
- package/dist/plugins/walrus/index.mjs +119 -122
- package/dist/plugins/walrus/index.mjs.map +1 -1
- package/dist/plugins/walrus/mode/known-deploy.mjs +6 -6
- package/dist/plugins/walrus/mode/known-deploy.mjs.map +1 -1
- package/dist/plugins/walrus/mode/local-cluster.d.mts +2 -2
- package/dist/plugins/walrus/mode/local-cluster.mjs +2 -10
- package/dist/plugins/walrus/mode/local-cluster.mjs.map +1 -1
- package/dist/plugins/walrus/plugin-key.mjs.map +1 -1
- package/dist/plugins/walrus/registry-publish.mjs.map +1 -1
- package/dist/plugins/walrus/routable.mjs.map +1 -1
- package/dist/plugins/walrus/service.mjs.map +1 -1
- package/dist/plugins/walrus/snapshot.mjs +3 -3
- package/dist/plugins/walrus/snapshot.mjs.map +1 -1
- package/dist/plugins/walrus/storage-nodes.mjs +53 -14
- package/dist/plugins/walrus/storage-nodes.mjs.map +1 -1
- package/dist/plugins/walrus/wal-swap.mjs +4 -8
- package/dist/plugins/walrus/wal-swap.mjs.map +1 -1
- package/dist/primitives/artifact-publisher.mjs.map +1 -1
- package/dist/primitives/cache.d.mts +1 -1
- package/dist/runtime/docker/client.mjs +47 -3
- package/dist/runtime/docker/client.mjs.map +1 -1
- package/dist/runtime/docker/container.mjs +37 -57
- package/dist/runtime/docker/container.mjs.map +1 -1
- package/dist/runtime/docker/errors.mjs.map +1 -1
- package/dist/runtime/docker/exec.mjs +2 -2
- package/dist/runtime/docker/exec.mjs.map +1 -1
- package/dist/runtime/docker/image.mjs +10 -11
- package/dist/runtime/docker/image.mjs.map +1 -1
- package/dist/runtime/docker/index.mjs +0 -1
- package/dist/runtime/docker/inspect-and-decode.mjs.map +1 -1
- package/dist/runtime/docker/inventory.mjs +9 -9
- package/dist/runtime/docker/inventory.mjs.map +1 -1
- package/dist/runtime/docker/labels.mjs +12 -1
- package/dist/runtime/docker/labels.mjs.map +1 -1
- package/dist/runtime/docker/network.mjs +6 -6
- package/dist/runtime/docker/network.mjs.map +1 -1
- package/dist/runtime/docker/render-run-args.mjs.map +1 -1
- package/dist/runtime/docker/service.mjs +31 -45
- package/dist/runtime/docker/service.mjs.map +1 -1
- package/dist/runtime/docker/sweep.mjs +14 -64
- package/dist/runtime/docker/sweep.mjs.map +1 -1
- package/dist/runtime/docker/volume.mjs +1 -1
- package/dist/runtime/docker/volume.mjs.map +1 -1
- package/dist/runtime/docker/wrap.mjs +14 -2
- package/dist/runtime/docker/wrap.mjs.map +1 -1
- package/dist/substrate/brand.d.mts +2 -5
- package/dist/substrate/brand.mjs +3 -2
- package/dist/substrate/brand.mjs.map +1 -1
- package/dist/substrate/cross-process.mjs +2 -16
- package/dist/substrate/cross-process.mjs.map +1 -1
- package/dist/substrate/event-time.mjs +0 -2
- package/dist/substrate/event-time.mjs.map +1 -1
- package/dist/substrate/events.d.mts +46 -16
- package/dist/substrate/identity.d.mts +11 -5
- package/dist/substrate/manifest.d.mts +33 -26
- package/dist/substrate/manifest.mjs +8 -3
- package/dist/substrate/manifest.mjs.map +1 -1
- package/dist/substrate/options.d.mts +33 -4
- package/dist/substrate/plugin-ctx.d.mts +70 -0
- package/dist/substrate/plugin-ctx.mjs +66 -0
- package/dist/substrate/plugin-ctx.mjs.map +1 -0
- package/dist/substrate/plugin.d.mts +46 -38
- package/dist/substrate/plugin.mjs +13 -9
- package/dist/substrate/plugin.mjs.map +1 -1
- package/dist/substrate/projection.d.mts +1 -1
- package/dist/substrate/runtime/atomic-write.mjs +3 -4
- package/dist/substrate/runtime/atomic-write.mjs.map +1 -1
- package/dist/substrate/runtime/cache/schema.mjs.map +1 -1
- package/dist/substrate/runtime/cache/service.mjs +50 -20
- package/dist/substrate/runtime/cache/service.mjs.map +1 -1
- package/dist/substrate/runtime/config-validation.mjs.map +1 -1
- package/dist/substrate/runtime/control-plane/domain.mjs +34 -12
- package/dist/substrate/runtime/control-plane/domain.mjs.map +1 -1
- package/dist/substrate/runtime/control-plane/service.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/command-channel/channel.mjs +14 -17
- package/dist/substrate/runtime/cross-process/command-channel/channel.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/command-channel/file-channel.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/command-channel/protocol.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/command-channel/runtime-control-lock.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/index.mjs +0 -2
- package/dist/substrate/runtime/cross-process/live-clock.mjs +1 -1
- package/dist/substrate/runtime/cross-process/live-clock.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/liveness.mjs +11 -18
- package/dist/substrate/runtime/cross-process/liveness.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/reclaim-stale-file.mjs +2 -2
- package/dist/substrate/runtime/cross-process/reclaim-stale-file.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/roster.mjs +17 -127
- package/dist/substrate/runtime/cross-process/roster.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/self-pid.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/stack-lock.mjs +29 -28
- package/dist/substrate/runtime/cross-process/stack-lock.mjs.map +1 -1
- package/dist/substrate/runtime/current-plugin.mjs.map +1 -1
- package/dist/substrate/runtime/errors.mjs +1 -13
- package/dist/substrate/runtime/errors.mjs.map +1 -1
- package/dist/substrate/runtime/format-unknown-error.mjs.map +1 -1
- package/dist/substrate/runtime/host-bind-mount-owner.mjs.map +1 -1
- package/dist/substrate/runtime/host-gateway.mjs.map +1 -1
- package/dist/substrate/runtime/host-tree-tar/index.mjs +15 -163
- package/dist/substrate/runtime/host-tree-tar/index.mjs.map +1 -1
- package/dist/substrate/runtime/http-probe.d.mts +1 -3
- package/dist/substrate/runtime/http-probe.mjs.map +1 -1
- package/dist/substrate/runtime/index.mjs +1 -6
- package/dist/substrate/runtime/lease-broker/service.mjs +5 -23
- package/dist/substrate/runtime/lease-broker/service.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/dep-graph.mjs +3 -3
- package/dist/substrate/runtime/lifecycle/dep-graph.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/graph-input-id.d.mts +1 -0
- package/dist/substrate/runtime/lifecycle/graph-input-id.mjs +133 -0
- package/dist/substrate/runtime/lifecycle/graph-input-id.mjs.map +1 -0
- package/dist/substrate/runtime/lifecycle/index.mjs +2 -2
- package/dist/substrate/runtime/lifecycle/plugin-registry.d.mts +1 -1
- package/dist/substrate/runtime/lifecycle/plugin-registry.mjs +22 -1
- package/dist/substrate/runtime/lifecycle/plugin-registry.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/ready-gate.mjs +2 -15
- package/dist/substrate/runtime/lifecycle/ready-gate.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/selective-restart.mjs +29 -25
- package/dist/substrate/runtime/lifecycle/selective-restart.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/signals.mjs +1 -1
- package/dist/substrate/runtime/lifecycle/signals.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/state-machine.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/watch-attribution.d.mts +1 -1
- package/dist/substrate/runtime/lifecycle/watch-attribution.mjs +0 -1
- package/dist/substrate/runtime/lifecycle/watch-attribution.mjs.map +1 -1
- package/dist/substrate/runtime/managed-container.d.mts +5 -1
- package/dist/substrate/runtime/managed-container.mjs +8 -10
- package/dist/substrate/runtime/managed-container.mjs.map +1 -1
- package/dist/substrate/runtime/manifest/manifest.mjs +8 -30
- package/dist/substrate/runtime/manifest/manifest.mjs.map +1 -1
- package/dist/substrate/runtime/mode-errors.d.mts +1 -2
- package/dist/substrate/runtime/mode-errors.mjs.map +1 -1
- package/dist/substrate/runtime/observability/cascade-formatter.mjs +1 -11
- package/dist/substrate/runtime/observability/cascade-formatter.mjs.map +1 -1
- package/dist/substrate/runtime/observability/ignore-with-log.mjs.map +1 -1
- package/dist/substrate/runtime/observability/index.d.mts +1 -1
- package/dist/substrate/runtime/observability/index.mjs +4 -6
- package/dist/substrate/runtime/observability/log-attrs.mjs +46 -0
- package/dist/substrate/runtime/observability/log-attrs.mjs.map +1 -0
- package/dist/substrate/runtime/observability/log-store.mjs.map +1 -1
- package/dist/substrate/runtime/observability/logger.mjs +3 -3
- package/dist/substrate/runtime/observability/logger.mjs.map +1 -1
- package/dist/substrate/runtime/observability/output-truncate.mjs.map +1 -1
- package/dist/substrate/runtime/observability/pretty-error.mjs.map +1 -1
- package/dist/substrate/runtime/observability/process-lines.mjs.map +1 -1
- package/dist/substrate/runtime/observability/redaction.mjs.map +1 -1
- package/dist/substrate/runtime/observability/subprocess-capture.mjs +2 -2
- package/dist/substrate/runtime/observability/subprocess-capture.mjs.map +1 -1
- package/dist/substrate/runtime/passthrough-or-wrap.mjs.map +1 -1
- package/dist/substrate/runtime/paths.mjs +27 -9
- package/dist/substrate/runtime/paths.mjs.map +1 -1
- package/dist/substrate/runtime/phase-preserving-produce.mjs.map +1 -1
- package/dist/substrate/runtime/port-broker/service.mjs +10 -27
- package/dist/substrate/runtime/port-broker/service.mjs.map +1 -1
- package/dist/substrate/runtime/post-acquire-tasks.mjs.map +1 -1
- package/dist/substrate/runtime/probes.d.mts +2 -3
- package/dist/substrate/runtime/probes.mjs.map +1 -1
- package/dist/substrate/runtime/process-supervisor.mjs.map +1 -1
- package/dist/substrate/runtime/projection/operational-endpoints.mjs.map +1 -1
- package/dist/substrate/runtime/projection/state-ref.mjs.map +1 -1
- package/dist/substrate/runtime/projection/update.mjs +87 -11
- package/dist/substrate/runtime/projection/update.mjs.map +1 -1
- package/dist/substrate/runtime/random-suffix.mjs.map +1 -1
- package/dist/substrate/runtime/reconcile/fs-plan.mjs +146 -0
- package/dist/substrate/runtime/reconcile/fs-plan.mjs.map +1 -0
- package/dist/substrate/runtime/reconcile/graph.mjs +19 -0
- package/dist/substrate/runtime/reconcile/graph.mjs.map +1 -0
- package/dist/substrate/runtime/reconcile/index.mjs +5 -0
- package/dist/substrate/runtime/reconcile/label.mjs +41 -0
- package/dist/substrate/runtime/reconcile/label.mjs.map +1 -0
- package/dist/substrate/runtime/reconcile/spec.mjs +15 -0
- package/dist/substrate/runtime/reconcile/spec.mjs.map +1 -0
- package/dist/substrate/runtime/retry-policy.d.mts +2 -3
- package/dist/substrate/runtime/retry-policy.mjs.map +1 -1
- package/dist/substrate/runtime/routed-url.mjs.map +1 -1
- package/dist/substrate/runtime/runtime-decode.mjs.map +1 -1
- package/dist/substrate/runtime/scoped-http-server.mjs.map +1 -1
- package/dist/substrate/runtime/stage-and-swap/index.mjs +49 -12
- package/dist/substrate/runtime/stage-and-swap/index.mjs.map +1 -1
- package/dist/substrate/runtime/strategy-registry/chain-keyed-strategy-for.mjs.map +1 -1
- package/dist/substrate/runtime/strategy-registry/chain-probe-for.mjs.map +1 -1
- package/dist/substrate/runtime/strategy-registry/service.mjs +29 -17
- package/dist/substrate/runtime/strategy-registry/service.mjs.map +1 -1
- package/dist/substrate/runtime/subnet-broker.mjs.map +1 -1
- package/dist/substrate/runtime/supervisor/acquire-node.mjs +188 -56
- package/dist/substrate/runtime/supervisor/acquire-node.mjs.map +1 -1
- package/dist/substrate/runtime/supervisor/background-tasks.mjs +79 -65
- package/dist/substrate/runtime/supervisor/background-tasks.mjs.map +1 -1
- package/dist/substrate/runtime/supervisor/command-loop.mjs +82 -23
- package/dist/substrate/runtime/supervisor/command-loop.mjs.map +1 -1
- package/dist/substrate/runtime/supervisor/contribution-dispatcher.mjs +16 -0
- package/dist/substrate/runtime/supervisor/contribution-dispatcher.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor/errors.mjs +11 -2
- package/dist/substrate/runtime/supervisor/errors.mjs.map +1 -1
- package/dist/substrate/runtime/supervisor/index.mjs +2 -0
- package/dist/substrate/runtime/supervisor/shutdown.mjs +6 -6
- package/dist/substrate/runtime/supervisor/shutdown.mjs.map +1 -1
- package/dist/substrate/runtime/supervisor/start-supervisor.mjs +60 -70
- package/dist/substrate/runtime/supervisor/start-supervisor.mjs.map +1 -1
- package/dist/substrate/runtime/supervisor/state.d.mts +1 -1
- package/dist/substrate/runtime/supervisor/state.mjs +1 -1
- package/dist/substrate/runtime/supervisor/state.mjs.map +1 -1
- package/dist/substrate/runtime/supervisor/teardown.mjs +10 -9
- package/dist/substrate/runtime/supervisor/teardown.mjs.map +1 -1
- package/dist/substrate/runtime/supervisor/wiring.mjs +6 -20
- package/dist/substrate/runtime/supervisor/wiring.mjs.map +1 -1
- package/dist/substrate/runtime/tar/reader.mjs +216 -0
- package/dist/substrate/runtime/tar/reader.mjs.map +1 -0
- package/dist/substrate/runtime/typed-env.mjs.map +1 -1
- package/dist/substrate/versioned-doc-schema.mjs.map +1 -1
- package/dist/substrate/versioned-doc-sync.mjs +5 -5
- package/dist/substrate/versioned-doc-sync.mjs.map +1 -1
- package/dist/surfaces/cli/command-tree.mjs +49 -7
- package/dist/surfaces/cli/command-tree.mjs.map +1 -1
- package/dist/surfaces/cli/commands/config.mjs +1 -1
- package/dist/surfaces/cli/commands/config.mjs.map +1 -1
- package/dist/surfaces/cli/commands/confirm-node.mjs.map +1 -1
- package/dist/surfaces/cli/commands/confirm.mjs.map +1 -1
- package/dist/surfaces/cli/commands/doctor.mjs +1 -1
- package/dist/surfaces/cli/commands/doctor.mjs.map +1 -1
- package/dist/surfaces/cli/commands/prune-picker-entry.mjs.map +1 -1
- package/dist/surfaces/cli/commands/prune-picker.mjs.map +1 -1
- package/dist/surfaces/cli/commands/prune.mjs +1 -1
- package/dist/surfaces/cli/commands/prune.mjs.map +1 -1
- package/dist/surfaces/cli/commands/snapshot.mjs +1 -1
- package/dist/surfaces/cli/commands/snapshot.mjs.map +1 -1
- package/dist/surfaces/cli/commands/status.mjs +1 -1
- package/dist/surfaces/cli/commands/status.mjs.map +1 -1
- package/dist/surfaces/cli/commands/supervisor-presence.mjs.map +1 -1
- package/dist/surfaces/cli/commands/wipe.mjs +3 -4
- package/dist/surfaces/cli/commands/wipe.mjs.map +1 -1
- package/dist/surfaces/cli/envelope.mjs.map +1 -1
- package/dist/surfaces/cli/errors.mjs.map +1 -1
- package/dist/surfaces/cli/flags.mjs.map +1 -1
- package/dist/surfaces/cli/index.mjs +45 -14
- package/dist/surfaces/cli/index.mjs.map +1 -1
- package/dist/surfaces/cli/output.mjs.map +1 -1
- package/dist/surfaces/cli/sysexits.mjs.map +1 -1
- package/dist/surfaces/tui/app.mjs +0 -21
- package/dist/surfaces/tui/app.mjs.map +1 -1
- package/dist/surfaces/tui/dashboard.mjs +0 -48
- package/dist/surfaces/tui/dashboard.mjs.map +1 -1
- package/dist/surfaces/tui/display-derivation.mjs +80 -16
- package/dist/surfaces/tui/display-derivation.mjs.map +1 -1
- package/dist/surfaces/tui/errors.mjs.map +1 -1
- package/dist/surfaces/tui/event-log.mjs +0 -9
- package/dist/surfaces/tui/event-log.mjs.map +1 -1
- package/dist/surfaces/tui/heartbeat.mjs.map +1 -1
- package/dist/surfaces/tui/index.mjs +2 -2
- package/dist/surfaces/tui/index.mjs.map +1 -1
- package/dist/surfaces/tui/input.mjs.map +1 -1
- package/dist/surfaces/tui/mode-detect.mjs.map +1 -1
- package/dist/surfaces/tui/mount-ink.mjs.map +1 -1
- package/dist/surfaces/tui/plain-renderer.mjs +26 -19
- package/dist/surfaces/tui/plain-renderer.mjs.map +1 -1
- package/dist/surfaces/tui/resource-table.mjs +8 -10
- package/dist/surfaces/tui/resource-table.mjs.map +1 -1
- package/images/postgres/Dockerfile +0 -1
- package/images/sui/Dockerfile +27 -54
- package/images/sui/entrypoint.sh +17 -179
- package/package.json +23 -15
- package/dashboard-ui/assets/index-Bmi1UtAg.js +0 -1356
- package/dashboard-ui/assets/index-D5EShVt4.js +0 -3
- package/dashboard-ui/assets/index-Deml9drg.css +0 -1
- package/dist/api/plugin-errors.d.mts +0 -7
- package/dist/api/plugin-errors.mjs +0 -10
- package/dist/api/plugin-errors.mjs.map +0 -1
- package/dist/cli/wirings/build-verb-layers.mjs +0 -42
- package/dist/cli/wirings/build-verb-layers.mjs.map +0 -1
- package/dist/contracts/capability-decl.d.mts +0 -40
- package/dist/orchestrators/built-in-plugin-layers.mjs +0 -54
- package/dist/orchestrators/built-in-plugin-layers.mjs.map +0 -1
- package/dist/orchestrators/run.mjs +0 -91
- package/dist/orchestrators/run.mjs.map +0 -1
- package/dist/orchestrators/runtime-composition.d.mts +0 -10
- package/dist/orchestrators/runtime-composition.mjs +0 -252
- package/dist/orchestrators/runtime-composition.mjs.map +0 -1
- package/dist/orchestrators/snapshot/capture-command.d.mts +0 -1
- package/dist/orchestrators/snapshot/capture-command.mjs +0 -25
- package/dist/orchestrators/snapshot/capture-command.mjs.map +0 -1
- package/dist/orchestrators/snapshot/pending-marker.mjs +0 -99
- package/dist/orchestrators/snapshot/pending-marker.mjs.map +0 -1
- package/dist/orchestrators/snapshot/recover-pending.mjs +0 -223
- package/dist/orchestrators/snapshot/recover-pending.mjs.map +0 -1
- package/dist/orchestrators/snapshot/state-document.d.mts +0 -1
- package/dist/orchestrators/snapshot/state-document.mjs +0 -58
- package/dist/orchestrators/snapshot/state-document.mjs.map +0 -1
- package/dist/plugins/account/spans.mjs +0 -16
- package/dist/plugins/account/spans.mjs.map +0 -1
- package/dist/plugins/account/variants/env.mjs +0 -24
- package/dist/plugins/account/variants/env.mjs.map +0 -1
- package/dist/plugins/account/variants/inline.mjs +0 -13
- package/dist/plugins/account/variants/inline.mjs.map +0 -1
- package/dist/plugins/account/variants/keystore.mjs +0 -91
- package/dist/plugins/account/variants/keystore.mjs.map +0 -1
- package/dist/plugins/action/spans.mjs +0 -11
- package/dist/plugins/action/spans.mjs.map +0 -1
- package/dist/plugins/coin/spans.mjs +0 -20
- package/dist/plugins/coin/spans.mjs.map +0 -1
- package/dist/plugins/deepbook/spans.mjs +0 -18
- package/dist/plugins/deepbook/spans.mjs.map +0 -1
- package/dist/plugins/faucet/spans.mjs +0 -12
- package/dist/plugins/faucet/spans.mjs.map +0 -1
- package/dist/plugins/package/spans.mjs +0 -14
- package/dist/plugins/package/spans.mjs.map +0 -1
- package/dist/plugins/postgres/codegen.mjs +0 -42
- package/dist/plugins/postgres/codegen.mjs.map +0 -1
- package/dist/plugins/postgres/connection.d.mts +0 -33
- package/dist/plugins/postgres/connection.mjs.map +0 -1
- package/dist/plugins/postgres/db-ensure.mjs.map +0 -1
- package/dist/plugins/postgres/errors.d.mts +0 -60
- package/dist/plugins/postgres/errors.mjs +0 -29
- package/dist/plugins/postgres/errors.mjs.map +0 -1
- package/dist/plugins/postgres/index.d.mts +0 -37
- package/dist/plugins/postgres/index.mjs +0 -68
- package/dist/plugins/postgres/index.mjs.map +0 -1
- package/dist/plugins/postgres/routable.mjs +0 -33
- package/dist/plugins/postgres/routable.mjs.map +0 -1
- package/dist/plugins/postgres/service.d.mts +0 -50
- package/dist/plugins/postgres/service.mjs +0 -179
- package/dist/plugins/postgres/service.mjs.map +0 -1
- package/dist/plugins/postgres/snapshot.mjs +0 -32
- package/dist/plugins/postgres/snapshot.mjs.map +0 -1
- package/dist/plugins/postgres/spans.mjs +0 -11
- package/dist/plugins/postgres/spans.mjs.map +0 -1
- package/dist/plugins/seal/spans.mjs +0 -18
- package/dist/plugins/seal/spans.mjs.map +0 -1
- package/dist/plugins/sui/spans.mjs +0 -17
- package/dist/plugins/sui/spans.mjs.map +0 -1
- package/dist/plugins/wallet/spans.mjs +0 -22
- package/dist/plugins/wallet/spans.mjs.map +0 -1
- package/dist/plugins/walrus/registry-publish.d.mts +0 -24
- package/dist/plugins/walrus/spans.mjs +0 -18
- package/dist/plugins/walrus/spans.mjs.map +0 -1
- package/dist/runtime/docker/logs.d.mts +0 -1
- package/dist/runtime/docker/logs.mjs +0 -34
- package/dist/runtime/docker/logs.mjs.map +0 -1
- package/dist/substrate/runtime/artifact-publisher/index.mjs +0 -86
- package/dist/substrate/runtime/artifact-publisher/index.mjs.map +0 -1
- package/dist/substrate/runtime/capability-sinks/index.d.mts +0 -1
- package/dist/substrate/runtime/capability-sinks/index.mjs +0 -3
- package/dist/substrate/runtime/capability-sinks/layer.d.mts +0 -1
- package/dist/substrate/runtime/capability-sinks/layer.mjs +0 -31
- package/dist/substrate/runtime/capability-sinks/layer.mjs.map +0 -1
- package/dist/substrate/runtime/capability-sinks/service.d.mts +0 -95
- package/dist/substrate/runtime/capability-sinks/service.mjs +0 -69
- package/dist/substrate/runtime/capability-sinks/service.mjs.map +0 -1
- package/dist/substrate/runtime/cross-process/lock.d.mts +0 -1
- package/dist/substrate/runtime/cross-process/lock.mjs +0 -23
- package/dist/substrate/runtime/cross-process/lock.mjs.map +0 -1
- package/dist/substrate/runtime/cross-process/snapshot-reservation.mjs +0 -113
- package/dist/substrate/runtime/cross-process/snapshot-reservation.mjs.map +0 -1
- package/dist/substrate/runtime/lifecycle/lifecycle-fact.mjs +0 -31
- package/dist/substrate/runtime/lifecycle/lifecycle-fact.mjs.map +0 -1
- package/dist/substrate/runtime/observability/formatter-registry.d.mts +0 -1
- package/dist/substrate/runtime/observability/formatter-registry.mjs +0 -48
- package/dist/substrate/runtime/observability/formatter-registry.mjs.map +0 -1
- package/dist/substrate/runtime/observability/span-store.d.mts +0 -1
- package/dist/substrate/runtime/observability/span-store.mjs +0 -110
- package/dist/substrate/runtime/observability/span-store.mjs.map +0 -1
- package/dist/substrate/runtime/observability/spans.d.mts +0 -1
- package/dist/substrate/runtime/observability/spans.mjs +0 -87
- package/dist/substrate/runtime/observability/spans.mjs.map +0 -1
- package/dist/substrate/runtime/projection/index.mjs +0 -4
- package/dist/substrate/runtime/projection/persisted.mjs +0 -213
- package/dist/substrate/runtime/projection/persisted.mjs.map +0 -1
- package/dist/substrate/runtime/scoped-multimap/service.mjs +0 -52
- package/dist/substrate/runtime/scoped-multimap/service.mjs.map +0 -1
- package/dist/substrate/runtime/scoped-ref-map/index.mjs +0 -2
- package/dist/substrate/runtime/scoped-ref-map/service.mjs +0 -83
- package/dist/substrate/runtime/scoped-ref-map/service.mjs.map +0 -1
- package/dist/substrate/runtime/state-store/index.mjs +0 -3
- package/dist/substrate/runtime/state-store/schema.d.mts +0 -1
- package/dist/substrate/runtime/state-store/schema.mjs +0 -41
- package/dist/substrate/runtime/state-store/schema.mjs.map +0 -1
- package/dist/substrate/runtime/state-store/service.d.mts +0 -1
- package/dist/substrate/runtime/state-store/service.mjs +0 -145
- package/dist/substrate/runtime/state-store/service.mjs.map +0 -1
- package/dist/substrate/runtime/sui-execute/index.mjs.map +0 -1
- package/dist/substrate/runtime/sui-execute/sign-and-dispatch.mjs.map +0 -1
- package/dist/substrate/runtime/sui-ledger/object-ref.mjs.map +0 -1
- package/dist/substrate/runtime/sui-move-build/index.mjs.map +0 -1
- package/dist/substrate/runtime/supervisor/dispatch-contributions.mjs +0 -151
- package/dist/substrate/runtime/supervisor/dispatch-contributions.mjs.map +0 -1
- package/dist/substrate/state-store.d.mts +0 -1
- /package/dist/orchestrators/{snapshot/pending-marker.d.mts → codegen/id-config.d.mts} +0 -0
- /package/dist/orchestrators/snapshot/{recover-pending.d.mts → interrupted-restore.d.mts} +0 -0
- /package/dist/{substrate/runtime/sui-execute → plugins/sui/exec}/sign-and-dispatch.d.mts +0 -0
- /package/dist/plugins/{postgres/snapshot.d.mts → sui/ledger/object-ref.d.mts} +0 -0
- /package/dist/{substrate/runtime/sui-move-build → plugins/sui/move}/index.d.mts +0 -0
- /package/dist/substrate/runtime/{state-store/index.d.mts → reconcile/graph.d.mts} +0 -0
- /package/dist/substrate/runtime/{cross-process/snapshot-reservation.d.mts → supervisor/contribution-dispatcher.d.mts} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"up.mjs","names":["resolvePath"],"sources":["../../../src/cli/wirings/up.ts"],"sourcesContent":["// `devstack up` verb wiring.\n//\n// Wires the substrate Layer stack, supervisor, attached renderer, and\n// in-process TUI command queue. The Effect runs as the outer Node fiber\n// so SIGINT reaches scope finalizers (see surfaces/cli/index.ts\n// architecture invariant).\n//\n// Logger layer: `Logger.layer([])` (silent). `up` owns the TUI, which is\n// the operator-facing output channel; routing structured `Effect.log*`\n// records to stderr would scribble on top of the live ink renderer in\n// human mode and would duplicate the structured event stream the plain\n// renderer already emits in non-TTY mode. The sibling `apply` verb (no\n// TUI) uses `Logger.consolePretty()` because its consumer is CI.\n\nimport { dirname, resolve as resolvePath } from 'node:path';\n\nimport { Cause, Effect, Exit, FileSystem, Logger, Queue, Ref, Scope, Stream } from 'effect';\n\nimport type { Identity } from '../../substrate/identity.ts';\nimport type { EngineCommand, EngineEvent } from '../../substrate/events.ts';\nimport { StackPathsService } from '../../substrate/runtime/paths.ts';\nimport {\n\tclaim,\n\tcommandChannelPaths,\n\theartbeatFiber,\n\tmakeCommandChannelSubscriber,\n\tmakeProjectionRef,\n\tpersistProjectionChanges,\n\trelease,\n\ttype SupervisedStack,\n\ttype SupervisorCommandHandler,\n\ttype SupervisorHandle,\n} from '../../substrate/runtime/index.ts';\nimport {\n\tcollectLifecyclePruneInventory,\n\tdefaultLifecyclePruneSelection,\n\tDEFAULT_LIFECYCLE_PRUNE_RESOURCES,\n\trunLifecyclePrune,\n} from '../../orchestrators/lifecycle-prune/index.ts';\nimport { superviseStackEffect } from '../../orchestrators/run.ts';\nimport {\n\tbuildProductionOrchestratorSinks,\n\tbuildProductionPostAcquireHook,\n} from '../../orchestrators/runtime-composition.ts';\nimport {\n\textendBuiltInPluginContext,\n\tlayerBuiltInPluginRuntime,\n} from '../../orchestrators/built-in-plugin-layers.ts';\nimport {\n\tcaptureSnapshot,\n\tSnapshotOrchestratorService,\n} from '../../orchestrators/snapshot/index.ts';\nimport {\n\ttype CliError,\n\tCliInternalError,\n\tCliSupervisorLiveError,\n\ttype GlobalFlags,\n} from '../../surfaces/cli/index.ts';\nimport type { CommandResult } from '../../surfaces/cli/commands/index.ts';\nimport { ExitCode } from '../../surfaces/cli/sysexits.ts';\nimport { makeTuiSurface } from '../../surfaces/tui/index.ts';\nimport type { LoadedConfig } from '../../surfaces/cli/commands/config-loader.ts';\n\nimport { cliErrorFromConfigExit } from '../bail.ts';\nimport { makeQueueCommandPublisher, resolveUpRendererMode } from '../up-lifecycle.ts';\nimport { makeConfigLoader } from './config-loader.ts';\nimport { isEngineCommand } from './engine-command.ts';\nimport {\n\tfindCliSupervisorLiveError,\n\tidentityValueFor,\n\tresolvedIdentityForStack,\n\ttype ResolvedIdentity,\n} from './identity.ts';\nimport { buildVerbLayers } from './build-verb-layers.ts';\nimport { provideFileSystem } from './provide-file-system.ts';\n\nconst rosterPathsFor = (stackRoot: string) => ({\n\tstackLockFile: resolvePath(stackRoot, 'stack.lock'),\n\trosterFile: resolvePath(stackRoot, 'roster.json'),\n});\n\n// -----------------------------------------------------------------------------\n// Supervisor command handler — snapshot/wipe/prune injected dispatch\n// -----------------------------------------------------------------------------\n\n/** Captured snapshot metadata is round-tripped through the\n * command-channel ack payload so the publisher's `awaitCompletion`\n * can surface it without tailing the engine event stream. */\ninterface SnapshotCaptureAckPayload {\n\treadonly kind: 'captured' | 'failed' | 'skipped';\n\treadonly snapshotId?: string;\n\treadonly name?: string;\n\treadonly summary?: string;\n\treadonly reason?: string;\n}\n\nconst makeSnapshotCommandHandler = (params: {\n\treadonly snapshot: import('../../orchestrators/snapshot/index.ts').SnapshotOrchestrator;\n\treadonly fs: FileSystem.FileSystem;\n\treadonly runtimeRoot: string;\n}): SupervisorCommandHandler => {\n\treturn (cmd, handlerCtx) => {\n\t\tswitch (cmd.tag) {\n\t\t\tcase 'snapshot.capture':\n\t\t\t\treturn captureSnapshot({\n\t\t\t\t\tsnapshotId: cmd.snapshotId,\n\t\t\t\t\tname: cmd.name,\n\t\t\t\t\tonProgress: (progress) =>\n\t\t\t\t\t\thandlerCtx.publish({\n\t\t\t\t\t\t\ttag: 'snapshot.captureProgress',\n\t\t\t\t\t\t\t...(cmd.snapshotId === undefined ? {} : { snapshotId: cmd.snapshotId }),\n\t\t\t\t\t\t\t...(cmd.name === undefined ? {} : { name: cmd.name }),\n\t\t\t\t\t\t\tphase: progress.phase,\n\t\t\t\t\t\t\t...(progress.detail === undefined ? {} : { detail: progress.detail }),\n\t\t\t\t\t\t\t...(progress.pausedContainers === undefined\n\t\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t\t: { pausedContainers: progress.pausedContainers }),\n\t\t\t\t\t\t\t...(progress.totalContainers === undefined\n\t\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t\t: { totalContainers: progress.totalContainers }),\n\t\t\t\t\t\t\tat: Date.now(),\n\t\t\t\t\t\t}),\n\t\t\t\t}).pipe(\n\t\t\t\t\tEffect.provideService(SnapshotOrchestratorService, params.snapshot),\n\t\t\t\t\tEffect.provideService(FileSystem.FileSystem, params.fs),\n\t\t\t\t\tEffect.map((meta) => [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttag: 'snapshot.captured',\n\t\t\t\t\t\t\tsnapshotId: meta.id,\n\t\t\t\t\t\t\t...(meta.label === null ? {} : { name: meta.label }),\n\t\t\t\t\t\t\tat: Date.now(),\n\t\t\t\t\t\t},\n\t\t\t\t\t]),\n\t\t\t\t);\n\t\t\tcase 'snapshot.restore':\n\t\t\t\treturn provideFileSystem(params.fs, params.snapshot.restore({ id: cmd.snapshotId })).pipe(\n\t\t\t\t\tEffect.map((meta) => [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttag: 'snapshot.restored',\n\t\t\t\t\t\t\tsnapshotId: meta.id,\n\t\t\t\t\t\t\tat: Date.now(),\n\t\t\t\t\t\t},\n\t\t\t\t\t]),\n\t\t\t\t);\n\t\t\tcase 'snapshot.list':\n\t\t\t\treturn provideFileSystem(params.fs, params.snapshot.list).pipe(Effect.as([]));\n\t\t\tcase 'snapshot.delete':\n\t\t\t\treturn provideFileSystem(params.fs, params.snapshot.delete(cmd.snapshotId)).pipe(\n\t\t\t\t\tEffect.as([]),\n\t\t\t\t);\n\t\t\tcase 'wipe.requested':\n\t\t\t\treturn provideFileSystem(params.fs, params.snapshot.wipe({})).pipe(Effect.as([]));\n\t\t\tcase 'prune.requested':\n\t\t\t\t// Route to the same orchestrator the offline `devstack prune`\n\t\t\t\t// verb uses (`runLifecyclePrune`), NOT the snapshot-orchestrator\n\t\t\t\t// prune (which only cleans the snapshot catalog and would leave\n\t\t\t\t// stale containers/networks/volumes/images behind for an attached\n\t\t\t\t// supervisor — silent under-prune is the bug we're closing).\n\t\t\t\t// Live supervisor implies the current stack's group is live and\n\t\t\t\t// therefore excluded from the default selection — exactly the\n\t\t\t\t// invariant the live-attached `prune` needs (operator can prune\n\t\t\t\t// sibling stacks under the same Docker daemon without touching\n\t\t\t\t// the running one).\n\t\t\t\treturn collectLifecyclePruneInventory({ runtimeRoot: params.runtimeRoot }).pipe(\n\t\t\t\t\tEffect.flatMap((inventory) =>\n\t\t\t\t\t\trunLifecyclePrune(\n\t\t\t\t\t\t\t{ runtimeRoot: params.runtimeRoot },\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tgroupKeys: defaultLifecyclePruneSelection(\n\t\t\t\t\t\t\t\t\tinventory,\n\t\t\t\t\t\t\t\t\tDEFAULT_LIFECYCLE_PRUNE_RESOURCES,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\tresources: DEFAULT_LIFECYCLE_PRUNE_RESOURCES,\n\t\t\t\t\t\t\t\tdryRun: false,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t\tEffect.as([]),\n\t\t\t\t);\n\t\t\tdefault:\n\t\t\t\treturn Effect.succeed([]);\n\t\t}\n\t};\n};\n\nconst installLiveSupervisorRoster = (params: {\n\treadonly stackRoot: string;\n\treadonly app: string;\n\treadonly stack: string;\n}): Effect.Effect<void, unknown, Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\tconst paths = rosterPathsFor(params.stackRoot);\n\t\tconst claimed = yield* claim(paths);\n\t\tif (!claimed.soleHolder) {\n\t\t\tyield* release(paths).pipe(Effect.catch(() => Effect.void));\n\t\t\treturn yield* Effect.fail(\n\t\t\t\tnew CliSupervisorLiveError({\n\t\t\t\t\tapp: params.app,\n\t\t\t\t\tstack: params.stack,\n\t\t\t\t\thint: 'use `devstack apply` from another shell, or choose a different --stack name',\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\tyield* Effect.addFinalizer(() => release(paths).pipe(Effect.catch(() => Effect.void)));\n\t\tyield* Effect.forkScoped(heartbeatFiber(paths));\n\t});\n\ninterface PendingSnapshotCapture {\n\treadonly commandId: string;\n\treadonly snapshotId: string;\n\treadonly name?: string;\n}\n\n/** Detect snapshot-capture completion events on the published stream\n * so we can ack/fail the originating `snapshot.capture` command with\n * a structured payload (snapshot metadata on success; failure summary\n * on failure). Drops the legacy tail-fiber on the CLI side — the\n * `summary` is now surfaced through `awaitCompletion`'s reply.payload. */\nconst snapshotCaptureAckFromEvent = (\n\tevent: unknown,\n): { readonly snapshotId: string; readonly payload: SnapshotCaptureAckPayload } | null => {\n\tif (typeof event !== 'object' || event === null) return null;\n\tconst record = event as {\n\t\treadonly tag?: string;\n\t\treadonly snapshotId?: string;\n\t\treadonly name?: string;\n\t\treadonly summary?: string;\n\t\treadonly reason?: string;\n\t};\n\tif (typeof record.snapshotId !== 'string') return null;\n\tif (record.tag === 'snapshot.captured') {\n\t\treturn {\n\t\t\tsnapshotId: record.snapshotId,\n\t\t\tpayload: {\n\t\t\t\tkind: 'captured',\n\t\t\t\tsnapshotId: record.snapshotId,\n\t\t\t\t...(record.name === undefined ? {} : { name: record.name }),\n\t\t\t},\n\t\t};\n\t}\n\tif (record.tag === 'snapshot.captureFailed') {\n\t\treturn {\n\t\t\tsnapshotId: record.snapshotId,\n\t\t\tpayload: {\n\t\t\t\tkind: 'failed',\n\t\t\t\tsnapshotId: record.snapshotId,\n\t\t\t\t...(record.name === undefined ? {} : { name: record.name }),\n\t\t\t\t...(typeof record.summary === 'string' ? { summary: record.summary } : {}),\n\t\t\t},\n\t\t};\n\t}\n\tif (record.tag === 'snapshot.captureSkipped') {\n\t\treturn {\n\t\t\tsnapshotId: record.snapshotId,\n\t\t\tpayload: {\n\t\t\t\tkind: 'skipped',\n\t\t\t\tsnapshotId: record.snapshotId,\n\t\t\t\t...(typeof record.reason === 'string' ? { reason: record.reason } : {}),\n\t\t\t},\n\t\t};\n\t}\n\treturn null;\n};\n\nconst installCommandChannelBridge = (params: {\n\treadonly stackRoot: string;\n\treadonly handle: SupervisorHandle;\n}): Effect.Effect<\n\t{\n\t\treadonly publishEvent: (event: EngineEvent) => Effect.Effect<void>;\n\t},\n\tunknown,\n\tScope.Scope\n> =>\n\tEffect.gen(function* () {\n\t\tconst subscriber = yield* makeCommandChannelSubscriber(commandChannelPaths(params.stackRoot), {\n\t\t\tfromOffset: 'current',\n\t\t});\n\n\t\t// snapshotId → pending command record id. Populated when the\n\t\t// bridge dispatches a `snapshot.capture` command; drained when\n\t\t// the matching completion event flows through `publishEvent`.\n\t\tconst pendingCaptures = yield* Ref.make<ReadonlyMap<string, PendingSnapshotCapture>>(new Map());\n\n\t\t// Drive the command stream so a stream-LEVEL failure does not\n\t\t// permanently wedge cross-process IPC. The subscriber's `commands`\n\t\t// tail decodes with the `onDecodeError: 'fail'` default, so ONE\n\t\t// malformed/truncated NDJSON line (CLI killed mid-append, partial\n\t\t// disk write) raises `CommandChannelError` and terminates the\n\t\t// stream. If `runForEach` were the only consumer, the live\n\t\t// supervisor would then process NO further commands for the rest of\n\t\t// the `up` session (a sibling `snapshot save`/`apply`/`prune`\n\t\t// appends but is never read, and its `awaitCompletion` times out\n\t\t// with no diagnostic). Instead we log the failure and RE-SUBSCRIBE:\n\t\t// `subscriber.commands` is `tailRecords(... fromOffset: 'current')`,\n\t\t// and each subscription re-runs its builder, re-anchoring the tail\n\t\t// at the file's current EOF — so the corrupt line (and any records\n\t\t// that were buffered alongside it) are skipped and subsequent\n\t\t// commands are processed again. A short delay before resume avoids a\n\t\t// busy spin if the tail keeps failing. The publisher's reply-tail\n\t\t// already uses `onDecodeError: 'skip'` for the same NDJSON-tolerance\n\t\t// reason; this gives the command-subscriber side equivalent\n\t\t// resilience without touching the shared subscriber.\n\t\tconst consumeCommands: Effect.Effect<void, never, Scope.Scope> = subscriber.commands\n\t\t\t.pipe(\n\t\t\t\tStream.runForEach((record) =>\n\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\tif (!isEngineCommand(record.command)) {\n\t\t\t\t\t\t\tyield* subscriber\n\t\t\t\t\t\t\t\t.fail(record.id, 'invalid command', 'command payload did not match EngineCommand')\n\t\t\t\t\t\t\t\t.pipe(Effect.catch(() => Effect.void));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst cmd: EngineCommand = record.command;\n\t\t\t\t\t\t// Snapshot capture is a background task in the supervisor:\n\t\t\t\t\t\t// `runCommand` returns as soon as the fork is scheduled, so\n\t\t\t\t\t\t// auto-acking here would race the actual capture. We defer\n\t\t\t\t\t\t// ack/fail until the matching `snapshot.captured` /\n\t\t\t\t\t\t// `snapshot.captureFailed` / `snapshot.captureSkipped` event\n\t\t\t\t\t\t// flows through `publishEvent` below.\n\t\t\t\t\t\tif (cmd.tag === 'snapshot.capture') {\n\t\t\t\t\t\t\tif (cmd.snapshotId === undefined) {\n\t\t\t\t\t\t\t\t// Without a snapshotId we cannot correlate the completion\n\t\t\t\t\t\t\t\t// event back to this command record. Fall through to the\n\t\t\t\t\t\t\t\t// legacy auto-ack path — the CLI side mints an id today, so\n\t\t\t\t\t\t\t\t// this branch is defensive.\n\t\t\t\t\t\t\t\tyield* params.handle.runCommand(cmd).pipe(\n\t\t\t\t\t\t\t\t\tEffect.andThen(subscriber.ack(record.id)),\n\t\t\t\t\t\t\t\t\tEffect.catchCause((cause) =>\n\t\t\t\t\t\t\t\t\t\tsubscriber\n\t\t\t\t\t\t\t\t\t\t\t.fail(\n\t\t\t\t\t\t\t\t\t\t\t\trecord.id,\n\t\t\t\t\t\t\t\t\t\t\t\t'command failed',\n\t\t\t\t\t\t\t\t\t\t\t\tCause.pretty(cause as Cause.Cause<unknown>),\n\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t.pipe(Effect.catch(() => Effect.void)),\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tyield* Ref.update(pendingCaptures, (map) => {\n\t\t\t\t\t\t\t\tconst next = new Map(map);\n\t\t\t\t\t\t\t\tnext.set(cmd.snapshotId!, {\n\t\t\t\t\t\t\t\t\tcommandId: record.id,\n\t\t\t\t\t\t\t\t\tsnapshotId: cmd.snapshotId!,\n\t\t\t\t\t\t\t\t\t...(cmd.name === undefined ? {} : { name: cmd.name }),\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\treturn next;\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tyield* params.handle.runCommand(cmd).pipe(\n\t\t\t\t\t\t\t\tEffect.catchCause((cause) =>\n\t\t\t\t\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\t\t\t\t\t// Synchronous dispatch failure (e.g. command-loop refused).\n\t\t\t\t\t\t\t\t\t\t// Drain the pending entry and surface the failure now.\n\t\t\t\t\t\t\t\t\t\tyield* Ref.update(pendingCaptures, (map) => {\n\t\t\t\t\t\t\t\t\t\t\tconst next = new Map(map);\n\t\t\t\t\t\t\t\t\t\t\tnext.delete(cmd.snapshotId!);\n\t\t\t\t\t\t\t\t\t\t\treturn next;\n\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\tyield* subscriber\n\t\t\t\t\t\t\t\t\t\t\t.fail(\n\t\t\t\t\t\t\t\t\t\t\t\trecord.id,\n\t\t\t\t\t\t\t\t\t\t\t\t'command failed',\n\t\t\t\t\t\t\t\t\t\t\t\tCause.pretty(cause as Cause.Cause<unknown>),\n\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t.pipe(Effect.catch(() => Effect.void));\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tyield* params.handle.runCommand(cmd).pipe(\n\t\t\t\t\t\t\tEffect.andThen(subscriber.ack(record.id)),\n\t\t\t\t\t\t\tEffect.catchCause((cause) =>\n\t\t\t\t\t\t\t\tsubscriber\n\t\t\t\t\t\t\t\t\t.fail(record.id, 'command failed', Cause.pretty(cause as Cause.Cause<unknown>))\n\t\t\t\t\t\t\t\t\t.pipe(Effect.catch(() => Effect.void)),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t)\n\t\t\t.pipe(\n\t\t\t\tEffect.catchCause((cause): Effect.Effect<void, never, Scope.Scope> => {\n\t\t\t\t\t// Scope-close interrupts this forked fiber via an interrupt\n\t\t\t\t\t// cause. Re-raise it so the fork stops cleanly on `up`\n\t\t\t\t\t// teardown — resuming here would leak the fiber and spam\n\t\t\t\t\t// stderr forever.\n\t\t\t\t\tif (Cause.hasInterrupts(cause as Cause.Cause<unknown>)) {\n\t\t\t\t\t\treturn Effect.failCause(cause as Cause.Cause<never>);\n\t\t\t\t\t}\n\t\t\t\t\t// Otherwise a stream-level failure (e.g. a corrupt NDJSON\n\t\t\t\t\t// line tripping the subscriber's `onDecodeError: 'fail'`\n\t\t\t\t\t// default). Log it, pause briefly to avoid a busy spin, then\n\t\t\t\t\t// re-subscribe by recursing — a fresh tail re-anchors at the\n\t\t\t\t\t// file's current EOF, so the next command is processed\n\t\t\t\t\t// instead of IPC wedging for the session.\n\t\t\t\t\treturn Effect.sync(() => {\n\t\t\t\t\t\tprocess.stderr.write(\n\t\t\t\t\t\t\t`command channel decode failed; resuming tail: ${Cause.pretty(cause as Cause.Cause<unknown>)}\\n`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}).pipe(\n\t\t\t\t\t\tEffect.andThen(Effect.sleep('200 millis')),\n\t\t\t\t\t\tEffect.andThen(Effect.suspend(() => consumeCommands)),\n\t\t\t\t\t);\n\t\t\t\t}),\n\t\t\t);\n\n\t\tyield* Effect.forkScoped(consumeCommands);\n\n\t\tconst publishEvent = (event: EngineEvent): Effect.Effect<void> =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\t// First, route the event to the events file so peer\n\t\t\t\t// subscribers see it. THEN drain any matching pending\n\t\t\t\t// capture so the ack lands after the engine event — this\n\t\t\t\t// preserves the \"captured before ack\" ordering tests rely\n\t\t\t\t// on (test/cli/main.test.ts:483-491 publishes captured then\n\t\t\t\t// acks; we mirror that ordering from the supervisor side).\n\t\t\t\tyield* subscriber.publishEvent(event).pipe(Effect.catch(() => Effect.void));\n\t\t\t\tconst ackFromEvent = snapshotCaptureAckFromEvent(event);\n\t\t\t\tif (ackFromEvent === null) return;\n\t\t\t\tconst pending = yield* Ref.modify(pendingCaptures, (map) => {\n\t\t\t\t\tconst entry = map.get(ackFromEvent.snapshotId);\n\t\t\t\t\tif (entry === undefined) return [null, map];\n\t\t\t\t\tconst next = new Map(map);\n\t\t\t\t\tnext.delete(ackFromEvent.snapshotId);\n\t\t\t\t\treturn [entry, next];\n\t\t\t\t});\n\t\t\t\tif (pending === null) return;\n\t\t\t\tif (ackFromEvent.payload.kind === 'captured') {\n\t\t\t\t\tyield* subscriber\n\t\t\t\t\t\t.ack(pending.commandId, 'captured', ackFromEvent.payload)\n\t\t\t\t\t\t.pipe(Effect.catch(() => Effect.void));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (ackFromEvent.payload.kind === 'failed') {\n\t\t\t\t\tyield* subscriber\n\t\t\t\t\t\t.fail(\n\t\t\t\t\t\t\tpending.commandId,\n\t\t\t\t\t\t\t'snapshot capture failed',\n\t\t\t\t\t\t\tackFromEvent.payload.summary,\n\t\t\t\t\t\t\tackFromEvent.payload,\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.pipe(Effect.catch(() => Effect.void));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// skipped\n\t\t\t\tyield* subscriber\n\t\t\t\t\t.fail(\n\t\t\t\t\t\tpending.commandId,\n\t\t\t\t\t\t'snapshot capture skipped',\n\t\t\t\t\t\tackFromEvent.payload.reason,\n\t\t\t\t\t\tackFromEvent.payload,\n\t\t\t\t\t)\n\t\t\t\t\t.pipe(Effect.catch(() => Effect.void));\n\t\t\t});\n\n\t\treturn { publishEvent };\n\t});\n\n/**\n * Run `devstack up`. Wires the substrate Layer stack, supervisor,\n * attached renderer, and in-process TUI command queue. The Effect runs\n * as the outer Node fiber so SIGINT reaches scope finalizers.\n *\n * Returns a typed `CommandResult` / fails with a typed `CliError` so\n * the dispatcher's `emitFailure` renders the envelope (JSON mode) or\n * human-mode stderr line. Wirings MUST NOT write raw bytes to\n * `process.stderr` or mutate `process.exitCode` for terminal failures —\n * the dispatcher owns the projection.\n */\nexport const runUpLive = (\n\tconfigPath: string | undefined,\n\tidentity: ResolvedIdentity,\n\toptions: {\n\t\treadonly renderer: GlobalFlags['renderer'];\n\t\treadonly stdoutIsTty: boolean;\n\t},\n): Effect.Effect<CommandResult, CliError> => {\n\tconst loader = makeConfigLoader();\n\treturn Effect.gen(function* () {\n\t\tconst loadExit = yield* Effect.exit(loader.load(configPath));\n\t\tif (Exit.isFailure(loadExit)) {\n\t\t\treturn yield* Effect.fail(cliErrorFromConfigExit(loadExit));\n\t\t}\n\t\tconst loaded = loadExit.value;\n\t\tconst stack = (loaded as LoadedConfig & { readonly stack: SupervisedStack }).stack;\n\n\t\t// Re-derive the identity against the EFFECTIVE stack (explicit\n\t\t// `--stack`/`$DEVSTACK_STACK` > `config.stackName` > inferred) so\n\t\t// the roster lock, command channel, and container/router naming all\n\t\t// target the same stack the operator selected — matching what\n\t\t// `snapshot.ts` already does. Without this, an explicit `--stack`\n\t\t// would boot the supervisor under the config's `stackName` and a\n\t\t// concurrent default-stack `up` would falsely collide on the live\n\t\t// supervisor (`error: supervisor live for <app>/<stack>`, exit 40).\n\t\tconst effectiveIdentity = resolvedIdentityForStack(identity, stack);\n\t\tconst identityValue: Identity = identityValueFor(effectiveIdentity);\n\n\t\tconst appRoot = dirname(loaded.resolvedConfigPath);\n\t\tconst rendererMode = resolveUpRendererMode({\n\t\t\tcliRenderer: options.renderer,\n\t\t\tstackRenderer: stack.options.renderer,\n\t\t\tstdoutIsTty: options.stdoutIsTty,\n\t\t});\n\t\tconst substrateLayers = buildVerbLayers({\n\t\t\tidentity: identityValue,\n\t\t\tstack,\n\t\t\tappRoot,\n\t\t\truntimeRoot: effectiveIdentity.runtimeRoot,\n\t\t});\n\n\t\tconst program = Effect.gen(function* () {\n\t\t\tconst state = yield* makeProjectionRef();\n\t\t\tconst snapshot = yield* SnapshotOrchestratorService;\n\t\t\tconst fs = yield* FileSystem.FileSystem;\n\t\t\tconst snapshotCommandHandler = makeSnapshotCommandHandler({\n\t\t\t\tsnapshot,\n\t\t\t\tfs,\n\t\t\t\truntimeRoot: effectiveIdentity.runtimeRoot,\n\t\t\t});\n\t\t\tconst orchestratorSinks = yield* buildProductionOrchestratorSinks();\n\t\t\tconst postAcquireHook = yield* buildProductionPostAcquireHook({\n\t\t\t\textras: stack.options.extras,\n\t\t\t});\n\t\t\tyield* superviseStackEffect(\n\t\t\t\t{ _tag: 'Stack', members: stack.members, options: stack.options },\n\t\t\t\tidentityValue,\n\t\t\t\tstate,\n\t\t\t\t{\n\t\t\t\t\torchestratorSinks,\n\t\t\t\t\tcommandHandler: snapshotCommandHandler,\n\t\t\t\t\tpostAcquireHook,\n\t\t\t\t\textendContext: extendBuiltInPluginContext,\n\t\t\t\t\tbeforeInitialAcquire: (handle) =>\n\t\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\t\tconst stackPaths = yield* StackPathsService;\n\t\t\t\t\t\t\t// Reconcile any half-promoted snapshot restore from a\n\t\t\t\t\t\t\t// prior supervise (process hard-killed mid `tagImage`\n\t\t\t\t\t\t\t// loop, Docker daemon outage, etc.) BEFORE any plugin\n\t\t\t\t\t\t\t// acquire fires. The scanner is idempotent and a no-op\n\t\t\t\t\t\t\t// when no marker is present; partial recovery surfaces\n\t\t\t\t\t\t\t// via the returned summary's `stillPending` list which\n\t\t\t\t\t\t\t// we log so the operator can investigate.\n\t\t\t\t\t\t\tconst recovery = yield* snapshot.recoverPendingRestore.pipe(\n\t\t\t\t\t\t\t\tEffect.tapCause((cause) =>\n\t\t\t\t\t\t\t\t\tEffect.sync(() => {\n\t\t\t\t\t\t\t\t\t\tprocess.stderr.write(\n\t\t\t\t\t\t\t\t\t\t\t`snapshot recovery scan failed: ${Cause.pretty(cause as Cause.Cause<unknown>)}\\n`,\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\tEffect.catch(() => Effect.succeed(null)),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tif (recovery && !recovery.noMarker) {\n\t\t\t\t\t\t\t\tconst summary = `snapshot.recover-pending: inspected=${recovery.inspected} recovered=${recovery.recovered} stillPending=${recovery.stillPending.length} markerCleared=${recovery.markerCleared}`;\n\t\t\t\t\t\t\t\tprocess.stderr.write(`${summary}\\n`);\n\t\t\t\t\t\t\t\tif (recovery.stillPending.length > 0) {\n\t\t\t\t\t\t\t\t\tfor (const entry of recovery.stillPending) {\n\t\t\t\t\t\t\t\t\t\tprocess.stderr.write(\n\t\t\t\t\t\t\t\t\t\t\t` pending: ${entry.targetImageName} ← ${entry.stagedImageTag} (${entry.plugin}/${entry.role})\\n`,\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst commandChannel = yield* installCommandChannelBridge({\n\t\t\t\t\t\t\t\tstackRoot: stackPaths.stackRoot,\n\t\t\t\t\t\t\t\thandle,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tyield* installLiveSupervisorRoster({\n\t\t\t\t\t\t\t\tstackRoot: stackPaths.stackRoot,\n\t\t\t\t\t\t\t\tapp: String(identityValue.app),\n\t\t\t\t\t\t\t\tstack: String(identityValue.stack),\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tconst rendererEvents = yield* Queue.unbounded<EngineEvent>();\n\t\t\t\t\t\t\tconst renderer = makeTuiSurface({\n\t\t\t\t\t\t\t\tmode: rendererMode,\n\t\t\t\t\t\t\t\tpublishCommand: makeQueueCommandPublisher(handle.commands),\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tyield* Effect.addFinalizer(() =>\n\t\t\t\t\t\t\t\trenderer.flush.pipe(Effect.catch(() => Effect.void)),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tyield* Effect.forkScoped(\n\t\t\t\t\t\t\t\trenderer.mount(handle.state, Stream.fromQueue(rendererEvents)).pipe(\n\t\t\t\t\t\t\t\t\tEffect.catch((cause) =>\n\t\t\t\t\t\t\t\t\t\tEffect.sync(() => {\n\t\t\t\t\t\t\t\t\t\t\tprocess.stderr.write(`renderer failed: ${cause.detail ?? String(cause)}\\n`);\n\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tyield* Effect.forkScoped(\n\t\t\t\t\t\t\t\tpersistProjectionChanges(stackPaths.stackRoot, handle.state),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tyield* Effect.forkScoped(\n\t\t\t\t\t\t\t\tStream.fromQueue(handle.events).pipe(\n\t\t\t\t\t\t\t\t\tStream.runForEach((event) =>\n\t\t\t\t\t\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\t\t\t\t\t\tyield* Queue.offer(rendererEvents, event);\n\t\t\t\t\t\t\t\t\t\t\tyield* commandChannel.publishEvent(event);\n\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t).pipe(Effect.provide(layerBuiltInPluginRuntime(orchestratorSinks)));\n\t\t});\n\n\t\t// `Effect.matchCauseEffect` projects the inner program's\n\t\t// cause to a typed `CliError` outcome — `CliSupervisorLiveError`\n\t\t// when the roster-claim path failed, otherwise a wrapped\n\t\t// `CliInternalError` whose `cause` carries the cascade for the\n\t\t// envelope renderer's `error.chain[]`.\n\t\treturn yield* program.pipe(\n\t\t\tEffect.provide(substrateLayers),\n\t\t\tEffect.provide(Logger.layer([])),\n\t\t\tEffect.matchCauseEffect({\n\t\t\t\tonFailure: (cause): Effect.Effect<CommandResult, CliError> => {\n\t\t\t\t\tconst live = findCliSupervisorLiveError(cause as Cause.Cause<unknown>);\n\t\t\t\t\tif (live !== null) {\n\t\t\t\t\t\treturn Effect.fail(live);\n\t\t\t\t\t}\n\t\t\t\t\treturn Effect.fail(\n\t\t\t\t\t\tnew CliInternalError({\n\t\t\t\t\t\t\tmessage: 'stack failed',\n\t\t\t\t\t\t\tcause: Cause.pretty(cause as Cause.Cause<unknown>),\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\tonSuccess: (): Effect.Effect<CommandResult, CliError> =>\n\t\t\t\t\tEffect.succeed({ exitCode: ExitCode.OK }),\n\t\t\t}),\n\t\t);\n\t});\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"up.mjs","names":["resolvePath"],"sources":["../../../src/cli/wirings/up.ts"],"sourcesContent":["// `devstack up` verb wiring.\n//\n// Wires the substrate Layer stack, supervisor, attached renderer, and\n// in-process TUI command queue. The Effect runs as the outer Node fiber\n// so SIGINT reaches scope finalizers (see surfaces/cli/index.ts\n// architecture invariant).\n//\n// Logger layer: `Logger.layer([])` (silent). `up` owns the TUI, which is\n// the operator-facing output channel; routing structured `Effect.log*`\n// records to stderr would scribble on top of the live ink renderer in\n// human mode and would duplicate the structured event stream the plain\n// renderer already emits in non-TTY mode. The sibling `apply` verb (no\n// TUI) uses `Logger.consolePretty()` because its consumer is CI.\n\nimport { dirname, resolve as resolvePath } from 'node:path';\n\nimport { Cause, Effect, Exit, FileSystem, Queue, Scope, Stream } from 'effect';\n\nimport type { Identity } from '../../substrate/identity.ts';\nimport type { EngineEvent } from '../../substrate/events.ts';\nimport { StackPathsService } from '../../substrate/runtime/paths.ts';\nimport {\n\tclaim,\n\theartbeatFiber,\n\trelease,\n\ttype SupervisedStack,\n\ttype SupervisorCommandHandler,\n} from '../../substrate/runtime/index.ts';\nimport {\n\tcollectLifecyclePruneInventory,\n\tdefaultLifecyclePruneSelection,\n\tDEFAULT_LIFECYCLE_PRUNE_RESOURCES,\n\trunLifecyclePrune,\n} from '../../orchestrators/lifecycle-prune/index.ts';\nimport {\n\tcomputeSnapshotGraphInputFromStack,\n\trecoverInterruptedRestore,\n\tSnapshotOrchestratorService,\n} from '../../orchestrators/snapshot/index.ts';\nimport type { Stack } from '../../api/define-devstack.ts';\nimport {\n\trunStackWithBoot,\n\ttype CommandHandlerFactory,\n\ttype RunStackBootBag,\n} from '../../api/run-stack-internal.ts';\nimport type { BootError } from '../../api/run-stack.ts';\nimport {\n\ttype CliError,\n\tCliInternalError,\n\tCliSnapshotNotFoundError,\n\tCliSupervisorLiveError,\n\tCliUsageError,\n\ttype GlobalFlags,\n} from '../../surfaces/cli/index.ts';\nimport type { CommandResult } from '../../surfaces/cli/commands/index.ts';\nimport { ExitCode } from '../../surfaces/cli/sysexits.ts';\nimport { makeTuiSurface } from '../../surfaces/tui/index.ts';\nimport type { LoadedConfig } from '../../surfaces/cli/commands/config-loader.ts';\n\nimport { cliErrorFromConfigExit } from '../bail.ts';\nimport { makeQueueCommandPublisher, resolveUpRendererMode } from '../up-lifecycle.ts';\nimport { makeConfigLoader } from './config-loader.ts';\nimport { makeSnapshotReader } from '../snapshot-reader.ts';\nimport {\n\tfindCliSupervisorLiveError,\n\tidentityValueFor,\n\tresolvedIdentityForStack,\n\ttype ResolvedIdentity,\n} from './identity.ts';\nimport { installCommandChannelBridge } from './up-ipc.ts';\nimport { provideFileSystem } from './provide-file-system.ts';\nimport { readDevstackVersion } from './read-devstack-version.ts';\n\nconst rosterPathsFor = (stackRoot: string) => ({\n\tstackLockFile: resolvePath(stackRoot, 'stack.lock'),\n\trosterFile: resolvePath(stackRoot, 'roster.json'),\n});\n\n// -----------------------------------------------------------------------------\n// Supervisor command handler — snapshot/wipe/prune injected dispatch\n// -----------------------------------------------------------------------------\n\n/** Build the snapshot/wipe/prune `commandHandler` as a FACTORY the seam\n * resolves against its LIVE substrate (see `CommandHandlerFactory`). The\n * factory yields the seam's `SnapshotOrchestratorService` + `FileSystem` —\n * the SAME orchestrator instance the supervisor's contribution dispatcher\n * registers live participants on, so an operator `snapshot save` captures\n * real chain/blob/db state, not an empty set — and returns a handler\n * (R = `never`, as the command loop requires) that closes over them\n * directly. No Deferred hand-off: the seam runs this factory before\n * `startSupervisor` consumes the handler. */\nconst makeSnapshotCommandHandler = (params: {\n\treadonly runtimeRoot: string;\n\treadonly stack: SupervisedStack;\n\treadonly devstackVersion: string;\n}): CommandHandlerFactory =>\n\tEffect.gen(function* () {\n\t\tconst snapshot = yield* SnapshotOrchestratorService;\n\t\tconst fs = yield* FileSystem.FileSystem;\n\t\tconst computeGraphInput = computeSnapshotGraphInputFromStack({\n\t\t\tstack: params.stack,\n\t\t\tdevstackVersion: params.devstackVersion,\n\t\t});\n\t\tconst handler: SupervisorCommandHandler = (cmd) => {\n\t\t\tswitch (cmd.tag) {\n\t\t\t\tcase 'snapshot.capture':\n\t\t\t\t\t// The L3 capture is the bounce's gather → stop → commit → retag\n\t\t\t\t\t// → hard-rm half; the RESUME (recreate + wait-write-ready) is the\n\t\t\t\t\t// command-loop's converge after this handler succeeds (it owns the\n\t\t\t\t\t// graph), mirroring restore. So no `resume` is injected here.\n\t\t\t\t\treturn provideFileSystem(\n\t\t\t\t\t\tfs,\n\t\t\t\t\t\tcomputeGraphInput.pipe(\n\t\t\t\t\t\t\tEffect.flatMap((graphInput) =>\n\t\t\t\t\t\t\t\tsnapshot.capture({\n\t\t\t\t\t\t\t\t\tid: cmd.snapshotId,\n\t\t\t\t\t\t\t\t\t...(cmd.name === undefined ? {} : { label: cmd.name }),\n\t\t\t\t\t\t\t\t\tgraphInput,\n\t\t\t\t\t\t\t\t\t...(cmd.replaceExisting === true ? { replaceExistingLabel: true } : {}),\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t).pipe(\n\t\t\t\t\t\tEffect.map((meta) => [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttag: 'snapshot.captured',\n\t\t\t\t\t\t\t\tsnapshotId: meta.id,\n\t\t\t\t\t\t\t\t...(meta.label === null ? {} : { name: meta.label }),\n\t\t\t\t\t\t\t\tat: Date.now(),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t]),\n\t\t\t\t\t);\n\t\t\t\tcase 'snapshot.restore':\n\t\t\t\t\treturn provideFileSystem(\n\t\t\t\t\t\tfs,\n\t\t\t\t\t\tcomputeGraphInput.pipe(\n\t\t\t\t\t\t\tEffect.flatMap((currentGraphInput) =>\n\t\t\t\t\t\t\t\tsnapshot.restore({\n\t\t\t\t\t\t\t\t\tid: cmd.snapshotId,\n\t\t\t\t\t\t\t\t\tcurrentGraphInput,\n\t\t\t\t\t\t\t\t\tgraphInputMismatchPolicy: 'warn',\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t).pipe(\n\t\t\t\t\t\tEffect.map((meta) => [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttag: 'snapshot.restored',\n\t\t\t\t\t\t\t\tsnapshotId: meta.id,\n\t\t\t\t\t\t\t\tat: Date.now(),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t]),\n\t\t\t\t\t);\n\t\t\t\tcase 'snapshot.list':\n\t\t\t\t\treturn provideFileSystem(fs, snapshot.list).pipe(Effect.as([]));\n\t\t\t\tcase 'snapshot.delete':\n\t\t\t\t\treturn provideFileSystem(fs, snapshot.delete(cmd.snapshotId)).pipe(Effect.as([]));\n\t\t\t\tcase 'wipe.requested':\n\t\t\t\t\treturn provideFileSystem(fs, snapshot.wipe({})).pipe(Effect.as([]));\n\t\t\t\tcase 'prune.requested':\n\t\t\t\t\t// Route to the same orchestrator the offline `devstack prune`\n\t\t\t\t\t// verb uses (`runLifecyclePrune`), NOT the snapshot-orchestrator\n\t\t\t\t\t// prune (which only cleans the snapshot catalog and would leave\n\t\t\t\t\t// stale containers/networks/volumes/images behind for an attached\n\t\t\t\t\t// supervisor — silent under-prune is the bug we're closing).\n\t\t\t\t\t// Live supervisor implies the current stack's group is live and\n\t\t\t\t\t// therefore excluded from the default selection — exactly the\n\t\t\t\t\t// invariant the live-attached `prune` needs (operator can prune\n\t\t\t\t\t// sibling stacks under the same Docker daemon without touching\n\t\t\t\t\t// the running one).\n\t\t\t\t\treturn collectLifecyclePruneInventory({ runtimeRoot: params.runtimeRoot }).pipe(\n\t\t\t\t\t\tEffect.flatMap((inventory) =>\n\t\t\t\t\t\t\trunLifecyclePrune(\n\t\t\t\t\t\t\t\t{ runtimeRoot: params.runtimeRoot },\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tgroupKeys: defaultLifecyclePruneSelection(\n\t\t\t\t\t\t\t\t\t\tinventory,\n\t\t\t\t\t\t\t\t\t\tDEFAULT_LIFECYCLE_PRUNE_RESOURCES,\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\tresources: DEFAULT_LIFECYCLE_PRUNE_RESOURCES,\n\t\t\t\t\t\t\t\t\tdryRun: false,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t\tEffect.as([]),\n\t\t\t\t\t);\n\t\t\t\tdefault:\n\t\t\t\t\treturn Effect.succeed([]);\n\t\t\t}\n\t\t};\n\t\treturn handler;\n\t});\n\nconst installLiveSupervisorRoster = (params: {\n\treadonly stackRoot: string;\n\treadonly app: string;\n\treadonly stack: string;\n}): Effect.Effect<void, unknown, Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\tconst paths = rosterPathsFor(params.stackRoot);\n\t\tconst claimed = yield* claim(paths);\n\t\tif (!claimed.soleHolder) {\n\t\t\tyield* release(paths).pipe(Effect.catch(() => Effect.void));\n\t\t\treturn yield* Effect.fail(\n\t\t\t\tnew CliSupervisorLiveError({\n\t\t\t\t\tapp: params.app,\n\t\t\t\t\tstack: params.stack,\n\t\t\t\t\thint: 'use `devstack apply` from another shell, or choose a different --stack name',\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\tyield* Effect.addFinalizer(() => release(paths).pipe(Effect.catch(() => Effect.void)));\n\t\tyield* Effect.forkScoped(heartbeatFiber(paths));\n\t});\n\n// -----------------------------------------------------------------------------\n// CLI boot bundle — the `commandHandler` + `boot` hooks the seam consumes\n// -----------------------------------------------------------------------------\n\nexport interface UpBootBundleInput {\n\treadonly stack: SupervisedStack;\n\treadonly identityValue: Identity;\n\treadonly runtimeRoot: string;\n\treadonly devstackVersion: string;\n\treadonly rendererMode: import('../../surfaces/tui/mode-detect.ts').RendererMode;\n\treadonly startFromSnapshot?: {\n\t\treadonly id: string;\n\t\treadonly stalePolicy: 'warn' | 'block' | 'clean-start';\n\t};\n\treadonly snapshotCache?: {\n\t\treadonly name: string;\n\t\treadonly existingSnapshotId?: string;\n\t};\n}\n\nexport interface UpBootBundle {\n\treadonly commandHandler: CommandHandlerFactory;\n\treadonly boot: RunStackBootBag;\n}\n\ntype StartFromSnapshot = NonNullable<UpBootBundleInput['startFromSnapshot']>;\ntype SnapshotCache = NonNullable<UpBootBundleInput['snapshotCache']>;\n\n/**\n * Build the CLI's boot concerns as a VALUE bundle the seam consumes — the\n * snapshot/wipe/prune `commandHandler` plus the `beforeInitialAcquire`\n * (recover → IPC bridge → roster claim → TUI mount + event tee). Pure\n * value construction: no substrate is touched here; the hooks pull the\n * SEAM's substrate services at boot (they run inside the supervised scope).\n *\n * Extracted from `runUpLive` so the Docker-free CLI-boot smoke test drives\n * the EXACT bundle the production path feeds `runStackWithBoot` — the only\n * non-e2e gate on the cutover (`main.test.ts` only runs `up --help`).\n */\nexport const buildUpBootBundle = (input: UpBootBundleInput): UpBootBundle => {\n\tconst {\n\t\tstack,\n\t\tidentityValue,\n\t\truntimeRoot,\n\t\tdevstackVersion,\n\t\trendererMode,\n\t\tstartFromSnapshot,\n\t\tsnapshotCache,\n\t} = input;\n\n\tconst computeGraphInput = computeSnapshotGraphInputFromStack({ stack, devstackVersion });\n\tlet refreshSnapshotCache =\n\t\tsnapshotCache !== undefined && snapshotCache.existingSnapshotId === undefined;\n\n\t// The snapshot/wipe/prune `commandHandler` — a FACTORY the seam resolves\n\t// against its LIVE substrate (the seam runs it before `startSupervisor`\n\t// consumes the handler). The factory closes over the seam's ONE\n\t// `SnapshotOrchestratorService` instance — the same one the supervisor's\n\t// contribution dispatcher registers live participants on — so an operator\n\t// `snapshot save` captures the LIVE chain/blob/db state, not an empty set\n\t// off a sibling orchestrator. No Deferred hand-off.\n\tconst commandHandler = makeSnapshotCommandHandler({ runtimeRoot, stack, devstackVersion });\n\n\tconst boot: RunStackBootBag = {\n\t\tdevstackVersion,\n\t\tbeforeInitialAcquire: (h) =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\t// The seam's substrate services — the SAME instances the\n\t\t\t\t// `commandHandler` factory closed over and the supervisor uses,\n\t\t\t\t// driven here for the recover/IPC/roster/TUI work.\n\t\t\t\tconst snapshot = yield* SnapshotOrchestratorService;\n\t\t\t\tconst fs = yield* FileSystem.FileSystem;\n\t\t\t\tconst stackPaths = yield* StackPathsService;\n\t\t\t\t// Resume any restore interrupted by a hard kill / power-loss\n\t\t\t\t// between the atomic swap and the end of the image-promotion\n\t\t\t\t// handoff (the interrupted-restore sentinel rode the swap into\n\t\t\t\t// the live root and was never cleared). Runs BEFORE any plugin\n\t\t\t\t// acquire so a half-promoted image set is reconciled before any\n\t\t\t\t// L2 lookup observes the runtime root. No-op when the sentinel\n\t\t\t\t// is absent (the clean-boot case); idempotent re-run of restore\n\t\t\t\t// when present.\n\t\t\t\t//\n\t\t\t\t// `restore({ id })` passes NO participants on purpose: this\n\t\t\t\t// hook fires BEFORE the initial acquire registers any snapshot\n\t\t\t\t// participant, so there is no live stack to contribute identity.\n\t\t\t\t// `runRestore` reads the empty participant set as \"no live\n\t\t\t\t// stack\" and skips ONLY the cross-plugin contribution guard\n\t\t\t\t// (the runtime + snapshot-emptiness guards still fire). With a\n\t\t\t\t// participants-required guard this recovery could never clear\n\t\t\t\t// the sentinel — it failed `IdentityMissingLive` every boot.\n\t\t\t\tyield* recoverInterruptedRestore({\n\t\t\t\t\tliveRoot: stackPaths.stackRoot,\n\t\t\t\t\trestoreSnapshot: (id) =>\n\t\t\t\t\t\tcomputeGraphInput.pipe(\n\t\t\t\t\t\t\tEffect.flatMap((currentGraphInput) =>\n\t\t\t\t\t\t\t\tsnapshot.restore({\n\t\t\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\t\t\tcurrentGraphInput,\n\t\t\t\t\t\t\t\t\tgraphInputMismatchPolicy: 'warn',\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t});\n\t\t\t\tif (snapshotCache !== undefined) {\n\t\t\t\t\tif (snapshotCache.existingSnapshotId === undefined) {\n\t\t\t\t\t\tyield* Effect.logWarning(\n\t\t\t\t\t\t\t`snapshot cache ${snapshotCache.name} was not found; boot will refresh it`,\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst graphInput = yield* computeGraphInput;\n\t\t\t\t\t\tconst catalog = yield* provideFileSystem(fs, snapshot.list);\n\t\t\t\t\t\tconst entry = catalog.find(\n\t\t\t\t\t\t\t(snapshotEntry) => snapshotEntry.id === snapshotCache.existingSnapshotId,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst snapshotGraphInputId = entry?.metadata?.graphInput.graphInputId ?? null;\n\t\t\t\t\t\tif (snapshotGraphInputId === graphInput.graphInputId) {\n\t\t\t\t\t\t\trefreshSnapshotCache = false;\n\t\t\t\t\t\t\tyield* provideFileSystem(\n\t\t\t\t\t\t\t\tfs,\n\t\t\t\t\t\t\t\tsnapshot.restore({\n\t\t\t\t\t\t\t\t\tid: snapshotCache.existingSnapshotId,\n\t\t\t\t\t\t\t\t\tcurrentGraphInput: graphInput,\n\t\t\t\t\t\t\t\t\tgraphInputMismatchPolicy: 'block',\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\trefreshSnapshotCache = true;\n\t\t\t\t\t\t\tyield* Effect.logWarning(\n\t\t\t\t\t\t\t\t`snapshot cache ${snapshotCache.name} graph input is stale or unreadable; boot will refresh it`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (startFromSnapshot !== undefined) {\n\t\t\t\t\tconst graphInput = yield* computeGraphInput;\n\t\t\t\t\tif (startFromSnapshot.stalePolicy === 'clean-start') {\n\t\t\t\t\t\tconst catalog = yield* provideFileSystem(fs, snapshot.list);\n\t\t\t\t\t\tconst entry = catalog.find(\n\t\t\t\t\t\t\t(snapshotEntry) => snapshotEntry.id === startFromSnapshot.id,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst snapshotGraphInputId = entry?.metadata?.graphInput.graphInputId ?? null;\n\t\t\t\t\t\tif (snapshotGraphInputId !== graphInput.graphInputId) {\n\t\t\t\t\t\t\tyield* Effect.logWarning(\n\t\t\t\t\t\t\t\t`snapshot ${startFromSnapshot.id} graph input is stale; clean-start policy skipped restore`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tyield* provideFileSystem(\n\t\t\t\t\t\t\t\tfs,\n\t\t\t\t\t\t\t\tsnapshot.restore({\n\t\t\t\t\t\t\t\t\tid: startFromSnapshot.id,\n\t\t\t\t\t\t\t\t\tcurrentGraphInput: graphInput,\n\t\t\t\t\t\t\t\t\tgraphInputMismatchPolicy: 'block',\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tyield* provideFileSystem(\n\t\t\t\t\t\t\tfs,\n\t\t\t\t\t\t\tsnapshot.restore({\n\t\t\t\t\t\t\t\tid: startFromSnapshot.id,\n\t\t\t\t\t\t\t\tcurrentGraphInput: graphInput,\n\t\t\t\t\t\t\t\tgraphInputMismatchPolicy: startFromSnapshot.stalePolicy,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst commandChannel = yield* installCommandChannelBridge({\n\t\t\t\t\tstackRoot: stackPaths.stackRoot,\n\t\t\t\t\thandle: h.supervisor,\n\t\t\t\t});\n\t\t\t\tyield* installLiveSupervisorRoster({\n\t\t\t\t\tstackRoot: stackPaths.stackRoot,\n\t\t\t\t\tapp: String(identityValue.app),\n\t\t\t\t\tstack: String(identityValue.stack),\n\t\t\t\t});\n\t\t\t\tconst rendererEvents = yield* Queue.unbounded<EngineEvent>();\n\t\t\t\tconst renderer = makeTuiSurface({\n\t\t\t\t\tmode: rendererMode,\n\t\t\t\t\tpublishCommand: makeQueueCommandPublisher(h.commands),\n\t\t\t\t\t// Opt-in quiet plain stream (readiness/endpoint/codegen\n\t\t\t\t\t// milestones + warns/errors only). Set by embedded consumers\n\t\t\t\t\t// that pipe `devstack up` output through another tool — the\n\t\t\t\t\t// Playwright `webServer` (see `devstackPlaywrightWebServer`)\n\t\t\t\t\t// — where the full per-event firehose reads as `[WebServer]`\n\t\t\t\t\t// noise. No effect on a TTY (`ink`) or normal CI `plain` run.\n\t\t\t\t\tquiet: process.env.DEVSTACK_PLAIN_QUIET === '1',\n\t\t\t\t});\n\t\t\t\tyield* Effect.addFinalizer(() => renderer.flush.pipe(Effect.catch(() => Effect.void)));\n\t\t\t\tyield* Effect.forkScoped(\n\t\t\t\t\trenderer.mount(h.state, Stream.fromQueue(rendererEvents)).pipe(\n\t\t\t\t\t\tEffect.catch((cause) =>\n\t\t\t\t\t\t\tEffect.sync(() => {\n\t\t\t\t\t\t\t\tprocess.stderr.write(`renderer failed: ${cause.detail ?? String(cause)}\\n`);\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tyield* Effect.forkScoped(\n\t\t\t\t\th.events.pipe(\n\t\t\t\t\t\tStream.runForEach((event) =>\n\t\t\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\t\t\tyield* Queue.offer(rendererEvents, event);\n\t\t\t\t\t\t\t\tyield* commandChannel.publishEvent(event);\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}),\n\t\twithinScope: (h) =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tif (snapshotCache === undefined || !refreshSnapshotCache) return;\n\t\t\t\tyield* h.supervisor.runCommand({\n\t\t\t\t\ttag: 'snapshot.capture',\n\t\t\t\t\tname: snapshotCache.name,\n\t\t\t\t\treplaceExisting: true,\n\t\t\t\t});\n\t\t\t}),\n\t};\n\n\treturn { commandHandler, boot };\n};\n\n/**\n * Run `devstack up`. Wires the substrate Layer stack, supervisor,\n * attached renderer, and in-process TUI command queue. The Effect runs\n * as the outer Node fiber so SIGINT reaches scope finalizers.\n *\n * Returns a typed `CommandResult` / fails with a typed `CliError` so\n * the dispatcher's `emitFailure` renders the envelope (JSON mode) or\n * human-mode stderr line. Wirings MUST NOT write raw bytes to\n * `process.stderr` or mutate `process.exitCode` for terminal failures —\n * the dispatcher owns the projection.\n */\nexport const runUpLive = (\n\tconfigPath: string | undefined,\n\tidentity: ResolvedIdentity,\n\toptions: {\n\t\treadonly renderer: GlobalFlags['renderer'];\n\t\treadonly stdoutIsTty: boolean;\n\t\treadonly fromSnapshot?: string;\n\t\treadonly snapshotCache?: string;\n\t\treadonly snapshotStalePolicy?: GlobalFlags['snapshotStalePolicy'];\n\t},\n): Effect.Effect<CommandResult, CliError> => {\n\tconst loader = makeConfigLoader();\n\treturn Effect.gen(function* () {\n\t\tif (options.fromSnapshot !== undefined && options.snapshotCache !== undefined) {\n\t\t\treturn yield* Effect.fail(\n\t\t\t\tnew CliUsageError({\n\t\t\t\t\tmessage: '--snapshot-cache cannot be combined with --from-snapshot',\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\tif (options.snapshotCache !== undefined && options.snapshotStalePolicy !== undefined) {\n\t\t\treturn yield* Effect.fail(\n\t\t\t\tnew CliUsageError({\n\t\t\t\t\tmessage: '--snapshot-stale is only valid with --from-snapshot',\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\tconst loadExit = yield* Effect.exit(loader.load(configPath));\n\t\tif (Exit.isFailure(loadExit)) {\n\t\t\treturn yield* Effect.fail(cliErrorFromConfigExit(loadExit));\n\t\t}\n\t\tconst loaded = loadExit.value;\n\t\tconst publicStack = (\n\t\t\tloaded as LoadedConfig & {\n\t\t\t\treadonly stack: Stack<SupervisedStack['members']>;\n\t\t\t}\n\t\t).stack;\n\t\tconst stack = (loaded as LoadedConfig & { readonly engine: SupervisedStack }).engine;\n\n\t\t// Re-derive the identity against the EFFECTIVE stack (explicit\n\t\t// `--stack`/`$DEVSTACK_STACK` > `config.stackName` > inferred) so\n\t\t// the roster lock, command channel, and container/router naming all\n\t\t// target the same stack the operator selected — matching what\n\t\t// `snapshot.ts` already does. Without this, an explicit `--stack`\n\t\t// would boot the supervisor under the config's `stackName` and a\n\t\t// concurrent default-stack `up` would falsely collide on the live\n\t\t// supervisor (`error: supervisor live for <app>/<stack>`, exit 40).\n\t\tconst effectiveIdentity = resolvedIdentityForStack(identity, stack);\n\t\tconst identityValue: Identity = identityValueFor(effectiveIdentity);\n\t\tconst appRoot = dirname(loaded.resolvedConfigPath);\n\n\t\tconst devstackVersion = readDevstackVersion({ fallback: '0.0.0' });\n\t\tconst rendererMode = resolveUpRendererMode({\n\t\t\tcliRenderer: options.renderer,\n\t\t\tstackRenderer: stack.options.renderer,\n\t\t\tstdoutIsTty: options.stdoutIsTty,\n\t\t});\n\t\tlet startFromSnapshot: StartFromSnapshot | undefined;\n\t\tlet snapshotCache: SnapshotCache | undefined;\n\t\tif (options.fromSnapshot !== undefined) {\n\t\t\tconst resolved = yield* makeSnapshotReader({ stackRoot: effectiveIdentity.stackRoot })\n\t\t\t\t.resolve(options.fromSnapshot)\n\t\t\t\t.pipe(\n\t\t\t\t\tEffect.mapError(\n\t\t\t\t\t\t(cause) =>\n\t\t\t\t\t\t\tnew CliInternalError({\n\t\t\t\t\t\t\t\tmessage: 'snapshot lookup failed',\n\t\t\t\t\t\t\t\tcause,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\tswitch (resolved.tag) {\n\t\t\t\tcase 'found':\n\t\t\t\t\tstartFromSnapshot = {\n\t\t\t\t\t\tid: resolved.entry.snapshotId,\n\t\t\t\t\t\tstalePolicy: options.snapshotStalePolicy ?? 'warn',\n\t\t\t\t\t};\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'not-found':\n\t\t\t\t\treturn yield* Effect.fail(\n\t\t\t\t\t\tnew CliSnapshotNotFoundError({ snapshotRef: options.fromSnapshot }),\n\t\t\t\t\t);\n\t\t\t\tcase 'ambiguous':\n\t\t\t\t\treturn yield* Effect.fail(\n\t\t\t\t\t\tnew CliUsageError({\n\t\t\t\t\t\t\tmessage: `snapshot reference is ambiguous: ${resolved.snapshotRef}`,\n\t\t\t\t\t\t\thint: `matches: ${resolved.matches.map((entry) => entry.snapshotId).join(', ')}`,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tif (options.snapshotCache !== undefined) {\n\t\t\tconst resolved = yield* makeSnapshotReader({ stackRoot: effectiveIdentity.stackRoot })\n\t\t\t\t.resolve(options.snapshotCache)\n\t\t\t\t.pipe(\n\t\t\t\t\tEffect.mapError(\n\t\t\t\t\t\t(cause) =>\n\t\t\t\t\t\t\tnew CliInternalError({\n\t\t\t\t\t\t\t\tmessage: 'snapshot lookup failed',\n\t\t\t\t\t\t\t\tcause,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\tswitch (resolved.tag) {\n\t\t\t\tcase 'found':\n\t\t\t\t\tsnapshotCache = {\n\t\t\t\t\t\tname: options.snapshotCache,\n\t\t\t\t\t\texistingSnapshotId: resolved.entry.snapshotId,\n\t\t\t\t\t};\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'not-found':\n\t\t\t\t\tsnapshotCache = { name: options.snapshotCache };\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'ambiguous':\n\t\t\t\t\treturn yield* Effect.fail(\n\t\t\t\t\t\tnew CliUsageError({\n\t\t\t\t\t\t\tmessage: `snapshot reference is ambiguous: ${resolved.snapshotRef}`,\n\t\t\t\t\t\t\thint: `matches: ${resolved.matches.map((entry) => entry.snapshotId).join(', ')}`,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// The CLI concerns (snapshot/wipe/prune `commandHandler` + the\n\t\t// recover/roster/IPC/TUI boot hooks) as a value bundle — the\n\t\t// EXACT thing the seam consumes, extracted so the Docker-free CLI-boot\n\t\t// smoke test can drive the real bundle (see `test/cli/up-boot-smoke`).\n\t\tconst { commandHandler, boot } = buildUpBootBundle({\n\t\t\tstack,\n\t\t\tidentityValue,\n\t\t\truntimeRoot: effectiveIdentity.runtimeRoot,\n\t\t\tdevstackVersion,\n\t\t\trendererMode,\n\t\t\t...(startFromSnapshot === undefined ? {} : { startFromSnapshot }),\n\t\t\t...(snapshotCache === undefined ? {} : { snapshotCache }),\n\t\t});\n\n\t\t// The ONE boot seam. `runStackWithBoot` owns the substrate Layer\n\t\t// composition, the contribution dispatcher + post-acquire hook +\n\t\t// `extendContext` assembly, the projection ref, and the\n\t\t// forkDetach/Deferred boot lifecycle — `up` no longer forks its own\n\t\t// parallel orchestration. The CLI concerns (recover/roster/IPC/TUI\n\t\t// + snapshot handler) are passed as injected hooks + `commandHandler`.\n\t\tconst handle = runStackWithBoot(publicStack, {\n\t\t\tidentity: {\n\t\t\t\tapp: String(identityValue.app),\n\t\t\t\tstack: String(identityValue.stack),\n\t\t\t\tnetwork: String(identityValue.network),\n\t\t\t},\n\t\t\tappRoot,\n\t\t\truntimeRoot: effectiveIdentity.runtimeRoot,\n\t\t\tcodegen: stack.options.codegen,\n\t\t\tcommandHandler,\n\t\t\tboot,\n\t\t});\n\n\t\t// The outer fiber BLOCKS on `awaitShutdown` so SIGINT reaches the\n\t\t// supervisor's in-scope signal handler (forked inside `startSupervisor`)\n\t\t// and drives teardown through the command-channel/latch — the same path\n\t\t// the CLI used as the outer fiber before the cutover. `Effect.scoped`\n\t\t// owns the supervised scope so the TUI flush finalizer + roster release\n\t\t// run on scope close.\n\t\t//\n\t\t// Errors project through the seam's DISCRIMINATED channels — no\n\t\t// `matchCauseEffect` re-discrimination:\n\t\t// - `handle.start` fails ⇒ BOOT-time `BootError`. Extract a\n\t\t// `CliSupervisorLiveError` (roster-claim loss) for exit 40; else\n\t\t// wrap as `CliInternalError`.\n\t\t// - `handle.awaitShutdown` fails ⇒ MID-RUN cause. Wrap as\n\t\t// `CliInternalError` (boot already succeeded by then).\n\t\treturn yield* Effect.scoped(\n\t\t\tEffect.gen(function* () {\n\t\t\t\tyield* handle.start.pipe(\n\t\t\t\t\tEffect.catch((bootError: BootError) => {\n\t\t\t\t\t\tconst live = findCliSupervisorLiveError(bootError.cause);\n\t\t\t\t\t\treturn Effect.fail(\n\t\t\t\t\t\t\tlive ??\n\t\t\t\t\t\t\t\tnew CliInternalError({\n\t\t\t\t\t\t\t\t\tmessage: 'stack failed',\n\t\t\t\t\t\t\t\t\tcause: Cause.pretty(bootError.cause),\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tyield* handle.awaitShutdown.pipe(\n\t\t\t\t\tEffect.catchCause(\n\t\t\t\t\t\t(cause): Effect.Effect<never, CliError> =>\n\t\t\t\t\t\t\tEffect.fail(\n\t\t\t\t\t\t\t\tnew CliInternalError({\n\t\t\t\t\t\t\t\t\tmessage: 'stack failed',\n\t\t\t\t\t\t\t\t\tcause: Cause.pretty(cause as Cause.Cause<unknown>),\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\treturn { exitCode: ExitCode.OK } satisfies CommandResult;\n\t\t\t}),\n\t\t);\n\t});\n};\n"],"mappings":"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"}
|
|
@@ -2,8 +2,8 @@ import { SnapshotOrchestratorService } from "../../orchestrators/snapshot/servic
|
|
|
2
2
|
import "../../orchestrators/snapshot/index.mjs";
|
|
3
3
|
import { removeRouterDispatchFilesForStack } from "../../orchestrators/router/cleanup.mjs";
|
|
4
4
|
import { ensureNoLiveSupervisor, identityValueFor } from "./identity.mjs";
|
|
5
|
-
import { buildDirectSnapshotLayers } from "./build-verb-layers.mjs";
|
|
6
5
|
import { provideFileSystem } from "./provide-file-system.mjs";
|
|
6
|
+
import { buildDirectSnapshotLayers } from "../../orchestrators/layers.mjs";
|
|
7
7
|
import { Effect, FileSystem, Logger } from "effect";
|
|
8
8
|
//#region src/cli/wirings/wipe.ts
|
|
9
9
|
const runWipeDirect = (identity) => Effect.gen(function* () {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wipe.mjs","names":[],"sources":["../../../src/cli/wirings/wipe.ts"],"sourcesContent":["// `devstack wipe` verb wiring — direct/offline path.\n//\n// Refuses to run when a supervisor owns the stack (the operator must\n// shut down `devstack up` first). When safe, drains the snapshot\n// catalog AND removes any router-dispatch files this stack contributed\n// so the router doesn't keep referencing endpoints that no longer\n// exist on disk.\n\nimport { Effect, FileSystem, Logger } from 'effect';\n\nimport {\n\tSnapshotOrchestratorService,\n\ttype WipeTargets,\n} from '../../orchestrators/snapshot/index.ts';\nimport { removeRouterDispatchFilesForStack } from '../../orchestrators/router/cleanup.ts';\n\nimport { ensureNoLiveSupervisor, identityValueFor, type ResolvedIdentity } from './identity.ts';\nimport { buildDirectSnapshotLayers } from '
|
|
1
|
+
{"version":3,"file":"wipe.mjs","names":[],"sources":["../../../src/cli/wirings/wipe.ts"],"sourcesContent":["// `devstack wipe` verb wiring — direct/offline path.\n//\n// Refuses to run when a supervisor owns the stack (the operator must\n// shut down `devstack up` first). When safe, drains the snapshot\n// catalog AND removes any router-dispatch files this stack contributed\n// so the router doesn't keep referencing endpoints that no longer\n// exist on disk.\n\nimport { Effect, FileSystem, Logger } from 'effect';\n\nimport {\n\tSnapshotOrchestratorService,\n\ttype WipeTargets,\n} from '../../orchestrators/snapshot/index.ts';\nimport { removeRouterDispatchFilesForStack } from '../../orchestrators/router/cleanup.ts';\n\nimport { ensureNoLiveSupervisor, identityValueFor, type ResolvedIdentity } from './identity.ts';\nimport { buildDirectSnapshotLayers } from '../../orchestrators/layers.ts';\nimport { provideFileSystem } from './provide-file-system.ts';\n\nexport const runWipeDirect = (identity: ResolvedIdentity): Effect.Effect<void, unknown> =>\n\tEffect.gen(function* () {\n\t\tyield* ensureNoLiveSupervisor(identity, 'shut down the attached `devstack up` session first');\n\t\tconst program = Effect.gen(function* () {\n\t\t\tconst snapshot = yield* SnapshotOrchestratorService;\n\t\t\tconst fs = yield* FileSystem.FileSystem;\n\t\t\tyield* provideFileSystem(fs, snapshot.wipe({}));\n\t\t\tyield* removeRouterDispatchFilesForStack({\n\t\t\t\truntimeRoot: identity.runtimeRoot,\n\t\t\t\tapp: identity.app,\n\t\t\t\tstack: identity.stack,\n\t\t\t});\n\t\t});\n\t\treturn yield* program.pipe(\n\t\t\tEffect.provide(\n\t\t\t\tbuildDirectSnapshotLayers({\n\t\t\t\t\tidentity: identityValueFor(identity),\n\t\t\t\t\truntimeRoot: identity.runtimeRoot,\n\t\t\t\t}),\n\t\t\t),\n\t\t\tEffect.provide(Logger.layer([Logger.consolePretty()])),\n\t\t);\n\t});\n\n/** Read-only enumeration of the concrete targets a real `wipe` would\n * remove — backs `devstack wipe --dry-run`. Deliberately does NOT\n * `ensureNoLiveSupervisor` (a preview must work whether or not a\n * supervisor is attached; it mutates nothing) and skips the router\n * dispatch-file removal (that is a destructive side effect of the real\n * wipe, not part of the preview). */\nexport const runWipePlanDirect = (\n\tidentity: ResolvedIdentity,\n): Effect.Effect<WipeTargets, unknown> =>\n\tEffect.gen(function* () {\n\t\tconst snapshot = yield* SnapshotOrchestratorService;\n\t\tconst fs = yield* FileSystem.FileSystem;\n\t\treturn yield* provideFileSystem(fs, snapshot.wipePlan({}));\n\t}).pipe(\n\t\tEffect.provide(\n\t\t\tbuildDirectSnapshotLayers({\n\t\t\t\tidentity: identityValueFor(identity),\n\t\t\t\truntimeRoot: identity.runtimeRoot,\n\t\t\t}),\n\t\t),\n\t\tEffect.provide(Logger.layer([Logger.consolePretty()])),\n\t);\n"],"mappings":";;;;;;;;AAoBA,MAAa,iBAAiB,aAC7B,OAAO,IAAI,aAAa;CACvB,OAAO,uBAAuB,UAAU,oDAAoD;CAW5F,OAAO,OAVS,OAAO,IAAI,aAAa;EACvC,MAAM,WAAW,OAAO;EAExB,OAAO,kBAAkB,OADP,WAAW,YACA,SAAS,KAAK,CAAC,CAAC,CAAC;EAC9C,OAAO,kCAAkC;GACxC,aAAa,SAAS;GACtB,KAAK,SAAS;GACd,OAAO,SAAS;EACjB,CAAC;CACF,CACoB,CAAC,CAAC,KACrB,OAAO,QACN,0BAA0B;EACzB,UAAU,iBAAiB,QAAQ;EACnC,aAAa,SAAS;CACvB,CAAC,CACF,GACA,OAAO,QAAQ,OAAO,MAAM,CAAC,OAAO,cAAc,CAAC,CAAC,CAAC,CACtD;AACD,CAAC;;;;;;;AAQF,MAAa,qBACZ,aAEA,OAAO,IAAI,aAAa;CACvB,MAAM,WAAW,OAAO;CAExB,OAAO,OAAO,kBAAkB,OADd,WAAW,YACO,SAAS,SAAS,CAAC,CAAC,CAAC;AAC1D,CAAC,CAAC,CAAC,KACF,OAAO,QACN,0BAA0B;CACzB,UAAU,iBAAiB,QAAQ;CACnC,aAAa,SAAS;AACvB,CAAC,CACF,GACA,OAAO,QAAQ,OAAO,MAAM,CAAC,OAAO,cAAc,CAAC,CAAC,CAAC,CACtD"}
|
|
@@ -18,7 +18,7 @@ interface ChainProbe<Key> {
|
|
|
18
18
|
interface ChainProbeError {
|
|
19
19
|
readonly _tag: 'ChainProbeError';
|
|
20
20
|
readonly reason: 'decode-failed' | 'not-found' | 'transient' | 'no-probe-registered';
|
|
21
|
-
readonly
|
|
21
|
+
readonly chainId: string;
|
|
22
22
|
readonly detail: string;
|
|
23
23
|
}
|
|
24
24
|
//#endregion
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
//#region src/contracts/chain-probe.ts
|
|
2
2
|
/** Capability-key constructor — chain-probes are dispatched through
|
|
3
3
|
* the StrategyContributor registry by this key shape. */
|
|
4
|
-
const chainProbeCapabilityKey = (
|
|
4
|
+
const chainProbeCapabilityKey = (chainId) => `chain-probe:${chainId}`;
|
|
5
5
|
//#endregion
|
|
6
6
|
export { chainProbeCapabilityKey };
|
|
7
7
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chain-probe.mjs","names":[],"sources":["../../src/contracts/chain-probe.ts"],"sourcesContent":["// ChainProbe capability contract (architecture §9).\n//\n// Typed, schema-validated read surface over an on-chain RPC.\n// Consumers never depend on raw SDK property access.\n//\n// Lenient mode returns absence for both not-found and transient RPC\n// failure (so verify probes re-derive on the next cycle); strict\n// throws on transient failure.\n\nimport type { Effect, Schema } from 'effect';\n\
|
|
1
|
+
{"version":3,"file":"chain-probe.mjs","names":[],"sources":["../../src/contracts/chain-probe.ts"],"sourcesContent":["// ChainProbe capability contract (architecture §9).\n//\n// Typed, schema-validated read surface over an on-chain RPC.\n// Consumers never depend on raw SDK property access.\n//\n// Lenient mode returns absence for both not-found and transient RPC\n// failure (so verify probes re-derive on the next cycle); strict\n// throws on transient failure.\n\nimport type { Effect, Schema } from 'effect';\n\nexport type ChainProbeMode = 'lenient' | 'strict';\n\n/** Capability-key constructor — chain-probes are dispatched through\n * the StrategyContributor registry by this key shape. */\nexport const chainProbeCapabilityKey = (chainId: string): `chain-probe:${string}` =>\n\t`chain-probe:${chainId}`;\n\n/**\n * Plugin-typed read interface. `Key` is the chain's native id\n * shape (object id, tx digest); `Shape` is the expected decoded\n * shape.\n */\n/** Schema-shape accepted by the probe. We constrain `DecodingServices`\n * to `never` because the probe pipeline cannot inject services from\n * the caller — schemas with dependencies are unsupported here. */\nexport type ChainProbeSchema<Shape> = Schema.Codec<Shape, unknown, never, never>;\n\nexport interface ChainProbe<Key> {\n\treadonly get: <Shape>(\n\t\tkey: Key,\n\t\tschema: ChainProbeSchema<Shape>,\n\t\tmode: ChainProbeMode,\n\t) => Effect.Effect<Shape | null, ChainProbeError>;\n\treadonly batchGet?: <Shape>(\n\t\tkeys: ReadonlyArray<Key>,\n\t\tschema: ChainProbeSchema<Shape>,\n\t\tmode: ChainProbeMode,\n\t) => Effect.Effect<ReadonlyArray<Shape | null>, ChainProbeError>;\n}\n\nexport interface ChainProbeError {\n\treadonly _tag: 'ChainProbeError';\n\treadonly reason: 'decode-failed' | 'not-found' | 'transient' | 'no-probe-registered';\n\treadonly chainId: string;\n\treadonly detail: string;\n}\n"],"mappings":";;;AAeA,MAAa,2BAA2B,YACvC,eAAe"}
|
|
@@ -36,15 +36,16 @@ interface CodegenEmitDone {
|
|
|
36
36
|
*/
|
|
37
37
|
interface AggregateContribution {
|
|
38
38
|
/** Which aggregate file this decl contributes to (e.g.
|
|
39
|
-
* `'accounts.ts'`, `'coins.ts'`, `'
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
39
|
+
* `'accounts.ts'`, `'coins.ts'`, `'config.ts'`). The plugin
|
|
40
|
+
* chooses; the orchestrator treats it as opaque. Distinct decls
|
|
41
|
+
* that target the same `bucket` deep-merge into one aggregate
|
|
42
|
+
* file (so e.g. sui's `networks.localnet` and every package's
|
|
43
|
+
* `packages.<name>` coexist in one `config.ts`). */
|
|
43
44
|
readonly bucket: string;
|
|
44
45
|
/** Project this decl's `exported` map into the value to merge
|
|
45
46
|
* into the aggregate bucket. Returning `null` opts out of
|
|
46
47
|
* contributing for this cycle (e.g. when the emitter produced
|
|
47
|
-
* no usable shape). The returned record is
|
|
48
|
+
* no usable shape). The returned record is deep-merged onto
|
|
48
49
|
* the bucket; for typed shapes the plugin owns the merge
|
|
49
50
|
* semantics via the returned object's key set. */
|
|
50
51
|
readonly project: (exported: Readonly<Record<string, unknown>>) => Readonly<Record<string, unknown>> | null;
|
|
@@ -53,7 +54,50 @@ interface AggregateContribution {
|
|
|
53
54
|
* orchestrator MUST NOT branch on this value — it is annotation-
|
|
54
55
|
* only. */
|
|
55
56
|
readonly kind?: string;
|
|
57
|
+
/** Where the synthesized aggregate file lands. `'generated'` is
|
|
58
|
+
* the canonical runtime tree (`src/generated/`); `'generated-extras'`
|
|
59
|
+
* routes the aggregate to the gitignored
|
|
60
|
+
* `.devstack/stacks/<stack>/generated-extras/` tree (dev-only +
|
|
61
|
+
* secret artifacts). All decls contributing to one bucket MUST
|
|
62
|
+
* agree on this; the orchestrator reads it from the first
|
|
63
|
+
* contributor it sees for the bucket. Defaults to `'generated'`. */
|
|
64
|
+
readonly outputLocation?: OutputLocation;
|
|
65
|
+
/** When `true`, the synthesized aggregate file is written with
|
|
66
|
+
* tightened `0o600` perms and injected into `.gitignore`. Mirrors
|
|
67
|
+
* `CodegenableDecl.sensitive` for aggregate files. Defaults to
|
|
68
|
+
* `false`. */
|
|
69
|
+
readonly sensitive?: boolean;
|
|
70
|
+
/** Generic-channel contributions for the loadable id-config. Only the
|
|
71
|
+
* LIVE (boot) aggregate of a unified config-binding set sets this;
|
|
72
|
+
* boot's `assembleIdConfig` folds it into `idConfig.values[ns][key]`.
|
|
73
|
+
* Carries the live plugin JSON the typed id-config fields can't (pool
|
|
74
|
+
* ids, coin types, walrus/seal endpoints). The committed-tree (static)
|
|
75
|
+
* aggregate omits it — those values resolve at app build time. */
|
|
76
|
+
readonly idConfigValues?: {
|
|
77
|
+
readonly [namespace: string]: {
|
|
78
|
+
readonly [key: string]: unknown;
|
|
79
|
+
};
|
|
80
|
+
};
|
|
56
81
|
}
|
|
82
|
+
/** Which codegen output tree a decl (or aggregate) emits into.
|
|
83
|
+
* `'generated'` is the runtime-imported `src/generated/` tree;
|
|
84
|
+
* `'generated-extras'` is the gitignored
|
|
85
|
+
* `.devstack/stacks/<stack>/generated-extras/` dev-only tree reached
|
|
86
|
+
* via the `@devstack-dev` alias. */
|
|
87
|
+
type OutputLocation = 'generated' | 'generated-extras';
|
|
88
|
+
/**
|
|
89
|
+
* Static, stack-free codegen-decl source. A plugin that can describe its
|
|
90
|
+
* codegen contributions from CONFIG ALONE (no live acquire) exposes this
|
|
91
|
+
* on its spec so the `codegen` verb can emit a committed projection without
|
|
92
|
+
* booting a stack. The hook is pure: it returns the same `CodegenableDecl`s
|
|
93
|
+
* the live `acquire` would emit, but stack-free — KNOWN package ids come
|
|
94
|
+
* from the declared `networks` literals, LOCAL ids stay the all-zero
|
|
95
|
+
* sentinel (`UNRESOLVED_ID`) resolved at app build/dev time through the
|
|
96
|
+
* injected `__DEVSTACK_IDS__` global. Plugins whose contributions genuinely
|
|
97
|
+
* require live resolution (or which only land in the gitignored
|
|
98
|
+
* `generated-extras` dev tree) omit this — the verb simply skips them.
|
|
99
|
+
*/
|
|
100
|
+
type StaticCodegenSource = () => ReadonlyArray<CodegenableDecl>;
|
|
57
101
|
/**
|
|
58
102
|
* Codegen contribution. `Emitter` is a literal emitter name used
|
|
59
103
|
* by the codegen orchestrator for attribution and grouping.
|
|
@@ -63,6 +107,16 @@ interface CodegenableDecl<Emitter extends string = string> {
|
|
|
63
107
|
readonly emitterName: Emitter;
|
|
64
108
|
/** Relative path under the codegen staging dir. */
|
|
65
109
|
readonly outputPath: string;
|
|
110
|
+
/** Which codegen tree this decl's standalone file emits into.
|
|
111
|
+
* `'generated'` (default) → `src/generated/`; `'generated-extras'`
|
|
112
|
+
* → the gitignored `.devstack/stacks/<stack>/generated-extras/`
|
|
113
|
+
* dev-only tree (reached via the `@devstack-dev` alias). */
|
|
114
|
+
readonly outputLocation?: OutputLocation;
|
|
115
|
+
/** When `true`, this decl contributes ONLY to its `aggregate`
|
|
116
|
+
* bucket — the orchestrator skips emitting the standalone
|
|
117
|
+
* per-decl file. Use when the per-decl singleton has no consumer
|
|
118
|
+
* (the combined aggregate is the only app-facing surface). */
|
|
119
|
+
readonly aggregateOnly?: boolean;
|
|
66
120
|
/** Optional sensitivity flag — drives file permissions and
|
|
67
121
|
* `.gitignore` inclusion. */
|
|
68
122
|
readonly sensitive?: boolean;
|
|
@@ -82,5 +136,5 @@ interface CodegenableDecl<Emitter extends string = string> {
|
|
|
82
136
|
readonly emit: (ctx: CodegenEmitContext) => Effect.Effect<CodegenEmitDone>;
|
|
83
137
|
}
|
|
84
138
|
//#endregion
|
|
85
|
-
export { CodegenEmitContext, CodegenEmitDone, CodegenableDecl };
|
|
139
|
+
export { CodegenEmitContext, CodegenEmitDone, CodegenableDecl, StaticCodegenSource };
|
|
86
140
|
//# sourceMappingURL=codegenable.d.mts.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
//#region src/contracts/codegenable.ts
|
|
2
|
+
/**
|
|
3
|
+
* A value the codegen renderer emits VERBATIM (not as a quoted literal).
|
|
4
|
+
*
|
|
5
|
+
* The one authorized use is id resolution in the emitted `config.ts`:
|
|
6
|
+
* `byNetwork` / `mvrOverrides` / `packageId` entries hold a
|
|
7
|
+
* `RawExpr('resolveId("@local/foo")')` so the COMMITTED config carries NO
|
|
8
|
+
* on-chain id. The id resolves at app build/dev time through the injected
|
|
9
|
+
* `__DEVSTACK_IDS__` global (see the emitted `config-runtime.ts`), which
|
|
10
|
+
* throws loudly when an id is unresolved. Lives at the L0 contract layer
|
|
11
|
+
* so both the package plugin (producer) and the renderer (consumer) can
|
|
12
|
+
* reach it without a layering cycle.
|
|
13
|
+
*/
|
|
14
|
+
var RawExpr = class {
|
|
15
|
+
expr;
|
|
16
|
+
__rawExpr = true;
|
|
17
|
+
constructor(expr) {
|
|
18
|
+
this.expr = expr;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
/** Build a `RawExpr`. */
|
|
22
|
+
const rawExpr = (expr) => new RawExpr(expr);
|
|
23
|
+
/** Type guard for `RawExpr` — the renderer's verbatim-emit branch. */
|
|
24
|
+
const isRawExpr = (v) => typeof v === "object" && v !== null && v.__rawExpr === true;
|
|
25
|
+
//#endregion
|
|
26
|
+
export { isRawExpr, rawExpr };
|
|
27
|
+
|
|
28
|
+
//# sourceMappingURL=codegenable.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codegenable.mjs","names":[],"sources":["../../src/contracts/codegenable.ts"],"sourcesContent":["// Codegenable capability contract (architecture §6).\n//\n// Lets a plugin contribute files to the user's source tree without\n// the codegen surface (L4) knowing the plugin exists. The runtime\n// contract only needs the literal emitter name, output path,\n// sensitivity, and an emit operation that writes through an opaque\n// context. Generated files own their app-facing export types directly.\n\nimport type { Effect } from 'effect';\n\n// -----------------------------------------------------------------------------\n// Raw-expression escape hatch\n// -----------------------------------------------------------------------------\n\n/**\n * A value the codegen renderer emits VERBATIM (not as a quoted literal).\n *\n * The one authorized use is id resolution in the emitted `config.ts`:\n * `byNetwork` / `mvrOverrides` / `packageId` entries hold a\n * `RawExpr('resolveId(\"@local/foo\")')` so the COMMITTED config carries NO\n * on-chain id. The id resolves at app build/dev time through the injected\n * `__DEVSTACK_IDS__` global (see the emitted `config-runtime.ts`), which\n * throws loudly when an id is unresolved. Lives at the L0 contract layer\n * so both the package plugin (producer) and the renderer (consumer) can\n * reach it without a layering cycle.\n */\nexport class RawExpr {\n\treadonly __rawExpr = true as const;\n\tconstructor(readonly expr: string) {}\n}\n\n/** Build a `RawExpr`. */\nexport const rawExpr = (expr: string): RawExpr => new RawExpr(expr);\n\n/** Type guard for `RawExpr` — the renderer's verbatim-emit branch. */\nexport const isRawExpr = (v: unknown): v is RawExpr =>\n\ttypeof v === 'object' && v !== null && (v as { __rawExpr?: unknown }).__rawExpr === true;\n\n/**\n * Opaque per-file emission context.\n *\n * Plugin authors declare named generated exports by calling\n * `exportConst(...)`. The orchestrator owns how those declarations are\n * collected, rendered, grouped, permissioned, and written. Emitters do\n * not return a raw `{ [exportName]: value }` record, which keeps the\n * codegen contract focused on the public generated file shape instead\n * of an internal renderer payload.\n */\nexport interface CodegenEmitContext {\n\t/** Add one `export const <name> = <value> as const;` to the file. */\n\treadonly exportConst: (name: string, value: unknown) => void;\n\t/** Add a raw import statement before the generated exports. */\n\treadonly importStatement: (statement: string) => void;\n\t/** Finish emission after all exports/imports have been written. */\n\treadonly done: () => CodegenEmitDone;\n}\n\nexport interface CodegenEmitDone {\n\treadonly _tag: 'CodegenEmitDone';\n}\n\n/**\n * Optional cross-decl aggregation. When present, the codegen\n * orchestrator additionally folds this decl's exported map into a\n * shared aggregate file alongside its own per-decl output.\n *\n * Architectural note: the orchestrator treats `bucket` as opaque and\n * delegates the projection to the plugin via `project`. Aggregate\n * special-casing (e.g. \"the Sui `services.ts` row holds `{rpc,\n * faucet, graphql}`\") belongs in the plugin's contributor, NOT in\n * the codegen orchestrator (architecture: \"Orchestrator boundaries\n * — never names a service\").\n */\nexport interface AggregateContribution {\n\t/** Which aggregate file this decl contributes to (e.g.\n\t * `'accounts.ts'`, `'coins.ts'`, `'config.ts'`). The plugin\n\t * chooses; the orchestrator treats it as opaque. Distinct decls\n\t * that target the same `bucket` deep-merge into one aggregate\n\t * file (so e.g. sui's `networks.localnet` and every package's\n\t * `packages.<name>` coexist in one `config.ts`). */\n\treadonly bucket: string;\n\t/** Project this decl's `exported` map into the value to merge\n\t * into the aggregate bucket. Returning `null` opts out of\n\t * contributing for this cycle (e.g. when the emitter produced\n\t * no usable shape). The returned record is deep-merged onto\n\t * the bucket; for typed shapes the plugin owns the merge\n\t * semantics via the returned object's key set. */\n\treadonly project: (\n\t\texported: Readonly<Record<string, unknown>>,\n\t) => Readonly<Record<string, unknown>> | null;\n\t/** Optional plugin-supplied kind tag for diagnostics / span\n\t * attributes (e.g. `'sui-network'`, `'account'`). The\n\t * orchestrator MUST NOT branch on this value — it is annotation-\n\t * only. */\n\treadonly kind?: string;\n\t/** Where the synthesized aggregate file lands. `'generated'` is\n\t * the canonical runtime tree (`src/generated/`); `'generated-extras'`\n\t * routes the aggregate to the gitignored\n\t * `.devstack/stacks/<stack>/generated-extras/` tree (dev-only +\n\t * secret artifacts). All decls contributing to one bucket MUST\n\t * agree on this; the orchestrator reads it from the first\n\t * contributor it sees for the bucket. Defaults to `'generated'`. */\n\treadonly outputLocation?: OutputLocation;\n\t/** When `true`, the synthesized aggregate file is written with\n\t * tightened `0o600` perms and injected into `.gitignore`. Mirrors\n\t * `CodegenableDecl.sensitive` for aggregate files. Defaults to\n\t * `false`. */\n\treadonly sensitive?: boolean;\n\t/** Generic-channel contributions for the loadable id-config. Only the\n\t * LIVE (boot) aggregate of a unified config-binding set sets this;\n\t * boot's `assembleIdConfig` folds it into `idConfig.values[ns][key]`.\n\t * Carries the live plugin JSON the typed id-config fields can't (pool\n\t * ids, coin types, walrus/seal endpoints). The committed-tree (static)\n\t * aggregate omits it — those values resolve at app build time. */\n\treadonly idConfigValues?: {\n\t\treadonly [namespace: string]: { readonly [key: string]: unknown };\n\t};\n}\n\n/** Which codegen output tree a decl (or aggregate) emits into.\n * `'generated'` is the runtime-imported `src/generated/` tree;\n * `'generated-extras'` is the gitignored\n * `.devstack/stacks/<stack>/generated-extras/` dev-only tree reached\n * via the `@devstack-dev` alias. */\nexport type OutputLocation = 'generated' | 'generated-extras';\n\n/**\n * Static, stack-free codegen-decl source. A plugin that can describe its\n * codegen contributions from CONFIG ALONE (no live acquire) exposes this\n * on its spec so the `codegen` verb can emit a committed projection without\n * booting a stack. The hook is pure: it returns the same `CodegenableDecl`s\n * the live `acquire` would emit, but stack-free — KNOWN package ids come\n * from the declared `networks` literals, LOCAL ids stay the all-zero\n * sentinel (`UNRESOLVED_ID`) resolved at app build/dev time through the\n * injected `__DEVSTACK_IDS__` global. Plugins whose contributions genuinely\n * require live resolution (or which only land in the gitignored\n * `generated-extras` dev tree) omit this — the verb simply skips them.\n */\nexport type StaticCodegenSource = () => ReadonlyArray<CodegenableDecl>;\n\n/**\n * Codegen contribution. `Emitter` is a literal emitter name used\n * by the codegen orchestrator for attribution and grouping.\n */\nexport interface CodegenableDecl<Emitter extends string = string> {\n\treadonly kind: 'codegenable';\n\treadonly emitterName: Emitter;\n\t/** Relative path under the codegen staging dir. */\n\treadonly outputPath: string;\n\t/** Which codegen tree this decl's standalone file emits into.\n\t * `'generated'` (default) → `src/generated/`; `'generated-extras'`\n\t * → the gitignored `.devstack/stacks/<stack>/generated-extras/`\n\t * dev-only tree (reached via the `@devstack-dev` alias). */\n\treadonly outputLocation?: OutputLocation;\n\t/** When `true`, this decl contributes ONLY to its `aggregate`\n\t * bucket — the orchestrator skips emitting the standalone\n\t * per-decl file. Use when the per-decl singleton has no consumer\n\t * (the combined aggregate is the only app-facing surface). */\n\treadonly aggregateOnly?: boolean;\n\t/** Optional sensitivity flag — drives file permissions and\n\t * `.gitignore` inclusion. */\n\treadonly sensitive?: boolean;\n\t/** When `true`, multiple decls may share this `emitterName`\n\t * (the orchestrator skips the emitter-name uniqueness check for\n\t * this decl). Use sparingly — only when the plugin legitimately\n\t * emits one decl per item (e.g. one `Package` per published\n\t * package). Output-path uniqueness is still enforced. */\n\treadonly allowEmitterNameRepetition?: boolean;\n\t/** Optional aggregation seam — when present, the orchestrator\n\t * folds the per-decl exported map into a shared aggregate file\n\t * via `aggregate.project(exported)`. Plugins own the projection\n\t * shape; the orchestrator is name-blind. */\n\treadonly aggregate?: AggregateContribution;\n\t/** Emit operation; writes generated file declarations through the\n\t * supplied context. */\n\treadonly emit: (ctx: CodegenEmitContext) => Effect.Effect<CodegenEmitDone>;\n}\n"],"mappings":";;;;;;;;;;;;;AA0BA,IAAa,UAAb,MAAqB;CAEC;CADrB,YAAqB;CACrB,YAAY,MAAuB;EAAd,KAAA,OAAA;CAAe;AACrC;;AAGA,MAAa,WAAW,SAA0B,IAAI,QAAQ,IAAI;;AAGlE,MAAa,aAAa,MACzB,OAAO,MAAM,YAAY,MAAM,QAAS,EAA8B,cAAc"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { rawExpr } from "./codegenable.mjs";
|
|
2
|
+
import { Effect } from "effect";
|
|
3
|
+
//#region src/contracts/config-bindings.ts
|
|
4
|
+
/** Set `value` at `path` inside `root`, creating intermediate objects. */
|
|
5
|
+
const setAtPath = (root, path, value) => {
|
|
6
|
+
let cursor = root;
|
|
7
|
+
for (let i = 0; i < path.length - 1; i++) {
|
|
8
|
+
const segment = path[i];
|
|
9
|
+
const next = cursor[segment];
|
|
10
|
+
if (typeof next === "object" && next !== null && !Array.isArray(next)) cursor = next;
|
|
11
|
+
else {
|
|
12
|
+
const created = {};
|
|
13
|
+
cursor[segment] = created;
|
|
14
|
+
cursor = created;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
cursor[path[path.length - 1]] = value;
|
|
18
|
+
};
|
|
19
|
+
/** The `rawExpr` the STATIC path emits for a resolved binding. */
|
|
20
|
+
const staticExprFor = (binding) => {
|
|
21
|
+
const sugar = binding.sugar;
|
|
22
|
+
if (sugar === void 0) {
|
|
23
|
+
const call = `resolveValue(${JSON.stringify(binding.namespace)}, ${JSON.stringify(binding.key)})`;
|
|
24
|
+
return rawExpr(binding.tsType === void 0 ? call : `${call} as ${binding.tsType}`);
|
|
25
|
+
}
|
|
26
|
+
switch (sugar.kind) {
|
|
27
|
+
case "id": return rawExpr(`resolveId(${JSON.stringify(sugar.mvrPlaceholder)})`);
|
|
28
|
+
case "network": return rawExpr("resolveNetwork()");
|
|
29
|
+
case "networks": return rawExpr("resolveNetworks()");
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
/** Build the STATIC (committed-tree) aggregate projection from a binding
|
|
33
|
+
* set — `rawExpr(resolve…())` for resolved bindings, literals for the
|
|
34
|
+
* rest. Pure: needs no acquired state. */
|
|
35
|
+
const projectStaticConfig = (set) => {
|
|
36
|
+
const root = {};
|
|
37
|
+
for (const binding of set.bindings) {
|
|
38
|
+
const value = binding.variant === "literal" ? binding.value : staticExprFor(binding);
|
|
39
|
+
setAtPath(root, binding.configPath, value);
|
|
40
|
+
}
|
|
41
|
+
return root;
|
|
42
|
+
};
|
|
43
|
+
/** Build the LIVE (boot) aggregate projection from a binding set against
|
|
44
|
+
* the acquired plugin state — concrete resolved values everywhere. */
|
|
45
|
+
const projectLiveConfig = (set, state) => {
|
|
46
|
+
const root = {};
|
|
47
|
+
for (const binding of set.bindings) {
|
|
48
|
+
const value = binding.variant === "literal" ? binding.value : binding.live(state);
|
|
49
|
+
setAtPath(root, binding.configPath, value);
|
|
50
|
+
}
|
|
51
|
+
return root;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Derive the live `idConfig.values[namespace][key]` contributions of a
|
|
55
|
+
* binding set. Only `resolved` bindings WITHOUT a `sugar` resolver land in
|
|
56
|
+
* the generic channel (sugar bindings feed the typed id-config fields,
|
|
57
|
+
* sliced from the live `config.ts` bucket by `idConfigFromBucket`). The
|
|
58
|
+
* generic channel is the part the fixed typed schema can't carry.
|
|
59
|
+
*/
|
|
60
|
+
const liveValuesOf = (set, state) => {
|
|
61
|
+
const out = {};
|
|
62
|
+
for (const binding of set.bindings) {
|
|
63
|
+
if (binding.variant !== "resolved" || binding.sugar !== void 0) continue;
|
|
64
|
+
const ns = out[binding.namespace] ??= {};
|
|
65
|
+
ns[binding.key] = binding.live(state);
|
|
66
|
+
}
|
|
67
|
+
return out;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Derive a `CodegenableDecl` from a binding set.
|
|
71
|
+
*
|
|
72
|
+
* `'static'` → the committed-tree decl (stack-free `codegen` verb). Its
|
|
73
|
+
* aggregate emits `rawExpr(resolve…())` for resolved bindings.
|
|
74
|
+
*
|
|
75
|
+
* `{ mode: 'live', state }` → the boot decl. Its aggregate bakes concrete
|
|
76
|
+
* values from `state`; boot's `assembleIdConfig` reads those back into the
|
|
77
|
+
* loadable id-config (typed channel + the generic `values` channel).
|
|
78
|
+
*/
|
|
79
|
+
const configCodegenable = (set, how, options = {}) => {
|
|
80
|
+
const live = how !== "static";
|
|
81
|
+
const projected = live ? projectLiveConfig(set, how.state) : projectStaticConfig(set);
|
|
82
|
+
const idConfigValues = live ? liveValuesOf(set, how.state) : {};
|
|
83
|
+
const extraExports = options.extraExports;
|
|
84
|
+
return {
|
|
85
|
+
kind: "codegenable",
|
|
86
|
+
emitterName: set.emitterName,
|
|
87
|
+
outputPath: set.outputPath ?? set.bucket,
|
|
88
|
+
aggregateOnly: true,
|
|
89
|
+
...set.allowEmitterNameRepetition === true ? { allowEmitterNameRepetition: true } : {},
|
|
90
|
+
aggregate: {
|
|
91
|
+
kind: set.kind,
|
|
92
|
+
bucket: set.bucket,
|
|
93
|
+
project: () => projected,
|
|
94
|
+
...live && Object.keys(idConfigValues).length > 0 ? { idConfigValues } : {}
|
|
95
|
+
},
|
|
96
|
+
emit: (ctx) => Effect.sync(() => {
|
|
97
|
+
if (extraExports !== void 0) for (const [name, value] of Object.entries(extraExports)) ctx.exportConst(name, value);
|
|
98
|
+
else ctx.exportConst("__configBindings", set.kind);
|
|
99
|
+
return ctx.done();
|
|
100
|
+
})
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
/** Convenience constructor for the keyed-bucket shape the service plugins
|
|
104
|
+
* share (coin/deepbook/seal): every sibling instance keys under `<key>` in
|
|
105
|
+
* `<bucket>`, with `emitterName = `<kind>/<key>``, `namespace = `<kind>:<key>``,
|
|
106
|
+
* `instanceKey = <key>`, and `allowEmitterNameRepetition` (instances share the
|
|
107
|
+
* `<kind>/` emitter prefix). Only `bucket`/`kind`/`key`/`fields` vary across
|
|
108
|
+
* those plugins, so this keeps the `<kind>/<key>` + `<kind>:<key>` naming
|
|
109
|
+
* convention in ONE place instead of re-spelling it per plugin. */
|
|
110
|
+
const keyedBucketSpec = (input) => ({
|
|
111
|
+
bucket: input.bucket,
|
|
112
|
+
kind: input.kind,
|
|
113
|
+
emitterName: `${input.kind}/${input.key}`,
|
|
114
|
+
instanceKey: input.key,
|
|
115
|
+
namespace: `${input.kind}:${input.key}`,
|
|
116
|
+
allowEmitterNameRepetition: true,
|
|
117
|
+
fields: input.fields
|
|
118
|
+
});
|
|
119
|
+
/** Build the `ConfigBindingSet` for a sibling-keyed bucket instance. The
|
|
120
|
+
* `configPath` of every binding is rooted at the instance key, so distinct
|
|
121
|
+
* instances deep-merge into one `<bucket>.ts` exporting
|
|
122
|
+
* `{ <instanceKey>: { ...fields } }`. */
|
|
123
|
+
const siblingBucketBindings = (spec) => {
|
|
124
|
+
const bindings = spec.fields.map((field) => {
|
|
125
|
+
const configPath = [spec.instanceKey, field.key];
|
|
126
|
+
if (field.variant === "literal") return {
|
|
127
|
+
variant: "literal",
|
|
128
|
+
configPath: [...configPath],
|
|
129
|
+
value: field.value
|
|
130
|
+
};
|
|
131
|
+
return {
|
|
132
|
+
variant: "resolved",
|
|
133
|
+
configPath: [...configPath],
|
|
134
|
+
namespace: spec.namespace,
|
|
135
|
+
key: field.valueKey ?? field.key,
|
|
136
|
+
...field.tsType !== void 0 ? { tsType: field.tsType } : {},
|
|
137
|
+
live: field.live
|
|
138
|
+
};
|
|
139
|
+
});
|
|
140
|
+
return {
|
|
141
|
+
bucket: spec.bucket,
|
|
142
|
+
kind: spec.kind,
|
|
143
|
+
emitterName: spec.emitterName,
|
|
144
|
+
...spec.outputPath !== void 0 ? { outputPath: spec.outputPath } : {},
|
|
145
|
+
...spec.allowEmitterNameRepetition === true ? { allowEmitterNameRepetition: true } : {},
|
|
146
|
+
bindings
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
/** Derive the LIVE bucket decl — feeds concrete values into the generic
|
|
150
|
+
* id-config `values` channel (no per-stack generated file is written). */
|
|
151
|
+
const liveBucketCodegen = (spec, state) => configCodegenable(siblingBucketBindings(spec), {
|
|
152
|
+
mode: "live",
|
|
153
|
+
state
|
|
154
|
+
});
|
|
155
|
+
/** Derive the STATIC (stack-free) bucket decl — emits
|
|
156
|
+
* `resolveValue(namespace, key)` for resolved fields, literals for the
|
|
157
|
+
* rest. The committed `<bucket>.ts` carries no baked runtime value. */
|
|
158
|
+
const staticBucketCodegen = (spec) => configCodegenable(siblingBucketBindings(spec), "static");
|
|
159
|
+
//#endregion
|
|
160
|
+
export { configCodegenable, keyedBucketSpec, liveBucketCodegen, staticBucketCodegen };
|
|
161
|
+
|
|
162
|
+
//# sourceMappingURL=config-bindings.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-bindings.mjs","names":[],"sources":["../../src/contracts/config-bindings.ts"],"sourcesContent":["// Unified config-binding contract.\n//\n// THE PROBLEM THIS SOLVES. A config-emitting plugin used to maintain TWO\n// near-duplicate projectors:\n// - a LIVE one (boot): bakes concrete resolved values (real ids, rpc\n// URLs) into the loadable id-config (`assembleIdConfig`), and\n// - a STATIC one (the stack-free `codegen` verb): emits\n// `rawExpr(resolve…())` into the committed `config.ts` so the tree\n// carries NO on-chain id.\n// Two hand-written projectors per plugin is error-prone: forget the static\n// path and the committed tree is incomplete (broken clean-clone build);\n// the fixed typed id-config channel also can't carry arbitrary plugin live\n// values (deepbook pool ids, coin types, walrus/seal endpoints).\n//\n// THE UNIFICATION. A plugin declares its `config.ts` contributions ONCE as\n// a `ConfigBindingSet`. BOTH paths are DERIVED from it:\n// - `configCodegenable(set, 'static')` → the committed-tree decl whose\n// aggregate emits `rawExpr(resolveValue(...))` / typed-sugar resolvers\n// (and pure literals as literals).\n// - `configCodegenable(set, { mode: 'live', state })` → the boot decl\n// whose aggregate carries concrete resolved values that feed ONLY the\n// loadable id-config (typed channel + the generic `values` channel) —\n// no per-stack generated source is written; the committed `src/generated`\n// tree stays the single bindings source.\n//\n// One declaration, two derivations — no parallel projectors to drift.\n\nimport { Effect } from 'effect';\n\nimport type { CodegenableDecl } from './codegenable.ts';\nimport { rawExpr } from './codegenable.ts';\nimport type { JsonValue } from '../orchestrators/codegen/id-config.ts';\n\n// -----------------------------------------------------------------------------\n// Binding shape\n// -----------------------------------------------------------------------------\n\n/** A typed-sugar resolver a binding may target instead of the generic\n * `resolveValue(namespace, key)` channel. Each maps to a `config-runtime.ts`\n * function: `id` → `resolveId(<arg>)`, `network` → `resolveNetwork()`,\n * `networks` → `resolveNetworks()`. Sugar bindings also feed the TYPED\n * id-config fields (`mvrOverrides`/`network`/`networks`), not the generic\n * `values` channel — that keeps `config.network`/`config.mvrOverrides`\n * readable by apps exactly as before. */\nexport type ConfigSugarResolver =\n\t| { readonly kind: 'id'; readonly mvrPlaceholder: string }\n\t| { readonly kind: 'network' }\n\t| { readonly kind: 'networks' };\n\n/**\n * One config-binding. A plugin returns a list of these ONCE; the framework\n * derives both the live and static behaviors from them.\n *\n * Variants:\n * - `literal`: the SAME value in both paths (e.g. the package `mvr`\n * placeholder string, a network NAME you decide is static). Emitted\n * verbatim in `config.ts`; mirrored into the live id-config too.\n * - `resolved`: runtime-resolved. STATIC emits a resolver `rawExpr`;\n * LIVE computes the concrete value via `live(state)` and routes it into\n * the id-config — through the typed channel for a `sugar` resolver, or\n * through the generic `values[namespace][key]` channel otherwise.\n */\nexport type ConfigBinding<State = unknown> =\n\t| {\n\t\t\treadonly variant: 'literal';\n\t\t\t/** Path into the `config.ts` object literal, e.g. `['network']`\n\t\t\t * or `['packages', 'connect_four', 'mvr']`. */\n\t\t\treadonly configPath: ReadonlyArray<string>;\n\t\t\t/** The literal value (identical in both paths). */\n\t\t\treadonly value: JsonValue;\n\t }\n\t| {\n\t\t\treadonly variant: 'resolved';\n\t\t\t/** Path into the `config.ts` object literal. */\n\t\t\treadonly configPath: ReadonlyArray<string>;\n\t\t\t/** Generic-channel coordinates. Always present so the live path\n\t\t\t * can populate `idConfig.values[namespace][key]` even for a\n\t\t\t * sugar-resolved binding (the sugar ALSO feeds the typed field;\n\t\t\t * `values` is harmless redundancy and keeps the guard simple). */\n\t\t\treadonly namespace: string;\n\t\t\treadonly key: string;\n\t\t\t/** When set, the static path emits the typed-sugar resolver\n\t\t\t * (`resolveId`/`resolveNetwork`/`resolveNetworks`) and the live\n\t\t\t * path additionally feeds the TYPED id-config field. When\n\t\t\t * omitted, the static path emits `resolveValue(namespace, key)`\n\t\t\t * and the live value lands ONLY in the generic `values` channel. */\n\t\t\treadonly sugar?: ConfigSugarResolver;\n\t\t\t/** The field's STATIC TypeScript type, as a source string (e.g.\n\t\t\t * `'string'`, `'string | null'`, or a structural literal type for a\n\t\t\t * composite). When set, the static path emits\n\t\t\t * `resolveValue(ns, key) as <tsType>` so the committed value carries\n\t\t\t * its concrete type instead of the `unknown` the generic channel\n\t\t\t * returns. Ignored for sugar bindings (those use the typed resolver\n\t\t\t * whose return type is already concrete). When omitted, the static\n\t\t\t * path emits a bare `resolveValue(ns, key)` (type `unknown`). */\n\t\t\treadonly tsType?: string;\n\t\t\t/** Compute the concrete value at boot from acquired plugin state.\n\t\t\t * Only invoked on the LIVE path. */\n\t\t\treadonly live: (state: State) => JsonValue;\n\t };\n\n/**\n * A plugin's full `config.ts` contribution, declared ONCE.\n *\n * `bucket` is always `'config.ts'` for the typed app config; carried as a\n * field so the orchestrator stays name-blind (it reads the bucket off the\n * decl rather than hard-coding it).\n */\nexport interface ConfigBindingSet<State = unknown> {\n\t/** Aggregate bucket the bindings fold into (always `'config.ts'` today;\n\t * a field so the orchestrator never hard-codes it). */\n\treadonly bucket: string;\n\t/** Diagnostic tag for span attributes (e.g. `'sui-network'`,\n\t * `'package'`). The orchestrator MUST NOT branch on it. */\n\treadonly kind: string;\n\t/** The emitter name the derived `CodegenableDecl` carries. */\n\treadonly emitterName: string;\n\t/** Optional standalone output path. The derived decl is `aggregateOnly`,\n\t * so no per-decl file is written; path-resolution only needs a non-empty,\n\t * per-bucket-unique string, which defaults to `bucket` when omitted. Set\n\t * it only when a standalone path would be genuinely meaningful. */\n\treadonly outputPath?: string;\n\t/** When `true`, the derived decl sets `allowEmitterNameRepetition`\n\t * (one decl per item, e.g. one `package` per published package). */\n\treadonly allowEmitterNameRepetition?: boolean;\n\t/** The bindings. */\n\treadonly bindings: ReadonlyArray<ConfigBinding<State>>;\n}\n\n// -----------------------------------------------------------------------------\n// Derivation\n// -----------------------------------------------------------------------------\n\n/** Set `value` at `path` inside `root`, creating intermediate objects. */\nconst setAtPath = (\n\troot: Record<string, unknown>,\n\tpath: ReadonlyArray<string>,\n\tvalue: unknown,\n): void => {\n\tlet cursor = root;\n\tfor (let i = 0; i < path.length - 1; i++) {\n\t\tconst segment = path[i]!;\n\t\tconst next = cursor[segment];\n\t\tif (typeof next === 'object' && next !== null && !Array.isArray(next)) {\n\t\t\tcursor = next as Record<string, unknown>;\n\t\t} else {\n\t\t\tconst created: Record<string, unknown> = {};\n\t\t\tcursor[segment] = created;\n\t\t\tcursor = created;\n\t\t}\n\t}\n\tcursor[path[path.length - 1]!] = value;\n};\n\n/** The `rawExpr` the STATIC path emits for a resolved binding. */\nconst staticExprFor = <State>(\n\tbinding: Extract<ConfigBinding<State>, { variant: 'resolved' }>,\n): ReturnType<typeof rawExpr> => {\n\tconst sugar = binding.sugar;\n\tif (sugar === undefined) {\n\t\tconst call = `resolveValue(${JSON.stringify(binding.namespace)}, ${JSON.stringify(binding.key)})`;\n\t\t// A `tsType` carries the field's concrete static type so the committed\n\t\t// value typechecks against the app's usage (the generic channel returns\n\t\t// `unknown`). Emit the call as a typed cast; bare otherwise.\n\t\treturn rawExpr(binding.tsType === undefined ? call : `${call} as ${binding.tsType}`);\n\t}\n\tswitch (sugar.kind) {\n\t\tcase 'id':\n\t\t\treturn rawExpr(`resolveId(${JSON.stringify(sugar.mvrPlaceholder)})`);\n\t\tcase 'network':\n\t\t\treturn rawExpr('resolveNetwork()');\n\t\tcase 'networks':\n\t\t\treturn rawExpr('resolveNetworks()');\n\t}\n};\n\n/** Build the STATIC (committed-tree) aggregate projection from a binding\n * set — `rawExpr(resolve…())` for resolved bindings, literals for the\n * rest. Pure: needs no acquired state. */\nexport const projectStaticConfig = <State>(\n\tset: ConfigBindingSet<State>,\n): Record<string, unknown> => {\n\tconst root: Record<string, unknown> = {};\n\tfor (const binding of set.bindings) {\n\t\tconst value = binding.variant === 'literal' ? binding.value : staticExprFor(binding);\n\t\tsetAtPath(root, binding.configPath, value);\n\t}\n\treturn root;\n};\n\n/** Build the LIVE (boot) aggregate projection from a binding set against\n * the acquired plugin state — concrete resolved values everywhere. */\nexport const projectLiveConfig = <State>(\n\tset: ConfigBindingSet<State>,\n\tstate: State,\n): Record<string, unknown> => {\n\tconst root: Record<string, unknown> = {};\n\tfor (const binding of set.bindings) {\n\t\tconst value = binding.variant === 'literal' ? binding.value : binding.live(state);\n\t\tsetAtPath(root, binding.configPath, value);\n\t}\n\treturn root;\n};\n\n/**\n * Derive the live `idConfig.values[namespace][key]` contributions of a\n * binding set. Only `resolved` bindings WITHOUT a `sugar` resolver land in\n * the generic channel (sugar bindings feed the typed id-config fields,\n * sliced from the live `config.ts` bucket by `idConfigFromBucket`). The\n * generic channel is the part the fixed typed schema can't carry.\n */\nexport const liveValuesOf = <State>(\n\tset: ConfigBindingSet<State>,\n\tstate: State,\n): Record<string, Record<string, JsonValue>> => {\n\tconst out: Record<string, Record<string, JsonValue>> = {};\n\tfor (const binding of set.bindings) {\n\t\tif (binding.variant !== 'resolved' || binding.sugar !== undefined) continue;\n\t\tconst ns = (out[binding.namespace] ??= {});\n\t\tns[binding.key] = binding.live(state);\n\t}\n\treturn out;\n};\n\n/**\n * Derive a `CodegenableDecl` from a binding set.\n *\n * `'static'` → the committed-tree decl (stack-free `codegen` verb). Its\n * aggregate emits `rawExpr(resolve…())` for resolved bindings.\n *\n * `{ mode: 'live', state }` → the boot decl. Its aggregate bakes concrete\n * values from `state`; boot's `assembleIdConfig` reads those back into the\n * loadable id-config (typed channel + the generic `values` channel).\n */\nexport const configCodegenable = <State, Emitter extends string = string>(\n\tset: ConfigBindingSet<State>,\n\thow: 'static' | { readonly mode: 'live'; readonly state: State },\n\toptions: {\n\t\t/** Extra `export const <name> = <value>` declarations to emit on the\n\t\t * decl's `emit` context, instead of the default placeholder export.\n\t\t * The package plugin uses this to export its `packageBindings` object\n\t\t * so the orchestrator's `isPackageBindings` seam can forward it to the\n\t\t * Move-bindings emitter. When omitted, a single minimal placeholder\n\t\t * export is emitted (the projection is what the aggregate folds). */\n\t\treadonly extraExports?: Readonly<Record<string, unknown>>;\n\t} = {},\n): CodegenableDecl<Emitter> => {\n\tconst live = how !== 'static';\n\tconst projected = live ? projectLiveConfig(set, how.state) : projectStaticConfig(set);\n\tconst idConfigValues = live ? liveValuesOf(set, how.state) : {};\n\tconst extraExports = options.extraExports;\n\treturn {\n\t\tkind: 'codegenable',\n\t\temitterName: set.emitterName as Emitter,\n\t\t// `aggregateOnly` never writes a standalone file; default the\n\t\t// path-resolution placeholder to the bucket name so plugins don't\n\t\t// invent dead paths.\n\t\toutputPath: set.outputPath ?? set.bucket,\n\t\taggregateOnly: true,\n\t\t...(set.allowEmitterNameRepetition === true ? { allowEmitterNameRepetition: true } : {}),\n\t\taggregate: {\n\t\t\tkind: set.kind,\n\t\t\tbucket: set.bucket,\n\t\t\t// The projection is precomputed above (pure over `set`/`state`);\n\t\t\t// the orchestrator calls `project(exported)` with the emitted map\n\t\t\t// but the value is already fixed, so we ignore the argument.\n\t\t\tproject: () => projected,\n\t\t\t// Only the live aggregate feeds the generic id-config channel.\n\t\t\t...(live && Object.keys(idConfigValues).length > 0 ? { idConfigValues } : {}),\n\t\t},\n\t\temit: (ctx) =>\n\t\t\tEffect.sync(() => {\n\t\t\t\tif (extraExports !== undefined) {\n\t\t\t\t\tfor (const [name, value] of Object.entries(extraExports)) {\n\t\t\t\t\t\tctx.exportConst(name, value);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// A placeholder export so the emitter runs; the projection is\n\t\t\t\t\t// what the aggregate folds. Kept minimal + name-stable.\n\t\t\t\t\tctx.exportConst('__configBindings', set.kind);\n\t\t\t\t}\n\t\t\t\treturn ctx.done();\n\t\t\t}),\n\t};\n};\n\n// -----------------------------------------------------------------------------\n// Sibling-keyed bucket bindings\n// -----------------------------------------------------------------------------\n//\n// The own-bucket service plugins (coin → `coins.ts`, deepbook → `deepbook.ts`,\n// seal → `seal.ts`) emit a name-keyed bucket where distinct instances deep-merge\n// into one `<bucket>.ts` exporting `{ <instanceKey>: { ...fields } }`. They\n// declare their per-instance contribution as a flat list of `BucketField`s\n// (each a structural literal or a runtime-resolved value rooted under the\n// instance key); the helpers below derive the `ConfigBindingSet` and both the\n// live/static decls from it, so there are no parallel projectors to drift.\n\n/** One field of an instance's bucket entry, classified as either a pure\n * STRUCTURAL literal (a name / mode / decimals — the same in both paths)\n * or a runtime-RESOLVED value (an on-chain id, coin type, or endpoint URL —\n * the static path emits `resolveValue`, the live path feeds the concrete\n * value into the id-config). The `key` is the leaf field name written under\n * the instance key in the bucket object literal. */\nexport type BucketField<State> =\n\t| { readonly key: string; readonly variant: 'literal'; readonly value: JsonValue }\n\t| {\n\t\t\treadonly key: string;\n\t\t\treadonly variant: 'resolved';\n\t\t\t/** `resolveValue(namespace, valueKey)` coordinates. `valueKey`\n\t\t\t * defaults to `key` when omitted. */\n\t\t\treadonly valueKey?: string;\n\t\t\t/** The field's STATIC TypeScript type as a source string (see\n\t\t\t * `ConfigBinding.tsType`). When set, the static path emits\n\t\t\t * `resolveValue(...) as <tsType>` so the committed value carries its\n\t\t\t * concrete type instead of `unknown`. */\n\t\t\treadonly tsType?: string;\n\t\t\treadonly live: (state: State) => JsonValue;\n\t };\n\nexport interface SiblingBucketSpec<State> {\n\t/** The aggregate bucket filename, e.g. `'coins.ts'`. */\n\treadonly bucket: string;\n\t/** Diagnostic kind tag (e.g. `'coin'`) — the orchestrator never\n\t * branches on it. */\n\treadonly kind: string;\n\t/** The emitter name the derived decl carries (literal, e.g.\n\t * `coin/<symbol>`). */\n\treadonly emitterName: string;\n\t/** Optional standalone output path. Defaults to `bucket` (the decl is\n\t * `aggregateOnly`, so no per-decl file is written). */\n\treadonly outputPath?: string;\n\t/** The instance key the entry lives under in the bucket object\n\t * (e.g. the coin symbol, the deepbook instance name). */\n\treadonly instanceKey: string;\n\t/** The `resolveValue` namespace shared by every resolved field\n\t * (e.g. `coin:<symbol>`, `deepbook:<name>`). */\n\treadonly namespace: string;\n\t/** The instance's fields. */\n\treadonly fields: ReadonlyArray<BucketField<State>>;\n\t/** When `true`, the derived decl sets `allowEmitterNameRepetition`\n\t * (sibling instances share an emitter-name prefix). */\n\treadonly allowEmitterNameRepetition?: boolean;\n}\n\n/** Convenience constructor for the keyed-bucket shape the service plugins\n * share (coin/deepbook/seal): every sibling instance keys under `<key>` in\n * `<bucket>`, with `emitterName = `<kind>/<key>``, `namespace = `<kind>:<key>``,\n * `instanceKey = <key>`, and `allowEmitterNameRepetition` (instances share the\n * `<kind>/` emitter prefix). Only `bucket`/`kind`/`key`/`fields` vary across\n * those plugins, so this keeps the `<kind>/<key>` + `<kind>:<key>` naming\n * convention in ONE place instead of re-spelling it per plugin. */\nexport const keyedBucketSpec = <State>(input: {\n\treadonly bucket: string;\n\treadonly kind: string;\n\treadonly key: string;\n\treadonly fields: ReadonlyArray<BucketField<State>>;\n}): SiblingBucketSpec<State> => ({\n\tbucket: input.bucket,\n\tkind: input.kind,\n\temitterName: `${input.kind}/${input.key}`,\n\tinstanceKey: input.key,\n\tnamespace: `${input.kind}:${input.key}`,\n\tallowEmitterNameRepetition: true,\n\tfields: input.fields,\n});\n\n/** Build the `ConfigBindingSet` for a sibling-keyed bucket instance. The\n * `configPath` of every binding is rooted at the instance key, so distinct\n * instances deep-merge into one `<bucket>.ts` exporting\n * `{ <instanceKey>: { ...fields } }`. */\nexport const siblingBucketBindings = <State>(\n\tspec: SiblingBucketSpec<State>,\n): ConfigBindingSet<State> => {\n\tconst bindings: Array<ConfigBinding<State>> = spec.fields.map((field) => {\n\t\tconst configPath = [spec.instanceKey, field.key] as const;\n\t\tif (field.variant === 'literal') {\n\t\t\treturn { variant: 'literal', configPath: [...configPath], value: field.value };\n\t\t}\n\t\treturn {\n\t\t\tvariant: 'resolved',\n\t\t\tconfigPath: [...configPath],\n\t\t\tnamespace: spec.namespace,\n\t\t\tkey: field.valueKey ?? field.key,\n\t\t\t// No `sugar` — these are generic `resolveValue` bindings (the typed\n\t\t\t// id-config channel only carries network/packages/mvrOverrides).\n\t\t\t...(field.tsType !== undefined ? { tsType: field.tsType } : {}),\n\t\t\tlive: field.live,\n\t\t};\n\t});\n\treturn {\n\t\tbucket: spec.bucket,\n\t\tkind: spec.kind,\n\t\temitterName: spec.emitterName,\n\t\t...(spec.outputPath !== undefined ? { outputPath: spec.outputPath } : {}),\n\t\t...(spec.allowEmitterNameRepetition === true ? { allowEmitterNameRepetition: true } : {}),\n\t\tbindings,\n\t};\n};\n\n/** Derive the LIVE bucket decl — feeds concrete values into the generic\n * id-config `values` channel (no per-stack generated file is written). */\nexport const liveBucketCodegen = <State>(\n\tspec: SiblingBucketSpec<State>,\n\tstate: State,\n): CodegenableDecl => configCodegenable(siblingBucketBindings(spec), { mode: 'live', state });\n\n/** Derive the STATIC (stack-free) bucket decl — emits\n * `resolveValue(namespace, key)` for resolved fields, literals for the\n * rest. The committed `<bucket>.ts` carries no baked runtime value. */\nexport const staticBucketCodegen = <State>(spec: SiblingBucketSpec<State>): CodegenableDecl =>\n\tconfigCodegenable(siblingBucketBindings(spec), 'static');\n"],"mappings":"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"}
|