@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
|
@@ -1,58 +1,17 @@
|
|
|
1
|
+
import { fetchWithSsrFGuard } from "../infra/net/fetch-guard.js";
|
|
1
2
|
import { listLocalMarketplaceDeliveryTargets, listLocalMarketplaceOrders, upsertMarketplaceOrderConfig } from "./offers.js";
|
|
2
|
-
import { resolveFederationBaseUrl } from "./runtime.js";
|
|
3
|
+
import { resolveFederationBaseUrl, resolveFederationHandle } from "./runtime.js";
|
|
3
4
|
import { deliverOutboundPayloads } from "../infra/outbound/deliver.js";
|
|
5
|
+
import { FEDERATION_MARKETPLACE_DELIVERY_PATH, buildSignedFederationPeerRequest, isTrustedFederationPeerUrl, lookupFederationPeerDirectory } from "./peer-auth-v2.js";
|
|
6
|
+
import { claimMarketplaceDelivery, reserveMarketplaceDelivery, updateMarketplaceDeliveryOutbox } from "./marketplace-delivery-outbox.js";
|
|
4
7
|
|
|
5
8
|
//#region src/federation/marketplace-delivery.ts
|
|
6
9
|
const DELIVERY_SCHEMA = "https://schemas.fased.ai/fased-marketplace-delivery-v0.json";
|
|
10
|
+
const FEDERATION_DELIVERY_TIMEOUT_MS = 1e4;
|
|
11
|
+
const FEDERATION_PROTOCOL_V2_UPGRADE_ERROR = "federation recipient does not advertise federation peer protocol v2; upgrade both nodes before retrying";
|
|
7
12
|
function trimString(value) {
|
|
8
13
|
return typeof value === "string" ? value.trim() : "";
|
|
9
14
|
}
|
|
10
|
-
function isRecord(value) {
|
|
11
|
-
return typeof value === "object" && value !== null;
|
|
12
|
-
}
|
|
13
|
-
function readRecordString(record, key) {
|
|
14
|
-
return typeof record[key] === "string" ? record[key].trim() : "";
|
|
15
|
-
}
|
|
16
|
-
function directoryEntryCandidates(body) {
|
|
17
|
-
if (!isRecord(body)) {
|
|
18
|
-
return [];
|
|
19
|
-
}
|
|
20
|
-
return [
|
|
21
|
-
body,
|
|
22
|
-
isRecord(body.entry) ? body.entry : undefined,
|
|
23
|
-
isRecord(body.record) ? body.record : undefined,
|
|
24
|
-
isRecord(body.directory) ? body.directory : undefined,
|
|
25
|
-
isRecord(body.node) ? body.node : undefined
|
|
26
|
-
].filter((candidate) => Boolean(candidate));
|
|
27
|
-
}
|
|
28
|
-
function extractDirectoryStatus(body) {
|
|
29
|
-
for (const entry of directoryEntryCandidates(body)) {
|
|
30
|
-
const status = readRecordString(entry, "status").toLowerCase();
|
|
31
|
-
if (status) {
|
|
32
|
-
return status;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
return "";
|
|
36
|
-
}
|
|
37
|
-
function extractDirectoryNodeEndpoint(body) {
|
|
38
|
-
for (const entry of directoryEntryCandidates(body)) {
|
|
39
|
-
for (const key of [
|
|
40
|
-
"nodeEndpoint",
|
|
41
|
-
"endpoint",
|
|
42
|
-
"publicUrl"
|
|
43
|
-
]) {
|
|
44
|
-
const value = readRecordString(entry, key);
|
|
45
|
-
if (value) {
|
|
46
|
-
return value;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
return "";
|
|
51
|
-
}
|
|
52
|
-
function buildAuthHeaders(apiToken) {
|
|
53
|
-
const token = trimString(apiToken);
|
|
54
|
-
return token ? { Authorization: `Bearer ${token}` } : {};
|
|
55
|
-
}
|
|
56
15
|
function safeRefSegment(value) {
|
|
57
16
|
return value.trim().toLowerCase().replace(/[^a-z0-9._:-]+/gu, "-").replace(/^-+|-+$/gu, "").slice(0, 96);
|
|
58
17
|
}
|
|
@@ -108,15 +67,37 @@ async function postWebhookDelivery(params) {
|
|
|
108
67
|
};
|
|
109
68
|
}
|
|
110
69
|
try {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
70
|
+
if (new URL(url).protocol !== "https:") {
|
|
71
|
+
return {
|
|
72
|
+
ok: false,
|
|
73
|
+
reason: "webhook delivery requires HTTPS"
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
} catch {
|
|
77
|
+
return {
|
|
78
|
+
ok: false,
|
|
79
|
+
reason: "webhook delivery target has an invalid URL"
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
let guarded;
|
|
83
|
+
try {
|
|
84
|
+
guarded = await fetchWithSsrFGuard({
|
|
85
|
+
url,
|
|
86
|
+
fetchImpl: params.fetchImpl,
|
|
87
|
+
lookupFn: params.ssrfLookupFn,
|
|
88
|
+
timeoutMs: FEDERATION_DELIVERY_TIMEOUT_MS,
|
|
89
|
+
auditContext: "marketplace-content-webhook",
|
|
90
|
+
init: {
|
|
91
|
+
method: "POST",
|
|
92
|
+
headers: {
|
|
93
|
+
"content-type": "application/json",
|
|
94
|
+
"x-fased-marketplace-delivery": "content.summarize",
|
|
95
|
+
"x-fased-marketplace-order": params.orderId
|
|
96
|
+
},
|
|
97
|
+
body: JSON.stringify(params.payload)
|
|
98
|
+
}
|
|
119
99
|
});
|
|
100
|
+
const response = guarded.response;
|
|
120
101
|
if (!response.ok) {
|
|
121
102
|
return {
|
|
122
103
|
ok: false,
|
|
@@ -129,6 +110,8 @@ async function postWebhookDelivery(params) {
|
|
|
129
110
|
ok: false,
|
|
130
111
|
reason: error instanceof Error ? error.message : String(error)
|
|
131
112
|
};
|
|
113
|
+
} finally {
|
|
114
|
+
await guarded?.release();
|
|
132
115
|
}
|
|
133
116
|
}
|
|
134
117
|
async function postFederationDelivery(params) {
|
|
@@ -142,7 +125,15 @@ async function postFederationDelivery(params) {
|
|
|
142
125
|
if (!endpointResult.ok) {
|
|
143
126
|
return endpointResult;
|
|
144
127
|
}
|
|
128
|
+
if (!handle) {
|
|
129
|
+
return {
|
|
130
|
+
ok: false,
|
|
131
|
+
blocked: true,
|
|
132
|
+
reason: "federation delivery target is missing the verified recipient handle"
|
|
133
|
+
};
|
|
134
|
+
}
|
|
145
135
|
let url;
|
|
136
|
+
let guarded;
|
|
146
137
|
try {
|
|
147
138
|
url = new URL("/api/federation/marketplace/deliveries", endpointResult.endpoint);
|
|
148
139
|
} catch {
|
|
@@ -151,17 +142,46 @@ async function postFederationDelivery(params) {
|
|
|
151
142
|
reason: "federation delivery target has an invalid node endpoint"
|
|
152
143
|
};
|
|
153
144
|
}
|
|
145
|
+
if (!isTrustedFederationPeerUrl(url)) {
|
|
146
|
+
return {
|
|
147
|
+
ok: false,
|
|
148
|
+
blocked: true,
|
|
149
|
+
reason: "federation delivery endpoint must use HTTPS (plain HTTP is allowed only for an explicit loopback URL)"
|
|
150
|
+
};
|
|
151
|
+
}
|
|
154
152
|
try {
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
153
|
+
const federationBaseUrl = trimString(params.federationBaseUrl) || resolveFederationBaseUrl(process.env);
|
|
154
|
+
const senderHandle = resolveFederationHandle({
|
|
155
|
+
env: process.env,
|
|
156
|
+
fallbackDomain: federationBaseUrl ? new URL(federationBaseUrl).hostname : "localhost"
|
|
157
|
+
});
|
|
158
|
+
const signedRequest = buildSignedFederationPeerRequest({
|
|
159
|
+
senderHandle,
|
|
160
|
+
recipientHandle: handle,
|
|
161
|
+
path: FEDERATION_MARKETPLACE_DELIVERY_PATH,
|
|
162
|
+
body: params.payload,
|
|
163
|
+
env: process.env
|
|
164
|
+
});
|
|
165
|
+
guarded = await fetchWithSsrFGuard({
|
|
166
|
+
url: url.toString(),
|
|
167
|
+
fetchImpl: params.fetchImpl,
|
|
168
|
+
lookupFn: params.ssrfLookupFn,
|
|
169
|
+
maxRedirects: 0,
|
|
170
|
+
timeoutMs: FEDERATION_DELIVERY_TIMEOUT_MS,
|
|
171
|
+
auditContext: "marketplace-federation-delivery",
|
|
172
|
+
init: {
|
|
173
|
+
method: "POST",
|
|
174
|
+
headers: {
|
|
175
|
+
"content-type": "application/json",
|
|
176
|
+
"x-fased-marketplace-delivery": "content.summarize",
|
|
177
|
+
"x-fased-marketplace-order": params.orderId,
|
|
178
|
+
"x-fased-federation-recipient": handle,
|
|
179
|
+
...signedRequest.headers
|
|
180
|
+
},
|
|
181
|
+
body: signedRequest.body
|
|
182
|
+
}
|
|
164
183
|
});
|
|
184
|
+
const response = guarded.response;
|
|
165
185
|
if (!response.ok) {
|
|
166
186
|
return {
|
|
167
187
|
ok: false,
|
|
@@ -174,50 +194,55 @@ async function postFederationDelivery(params) {
|
|
|
174
194
|
ok: false,
|
|
175
195
|
reason: error instanceof Error ? error.message : String(error)
|
|
176
196
|
};
|
|
197
|
+
} finally {
|
|
198
|
+
await guarded?.release();
|
|
177
199
|
}
|
|
178
200
|
}
|
|
179
201
|
async function resolveFederationDeliveryEndpoint(params) {
|
|
180
202
|
const explicitEndpoint = trimString(params.target.federation?.nodeEndpoint);
|
|
181
|
-
if (explicitEndpoint) {
|
|
182
|
-
return {
|
|
183
|
-
ok: true,
|
|
184
|
-
endpoint: explicitEndpoint
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
203
|
const handle = trimString(params.target.federation?.handle);
|
|
188
204
|
if (!handle) {
|
|
189
205
|
return {
|
|
190
206
|
ok: false,
|
|
191
207
|
blocked: true,
|
|
192
|
-
reason: "federation delivery target is missing
|
|
208
|
+
reason: "federation delivery target is missing the verified recipient handle"
|
|
193
209
|
};
|
|
194
210
|
}
|
|
195
|
-
const
|
|
196
|
-
|
|
211
|
+
const canonicalDeliveryUrl = (endpoint) => {
|
|
212
|
+
try {
|
|
213
|
+
const endpointUrl = new URL(endpoint);
|
|
214
|
+
if (!isTrustedFederationPeerUrl(endpointUrl)) {
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
const deliveryUrl = new URL(FEDERATION_MARKETPLACE_DELIVERY_PATH, endpointUrl);
|
|
218
|
+
return isTrustedFederationPeerUrl(deliveryUrl) ? deliveryUrl : null;
|
|
219
|
+
} catch {
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
const explicitDeliveryUrl = explicitEndpoint ? canonicalDeliveryUrl(explicitEndpoint) : undefined;
|
|
224
|
+
if (explicitEndpoint && !explicitDeliveryUrl) {
|
|
197
225
|
return {
|
|
198
226
|
ok: false,
|
|
199
227
|
blocked: true,
|
|
200
|
-
reason: "federation
|
|
228
|
+
reason: "federation delivery endpoint must use HTTPS (plain HTTP is allowed only for an explicit loopback URL)"
|
|
201
229
|
};
|
|
202
230
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
directoryUrl = new URL(`/api/federation/directory/${encodeURIComponent(handle)}`, baseUrl);
|
|
206
|
-
} catch {
|
|
231
|
+
const baseUrl = trimString(params.federationBaseUrl) || resolveFederationBaseUrl();
|
|
232
|
+
if (!baseUrl) {
|
|
207
233
|
return {
|
|
208
234
|
ok: false,
|
|
209
235
|
blocked: true,
|
|
210
|
-
reason: "federation directory base URL is
|
|
236
|
+
reason: "federation directory base URL is not configured"
|
|
211
237
|
};
|
|
212
238
|
}
|
|
213
|
-
let
|
|
239
|
+
let directoryIdentity;
|
|
214
240
|
try {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
}
|
|
241
|
+
directoryIdentity = await lookupFederationPeerDirectory({
|
|
242
|
+
senderHandle: handle,
|
|
243
|
+
baseUrl,
|
|
244
|
+
apiToken: params.federationApiToken ?? process.env.FASED_FEDERATION_API_TOKEN,
|
|
245
|
+
fetchImpl: params.fetchImpl
|
|
221
246
|
});
|
|
222
247
|
} catch (error) {
|
|
223
248
|
return {
|
|
@@ -226,42 +251,53 @@ async function resolveFederationDeliveryEndpoint(params) {
|
|
|
226
251
|
reason: `federation directory lookup failed: ${error instanceof Error ? error.message : String(error)}`
|
|
227
252
|
};
|
|
228
253
|
}
|
|
229
|
-
if (
|
|
254
|
+
if (directoryIdentity.status !== "verified") {
|
|
230
255
|
return {
|
|
231
256
|
ok: false,
|
|
232
257
|
blocked: true,
|
|
233
|
-
reason: `federation directory
|
|
258
|
+
reason: `federation directory status is ${directoryIdentity.status || "unverified"}`
|
|
234
259
|
};
|
|
235
260
|
}
|
|
236
|
-
|
|
237
|
-
try {
|
|
238
|
-
body = await response.json();
|
|
239
|
-
} catch {
|
|
261
|
+
if (directoryIdentity.handle && directoryIdentity.handle.trim().toLowerCase() !== handle.toLowerCase()) {
|
|
240
262
|
return {
|
|
241
263
|
ok: false,
|
|
242
264
|
blocked: true,
|
|
243
|
-
reason: "federation directory
|
|
265
|
+
reason: "federation directory returned a different recipient handle"
|
|
244
266
|
};
|
|
245
267
|
}
|
|
246
|
-
|
|
247
|
-
if (status === "blocked" || status === "revoked") {
|
|
268
|
+
if (!directoryIdentity.supportsProtocolV2) {
|
|
248
269
|
return {
|
|
249
270
|
ok: false,
|
|
250
271
|
blocked: true,
|
|
251
|
-
reason:
|
|
272
|
+
reason: FEDERATION_PROTOCOL_V2_UPGRADE_ERROR
|
|
252
273
|
};
|
|
253
274
|
}
|
|
254
|
-
const
|
|
255
|
-
if (!
|
|
275
|
+
const registeredEndpoint = trimString(directoryIdentity.nodeEndpoint);
|
|
276
|
+
if (!registeredEndpoint) {
|
|
256
277
|
return {
|
|
257
278
|
ok: false,
|
|
258
279
|
blocked: true,
|
|
259
280
|
reason: "federation directory entry did not include a node endpoint"
|
|
260
281
|
};
|
|
261
282
|
}
|
|
283
|
+
const registeredDeliveryUrl = canonicalDeliveryUrl(registeredEndpoint);
|
|
284
|
+
if (!registeredDeliveryUrl) {
|
|
285
|
+
return {
|
|
286
|
+
ok: false,
|
|
287
|
+
blocked: true,
|
|
288
|
+
reason: "verified federation directory endpoint must use HTTPS (plain HTTP is allowed only for an explicit loopback URL)"
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
if (explicitDeliveryUrl && explicitDeliveryUrl.href !== registeredDeliveryUrl.href) {
|
|
292
|
+
return {
|
|
293
|
+
ok: false,
|
|
294
|
+
blocked: true,
|
|
295
|
+
reason: "explicit federation node endpoint does not match the verified directory endpoint"
|
|
296
|
+
};
|
|
297
|
+
}
|
|
262
298
|
return {
|
|
263
299
|
ok: true,
|
|
264
|
-
endpoint
|
|
300
|
+
endpoint: registeredDeliveryUrl.href
|
|
265
301
|
};
|
|
266
302
|
}
|
|
267
303
|
function buildChannelDeliveryText(params) {
|
|
@@ -376,140 +412,241 @@ async function deliverMarketplaceContentSummarizeResult(params) {
|
|
|
376
412
|
artifactRef,
|
|
377
413
|
updatedAt: now
|
|
378
414
|
};
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
...baseDelivery,
|
|
386
|
-
status: "blocked",
|
|
387
|
-
notes: `content.summarize completed, but delivery target ${targetDescriptor} is ${targetStatus}. Result is retained in the Fased app inbox for manual handling.`
|
|
388
|
-
};
|
|
389
|
-
message = `Order ${order.id ?? orderId} completed, but delivery is blocked by target status ${targetStatus}.`;
|
|
390
|
-
} else if (targetKind === "app-inbox" || targetKind === "artifact") {
|
|
391
|
-
orderStatus = "delivered";
|
|
392
|
-
delivered = true;
|
|
393
|
-
delivery = {
|
|
394
|
-
...baseDelivery,
|
|
395
|
-
status: "delivered",
|
|
396
|
-
notes: `Delivered content.summarize result to ${targetDescriptor}. External delivery adapters were not used.`,
|
|
397
|
-
deliveredAt: now
|
|
398
|
-
};
|
|
399
|
-
message = `Order ${order.id ?? orderId} delivered to ${targetDescriptor}.`;
|
|
400
|
-
} else if (targetKind === "webhook") {
|
|
401
|
-
const webhookResult = await postWebhookDelivery({
|
|
402
|
-
fetchImpl,
|
|
403
|
-
target,
|
|
404
|
-
payload: buildDeliveryPayload({
|
|
405
|
-
order,
|
|
406
|
-
target,
|
|
407
|
-
result: params.result,
|
|
408
|
-
resultRef,
|
|
409
|
-
artifactRef,
|
|
410
|
-
deliveredAt: now
|
|
411
|
-
}),
|
|
412
|
-
orderId: order.id ?? orderId
|
|
413
|
-
});
|
|
414
|
-
if (webhookResult.ok) {
|
|
415
|
-
orderStatus = "delivered";
|
|
416
|
-
delivered = true;
|
|
415
|
+
const performDeliveryOutcome = async () => {
|
|
416
|
+
let orderStatus = "running";
|
|
417
|
+
let delivery;
|
|
418
|
+
let delivered = false;
|
|
419
|
+
let message = "";
|
|
420
|
+
if (targetStatus !== "ready") {
|
|
417
421
|
delivery = {
|
|
418
422
|
...baseDelivery,
|
|
419
|
-
status: "
|
|
420
|
-
notes: `
|
|
421
|
-
deliveredAt: now
|
|
423
|
+
status: "blocked",
|
|
424
|
+
notes: `content.summarize completed, but delivery target ${targetDescriptor} is ${targetStatus}. Result is retained in the Fased app inbox for manual handling.`
|
|
422
425
|
};
|
|
423
|
-
message = `Order ${order.id ?? orderId}
|
|
424
|
-
} else {
|
|
425
|
-
delivery = {
|
|
426
|
-
...baseDelivery,
|
|
427
|
-
status: "failed",
|
|
428
|
-
notes: `Webhook delivery failed: ${webhookResult.reason}. Result is retained in the Fased app inbox for manual handling.`
|
|
429
|
-
};
|
|
430
|
-
message = `Order ${order.id ?? orderId} completed, but webhook delivery failed.`;
|
|
431
|
-
}
|
|
432
|
-
} else if (targetKind === "channel" && trimString(target.channel?.provider).toLowerCase() === "telegram") {
|
|
433
|
-
const channelResult = await sendTelegramChannelDelivery({
|
|
434
|
-
config: params.config,
|
|
435
|
-
deliverOutboundPayloadsImpl,
|
|
436
|
-
outboundSendDeps: params.deps?.outboundSendDeps,
|
|
437
|
-
target,
|
|
438
|
-
text: buildChannelDeliveryText({
|
|
439
|
-
order,
|
|
440
|
-
result: params.result,
|
|
441
|
-
resultRef
|
|
442
|
-
})
|
|
443
|
-
});
|
|
444
|
-
if (channelResult.ok) {
|
|
426
|
+
message = `Order ${order.id ?? orderId} completed, but delivery is blocked by target status ${targetStatus}.`;
|
|
427
|
+
} else if (targetKind === "app-inbox" || targetKind === "artifact") {
|
|
445
428
|
orderStatus = "delivered";
|
|
446
429
|
delivered = true;
|
|
447
430
|
delivery = {
|
|
448
431
|
...baseDelivery,
|
|
449
432
|
status: "delivered",
|
|
450
|
-
notes: `Delivered content.summarize result to
|
|
433
|
+
notes: `Delivered content.summarize result to ${targetDescriptor}. External delivery adapters were not used.`,
|
|
451
434
|
deliveredAt: now
|
|
452
435
|
};
|
|
453
|
-
message = `Order ${order.id ?? orderId} delivered to
|
|
436
|
+
message = `Order ${order.id ?? orderId} delivered to ${targetDescriptor}.`;
|
|
437
|
+
} else if (targetKind === "webhook") {
|
|
438
|
+
const webhookResult = await postWebhookDelivery({
|
|
439
|
+
fetchImpl,
|
|
440
|
+
ssrfLookupFn: params.deps?.ssrfLookupFn,
|
|
441
|
+
target,
|
|
442
|
+
payload: buildDeliveryPayload({
|
|
443
|
+
order,
|
|
444
|
+
target,
|
|
445
|
+
result: params.result,
|
|
446
|
+
resultRef,
|
|
447
|
+
artifactRef,
|
|
448
|
+
deliveredAt: now
|
|
449
|
+
}),
|
|
450
|
+
orderId: order.id ?? orderId
|
|
451
|
+
});
|
|
452
|
+
if (webhookResult.ok) {
|
|
453
|
+
orderStatus = "delivered";
|
|
454
|
+
delivered = true;
|
|
455
|
+
delivery = {
|
|
456
|
+
...baseDelivery,
|
|
457
|
+
status: "delivered",
|
|
458
|
+
notes: `Delivered content.summarize result to webhook ${targetDescriptor}.`,
|
|
459
|
+
deliveredAt: now
|
|
460
|
+
};
|
|
461
|
+
message = `Order ${order.id ?? orderId} delivered to webhook ${targetDescriptor}.`;
|
|
462
|
+
} else {
|
|
463
|
+
delivery = {
|
|
464
|
+
...baseDelivery,
|
|
465
|
+
status: "failed",
|
|
466
|
+
notes: `Webhook delivery failed: ${webhookResult.reason}. Result is retained in the Fased app inbox for manual handling.`
|
|
467
|
+
};
|
|
468
|
+
message = `Order ${order.id ?? orderId} completed, but webhook delivery failed.`;
|
|
469
|
+
}
|
|
470
|
+
} else if (targetKind === "channel" && trimString(target.channel?.provider).toLowerCase() === "telegram") {
|
|
471
|
+
const channelResult = await sendTelegramChannelDelivery({
|
|
472
|
+
config: params.config,
|
|
473
|
+
deliverOutboundPayloadsImpl,
|
|
474
|
+
outboundSendDeps: params.deps?.outboundSendDeps,
|
|
475
|
+
target,
|
|
476
|
+
text: buildChannelDeliveryText({
|
|
477
|
+
order,
|
|
478
|
+
result: params.result,
|
|
479
|
+
resultRef
|
|
480
|
+
})
|
|
481
|
+
});
|
|
482
|
+
if (channelResult.ok) {
|
|
483
|
+
orderStatus = "delivered";
|
|
484
|
+
delivered = true;
|
|
485
|
+
delivery = {
|
|
486
|
+
...baseDelivery,
|
|
487
|
+
status: "delivered",
|
|
488
|
+
notes: `Delivered content.summarize result to Telegram ${targetDescriptor}.`,
|
|
489
|
+
deliveredAt: now
|
|
490
|
+
};
|
|
491
|
+
message = `Order ${order.id ?? orderId} delivered to Telegram ${targetDescriptor}.`;
|
|
492
|
+
} else {
|
|
493
|
+
delivery = {
|
|
494
|
+
...baseDelivery,
|
|
495
|
+
status: "failed",
|
|
496
|
+
notes: `Telegram delivery failed: ${channelResult.reason}. Result is retained in the Fased app inbox for manual handling.`
|
|
497
|
+
};
|
|
498
|
+
message = `Order ${order.id ?? orderId} completed, but Telegram delivery failed.`;
|
|
499
|
+
}
|
|
500
|
+
} else if (targetKind === "federation") {
|
|
501
|
+
const federationResult = await postFederationDelivery({
|
|
502
|
+
fetchImpl,
|
|
503
|
+
ssrfLookupFn: params.deps?.ssrfLookupFn,
|
|
504
|
+
target,
|
|
505
|
+
payload: buildDeliveryPayload({
|
|
506
|
+
order,
|
|
507
|
+
target,
|
|
508
|
+
result: params.result,
|
|
509
|
+
resultRef,
|
|
510
|
+
artifactRef,
|
|
511
|
+
deliveredAt: now
|
|
512
|
+
}),
|
|
513
|
+
orderId: order.id ?? orderId,
|
|
514
|
+
federationBaseUrl: params.deps?.federationBaseUrl,
|
|
515
|
+
federationApiToken: params.deps?.federationApiToken
|
|
516
|
+
});
|
|
517
|
+
if (federationResult.ok) {
|
|
518
|
+
orderStatus = "delivered";
|
|
519
|
+
delivered = true;
|
|
520
|
+
delivery = {
|
|
521
|
+
...baseDelivery,
|
|
522
|
+
status: "delivered",
|
|
523
|
+
notes: `Delivered content.summarize result to federation target ${targetDescriptor}.`,
|
|
524
|
+
deliveredAt: now
|
|
525
|
+
};
|
|
526
|
+
message = `Order ${order.id ?? orderId} delivered to federation target ${targetDescriptor}.`;
|
|
527
|
+
} else {
|
|
528
|
+
const status = federationResult.blocked ? "blocked" : "failed";
|
|
529
|
+
delivery = {
|
|
530
|
+
...baseDelivery,
|
|
531
|
+
status,
|
|
532
|
+
notes: `Federation delivery ${status}: ${federationResult.reason}. Result is retained in the Fased app inbox for manual handling.`
|
|
533
|
+
};
|
|
534
|
+
message = `Order ${order.id ?? orderId} completed, but federation delivery ${status}.`;
|
|
535
|
+
}
|
|
536
|
+
} else if (targetKind === "channel") {
|
|
537
|
+
const provider = trimString(target.channel?.provider) || "channel";
|
|
538
|
+
delivery = {
|
|
539
|
+
...baseDelivery,
|
|
540
|
+
status: "blocked",
|
|
541
|
+
notes: `${provider} delivery adapter is not enabled yet for content.summarize. Result is retained in the Fased app inbox until a dedicated adapter is added.`
|
|
542
|
+
};
|
|
543
|
+
message = `Order ${order.id ?? orderId} completed, but ${provider} delivery needs its adapter.`;
|
|
454
544
|
} else {
|
|
455
545
|
delivery = {
|
|
456
546
|
...baseDelivery,
|
|
457
|
-
status: "
|
|
458
|
-
notes:
|
|
547
|
+
status: "blocked",
|
|
548
|
+
notes: `${targetKind} delivery adapter is not enabled yet for content.summarize. Result is retained in the Fased app inbox until a dedicated adapter is added.`
|
|
459
549
|
};
|
|
460
|
-
message = `Order ${order.id ?? orderId} completed, but
|
|
550
|
+
message = `Order ${order.id ?? orderId} completed, but ${targetKind} delivery needs its adapter.`;
|
|
461
551
|
}
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
552
|
+
return {
|
|
553
|
+
delivered,
|
|
554
|
+
orderStatus,
|
|
555
|
+
targetKind,
|
|
556
|
+
delivery,
|
|
557
|
+
message
|
|
558
|
+
};
|
|
559
|
+
};
|
|
560
|
+
const targetId = trimString(target.targetId) || trimString(order.delivery?.targetId) || "default";
|
|
561
|
+
const deliveryId = `marketplace-delivery:${order.id ?? orderId}:${resultRef}:${targetId}`;
|
|
562
|
+
let reserved;
|
|
563
|
+
try {
|
|
564
|
+
reserved = await reserveMarketplaceDelivery({
|
|
565
|
+
deliveryId,
|
|
566
|
+
orderId: order.id ?? orderId,
|
|
567
|
+
intent: {
|
|
568
|
+
orderId: order.id ?? orderId,
|
|
469
569
|
result: params.result,
|
|
470
570
|
resultRef,
|
|
471
571
|
artifactRef,
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
federationApiToken: params.deps?.federationApiToken
|
|
572
|
+
target,
|
|
573
|
+
targetKind,
|
|
574
|
+
targetStatus
|
|
575
|
+
}
|
|
477
576
|
});
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
577
|
+
} catch (error) {
|
|
578
|
+
return {
|
|
579
|
+
error: error instanceof Error ? error.message : String(error),
|
|
580
|
+
statusCode: 409
|
|
581
|
+
};
|
|
582
|
+
}
|
|
583
|
+
const releaseDelivery = await claimMarketplaceDelivery({ deliveryId });
|
|
584
|
+
if (!releaseDelivery) {
|
|
585
|
+
return {
|
|
586
|
+
error: "marketplace delivery is already in progress",
|
|
587
|
+
statusCode: 409
|
|
588
|
+
};
|
|
589
|
+
}
|
|
590
|
+
let outcome;
|
|
591
|
+
try {
|
|
592
|
+
if (reserved.record.outcome && [
|
|
593
|
+
"delivered",
|
|
594
|
+
"blocked",
|
|
595
|
+
"unknown"
|
|
596
|
+
].includes(reserved.record.state)) {
|
|
597
|
+
outcome = reserved.record.outcome;
|
|
598
|
+
} else if (!reserved.created && reserved.record.state === "delivering") {
|
|
599
|
+
outcome = {
|
|
600
|
+
delivered: false,
|
|
601
|
+
orderStatus: "running",
|
|
602
|
+
targetKind,
|
|
603
|
+
delivery: {
|
|
604
|
+
...baseDelivery,
|
|
605
|
+
status: "failed",
|
|
606
|
+
notes: "Delivery outcome is unknown after an interrupted external send. Automatic retry is disabled; reconcile the recipient before creating a new delivery intent."
|
|
607
|
+
},
|
|
608
|
+
message: `Order ${order.id ?? orderId} delivery outcome is unknown and requires reconciliation.`
|
|
486
609
|
};
|
|
487
|
-
|
|
610
|
+
await updateMarketplaceDeliveryOutbox({
|
|
611
|
+
deliveryId,
|
|
612
|
+
expectedStates: ["delivering"],
|
|
613
|
+
state: "unknown",
|
|
614
|
+
outcome,
|
|
615
|
+
reason: outcome.delivery.notes
|
|
616
|
+
});
|
|
488
617
|
} else {
|
|
489
|
-
const
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
618
|
+
const externalDelivery = targetStatus === "ready" && (targetKind === "webhook" || targetKind === "federation" || targetKind === "channel" && trimString(target.channel?.provider).toLowerCase() === "telegram");
|
|
619
|
+
if (externalDelivery) {
|
|
620
|
+
await updateMarketplaceDeliveryOutbox({
|
|
621
|
+
deliveryId,
|
|
622
|
+
expectedStates: ["reserved"],
|
|
623
|
+
state: "delivering"
|
|
624
|
+
});
|
|
625
|
+
}
|
|
626
|
+
outcome = await performDeliveryOutcome();
|
|
627
|
+
const ambiguous = externalDelivery && outcome.delivery.status === "failed";
|
|
628
|
+
if (ambiguous) {
|
|
629
|
+
outcome.delivery = {
|
|
630
|
+
...outcome.delivery,
|
|
631
|
+
notes: `${outcome.delivery.notes ?? "External delivery failed."} The outcome is treated as unknown and will not be retried automatically.`
|
|
632
|
+
};
|
|
633
|
+
outcome.message = `${outcome.message} Delivery outcome is unknown; reconcile it manually before retrying.`;
|
|
634
|
+
}
|
|
635
|
+
await updateMarketplaceDeliveryOutbox({
|
|
636
|
+
deliveryId,
|
|
637
|
+
expectedStates: externalDelivery ? ["delivering"] : ["reserved"],
|
|
638
|
+
state: outcome.delivered ? "delivered" : ambiguous ? "unknown" : "blocked",
|
|
639
|
+
outcome,
|
|
640
|
+
reason: ambiguous ? outcome.delivery.notes : undefined
|
|
641
|
+
});
|
|
496
642
|
}
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
delivery = {
|
|
500
|
-
...baseDelivery,
|
|
501
|
-
status: "blocked",
|
|
502
|
-
notes: `${provider} delivery adapter is not enabled yet for content.summarize. Result is retained in the Fased app inbox until a dedicated adapter is added.`
|
|
503
|
-
};
|
|
504
|
-
message = `Order ${order.id ?? orderId} completed, but ${provider} delivery needs its adapter.`;
|
|
505
|
-
} else {
|
|
506
|
-
delivery = {
|
|
507
|
-
...baseDelivery,
|
|
508
|
-
status: "blocked",
|
|
509
|
-
notes: `${targetKind} delivery adapter is not enabled yet for content.summarize. Result is retained in the Fased app inbox until a dedicated adapter is added.`
|
|
510
|
-
};
|
|
511
|
-
message = `Order ${order.id ?? orderId} completed, but ${targetKind} delivery needs its adapter.`;
|
|
643
|
+
} finally {
|
|
644
|
+
await releaseDelivery();
|
|
512
645
|
}
|
|
646
|
+
const { orderStatus, delivery, delivered, message } = outcome;
|
|
647
|
+
const escrowStatus = order.settlement?.escrow?.status;
|
|
648
|
+
const escrowClosed = escrowStatus === "released" || escrowStatus === "refunded" || escrowStatus === "cancelled";
|
|
649
|
+
const settlementStatusAfterDelivery = order.settlement?.mode !== "escrow" ? "settled" : order.settlement.status === "released" || order.settlement.status === "cancelled" || order.settlement.status === "failed" || order.settlement.status === "disputed" ? order.settlement.status : "held";
|
|
513
650
|
const updated = upsertMarketplaceOrderConfig({
|
|
514
651
|
config: params.config,
|
|
515
652
|
input: {
|
|
@@ -525,7 +662,7 @@ async function deliverMarketplaceContentSummarizeResult(params) {
|
|
|
525
662
|
settlement: {
|
|
526
663
|
...order.settlement,
|
|
527
664
|
mode: order.settlement?.mode ?? "direct",
|
|
528
|
-
status: payment?.status === "verified" ?
|
|
665
|
+
status: payment?.status === "verified" ? settlementStatusAfterDelivery : "submitted",
|
|
529
666
|
amount: order.settlement?.amount ?? order.paymentIntent?.amount,
|
|
530
667
|
currency: order.settlement?.currency ?? order.paymentIntent?.currency,
|
|
531
668
|
chain: order.settlement?.chain ?? order.paymentIntent?.chain,
|
|
@@ -539,13 +676,12 @@ async function deliverMarketplaceContentSummarizeResult(params) {
|
|
|
539
676
|
payeeAddress: order.settlement?.payeeAddress ?? order.paymentIntent?.payeeAddress,
|
|
540
677
|
escrow: {
|
|
541
678
|
...order.settlement?.escrow,
|
|
542
|
-
status: order.settlement?.mode === "escrow" ?
|
|
679
|
+
status: order.settlement?.mode === "escrow" ? escrowClosed || escrowStatus === "blocked" ? escrowStatus : "held" : "not_applicable",
|
|
543
680
|
holdPolicy: order.settlement?.escrow?.holdPolicy ?? (order.settlement?.mode === "escrow" ? "release_on_delivery" : "none"),
|
|
544
|
-
releaseRequired: order.settlement?.mode === "escrow",
|
|
545
|
-
...order.settlement?.mode === "escrow" && delivered ? { releasedAt: now } : {},
|
|
681
|
+
releaseRequired: order.settlement?.mode === "escrow" && !escrowClosed,
|
|
546
682
|
updatedAt: now
|
|
547
683
|
},
|
|
548
|
-
notes: order.settlement?.mode === "escrow" ? delivered ? "Escrow
|
|
684
|
+
notes: order.settlement?.mode === "escrow" ? delivered && !escrowClosed ? "Delivery is complete. Escrow remains held until an explicit reviewed release transaction succeeds." : escrowClosed ? order.settlement?.notes : "Escrow settlement verified; release is waiting on delivery or manual review." : "Direct Agent-wallet settlement verified by marketplace payment proof.",
|
|
549
685
|
...payment?.status === "verified" ? { verifiedAt: now } : {},
|
|
550
686
|
...payment?.status === "verified" && order.settlement?.mode !== "escrow" ? { settledAt: now } : {},
|
|
551
687
|
updatedAt: now
|