@fased/fased 0.1.61 → 0.1.64
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/CHANGELOG.md +43 -0
- package/README.md +38 -30
- package/config/dependency-ownership.json +1 -1
- package/config/signer-policies/README.md +49 -0
- package/config/signer-policies/agent.json.template +32 -0
- package/config/signer-policies/mining.json.template +69 -0
- package/config/signer-policies/network.json.template +5 -0
- package/config/signer-policies/vault.json.template +70 -0
- package/config/signer-protocol-v2.json +76 -0
- package/config/typescript-noemit-baseline.json +680 -0
- package/dist/acp/client.js +2 -2
- package/dist/acp/secret-file.js +2 -2
- package/dist/agents/agent-scope.js +2 -2
- package/dist/agents/apply-patch.js +8 -8
- package/dist/agents/auth-profiles/paths.js +2 -2
- package/dist/agents/auth-profiles/store.js +269 -33
- package/dist/agents/bash-tools.exec.js +10 -4
- package/dist/agents/bash-tools.shared.js +2 -2
- package/dist/agents/cli-credentials.js +4 -4
- package/dist/agents/current-model-catalog.js +3 -3
- package/dist/agents/docs-path.js +3 -3
- package/dist/agents/embedded-pi-mcp.js +4 -4
- package/dist/agents/identity-avatar.js +3 -3
- package/dist/agents/identity-file.js +2 -2
- package/dist/agents/memory-search.js +7 -1
- package/dist/agents/model-catalog-access.js +1 -2
- package/dist/agents/model-catalog-snapshot.js +1 -1
- package/dist/agents/model-catalog-source.js +1 -1
- package/dist/agents/model-metadata.js +1 -1
- package/dist/agents/model-selection.js +2 -28
- package/dist/agents/models-config.providers.js +6 -6
- package/dist/agents/openai-codex-app-server.js +5 -5
- package/dist/agents/pi-embedded-runner/compact.js +15 -7
- package/dist/agents/pi-embedded-runner/model.js +1 -1
- package/dist/agents/pi-embedded-runner/run/attempt.js +24 -13
- package/dist/agents/pi-embedded-runner/run.js +2 -0
- package/dist/agents/pi-embedded-runner/tool-split.js +40 -2
- package/dist/agents/pi-embedded-subscribe.raw-stream.js +3 -3
- package/dist/agents/pi-extensions/compaction-safeguard.js +3 -3
- package/dist/agents/pi-model-discovery.js +6 -6
- package/dist/agents/pi-project-settings.js +3 -3
- package/dist/agents/pi-tool-definition-adapter.js +16 -1
- package/dist/agents/pi-tools.js +2 -1
- package/dist/agents/sandbox/config.js +1 -1
- package/dist/agents/sandbox/context.js +27 -2
- package/dist/agents/sandbox/fs-bridge.js +2 -2
- package/dist/agents/session-dirs.js +4 -4
- package/dist/agents/session-write-lock.js +13 -13
- package/dist/agents/shell-utils.js +5 -5
- package/dist/agents/skills/bundled-dir.js +4 -4
- package/dist/agents/skills/env-overrides.js +38 -28
- package/dist/agents/skills/local-loader.js +6 -6
- package/dist/agents/skills/plugin-skills.js +2 -2
- package/dist/agents/skills/trust.js +93 -0
- package/dist/agents/skills/workspace.js +141 -13
- package/dist/agents/skills-clawhub.js +36 -11
- package/dist/agents/skills-install-download.js +7 -7
- package/dist/agents/skills-install-plan.js +2 -2
- package/dist/agents/skills-install.js +2 -2
- package/dist/agents/skills-marketplace-scan.js +49 -0
- package/dist/agents/skills-status.js +2 -2
- package/dist/agents/subagent-depth.js +2 -2
- package/dist/agents/system-prompt-params.js +2 -2
- package/dist/agents/tools/marketplace-offer-draft-tool.js +1 -1
- package/dist/agents/tools/mining-tool.js +1 -1
- package/dist/agents/tools/session-status-tool.js +1 -1
- package/dist/agents/tools/wallet-action-tool.js +172 -36
- package/dist/agents/tools/wallet-skill-policy.js +65 -23
- package/dist/agents/tools/wallet-tool.js +7 -11
- package/dist/agents/workspace.js +22 -22
- package/dist/auto-reply/reply/agent-runner-execution.js +2 -2
- package/dist/auto-reply/reply/agent-runner.js +2 -2
- package/dist/auto-reply/reply/commands-export-session.js +7 -7
- package/dist/auto-reply/reply/directive-handling.fast-lane.js +2 -1
- package/dist/auto-reply/reply/directive-handling.impl.js +2 -1
- package/dist/auto-reply/reply/directive-handling.model.js +2 -1
- package/dist/auto-reply/reply/directive-handling.persist.js +2 -2
- package/dist/auto-reply/reply/get-reply-directives-apply.js +2 -0
- package/dist/auto-reply/reply/get-reply-inline-actions.js +25 -1
- package/dist/auto-reply/reply/model-selection.js +7 -4
- package/dist/auto-reply/reply/post-compaction-audit.js +3 -3
- package/dist/auto-reply/reply/post-compaction-context.js +3 -3
- package/dist/auto-reply/reply/session-reset-model.js +4 -4
- package/dist/auto-reply/reply/session.js +3 -3
- package/dist/auto-reply/skill-commands.js +3 -3
- package/dist/auto-reply/status.js +6 -6
- package/dist/brand.js +1 -1
- package/dist/browser/chrome.executables.js +3 -3
- package/dist/browser/chrome.js +3 -3
- package/dist/browser/chrome.profile-decoration.js +6 -6
- package/dist/browser/profiles-service.js +2 -2
- package/dist/browser/server-context.js +2 -2
- package/dist/browser/trash.js +4 -4
- package/dist/build-info.json +3 -3
- package/dist/canvas-host/a2ui/.bundle.hash +1 -1
- package/dist/canvas-host/server.js +4 -4
- package/dist/capabilities/catalog.js +3 -3
- package/dist/channel-web.js +2 -2
- package/dist/channels/plugins/catalog.js +3 -3
- package/dist/cli/browser-cli-extension.js +6 -6
- package/dist/cli/command-format.js +2 -2
- package/dist/cli/cron-cli/register.cron-simple.js +2 -2
- package/dist/cli/dns-cli.js +9 -9
- package/dist/cli/gateway-cli/dev.js +5 -5
- package/dist/cli/gateway-cli/run.js +10 -2
- package/dist/cli/hooks-cli.js +5 -5
- package/dist/cli/lightweight/gateway-runtime-probe.js +2 -2
- package/dist/cli/memory-cli.js +7 -7
- package/dist/cli/nodes-media-utils.js +2 -2
- package/dist/cli/plugins-cli.js +2 -2
- package/dist/cli/program/command-registry.js +1 -1
- package/dist/cli/program/register.onboard.js +2 -3
- package/dist/cli/program/register.wallet.js +16 -123
- package/dist/cli/providers-cli.js +1 -1
- package/dist/cli/sat-cli.js +129 -2
- package/dist/cli/secrets-cli.js +3 -3
- package/dist/cli/update-cli/update-command.js +260 -11
- package/dist/cli/windows-argv.js +2 -2
- package/dist/commands/auth-choice.apply.api-providers.js +3 -3
- package/dist/commands/dashboard-link.js +3 -3
- package/dist/commands/doctor-config-flow.js +1 -1
- package/dist/commands/doctor-install.js +5 -5
- package/dist/commands/doctor-legacy-config.js +2 -13
- package/dist/commands/doctor-memory-search.js +2 -2
- package/dist/commands/doctor-platform-notes.js +2 -2
- package/dist/commands/doctor-sandbox.js +2 -2
- package/dist/commands/doctor-state-integrity.js +23 -23
- package/dist/commands/doctor-workspace.js +3 -3
- package/dist/commands/doctor.js +3 -3
- package/dist/commands/managed-up.js +2 -2
- package/dist/commands/model-picker.js +6 -6
- package/dist/commands/models/auth.js +1 -1
- package/dist/commands/onboard-auth.config-gateways.js +1 -1
- package/dist/commands/onboard-auth.credentials.js +35 -11
- package/dist/commands/onboard-non-interactive/local/wallet-config.js +28 -27
- package/dist/commands/onboard-non-interactive/local.js +5 -1
- package/dist/commands/onboarding/plugin-install.js +2 -2
- package/dist/commands/sessions-cleanup.js +2 -2
- package/dist/commands/signal-install.js +6 -6
- package/dist/commands/status-all/channels.js +2 -2
- package/dist/commands/wallet.js +570 -1913
- package/dist/config/cache-utils.js +2 -2
- package/dist/config/config.js +2 -2
- package/dist/config/includes.js +5 -5
- package/dist/config/io.js +66 -4
- package/dist/config/paths.js +3 -3
- package/dist/config/sat-runtime-ids.js +3 -3
- package/dist/config/schema.help.js +8 -7
- package/dist/config/schema.labels.js +5 -4
- package/dist/config/sessions/disk-budget.js +6 -6
- package/dist/config/sessions/paths.js +2 -2
- package/dist/config/sessions/store.js +17 -17
- package/dist/config/sessions/transcript.js +4 -4
- package/dist/config/talk.js +2 -2
- package/dist/config/zod-schema.agent-runtime.js +1 -0
- package/dist/config/zod-schema.js +5 -0
- package/dist/control-ui/assets/{app-BXA4gPvN.js → app-bR-fO5ty.js} +1511 -1555
- package/dist/control-ui/assets/{config-CU5Zi8Dh.js → config-LeImukCW.js} +10 -10
- package/dist/control-ui/assets/{federation-D10Q4eP_.js → federation-DgA9e-Pn.js} +364 -422
- package/dist/control-ui/assets/{index-D2QbJhVg.js → index-ckCxHwjy.js} +3 -3
- package/dist/control-ui/assets/{mining-BdhMn18r.js → mining-BgHFh0ei.js} +134 -114
- package/dist/control-ui/assets/mining-commit-DFpB_4JN.js +2 -0
- package/dist/control-ui/assets/{open-external-url-DwSiwMPl.js → open-external-url-ulF1B-sA.js} +3 -3
- package/dist/control-ui/assets/{providers-QMn4w2_f.js → providers-CIx9fxc6.js} +2 -2
- package/dist/control-ui/assets/{wallet-C2g294QT.js → wallet-DvStR_AT.js} +259 -377
- package/dist/control-ui/index.html +1 -1
- package/dist/control-ui/version.json +1 -1
- package/dist/cron/service/store.js +2 -2
- package/dist/cron/store.js +6 -6
- package/dist/daemon/systemd-system.js +60 -54
- package/dist/discord/monitor/thread-bindings.state.js +2 -2
- package/dist/extensions/sat-mining/src/protocol-contract.js +43 -3
- package/dist/extensions/sat-mining/src/rpc-read.js +235 -67
- package/dist/extensions/sat-mining/src/sat-bond-layout.js +14 -11
- package/dist/extensions/sat-mining/src/signer-codec-manifest.js +406 -0
- package/dist/extensions/sat-mining/src/solana-submit.js +1038 -397
- package/dist/extensions/sat-mining/src/submission-ledger.js +349 -0
- package/dist/federation/auto-connect.js +98 -8
- package/dist/federation/marketplace-capability-adapter.js +33 -7
- package/dist/federation/marketplace-delivery-outbox.js +196 -0
- package/dist/federation/marketplace-delivery.js +351 -215
- package/dist/federation/marketplace-direct-payment.js +272 -141
- package/dist/federation/marketplace-escrow.js +607 -249
- package/dist/federation/marketplace-settlement-ledger.js +352 -0
- package/dist/federation/offers.js +9 -7
- package/dist/federation/peer-auth-v2.js +529 -0
- package/dist/gateway/a2a-http.js +425 -96
- package/dist/gateway/a2a-settlement.js +259 -153
- package/dist/gateway/a2a-task-store.js +524 -0
- package/dist/gateway/auth.js +38 -2
- package/dist/gateway/config-reload.js +46 -33
- package/dist/gateway/control-ui-boot-check.js +6 -6
- package/dist/gateway/control-ui-login.js +7 -7
- package/dist/gateway/control-ui.js +9 -9
- package/dist/gateway/durable-capacity.js +31 -0
- package/dist/gateway/federation-http.js +540 -135
- package/dist/gateway/federation-marketplace-run-store.js +397 -0
- package/dist/gateway/federation-marketplace.js +535 -230
- package/dist/gateway/hooks-mapping.js +4 -4
- package/dist/gateway/mutating-admin-rpc-rate-limit.js +5 -0
- package/dist/gateway/security-path.js +1 -1
- package/dist/gateway/server-discovery.js +2 -2
- package/dist/gateway/server-http.js +1088 -1209
- package/dist/gateway/server-methods/chat.js +3 -3
- package/dist/gateway/server-methods/models.js +1 -1
- package/dist/gateway/server-methods/secrets.js +40 -0
- package/dist/gateway/server-methods/sessions.js +6 -6
- package/dist/gateway/server-methods/usage.js +2 -2
- package/dist/gateway/server-methods.js +1 -2
- package/dist/gateway/server-reload-handlers.js +196 -66
- package/dist/gateway/server-runtime-config.js +1 -1
- package/dist/gateway/server-secrets-runtime.js +288 -0
- package/dist/gateway/server.impl.js +73 -42
- package/dist/gateway/session-compaction-checkpoints.js +4 -4
- package/dist/gateway/session-utils.fs.js +24 -24
- package/dist/gateway/session-utils.js +6 -6
- package/dist/gateway/sessions-patch.js +3 -5
- package/dist/hooks/bundled-dir.js +4 -4
- package/dist/hooks/gmail-setup-utils.js +6 -6
- package/dist/hooks/import-url.js +2 -2
- package/dist/hooks/loader.js +4 -4
- package/dist/hooks/workspace.js +7 -7
- package/dist/index.js +4 -2
- package/dist/infra/archive.js +17 -17
- package/dist/infra/boundary-file-read.js +2 -2
- package/dist/infra/boundary-path.js +15 -15
- package/dist/infra/brew.js +2 -2
- package/dist/infra/control-ui-assets.js +14 -14
- package/dist/infra/device-auth-store.js +8 -8
- package/dist/infra/device-identity.js +8 -8
- package/dist/infra/dotenv.js +2 -2
- package/dist/infra/exec-approvals.js +8 -8
- package/dist/infra/exec-command-resolution.js +4 -4
- package/dist/infra/exec-safe-bin-trust.js +2 -2
- package/dist/infra/fased-root.js +5 -5
- package/dist/infra/fasedhub.js +64 -1
- package/dist/infra/fs-safe.js +14 -14
- package/dist/infra/gateway-lock.js +11 -11
- package/dist/infra/git-commit.js +5 -5
- package/dist/infra/git-root.js +4 -4
- package/dist/infra/hosted-runtime-artifact.js +3 -3
- package/dist/infra/is-main.js +2 -2
- package/dist/infra/json-file.js +7 -7
- package/dist/infra/local-source-paired-update.js +538 -0
- package/dist/infra/managed-runtime-bootstrap.js +6 -6
- package/dist/infra/outbound/delivery-queue.js +16 -16
- package/dist/infra/path-env.js +3 -3
- package/dist/infra/ports-lsof.js +4 -4
- package/dist/infra/provider-usage.auth.js +3 -3
- package/dist/infra/restart.js +41 -10
- package/dist/infra/safe-open-sync.js +2 -2
- package/dist/infra/session-cost-usage.js +9 -9
- package/dist/infra/shell-env.js +2 -2
- package/dist/infra/state-migrations.fs.js +6 -6
- package/dist/infra/state-migrations.js +23 -23
- package/dist/infra/tmp-fased-dir.js +6 -6
- package/dist/infra/update-runner.js +96 -0
- package/dist/infra/widearea-dns.js +3 -3
- package/dist/infra/wsl.js +2 -2
- package/dist/light-update-status.js +11 -11
- package/dist/line/accounts.js +2 -2
- package/dist/line/download.js +2 -2
- package/dist/logging/config.js +3 -3
- package/dist/logging/logger.js +7 -7
- package/dist/managed/federation.js +3 -3
- package/dist/managed/tunnel.js +3 -3
- package/dist/media/store.js +13 -13
- package/dist/media-understanding/runner.js +3 -3
- package/dist/memory/backend-config.js +2 -1
- package/dist/memory/embeddings.js +2 -2
- package/dist/memory/internal.js +10 -10
- package/dist/memory/manager-sync-ops.js +7 -7
- package/dist/memory/repair-executor.js +17 -17
- package/dist/memory/session-files.js +16 -2
- package/dist/node-host/invoke-system-run-plan.js +8 -8
- package/dist/node-host/invoke.js +2 -2
- package/dist/node-host/runner.js +3 -3
- package/dist/pairing/pairing-store.js +3 -3
- package/dist/plugin-sdk/{accounts-DxblobYM.js → accounts-Brn3-uWN.js} +1 -1
- package/dist/plugin-sdk/{actions-D4UNimWa.js → actions-DRu135h0.js} +2 -2
- package/dist/plugin-sdk/{active-listener-CFuy106s.js → active-listener-B_NMtgPL.js} +1 -1
- package/dist/plugin-sdk/{audio-preflight-Bv0hUOWL.js → audio-preflight-BYxAt775.js} +27 -27
- package/dist/plugin-sdk/{audit-Cs0K7LBp.js → audit-C5d2z5U1.js} +1 -1
- package/dist/plugin-sdk/{channel-access-D5aHoTY8.js → channel-access-CcFRdRPO.js} +1 -1
- package/dist/plugin-sdk/{channel-access-configure-Dvch9mMQ.js → channel-access-configure-DaI5wevh.js} +1 -1
- package/dist/plugin-sdk/channel-plugin-common.d.ts +3 -3
- package/dist/plugin-sdk/channel-plugin-common.js +4 -4
- package/dist/plugin-sdk/{chunk-B0FUGc5A.js → chunk-CyoyqpbG.js} +1 -1
- package/dist/plugin-sdk/{chunk-items-Bk--NU3E.js → chunk-items-DIRHG2gJ.js} +1 -1
- package/dist/plugin-sdk/command-status.d.ts +2 -2
- package/dist/plugin-sdk/command-status.js +27 -27
- package/dist/plugin-sdk/{commands-registry-DmDRhRAU.js → commands-registry-BfqdEWdF.js} +2 -2
- package/dist/plugin-sdk/{common-CfUOowOp.js → common-HCcXU-NR.js} +1 -1
- package/dist/plugin-sdk/{config-mxULv0fQ.js → config-DlWVeLFB.js} +7113 -6877
- package/dist/plugin-sdk/{config-schema-CGW6J3Pv.js → config-schema-BOT7kHb6.js} +6779 -3696
- package/dist/plugin-sdk/device-pair.d.ts +1 -1
- package/dist/plugin-sdk/discord.d.ts +5 -5
- package/dist/plugin-sdk/discord.js +19 -19
- package/dist/plugin-sdk/file-lock.js +35 -4
- package/dist/plugin-sdk/{filesystem-manager-ZoHU8oA7.js → filesystem-manager-DoI8IBNF.js} +1 -1
- package/dist/plugin-sdk/{group-mentions-BHRff6j8.d.ts → group-mentions-q3hUTCt7.d.ts} +1 -1
- package/dist/plugin-sdk/{handle-action-DbVCF9HZ.js → handle-action-hvwapMKg.js} +13 -13
- package/dist/plugin-sdk/{helpers-BXbdgs5H.js → helpers-DMBU4oTo.js} +1 -1
- package/dist/plugin-sdk/{image-ops-D7jPxaph.js → image-ops-DQi0n_Tt.js} +1 -1
- package/dist/plugin-sdk/index.d.ts +9 -27
- package/dist/plugin-sdk/index.js +29 -29
- package/dist/plugin-sdk/json-store.js +6 -6
- package/dist/plugin-sdk/{login-BRxww6nv.js → login-Ca583Okc.js} +3 -3
- package/dist/plugin-sdk/{login-qr-DJXsk9XH.js → login-qr-CGciBSNP.js} +3 -3
- package/dist/plugin-sdk/{manager-Y2S_5IlI.js → manager-BegWxNYX.js} +4 -4
- package/dist/plugin-sdk/{markdown-tables-DHLFQqaF.js → markdown-tables-DCOXEUfZ.js} +1 -1
- package/dist/plugin-sdk/{media-Czo4carg.js → media-CAdQF5TG.js} +47 -47
- package/dist/plugin-sdk/{memory-search-DTjIMw8J.js → memory-search-CrFPOeTH.js} +4 -1
- package/dist/plugin-sdk/{monitor-B9Cmt_Je.js → monitor-BCFDaqJ-.js} +31 -31
- package/dist/plugin-sdk/{monitor-B71iwAgC.js → monitor-BgbjRiPM.js} +32 -32
- package/dist/plugin-sdk/{openresponses-http-Du4GMmwo.js → openresponses-http-DFf87SMM.js} +27 -27
- package/dist/plugin-sdk/{optional-runtime-dependency-DdMbxS24.js → optional-runtime-dependency-0dznm3ZO.js} +1 -1
- package/dist/plugin-sdk/{outbound-Db8mRN6P.js → outbound-BgVDdHxx.js} +6 -6
- package/dist/plugin-sdk/{outbound-attachment-BqFjcypb.js → outbound-attachment-QqTnIhZL.js} +2 -2
- package/dist/plugin-sdk/{pairing-message-BMkkS038.d.ts → pairing-message-CS-9BHug.d.ts} +2 -2
- package/dist/plugin-sdk/{pairing-message-B3GC_7CD.js → pairing-message-D0CoLHRJ.js} +1 -1
- package/dist/plugin-sdk/{pairing-store-CQikgIbw.js → pairing-store-BChahgI2.js} +2 -2
- package/dist/plugin-sdk/{pi-model-discovery-CY3m5zJP.js → pi-model-discovery-BX_JLcEJ.js} +1 -1
- package/dist/plugin-sdk/{pi-model-discovery-runtime-DSh1T2pn.js → pi-model-discovery-runtime-DxTMz_XF.js} +2 -2
- package/dist/plugin-sdk/provider-web-search-config-contract.d.ts +2 -2
- package/dist/plugin-sdk/{pw-ai-AFUqn-tQ.js → pw-ai-natjh3rm.js} +3 -3
- package/dist/plugin-sdk/{qmd-manager-DSyx77KY.js → qmd-manager-CgRaTxUq.js} +1 -1
- package/dist/plugin-sdk/{query-expansion-CAI2kKLQ.js → query-expansion-BG3FgzF7.js} +14 -3
- package/dist/plugin-sdk/{replies-Fzh9PhXl.js → replies-ChYo5ZQM.js} +2 -2
- package/dist/plugin-sdk/{resolve-outbound-target-KpF3co6T.js → resolve-outbound-target-D-KGgHJZ.js} +1 -1
- package/dist/plugin-sdk/{resolve-route-CDl74O19.js → resolve-route-C8tvQm8Z.js} +1 -1
- package/dist/plugin-sdk/{retry-policy-D4uiqUOG.js → retry-policy-C6SjKjQA.js} +1 -1
- package/dist/plugin-sdk/{runtime-Bb6KRnCC.js → runtime-2B9_WKoI.js} +8 -3
- package/dist/plugin-sdk/{runtime-dependency-DLDmB94f.js → runtime-dependency-DczkvPxn.js} +2 -2
- package/dist/plugin-sdk/sat-runtime.d.ts +549 -309
- package/dist/plugin-sdk/sat-runtime.js +29 -29
- package/dist/plugin-sdk/{send-C4k4JuJN.js → send-B6KkGKZD.js} +6 -6
- package/dist/plugin-sdk/{send-D-uDKGIq.js → send-CFzGKJXo.js} +6 -6
- package/dist/plugin-sdk/{send-Du8ykP1k.js → send-DCO441U7.js} +8 -8
- package/dist/plugin-sdk/{send-5nFktR1n.js → send-gDoGA-7e.js} +5 -5
- package/dist/plugin-sdk/{send-Bfzf11VY.js → send-q9HXrSwK.js} +7 -7
- package/dist/plugin-sdk/{session-CS-Td9EM.js → session-DHD4ZKyG.js} +2 -2
- package/dist/plugin-sdk/{skill-commands-CFAlXWHk.js → skill-commands-FKEPLS7T.js} +201 -26
- package/dist/plugin-sdk/{slack-D_bbE6Yd.js → slack-BUTt8cxK.js} +39 -39
- package/dist/plugin-sdk/{slack-actions-BcMkNv1Z.js → slack-actions-DhbMcp8M.js} +11 -11
- package/dist/plugin-sdk/slack.d.ts +5 -5
- package/dist/plugin-sdk/slack.js +9 -9
- package/dist/plugin-sdk/{sticker-cache-Dqo9nRhi.js → sticker-cache-D0wHVqjt.js} +3 -3
- package/dist/plugin-sdk/{tables-bFXyRpkx.js → tables-B3jr0Pvq.js} +1 -1
- package/dist/plugin-sdk/{targets-DH7a9lKB.js → targets-CtSbTxYX.js} +1 -1
- package/dist/plugin-sdk/{telegram-actions-Cnag7JTH.js → telegram-actions-CC_qN4v0.js} +30 -30
- package/dist/plugin-sdk/telegram.d.ts +5 -5
- package/dist/plugin-sdk/telegram.js +8 -8
- package/dist/plugin-sdk/{thread-bindings.lifecycle-CgOvvdw8.js → thread-bindings.lifecycle-QbkNl-m6.js} +3 -3
- package/dist/plugin-sdk/{thread-bindings.state-CQpk44Hq.js → thread-bindings.state-D9hg_M1c.js} +2 -2
- package/dist/plugin-sdk/tmp-fased-dir-xOTGlzBE.d.ts +486 -0
- package/dist/plugin-sdk/{types-CLIvQaVg.d.ts → types-C3avNytw.d.ts} +3 -4
- package/dist/plugin-sdk/{types-DyhXnYUr.d.ts → types-D0kDG8l0.d.ts} +3 -2
- package/dist/plugin-sdk/{types-BYDL6dQj.d.ts → types-DWfbSAaM.d.ts} +2 -2
- package/dist/plugin-sdk/{types.plugin-_fbu40Re.d.ts → types.plugin-BcSBq42x.d.ts} +8 -3
- package/dist/plugin-sdk/{web-BInKQkc4.js → web-BXsJ1vqe.js} +32 -32
- package/dist/plugin-sdk/{whatsapp-actions-BtSc2CBv.js → whatsapp-actions-Bj_rOncr.js} +13 -13
- package/dist/plugin-sdk/{whatsapp-heartbeat-Bg9TuYzl.js → whatsapp-heartbeat-B1WHkJIg.js} +2 -2
- package/dist/plugin-sdk/whatsapp.d.ts +5 -5
- package/dist/plugin-sdk/whatsapp.js +12 -12
- package/dist/plugin-sdk/{wsl-C4DGFkOd.js → wsl-J-HscWxS.js} +3 -3
- package/dist/plugins/bundled-dir.js +3 -3
- package/dist/plugins/discovery.js +11 -11
- package/dist/plugins/loader.js +13 -13
- package/dist/plugins/manifest-registry.js +2 -2
- package/dist/plugins/manifest.js +4 -4
- package/dist/plugins/path-safety.js +3 -3
- package/dist/plugins/status-cache.js +9 -9
- package/dist/plugins/update.js +3 -3
- package/dist/plugins/web-search-install-catalog.js +3 -3
- package/dist/providers/refresh.js +1 -1
- package/dist/providers/registry.js +1 -1
- package/dist/secrets/apply.js +17 -17
- package/dist/secrets/audit.js +11 -11
- package/dist/secrets/runtime.js +1 -1
- package/dist/secrets/shared.js +9 -9
- package/dist/security/scan-paths.js +2 -2
- package/dist/shared/config-eval.js +2 -2
- package/dist/shared/pid-alive.js +2 -2
- package/dist/tasks/standing-orders.js +5 -5
- package/dist/tasks/task-flow-registry.js +5 -5
- package/dist/tasks/task-registry.js +5 -5
- package/dist/tasks/workflow-definitions.js +6 -6
- package/dist/telegram/token.js +5 -5
- package/dist/utils.js +5 -5
- package/dist/wallet/external-submission-ledger.js +376 -0
- package/dist/wallet/legacy-embedded-keystore.js +40 -0
- package/dist/wallet/local-socket-signer-archive.js +30 -0
- package/dist/wallet/local-socket-signer-lifecycle.js +97 -0
- package/dist/wallet/local-socket-signer-policy.js +166 -0
- package/dist/wallet/local-socket-signer-protocol.js +561 -118
- package/dist/wallet/native-signer-wallet-id.js +25 -0
- package/dist/wallet/providers/alchemy-adapter.js +3 -0
- package/dist/wallet/providers/local-socket-signer-adapter.js +382 -107
- package/dist/wallet/providers/turnkey-adapter.js +292 -34
- package/dist/wallet/providers/wallet-standard-adapter.js +100 -0
- package/dist/wallet/signer-network-admin.js +184 -0
- package/dist/wallet/signer-protocol-v2.generated.js +90 -0
- package/dist/wallet/solana-bond-signing.js +157 -69
- package/dist/wallet/solana-reviewed-transaction.js +375 -0
- package/dist/wallet/solana-swap.js +520 -64
- package/dist/wallet/solana-transaction-inspection.js +106 -4
- package/dist/wallet/solana-trigger.js +658 -320
- package/dist/wallet/turnkey-reviewed-state.js +370 -0
- package/dist/wallet/wallet-approval-auth.js +20 -31
- package/dist/wallet/wallet-atomic-state.js +53 -0
- package/dist/wallet/wallet-audit-log.js +5 -5
- package/dist/wallet/wallet-canary.js +0 -1
- package/dist/wallet/wallet-inbound-events.js +19 -14
- package/dist/wallet/wallet-observability.js +5 -5
- package/dist/wallet/wallet-policy-simulation.js +1 -1
- package/dist/wallet/wallet-policy.js +95 -41
- package/dist/wallet/wallet-provider-capabilities.js +28 -4
- package/dist/wallet/wallet-provider-registry.js +64 -51
- package/dist/wallet/wallet-provider-resolver.js +62 -63
- package/dist/wallet/wallet-runtime-config.js +31 -44
- package/dist/wallet/wallet-secrets-store.js +44 -22
- package/dist/wallet/wallet-send-approvals.js +1894 -592
- package/dist/wallet/wallet-send-execution-ledger.js +292 -0
- package/dist/wallet/wallet-settlement-links.js +17 -16
- package/dist/wallet/wallet-standard-review.js +353 -0
- package/dist/wallet/wallet-status.js +0 -9
- package/dist/wallet/wallet-task-ledger.js +16 -2
- package/dist/web/accounts.js +3 -3
- package/dist/web/auth-store.js +18 -18
- package/dist/web/auto-reply/heartbeat-runner.js +1 -1
- package/dist/web/auto-reply/monitor.js +2 -2
- package/dist/web/session.js +4 -4
- package/dist/wizard/host-security-capability.js +15 -24
- package/dist/wizard/onboarding.finalize.js +63 -184
- package/dist/wizard/onboarding.host-security.js +118 -1368
- package/dist/wizard/onboarding.js +180 -242
- package/dist/wizard/onboarding.wallet.js +323 -829
- package/extensions/acpx/package.json +1 -1
- package/extensions/bluebubbles/package.json +1 -1
- package/extensions/copilot-proxy/package.json +1 -1
- package/extensions/diagnostics-otel/package.json +1 -1
- package/extensions/fased-federation/package.json +1 -1
- package/extensions/google-gemini-cli-auth/package.json +1 -1
- package/extensions/imessage/package.json +1 -1
- package/extensions/irc/package.json +1 -1
- package/extensions/line/package.json +1 -1
- package/extensions/llm-task/package.json +1 -1
- package/extensions/lobster/package.json +1 -1
- package/extensions/matrix/CHANGELOG.md +18 -0
- package/extensions/matrix/package.json +1 -1
- package/extensions/mattermost/package.json +1 -1
- package/extensions/memory-core/package.json +2 -2
- package/extensions/memory-lancedb/package.json +1 -1
- package/extensions/minimax-portal-auth/package.json +1 -1
- package/extensions/msteams/CHANGELOG.md +18 -0
- package/extensions/msteams/package.json +1 -1
- package/extensions/nextcloud-talk/package.json +1 -1
- package/extensions/nostr/CHANGELOG.md +18 -0
- package/extensions/nostr/package.json +1 -1
- package/extensions/open-prose/package.json +1 -1
- package/extensions/sat-mining/index.ts +498 -153
- package/extensions/sat-mining/package.json +1 -1
- package/extensions/sat-mining/signer-codec-schema.v1.json +374 -0
- package/extensions/sat-mining/src/audit-store.ts +50 -5
- package/extensions/sat-mining/src/claim-service.ts +85 -14
- package/extensions/sat-mining/src/config.ts +9 -0
- package/extensions/sat-mining/src/cycle-progress.ts +16 -8
- package/extensions/sat-mining/src/epoch-service.ts +9 -5
- package/extensions/sat-mining/src/gateway-runner.ts +21 -1
- package/extensions/sat-mining/src/protocol-contract.ts +45 -1
- package/extensions/sat-mining/src/recovery-service.ts +312 -0
- package/extensions/sat-mining/src/round-watcher.ts +391 -81
- package/extensions/sat-mining/src/rpc-read.ts +330 -89
- package/extensions/sat-mining/src/runtime.ts +14 -0
- package/extensions/sat-mining/src/sat-bond-layout.ts +6 -0
- package/extensions/sat-mining/src/signer-codec-manifest.ts +429 -0
- package/extensions/sat-mining/src/solana-submit.ts +1199 -428
- package/extensions/sat-mining/src/submission-ledger.ts +433 -0
- package/extensions/signal/package.json +1 -1
- package/extensions/synology-chat/package.json +1 -1
- package/extensions/tlon/package.json +1 -1
- package/extensions/twitch/CHANGELOG.md +18 -0
- package/extensions/twitch/package.json +1 -1
- package/extensions/voice-call/CHANGELOG.md +18 -0
- package/extensions/voice-call/package.json +1 -1
- package/extensions/zalo/CHANGELOG.md +18 -0
- package/extensions/zalo/package.json +1 -1
- package/extensions/zalouser/CHANGELOG.md +18 -0
- package/extensions/zalouser/package.json +1 -1
- package/install.sh +4955 -0
- package/package.json +24 -5
- package/scripts/fased-host-updater.mjs +1421 -0
- package/scripts/fased-host-updaterctl.mjs +186 -0
- package/scripts/fased-managed-service.sh +36 -0
- package/scripts/fased-managed-updater.mjs +3065 -156
- package/scripts/fased-signer-enroll-hosting.sh +275 -0
- package/scripts/fased-signer-network-hosting.sh +143 -0
- package/scripts/fased-signer-owner-policy.mjs +1430 -0
- package/scripts/fased-signer-policy-hosting.sh +50 -0
- package/scripts/fased-signer-policy-local.sh +26 -0
- package/scripts/hosted-release-manifest.mjs +185 -0
- package/scripts/install-fased-signerd.sh +217 -0
- package/scripts/install-managed-runtime.mjs +212 -10
- package/scripts/managed-runtime-layout.mjs +75 -3
- package/scripts/migrate-hosted-signer-v2.mjs +58 -0
- package/scripts/start-managed.sh +169 -360
- package/dist/control-ui/assets/mining-commit-R-6nu87p.js +0 -2
- package/dist/plugin-sdk/tmp-fased-dir-BdFQvrvw.d.ts +0 -77
- package/dist/wallet/local-socket-signer-broker.js +0 -224
- package/dist/wallet/local-socket-signer-custody.js +0 -42
- package/dist/wallet/providers/embedded-keystore-adapter.js +0 -402
- package/dist/wallet/providers/privy-adapter.js +0 -80
- package/dist/wallet/wallet-custody.js +0 -1836
|
@@ -0,0 +1,538 @@
|
|
|
1
|
+
import { resolveStateDir } from "../config/paths.js";
|
|
2
|
+
import { runCommandWithTimeout } from "../process/exec.js";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import fs from "node:fs/promises";
|
|
5
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
6
|
+
import * as tar from "tar";
|
|
7
|
+
|
|
8
|
+
//#region src/infra/local-source-paired-update.ts
|
|
9
|
+
const JOURNAL_SCHEMA_VERSION = 1;
|
|
10
|
+
const PHASES = new Set([
|
|
11
|
+
"prepared",
|
|
12
|
+
"app-active",
|
|
13
|
+
"signer-active",
|
|
14
|
+
"gateway-verified",
|
|
15
|
+
"committing",
|
|
16
|
+
"rolling-back"
|
|
17
|
+
]);
|
|
18
|
+
const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
19
|
+
const SHA_PATTERN = /^[a-f0-9]{40}$/;
|
|
20
|
+
const VERSION_PATTERN = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z]+(?:[.-][0-9A-Za-z]+)*)?$/;
|
|
21
|
+
function resolveContext(env = process.env) {
|
|
22
|
+
const stateDir = path.resolve(resolveStateDir(env));
|
|
23
|
+
const updateRoot = path.join(stateDir, "source-paired-update");
|
|
24
|
+
return {
|
|
25
|
+
stateDir,
|
|
26
|
+
updateRoot,
|
|
27
|
+
transactionsDir: path.join(updateRoot, "transactions"),
|
|
28
|
+
journalPath: path.join(updateRoot, "transaction.json")
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function pathIsInside(parent, candidate) {
|
|
32
|
+
const relative = path.relative(path.resolve(parent), path.resolve(candidate));
|
|
33
|
+
return relative !== "" && !relative.startsWith("..") && !path.isAbsolute(relative);
|
|
34
|
+
}
|
|
35
|
+
async function fsyncPath(target) {
|
|
36
|
+
const handle = await fs.open(target, "r");
|
|
37
|
+
try {
|
|
38
|
+
await handle.sync();
|
|
39
|
+
} finally {
|
|
40
|
+
await handle.close();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
async function sha256File(filePath) {
|
|
44
|
+
const bytes = await fs.readFile(filePath);
|
|
45
|
+
return createHash("sha256").update(bytes).digest("hex");
|
|
46
|
+
}
|
|
47
|
+
function validateRelease(value, label) {
|
|
48
|
+
const release = value;
|
|
49
|
+
if (!release || !SHA_PATTERN.test(release.sha ?? "") || !VERSION_PATTERN.test(release.version ?? "")) {
|
|
50
|
+
throw new Error(`Local source paired update has an invalid ${label} release identity`);
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
sha: release.sha,
|
|
54
|
+
version: release.version
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function validateJournal(context, value) {
|
|
58
|
+
const journal = value;
|
|
59
|
+
if (!journal || journal.schemaVersion !== JOURNAL_SCHEMA_VERSION || journal.kind !== "source-checkout" || !UUID_PATTERN.test(journal.transactionId ?? "") || !PHASES.has(journal.phase) || typeof journal.sourceRoot !== "string" || !path.isAbsolute(journal.sourceRoot) || typeof journal.transactionDir !== "string" || path.resolve(journal.transactionDir) !== path.join(context.transactionsDir, journal.transactionId ?? "") || !pathIsInside(context.updateRoot, journal.transactionDir) || path.resolve(journal.controllerPath ?? "") !== path.join(journal.transactionDir, "controller", "fased-managed-updater.mjs") || typeof journal.previous?.branch !== "string" && journal.previous?.branch !== null || typeof journal.previous?.branch === "string" && (!journal.previous.branch || journal.previous.branch.includes("..") || !/^[0-9A-Za-z._/-]+$/.test(journal.previous.branch)) || typeof journal.distSnapshot?.path !== "string" || path.resolve(journal.distSnapshot.path) !== path.join(journal.transactionDir, "dist.tar.gz") || !/^[a-f0-9]{64}$/.test(journal.distSnapshot?.sha256 ?? "") || !Number.isSafeInteger(journal.distSnapshot?.size) || (journal.distSnapshot?.size ?? -1) <= 0) {
|
|
60
|
+
throw new Error("Local source paired update journal is invalid");
|
|
61
|
+
}
|
|
62
|
+
const previous = validateRelease(journal.previous, "previous");
|
|
63
|
+
const needsTarget = new Set([
|
|
64
|
+
"app-active",
|
|
65
|
+
"signer-active",
|
|
66
|
+
"gateway-verified",
|
|
67
|
+
"committing"
|
|
68
|
+
]).has(journal.phase);
|
|
69
|
+
const target = journal.target === null ? null : validateRelease(journal.target, "target");
|
|
70
|
+
if (needsTarget && target === null) {
|
|
71
|
+
throw new Error("Local source paired update journal is missing its target release identity");
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
...journal,
|
|
75
|
+
sourceRoot: path.resolve(journal.sourceRoot),
|
|
76
|
+
previous: {
|
|
77
|
+
...previous,
|
|
78
|
+
branch: journal.previous.branch
|
|
79
|
+
},
|
|
80
|
+
target
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
async function writeJournal(context, journal, phase = journal.phase, exclusive = false) {
|
|
84
|
+
const next = validateJournal(context, {
|
|
85
|
+
...journal,
|
|
86
|
+
phase,
|
|
87
|
+
updatedAt: new Date().toISOString()
|
|
88
|
+
});
|
|
89
|
+
await fs.mkdir(context.updateRoot, {
|
|
90
|
+
recursive: true,
|
|
91
|
+
mode: 448
|
|
92
|
+
});
|
|
93
|
+
if (exclusive) {
|
|
94
|
+
const handle = await fs.open(context.journalPath, "wx", 384);
|
|
95
|
+
try {
|
|
96
|
+
await handle.writeFile(`${JSON.stringify(next, null, 2)}\n`);
|
|
97
|
+
await handle.sync();
|
|
98
|
+
} finally {
|
|
99
|
+
await handle.close();
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
102
|
+
const temporary = `${context.journalPath}.tmp-${process.pid}-${Date.now()}`;
|
|
103
|
+
const handle = await fs.open(temporary, "wx", 384);
|
|
104
|
+
try {
|
|
105
|
+
await handle.writeFile(`${JSON.stringify(next, null, 2)}\n`);
|
|
106
|
+
await handle.sync();
|
|
107
|
+
} finally {
|
|
108
|
+
await handle.close();
|
|
109
|
+
}
|
|
110
|
+
await fs.rename(temporary, context.journalPath);
|
|
111
|
+
}
|
|
112
|
+
await fsyncPath(context.updateRoot);
|
|
113
|
+
return next;
|
|
114
|
+
}
|
|
115
|
+
async function readLocalSourcePairedUpdateJournal(env = process.env) {
|
|
116
|
+
const context = resolveContext(env);
|
|
117
|
+
try {
|
|
118
|
+
return validateJournal(context, JSON.parse(await fs.readFile(context.journalPath, "utf8")));
|
|
119
|
+
} catch (error) {
|
|
120
|
+
if (error.code === "ENOENT") {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
throw error;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
async function runExact(argv, options) {
|
|
127
|
+
const result = await runCommandWithTimeout(argv, {
|
|
128
|
+
cwd: options.cwd,
|
|
129
|
+
timeoutMs: options.timeoutMs,
|
|
130
|
+
env: options.env
|
|
131
|
+
});
|
|
132
|
+
if (result.code !== 0) {
|
|
133
|
+
const detail = (result.stderr || result.stdout).trim().split("\n").slice(-5).join("\n");
|
|
134
|
+
throw new Error(`${options.label} failed${detail ? `: ${detail}` : ""}`);
|
|
135
|
+
}
|
|
136
|
+
return result.stdout.trim();
|
|
137
|
+
}
|
|
138
|
+
async function readGitHead(sourceRoot, timeoutMs, env) {
|
|
139
|
+
const sha = await runExact([
|
|
140
|
+
"git",
|
|
141
|
+
"-C",
|
|
142
|
+
sourceRoot,
|
|
143
|
+
"rev-parse",
|
|
144
|
+
"HEAD"
|
|
145
|
+
], {
|
|
146
|
+
cwd: sourceRoot,
|
|
147
|
+
timeoutMs,
|
|
148
|
+
env,
|
|
149
|
+
label: "git HEAD verification"
|
|
150
|
+
});
|
|
151
|
+
if (!SHA_PATTERN.test(sha)) {
|
|
152
|
+
throw new Error("Source checkout did not report an exact Git commit");
|
|
153
|
+
}
|
|
154
|
+
return sha;
|
|
155
|
+
}
|
|
156
|
+
async function readPackageVersion(sourceRoot) {
|
|
157
|
+
const parsed = JSON.parse(await fs.readFile(path.join(sourceRoot, "package.json"), "utf8"));
|
|
158
|
+
const version = typeof parsed.version === "string" ? parsed.version.trim() : "";
|
|
159
|
+
if (!VERSION_PATTERN.test(version)) {
|
|
160
|
+
throw new Error("Source checkout package.json has no exact release version");
|
|
161
|
+
}
|
|
162
|
+
return version;
|
|
163
|
+
}
|
|
164
|
+
async function copyController(sourceRoot, transactionDir) {
|
|
165
|
+
const controllerDir = path.join(transactionDir, "controller");
|
|
166
|
+
await fs.mkdir(controllerDir, {
|
|
167
|
+
recursive: true,
|
|
168
|
+
mode: 448
|
|
169
|
+
});
|
|
170
|
+
for (const name of ["fased-managed-updater.mjs", "managed-runtime-layout.mjs"]) {
|
|
171
|
+
const source = path.join(sourceRoot, "scripts", name);
|
|
172
|
+
const stat = await fs.lstat(source);
|
|
173
|
+
if (!stat.isFile() || stat.isSymbolicLink()) {
|
|
174
|
+
throw new Error(`Source checkout is missing a safe signer transaction controller: ${source}`);
|
|
175
|
+
}
|
|
176
|
+
const destination = path.join(controllerDir, name);
|
|
177
|
+
await fs.copyFile(source, destination);
|
|
178
|
+
await fs.chmod(destination, name.endsWith("updater.mjs") ? 448 : 384);
|
|
179
|
+
await fsyncPath(destination);
|
|
180
|
+
}
|
|
181
|
+
await fsyncPath(controllerDir);
|
|
182
|
+
return path.join(controllerDir, "fased-managed-updater.mjs");
|
|
183
|
+
}
|
|
184
|
+
async function isLocalSourceSignerConfigured(env = process.env) {
|
|
185
|
+
const stateDir = resolveContext(env).stateDir;
|
|
186
|
+
for (const candidate of [path.join(stateDir, "bin", "fased-signerd"), path.join(stateDir, "wallet", "signerd-v2.db")]) {
|
|
187
|
+
const found = await fs.lstat(candidate).then((stat) => stat.isFile() && !stat.isSymbolicLink()).catch(() => false);
|
|
188
|
+
if (found) {
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
try {
|
|
193
|
+
const registry = JSON.parse(await fs.readFile(path.join(stateDir, "wallet", "provider-registry.v1.json"), "utf8"));
|
|
194
|
+
return (registry.wallets ?? []).some((wallet) => wallet?.providerId === "local-socket-signer");
|
|
195
|
+
} catch {
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
async function prepareLocalSourcePairedUpdate(params) {
|
|
200
|
+
const env = params.env ?? process.env;
|
|
201
|
+
const context = resolveContext(env);
|
|
202
|
+
if (await readLocalSourcePairedUpdateJournal(env)) {
|
|
203
|
+
throw new Error("An unfinished Local source app/signer transaction must be recovered first");
|
|
204
|
+
}
|
|
205
|
+
const sourceRoot = path.resolve(params.sourceRoot);
|
|
206
|
+
const previousSha = await readGitHead(sourceRoot, params.timeoutMs, env);
|
|
207
|
+
const previousVersion = await readPackageVersion(sourceRoot);
|
|
208
|
+
const branchResult = await runCommandWithTimeout([
|
|
209
|
+
"git",
|
|
210
|
+
"-C",
|
|
211
|
+
sourceRoot,
|
|
212
|
+
"symbolic-ref",
|
|
213
|
+
"--quiet",
|
|
214
|
+
"--short",
|
|
215
|
+
"HEAD"
|
|
216
|
+
], {
|
|
217
|
+
cwd: sourceRoot,
|
|
218
|
+
timeoutMs: params.timeoutMs,
|
|
219
|
+
env
|
|
220
|
+
});
|
|
221
|
+
const branch = branchResult.code === 0 && branchResult.stdout.trim() ? branchResult.stdout.trim() : null;
|
|
222
|
+
if (branch !== null && (branch.includes("..") || !/^[0-9A-Za-z._/-]+$/.test(branch))) {
|
|
223
|
+
throw new Error("Source checkout branch name is unsafe for transactional rollback");
|
|
224
|
+
}
|
|
225
|
+
const transactionId = randomUUID();
|
|
226
|
+
const transactionDir = path.join(context.transactionsDir, transactionId);
|
|
227
|
+
await fs.mkdir(transactionDir, {
|
|
228
|
+
recursive: true,
|
|
229
|
+
mode: 448
|
|
230
|
+
});
|
|
231
|
+
try {
|
|
232
|
+
const distRoot = path.join(sourceRoot, "dist");
|
|
233
|
+
const distStat = await fs.lstat(distRoot);
|
|
234
|
+
if (!distStat.isDirectory() || distStat.isSymbolicLink()) {
|
|
235
|
+
throw new Error("Source checkout has no safe built dist directory to snapshot");
|
|
236
|
+
}
|
|
237
|
+
const distSnapshotPath = path.join(transactionDir, "dist.tar.gz");
|
|
238
|
+
await tar.c({
|
|
239
|
+
cwd: sourceRoot,
|
|
240
|
+
file: distSnapshotPath,
|
|
241
|
+
gzip: true,
|
|
242
|
+
portable: true,
|
|
243
|
+
noMtime: true
|
|
244
|
+
}, ["dist"]);
|
|
245
|
+
await fs.chmod(distSnapshotPath, 384);
|
|
246
|
+
await fsyncPath(distSnapshotPath);
|
|
247
|
+
const distSnapshotStat = await fs.lstat(distSnapshotPath);
|
|
248
|
+
const controllerPath = await copyController(sourceRoot, transactionDir);
|
|
249
|
+
const now = new Date().toISOString();
|
|
250
|
+
const journal = {
|
|
251
|
+
schemaVersion: 1,
|
|
252
|
+
kind: "source-checkout",
|
|
253
|
+
transactionId,
|
|
254
|
+
transactionDir,
|
|
255
|
+
sourceRoot,
|
|
256
|
+
controllerPath,
|
|
257
|
+
phase: "prepared",
|
|
258
|
+
previous: {
|
|
259
|
+
sha: previousSha,
|
|
260
|
+
version: previousVersion,
|
|
261
|
+
branch
|
|
262
|
+
},
|
|
263
|
+
target: null,
|
|
264
|
+
distSnapshot: {
|
|
265
|
+
path: distSnapshotPath,
|
|
266
|
+
sha256: await sha256File(distSnapshotPath),
|
|
267
|
+
size: distSnapshotStat.size
|
|
268
|
+
},
|
|
269
|
+
createdAt: now,
|
|
270
|
+
updatedAt: now
|
|
271
|
+
};
|
|
272
|
+
await fsyncPath(transactionDir);
|
|
273
|
+
return await writeJournal(context, journal, "prepared", true);
|
|
274
|
+
} catch (error) {
|
|
275
|
+
await fs.rm(transactionDir, {
|
|
276
|
+
recursive: true,
|
|
277
|
+
force: true
|
|
278
|
+
});
|
|
279
|
+
throw error;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
async function markLocalSourceAppActive(params) {
|
|
283
|
+
if (params.journal.phase !== "prepared") {
|
|
284
|
+
throw new Error(`Cannot activate source app from phase ${params.journal.phase}`);
|
|
285
|
+
}
|
|
286
|
+
const context = resolveContext(params.env ?? process.env);
|
|
287
|
+
const target = validateRelease({
|
|
288
|
+
sha: params.targetSha,
|
|
289
|
+
version: params.targetVersion
|
|
290
|
+
}, "target");
|
|
291
|
+
return await writeJournal(context, {
|
|
292
|
+
...params.journal,
|
|
293
|
+
target
|
|
294
|
+
}, "app-active");
|
|
295
|
+
}
|
|
296
|
+
async function runSignerController(params) {
|
|
297
|
+
const args = [
|
|
298
|
+
params.journal.controllerPath,
|
|
299
|
+
"local-signer",
|
|
300
|
+
params.action
|
|
301
|
+
];
|
|
302
|
+
if (params.action === "verify") {
|
|
303
|
+
if (!params.journal.target) {
|
|
304
|
+
throw new Error("Cannot verify a Local signer without a target release");
|
|
305
|
+
}
|
|
306
|
+
args.push("--version", params.journal.target.version, "--expected-commit", params.journal.target.sha, "--timeout", String(Math.ceil(params.timeoutMs / 1e3)));
|
|
307
|
+
}
|
|
308
|
+
await runExact([process.execPath, ...args], {
|
|
309
|
+
cwd: path.dirname(params.journal.controllerPath),
|
|
310
|
+
timeoutMs: params.timeoutMs,
|
|
311
|
+
env: params.env,
|
|
312
|
+
label: `Local signer ${params.action}`
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
async function activateLocalSourceSigner(params) {
|
|
316
|
+
if (params.journal.phase !== "app-active" || !params.journal.target) {
|
|
317
|
+
throw new Error(`Cannot activate Local signer from phase ${params.journal.phase}`);
|
|
318
|
+
}
|
|
319
|
+
const env = params.env ?? process.env;
|
|
320
|
+
const installer = path.join(params.journal.sourceRoot, "scripts", "install-fased-signerd.sh");
|
|
321
|
+
const stat = await fs.lstat(installer);
|
|
322
|
+
if (!stat.isFile() || stat.isSymbolicLink()) {
|
|
323
|
+
throw new Error("Updated source checkout is missing its safe Local signer installer");
|
|
324
|
+
}
|
|
325
|
+
await runExact([
|
|
326
|
+
"bash",
|
|
327
|
+
installer,
|
|
328
|
+
"--version",
|
|
329
|
+
params.journal.target.version,
|
|
330
|
+
"--expected-commit",
|
|
331
|
+
params.journal.target.sha,
|
|
332
|
+
"--defer-commit"
|
|
333
|
+
], {
|
|
334
|
+
cwd: params.journal.sourceRoot,
|
|
335
|
+
timeoutMs: params.timeoutMs,
|
|
336
|
+
env,
|
|
337
|
+
label: "Local signer prepare and activation"
|
|
338
|
+
});
|
|
339
|
+
return await writeJournal(resolveContext(env), params.journal, "signer-active");
|
|
340
|
+
}
|
|
341
|
+
async function verifyLocalSourceSigner(params) {
|
|
342
|
+
if (!new Set(["signer-active", "gateway-verified"]).has(params.journal.phase)) {
|
|
343
|
+
throw new Error(`Cannot verify Local signer from phase ${params.journal.phase}`);
|
|
344
|
+
}
|
|
345
|
+
await runSignerController({
|
|
346
|
+
journal: params.journal,
|
|
347
|
+
action: "verify",
|
|
348
|
+
timeoutMs: params.timeoutMs,
|
|
349
|
+
env: params.env ?? process.env
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
async function markLocalSourceGatewayVerified(journal, env = process.env) {
|
|
353
|
+
if (journal.phase !== "signer-active") {
|
|
354
|
+
throw new Error(`Cannot record Gateway verification from phase ${journal.phase}`);
|
|
355
|
+
}
|
|
356
|
+
return await writeJournal(resolveContext(env), journal, "gateway-verified");
|
|
357
|
+
}
|
|
358
|
+
async function removeTransaction(journal, env) {
|
|
359
|
+
const context = resolveContext(env);
|
|
360
|
+
await fs.rm(context.journalPath, { force: true });
|
|
361
|
+
await fsyncPath(context.updateRoot);
|
|
362
|
+
await fs.rm(journal.transactionDir, {
|
|
363
|
+
recursive: true,
|
|
364
|
+
force: true
|
|
365
|
+
});
|
|
366
|
+
await fsyncPath(context.transactionsDir);
|
|
367
|
+
}
|
|
368
|
+
async function commitLocalSourcePairedUpdate(params) {
|
|
369
|
+
const env = params.env ?? process.env;
|
|
370
|
+
let journal = params.journal;
|
|
371
|
+
if (journal.phase !== "gateway-verified" && journal.phase !== "committing") {
|
|
372
|
+
throw new Error(`Cannot commit Local source pair from phase ${journal.phase}`);
|
|
373
|
+
}
|
|
374
|
+
if (journal.phase !== "committing") {
|
|
375
|
+
journal = await writeJournal(resolveContext(env), journal, "committing");
|
|
376
|
+
}
|
|
377
|
+
await runSignerController({
|
|
378
|
+
journal,
|
|
379
|
+
action: "commit",
|
|
380
|
+
timeoutMs: params.timeoutMs,
|
|
381
|
+
env
|
|
382
|
+
});
|
|
383
|
+
await removeTransaction(journal, env);
|
|
384
|
+
}
|
|
385
|
+
async function restoreSourceApplication(params) {
|
|
386
|
+
const { journal, timeoutMs, env } = params;
|
|
387
|
+
const snapshotStat = await fs.lstat(journal.distSnapshot.path);
|
|
388
|
+
if (!snapshotStat.isFile() || snapshotStat.isSymbolicLink() || snapshotStat.size !== journal.distSnapshot.size || await sha256File(journal.distSnapshot.path) !== journal.distSnapshot.sha256) {
|
|
389
|
+
throw new Error("Local source rollback dist snapshot failed integrity verification");
|
|
390
|
+
}
|
|
391
|
+
if (journal.previous.branch) {
|
|
392
|
+
await runExact([
|
|
393
|
+
"git",
|
|
394
|
+
"-C",
|
|
395
|
+
journal.sourceRoot,
|
|
396
|
+
"checkout",
|
|
397
|
+
journal.previous.branch
|
|
398
|
+
], {
|
|
399
|
+
cwd: journal.sourceRoot,
|
|
400
|
+
timeoutMs,
|
|
401
|
+
env,
|
|
402
|
+
label: "source rollback branch checkout"
|
|
403
|
+
});
|
|
404
|
+
await runExact([
|
|
405
|
+
"git",
|
|
406
|
+
"-C",
|
|
407
|
+
journal.sourceRoot,
|
|
408
|
+
"reset",
|
|
409
|
+
"--hard",
|
|
410
|
+
journal.previous.sha
|
|
411
|
+
], {
|
|
412
|
+
cwd: journal.sourceRoot,
|
|
413
|
+
timeoutMs,
|
|
414
|
+
env,
|
|
415
|
+
label: "source rollback commit restore"
|
|
416
|
+
});
|
|
417
|
+
} else {
|
|
418
|
+
await runExact([
|
|
419
|
+
"git",
|
|
420
|
+
"-C",
|
|
421
|
+
journal.sourceRoot,
|
|
422
|
+
"checkout",
|
|
423
|
+
"--detach",
|
|
424
|
+
journal.previous.sha
|
|
425
|
+
], {
|
|
426
|
+
cwd: journal.sourceRoot,
|
|
427
|
+
timeoutMs,
|
|
428
|
+
env,
|
|
429
|
+
label: "source rollback detached commit restore"
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
await runExact([
|
|
433
|
+
"pnpm",
|
|
434
|
+
"install",
|
|
435
|
+
"--offline",
|
|
436
|
+
"--frozen-lockfile"
|
|
437
|
+
], {
|
|
438
|
+
cwd: journal.sourceRoot,
|
|
439
|
+
timeoutMs,
|
|
440
|
+
env,
|
|
441
|
+
label: "offline source dependency rollback"
|
|
442
|
+
});
|
|
443
|
+
await fs.rm(path.join(journal.sourceRoot, "dist"), {
|
|
444
|
+
recursive: true,
|
|
445
|
+
force: true
|
|
446
|
+
});
|
|
447
|
+
await tar.x({
|
|
448
|
+
cwd: journal.sourceRoot,
|
|
449
|
+
file: journal.distSnapshot.path,
|
|
450
|
+
strict: true,
|
|
451
|
+
filter: (entryPath) => entryPath === "dist" || entryPath.startsWith("dist/")
|
|
452
|
+
});
|
|
453
|
+
if (await readGitHead(journal.sourceRoot, timeoutMs, env) !== journal.previous.sha) {
|
|
454
|
+
throw new Error("Local source rollback restored the wrong Git commit");
|
|
455
|
+
}
|
|
456
|
+
if (await readPackageVersion(journal.sourceRoot) !== journal.previous.version) {
|
|
457
|
+
throw new Error("Local source rollback restored the wrong package version");
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
async function rollbackLocalSourcePairedUpdate(params) {
|
|
461
|
+
const env = params.env ?? process.env;
|
|
462
|
+
let journal = params.journal;
|
|
463
|
+
if (journal.phase !== "rolling-back") {
|
|
464
|
+
journal = await writeJournal(resolveContext(env), journal, "rolling-back");
|
|
465
|
+
}
|
|
466
|
+
const failures = [];
|
|
467
|
+
try {
|
|
468
|
+
await runSignerController({
|
|
469
|
+
journal,
|
|
470
|
+
action: "rollback",
|
|
471
|
+
timeoutMs: params.timeoutMs,
|
|
472
|
+
env
|
|
473
|
+
});
|
|
474
|
+
} catch (error) {
|
|
475
|
+
failures.push(`signer: ${String(error)}`);
|
|
476
|
+
}
|
|
477
|
+
if (failures.length === 0) {
|
|
478
|
+
try {
|
|
479
|
+
await restoreSourceApplication({
|
|
480
|
+
journal,
|
|
481
|
+
timeoutMs: params.timeoutMs,
|
|
482
|
+
env
|
|
483
|
+
});
|
|
484
|
+
} catch (error) {
|
|
485
|
+
failures.push(`application: ${String(error)}`);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
if (failures.length > 0) {
|
|
489
|
+
throw new Error(`Local source paired rollback is incomplete (${failures.join("; ")}). Re-run fased update after correcting the failure.`);
|
|
490
|
+
}
|
|
491
|
+
await removeTransaction(journal, env);
|
|
492
|
+
}
|
|
493
|
+
async function recoverLocalSourcePairedUpdate(params) {
|
|
494
|
+
const env = params.env ?? process.env;
|
|
495
|
+
const journal = await readLocalSourcePairedUpdateJournal(env);
|
|
496
|
+
if (!journal) {
|
|
497
|
+
return "none";
|
|
498
|
+
}
|
|
499
|
+
if (journal.phase === "gateway-verified" || journal.phase === "committing") {
|
|
500
|
+
await commitLocalSourcePairedUpdate({
|
|
501
|
+
journal,
|
|
502
|
+
timeoutMs: params.timeoutMs,
|
|
503
|
+
env
|
|
504
|
+
});
|
|
505
|
+
return "committed";
|
|
506
|
+
}
|
|
507
|
+
await rollbackLocalSourcePairedUpdate({
|
|
508
|
+
journal,
|
|
509
|
+
timeoutMs: params.timeoutMs,
|
|
510
|
+
env
|
|
511
|
+
});
|
|
512
|
+
return "rolled-back";
|
|
513
|
+
}
|
|
514
|
+
async function assertLocalSourcePairedGatewayStartAllowed(params) {
|
|
515
|
+
const env = params.env ?? process.env;
|
|
516
|
+
const journal = await readLocalSourcePairedUpdateJournal(env);
|
|
517
|
+
if (!journal) {
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
if (journal.phase !== "signer-active" && journal.phase !== "gateway-verified" && journal.phase !== "committing") {
|
|
521
|
+
throw new Error(`Gateway startup is blocked by an unfinished Local source app/signer update (${journal.phase}). Run fased update to recover it.`);
|
|
522
|
+
}
|
|
523
|
+
if (!journal.target || path.resolve(params.runtimeRoot) !== journal.sourceRoot) {
|
|
524
|
+
throw new Error("Gateway startup is blocked because the source update target root does not match");
|
|
525
|
+
}
|
|
526
|
+
const timeoutMs = params.timeoutMs ?? 5e3;
|
|
527
|
+
const [sha, version] = await Promise.all([readGitHead(journal.sourceRoot, timeoutMs, env), readPackageVersion(journal.sourceRoot)]);
|
|
528
|
+
if (sha !== journal.target.sha || version !== journal.target.version) {
|
|
529
|
+
throw new Error("Gateway startup is blocked because the source update target identity changed");
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
const __testing = {
|
|
533
|
+
resolveContext,
|
|
534
|
+
validateJournal
|
|
535
|
+
};
|
|
536
|
+
|
|
537
|
+
//#endregion
|
|
538
|
+
export { activateLocalSourceSigner, assertLocalSourcePairedGatewayStartAllowed, commitLocalSourcePairedUpdate, isLocalSourceSignerConfigured, markLocalSourceAppActive, markLocalSourceGatewayVerified, prepareLocalSourcePairedUpdate, readLocalSourcePairedUpdateJournal, recoverLocalSourcePairedUpdate, rollbackLocalSourcePairedUpdate, verifyLocalSourceSigner };
|
|
@@ -4,7 +4,7 @@ import { existsSync } from "node:fs";
|
|
|
4
4
|
import os from "node:os";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { promisify } from "node:util";
|
|
7
|
-
import fs
|
|
7
|
+
import fs from "node:fs/promises";
|
|
8
8
|
import { execFile } from "node:child_process";
|
|
9
9
|
|
|
10
10
|
//#region src/infra/managed-runtime-bootstrap.ts
|
|
@@ -35,12 +35,12 @@ async function ensureManagedRuntimeBootstrap(params) {
|
|
|
35
35
|
const manifestPath = path.join(stateDir, "install.json");
|
|
36
36
|
const updaterPath = path.join(stateDir, "updater", "fased-managed-updater.mjs");
|
|
37
37
|
try {
|
|
38
|
-
const parsed = JSON.parse(await fs
|
|
38
|
+
const parsed = JSON.parse(await fs.readFile(manifestPath, "utf8"));
|
|
39
39
|
if (parsed.schemaVersion === 1) {
|
|
40
40
|
try {
|
|
41
|
-
await fs
|
|
42
|
-
await fs
|
|
43
|
-
await fs
|
|
41
|
+
await fs.access(updaterPath);
|
|
42
|
+
await fs.access(path.join(stateDir, "bin", "fased"));
|
|
43
|
+
await fs.access(path.join(stateDir, "bin", "fased-service"));
|
|
44
44
|
return {
|
|
45
45
|
installed: false,
|
|
46
46
|
manifestPath,
|
|
@@ -71,7 +71,7 @@ async function ensureManagedRuntimeBootstrap(params) {
|
|
|
71
71
|
}
|
|
72
72
|
const installer = path.join(packageRoot, "scripts", "install-managed-runtime.mjs");
|
|
73
73
|
try {
|
|
74
|
-
await fs
|
|
74
|
+
await fs.access(installer);
|
|
75
75
|
} catch {
|
|
76
76
|
return {
|
|
77
77
|
installed: false,
|
|
@@ -2,7 +2,7 @@ import { resolveStateDir } from "../../config/paths.js";
|
|
|
2
2
|
import { formatErrorMessage } from "../errors.js";
|
|
3
3
|
import { generateSecureUuid } from "../secure-random.js";
|
|
4
4
|
import { formatOutboundTargetForLog, redactOutboundTargetInText } from "./format.js";
|
|
5
|
-
import
|
|
5
|
+
import syncFs from "node:fs";
|
|
6
6
|
import path from "node:path";
|
|
7
7
|
|
|
8
8
|
//#region src/infra/outbound/delivery-queue.ts
|
|
@@ -26,11 +26,11 @@ function resolveFailedDir(stateDir) {
|
|
|
26
26
|
/** Ensure the queue directory (and failed/ subdirectory) exist. */
|
|
27
27
|
async function ensureQueueDir(stateDir) {
|
|
28
28
|
const queueDir = resolveQueueDir(stateDir);
|
|
29
|
-
await
|
|
29
|
+
await syncFs.promises.mkdir(queueDir, {
|
|
30
30
|
recursive: true,
|
|
31
31
|
mode: 448
|
|
32
32
|
});
|
|
33
|
-
await
|
|
33
|
+
await syncFs.promises.mkdir(resolveFailedDir(stateDir), {
|
|
34
34
|
recursive: true,
|
|
35
35
|
mode: 448
|
|
36
36
|
});
|
|
@@ -57,18 +57,18 @@ async function enqueueDelivery(params, stateDir) {
|
|
|
57
57
|
const filePath = path.join(queueDir, `${id}.json`);
|
|
58
58
|
const tmp = `${filePath}.${process.pid}.tmp`;
|
|
59
59
|
const json = JSON.stringify(entry, null, 2);
|
|
60
|
-
await
|
|
60
|
+
await syncFs.promises.writeFile(tmp, json, {
|
|
61
61
|
encoding: "utf-8",
|
|
62
62
|
mode: 384
|
|
63
63
|
});
|
|
64
|
-
await
|
|
64
|
+
await syncFs.promises.rename(tmp, filePath);
|
|
65
65
|
return id;
|
|
66
66
|
}
|
|
67
67
|
/** Remove a successfully delivered entry from the queue. */
|
|
68
68
|
async function ackDelivery(id, stateDir) {
|
|
69
69
|
const filePath = path.join(resolveQueueDir(stateDir), `${id}.json`);
|
|
70
70
|
try {
|
|
71
|
-
await
|
|
71
|
+
await syncFs.promises.unlink(filePath);
|
|
72
72
|
} catch (err) {
|
|
73
73
|
const code = err && typeof err === "object" && "code" in err ? String(err.code) : null;
|
|
74
74
|
if (code !== "ENOENT") {
|
|
@@ -79,24 +79,24 @@ async function ackDelivery(id, stateDir) {
|
|
|
79
79
|
/** Update a queue entry after a failed delivery attempt. */
|
|
80
80
|
async function failDelivery(id, error, stateDir) {
|
|
81
81
|
const filePath = path.join(resolveQueueDir(stateDir), `${id}.json`);
|
|
82
|
-
const raw = await
|
|
82
|
+
const raw = await syncFs.promises.readFile(filePath, "utf-8");
|
|
83
83
|
const entry = JSON.parse(raw);
|
|
84
84
|
entry.retryCount += 1;
|
|
85
85
|
entry.lastAttemptAt = Date.now();
|
|
86
86
|
entry.lastError = error;
|
|
87
87
|
const tmp = `${filePath}.${process.pid}.tmp`;
|
|
88
|
-
await
|
|
88
|
+
await syncFs.promises.writeFile(tmp, JSON.stringify(entry, null, 2), {
|
|
89
89
|
encoding: "utf-8",
|
|
90
90
|
mode: 384
|
|
91
91
|
});
|
|
92
|
-
await
|
|
92
|
+
await syncFs.promises.rename(tmp, filePath);
|
|
93
93
|
}
|
|
94
94
|
/** Load all pending delivery entries from the queue directory. */
|
|
95
95
|
async function loadPendingDeliveries(stateDir) {
|
|
96
96
|
const queueDir = resolveQueueDir(stateDir);
|
|
97
97
|
let files;
|
|
98
98
|
try {
|
|
99
|
-
files = await
|
|
99
|
+
files = await syncFs.promises.readdir(queueDir);
|
|
100
100
|
} catch (err) {
|
|
101
101
|
const code = err && typeof err === "object" && "code" in err ? String(err.code) : null;
|
|
102
102
|
if (code === "ENOENT") {
|
|
@@ -111,20 +111,20 @@ async function loadPendingDeliveries(stateDir) {
|
|
|
111
111
|
}
|
|
112
112
|
const filePath = path.join(queueDir, file);
|
|
113
113
|
try {
|
|
114
|
-
const stat = await
|
|
114
|
+
const stat = await syncFs.promises.stat(filePath);
|
|
115
115
|
if (!stat.isFile()) {
|
|
116
116
|
continue;
|
|
117
117
|
}
|
|
118
|
-
const raw = await
|
|
118
|
+
const raw = await syncFs.promises.readFile(filePath, "utf-8");
|
|
119
119
|
const parsed = JSON.parse(raw);
|
|
120
120
|
const { entry, migrated } = normalizeLegacyQueuedDeliveryEntry(parsed);
|
|
121
121
|
if (migrated) {
|
|
122
122
|
const tmp = `${filePath}.${process.pid}.tmp`;
|
|
123
|
-
await
|
|
123
|
+
await syncFs.promises.writeFile(tmp, JSON.stringify(entry, null, 2), {
|
|
124
124
|
encoding: "utf-8",
|
|
125
125
|
mode: 384
|
|
126
126
|
});
|
|
127
|
-
await
|
|
127
|
+
await syncFs.promises.rename(tmp, filePath);
|
|
128
128
|
}
|
|
129
129
|
entries.push(entry);
|
|
130
130
|
} catch {}
|
|
@@ -135,13 +135,13 @@ async function loadPendingDeliveries(stateDir) {
|
|
|
135
135
|
async function moveToFailed(id, stateDir) {
|
|
136
136
|
const queueDir = resolveQueueDir(stateDir);
|
|
137
137
|
const failedDir = resolveFailedDir(stateDir);
|
|
138
|
-
await
|
|
138
|
+
await syncFs.promises.mkdir(failedDir, {
|
|
139
139
|
recursive: true,
|
|
140
140
|
mode: 448
|
|
141
141
|
});
|
|
142
142
|
const src = path.join(queueDir, `${id}.json`);
|
|
143
143
|
const dest = path.join(failedDir, `${id}.json`);
|
|
144
|
-
await
|
|
144
|
+
await syncFs.promises.rename(src, dest);
|
|
145
145
|
}
|
|
146
146
|
/** Compute the backoff delay in ms for a given retry count. */
|
|
147
147
|
function computeBackoffMs(retryCount) {
|