botmux 3.9.1 → 3.10.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 +1 -1
- package/README.md +1 -1
- package/dist/.runtime-build-id +1 -1
- package/dist/adapters/cli/codex.d.ts.map +1 -1
- package/dist/adapters/cli/codex.js +6 -0
- package/dist/adapters/cli/codex.js.map +1 -1
- package/dist/adapters/cli/opencode.d.ts.map +1 -1
- package/dist/adapters/cli/opencode.js +7 -1
- package/dist/adapters/cli/opencode.js.map +1 -1
- package/dist/adapters/cli/reasonix.d.ts +35 -0
- package/dist/adapters/cli/reasonix.d.ts.map +1 -0
- package/dist/adapters/cli/reasonix.js +236 -0
- package/dist/adapters/cli/reasonix.js.map +1 -0
- package/dist/adapters/cli/registry.d.ts +2 -1
- package/dist/adapters/cli/registry.d.ts.map +1 -1
- package/dist/adapters/cli/registry.js +4 -1
- package/dist/adapters/cli/registry.js.map +1 -1
- package/dist/adapters/cli/traex.d.ts.map +1 -1
- package/dist/adapters/cli/traex.js +87 -87
- package/dist/adapters/cli/traex.js.map +1 -1
- package/dist/adapters/cli/types.d.ts +5 -1
- package/dist/adapters/cli/types.d.ts.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +253 -69
- package/dist/cli.js.map +1 -1
- package/dist/core/command-handler.d.ts +18 -4
- package/dist/core/command-handler.d.ts.map +1 -1
- package/dist/core/command-handler.js +274 -27
- package/dist/core/command-handler.js.map +1 -1
- package/dist/core/dashboard-ipc-server.d.ts +1 -0
- package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
- package/dist/core/dashboard-ipc-server.js +27 -3
- package/dist/core/dashboard-ipc-server.js.map +1 -1
- package/dist/core/dispatch.d.ts +54 -24
- package/dist/core/dispatch.d.ts.map +1 -1
- package/dist/core/dispatch.js +81 -27
- package/dist/core/dispatch.js.map +1 -1
- package/dist/core/input-turn-dedupe.d.ts +20 -0
- package/dist/core/input-turn-dedupe.d.ts.map +1 -0
- package/dist/core/input-turn-dedupe.js +57 -0
- package/dist/core/input-turn-dedupe.js.map +1 -0
- package/dist/core/local-terminal-opener.d.ts.map +1 -1
- package/dist/core/local-terminal-opener.js +10 -1
- package/dist/core/local-terminal-opener.js.map +1 -1
- package/dist/core/passthrough-commands.d.ts.map +1 -1
- package/dist/core/passthrough-commands.js +1 -1
- package/dist/core/passthrough-commands.js.map +1 -1
- package/dist/core/plugins/pm2.d.ts.map +1 -1
- package/dist/core/plugins/pm2.js +7 -1
- package/dist/core/plugins/pm2.js.map +1 -1
- package/dist/core/resource-monitor/attribution.d.ts.map +1 -1
- package/dist/core/resource-monitor/attribution.js +17 -1
- package/dist/core/resource-monitor/attribution.js.map +1 -1
- package/dist/core/resource-monitor/darwin.d.ts +145 -0
- package/dist/core/resource-monitor/darwin.d.ts.map +1 -0
- package/dist/core/resource-monitor/darwin.js +360 -0
- package/dist/core/resource-monitor/darwin.js.map +1 -0
- package/dist/core/resource-monitor/procfs.d.ts.map +1 -1
- package/dist/core/resource-monitor/procfs.js +6 -0
- package/dist/core/resource-monitor/procfs.js.map +1 -1
- package/dist/core/resource-monitor/types.d.ts +1 -1
- package/dist/core/resource-monitor/types.d.ts.map +1 -1
- package/dist/core/scheduler.d.ts.map +1 -1
- package/dist/core/scheduler.js +5 -2
- package/dist/core/scheduler.js.map +1 -1
- package/dist/core/session-discovery.d.ts.map +1 -1
- package/dist/core/session-discovery.js +3 -0
- package/dist/core/session-discovery.js.map +1 -1
- package/dist/core/session-manager.d.ts +3 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +46 -0
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-marker.d.ts +1 -8
- package/dist/core/session-marker.d.ts.map +1 -1
- package/dist/core/session-marker.js +2 -50
- package/dist/core/session-marker.js.map +1 -1
- package/dist/core/types.d.ts +3 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/worker-pool.d.ts +17 -0
- package/dist/core/worker-pool.d.ts.map +1 -1
- package/dist/core/worker-pool.js +292 -9
- package/dist/core/worker-pool.js.map +1 -1
- package/dist/daemon.d.ts +11 -1
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +59 -15
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard/daemon-internal-api.d.ts.map +1 -1
- package/dist/dashboard/daemon-internal-api.js +11 -2
- package/dist/dashboard/daemon-internal-api.js.map +1 -1
- package/dist/dashboard/groups-action-helpers.d.ts +2 -0
- package/dist/dashboard/groups-action-helpers.d.ts.map +1 -1
- package/dist/dashboard/groups-action-helpers.js +9 -0
- package/dist/dashboard/groups-action-helpers.js.map +1 -1
- package/dist/dashboard/groups-matrix-snapshot.d.ts +56 -0
- package/dist/dashboard/groups-matrix-snapshot.d.ts.map +1 -0
- package/dist/dashboard/groups-matrix-snapshot.js +127 -0
- package/dist/dashboard/groups-matrix-snapshot.js.map +1 -0
- package/dist/dashboard/resource-monitor-service.d.ts.map +1 -1
- package/dist/dashboard/resource-monitor-service.js +18 -2
- package/dist/dashboard/resource-monitor-service.js.map +1 -1
- package/dist/dashboard/web/app.d.ts.map +1 -1
- package/dist/dashboard/web/app.js +45 -4
- package/dist/dashboard/web/app.js.map +1 -1
- package/dist/dashboard/web/groups-api.js +1 -1
- package/dist/dashboard/web/groups-api.js.map +1 -1
- package/dist/dashboard/web/i18n.js +10 -10
- package/dist/dashboard/web/i18n.js.map +1 -1
- package/dist/dashboard/web/roles-page.d.ts.map +1 -1
- package/dist/dashboard/web/roles-page.js +26 -11
- package/dist/dashboard/web/roles-page.js.map +1 -1
- package/dist/dashboard-web/app.js +1 -1
- package/dist/dashboard-web/chunks/{bot-defaults-page-BHTQEWCH.js → bot-defaults-page-LTVOUDIS.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-KLZCQAHF.js → chunk-3UE7S77S.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-W77TPKZH.js → chunk-DCS35UMD.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-E3HZZXK5.js → chunk-MFQPCVHY.js} +4 -4
- package/dist/dashboard-web/chunks/{chunk-EZH56JCI.js → chunk-ZU3UUKAR.js} +1 -1
- package/dist/dashboard-web/chunks/{connectors-page-BP255CAX.js → connectors-page-5KWDIMKC.js} +1 -1
- package/dist/dashboard-web/chunks/{groups-page-CDHVXBUT.js → groups-page-FHOKYXMW.js} +1 -1
- package/dist/dashboard-web/chunks/{insights-page-57BFE6GT.js → insights-page-T2ZX2RWL.js} +1 -1
- package/dist/dashboard-web/chunks/{monitor-room-UTOYGQVF.js → monitor-room-YNVBAGR6.js} +1 -1
- package/dist/dashboard-web/chunks/{monitoring-page-WTHYAIUM.js → monitoring-page-LHM55YWN.js} +1 -1
- package/dist/dashboard-web/chunks/{office-page-JSMIB353.js → office-page-ATXVP7PW.js} +1 -1
- package/dist/dashboard-web/chunks/{overview-page-3VDBOH7L.js → overview-page-QYI3KBDD.js} +1 -1
- package/dist/dashboard-web/chunks/roles-page-56VWM6CD.js +1 -0
- package/dist/dashboard-web/chunks/{schedules-page-HHN736H6.js → schedules-page-S5K6U4EO.js} +1 -1
- package/dist/dashboard-web/chunks/{sessions-page-EIWOZD7A.js → sessions-page-WBP4N7D2.js} +1 -1
- package/dist/dashboard-web/chunks/{settings-page-2IUT5LS4.js → settings-page-QUZDQARR.js} +1 -1
- package/dist/dashboard-web/chunks/{skills-page-JKFKMUEM.js → skills-page-IFY7AEND.js} +1 -1
- package/dist/dashboard-web/chunks/{team-federation-page-Q2PXC3UY.js → team-federation-page-C7FJQPFZ.js} +1 -1
- package/dist/dashboard-web/chunks/{v3-page-EBQCD4AO.js → v3-page-2LMF3WWR.js} +1 -1
- package/dist/dashboard-web/chunks/{whiteboards-page-QZRMVNZN.js → whiteboards-page-3XC6QRMY.js} +1 -1
- package/dist/dashboard-web/style.css +2 -4
- package/dist/dashboard.js +65 -9
- package/dist/dashboard.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +34 -7
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +32 -7
- package/dist/i18n/zh.js.map +1 -1
- package/dist/im/lark/card-builder.d.ts +7 -0
- package/dist/im/lark/card-builder.d.ts.map +1 -1
- package/dist/im/lark/card-builder.js +56 -0
- package/dist/im/lark/card-builder.js.map +1 -1
- package/dist/im/lark/card-handler.d.ts.map +1 -1
- package/dist/im/lark/card-handler.js +51 -19
- package/dist/im/lark/card-handler.js.map +1 -1
- package/dist/im/lark/client.d.ts +10 -0
- package/dist/im/lark/client.d.ts.map +1 -1
- package/dist/im/lark/client.js +79 -0
- package/dist/im/lark/client.js.map +1 -1
- package/dist/im/lark/event-dispatcher.d.ts +14 -1
- package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
- package/dist/im/lark/event-dispatcher.js +171 -15
- package/dist/im/lark/event-dispatcher.js.map +1 -1
- package/dist/im/lark/issue-card.d.ts +223 -0
- package/dist/im/lark/issue-card.d.ts.map +1 -0
- package/dist/im/lark/issue-card.js +542 -0
- package/dist/im/lark/issue-card.js.map +1 -0
- package/dist/im/lark/issue-command-deps.d.ts +41 -0
- package/dist/im/lark/issue-command-deps.d.ts.map +1 -0
- package/dist/im/lark/issue-command-deps.js +195 -0
- package/dist/im/lark/issue-command-deps.js.map +1 -0
- package/dist/im/lark/issue-command.d.ts +137 -0
- package/dist/im/lark/issue-command.d.ts.map +1 -0
- package/dist/im/lark/issue-command.js +335 -0
- package/dist/im/lark/issue-command.js.map +1 -0
- package/dist/im/lark/lark-hosts.d.ts +5 -0
- package/dist/im/lark/lark-hosts.d.ts.map +1 -1
- package/dist/im/lark/lark-hosts.js +10 -0
- package/dist/im/lark/lark-hosts.js.map +1 -1
- package/dist/im/lark/message-parser.d.ts.map +1 -1
- package/dist/im/lark/message-parser.js +24 -7
- package/dist/im/lark/message-parser.js.map +1 -1
- package/dist/platform/issue-client.d.ts +201 -0
- package/dist/platform/issue-client.d.ts.map +1 -0
- package/dist/platform/issue-client.js +142 -0
- package/dist/platform/issue-client.js.map +1 -0
- package/dist/platform/platform-http.d.ts +4 -0
- package/dist/platform/platform-http.d.ts.map +1 -1
- package/dist/platform/platform-http.js +38 -2
- package/dist/platform/platform-http.js.map +1 -1
- package/dist/pm2-graceful-exit.d.ts +28 -0
- package/dist/pm2-graceful-exit.d.ts.map +1 -0
- package/dist/pm2-graceful-exit.js +39 -0
- package/dist/pm2-graceful-exit.js.map +1 -0
- package/dist/services/bridge-fallback-gate.d.ts +9 -2
- package/dist/services/bridge-fallback-gate.d.ts.map +1 -1
- package/dist/services/bridge-fallback-gate.js +31 -19
- package/dist/services/bridge-fallback-gate.js.map +1 -1
- package/dist/services/issue-board-store.d.ts +214 -0
- package/dist/services/issue-board-store.d.ts.map +1 -0
- package/dist/services/issue-board-store.js +472 -0
- package/dist/services/issue-board-store.js.map +1 -0
- package/dist/services/issue-claim-flow.d.ts +160 -0
- package/dist/services/issue-claim-flow.d.ts.map +1 -0
- package/dist/services/issue-claim-flow.js +222 -0
- package/dist/services/issue-claim-flow.js.map +1 -0
- package/dist/services/issue-outbox-pump.d.ts +25 -0
- package/dist/services/issue-outbox-pump.d.ts.map +1 -0
- package/dist/services/issue-outbox-pump.js +102 -0
- package/dist/services/issue-outbox-pump.js.map +1 -0
- package/dist/services/issue-release.d.ts +78 -0
- package/dist/services/issue-release.d.ts.map +1 -0
- package/dist/services/issue-release.js +89 -0
- package/dist/services/issue-release.js.map +1 -0
- package/dist/services/issue-report.d.ts +72 -0
- package/dist/services/issue-report.d.ts.map +1 -0
- package/dist/services/issue-report.js +84 -0
- package/dist/services/issue-report.js.map +1 -0
- package/dist/services/issue-status-view.d.ts +52 -0
- package/dist/services/issue-status-view.d.ts.map +1 -0
- package/dist/services/issue-status-view.js +42 -0
- package/dist/services/issue-status-view.js.map +1 -0
- package/dist/services/issue-status-writer.d.ts +98 -0
- package/dist/services/issue-status-writer.d.ts.map +1 -0
- package/dist/services/issue-status-writer.js +123 -0
- package/dist/services/issue-status-writer.js.map +1 -0
- package/dist/services/message-listener-store.d.ts +18 -0
- package/dist/services/message-listener-store.d.ts.map +1 -1
- package/dist/services/message-listener-store.js +35 -10
- package/dist/services/message-listener-store.js.map +1 -1
- package/dist/services/message-listener.d.ts +17 -0
- package/dist/services/message-listener.d.ts.map +1 -1
- package/dist/services/message-listener.js +26 -0
- package/dist/services/message-listener.js.map +1 -1
- package/dist/services/traex-paths.d.ts +14 -2
- package/dist/services/traex-paths.d.ts.map +1 -1
- package/dist/services/traex-paths.js +16 -2
- package/dist/services/traex-paths.js.map +1 -1
- package/dist/services/traex-transcript.d.ts +33 -0
- package/dist/services/traex-transcript.d.ts.map +1 -1
- package/dist/services/traex-transcript.js +135 -28
- package/dist/services/traex-transcript.js.map +1 -1
- package/dist/setup/bot-config-editor.d.ts.map +1 -1
- package/dist/setup/bot-config-editor.js +2 -0
- package/dist/setup/bot-config-editor.js.map +1 -1
- package/dist/setup/lark-scopes.json +1 -2
- package/dist/setup/verify-permissions.d.ts.map +1 -1
- package/dist/setup/verify-permissions.js +8 -0
- package/dist/setup/verify-permissions.js.map +1 -1
- package/dist/types.d.ts +34 -0
- package/dist/types.d.ts.map +1 -1
- 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 +13 -0
- package/dist/utils/child-env.js.map +1 -1
- package/dist/utils/file-lock.d.ts.map +1 -1
- package/dist/utils/file-lock.js +1 -1
- package/dist/utils/file-lock.js.map +1 -1
- package/dist/utils/global-install.d.ts.map +1 -1
- package/dist/utils/global-install.js +56 -10
- package/dist/utils/global-install.js.map +1 -1
- package/dist/utils/idle-detector.d.ts +4 -0
- package/dist/utils/idle-detector.d.ts.map +1 -1
- package/dist/utils/idle-detector.js +25 -0
- package/dist/utils/idle-detector.js.map +1 -1
- package/dist/utils/process-identity.d.ts +7 -0
- package/dist/utils/process-identity.d.ts.map +1 -0
- package/dist/utils/process-identity.js +62 -0
- package/dist/utils/process-identity.js.map +1 -0
- package/dist/worker.js +264 -24
- package/dist/worker.js.map +1 -1
- package/dist/workflows/events/payloads.d.ts +10 -10
- package/dist/workflows/events/schema.d.ts +28 -28
- package/dist/workflows/hostExecutors/registry.d.ts +2 -7
- package/dist/workflows/hostExecutors/registry.d.ts.map +1 -1
- package/dist/workflows/hostExecutors/registry.js.map +1 -1
- package/dist/workflows/shared/provider-reconciler.d.ts +1 -30
- package/dist/workflows/shared/provider-reconciler.d.ts.map +1 -1
- package/dist/workflows/shared/provider-reconciler.js.map +1 -1
- package/dist/workflows/v3/artifact-contract.d.ts +41 -0
- package/dist/workflows/v3/artifact-contract.d.ts.map +1 -0
- package/dist/workflows/v3/artifact-contract.js +20 -0
- package/dist/workflows/v3/artifact-contract.js.map +1 -0
- package/dist/workflows/v3/botmux-attempt-lease.d.ts +7 -0
- package/dist/workflows/v3/botmux-attempt-lease.d.ts.map +1 -0
- package/dist/workflows/v3/botmux-attempt-lease.js +189 -0
- package/dist/workflows/v3/botmux-attempt-lease.js.map +1 -0
- package/dist/workflows/v3/botmux-host-policy.d.ts +7 -0
- package/dist/workflows/v3/botmux-host-policy.d.ts.map +1 -0
- package/dist/workflows/v3/botmux-host-policy.js +34 -0
- package/dist/workflows/v3/botmux-host-policy.js.map +1 -0
- package/dist/workflows/v3/cli-run.d.ts +1 -1
- package/dist/workflows/v3/cli-run.d.ts.map +1 -1
- package/dist/workflows/v3/cli-run.js +1 -1
- package/dist/workflows/v3/cli-run.js.map +1 -1
- package/dist/workflows/v3/contract.d.ts +8 -89
- package/dist/workflows/v3/contract.d.ts.map +1 -1
- package/dist/workflows/v3/contract.js +2 -8
- package/dist/workflows/v3/contract.js.map +1 -1
- package/dist/workflows/v3/core-control.d.ts +16 -0
- package/dist/workflows/v3/core-control.d.ts.map +1 -0
- package/dist/workflows/v3/core-control.js +60 -0
- package/dist/workflows/v3/core-control.js.map +1 -0
- package/dist/workflows/v3/daemon-run.d.ts.map +1 -1
- package/dist/workflows/v3/daemon-run.js +2 -1
- package/dist/workflows/v3/daemon-run.js.map +1 -1
- package/dist/workflows/v3/dag-loader.d.ts +5 -0
- package/dist/workflows/v3/dag-loader.d.ts.map +1 -0
- package/dist/workflows/v3/dag-loader.js +22 -0
- package/dist/workflows/v3/dag-loader.js.map +1 -0
- package/dist/workflows/v3/dag.d.ts +2 -6
- package/dist/workflows/v3/dag.d.ts.map +1 -1
- package/dist/workflows/v3/dag.js +2 -24
- package/dist/workflows/v3/dag.js.map +1 -1
- package/dist/workflows/v3/ephemeral-pool.d.ts.map +1 -1
- package/dist/workflows/v3/ephemeral-pool.js +22 -12
- package/dist/workflows/v3/ephemeral-pool.js.map +1 -1
- package/dist/workflows/v3/event-contract.d.ts +273 -0
- package/dist/workflows/v3/event-contract.d.ts.map +1 -0
- package/dist/workflows/v3/event-contract.js +8 -0
- package/dist/workflows/v3/event-contract.js.map +1 -0
- package/dist/workflows/v3/gate-policy.d.ts +12 -0
- package/dist/workflows/v3/gate-policy.d.ts.map +1 -0
- package/dist/workflows/v3/gate-policy.js +20 -0
- package/dist/workflows/v3/gate-policy.js.map +1 -0
- package/dist/workflows/v3/gate-wait-store.d.ts +99 -0
- package/dist/workflows/v3/gate-wait-store.d.ts.map +1 -0
- package/dist/workflows/v3/gate-wait-store.js +263 -0
- package/dist/workflows/v3/gate-wait-store.js.map +1 -0
- package/dist/workflows/v3/host.js +1 -1
- package/dist/workflows/v3/host.js.map +1 -1
- package/dist/workflows/v3/human-gate.d.ts +4 -99
- package/dist/workflows/v3/human-gate.d.ts.map +1 -1
- package/dist/workflows/v3/human-gate.js +4 -275
- package/dist/workflows/v3/human-gate.js.map +1 -1
- package/dist/workflows/v3/in-process-attempt-lease.d.ts +10 -0
- package/dist/workflows/v3/in-process-attempt-lease.d.ts.map +1 -0
- package/dist/workflows/v3/in-process-attempt-lease.js +47 -0
- package/dist/workflows/v3/in-process-attempt-lease.js.map +1 -0
- package/dist/workflows/v3/journal.d.ts +2 -275
- package/dist/workflows/v3/journal.d.ts.map +1 -1
- package/dist/workflows/v3/journal.js.map +1 -1
- package/dist/workflows/v3/library-service.js +1 -1
- package/dist/workflows/v3/library-service.js.map +1 -1
- package/dist/workflows/v3/orchestrator.d.ts +1 -2
- package/dist/workflows/v3/orchestrator.d.ts.map +1 -1
- package/dist/workflows/v3/orchestrator.js.map +1 -1
- package/dist/workflows/v3/portable-artifact-snapshot.d.ts +15 -0
- package/dist/workflows/v3/portable-artifact-snapshot.d.ts.map +1 -0
- package/dist/workflows/v3/portable-artifact-snapshot.js +76 -0
- package/dist/workflows/v3/portable-artifact-snapshot.js.map +1 -0
- package/dist/workflows/v3/portable-final-outputs.d.ts +37 -0
- package/dist/workflows/v3/portable-final-outputs.d.ts.map +1 -0
- package/dist/workflows/v3/portable-final-outputs.js +137 -0
- package/dist/workflows/v3/portable-final-outputs.js.map +1 -0
- package/dist/workflows/v3/portable-run-snapshot.d.ts +14 -0
- package/dist/workflows/v3/portable-run-snapshot.d.ts.map +1 -0
- package/dist/workflows/v3/portable-run-snapshot.js +176 -0
- package/dist/workflows/v3/portable-run-snapshot.js.map +1 -0
- package/dist/workflows/v3/portable-runtime.d.ts +83 -0
- package/dist/workflows/v3/portable-runtime.d.ts.map +1 -0
- package/dist/workflows/v3/portable-runtime.js +135 -0
- package/dist/workflows/v3/portable-runtime.js.map +1 -0
- package/dist/workflows/v3/runtime-host-contract.d.ts +182 -0
- package/dist/workflows/v3/runtime-host-contract.d.ts.map +1 -0
- package/dist/workflows/v3/runtime-host-contract.js +9 -0
- package/dist/workflows/v3/runtime-host-contract.js.map +1 -0
- package/dist/workflows/v3/runtime.d.ts +12 -226
- package/dist/workflows/v3/runtime.d.ts.map +1 -1
- package/dist/workflows/v3/runtime.js +14 -3173
- package/dist/workflows/v3/runtime.js.map +1 -1
- package/dist/workflows/v3/shared-node-runtime.d.ts +203 -0
- package/dist/workflows/v3/shared-node-runtime.d.ts.map +1 -0
- package/dist/workflows/v3/shared-node-runtime.js +2978 -0
- package/dist/workflows/v3/shared-node-runtime.js.map +1 -0
- package/dist/workflows/v3/shared-runtime.d.ts +17 -0
- package/dist/workflows/v3/shared-runtime.d.ts.map +1 -0
- package/dist/workflows/v3/shared-runtime.js +12 -0
- package/dist/workflows/v3/shared-runtime.js.map +1 -0
- package/package.json +4 -1
- package/dist/dashboard-web/chunks/roles-page-LHVAU2BI.js +0 -1
package/dist/worker.js
CHANGED
|
@@ -52,6 +52,7 @@ import { deriveTerminalViewToken, deriveTerminalWriteToken, resolveTerminalAcces
|
|
|
52
52
|
import { readPlatformBinding } from './platform/binding.js';
|
|
53
53
|
import { loadDashboardSecret, loadPersistedToken } from './dashboard/auth.js';
|
|
54
54
|
import { InflightInputTracker } from './core/inflight-input-tracker.js';
|
|
55
|
+
import { InputTurnDeduper } from './core/input-turn-dedupe.js';
|
|
55
56
|
import { shouldRunQuietRotation, evaluatePidResolverPullback, decideFingerprintSwitch, shouldHealAbsentBaseline, sessionIdFromJsonlPath, SESSION_ID_FILENAME_RE, } from './services/bridge-rotation-policy.js';
|
|
56
57
|
import { CodexBridgeQueue } from './services/codex-bridge-queue.js';
|
|
57
58
|
import { detectCodexComposerState } from './services/codex-composer-state.js';
|
|
@@ -59,7 +60,7 @@ import { generateCodexAppThreadTitle, readCodexAppThreadMetadata, setCodexAppThr
|
|
|
59
60
|
import { buildBotmuxLarkNativeSessionTitle } from './core/session-title.js';
|
|
60
61
|
import { drainCodexRollout, findCodexRolloutBySessionId, findCodexRolloutByPid, findCodexRolloutSetByPid, codexHistorySidIsOwned, splitCodexEventsByCutoff, extractLastCodexTurn, codexSessionIdFromRolloutPath, scanCodexThreadSettings } from './services/codex-transcript.js';
|
|
61
62
|
import { CodexServiceTierTracker, resolveCodexServiceTierSnapshot } from './services/codex-service-tier.js';
|
|
62
|
-
import { drainTraexRollout, findTraexRolloutBySessionId, findTraexRolloutByPid } from './services/traex-transcript.js';
|
|
63
|
+
import { drainTraexRollout, findTraexRolloutBySessionId, findTraexRolloutByPid, findTraexRolloutSetByPid, traexHistorySidIsOwned } from './services/traex-transcript.js';
|
|
63
64
|
import { parseTraexUserInputQuestions } from './services/traex-user-input.js';
|
|
64
65
|
import { cocoEventsPathForSession, drainCocoEvents, findCocoSessionByPid } from './services/coco-transcript.js';
|
|
65
66
|
import { currentHermesStateOffset, drainHermesStateDb, resolveHermesStateDbPath } from './services/hermes-transcript.js';
|
|
@@ -1027,6 +1028,11 @@ let lastSpawnEffectiveCliSessionId;
|
|
|
1027
1028
|
let lastSpawnDeferInitialPrompt = false;
|
|
1028
1029
|
let lastSpawnQueuedInitialPrompt;
|
|
1029
1030
|
let lastSpawnQueuedInitialPromptLogicalContent;
|
|
1031
|
+
// True when this session runs under an outer bwrap supervisor (file sandbox OR
|
|
1032
|
+
// Linux credential-only bwrap) — both make getChildPid() the supervisor, not the
|
|
1033
|
+
// CLI leaf. credentialOnlyBwrap needs host probes so it can't be recomputed from
|
|
1034
|
+
// cfg at gate-check time; capture the spawn-time verdict for currentTraexObservedPid.
|
|
1035
|
+
let lastSpawnOuterBwrapActive = false;
|
|
1030
1036
|
/**
|
|
1031
1037
|
* True only when {@link shouldArmSpawnArgvInitialPromptBusy} says so: argv-
|
|
1032
1038
|
* baked first prompt + SessionStart ready (Grok-class). First markPromptReady
|
|
@@ -1155,7 +1161,7 @@ let closeRequested = false;
|
|
|
1155
1161
|
let capturedSpawnCommand = null;
|
|
1156
1162
|
let deferredTopicOutputTail = '';
|
|
1157
1163
|
const reportedDeferredTopicRoots = new Set();
|
|
1158
|
-
const CLI_DISPLAY_NAMES = { 'claude-code': 'Claude', seed: 'Seed', relay: 'Relay', aiden: 'Aiden', coco: 'CoCo', codex: 'Codex', 'codex-app': 'Codex App', cursor: 'Cursor', gemini: 'Gemini', genius: 'Genius', opencode: 'OpenCode', antigravity: 'Antigravity', mtr: 'MTR', hermes: 'Hermes', mira: 'Mira', mir: 'Mir CLI', traex: 'TRAE', pi: 'Pi', copilot: 'Copilot', 'oh-my-pi': 'Oh My Pi', kimi: 'Kimi', grok: 'Grok Build', 'kiro-cli': 'Kiro', riff: 'Riff' };
|
|
1164
|
+
const CLI_DISPLAY_NAMES = { 'claude-code': 'Claude', seed: 'Seed', relay: 'Relay', aiden: 'Aiden', coco: 'CoCo', codex: 'Codex', 'codex-app': 'Codex App', cursor: 'Cursor', gemini: 'Gemini', genius: 'Genius', opencode: 'OpenCode', antigravity: 'Antigravity', mtr: 'MTR', hermes: 'Hermes', mira: 'Mira', mir: 'Mir CLI', traex: 'TRAE', pi: 'Pi', copilot: 'Copilot', 'oh-my-pi': 'Oh My Pi', kimi: 'Kimi', grok: 'Grok Build', 'kiro-cli': 'Kiro', riff: 'Riff', reasonix: 'Reasonix' };
|
|
1159
1165
|
function cliName() {
|
|
1160
1166
|
return (lastInitConfig?.cliRuntime?.source === 'configured'
|
|
1161
1167
|
? (lastInitConfig.cliRuntime.displayName?.trim() || lastInitConfig.cliRuntime.id)
|
|
@@ -1166,6 +1172,10 @@ function cliName() {
|
|
|
1166
1172
|
let isPromptReady = false;
|
|
1167
1173
|
/** Mutex for async flushPending — prevents concurrent flush loops. */
|
|
1168
1174
|
let isFlushing = false;
|
|
1175
|
+
/** An init prompt exists but spawn/RPC policy has not yet established whether
|
|
1176
|
+
* it is argv-baked, RPC-owned, or queued. Concurrent follow-ups may enter the
|
|
1177
|
+
* queue during async init, but must not flush ahead of this first turn. */
|
|
1178
|
+
let initialInputOwnershipPending = false;
|
|
1169
1179
|
/** True from the moment an owned CLI restart begins until the replacement
|
|
1170
1180
|
* backend has been synchronously installed. Async backends (notably Riff)
|
|
1171
1181
|
* keep the old backend object alive while destroySession() awaits remote
|
|
@@ -1471,6 +1481,13 @@ async function runStartupCommands() {
|
|
|
1471
1481
|
}
|
|
1472
1482
|
const freshnessInputQueue = new CodexRunnerFreshnessInputQueue(() => codexRunnerFreshness, state => { codexRunnerFreshness = state; });
|
|
1473
1483
|
const pendingMessages = freshnessInputQueue.normal;
|
|
1484
|
+
/** Ordinary Lark IM turns may be retransmitted by the daemon when the exact
|
|
1485
|
+
* receipt ACK times out. Fence those retries before any renderer / adapter side
|
|
1486
|
+
* effects so one Lark message can enter the CLI input queue at most once per
|
|
1487
|
+
* worker generation. Durable receiver attempts already have their own lease
|
|
1488
|
+
* protocol and adopt writes have an ambiguity journal, so this gate stays on
|
|
1489
|
+
* non-adopt `om_` turns without dispatchAttempt. */
|
|
1490
|
+
const ordinaryImTurnDedupe = new InputTurnDeduper(256);
|
|
1474
1491
|
/** Correlation ids that this worker actually wrote into the owned Codex App
|
|
1475
1492
|
* runner. Runner lifecycle/final markers may route only to ids in this bounded
|
|
1476
1493
|
* local set; model/user display bytes cannot add entries. */
|
|
@@ -3515,18 +3532,21 @@ function codexBridgeStartTimer() {
|
|
|
3515
3532
|
cwd: lastInitConfig?.workingDir,
|
|
3516
3533
|
pid: codexAdoptPendingPid,
|
|
3517
3534
|
});
|
|
3518
|
-
// Codex defense-in-depth: resolveFileBridgePath resolves
|
|
3519
|
-
// so a pending sid that is actually a shared-
|
|
3520
|
-
//
|
|
3521
|
-
//
|
|
3522
|
-
//
|
|
3523
|
-
//
|
|
3524
|
-
//
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
})()
|
|
3535
|
+
// Codex/TRAE defense-in-depth: resolveFileBridgePath resolves
|
|
3536
|
+
// sessionId-first, so a pending sid that is actually a shared-home
|
|
3537
|
+
// sibling's (CODEX_HOME / TRAE_HOME) would resolve to that foreign
|
|
3538
|
+
// rollout. Only attach when the resolved rollout's sid is one the
|
|
3539
|
+
// observed pid actually holds open. This poller re-runs every 1s, so a
|
|
3540
|
+
// lazily-opened owned fd is picked up on a later tick. Skip the gate
|
|
3541
|
+
// only when we have no pid to prove ownership with (keeps the sid/pid
|
|
3542
|
+
// resolution working for non-adopt / pid-less flows).
|
|
3543
|
+
const codexAttachGated = structuredBridgeIsCodex() && lastInitConfig?.adoptMode && path && currentCodexObservedPid();
|
|
3544
|
+
const traexAttachGated = structuredBridgeIsTraex() && lastInitConfig?.adoptMode && path && currentTraexObservedPid();
|
|
3545
|
+
const attachOk = codexAttachGated
|
|
3546
|
+
? (() => { const sid = codexSessionIdFromRolloutPath(path); return !!sid && codexHistorySidOwnedByCurrentPid(sid); })()
|
|
3547
|
+
: traexAttachGated
|
|
3548
|
+
? (() => { const sid = codexSessionIdFromRolloutPath(path); return !!sid && traexHistorySidOwnedByCurrentPid(sid); })()
|
|
3549
|
+
: true;
|
|
3530
3550
|
if (path && attachOk) {
|
|
3531
3551
|
if (codexAdoptPendingPid && (lastInitConfig?.cliId === 'codex' || lastInitConfig?.cliId === 'traex')) {
|
|
3532
3552
|
const discoveredSessionId = codexSessionIdFromRolloutPath(path);
|
|
@@ -3804,6 +3824,54 @@ function codexHistorySidOwnedByCurrentPid(cliSessionId) {
|
|
|
3804
3824
|
}
|
|
3805
3825
|
return owned;
|
|
3806
3826
|
}
|
|
3827
|
+
/** Resolve the pid that actually holds a TRAE rollout open, given a candidate
|
|
3828
|
+
* that may be a bwrap supervisor. Under the file sandbox, botmux launches
|
|
3829
|
+
* `bwrap --unshare-pid -- traex`, so the tmux pane leaf / getChildPid() is the
|
|
3830
|
+
* bwrap process — its /proc/<pid>/fd holds no rollout, and the ownership gate
|
|
3831
|
+
* would always fail. The real traex leaf is host-visible across the pid ns
|
|
3832
|
+
* (ps -A ppid links), so a comm-based BFS descends to it. Outside the sandbox
|
|
3833
|
+
* (or if traex hasn't been forked yet) the candidate already is the leaf, so
|
|
3834
|
+
* we return it unchanged — fail closed to the launcher pid rather than guess. */
|
|
3835
|
+
function resolveTraexOwnershipPid(candidatePid, sandbox) {
|
|
3836
|
+
if (!sandbox || !candidatePid)
|
|
3837
|
+
return candidatePid;
|
|
3838
|
+
return findLaunchedCliPid(candidatePid, 'traex') ?? candidatePid;
|
|
3839
|
+
}
|
|
3840
|
+
/** TRAE counterpart of currentCodexObservedPid: the pid of the TRAE process
|
|
3841
|
+
* this worker observes (spawned child or adopted pane). Same resolution order
|
|
3842
|
+
* — the wired backend.cliPid first, then the live pane child pid, then the
|
|
3843
|
+
* adopt-pending pid (which is populated for TRAE too, see the codex/traex
|
|
3844
|
+
* branch around line 3674). backend.cliPid is already sandbox-resolved at wire
|
|
3845
|
+
* time; the getChildPid() fallback is not, so descend it here too (no-op
|
|
3846
|
+
* outside the sandbox / when already a leaf). */
|
|
3847
|
+
function currentTraexObservedPid() {
|
|
3848
|
+
const wired = backend?.cliPid;
|
|
3849
|
+
if (wired)
|
|
3850
|
+
return wired;
|
|
3851
|
+
const child = backend?.getChildPid?.();
|
|
3852
|
+
if (child)
|
|
3853
|
+
return resolveTraexOwnershipPid(child, lastSpawnOuterBwrapActive);
|
|
3854
|
+
return codexAdoptPendingPid;
|
|
3855
|
+
}
|
|
3856
|
+
/** Ownership gate for binding a TRAE session id that came from the GLOBAL
|
|
3857
|
+
* history.jsonl (shared by every TRAE pane under one TRAE_HOME). A concurrent
|
|
3858
|
+
* sibling pane submitting identical text — e.g. a bare "继续" in adopt mode,
|
|
3859
|
+
* which carries no unique <session_id> — can make writeInput's history match
|
|
3860
|
+
* surface a FOREIGN session id. Before persisting it (resume target) or
|
|
3861
|
+
* (re-)attaching the transcript bridge, require the id to be one THIS pid
|
|
3862
|
+
* actually holds open. FAIL CLOSED: unavailable fd enumeration (undefined set)
|
|
3863
|
+
* or a non-member id → false, so the caller keeps its current binding. Mirrors
|
|
3864
|
+
* codexHistorySidOwnedByCurrentPid; the pure decision lives in
|
|
3865
|
+
* traexHistorySidIsOwned for unit testing without a live pid. */
|
|
3866
|
+
function traexHistorySidOwnedByCurrentPid(cliSessionId) {
|
|
3867
|
+
const pid = currentTraexObservedPid();
|
|
3868
|
+
const ownedRollouts = pid ? findTraexRolloutSetByPid(pid) : undefined;
|
|
3869
|
+
const owned = traexHistorySidIsOwned(cliSessionId, ownedRollouts);
|
|
3870
|
+
if (!owned) {
|
|
3871
|
+
log(`TRAE session id ${cliSessionId} not owned by pid ${pid ?? '?'} (open rollouts: ${ownedRollouts ? [...ownedRollouts].join(',') || 'none' : 'unknown'})`);
|
|
3872
|
+
}
|
|
3873
|
+
return owned;
|
|
3874
|
+
}
|
|
3807
3875
|
/** Called from flushPending after writeInput first returns a cliSessionId.
|
|
3808
3876
|
* Tries to locate the rollout file immediately; if it's not on disk yet,
|
|
3809
3877
|
* remembers the sid so the 1s poller can keep retrying. */
|
|
@@ -3863,6 +3931,15 @@ function codexBridgeNotifyCliSessionId(cliSessionId) {
|
|
|
3863
3931
|
const currentSid = codexSessionIdFromRolloutPath(codexBridgeRolloutPath);
|
|
3864
3932
|
if (currentSid && currentSid.toLowerCase() === cliSessionId.toLowerCase())
|
|
3865
3933
|
return;
|
|
3934
|
+
// Ownership gate: the reported id came from the GLOBAL history.jsonl, so a
|
|
3935
|
+
// sibling pane's identical text (e.g. a bare adopt-mode reply with no
|
|
3936
|
+
// unique <session_id>) could surface a foreign id. Only rotate the bridge
|
|
3937
|
+
// to a rollout THIS pid holds open; otherwise keep the current binding
|
|
3938
|
+
// (fail closed on unknown/unowned). Mirrors the codex branch above.
|
|
3939
|
+
if (!traexHistorySidOwnedByCurrentPid(cliSessionId)) {
|
|
3940
|
+
log(`Keeping current TRAE bridge ${currentSid ?? '?'} — refusing history-only re-attach to ${cliSessionId}`);
|
|
3941
|
+
return;
|
|
3942
|
+
}
|
|
3866
3943
|
const next = resolveFileBridgePath('traex', { sessionId: cliSessionId });
|
|
3867
3944
|
// Close any terminal already committed to the retired rollout before
|
|
3868
3945
|
// switching. A durable turn is a worker HOL barrier, so a legitimate
|
|
@@ -3982,6 +4059,19 @@ function codexBridgeNotifyCliSessionId(cliSessionId) {
|
|
|
3982
4059
|
return;
|
|
3983
4060
|
}
|
|
3984
4061
|
}
|
|
4062
|
+
// TRAE INITIAL attach: same shared-history.jsonl hazard as codex above. The
|
|
4063
|
+
// TRAE adapter only returns an owned sid, but keep a defense-in-depth gate so
|
|
4064
|
+
// a foreign sid from any other path can't first-attach the bridge in adopt
|
|
4065
|
+
// mode. Fail closed identically: keep the poller armed on the adopt pid rather
|
|
4066
|
+
// than pinning an unverified sid (which would wedge the bridge).
|
|
4067
|
+
if (structuredBridgeIsTraex() && lastInitConfig?.adoptMode && currentTraexObservedPid()) {
|
|
4068
|
+
if (!traexHistorySidOwnedByCurrentPid(cliSessionId)) {
|
|
4069
|
+
log(`TRAE initial-attach refused for unverified session ${cliSessionId}; keeping poller armed on pid ${currentTraexObservedPid()}`);
|
|
4070
|
+
codexBridgePendingSessionId = undefined;
|
|
4071
|
+
codexBridgeStartTimer();
|
|
4072
|
+
return;
|
|
4073
|
+
}
|
|
4074
|
+
}
|
|
3985
4075
|
const path = resolveFileBridgePath(lastInitConfig?.cliId, {
|
|
3986
4076
|
sessionId: cliSessionId,
|
|
3987
4077
|
cwd: lastInitConfig?.workingDir,
|
|
@@ -6441,6 +6531,8 @@ async function flushPending() {
|
|
|
6441
6531
|
// backend's idle/task-done callback) write across that restart boundary.
|
|
6442
6532
|
if (cliRestartInProgress)
|
|
6443
6533
|
return;
|
|
6534
|
+
if (initialInputOwnershipPending)
|
|
6535
|
+
return;
|
|
6444
6536
|
if (shouldHoldCodexRunnerInput(codexRunnerFreshness))
|
|
6445
6537
|
return;
|
|
6446
6538
|
if (isFlushing)
|
|
@@ -6845,8 +6937,6 @@ async function flushPending() {
|
|
|
6845
6937
|
}
|
|
6846
6938
|
}
|
|
6847
6939
|
function sendToPty(content, turnId, opts = {}) {
|
|
6848
|
-
if (!cliAdapter)
|
|
6849
|
-
return false;
|
|
6850
6940
|
const next = {
|
|
6851
6941
|
content,
|
|
6852
6942
|
turnId,
|
|
@@ -6865,6 +6955,8 @@ function sendToPty(content, turnId, opts = {}) {
|
|
|
6865
6955
|
log(`Queued message while CLI backend is restarting (${pendingMessages.length} pending)`);
|
|
6866
6956
|
return true;
|
|
6867
6957
|
}
|
|
6958
|
+
if (!cliAdapter)
|
|
6959
|
+
return false;
|
|
6868
6960
|
const supportsTypeAhead = pendingInputAllowsTypeAhead(cliAdapter.supportsTypeAhead === true, durableTurnInFlight, next);
|
|
6869
6961
|
const shouldMergeQueued = opts.dispatchAttempt === undefined && !durableTurnInFlight
|
|
6870
6962
|
&& !isFlushing && !shouldWriteNow({
|
|
@@ -7194,8 +7286,18 @@ function setupAdoptInputAdapter(cfg) {
|
|
|
7194
7286
|
cliAdapter = createCliAdapterSync(cfg.cliId, cfg.cliPathOverride);
|
|
7195
7287
|
}
|
|
7196
7288
|
}
|
|
7289
|
+
function wireIdleDetectorBusyTransition(detector, label) {
|
|
7290
|
+
detector.onBusy(() => {
|
|
7291
|
+
if (!isPromptReady)
|
|
7292
|
+
return;
|
|
7293
|
+
isPromptReady = false;
|
|
7294
|
+
log(`Explicit busy marker detected — ${label}`);
|
|
7295
|
+
publishScreenStatus('working', { force: true });
|
|
7296
|
+
});
|
|
7297
|
+
}
|
|
7197
7298
|
function setupAdoptIdleDetection(cfg, label) {
|
|
7198
7299
|
idleDetector = new IdleDetector(adoptIdleAdapter(cfg));
|
|
7300
|
+
wireIdleDetectorBusyTransition(idleDetector, `${label} adopt mode`);
|
|
7199
7301
|
idleDetector.onIdle(() => {
|
|
7200
7302
|
if (backend && deferPromptReadyWhileBusy(`${label} adopt-idle`, backend))
|
|
7201
7303
|
return;
|
|
@@ -9360,17 +9462,63 @@ async function spawnCli(cfg, opts = {}) {
|
|
|
9360
9462
|
startWrapperRealPidResolve(cliPid);
|
|
9361
9463
|
if (cliPid)
|
|
9362
9464
|
observeCursorCliSessionId(cliPid);
|
|
9465
|
+
// File sandbox / Linux credential-only bwrap launches `bwrap --unshare-pid --
|
|
9466
|
+
// traex`, so the pane leaf (getChildPid) is the bwrap SUPERVISOR — its
|
|
9467
|
+
// /proc/<pid>/fd holds no rollout and the TRAE ownership gate can never admit
|
|
9468
|
+
// a session id (fresh sandbox TRAE then never captures its SID, the bridge
|
|
9469
|
+
// never attaches, and because reliableTurnTerminal disables screen-idle the
|
|
9470
|
+
// durable turn can wedge — it does NOT self-heal). The real traex leaf is
|
|
9471
|
+
// host-visible across the pid ns (ps -A ppid links), so BFS-descend to it and
|
|
9472
|
+
// rewire backend.cliPid. Bounded retry (not one-shot): bwrap may not have
|
|
9473
|
+
// forked traex yet at spawn. Reuses scheduleWrapperRealCliPid's stale-backend
|
|
9474
|
+
// guard so a mid-retry worker restart can't rewire the new session. Gated on
|
|
9475
|
+
// outerBwrapActive — sandboxRequested OR the Linux credential-only bwrap path,
|
|
9476
|
+
// both of which produce an outer supervisor pid. */
|
|
9477
|
+
const outerBwrapActive = sandboxRequested || credentialOnlyBwrap;
|
|
9478
|
+
lastSpawnOuterBwrapActive = outerBwrapActive;
|
|
9479
|
+
const startTraexSandboxPidResolve = (launcherPid) => {
|
|
9480
|
+
if (cfg.cliId !== 'traex' || !outerBwrapActive)
|
|
9481
|
+
return;
|
|
9482
|
+
scheduleWrapperRealCliPid(launcherPid, {
|
|
9483
|
+
findRealPid: (lp) => findLaunchedCliPid(lp, 'traex'),
|
|
9484
|
+
getBackend: () => backend,
|
|
9485
|
+
getChildPid: () => backend?.getChildPid?.(),
|
|
9486
|
+
applyRealPid: (realPid) => {
|
|
9487
|
+
log(`TRAE sandbox: resolved real traex leaf pid ${realPid} under bwrap supervisor ${launcherPid}; rewiring ownership pid`);
|
|
9488
|
+
backend.cliPid = realPid;
|
|
9489
|
+
backend.cliCwd = cfg.workingDir;
|
|
9490
|
+
publishLocalProcessAttestation(realPid);
|
|
9491
|
+
},
|
|
9492
|
+
schedule: (fn, ms) => { setTimeout(fn, ms); },
|
|
9493
|
+
});
|
|
9494
|
+
};
|
|
9363
9495
|
// Wire pid + cwd so adapters' writeInput can bind submits to this process:
|
|
9364
9496
|
// - claude-code: ~/.claude/sessions/<pid>.json
|
|
9365
9497
|
// - grok: findGrokSessionByPid → preferSessionId against shared
|
|
9366
9498
|
// prompt_history (concurrent same-cwd workers must not cross-claim)
|
|
9499
|
+
// - traex: findTraexRolloutSetByPid → ownership gate for the shared global
|
|
9500
|
+
// history.jsonl (concurrent same-TRAE_HOME panes must not cross-claim a
|
|
9501
|
+
// sibling's session id from an identical-text submit). getChildPid() is
|
|
9502
|
+
// normally the traex process itself, EXCEPT under the file sandbox: bwrap
|
|
9503
|
+
// runs `--unshare-pid -- traex`, so the pane leaf is the bwrap supervisor
|
|
9504
|
+
// and /proc/<bwrap>/fd holds no rollout. resolveTraexOwnershipPid() BFS-
|
|
9505
|
+
// descends to the real traex leaf (host-visible across the pid ns via
|
|
9506
|
+
// `ps -A` ppid links) so the ownership gate can actually admit the id;
|
|
9507
|
+
// it fails closed to the launcher pid when no leaf is found yet (the async
|
|
9508
|
+
// retry below re-resolves once bwrap has forked traex).
|
|
9509
|
+
// - reasonix: identify the lease owned by this process tree
|
|
9367
9510
|
// Claude's sessionId is set ONCE at process start (2.1.123); a `--resume`
|
|
9368
9511
|
// lookup will surface here, but in-pane `/clear` won't. The pinned
|
|
9369
9512
|
// claudeJsonlPath above is still the initial guess; the resolver corrects
|
|
9370
9513
|
// it on first write when Claude was started with `--resume`.
|
|
9371
|
-
if (cliPid && (claudeDataDir || cfg.cliId === 'grok')) {
|
|
9372
|
-
|
|
9514
|
+
if (cliPid && (claudeDataDir || cfg.cliId === 'grok' || cfg.cliId === 'traex' || cfg.cliId === 'reasonix')) {
|
|
9515
|
+
// TRAE under outer bwrap: best-effort immediate resolve (leaf may already be
|
|
9516
|
+
// forked), then a bounded retry below covers the not-yet-forked case.
|
|
9517
|
+
const wiredPid = cfg.cliId === 'traex' ? resolveTraexOwnershipPid(cliPid, outerBwrapActive) : cliPid;
|
|
9518
|
+
backend.cliPid = wiredPid;
|
|
9373
9519
|
backend.cliCwd = cfg.workingDir;
|
|
9520
|
+
if (cfg.cliId === 'traex' && outerBwrapActive)
|
|
9521
|
+
startTraexSandboxPidResolve(cliPid);
|
|
9374
9522
|
}
|
|
9375
9523
|
// Async pid fallback: tmux/pty resolve the CLI pid synchronously above, but
|
|
9376
9524
|
// zellij's CLI subprocess starts AFTER spawn() returns (the zellij server
|
|
@@ -9399,9 +9547,12 @@ async function spawnCli(cfg, opts = {}) {
|
|
|
9399
9547
|
log(`Failed to write CLI PID marker (async): ${err.message}`);
|
|
9400
9548
|
}
|
|
9401
9549
|
}
|
|
9402
|
-
if (claudeDataDir || cfg.cliId === 'grok') {
|
|
9403
|
-
|
|
9550
|
+
if (claudeDataDir || cfg.cliId === 'grok' || cfg.cliId === 'traex' || cfg.cliId === 'reasonix') {
|
|
9551
|
+
const wiredPid = cfg.cliId === 'traex' ? resolveTraexOwnershipPid(pid, outerBwrapActive) : pid;
|
|
9552
|
+
backend.cliPid = wiredPid;
|
|
9404
9553
|
backend.cliCwd = cfg.workingDir;
|
|
9554
|
+
if (cfg.cliId === 'traex' && outerBwrapActive)
|
|
9555
|
+
startTraexSandboxPidResolve(pid);
|
|
9405
9556
|
}
|
|
9406
9557
|
// wrapperCli under a late-pid backend (zellij): `pid` here is still the
|
|
9407
9558
|
// LAUNCHER. Kick the descendant resolver so the bridge gets the real CLI
|
|
@@ -9628,6 +9779,7 @@ async function spawnCli(cfg, opts = {}) {
|
|
|
9628
9779
|
// quiescence, repeatedly triggering markPromptReady() and duplicate cards.
|
|
9629
9780
|
if (effectiveBackendType !== 'riff') {
|
|
9630
9781
|
idleDetector = new IdleDetector(cliAdapter);
|
|
9782
|
+
wireIdleDetectorBusyTransition(idleDetector, `${cliName()} PTY`);
|
|
9631
9783
|
idleDetector.onIdle(async (evidenceSource) => {
|
|
9632
9784
|
log('Prompt detected (idle)');
|
|
9633
9785
|
// Snapshot-only backends (ZMX) must complete one authoritative refresh
|
|
@@ -11401,8 +11553,23 @@ function send(msg) {
|
|
|
11401
11553
|
process.send?.(payload);
|
|
11402
11554
|
}
|
|
11403
11555
|
function acknowledgeTurnInputCommitted(turnId) {
|
|
11556
|
+
if (!turnId)
|
|
11557
|
+
return;
|
|
11558
|
+
ordinaryImTurnDedupe.commit(turnId);
|
|
11559
|
+
send({ type: 'turn_input_committed', turnId });
|
|
11560
|
+
}
|
|
11561
|
+
function acknowledgeTurnInputReceived(turnId) {
|
|
11404
11562
|
if (turnId)
|
|
11405
|
-
send({ type: '
|
|
11563
|
+
send({ type: 'turn_input_received', turnId });
|
|
11564
|
+
}
|
|
11565
|
+
function receiveOrdinaryImTurn(turnId) {
|
|
11566
|
+
const state = ordinaryImTurnDedupe.begin(turnId);
|
|
11567
|
+
acknowledgeTurnInputReceived(turnId);
|
|
11568
|
+
return state;
|
|
11569
|
+
}
|
|
11570
|
+
function rejectOrdinaryImTurn(turnId, reason) {
|
|
11571
|
+
ordinaryImTurnDedupe.release(turnId);
|
|
11572
|
+
send({ type: 'turn_input_rejected', turnId, reason });
|
|
11406
11573
|
}
|
|
11407
11574
|
function publishLocalProcessAttestation(cliPid) {
|
|
11408
11575
|
const cliProcStart = cliPid ? readProcessStartIdentity(cliPid) : undefined;
|
|
@@ -11492,9 +11659,44 @@ process.on('message', async (raw) => {
|
|
|
11492
11659
|
switch (msg.type) {
|
|
11493
11660
|
case 'init': {
|
|
11494
11661
|
const initStartedAtMs = Date.now();
|
|
11495
|
-
|
|
11496
|
-
|
|
11662
|
+
const ordinaryImTurnId = !msg.adoptMode
|
|
11663
|
+
&& msg.dispatchAttempt === undefined
|
|
11664
|
+
&& !!msg.prompt
|
|
11665
|
+
&& msg.turnId?.startsWith('om_')
|
|
11666
|
+
? msg.turnId
|
|
11667
|
+
: undefined;
|
|
11668
|
+
if (lastInitConfig) {
|
|
11669
|
+
// Only an exact retry of this generation's init may be acknowledged.
|
|
11670
|
+
// A different init is still rejected as an invalid re-initialization.
|
|
11671
|
+
if (ordinaryImTurnId && lastInitConfig.turnId === ordinaryImTurnId) {
|
|
11672
|
+
const duplicateState = receiveOrdinaryImTurn(ordinaryImTurnId);
|
|
11673
|
+
if (duplicateState === 'committed') {
|
|
11674
|
+
log(`Re-ACKing committed duplicate init turn ${ordinaryImTurnId.substring(0, 16)}`);
|
|
11675
|
+
acknowledgeTurnInputCommitted(ordinaryImTurnId);
|
|
11676
|
+
}
|
|
11677
|
+
else {
|
|
11678
|
+
log(`Re-ACKing received duplicate init turn ${ordinaryImTurnId.substring(0, 16)}`);
|
|
11679
|
+
}
|
|
11680
|
+
}
|
|
11681
|
+
return;
|
|
11682
|
+
}
|
|
11683
|
+
if (ordinaryImTurnId) {
|
|
11684
|
+
const duplicateState = receiveOrdinaryImTurn(ordinaryImTurnId);
|
|
11685
|
+
// Receipt is the daemon ↔ worker transport boundary. Publish it before
|
|
11686
|
+
// startup work can await a slow backend, plugin gateway, or Codex
|
|
11687
|
+
// metadata read. The later committed ACK keeps its existing meaning.
|
|
11688
|
+
if (duplicateState === 'committed') {
|
|
11689
|
+
log(`Re-ACKing committed duplicate init turn ${ordinaryImTurnId.substring(0, 16)}`);
|
|
11690
|
+
acknowledgeTurnInputCommitted(ordinaryImTurnId);
|
|
11691
|
+
break;
|
|
11692
|
+
}
|
|
11693
|
+
if (duplicateState === 'inflight') {
|
|
11694
|
+
log(`Re-ACKing received duplicate init turn ${ordinaryImTurnId.substring(0, 16)}`);
|
|
11695
|
+
break;
|
|
11696
|
+
}
|
|
11697
|
+
}
|
|
11497
11698
|
lastInitConfig = msg;
|
|
11699
|
+
initialInputOwnershipPending = !!msg.prompt;
|
|
11498
11700
|
activeRestartAttemptId = msg.restartAttemptId;
|
|
11499
11701
|
sessionId = msg.sessionId;
|
|
11500
11702
|
refreshTerminalViewToken();
|
|
@@ -11649,7 +11851,10 @@ process.on('message', async (raw) => {
|
|
|
11649
11851
|
passesInitialPromptViaArgs: cliAdapter?.passesInitialPromptViaArgs === true,
|
|
11650
11852
|
deferInitialPrompt,
|
|
11651
11853
|
})) {
|
|
11652
|
-
|
|
11854
|
+
// Follow-up IPC handlers can run while this async init is awaiting
|
|
11855
|
+
// backend startup. They queue safely behind !backend above, but the
|
|
11856
|
+
// original init prompt must remain first in logical turn order.
|
|
11857
|
+
pendingMessages.unshift({
|
|
11653
11858
|
content: lastSpawnQueuedInitialPrompt ?? msg.prompt,
|
|
11654
11859
|
...(lastSpawnQueuedInitialPromptLogicalContent
|
|
11655
11860
|
? { logicalContent: lastSpawnQueuedInitialPromptLogicalContent }
|
|
@@ -11666,6 +11871,10 @@ process.on('message', async (raw) => {
|
|
|
11666
11871
|
// it into argv or the RPC engine already accepted it.
|
|
11667
11872
|
initialInputCommitted = true;
|
|
11668
11873
|
}
|
|
11874
|
+
// The first turn is now either at queue head or already owned by the
|
|
11875
|
+
// argv/RPC startup path. Only now may an early idle edge drain
|
|
11876
|
+
// follow-ups that arrived while init was awaiting slow startup work.
|
|
11877
|
+
initialInputOwnershipPending = false;
|
|
11669
11878
|
if (initialInputCommitted)
|
|
11670
11879
|
acknowledgeTurnInputCommitted(msg.turnId);
|
|
11671
11880
|
// A backend may become prompt-ready before spawnCli() returns. The
|
|
@@ -11692,6 +11901,7 @@ process.on('message', async (raw) => {
|
|
|
11692
11901
|
});
|
|
11693
11902
|
}
|
|
11694
11903
|
catch (err) {
|
|
11904
|
+
initialInputOwnershipPending = false;
|
|
11695
11905
|
await sendFatalWorkerErrorAndExit(err);
|
|
11696
11906
|
return;
|
|
11697
11907
|
}
|
|
@@ -11699,6 +11909,25 @@ process.on('message', async (raw) => {
|
|
|
11699
11909
|
}
|
|
11700
11910
|
case 'message': {
|
|
11701
11911
|
const messageAdoptMode = lastInitConfig?.adoptMode === true;
|
|
11912
|
+
const ordinaryImTurnId = !messageAdoptMode
|
|
11913
|
+
&& msg.dispatchAttempt === undefined
|
|
11914
|
+
&& msg.turnId?.startsWith('om_')
|
|
11915
|
+
? msg.turnId
|
|
11916
|
+
: undefined;
|
|
11917
|
+
if (ordinaryImTurnId) {
|
|
11918
|
+
const duplicateState = receiveOrdinaryImTurn(ordinaryImTurnId);
|
|
11919
|
+
// ACK process ownership synchronously, before crash recovery or any
|
|
11920
|
+
// other awaited work. Actual queue ownership remains committed below.
|
|
11921
|
+
if (duplicateState === 'committed') {
|
|
11922
|
+
log(`Re-ACKing committed duplicate IM turn ${ordinaryImTurnId.substring(0, 16)}`);
|
|
11923
|
+
acknowledgeTurnInputCommitted(ordinaryImTurnId);
|
|
11924
|
+
break;
|
|
11925
|
+
}
|
|
11926
|
+
if (duplicateState === 'inflight') {
|
|
11927
|
+
log(`Re-ACKing received duplicate IM turn ${ordinaryImTurnId.substring(0, 16)}`);
|
|
11928
|
+
break;
|
|
11929
|
+
}
|
|
11930
|
+
}
|
|
11702
11931
|
// Adopt IPC handlers can overlap. Delay their turn baseline until the
|
|
11703
11932
|
// submission mutex is held so a queued message cannot steal attribution
|
|
11704
11933
|
// from the write/verification already in flight.
|
|
@@ -11746,6 +11975,8 @@ process.on('message', async (raw) => {
|
|
|
11746
11975
|
await prepareCodexNativeTitleGeneration(restartCfg, codexRpcEngine);
|
|
11747
11976
|
}
|
|
11748
11977
|
catch (err) {
|
|
11978
|
+
if (ordinaryImTurnId)
|
|
11979
|
+
ordinaryImTurnDedupe.release(ordinaryImTurnId);
|
|
11749
11980
|
// Pass the message's own attempt (not the stale currentBotmux* from a
|
|
11750
11981
|
// prior IM turn) so a durable delivery relaunch failure carries the
|
|
11751
11982
|
// right attribution for the daemon's receipt/lease gate.
|
|
@@ -11936,6 +12167,8 @@ process.on('message', async (raw) => {
|
|
|
11936
12167
|
});
|
|
11937
12168
|
if (inputCommitted)
|
|
11938
12169
|
acknowledgeTurnInputCommitted(msg.turnId);
|
|
12170
|
+
else if (ordinaryImTurnId)
|
|
12171
|
+
rejectOrdinaryImTurn(ordinaryImTurnId, 'cli_input_unavailable');
|
|
11939
12172
|
}
|
|
11940
12173
|
break;
|
|
11941
12174
|
}
|
|
@@ -12383,6 +12616,13 @@ process.on('message', async (raw) => {
|
|
|
12383
12616
|
killCli({ preserveSandbox: true });
|
|
12384
12617
|
cleanup();
|
|
12385
12618
|
await flushTransferDetachAck(msg.requestId);
|
|
12619
|
+
// NOTE: process.exit(0) can wedge in node-pty's native teardown when a
|
|
12620
|
+
// web-terminal client PTY was attached (the reader-thread join blocks and
|
|
12621
|
+
// the JS event loop is already stopped, so this process cannot self-kill
|
|
12622
|
+
// via a timer). killCli() above already detached the observer and the ACK
|
|
12623
|
+
// just flushed, so the daemon force-kills this now-disposable process
|
|
12624
|
+
// shortly after the ACK (see detachWorkerForTransfer's post-ACK kill).
|
|
12625
|
+
// We still request a clean exit; the daemon SIGKILL is the hard backstop.
|
|
12386
12626
|
process.exit(0);
|
|
12387
12627
|
}
|
|
12388
12628
|
case 'suspend': {
|