@cuna_labs/cli 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/LICENSE +201 -0
- package/NOTICE +9 -0
- package/README.md +169 -0
- package/THIRD_PARTY_NOTICES.md +29 -0
- package/dist/api/capability-evidence.d.ts +19 -0
- package/dist/api/capability-evidence.d.ts.map +1 -0
- package/dist/api/capability-evidence.js +38 -0
- package/dist/api/capability-evidence.js.map +1 -0
- package/dist/api/client.d.ts +167 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +937 -0
- package/dist/api/client.js.map +1 -0
- package/dist/api/contracts.d.ts +345 -0
- package/dist/api/contracts.d.ts.map +1 -0
- package/dist/api/contracts.js +976 -0
- package/dist/api/contracts.js.map +1 -0
- package/dist/api/execution-workspaces.d.ts +17 -0
- package/dist/api/execution-workspaces.d.ts.map +1 -0
- package/dist/api/execution-workspaces.js +46 -0
- package/dist/api/execution-workspaces.js.map +1 -0
- package/dist/api/http.d.ts +76 -0
- package/dist/api/http.d.ts.map +1 -0
- package/dist/api/http.js +838 -0
- package/dist/api/http.js.map +1 -0
- package/dist/api/managed-executions.d.ts +37 -0
- package/dist/api/managed-executions.d.ts.map +1 -0
- package/dist/api/managed-executions.js +80 -0
- package/dist/api/managed-executions.js.map +1 -0
- package/dist/api/observer-v2-schema.d.ts +206 -0
- package/dist/api/observer-v2-schema.d.ts.map +1 -0
- package/dist/api/observer-v2-schema.js +264 -0
- package/dist/api/observer-v2-schema.js.map +1 -0
- package/dist/api/observer-v2.d.ts +33 -0
- package/dist/api/observer-v2.d.ts.map +1 -0
- package/dist/api/observer-v2.js +60 -0
- package/dist/api/observer-v2.js.map +1 -0
- package/dist/api/owner-observe-grants-v2-schema.d.ts +678 -0
- package/dist/api/owner-observe-grants-v2-schema.d.ts.map +1 -0
- package/dist/api/owner-observe-grants-v2-schema.js +887 -0
- package/dist/api/owner-observe-grants-v2-schema.js.map +1 -0
- package/dist/api/owner-observe-grants-v2.d.ts +268 -0
- package/dist/api/owner-observe-grants-v2.d.ts.map +1 -0
- package/dist/api/owner-observe-grants-v2.js +604 -0
- package/dist/api/owner-observe-grants-v2.js.map +1 -0
- package/dist/api/provider-v2-schema.d.ts +293 -0
- package/dist/api/provider-v2-schema.d.ts.map +1 -0
- package/dist/api/provider-v2-schema.js +381 -0
- package/dist/api/provider-v2-schema.js.map +1 -0
- package/dist/api/provider-v2.d.ts +55 -0
- package/dist/api/provider-v2.d.ts.map +1 -0
- package/dist/api/provider-v2.js +54 -0
- package/dist/api/provider-v2.js.map +1 -0
- package/dist/api/remote-workspace.d.ts +29 -0
- package/dist/api/remote-workspace.d.ts.map +1 -0
- package/dist/api/remote-workspace.js +62 -0
- package/dist/api/remote-workspace.js.map +1 -0
- package/dist/api/supervisor-live-update.d.ts +248 -0
- package/dist/api/supervisor-live-update.d.ts.map +1 -0
- package/dist/api/supervisor-live-update.js +434 -0
- package/dist/api/supervisor-live-update.js.map +1 -0
- package/dist/api/terminal-reason.d.ts +5 -0
- package/dist/api/terminal-reason.d.ts.map +1 -0
- package/dist/api/terminal-reason.js +12 -0
- package/dist/api/terminal-reason.js.map +1 -0
- package/dist/auth/browser-handoff.d.ts +59 -0
- package/dist/auth/browser-handoff.d.ts.map +1 -0
- package/dist/auth/browser-handoff.js +33 -0
- package/dist/auth/browser-handoff.js.map +1 -0
- package/dist/auth/browser.d.ts +11 -0
- package/dist/auth/browser.d.ts.map +1 -0
- package/dist/auth/browser.js +47 -0
- package/dist/auth/browser.js.map +1 -0
- package/dist/auth/human-client.d.ts +39 -0
- package/dist/auth/human-client.d.ts.map +1 -0
- package/dist/auth/human-client.js +66 -0
- package/dist/auth/human-client.js.map +1 -0
- package/dist/auth/human-contracts.d.ts +52 -0
- package/dist/auth/human-contracts.d.ts.map +1 -0
- package/dist/auth/human-contracts.js +229 -0
- package/dist/auth/human-contracts.js.map +1 -0
- package/dist/auth/human-session.d.ts +48 -0
- package/dist/auth/human-session.d.ts.map +1 -0
- package/dist/auth/human-session.js +902 -0
- package/dist/auth/human-session.js.map +1 -0
- package/dist/auth/onboarding-state.d.ts +31 -0
- package/dist/auth/onboarding-state.d.ts.map +1 -0
- package/dist/auth/onboarding-state.js +52 -0
- package/dist/auth/onboarding-state.js.map +1 -0
- package/dist/auth/pkce.d.ts +15 -0
- package/dist/auth/pkce.d.ts.map +1 -0
- package/dist/auth/pkce.js +19 -0
- package/dist/auth/pkce.js.map +1 -0
- package/dist/bin/cuna.d.ts +3 -0
- package/dist/bin/cuna.d.ts.map +1 -0
- package/dist/bin/cuna.js +4 -0
- package/dist/bin/cuna.js.map +1 -0
- package/dist/build-identity.d.ts +20 -0
- package/dist/build-identity.d.ts.map +1 -0
- package/dist/build-identity.js +77 -0
- package/dist/build-identity.js.map +1 -0
- package/dist/cli/command-help.d.ts +9 -0
- package/dist/cli/command-help.d.ts.map +1 -0
- package/dist/cli/command-help.js +324 -0
- package/dist/cli/command-help.js.map +1 -0
- package/dist/cli/help.d.ts +40 -0
- package/dist/cli/help.d.ts.map +1 -0
- package/dist/cli/help.js +256 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/output.d.ts +28 -0
- package/dist/cli/output.d.ts.map +1 -0
- package/dist/cli/output.js +95 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/cli/parser.d.ts +65 -0
- package/dist/cli/parser.d.ts.map +1 -0
- package/dist/cli/parser.js +294 -0
- package/dist/cli/parser.js.map +1 -0
- package/dist/cli/process-entrypoint.d.ts +18 -0
- package/dist/cli/process-entrypoint.d.ts.map +1 -0
- package/dist/cli/process-entrypoint.js +26 -0
- package/dist/cli/process-entrypoint.js.map +1 -0
- package/dist/cli/run.d.ts +114 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +1969 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/commands/commands.d.ts +74 -0
- package/dist/commands/commands.d.ts.map +1 -0
- package/dist/commands/commands.js +2814 -0
- package/dist/commands/commands.js.map +1 -0
- package/dist/config/config.d.ts +86 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +323 -0
- package/dist/config/config.js.map +1 -0
- package/dist/config/infra-contract-witness.d.ts +29 -0
- package/dist/config/infra-contract-witness.d.ts.map +1 -0
- package/dist/config/infra-contract-witness.js +30 -0
- package/dist/config/infra-contract-witness.js.map +1 -0
- package/dist/core/browser-url.d.ts +2 -0
- package/dist/core/browser-url.d.ts.map +1 -0
- package/dist/core/browser-url.js +20 -0
- package/dist/core/browser-url.js.map +1 -0
- package/dist/core/deployed-wire-compatibility.d.ts +15 -0
- package/dist/core/deployed-wire-compatibility.d.ts.map +1 -0
- package/dist/core/deployed-wire-compatibility.js +15 -0
- package/dist/core/deployed-wire-compatibility.js.map +1 -0
- package/dist/core/errors.d.ts +59 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +82 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/exit-codes.d.ts +68 -0
- package/dist/core/exit-codes.d.ts.map +1 -0
- package/dist/core/exit-codes.js +84 -0
- package/dist/core/exit-codes.js.map +1 -0
- package/dist/core/instant.d.ts +60 -0
- package/dist/core/instant.d.ts.map +1 -0
- package/dist/core/instant.js +90 -0
- package/dist/core/instant.js.map +1 -0
- package/dist/core/namespace.d.ts +171 -0
- package/dist/core/namespace.d.ts.map +1 -0
- package/dist/core/namespace.js +227 -0
- package/dist/core/namespace.js.map +1 -0
- package/dist/core/observation-budget.d.ts +185 -0
- package/dist/core/observation-budget.d.ts.map +1 -0
- package/dist/core/observation-budget.js +209 -0
- package/dist/core/observation-budget.js.map +1 -0
- package/dist/core/product-web.d.ts +81 -0
- package/dist/core/product-web.d.ts.map +1 -0
- package/dist/core/product-web.js +87 -0
- package/dist/core/product-web.js.map +1 -0
- package/dist/core/validation.d.ts +90 -0
- package/dist/core/validation.d.ts.map +1 -0
- package/dist/core/validation.js +199 -0
- package/dist/core/validation.js.map +1 -0
- package/dist/credentials/contracts.d.ts +82 -0
- package/dist/credentials/contracts.d.ts.map +1 -0
- package/dist/credentials/contracts.js +2 -0
- package/dist/credentials/contracts.js.map +1 -0
- package/dist/credentials/errors.d.ts +19 -0
- package/dist/credentials/errors.d.ts.map +1 -0
- package/dist/credentials/errors.js +16 -0
- package/dist/credentials/errors.js.map +1 -0
- package/dist/credentials/index.d.ts +6 -0
- package/dist/credentials/index.d.ts.map +1 -0
- package/dist/credentials/index.js +6 -0
- package/dist/credentials/index.js.map +1 -0
- package/dist/credentials/local-session.d.ts +101 -0
- package/dist/credentials/local-session.d.ts.map +1 -0
- package/dist/credentials/local-session.js +839 -0
- package/dist/credentials/local-session.js.map +1 -0
- package/dist/credentials/secret-material.d.ts +17 -0
- package/dist/credentials/secret-material.d.ts.map +1 -0
- package/dist/credentials/secret-material.js +49 -0
- package/dist/credentials/secret-material.js.map +1 -0
- package/dist/credentials/vault.d.ts +41 -0
- package/dist/credentials/vault.d.ts.map +1 -0
- package/dist/credentials/vault.js +719 -0
- package/dist/credentials/vault.js.map +1 -0
- package/dist/daemon/endpoint.d.ts +29 -0
- package/dist/daemon/endpoint.d.ts.map +1 -0
- package/dist/daemon/endpoint.js +66 -0
- package/dist/daemon/endpoint.js.map +1 -0
- package/dist/daemon/journal.d.ts +62 -0
- package/dist/daemon/journal.d.ts.map +1 -0
- package/dist/daemon/journal.js +299 -0
- package/dist/daemon/journal.js.map +1 -0
- package/dist/daemon/lease.d.ts +25 -0
- package/dist/daemon/lease.d.ts.map +1 -0
- package/dist/daemon/lease.js +94 -0
- package/dist/daemon/lease.js.map +1 -0
- package/dist/daemon/lifecycle.d.ts +14 -0
- package/dist/daemon/lifecycle.d.ts.map +1 -0
- package/dist/daemon/lifecycle.js +29 -0
- package/dist/daemon/lifecycle.js.map +1 -0
- package/dist/daemon/protocol.d.ts +65 -0
- package/dist/daemon/protocol.d.ts.map +1 -0
- package/dist/daemon/protocol.js +194 -0
- package/dist/daemon/protocol.js.map +1 -0
- package/dist/daemon/supervisor.d.ts +29 -0
- package/dist/daemon/supervisor.d.ts.map +1 -0
- package/dist/daemon/supervisor.js +87 -0
- package/dist/daemon/supervisor.js.map +1 -0
- package/dist/daemon/views.d.ts +31 -0
- package/dist/daemon/views.d.ts.map +1 -0
- package/dist/daemon/views.js +86 -0
- package/dist/daemon/views.js.map +1 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/journey/api-effects.d.ts +59 -0
- package/dist/journey/api-effects.d.ts.map +1 -0
- package/dist/journey/api-effects.js +386 -0
- package/dist/journey/api-effects.js.map +1 -0
- package/dist/journey/derived-identity.d.ts +91 -0
- package/dist/journey/derived-identity.d.ts.map +1 -0
- package/dist/journey/derived-identity.js +123 -0
- package/dist/journey/derived-identity.js.map +1 -0
- package/dist/journey/index.d.ts +6 -0
- package/dist/journey/index.d.ts.map +1 -0
- package/dist/journey/index.js +6 -0
- package/dist/journey/index.js.map +1 -0
- package/dist/journey/intent.d.ts +36 -0
- package/dist/journey/intent.d.ts.map +1 -0
- package/dist/journey/intent.js +191 -0
- package/dist/journey/intent.js.map +1 -0
- package/dist/journey/orchestrator.d.ts +140 -0
- package/dist/journey/orchestrator.d.ts.map +1 -0
- package/dist/journey/orchestrator.js +415 -0
- package/dist/journey/orchestrator.js.map +1 -0
- package/dist/journey/provider-launch-intent.d.ts +12 -0
- package/dist/journey/provider-launch-intent.d.ts.map +1 -0
- package/dist/journey/provider-launch-intent.js +40 -0
- package/dist/journey/provider-launch-intent.js.map +1 -0
- package/dist/journey/remote-workspace.d.ts +34 -0
- package/dist/journey/remote-workspace.d.ts.map +1 -0
- package/dist/journey/remote-workspace.js +91 -0
- package/dist/journey/remote-workspace.js.map +1 -0
- package/dist/journey/root-entry.d.ts +56 -0
- package/dist/journey/root-entry.d.ts.map +1 -0
- package/dist/journey/root-entry.js +19 -0
- package/dist/journey/root-entry.js.map +1 -0
- package/dist/journey/selection.d.ts +165 -0
- package/dist/journey/selection.d.ts.map +1 -0
- package/dist/journey/selection.js +565 -0
- package/dist/journey/selection.js.map +1 -0
- package/dist/journey/session-failure.d.ts +4 -0
- package/dist/journey/session-failure.d.ts.map +1 -0
- package/dist/journey/session-failure.js +28 -0
- package/dist/journey/session-failure.js.map +1 -0
- package/dist/journey/workspace-effects.d.ts +30 -0
- package/dist/journey/workspace-effects.d.ts.map +1 -0
- package/dist/journey/workspace-effects.js +348 -0
- package/dist/journey/workspace-effects.js.map +1 -0
- package/dist/local-actions/broker.d.ts +32 -0
- package/dist/local-actions/broker.d.ts.map +1 -0
- package/dist/local-actions/broker.js +400 -0
- package/dist/local-actions/broker.js.map +1 -0
- package/dist/local-actions/browser-action.d.ts +78 -0
- package/dist/local-actions/browser-action.d.ts.map +1 -0
- package/dist/local-actions/browser-action.js +307 -0
- package/dist/local-actions/browser-action.js.map +1 -0
- package/dist/local-actions/callback-relay.d.ts +45 -0
- package/dist/local-actions/callback-relay.d.ts.map +1 -0
- package/dist/local-actions/callback-relay.js +265 -0
- package/dist/local-actions/callback-relay.js.map +1 -0
- package/dist/local-actions/clipboard.d.ts +3 -0
- package/dist/local-actions/clipboard.d.ts.map +1 -0
- package/dist/local-actions/clipboard.js +18 -0
- package/dist/local-actions/clipboard.js.map +1 -0
- package/dist/local-actions/contracts.d.ts +63 -0
- package/dist/local-actions/contracts.d.ts.map +1 -0
- package/dist/local-actions/contracts.js +18 -0
- package/dist/local-actions/contracts.js.map +1 -0
- package/dist/local-actions/desktop-presentation.d.ts +141 -0
- package/dist/local-actions/desktop-presentation.d.ts.map +1 -0
- package/dist/local-actions/desktop-presentation.js +253 -0
- package/dist/local-actions/desktop-presentation.js.map +1 -0
- package/dist/local-actions/device-selection.d.ts +43 -0
- package/dist/local-actions/device-selection.d.ts.map +1 -0
- package/dist/local-actions/device-selection.js +154 -0
- package/dist/local-actions/device-selection.js.map +1 -0
- package/dist/local-actions/executor.d.ts +49 -0
- package/dist/local-actions/executor.d.ts.map +1 -0
- package/dist/local-actions/executor.js +329 -0
- package/dist/local-actions/executor.js.map +1 -0
- package/dist/local-actions/file-transfers.d.ts +141 -0
- package/dist/local-actions/file-transfers.d.ts.map +1 -0
- package/dist/local-actions/file-transfers.js +446 -0
- package/dist/local-actions/file-transfers.js.map +1 -0
- package/dist/local-actions/foreground-notifications.d.ts +45 -0
- package/dist/local-actions/foreground-notifications.d.ts.map +1 -0
- package/dist/local-actions/foreground-notifications.js +163 -0
- package/dist/local-actions/foreground-notifications.js.map +1 -0
- package/dist/local-actions/git-signing.d.ts +39 -0
- package/dist/local-actions/git-signing.d.ts.map +1 -0
- package/dist/local-actions/git-signing.js +135 -0
- package/dist/local-actions/git-signing.js.map +1 -0
- package/dist/local-actions/index.d.ts +19 -0
- package/dist/local-actions/index.d.ts.map +1 -0
- package/dist/local-actions/index.js +19 -0
- package/dist/local-actions/index.js.map +1 -0
- package/dist/local-actions/local-service-actions.d.ts +87 -0
- package/dist/local-actions/local-service-actions.d.ts.map +1 -0
- package/dist/local-actions/local-service-actions.js +347 -0
- package/dist/local-actions/local-service-actions.js.map +1 -0
- package/dist/local-actions/loopback.d.ts +5 -0
- package/dist/local-actions/loopback.d.ts.map +1 -0
- package/dist/local-actions/loopback.js +15 -0
- package/dist/local-actions/loopback.js.map +1 -0
- package/dist/local-actions/policy-store.d.ts +7 -0
- package/dist/local-actions/policy-store.d.ts.map +1 -0
- package/dist/local-actions/policy-store.js +70 -0
- package/dist/local-actions/policy-store.js.map +1 -0
- package/dist/local-actions/policy.d.ts +21 -0
- package/dist/local-actions/policy.d.ts.map +1 -0
- package/dist/local-actions/policy.js +43 -0
- package/dist/local-actions/policy.js.map +1 -0
- package/dist/local-actions/private-port-forward.d.ts +36 -0
- package/dist/local-actions/private-port-forward.d.ts.map +1 -0
- package/dist/local-actions/private-port-forward.js +154 -0
- package/dist/local-actions/private-port-forward.js.map +1 -0
- package/dist/local-actions/provider-mcp-config.d.ts +101 -0
- package/dist/local-actions/provider-mcp-config.d.ts.map +1 -0
- package/dist/local-actions/provider-mcp-config.js +166 -0
- package/dist/local-actions/provider-mcp-config.js.map +1 -0
- package/dist/local-actions/providers.d.ts +12 -0
- package/dist/local-actions/providers.d.ts.map +1 -0
- package/dist/local-actions/providers.js +42 -0
- package/dist/local-actions/providers.js.map +1 -0
- package/dist/local-actions/schemas.d.ts +4 -0
- package/dist/local-actions/schemas.d.ts.map +1 -0
- package/dist/local-actions/schemas.js +314 -0
- package/dist/local-actions/schemas.js.map +1 -0
- package/dist/local-actions/sensitive-consent.d.ts +32 -0
- package/dist/local-actions/sensitive-consent.d.ts.map +1 -0
- package/dist/local-actions/sensitive-consent.js +47 -0
- package/dist/local-actions/sensitive-consent.js.map +1 -0
- package/dist/machines/command-launch.d.ts +17 -0
- package/dist/machines/command-launch.d.ts.map +1 -0
- package/dist/machines/command-launch.js +52 -0
- package/dist/machines/command-launch.js.map +1 -0
- package/dist/machines/execution-receipt.d.ts +18 -0
- package/dist/machines/execution-receipt.d.ts.map +1 -0
- package/dist/machines/execution-receipt.js +87 -0
- package/dist/machines/execution-receipt.js.map +1 -0
- package/dist/machines/executions-screen.d.ts +6 -0
- package/dist/machines/executions-screen.d.ts.map +1 -0
- package/dist/machines/executions-screen.js +410 -0
- package/dist/machines/executions-screen.js.map +1 -0
- package/dist/machines/explorer.d.ts +75 -0
- package/dist/machines/explorer.d.ts.map +1 -0
- package/dist/machines/explorer.js +1726 -0
- package/dist/machines/explorer.js.map +1 -0
- package/dist/machines/live-supervisor-update.d.ts +325 -0
- package/dist/machines/live-supervisor-update.d.ts.map +1 -0
- package/dist/machines/live-supervisor-update.js +513 -0
- package/dist/machines/live-supervisor-update.js.map +1 -0
- package/dist/machines/machine-first.d.ts +123 -0
- package/dist/machines/machine-first.d.ts.map +1 -0
- package/dist/machines/machine-first.js +119 -0
- package/dist/machines/machine-first.js.map +1 -0
- package/dist/machines/opencode-supervisor.d.ts +51 -0
- package/dist/machines/opencode-supervisor.d.ts.map +1 -0
- package/dist/machines/opencode-supervisor.js +124 -0
- package/dist/machines/opencode-supervisor.js.map +1 -0
- package/dist/machines/pagination.d.ts +4 -0
- package/dist/machines/pagination.d.ts.map +1 -0
- package/dist/machines/pagination.js +7 -0
- package/dist/machines/pagination.js.map +1 -0
- package/dist/machines/provider-availability.d.ts +42 -0
- package/dist/machines/provider-availability.d.ts.map +1 -0
- package/dist/machines/provider-availability.js +82 -0
- package/dist/machines/provider-availability.js.map +1 -0
- package/dist/machines/provider-screen.d.ts +12 -0
- package/dist/machines/provider-screen.d.ts.map +1 -0
- package/dist/machines/provider-screen.js +129 -0
- package/dist/machines/provider-screen.js.map +1 -0
- package/dist/machines/session-actionability.d.ts +86 -0
- package/dist/machines/session-actionability.d.ts.map +1 -0
- package/dist/machines/session-actionability.js +125 -0
- package/dist/machines/session-actionability.js.map +1 -0
- package/dist/machines/session-visibility.d.ts +139 -0
- package/dist/machines/session-visibility.d.ts.map +1 -0
- package/dist/machines/session-visibility.js +109 -0
- package/dist/machines/session-visibility.js.map +1 -0
- package/dist/platform/adapter.d.ts +62 -0
- package/dist/platform/adapter.d.ts.map +1 -0
- package/dist/platform/adapter.js +240 -0
- package/dist/platform/adapter.js.map +1 -0
- package/dist/platform/support.d.ts +12 -0
- package/dist/platform/support.d.ts.map +1 -0
- package/dist/platform/support.js +25 -0
- package/dist/platform/support.js.map +1 -0
- package/dist/pty/contracts.d.ts +45 -0
- package/dist/pty/contracts.d.ts.map +1 -0
- package/dist/pty/contracts.js +2 -0
- package/dist/pty/contracts.js.map +1 -0
- package/dist/pty/evidence-gate.d.ts +14 -0
- package/dist/pty/evidence-gate.d.ts.map +1 -0
- package/dist/pty/evidence-gate.js +35 -0
- package/dist/pty/evidence-gate.js.map +1 -0
- package/dist/pty/index.d.ts +5 -0
- package/dist/pty/index.d.ts.map +1 -0
- package/dist/pty/index.js +5 -0
- package/dist/pty/index.js.map +1 -0
- package/dist/pty/node-host-terminal.d.ts +14 -0
- package/dist/pty/node-host-terminal.d.ts.map +1 -0
- package/dist/pty/node-host-terminal.js +173 -0
- package/dist/pty/node-host-terminal.js.map +1 -0
- package/dist/pty/node-process.d.ts +26 -0
- package/dist/pty/node-process.d.ts.map +1 -0
- package/dist/pty/node-process.js +102 -0
- package/dist/pty/node-process.js.map +1 -0
- package/dist/runtime/api-terminal-control-plane.d.ts +7 -0
- package/dist/runtime/api-terminal-control-plane.d.ts.map +1 -0
- package/dist/runtime/api-terminal-control-plane.js +95 -0
- package/dist/runtime/api-terminal-control-plane.js.map +1 -0
- package/dist/runtime/backoff.d.ts +17 -0
- package/dist/runtime/backoff.d.ts.map +1 -0
- package/dist/runtime/backoff.js +61 -0
- package/dist/runtime/backoff.js.map +1 -0
- package/dist/runtime/boundary.d.ts +171 -0
- package/dist/runtime/boundary.d.ts.map +1 -0
- package/dist/runtime/boundary.js +1858 -0
- package/dist/runtime/boundary.js.map +1 -0
- package/dist/runtime/capability-gate.d.ts +25 -0
- package/dist/runtime/capability-gate.d.ts.map +1 -0
- package/dist/runtime/capability-gate.js +77 -0
- package/dist/runtime/capability-gate.js.map +1 -0
- package/dist/runtime/contracts.d.ts +25 -0
- package/dist/runtime/contracts.d.ts.map +1 -0
- package/dist/runtime/contracts.js +66 -0
- package/dist/runtime/contracts.js.map +1 -0
- package/dist/runtime/errors.d.ts +20 -0
- package/dist/runtime/errors.d.ts.map +1 -0
- package/dist/runtime/errors.js +22 -0
- package/dist/runtime/errors.js.map +1 -0
- package/dist/runtime/index.d.ts +9 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +9 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/node-foreground-session.d.ts +50 -0
- package/dist/runtime/node-foreground-session.d.ts.map +1 -0
- package/dist/runtime/node-foreground-session.js +431 -0
- package/dist/runtime/node-foreground-session.js.map +1 -0
- package/dist/runtime/node-websocket-connector.d.ts +6 -0
- package/dist/runtime/node-websocket-connector.d.ts.map +1 -0
- package/dist/runtime/node-websocket-connector.js +344 -0
- package/dist/runtime/node-websocket-connector.js.map +1 -0
- package/dist/runtime/observer-screen.d.ts +6 -0
- package/dist/runtime/observer-screen.d.ts.map +1 -0
- package/dist/runtime/observer-screen.js +144 -0
- package/dist/runtime/observer-screen.js.map +1 -0
- package/dist/runtime/owner-grant-operations.d.ts +136 -0
- package/dist/runtime/owner-grant-operations.d.ts.map +1 -0
- package/dist/runtime/owner-grant-operations.js +216 -0
- package/dist/runtime/owner-grant-operations.js.map +1 -0
- package/dist/runtime/owner-grants-screen.d.ts +40 -0
- package/dist/runtime/owner-grants-screen.d.ts.map +1 -0
- package/dist/runtime/owner-grants-screen.js +987 -0
- package/dist/runtime/owner-grants-screen.js.map +1 -0
- package/dist/runtime/terminal-transport.d.ts +85 -0
- package/dist/runtime/terminal-transport.d.ts.map +1 -0
- package/dist/runtime/terminal-transport.js +152 -0
- package/dist/runtime/terminal-transport.js.map +1 -0
- package/dist/sync/continuous-sync-supervisor.d.ts +107 -0
- package/dist/sync/continuous-sync-supervisor.d.ts.map +1 -0
- package/dist/sync/continuous-sync-supervisor.js +1117 -0
- package/dist/sync/continuous-sync-supervisor.js.map +1 -0
- package/dist/sync/index.d.ts +9 -0
- package/dist/sync/index.d.ts.map +1 -0
- package/dist/sync/index.js +9 -0
- package/dist/sync/index.js.map +1 -0
- package/dist/sync/journal.d.ts +57 -0
- package/dist/sync/journal.d.ts.map +1 -0
- package/dist/sync/journal.js +685 -0
- package/dist/sync/journal.js.map +1 -0
- package/dist/sync/revisions.d.ts +118 -0
- package/dist/sync/revisions.d.ts.map +1 -0
- package/dist/sync/revisions.js +364 -0
- package/dist/sync/revisions.js.map +1 -0
- package/dist/sync/supervisor.d.ts +107 -0
- package/dist/sync/supervisor.d.ts.map +1 -0
- package/dist/sync/supervisor.js +246 -0
- package/dist/sync/supervisor.js.map +1 -0
- package/dist/sync/workspace-sync-client.d.ts +18 -0
- package/dist/sync/workspace-sync-client.d.ts.map +1 -0
- package/dist/sync/workspace-sync-client.js +150 -0
- package/dist/sync/workspace-sync-client.js.map +1 -0
- package/dist/sync/workspace-sync-coordinator.d.ts +76 -0
- package/dist/sync/workspace-sync-coordinator.d.ts.map +1 -0
- package/dist/sync/workspace-sync-coordinator.js +621 -0
- package/dist/sync/workspace-sync-coordinator.js.map +1 -0
- package/dist/sync/workspace-sync-product-service.d.ts +79 -0
- package/dist/sync/workspace-sync-product-service.d.ts.map +1 -0
- package/dist/sync/workspace-sync-product-service.js +398 -0
- package/dist/sync/workspace-sync-product-service.js.map +1 -0
- package/dist/sync/workspace-sync-protocol.d.ts +145 -0
- package/dist/sync/workspace-sync-protocol.d.ts.map +1 -0
- package/dist/sync/workspace-sync-protocol.js +347 -0
- package/dist/sync/workspace-sync-protocol.js.map +1 -0
- package/dist/terminal/appbar.d.ts +40 -0
- package/dist/terminal/appbar.d.ts.map +1 -0
- package/dist/terminal/appbar.js +55 -0
- package/dist/terminal/appbar.js.map +1 -0
- package/dist/terminal/cell-width.d.ts +3 -0
- package/dist/terminal/cell-width.d.ts.map +1 -0
- package/dist/terminal/cell-width.js +53 -0
- package/dist/terminal/cell-width.js.map +1 -0
- package/dist/terminal/codec.d.ts +107 -0
- package/dist/terminal/codec.d.ts.map +1 -0
- package/dist/terminal/codec.js +538 -0
- package/dist/terminal/codec.js.map +1 -0
- package/dist/terminal/foreground.d.ts +135 -0
- package/dist/terminal/foreground.d.ts.map +1 -0
- package/dist/terminal/foreground.js +2097 -0
- package/dist/terminal/foreground.js.map +1 -0
- package/dist/terminal/generated/terminal-wire-v1.d.ts +26 -0
- package/dist/terminal/generated/terminal-wire-v1.d.ts.map +1 -0
- package/dist/terminal/generated/terminal-wire-v1.js +27 -0
- package/dist/terminal/generated/terminal-wire-v1.js.map +1 -0
- package/dist/terminal/mode.d.ts +33 -0
- package/dist/terminal/mode.d.ts.map +1 -0
- package/dist/terminal/mode.js +99 -0
- package/dist/terminal/mode.js.map +1 -0
- package/dist/terminal/passthrough.d.ts +47 -0
- package/dist/terminal/passthrough.d.ts.map +1 -0
- package/dist/terminal/passthrough.js +666 -0
- package/dist/terminal/passthrough.js.map +1 -0
- package/dist/terminal/resume.d.ts +58 -0
- package/dist/terminal/resume.d.ts.map +1 -0
- package/dist/terminal/resume.js +185 -0
- package/dist/terminal/resume.js.map +1 -0
- package/dist/terminal/viewport.d.ts +93 -0
- package/dist/terminal/viewport.d.ts.map +1 -0
- package/dist/terminal/viewport.js +266 -0
- package/dist/terminal/viewport.js.map +1 -0
- package/dist/terminal/workbench.d.ts +32 -0
- package/dist/terminal/workbench.d.ts.map +1 -0
- package/dist/terminal/workbench.js +316 -0
- package/dist/terminal/workbench.js.map +1 -0
- package/dist/terminal/xterm-vte.d.ts +49 -0
- package/dist/terminal/xterm-vte.d.ts.map +1 -0
- package/dist/terminal/xterm-vte.js +602 -0
- package/dist/terminal/xterm-vte.js.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/dist/workspace/binding-path.d.ts +17 -0
- package/dist/workspace/binding-path.d.ts.map +1 -0
- package/dist/workspace/binding-path.js +91 -0
- package/dist/workspace/binding-path.js.map +1 -0
- package/dist/workspace/binding-store.d.ts +107 -0
- package/dist/workspace/binding-store.d.ts.map +1 -0
- package/dist/workspace/binding-store.js +783 -0
- package/dist/workspace/binding-store.js.map +1 -0
- package/dist/workspace/binding.d.ts +35 -0
- package/dist/workspace/binding.d.ts.map +1 -0
- package/dist/workspace/binding.js +70 -0
- package/dist/workspace/binding.js.map +1 -0
- package/dist/workspace/errors.d.ts +4 -0
- package/dist/workspace/errors.d.ts.map +1 -0
- package/dist/workspace/errors.js +19 -0
- package/dist/workspace/errors.js.map +1 -0
- package/dist/workspace/exclusion.d.ts +21 -0
- package/dist/workspace/exclusion.d.ts.map +1 -0
- package/dist/workspace/exclusion.js +243 -0
- package/dist/workspace/exclusion.js.map +1 -0
- package/dist/workspace/index.d.ts +8 -0
- package/dist/workspace/index.d.ts.map +1 -0
- package/dist/workspace/index.js +8 -0
- package/dist/workspace/index.js.map +1 -0
- package/dist/workspace/lifecycle.d.ts +56 -0
- package/dist/workspace/lifecycle.d.ts.map +1 -0
- package/dist/workspace/lifecycle.js +94 -0
- package/dist/workspace/lifecycle.js.map +1 -0
- package/dist/workspace/manifest.d.ts +47 -0
- package/dist/workspace/manifest.d.ts.map +1 -0
- package/dist/workspace/manifest.js +243 -0
- package/dist/workspace/manifest.js.map +1 -0
- package/dist/workspace/paths.d.ts +14 -0
- package/dist/workspace/paths.d.ts.map +1 -0
- package/dist/workspace/paths.js +67 -0
- package/dist/workspace/paths.js.map +1 -0
- package/dist/workspace/schema.d.ts +15 -0
- package/dist/workspace/schema.d.ts.map +1 -0
- package/dist/workspace/schema.js +33 -0
- package/dist/workspace/schema.js.map +1 -0
- package/dist/workspace/selection-screen.d.ts +4 -0
- package/dist/workspace/selection-screen.d.ts.map +1 -0
- package/dist/workspace/selection-screen.js +216 -0
- package/dist/workspace/selection-screen.js.map +1 -0
- package/dist/workspace/selection-service.d.ts +16 -0
- package/dist/workspace/selection-service.d.ts.map +1 -0
- package/dist/workspace/selection-service.js +65 -0
- package/dist/workspace/selection-service.js.map +1 -0
- package/node_modules/@xterm/headless/README.md +31 -0
- package/node_modules/@xterm/headless/lib-headless/xterm-headless.js +2 -0
- package/node_modules/@xterm/headless/lib-headless/xterm-headless.js.map +1 -0
- package/node_modules/@xterm/headless/lib-headless/xterm-headless.mjs +46 -0
- package/node_modules/@xterm/headless/lib-headless/xterm-headless.mjs.map +7 -0
- package/node_modules/@xterm/headless/package.json +29 -0
- package/node_modules/@xterm/headless/typings/xterm-headless.d.ts +1385 -0
- package/package.json +75 -0
|
@@ -0,0 +1,685 @@
|
|
|
1
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
2
|
+
import { constants as fileConstants } from "node:fs";
|
|
3
|
+
import { chmod, lstat, mkdir, open, realpath, rename, unlink, writeFile } from "node:fs/promises";
|
|
4
|
+
import { connect, createServer } from "node:net";
|
|
5
|
+
import { isAbsolute, join, parse, resolve } from "node:path";
|
|
6
|
+
import { assertReadableSchema, assertWritableSchema } from "../workspace/schema.js";
|
|
7
|
+
import { workspaceError } from "../workspace/errors.js";
|
|
8
|
+
const META_FILE = "journal.meta.json";
|
|
9
|
+
const RECORD_FILE = "journal.ndjson";
|
|
10
|
+
const LEASE_FILE = "writer.lease";
|
|
11
|
+
export class DurableSyncJournal {
|
|
12
|
+
#directory;
|
|
13
|
+
#ownerId;
|
|
14
|
+
#fence;
|
|
15
|
+
#leaseMs;
|
|
16
|
+
#clock;
|
|
17
|
+
#authority;
|
|
18
|
+
#metadata;
|
|
19
|
+
#records;
|
|
20
|
+
#tail = Promise.resolve();
|
|
21
|
+
#closed = false;
|
|
22
|
+
#lastObservedNow;
|
|
23
|
+
constructor(input) {
|
|
24
|
+
this.#directory = input.directory;
|
|
25
|
+
this.#ownerId = input.ownerId;
|
|
26
|
+
this.#fence = input.fence;
|
|
27
|
+
this.#leaseMs = input.leaseMs;
|
|
28
|
+
this.#metadata = input.metadata;
|
|
29
|
+
this.#records = input.records;
|
|
30
|
+
this.#clock = input.clock;
|
|
31
|
+
this.#authority = input.authority;
|
|
32
|
+
this.#lastObservedNow = input.observedAt;
|
|
33
|
+
}
|
|
34
|
+
static async open(input) {
|
|
35
|
+
const leaseMs = input.leaseMs ?? 30_000;
|
|
36
|
+
const clock = input.clock ?? Date.now;
|
|
37
|
+
if (!Number.isSafeInteger(leaseMs) || leaseMs < 1)
|
|
38
|
+
throw journalFailure("invalid_lease");
|
|
39
|
+
const directory = await prepareJournalDirectory(input.directory);
|
|
40
|
+
const authority = await acquireWriterAuthority(directory);
|
|
41
|
+
let leaseOwned = false;
|
|
42
|
+
let ownerFence = 0;
|
|
43
|
+
try {
|
|
44
|
+
await assertDirectoryAuthority(directory);
|
|
45
|
+
const metadataPath = join(directory, META_FILE);
|
|
46
|
+
let metadata = await readMetadata(metadataPath, input.bindingId, input.bindingGeneration);
|
|
47
|
+
assertWritableSchema(metadata);
|
|
48
|
+
const leasePath = join(directory, LEASE_FILE);
|
|
49
|
+
const previousLease = await readOptionalJson(leasePath, validLeaseRecord);
|
|
50
|
+
const previousFence = Math.max(metadata.lastFence, previousLease?.fence ?? 0);
|
|
51
|
+
const fence = safeIncrement(previousFence, "fence_overflow");
|
|
52
|
+
const observedAt = trustedNow(clock);
|
|
53
|
+
const expiresAt = safeAdd(observedAt, leaseMs, "lease_overflow");
|
|
54
|
+
await atomicWriteJson(leasePath, {
|
|
55
|
+
ownerId: input.ownerId,
|
|
56
|
+
fence,
|
|
57
|
+
expiresAt,
|
|
58
|
+
});
|
|
59
|
+
leaseOwned = true;
|
|
60
|
+
ownerFence = fence;
|
|
61
|
+
metadata = Object.freeze({ ...metadata, lastFence: fence });
|
|
62
|
+
await atomicWriteJson(metadataPath, metadata);
|
|
63
|
+
const inspection = await inspectSyncJournal(directory);
|
|
64
|
+
if (inspection.requiresReconciliation) {
|
|
65
|
+
throw journalFailure(inspection.reason ?? "journal_untrusted");
|
|
66
|
+
}
|
|
67
|
+
const readyAt = trustedNow(clock);
|
|
68
|
+
if (readyAt < observedAt)
|
|
69
|
+
throw journalFailure("clock_rollback");
|
|
70
|
+
if (readyAt >= expiresAt)
|
|
71
|
+
throw journalFailure("lease_expired_during_open");
|
|
72
|
+
return new DurableSyncJournal({
|
|
73
|
+
directory,
|
|
74
|
+
ownerId: input.ownerId,
|
|
75
|
+
fence,
|
|
76
|
+
leaseMs,
|
|
77
|
+
metadata,
|
|
78
|
+
records: [...inspection.records],
|
|
79
|
+
clock,
|
|
80
|
+
authority,
|
|
81
|
+
observedAt: readyAt,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
const cleanupFailures = [];
|
|
86
|
+
if (leaseOwned) {
|
|
87
|
+
try {
|
|
88
|
+
await releaseLeaseFile(join(directory, LEASE_FILE), input.ownerId, ownerFence);
|
|
89
|
+
}
|
|
90
|
+
catch (cleanupError) {
|
|
91
|
+
cleanupFailures.push(cleanupError);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
try {
|
|
95
|
+
await authority.close();
|
|
96
|
+
}
|
|
97
|
+
catch (cleanupError) {
|
|
98
|
+
cleanupFailures.push(cleanupError);
|
|
99
|
+
}
|
|
100
|
+
if (cleanupFailures.length > 0) {
|
|
101
|
+
throw new AggregateError([error, ...cleanupFailures], "The journal failed to release writer authority after open failed.");
|
|
102
|
+
}
|
|
103
|
+
throw error;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
get fence() {
|
|
107
|
+
return this.#fence;
|
|
108
|
+
}
|
|
109
|
+
get metadata() {
|
|
110
|
+
return Object.freeze({
|
|
111
|
+
schemaVersion: this.#metadata.schemaVersion,
|
|
112
|
+
minimumReaderVersion: this.#metadata.minimumReaderVersion,
|
|
113
|
+
minimumWriterVersion: this.#metadata.minimumWriterVersion,
|
|
114
|
+
bindingId: this.#metadata.bindingId,
|
|
115
|
+
bindingGeneration: this.#metadata.bindingGeneration,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
get records() {
|
|
119
|
+
return Object.freeze([...this.#records]);
|
|
120
|
+
}
|
|
121
|
+
async renew() {
|
|
122
|
+
await this.#serialized(async () => {
|
|
123
|
+
await this.#assertLease();
|
|
124
|
+
const now = this.#trustedNow();
|
|
125
|
+
await atomicWriteJson(join(this.#directory, LEASE_FILE), {
|
|
126
|
+
ownerId: this.#ownerId,
|
|
127
|
+
fence: this.#fence,
|
|
128
|
+
expiresAt: safeAdd(now, this.#leaseMs, "lease_overflow"),
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
async append(intent) {
|
|
133
|
+
let result;
|
|
134
|
+
await this.#serialized(async () => {
|
|
135
|
+
validateIntent(intent);
|
|
136
|
+
const sameOperation = this.#records.filter((record) => record.operationId === intent.operationId);
|
|
137
|
+
const intentHash = hashIntent(intent);
|
|
138
|
+
if (sameOperation.some((record) => record.intentHash !== intentHash)) {
|
|
139
|
+
throw workspaceError("idempotency_conflict", "The operation identifier was reused for a different intent.", "conflict", "operation_id_reuse");
|
|
140
|
+
}
|
|
141
|
+
const existing = sameOperation.at(-1);
|
|
142
|
+
if (existing !== undefined) {
|
|
143
|
+
result = existing;
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
result = await this.#appendRecord(intent, "queued", intentHash);
|
|
147
|
+
});
|
|
148
|
+
if (result === undefined)
|
|
149
|
+
throw journalFailure("append_incomplete");
|
|
150
|
+
return result;
|
|
151
|
+
}
|
|
152
|
+
async transition(operationId, state) {
|
|
153
|
+
let result;
|
|
154
|
+
await this.#serialized(async () => {
|
|
155
|
+
const latest = [...this.#records].reverse().find((record) => record.operationId === operationId);
|
|
156
|
+
if (latest === undefined)
|
|
157
|
+
throw journalFailure("operation_unknown");
|
|
158
|
+
if (latest.state === state) {
|
|
159
|
+
result = latest;
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
if (!allowedTransition(latest.state, state))
|
|
163
|
+
throw journalFailure("invalid_transition");
|
|
164
|
+
result = await this.#appendRecord(latest, state, latest.intentHash);
|
|
165
|
+
});
|
|
166
|
+
if (result === undefined)
|
|
167
|
+
throw journalFailure("transition_incomplete");
|
|
168
|
+
return result;
|
|
169
|
+
}
|
|
170
|
+
async close() {
|
|
171
|
+
await this.#serialized(async () => {
|
|
172
|
+
const failures = [];
|
|
173
|
+
try {
|
|
174
|
+
await releaseLeaseFile(join(this.#directory, LEASE_FILE), this.#ownerId, this.#fence);
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
failures.push(error);
|
|
178
|
+
}
|
|
179
|
+
try {
|
|
180
|
+
await this.#authority.close();
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
failures.push(error);
|
|
184
|
+
}
|
|
185
|
+
this.#closed = true;
|
|
186
|
+
if (failures.length > 0)
|
|
187
|
+
throw new AggregateError(failures, "The journal failed to release writer authority.");
|
|
188
|
+
}, true);
|
|
189
|
+
}
|
|
190
|
+
async #appendRecord(intent, state, intentHash) {
|
|
191
|
+
await this.#assertLease();
|
|
192
|
+
const previousChecksum = this.#records.at(-1)?.checksum ?? "0".repeat(64);
|
|
193
|
+
const body = {
|
|
194
|
+
operationId: intent.operationId,
|
|
195
|
+
baseGeneration: intent.baseGeneration,
|
|
196
|
+
digest: intent.digest,
|
|
197
|
+
byteLength: intent.byteLength,
|
|
198
|
+
recordSequence: this.#records.length + 1,
|
|
199
|
+
fence: this.#fence,
|
|
200
|
+
state,
|
|
201
|
+
intentHash,
|
|
202
|
+
previousChecksum,
|
|
203
|
+
};
|
|
204
|
+
const record = Object.freeze({ ...body, checksum: hashRecord(body) });
|
|
205
|
+
await assertDirectoryAuthority(this.#directory);
|
|
206
|
+
const handle = await openSecureAppendFile(join(this.#directory, RECORD_FILE));
|
|
207
|
+
try {
|
|
208
|
+
await handle.writeFile(`${JSON.stringify(record)}\n`, "utf8");
|
|
209
|
+
await handle.sync();
|
|
210
|
+
}
|
|
211
|
+
finally {
|
|
212
|
+
await handle.close();
|
|
213
|
+
}
|
|
214
|
+
this.#records.push(record);
|
|
215
|
+
return record;
|
|
216
|
+
}
|
|
217
|
+
async #assertLease() {
|
|
218
|
+
if (this.#closed)
|
|
219
|
+
throw journalFailure("writer_closed");
|
|
220
|
+
await assertDirectoryAuthority(this.#directory);
|
|
221
|
+
const lease = await readJson(join(this.#directory, LEASE_FILE), validLeaseRecord);
|
|
222
|
+
if (lease.ownerId !== this.#ownerId ||
|
|
223
|
+
lease.fence !== this.#fence ||
|
|
224
|
+
!Number.isSafeInteger(lease.expiresAt) ||
|
|
225
|
+
lease.expiresAt <= this.#trustedNow()) {
|
|
226
|
+
throw workspaceError("writer_fenced", "The journal writer lease has been fenced.", "conflict", "stale_fence");
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
#trustedNow() {
|
|
230
|
+
const now = trustedNow(this.#clock);
|
|
231
|
+
if (now < this.#lastObservedNow)
|
|
232
|
+
throw journalFailure("clock_rollback");
|
|
233
|
+
this.#lastObservedNow = now;
|
|
234
|
+
return now;
|
|
235
|
+
}
|
|
236
|
+
async #serialized(action, allowClosed = false) {
|
|
237
|
+
const run = this.#tail.then(async () => {
|
|
238
|
+
if (this.#closed && !allowClosed)
|
|
239
|
+
throw journalFailure("writer_closed");
|
|
240
|
+
await action();
|
|
241
|
+
});
|
|
242
|
+
this.#tail = run.catch(() => undefined);
|
|
243
|
+
await run;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
async function prepareJournalDirectory(directory) {
|
|
247
|
+
if (!isAbsolute(directory) || directory.includes("\0"))
|
|
248
|
+
throw journalFailure("directory_untrusted");
|
|
249
|
+
const requested = resolve(directory);
|
|
250
|
+
const parsed = parse(requested);
|
|
251
|
+
let current = parsed.root;
|
|
252
|
+
for (const component of requested.slice(parsed.root.length).split(/[\\/]+/u).filter(Boolean)) {
|
|
253
|
+
current = join(current, component);
|
|
254
|
+
try {
|
|
255
|
+
await assertPlainDirectory(current);
|
|
256
|
+
}
|
|
257
|
+
catch (error) {
|
|
258
|
+
if (error.code !== "ENOENT")
|
|
259
|
+
throw error;
|
|
260
|
+
try {
|
|
261
|
+
await mkdir(current, { mode: 0o700 });
|
|
262
|
+
}
|
|
263
|
+
catch (mkdirError) {
|
|
264
|
+
if (mkdirError.code !== "EEXIST")
|
|
265
|
+
throw mkdirError;
|
|
266
|
+
}
|
|
267
|
+
await assertPlainDirectory(current);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
const canonical = await realpath(requested);
|
|
271
|
+
if (!samePath(canonical, requested))
|
|
272
|
+
throw journalFailure("directory_untrusted");
|
|
273
|
+
await chmod(canonical, 0o700);
|
|
274
|
+
return canonical;
|
|
275
|
+
}
|
|
276
|
+
async function assertPlainDirectory(path) {
|
|
277
|
+
const entry = await lstat(path);
|
|
278
|
+
if (!entry.isDirectory() || entry.isSymbolicLink())
|
|
279
|
+
throw journalFailure("directory_untrusted");
|
|
280
|
+
const canonical = await realpath(path);
|
|
281
|
+
if (!samePath(canonical, resolve(path)))
|
|
282
|
+
throw journalFailure("directory_untrusted");
|
|
283
|
+
}
|
|
284
|
+
async function assertDirectoryAuthority(directory) {
|
|
285
|
+
await assertPlainDirectory(directory);
|
|
286
|
+
}
|
|
287
|
+
function samePath(left, right) {
|
|
288
|
+
const normalizedLeft = resolve(left);
|
|
289
|
+
const normalizedRight = resolve(right);
|
|
290
|
+
return process.platform === "win32"
|
|
291
|
+
? normalizedLeft.toLowerCase() === normalizedRight.toLowerCase()
|
|
292
|
+
: normalizedLeft === normalizedRight;
|
|
293
|
+
}
|
|
294
|
+
function trustedNow(clock) {
|
|
295
|
+
const now = clock();
|
|
296
|
+
if (!Number.isSafeInteger(now) || now < 0)
|
|
297
|
+
throw journalFailure("clock_untrusted");
|
|
298
|
+
return now;
|
|
299
|
+
}
|
|
300
|
+
export async function inspectSyncJournal(directory) {
|
|
301
|
+
const canonical = resolve(directory);
|
|
302
|
+
await assertDirectoryAuthority(canonical);
|
|
303
|
+
const metadata = await readJson(join(canonical, META_FILE));
|
|
304
|
+
try {
|
|
305
|
+
assertReadableSchema(metadata);
|
|
306
|
+
}
|
|
307
|
+
catch {
|
|
308
|
+
return Object.freeze({
|
|
309
|
+
metadata,
|
|
310
|
+
records: Object.freeze([]),
|
|
311
|
+
requiresReconciliation: true,
|
|
312
|
+
reason: "schema_incompatible",
|
|
313
|
+
recoveryActions: Object.freeze([]),
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
let text = "";
|
|
317
|
+
try {
|
|
318
|
+
text = await readSecureTextFile(join(canonical, RECORD_FILE));
|
|
319
|
+
}
|
|
320
|
+
catch (error) {
|
|
321
|
+
if (error.code !== "ENOENT")
|
|
322
|
+
throw error;
|
|
323
|
+
}
|
|
324
|
+
const records = [];
|
|
325
|
+
const latestByOperation = new Map();
|
|
326
|
+
let previousChecksum = "0".repeat(64);
|
|
327
|
+
let previousFence = 0;
|
|
328
|
+
for (const [index, line] of text.split("\n").filter(Boolean).entries()) {
|
|
329
|
+
try {
|
|
330
|
+
const record = JSON.parse(line);
|
|
331
|
+
const { checksum, ...body } = record;
|
|
332
|
+
const previousOperation = latestByOperation.get(record.operationId);
|
|
333
|
+
if (!validRecordShape(record) ||
|
|
334
|
+
record.recordSequence !== index + 1 ||
|
|
335
|
+
record.previousChecksum !== previousChecksum ||
|
|
336
|
+
hashRecord(body) !== checksum ||
|
|
337
|
+
record.intentHash !== hashIntent(record) ||
|
|
338
|
+
record.fence < previousFence ||
|
|
339
|
+
record.fence > metadata.lastFence ||
|
|
340
|
+
(previousOperation === undefined
|
|
341
|
+
? record.state !== "queued"
|
|
342
|
+
: previousOperation.intentHash !== record.intentHash || !allowedTransition(previousOperation.state, record.state))) {
|
|
343
|
+
throw new Error("invalid chain");
|
|
344
|
+
}
|
|
345
|
+
validateIntent(record);
|
|
346
|
+
records.push(Object.freeze(record));
|
|
347
|
+
latestByOperation.set(record.operationId, record);
|
|
348
|
+
previousChecksum = checksum;
|
|
349
|
+
previousFence = record.fence;
|
|
350
|
+
}
|
|
351
|
+
catch {
|
|
352
|
+
return Object.freeze({
|
|
353
|
+
metadata,
|
|
354
|
+
records: Object.freeze(records),
|
|
355
|
+
requiresReconciliation: true,
|
|
356
|
+
reason: "checksum_or_sequence_gap",
|
|
357
|
+
recoveryActions: Object.freeze([]),
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
const latest = new Map();
|
|
362
|
+
for (const record of records)
|
|
363
|
+
latest.set(record.operationId, record);
|
|
364
|
+
const recoveryActions = [...latest.values()]
|
|
365
|
+
.sort((left, right) => left.recordSequence - right.recordSequence)
|
|
366
|
+
.map((record) => Object.freeze({
|
|
367
|
+
operationId: record.operationId,
|
|
368
|
+
action: recoveryAction(record.state),
|
|
369
|
+
}));
|
|
370
|
+
return Object.freeze({
|
|
371
|
+
metadata,
|
|
372
|
+
records: Object.freeze(records),
|
|
373
|
+
requiresReconciliation: false,
|
|
374
|
+
recoveryActions: Object.freeze(recoveryActions),
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
export function exportJournalRecoveryMetadata(inspection) {
|
|
378
|
+
return Object.freeze({
|
|
379
|
+
schemaVersion: inspection.metadata.schemaVersion,
|
|
380
|
+
bindingId: inspection.metadata.bindingId,
|
|
381
|
+
bindingGeneration: inspection.metadata.bindingGeneration,
|
|
382
|
+
requiresReconciliation: inspection.requiresReconciliation,
|
|
383
|
+
reason: inspection.reason ?? null,
|
|
384
|
+
operations: inspection.recoveryActions,
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
async function readMetadata(path, bindingId, bindingGeneration) {
|
|
388
|
+
try {
|
|
389
|
+
const metadata = await readJson(path);
|
|
390
|
+
if (metadata.bindingId !== bindingId || metadata.bindingGeneration !== bindingGeneration) {
|
|
391
|
+
throw workspaceError("journal_identity", "The journal belongs to another binding generation.", "policy", "identity_mismatch");
|
|
392
|
+
}
|
|
393
|
+
return metadata;
|
|
394
|
+
}
|
|
395
|
+
catch (error) {
|
|
396
|
+
if (error.code !== "ENOENT")
|
|
397
|
+
throw error;
|
|
398
|
+
const metadata = Object.freeze({
|
|
399
|
+
schemaVersion: 2,
|
|
400
|
+
minimumReaderVersion: 1,
|
|
401
|
+
minimumWriterVersion: 2,
|
|
402
|
+
bindingId,
|
|
403
|
+
bindingGeneration,
|
|
404
|
+
lastFence: 0,
|
|
405
|
+
});
|
|
406
|
+
await atomicWriteJson(path, metadata);
|
|
407
|
+
return metadata;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
async function releaseLeaseFile(path, ownerId, fence) {
|
|
411
|
+
try {
|
|
412
|
+
const current = await readJson(path, validLeaseRecord);
|
|
413
|
+
if (current.ownerId !== ownerId || current.fence !== fence)
|
|
414
|
+
return;
|
|
415
|
+
await unlink(path);
|
|
416
|
+
}
|
|
417
|
+
catch (error) {
|
|
418
|
+
if (error.code !== "ENOENT")
|
|
419
|
+
throw error;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
async function atomicWriteJson(path, value) {
|
|
423
|
+
const temporary = `${path}.${process.pid}.${randomUUID()}.tmp`;
|
|
424
|
+
await assertSafeExistingFile(path, true);
|
|
425
|
+
try {
|
|
426
|
+
await writeFile(temporary, JSON.stringify(value), { encoding: "utf8", mode: 0o600, flag: "wx" });
|
|
427
|
+
await assertSafeExistingFile(temporary, false);
|
|
428
|
+
await rename(temporary, path);
|
|
429
|
+
await chmod(path, 0o600);
|
|
430
|
+
}
|
|
431
|
+
catch (error) {
|
|
432
|
+
await unlink(temporary).catch(() => undefined);
|
|
433
|
+
throw error;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
async function readJson(path, validate) {
|
|
437
|
+
const value = JSON.parse(await readSecureTextFile(path));
|
|
438
|
+
if (validate !== undefined && !validate(value))
|
|
439
|
+
throw journalFailure("file_shape_untrusted");
|
|
440
|
+
return value;
|
|
441
|
+
}
|
|
442
|
+
async function readOptionalJson(path, validate) {
|
|
443
|
+
try {
|
|
444
|
+
return await readJson(path, validate);
|
|
445
|
+
}
|
|
446
|
+
catch (error) {
|
|
447
|
+
if (error.code === "ENOENT")
|
|
448
|
+
return undefined;
|
|
449
|
+
throw error;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
async function readSecureTextFile(path) {
|
|
453
|
+
await assertSafeExistingFile(path, false);
|
|
454
|
+
const handle = await open(path, fileConstants.O_RDONLY | noFollowFlag());
|
|
455
|
+
try {
|
|
456
|
+
await assertSecureHandle(handle, path);
|
|
457
|
+
return await handle.readFile("utf8");
|
|
458
|
+
}
|
|
459
|
+
finally {
|
|
460
|
+
await handle.close();
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
async function openSecureAppendFile(path) {
|
|
464
|
+
let handle;
|
|
465
|
+
try {
|
|
466
|
+
handle = await open(path, fileConstants.O_APPEND | fileConstants.O_CREAT | fileConstants.O_EXCL | fileConstants.O_WRONLY | noFollowFlag(), 0o600);
|
|
467
|
+
}
|
|
468
|
+
catch (error) {
|
|
469
|
+
if (error.code !== "EEXIST")
|
|
470
|
+
throw error;
|
|
471
|
+
await assertSafeExistingFile(path, false);
|
|
472
|
+
handle = await open(path, fileConstants.O_APPEND | fileConstants.O_WRONLY | noFollowFlag(), 0o600);
|
|
473
|
+
}
|
|
474
|
+
try {
|
|
475
|
+
await assertSecureHandle(handle, path);
|
|
476
|
+
return handle;
|
|
477
|
+
}
|
|
478
|
+
catch (error) {
|
|
479
|
+
await handle.close();
|
|
480
|
+
throw error;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
async function assertSafeExistingFile(path, allowMissing) {
|
|
484
|
+
try {
|
|
485
|
+
const entry = await lstat(path);
|
|
486
|
+
if (!entry.isFile() || entry.isSymbolicLink() || entry.nlink !== 1)
|
|
487
|
+
throw journalFailure("file_untrusted");
|
|
488
|
+
}
|
|
489
|
+
catch (error) {
|
|
490
|
+
if (allowMissing && error.code === "ENOENT")
|
|
491
|
+
return;
|
|
492
|
+
throw error;
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
async function assertSecureHandle(handle, path) {
|
|
496
|
+
const entry = await handle.stat();
|
|
497
|
+
if (!entry.isFile() || entry.nlink !== 1)
|
|
498
|
+
throw journalFailure("file_untrusted");
|
|
499
|
+
const linked = await lstat(path);
|
|
500
|
+
if (!linked.isFile() || linked.isSymbolicLink() || linked.nlink !== 1)
|
|
501
|
+
throw journalFailure("file_untrusted");
|
|
502
|
+
if (typeof entry.dev === "number" && typeof linked.dev === "number" && (entry.dev !== linked.dev || entry.ino !== linked.ino)) {
|
|
503
|
+
throw journalFailure("file_identity_changed");
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
function noFollowFlag() {
|
|
507
|
+
return typeof fileConstants.O_NOFOLLOW === "number" ? fileConstants.O_NOFOLLOW : 0;
|
|
508
|
+
}
|
|
509
|
+
async function acquireWriterAuthority(directory) {
|
|
510
|
+
const canonicalIdentity = process.platform === "win32" ? directory.toLowerCase() : directory;
|
|
511
|
+
const digest = createHash("sha256")
|
|
512
|
+
.update("cuna-journal-authority-v2\0")
|
|
513
|
+
.update(canonicalIdentity)
|
|
514
|
+
.digest("hex");
|
|
515
|
+
// Windows reserves dynamic TCP port ranges for system services. Deriving a
|
|
516
|
+
// lock port from a directory hash can therefore fail with EACCES even when
|
|
517
|
+
// no peer owns the journal. A named pipe is kernel-owned, directory-scoped,
|
|
518
|
+
// and released automatically when the process exits.
|
|
519
|
+
const endpoints = process.platform === "win32"
|
|
520
|
+
? [`\\\\.\\pipe\\cuna-workspace-journal-${digest}`]
|
|
521
|
+
: Array.from({ length: 4 }, (_, attempt) => Object.freeze({
|
|
522
|
+
host: "127.0.0.1",
|
|
523
|
+
// A single deterministic TCP port can collide with an unrelated
|
|
524
|
+
// workspace test. The ordered candidate set remains identical for one
|
|
525
|
+
// journal across processes, while making that unrelated collision a
|
|
526
|
+
// recoverable selection event instead of a false busy result.
|
|
527
|
+
port: 20_000 + Number.parseInt(digest.slice(attempt * 4, attempt * 4 + 4), 16) % 40_000,
|
|
528
|
+
exclusive: true,
|
|
529
|
+
}));
|
|
530
|
+
let server;
|
|
531
|
+
for (const endpoint of endpoints) {
|
|
532
|
+
const candidate = createServer((socket) => socket.end(digest));
|
|
533
|
+
try {
|
|
534
|
+
await new Promise((resolveListen, rejectListen) => {
|
|
535
|
+
const onError = (error) => {
|
|
536
|
+
candidate.removeListener("listening", onListening);
|
|
537
|
+
rejectListen(error);
|
|
538
|
+
};
|
|
539
|
+
const onListening = () => {
|
|
540
|
+
candidate.removeListener("error", onError);
|
|
541
|
+
resolveListen();
|
|
542
|
+
};
|
|
543
|
+
candidate.once("error", onError);
|
|
544
|
+
candidate.once("listening", onListening);
|
|
545
|
+
candidate.listen(endpoint);
|
|
546
|
+
});
|
|
547
|
+
server = candidate;
|
|
548
|
+
break;
|
|
549
|
+
}
|
|
550
|
+
catch (error) {
|
|
551
|
+
if (error.code !== "EADDRINUSE")
|
|
552
|
+
throw error;
|
|
553
|
+
// Falling back is safe only when a peer positively identifies itself as
|
|
554
|
+
// a different journal. A legacy listener or arbitrary process that
|
|
555
|
+
// owns the port remains a fail-closed busy result; otherwise a new
|
|
556
|
+
// writer could bypass a live older writer for the same directory.
|
|
557
|
+
if (process.platform === "win32" || typeof endpoint === "string")
|
|
558
|
+
break;
|
|
559
|
+
const owner = await new Promise((resolveOwner) => {
|
|
560
|
+
const peer = connect(endpoint);
|
|
561
|
+
let response = "";
|
|
562
|
+
let settled = false;
|
|
563
|
+
const finish = (result) => {
|
|
564
|
+
if (settled)
|
|
565
|
+
return;
|
|
566
|
+
settled = true;
|
|
567
|
+
peer.destroy();
|
|
568
|
+
resolveOwner(result);
|
|
569
|
+
};
|
|
570
|
+
peer.setEncoding("utf8");
|
|
571
|
+
peer.setTimeout(250, () => finish("unknown"));
|
|
572
|
+
peer.on("data", (chunk) => {
|
|
573
|
+
response += chunk;
|
|
574
|
+
if (response.length > digest.length)
|
|
575
|
+
finish("unknown");
|
|
576
|
+
});
|
|
577
|
+
peer.once("end", () => finish(response === digest ? "same" : /^[a-f0-9]{64}$/u.test(response) ? "other" : "unknown"));
|
|
578
|
+
peer.once("error", () => finish("unknown"));
|
|
579
|
+
});
|
|
580
|
+
if (owner !== "other")
|
|
581
|
+
break;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
if (server === undefined) {
|
|
585
|
+
throw workspaceError("workspace_busy", "Another process owns the workspace journal.", "conflict", "active_writer");
|
|
586
|
+
}
|
|
587
|
+
let closed = false;
|
|
588
|
+
return Object.freeze({
|
|
589
|
+
server,
|
|
590
|
+
close: async () => {
|
|
591
|
+
if (closed)
|
|
592
|
+
return;
|
|
593
|
+
await new Promise((resolveClose, rejectClose) => {
|
|
594
|
+
server.close((error) => error === undefined ? resolveClose() : rejectClose(error));
|
|
595
|
+
});
|
|
596
|
+
closed = true;
|
|
597
|
+
},
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
function validLeaseRecord(value) {
|
|
601
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
602
|
+
return false;
|
|
603
|
+
const record = value;
|
|
604
|
+
const keys = Object.keys(record).sort();
|
|
605
|
+
return keys.length === 3 && keys[0] === "expiresAt" && keys[1] === "fence" && keys[2] === "ownerId" &&
|
|
606
|
+
typeof record.ownerId === "string" && record.ownerId.length > 0 && record.ownerId.length <= 256 &&
|
|
607
|
+
Number.isSafeInteger(record.fence) && record.fence >= 1 &&
|
|
608
|
+
Number.isSafeInteger(record.expiresAt) && record.expiresAt >= 0;
|
|
609
|
+
}
|
|
610
|
+
function safeIncrement(value, reason) {
|
|
611
|
+
return safeAdd(value, 1, reason);
|
|
612
|
+
}
|
|
613
|
+
function safeAdd(left, right, reason) {
|
|
614
|
+
if (!Number.isSafeInteger(left) || !Number.isSafeInteger(right) || left < 0 || right < 0 || left > Number.MAX_SAFE_INTEGER - right) {
|
|
615
|
+
throw journalFailure(reason);
|
|
616
|
+
}
|
|
617
|
+
return left + right;
|
|
618
|
+
}
|
|
619
|
+
function validateIntent(intent) {
|
|
620
|
+
if (intent.operationId.length === 0 ||
|
|
621
|
+
!Number.isSafeInteger(intent.baseGeneration) ||
|
|
622
|
+
intent.baseGeneration < 0 ||
|
|
623
|
+
!Number.isSafeInteger(intent.byteLength) ||
|
|
624
|
+
intent.byteLength < 0 ||
|
|
625
|
+
!/^[a-f0-9]{64}$/u.test(intent.digest))
|
|
626
|
+
throw journalFailure("invalid_intent");
|
|
627
|
+
}
|
|
628
|
+
function allowedTransition(from, to) {
|
|
629
|
+
const allowed = {
|
|
630
|
+
queued: ["sending", "conflicted"],
|
|
631
|
+
sending: ["uncertain", "acknowledged", "conflicted"],
|
|
632
|
+
uncertain: ["acknowledged", "conflicted"],
|
|
633
|
+
acknowledged: ["applied", "conflicted"],
|
|
634
|
+
applied: [],
|
|
635
|
+
conflicted: [],
|
|
636
|
+
};
|
|
637
|
+
return allowed[from].includes(to);
|
|
638
|
+
}
|
|
639
|
+
function recoveryAction(state) {
|
|
640
|
+
if (state === "queued")
|
|
641
|
+
return "send";
|
|
642
|
+
if (state === "sending" || state === "uncertain")
|
|
643
|
+
return "query_outcome";
|
|
644
|
+
if (state === "acknowledged")
|
|
645
|
+
return "apply_receipt";
|
|
646
|
+
return "none";
|
|
647
|
+
}
|
|
648
|
+
function hashIntent(intent) {
|
|
649
|
+
return createHash("sha256")
|
|
650
|
+
.update("cuna-journal-intent-v2\0")
|
|
651
|
+
.update(JSON.stringify({
|
|
652
|
+
baseGeneration: intent.baseGeneration,
|
|
653
|
+
byteLength: intent.byteLength,
|
|
654
|
+
digest: intent.digest,
|
|
655
|
+
operationId: intent.operationId,
|
|
656
|
+
}))
|
|
657
|
+
.digest("hex");
|
|
658
|
+
}
|
|
659
|
+
function validRecordShape(record) {
|
|
660
|
+
if (record === null || typeof record !== "object")
|
|
661
|
+
return false;
|
|
662
|
+
const keys = Object.keys(record).sort();
|
|
663
|
+
const expected = [
|
|
664
|
+
"baseGeneration", "byteLength", "checksum", "digest", "fence", "intentHash",
|
|
665
|
+
"operationId", "previousChecksum", "recordSequence", "state",
|
|
666
|
+
];
|
|
667
|
+
return (keys.length === expected.length &&
|
|
668
|
+
keys.every((key, index) => key === expected[index]) &&
|
|
669
|
+
Number.isSafeInteger(record.recordSequence) && record.recordSequence >= 1 &&
|
|
670
|
+
Number.isSafeInteger(record.fence) && record.fence >= 1 &&
|
|
671
|
+
/^[a-f0-9]{64}$/u.test(record.intentHash) &&
|
|
672
|
+
/^[a-f0-9]{64}$/u.test(record.previousChecksum) &&
|
|
673
|
+
/^[a-f0-9]{64}$/u.test(record.checksum) &&
|
|
674
|
+
["queued", "sending", "uncertain", "acknowledged", "applied", "conflicted"].includes(record.state));
|
|
675
|
+
}
|
|
676
|
+
function hashRecord(body) {
|
|
677
|
+
return createHash("sha256")
|
|
678
|
+
.update("cuna-journal-record-v2\0")
|
|
679
|
+
.update(JSON.stringify(body))
|
|
680
|
+
.digest("hex");
|
|
681
|
+
}
|
|
682
|
+
function journalFailure(reason) {
|
|
683
|
+
return workspaceError("journal_invalid", "The durable sync journal cannot be safely used.", "integrity", reason);
|
|
684
|
+
}
|
|
685
|
+
//# sourceMappingURL=journal.js.map
|