botmux 2.111.0 → 2.112.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +19 -7
- package/README.md +19 -7
- package/dist/adapters/adopt-route.d.ts.map +1 -1
- package/dist/adapters/adopt-route.js +2 -1
- package/dist/adapters/adopt-route.js.map +1 -1
- package/dist/adapters/backend/herdr-backend.d.ts +29 -0
- package/dist/adapters/backend/herdr-backend.d.ts.map +1 -1
- package/dist/adapters/backend/herdr-backend.js +167 -0
- package/dist/adapters/backend/herdr-backend.js.map +1 -1
- package/dist/adapters/backend/riff-backend.js +2 -2
- package/dist/adapters/backend/sandbox.d.ts +61 -6
- package/dist/adapters/backend/sandbox.d.ts.map +1 -1
- package/dist/adapters/backend/sandbox.js +235 -43
- package/dist/adapters/backend/sandbox.js.map +1 -1
- package/dist/adapters/backend/tmux-backend.d.ts +1 -0
- package/dist/adapters/backend/tmux-backend.d.ts.map +1 -1
- package/dist/adapters/backend/tmux-backend.js +1 -0
- package/dist/adapters/backend/tmux-backend.js.map +1 -1
- package/dist/adapters/cli/claude-code.d.ts +2 -0
- package/dist/adapters/cli/claude-code.d.ts.map +1 -1
- package/dist/adapters/cli/claude-code.js +7 -0
- package/dist/adapters/cli/claude-code.js.map +1 -1
- package/dist/adapters/cli/codex-app-turn.d.ts +16 -0
- package/dist/adapters/cli/codex-app-turn.d.ts.map +1 -1
- package/dist/adapters/cli/codex-app-turn.js +26 -0
- package/dist/adapters/cli/codex-app-turn.js.map +1 -1
- package/dist/adapters/cli/codex.d.ts.map +1 -1
- package/dist/adapters/cli/codex.js +1 -0
- package/dist/adapters/cli/codex.js.map +1 -1
- package/dist/adapters/cli/grok.d.ts +8 -6
- package/dist/adapters/cli/grok.d.ts.map +1 -1
- package/dist/adapters/cli/grok.js +14 -6
- package/dist/adapters/cli/grok.js.map +1 -1
- package/dist/adapters/cli/read-isolation.d.ts +40 -14
- package/dist/adapters/cli/read-isolation.d.ts.map +1 -1
- package/dist/adapters/cli/read-isolation.js +116 -19
- package/dist/adapters/cli/read-isolation.js.map +1 -1
- package/dist/adapters/cli/runner-control-channel.d.ts +32 -0
- package/dist/adapters/cli/runner-control-channel.d.ts.map +1 -0
- package/dist/adapters/cli/runner-control-channel.js +104 -0
- package/dist/adapters/cli/runner-control-channel.js.map +1 -0
- package/dist/adapters/cli/shared-hints.d.ts +1 -1
- package/dist/adapters/cli/shared-hints.d.ts.map +1 -1
- package/dist/adapters/cli/shared-hints.js +9 -0
- package/dist/adapters/cli/shared-hints.js.map +1 -1
- package/dist/adapters/cli/traex.d.ts.map +1 -1
- package/dist/adapters/cli/traex.js +100 -64
- package/dist/adapters/cli/traex.js.map +1 -1
- package/dist/adapters/cli/types.d.ts +13 -0
- package/dist/adapters/cli/types.d.ts.map +1 -1
- package/dist/bot-registry.d.ts +36 -27
- package/dist/bot-registry.d.ts.map +1 -1
- package/dist/bot-registry.js +354 -8
- package/dist/bot-registry.js.map +1 -1
- package/dist/cli/saved-workflow.d.ts +25 -0
- package/dist/cli/saved-workflow.d.ts.map +1 -0
- package/dist/cli/saved-workflow.js +338 -0
- package/dist/cli/saved-workflow.js.map +1 -0
- package/dist/cli/send-dispatch.d.ts +18 -3
- package/dist/cli/send-dispatch.d.ts.map +1 -1
- package/dist/cli/send-dispatch.js +22 -3
- package/dist/cli/send-dispatch.js.map +1 -1
- package/dist/cli/v3-run-cancel.d.ts +47 -0
- package/dist/cli/v3-run-cancel.d.ts.map +1 -0
- package/dist/cli/v3-run-cancel.js +96 -0
- package/dist/cli/v3-run-cancel.js.map +1 -0
- package/dist/cli/vc-agent.d.ts.map +1 -1
- package/dist/cli/vc-agent.js +54 -1
- package/dist/cli/vc-agent.js.map +1 -1
- package/dist/cli/workflow-migration.d.ts +39 -0
- package/dist/cli/workflow-migration.d.ts.map +1 -0
- package/dist/cli/workflow-migration.js +302 -0
- package/dist/cli/workflow-migration.js.map +1 -0
- package/dist/cli/workflow-run-archive.d.ts +29 -0
- package/dist/cli/workflow-run-archive.d.ts.map +1 -0
- package/dist/cli/workflow-run-archive.js +183 -0
- package/dist/cli/workflow-run-archive.js.map +1 -0
- package/dist/cli/workflow.d.ts +5 -10
- package/dist/cli/workflow.d.ts.map +1 -1
- package/dist/cli/workflow.js +85 -764
- package/dist/cli/workflow.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +1018 -191
- package/dist/cli.js.map +1 -1
- package/dist/codex-app-runner.js +30 -21
- package/dist/codex-app-runner.js.map +1 -1
- package/dist/core/command-handler.d.ts.map +1 -1
- package/dist/core/command-handler.js +21 -9
- package/dist/core/command-handler.js.map +1 -1
- package/dist/core/current-turn-provenance.d.ts +39 -0
- package/dist/core/current-turn-provenance.d.ts.map +1 -0
- package/dist/core/current-turn-provenance.js +122 -0
- package/dist/core/current-turn-provenance.js.map +1 -0
- package/dist/core/daemon-ipc-auth.d.ts +20 -0
- package/dist/core/daemon-ipc-auth.d.ts.map +1 -0
- package/dist/core/daemon-ipc-auth.js +44 -0
- package/dist/core/daemon-ipc-auth.js.map +1 -0
- package/dist/core/daemon-ipc-session-auth.d.ts +37 -0
- package/dist/core/daemon-ipc-session-auth.d.ts.map +1 -0
- package/dist/core/daemon-ipc-session-auth.js +35 -0
- package/dist/core/daemon-ipc-session-auth.js.map +1 -0
- package/dist/core/dashboard-command/index.d.ts +0 -2
- package/dist/core/dashboard-command/index.d.ts.map +1 -1
- package/dist/core/dashboard-command/index.js +2 -2
- package/dist/core/dashboard-command/index.js.map +1 -1
- package/dist/core/dashboard-command/stub.d.ts +1 -1
- package/dist/core/dashboard-command/stub.d.ts.map +1 -1
- package/dist/core/dashboard-command/stub.js +0 -1
- package/dist/core/dashboard-command/stub.js.map +1 -1
- package/dist/core/dashboard-ipc-server.d.ts +11 -2
- package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
- package/dist/core/dashboard-ipc-server.js +266 -41
- package/dist/core/dashboard-ipc-server.js.map +1 -1
- package/dist/core/dashboard-secret.d.ts +3 -0
- package/dist/core/dashboard-secret.d.ts.map +1 -0
- package/dist/core/dashboard-secret.js +7 -0
- package/dist/core/dashboard-secret.js.map +1 -0
- package/dist/core/data-dir.d.ts +24 -0
- package/dist/core/data-dir.d.ts.map +1 -0
- package/dist/core/data-dir.js +48 -0
- package/dist/core/data-dir.js.map +1 -0
- package/dist/core/inflight-input-tracker.d.ts +4 -2
- package/dist/core/inflight-input-tracker.d.ts.map +1 -1
- package/dist/core/inflight-input-tracker.js +6 -5
- package/dist/core/inflight-input-tracker.js.map +1 -1
- package/dist/core/inject-queue-policy.d.ts +70 -0
- package/dist/core/inject-queue-policy.d.ts.map +1 -0
- package/dist/core/inject-queue-policy.js +30 -0
- package/dist/core/inject-queue-policy.js.map +1 -0
- package/dist/core/maintenance.d.ts +1 -1
- package/dist/core/maintenance.d.ts.map +1 -1
- package/dist/core/maintenance.js +3 -2
- package/dist/core/maintenance.js.map +1 -1
- package/dist/core/managed-origin-capability.d.ts +30 -0
- package/dist/core/managed-origin-capability.d.ts.map +1 -0
- package/dist/core/managed-origin-capability.js +88 -0
- package/dist/core/managed-origin-capability.js.map +1 -0
- package/dist/core/role-library.d.ts +15 -0
- package/dist/core/role-library.d.ts.map +1 -0
- package/dist/core/role-library.js +75 -0
- package/dist/core/role-library.js.map +1 -0
- package/dist/core/session-cwd.d.ts +14 -0
- package/dist/core/session-cwd.d.ts.map +1 -0
- package/dist/core/session-cwd.js +17 -0
- package/dist/core/session-cwd.js.map +1 -0
- package/dist/core/session-manager.d.ts +4 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +27 -8
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-marker.d.ts +22 -0
- package/dist/core/session-marker.d.ts.map +1 -1
- package/dist/core/session-marker.js +185 -20
- package/dist/core/session-marker.js.map +1 -1
- package/dist/core/slash-inject.d.ts +15 -0
- package/dist/core/slash-inject.d.ts.map +1 -0
- package/dist/core/slash-inject.js +25 -0
- package/dist/core/slash-inject.js.map +1 -0
- package/dist/core/terminal-url.d.ts +1 -0
- package/dist/core/terminal-url.d.ts.map +1 -1
- package/dist/core/terminal-url.js +14 -8
- package/dist/core/terminal-url.js.map +1 -1
- package/dist/core/terminal-write-auth.d.ts +26 -0
- package/dist/core/terminal-write-auth.d.ts.map +1 -1
- package/dist/core/terminal-write-auth.js +48 -3
- package/dist/core/terminal-write-auth.js.map +1 -1
- package/dist/core/trigger-session.d.ts +24 -1
- package/dist/core/trigger-session.d.ts.map +1 -1
- package/dist/core/trigger-session.js +106 -15
- package/dist/core/trigger-session.js.map +1 -1
- package/dist/core/types.d.ts +26 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +10 -0
- package/dist/core/types.js.map +1 -1
- package/dist/core/worker-pool.d.ts +65 -2
- package/dist/core/worker-pool.d.ts.map +1 -1
- package/dist/core/worker-pool.js +459 -39
- package/dist/core/worker-pool.js.map +1 -1
- package/dist/daemon.d.ts +249 -8
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +7383 -1195
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard/aggregator.d.ts +1 -1
- package/dist/dashboard/aggregator.d.ts.map +1 -1
- package/dist/dashboard/aggregator.js +2 -2
- package/dist/dashboard/aggregator.js.map +1 -1
- package/dist/dashboard/auth.d.ts +3 -8
- package/dist/dashboard/auth.d.ts.map +1 -1
- package/dist/dashboard/auth.js +63 -22
- package/dist/dashboard/auth.js.map +1 -1
- package/dist/dashboard/bot-onboarding.d.ts +5 -0
- package/dist/dashboard/bot-onboarding.d.ts.map +1 -1
- package/dist/dashboard/bot-onboarding.js +37 -0
- package/dist/dashboard/bot-onboarding.js.map +1 -1
- package/dist/dashboard/connector-api.d.ts.map +1 -1
- package/dist/dashboard/connector-api.js +42 -2
- package/dist/dashboard/connector-api.js.map +1 -1
- package/dist/dashboard/daemon-internal-api.d.ts +0 -2
- package/dist/dashboard/daemon-internal-api.d.ts.map +1 -1
- package/dist/dashboard/daemon-internal-api.js +26 -93
- package/dist/dashboard/daemon-internal-api.js.map +1 -1
- package/dist/dashboard/daemon-internal-client.d.ts.map +1 -1
- package/dist/dashboard/daemon-internal-client.js +2 -3
- package/dist/dashboard/daemon-internal-client.js.map +1 -1
- package/dist/dashboard/federation-api.js +1 -1
- package/dist/dashboard/federation-api.js.map +1 -1
- package/dist/dashboard/federation-spoke-api.js +1 -1
- package/dist/dashboard/federation-spoke-api.js.map +1 -1
- package/dist/dashboard/history-senders.d.ts +3 -0
- package/dist/dashboard/history-senders.d.ts.map +1 -1
- package/dist/dashboard/history-senders.js.map +1 -1
- package/dist/dashboard/http.d.ts +4 -0
- package/dist/dashboard/http.d.ts.map +1 -0
- package/dist/dashboard/http.js +6 -0
- package/dist/dashboard/http.js.map +1 -0
- package/dist/dashboard/registry.d.ts +4 -0
- package/dist/dashboard/registry.d.ts.map +1 -1
- package/dist/dashboard/registry.js.map +1 -1
- package/dist/dashboard/trigger-api.js +1 -1
- package/dist/dashboard/trigger-api.js.map +1 -1
- package/dist/dashboard/v3-runs-api.d.ts +13 -10
- package/dist/dashboard/v3-runs-api.d.ts.map +1 -1
- package/dist/dashboard/v3-runs-api.js +121 -4
- package/dist/dashboard/v3-runs-api.js.map +1 -1
- package/dist/dashboard/vc-consumer-profiles-api.d.ts +105 -0
- package/dist/dashboard/vc-consumer-profiles-api.d.ts.map +1 -0
- package/dist/dashboard/vc-consumer-profiles-api.js +312 -0
- package/dist/dashboard/vc-consumer-profiles-api.js.map +1 -0
- package/dist/dashboard/web/app.d.ts.map +1 -1
- package/dist/dashboard/web/app.js +7 -6
- package/dist/dashboard/web/app.js.map +1 -1
- package/dist/dashboard/web/bot-defaults-page.d.ts.map +1 -1
- package/dist/dashboard/web/bot-defaults-page.js +9 -14
- package/dist/dashboard/web/bot-defaults-page.js.map +1 -1
- package/dist/dashboard/web/bot-onboarding.d.ts.map +1 -1
- package/dist/dashboard/web/bot-onboarding.js +7 -3
- package/dist/dashboard/web/bot-onboarding.js.map +1 -1
- package/dist/dashboard/web/connectors-page.d.ts +5 -0
- package/dist/dashboard/web/connectors-page.d.ts.map +1 -1
- package/dist/dashboard/web/connectors-page.js +16 -12
- package/dist/dashboard/web/connectors-page.js.map +1 -1
- package/dist/dashboard/web/create-session-entry.d.ts +4 -0
- package/dist/dashboard/web/create-session-entry.d.ts.map +1 -0
- package/dist/dashboard/web/create-session-entry.js +17 -0
- package/dist/dashboard/web/create-session-entry.js.map +1 -0
- package/dist/dashboard/web/dashboard-components.d.ts +5 -0
- package/dist/dashboard/web/dashboard-components.d.ts.map +1 -1
- package/dist/dashboard/web/dashboard-components.js +29 -4
- package/dist/dashboard/web/dashboard-components.js.map +1 -1
- package/dist/dashboard/web/dashboard-routes.d.ts.map +1 -1
- package/dist/dashboard/web/dashboard-routes.js +0 -1
- package/dist/dashboard/web/dashboard-routes.js.map +1 -1
- package/dist/dashboard/web/i18n.d.ts.map +1 -1
- package/dist/dashboard/web/i18n.js +192 -382
- package/dist/dashboard/web/i18n.js.map +1 -1
- package/dist/dashboard/web/preferences.d.ts +3 -0
- package/dist/dashboard/web/preferences.d.ts.map +1 -1
- package/dist/dashboard/web/preferences.js +18 -0
- package/dist/dashboard/web/preferences.js.map +1 -1
- package/dist/dashboard/web/schedules-page.d.ts.map +1 -1
- package/dist/dashboard/web/schedules-page.js +4 -1
- package/dist/dashboard/web/schedules-page.js.map +1 -1
- package/dist/dashboard/web/sessions-page.d.ts.map +1 -1
- package/dist/dashboard/web/sessions-page.js +64 -18
- package/dist/dashboard/web/sessions-page.js.map +1 -1
- package/dist/dashboard/web/settings-page.d.ts.map +1 -1
- package/dist/dashboard/web/settings-page.js +2 -1
- package/dist/dashboard/web/settings-page.js.map +1 -1
- package/dist/dashboard/web/v3-api.d.ts +12 -2
- package/dist/dashboard/web/v3-api.d.ts.map +1 -1
- package/dist/dashboard/web/v3-api.js +34 -6
- package/dist/dashboard/web/v3-api.js.map +1 -1
- package/dist/dashboard/web/v3-components.d.ts +6 -0
- package/dist/dashboard/web/v3-components.d.ts.map +1 -1
- package/dist/dashboard/web/v3-components.js +66 -23
- package/dist/dashboard/web/v3-components.js.map +1 -1
- package/dist/dashboard/web/v3-model.js +1 -1
- package/dist/dashboard/web/v3-model.js.map +1 -1
- package/dist/dashboard/web/v3-terminal.js +2 -2
- package/dist/dashboard/web/v3-terminal.js.map +1 -1
- package/dist/dashboard/web/vc-consumer-profiles-section.d.ts +19 -0
- package/dist/dashboard/web/vc-consumer-profiles-section.d.ts.map +1 -0
- package/dist/dashboard/web/vc-consumer-profiles-section.js +382 -0
- package/dist/dashboard/web/vc-consumer-profiles-section.js.map +1 -0
- package/dist/dashboard/webhook-routes.d.ts.map +1 -1
- package/dist/dashboard/webhook-routes.js +29 -6
- package/dist/dashboard/webhook-routes.js.map +1 -1
- package/dist/dashboard-web/app.js +1 -1
- package/dist/dashboard-web/chunks/bot-defaults-page-RYBL4ZYE.js +4 -0
- package/dist/dashboard-web/chunks/{chunk-OEJIT66L.js → chunk-CMDPZOPK.js} +1 -1
- package/dist/dashboard-web/chunks/chunk-I35DXGM4.js +1 -0
- package/dist/dashboard-web/chunks/chunk-NYZHARIU.js +47 -0
- package/dist/dashboard-web/chunks/chunk-SZOB6VK2.js +1 -0
- package/dist/dashboard-web/chunks/{chunk-YQFXGRSD.js → chunk-YBOHL7T7.js} +1 -1
- package/dist/dashboard-web/chunks/chunk-YWCPDL4S.js +1 -0
- package/dist/dashboard-web/chunks/connectors-page-DAMP7TTV.js +1 -0
- package/dist/dashboard-web/chunks/{groups-page-5AJPPJH2.js → groups-page-BPFA356N.js} +1 -1
- package/dist/dashboard-web/chunks/{insights-page-R3DFECX4.js → insights-page-SHOPHTWY.js} +1 -1
- package/dist/dashboard-web/chunks/{monitor-room-NLMKJLDY.js → monitor-room-PXPJGZCN.js} +1 -1
- package/dist/dashboard-web/chunks/{monitoring-page-EHSOX4GV.js → monitoring-page-4DF54M5Y.js} +1 -1
- package/dist/dashboard-web/chunks/{office-page-OXJKFJ4R.js → office-page-6OHU6KMZ.js} +1 -1
- package/dist/dashboard-web/chunks/{overview-page-GJHIVXJF.js → overview-page-IHIZ6F5M.js} +1 -1
- package/dist/dashboard-web/chunks/{roles-page-6ZODQISW.js → roles-page-JYTBYKEF.js} +1 -1
- package/dist/dashboard-web/chunks/{schedules-page-DAGMHVCH.js → schedules-page-WJ72T7KV.js} +1 -1
- package/dist/dashboard-web/chunks/sessions-page-QC56OIAI.js +3 -0
- package/dist/dashboard-web/chunks/settings-page-TCKWEXTN.js +2 -0
- package/dist/dashboard-web/chunks/{skills-page-J7EVUHXP.js → skills-page-RJJNIECW.js} +1 -1
- package/dist/dashboard-web/chunks/{team-federation-page-YM5JBIII.js → team-federation-page-ZMDX3E7K.js} +1 -1
- package/dist/dashboard-web/chunks/v3-page-VLLAUQ33.js +94 -0
- package/dist/dashboard-web/chunks/{whiteboards-page-75N2U6W4.js → whiteboards-page-NAO53CKM.js} +1 -1
- package/dist/dashboard-web/style.css +363 -274
- package/dist/dashboard.js +194 -78
- package/dist/dashboard.js.map +1 -1
- package/dist/global-config.d.ts +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +12 -87
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +12 -87
- package/dist/i18n/zh.js.map +1 -1
- package/dist/im/lark/brand-template.d.ts +15 -0
- package/dist/im/lark/brand-template.d.ts.map +1 -0
- package/dist/im/lark/brand-template.js +114 -0
- package/dist/im/lark/brand-template.js.map +1 -0
- package/dist/im/lark/card-handler.d.ts +6 -3
- package/dist/im/lark/card-handler.d.ts.map +1 -1
- package/dist/im/lark/card-handler.js +23 -39
- package/dist/im/lark/card-handler.js.map +1 -1
- package/dist/im/lark/client.d.ts +8 -2
- package/dist/im/lark/client.d.ts.map +1 -1
- package/dist/im/lark/client.js +33 -31
- package/dist/im/lark/client.js.map +1 -1
- package/dist/im/lark/doc-comment.d.ts +18 -0
- package/dist/im/lark/doc-comment.d.ts.map +1 -1
- package/dist/im/lark/doc-comment.js +119 -5
- package/dist/im/lark/doc-comment.js.map +1 -1
- package/dist/im/lark/event-dispatcher.d.ts +18 -2
- package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
- package/dist/im/lark/event-dispatcher.js +41 -19
- package/dist/im/lark/event-dispatcher.js.map +1 -1
- package/dist/im/lark/merge-forward.d.ts.map +1 -1
- package/dist/im/lark/merge-forward.js +7 -2
- package/dist/im/lark/merge-forward.js.map +1 -1
- package/dist/im/lark/message-parser.d.ts.map +1 -1
- package/dist/im/lark/message-parser.js +7 -0
- package/dist/im/lark/message-parser.js.map +1 -1
- package/dist/im/lark/overview-card.d.ts +1 -2
- package/dist/im/lark/overview-card.d.ts.map +1 -1
- package/dist/im/lark/overview-card.js +1 -48
- package/dist/im/lark/overview-card.js.map +1 -1
- package/dist/im/lark/v3-blocked-card-handler.d.ts.map +1 -1
- package/dist/im/lark/v3-blocked-card-handler.js +5 -5
- package/dist/im/lark/v3-blocked-card-handler.js.map +1 -1
- package/dist/im/lark/v3-blocked-card.d.ts +1 -0
- package/dist/im/lark/v3-blocked-card.d.ts.map +1 -1
- package/dist/im/lark/v3-blocked-card.js +19 -2
- package/dist/im/lark/v3-blocked-card.js.map +1 -1
- package/dist/im/lark/v3-distillation-card-handler.d.ts +12 -0
- package/dist/im/lark/v3-distillation-card-handler.d.ts.map +1 -0
- package/dist/im/lark/v3-distillation-card-handler.js +107 -0
- package/dist/im/lark/v3-distillation-card-handler.js.map +1 -0
- package/dist/im/lark/v3-distillation-card.d.ts +42 -0
- package/dist/im/lark/v3-distillation-card.d.ts.map +1 -0
- package/dist/im/lark/v3-distillation-card.js +206 -0
- package/dist/im/lark/v3-distillation-card.js.map +1 -0
- package/dist/im/lark/v3-gate-card-handler.d.ts +1 -1
- package/dist/im/lark/v3-gate-card-handler.d.ts.map +1 -1
- package/dist/im/lark/v3-gate-card-handler.js +6 -5
- package/dist/im/lark/v3-gate-card-handler.js.map +1 -1
- package/dist/im/lark/v3-gate-card.d.ts +8 -1
- package/dist/im/lark/v3-gate-card.d.ts.map +1 -1
- package/dist/im/lark/v3-gate-card.js +38 -7
- package/dist/im/lark/v3-gate-card.js.map +1 -1
- package/dist/im/lark/v3-loop-grant-card-handler.d.ts.map +1 -1
- package/dist/im/lark/v3-loop-grant-card-handler.js +3 -4
- package/dist/im/lark/v3-loop-grant-card-handler.js.map +1 -1
- package/dist/im/lark/v3-loop-grant-card.js +1 -1
- package/dist/im/lark/v3-loop-grant-card.js.map +1 -1
- package/dist/im/lark/v3-progress-card-manager.d.ts +79 -0
- package/dist/im/lark/v3-progress-card-manager.d.ts.map +1 -0
- package/dist/im/lark/v3-progress-card-manager.js +444 -0
- package/dist/im/lark/v3-progress-card-manager.js.map +1 -0
- package/dist/im/lark/v3-progress-card.d.ts +26 -0
- package/dist/im/lark/v3-progress-card.d.ts.map +1 -0
- package/dist/im/lark/v3-progress-card.js +211 -0
- package/dist/im/lark/v3-progress-card.js.map +1 -0
- package/dist/im/lark/v3-revisit-grant-card-handler.d.ts.map +1 -1
- package/dist/im/lark/v3-revisit-grant-card-handler.js +3 -4
- package/dist/im/lark/v3-revisit-grant-card-handler.js.map +1 -1
- package/dist/im/lark/v3-revisit-grant-card.js +1 -1
- package/dist/im/lark/v3-revisit-grant-card.js.map +1 -1
- package/dist/im/lark/v3-run-save-card-handler.d.ts +12 -0
- package/dist/im/lark/v3-run-save-card-handler.d.ts.map +1 -0
- package/dist/im/lark/v3-run-save-card-handler.js +160 -0
- package/dist/im/lark/v3-run-save-card-handler.js.map +1 -0
- package/dist/im/lark/v3-run-save-card.d.ts +38 -0
- package/dist/im/lark/v3-run-save-card.d.ts.map +1 -0
- package/dist/im/lark/v3-run-save-card.js +125 -0
- package/dist/im/lark/v3-run-save-card.js.map +1 -0
- package/dist/im/lark/v3-saved-workflow-command.d.ts +36 -0
- package/dist/im/lark/v3-saved-workflow-command.d.ts.map +1 -0
- package/dist/im/lark/v3-saved-workflow-command.js +186 -0
- package/dist/im/lark/v3-saved-workflow-command.js.map +1 -0
- package/dist/im/lark/v3-saved-workflow-handler.d.ts +89 -0
- package/dist/im/lark/v3-saved-workflow-handler.d.ts.map +1 -0
- package/dist/im/lark/v3-saved-workflow-handler.js +212 -0
- package/dist/im/lark/v3-saved-workflow-handler.js.map +1 -0
- package/dist/im/lark/workflow-slash-command.d.ts +7 -110
- package/dist/im/lark/workflow-slash-command.d.ts.map +1 -1
- package/dist/im/lark/workflow-slash-command.js +16 -230
- package/dist/im/lark/workflow-slash-command.js.map +1 -1
- package/dist/index-daemon.js +1 -1
- package/dist/index-daemon.js.map +1 -1
- package/dist/mir-runner.js +11 -15
- package/dist/mir-runner.js.map +1 -1
- package/dist/mira-runner.js +8 -12
- package/dist/mira-runner.js.map +1 -1
- package/dist/services/bridge-turn-queue.d.ts +29 -12
- package/dist/services/bridge-turn-queue.d.ts.map +1 -1
- package/dist/services/bridge-turn-queue.js +59 -23
- package/dist/services/bridge-turn-queue.js.map +1 -1
- package/dist/services/claude-transcript.d.ts +15 -0
- package/dist/services/claude-transcript.d.ts.map +1 -1
- package/dist/services/claude-transcript.js +24 -0
- package/dist/services/claude-transcript.js.map +1 -1
- package/dist/services/codex-bridge-queue.d.ts +13 -2
- package/dist/services/codex-bridge-queue.d.ts.map +1 -1
- package/dist/services/codex-bridge-queue.js +20 -3
- package/dist/services/codex-bridge-queue.js.map +1 -1
- package/dist/services/codex-transcript.d.ts +6 -0
- package/dist/services/codex-transcript.d.ts.map +1 -1
- package/dist/services/codex-transcript.js.map +1 -1
- package/dist/services/grok-transcript.d.ts +3 -2
- package/dist/services/grok-transcript.d.ts.map +1 -1
- package/dist/services/grok-transcript.js +73 -22
- package/dist/services/grok-transcript.js.map +1 -1
- package/dist/services/hook-runner.d.ts.map +1 -1
- package/dist/services/hook-runner.js +26 -3
- package/dist/services/hook-runner.js.map +1 -1
- package/dist/services/schedule-store.d.ts +37 -0
- package/dist/services/schedule-store.d.ts.map +1 -1
- package/dist/services/schedule-store.js +259 -141
- package/dist/services/schedule-store.js.map +1 -1
- package/dist/services/send-policy.d.ts +50 -0
- package/dist/services/send-policy.d.ts.map +1 -1
- package/dist/services/send-policy.js +65 -0
- package/dist/services/send-policy.js.map +1 -1
- package/dist/services/session-lifecycle-hooks.d.ts.map +1 -1
- package/dist/services/session-lifecycle-hooks.js +12 -0
- package/dist/services/session-lifecycle-hooks.js.map +1 -1
- package/dist/services/traex-transcript.d.ts +11 -2
- package/dist/services/traex-transcript.d.ts.map +1 -1
- package/dist/services/traex-transcript.js +142 -8
- package/dist/services/traex-transcript.js.map +1 -1
- package/dist/services/trigger-types.d.ts +6 -1
- package/dist/services/trigger-types.d.ts.map +1 -1
- package/dist/services/trigger-types.js.map +1 -1
- package/dist/services/turn-terminal-deduper.d.ts +14 -0
- package/dist/services/turn-terminal-deduper.d.ts.map +1 -0
- package/dist/services/turn-terminal-deduper.js +34 -0
- package/dist/services/turn-terminal-deduper.js.map +1 -0
- package/dist/services/vc-meeting-action-gate.d.ts +246 -0
- package/dist/services/vc-meeting-action-gate.d.ts.map +1 -0
- package/dist/services/vc-meeting-action-gate.js +756 -0
- package/dist/services/vc-meeting-action-gate.js.map +1 -0
- package/dist/services/vc-meeting-action-store.d.ts +222 -0
- package/dist/services/vc-meeting-action-store.d.ts.map +1 -0
- package/dist/services/vc-meeting-action-store.js +806 -0
- package/dist/services/vc-meeting-action-store.js.map +1 -0
- package/dist/services/vc-meeting-consumer-isolation.d.ts +27 -0
- package/dist/services/vc-meeting-consumer-isolation.d.ts.map +1 -0
- package/dist/services/vc-meeting-consumer-isolation.js +37 -0
- package/dist/services/vc-meeting-consumer-isolation.js.map +1 -0
- package/dist/services/vc-meeting-consumer-profile-bootstrap.d.ts +72 -0
- package/dist/services/vc-meeting-consumer-profile-bootstrap.d.ts.map +1 -0
- package/dist/services/vc-meeting-consumer-profile-bootstrap.js +343 -0
- package/dist/services/vc-meeting-consumer-profile-bootstrap.js.map +1 -0
- package/dist/services/vc-meeting-consumer-profile-store.d.ts +39 -0
- package/dist/services/vc-meeting-consumer-profile-store.d.ts.map +1 -0
- package/dist/services/vc-meeting-consumer-profile-store.js +190 -0
- package/dist/services/vc-meeting-consumer-profile-store.js.map +1 -0
- package/dist/services/vc-meeting-daemon-auth.d.ts +29 -0
- package/dist/services/vc-meeting-daemon-auth.d.ts.map +1 -0
- package/dist/services/vc-meeting-daemon-auth.js +117 -0
- package/dist/services/vc-meeting-daemon-auth.js.map +1 -0
- package/dist/services/vc-meeting-delivery-feed.d.ts +52 -0
- package/dist/services/vc-meeting-delivery-feed.d.ts.map +1 -0
- package/dist/services/vc-meeting-delivery-feed.js +231 -0
- package/dist/services/vc-meeting-delivery-feed.js.map +1 -0
- package/dist/services/vc-meeting-delivery-hub-store.d.ts +213 -0
- package/dist/services/vc-meeting-delivery-hub-store.d.ts.map +1 -0
- package/dist/services/vc-meeting-delivery-hub-store.js +1230 -0
- package/dist/services/vc-meeting-delivery-hub-store.js.map +1 -0
- package/dist/services/vc-meeting-delivery-protocol.d.ts +159 -0
- package/dist/services/vc-meeting-delivery-protocol.d.ts.map +1 -0
- package/dist/services/vc-meeting-delivery-protocol.js +443 -0
- package/dist/services/vc-meeting-delivery-protocol.js.map +1 -0
- package/dist/services/vc-meeting-delivery-receiver.d.ts +80 -0
- package/dist/services/vc-meeting-delivery-receiver.d.ts.map +1 -0
- package/dist/services/vc-meeting-delivery-receiver.js +543 -0
- package/dist/services/vc-meeting-delivery-receiver.js.map +1 -0
- package/dist/services/vc-meeting-delivery-store.d.ts +339 -0
- package/dist/services/vc-meeting-delivery-store.d.ts.map +1 -0
- package/dist/services/vc-meeting-delivery-store.js +1024 -0
- package/dist/services/vc-meeting-delivery-store.js.map +1 -0
- package/dist/services/vc-meeting-feed-metadata-store.d.ts +58 -0
- package/dist/services/vc-meeting-feed-metadata-store.d.ts.map +1 -0
- package/dist/services/vc-meeting-feed-metadata-store.js +356 -0
- package/dist/services/vc-meeting-feed-metadata-store.js.map +1 -0
- package/dist/services/vc-meeting-im-reply.d.ts +55 -0
- package/dist/services/vc-meeting-im-reply.d.ts.map +1 -0
- package/dist/services/vc-meeting-im-reply.js +279 -0
- package/dist/services/vc-meeting-im-reply.js.map +1 -0
- package/dist/services/vc-meeting-im-routing.d.ts +131 -0
- package/dist/services/vc-meeting-im-routing.d.ts.map +1 -0
- package/dist/services/vc-meeting-im-routing.js +449 -0
- package/dist/services/vc-meeting-im-routing.js.map +1 -0
- package/dist/services/vc-meeting-listener-message-store.d.ts +23 -0
- package/dist/services/vc-meeting-listener-message-store.d.ts.map +1 -0
- package/dist/services/vc-meeting-listener-message-store.js +142 -0
- package/dist/services/vc-meeting-listener-message-store.js.map +1 -0
- package/dist/services/vc-meeting-member-policy.d.ts +37 -0
- package/dist/services/vc-meeting-member-policy.d.ts.map +1 -0
- package/dist/services/vc-meeting-member-policy.js +102 -0
- package/dist/services/vc-meeting-member-policy.js.map +1 -0
- package/dist/services/vc-meeting-profile-instructions.d.ts +22 -0
- package/dist/services/vc-meeting-profile-instructions.d.ts.map +1 -0
- package/dist/services/vc-meeting-profile-instructions.js +64 -0
- package/dist/services/vc-meeting-profile-instructions.js.map +1 -0
- package/dist/services/vc-meeting-runtime-store.d.ts +63 -0
- package/dist/services/vc-meeting-runtime-store.d.ts.map +1 -1
- package/dist/services/vc-meeting-runtime-store.js +605 -116
- package/dist/services/vc-meeting-runtime-store.js.map +1 -1
- package/dist/services/vc-meeting-send-policy.d.ts +89 -0
- package/dist/services/vc-meeting-send-policy.d.ts.map +1 -0
- package/dist/services/vc-meeting-send-policy.js +150 -0
- package/dist/services/vc-meeting-send-policy.js.map +1 -0
- package/dist/services/vc-meeting-terminal-reconciler.d.ts +93 -0
- package/dist/services/vc-meeting-terminal-reconciler.d.ts.map +1 -0
- package/dist/services/vc-meeting-terminal-reconciler.js +198 -0
- package/dist/services/vc-meeting-terminal-reconciler.js.map +1 -0
- package/dist/setup/open-platform-automation.d.ts +2 -0
- package/dist/setup/open-platform-automation.d.ts.map +1 -1
- package/dist/setup/open-platform-automation.js +1 -0
- package/dist/setup/open-platform-automation.js.map +1 -1
- package/dist/setup/open-platform-outcome.d.ts +50 -0
- package/dist/setup/open-platform-outcome.d.ts.map +1 -0
- package/dist/setup/open-platform-outcome.js +56 -0
- package/dist/setup/open-platform-outcome.js.map +1 -0
- package/dist/setup/setup-args.d.ts +7 -2
- package/dist/setup/setup-args.d.ts.map +1 -1
- package/dist/setup/setup-args.js +21 -5
- package/dist/setup/setup-args.js.map +1 -1
- package/dist/skills/definitions.d.ts.map +1 -1
- package/dist/skills/definitions.js +66 -54
- package/dist/skills/definitions.js.map +1 -1
- package/dist/skills/injection-mode.d.ts +5 -4
- package/dist/skills/injection-mode.d.ts.map +1 -1
- package/dist/skills/injection-mode.js +19 -10
- package/dist/skills/injection-mode.js.map +1 -1
- package/dist/types.d.ts +187 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/canonical-input-hash.d.ts +5 -0
- package/dist/utils/canonical-input-hash.d.ts.map +1 -0
- package/dist/utils/canonical-input-hash.js +43 -0
- package/dist/utils/canonical-input-hash.js.map +1 -0
- package/dist/utils/canonical-json.d.ts +10 -0
- package/dist/utils/canonical-json.d.ts.map +1 -0
- package/dist/utils/canonical-json.js +23 -0
- package/dist/utils/canonical-json.js.map +1 -0
- package/dist/utils/child-env.d.ts +1 -1
- package/dist/utils/child-env.d.ts.map +1 -1
- package/dist/utils/child-env.js +8 -0
- package/dist/utils/child-env.js.map +1 -1
- package/dist/utils/daemon-discovery.d.ts +4 -0
- package/dist/utils/daemon-discovery.d.ts.map +1 -1
- package/dist/utils/daemon-discovery.js +12 -6
- package/dist/utils/daemon-discovery.js.map +1 -1
- package/dist/utils/file-lock.d.ts.map +1 -1
- package/dist/utils/file-lock.js +696 -102
- package/dist/utils/file-lock.js.map +1 -1
- package/dist/utils/fs-durability.d.ts +20 -0
- package/dist/utils/fs-durability.d.ts.map +1 -0
- package/dist/utils/fs-durability.js +84 -0
- package/dist/utils/fs-durability.js.map +1 -0
- package/dist/utils/global-install.d.ts +5 -2
- package/dist/utils/global-install.d.ts.map +1 -1
- package/dist/utils/global-install.js +22 -4
- package/dist/utils/global-install.js.map +1 -1
- package/dist/utils/herdr-web-history.d.ts +12 -0
- package/dist/utils/herdr-web-history.d.ts.map +1 -0
- package/dist/utils/herdr-web-history.js +74 -0
- package/dist/utils/herdr-web-history.js.map +1 -0
- package/dist/utils/herdr-web-terminal-binding.d.ts +39 -0
- package/dist/utils/herdr-web-terminal-binding.d.ts.map +1 -0
- package/dist/utils/herdr-web-terminal-binding.js +56 -0
- package/dist/utils/herdr-web-terminal-binding.js.map +1 -0
- package/dist/utils/pending-input-queue.d.ts +30 -1
- package/dist/utils/pending-input-queue.d.ts.map +1 -1
- package/dist/utils/pending-input-queue.js +45 -5
- package/dist/utils/pending-input-queue.js.map +1 -1
- package/dist/vc-agent/cards.d.ts +49 -4
- package/dist/vc-agent/cards.d.ts.map +1 -1
- package/dist/vc-agent/cards.js +460 -70
- package/dist/vc-agent/cards.js.map +1 -1
- package/dist/vc-agent/polling-source.d.ts +6 -1
- package/dist/vc-agent/polling-source.d.ts.map +1 -1
- package/dist/vc-agent/polling-source.js +17 -4
- package/dist/vc-agent/polling-source.js.map +1 -1
- package/dist/worker.js +1333 -283
- package/dist/worker.js.map +1 -1
- package/dist/workflows/definition.d.ts +28 -35
- package/dist/workflows/definition.d.ts.map +1 -1
- package/dist/workflows/definition.js +7 -24
- package/dist/workflows/definition.js.map +1 -1
- package/dist/workflows/events/payloads.d.ts +28 -28
- package/dist/workflows/events/replay.d.ts +5 -0
- package/dist/workflows/events/replay.d.ts.map +1 -1
- package/dist/workflows/events/replay.js +6 -1
- package/dist/workflows/events/replay.js.map +1 -1
- package/dist/workflows/events/schema.d.ts +663 -663
- package/dist/workflows/events/schema.d.ts.map +1 -1
- package/dist/workflows/events/schema.js +1 -4
- package/dist/workflows/events/schema.js.map +1 -1
- package/dist/workflows/hostExecutors/botmux-schedule.d.ts +5 -4
- package/dist/workflows/hostExecutors/botmux-schedule.d.ts.map +1 -1
- package/dist/workflows/hostExecutors/botmux-schedule.js +80 -35
- package/dist/workflows/hostExecutors/botmux-schedule.js.map +1 -1
- package/dist/workflows/hostExecutors/feishu-im.d.ts +3 -3
- package/dist/workflows/hostExecutors/feishu-im.d.ts.map +1 -1
- package/dist/workflows/hostExecutors/feishu-im.js +3 -3
- package/dist/workflows/hostExecutors/feishu-im.js.map +1 -1
- package/dist/workflows/hostExecutors/feishu-reply.d.ts +1 -1
- package/dist/workflows/hostExecutors/feishu-reply.d.ts.map +1 -1
- package/dist/workflows/hostExecutors/feishu-reply.js +1 -1
- package/dist/workflows/hostExecutors/feishu-reply.js.map +1 -1
- package/dist/workflows/hostExecutors/feishu-send.d.ts +1 -1
- package/dist/workflows/hostExecutors/feishu-send.d.ts.map +1 -1
- package/dist/workflows/hostExecutors/feishu-send.js +1 -1
- package/dist/workflows/hostExecutors/feishu-send.js.map +1 -1
- package/dist/workflows/hostExecutors/index.d.ts +0 -1
- package/dist/workflows/hostExecutors/index.d.ts.map +1 -1
- package/dist/workflows/hostExecutors/index.js +0 -1
- package/dist/workflows/hostExecutors/index.js.map +1 -1
- package/dist/workflows/hostExecutors/registry.d.ts +1 -1
- package/dist/workflows/hostExecutors/registry.d.ts.map +1 -1
- package/dist/workflows/hostExecutors/types.d.ts +21 -29
- package/dist/workflows/hostExecutors/types.d.ts.map +1 -1
- package/dist/workflows/migration/v2-definition-paths.d.ts +3 -0
- package/dist/workflows/migration/v2-definition-paths.d.ts.map +1 -0
- package/dist/workflows/migration/v2-definition-paths.js +10 -0
- package/dist/workflows/migration/v2-definition-paths.js.map +1 -0
- package/dist/workflows/migration/v2-ledger.d.ts +138 -0
- package/dist/workflows/migration/v2-ledger.d.ts.map +1 -0
- package/dist/workflows/migration/v2-ledger.js +599 -0
- package/dist/workflows/migration/v2-ledger.js.map +1 -0
- package/dist/workflows/migration/v2-migration-service.d.ts +40 -0
- package/dist/workflows/migration/v2-migration-service.d.ts.map +1 -0
- package/dist/workflows/migration/v2-migration-service.js +454 -0
- package/dist/workflows/migration/v2-migration-service.js.map +1 -0
- package/dist/workflows/migration/v2-read-only-ids.d.ts +7 -0
- package/dist/workflows/migration/v2-read-only-ids.d.ts.map +1 -0
- package/dist/workflows/migration/v2-read-only-ids.js +9 -0
- package/dist/workflows/migration/v2-read-only-ids.js.map +1 -0
- package/dist/workflows/migration/v2-run-archive-schema.d.ts +976 -0
- package/dist/workflows/migration/v2-run-archive-schema.d.ts.map +1 -0
- package/dist/workflows/migration/v2-run-archive-schema.js +113 -0
- package/dist/workflows/migration/v2-run-archive-schema.js.map +1 -0
- package/dist/workflows/migration/v2-run-archive.d.ts +92 -0
- package/dist/workflows/migration/v2-run-archive.d.ts.map +1 -0
- package/dist/workflows/migration/v2-run-archive.js +1220 -0
- package/dist/workflows/migration/v2-run-archive.js.map +1 -0
- package/dist/workflows/migration/v2-scanner.d.ts +22 -0
- package/dist/workflows/migration/v2-scanner.d.ts.map +1 -0
- package/dist/workflows/migration/v2-scanner.js +114 -0
- package/dist/workflows/migration/v2-scanner.js.map +1 -0
- package/dist/workflows/migration/v2-to-v3.d.ts +32 -0
- package/dist/workflows/migration/v2-to-v3.d.ts.map +1 -0
- package/dist/workflows/migration/v2-to-v3.js +494 -0
- package/dist/workflows/migration/v2-to-v3.js.map +1 -0
- package/dist/workflows/ops-projection.d.ts.map +1 -1
- package/dist/workflows/ops-projection.js +4 -3
- package/dist/workflows/ops-projection.js.map +1 -1
- package/dist/workflows/shared/idempotency-key.d.ts +19 -0
- package/dist/workflows/shared/idempotency-key.d.ts.map +1 -0
- package/dist/workflows/shared/idempotency-key.js +23 -0
- package/dist/workflows/shared/idempotency-key.js.map +1 -0
- package/dist/workflows/{params.d.ts → shared/params.d.ts} +42 -6
- package/dist/workflows/shared/params.d.ts.map +1 -0
- package/dist/workflows/{params.js → shared/params.js} +91 -4
- package/dist/workflows/shared/params.js.map +1 -0
- package/dist/workflows/shared/provider-reconciler.d.ts +47 -0
- package/dist/workflows/shared/provider-reconciler.d.ts.map +1 -0
- package/dist/workflows/shared/provider-reconciler.js +17 -0
- package/dist/workflows/shared/provider-reconciler.js.map +1 -0
- package/dist/workflows/{spawn-policy.d.ts → shared/sandbox-policy.d.ts} +2 -2
- package/dist/workflows/shared/sandbox-policy.d.ts.map +1 -0
- package/dist/workflows/{spawn-policy.js → shared/sandbox-policy.js} +1 -1
- package/dist/workflows/shared/sandbox-policy.js.map +1 -0
- package/dist/workflows/shared/worker-process.d.ts +29 -0
- package/dist/workflows/shared/worker-process.d.ts.map +1 -0
- package/dist/workflows/shared/worker-process.js +56 -0
- package/dist/workflows/shared/worker-process.js.map +1 -0
- package/dist/workflows/v3/architect.d.ts.map +1 -1
- package/dist/workflows/v3/architect.js +16 -4
- package/dist/workflows/v3/architect.js.map +1 -1
- package/dist/workflows/v3/attempt-ledger.d.ts +23 -0
- package/dist/workflows/v3/attempt-ledger.d.ts.map +1 -0
- package/dist/workflows/v3/attempt-ledger.js +74 -0
- package/dist/workflows/v3/attempt-ledger.js.map +1 -0
- package/dist/workflows/v3/bot-resolve.d.ts +19 -1
- package/dist/workflows/v3/bot-resolve.d.ts.map +1 -1
- package/dist/workflows/v3/bot-resolve.js +129 -3
- package/dist/workflows/v3/bot-resolve.js.map +1 -1
- package/dist/workflows/v3/cli-daemon-command-authority.d.ts +59 -0
- package/dist/workflows/v3/cli-daemon-command-authority.d.ts.map +1 -0
- package/dist/workflows/v3/cli-daemon-command-authority.js +175 -0
- package/dist/workflows/v3/cli-daemon-command-authority.js.map +1 -0
- package/dist/workflows/v3/cli-run.d.ts +27 -0
- package/dist/workflows/v3/cli-run.d.ts.map +1 -1
- package/dist/workflows/v3/cli-run.js +113 -29
- package/dist/workflows/v3/cli-run.js.map +1 -1
- package/dist/workflows/v3/contract.d.ts +16 -16
- package/dist/workflows/v3/contract.d.ts.map +1 -1
- package/dist/workflows/v3/contract.js +15 -11
- package/dist/workflows/v3/contract.js.map +1 -1
- package/dist/workflows/v3/daemon-ipc-auth.d.ts +113 -0
- package/dist/workflows/v3/daemon-ipc-auth.d.ts.map +1 -0
- package/dist/workflows/v3/daemon-ipc-auth.js +294 -0
- package/dist/workflows/v3/daemon-ipc-auth.js.map +1 -0
- package/dist/workflows/v3/daemon-ipc-body.d.ts +30 -0
- package/dist/workflows/v3/daemon-ipc-body.d.ts.map +1 -0
- package/dist/workflows/v3/daemon-ipc-body.js +65 -0
- package/dist/workflows/v3/daemon-ipc-body.js.map +1 -0
- package/dist/workflows/v3/daemon-ipc-client.d.ts +32 -0
- package/dist/workflows/v3/daemon-ipc-client.d.ts.map +1 -0
- package/dist/workflows/v3/daemon-ipc-client.js +74 -0
- package/dist/workflows/v3/daemon-ipc-client.js.map +1 -0
- package/dist/workflows/v3/daemon-run.d.ts +87 -2
- package/dist/workflows/v3/daemon-run.d.ts.map +1 -1
- package/dist/workflows/v3/daemon-run.js +863 -68
- package/dist/workflows/v3/daemon-run.js.map +1 -1
- package/dist/workflows/v3/dag.d.ts +22 -8
- package/dist/workflows/v3/dag.d.ts.map +1 -1
- package/dist/workflows/v3/dag.js +214 -22
- package/dist/workflows/v3/dag.js.map +1 -1
- package/dist/workflows/v3/distillation-compiler.d.ts +36 -0
- package/dist/workflows/v3/distillation-compiler.d.ts.map +1 -0
- package/dist/workflows/v3/distillation-compiler.js +704 -0
- package/dist/workflows/v3/distillation-compiler.js.map +1 -0
- package/dist/workflows/v3/distillation-private-root.d.ts +10 -0
- package/dist/workflows/v3/distillation-private-root.d.ts.map +1 -0
- package/dist/workflows/v3/distillation-private-root.js +34 -0
- package/dist/workflows/v3/distillation-private-root.js.map +1 -0
- package/dist/workflows/v3/distillation-runner.d.ts +64 -0
- package/dist/workflows/v3/distillation-runner.d.ts.map +1 -0
- package/dist/workflows/v3/distillation-runner.js +1028 -0
- package/dist/workflows/v3/distillation-runner.js.map +1 -0
- package/dist/workflows/v3/distillation-schema.d.ts +63 -0
- package/dist/workflows/v3/distillation-schema.d.ts.map +1 -0
- package/dist/workflows/v3/distillation-schema.js +184 -0
- package/dist/workflows/v3/distillation-schema.js.map +1 -0
- package/dist/workflows/v3/distillation-service.d.ts +78 -0
- package/dist/workflows/v3/distillation-service.d.ts.map +1 -0
- package/dist/workflows/v3/distillation-service.js +416 -0
- package/dist/workflows/v3/distillation-service.js.map +1 -0
- package/dist/workflows/v3/distillation-source.d.ts +35 -0
- package/dist/workflows/v3/distillation-source.d.ts.map +1 -0
- package/dist/workflows/v3/distillation-source.js +118 -0
- package/dist/workflows/v3/distillation-source.js.map +1 -0
- package/dist/workflows/v3/distillation-store.d.ts +185 -0
- package/dist/workflows/v3/distillation-store.d.ts.map +1 -0
- package/dist/workflows/v3/distillation-store.js +1127 -0
- package/dist/workflows/v3/distillation-store.js.map +1 -0
- package/dist/workflows/v3/drive-lease.d.ts +7 -0
- package/dist/workflows/v3/drive-lease.d.ts.map +1 -0
- package/dist/workflows/v3/drive-lease.js +10 -0
- package/dist/workflows/v3/drive-lease.js.map +1 -0
- package/dist/workflows/v3/ephemeral-pool.d.ts +1 -1
- package/dist/workflows/v3/ephemeral-pool.d.ts.map +1 -1
- package/dist/workflows/v3/ephemeral-pool.js +222 -37
- package/dist/workflows/v3/ephemeral-pool.js.map +1 -1
- package/dist/workflows/v3/grill-state.d.ts +18 -3
- package/dist/workflows/v3/grill-state.d.ts.map +1 -1
- package/dist/workflows/v3/grill-state.js +22 -5
- package/dist/workflows/v3/grill-state.js.map +1 -1
- package/dist/workflows/v3/host-bindings.d.ts +40 -0
- package/dist/workflows/v3/host-bindings.d.ts.map +1 -0
- package/dist/workflows/v3/host-bindings.js +272 -0
- package/dist/workflows/v3/host-bindings.js.map +1 -0
- package/dist/workflows/v3/host-effect-ledger.d.ts +22 -0
- package/dist/workflows/v3/host-effect-ledger.d.ts.map +1 -0
- package/dist/workflows/v3/host-effect-ledger.js +110 -0
- package/dist/workflows/v3/host-effect-ledger.js.map +1 -0
- package/dist/workflows/v3/host-execution.d.ts +142 -0
- package/dist/workflows/v3/host-execution.d.ts.map +1 -0
- package/dist/workflows/v3/host-execution.js +424 -0
- package/dist/workflows/v3/host-execution.js.map +1 -0
- package/dist/workflows/v3/host.d.ts +46 -10
- package/dist/workflows/v3/host.d.ts.map +1 -1
- package/dist/workflows/v3/host.js +419 -140
- package/dist/workflows/v3/host.js.map +1 -1
- package/dist/workflows/v3/human-gate.d.ts +19 -1
- package/dist/workflows/v3/human-gate.d.ts.map +1 -1
- package/dist/workflows/v3/human-gate.js +145 -19
- package/dist/workflows/v3/human-gate.js.map +1 -1
- package/dist/workflows/v3/journal.d.ts +125 -7
- package/dist/workflows/v3/journal.d.ts.map +1 -1
- package/dist/workflows/v3/journal.js +154 -38
- package/dist/workflows/v3/journal.js.map +1 -1
- package/dist/workflows/v3/library-materialize.d.ts +88 -0
- package/dist/workflows/v3/library-materialize.d.ts.map +1 -0
- package/dist/workflows/v3/library-materialize.js +294 -0
- package/dist/workflows/v3/library-materialize.js.map +1 -0
- package/dist/workflows/v3/library-schema.d.ts +138 -0
- package/dist/workflows/v3/library-schema.d.ts.map +1 -0
- package/dist/workflows/v3/library-schema.js +573 -0
- package/dist/workflows/v3/library-schema.js.map +1 -0
- package/dist/workflows/v3/library-service.d.ts +126 -0
- package/dist/workflows/v3/library-service.d.ts.map +1 -0
- package/dist/workflows/v3/library-service.js +542 -0
- package/dist/workflows/v3/library-service.js.map +1 -0
- package/dist/workflows/v3/library-store.d.ts +124 -0
- package/dist/workflows/v3/library-store.d.ts.map +1 -0
- package/dist/workflows/v3/library-store.js +665 -0
- package/dist/workflows/v3/library-store.js.map +1 -0
- package/dist/workflows/v3/orchestrator.d.ts +9 -1
- package/dist/workflows/v3/orchestrator.d.ts.map +1 -1
- package/dist/workflows/v3/orchestrator.js +2 -1
- package/dist/workflows/v3/orchestrator.js.map +1 -1
- package/dist/workflows/v3/progress-projection.d.ts +99 -0
- package/dist/workflows/v3/progress-projection.d.ts.map +1 -0
- package/dist/workflows/v3/progress-projection.js +197 -0
- package/dist/workflows/v3/progress-projection.js.map +1 -0
- package/dist/workflows/v3/run-envelope.d.ts +1279 -0
- package/dist/workflows/v3/run-envelope.d.ts.map +1 -0
- package/dist/workflows/v3/run-envelope.js +681 -0
- package/dist/workflows/v3/run-envelope.js.map +1 -0
- package/dist/workflows/v3/runtime.d.ts +39 -7
- package/dist/workflows/v3/runtime.d.ts.map +1 -1
- package/dist/workflows/v3/runtime.js +1992 -100
- package/dist/workflows/v3/runtime.js.map +1 -1
- package/dist/workflows/v3/session-relay-client.d.ts +61 -0
- package/dist/workflows/v3/session-relay-client.d.ts.map +1 -0
- package/dist/workflows/v3/session-relay-client.js +92 -0
- package/dist/workflows/v3/session-relay-client.js.map +1 -0
- package/dist/workflows/v3/session-relay.d.ts +66 -0
- package/dist/workflows/v3/session-relay.d.ts.map +1 -0
- package/dist/workflows/v3/session-relay.js +157 -0
- package/dist/workflows/v3/session-relay.js.map +1 -0
- package/dist/workflows/v3/start-intent.d.ts +8 -0
- package/dist/workflows/v3/start-intent.d.ts.map +1 -0
- package/dist/workflows/v3/start-intent.js +34 -0
- package/dist/workflows/v3/start-intent.js.map +1 -0
- package/dist/workflows/v3/state.d.ts +11 -2
- package/dist/workflows/v3/state.d.ts.map +1 -1
- package/dist/workflows/v3/state.js +182 -10
- package/dist/workflows/v3/state.js.map +1 -1
- package/dist/workflows/v3/template-bindings.d.ts +22 -0
- package/dist/workflows/v3/template-bindings.d.ts.map +1 -0
- package/dist/workflows/v3/template-bindings.js +204 -0
- package/dist/workflows/v3/template-bindings.js.map +1 -0
- package/dist/workflows/v3/worker-fence.d.ts +158 -0
- package/dist/workflows/v3/worker-fence.d.ts.map +1 -0
- package/dist/workflows/v3/worker-fence.js +685 -0
- package/dist/workflows/v3/worker-fence.js.map +1 -0
- package/package.json +3 -2
- package/dist/core/dashboard-command/workflows.d.ts +0 -20
- package/dist/core/dashboard-command/workflows.d.ts.map +0 -1
- package/dist/core/dashboard-command/workflows.js +0 -45
- package/dist/core/dashboard-command/workflows.js.map +0 -1
- package/dist/dashboard/web/legacy-workflow-link.d.ts +0 -2
- package/dist/dashboard/web/legacy-workflow-link.d.ts.map +0 -1
- package/dist/dashboard/web/legacy-workflow-link.js +0 -12
- package/dist/dashboard/web/legacy-workflow-link.js.map +0 -1
- package/dist/dashboard/web/legacy-workflow-page.d.ts +0 -3
- package/dist/dashboard/web/legacy-workflow-page.d.ts.map +0 -1
- package/dist/dashboard/web/legacy-workflow-page.js +0 -717
- package/dist/dashboard/web/legacy-workflow-page.js.map +0 -1
- package/dist/dashboard/web/workflow-version-switch.d.ts +0 -8
- package/dist/dashboard/web/workflow-version-switch.d.ts.map +0 -1
- package/dist/dashboard/web/workflow-version-switch.js +0 -9
- package/dist/dashboard/web/workflow-version-switch.js.map +0 -1
- package/dist/dashboard/web/workflows.d.ts +0 -273
- package/dist/dashboard/web/workflows.d.ts.map +0 -1
- package/dist/dashboard/web/workflows.js +0 -436
- package/dist/dashboard/web/workflows.js.map +0 -1
- package/dist/dashboard/workflow-api.d.ts +0 -30
- package/dist/dashboard/workflow-api.d.ts.map +0 -1
- package/dist/dashboard/workflow-api.js +0 -397
- package/dist/dashboard/workflow-api.js.map +0 -1
- package/dist/dashboard/workflow-card-model.d.ts +0 -127
- package/dist/dashboard/workflow-card-model.d.ts.map +0 -1
- package/dist/dashboard/workflow-card-model.js +0 -186
- package/dist/dashboard/workflow-card-model.js.map +0 -1
- package/dist/dashboard/workflows-action-helpers.d.ts +0 -105
- package/dist/dashboard/workflows-action-helpers.d.ts.map +0 -1
- package/dist/dashboard/workflows-action-helpers.js +0 -196
- package/dist/dashboard/workflows-action-helpers.js.map +0 -1
- package/dist/dashboard-web/chunks/bot-defaults-page-7T7DPOV6.js +0 -4
- package/dist/dashboard-web/chunks/chunk-IGXYYRYJ.js +0 -1
- package/dist/dashboard-web/chunks/chunk-ISOD7VDX.js +0 -1
- package/dist/dashboard-web/chunks/chunk-PNK3HQBI.js +0 -37
- package/dist/dashboard-web/chunks/chunk-SRIE4MLQ.js +0 -1
- package/dist/dashboard-web/chunks/connectors-page-UQ4QBE45.js +0 -1
- package/dist/dashboard-web/chunks/legacy-workflow-page-QMC7OZXH.js +0 -2
- package/dist/dashboard-web/chunks/sessions-page-NNZIDHZM.js +0 -3
- package/dist/dashboard-web/chunks/settings-page-LJIXX5LQ.js +0 -2
- package/dist/dashboard-web/chunks/v3-page-YLYVHGKD.js +0 -94
- package/dist/dashboard-web/terminal-replay.html +0 -227
- package/dist/im/lark/workflow-card-handler.d.ts +0 -51
- package/dist/im/lark/workflow-card-handler.d.ts.map +0 -1
- package/dist/im/lark/workflow-card-handler.js +0 -163
- package/dist/im/lark/workflow-card-handler.js.map +0 -1
- package/dist/im/lark/workflow-cards.d.ts +0 -47
- package/dist/im/lark/workflow-cards.d.ts.map +0 -1
- package/dist/im/lark/workflow-cards.js +0 -231
- package/dist/im/lark/workflow-cards.js.map +0 -1
- package/dist/im/lark/workflow-progress-card.d.ts +0 -81
- package/dist/im/lark/workflow-progress-card.d.ts.map +0 -1
- package/dist/im/lark/workflow-progress-card.js +0 -336
- package/dist/im/lark/workflow-progress-card.js.map +0 -1
- package/dist/im/lark/workflows-card.d.ts +0 -102
- package/dist/im/lark/workflows-card.d.ts.map +0 -1
- package/dist/im/lark/workflows-card.js +0 -737
- package/dist/im/lark/workflows-card.js.map +0 -1
- package/dist/workflows/attempt-resume.d.ts +0 -119
- package/dist/workflows/attempt-resume.d.ts.map +0 -1
- package/dist/workflows/attempt-resume.js +0 -392
- package/dist/workflows/attempt-resume.js.map +0 -1
- package/dist/workflows/blob.d.ts +0 -27
- package/dist/workflows/blob.d.ts.map +0 -1
- package/dist/workflows/blob.js +0 -40
- package/dist/workflows/blob.js.map +0 -1
- package/dist/workflows/cancel-run.d.ts +0 -45
- package/dist/workflows/cancel-run.d.ts.map +0 -1
- package/dist/workflows/cancel-run.js +0 -99
- package/dist/workflows/cancel-run.js.map +0 -1
- package/dist/workflows/cancel.d.ts +0 -111
- package/dist/workflows/cancel.d.ts.map +0 -1
- package/dist/workflows/cancel.js +0 -120
- package/dist/workflows/cancel.js.map +0 -1
- package/dist/workflows/catalog.d.ts +0 -60
- package/dist/workflows/catalog.d.ts.map +0 -1
- package/dist/workflows/catalog.js +0 -119
- package/dist/workflows/catalog.js.map +0 -1
- package/dist/workflows/cold-attach.d.ts +0 -30
- package/dist/workflows/cold-attach.d.ts.map +0 -1
- package/dist/workflows/cold-attach.js +0 -40
- package/dist/workflows/cold-attach.js.map +0 -1
- package/dist/workflows/cold-scan.d.ts +0 -21
- package/dist/workflows/cold-scan.d.ts.map +0 -1
- package/dist/workflows/cold-scan.js +0 -70
- package/dist/workflows/cold-scan.js.map +0 -1
- package/dist/workflows/daemon-spawn.d.ts +0 -119
- package/dist/workflows/daemon-spawn.d.ts.map +0 -1
- package/dist/workflows/daemon-spawn.js +0 -564
- package/dist/workflows/daemon-spawn.js.map +0 -1
- package/dist/workflows/effect-input.d.ts +0 -4
- package/dist/workflows/effect-input.d.ts.map +0 -1
- package/dist/workflows/effect-input.js +0 -19
- package/dist/workflows/effect-input.js.map +0 -1
- package/dist/workflows/events/append.d.ts +0 -77
- package/dist/workflows/events/append.d.ts.map +0 -1
- package/dist/workflows/events/append.js +0 -214
- package/dist/workflows/events/append.js.map +0 -1
- package/dist/workflows/events/idempotency.d.ts +0 -77
- package/dist/workflows/events/idempotency.d.ts.map +0 -1
- package/dist/workflows/events/idempotency.js +0 -116
- package/dist/workflows/events/idempotency.js.map +0 -1
- package/dist/workflows/events/index.d.ts +0 -7
- package/dist/workflows/events/index.d.ts.map +0 -1
- package/dist/workflows/events/index.js +0 -7
- package/dist/workflows/events/index.js.map +0 -1
- package/dist/workflows/fanout.d.ts +0 -36
- package/dist/workflows/fanout.d.ts.map +0 -1
- package/dist/workflows/fanout.js +0 -115
- package/dist/workflows/fanout.js.map +0 -1
- package/dist/workflows/hostExecutors/protocol.d.ts +0 -42
- package/dist/workflows/hostExecutors/protocol.d.ts.map +0 -1
- package/dist/workflows/hostExecutors/protocol.js +0 -181
- package/dist/workflows/hostExecutors/protocol.js.map +0 -1
- package/dist/workflows/loader.d.ts +0 -30
- package/dist/workflows/loader.d.ts.map +0 -1
- package/dist/workflows/loader.js +0 -84
- package/dist/workflows/loader.js.map +0 -1
- package/dist/workflows/loop.d.ts +0 -50
- package/dist/workflows/loop.d.ts.map +0 -1
- package/dist/workflows/loop.js +0 -408
- package/dist/workflows/loop.js.map +0 -1
- package/dist/workflows/orchestrator.d.ts +0 -171
- package/dist/workflows/orchestrator.d.ts.map +0 -1
- package/dist/workflows/orchestrator.js +0 -609
- package/dist/workflows/orchestrator.js.map +0 -1
- package/dist/workflows/output-binding.d.ts +0 -77
- package/dist/workflows/output-binding.d.ts.map +0 -1
- package/dist/workflows/output-binding.js +0 -329
- package/dist/workflows/output-binding.js.map +0 -1
- package/dist/workflows/params.d.ts.map +0 -1
- package/dist/workflows/params.js.map +0 -1
- package/dist/workflows/resume.d.ts +0 -263
- package/dist/workflows/resume.d.ts.map +0 -1
- package/dist/workflows/resume.js +0 -808
- package/dist/workflows/resume.js.map +0 -1
- package/dist/workflows/run-id.d.ts +0 -2
- package/dist/workflows/run-id.d.ts.map +0 -1
- package/dist/workflows/run-id.js +0 -7
- package/dist/workflows/run-id.js.map +0 -1
- package/dist/workflows/run-init.d.ts +0 -48
- package/dist/workflows/run-init.d.ts.map +0 -1
- package/dist/workflows/run-init.js +0 -100
- package/dist/workflows/run-init.js.map +0 -1
- package/dist/workflows/runs-dir.d.ts +0 -4
- package/dist/workflows/runs-dir.d.ts.map +0 -1
- package/dist/workflows/runs-dir.js +0 -15
- package/dist/workflows/runs-dir.js.map +0 -1
- package/dist/workflows/runtime.d.ts +0 -215
- package/dist/workflows/runtime.d.ts.map +0 -1
- package/dist/workflows/runtime.js +0 -630
- package/dist/workflows/runtime.js.map +0 -1
- package/dist/workflows/spawn-bot.d.ts +0 -165
- package/dist/workflows/spawn-bot.d.ts.map +0 -1
- package/dist/workflows/spawn-bot.js +0 -215
- package/dist/workflows/spawn-bot.js.map +0 -1
- package/dist/workflows/spawn-policy.d.ts.map +0 -1
- package/dist/workflows/spawn-policy.js.map +0 -1
- package/dist/workflows/system.d.ts +0 -49
- package/dist/workflows/system.d.ts.map +0 -1
- package/dist/workflows/system.js +0 -48
- package/dist/workflows/system.js.map +0 -1
- package/dist/workflows/trigger-from-envelope.d.ts +0 -13
- package/dist/workflows/trigger-from-envelope.d.ts.map +0 -1
- package/dist/workflows/trigger-from-envelope.js +0 -68
- package/dist/workflows/trigger-from-envelope.js.map +0 -1
- package/dist/workflows/trigger-run.d.ts +0 -70
- package/dist/workflows/trigger-run.d.ts.map +0 -1
- package/dist/workflows/trigger-run.js +0 -88
- package/dist/workflows/trigger-run.js.map +0 -1
- package/dist/workflows/wait.d.ts +0 -141
- package/dist/workflows/wait.d.ts.map +0 -1
- package/dist/workflows/wait.js +0 -203
- package/dist/workflows/wait.js.map +0 -1
|
@@ -15,20 +15,31 @@
|
|
|
15
15
|
* The daemon owns a lightweight per-runId in-flight guard around this so two
|
|
16
16
|
* concurrent clicks / start can't double-spawn.
|
|
17
17
|
*/
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
18
|
+
import { randomUUID } from 'node:crypto';
|
|
19
|
+
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';
|
|
20
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, statSync, writeFileSync } from 'node:fs';
|
|
20
21
|
import { loadBotConfigs } from '../../bot-registry.js';
|
|
21
|
-
import {
|
|
22
|
+
import { atomicWriteFileSync } from '../../utils/atomic-write.js';
|
|
23
|
+
import { withFileLock, withFileLockSync } from '../../utils/file-lock.js';
|
|
24
|
+
import { isHostNode, isLoopNode, loadDag } from './dag.js';
|
|
22
25
|
import { runWorkflow, nextAttemptIdFor, latestAttemptIdFor, revisitBudgetStatus, } from './runtime.js';
|
|
23
26
|
import { createEphemeralPool } from './ephemeral-pool.js';
|
|
24
27
|
import { readAndValidateManifest, ManifestValidationError } from './manifest.js';
|
|
25
|
-
import { readGrillState, defaultBaseDir, } from './grill-state.js';
|
|
26
|
-
import { resolveBotConfig, botToSnapshot } from './bot-resolve.js';
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
28
|
+
import { readGrillState, defaultBaseDir, GRILL_STATUS_FILE, } from './grill-state.js';
|
|
29
|
+
import { resolveBotConfig, botToSnapshot, freezeDagBotSnapshots, parseFrozenBotSnapshots, serializeFrozenBotSnapshots, } from './bot-resolve.js';
|
|
30
|
+
import { loadAuthorizedV3Run, artifactRef, makeLegacyV3RunEnvelope, publishRunEnvelopeOnce, readRunEnvelope, RunEnvelopeIntegrityError, } from './run-envelope.js';
|
|
31
|
+
import { canResolveGateWait, normalizeGateWaitInput, readWait, resolveWaitOnce, selectedResolution, v3GateWaitId, writePendingWait, } from './human-gate.js';
|
|
32
|
+
import { readJournal, appendEvent, withJournalMutationSync, } from './journal.js';
|
|
29
33
|
import { materialize } from './state.js';
|
|
34
|
+
import { openV3WorkerAttempts } from './attempt-ledger.js';
|
|
35
|
+
import { openV3HostEffects } from './host-effect-ledger.js';
|
|
36
|
+
import { readAndVerifyV3PreparedHostInput } from './host-execution.js';
|
|
37
|
+
import { composeV3HostGatePrompt, renderV3HostInputPreview } from './host-bindings.js';
|
|
38
|
+
import { V3_DRIVE_LEASE_MAX_WAIT_MS, v3DriveLeaseTarget } from './drive-lease.js';
|
|
39
|
+
import { createDefaultHostExecutorRegistry, createDefaultProviderReconcilers, } from '../hostExecutors/registry.js';
|
|
30
40
|
import { isValidRunId } from './ops-projection.js';
|
|
31
41
|
import { GOAL_ANSWER_FILE } from './contract.js';
|
|
42
|
+
import { validateSpec } from './spec.js';
|
|
32
43
|
/**
|
|
33
44
|
* runId → runDir with a path-traversal guard (codex review #2). runIds reach
|
|
34
45
|
* the daemon from outside (start IPC, card clicks) — never trust them into a
|
|
@@ -39,6 +50,477 @@ export function safeRunDir(baseDir, runId) {
|
|
|
39
50
|
throw new Error(`v3: invalid runId "${runId}"`);
|
|
40
51
|
return join(baseDir, runId);
|
|
41
52
|
}
|
|
53
|
+
function parseResolvedWorkflowData(raw) {
|
|
54
|
+
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
|
|
55
|
+
throw new Error('params.resolved.json must be an object');
|
|
56
|
+
}
|
|
57
|
+
const root = raw;
|
|
58
|
+
const extra = Object.keys(root).filter((key) => key !== 'params' && key !== 'context');
|
|
59
|
+
if (extra.length > 0)
|
|
60
|
+
throw new Error(`params.resolved.json has unsupported key(s): ${extra.join(', ')}`);
|
|
61
|
+
if (!root.params || typeof root.params !== 'object' || Array.isArray(root.params)) {
|
|
62
|
+
throw new Error('params.resolved.json.params must be an object');
|
|
63
|
+
}
|
|
64
|
+
if (!root.context || typeof root.context !== 'object' || Array.isArray(root.context)) {
|
|
65
|
+
throw new Error('params.resolved.json.context must be an object');
|
|
66
|
+
}
|
|
67
|
+
const context = root.context;
|
|
68
|
+
if (Object.values(context).some((value) => typeof value !== 'string')) {
|
|
69
|
+
throw new Error('params.resolved.json.context values must be strings');
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
params: { ...root.params },
|
|
73
|
+
context: { ...context },
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function assertResolvedWorkflowContextMatchesBinding(data, binding) {
|
|
77
|
+
if (!binding) {
|
|
78
|
+
throw new Error('saved definition run must carry an authorized chatBinding');
|
|
79
|
+
}
|
|
80
|
+
const expected = {
|
|
81
|
+
chatId: binding.chatId,
|
|
82
|
+
larkAppId: binding.larkAppId,
|
|
83
|
+
chatType: binding.chatType,
|
|
84
|
+
rootMessageId: binding.rootMessageId,
|
|
85
|
+
initiatorOpenId: binding.ownerOpenId,
|
|
86
|
+
};
|
|
87
|
+
for (const [key, actual] of Object.entries(data.context)) {
|
|
88
|
+
if (!Object.prototype.hasOwnProperty.call(expected, key))
|
|
89
|
+
continue;
|
|
90
|
+
if (!expected[key] || expected[key] !== actual) {
|
|
91
|
+
throw new Error(`params.resolved.json context.${key} does not match run.json chatBinding`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function parseSavedDefinitionWorkflowData(raw, binding) {
|
|
96
|
+
const data = parseResolvedWorkflowData(raw);
|
|
97
|
+
assertResolvedWorkflowContextMatchesBinding(data, binding);
|
|
98
|
+
return data;
|
|
99
|
+
}
|
|
100
|
+
function bindingWorkflowData(binding) {
|
|
101
|
+
if (!binding)
|
|
102
|
+
return undefined;
|
|
103
|
+
return {
|
|
104
|
+
params: {},
|
|
105
|
+
context: {
|
|
106
|
+
chatId: binding.chatId,
|
|
107
|
+
larkAppId: binding.larkAppId,
|
|
108
|
+
...(binding.chatType ? { chatType: binding.chatType } : {}),
|
|
109
|
+
...(binding.rootMessageId ? { rootMessageId: binding.rootMessageId } : {}),
|
|
110
|
+
...(binding.ownerOpenId ? { initiatorOpenId: binding.ownerOpenId } : {}),
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
function mutationIntegrityError(detail) {
|
|
115
|
+
return new RunEnvelopeIntegrityError('envelope_invalid', `v3 run mutation authorization failed: ${detail}`);
|
|
116
|
+
}
|
|
117
|
+
function assertLegacyMutationIdentity(runDir) {
|
|
118
|
+
const expectedRunId = basename(runDir);
|
|
119
|
+
const journalPath = join(runDir, 'journal.ndjson');
|
|
120
|
+
const events = readJournal(journalPath);
|
|
121
|
+
const starts = events.filter((event) => event.type === 'runStarted');
|
|
122
|
+
if (starts.length !== 1 || starts[0].runId !== expectedRunId) {
|
|
123
|
+
const seen = starts.map((event) => event.runId).join(', ') || '(none)';
|
|
124
|
+
throw mutationIntegrityError(`legacy journal identity mismatch: directory=${expectedRunId}, runStarted=${seen}`);
|
|
125
|
+
}
|
|
126
|
+
const grillPath = join(runDir, GRILL_STATUS_FILE);
|
|
127
|
+
const grill = readGrillState(runDir);
|
|
128
|
+
if (existsSync(grillPath) && !grill) {
|
|
129
|
+
throw mutationIntegrityError('legacy grill state exists but is unreadable');
|
|
130
|
+
}
|
|
131
|
+
if (grill) {
|
|
132
|
+
if (grill.runId !== expectedRunId) {
|
|
133
|
+
throw mutationIntegrityError(`legacy grill identity mismatch: directory=${expectedRunId}, grill=${grill.runId}`);
|
|
134
|
+
}
|
|
135
|
+
if (grill.status !== 'dag_approved') {
|
|
136
|
+
throw mutationIntegrityError(`legacy grill is not Gate-2 approved (status=${grill.status})`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const candidateDagPaths = new Set();
|
|
140
|
+
const canonicalDagPath = join(runDir, 'dag.json');
|
|
141
|
+
if (existsSync(canonicalDagPath))
|
|
142
|
+
candidateDagPaths.add(canonicalDagPath);
|
|
143
|
+
if (grill?.dagPath) {
|
|
144
|
+
const runRoot = resolve(runDir);
|
|
145
|
+
const approvedDagPath = resolve(grill.dagPath);
|
|
146
|
+
const rel = relative(runRoot, approvedDagPath);
|
|
147
|
+
if (rel === '' || isAbsolute(rel) || rel === '..' || rel.startsWith(`..${sep}`)) {
|
|
148
|
+
throw mutationIntegrityError('legacy approved DAG path must stay inside its run directory');
|
|
149
|
+
}
|
|
150
|
+
if (!existsSync(approvedDagPath)) {
|
|
151
|
+
throw mutationIntegrityError('legacy approved DAG is missing');
|
|
152
|
+
}
|
|
153
|
+
candidateDagPaths.add(approvedDagPath);
|
|
154
|
+
}
|
|
155
|
+
if (candidateDagPaths.size === 0) {
|
|
156
|
+
throw mutationIntegrityError('legacy run has no verifiable DAG');
|
|
157
|
+
}
|
|
158
|
+
for (const dagPath of candidateDagPaths) {
|
|
159
|
+
let dag;
|
|
160
|
+
try {
|
|
161
|
+
dag = loadDag(dagPath);
|
|
162
|
+
}
|
|
163
|
+
catch (err) {
|
|
164
|
+
throw mutationIntegrityError(`legacy DAG is invalid (${dagPath}): ${err instanceof Error ? err.message : String(err)}`);
|
|
165
|
+
}
|
|
166
|
+
if (dag.runId !== expectedRunId) {
|
|
167
|
+
throw mutationIntegrityError(`legacy DAG identity mismatch: directory=${expectedRunId}, dag=${dag.runId}`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Mutation authorization boundary for card/CLI recovery actions.
|
|
173
|
+
*
|
|
174
|
+
* Envelope-backed runs re-verify every pinned artifact immediately before a
|
|
175
|
+
* wait file or journal can change. Only a genuinely missing run.json may use
|
|
176
|
+
* the one-release legacy path, which still requires directory, journal, grill,
|
|
177
|
+
* and DAG identities to agree. An existing invalid/tampered envelope never
|
|
178
|
+
* falls back to legacy state.
|
|
179
|
+
*/
|
|
180
|
+
export function assertV3RunIntegrityForMutation(runDir) {
|
|
181
|
+
const expectedRunId = basename(runDir);
|
|
182
|
+
const envelope = readRunEnvelope(runDir, expectedRunId);
|
|
183
|
+
if (envelope.kind === 'invalid') {
|
|
184
|
+
throw mutationIntegrityError(envelope.problems.join('; '));
|
|
185
|
+
}
|
|
186
|
+
if (envelope.kind === 'missing') {
|
|
187
|
+
assertLegacyMutationIdentity(runDir);
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const loaded = loadAuthorizedV3Run(runDir, { expectedRunId });
|
|
191
|
+
if (loaded.botSnapshots !== undefined) {
|
|
192
|
+
parseFrozenBotSnapshots(loaded.botSnapshots, loaded.dag);
|
|
193
|
+
}
|
|
194
|
+
if (loaded.envelope.source.kind === 'saved_definition') {
|
|
195
|
+
parseSavedDefinitionWorkflowData(loaded.resolvedParams, loaded.envelope.chatBinding);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
function assertPathInsideRunDir(runDir, path, label) {
|
|
199
|
+
const runRoot = resolve(runDir);
|
|
200
|
+
const candidate = resolve(path);
|
|
201
|
+
const rel = relative(runRoot, candidate);
|
|
202
|
+
if (rel === '' || isAbsolute(rel) || rel === '..' || rel.startsWith(`..${sep}`)) {
|
|
203
|
+
throw new Error(`${label} must stay inside its run directory`);
|
|
204
|
+
}
|
|
205
|
+
return candidate;
|
|
206
|
+
}
|
|
207
|
+
function loadLegacyDagForStart(runDir, grill) {
|
|
208
|
+
const expectedRunId = basename(runDir);
|
|
209
|
+
if (grill.runId !== expectedRunId) {
|
|
210
|
+
throw new Error(`legacy run identity mismatch: directory=${expectedRunId}, grill=${grill.runId}`);
|
|
211
|
+
}
|
|
212
|
+
const approvedDagPath = assertPathInsideRunDir(runDir, grill.dagPath, 'legacy approved DAG path');
|
|
213
|
+
if (!existsSync(approvedDagPath))
|
|
214
|
+
throw new Error('legacy approved DAG is missing');
|
|
215
|
+
const journalPath = join(runDir, 'journal.ndjson');
|
|
216
|
+
const events = readJournal(journalPath);
|
|
217
|
+
if (events.length > 0) {
|
|
218
|
+
const starts = events.filter((event) => event.type === 'runStarted');
|
|
219
|
+
if (starts.length !== 1 || starts[0].runId !== expectedRunId) {
|
|
220
|
+
throw new Error(`legacy journal identity mismatch: directory=${expectedRunId}, ` +
|
|
221
|
+
`runStarted=${starts.map((event) => event.runId).join(', ') || '(none)'}`);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
// Once runtime has created the canonical root DAG, it is execution truth.
|
|
225
|
+
// Before first dispatch the approved grill DAG is the only available source.
|
|
226
|
+
const canonicalDagPath = join(runDir, 'dag.json');
|
|
227
|
+
const dag = loadDag(existsSync(canonicalDagPath) ? canonicalDagPath : approvedDagPath);
|
|
228
|
+
if (dag.runId !== expectedRunId) {
|
|
229
|
+
throw new Error(`legacy DAG identity mismatch: directory=${expectedRunId}, dag=${dag.runId}`);
|
|
230
|
+
}
|
|
231
|
+
return dag;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Gate-2 authorization seam shared by the daemon IPC and the actual driver.
|
|
235
|
+
* Checking only `dagPath` is insufficient: architect writes that path while
|
|
236
|
+
* the run is still `dag_ready`, before the user has approved the DAG.
|
|
237
|
+
*/
|
|
238
|
+
export function preflightV3RunStart(runDir) {
|
|
239
|
+
const envelopeRead = readRunEnvelope(runDir);
|
|
240
|
+
if (envelopeRead.kind === 'invalid') {
|
|
241
|
+
return {
|
|
242
|
+
ok: false,
|
|
243
|
+
error: 'run_envelope_invalid',
|
|
244
|
+
detail: envelopeRead.problems.join('; '),
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
if (envelopeRead.kind === 'ok') {
|
|
248
|
+
if (envelopeRead.envelope.source.kind === 'manual_cli') {
|
|
249
|
+
return {
|
|
250
|
+
ok: false,
|
|
251
|
+
error: 'run_source_not_daemon_startable',
|
|
252
|
+
detail: 'manual_cli runs are local-only',
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
try {
|
|
256
|
+
const loaded = loadAuthorizedV3Run(runDir, {
|
|
257
|
+
allowedSources: ['ad_hoc', 'saved_definition', 'legacy_v3'],
|
|
258
|
+
});
|
|
259
|
+
const botSnapshots = loaded.botSnapshots === undefined
|
|
260
|
+
? undefined
|
|
261
|
+
: parseFrozenBotSnapshots(loaded.botSnapshots, loaded.dag);
|
|
262
|
+
const resolvedWorkflowData = loaded.envelope.source.kind === 'saved_definition'
|
|
263
|
+
? parseSavedDefinitionWorkflowData(loaded.resolvedParams, loaded.envelope.chatBinding)
|
|
264
|
+
: bindingWorkflowData(loaded.envelope.chatBinding);
|
|
265
|
+
return {
|
|
266
|
+
ok: true,
|
|
267
|
+
context: {
|
|
268
|
+
dag: loaded.dag,
|
|
269
|
+
binding: loaded.envelope.chatBinding,
|
|
270
|
+
...(botSnapshots ? { botSnapshots } : {}),
|
|
271
|
+
...(resolvedWorkflowData ? { resolvedWorkflowData } : {}),
|
|
272
|
+
envelope: loaded.envelope,
|
|
273
|
+
authorizedArtifacts: true,
|
|
274
|
+
},
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
catch (err) {
|
|
278
|
+
return {
|
|
279
|
+
ok: false,
|
|
280
|
+
error: 'run_envelope_invalid',
|
|
281
|
+
detail: err instanceof Error ? err.message : String(err),
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
// One-version compatibility: a run created before run.json existed may still
|
|
286
|
+
// start from the old Gate-2 grill marker. Existing-but-corrupt envelopes
|
|
287
|
+
// never reach this fallback.
|
|
288
|
+
const grill = readGrillState(runDir);
|
|
289
|
+
if (!grill)
|
|
290
|
+
return { ok: false, error: 'no_grill_state' };
|
|
291
|
+
if (grill.status !== 'dag_approved') {
|
|
292
|
+
return { ok: false, error: 'dag_not_approved', status: grill.status };
|
|
293
|
+
}
|
|
294
|
+
if (!grill.dagPath) {
|
|
295
|
+
return { ok: false, error: 'approved_dag_missing', status: grill.status };
|
|
296
|
+
}
|
|
297
|
+
try {
|
|
298
|
+
const approvedGrill = grill;
|
|
299
|
+
const dag = loadLegacyDagForStart(runDir, approvedGrill);
|
|
300
|
+
return {
|
|
301
|
+
ok: true,
|
|
302
|
+
grill: approvedGrill,
|
|
303
|
+
context: {
|
|
304
|
+
dag,
|
|
305
|
+
binding: grill.chatBinding,
|
|
306
|
+
...(bindingWorkflowData(grill.chatBinding)
|
|
307
|
+
? { resolvedWorkflowData: bindingWorkflowData(grill.chatBinding) }
|
|
308
|
+
: {}),
|
|
309
|
+
authorizedArtifacts: false,
|
|
310
|
+
},
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
catch (err) {
|
|
314
|
+
if (err instanceof Error && err.message === 'legacy approved DAG is missing') {
|
|
315
|
+
return {
|
|
316
|
+
ok: false,
|
|
317
|
+
error: 'approved_dag_missing',
|
|
318
|
+
status: grill.status,
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
return {
|
|
322
|
+
ok: false,
|
|
323
|
+
error: 'approved_dag_invalid',
|
|
324
|
+
status: grill.status,
|
|
325
|
+
detail: err instanceof Error ? err.message : String(err),
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Seal a pre-run.json grill run immediately before its first worker dispatch.
|
|
331
|
+
* Legacy Gate-2 bytes were never digest-pinned, so the envelope is honest
|
|
332
|
+
* about that historical limitation; from this point onward the canonical DAG
|
|
333
|
+
* and bot identities are immutable and every retry/resume verifies them.
|
|
334
|
+
*/
|
|
335
|
+
function sealLegacyV3Run(runDir, grill, preflightDag, bots) {
|
|
336
|
+
return withFileLockSync(join(runDir, 'run.json'), () => {
|
|
337
|
+
const current = readRunEnvelope(runDir);
|
|
338
|
+
if (current.kind === 'invalid') {
|
|
339
|
+
throw new Error(`legacy run envelope is invalid: ${current.problems.join('; ')}`);
|
|
340
|
+
}
|
|
341
|
+
if (current.kind === 'ok') {
|
|
342
|
+
if (current.envelope.source.kind === 'manual_cli') {
|
|
343
|
+
throw new Error('manual_cli runs are local-only');
|
|
344
|
+
}
|
|
345
|
+
const loaded = loadAuthorizedV3Run(runDir, {
|
|
346
|
+
allowedSources: ['ad_hoc', 'saved_definition', 'legacy_v3'],
|
|
347
|
+
});
|
|
348
|
+
const botSnapshots = loaded.botSnapshots === undefined
|
|
349
|
+
? undefined
|
|
350
|
+
: parseFrozenBotSnapshots(loaded.botSnapshots, loaded.dag);
|
|
351
|
+
const resolvedWorkflowData = loaded.envelope.source.kind === 'saved_definition'
|
|
352
|
+
? parseSavedDefinitionWorkflowData(loaded.resolvedParams, loaded.envelope.chatBinding)
|
|
353
|
+
: bindingWorkflowData(loaded.envelope.chatBinding);
|
|
354
|
+
return {
|
|
355
|
+
dag: loaded.dag,
|
|
356
|
+
binding: loaded.envelope.chatBinding,
|
|
357
|
+
...(botSnapshots ? { botSnapshots } : {}),
|
|
358
|
+
...(resolvedWorkflowData ? { resolvedWorkflowData } : {}),
|
|
359
|
+
envelope: loaded.envelope,
|
|
360
|
+
authorizedArtifacts: true,
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
const runId = basename(runDir);
|
|
364
|
+
if (grill.runId !== runId || preflightDag.runId !== runId) {
|
|
365
|
+
throw new Error(`legacy run identity changed before sealing: directory=${runId}, ` +
|
|
366
|
+
`grill=${grill.runId}, dag=${preflightDag.runId}`);
|
|
367
|
+
}
|
|
368
|
+
const canonicalDagPath = join(runDir, 'dag.json');
|
|
369
|
+
if (existsSync(canonicalDagPath)) {
|
|
370
|
+
const canonicalDag = loadDag(canonicalDagPath);
|
|
371
|
+
if (JSON.stringify(canonicalDag) !== JSON.stringify(preflightDag)) {
|
|
372
|
+
throw new Error('legacy canonical DAG changed between preflight and sealing');
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
else {
|
|
376
|
+
atomicWriteFileSync(canonicalDagPath, `${JSON.stringify(preflightDag, null, 2)}\n`, { mode: 0o600 });
|
|
377
|
+
}
|
|
378
|
+
const dag = loadDag(canonicalDagPath);
|
|
379
|
+
const botPath = join(runDir, 'bots.snapshot.json');
|
|
380
|
+
let botSnapshots;
|
|
381
|
+
if (existsSync(botPath)) {
|
|
382
|
+
const raw = JSON.parse(readFileSync(botPath, 'utf-8'));
|
|
383
|
+
botSnapshots = parseFrozenBotSnapshots(raw, dag);
|
|
384
|
+
}
|
|
385
|
+
else {
|
|
386
|
+
botSnapshots = freezeDagBotSnapshots(dag, bots);
|
|
387
|
+
atomicWriteFileSync(botPath, `${JSON.stringify(serializeFrozenBotSnapshots(botSnapshots), null, 2)}\n`, { mode: 0o600 });
|
|
388
|
+
}
|
|
389
|
+
const artifacts = {
|
|
390
|
+
dag: artifactRef(runDir, 'dag.json'),
|
|
391
|
+
botSnapshots: artifactRef(runDir, 'bots.snapshot.json'),
|
|
392
|
+
};
|
|
393
|
+
const specPath = join(runDir, 'spec.json');
|
|
394
|
+
if (existsSync(specPath)) {
|
|
395
|
+
try {
|
|
396
|
+
const spec = validateSpec(JSON.parse(readFileSync(specPath, 'utf-8')));
|
|
397
|
+
if (spec.runId === runId)
|
|
398
|
+
artifacts.spec = artifactRef(runDir, 'spec.json');
|
|
399
|
+
}
|
|
400
|
+
catch {
|
|
401
|
+
// Historical specs were optional and not execution inputs. Omit an
|
|
402
|
+
// unverifiable/corrupt one rather than blessing it into the envelope.
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
const journalEvents = readJournal(join(runDir, 'journal.ndjson'));
|
|
406
|
+
const legacyEnvelope = makeLegacyV3RunEnvelope({
|
|
407
|
+
runId,
|
|
408
|
+
createdAt: grill.createdAt,
|
|
409
|
+
backfilledAt: new Date().toISOString(),
|
|
410
|
+
original: 'grill',
|
|
411
|
+
basis: journalEvents.length > 0 ? 'runtime_started' : 'grill_dag_approved',
|
|
412
|
+
...(grill.chatBinding ? { chatBinding: grill.chatBinding } : {}),
|
|
413
|
+
artifacts,
|
|
414
|
+
});
|
|
415
|
+
publishRunEnvelopeOnce(runDir, legacyEnvelope);
|
|
416
|
+
const loaded = loadAuthorizedV3Run(runDir, { allowedSources: ['legacy_v3'] });
|
|
417
|
+
return {
|
|
418
|
+
dag: loaded.dag,
|
|
419
|
+
binding: loaded.envelope.chatBinding,
|
|
420
|
+
botSnapshots: parseFrozenBotSnapshots(loaded.botSnapshots, loaded.dag),
|
|
421
|
+
...(bindingWorkflowData(loaded.envelope.chatBinding)
|
|
422
|
+
? { resolvedWorkflowData: bindingWorkflowData(loaded.envelope.chatBinding) }
|
|
423
|
+
: {}),
|
|
424
|
+
envelope: loaded.envelope,
|
|
425
|
+
authorizedArtifacts: true,
|
|
426
|
+
};
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
/** Envelope-first binding lookup shared by daemon routes, card handlers, and
|
|
430
|
+
* cold attach. Corrupt run.json fails closed; only a genuinely missing
|
|
431
|
+
* envelope may use the one-version grill fallback. */
|
|
432
|
+
export function readV3RunChatBinding(runDir) {
|
|
433
|
+
const envelope = readRunEnvelope(runDir);
|
|
434
|
+
if (envelope.kind === 'ok')
|
|
435
|
+
return envelope.envelope.chatBinding;
|
|
436
|
+
if (envelope.kind === 'invalid')
|
|
437
|
+
return undefined;
|
|
438
|
+
return readGrillState(runDir)?.chatBinding;
|
|
439
|
+
}
|
|
440
|
+
/** Verified DAG for recovery/display logic, with the same missing-only legacy
|
|
441
|
+
* fallback as the start path. */
|
|
442
|
+
export function loadV3RunDagForRecovery(runDir) {
|
|
443
|
+
const envelope = readRunEnvelope(runDir);
|
|
444
|
+
if (envelope.kind === 'ok') {
|
|
445
|
+
try {
|
|
446
|
+
return loadAuthorizedV3Run(runDir).dag;
|
|
447
|
+
}
|
|
448
|
+
catch {
|
|
449
|
+
return undefined;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
if (envelope.kind === 'invalid')
|
|
453
|
+
return undefined;
|
|
454
|
+
const grill = readGrillState(runDir);
|
|
455
|
+
if (!grill?.dagPath || !existsSync(grill.dagPath))
|
|
456
|
+
return undefined;
|
|
457
|
+
try {
|
|
458
|
+
return loadDag(grill.dagPath);
|
|
459
|
+
}
|
|
460
|
+
catch {
|
|
461
|
+
return undefined;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
/** Rebuild the host approval UI from authorized DAG + durable prepared bytes.
|
|
465
|
+
* waits/*.json is mutable delivery state and is never trusted as the approval
|
|
466
|
+
* object by itself. */
|
|
467
|
+
function trustedHostGateMaterial(runDir, runId, nodeId, instanceId, events) {
|
|
468
|
+
const dag = loadV3RunDagForRecovery(runDir);
|
|
469
|
+
const node = dag?.nodes.find((candidate) => candidate.id === nodeId);
|
|
470
|
+
if (!node || !isHostNode(node) || !node.humanGate)
|
|
471
|
+
return undefined;
|
|
472
|
+
const dispatched = [...events].reverse().find((event) => event.type === 'gateDispatched' &&
|
|
473
|
+
event.nodeId === nodeId &&
|
|
474
|
+
event.instanceId === instanceId &&
|
|
475
|
+
!!event.hostApproval);
|
|
476
|
+
if (!dispatched?.hostApproval)
|
|
477
|
+
return undefined;
|
|
478
|
+
const prepared = [...events].reverse().find((event) => event.type === 'hostInputPrepared' &&
|
|
479
|
+
event.nodeId === nodeId &&
|
|
480
|
+
event.instanceId === instanceId &&
|
|
481
|
+
event.attemptId === dispatched.hostApproval.attemptId);
|
|
482
|
+
const registered = createDefaultHostExecutorRegistry().get(node.executor);
|
|
483
|
+
if (!prepared || !registered)
|
|
484
|
+
return undefined;
|
|
485
|
+
if (prepared.approvalDigest !== dispatched.hostApproval.approvalDigest ||
|
|
486
|
+
prepared.inputHash !== dispatched.hostApproval.inputHash)
|
|
487
|
+
return undefined;
|
|
488
|
+
try {
|
|
489
|
+
const artifact = readAndVerifyV3PreparedHostInput({
|
|
490
|
+
runDir,
|
|
491
|
+
inputRef: prepared.inputRef,
|
|
492
|
+
expected: { ...prepared, runId },
|
|
493
|
+
registered,
|
|
494
|
+
});
|
|
495
|
+
const authored = normalizeGateWaitInput(node.humanGate);
|
|
496
|
+
const hostApproval = {
|
|
497
|
+
attemptId: prepared.attemptId,
|
|
498
|
+
approvalDigest: prepared.approvalDigest,
|
|
499
|
+
inputHash: prepared.inputHash,
|
|
500
|
+
};
|
|
501
|
+
return {
|
|
502
|
+
nodeId,
|
|
503
|
+
instanceId,
|
|
504
|
+
waitId: v3GateWaitId(nodeId, instanceId, hostApproval),
|
|
505
|
+
...authored,
|
|
506
|
+
prompt: composeV3HostGatePrompt(authored.prompt, renderV3HostInputPreview(node.executor, artifact.prepared.parsedInput, prepared.inputHash)),
|
|
507
|
+
hostApproval,
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
catch {
|
|
511
|
+
return undefined;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
function waitMatchesTrustedHostGate(wait, trusted) {
|
|
515
|
+
return wait.waitId === trusted.waitId &&
|
|
516
|
+
wait.nodeId === trusted.nodeId &&
|
|
517
|
+
wait.instanceId === trusted.instanceId &&
|
|
518
|
+
wait.prompt === trusted.prompt &&
|
|
519
|
+
JSON.stringify(wait.options) === JSON.stringify(trusted.options) &&
|
|
520
|
+
JSON.stringify(wait.approveOptions) === JSON.stringify(trusted.approveOptions) &&
|
|
521
|
+
JSON.stringify(wait.approvers) === JSON.stringify(trusted.approvers) &&
|
|
522
|
+
JSON.stringify(wait.hostApproval) === JSON.stringify(trusted.hostApproval);
|
|
523
|
+
}
|
|
42
524
|
/** Latest `nodeBlocked` details for a node (card content). Falls back to a
|
|
43
525
|
* bare nodeId/attempt when the journal has no blocked event (shouldn't
|
|
44
526
|
* happen for a blocked run, but the card must still render). */
|
|
@@ -56,6 +538,16 @@ export function blockedInfoFor(events, nodeId) {
|
|
|
56
538
|
...(e.revisitTo ? { revisitTo: e.revisitTo } : {}),
|
|
57
539
|
};
|
|
58
540
|
}
|
|
541
|
+
else if (e.type === 'hostEffectUncertain' && e.nodeId === nodeId) {
|
|
542
|
+
found = {
|
|
543
|
+
nodeId,
|
|
544
|
+
attemptId: e.attemptId,
|
|
545
|
+
errorClass: 'workerError',
|
|
546
|
+
errorCode: e.errorCode,
|
|
547
|
+
message: '外部操作的最终状态无法确认,请先在目标系统完成对账;为避免重复副作用,普通重试已禁用。',
|
|
548
|
+
retryForbidden: 'host-effect-uncertain',
|
|
549
|
+
};
|
|
550
|
+
}
|
|
59
551
|
}
|
|
60
552
|
return found ?? { nodeId, attemptId: latestAttemptIdFor(events, nodeId) ?? `${nodeId}/attempts/001` };
|
|
61
553
|
}
|
|
@@ -92,21 +584,34 @@ export function loopExhaustedInfoFor(events, loopId) {
|
|
|
92
584
|
export async function driveV3Run(runId, deps) {
|
|
93
585
|
const baseDir = deps.baseDir ?? defaultBaseDir();
|
|
94
586
|
const runDir = safeRunDir(baseDir, runId);
|
|
95
|
-
const
|
|
96
|
-
if (!
|
|
587
|
+
const preflight = preflightV3RunStart(runDir);
|
|
588
|
+
if (!preflight.ok && preflight.error === 'no_grill_state') {
|
|
97
589
|
throw new Error(`v3 daemon run: no grill state for "${runId}" in ${runDir}`);
|
|
98
|
-
if (!grill.dagPath || !existsSync(grill.dagPath)) {
|
|
99
|
-
throw new Error(`v3 daemon run: "${runId}" has no approved dag (status=${grill.status})`);
|
|
100
590
|
}
|
|
101
|
-
|
|
591
|
+
if (!preflight.ok) {
|
|
592
|
+
if (preflight.error === 'run_envelope_invalid' ||
|
|
593
|
+
preflight.error === 'run_source_not_daemon_startable') {
|
|
594
|
+
throw new Error(`v3 daemon run: "${runId}" authorization failed (${preflight.error})` +
|
|
595
|
+
(preflight.detail ? `: ${preflight.detail}` : ''));
|
|
596
|
+
}
|
|
597
|
+
throw new Error(`v3 daemon run: "${runId}" has no approved dag (status=${preflight.status ?? 'unknown'})`);
|
|
598
|
+
}
|
|
599
|
+
let context = preflight.context;
|
|
102
600
|
// Was the run ALREADY terminal before this (re-)drive? A coalesced re-drive or
|
|
103
601
|
// a `/start` retry of a finished run re-runs no work (the journal is terminal),
|
|
104
602
|
// but the notify block below would otherwise re-post cards / re-fire onTerminal
|
|
105
603
|
// — duplicate "done/failed" messages. Capture now, short-circuit after runWorkflow.
|
|
106
604
|
const journalPath = join(runDir, 'journal.ndjson');
|
|
107
605
|
const wasAlreadyTerminal = existsSync(journalPath) &&
|
|
108
|
-
['succeeded', 'failed'].includes(materialize(readJournal(journalPath)).runStatus);
|
|
606
|
+
['succeeded', 'failed', 'cancelled'].includes(materialize(readJournal(journalPath)).runStatus);
|
|
109
607
|
const bots = (deps.loadBots ?? loadBotConfigs)();
|
|
608
|
+
if (!context.authorizedArtifacts) {
|
|
609
|
+
if (!preflight.grill) {
|
|
610
|
+
throw new Error(`v3 daemon run: legacy run "${runId}" has no approved grill basis`);
|
|
611
|
+
}
|
|
612
|
+
context = sealLegacyV3Run(runDir, preflight.grill, context.dag, bots);
|
|
613
|
+
}
|
|
614
|
+
const binding = context.binding;
|
|
110
615
|
// Secret resolver by larkAppId from live bots.json; no env fallback (contract).
|
|
111
616
|
const secretById = new Map(bots.map((b) => [b.larkAppId, b.larkAppSecret]));
|
|
112
617
|
const resolveLarkAppSecret = (larkAppId) => secretById.get(larkAppId);
|
|
@@ -122,13 +627,23 @@ export async function driveV3Run(runId, deps) {
|
|
|
122
627
|
});
|
|
123
628
|
const resolveBotSnapshot = (botId) => botToSnapshot(resolveBotConfig(botId, bots));
|
|
124
629
|
const runNode = (deps.makeRunNode ?? defaultMakeRunNode)(resolveLarkAppSecret);
|
|
125
|
-
const dag =
|
|
630
|
+
const dag = context.dag;
|
|
126
631
|
// suspend mode → no resolveGate (runtime writes the wait + returns awaitingGate).
|
|
127
|
-
const runtimeDeps = {
|
|
632
|
+
const runtimeDeps = {
|
|
633
|
+
runNode,
|
|
634
|
+
validateManifest,
|
|
635
|
+
resolveBotSnapshot,
|
|
636
|
+
hostExecutors: createDefaultHostExecutorRegistry(),
|
|
637
|
+
hostReconcilers: createDefaultProviderReconcilers(),
|
|
638
|
+
};
|
|
128
639
|
const opts = {
|
|
129
640
|
baseDir,
|
|
130
641
|
gateMode: 'suspend',
|
|
642
|
+
...(context.botSnapshots ? { frozenBotSnapshots: context.botSnapshots } : {}),
|
|
643
|
+
...(context.authorizedArtifacts ? { authorizedArtifacts: true } : {}),
|
|
644
|
+
...(context.resolvedWorkflowData ? { resolvedWorkflowData: context.resolvedWorkflowData } : {}),
|
|
131
645
|
...(deps.maxParallel ? { globalConcurrency: deps.maxParallel } : {}),
|
|
646
|
+
...(deps.cancelSignal ? { cancelSignal: deps.cancelSignal } : {}),
|
|
132
647
|
};
|
|
133
648
|
const outcome = await runWorkflow(dag, runtimeDeps, opts);
|
|
134
649
|
if (wasAlreadyTerminal) {
|
|
@@ -202,6 +717,7 @@ export function resolveV3GateClick(baseDir, runId, input) {
|
|
|
202
717
|
const journalPath = join(runDir, 'journal.ndjson');
|
|
203
718
|
if (!existsSync(journalPath))
|
|
204
719
|
return { kind: 'stale-run', reason: 'missing' };
|
|
720
|
+
assertV3RunIntegrityForMutation(runDir);
|
|
205
721
|
const snap = materialize(readJournal(journalPath));
|
|
206
722
|
if (snap.runStatus !== 'running')
|
|
207
723
|
return { kind: 'stale-run', reason: 'terminal' };
|
|
@@ -219,27 +735,98 @@ export function resolveV3GateClick(baseDir, runId, input) {
|
|
|
219
735
|
if (wait.instanceId && wait.instanceId !== snap.nodes.get(wait.nodeId)?.effectiveInstanceId) {
|
|
220
736
|
return { kind: 'stale-run', reason: 'stale-node' };
|
|
221
737
|
}
|
|
738
|
+
const dagNode = loadV3RunDagForRecovery(runDir)?.nodes.find((node) => node.id === wait.nodeId);
|
|
739
|
+
const trustedHost = dagNode && isHostNode(dagNode) && wait.instanceId
|
|
740
|
+
? trustedHostGateMaterial(runDir, runId, wait.nodeId, wait.instanceId, readJournal(journalPath))
|
|
741
|
+
: undefined;
|
|
742
|
+
if (dagNode && isHostNode(dagNode)) {
|
|
743
|
+
if (!trustedHost || !waitMatchesTrustedHostGate(wait, trustedHost)) {
|
|
744
|
+
return { kind: 'stale-run', reason: 'no-wait' };
|
|
745
|
+
}
|
|
746
|
+
}
|
|
222
747
|
if (!canResolveGateWait(wait, input.by))
|
|
223
748
|
return { kind: 'unauthorized' };
|
|
224
749
|
const resolution = selectedResolution(wait, input.selected);
|
|
225
750
|
if (!resolution)
|
|
226
751
|
return { kind: 'stale-run', reason: 'no-wait' };
|
|
227
|
-
|
|
228
|
-
|
|
752
|
+
const settled = resolveWaitOnce(runDir, input.waitId, resolution, input.by, input.selected);
|
|
753
|
+
if (!settled.changed) {
|
|
754
|
+
return { kind: 'already-settled', status: settled.wait.status };
|
|
755
|
+
}
|
|
756
|
+
const resolvedWait = settled.wait;
|
|
757
|
+
if (trustedHost && !waitMatchesTrustedHostGate(resolvedWait, trustedHost)) {
|
|
758
|
+
appendEvent(journalPath, {
|
|
759
|
+
type: 'gateResolved',
|
|
760
|
+
nodeId: trustedHost.nodeId,
|
|
761
|
+
instanceId: trustedHost.instanceId,
|
|
762
|
+
waitId: trustedHost.waitId,
|
|
763
|
+
resolution: 'rejected',
|
|
764
|
+
by: 'system-host-wait-integrity',
|
|
765
|
+
hostApproval: trustedHost.hostApproval,
|
|
766
|
+
});
|
|
767
|
+
return { kind: 'resolved', resolution: 'rejected' };
|
|
768
|
+
}
|
|
769
|
+
const instanceId = snap.nodes.get(resolvedWait.nodeId)?.effectiveInstanceId;
|
|
229
770
|
appendEvent(journalPath, {
|
|
230
771
|
type: 'gateResolved',
|
|
231
772
|
// nodeId from the WAIT FILE, not caller input (codex review #1): the wait is
|
|
232
773
|
// the authoritative state — a wrong/stale caller nodeId must not let us write
|
|
233
774
|
// gateResolved for a different node.
|
|
234
|
-
nodeId:
|
|
775
|
+
nodeId: resolvedWait.nodeId,
|
|
235
776
|
...(instanceId ? { instanceId } : {}),
|
|
236
777
|
waitId: input.waitId,
|
|
237
778
|
resolution,
|
|
238
779
|
by: input.by,
|
|
239
780
|
selected: input.selected,
|
|
781
|
+
...(trustedHost
|
|
782
|
+
? { hostApproval: trustedHost.hostApproval }
|
|
783
|
+
: resolvedWait.hostApproval ? { hostApproval: resolvedWait.hostApproval } : {}),
|
|
240
784
|
});
|
|
241
785
|
return { kind: 'resolved', resolution };
|
|
242
786
|
}
|
|
787
|
+
const CANCEL_ACTOR_MAX = 128;
|
|
788
|
+
const CANCEL_REASON_MAX = 500;
|
|
789
|
+
/**
|
|
790
|
+
* Durable, idempotent run-cancel mutation shared by CLI, IM, cards and the
|
|
791
|
+
* dashboard daemon endpoint. The journal lock is the linearization boundary:
|
|
792
|
+
* a true terminal committed first wins; otherwise the first cancel request
|
|
793
|
+
* wins and every repeat reuses its id.
|
|
794
|
+
*/
|
|
795
|
+
export function requestV3RunCancel(baseDir, runId, input) {
|
|
796
|
+
const runDir = safeRunDir(baseDir, runId);
|
|
797
|
+
if (!existsSync(runDir))
|
|
798
|
+
return { kind: 'stale-run', reason: 'missing' };
|
|
799
|
+
assertV3RunIntegrityForMutation(runDir);
|
|
800
|
+
const by = input.by.trim();
|
|
801
|
+
if (!by || by.length > CANCEL_ACTOR_MAX || /[\r\n\0]/.test(by)) {
|
|
802
|
+
throw new Error(`v3 cancel actor must be 1-${CANCEL_ACTOR_MAX} safe characters`);
|
|
803
|
+
}
|
|
804
|
+
const reason = input.reason?.trim();
|
|
805
|
+
if (reason !== undefined && (reason.length === 0 || reason.length > CANCEL_REASON_MAX || /[\0]/.test(reason))) {
|
|
806
|
+
throw new Error(`v3 cancel reason must be 1-${CANCEL_REASON_MAX} characters`);
|
|
807
|
+
}
|
|
808
|
+
const journalPath = join(runDir, 'journal.ndjson');
|
|
809
|
+
return withJournalMutationSync(journalPath, ({ events, append }) => {
|
|
810
|
+
const snap = materialize([...events]);
|
|
811
|
+
if (snap.runStatus === 'cancelled') {
|
|
812
|
+
return { kind: 'already-cancelled', cancelRequestId: snap.cancelRequestId };
|
|
813
|
+
}
|
|
814
|
+
if (snap.runStatus === 'succeeded' || snap.runStatus === 'failed') {
|
|
815
|
+
return { kind: 'already-terminal', status: snap.runStatus };
|
|
816
|
+
}
|
|
817
|
+
if (snap.runStatus === 'cancelling' && snap.cancelRequestId) {
|
|
818
|
+
return { kind: 'already-requested', cancelRequestId: snap.cancelRequestId };
|
|
819
|
+
}
|
|
820
|
+
const cancelRequestId = `cancel-${randomUUID()}`;
|
|
821
|
+
append({
|
|
822
|
+
type: 'runCancelRequested',
|
|
823
|
+
cancelRequestId,
|
|
824
|
+
by,
|
|
825
|
+
...(reason ? { reason } : {}),
|
|
826
|
+
}, { durable: true });
|
|
827
|
+
return { kind: 'requested', cancelRequestId };
|
|
828
|
+
});
|
|
829
|
+
}
|
|
243
830
|
function atomicWriteJson(path, value) {
|
|
244
831
|
mkdirSync(dirname(path), { recursive: true });
|
|
245
832
|
const tmp = `${path}.tmp`;
|
|
@@ -276,6 +863,7 @@ export function requestV3Retry(baseDir, runId, input = {}) {
|
|
|
276
863
|
const journalPath = join(runDir, 'journal.ndjson');
|
|
277
864
|
if (!existsSync(journalPath))
|
|
278
865
|
return { kind: 'stale-run', reason: 'missing' };
|
|
866
|
+
assertV3RunIntegrityForMutation(runDir);
|
|
279
867
|
const events = readJournal(journalPath);
|
|
280
868
|
const snap = materialize(events);
|
|
281
869
|
// Target resolution: explicit nodeId > the run's blocked pointer > a node
|
|
@@ -318,12 +906,17 @@ export function requestV3Retry(baseDir, runId, input = {}) {
|
|
|
318
906
|
if (!previousAttemptId)
|
|
319
907
|
return { kind: 'stale-run', reason: 'not-blocked' };
|
|
320
908
|
const info = blockedInfoFor(events, nodeId);
|
|
909
|
+
if (events.some((event) => (event.type === 'hostEffectIntent' || event.type === 'hostEffectUncertain') &&
|
|
910
|
+
event.attemptId === previousAttemptId)) {
|
|
911
|
+
return { kind: 'stale-run', reason: 'host-effect-uncertain' };
|
|
912
|
+
}
|
|
321
913
|
// Freshness gate (codex blocker): the click must target the CURRENTLY
|
|
322
914
|
// blocked attempt, not an earlier one whose card survived in the chat.
|
|
323
915
|
if (input.expectedAttemptId && input.expectedAttemptId !== info.attemptId) {
|
|
324
916
|
return { kind: 'stale-run', reason: 'stale-attempt' };
|
|
325
917
|
}
|
|
326
918
|
const nextAttemptId = nextAttemptIdFor(events, attemptKey);
|
|
919
|
+
const resetGate = events.some((event) => event.type === 'hostInputPrepared' && event.attemptId === previousAttemptId);
|
|
327
920
|
// Runtime human-ask answer: persist the chosen option next to the asked
|
|
328
921
|
// attempt (answer.json) and carry its path on the retry event — buildInputs
|
|
329
922
|
// injects it into the next attempt as `{from:'human', name:'answer'}`. Plain
|
|
@@ -365,6 +958,7 @@ export function requestV3Retry(baseDir, runId, input = {}) {
|
|
|
365
958
|
reason: 'blockedRetry',
|
|
366
959
|
previousErrorClass: info.errorClass,
|
|
367
960
|
previousErrorCode: info.errorCode,
|
|
961
|
+
...(resetGate ? { resetGate: true } : {}),
|
|
368
962
|
...(answer ? { answer } : {}),
|
|
369
963
|
});
|
|
370
964
|
return { kind: 'requested', nodeId, previousAttemptId, nextAttemptId };
|
|
@@ -386,6 +980,7 @@ export function requestRevisitGrant(baseDir, runId, input) {
|
|
|
386
980
|
const journalPath = join(runDir, 'journal.ndjson');
|
|
387
981
|
if (!existsSync(journalPath))
|
|
388
982
|
return { kind: 'stale-run', reason: 'missing' };
|
|
983
|
+
assertV3RunIntegrityForMutation(runDir);
|
|
389
984
|
// Reject a half-filled pair before touching state (never widen to run grant).
|
|
390
985
|
const hasSource = input.sourceNodeId !== undefined;
|
|
391
986
|
const hasTo = input.toNodeId !== undefined;
|
|
@@ -449,6 +1044,7 @@ export function requestV3LoopGrant(baseDir, runId, input = {}) {
|
|
|
449
1044
|
const journalPath = join(runDir, 'journal.ndjson');
|
|
450
1045
|
if (!existsSync(journalPath))
|
|
451
1046
|
return { kind: 'stale-run', reason: 'missing' };
|
|
1047
|
+
assertV3RunIntegrityForMutation(runDir);
|
|
452
1048
|
const events = readJournal(journalPath);
|
|
453
1049
|
const snap = materialize(events);
|
|
454
1050
|
// Target: explicit loopId > the run's blocked pointer when it IS a loop >
|
|
@@ -497,8 +1093,17 @@ function unconsumedRetryEvent(events, key) {
|
|
|
497
1093
|
* source is always the runDir.
|
|
498
1094
|
*/
|
|
499
1095
|
export function createV3GateRunner(deps) {
|
|
1096
|
+
const baseDir = deps.baseDir ?? defaultBaseDir();
|
|
500
1097
|
const inFlight = new Set();
|
|
501
1098
|
const rerunRequested = new Set();
|
|
1099
|
+
const activeControllers = new Map();
|
|
1100
|
+
const invokeLifecycleHook = (hook, runId, phase) => {
|
|
1101
|
+
if (!hook)
|
|
1102
|
+
return;
|
|
1103
|
+
void Promise.resolve()
|
|
1104
|
+
.then(() => hook(runId))
|
|
1105
|
+
.catch((err) => deps.onError?.(runId, new Error(`v3 progress ${phase} hook failed: ${err instanceof Error ? err.message : String(err)}`)));
|
|
1106
|
+
};
|
|
502
1107
|
async function drive(runId) {
|
|
503
1108
|
// Coalesce (codex blocker #2): if a drive is already in flight for this run,
|
|
504
1109
|
// DON'T silently no-op — a click that resolved a gate + called driveDetached
|
|
@@ -513,18 +1118,61 @@ export function createV3GateRunner(deps) {
|
|
|
513
1118
|
try {
|
|
514
1119
|
do {
|
|
515
1120
|
rerunRequested.delete(runId); // clear before the run; a request DURING re-sets it
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
1121
|
+
invokeLifecycleHook(deps.onDriveBegin, runId, 'begin');
|
|
1122
|
+
const controller = new AbortController();
|
|
1123
|
+
activeControllers.set(runId, controller);
|
|
1124
|
+
try {
|
|
1125
|
+
// The in-memory guard above prevents duplicate drives inside one
|
|
1126
|
+
// daemon. This lease extends the same invariant across rolling
|
|
1127
|
+
// restarts / an accidental second daemon: only the process that owns
|
|
1128
|
+
// the live worker promises may schedule, drain peers, or publish a
|
|
1129
|
+
// run boundary.
|
|
1130
|
+
// A cancel request itself uses the independent journal lock, so it
|
|
1131
|
+
// can still wake the lease holder while a second daemon waits here.
|
|
1132
|
+
const leaseTarget = v3DriveLeaseTarget(baseDir, runId);
|
|
1133
|
+
let leaseSettled = false;
|
|
1134
|
+
while (!leaseSettled) {
|
|
1135
|
+
try {
|
|
1136
|
+
await withFileLock(leaseTarget, async () => {
|
|
1137
|
+
// A durable cancel can land while driveV3Run is no longer in
|
|
1138
|
+
// runtime (for example it is awaiting a slow gate-card POST).
|
|
1139
|
+
// Re-fold under the SAME lease before releasing ownership so
|
|
1140
|
+
// the request cannot be stranded between runtime and transport.
|
|
1141
|
+
do {
|
|
1142
|
+
await driveV3Run(runId, {
|
|
1143
|
+
baseDir,
|
|
1144
|
+
loadBots: deps.loadBots,
|
|
1145
|
+
makeRunNode: deps.makeRunNode,
|
|
1146
|
+
validateManifest: deps.validateManifest,
|
|
1147
|
+
maxParallel: deps.maxParallel,
|
|
1148
|
+
cancelSignal: controller.signal,
|
|
1149
|
+
postGateCard: (binding, gate, rid) => deps.postCard(binding, gate, rid),
|
|
1150
|
+
postBlockedCard: deps.postBlockedCard,
|
|
1151
|
+
postLoopGrantCard: deps.postLoopGrantCard,
|
|
1152
|
+
postRevisitGrantCard: deps.postRevisitGrantCard,
|
|
1153
|
+
onTerminal: (rid, outcome, binding) => deps.notifyTerminal ? deps.notifyTerminal(binding, rid, outcome) : Promise.resolve(),
|
|
1154
|
+
});
|
|
1155
|
+
} while (currentRunStatus(baseDir, runId) === 'cancelling');
|
|
1156
|
+
}, { maxWaitMs: V3_DRIVE_LEASE_MAX_WAIT_MS });
|
|
1157
|
+
leaseSettled = true;
|
|
1158
|
+
}
|
|
1159
|
+
catch (err) {
|
|
1160
|
+
// A second daemon may legitimately wait longer than one lock
|
|
1161
|
+
// window while the owner drains a wedged CLI or a Lark request.
|
|
1162
|
+
// Durable cancellation must keep a waiter alive until the lease
|
|
1163
|
+
// is released; ordinary duplicate drives may still fail fast.
|
|
1164
|
+
const lockTimedOut = err instanceof Error && err.message.includes('file-lock timeout waiting for');
|
|
1165
|
+
if (lockTimedOut && currentRunStatus(baseDir, runId) === 'cancelling')
|
|
1166
|
+
continue;
|
|
1167
|
+
throw err;
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
finally {
|
|
1172
|
+
if (activeControllers.get(runId) === controller)
|
|
1173
|
+
activeControllers.delete(runId);
|
|
1174
|
+
invokeLifecycleHook(deps.onDriveEnd, runId, 'end');
|
|
1175
|
+
}
|
|
528
1176
|
} while (rerunRequested.has(runId));
|
|
529
1177
|
}
|
|
530
1178
|
catch (err) {
|
|
@@ -533,16 +1181,26 @@ export function createV3GateRunner(deps) {
|
|
|
533
1181
|
finally {
|
|
534
1182
|
inFlight.delete(runId);
|
|
535
1183
|
rerunRequested.delete(runId);
|
|
1184
|
+
activeControllers.delete(runId);
|
|
536
1185
|
}
|
|
537
1186
|
}
|
|
538
1187
|
/** Fire-and-forget drive (card-click / start IPC call this). */
|
|
539
1188
|
function driveDetached(runId) {
|
|
540
1189
|
void drive(runId);
|
|
541
1190
|
}
|
|
1191
|
+
/** Deliver an already-durable cancel request to the active runtime and make
|
|
1192
|
+
* sure a fresh replay runs even when the request raced post-card/teardown. */
|
|
1193
|
+
function cancelAndDrive(runId, cancelRequestId) {
|
|
1194
|
+
const controller = activeControllers.get(runId);
|
|
1195
|
+
if (controller && !controller.signal.aborted) {
|
|
1196
|
+
controller.abort({ kind: 'run', cancelRequestId });
|
|
1197
|
+
}
|
|
1198
|
+
driveDetached(runId);
|
|
1199
|
+
}
|
|
542
1200
|
async function coldAttach(ownerLarkAppId) {
|
|
543
1201
|
let recs = [];
|
|
544
1202
|
try {
|
|
545
|
-
recs = reconcileV3PendingGates(
|
|
1203
|
+
recs = reconcileV3PendingGates(baseDir, ownerLarkAppId);
|
|
546
1204
|
}
|
|
547
1205
|
catch (err) {
|
|
548
1206
|
deps.onError?.('(cold-attach)', err);
|
|
@@ -595,7 +1253,20 @@ export function createV3GateRunner(deps) {
|
|
|
595
1253
|
driveDetached(rec.runId);
|
|
596
1254
|
}
|
|
597
1255
|
}
|
|
598
|
-
return { drive, driveDetached, coldAttach };
|
|
1256
|
+
return { drive, driveDetached, cancelAndDrive, coldAttach };
|
|
1257
|
+
}
|
|
1258
|
+
function currentRunStatus(baseDir, runId) {
|
|
1259
|
+
try {
|
|
1260
|
+
const journalPath = join(safeRunDir(baseDir, runId), 'journal.ndjson');
|
|
1261
|
+
if (!existsSync(journalPath))
|
|
1262
|
+
return undefined;
|
|
1263
|
+
return materialize(readJournal(journalPath)).runStatus;
|
|
1264
|
+
}
|
|
1265
|
+
catch {
|
|
1266
|
+
// The actual drive path reports integrity/journal errors. This helper is
|
|
1267
|
+
// only a retry predicate and must never convert corruption into a spin.
|
|
1268
|
+
return undefined;
|
|
1269
|
+
}
|
|
599
1270
|
}
|
|
600
1271
|
/**
|
|
601
1272
|
* Cold-attach reconcile (daemon startup, codex review #2/#3). Finds v3 runs
|
|
@@ -624,31 +1295,66 @@ export function reconcileV3PendingGates(baseDir = defaultBaseDir(), ownerLarkApp
|
|
|
624
1295
|
const journalPath = join(runDir, 'journal.ndjson');
|
|
625
1296
|
if (!existsSync(journalPath))
|
|
626
1297
|
continue;
|
|
1298
|
+
// Recovery may recreate a missing wait or heal a resolved wait by
|
|
1299
|
+
// appending gateResolved. Apply the same authorization boundary as live
|
|
1300
|
+
// clicks before cold-attach can mutate or repost anything for this run.
|
|
1301
|
+
assertV3RunIntegrityForMutation(runDir);
|
|
627
1302
|
const events = readJournal(journalPath);
|
|
628
1303
|
const snap = materialize(events);
|
|
629
|
-
|
|
1304
|
+
const hasOpenAttempts = openV3WorkerAttempts(events).length > 0 || openV3HostEffects(events).length > 0;
|
|
1305
|
+
if (snap.runStatus === 'succeeded' ||
|
|
1306
|
+
snap.runStatus === 'failed' ||
|
|
1307
|
+
snap.runStatus === 'cancelled') {
|
|
1308
|
+
if (!hasOpenAttempts)
|
|
1309
|
+
continue;
|
|
1310
|
+
const binding = readV3RunChatBinding(runDir);
|
|
1311
|
+
if (ownerLarkAppId && binding?.larkAppId !== ownerLarkAppId)
|
|
1312
|
+
continue;
|
|
1313
|
+
if (!binding)
|
|
1314
|
+
continue;
|
|
1315
|
+
// Pre-barrier histories may have published a terminal before a peer
|
|
1316
|
+
// outer process closed. Re-drive only to clean resources; driveV3Run's
|
|
1317
|
+
// already-terminal guard suppresses duplicate terminal notification.
|
|
1318
|
+
out.push({ runId, runDir, binding, repost: [], resume: true });
|
|
1319
|
+
continue;
|
|
1320
|
+
}
|
|
1321
|
+
if (snap.runStatus === 'cancelling') {
|
|
1322
|
+
const binding = readV3RunChatBinding(runDir);
|
|
1323
|
+
if (ownerLarkAppId && binding?.larkAppId !== ownerLarkAppId)
|
|
1324
|
+
continue;
|
|
1325
|
+
// Never repost stale gate/retry cards while cancellation is in
|
|
1326
|
+
// progress. A cold drive converges pending/gated nodes immediately;
|
|
1327
|
+
// workers from the dead daemon exit on IPC disconnect.
|
|
1328
|
+
out.push({ runId, runDir, binding, repost: [], resume: true });
|
|
630
1329
|
continue;
|
|
1330
|
+
}
|
|
631
1331
|
if (snap.runStatus === 'blocked') {
|
|
1332
|
+
if (hasOpenAttempts) {
|
|
1333
|
+
const binding = readV3RunChatBinding(runDir);
|
|
1334
|
+
if (ownerLarkAppId && binding?.larkAppId !== ownerLarkAppId)
|
|
1335
|
+
continue;
|
|
1336
|
+
if (!binding)
|
|
1337
|
+
continue;
|
|
1338
|
+
// Cleanup must finish before the retry/grant card is visible: an
|
|
1339
|
+
// immediate click must never overlap a pre-block bypass worker.
|
|
1340
|
+
out.push({ runId, runDir, binding, repost: [], resume: true });
|
|
1341
|
+
continue;
|
|
1342
|
+
}
|
|
632
1343
|
// Blocked run: repost the recovery card (covers the crash window
|
|
633
1344
|
// between the runBlocked append and the original card send) — grant
|
|
634
1345
|
// card for an exhausted loop, retry card for a blocked node. Owner-
|
|
635
1346
|
// filtered like gates; binding-less (CLI/dev) runs are left alone.
|
|
636
|
-
const
|
|
637
|
-
const binding = grill?.chatBinding;
|
|
1347
|
+
const binding = readV3RunChatBinding(runDir);
|
|
638
1348
|
if (ownerLarkAppId && binding?.larkAppId !== ownerLarkAppId)
|
|
639
1349
|
continue;
|
|
640
1350
|
if (!binding || !snap.blockedNodeId)
|
|
641
1351
|
continue;
|
|
642
1352
|
if (snap.loops.has(snap.blockedNodeId)) {
|
|
643
1353
|
const info = loopExhaustedInfoFor(events, snap.blockedNodeId);
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
info.maxIterations = loopNode.maxIterations;
|
|
649
|
-
}
|
|
650
|
-
catch { /* display-only enrichment — card renders without it */ }
|
|
651
|
-
}
|
|
1354
|
+
const recoveryDag = loadV3RunDagForRecovery(runDir);
|
|
1355
|
+
const loopNode = recoveryDag?.nodes.find((n) => n.id === snap.blockedNodeId);
|
|
1356
|
+
if (loopNode && isLoopNode(loopNode))
|
|
1357
|
+
info.maxIterations = loopNode.maxIterations;
|
|
652
1358
|
out.push({ runId, runDir, binding, repost: [], repostLoopGrant: info, resume: false });
|
|
653
1359
|
}
|
|
654
1360
|
else {
|
|
@@ -671,14 +1377,27 @@ export function reconcileV3PendingGates(baseDir = defaultBaseDir(), ownerLarkApp
|
|
|
671
1377
|
// runStatus === 'running'
|
|
672
1378
|
const rec = reconcileOneRun(runId, runDir, journalPath, snap, ownerLarkAppId);
|
|
673
1379
|
if (rec) {
|
|
674
|
-
|
|
1380
|
+
// A pending gate may coexist with an attempt owned by the dead daemon.
|
|
1381
|
+
// Let the drive fence/requeue it first; that drive will post every gate
|
|
1382
|
+
// still pending after resource convergence.
|
|
1383
|
+
out.push(hasOpenAttempts ? { ...rec, repost: [], resume: true } : rec);
|
|
1384
|
+
continue;
|
|
1385
|
+
}
|
|
1386
|
+
if (hasOpenAttempts) {
|
|
1387
|
+
const binding = readV3RunChatBinding(runDir);
|
|
1388
|
+
if (ownerLarkAppId && binding?.larkAppId !== ownerLarkAppId)
|
|
1389
|
+
continue;
|
|
1390
|
+
if (!binding)
|
|
1391
|
+
continue;
|
|
1392
|
+
out.push({ runId, runDir, binding, repost: [], resume: true });
|
|
675
1393
|
continue;
|
|
676
1394
|
}
|
|
677
|
-
// No gate to reconcile.
|
|
678
|
-
// a resumable spot — e.g. crash right
|
|
679
|
-
//
|
|
680
|
-
//
|
|
681
|
-
//
|
|
1395
|
+
// No gate or open attempt to reconcile. If nothing is materialized as
|
|
1396
|
+
// running, the run died in a resumable control spot — e.g. crash right
|
|
1397
|
+
// after `nodeRetryRequested` or start — so re-drive it. Open worker
|
|
1398
|
+
// attempts were handled above by the unified fence barrier; a remaining
|
|
1399
|
+
// running node without an open ledger record is malformed/legacy state
|
|
1400
|
+
// and stays fail-closed here.
|
|
682
1401
|
//
|
|
683
1402
|
// Composite LOOP nodes are excluded from the phantom check (codex loop
|
|
684
1403
|
// review blocker): a loop is 'running' in PURE CONTROL states with no
|
|
@@ -689,8 +1408,7 @@ export function reconcileV3PendingGates(baseDir = defaultBaseDir(), ownerLarkApp
|
|
|
689
1408
|
// before redrive). Body INSTANCES still count as real in-flight.
|
|
690
1409
|
const hasRunning = [...snap.nodes.entries()].some(([id, s]) => s.status === 'running' && !snap.loops.has(id));
|
|
691
1410
|
if (!hasRunning) {
|
|
692
|
-
const
|
|
693
|
-
const binding = grill?.chatBinding;
|
|
1411
|
+
const binding = readV3RunChatBinding(runDir);
|
|
694
1412
|
if (ownerLarkAppId && binding?.larkAppId !== ownerLarkAppId)
|
|
695
1413
|
continue;
|
|
696
1414
|
if (!binding)
|
|
@@ -707,13 +1425,13 @@ export function reconcileV3PendingGates(baseDir = defaultBaseDir(), ownerLarkApp
|
|
|
707
1425
|
return out;
|
|
708
1426
|
}
|
|
709
1427
|
function reconcileOneRun(runId, runDir, journalPath, snap, ownerLarkAppId) {
|
|
1428
|
+
const events = readJournal(journalPath);
|
|
710
1429
|
const gateWaitingNodes = [...snap.nodes.entries()]
|
|
711
1430
|
.filter(([, s]) => s.status === 'gateWaiting')
|
|
712
1431
|
.map(([id]) => id);
|
|
713
1432
|
if (gateWaitingNodes.length === 0)
|
|
714
1433
|
return undefined;
|
|
715
|
-
const
|
|
716
|
-
const binding = grill?.chatBinding;
|
|
1434
|
+
const binding = readV3RunChatBinding(runDir);
|
|
717
1435
|
// Multi-daemon owner filter (codex blocker #1): each bot daemon must only
|
|
718
1436
|
// touch runs bound to ITS larkAppId — otherwise every online daemon re-posts
|
|
719
1437
|
// / resumes the same pending gate. A run with no binding (CLI/dev) or a
|
|
@@ -722,15 +1440,25 @@ function reconcileOneRun(runId, runDir, journalPath, snap, ownerLarkAppId) {
|
|
|
722
1440
|
return undefined;
|
|
723
1441
|
// dag (for humanGate.prompt when re-creating a missing wait).
|
|
724
1442
|
const dagNodeGate = new Map();
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
1443
|
+
const trustedHostGates = new Map();
|
|
1444
|
+
const recoveryDag = loadV3RunDagForRecovery(runDir);
|
|
1445
|
+
if (recoveryDag) {
|
|
1446
|
+
for (const n of recoveryDag.nodes) {
|
|
1447
|
+
if (!n.humanGate?.prompt)
|
|
1448
|
+
continue;
|
|
1449
|
+
const gate = normalizeGateWaitInput(n.humanGate);
|
|
1450
|
+
if (!isHostNode(n)) {
|
|
1451
|
+
dagNodeGate.set(n.id, gate);
|
|
1452
|
+
continue;
|
|
1453
|
+
}
|
|
1454
|
+
const instanceId = snap.nodes.get(n.id)?.effectiveInstanceId;
|
|
1455
|
+
if (!instanceId)
|
|
1456
|
+
continue;
|
|
1457
|
+
const trusted = trustedHostGateMaterial(runDir, runId, n.id, instanceId, events);
|
|
1458
|
+
if (trusted) {
|
|
1459
|
+
trustedHostGates.set(n.id, trusted);
|
|
1460
|
+
dagNodeGate.set(n.id, trusted);
|
|
730
1461
|
}
|
|
731
|
-
}
|
|
732
|
-
catch {
|
|
733
|
-
/* dag unreadable — fall back to a generic prompt below */
|
|
734
1462
|
}
|
|
735
1463
|
}
|
|
736
1464
|
const repost = [];
|
|
@@ -739,20 +1467,84 @@ function reconcileOneRun(runId, runDir, journalPath, snap, ownerLarkAppId) {
|
|
|
739
1467
|
// Instance-level waitId mirrors startGate so recovery reads the SAME wait
|
|
740
1468
|
// file the dispatch wrote (stale-card protection).
|
|
741
1469
|
const instanceId = snap.nodes.get(nodeId)?.effectiveInstanceId;
|
|
742
|
-
const
|
|
1470
|
+
const recoveredGate = dagNodeGate.get(nodeId);
|
|
1471
|
+
const trustedHostGate = trustedHostGates.get(nodeId);
|
|
1472
|
+
const dispatchedHostApproval = [...events].reverse().find((event) => event.type === 'gateDispatched' &&
|
|
1473
|
+
event.nodeId === nodeId &&
|
|
1474
|
+
event.instanceId === instanceId &&
|
|
1475
|
+
!!event.hostApproval)?.hostApproval;
|
|
1476
|
+
const waitId = v3GateWaitId(nodeId, instanceId, trustedHostGate?.hostApproval ?? recoveredGate?.hostApproval ?? dispatchedHostApproval);
|
|
743
1477
|
let wait = readWait(runDir, waitId);
|
|
1478
|
+
const recoveryNode = recoveryDag?.nodes.find((node) => node.id === nodeId);
|
|
1479
|
+
if (recoveryNode && isHostNode(recoveryNode)) {
|
|
1480
|
+
if (!trustedHostGate) {
|
|
1481
|
+
// The mutable wait can never substitute for missing/corrupt frozen
|
|
1482
|
+
// input. Reject with the token from the durable dispatch, if any.
|
|
1483
|
+
appendEvent(journalPath, {
|
|
1484
|
+
type: 'gateResolved',
|
|
1485
|
+
nodeId,
|
|
1486
|
+
...(instanceId ? { instanceId } : {}),
|
|
1487
|
+
waitId,
|
|
1488
|
+
resolution: 'rejected',
|
|
1489
|
+
by: 'system-host-input-unrecoverable',
|
|
1490
|
+
...(dispatchedHostApproval ? { hostApproval: dispatchedHostApproval } : {}),
|
|
1491
|
+
});
|
|
1492
|
+
resume = true;
|
|
1493
|
+
continue;
|
|
1494
|
+
}
|
|
1495
|
+
if (wait?.status === 'pending' && !waitMatchesTrustedHostGate(wait, trustedHostGate)) {
|
|
1496
|
+
// Pending delivery state is safe to repair because no human decision
|
|
1497
|
+
// has landed. Re-render from authorized DAG + verified sidecar.
|
|
1498
|
+
wait = writePendingWait(runDir, trustedHostGate);
|
|
1499
|
+
}
|
|
1500
|
+
else if (wait && wait.status !== 'pending' && !waitMatchesTrustedHostGate(wait, trustedHostGate)) {
|
|
1501
|
+
appendEvent(journalPath, {
|
|
1502
|
+
type: 'gateResolved',
|
|
1503
|
+
nodeId,
|
|
1504
|
+
...(instanceId ? { instanceId } : {}),
|
|
1505
|
+
waitId,
|
|
1506
|
+
resolution: 'rejected',
|
|
1507
|
+
by: 'system-host-wait-integrity',
|
|
1508
|
+
hostApproval: trustedHostGate.hostApproval,
|
|
1509
|
+
});
|
|
1510
|
+
resume = true;
|
|
1511
|
+
continue;
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
744
1514
|
if (!wait) {
|
|
745
|
-
const gate = dagNodeGate.get(nodeId)
|
|
746
|
-
|
|
1515
|
+
const gate = dagNodeGate.get(nodeId);
|
|
1516
|
+
if (!gate && recoveryNode && isHostNode(recoveryNode)) {
|
|
1517
|
+
// A host gate is approval of one frozen input hash. If that input
|
|
1518
|
+
// cannot be verified, never recreate a generic/static card that could
|
|
1519
|
+
// approve different bytes; reject the gate and surface a failed run.
|
|
1520
|
+
const dispatched = [...events].reverse().find((event) => event.type === 'gateDispatched' && event.nodeId === nodeId && event.instanceId === instanceId);
|
|
1521
|
+
appendEvent(journalPath, {
|
|
1522
|
+
type: 'gateResolved',
|
|
1523
|
+
nodeId,
|
|
1524
|
+
...(instanceId ? { instanceId } : {}),
|
|
1525
|
+
waitId,
|
|
1526
|
+
resolution: 'rejected',
|
|
1527
|
+
by: 'system-host-input-unrecoverable',
|
|
1528
|
+
...(dispatched?.hostApproval ? { hostApproval: dispatched.hostApproval } : {}),
|
|
1529
|
+
});
|
|
1530
|
+
resume = true;
|
|
1531
|
+
continue;
|
|
1532
|
+
}
|
|
1533
|
+
const safeGate = gate ?? normalizeGateWaitInput({ prompt: '(humanGate — 等待人工审批)' });
|
|
1534
|
+
wait = writePendingWait(runDir, { waitId, nodeId, ...(instanceId ? { instanceId } : {}), ...safeGate });
|
|
747
1535
|
}
|
|
748
1536
|
if (wait.status === 'pending') {
|
|
1537
|
+
const display = trustedHostGate ?? wait;
|
|
749
1538
|
repost.push({
|
|
750
1539
|
nodeId,
|
|
751
1540
|
waitId,
|
|
752
|
-
prompt:
|
|
753
|
-
options:
|
|
754
|
-
approveOptions:
|
|
755
|
-
approvers:
|
|
1541
|
+
prompt: display.prompt,
|
|
1542
|
+
options: display.options,
|
|
1543
|
+
approveOptions: display.approveOptions,
|
|
1544
|
+
approvers: display.approvers,
|
|
1545
|
+
...(trustedHostGate
|
|
1546
|
+
? { hostApproval: trustedHostGate.hostApproval }
|
|
1547
|
+
: wait.hostApproval ? { hostApproval: wait.hostApproval } : {}),
|
|
756
1548
|
});
|
|
757
1549
|
}
|
|
758
1550
|
else {
|
|
@@ -766,6 +1558,9 @@ function reconcileOneRun(runId, runDir, journalPath, snap, ownerLarkAppId) {
|
|
|
766
1558
|
resolution: wait.status,
|
|
767
1559
|
by: wait.by ?? 'system',
|
|
768
1560
|
selected: wait.selected,
|
|
1561
|
+
...(trustedHostGate
|
|
1562
|
+
? { hostApproval: trustedHostGate.hostApproval }
|
|
1563
|
+
: wait.hostApproval ? { hostApproval: wait.hostApproval } : {}),
|
|
769
1564
|
});
|
|
770
1565
|
resume = true;
|
|
771
1566
|
}
|