@mysten-incubation/devstack 0.0.1 → 0.1.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 +7 -3
- package/dashboard-ui/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
- package/dashboard-ui/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
- package/dashboard-ui/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
- package/dashboard-ui/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
- package/dashboard-ui/assets/geist-mono-cyrillic-ext-wght-normal-I4S5GZfc.woff2 +0 -0
- package/dashboard-ui/assets/geist-mono-cyrillic-wght-normal-BmXc_FBt.woff2 +0 -0
- package/dashboard-ui/assets/geist-mono-latin-ext-wght-normal-DrnZ1wKl.woff2 +0 -0
- package/dashboard-ui/assets/geist-mono-latin-wght-normal-B_7UjwxQ.woff2 +0 -0
- package/dashboard-ui/assets/geist-mono-symbols2-wght-normal-GZpp1pK2.woff2 +0 -0
- package/dashboard-ui/assets/geist-mono-vietnamese-wght-normal-D8KDMBhC.woff2 +0 -0
- package/dashboard-ui/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
- package/dashboard-ui/assets/index-Bmi1UtAg.js +1356 -0
- package/dashboard-ui/assets/index-D5EShVt4.js +3 -0
- package/dashboard-ui/assets/index-Deml9drg.css +1 -0
- package/dashboard-ui/index.html +13 -0
- package/dist/api/define-capabilities.d.mts +14 -3
- package/dist/api/define-capabilities.mjs +18 -1
- package/dist/api/define-capabilities.mjs.map +1 -1
- package/dist/api/define-devstack.d.mts +1 -1
- package/dist/api/define-devstack.mjs +6 -26
- package/dist/api/define-devstack.mjs.map +1 -1
- package/dist/api/define-plugin.d.mts +1 -0
- package/dist/api/define-plugin.mjs +2 -0
- package/dist/api/inference-network.d.mts +132 -0
- package/dist/api/inference-network.mjs +105 -16
- package/dist/api/inference-network.mjs.map +1 -1
- package/dist/api/plugin-errors.d.mts +7 -0
- package/dist/api/run-stack.d.mts +20 -9
- package/dist/api/run-stack.mjs +56 -29
- package/dist/api/run-stack.mjs.map +1 -1
- package/dist/build-integrations/playwright/config.d.mts +6 -4
- package/dist/build-integrations/playwright/config.mjs +5 -3
- package/dist/build-integrations/playwright/config.mjs.map +1 -1
- package/dist/build-integrations/playwright/errors.d.mts +1 -1
- package/dist/build-integrations/playwright/global-setup.d.mts +43 -17
- package/dist/build-integrations/playwright/global-setup.mjs +250 -13
- package/dist/build-integrations/playwright/global-setup.mjs.map +1 -1
- package/dist/build-integrations/playwright/index.d.mts +5 -3
- package/dist/build-integrations/playwright/index.mjs +4 -2
- package/dist/build-integrations/playwright/stack-context.d.mts +0 -1
- package/dist/build-integrations/playwright/stack-context.mjs +24 -63
- package/dist/build-integrations/playwright/stack-context.mjs.map +1 -1
- package/dist/build-integrations/playwright/wallet-context.d.mts +7 -10
- package/dist/build-integrations/playwright/wallet-context.mjs +8 -13
- package/dist/build-integrations/playwright/wallet-context.mjs.map +1 -1
- package/dist/build-integrations/runtime/cold-start-url.d.mts +5 -0
- package/dist/build-integrations/runtime/cold-start-url.mjs +4 -3
- package/dist/build-integrations/runtime/cold-start-url.mjs.map +1 -1
- package/dist/build-integrations/runtime/conventional-routes.d.mts +51 -0
- package/dist/build-integrations/runtime/conventional-routes.mjs +92 -0
- package/dist/build-integrations/runtime/conventional-routes.mjs.map +1 -0
- package/dist/build-integrations/runtime/discover.d.mts +38 -30
- package/dist/build-integrations/runtime/discover.mjs +73 -70
- package/dist/build-integrations/runtime/discover.mjs.map +1 -1
- package/dist/build-integrations/runtime/endpoint-registry.d.mts +3 -1
- package/dist/build-integrations/runtime/endpoint-registry.mjs +3 -1
- package/dist/build-integrations/runtime/endpoint-registry.mjs.map +1 -1
- package/dist/build-integrations/runtime/index.d.mts +7 -2
- package/dist/build-integrations/runtime/index.mjs +9 -2
- package/dist/build-integrations/runtime/manifest-types.d.mts +2 -0
- package/dist/build-integrations/runtime/manifest-types.mjs +3 -0
- package/dist/build-integrations/runtime/playwright-stack-context-slot.d.mts +29 -0
- package/dist/build-integrations/runtime/playwright-stack-context-slot.mjs +10 -0
- package/dist/build-integrations/runtime/playwright-stack-context-slot.mjs.map +1 -0
- package/dist/build-integrations/runtime/read-stack-context.d.mts +1 -1
- package/dist/build-integrations/runtime/read-stack-context.mjs +10 -4
- package/dist/build-integrations/runtime/read-stack-context.mjs.map +1 -1
- package/dist/build-integrations/runtime/resolve-discovery-env.d.mts +48 -0
- package/dist/build-integrations/runtime/resolve-discovery-env.mjs +42 -0
- package/dist/build-integrations/runtime/resolve-discovery-env.mjs.map +1 -0
- package/dist/build-integrations/runtime/stack-context.d.mts +1 -1
- package/dist/build-integrations/runtime/wallet-paths.mjs +2 -0
- package/dist/build-integrations/vite/index.d.mts +51 -0
- package/dist/build-integrations/vite/index.mjs +73 -0
- package/dist/build-integrations/vite/index.mjs.map +1 -0
- package/dist/build-integrations/vitest/env.d.mts +4 -3
- package/dist/build-integrations/vitest/env.mjs +6 -4
- package/dist/build-integrations/vitest/env.mjs.map +1 -1
- package/dist/build-integrations/vitest/errors.d.mts +25 -4
- package/dist/build-integrations/vitest/errors.mjs +15 -2
- package/dist/build-integrations/vitest/errors.mjs.map +1 -1
- package/dist/build-integrations/vitest/index.d.mts +2 -2
- package/dist/build-integrations/vitest/index.mjs +3 -3
- package/dist/build-integrations/vitest/setup.d.mts +4 -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 +0 -1
- package/dist/build-integrations/vitest/stack-context.mjs +33 -13
- package/dist/build-integrations/vitest/stack-context.mjs.map +1 -1
- package/dist/cli/bail.mjs +23 -0
- package/dist/cli/bail.mjs.map +1 -0
- package/dist/{surfaces/cli/commands → cli}/doctor-probes.mjs +26 -16
- package/dist/cli/doctor-probes.mjs.map +1 -0
- package/dist/cli/main.d.mts +15 -1
- package/dist/cli/main.mjs +166 -482
- package/dist/cli/main.mjs.map +1 -1
- package/dist/cli/prune-direct.mjs +31 -201
- package/dist/cli/prune-direct.mjs.map +1 -1
- package/dist/cli/snapshot-reader.mjs +14 -11
- package/dist/cli/snapshot-reader.mjs.map +1 -1
- package/dist/cli/up-lifecycle.mjs +4 -1
- package/dist/cli/up-lifecycle.mjs.map +1 -1
- package/dist/cli/wirings/apply.mjs +95 -0
- package/dist/cli/wirings/apply.mjs.map +1 -0
- package/dist/cli/wirings/build-verb-layers.mjs +42 -0
- package/dist/cli/wirings/build-verb-layers.mjs.map +1 -0
- package/dist/cli/wirings/config-loader.mjs +69 -0
- package/dist/cli/wirings/config-loader.mjs.map +1 -0
- package/dist/cli/wirings/engine-command.mjs +30 -0
- package/dist/cli/wirings/engine-command.mjs.map +1 -0
- package/dist/cli/wirings/identity.mjs +72 -0
- package/dist/cli/wirings/identity.mjs.map +1 -0
- package/dist/cli/wirings/provide-file-system.mjs +7 -0
- package/dist/cli/wirings/provide-file-system.mjs.map +1 -0
- package/dist/cli/wirings/snapshot.mjs +177 -0
- package/dist/cli/wirings/snapshot.mjs.map +1 -0
- package/dist/cli/wirings/up.mjs +287 -0
- package/dist/cli/wirings/up.mjs.map +1 -0
- package/dist/cli/wirings/wipe.mjs +40 -0
- package/dist/cli/wirings/wipe.mjs.map +1 -0
- package/dist/contracts/capability-decl.d.mts +0 -2
- package/dist/contracts/codegenable.d.mts +43 -0
- package/dist/contracts/container-runtime.d.mts +26 -1
- package/dist/contracts/faucet-strategy.d.mts +25 -0
- package/dist/contracts/funding-strategy.d.mts +42 -0
- package/dist/contracts/plugin-expander.mjs +60 -0
- package/dist/contracts/plugin-expander.mjs.map +1 -0
- package/dist/contracts/projection.d.mts +5 -3
- package/dist/contracts/renderer.d.mts +23 -0
- package/dist/contracts/routable.d.mts +14 -1
- package/dist/contracts/snapshotable.d.mts +25 -3
- package/dist/contracts/wallet-protocol.d.mts +52 -0
- package/dist/contracts/wallet-protocol.mjs +52 -0
- package/dist/contracts/wallet-protocol.mjs.map +1 -0
- package/dist/index.d.mts +26 -25
- package/dist/index.mjs +20 -13
- package/dist/{runtime → orchestrators}/built-in-plugin-layers.mjs +10 -5
- package/dist/orchestrators/built-in-plugin-layers.mjs.map +1 -0
- package/dist/orchestrators/codegen/bindings.d.mts +1 -2
- package/dist/orchestrators/codegen/bindings.mjs +52 -186
- package/dist/orchestrators/codegen/bindings.mjs.map +1 -1
- package/dist/orchestrators/codegen/emit.mjs +19 -1
- package/dist/orchestrators/codegen/emit.mjs.map +1 -1
- package/dist/orchestrators/codegen/errors.mjs +8 -3
- package/dist/orchestrators/codegen/errors.mjs.map +1 -1
- package/dist/orchestrators/codegen/format.mjs +47 -39
- package/dist/orchestrators/codegen/format.mjs.map +1 -1
- package/dist/orchestrators/codegen/gitignore.mjs +3 -1
- package/dist/orchestrators/codegen/gitignore.mjs.map +1 -1
- package/dist/orchestrators/codegen/output-location.mjs +40 -0
- package/dist/orchestrators/codegen/output-location.mjs.map +1 -0
- package/dist/orchestrators/codegen/paths.d.mts +1 -1
- package/dist/orchestrators/codegen/paths.mjs +40 -14
- package/dist/orchestrators/codegen/paths.mjs.map +1 -1
- package/dist/orchestrators/codegen/permissions.mjs +3 -1
- package/dist/orchestrators/codegen/permissions.mjs.map +1 -1
- package/dist/orchestrators/codegen/service.mjs +157 -105
- package/dist/orchestrators/codegen/service.mjs.map +1 -1
- package/dist/orchestrators/lifecycle-prune/errors.mjs +31 -0
- package/dist/orchestrators/lifecycle-prune/errors.mjs.map +1 -0
- package/dist/orchestrators/lifecycle-prune/index.mjs +350 -0
- package/dist/orchestrators/lifecycle-prune/index.mjs.map +1 -0
- package/dist/orchestrators/router/cleanup.mjs +26 -27
- package/dist/orchestrators/router/cleanup.mjs.map +1 -1
- package/dist/orchestrators/router/entrypoints.mjs +2 -2
- package/dist/orchestrators/router/entrypoints.mjs.map +1 -1
- package/dist/orchestrators/router/file-provider.mjs +14 -5
- package/dist/orchestrators/router/file-provider.mjs.map +1 -1
- package/dist/orchestrators/router/hostname.mjs +19 -55
- package/dist/orchestrators/router/hostname.mjs.map +1 -1
- package/dist/orchestrators/router/index.mjs +11 -0
- package/dist/orchestrators/router/profile.mjs +2 -2
- package/dist/orchestrators/router/sentinels.mjs +26 -0
- package/dist/orchestrators/router/sentinels.mjs.map +1 -0
- package/dist/orchestrators/router/service.mjs +40 -37
- package/dist/orchestrators/router/service.mjs.map +1 -1
- package/dist/orchestrators/router/traefik-container.mjs +27 -16
- package/dist/orchestrators/router/traefik-container.mjs.map +1 -1
- package/dist/{substrate/runtime → orchestrators}/run.mjs +26 -21
- package/dist/orchestrators/run.mjs.map +1 -0
- package/dist/orchestrators/runtime-composition.d.mts +1 -1
- package/dist/orchestrators/runtime-composition.mjs +123 -39
- package/dist/orchestrators/runtime-composition.mjs.map +1 -1
- package/dist/orchestrators/snapshot/capture-command.d.mts +1 -0
- package/dist/orchestrators/snapshot/capture-command.mjs +25 -0
- package/dist/orchestrators/snapshot/capture-command.mjs.map +1 -0
- package/dist/orchestrators/snapshot/capture.mjs +42 -28
- package/dist/orchestrators/snapshot/capture.mjs.map +1 -1
- package/dist/orchestrators/snapshot/descriptor.mjs +35 -10
- package/dist/orchestrators/snapshot/descriptor.mjs.map +1 -1
- package/dist/orchestrators/snapshot/identity-guard.mjs +1 -1
- package/dist/orchestrators/snapshot/index.mjs +13 -0
- package/dist/orchestrators/snapshot/integrity.d.mts +1 -1
- package/dist/orchestrators/snapshot/integrity.mjs +73 -17
- package/dist/orchestrators/snapshot/integrity.mjs.map +1 -1
- package/dist/orchestrators/snapshot/pending-marker.d.mts +1 -0
- package/dist/orchestrators/snapshot/pending-marker.mjs +99 -0
- package/dist/orchestrators/snapshot/pending-marker.mjs.map +1 -0
- package/dist/orchestrators/snapshot/phase-error.mjs +23 -0
- package/dist/orchestrators/snapshot/phase-error.mjs.map +1 -0
- package/dist/orchestrators/snapshot/prune.mjs +20 -55
- package/dist/orchestrators/snapshot/prune.mjs.map +1 -1
- package/dist/orchestrators/snapshot/recover-pending.d.mts +1 -0
- package/dist/orchestrators/snapshot/recover-pending.mjs +223 -0
- package/dist/orchestrators/snapshot/recover-pending.mjs.map +1 -0
- package/dist/orchestrators/snapshot/restore.mjs +118 -84
- package/dist/orchestrators/snapshot/restore.mjs.map +1 -1
- package/dist/orchestrators/snapshot/service.mjs +53 -56
- package/dist/orchestrators/snapshot/service.mjs.map +1 -1
- package/dist/orchestrators/snapshot/state-document.d.mts +1 -0
- package/dist/orchestrators/snapshot/state-document.mjs +47 -7
- package/dist/orchestrators/snapshot/state-document.mjs.map +1 -1
- package/dist/orchestrators/snapshot/wipe.mjs +67 -10
- package/dist/orchestrators/snapshot/wipe.mjs.map +1 -1
- package/dist/plugins/account/codegen.mjs +9 -8
- package/dist/plugins/account/codegen.mjs.map +1 -1
- package/dist/plugins/account/errors.d.mts +33 -6
- package/dist/plugins/account/errors.mjs.map +1 -1
- package/dist/plugins/account/funding.d.mts +29 -19
- package/dist/plugins/account/funding.mjs +84 -66
- package/dist/plugins/account/funding.mjs.map +1 -1
- package/dist/plugins/account/index.d.mts +2 -4
- package/dist/plugins/account/index.mjs +64 -31
- package/dist/plugins/account/index.mjs.map +1 -1
- package/dist/plugins/account/keypair.mjs +6 -9
- package/dist/plugins/account/keypair.mjs.map +1 -1
- package/dist/plugins/account/lease.mjs +1 -0
- package/dist/plugins/account/lease.mjs.map +1 -1
- package/dist/plugins/account/registry.d.mts +14 -1
- package/dist/plugins/account/registry.mjs +18 -18
- package/dist/plugins/account/registry.mjs.map +1 -1
- package/dist/plugins/account/service.d.mts +23 -4
- package/dist/plugins/account/service.mjs +83 -45
- package/dist/plugins/account/service.mjs.map +1 -1
- package/dist/plugins/account/snapshot.mjs +2 -5
- package/dist/plugins/account/snapshot.mjs.map +1 -1
- package/dist/plugins/account/spans.mjs +16 -0
- package/dist/plugins/account/spans.mjs.map +1 -0
- package/dist/plugins/account/variants/keystore.mjs +6 -8
- package/dist/plugins/account/variants/keystore.mjs.map +1 -1
- package/dist/plugins/action/build-context.d.mts +3 -2
- package/dist/plugins/action/errors.d.mts +16 -12
- package/dist/plugins/action/errors.mjs.map +1 -1
- package/dist/plugins/action/execute.mjs +65 -103
- package/dist/plugins/action/execute.mjs.map +1 -1
- package/dist/plugins/action/index.d.mts +0 -2
- package/dist/plugins/action/index.mjs +17 -13
- package/dist/plugins/action/index.mjs.map +1 -1
- package/dist/plugins/action/service.mjs +38 -35
- package/dist/plugins/action/service.mjs.map +1 -1
- package/dist/plugins/action/spans.mjs +11 -0
- package/dist/plugins/action/spans.mjs.map +1 -0
- package/dist/plugins/coin/codegen.mjs +9 -8
- package/dist/plugins/coin/codegen.mjs.map +1 -1
- package/dist/plugins/coin/discovery.mjs +8 -4
- package/dist/plugins/coin/discovery.mjs.map +1 -1
- package/dist/plugins/coin/index.d.mts +11 -29
- package/dist/plugins/coin/index.mjs +56 -27
- package/dist/plugins/coin/index.mjs.map +1 -1
- package/dist/plugins/coin/metadata.mjs +8 -15
- package/dist/plugins/coin/metadata.mjs.map +1 -1
- package/dist/plugins/coin/mint.d.mts +30 -11
- package/dist/plugins/coin/mint.mjs +78 -74
- package/dist/plugins/coin/mint.mjs.map +1 -1
- package/dist/plugins/coin/registry.mjs +4 -7
- package/dist/plugins/coin/registry.mjs.map +1 -1
- package/dist/plugins/coin/service.d.mts +39 -1
- package/dist/plugins/coin/service.mjs +11 -4
- package/dist/plugins/coin/service.mjs.map +1 -1
- package/dist/plugins/coin/spans.mjs +20 -0
- package/dist/plugins/coin/spans.mjs.map +1 -0
- package/dist/plugins/dashboard/domain.mjs +402 -0
- package/dist/plugins/dashboard/domain.mjs.map +1 -0
- package/dist/plugins/dashboard/index.d.mts +29 -0
- package/dist/plugins/dashboard/index.mjs +91 -0
- package/dist/plugins/dashboard/index.mjs.map +1 -0
- package/dist/plugins/dashboard/origin-policy.mjs +36 -0
- package/dist/plugins/dashboard/origin-policy.mjs.map +1 -0
- package/dist/plugins/dashboard/routable.mjs +27 -0
- package/dist/plugins/dashboard/routable.mjs.map +1 -0
- package/dist/plugins/dashboard/schema/builder.mjs +21 -0
- package/dist/plugins/dashboard/schema/builder.mjs.map +1 -0
- package/dist/plugins/dashboard/schema/enums.mjs +72 -0
- package/dist/plugins/dashboard/schema/enums.mjs.map +1 -0
- package/dist/plugins/dashboard/schema/root.mjs +351 -0
- package/dist/plugins/dashboard/schema/root.mjs.map +1 -0
- package/dist/plugins/dashboard/schema/types.mjs +508 -0
- package/dist/plugins/dashboard/schema/types.mjs.map +1 -0
- package/dist/plugins/dashboard/schema.mjs +11 -0
- package/dist/plugins/dashboard/schema.mjs.map +1 -0
- package/dist/plugins/dashboard/server.mjs +166 -0
- package/dist/plugins/dashboard/server.mjs.map +1 -0
- package/dist/plugins/deepbook/deploy.mjs +53 -115
- package/dist/plugins/deepbook/deploy.mjs.map +1 -1
- package/dist/plugins/deepbook/errors.mjs +1 -0
- package/dist/plugins/deepbook/errors.mjs.map +1 -1
- package/dist/plugins/deepbook/faucet-strategy.mjs +47 -34
- package/dist/plugins/deepbook/faucet-strategy.mjs.map +1 -1
- package/dist/plugins/deepbook/hash.mjs +9 -0
- package/dist/plugins/deepbook/hash.mjs.map +1 -0
- package/dist/plugins/deepbook/index.d.mts +1 -10
- package/dist/plugins/deepbook/index.mjs +25 -22
- package/dist/plugins/deepbook/index.mjs.map +1 -1
- package/dist/plugins/deepbook/pyth/index.mjs +26 -55
- package/dist/plugins/deepbook/pyth/index.mjs.map +1 -1
- package/dist/plugins/deepbook/snapshot.mjs +17 -29
- package/dist/plugins/deepbook/snapshot.mjs.map +1 -1
- package/dist/plugins/deepbook/spans.mjs +18 -0
- package/dist/plugins/deepbook/spans.mjs.map +1 -0
- package/dist/plugins/deepbook/type-strings.mjs +65 -0
- package/dist/plugins/deepbook/type-strings.mjs.map +1 -0
- package/dist/plugins/deepbook/types.d.mts +2 -3
- package/dist/plugins/deepbook/types.mjs.map +1 -1
- package/dist/plugins/faucet/dispatcher.d.mts +21 -2
- package/dist/plugins/faucet/dispatcher.mjs +1 -2
- package/dist/plugins/faucet/dispatcher.mjs.map +1 -1
- package/dist/plugins/faucet/errors.d.mts +11 -24
- package/dist/plugins/faucet/errors.mjs.map +1 -1
- package/dist/plugins/faucet/http.mjs +33 -14
- package/dist/plugins/faucet/http.mjs.map +1 -1
- package/dist/plugins/faucet/index.d.mts +15 -5
- package/dist/plugins/faucet/index.mjs +3 -0
- package/dist/plugins/faucet/index.mjs.map +1 -1
- package/dist/plugins/faucet/spans.mjs +12 -0
- package/dist/plugins/faucet/spans.mjs.map +1 -0
- package/dist/plugins/host-service/errors.d.mts +1 -1
- package/dist/plugins/host-service/index.mjs +34 -8
- package/dist/plugins/host-service/index.mjs.map +1 -1
- package/dist/plugins/host-service/routable.mjs +2 -1
- package/dist/plugins/host-service/routable.mjs.map +1 -1
- package/dist/plugins/host-service/service.d.mts +21 -0
- package/dist/plugins/host-service/service.mjs +136 -81
- package/dist/plugins/host-service/service.mjs.map +1 -1
- package/dist/plugins/internal/acquire-on-chain-artifact.mjs +23 -0
- package/dist/plugins/internal/acquire-on-chain-artifact.mjs.map +1 -0
- package/dist/plugins/internal/codegen-helpers.mjs +18 -0
- package/dist/plugins/internal/codegen-helpers.mjs.map +1 -0
- package/dist/plugins/internal/funding-failure-error.mjs +32 -0
- package/dist/plugins/internal/funding-failure-error.mjs.map +1 -0
- package/dist/plugins/package/build.mjs +1 -1
- package/dist/plugins/package/build.mjs.map +1 -1
- package/dist/plugins/package/codegen.mjs +26 -0
- package/dist/plugins/package/codegen.mjs.map +1 -1
- package/dist/plugins/package/errors.d.mts +16 -6
- package/dist/plugins/package/errors.mjs.map +1 -1
- package/dist/plugins/package/index.d.mts +0 -4
- package/dist/plugins/package/index.mjs +27 -21
- package/dist/plugins/package/index.mjs.map +1 -1
- package/dist/plugins/package/mode-known.mjs +26 -12
- package/dist/plugins/package/mode-known.mjs.map +1 -1
- package/dist/plugins/package/mode-local.mjs +47 -41
- package/dist/plugins/package/mode-local.mjs.map +1 -1
- package/dist/plugins/package/publish-executor.mjs +55 -114
- package/dist/plugins/package/publish-executor.mjs.map +1 -1
- package/dist/plugins/package/registry.mjs +2 -1
- package/dist/plugins/package/registry.mjs.map +1 -1
- package/dist/plugins/package/service.mjs.map +1 -1
- package/dist/plugins/package/spans.mjs +14 -0
- package/dist/plugins/package/spans.mjs.map +1 -0
- package/dist/plugins/postgres/db-ensure.mjs +19 -12
- package/dist/plugins/postgres/db-ensure.mjs.map +1 -1
- package/dist/plugins/postgres/errors.d.mts +5 -0
- package/dist/plugins/postgres/errors.mjs.map +1 -1
- package/dist/plugins/postgres/index.mjs +10 -17
- package/dist/plugins/postgres/index.mjs.map +1 -1
- package/dist/plugins/postgres/service.mjs +58 -24
- package/dist/plugins/postgres/service.mjs.map +1 -1
- package/dist/plugins/postgres/snapshot.mjs.map +1 -1
- package/dist/plugins/postgres/spans.mjs +11 -0
- package/dist/plugins/postgres/spans.mjs.map +1 -0
- package/dist/plugins/router-entrypoints.mjs +4 -4
- package/dist/plugins/router-entrypoints.mjs.map +1 -1
- package/dist/plugins/seal/bootstrap-assets/cargo-image.mjs +15 -13
- package/dist/plugins/seal/bootstrap-assets/cargo-image.mjs.map +1 -1
- package/dist/plugins/seal/bootstrap-assets/source-fetch.mjs +15 -19
- package/dist/plugins/seal/bootstrap-assets/source-fetch.mjs.map +1 -1
- package/dist/plugins/seal/codegen.d.mts +2 -3
- package/dist/plugins/seal/codegen.mjs.map +1 -1
- package/dist/plugins/seal/config-render.mjs +35 -8
- package/dist/plugins/seal/config-render.mjs.map +1 -1
- package/dist/plugins/seal/deploy.mjs +31 -39
- package/dist/plugins/seal/deploy.mjs.map +1 -1
- package/dist/plugins/seal/errors.d.mts +1 -3
- package/dist/plugins/seal/errors.mjs +7 -1
- package/dist/plugins/seal/errors.mjs.map +1 -1
- package/dist/plugins/seal/index.d.mts +1 -6
- package/dist/plugins/seal/index.mjs +40 -14
- package/dist/plugins/seal/index.mjs.map +1 -1
- package/dist/plugins/seal/key-manager.d.mts +1 -9
- package/dist/plugins/seal/key-manager.mjs +2 -18
- package/dist/plugins/seal/key-manager.mjs.map +1 -1
- package/dist/plugins/seal/key-server.mjs +37 -36
- package/dist/plugins/seal/key-server.mjs.map +1 -1
- package/dist/plugins/seal/keygen.mjs +16 -17
- package/dist/plugins/seal/keygen.mjs.map +1 -1
- package/dist/plugins/seal/mode/fork-known.mjs +36 -14
- package/dist/plugins/seal/mode/fork-known.mjs.map +1 -1
- package/dist/plugins/seal/mode/live.d.mts +6 -4
- package/dist/plugins/seal/mode/live.mjs +14 -21
- package/dist/plugins/seal/mode/live.mjs.map +1 -1
- package/dist/plugins/seal/mode/local-keygen.mjs +57 -21
- package/dist/plugins/seal/mode/local-keygen.mjs.map +1 -1
- package/dist/plugins/seal/registry-publish.mjs +1 -0
- 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/spans.mjs +18 -0
- package/dist/plugins/seal/spans.mjs.map +1 -0
- package/dist/plugins/sui/auto-tick.mjs +17 -23
- package/dist/plugins/sui/auto-tick.mjs.map +1 -1
- package/dist/plugins/sui/chain-build-container.mjs +18 -0
- package/dist/plugins/sui/chain-build-container.mjs.map +1 -0
- package/dist/plugins/sui/chain-probe.d.mts +5 -5
- package/dist/plugins/sui/chain-probe.mjs +28 -58
- package/dist/plugins/sui/chain-probe.mjs.map +1 -1
- package/dist/plugins/sui/codegen.mjs +26 -0
- package/dist/plugins/sui/codegen.mjs.map +1 -1
- package/dist/plugins/sui/errors.d.mts +2 -29
- package/dist/plugins/sui/errors.mjs +1 -3
- package/dist/plugins/sui/errors.mjs.map +1 -1
- package/dist/plugins/sui/fork-faucet-strategy.d.mts +1 -0
- package/dist/plugins/sui/fork-faucet-strategy.mjs +55 -0
- package/dist/plugins/sui/fork-faucet-strategy.mjs.map +1 -0
- package/dist/plugins/sui/fork-orchestration.d.mts +1 -0
- package/dist/plugins/sui/fork-orchestration.mjs +170 -2
- package/dist/plugins/sui/fork-orchestration.mjs.map +1 -1
- package/dist/plugins/sui/fork-transaction.d.mts +2 -0
- package/dist/plugins/sui/fork-transaction.mjs +92 -28
- package/dist/plugins/sui/fork-transaction.mjs.map +1 -1
- package/dist/plugins/sui/index.d.mts +33 -70
- package/dist/plugins/sui/index.mjs +58 -35
- package/dist/plugins/sui/index.mjs.map +1 -1
- package/dist/plugins/{faucet/strategies/sui-local.mjs → sui/local-faucet-strategy.mjs} +10 -7
- package/dist/plugins/sui/local-faucet-strategy.mjs.map +1 -0
- package/dist/plugins/sui/mode/external.mjs +7 -13
- package/dist/plugins/sui/mode/external.mjs.map +1 -1
- package/dist/plugins/sui/mode/fork.mjs +136 -59
- package/dist/plugins/sui/mode/fork.mjs.map +1 -1
- package/dist/plugins/sui/mode/live.mjs +10 -16
- package/dist/plugins/sui/mode/live.mjs.map +1 -1
- package/dist/plugins/sui/mode/local.mjs +37 -36
- package/dist/plugins/sui/mode/local.mjs.map +1 -1
- package/dist/plugins/sui/mode/shared-boot.mjs +38 -115
- package/dist/plugins/sui/mode/shared-boot.mjs.map +1 -1
- package/dist/plugins/sui/mode/shared.d.mts +1 -5
- package/dist/plugins/sui/mode/shared.mjs.map +1 -1
- package/dist/plugins/sui/mode/spec.d.mts +18 -0
- package/dist/plugins/sui/move-summary-runner.mjs +207 -0
- package/dist/plugins/sui/move-summary-runner.mjs.map +1 -0
- package/dist/plugins/sui/network-resolver.d.mts +4 -3
- package/dist/plugins/sui/service.mjs.map +1 -1
- package/dist/plugins/sui/snapshot.mjs +3 -0
- package/dist/plugins/sui/snapshot.mjs.map +1 -1
- package/dist/plugins/sui/spans.mjs +17 -0
- package/dist/plugins/sui/spans.mjs.map +1 -0
- package/dist/plugins/wallet/codegen.d.mts +0 -1
- package/dist/plugins/wallet/codegen.mjs +8 -9
- package/dist/plugins/wallet/codegen.mjs.map +1 -1
- package/dist/plugins/wallet/index.d.mts +6 -8
- package/dist/plugins/wallet/index.mjs +46 -35
- package/dist/plugins/wallet/index.mjs.map +1 -1
- package/dist/plugins/wallet/origin-policy.mjs +12 -28
- package/dist/plugins/wallet/origin-policy.mjs.map +1 -1
- package/dist/plugins/wallet/pairing.mjs +6 -4
- package/dist/plugins/wallet/pairing.mjs.map +1 -1
- package/dist/plugins/wallet/protocol.d.mts +1 -0
- package/dist/plugins/wallet/protocol.mjs +5 -44
- package/dist/plugins/wallet/protocol.mjs.map +1 -1
- package/dist/plugins/wallet/routable.mjs +2 -8
- package/dist/plugins/wallet/routable.mjs.map +1 -1
- package/dist/plugins/wallet/server.mjs +36 -44
- package/dist/plugins/wallet/server.mjs.map +1 -1
- package/dist/plugins/wallet/service.d.mts +1 -5
- package/dist/plugins/wallet/service.mjs +22 -18
- package/dist/plugins/wallet/service.mjs.map +1 -1
- package/dist/plugins/wallet/spans.mjs +22 -0
- package/dist/plugins/wallet/spans.mjs.map +1 -0
- package/dist/plugins/walrus/bootstrap-assets/cargo-image.mjs +33 -8
- package/dist/plugins/walrus/bootstrap-assets/cargo-image.mjs.map +1 -1
- package/dist/plugins/walrus/codegen.d.mts +3 -3
- package/dist/plugins/walrus/codegen.mjs.map +1 -1
- package/dist/plugins/walrus/deploy-paths.mjs +21 -5
- package/dist/plugins/walrus/deploy-paths.mjs.map +1 -1
- package/dist/plugins/walrus/deploy.mjs +67 -69
- package/dist/plugins/walrus/deploy.mjs.map +1 -1
- package/dist/plugins/walrus/errors.mjs +1 -0
- package/dist/plugins/walrus/errors.mjs.map +1 -1
- package/dist/plugins/walrus/faucet-strategy.mjs +12 -7
- package/dist/plugins/walrus/faucet-strategy.mjs.map +1 -1
- package/dist/plugins/walrus/index.d.mts +2 -13
- package/dist/plugins/walrus/index.mjs +18 -23
- package/dist/plugins/walrus/index.mjs.map +1 -1
- package/dist/plugins/walrus/mode/known-deploy.mjs +7 -5
- package/dist/plugins/walrus/mode/known-deploy.mjs.map +1 -1
- package/dist/plugins/walrus/mode/local-cluster.mjs +26 -7
- package/dist/plugins/walrus/mode/local-cluster.mjs.map +1 -1
- package/dist/plugins/walrus/registry-publish.mjs.map +1 -1
- package/dist/plugins/walrus/routable.mjs +7 -23
- package/dist/plugins/walrus/routable.mjs.map +1 -1
- package/dist/plugins/walrus/service.mjs.map +1 -1
- package/dist/plugins/walrus/spans.mjs +18 -0
- package/dist/plugins/walrus/spans.mjs.map +1 -0
- package/dist/plugins/walrus/storage-nodes.d.mts +6 -2
- package/dist/plugins/walrus/storage-nodes.mjs +15 -8
- package/dist/plugins/walrus/storage-nodes.mjs.map +1 -1
- package/dist/plugins/walrus/wal-swap.mjs +58 -15
- package/dist/plugins/walrus/wal-swap.mjs.map +1 -1
- package/dist/primitives/artifact-publisher.d.mts +1 -1
- package/dist/primitives/artifact-publisher.mjs +15 -0
- package/dist/primitives/artifact-publisher.mjs.map +1 -0
- package/dist/runtime/docker/client.mjs +17 -4
- package/dist/runtime/docker/client.mjs.map +1 -1
- package/dist/runtime/docker/container.mjs +219 -132
- package/dist/runtime/docker/container.mjs.map +1 -1
- package/dist/runtime/docker/errors.mjs +0 -6
- package/dist/runtime/docker/errors.mjs.map +1 -1
- package/dist/runtime/docker/exec.mjs +21 -18
- package/dist/runtime/docker/exec.mjs.map +1 -1
- package/dist/runtime/docker/image.mjs +36 -13
- package/dist/runtime/docker/image.mjs.map +1 -1
- package/dist/runtime/docker/index.mjs +14 -0
- package/dist/runtime/docker/inspect-and-decode.mjs +51 -0
- package/dist/runtime/docker/inspect-and-decode.mjs.map +1 -0
- package/dist/runtime/docker/inventory.mjs +14 -11
- package/dist/runtime/docker/inventory.mjs.map +1 -1
- package/dist/runtime/docker/labels.mjs +38 -5
- package/dist/runtime/docker/labels.mjs.map +1 -1
- package/dist/runtime/docker/logs.d.mts +1 -1
- package/dist/runtime/docker/logs.mjs.map +1 -1
- package/dist/runtime/docker/network.mjs +83 -47
- package/dist/runtime/docker/network.mjs.map +1 -1
- package/dist/runtime/docker/render-run-args.mjs +82 -0
- package/dist/runtime/docker/render-run-args.mjs.map +1 -0
- package/dist/runtime/docker/service.d.mts +1 -1
- package/dist/runtime/docker/service.mjs +12 -7
- package/dist/runtime/docker/service.mjs.map +1 -1
- package/dist/runtime/docker/sweep.mjs +118 -43
- package/dist/runtime/docker/sweep.mjs.map +1 -1
- package/dist/runtime/docker/volume.mjs +2 -0
- package/dist/runtime/docker/volume.mjs.map +1 -1
- package/dist/runtime/docker/wrap.mjs +30 -1
- package/dist/runtime/docker/wrap.mjs.map +1 -1
- package/dist/substrate/cross-process.mjs +14 -8
- package/dist/substrate/cross-process.mjs.map +1 -1
- package/dist/substrate/event-time.mjs +33 -0
- package/dist/substrate/event-time.mjs.map +1 -0
- package/dist/substrate/events.d.mts +28 -8
- package/dist/substrate/identity.d.mts +2 -1
- package/dist/substrate/manifest.d.mts +68 -5
- package/dist/substrate/manifest.mjs +34 -5
- package/dist/substrate/manifest.mjs.map +1 -1
- package/dist/substrate/network.d.mts +3 -5
- package/dist/substrate/options.d.mts +0 -2
- package/dist/substrate/plugin.d.mts +13 -0
- package/dist/substrate/plugin.mjs +4 -2
- package/dist/substrate/plugin.mjs.map +1 -1
- package/dist/substrate/projection.d.mts +35 -3
- package/dist/substrate/runtime/artifact-publisher/index.mjs +19 -9
- package/dist/substrate/runtime/artifact-publisher/index.mjs.map +1 -1
- package/dist/substrate/runtime/atomic-write.mjs +97 -32
- package/dist/substrate/runtime/atomic-write.mjs.map +1 -1
- package/dist/substrate/runtime/cache/index.mjs +3 -0
- package/dist/substrate/runtime/cache/schema.mjs +2 -2
- package/dist/substrate/runtime/cache/schema.mjs.map +1 -1
- package/dist/substrate/runtime/cache/service.mjs +9 -7
- package/dist/substrate/runtime/cache/service.mjs.map +1 -1
- package/dist/substrate/runtime/capability-sinks/index.d.mts +1 -1
- package/dist/substrate/runtime/capability-sinks/index.mjs +3 -0
- package/dist/substrate/runtime/capability-sinks/layer.mjs +1 -1
- package/dist/substrate/runtime/capability-sinks/service.d.mts +61 -2
- package/dist/substrate/runtime/capability-sinks/service.mjs +21 -26
- package/dist/substrate/runtime/capability-sinks/service.mjs.map +1 -1
- package/dist/substrate/runtime/config-validation.d.mts +1 -13
- package/dist/substrate/runtime/config-validation.mjs +2 -91
- package/dist/substrate/runtime/config-validation.mjs.map +1 -1
- package/dist/substrate/runtime/container-runtime.d.mts +1 -0
- package/dist/substrate/runtime/container-runtime.mjs +2 -0
- package/dist/substrate/runtime/control-plane/domain.mjs +101 -0
- package/dist/substrate/runtime/control-plane/domain.mjs.map +1 -0
- package/dist/substrate/runtime/control-plane/service.mjs +7 -0
- package/dist/substrate/runtime/control-plane/service.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/command-channel/channel.mjs +46 -19
- package/dist/substrate/runtime/cross-process/command-channel/channel.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/command-channel/file-channel.mjs +30 -12
- package/dist/substrate/runtime/cross-process/command-channel/file-channel.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/command-channel/index.mjs +5 -0
- package/dist/substrate/runtime/cross-process/command-channel/protocol.mjs +11 -2
- 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 +1 -1
- package/dist/substrate/runtime/cross-process/index.mjs +11 -0
- package/dist/substrate/runtime/cross-process/live-clock.mjs +34 -0
- package/dist/substrate/runtime/cross-process/live-clock.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/liveness.mjs +52 -10
- package/dist/substrate/runtime/cross-process/liveness.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/lock.d.mts +1 -0
- package/dist/substrate/runtime/cross-process/lock.mjs +23 -0
- package/dist/substrate/runtime/cross-process/lock.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/reclaim-stale-file.mjs +64 -0
- package/dist/substrate/runtime/cross-process/reclaim-stale-file.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/roster.mjs +97 -83
- package/dist/substrate/runtime/cross-process/roster.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/self-pid.mjs +8 -0
- package/dist/substrate/runtime/cross-process/self-pid.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/snapshot-reservation.mjs +24 -28
- package/dist/substrate/runtime/cross-process/snapshot-reservation.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/stack-lock.mjs +41 -20
- package/dist/substrate/runtime/cross-process/stack-lock.mjs.map +1 -1
- package/dist/substrate/runtime/current-plugin.mjs +2 -2
- package/dist/substrate/runtime/current-plugin.mjs.map +1 -1
- package/dist/substrate/runtime/errors.mjs +12 -6
- package/dist/substrate/runtime/errors.mjs.map +1 -1
- package/dist/substrate/runtime/format-unknown-error.mjs +30 -0
- package/dist/substrate/runtime/format-unknown-error.mjs.map +1 -0
- package/dist/substrate/runtime/host-bind-mount-owner.mjs +10 -0
- package/dist/substrate/runtime/host-bind-mount-owner.mjs.map +1 -0
- package/dist/substrate/runtime/host-gateway.mjs +20 -0
- package/dist/substrate/runtime/host-gateway.mjs.map +1 -0
- package/dist/substrate/runtime/host-tree-tar/index.mjs +61 -50
- package/dist/substrate/runtime/host-tree-tar/index.mjs.map +1 -1
- package/dist/substrate/runtime/http-probe.d.mts +1 -1
- package/dist/substrate/runtime/index.mjs +14 -0
- package/dist/substrate/runtime/lease-broker/index.d.mts +1 -1
- package/dist/substrate/runtime/lease-broker/index.mjs +2 -0
- package/dist/substrate/runtime/lease-broker/service.d.mts +1 -64
- package/dist/substrate/runtime/lease-broker/service.mjs +1 -1
- package/dist/substrate/runtime/lease-broker/service.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/dep-graph.mjs +22 -3
- package/dist/substrate/runtime/lifecycle/dep-graph.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/index.mjs +9 -0
- package/dist/substrate/runtime/lifecycle/lifecycle-fact.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/plugin-registry.mjs +20 -3
- package/dist/substrate/runtime/lifecycle/plugin-registry.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/selective-restart.mjs +1 -1
- package/dist/substrate/runtime/lifecycle/signals.mjs +5 -5
- package/dist/substrate/runtime/lifecycle/signals.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/state-machine.mjs +1 -1
- package/dist/substrate/runtime/managed-container.d.mts +19 -1
- package/dist/substrate/runtime/managed-container.mjs +20 -1
- package/dist/substrate/runtime/managed-container.mjs.map +1 -1
- package/dist/substrate/runtime/manifest/index.mjs +3 -0
- package/dist/substrate/runtime/manifest/manifest.mjs +15 -11
- package/dist/substrate/runtime/manifest/manifest.mjs.map +1 -1
- package/dist/substrate/runtime/mode-errors.mjs +20 -0
- package/dist/substrate/runtime/mode-errors.mjs.map +1 -0
- package/dist/substrate/runtime/observability/cascade-formatter.mjs +9 -13
- package/dist/substrate/runtime/observability/cascade-formatter.mjs.map +1 -1
- package/dist/substrate/runtime/observability/formatter-registry.mjs +19 -36
- package/dist/substrate/runtime/observability/formatter-registry.mjs.map +1 -1
- package/dist/substrate/runtime/observability/ignore-with-log.d.mts +1 -0
- package/dist/substrate/runtime/observability/ignore-with-log.mjs +17 -0
- package/dist/substrate/runtime/observability/ignore-with-log.mjs.map +1 -0
- package/dist/substrate/runtime/observability/index.d.mts +1 -1
- package/dist/substrate/runtime/observability/index.mjs +13 -0
- package/dist/substrate/runtime/observability/log-store.d.mts +1 -0
- package/dist/substrate/runtime/observability/log-store.mjs +175 -0
- package/dist/substrate/runtime/observability/log-store.mjs.map +1 -0
- package/dist/substrate/runtime/observability/logger.d.mts +2 -1
- package/dist/substrate/runtime/observability/logger.mjs +5 -9
- package/dist/substrate/runtime/observability/logger.mjs.map +1 -1
- package/dist/substrate/runtime/observability/output-truncate.mjs +35 -0
- package/dist/substrate/runtime/observability/output-truncate.mjs.map +1 -0
- package/dist/substrate/runtime/observability/pretty-error.mjs +9 -12
- package/dist/substrate/runtime/observability/pretty-error.mjs.map +1 -1
- package/dist/substrate/runtime/observability/redaction.d.mts +2 -13
- package/dist/substrate/runtime/observability/redaction.mjs +8 -14
- package/dist/substrate/runtime/observability/redaction.mjs.map +1 -1
- package/dist/substrate/runtime/observability/span-store.d.mts +1 -0
- package/dist/substrate/runtime/observability/span-store.mjs +110 -0
- package/dist/substrate/runtime/observability/span-store.mjs.map +1 -0
- package/dist/substrate/runtime/observability/spans.mjs +14 -14
- package/dist/substrate/runtime/observability/spans.mjs.map +1 -1
- package/dist/substrate/runtime/observability/subprocess-capture.mjs +1 -1
- package/dist/substrate/runtime/passthrough-or-wrap.mjs +33 -0
- package/dist/substrate/runtime/passthrough-or-wrap.mjs.map +1 -0
- package/dist/substrate/runtime/paths.d.mts +1 -1
- package/dist/substrate/runtime/paths.mjs +4 -3
- package/dist/substrate/runtime/paths.mjs.map +1 -1
- package/dist/substrate/runtime/phase-preserving-produce.mjs +40 -0
- package/dist/substrate/runtime/phase-preserving-produce.mjs.map +1 -0
- package/dist/substrate/runtime/port-broker/index.mjs +3 -0
- package/dist/substrate/runtime/port-broker/service.mjs +170 -126
- package/dist/substrate/runtime/port-broker/service.mjs.map +1 -1
- package/dist/substrate/runtime/post-acquire-tasks.mjs +1 -1
- package/dist/substrate/runtime/post-acquire-tasks.mjs.map +1 -1
- package/dist/substrate/runtime/probes.d.mts +7 -5
- package/dist/substrate/runtime/probes.mjs +3 -1
- package/dist/substrate/runtime/probes.mjs.map +1 -1
- package/dist/substrate/runtime/projection/index.mjs +4 -0
- package/dist/substrate/runtime/projection/operational-endpoints.mjs +1 -2
- package/dist/substrate/runtime/projection/operational-endpoints.mjs.map +1 -1
- package/dist/substrate/runtime/projection/persisted.mjs +33 -15
- package/dist/substrate/runtime/projection/persisted.mjs.map +1 -1
- package/dist/substrate/runtime/projection/state-ref.mjs +26 -2
- package/dist/substrate/runtime/projection/state-ref.mjs.map +1 -1
- package/dist/substrate/runtime/projection/update.mjs +88 -24
- package/dist/substrate/runtime/projection/update.mjs.map +1 -1
- package/dist/substrate/runtime/random-suffix.mjs +11 -0
- package/dist/substrate/runtime/random-suffix.mjs.map +1 -0
- package/dist/substrate/runtime/retry-policy.d.mts +59 -1
- package/dist/substrate/runtime/retry-policy.mjs +66 -1
- package/dist/substrate/runtime/retry-policy.mjs.map +1 -1
- package/dist/substrate/runtime/routed-url.d.mts +1 -0
- package/dist/substrate/runtime/routed-url.mjs +79 -0
- package/dist/substrate/runtime/routed-url.mjs.map +1 -0
- package/dist/substrate/runtime/runtime-decode.d.mts +1 -1
- package/dist/substrate/runtime/runtime-decode.mjs.map +1 -1
- package/dist/substrate/runtime/scoped-http-server.mjs +2 -3
- package/dist/substrate/runtime/scoped-http-server.mjs.map +1 -1
- package/dist/substrate/runtime/scoped-multimap/index.mjs +2 -0
- package/dist/substrate/runtime/scoped-multimap/service.mjs +52 -0
- package/dist/substrate/runtime/scoped-multimap/service.mjs.map +1 -0
- package/dist/substrate/runtime/scoped-ref-map/index.mjs +2 -0
- package/dist/substrate/runtime/scoped-ref-map/service.mjs +2 -2
- package/dist/substrate/runtime/scoped-ref-map/service.mjs.map +1 -1
- package/dist/substrate/runtime/stage-and-swap/index.mjs +72 -4
- package/dist/substrate/runtime/stage-and-swap/index.mjs.map +1 -1
- package/dist/substrate/runtime/state-store/index.d.mts +1 -0
- package/dist/substrate/runtime/state-store/index.mjs +3 -0
- package/dist/substrate/runtime/state-store/schema.d.mts +1 -0
- package/dist/substrate/runtime/state-store/schema.mjs +19 -14
- package/dist/substrate/runtime/state-store/schema.mjs.map +1 -1
- package/dist/substrate/runtime/state-store/service.d.mts +1 -0
- package/dist/substrate/runtime/state-store/service.mjs +145 -0
- package/dist/substrate/runtime/state-store/service.mjs.map +1 -0
- package/dist/substrate/runtime/strategy-registry/chain-keyed-strategy-for.d.mts +1 -0
- package/dist/substrate/runtime/strategy-registry/chain-keyed-strategy-for.mjs +33 -0
- package/dist/substrate/runtime/strategy-registry/chain-keyed-strategy-for.mjs.map +1 -0
- package/dist/substrate/runtime/strategy-registry/chain-probe-for.mjs +1 -1
- package/dist/substrate/runtime/strategy-registry/chain-probe-for.mjs.map +1 -1
- package/dist/substrate/runtime/strategy-registry/index.mjs +4 -0
- package/dist/substrate/runtime/strategy-registry/service.mjs +19 -33
- package/dist/substrate/runtime/strategy-registry/service.mjs.map +1 -1
- package/dist/substrate/runtime/subnet-broker.mjs +60 -0
- package/dist/substrate/runtime/subnet-broker.mjs.map +1 -0
- package/dist/substrate/runtime/sui-execute/index.d.mts +21 -1
- package/dist/substrate/runtime/sui-execute/index.mjs +84 -20
- package/dist/substrate/runtime/sui-execute/index.mjs.map +1 -1
- package/dist/substrate/runtime/sui-execute/sign-and-dispatch.d.mts +1 -0
- package/dist/substrate/runtime/sui-execute/sign-and-dispatch.mjs +32 -0
- package/dist/substrate/runtime/sui-execute/sign-and-dispatch.mjs.map +1 -0
- package/dist/substrate/runtime/sui-ledger/object-ref.mjs +32 -0
- package/dist/substrate/runtime/sui-ledger/object-ref.mjs.map +1 -0
- package/dist/substrate/runtime/sui-move-build/index.mjs +93 -19
- package/dist/substrate/runtime/sui-move-build/index.mjs.map +1 -1
- package/dist/substrate/runtime/supervisor/acquire-node.mjs +181 -0
- package/dist/substrate/runtime/supervisor/acquire-node.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor/background-tasks.mjs +144 -0
- package/dist/substrate/runtime/supervisor/background-tasks.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor/command-loop.mjs +68 -0
- package/dist/substrate/runtime/supervisor/command-loop.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor/dispatch-contributions.mjs +151 -0
- package/dist/substrate/runtime/supervisor/dispatch-contributions.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor/errors.d.mts +1 -0
- package/dist/substrate/runtime/supervisor/errors.mjs +9 -0
- package/dist/substrate/runtime/supervisor/errors.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor/index.d.mts +1 -0
- package/dist/substrate/runtime/supervisor/index.mjs +3 -0
- package/dist/substrate/runtime/supervisor/shutdown.mjs +51 -0
- package/dist/substrate/runtime/supervisor/shutdown.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor/start-supervisor.d.mts +1 -0
- package/dist/substrate/runtime/supervisor/start-supervisor.mjs +250 -0
- package/dist/substrate/runtime/supervisor/start-supervisor.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor/state.d.mts +1 -0
- package/dist/substrate/runtime/supervisor/state.mjs +22 -0
- package/dist/substrate/runtime/supervisor/state.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor/teardown.mjs +57 -0
- package/dist/substrate/runtime/supervisor/teardown.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor/types.d.mts +1 -0
- package/dist/substrate/runtime/supervisor/wiring.mjs +133 -0
- package/dist/substrate/runtime/supervisor/wiring.mjs.map +1 -0
- package/dist/substrate/runtime/typed-env.mjs +8 -0
- package/dist/substrate/runtime/typed-env.mjs.map +1 -0
- package/dist/substrate/state-store.d.mts +1 -0
- package/dist/substrate/versioned-doc-schema.mjs +17 -0
- package/dist/substrate/versioned-doc-schema.mjs.map +1 -0
- package/dist/substrate/versioned-doc-sync.mjs +94 -0
- package/dist/substrate/versioned-doc-sync.mjs.map +1 -0
- package/dist/surfaces/cli/command-tree.mjs.map +1 -1
- package/dist/surfaces/cli/commands/index.mjs +9 -0
- package/dist/surfaces/cli/commands/prune-picker-entry.mjs +13 -0
- package/dist/surfaces/cli/commands/prune-picker-entry.mjs.map +1 -0
- package/dist/surfaces/cli/commands/prune-picker.mjs +3 -2
- package/dist/surfaces/cli/commands/prune-picker.mjs.map +1 -1
- package/dist/surfaces/cli/commands/prune.mjs +34 -17
- package/dist/surfaces/cli/commands/prune.mjs.map +1 -1
- package/dist/surfaces/cli/commands/status.mjs +2 -2
- package/dist/surfaces/cli/commands/status.mjs.map +1 -1
- package/dist/surfaces/cli/commands/supervisor-presence.mjs +5 -3
- package/dist/surfaces/cli/commands/supervisor-presence.mjs.map +1 -1
- package/dist/surfaces/cli/commands/wipe.mjs +38 -4
- package/dist/surfaces/cli/commands/wipe.mjs.map +1 -1
- package/dist/surfaces/cli/errors.mjs +1 -1
- package/dist/surfaces/cli/errors.mjs.map +1 -1
- package/dist/surfaces/cli/flags.mjs +0 -1
- package/dist/surfaces/cli/flags.mjs.map +1 -1
- package/dist/surfaces/cli/index.mjs +98 -18
- package/dist/surfaces/cli/index.mjs.map +1 -1
- package/dist/surfaces/cli/output.mjs +1 -0
- package/dist/surfaces/cli/output.mjs.map +1 -1
- package/dist/surfaces/cli/sysexits.mjs +2 -1
- package/dist/surfaces/cli/sysexits.mjs.map +1 -1
- package/dist/surfaces/tui/app.mjs +25 -3
- package/dist/surfaces/tui/app.mjs.map +1 -1
- package/dist/surfaces/tui/display-derivation.mjs +23 -74
- package/dist/surfaces/tui/display-derivation.mjs.map +1 -1
- package/dist/surfaces/tui/event-log.mjs +35 -23
- package/dist/surfaces/tui/event-log.mjs.map +1 -1
- package/dist/surfaces/tui/input.mjs +5 -1
- package/dist/surfaces/tui/input.mjs.map +1 -1
- package/dist/surfaces/tui/plain-renderer.mjs +70 -34
- package/dist/surfaces/tui/plain-renderer.mjs.map +1 -1
- package/package.json +24 -4
- package/dist/contracts/liveness-classifier.d.mts +0 -19
- package/dist/contracts/network-resolver.d.mts +0 -15
- package/dist/contracts/network-resolver.mjs +0 -7
- package/dist/contracts/network-resolver.mjs.map +0 -1
- package/dist/orchestrators/codegen/extras.mjs +0 -16
- package/dist/orchestrators/codegen/extras.mjs.map +0 -1
- package/dist/plugins/deepbook/routable.mjs +0 -21
- package/dist/plugins/deepbook/routable.mjs.map +0 -1
- package/dist/plugins/faucet/service.d.mts +0 -20
- package/dist/plugins/faucet/strategies/sui-local.d.mts +0 -23
- package/dist/plugins/faucet/strategies/sui-local.mjs.map +0 -1
- package/dist/plugins/sui/seed-objects.d.mts +0 -18
- package/dist/plugins/sui/seed-objects.mjs +0 -25
- package/dist/plugins/sui/seed-objects.mjs.map +0 -1
- package/dist/runtime/built-in-plugin-layers.mjs.map +0 -1
- package/dist/substrate/runtime/context-helpers.mjs +0 -32
- package/dist/substrate/runtime/context-helpers.mjs.map +0 -1
- package/dist/substrate/runtime/run.mjs.map +0 -1
- package/dist/substrate/runtime/strategy-registry/faucet-capability-for.mjs +0 -30
- package/dist/substrate/runtime/strategy-registry/faucet-capability-for.mjs.map +0 -1
- package/dist/substrate/runtime/supervisor.d.mts +0 -1
- package/dist/substrate/runtime/supervisor.mjs +0 -831
- package/dist/substrate/runtime/supervisor.mjs.map +0 -1
- package/dist/surfaces/cli/commands/doctor-probes.mjs.map +0 -1
- /package/dist/{substrate/runtime/strategy-registry/faucet-capability-for.d.mts → plugins/faucet/http.d.mts} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sysexits.mjs","names":[],"sources":["../../../src/surfaces/cli/sysexits.ts"],"sourcesContent":["// CLI surface — sysexits.h exit codes.\n//\n// Architecture (distilled/20-cli.md § Invariants) requires a single\n// centralized table. Numbers are pinned, names are stable, new\n// devstack-domain codes are added at the END of the domain block (so\n// downstream scripts keying off numerics never shift).\n//\n// Reference: /usr/include/sysexits.h (BSD-derived). We use only the\n// subset that maps to CLI failure shapes; everything else collapses to\n// `EX_SOFTWARE` (70). The devstack-domain block (40-43) is a private\n// extension carved out below the standard 64-78 range so it cannot\n// collide with the OS table.\n//\n// Surface invariant: every CLI failure carries one of these codes in\n// the JSON envelope's `error.exitCode` AND drives `process.exitCode`.\n// \"1 for everything\" is explicitly disallowed by the architecture.\n\n/** Sysexits-named exit codes (numeric values are stable; do NOT reuse). */\nexport const ExitCode = {\n\t/** Successful termination. */\n\tOK: 0,\n\t/** Generic catch-all failure. Use only when no specific code applies. */\n\tGENERIC: 1,\n\t/** Devstack-domain: supervisor for the target stack is already live\n\t * in another process. Destructive verbs refuse with this code. */\n\tSUPERVISOR_LIVE: 40,\n\t/** Devstack-domain: requested snapshot name / id not found. */\n\tSNAPSHOT_NOT_FOUND: 41,\n\t/** Devstack-domain: seed manifest mismatch between current chain\n\t * identity and the snapshot/seed being restored. */\n\tSEED_MISMATCH: 42,\n\t/** Devstack-domain: destructive verb requires explicit confirm but\n\t * `--no-input` / non-TTY / no `--yes` is in effect, or the\n\t * interactive prompt was declined. */\n\tCONFIRM_REQUIRED: 43,\n\t/** Bad usage (unknown flag, malformed args, mutually-exclusive\n\t * flag pair, ambiguous reference). */\n\tUSAGE: 64,\n\t/** Input data malformed (config schema invalid, JSON parse error\n\t * inside a snapshot manifest, etc.). */\n\tDATA_ERR: 65,\n\t/** Cannot open input (config not found, snapshot file missing). */\n\tNO_INPUT: 66,\n\t/** Internal software error / unhandled defect. Default for\n\t * defects that escape Effect.
|
|
1
|
+
{"version":3,"file":"sysexits.mjs","names":["_exhaustive"],"sources":["../../../src/surfaces/cli/sysexits.ts"],"sourcesContent":["// CLI surface — sysexits.h exit codes.\n//\n// Architecture (distilled/20-cli.md § Invariants) requires a single\n// centralized table. Numbers are pinned, names are stable, new\n// devstack-domain codes are added at the END of the domain block (so\n// downstream scripts keying off numerics never shift).\n//\n// Reference: /usr/include/sysexits.h (BSD-derived). We use only the\n// subset that maps to CLI failure shapes; everything else collapses to\n// `EX_SOFTWARE` (70). The devstack-domain block (40-43) is a private\n// extension carved out below the standard 64-78 range so it cannot\n// collide with the OS table.\n//\n// Surface invariant: every CLI failure carries one of these codes in\n// the JSON envelope's `error.exitCode` AND drives `process.exitCode`.\n// \"1 for everything\" is explicitly disallowed by the architecture.\n\n/** Sysexits-named exit codes (numeric values are stable; do NOT reuse). */\nexport const ExitCode = {\n\t/** Successful termination. */\n\tOK: 0,\n\t/** Generic catch-all failure. Use only when no specific code applies. */\n\tGENERIC: 1,\n\t/** Devstack-domain: supervisor for the target stack is already live\n\t * in another process. Destructive verbs refuse with this code. */\n\tSUPERVISOR_LIVE: 40,\n\t/** Devstack-domain: requested snapshot name / id not found. */\n\tSNAPSHOT_NOT_FOUND: 41,\n\t/** Devstack-domain: seed manifest mismatch between current chain\n\t * identity and the snapshot/seed being restored. */\n\tSEED_MISMATCH: 42,\n\t/** Devstack-domain: destructive verb requires explicit confirm but\n\t * `--no-input` / non-TTY / no `--yes` is in effect, or the\n\t * interactive prompt was declined. */\n\tCONFIRM_REQUIRED: 43,\n\t/** Bad usage (unknown flag, malformed args, mutually-exclusive\n\t * flag pair, ambiguous reference). */\n\tUSAGE: 64,\n\t/** Input data malformed (config schema invalid, JSON parse error\n\t * inside a snapshot manifest, etc.). */\n\tDATA_ERR: 65,\n\t/** Cannot open input (config not found, snapshot file missing). */\n\tNO_INPUT: 66,\n\t/** Internal software error / unhandled defect. Default for\n\t * defects that escape Effect.catch. */\n\tSOFTWARE: 70,\n\t/** Service required by the CLI is unavailable (Docker daemon\n\t * unreachable, network down). */\n\tUNAVAILABLE: 69,\n\t/** Output file/directory cannot be created (permissions, disk\n\t * full). */\n\tCANT_CREATE: 73,\n\t/** Temporary failure; retry might succeed (lock contention,\n\t * transient daemon hiccup). */\n\tTEMP_FAIL: 75,\n\t/** Configuration error — the user's devstack.config.ts is wrong\n\t * in a way that prevents *any* verb from running. */\n\tCONFIG: 78,\n} as const;\n\nexport type ExitCode = (typeof ExitCode)[keyof typeof ExitCode];\n\n/** Human-readable identifier for an exit code. Used by the\n * `schema --json` command and by the envelope `error.code` field. */\nexport const exitCodeName = (code: ExitCode): string => {\n\tswitch (code) {\n\t\tcase ExitCode.OK:\n\t\t\treturn 'OK';\n\t\tcase ExitCode.GENERIC:\n\t\t\treturn 'GENERIC';\n\t\tcase ExitCode.SUPERVISOR_LIVE:\n\t\t\treturn 'SUPERVISOR_LIVE';\n\t\tcase ExitCode.SNAPSHOT_NOT_FOUND:\n\t\t\treturn 'SNAPSHOT_NOT_FOUND';\n\t\tcase ExitCode.SEED_MISMATCH:\n\t\t\treturn 'SEED_MISMATCH';\n\t\tcase ExitCode.CONFIRM_REQUIRED:\n\t\t\treturn 'CONFIRM_REQUIRED';\n\t\tcase ExitCode.USAGE:\n\t\t\treturn 'USAGE';\n\t\tcase ExitCode.DATA_ERR:\n\t\t\treturn 'DATA_ERR';\n\t\tcase ExitCode.NO_INPUT:\n\t\t\treturn 'NO_INPUT';\n\t\tcase ExitCode.SOFTWARE:\n\t\t\treturn 'SOFTWARE';\n\t\tcase ExitCode.UNAVAILABLE:\n\t\t\treturn 'UNAVAILABLE';\n\t\tcase ExitCode.CANT_CREATE:\n\t\t\treturn 'CANT_CREATE';\n\t\tcase ExitCode.TEMP_FAIL:\n\t\t\treturn 'TEMP_FAIL';\n\t\tcase ExitCode.CONFIG:\n\t\t\treturn 'CONFIG';\n\t\tdefault: {\n\t\t\t// Proof-of-exhaustiveness — adding a new entry to `ExitCode`\n\t\t\t// without extending this switch fails compilation here.\n\t\t\tconst _exhaustive: never = code;\n\t\t\tthrow new Error(`Unknown ExitCode: ${String(_exhaustive)}`);\n\t\t}\n\t}\n};\n\n/** Schema-emit entry: full table of `(code, name, description)`. The\n * programmable `schema --json` command serializes this verbatim. */\nexport interface ExitCodeEntry {\n\treadonly code: ExitCode;\n\treadonly name: string;\n\treadonly description: string;\n}\n\nexport const exitCodeTable: ReadonlyArray<ExitCodeEntry> = [\n\t{ code: ExitCode.OK, name: 'OK', description: 'Successful termination.' },\n\t{\n\t\tcode: ExitCode.GENERIC,\n\t\tname: 'GENERIC',\n\t\tdescription: 'Generic failure; no specific code applies.',\n\t},\n\t{\n\t\tcode: ExitCode.SUPERVISOR_LIVE,\n\t\tname: 'SUPERVISOR_LIVE',\n\t\tdescription: 'Devstack: supervisor for the target stack is already live in another process.',\n\t},\n\t{\n\t\tcode: ExitCode.SNAPSHOT_NOT_FOUND,\n\t\tname: 'SNAPSHOT_NOT_FOUND',\n\t\tdescription: 'Devstack: requested snapshot name or id not found.',\n\t},\n\t{\n\t\tcode: ExitCode.SEED_MISMATCH,\n\t\tname: 'SEED_MISMATCH',\n\t\tdescription: 'Devstack: seed-manifest mismatch (chain identity diverges from snapshot).',\n\t},\n\t{\n\t\tcode: ExitCode.CONFIRM_REQUIRED,\n\t\tname: 'CONFIRM_REQUIRED',\n\t\tdescription: 'Devstack: destructive verb needs confirmation or the prompt was declined.',\n\t},\n\t{ code: ExitCode.USAGE, name: 'USAGE', description: 'Bad command-line usage.' },\n\t{ code: ExitCode.DATA_ERR, name: 'DATA_ERR', description: 'Input data malformed.' },\n\t{ code: ExitCode.NO_INPUT, name: 'NO_INPUT', description: 'Required input could not be opened.' },\n\t{\n\t\tcode: ExitCode.UNAVAILABLE,\n\t\tname: 'UNAVAILABLE',\n\t\tdescription: 'A required service (e.g. Docker daemon) is unavailable.',\n\t},\n\t{ code: ExitCode.SOFTWARE, name: 'SOFTWARE', description: 'Internal software error.' },\n\t{\n\t\tcode: ExitCode.CANT_CREATE,\n\t\tname: 'CANT_CREATE',\n\t\tdescription: 'Cannot create output (permissions, disk).',\n\t},\n\t{\n\t\tcode: ExitCode.TEMP_FAIL,\n\t\tname: 'TEMP_FAIL',\n\t\tdescription: 'Transient failure; retry may succeed.',\n\t},\n\t{ code: ExitCode.CONFIG, name: 'CONFIG', description: 'User configuration error.' },\n];\n"],"mappings":";;AAkBA,MAAa,WAAW;;CAEvB,IAAI;;CAEJ,SAAS;;;CAGT,iBAAiB;;CAEjB,oBAAoB;;;CAGpB,eAAe;;;;CAIf,kBAAkB;;;CAGlB,OAAO;;;CAGP,UAAU;;CAEV,UAAU;;;CAGV,UAAU;;;CAGV,aAAa;;;CAGb,aAAa;;;CAGb,WAAW;;;CAGX,QAAQ;CACR;;;AAMD,MAAa,gBAAgB,SAA2B;AACvD,SAAQ,MAAR;EACC,KAAK,SAAS,GACb,QAAO;EACR,KAAK,SAAS,QACb,QAAO;EACR,KAAK,SAAS,gBACb,QAAO;EACR,KAAK,SAAS,mBACb,QAAO;EACR,KAAK,SAAS,cACb,QAAO;EACR,KAAK,SAAS,iBACb,QAAO;EACR,KAAK,SAAS,MACb,QAAO;EACR,KAAK,SAAS,SACb,QAAO;EACR,KAAK,SAAS,SACb,QAAO;EACR,KAAK,SAAS,SACb,QAAO;EACR,KAAK,SAAS,YACb,QAAO;EACR,KAAK,SAAS,YACb,QAAO;EACR,KAAK,SAAS,UACb,QAAO;EACR,KAAK,SAAS,OACb,QAAO;EACR,QAIC,OAAM,IAAI,MAAM,qBAAqB,OAAOA,KAAY,GAAG;;;AAa9D,MAAa,gBAA8C;CAC1D;EAAE,MAAM,SAAS;EAAI,MAAM;EAAM,aAAa;EAA2B;CACzE;EACC,MAAM,SAAS;EACf,MAAM;EACN,aAAa;EACb;CACD;EACC,MAAM,SAAS;EACf,MAAM;EACN,aAAa;EACb;CACD;EACC,MAAM,SAAS;EACf,MAAM;EACN,aAAa;EACb;CACD;EACC,MAAM,SAAS;EACf,MAAM;EACN,aAAa;EACb;CACD;EACC,MAAM,SAAS;EACf,MAAM;EACN,aAAa;EACb;CACD;EAAE,MAAM,SAAS;EAAO,MAAM;EAAS,aAAa;EAA2B;CAC/E;EAAE,MAAM,SAAS;EAAU,MAAM;EAAY,aAAa;EAAyB;CACnF;EAAE,MAAM,SAAS;EAAU,MAAM;EAAY,aAAa;EAAuC;CACjG;EACC,MAAM,SAAS;EACf,MAAM;EACN,aAAa;EACb;CACD;EAAE,MAAM,SAAS;EAAU,MAAM;EAAY,aAAa;EAA4B;CACtF;EACC,MAAM,SAAS;EACf,MAAM;EACN,aAAa;EACb;CACD;EACC,MAAM,SAAS;EACf,MAAM;EACN,aAAa;EACb;CACD;EAAE,MAAM,SAAS;EAAQ,MAAM;EAAU,aAAa;EAA6B;CACnF"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Dashboard } from "./dashboard.mjs";
|
|
2
|
-
import { appendEventLogLine, eventLogLineFromEvent, shutdownRequestedLine } from "./event-log.mjs";
|
|
2
|
+
import { appendEventLogLine, appendEventLogLines, eventLogLineFromEvent, shutdownRequestedLine } from "./event-log.mjs";
|
|
3
3
|
import { InputHandler } from "./input.mjs";
|
|
4
4
|
import { Effect, Fiber, Stream, SubscriptionRef } from "effect";
|
|
5
5
|
import { useEffect, useRef, useState } from "react";
|
|
@@ -12,6 +12,8 @@ const App = ({ stateRef, events, publish }) => {
|
|
|
12
12
|
const [snapshotStatus, setSnapshotStatus] = useState(null);
|
|
13
13
|
const eventSeq = useRef(0);
|
|
14
14
|
const shutdownLogged = useRef(false);
|
|
15
|
+
const rowsRef = useRef(state.rows);
|
|
16
|
+
rowsRef.current = state.rows;
|
|
15
17
|
useEffect(() => {
|
|
16
18
|
const fiber = Effect.runFork(Stream.runForEach(SubscriptionRef.changes(stateRef), (next) => Effect.sync(() => setState(next))));
|
|
17
19
|
return () => {
|
|
@@ -19,9 +21,24 @@ const App = ({ stateRef, events, publish }) => {
|
|
|
19
21
|
};
|
|
20
22
|
}, [stateRef]);
|
|
21
23
|
useEffect(() => {
|
|
24
|
+
const sectionLookup = (pluginKey) => rowsRef.current.find((row) => row.key === pluginKey)?.section;
|
|
25
|
+
let pendingLines = [];
|
|
26
|
+
let flushScheduled = false;
|
|
27
|
+
const scheduleFlush = () => {
|
|
28
|
+
if (flushScheduled) return;
|
|
29
|
+
flushScheduled = true;
|
|
30
|
+
queueMicrotask(() => {
|
|
31
|
+
flushScheduled = false;
|
|
32
|
+
if (pendingLines.length === 0) return;
|
|
33
|
+
const drained = pendingLines;
|
|
34
|
+
pendingLines = [];
|
|
35
|
+
setEventLog((prev) => appendEventLogLines(prev, drained));
|
|
36
|
+
});
|
|
37
|
+
};
|
|
22
38
|
const fiber = Effect.runFork(Stream.runForEach(events, (event) => Effect.sync(() => {
|
|
23
|
-
const line = eventLogLineFromEvent(event, eventSeq.current
|
|
24
|
-
|
|
39
|
+
const line = eventLogLineFromEvent(event, eventSeq.current++, sectionLookup);
|
|
40
|
+
pendingLines.push(line);
|
|
41
|
+
scheduleFlush();
|
|
25
42
|
switch (event.tag) {
|
|
26
43
|
case "snapshot.captureStarted":
|
|
27
44
|
setSnapshotStatus({
|
|
@@ -73,6 +90,11 @@ const App = ({ stateRef, events, publish }) => {
|
|
|
73
90
|
})));
|
|
74
91
|
return () => {
|
|
75
92
|
Effect.runFork(Fiber.interrupt(fiber));
|
|
93
|
+
if (pendingLines.length > 0) {
|
|
94
|
+
const drained = pendingLines;
|
|
95
|
+
pendingLines = [];
|
|
96
|
+
setEventLog((prev) => appendEventLogLines(prev, drained));
|
|
97
|
+
}
|
|
76
98
|
};
|
|
77
99
|
}, [events]);
|
|
78
100
|
useEffect(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.mjs","names":[],"sources":["../../../src/surfaces/tui/app.tsx"],"sourcesContent":["// Ink app root — the React tree mounted by `render()`.\n//\n// Reads from the `SubscriptionRef<SubscribableState>` from the\n// substrate's projection layer. The initial render samples the current\n// value synchronously; subsequent frame updates come from the\n// subscription. No polling loops, no setInterval-driven sampling.\n// The heartbeat component spins on its own timer for liveness, but\n// it does NOT trigger dashboard re-renders for projection data.\n//\n// Per architecture (distilled/21-tui § Learnings #3 + § Invariants):\n// - The renderer NEVER calls engine methods. Input handlers publish\n// typed `EngineCommand`s through the `publish` callback prop.\n// - Mount is process-scoped and survives engine cycle swaps; the\n// SubscriptionRef's lifecycle is decoupled from the engine cycle.\n// - Frame stability: SubscriptionRef updates already short-circuit\n// when reference equality holds (Effect's Ref impl).\n//\n// Runtime escape note: `Effect.runFork` is necessary at the\n// SubscriptionRef → React state boundary (React's hook model is\n// synchronous; Effect can't render). It is the ONLY escape this\n// surface uses, scoped to the App's mount lifetime. This is the\n// \"properly-scoped fiber on each surface\" pattern called out in\n// distilled/21-tui § Opportunities.\n\nimport { Effect, Fiber, Stream, SubscriptionRef } from 'effect';\nimport type React from 'react';\nimport { useEffect, useRef, useState } from 'react';\n\nimport type { EngineEvent } from '../../substrate/events.ts';\nimport type { SubscribableState } from '../../substrate/projection.ts';\nimport { Dashboard, type SnapshotStatus } from './dashboard.tsx';\nimport {\n\tappendEventLogLine,\n\teventLogLineFromEvent,\n\tshutdownRequestedLine,\n\ttype EventLogLine,\n} from './event-log.ts';\nimport { InputHandler, type CommandPublisher } from './input.tsx';\n\nexport interface AppProps {\n\t/** The renderer-facing subscribable projection. */\n\treadonly stateRef: SubscriptionRef.SubscriptionRef<SubscribableState>;\n\t/** Live engine event stream. */\n\treadonly events: Stream.Stream<EngineEvent, never>;\n\t/** Typed command-publisher callback. */\n\treadonly publish: CommandPublisher;\n}\n\nexport const App = ({ stateRef, events, publish }: AppProps): React.JSX.Element => {\n\tconst [state, setState] = useState<SubscribableState>(() =>\n\t\tEffect.runSync(SubscriptionRef.get(stateRef)),\n\t);\n\tconst [eventLog, setEventLog] = useState<ReadonlyArray<EventLogLine>>([]);\n\tconst [snapshotPromptValue, setSnapshotPromptValue] = useState<string | null>(null);\n\tconst [snapshotStatus, setSnapshotStatus] = useState<SnapshotStatus | null>(null);\n\tconst eventSeq = useRef(0);\n\tconst shutdownLogged = useRef(false);\n\n\tuseEffect(() => {\n\t\t// Stream.runForEach pulls each new state from the\n\t\t// SubscriptionRef and pushes it into React state. The fiber is\n\t\t// owned by this effect; cleanup interrupts it.\n\t\tconst fiber = Effect.runFork(\n\t\t\tStream.runForEach(SubscriptionRef.changes(stateRef), (next) =>\n\t\t\t\tEffect.sync(() => setState(next)),\n\t\t\t),\n\t\t);\n\t\treturn () => {\n\t\t\t// Interrupt the subscription fiber on unmount.\n\t\t\tEffect.runFork(Fiber.interrupt(fiber));\n\t\t};\n\t}, [stateRef]);\n\n\tuseEffect(() => {\n\t\tconst fiber = Effect.runFork(\n\t\t\tStream.runForEach(events, (event) =>\n\t\t\t\tEffect.sync(() => {\n\t\t\t\t\tconst line = eventLogLineFromEvent(event, eventSeq.current++);\n\t\t\t\t\tsetEventLog((prev) => appendEventLogLine(prev, line));\n\t\t\t\t\tswitch (event.tag) {\n\t\t\t\t\t\tcase 'snapshot.captureStarted':\n\t\t\t\t\t\t\tsetSnapshotStatus({\n\t\t\t\t\t\t\t\ttag: 'running',\n\t\t\t\t\t\t\t\tphase: 'starting',\n\t\t\t\t\t\t\t\t...(event.snapshotId === undefined ? {} : { snapshotId: event.snapshotId }),\n\t\t\t\t\t\t\t\t...(event.name === undefined ? {} : { name: event.name }),\n\t\t\t\t\t\t\t\tat: event.at,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'snapshot.captureProgress':\n\t\t\t\t\t\t\tsetSnapshotStatus((prev) => ({\n\t\t\t\t\t\t\t\ttag: 'running',\n\t\t\t\t\t\t\t\tphase: event.phase,\n\t\t\t\t\t\t\t\t...(event.snapshotId === undefined\n\t\t\t\t\t\t\t\t\t? prev?.tag === 'running' && prev.snapshotId !== undefined\n\t\t\t\t\t\t\t\t\t\t? { snapshotId: prev.snapshotId }\n\t\t\t\t\t\t\t\t\t\t: {}\n\t\t\t\t\t\t\t\t\t: { snapshotId: event.snapshotId }),\n\t\t\t\t\t\t\t\t...(event.name === undefined\n\t\t\t\t\t\t\t\t\t? prev?.tag === 'running' && prev.name !== undefined\n\t\t\t\t\t\t\t\t\t\t? { name: prev.name }\n\t\t\t\t\t\t\t\t\t\t: {}\n\t\t\t\t\t\t\t\t\t: { name: event.name }),\n\t\t\t\t\t\t\t\t...(event.detail === undefined ? {} : { detail: event.detail }),\n\t\t\t\t\t\t\t\t...(event.pausedContainers === undefined\n\t\t\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t\t\t: { pausedContainers: event.pausedContainers }),\n\t\t\t\t\t\t\t\t...(event.totalContainers === undefined\n\t\t\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t\t\t: { totalContainers: event.totalContainers }),\n\t\t\t\t\t\t\t\tat: event.at,\n\t\t\t\t\t\t\t}));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'snapshot.captureSkipped':\n\t\t\t\t\t\t\tsetSnapshotStatus({\n\t\t\t\t\t\t\t\ttag: 'skipped',\n\t\t\t\t\t\t\t\treason: event.reason,\n\t\t\t\t\t\t\t\tat: event.at,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'snapshot.captureFailed':\n\t\t\t\t\t\t\tsetSnapshotStatus({\n\t\t\t\t\t\t\t\ttag: 'failed',\n\t\t\t\t\t\t\t\t...(event.snapshotId === undefined ? {} : { snapshotId: event.snapshotId }),\n\t\t\t\t\t\t\t\t...(event.name === undefined ? {} : { name: event.name }),\n\t\t\t\t\t\t\t\tsummary: event.summary,\n\t\t\t\t\t\t\t\tat: event.at,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'snapshot.captured':\n\t\t\t\t\t\t\tsetSnapshotStatus({\n\t\t\t\t\t\t\t\ttag: 'captured',\n\t\t\t\t\t\t\t\tsnapshotId: event.snapshotId,\n\t\t\t\t\t\t\t\t...(event.name === undefined ? {} : { name: event.name }),\n\t\t\t\t\t\t\t\tat: event.at,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t),\n\t\t);\n\t\treturn () => {\n\t\t\tEffect.runFork(Fiber.interrupt(fiber));\n\t\t};\n\t}, [events]);\n\n\tuseEffect(() => {\n\t\tif (state.cycle.phase === 'shutting-down') {\n\t\t\tsetSnapshotPromptValue(null);\n\t\t\tsetSnapshotStatus(null);\n\t\t\tif (shutdownLogged.current) return;\n\t\t\tshutdownLogged.current = true;\n\t\t\tconst line = shutdownRequestedLine(Date.now(), eventSeq.current++);\n\t\t\tsetEventLog((prev) => appendEventLogLine(prev, line));\n\t\t\treturn;\n\t\t}\n\t\tshutdownLogged.current = false;\n\t}, [state.cycle.phase]);\n\n\treturn (\n\t\t<>\n\t\t\t<InputHandler\n\t\t\t\tpublish={publish}\n\t\t\t\tsnapshotPromptValue={snapshotPromptValue}\n\t\t\t\tonSnapshotPromptChange={setSnapshotPromptValue}\n\t\t\t/>\n\t\t\t<Dashboard\n\t\t\t\tstate={state}\n\t\t\t\teventLog={eventLog}\n\t\t\t\tsnapshotPromptValue={snapshotPromptValue}\n\t\t\t\tsnapshotStatus={snapshotStatus}\n\t\t\t/>\n\t\t</>\n\t);\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"app.mjs","names":[],"sources":["../../../src/surfaces/tui/app.tsx"],"sourcesContent":["// Ink app root — the React tree mounted by `render()`.\n//\n// Reads from the `SubscriptionRef<SubscribableState>` from the\n// substrate's projection layer. The initial render samples the current\n// value synchronously; subsequent frame updates come from the\n// subscription. No polling loops, no setInterval-driven sampling.\n// The heartbeat component spins on its own timer for liveness, but\n// it does NOT trigger dashboard re-renders for projection data.\n//\n// Per architecture (distilled/21-tui § Learnings #3 + § Invariants):\n// - The renderer NEVER calls engine methods. Input handlers publish\n// typed `EngineCommand`s through the `publish` callback prop.\n// - Mount is process-scoped and survives engine cycle swaps; the\n// SubscriptionRef's lifecycle is decoupled from the engine cycle.\n// - Frame stability: SubscriptionRef updates already short-circuit\n// when reference equality holds (Effect's Ref impl).\n//\n// Runtime escape note: `Effect.runFork` is necessary at the\n// SubscriptionRef → React state boundary (React's hook model is\n// synchronous; Effect can't render). It is the ONLY escape this\n// surface uses, scoped to the App's mount lifetime. This is the\n// \"properly-scoped fiber on each surface\" pattern called out in\n// distilled/21-tui § Opportunities.\n\nimport { Effect, Fiber, Stream, SubscriptionRef } from 'effect';\nimport type React from 'react';\nimport { useEffect, useRef, useState } from 'react';\n\nimport type { EngineEvent } from '../../substrate/events.ts';\nimport type { SubscribableState } from '../../substrate/projection.ts';\nimport { Dashboard, type SnapshotStatus } from './dashboard.tsx';\nimport {\n\tappendEventLogLine,\n\tappendEventLogLines,\n\teventLogLineFromEvent,\n\tshutdownRequestedLine,\n\ttype EventLogLine,\n} from './event-log.ts';\nimport { InputHandler, type CommandPublisher } from './input.tsx';\n\nexport interface AppProps {\n\t/** The renderer-facing subscribable projection. */\n\treadonly stateRef: SubscriptionRef.SubscriptionRef<SubscribableState>;\n\t/** Live engine event stream. */\n\treadonly events: Stream.Stream<EngineEvent, never>;\n\t/** Typed command-publisher callback. */\n\treadonly publish: CommandPublisher;\n}\n\nexport const App = ({ stateRef, events, publish }: AppProps): React.JSX.Element => {\n\tconst [state, setState] = useState<SubscribableState>(() =>\n\t\tEffect.runSync(SubscriptionRef.get(stateRef)),\n\t);\n\tconst [eventLog, setEventLog] = useState<ReadonlyArray<EventLogLine>>([]);\n\tconst [snapshotPromptValue, setSnapshotPromptValue] = useState<string | null>(null);\n\tconst [snapshotStatus, setSnapshotStatus] = useState<SnapshotStatus | null>(null);\n\tconst eventSeq = useRef(0);\n\tconst shutdownLogged = useRef(false);\n\t// Latest projection rows for `sectionLookup`. Held in a ref so the\n\t// event-subscription effect doesn't re-fire when state changes — it\n\t// reads the up-to-date snapshot through the ref instead.\n\tconst rowsRef = useRef(state.rows);\n\trowsRef.current = state.rows;\n\n\tuseEffect(() => {\n\t\t// Stream.runForEach pulls each new state from the\n\t\t// SubscriptionRef and pushes it into React state. The fiber is\n\t\t// owned by this effect; cleanup interrupts it.\n\t\tconst fiber = Effect.runFork(\n\t\t\tStream.runForEach(SubscriptionRef.changes(stateRef), (next) =>\n\t\t\t\tEffect.sync(() => setState(next)),\n\t\t\t),\n\t\t);\n\t\treturn () => {\n\t\t\t// Interrupt the subscription fiber on unmount.\n\t\t\tEffect.runFork(Fiber.interrupt(fiber));\n\t\t};\n\t}, [stateRef]);\n\n\tuseEffect(() => {\n\t\tconst sectionLookup = (pluginKey: string) =>\n\t\t\trowsRef.current.find((row) => row.key === pluginKey)?.section;\n\t\t// Microtask batching: a burst of N events used to trigger N\n\t\t// `setEventLog` calls, each forcing a React render. We instead\n\t\t// accumulate derived lines in `pendingLines` and flush them\n\t\t// inside a single `queueMicrotask` callback — one `setEventLog`\n\t\t// per tick regardless of burst size. The sidecar `setSnapshotStatus`\n\t\t// updates stay per-event (they're idempotent and don't drive the\n\t\t// hot path).\n\t\tlet pendingLines: Array<EventLogLine | null> = [];\n\t\tlet flushScheduled = false;\n\t\tconst scheduleFlush = (): void => {\n\t\t\tif (flushScheduled) return;\n\t\t\tflushScheduled = true;\n\t\t\tqueueMicrotask(() => {\n\t\t\t\tflushScheduled = false;\n\t\t\t\tif (pendingLines.length === 0) return;\n\t\t\t\tconst drained = pendingLines;\n\t\t\t\tpendingLines = [];\n\t\t\t\tsetEventLog((prev) => appendEventLogLines(prev, drained));\n\t\t\t});\n\t\t};\n\t\tconst fiber = Effect.runFork(\n\t\t\tStream.runForEach(events, (event) =>\n\t\t\t\tEffect.sync(() => {\n\t\t\t\t\tconst line = eventLogLineFromEvent(event, eventSeq.current++, sectionLookup);\n\t\t\t\t\tpendingLines.push(line);\n\t\t\t\t\tscheduleFlush();\n\t\t\t\t\tswitch (event.tag) {\n\t\t\t\t\t\tcase 'snapshot.captureStarted':\n\t\t\t\t\t\t\tsetSnapshotStatus({\n\t\t\t\t\t\t\t\ttag: 'running',\n\t\t\t\t\t\t\t\tphase: 'starting',\n\t\t\t\t\t\t\t\t...(event.snapshotId === undefined ? {} : { snapshotId: event.snapshotId }),\n\t\t\t\t\t\t\t\t...(event.name === undefined ? {} : { name: event.name }),\n\t\t\t\t\t\t\t\tat: event.at,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'snapshot.captureProgress':\n\t\t\t\t\t\t\tsetSnapshotStatus((prev) => ({\n\t\t\t\t\t\t\t\ttag: 'running',\n\t\t\t\t\t\t\t\tphase: event.phase,\n\t\t\t\t\t\t\t\t...(event.snapshotId === undefined\n\t\t\t\t\t\t\t\t\t? prev?.tag === 'running' && prev.snapshotId !== undefined\n\t\t\t\t\t\t\t\t\t\t? { snapshotId: prev.snapshotId }\n\t\t\t\t\t\t\t\t\t\t: {}\n\t\t\t\t\t\t\t\t\t: { snapshotId: event.snapshotId }),\n\t\t\t\t\t\t\t\t...(event.name === undefined\n\t\t\t\t\t\t\t\t\t? prev?.tag === 'running' && prev.name !== undefined\n\t\t\t\t\t\t\t\t\t\t? { name: prev.name }\n\t\t\t\t\t\t\t\t\t\t: {}\n\t\t\t\t\t\t\t\t\t: { name: event.name }),\n\t\t\t\t\t\t\t\t...(event.detail === undefined ? {} : { detail: event.detail }),\n\t\t\t\t\t\t\t\t...(event.pausedContainers === undefined\n\t\t\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t\t\t: { pausedContainers: event.pausedContainers }),\n\t\t\t\t\t\t\t\t...(event.totalContainers === undefined\n\t\t\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t\t\t: { totalContainers: event.totalContainers }),\n\t\t\t\t\t\t\t\tat: event.at,\n\t\t\t\t\t\t\t}));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'snapshot.captureSkipped':\n\t\t\t\t\t\t\tsetSnapshotStatus({\n\t\t\t\t\t\t\t\ttag: 'skipped',\n\t\t\t\t\t\t\t\treason: event.reason,\n\t\t\t\t\t\t\t\tat: event.at,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'snapshot.captureFailed':\n\t\t\t\t\t\t\tsetSnapshotStatus({\n\t\t\t\t\t\t\t\ttag: 'failed',\n\t\t\t\t\t\t\t\t...(event.snapshotId === undefined ? {} : { snapshotId: event.snapshotId }),\n\t\t\t\t\t\t\t\t...(event.name === undefined ? {} : { name: event.name }),\n\t\t\t\t\t\t\t\tsummary: event.summary,\n\t\t\t\t\t\t\t\tat: event.at,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'snapshot.captured':\n\t\t\t\t\t\t\tsetSnapshotStatus({\n\t\t\t\t\t\t\t\ttag: 'captured',\n\t\t\t\t\t\t\t\tsnapshotId: event.snapshotId,\n\t\t\t\t\t\t\t\t...(event.name === undefined ? {} : { name: event.name }),\n\t\t\t\t\t\t\t\tat: event.at,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t),\n\t\t);\n\t\treturn () => {\n\t\t\tEffect.runFork(Fiber.interrupt(fiber));\n\t\t\t// Final flush: drain any batched lines synchronously so an\n\t\t\t// unmount immediately after a burst doesn't lose the tail.\n\t\t\tif (pendingLines.length > 0) {\n\t\t\t\tconst drained = pendingLines;\n\t\t\t\tpendingLines = [];\n\t\t\t\tsetEventLog((prev) => appendEventLogLines(prev, drained));\n\t\t\t}\n\t\t};\n\t}, [events]);\n\n\tuseEffect(() => {\n\t\tif (state.cycle.phase === 'shutting-down') {\n\t\t\tsetSnapshotPromptValue(null);\n\t\t\tsetSnapshotStatus(null);\n\t\t\tif (shutdownLogged.current) return;\n\t\t\tshutdownLogged.current = true;\n\t\t\tconst line = shutdownRequestedLine(Date.now(), eventSeq.current++);\n\t\t\tsetEventLog((prev) => appendEventLogLine(prev, line));\n\t\t\treturn;\n\t\t}\n\t\tshutdownLogged.current = false;\n\t}, [state.cycle.phase]);\n\n\treturn (\n\t\t<>\n\t\t\t<InputHandler\n\t\t\t\tpublish={publish}\n\t\t\t\tsnapshotPromptValue={snapshotPromptValue}\n\t\t\t\tonSnapshotPromptChange={setSnapshotPromptValue}\n\t\t\t/>\n\t\t\t<Dashboard\n\t\t\t\tstate={state}\n\t\t\t\teventLog={eventLog}\n\t\t\t\tsnapshotPromptValue={snapshotPromptValue}\n\t\t\t\tsnapshotStatus={snapshotStatus}\n\t\t\t/>\n\t\t</>\n\t);\n};\n"],"mappings":"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"}
|
|
@@ -1,59 +1,4 @@
|
|
|
1
1
|
//#region src/surfaces/tui/display-derivation.ts
|
|
2
|
-
const ROW_SECTION_CLASSIFIERS = [
|
|
3
|
-
{
|
|
4
|
-
prefixes: ["package:", "package/"],
|
|
5
|
-
section: "package"
|
|
6
|
-
},
|
|
7
|
-
{
|
|
8
|
-
prefixes: ["account/"],
|
|
9
|
-
section: "account"
|
|
10
|
-
},
|
|
11
|
-
{
|
|
12
|
-
prefixes: ["action:", "action/"],
|
|
13
|
-
section: "action"
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
prefixes: ["coin:"],
|
|
17
|
-
section: "action"
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
prefixes: ["app:", "app/"],
|
|
21
|
-
section: "app",
|
|
22
|
-
endpointSection: "service"
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
prefixes: ["host-service/"],
|
|
26
|
-
section: "service"
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
prefixes: ["sui"],
|
|
30
|
-
section: "service"
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
prefixes: ["wallet"],
|
|
34
|
-
section: "service"
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
prefixes: ["walrus:", "walrus/"],
|
|
38
|
-
section: "service"
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
prefixes: ["seal:", "seal/"],
|
|
42
|
-
section: "service"
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
prefixes: ["deepbook:", "deepbook/"],
|
|
46
|
-
section: "service"
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
prefixes: ["postgres"],
|
|
50
|
-
section: "service"
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
prefixes: ["faucet"],
|
|
54
|
-
section: "service"
|
|
55
|
-
}
|
|
56
|
-
];
|
|
57
2
|
/** Pure: status → ANSI glyph. */
|
|
58
3
|
const statusGlyph = (status) => {
|
|
59
4
|
switch (status) {
|
|
@@ -137,17 +82,28 @@ const ownerForRow = (key) => {
|
|
|
137
82
|
const first = normalizeKey(key).split(/[/:._#-]/).find((part) => part.length > 0);
|
|
138
83
|
return first === void 0 ? "plugin" : humanizeToken(first);
|
|
139
84
|
};
|
|
85
|
+
/** Pure: pick the row's dashboard section. Reads `row.section`
|
|
86
|
+
* directly; if the plugin declared an `endpointSection` AND the row
|
|
87
|
+
* owns a routed endpoint, the endpoint variant wins. NEVER pattern-
|
|
88
|
+
* matches on `row.key`; the classifier is plugin-declared at
|
|
89
|
+
* `definePlugin({ section, endpointSection })` time and stamped by
|
|
90
|
+
* the supervisor. */
|
|
140
91
|
const sectionForRow = (row, endpoints = []) => {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
92
|
+
return (endpointsForRow(row, endpoints).length > 0 || row.endpoints.length > 0) && row.endpointSection !== row.section ? row.endpointSection : row.section;
|
|
93
|
+
};
|
|
94
|
+
/** Pure: section -> scope-chip color token used by the event log /
|
|
95
|
+
* activity stream. Coloring is driven by `RowSection` so the renderer
|
|
96
|
+
* doesn't pattern-match on plugin names. */
|
|
97
|
+
const sectionColor = (section) => {
|
|
98
|
+
switch (section) {
|
|
99
|
+
case "service": return "cyan";
|
|
100
|
+
case "package": return "blueBright";
|
|
101
|
+
case "account": return "magenta";
|
|
102
|
+
case "action": return "magenta";
|
|
103
|
+
case "app": return "white";
|
|
104
|
+
case "other": return "cyan";
|
|
105
|
+
default: return "cyan";
|
|
147
106
|
}
|
|
148
|
-
if (row.role === "service" || ownsEndpoint) return "service";
|
|
149
|
-
if (row.role === "task") return "action";
|
|
150
|
-
return "other";
|
|
151
107
|
};
|
|
152
108
|
const sectionLabel = (section) => {
|
|
153
109
|
switch (section) {
|
|
@@ -160,7 +116,7 @@ const sectionLabel = (section) => {
|
|
|
160
116
|
default: return "Other";
|
|
161
117
|
}
|
|
162
118
|
};
|
|
163
|
-
const endpointsForRow = (row, endpoints) => endpoints.filter((endpoint) => row.endpoints.includes(endpoint.endpointKey) || endpoint.
|
|
119
|
+
const endpointsForRow = (row, endpoints) => endpoints.filter((endpoint) => row.endpoints.includes(endpoint.endpointKey) || endpoint.pluginKey === row.key);
|
|
164
120
|
const OPERATIONAL_ENDPOINT_FIELDS = new Set([
|
|
165
121
|
"url",
|
|
166
122
|
"rpcUrl",
|
|
@@ -364,7 +320,6 @@ const deriveDisplayCells = (row, endpoints = []) => ({
|
|
|
364
320
|
secondary: secondaryForRow(row, endpoints)
|
|
365
321
|
});
|
|
366
322
|
const normalizeKey = (key) => key.replace(/^@devstack\//, "").replace(/^(devstack:|app:)/, "").replace(/#\d+$/, "").replace(/\/\d+$/, "");
|
|
367
|
-
const normalizeClassificationKey = (key) => key.replace(/^@devstack\//, "").replace(/^devstack:/, "").replace(/#\d+$/, "").replace(/\/\d+$/, "");
|
|
368
323
|
const humanizeToken = (token) => token.replace(/[-_]+/g, " ").replace(/^\w/, (head) => head.toUpperCase());
|
|
369
324
|
const containsKeyPart = (key, parts) => {
|
|
370
325
|
return key.split(/[/:._#-]/).filter((part) => part.length > 0).some((token) => parts.includes(token));
|
|
@@ -376,20 +331,14 @@ const isSectionish = (token) => containsKeyPart(token.toLowerCase(), [
|
|
|
376
331
|
"action",
|
|
377
332
|
"app"
|
|
378
333
|
]);
|
|
379
|
-
const rowSectionClassifierFor = (key) => ROW_SECTION_CLASSIFIERS.find((classifier) => classifier.prefixes.some((prefix) => keyMatchesClassifierPrefix(key, prefix)));
|
|
380
|
-
const keyMatchesClassifierPrefix = (key, prefix) => {
|
|
381
|
-
if (prefix.endsWith(":") || prefix.endsWith("/")) return key.startsWith(prefix);
|
|
382
|
-
if (key === prefix) return true;
|
|
383
|
-
const next = key[prefix.length];
|
|
384
|
-
return key.startsWith(prefix) && next !== void 0 && "/:._-".includes(next);
|
|
385
|
-
};
|
|
386
334
|
const isOperationalEndpoint = (rowKey, endpoint) => {
|
|
335
|
+
if (endpoint.pluginKey !== rowKey) return false;
|
|
387
336
|
const prefix = `${rowKey}:`;
|
|
388
337
|
if (!endpoint.endpointKey.startsWith(prefix)) return false;
|
|
389
338
|
const field = endpoint.endpointKey.slice(prefix.length);
|
|
390
339
|
return OPERATIONAL_ENDPOINT_FIELDS.has(field);
|
|
391
340
|
};
|
|
392
341
|
//#endregion
|
|
393
|
-
export { accountCells, accountLine, dashboardSummaryLine, deriveDashboardSummary, deriveDisplayCells, endpointLine, errorSummaryFor, groupRows, labelForRow, packageCells, packageLine, roleLabel, statusLabel, visibleEndpointsForRow };
|
|
342
|
+
export { accountCells, accountLine, dashboardSummaryLine, deriveDashboardSummary, deriveDisplayCells, endpointLine, errorSummaryFor, groupRows, labelForRow, packageCells, packageLine, roleLabel, sectionColor, statusLabel, visibleEndpointsForRow };
|
|
394
343
|
|
|
395
344
|
//# sourceMappingURL=display-derivation.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"display-derivation.mjs","names":[],"sources":["../../../src/surfaces/tui/display-derivation.ts"],"sourcesContent":["// Display derivation — the load-bearing transducer that makes the\n// \"no display vocab in projection\" invariant testable.\n//\n// The renderer consumes ONLY the typed projection (`Row`, `Endpoint`,\n// `StructuredError`, `LifecycleStatus`, `PluginRole`, ...) from\n// `substrate/projection.ts`. Every visible glyph, color, label, and\n// narration string is computed HERE from `row.role`, `row.status`,\n// `row.phase`, `row.lastError`, etc.\n//\n// HARD INVARIANT: this module never reads a field named `title`,\n// `primary`, or `extras` — those fields don't exist on the projection\n// (the substrate's `__ProjectionFieldsClosed` guard fails to compile\n// if they did). The TUI's test of that invariant is: every visible\n// cell rendered by `resource-table.tsx` flows through one of these pure\n// functions.\n//\n// Pure. No Effect, no IO, no clocks. Input typed projection → output\n// strings + enum-y \"color tokens\" (resolved to terminal colors by the\n// Ink layer via `Text color={…}`).\n\nimport type { LifecycleStatus, PhaseNarration, PluginRole } from '../../substrate/lifecycle.ts';\nimport type {\n\tAccountProjection,\n\tEndpoint,\n\tPackageProjection,\n\tRow,\n\tStructuredError,\n\tSubscribableState,\n} from '../../substrate/projection.ts';\n\n// -----------------------------------------------------------------------------\n// Color tokens\n// -----------------------------------------------------------------------------\n\n/**\n * Closed set of color tokens the TUI uses. Ink resolves these to ANSI\n * sequences. NO_COLOR / FORCE_COLOR / TERM=dumb are honored by Ink's\n * defaults (Tension: TUI must not override user color preferences).\n */\nexport type ColorToken = 'yellow' | 'green' | 'red' | 'magenta' | 'cyan' | 'blueBright' | 'white';\n\n// -----------------------------------------------------------------------------\n// Display cells — the public output shape of this module\n// -----------------------------------------------------------------------------\n\n/**\n * Per-row display cells the row renderer consumes. None of these\n * fields are read from the projection — they are computed from\n * `Row.role` + `Row.status` + `Row.phase` + `Row.lastError`.\n *\n * Naming note: we DELIBERATELY avoid the words `title`, `primary`,\n * `extras` in this type's field names to make the invariant grep-able.\n * `label` is computed from `key`; `narration` from `phase`;\n * `summary` from `lastError`.\n */\nexport interface DisplayCells {\n\t/** Status glyph (single char). */\n\treadonly statusGlyph: string;\n\t/** Status color token. */\n\treadonly statusColor: ColorToken;\n\t/** Status label (short verbal, e.g. \"ready\"). */\n\treadonly statusLabel: string;\n\t/** Role glyph (single char). */\n\treadonly roleGlyph: string;\n\t/** Role label (e.g. \"service\"). */\n\treadonly roleLabel: string;\n\t/** Computed row label — derived from `row.key`, not from any\n\t * projection-side `title`. */\n\treadonly label: string;\n\t/** Narration line — formatted from `row.phase`. */\n\treadonly narration: string;\n\t/** Error summary — formatted from `row.lastError`. */\n\treadonly errorSummary: string;\n\t/** Color the row's label should render in (role-derived,\n\t * optionally tinted by status). */\n\treadonly labelColor: ColorToken;\n\t/** Group bucket for dashboard sectioning. */\n\treadonly section: RowSection;\n\t/** Plugin-owner chip derived from the row key. */\n\treadonly owner: string;\n\t/** Main row value: usually the first endpoint or latest useful line. */\n\treadonly headline: string;\n\t/** Secondary details visible in the detail pane. */\n\treadonly secondary: ReadonlyArray<string>;\n}\n\nexport type RowSection = 'service' | 'package' | 'account' | 'action' | 'app' | 'other';\n\ninterface RowSectionClassifier {\n\treadonly prefixes: ReadonlyArray<string>;\n\treadonly section: RowSection;\n\treadonly endpointSection?: RowSection;\n}\n\nconst ROW_SECTION_CLASSIFIERS = [\n\t{ prefixes: ['package:', 'package/'], section: 'package' },\n\t{ prefixes: ['account/'], section: 'account' },\n\t{ prefixes: ['action:', 'action/'], section: 'action' },\n\t{ prefixes: ['coin:'], section: 'action' },\n\t{ prefixes: ['app:', 'app/'], section: 'app', endpointSection: 'service' },\n\t{ prefixes: ['host-service/'], section: 'service' },\n\t{ prefixes: ['sui'], section: 'service' },\n\t{ prefixes: ['wallet'], section: 'service' },\n\t{ prefixes: ['walrus:', 'walrus/'], section: 'service' },\n\t{ prefixes: ['seal:', 'seal/'], section: 'service' },\n\t{ prefixes: ['deepbook:', 'deepbook/'], section: 'service' },\n\t{ prefixes: ['postgres'], section: 'service' },\n\t{ prefixes: ['faucet'], section: 'service' },\n] as const satisfies ReadonlyArray<RowSectionClassifier>;\n\nexport interface DisplayRow {\n\treadonly row: Row;\n\treadonly cells: DisplayCells;\n}\n\nexport interface DisplaySection {\n\treadonly key: RowSection;\n\treadonly label: string;\n\treadonly rows: ReadonlyArray<DisplayRow>;\n}\n\nexport interface DashboardSummary {\n\treadonly totalRows: number;\n\treadonly readyRows: number;\n\treadonly activeRows: number;\n\treadonly failedRows: number;\n\treadonly waitingRows: number;\n\treadonly endpointCount: number;\n\treadonly accountCount: number;\n\treadonly packageCount: number;\n\treadonly errorCount: number;\n\treadonly health: 'ready' | 'active' | 'blocked' | 'empty';\n}\n\n// -----------------------------------------------------------------------------\n// Status → glyph / color / label\n// -----------------------------------------------------------------------------\n\n/** Pure: status → ANSI glyph. */\nexport const statusGlyph = (status: LifecycleStatus): string => {\n\tswitch (status) {\n\t\tcase 'pending':\n\t\t\treturn '○';\n\t\tcase 'acquiring':\n\t\t\treturn '◐';\n\t\tcase 'ready':\n\t\t\treturn '●';\n\t\tcase 'failed':\n\t\t\treturn '✖';\n\t\tcase 'stopping':\n\t\t\treturn '◑';\n\t\tcase 'stopped':\n\t\t\treturn '◌';\n\t\tcase 'done':\n\t\t\treturn '✓';\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = status;\n\t\t\tvoid _exhaustive;\n\t\t\treturn '?';\n\t\t}\n\t}\n};\n\n/** Pure: status → color token. */\nexport const statusColor = (status: LifecycleStatus): ColorToken => {\n\tswitch (status) {\n\t\tcase 'pending':\n\t\t\treturn 'white';\n\t\tcase 'acquiring':\n\t\t\treturn 'yellow';\n\t\tcase 'ready':\n\t\t\treturn 'green';\n\t\tcase 'failed':\n\t\t\treturn 'red';\n\t\tcase 'stopping':\n\t\t\treturn 'yellow';\n\t\tcase 'stopped':\n\t\t\treturn 'white';\n\t\tcase 'done':\n\t\t\treturn 'green';\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = status;\n\t\t\tvoid _exhaustive;\n\t\t\treturn 'white';\n\t\t}\n\t}\n};\n\n/** Pure: status → short operator-facing label. */\nexport const statusLabel = (status: LifecycleStatus): string => {\n\tswitch (status) {\n\t\tcase 'pending':\n\t\t\treturn 'pending';\n\t\tcase 'acquiring':\n\t\t\treturn 'starting';\n\t\tcase 'ready':\n\t\t\treturn 'ready';\n\t\tcase 'failed':\n\t\t\treturn 'failed';\n\t\tcase 'stopping':\n\t\t\treturn 'stopping';\n\t\tcase 'stopped':\n\t\t\treturn 'stopped';\n\t\tcase 'done':\n\t\t\treturn 'done';\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = status;\n\t\t\tvoid _exhaustive;\n\t\t\treturn 'unknown';\n\t\t}\n\t}\n};\n\n// -----------------------------------------------------------------------------\n// Role -> glyph / label / color\n// -----------------------------------------------------------------------------\n\n/** Pure: role -> ANSI glyph. */\nexport const roleGlyph = (role: PluginRole): string => {\n\tswitch (role) {\n\t\tcase 'service':\n\t\t\treturn '⚙';\n\t\tcase 'task':\n\t\t\treturn '⚡';\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = role;\n\t\t\tvoid _exhaustive;\n\t\t\treturn '?';\n\t\t}\n\t}\n};\n\n/** Pure: role -> short label. */\nexport const roleLabel = (role: PluginRole): string => {\n\tswitch (role) {\n\t\tcase 'service':\n\t\t\treturn 'service';\n\t\tcase 'task':\n\t\t\treturn 'task';\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = role;\n\t\t\tvoid _exhaustive;\n\t\t\treturn 'unknown';\n\t\t}\n\t}\n};\n\n/** Pure: role -> label color token. */\nexport const roleLabelColor = (role: PluginRole): ColorToken => {\n\tswitch (role) {\n\t\tcase 'service':\n\t\t\treturn 'cyan';\n\t\tcase 'task':\n\t\t\treturn 'magenta';\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = role;\n\t\t\tvoid _exhaustive;\n\t\t\treturn 'white';\n\t\t}\n\t}\n};\n\n// -----------------------------------------------------------------------------\n// Row label — derived from `key`, not from any pre-baked title\n// -----------------------------------------------------------------------------\n\n/**\n * Compute a human-friendly row label from the opaque branded plugin\n * key. The substrate keeps `key` an opaque digest; the renderer is\n * the layer that interprets it. We strip a few conventional prefixes\n * (`devstack:`, `app:`) plus instance counters so common cases read\n * cleanly.\n *\n * The function consumes `key` only — never `row.title`, which doesn't\n * exist in the projection.\n */\nexport const labelForRow = (key: string): string => {\n\tconst normalized = normalizeKey(key);\n\tconst parts = normalized.split(/[/:]/).filter((part) => part.length > 0);\n\tif (parts.length >= 2 && isSectionish(parts[0]!)) return humanizeToken(parts[parts.length - 1]!);\n\treturn humanizeToken(parts[parts.length - 1] ?? normalized);\n};\n\nexport const ownerForRow = (key: string): string => {\n\tconst normalized = normalizeKey(key);\n\tconst first = normalized.split(/[/:._#-]/).find((part) => part.length > 0);\n\treturn first === undefined ? 'plugin' : humanizeToken(first);\n};\n\nexport const sectionForRow = (\n\trow: Pick<Row, 'key' | 'role' | 'endpoints'>,\n\tendpoints: ReadonlyArray<Endpoint> = [],\n): RowSection => {\n\tconst normalized = normalizeClassificationKey(row.key).toLowerCase();\n\tconst ownsEndpoint = endpointsForRow(row, endpoints).length > 0 || row.endpoints.length > 0;\n\tconst classifier = rowSectionClassifierFor(normalized);\n\tif (classifier !== undefined) {\n\t\tif (ownsEndpoint && classifier.endpointSection !== undefined) return classifier.endpointSection;\n\t\treturn classifier.section;\n\t}\n\tif (row.role === 'service' || ownsEndpoint) return 'service';\n\tif (row.role === 'task') return 'action';\n\treturn 'other';\n};\n\nexport const sectionLabel = (section: RowSection): string => {\n\tswitch (section) {\n\t\tcase 'service':\n\t\t\treturn 'Services';\n\t\tcase 'package':\n\t\t\treturn 'Packages';\n\t\tcase 'account':\n\t\t\treturn 'Accounts';\n\t\tcase 'action':\n\t\t\treturn 'Actions';\n\t\tcase 'app':\n\t\t\treturn 'App';\n\t\tcase 'other':\n\t\t\treturn 'Other';\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = section;\n\t\t\tvoid _exhaustive;\n\t\t\treturn 'Other';\n\t\t}\n\t}\n};\n\nexport const endpointsForRow = (\n\trow: Pick<Row, 'key' | 'endpoints'>,\n\tendpoints: ReadonlyArray<Endpoint>,\n): ReadonlyArray<Endpoint> =>\n\tendpoints.filter(\n\t\t(endpoint) =>\n\t\t\trow.endpoints.includes(endpoint.endpointKey) || endpoint.endpointKey.startsWith(row.key),\n\t);\n\nconst OPERATIONAL_ENDPOINT_FIELDS = new Set(['url', 'rpcUrl', 'faucetUrl', 'graphqlUrl']);\n\nexport const visibleEndpointsForRow = (\n\trow: Pick<Row, 'key' | 'endpoints'>,\n\tendpoints: ReadonlyArray<Endpoint>,\n): ReadonlyArray<Endpoint> => {\n\tconst rowEndpoints = endpointsForRow(row, endpoints);\n\tconst routed = rowEndpoints.filter((endpoint) => !isOperationalEndpoint(row.key, endpoint));\n\treturn routed.length > 0 ? routed : rowEndpoints;\n};\n\nexport const headlineForRow = (row: Row, endpoints: ReadonlyArray<Endpoint> = []): string => {\n\tconst rowEndpoints = visibleEndpointsForRow(row, endpoints);\n\tif (rowEndpoints.length > 0) return endpointLine(rowEndpoints[0]!);\n\tif (row.lastError !== null && row.status === 'failed') return errorSummaryFor(row.lastError);\n\treturn narrationFor(row.phase, row.status);\n};\n\nexport const secondaryForRow = (\n\trow: Row,\n\tendpoints: ReadonlyArray<Endpoint> = [],\n): ReadonlyArray<string> => {\n\tconst out: Array<string> = [];\n\tconst rowEndpoints = endpointsForRow(row, endpoints);\n\tfor (const endpoint of rowEndpoints.slice(1)) out.push(endpointLine(endpoint));\n\tif (row.logTail.truncated) out.push('log tail truncated');\n\treturn out;\n};\n\nexport const groupRows = (\n\trows: ReadonlyArray<Row>,\n\tendpoints: ReadonlyArray<Endpoint> = [],\n): ReadonlyArray<DisplaySection> => {\n\tconst buckets = new Map<RowSection, Array<DisplayRow>>();\n\tfor (const row of rows) {\n\t\tconst cells = deriveDisplayCells(row, endpoints);\n\t\tconst list = buckets.get(cells.section) ?? [];\n\t\tlist.push({ row, cells });\n\t\tbuckets.set(cells.section, list);\n\t}\n\tconst order: ReadonlyArray<RowSection> = [\n\t\t'service',\n\t\t'package',\n\t\t'account',\n\t\t'action',\n\t\t'app',\n\t\t'other',\n\t];\n\treturn order\n\t\t.filter((section) => buckets.has(section))\n\t\t.map((section) => ({\n\t\t\tkey: section,\n\t\t\tlabel: sectionLabel(section),\n\t\t\trows: buckets.get(section) ?? [],\n\t\t}));\n};\n\nexport const deriveDashboardSummary = (\n\tstate: Pick<SubscribableState, 'rows' | 'endpoints' | 'accounts' | 'packages' | 'errors'>,\n): DashboardSummary => {\n\tconst readyRows = state.rows.filter(\n\t\t(row) => row.status === 'ready' || row.status === 'done',\n\t).length;\n\tconst activeRows = state.rows.filter(\n\t\t(row) => row.status === 'acquiring' || row.status === 'stopping',\n\t).length;\n\tconst failedRows = state.rows.filter((row) => row.status === 'failed').length;\n\tconst waitingRows = state.rows.filter(\n\t\t(row) => row.status === 'pending' || row.status === 'stopped',\n\t).length;\n\tconst health =\n\t\tstate.rows.length === 0\n\t\t\t? 'empty'\n\t\t\t: failedRows > 0\n\t\t\t\t? 'blocked'\n\t\t\t\t: activeRows > 0 || waitingRows > 0\n\t\t\t\t\t? 'active'\n\t\t\t\t\t: 'ready';\n\treturn {\n\t\ttotalRows: state.rows.length,\n\t\treadyRows,\n\t\tactiveRows,\n\t\tfailedRows,\n\t\twaitingRows,\n\t\tendpointCount: visibleEndpointCount(state.rows, state.endpoints),\n\t\taccountCount: state.accounts.length,\n\t\tpackageCount: state.packages.length,\n\t\terrorCount: state.errors.length,\n\t\thealth,\n\t};\n};\n\nconst visibleEndpointCount = (\n\trows: ReadonlyArray<Row>,\n\tendpoints: ReadonlyArray<Endpoint>,\n): number => {\n\tconst rowOwned = new Set<Endpoint['endpointKey']>();\n\tconst visible = new Set<Endpoint['endpointKey']>();\n\tfor (const row of rows) {\n\t\tfor (const endpoint of endpointsForRow(row, endpoints)) {\n\t\t\trowOwned.add(endpoint.endpointKey);\n\t\t}\n\t\tfor (const endpoint of visibleEndpointsForRow(row, endpoints)) {\n\t\t\tvisible.add(endpoint.endpointKey);\n\t\t}\n\t}\n\tfor (const endpoint of endpoints) {\n\t\tif (!rowOwned.has(endpoint.endpointKey)) visible.add(endpoint.endpointKey);\n\t}\n\treturn visible.size;\n};\n\nexport const dashboardSummaryLine = (summary: DashboardSummary): string =>\n\t[\n\t\t`${summary.readyRows}/${summary.totalRows} ready`,\n\t\tsummary.activeRows > 0 ? `${summary.activeRows} active` : null,\n\t\tsummary.waitingRows > 0 ? `${summary.waitingRows} waiting` : null,\n\t\tsummary.failedRows > 0 ? `${summary.failedRows} failed` : null,\n\t\t`${summary.endpointCount} urls`,\n\t\t`${summary.accountCount} accounts`,\n\t\tsummary.packageCount > 0 ? `${summary.packageCount} packages` : null,\n\t\tsummary.errorCount === 0 ? 'no errors' : `${summary.errorCount} errors`,\n\t]\n\t\t.filter((part): part is string => part !== null)\n\t\t.join(' ');\n\n// -----------------------------------------------------------------------------\n// Phase narration formatting\n// -----------------------------------------------------------------------------\n\n/**\n * Pure: phase narration string → renderable verb form. Phase is\n * free-form upstream (Tension 14). The renderer's job is to make it\n * legible; we keep this minimal — single-line, no fancy verb tense\n * inference. The truncation cap protects against pathological long\n * narrations.\n */\nexport const narrationFor = (phase: PhaseNarration | null, status: LifecycleStatus): string => {\n\tif (phase === null || phase.trim().length === 0) {\n\t\t// No phase set; surface a status-derived default for `acquiring`,\n\t\t// stay silent otherwise (Tension: don't manufacture text the\n\t\t// engine didn't ask for).\n\t\treturn status === 'acquiring' ? 'starting…' : '';\n\t}\n\tconst trimmed = phase.trim();\n\tconst TRUNC = 80;\n\treturn trimmed.length > TRUNC ? `${trimmed.slice(0, TRUNC - 1)}…` : trimmed;\n};\n\n// -----------------------------------------------------------------------------\n// Error summary formatting\n// -----------------------------------------------------------------------------\n\nconst ERR_SUMMARY_TRUNC = 120;\n\n/**\n * Pure: `Row.lastError` → renderable in-row summary. Keep it short;\n * detailed error context belongs in the activity/log stream.\n */\nexport const errorSummaryFor = (error: StructuredError | null): string => {\n\tif (error === null) return '';\n\tconst head = `${error.tag}: ${error.summary}`;\n\tconst detail = error.chain.find((line) => line !== head && line !== error.tag);\n\tconst compactDetail =\n\t\tdetail === undefined ? undefined : detail.replace(/^[A-Za-z0-9_[\\]-]+:\\s*/, '');\n\tconst summary = compactDetail === undefined ? head : `${head}: ${compactDetail}`;\n\treturn summary.length > ERR_SUMMARY_TRUNC\n\t\t? `${summary.slice(0, ERR_SUMMARY_TRUNC - 1)}…`\n\t\t: summary;\n};\n\n// -----------------------------------------------------------------------------\n// Endpoint formatting\n// -----------------------------------------------------------------------------\n\n/**\n * Pure: `Endpoint` → renderable line. Renderers prefer `displayUrl`\n * when set (codegen-friendly variant), falling back to `url`.\n */\nexport const endpointLine = (endpoint: Endpoint): string => {\n\tconst target = endpoint.displayUrl ?? endpoint.url;\n\tconst backing =\n\t\tendpoint.displayUrl !== null && endpoint.displayUrl !== endpoint.url\n\t\t\t? ` -> ${endpoint.url}`\n\t\t\t: '';\n\tconst protocol = endpoint.wireProtocol === 'http' ? '' : ` [${endpoint.wireProtocol}]`;\n\treturn `${endpoint.name}: ${target}${backing}${protocol}`;\n};\n\nexport const endpointsSummaryForRow = (\n\trow: Pick<Row, 'key' | 'endpoints'>,\n\tendpoints: ReadonlyArray<Endpoint>,\n): string => {\n\tconst rowEndpoints = visibleEndpointsForRow(row, endpoints);\n\tif (rowEndpoints.length === 0) return '';\n\treturn rowEndpoints.map(endpointLine).join(' | ');\n};\n\nexport const accountLine = (account: AccountProjection): string => {\n\tconst address = account.address ?? '<pending>';\n\tconst scheme = account.scheme ?? 'scheme pending';\n\tconst source = account.source ?? 'source pending';\n\tconst funding = accountFundingLine(account.funding);\n\tconst wallet = account.walletVisible ? 'wallet' : null;\n\treturn [humanizeToken(account.name), address, scheme, source, funding, wallet]\n\t\t.filter((part): part is string => part !== null && part.length > 0)\n\t\t.join(' ');\n};\n\nexport const packageLine = (pkg: PackageProjection): string => {\n\treturn [humanizeToken(pkg.name), pkg.packageId, pkg.mvrPlaceholder, pkg.kind]\n\t\t.filter((part): part is string => part !== null && part.length > 0)\n\t\t.join(' ');\n};\n\nexport interface AccountCells {\n\treadonly name: string;\n\treadonly address: string;\n\treadonly scheme: string;\n\treadonly source: string;\n\treadonly funding: string;\n}\n\nexport interface PackageCells {\n\treadonly name: string;\n\treadonly packageId: string;\n\treadonly mvr: string;\n\treadonly kind: string;\n\treadonly detail: string;\n}\n\nexport const accountCells = (account: AccountProjection): AccountCells => ({\n\tname: humanizeToken(account.name),\n\taddress: account.address ?? '<pending>',\n\tscheme: account.scheme ?? 'pending',\n\tsource: account.source ?? 'pending',\n\tfunding: accountFundingLine(account.funding),\n});\n\nconst accountFundingLine = (funding: AccountProjection['funding']): string => {\n\tconst entries = funding.entries ?? [];\n\tif (entries.length > 0) {\n\t\tconst rendered = entries\n\t\t\t.map(\n\t\t\t\t(entry) => `${entry.coin}:${entry.amount}${entry.status === 'skipped' ? ' skipped' : ''}`,\n\t\t\t)\n\t\t\t.join(', ');\n\t\treturn funding.status === 'funded' ? `funded ${rendered}` : `funding ${rendered}`;\n\t}\n\tswitch (funding.status) {\n\t\tcase 'pending':\n\t\t\treturn funding.requestedMist === null\n\t\t\t\t? 'funding pending'\n\t\t\t\t: `funding ${funding.requestedMist}`;\n\t\tcase 'funded':\n\t\t\treturn funding.balanceMist !== null\n\t\t\t\t? `funded ${funding.balanceMist}`\n\t\t\t\t: funding.requestedMist !== null\n\t\t\t\t\t? `funded ${funding.requestedMist}`\n\t\t\t\t\t: 'funded';\n\t\tcase 'skipped':\n\t\t\treturn 'funding skipped';\n\t\tcase 'failed':\n\t\t\treturn 'funding failed';\n\t\tcase 'unknown':\n\t\t\treturn 'funding unknown';\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = funding.status;\n\t\t\tvoid _exhaustive;\n\t\t\treturn '';\n\t\t}\n\t}\n};\n\nexport const packageCells = (pkg: PackageProjection): PackageCells => ({\n\tname: humanizeToken(pkg.name),\n\tpackageId: pkg.packageId,\n\tmvr: pkg.mvrPlaceholder,\n\tkind: pkg.kind,\n\tdetail: pkg.kind,\n});\n\n// -----------------------------------------------------------------------------\n// Top-level entry point\n// -----------------------------------------------------------------------------\n\n/**\n * Derive every visible display cell for a single row.\n *\n * Consumes ONLY `row.key`, `row.role`, `row.status`, `row.phase`,\n * `row.lastError`, `row.endpoints` (rendered separately by\n * `resource-table.tsx`), or `row.logTail` (kept in the projection\n * for renderer variants that need tails, but not used as primary\n * dashboard state because generic lifecycle log lines duplicate the\n * table).\n */\nexport const deriveDisplayCells = (\n\trow: Row,\n\tendpoints: ReadonlyArray<Endpoint> = [],\n): DisplayCells => ({\n\tstatusGlyph: statusGlyph(row.status),\n\tstatusColor: statusColor(row.status),\n\tstatusLabel: statusLabel(row.status),\n\troleGlyph: roleGlyph(row.role),\n\troleLabel: roleLabel(row.role),\n\tlabel: labelForRow(row.key),\n\tnarration: narrationFor(row.phase, row.status),\n\terrorSummary: errorSummaryFor(row.lastError),\n\tlabelColor: roleLabelColor(row.role),\n\tsection: sectionForRow(row, endpoints),\n\towner: ownerForRow(row.key),\n\theadline: headlineForRow(row, endpoints),\n\tsecondary: secondaryForRow(row, endpoints),\n});\n\nconst normalizeKey = (key: string): string =>\n\tkey\n\t\t.replace(/^@devstack\\//, '')\n\t\t.replace(/^(devstack:|app:)/, '')\n\t\t.replace(/#\\d+$/, '')\n\t\t.replace(/\\/\\d+$/, '');\n\nconst normalizeClassificationKey = (key: string): string =>\n\tkey\n\t\t.replace(/^@devstack\\//, '')\n\t\t.replace(/^devstack:/, '')\n\t\t.replace(/#\\d+$/, '')\n\t\t.replace(/\\/\\d+$/, '');\n\nconst humanizeToken = (token: string): string =>\n\ttoken.replace(/[-_]+/g, ' ').replace(/^\\w/, (head) => head.toUpperCase());\n\nconst containsKeyPart = (key: string, parts: ReadonlyArray<string>): boolean => {\n\tconst tokens = key.split(/[/:._#-]/).filter((part) => part.length > 0);\n\treturn tokens.some((token) => parts.includes(token));\n};\n\nconst isSectionish = (token: string): boolean =>\n\tcontainsKeyPart(token.toLowerCase(), ['service', 'package', 'account', 'action', 'app']);\n\nconst rowSectionClassifierFor = (key: string): RowSectionClassifier | undefined =>\n\tROW_SECTION_CLASSIFIERS.find((classifier) =>\n\t\tclassifier.prefixes.some((prefix) => keyMatchesClassifierPrefix(key, prefix)),\n\t);\n\nconst keyMatchesClassifierPrefix = (key: string, prefix: string): boolean => {\n\tif (prefix.endsWith(':') || prefix.endsWith('/')) return key.startsWith(prefix);\n\tif (key === prefix) return true;\n\tconst next = key[prefix.length];\n\treturn key.startsWith(prefix) && next !== undefined && '/:._-'.includes(next);\n};\n\nconst isOperationalEndpoint = (rowKey: Pick<Row, 'key'>['key'], endpoint: Endpoint): boolean => {\n\tconst prefix = `${rowKey}:`;\n\tif (!endpoint.endpointKey.startsWith(prefix)) return false;\n\tconst field = endpoint.endpointKey.slice(prefix.length);\n\treturn OPERATIONAL_ENDPOINT_FIELDS.has(field);\n};\n\n// -----------------------------------------------------------------------------\n// Compile-time invariant\n// -----------------------------------------------------------------------------\n//\n// Renderer code must never see a `title`/`primary`/`extras` field on\n// `Row`. If the projection ever sprouts one, the substrate's\n// `__ProjectionFieldsClosed` guard fails first; this module-local\n// guard exists as a second layer that explicitly mentions the\n// forbidden field names so a future renderer-side regression is\n// caught at the renderer boundary, not at the substrate boundary.\n\ntype _NoForbiddenOnRow = 'title' extends keyof Row\n\t? never\n\t: 'primary' extends keyof Row\n\t\t? never\n\t\t: 'extras' extends keyof Row\n\t\t\t? never\n\t\t\t: true;\n\n/** Renderer-side compile-time guard. If this resolves to `never`,\n * the renderer is reading a forbidden display-vocabulary field from\n * the projection. */\nexport type __TuiDisplayVocabClean = _NoForbiddenOnRow extends true ? true : never;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"display-derivation.mjs","names":[],"sources":["../../../src/surfaces/tui/display-derivation.ts"],"sourcesContent":["// INVARIANT: this module is Ink-free, React-free, and DOM-free. Its\n// only imports are `type`-only from `substrate/`. Every export returns\n// a plain TS value (string, ColorToken, plain object) — never a JSX or\n// Ink component. This is what lets a future web dashboard reuse the\n// same status→glyph/label/color derivation a browser renderer would\n// otherwise have to duplicate. Do not import from `ink`, `react`, or\n// any sibling `*.tsx` here.\n//\n// Display derivation — the load-bearing transducer that makes the\n// \"no display vocab in projection\" invariant testable.\n//\n// The renderer consumes ONLY the typed projection (`Row`, `Endpoint`,\n// `StructuredError`, `LifecycleStatus`, `PluginRole`, ...) from\n// `substrate/projection.ts`. Every visible glyph, color, label, and\n// narration string is computed HERE from `row.role`, `row.status`,\n// `row.phase`, `row.lastError`, etc.\n//\n// HARD INVARIANT: this module never reads a field named `title`,\n// `primary`, or `extras` — those fields don't exist on the projection\n// (the substrate's `__ProjectionFieldsClosed` guard fails to compile\n// if they did). The TUI's test of that invariant is: every visible\n// cell rendered by `resource-table.tsx` flows through one of these pure\n// functions.\n//\n// Pure. No Effect, no IO, no clocks. Input typed projection → output\n// strings + enum-y \"color tokens\" (resolved to terminal colors by the\n// Ink layer via `Text color={…}`).\n\nimport type { LifecycleStatus, PhaseNarration, PluginRole } from '../../substrate/lifecycle.ts';\nimport type {\n\tAccountProjection,\n\tEndpoint,\n\tPackageProjection,\n\tRow,\n\tRowSection,\n\tStructuredError,\n\tSubscribableState,\n} from '../../substrate/projection.ts';\n\nexport type { RowSection } from '../../substrate/projection.ts';\n\n// -----------------------------------------------------------------------------\n// Color tokens\n// -----------------------------------------------------------------------------\n\n/**\n * Closed set of color tokens the TUI uses. Ink resolves these to ANSI\n * sequences. NO_COLOR / FORCE_COLOR / TERM=dumb are honored by Ink's\n * defaults (Tension: TUI must not override user color preferences).\n */\nexport type ColorToken = 'yellow' | 'green' | 'red' | 'magenta' | 'cyan' | 'blueBright' | 'white';\n\n// -----------------------------------------------------------------------------\n// Display cells — the public output shape of this module\n// -----------------------------------------------------------------------------\n\n/**\n * Per-row display cells the row renderer consumes. None of these\n * fields are read from the projection — they are computed from\n * `Row.role` + `Row.status` + `Row.phase` + `Row.lastError`.\n *\n * Naming note: we DELIBERATELY avoid the words `title`, `primary`,\n * `extras` in this type's field names to make the invariant grep-able.\n * `label` is computed from `key`; `narration` from `phase`;\n * `summary` from `lastError`.\n */\nexport interface DisplayCells {\n\t/** Status glyph (single char). */\n\treadonly statusGlyph: string;\n\t/** Status color token. */\n\treadonly statusColor: ColorToken;\n\t/** Status label (short verbal, e.g. \"ready\"). */\n\treadonly statusLabel: string;\n\t/** Role glyph (single char). */\n\treadonly roleGlyph: string;\n\t/** Role label (e.g. \"service\"). */\n\treadonly roleLabel: string;\n\t/** Computed row label — derived from `row.key`, not from any\n\t * projection-side `title`. */\n\treadonly label: string;\n\t/** Narration line — formatted from `row.phase`. */\n\treadonly narration: string;\n\t/** Error summary — formatted from `row.lastError`. */\n\treadonly errorSummary: string;\n\t/** Color the row's label should render in (role-derived,\n\t * optionally tinted by status). */\n\treadonly labelColor: ColorToken;\n\t/** Group bucket for dashboard sectioning. */\n\treadonly section: RowSection;\n\t/** Plugin-owner chip derived from the row key. */\n\treadonly owner: string;\n\t/** Main row value: usually the first endpoint or latest useful line. */\n\treadonly headline: string;\n\t/** Secondary details visible in the detail pane. */\n\treadonly secondary: ReadonlyArray<string>;\n}\n\nexport interface DisplayRow {\n\treadonly row: Row;\n\treadonly cells: DisplayCells;\n}\n\nexport interface DisplaySection {\n\treadonly key: RowSection;\n\treadonly label: string;\n\treadonly rows: ReadonlyArray<DisplayRow>;\n}\n\nexport interface DashboardSummary {\n\treadonly totalRows: number;\n\treadonly readyRows: number;\n\treadonly activeRows: number;\n\treadonly failedRows: number;\n\treadonly waitingRows: number;\n\treadonly endpointCount: number;\n\treadonly accountCount: number;\n\treadonly packageCount: number;\n\treadonly errorCount: number;\n\treadonly health: 'ready' | 'active' | 'blocked' | 'empty';\n}\n\n// -----------------------------------------------------------------------------\n// Status → glyph / color / label\n// -----------------------------------------------------------------------------\n\n/** Pure: status → ANSI glyph. */\nexport const statusGlyph = (status: LifecycleStatus): string => {\n\tswitch (status) {\n\t\tcase 'pending':\n\t\t\treturn '○';\n\t\tcase 'acquiring':\n\t\t\treturn '◐';\n\t\tcase 'ready':\n\t\t\treturn '●';\n\t\tcase 'failed':\n\t\t\treturn '✖';\n\t\tcase 'stopping':\n\t\t\treturn '◑';\n\t\tcase 'stopped':\n\t\t\treturn '◌';\n\t\tcase 'done':\n\t\t\treturn '✓';\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = status;\n\t\t\tvoid _exhaustive;\n\t\t\treturn '?';\n\t\t}\n\t}\n};\n\n/** Pure: status → color token. */\nexport const statusColor = (status: LifecycleStatus): ColorToken => {\n\tswitch (status) {\n\t\tcase 'pending':\n\t\t\treturn 'white';\n\t\tcase 'acquiring':\n\t\t\treturn 'yellow';\n\t\tcase 'ready':\n\t\t\treturn 'green';\n\t\tcase 'failed':\n\t\t\treturn 'red';\n\t\tcase 'stopping':\n\t\t\treturn 'yellow';\n\t\tcase 'stopped':\n\t\t\treturn 'white';\n\t\tcase 'done':\n\t\t\treturn 'green';\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = status;\n\t\t\tvoid _exhaustive;\n\t\t\treturn 'white';\n\t\t}\n\t}\n};\n\n/** Pure: status → short operator-facing label. */\nexport const statusLabel = (status: LifecycleStatus): string => {\n\tswitch (status) {\n\t\tcase 'pending':\n\t\t\treturn 'pending';\n\t\tcase 'acquiring':\n\t\t\treturn 'starting';\n\t\tcase 'ready':\n\t\t\treturn 'ready';\n\t\tcase 'failed':\n\t\t\treturn 'failed';\n\t\tcase 'stopping':\n\t\t\treturn 'stopping';\n\t\tcase 'stopped':\n\t\t\treturn 'stopped';\n\t\tcase 'done':\n\t\t\treturn 'done';\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = status;\n\t\t\tvoid _exhaustive;\n\t\t\treturn 'unknown';\n\t\t}\n\t}\n};\n\n// -----------------------------------------------------------------------------\n// Role -> glyph / label / color\n// -----------------------------------------------------------------------------\n\n/** Pure: role -> ANSI glyph. */\nexport const roleGlyph = (role: PluginRole): string => {\n\tswitch (role) {\n\t\tcase 'service':\n\t\t\treturn '⚙';\n\t\tcase 'task':\n\t\t\treturn '⚡';\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = role;\n\t\t\tvoid _exhaustive;\n\t\t\treturn '?';\n\t\t}\n\t}\n};\n\n/** Pure: role -> short label. */\nexport const roleLabel = (role: PluginRole): string => {\n\tswitch (role) {\n\t\tcase 'service':\n\t\t\treturn 'service';\n\t\tcase 'task':\n\t\t\treturn 'task';\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = role;\n\t\t\tvoid _exhaustive;\n\t\t\treturn 'unknown';\n\t\t}\n\t}\n};\n\n/** Pure: role -> label color token. */\nexport const roleLabelColor = (role: PluginRole): ColorToken => {\n\tswitch (role) {\n\t\tcase 'service':\n\t\t\treturn 'cyan';\n\t\tcase 'task':\n\t\t\treturn 'magenta';\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = role;\n\t\t\tvoid _exhaustive;\n\t\t\treturn 'white';\n\t\t}\n\t}\n};\n\n// -----------------------------------------------------------------------------\n// Row label — derived from `key`, not from any pre-baked title\n// -----------------------------------------------------------------------------\n\n/**\n * Compute a human-friendly row label from the opaque branded plugin\n * key. The substrate keeps `key` an opaque digest; the renderer is\n * the layer that interprets it. We strip a few conventional prefixes\n * (`devstack:`, `app:`) plus instance counters so common cases read\n * cleanly.\n *\n * The function consumes `key` only — never `row.title`, which doesn't\n * exist in the projection.\n */\nexport const labelForRow = (key: string): string => {\n\tconst normalized = normalizeKey(key);\n\tconst parts = normalized.split(/[/:]/).filter((part) => part.length > 0);\n\tif (parts.length >= 2 && isSectionish(parts[0]!)) return humanizeToken(parts[parts.length - 1]!);\n\treturn humanizeToken(parts[parts.length - 1] ?? normalized);\n};\n\nexport const ownerForRow = (key: string): string => {\n\tconst normalized = normalizeKey(key);\n\tconst first = normalized.split(/[/:._#-]/).find((part) => part.length > 0);\n\treturn first === undefined ? 'plugin' : humanizeToken(first);\n};\n\n/** Pure: pick the row's dashboard section. Reads `row.section`\n * directly; if the plugin declared an `endpointSection` AND the row\n * owns a routed endpoint, the endpoint variant wins. NEVER pattern-\n * matches on `row.key`; the classifier is plugin-declared at\n * `definePlugin({ section, endpointSection })` time and stamped by\n * the supervisor. */\nexport const sectionForRow = (\n\trow: Pick<Row, 'key' | 'endpoints' | 'section' | 'endpointSection'>,\n\tendpoints: ReadonlyArray<Endpoint> = [],\n): RowSection => {\n\tconst ownsEndpoint = endpointsForRow(row, endpoints).length > 0 || row.endpoints.length > 0;\n\treturn ownsEndpoint && row.endpointSection !== row.section ? row.endpointSection : row.section;\n};\n\n/** Pure: section -> scope-chip color token used by the event log /\n * activity stream. Coloring is driven by `RowSection` so the renderer\n * doesn't pattern-match on plugin names. */\nexport const sectionColor = (section: RowSection): ColorToken => {\n\tswitch (section) {\n\t\tcase 'service':\n\t\t\treturn 'cyan';\n\t\tcase 'package':\n\t\t\treturn 'blueBright';\n\t\tcase 'account':\n\t\t\treturn 'magenta';\n\t\tcase 'action':\n\t\t\treturn 'magenta';\n\t\tcase 'app':\n\t\t\treturn 'white';\n\t\tcase 'other':\n\t\t\treturn 'cyan';\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = section;\n\t\t\tvoid _exhaustive;\n\t\t\treturn 'cyan';\n\t\t}\n\t}\n};\n\nexport const sectionLabel = (section: RowSection): string => {\n\tswitch (section) {\n\t\tcase 'service':\n\t\t\treturn 'Services';\n\t\tcase 'package':\n\t\t\treturn 'Packages';\n\t\tcase 'account':\n\t\t\treturn 'Accounts';\n\t\tcase 'action':\n\t\t\treturn 'Actions';\n\t\tcase 'app':\n\t\t\treturn 'App';\n\t\tcase 'other':\n\t\t\treturn 'Other';\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = section;\n\t\t\tvoid _exhaustive;\n\t\t\treturn 'Other';\n\t\t}\n\t}\n};\n\nexport const endpointsForRow = (\n\trow: Pick<Row, 'key' | 'endpoints'>,\n\tendpoints: ReadonlyArray<Endpoint>,\n): ReadonlyArray<Endpoint> =>\n\tendpoints.filter(\n\t\t(endpoint) => row.endpoints.includes(endpoint.endpointKey) || endpoint.pluginKey === row.key,\n\t);\n\nconst OPERATIONAL_ENDPOINT_FIELDS = new Set(['url', 'rpcUrl', 'faucetUrl', 'graphqlUrl']);\n\nexport const visibleEndpointsForRow = (\n\trow: Pick<Row, 'key' | 'endpoints'>,\n\tendpoints: ReadonlyArray<Endpoint>,\n): ReadonlyArray<Endpoint> => {\n\tconst rowEndpoints = endpointsForRow(row, endpoints);\n\tconst routed = rowEndpoints.filter((endpoint) => !isOperationalEndpoint(row.key, endpoint));\n\treturn routed.length > 0 ? routed : rowEndpoints;\n};\n\nexport const headlineForRow = (row: Row, endpoints: ReadonlyArray<Endpoint> = []): string => {\n\tconst rowEndpoints = visibleEndpointsForRow(row, endpoints);\n\tif (rowEndpoints.length > 0) return endpointLine(rowEndpoints[0]!);\n\tif (row.lastError !== null && row.status === 'failed') return errorSummaryFor(row.lastError);\n\treturn narrationFor(row.phase, row.status);\n};\n\nexport const secondaryForRow = (\n\trow: Row,\n\tendpoints: ReadonlyArray<Endpoint> = [],\n): ReadonlyArray<string> => {\n\tconst out: Array<string> = [];\n\tconst rowEndpoints = endpointsForRow(row, endpoints);\n\tfor (const endpoint of rowEndpoints.slice(1)) out.push(endpointLine(endpoint));\n\tif (row.logTail.truncated) out.push('log tail truncated');\n\treturn out;\n};\n\nexport const groupRows = (\n\trows: ReadonlyArray<Row>,\n\tendpoints: ReadonlyArray<Endpoint> = [],\n): ReadonlyArray<DisplaySection> => {\n\tconst buckets = new Map<RowSection, Array<DisplayRow>>();\n\tfor (const row of rows) {\n\t\tconst cells = deriveDisplayCells(row, endpoints);\n\t\tconst list = buckets.get(cells.section) ?? [];\n\t\tlist.push({ row, cells });\n\t\tbuckets.set(cells.section, list);\n\t}\n\tconst order: ReadonlyArray<RowSection> = [\n\t\t'service',\n\t\t'package',\n\t\t'account',\n\t\t'action',\n\t\t'app',\n\t\t'other',\n\t];\n\treturn order\n\t\t.filter((section) => buckets.has(section))\n\t\t.map((section) => ({\n\t\t\tkey: section,\n\t\t\tlabel: sectionLabel(section),\n\t\t\trows: buckets.get(section) ?? [],\n\t\t}));\n};\n\nexport const deriveDashboardSummary = (\n\tstate: Pick<SubscribableState, 'rows' | 'endpoints' | 'accounts' | 'packages' | 'errors'>,\n): DashboardSummary => {\n\tconst readyRows = state.rows.filter(\n\t\t(row) => row.status === 'ready' || row.status === 'done',\n\t).length;\n\tconst activeRows = state.rows.filter(\n\t\t(row) => row.status === 'acquiring' || row.status === 'stopping',\n\t).length;\n\tconst failedRows = state.rows.filter((row) => row.status === 'failed').length;\n\tconst waitingRows = state.rows.filter(\n\t\t(row) => row.status === 'pending' || row.status === 'stopped',\n\t).length;\n\tconst health =\n\t\tstate.rows.length === 0\n\t\t\t? 'empty'\n\t\t\t: failedRows > 0\n\t\t\t\t? 'blocked'\n\t\t\t\t: activeRows > 0 || waitingRows > 0\n\t\t\t\t\t? 'active'\n\t\t\t\t\t: 'ready';\n\treturn {\n\t\ttotalRows: state.rows.length,\n\t\treadyRows,\n\t\tactiveRows,\n\t\tfailedRows,\n\t\twaitingRows,\n\t\tendpointCount: visibleEndpointCount(state.rows, state.endpoints),\n\t\taccountCount: state.accounts.length,\n\t\tpackageCount: state.packages.length,\n\t\terrorCount: state.errors.length,\n\t\thealth,\n\t};\n};\n\nconst visibleEndpointCount = (\n\trows: ReadonlyArray<Row>,\n\tendpoints: ReadonlyArray<Endpoint>,\n): number => {\n\tconst rowOwned = new Set<Endpoint['endpointKey']>();\n\tconst visible = new Set<Endpoint['endpointKey']>();\n\tfor (const row of rows) {\n\t\tfor (const endpoint of endpointsForRow(row, endpoints)) {\n\t\t\trowOwned.add(endpoint.endpointKey);\n\t\t}\n\t\tfor (const endpoint of visibleEndpointsForRow(row, endpoints)) {\n\t\t\tvisible.add(endpoint.endpointKey);\n\t\t}\n\t}\n\tfor (const endpoint of endpoints) {\n\t\tif (!rowOwned.has(endpoint.endpointKey)) visible.add(endpoint.endpointKey);\n\t}\n\treturn visible.size;\n};\n\nexport const dashboardSummaryLine = (summary: DashboardSummary): string =>\n\t[\n\t\t`${summary.readyRows}/${summary.totalRows} ready`,\n\t\tsummary.activeRows > 0 ? `${summary.activeRows} active` : null,\n\t\tsummary.waitingRows > 0 ? `${summary.waitingRows} waiting` : null,\n\t\tsummary.failedRows > 0 ? `${summary.failedRows} failed` : null,\n\t\t`${summary.endpointCount} urls`,\n\t\t`${summary.accountCount} accounts`,\n\t\tsummary.packageCount > 0 ? `${summary.packageCount} packages` : null,\n\t\tsummary.errorCount === 0 ? 'no errors' : `${summary.errorCount} errors`,\n\t]\n\t\t.filter((part): part is string => part !== null)\n\t\t.join(' ');\n\n// -----------------------------------------------------------------------------\n// Phase narration formatting\n// -----------------------------------------------------------------------------\n\n/**\n * Pure: phase narration string → renderable verb form. Phase is\n * free-form upstream (Tension 14). The renderer's job is to make it\n * legible; we keep this minimal — single-line, no fancy verb tense\n * inference. The truncation cap protects against pathological long\n * narrations.\n */\nexport const narrationFor = (phase: PhaseNarration | null, status: LifecycleStatus): string => {\n\tif (phase === null || phase.trim().length === 0) {\n\t\t// No phase set; surface a status-derived default for `acquiring`,\n\t\t// stay silent otherwise (Tension: don't manufacture text the\n\t\t// engine didn't ask for).\n\t\treturn status === 'acquiring' ? 'starting…' : '';\n\t}\n\tconst trimmed = phase.trim();\n\tconst TRUNC = 80;\n\treturn trimmed.length > TRUNC ? `${trimmed.slice(0, TRUNC - 1)}…` : trimmed;\n};\n\n// -----------------------------------------------------------------------------\n// Error summary formatting\n// -----------------------------------------------------------------------------\n\nconst ERR_SUMMARY_TRUNC = 120;\n\n/**\n * Pure: `Row.lastError` → renderable in-row summary. Keep it short;\n * detailed error context belongs in the activity/log stream.\n */\nexport const errorSummaryFor = (error: StructuredError | null): string => {\n\tif (error === null) return '';\n\tconst head = `${error.tag}: ${error.summary}`;\n\tconst detail = error.chain.find((line) => line !== head && line !== error.tag);\n\tconst compactDetail =\n\t\tdetail === undefined ? undefined : detail.replace(/^[A-Za-z0-9_[\\]-]+:\\s*/, '');\n\tconst summary = compactDetail === undefined ? head : `${head}: ${compactDetail}`;\n\treturn summary.length > ERR_SUMMARY_TRUNC\n\t\t? `${summary.slice(0, ERR_SUMMARY_TRUNC - 1)}…`\n\t\t: summary;\n};\n\n// -----------------------------------------------------------------------------\n// Endpoint formatting\n// -----------------------------------------------------------------------------\n\n/**\n * Pure: `Endpoint` → renderable line. Renderers prefer `displayUrl`\n * when set (codegen-friendly variant), falling back to `url`.\n */\nexport const endpointLine = (endpoint: Endpoint): string => {\n\tconst target = endpoint.displayUrl ?? endpoint.url;\n\tconst backing =\n\t\tendpoint.displayUrl !== null && endpoint.displayUrl !== endpoint.url\n\t\t\t? ` -> ${endpoint.url}`\n\t\t\t: '';\n\tconst protocol = endpoint.wireProtocol === 'http' ? '' : ` [${endpoint.wireProtocol}]`;\n\treturn `${endpoint.name}: ${target}${backing}${protocol}`;\n};\n\nexport const endpointsSummaryForRow = (\n\trow: Pick<Row, 'key' | 'endpoints'>,\n\tendpoints: ReadonlyArray<Endpoint>,\n): string => {\n\tconst rowEndpoints = visibleEndpointsForRow(row, endpoints);\n\tif (rowEndpoints.length === 0) return '';\n\treturn rowEndpoints.map(endpointLine).join(' | ');\n};\n\nexport const accountLine = (account: AccountProjection): string => {\n\tconst address = account.address ?? '<pending>';\n\tconst scheme = account.scheme ?? 'scheme pending';\n\tconst source = account.source ?? 'source pending';\n\tconst funding = accountFundingLine(account.funding);\n\tconst wallet = account.walletVisible ? 'wallet' : null;\n\treturn [humanizeToken(account.name), address, scheme, source, funding, wallet]\n\t\t.filter((part): part is string => part !== null && part.length > 0)\n\t\t.join(' ');\n};\n\nexport const packageLine = (pkg: PackageProjection): string => {\n\treturn [humanizeToken(pkg.name), pkg.packageId, pkg.mvrPlaceholder, pkg.kind]\n\t\t.filter((part): part is string => part !== null && part.length > 0)\n\t\t.join(' ');\n};\n\nexport interface AccountCells {\n\treadonly name: string;\n\treadonly address: string;\n\treadonly scheme: string;\n\treadonly source: string;\n\treadonly funding: string;\n}\n\nexport interface PackageCells {\n\treadonly name: string;\n\treadonly packageId: string;\n\treadonly mvr: string;\n\treadonly kind: string;\n\treadonly detail: string;\n}\n\nexport const accountCells = (account: AccountProjection): AccountCells => ({\n\tname: humanizeToken(account.name),\n\taddress: account.address ?? '<pending>',\n\tscheme: account.scheme ?? 'pending',\n\tsource: account.source ?? 'pending',\n\tfunding: accountFundingLine(account.funding),\n});\n\nconst accountFundingLine = (funding: AccountProjection['funding']): string => {\n\tconst entries = funding.entries ?? [];\n\tif (entries.length > 0) {\n\t\tconst rendered = entries\n\t\t\t.map(\n\t\t\t\t(entry) => `${entry.coin}:${entry.amount}${entry.status === 'skipped' ? ' skipped' : ''}`,\n\t\t\t)\n\t\t\t.join(', ');\n\t\treturn funding.status === 'funded' ? `funded ${rendered}` : `funding ${rendered}`;\n\t}\n\tswitch (funding.status) {\n\t\tcase 'pending':\n\t\t\treturn funding.requestedMist === null\n\t\t\t\t? 'funding pending'\n\t\t\t\t: `funding ${funding.requestedMist}`;\n\t\tcase 'funded':\n\t\t\treturn funding.balanceMist !== null\n\t\t\t\t? `funded ${funding.balanceMist}`\n\t\t\t\t: funding.requestedMist !== null\n\t\t\t\t\t? `funded ${funding.requestedMist}`\n\t\t\t\t\t: 'funded';\n\t\tcase 'skipped':\n\t\t\treturn 'funding skipped';\n\t\tcase 'failed':\n\t\t\treturn 'funding failed';\n\t\tcase 'unknown':\n\t\t\treturn 'funding unknown';\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = funding.status;\n\t\t\tvoid _exhaustive;\n\t\t\treturn '';\n\t\t}\n\t}\n};\n\nexport const packageCells = (pkg: PackageProjection): PackageCells => ({\n\tname: humanizeToken(pkg.name),\n\tpackageId: pkg.packageId,\n\tmvr: pkg.mvrPlaceholder,\n\tkind: pkg.kind,\n\tdetail: pkg.kind,\n});\n\n// -----------------------------------------------------------------------------\n// Top-level entry point\n// -----------------------------------------------------------------------------\n\n/**\n * Derive every visible display cell for a single row.\n *\n * Consumes ONLY `row.key`, `row.role`, `row.status`, `row.phase`,\n * `row.lastError`, `row.endpoints` (rendered separately by\n * `resource-table.tsx`), or `row.logTail` (kept in the projection\n * for renderer variants that need tails, but not used as primary\n * dashboard state because generic lifecycle log lines duplicate the\n * table).\n */\nexport const deriveDisplayCells = (\n\trow: Row,\n\tendpoints: ReadonlyArray<Endpoint> = [],\n): DisplayCells => ({\n\tstatusGlyph: statusGlyph(row.status),\n\tstatusColor: statusColor(row.status),\n\tstatusLabel: statusLabel(row.status),\n\troleGlyph: roleGlyph(row.role),\n\troleLabel: roleLabel(row.role),\n\tlabel: labelForRow(row.key),\n\tnarration: narrationFor(row.phase, row.status),\n\terrorSummary: errorSummaryFor(row.lastError),\n\tlabelColor: roleLabelColor(row.role),\n\tsection: sectionForRow(row, endpoints),\n\towner: ownerForRow(row.key),\n\theadline: headlineForRow(row, endpoints),\n\tsecondary: secondaryForRow(row, endpoints),\n});\n\nconst normalizeKey = (key: string): string =>\n\tkey\n\t\t.replace(/^@devstack\\//, '')\n\t\t.replace(/^(devstack:|app:)/, '')\n\t\t.replace(/#\\d+$/, '')\n\t\t.replace(/\\/\\d+$/, '');\n\nconst humanizeToken = (token: string): string =>\n\ttoken.replace(/[-_]+/g, ' ').replace(/^\\w/, (head) => head.toUpperCase());\n\nconst containsKeyPart = (key: string, parts: ReadonlyArray<string>): boolean => {\n\tconst tokens = key.split(/[/:._#-]/).filter((part) => part.length > 0);\n\treturn tokens.some((token) => parts.includes(token));\n};\n\nconst isSectionish = (token: string): boolean =>\n\tcontainsKeyPart(token.toLowerCase(), ['service', 'package', 'account', 'action', 'app']);\n\nconst isOperationalEndpoint = (rowKey: Pick<Row, 'key'>['key'], endpoint: Endpoint): boolean => {\n\tif (endpoint.pluginKey !== rowKey) return false;\n\tconst prefix = `${rowKey}:`;\n\tif (!endpoint.endpointKey.startsWith(prefix)) return false;\n\tconst field = endpoint.endpointKey.slice(prefix.length);\n\treturn OPERATIONAL_ENDPOINT_FIELDS.has(field);\n};\n\n// -----------------------------------------------------------------------------\n// Compile-time invariant\n// -----------------------------------------------------------------------------\n//\n// Renderer code must never see a `title`/`primary`/`extras` field on\n// `Row`. If the projection ever sprouts one, the substrate's\n// `__ProjectionFieldsClosed` guard fails first; this module-local\n// guard exists as a second layer that explicitly mentions the\n// forbidden field names so a future renderer-side regression is\n// caught at the renderer boundary, not at the substrate boundary.\n\ntype _NoForbiddenOnRow = 'title' extends keyof Row\n\t? never\n\t: 'primary' extends keyof Row\n\t\t? never\n\t\t: 'extras' extends keyof Row\n\t\t\t? never\n\t\t\t: true;\n\n/** Renderer-side compile-time guard. If this resolves to `never`,\n * the renderer is reading a forbidden display-vocabulary field from\n * the projection. */\nexport type __TuiDisplayVocabClean = _NoForbiddenOnRow extends true ? true : never;\n"],"mappings":"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"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { eventAt } from "../../substrate/event-time.mjs";
|
|
2
|
+
import { errorSummaryFor, labelForRow, sectionColor } from "./display-derivation.mjs";
|
|
3
|
+
const eventLogLineFromEvent = (event, seq, sectionLookup = () => void 0) => {
|
|
3
4
|
const at = eventAt(event);
|
|
4
5
|
const id = `${at}-${seq}-${event.tag}`;
|
|
6
|
+
const scopeColorFor = (pluginKey) => sectionColor(sectionLookup(pluginKey) ?? "other");
|
|
5
7
|
switch (event.tag) {
|
|
6
8
|
case "log.appended":
|
|
7
9
|
if (event.level === "info" || isRedundantPluginLog(event.line)) return null;
|
|
@@ -10,7 +12,7 @@ const eventLogLineFromEvent = (event, seq) => {
|
|
|
10
12
|
at,
|
|
11
13
|
level: event.level,
|
|
12
14
|
scope: labelForRow(event.pluginKey),
|
|
13
|
-
scopeColor:
|
|
15
|
+
scopeColor: scopeColorFor(event.pluginKey),
|
|
14
16
|
message: event.line
|
|
15
17
|
});
|
|
16
18
|
case "error.reported": return line({
|
|
@@ -18,15 +20,14 @@ const eventLogLineFromEvent = (event, seq) => {
|
|
|
18
20
|
level: event.error.severity === "warn" ? "warn" : "error",
|
|
19
21
|
at,
|
|
20
22
|
scope: event.error.pluginKey === null ? "Stack" : labelForRow(event.error.pluginKey),
|
|
21
|
-
scopeColor: event.error.pluginKey === null ? "white" :
|
|
23
|
+
scopeColor: event.error.pluginKey === null ? "white" : scopeColorFor(event.error.pluginKey),
|
|
22
24
|
message: `failed: ${errorSummaryFor(event.error)}`
|
|
23
25
|
});
|
|
24
26
|
case "build.statusChanged":
|
|
25
27
|
case "lifecycle.statusChanged":
|
|
26
28
|
case "lifecycle.phaseSet":
|
|
27
29
|
case "endpoint.registered":
|
|
28
|
-
case "
|
|
29
|
-
case "package.updated": return null;
|
|
30
|
+
case "projection.updated": return null;
|
|
30
31
|
case "restart.requested": return line({
|
|
31
32
|
id,
|
|
32
33
|
level: "warn",
|
|
@@ -92,6 +93,14 @@ const eventLogLineFromEvent = (event, seq) => {
|
|
|
92
93
|
scopeColor: "blueBright",
|
|
93
94
|
message: `restored ${event.snapshotId}`
|
|
94
95
|
});
|
|
96
|
+
case "engine.orchestrator.dispatchFailed": return line({
|
|
97
|
+
id,
|
|
98
|
+
level: "warn",
|
|
99
|
+
at,
|
|
100
|
+
scope: labelForRow(event.pluginKey),
|
|
101
|
+
scopeColor: scopeColorFor(event.pluginKey),
|
|
102
|
+
message: event.causeType === void 0 ? `routing sink '${event.kind}' failed: ${event.message}` : `routing sink '${event.kind}' failed (${event.causeType}): ${event.message}`
|
|
103
|
+
});
|
|
95
104
|
case "endpoint.released":
|
|
96
105
|
case "strategy.registered":
|
|
97
106
|
case "strategy.unregistered":
|
|
@@ -114,14 +123,25 @@ const appendEventLogLine = (lines, next) => {
|
|
|
114
123
|
const appended = [...lines, next];
|
|
115
124
|
return appended.length > 200 ? appended.slice(-200) : appended;
|
|
116
125
|
};
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
126
|
+
/**
|
|
127
|
+
* Batched variant of `appendEventLogLine`: append many lines, slice to
|
|
128
|
+
* the bound ONCE. The per-event variant rebuilt the array on every
|
|
129
|
+
* call; a 100-event burst therefore allocated 100 arrays and ran the
|
|
130
|
+
* `.slice(-MAX_EVENT_LOG_LINES)` projection 100 times. The plural form
|
|
131
|
+
* collapses that to one allocation + one bound check — matching the
|
|
132
|
+
* microtask-batched dispatch path in `app.tsx`.
|
|
133
|
+
*
|
|
134
|
+
* `nexts` may contain `null` entries (the same null-pass-through
|
|
135
|
+
* contract as the singular form) — they're filtered before append.
|
|
136
|
+
* Returns the input array unchanged when no real lines remain so
|
|
137
|
+
* `setEventLog`'s referential-equality short-circuit still fires.
|
|
138
|
+
*/
|
|
139
|
+
const appendEventLogLines = (lines, nexts) => {
|
|
140
|
+
const real = [];
|
|
141
|
+
for (const line of nexts) if (line !== null) real.push(line);
|
|
142
|
+
if (real.length === 0) return lines;
|
|
143
|
+
const appended = lines.length === 0 ? real : [...lines, ...real];
|
|
144
|
+
return appended.length > 200 ? appended.slice(-200) : appended;
|
|
125
145
|
};
|
|
126
146
|
const time = (at) => new Date(at).toISOString().slice(11, 19);
|
|
127
147
|
const targetLabel = (target) => target === "stack" ? "stack" : target.pluginKey;
|
|
@@ -141,15 +161,7 @@ const isRedundantPluginLog = (message) => {
|
|
|
141
161
|
const normalized = message.trim().toLowerCase();
|
|
142
162
|
return normalized === "plugin acquire start" || normalized === "plugin ready" || normalized === "plugin acquire failed";
|
|
143
163
|
};
|
|
144
|
-
const colorForPluginKey = (pluginKey) => {
|
|
145
|
-
const normalized = pluginKey.toLowerCase();
|
|
146
|
-
if (normalized.includes("account")) return "magenta";
|
|
147
|
-
if (normalized.includes("package")) return "blueBright";
|
|
148
|
-
if (normalized.includes("action")) return "magenta";
|
|
149
|
-
if (normalized.includes("app") || normalized.includes("frontend")) return "white";
|
|
150
|
-
return "cyan";
|
|
151
|
-
};
|
|
152
164
|
//#endregion
|
|
153
|
-
export { appendEventLogLine, eventLogLineFromEvent, shutdownRequestedLine };
|
|
165
|
+
export { appendEventLogLine, appendEventLogLines, eventLogLineFromEvent, shutdownRequestedLine };
|
|
154
166
|
|
|
155
167
|
//# sourceMappingURL=event-log.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-log.mjs","names":[],"sources":["../../../src/surfaces/tui/event-log.ts"],"sourcesContent":["import type { EngineEvent } from '../../substrate/events.ts';\nimport { errorSummaryFor, labelForRow, type ColorToken } from './display-derivation.ts';\n\nexport interface EventLogLine {\n\treadonly id: string;\n\treadonly time: string;\n\treadonly scope: string;\n\treadonly scopeColor: ColorToken;\n\treadonly message: string;\n\treadonly text: string;\n\treadonly level: 'info' | 'warn' | 'error';\n}\n\nexport const MAX_EVENT_LOG_LINES = 200;\n\nexport const eventLogLineFromEvent = (event: EngineEvent, seq: number): EventLogLine | null => {\n\tconst at = eventAt(event);\n\tconst id = `${at}-${seq}-${event.tag}`;\n\tswitch (event.tag) {\n\t\tcase 'log.appended':\n\t\t\tif (event.level === 'info' || isRedundantPluginLog(event.line)) return null;\n\t\t\treturn line({\n\t\t\t\tid,\n\t\t\t\tat,\n\t\t\t\tlevel: event.level,\n\t\t\t\tscope: labelForRow(event.pluginKey),\n\t\t\t\tscopeColor: colorForPluginKey(event.pluginKey),\n\t\t\t\tmessage: event.line,\n\t\t\t});\n\t\tcase 'error.reported':\n\t\t\treturn line({\n\t\t\t\tid,\n\t\t\t\tlevel: event.error.severity === 'warn' ? 'warn' : 'error',\n\t\t\t\tat,\n\t\t\t\tscope: event.error.pluginKey === null ? 'Stack' : labelForRow(event.error.pluginKey),\n\t\t\t\tscopeColor:\n\t\t\t\t\tevent.error.pluginKey === null ? 'white' : colorForPluginKey(event.error.pluginKey),\n\t\t\t\tmessage: `failed: ${errorSummaryFor(event.error)}`,\n\t\t\t});\n\t\tcase 'build.statusChanged':\n\t\tcase 'lifecycle.statusChanged':\n\t\tcase 'lifecycle.phaseSet':\n\t\tcase 'endpoint.registered':\n\t\tcase 'account.updated':\n\t\tcase 'package.updated':\n\t\t\treturn null;\n\t\tcase 'restart.requested':\n\t\t\treturn line({\n\t\t\t\tid,\n\t\t\t\tlevel: 'warn',\n\t\t\t\tat,\n\t\t\t\tscope: 'Stack',\n\t\t\t\tscopeColor: 'white',\n\t\t\t\tmessage: `restart requested for ${targetLabel(event.target)}`,\n\t\t\t});\n\t\tcase 'restart.completed':\n\t\t\treturn line({\n\t\t\t\tid,\n\t\t\t\tlevel: 'info',\n\t\t\t\tat,\n\t\t\t\tscope: 'Stack',\n\t\t\t\tscopeColor: 'white',\n\t\t\t\tmessage: `restart completed for ${targetLabel(event.target)}`,\n\t\t\t});\n\t\tcase 'shutdown.escalated':\n\t\t\treturn line({\n\t\t\t\tid,\n\t\t\t\tlevel: 'warn',\n\t\t\t\tat,\n\t\t\t\tscope: 'Stack',\n\t\t\t\tscopeColor: 'white',\n\t\t\t\tmessage: `shutdown hard-kill escalated by ${event.signal} (exit ${event.exitCode})`,\n\t\t\t});\n\t\tcase 'snapshot.captureStarted':\n\t\t\treturn line({\n\t\t\t\tid,\n\t\t\t\tlevel: 'info',\n\t\t\t\tat,\n\t\t\t\tscope: 'Snapshot',\n\t\t\t\tscopeColor: 'blueBright',\n\t\t\t\tmessage: event.name === undefined ? 'capture started' : `capture started for ${event.name}`,\n\t\t\t});\n\t\tcase 'snapshot.captureProgress':\n\t\t\treturn null;\n\t\tcase 'snapshot.captureSkipped':\n\t\t\treturn line({\n\t\t\t\tid,\n\t\t\t\tlevel: 'warn',\n\t\t\t\tat,\n\t\t\t\tscope: 'Snapshot',\n\t\t\t\tscopeColor: 'blueBright',\n\t\t\t\tmessage: 'capture already running',\n\t\t\t});\n\t\tcase 'snapshot.captureFailed':\n\t\t\treturn line({\n\t\t\t\tid,\n\t\t\t\tlevel: 'error',\n\t\t\t\tat,\n\t\t\t\tscope: 'Snapshot',\n\t\t\t\tscopeColor: 'blueBright',\n\t\t\t\tmessage:\n\t\t\t\t\tevent.name === undefined\n\t\t\t\t\t\t? `capture failed: ${event.summary}`\n\t\t\t\t\t\t: `capture failed for ${event.name}: ${event.summary}`,\n\t\t\t});\n\t\tcase 'snapshot.captured':\n\t\t\treturn line({\n\t\t\t\tid,\n\t\t\t\tlevel: 'info',\n\t\t\t\tat,\n\t\t\t\tscope: 'Snapshot',\n\t\t\t\tscopeColor: 'blueBright',\n\t\t\t\tmessage:\n\t\t\t\t\tevent.name === undefined\n\t\t\t\t\t\t? `captured ${event.snapshotId}`\n\t\t\t\t\t\t: `captured ${event.name} (${event.snapshotId})`,\n\t\t\t});\n\t\tcase 'snapshot.restored':\n\t\t\treturn line({\n\t\t\t\tid,\n\t\t\t\tlevel: 'info',\n\t\t\t\tat,\n\t\t\t\tscope: 'Snapshot',\n\t\t\t\tscopeColor: 'blueBright',\n\t\t\t\tmessage: `restored ${event.snapshotId}`,\n\t\t\t});\n\t\tcase 'endpoint.released':\n\t\tcase 'strategy.registered':\n\t\tcase 'strategy.unregistered':\n\t\tcase 'manifest.flushed':\n\t\tcase 'codegen.emitted':\n\t\t\treturn null;\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = event;\n\t\t\tvoid _exhaustive;\n\t\t\treturn null;\n\t\t}\n\t}\n};\n\nexport const shutdownRequestedLine = (at: number, seq: number): EventLogLine => ({\n\tid: `${at}-${seq}-shutdown.requested`,\n\ttime: time(at),\n\tscope: 'Stack',\n\tscopeColor: 'white',\n\tmessage: 'shutdown requested; waiting for graceful stop',\n\tlevel: 'warn',\n\ttext: `${time(at)} shutdown requested; waiting for graceful stop`,\n});\n\nexport const appendEventLogLine = (\n\tlines: ReadonlyArray<EventLogLine>,\n\tnext: EventLogLine | null,\n): ReadonlyArray<EventLogLine> => {\n\tif (next === null) return lines;\n\tconst appended = [...lines, next];\n\treturn appended.length > MAX_EVENT_LOG_LINES ? appended.slice(-MAX_EVENT_LOG_LINES) : appended;\n};\n\nconst eventAt = (event: EngineEvent): number => {\n\tif ('at' in event && typeof event.at === 'number') return event.at;\n\tswitch (event.tag) {\n\t\tcase 'endpoint.registered':\n\t\t\treturn event.endpoint.registeredAt;\n\t\tcase 'error.reported':\n\t\t\treturn event.error.at;\n\t\tcase 'build.statusChanged':\n\t\t\treturn event.entry.startedAt;\n\t\tdefault:\n\t\t\treturn Date.now();\n\t}\n};\n\nconst time = (at: number): string => new Date(at).toISOString().slice(11, 19);\n\nconst targetLabel = (target: 'stack' | { readonly pluginKey: string }): string =>\n\ttarget === 'stack' ? 'stack' : target.pluginKey;\n\nconst line = (input: {\n\treadonly id: string;\n\treadonly at: number;\n\treadonly level: EventLogLine['level'];\n\treadonly scope: string;\n\treadonly scopeColor: ColorToken;\n\treadonly message: string;\n}): EventLogLine => {\n\tconst renderedTime = time(input.at);\n\treturn {\n\t\tid: input.id,\n\t\ttime: renderedTime,\n\t\tscope: input.scope,\n\t\tscopeColor: input.scopeColor,\n\t\tmessage: input.message,\n\t\tlevel: input.level,\n\t\ttext: `${renderedTime} ${input.scope}: ${input.message}`,\n\t};\n};\n\nconst isRedundantPluginLog = (message: string): boolean => {\n\tconst normalized = message.trim().toLowerCase();\n\treturn (\n\t\tnormalized === 'plugin acquire start' ||\n\t\tnormalized === 'plugin ready' ||\n\t\tnormalized === 'plugin acquire failed'\n\t);\n};\n\nconst colorForPluginKey = (pluginKey: string): ColorToken => {\n\tconst normalized = pluginKey.toLowerCase();\n\tif (normalized.includes('account')) return 'magenta';\n\tif (normalized.includes('package')) return 'blueBright';\n\tif (normalized.includes('action')) return 'magenta';\n\tif (normalized.includes('app') || normalized.includes('frontend')) return 'white';\n\treturn 'cyan';\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"event-log.mjs","names":[],"sources":["../../../src/surfaces/tui/event-log.ts"],"sourcesContent":["import type { EngineEvent } from '../../substrate/events.ts';\nimport type { RowSection } from '../../substrate/projection.ts';\nimport {\n\terrorSummaryFor,\n\tlabelForRow,\n\tsectionColor,\n\ttype ColorToken,\n} from './display-derivation.ts';\nimport { eventAt } from '../../substrate/event-time.ts';\n\nexport interface EventLogLine {\n\treadonly id: string;\n\treadonly time: string;\n\treadonly scope: string;\n\treadonly scopeColor: ColorToken;\n\treadonly message: string;\n\treadonly text: string;\n\treadonly level: 'info' | 'warn' | 'error';\n}\n\nexport const MAX_EVENT_LOG_LINES = 200;\n\n/** Pure: lookup a row's plugin-declared section by `pluginKey`. The\n * event log accepts this as a parameter rather than computing it\n * itself — the substrate forbids the renderer from pattern-matching\n * plugin-name substrings. Callers (e.g. `app.tsx`) build the lookup\n * from the live `state.rows` projection. */\nexport type SectionLookup = (pluginKey: string) => RowSection | undefined;\n\nexport const eventLogLineFromEvent = (\n\tevent: EngineEvent,\n\tseq: number,\n\tsectionLookup: SectionLookup = () => undefined,\n): EventLogLine | null => {\n\tconst at = eventAt(event);\n\tconst id = `${at}-${seq}-${event.tag}`;\n\tconst scopeColorFor = (pluginKey: string): ColorToken =>\n\t\tsectionColor(sectionLookup(pluginKey) ?? 'other');\n\tswitch (event.tag) {\n\t\tcase 'log.appended':\n\t\t\tif (event.level === 'info' || isRedundantPluginLog(event.line)) return null;\n\t\t\treturn line({\n\t\t\t\tid,\n\t\t\t\tat,\n\t\t\t\tlevel: event.level,\n\t\t\t\tscope: labelForRow(event.pluginKey),\n\t\t\t\tscopeColor: scopeColorFor(event.pluginKey),\n\t\t\t\tmessage: event.line,\n\t\t\t});\n\t\tcase 'error.reported':\n\t\t\treturn line({\n\t\t\t\tid,\n\t\t\t\tlevel: event.error.severity === 'warn' ? 'warn' : 'error',\n\t\t\t\tat,\n\t\t\t\tscope: event.error.pluginKey === null ? 'Stack' : labelForRow(event.error.pluginKey),\n\t\t\t\tscopeColor: event.error.pluginKey === null ? 'white' : scopeColorFor(event.error.pluginKey),\n\t\t\t\tmessage: `failed: ${errorSummaryFor(event.error)}`,\n\t\t\t});\n\t\tcase 'build.statusChanged':\n\t\tcase 'lifecycle.statusChanged':\n\t\tcase 'lifecycle.phaseSet':\n\t\tcase 'endpoint.registered':\n\t\tcase 'projection.updated':\n\t\t\treturn null;\n\t\tcase 'restart.requested':\n\t\t\treturn line({\n\t\t\t\tid,\n\t\t\t\tlevel: 'warn',\n\t\t\t\tat,\n\t\t\t\tscope: 'Stack',\n\t\t\t\tscopeColor: 'white',\n\t\t\t\tmessage: `restart requested for ${targetLabel(event.target)}`,\n\t\t\t});\n\t\tcase 'restart.completed':\n\t\t\treturn line({\n\t\t\t\tid,\n\t\t\t\tlevel: 'info',\n\t\t\t\tat,\n\t\t\t\tscope: 'Stack',\n\t\t\t\tscopeColor: 'white',\n\t\t\t\tmessage: `restart completed for ${targetLabel(event.target)}`,\n\t\t\t});\n\t\tcase 'shutdown.escalated':\n\t\t\treturn line({\n\t\t\t\tid,\n\t\t\t\tlevel: 'warn',\n\t\t\t\tat,\n\t\t\t\tscope: 'Stack',\n\t\t\t\tscopeColor: 'white',\n\t\t\t\tmessage: `shutdown hard-kill escalated by ${event.signal} (exit ${event.exitCode})`,\n\t\t\t});\n\t\tcase 'snapshot.captureStarted':\n\t\t\treturn line({\n\t\t\t\tid,\n\t\t\t\tlevel: 'info',\n\t\t\t\tat,\n\t\t\t\tscope: 'Snapshot',\n\t\t\t\tscopeColor: 'blueBright',\n\t\t\t\tmessage: event.name === undefined ? 'capture started' : `capture started for ${event.name}`,\n\t\t\t});\n\t\tcase 'snapshot.captureProgress':\n\t\t\treturn null;\n\t\tcase 'snapshot.captureSkipped':\n\t\t\treturn line({\n\t\t\t\tid,\n\t\t\t\tlevel: 'warn',\n\t\t\t\tat,\n\t\t\t\tscope: 'Snapshot',\n\t\t\t\tscopeColor: 'blueBright',\n\t\t\t\tmessage: 'capture already running',\n\t\t\t});\n\t\tcase 'snapshot.captureFailed':\n\t\t\treturn line({\n\t\t\t\tid,\n\t\t\t\tlevel: 'error',\n\t\t\t\tat,\n\t\t\t\tscope: 'Snapshot',\n\t\t\t\tscopeColor: 'blueBright',\n\t\t\t\tmessage:\n\t\t\t\t\tevent.name === undefined\n\t\t\t\t\t\t? `capture failed: ${event.summary}`\n\t\t\t\t\t\t: `capture failed for ${event.name}: ${event.summary}`,\n\t\t\t});\n\t\tcase 'snapshot.captured':\n\t\t\treturn line({\n\t\t\t\tid,\n\t\t\t\tlevel: 'info',\n\t\t\t\tat,\n\t\t\t\tscope: 'Snapshot',\n\t\t\t\tscopeColor: 'blueBright',\n\t\t\t\tmessage:\n\t\t\t\t\tevent.name === undefined\n\t\t\t\t\t\t? `captured ${event.snapshotId}`\n\t\t\t\t\t\t: `captured ${event.name} (${event.snapshotId})`,\n\t\t\t});\n\t\tcase 'snapshot.restored':\n\t\t\treturn line({\n\t\t\t\tid,\n\t\t\t\tlevel: 'info',\n\t\t\t\tat,\n\t\t\t\tscope: 'Snapshot',\n\t\t\t\tscopeColor: 'blueBright',\n\t\t\t\tmessage: `restored ${event.snapshotId}`,\n\t\t\t});\n\t\tcase 'engine.orchestrator.dispatchFailed':\n\t\t\t// A capability sink (e.g. `routable`) rejected, but the plugin is\n\t\t\t// left `ready` on purpose (non-fatal sink — see\n\t\t\t// dispatch-contributions.ts). Previously suppressed here, which\n\t\t\t// meant a live-dashboard operator saw a green stack with dead\n\t\t\t// RPC/wallet routing. Surface it as a warning so the failure is\n\t\t\t// visible; lead with the cause `_tag` when present so the line\n\t\t\t// names WHICH orchestrator broke.\n\t\t\treturn line({\n\t\t\t\tid,\n\t\t\t\tlevel: 'warn',\n\t\t\t\tat,\n\t\t\t\tscope: labelForRow(event.pluginKey),\n\t\t\t\tscopeColor: scopeColorFor(event.pluginKey),\n\t\t\t\tmessage:\n\t\t\t\t\tevent.causeType === undefined\n\t\t\t\t\t\t? `routing sink '${event.kind}' failed: ${event.message}`\n\t\t\t\t\t\t: `routing sink '${event.kind}' failed (${event.causeType}): ${event.message}`,\n\t\t\t});\n\t\tcase 'endpoint.released':\n\t\tcase 'strategy.registered':\n\t\tcase 'strategy.unregistered':\n\t\tcase 'manifest.flushed':\n\t\tcase 'codegen.emitted':\n\t\t\treturn null;\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = event;\n\t\t\tvoid _exhaustive;\n\t\t\treturn null;\n\t\t}\n\t}\n};\n\nexport const shutdownRequestedLine = (at: number, seq: number): EventLogLine => ({\n\tid: `${at}-${seq}-shutdown.requested`,\n\ttime: time(at),\n\tscope: 'Stack',\n\tscopeColor: 'white',\n\tmessage: 'shutdown requested; waiting for graceful stop',\n\tlevel: 'warn',\n\ttext: `${time(at)} shutdown requested; waiting for graceful stop`,\n});\n\nexport const appendEventLogLine = (\n\tlines: ReadonlyArray<EventLogLine>,\n\tnext: EventLogLine | null,\n): ReadonlyArray<EventLogLine> => {\n\tif (next === null) return lines;\n\tconst appended = [...lines, next];\n\treturn appended.length > MAX_EVENT_LOG_LINES ? appended.slice(-MAX_EVENT_LOG_LINES) : appended;\n};\n\n/**\n * Batched variant of `appendEventLogLine`: append many lines, slice to\n * the bound ONCE. The per-event variant rebuilt the array on every\n * call; a 100-event burst therefore allocated 100 arrays and ran the\n * `.slice(-MAX_EVENT_LOG_LINES)` projection 100 times. The plural form\n * collapses that to one allocation + one bound check — matching the\n * microtask-batched dispatch path in `app.tsx`.\n *\n * `nexts` may contain `null` entries (the same null-pass-through\n * contract as the singular form) — they're filtered before append.\n * Returns the input array unchanged when no real lines remain so\n * `setEventLog`'s referential-equality short-circuit still fires.\n */\nexport const appendEventLogLines = (\n\tlines: ReadonlyArray<EventLogLine>,\n\tnexts: ReadonlyArray<EventLogLine | null>,\n): ReadonlyArray<EventLogLine> => {\n\tconst real: Array<EventLogLine> = [];\n\tfor (const line of nexts) {\n\t\tif (line !== null) real.push(line);\n\t}\n\tif (real.length === 0) return lines;\n\tconst appended = lines.length === 0 ? real : [...lines, ...real];\n\treturn appended.length > MAX_EVENT_LOG_LINES ? appended.slice(-MAX_EVENT_LOG_LINES) : appended;\n};\n\nconst time = (at: number): string => new Date(at).toISOString().slice(11, 19);\n\nconst targetLabel = (target: 'stack' | { readonly pluginKey: string }): string =>\n\ttarget === 'stack' ? 'stack' : target.pluginKey;\n\nconst line = (input: {\n\treadonly id: string;\n\treadonly at: number;\n\treadonly level: EventLogLine['level'];\n\treadonly scope: string;\n\treadonly scopeColor: ColorToken;\n\treadonly message: string;\n}): EventLogLine => {\n\tconst renderedTime = time(input.at);\n\treturn {\n\t\tid: input.id,\n\t\ttime: renderedTime,\n\t\tscope: input.scope,\n\t\tscopeColor: input.scopeColor,\n\t\tmessage: input.message,\n\t\tlevel: input.level,\n\t\ttext: `${renderedTime} ${input.scope}: ${input.message}`,\n\t};\n};\n\nconst isRedundantPluginLog = (message: string): boolean => {\n\tconst normalized = message.trim().toLowerCase();\n\treturn (\n\t\tnormalized === 'plugin acquire start' ||\n\t\tnormalized === 'plugin ready' ||\n\t\tnormalized === 'plugin acquire failed'\n\t);\n};\n\n// Scope-chip color is driven by `Row.section`, looked up via the\n// `sectionLookup` argument the host (app.tsx / tests) constructs from\n// the live projection. Keeps the renderer name-blind: it sees only the\n// closed `RowSection` vocabulary (`service` / `package` / `account` /\n// ...), never a substring of a plugin name. Plugin authors declare\n// their section once via `definePlugin({ section })`.\n"],"mappings":"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"}
|