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.
Files changed (374) hide show
  1. package/README.en.md +1 -1
  2. package/README.md +1 -1
  3. package/dist/.runtime-build-id +1 -1
  4. package/dist/adapters/cli/codex.d.ts.map +1 -1
  5. package/dist/adapters/cli/codex.js +6 -0
  6. package/dist/adapters/cli/codex.js.map +1 -1
  7. package/dist/adapters/cli/opencode.d.ts.map +1 -1
  8. package/dist/adapters/cli/opencode.js +7 -1
  9. package/dist/adapters/cli/opencode.js.map +1 -1
  10. package/dist/adapters/cli/reasonix.d.ts +35 -0
  11. package/dist/adapters/cli/reasonix.d.ts.map +1 -0
  12. package/dist/adapters/cli/reasonix.js +236 -0
  13. package/dist/adapters/cli/reasonix.js.map +1 -0
  14. package/dist/adapters/cli/registry.d.ts +2 -1
  15. package/dist/adapters/cli/registry.d.ts.map +1 -1
  16. package/dist/adapters/cli/registry.js +4 -1
  17. package/dist/adapters/cli/registry.js.map +1 -1
  18. package/dist/adapters/cli/traex.d.ts.map +1 -1
  19. package/dist/adapters/cli/traex.js +87 -87
  20. package/dist/adapters/cli/traex.js.map +1 -1
  21. package/dist/adapters/cli/types.d.ts +5 -1
  22. package/dist/adapters/cli/types.d.ts.map +1 -1
  23. package/dist/cli.d.ts.map +1 -1
  24. package/dist/cli.js +253 -69
  25. package/dist/cli.js.map +1 -1
  26. package/dist/core/command-handler.d.ts +18 -4
  27. package/dist/core/command-handler.d.ts.map +1 -1
  28. package/dist/core/command-handler.js +274 -27
  29. package/dist/core/command-handler.js.map +1 -1
  30. package/dist/core/dashboard-ipc-server.d.ts +1 -0
  31. package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
  32. package/dist/core/dashboard-ipc-server.js +27 -3
  33. package/dist/core/dashboard-ipc-server.js.map +1 -1
  34. package/dist/core/dispatch.d.ts +54 -24
  35. package/dist/core/dispatch.d.ts.map +1 -1
  36. package/dist/core/dispatch.js +81 -27
  37. package/dist/core/dispatch.js.map +1 -1
  38. package/dist/core/input-turn-dedupe.d.ts +20 -0
  39. package/dist/core/input-turn-dedupe.d.ts.map +1 -0
  40. package/dist/core/input-turn-dedupe.js +57 -0
  41. package/dist/core/input-turn-dedupe.js.map +1 -0
  42. package/dist/core/local-terminal-opener.d.ts.map +1 -1
  43. package/dist/core/local-terminal-opener.js +10 -1
  44. package/dist/core/local-terminal-opener.js.map +1 -1
  45. package/dist/core/passthrough-commands.d.ts.map +1 -1
  46. package/dist/core/passthrough-commands.js +1 -1
  47. package/dist/core/passthrough-commands.js.map +1 -1
  48. package/dist/core/plugins/pm2.d.ts.map +1 -1
  49. package/dist/core/plugins/pm2.js +7 -1
  50. package/dist/core/plugins/pm2.js.map +1 -1
  51. package/dist/core/resource-monitor/attribution.d.ts.map +1 -1
  52. package/dist/core/resource-monitor/attribution.js +17 -1
  53. package/dist/core/resource-monitor/attribution.js.map +1 -1
  54. package/dist/core/resource-monitor/darwin.d.ts +145 -0
  55. package/dist/core/resource-monitor/darwin.d.ts.map +1 -0
  56. package/dist/core/resource-monitor/darwin.js +360 -0
  57. package/dist/core/resource-monitor/darwin.js.map +1 -0
  58. package/dist/core/resource-monitor/procfs.d.ts.map +1 -1
  59. package/dist/core/resource-monitor/procfs.js +6 -0
  60. package/dist/core/resource-monitor/procfs.js.map +1 -1
  61. package/dist/core/resource-monitor/types.d.ts +1 -1
  62. package/dist/core/resource-monitor/types.d.ts.map +1 -1
  63. package/dist/core/scheduler.d.ts.map +1 -1
  64. package/dist/core/scheduler.js +5 -2
  65. package/dist/core/scheduler.js.map +1 -1
  66. package/dist/core/session-discovery.d.ts.map +1 -1
  67. package/dist/core/session-discovery.js +3 -0
  68. package/dist/core/session-discovery.js.map +1 -1
  69. package/dist/core/session-manager.d.ts +3 -1
  70. package/dist/core/session-manager.d.ts.map +1 -1
  71. package/dist/core/session-manager.js +46 -0
  72. package/dist/core/session-manager.js.map +1 -1
  73. package/dist/core/session-marker.d.ts +1 -8
  74. package/dist/core/session-marker.d.ts.map +1 -1
  75. package/dist/core/session-marker.js +2 -50
  76. package/dist/core/session-marker.js.map +1 -1
  77. package/dist/core/types.d.ts +3 -1
  78. package/dist/core/types.d.ts.map +1 -1
  79. package/dist/core/types.js.map +1 -1
  80. package/dist/core/worker-pool.d.ts +17 -0
  81. package/dist/core/worker-pool.d.ts.map +1 -1
  82. package/dist/core/worker-pool.js +292 -9
  83. package/dist/core/worker-pool.js.map +1 -1
  84. package/dist/daemon.d.ts +11 -1
  85. package/dist/daemon.d.ts.map +1 -1
  86. package/dist/daemon.js +59 -15
  87. package/dist/daemon.js.map +1 -1
  88. package/dist/dashboard/daemon-internal-api.d.ts.map +1 -1
  89. package/dist/dashboard/daemon-internal-api.js +11 -2
  90. package/dist/dashboard/daemon-internal-api.js.map +1 -1
  91. package/dist/dashboard/groups-action-helpers.d.ts +2 -0
  92. package/dist/dashboard/groups-action-helpers.d.ts.map +1 -1
  93. package/dist/dashboard/groups-action-helpers.js +9 -0
  94. package/dist/dashboard/groups-action-helpers.js.map +1 -1
  95. package/dist/dashboard/groups-matrix-snapshot.d.ts +56 -0
  96. package/dist/dashboard/groups-matrix-snapshot.d.ts.map +1 -0
  97. package/dist/dashboard/groups-matrix-snapshot.js +127 -0
  98. package/dist/dashboard/groups-matrix-snapshot.js.map +1 -0
  99. package/dist/dashboard/resource-monitor-service.d.ts.map +1 -1
  100. package/dist/dashboard/resource-monitor-service.js +18 -2
  101. package/dist/dashboard/resource-monitor-service.js.map +1 -1
  102. package/dist/dashboard/web/app.d.ts.map +1 -1
  103. package/dist/dashboard/web/app.js +45 -4
  104. package/dist/dashboard/web/app.js.map +1 -1
  105. package/dist/dashboard/web/groups-api.js +1 -1
  106. package/dist/dashboard/web/groups-api.js.map +1 -1
  107. package/dist/dashboard/web/i18n.js +10 -10
  108. package/dist/dashboard/web/i18n.js.map +1 -1
  109. package/dist/dashboard/web/roles-page.d.ts.map +1 -1
  110. package/dist/dashboard/web/roles-page.js +26 -11
  111. package/dist/dashboard/web/roles-page.js.map +1 -1
  112. package/dist/dashboard-web/app.js +1 -1
  113. package/dist/dashboard-web/chunks/{bot-defaults-page-BHTQEWCH.js → bot-defaults-page-LTVOUDIS.js} +1 -1
  114. package/dist/dashboard-web/chunks/{chunk-KLZCQAHF.js → chunk-3UE7S77S.js} +1 -1
  115. package/dist/dashboard-web/chunks/{chunk-W77TPKZH.js → chunk-DCS35UMD.js} +1 -1
  116. package/dist/dashboard-web/chunks/{chunk-E3HZZXK5.js → chunk-MFQPCVHY.js} +4 -4
  117. package/dist/dashboard-web/chunks/{chunk-EZH56JCI.js → chunk-ZU3UUKAR.js} +1 -1
  118. package/dist/dashboard-web/chunks/{connectors-page-BP255CAX.js → connectors-page-5KWDIMKC.js} +1 -1
  119. package/dist/dashboard-web/chunks/{groups-page-CDHVXBUT.js → groups-page-FHOKYXMW.js} +1 -1
  120. package/dist/dashboard-web/chunks/{insights-page-57BFE6GT.js → insights-page-T2ZX2RWL.js} +1 -1
  121. package/dist/dashboard-web/chunks/{monitor-room-UTOYGQVF.js → monitor-room-YNVBAGR6.js} +1 -1
  122. package/dist/dashboard-web/chunks/{monitoring-page-WTHYAIUM.js → monitoring-page-LHM55YWN.js} +1 -1
  123. package/dist/dashboard-web/chunks/{office-page-JSMIB353.js → office-page-ATXVP7PW.js} +1 -1
  124. package/dist/dashboard-web/chunks/{overview-page-3VDBOH7L.js → overview-page-QYI3KBDD.js} +1 -1
  125. package/dist/dashboard-web/chunks/roles-page-56VWM6CD.js +1 -0
  126. package/dist/dashboard-web/chunks/{schedules-page-HHN736H6.js → schedules-page-S5K6U4EO.js} +1 -1
  127. package/dist/dashboard-web/chunks/{sessions-page-EIWOZD7A.js → sessions-page-WBP4N7D2.js} +1 -1
  128. package/dist/dashboard-web/chunks/{settings-page-2IUT5LS4.js → settings-page-QUZDQARR.js} +1 -1
  129. package/dist/dashboard-web/chunks/{skills-page-JKFKMUEM.js → skills-page-IFY7AEND.js} +1 -1
  130. package/dist/dashboard-web/chunks/{team-federation-page-Q2PXC3UY.js → team-federation-page-C7FJQPFZ.js} +1 -1
  131. package/dist/dashboard-web/chunks/{v3-page-EBQCD4AO.js → v3-page-2LMF3WWR.js} +1 -1
  132. package/dist/dashboard-web/chunks/{whiteboards-page-QZRMVNZN.js → whiteboards-page-3XC6QRMY.js} +1 -1
  133. package/dist/dashboard-web/style.css +2 -4
  134. package/dist/dashboard.js +65 -9
  135. package/dist/dashboard.js.map +1 -1
  136. package/dist/i18n/en.d.ts.map +1 -1
  137. package/dist/i18n/en.js +34 -7
  138. package/dist/i18n/en.js.map +1 -1
  139. package/dist/i18n/zh.d.ts.map +1 -1
  140. package/dist/i18n/zh.js +32 -7
  141. package/dist/i18n/zh.js.map +1 -1
  142. package/dist/im/lark/card-builder.d.ts +7 -0
  143. package/dist/im/lark/card-builder.d.ts.map +1 -1
  144. package/dist/im/lark/card-builder.js +56 -0
  145. package/dist/im/lark/card-builder.js.map +1 -1
  146. package/dist/im/lark/card-handler.d.ts.map +1 -1
  147. package/dist/im/lark/card-handler.js +51 -19
  148. package/dist/im/lark/card-handler.js.map +1 -1
  149. package/dist/im/lark/client.d.ts +10 -0
  150. package/dist/im/lark/client.d.ts.map +1 -1
  151. package/dist/im/lark/client.js +79 -0
  152. package/dist/im/lark/client.js.map +1 -1
  153. package/dist/im/lark/event-dispatcher.d.ts +14 -1
  154. package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
  155. package/dist/im/lark/event-dispatcher.js +171 -15
  156. package/dist/im/lark/event-dispatcher.js.map +1 -1
  157. package/dist/im/lark/issue-card.d.ts +223 -0
  158. package/dist/im/lark/issue-card.d.ts.map +1 -0
  159. package/dist/im/lark/issue-card.js +542 -0
  160. package/dist/im/lark/issue-card.js.map +1 -0
  161. package/dist/im/lark/issue-command-deps.d.ts +41 -0
  162. package/dist/im/lark/issue-command-deps.d.ts.map +1 -0
  163. package/dist/im/lark/issue-command-deps.js +195 -0
  164. package/dist/im/lark/issue-command-deps.js.map +1 -0
  165. package/dist/im/lark/issue-command.d.ts +137 -0
  166. package/dist/im/lark/issue-command.d.ts.map +1 -0
  167. package/dist/im/lark/issue-command.js +335 -0
  168. package/dist/im/lark/issue-command.js.map +1 -0
  169. package/dist/im/lark/lark-hosts.d.ts +5 -0
  170. package/dist/im/lark/lark-hosts.d.ts.map +1 -1
  171. package/dist/im/lark/lark-hosts.js +10 -0
  172. package/dist/im/lark/lark-hosts.js.map +1 -1
  173. package/dist/im/lark/message-parser.d.ts.map +1 -1
  174. package/dist/im/lark/message-parser.js +24 -7
  175. package/dist/im/lark/message-parser.js.map +1 -1
  176. package/dist/platform/issue-client.d.ts +201 -0
  177. package/dist/platform/issue-client.d.ts.map +1 -0
  178. package/dist/platform/issue-client.js +142 -0
  179. package/dist/platform/issue-client.js.map +1 -0
  180. package/dist/platform/platform-http.d.ts +4 -0
  181. package/dist/platform/platform-http.d.ts.map +1 -1
  182. package/dist/platform/platform-http.js +38 -2
  183. package/dist/platform/platform-http.js.map +1 -1
  184. package/dist/pm2-graceful-exit.d.ts +28 -0
  185. package/dist/pm2-graceful-exit.d.ts.map +1 -0
  186. package/dist/pm2-graceful-exit.js +39 -0
  187. package/dist/pm2-graceful-exit.js.map +1 -0
  188. package/dist/services/bridge-fallback-gate.d.ts +9 -2
  189. package/dist/services/bridge-fallback-gate.d.ts.map +1 -1
  190. package/dist/services/bridge-fallback-gate.js +31 -19
  191. package/dist/services/bridge-fallback-gate.js.map +1 -1
  192. package/dist/services/issue-board-store.d.ts +214 -0
  193. package/dist/services/issue-board-store.d.ts.map +1 -0
  194. package/dist/services/issue-board-store.js +472 -0
  195. package/dist/services/issue-board-store.js.map +1 -0
  196. package/dist/services/issue-claim-flow.d.ts +160 -0
  197. package/dist/services/issue-claim-flow.d.ts.map +1 -0
  198. package/dist/services/issue-claim-flow.js +222 -0
  199. package/dist/services/issue-claim-flow.js.map +1 -0
  200. package/dist/services/issue-outbox-pump.d.ts +25 -0
  201. package/dist/services/issue-outbox-pump.d.ts.map +1 -0
  202. package/dist/services/issue-outbox-pump.js +102 -0
  203. package/dist/services/issue-outbox-pump.js.map +1 -0
  204. package/dist/services/issue-release.d.ts +78 -0
  205. package/dist/services/issue-release.d.ts.map +1 -0
  206. package/dist/services/issue-release.js +89 -0
  207. package/dist/services/issue-release.js.map +1 -0
  208. package/dist/services/issue-report.d.ts +72 -0
  209. package/dist/services/issue-report.d.ts.map +1 -0
  210. package/dist/services/issue-report.js +84 -0
  211. package/dist/services/issue-report.js.map +1 -0
  212. package/dist/services/issue-status-view.d.ts +52 -0
  213. package/dist/services/issue-status-view.d.ts.map +1 -0
  214. package/dist/services/issue-status-view.js +42 -0
  215. package/dist/services/issue-status-view.js.map +1 -0
  216. package/dist/services/issue-status-writer.d.ts +98 -0
  217. package/dist/services/issue-status-writer.d.ts.map +1 -0
  218. package/dist/services/issue-status-writer.js +123 -0
  219. package/dist/services/issue-status-writer.js.map +1 -0
  220. package/dist/services/message-listener-store.d.ts +18 -0
  221. package/dist/services/message-listener-store.d.ts.map +1 -1
  222. package/dist/services/message-listener-store.js +35 -10
  223. package/dist/services/message-listener-store.js.map +1 -1
  224. package/dist/services/message-listener.d.ts +17 -0
  225. package/dist/services/message-listener.d.ts.map +1 -1
  226. package/dist/services/message-listener.js +26 -0
  227. package/dist/services/message-listener.js.map +1 -1
  228. package/dist/services/traex-paths.d.ts +14 -2
  229. package/dist/services/traex-paths.d.ts.map +1 -1
  230. package/dist/services/traex-paths.js +16 -2
  231. package/dist/services/traex-paths.js.map +1 -1
  232. package/dist/services/traex-transcript.d.ts +33 -0
  233. package/dist/services/traex-transcript.d.ts.map +1 -1
  234. package/dist/services/traex-transcript.js +135 -28
  235. package/dist/services/traex-transcript.js.map +1 -1
  236. package/dist/setup/bot-config-editor.d.ts.map +1 -1
  237. package/dist/setup/bot-config-editor.js +2 -0
  238. package/dist/setup/bot-config-editor.js.map +1 -1
  239. package/dist/setup/lark-scopes.json +1 -2
  240. package/dist/setup/verify-permissions.d.ts.map +1 -1
  241. package/dist/setup/verify-permissions.js +8 -0
  242. package/dist/setup/verify-permissions.js.map +1 -1
  243. package/dist/types.d.ts +34 -0
  244. package/dist/types.d.ts.map +1 -1
  245. package/dist/utils/child-env.d.ts +1 -1
  246. package/dist/utils/child-env.d.ts.map +1 -1
  247. package/dist/utils/child-env.js +13 -0
  248. package/dist/utils/child-env.js.map +1 -1
  249. package/dist/utils/file-lock.d.ts.map +1 -1
  250. package/dist/utils/file-lock.js +1 -1
  251. package/dist/utils/file-lock.js.map +1 -1
  252. package/dist/utils/global-install.d.ts.map +1 -1
  253. package/dist/utils/global-install.js +56 -10
  254. package/dist/utils/global-install.js.map +1 -1
  255. package/dist/utils/idle-detector.d.ts +4 -0
  256. package/dist/utils/idle-detector.d.ts.map +1 -1
  257. package/dist/utils/idle-detector.js +25 -0
  258. package/dist/utils/idle-detector.js.map +1 -1
  259. package/dist/utils/process-identity.d.ts +7 -0
  260. package/dist/utils/process-identity.d.ts.map +1 -0
  261. package/dist/utils/process-identity.js +62 -0
  262. package/dist/utils/process-identity.js.map +1 -0
  263. package/dist/worker.js +264 -24
  264. package/dist/worker.js.map +1 -1
  265. package/dist/workflows/events/payloads.d.ts +10 -10
  266. package/dist/workflows/events/schema.d.ts +28 -28
  267. package/dist/workflows/hostExecutors/registry.d.ts +2 -7
  268. package/dist/workflows/hostExecutors/registry.d.ts.map +1 -1
  269. package/dist/workflows/hostExecutors/registry.js.map +1 -1
  270. package/dist/workflows/shared/provider-reconciler.d.ts +1 -30
  271. package/dist/workflows/shared/provider-reconciler.d.ts.map +1 -1
  272. package/dist/workflows/shared/provider-reconciler.js.map +1 -1
  273. package/dist/workflows/v3/artifact-contract.d.ts +41 -0
  274. package/dist/workflows/v3/artifact-contract.d.ts.map +1 -0
  275. package/dist/workflows/v3/artifact-contract.js +20 -0
  276. package/dist/workflows/v3/artifact-contract.js.map +1 -0
  277. package/dist/workflows/v3/botmux-attempt-lease.d.ts +7 -0
  278. package/dist/workflows/v3/botmux-attempt-lease.d.ts.map +1 -0
  279. package/dist/workflows/v3/botmux-attempt-lease.js +189 -0
  280. package/dist/workflows/v3/botmux-attempt-lease.js.map +1 -0
  281. package/dist/workflows/v3/botmux-host-policy.d.ts +7 -0
  282. package/dist/workflows/v3/botmux-host-policy.d.ts.map +1 -0
  283. package/dist/workflows/v3/botmux-host-policy.js +34 -0
  284. package/dist/workflows/v3/botmux-host-policy.js.map +1 -0
  285. package/dist/workflows/v3/cli-run.d.ts +1 -1
  286. package/dist/workflows/v3/cli-run.d.ts.map +1 -1
  287. package/dist/workflows/v3/cli-run.js +1 -1
  288. package/dist/workflows/v3/cli-run.js.map +1 -1
  289. package/dist/workflows/v3/contract.d.ts +8 -89
  290. package/dist/workflows/v3/contract.d.ts.map +1 -1
  291. package/dist/workflows/v3/contract.js +2 -8
  292. package/dist/workflows/v3/contract.js.map +1 -1
  293. package/dist/workflows/v3/core-control.d.ts +16 -0
  294. package/dist/workflows/v3/core-control.d.ts.map +1 -0
  295. package/dist/workflows/v3/core-control.js +60 -0
  296. package/dist/workflows/v3/core-control.js.map +1 -0
  297. package/dist/workflows/v3/daemon-run.d.ts.map +1 -1
  298. package/dist/workflows/v3/daemon-run.js +2 -1
  299. package/dist/workflows/v3/daemon-run.js.map +1 -1
  300. package/dist/workflows/v3/dag-loader.d.ts +5 -0
  301. package/dist/workflows/v3/dag-loader.d.ts.map +1 -0
  302. package/dist/workflows/v3/dag-loader.js +22 -0
  303. package/dist/workflows/v3/dag-loader.js.map +1 -0
  304. package/dist/workflows/v3/dag.d.ts +2 -6
  305. package/dist/workflows/v3/dag.d.ts.map +1 -1
  306. package/dist/workflows/v3/dag.js +2 -24
  307. package/dist/workflows/v3/dag.js.map +1 -1
  308. package/dist/workflows/v3/ephemeral-pool.d.ts.map +1 -1
  309. package/dist/workflows/v3/ephemeral-pool.js +22 -12
  310. package/dist/workflows/v3/ephemeral-pool.js.map +1 -1
  311. package/dist/workflows/v3/event-contract.d.ts +273 -0
  312. package/dist/workflows/v3/event-contract.d.ts.map +1 -0
  313. package/dist/workflows/v3/event-contract.js +8 -0
  314. package/dist/workflows/v3/event-contract.js.map +1 -0
  315. package/dist/workflows/v3/gate-policy.d.ts +12 -0
  316. package/dist/workflows/v3/gate-policy.d.ts.map +1 -0
  317. package/dist/workflows/v3/gate-policy.js +20 -0
  318. package/dist/workflows/v3/gate-policy.js.map +1 -0
  319. package/dist/workflows/v3/gate-wait-store.d.ts +99 -0
  320. package/dist/workflows/v3/gate-wait-store.d.ts.map +1 -0
  321. package/dist/workflows/v3/gate-wait-store.js +263 -0
  322. package/dist/workflows/v3/gate-wait-store.js.map +1 -0
  323. package/dist/workflows/v3/host.js +1 -1
  324. package/dist/workflows/v3/host.js.map +1 -1
  325. package/dist/workflows/v3/human-gate.d.ts +4 -99
  326. package/dist/workflows/v3/human-gate.d.ts.map +1 -1
  327. package/dist/workflows/v3/human-gate.js +4 -275
  328. package/dist/workflows/v3/human-gate.js.map +1 -1
  329. package/dist/workflows/v3/in-process-attempt-lease.d.ts +10 -0
  330. package/dist/workflows/v3/in-process-attempt-lease.d.ts.map +1 -0
  331. package/dist/workflows/v3/in-process-attempt-lease.js +47 -0
  332. package/dist/workflows/v3/in-process-attempt-lease.js.map +1 -0
  333. package/dist/workflows/v3/journal.d.ts +2 -275
  334. package/dist/workflows/v3/journal.d.ts.map +1 -1
  335. package/dist/workflows/v3/journal.js.map +1 -1
  336. package/dist/workflows/v3/library-service.js +1 -1
  337. package/dist/workflows/v3/library-service.js.map +1 -1
  338. package/dist/workflows/v3/orchestrator.d.ts +1 -2
  339. package/dist/workflows/v3/orchestrator.d.ts.map +1 -1
  340. package/dist/workflows/v3/orchestrator.js.map +1 -1
  341. package/dist/workflows/v3/portable-artifact-snapshot.d.ts +15 -0
  342. package/dist/workflows/v3/portable-artifact-snapshot.d.ts.map +1 -0
  343. package/dist/workflows/v3/portable-artifact-snapshot.js +76 -0
  344. package/dist/workflows/v3/portable-artifact-snapshot.js.map +1 -0
  345. package/dist/workflows/v3/portable-final-outputs.d.ts +37 -0
  346. package/dist/workflows/v3/portable-final-outputs.d.ts.map +1 -0
  347. package/dist/workflows/v3/portable-final-outputs.js +137 -0
  348. package/dist/workflows/v3/portable-final-outputs.js.map +1 -0
  349. package/dist/workflows/v3/portable-run-snapshot.d.ts +14 -0
  350. package/dist/workflows/v3/portable-run-snapshot.d.ts.map +1 -0
  351. package/dist/workflows/v3/portable-run-snapshot.js +176 -0
  352. package/dist/workflows/v3/portable-run-snapshot.js.map +1 -0
  353. package/dist/workflows/v3/portable-runtime.d.ts +83 -0
  354. package/dist/workflows/v3/portable-runtime.d.ts.map +1 -0
  355. package/dist/workflows/v3/portable-runtime.js +135 -0
  356. package/dist/workflows/v3/portable-runtime.js.map +1 -0
  357. package/dist/workflows/v3/runtime-host-contract.d.ts +182 -0
  358. package/dist/workflows/v3/runtime-host-contract.d.ts.map +1 -0
  359. package/dist/workflows/v3/runtime-host-contract.js +9 -0
  360. package/dist/workflows/v3/runtime-host-contract.js.map +1 -0
  361. package/dist/workflows/v3/runtime.d.ts +12 -226
  362. package/dist/workflows/v3/runtime.d.ts.map +1 -1
  363. package/dist/workflows/v3/runtime.js +14 -3173
  364. package/dist/workflows/v3/runtime.js.map +1 -1
  365. package/dist/workflows/v3/shared-node-runtime.d.ts +203 -0
  366. package/dist/workflows/v3/shared-node-runtime.d.ts.map +1 -0
  367. package/dist/workflows/v3/shared-node-runtime.js +2978 -0
  368. package/dist/workflows/v3/shared-node-runtime.js.map +1 -0
  369. package/dist/workflows/v3/shared-runtime.d.ts +17 -0
  370. package/dist/workflows/v3/shared-runtime.d.ts.map +1 -0
  371. package/dist/workflows/v3/shared-runtime.js +12 -0
  372. package/dist/workflows/v3/shared-runtime.js.map +1 -0
  373. package/package.json +4 -1
  374. package/dist/dashboard-web/chunks/roles-page-LHVAU2BI.js +0 -1
package/dist/cli.js CHANGED
@@ -34,7 +34,7 @@ import { validateWorkingDir } from './core/working-dir.js';
34
34
  import { resolveSessionContext } from './core/session-marker.js';
35
35
  import { resolveBotmuxDataDir } from './core/data-dir.js';
36
36
  import { dashboardSecretPath } from './core/dashboard-secret.js';
37
- import { acceptedDispatchBotAppIds, activeConversationBotOpenIds, appendDispatchReportProtocol, appendLegacyDispatchReportProtocol, parseDispatchBotSpec, buildDispatchMessages, buildRepoPrimeText, buildReportContent, eligibleAutoMentionAliases, findDispatchRegistryEntry, foldableChatSessionAppIds, offTopicSubBotTopic, resolveReportTarget, resolveSendTarget, threadRootForReachability } from './core/dispatch.js';
37
+ import { acceptedDispatchBotAppIds, activeConversationBotOpenIds, appendDispatchReportProtocol, appendLegacyDispatchReportProtocol, parseDispatchBotSpec, buildDispatchMessages, buildRepoPrimeText, buildReportContent, eligibleAutoMentionAliases, findDispatchRegistryEntry, foldableChatSessionAppIds, offTopicSubBotTopic, resolveReportPlacement, resolveReportRecipient, resolveReportTarget, resolveSendTarget, threadRootForReachability } from './core/dispatch.js';
38
38
  import { pickTurnReplyTarget } from './core/reply-target.js';
39
39
  import { recordDispatchRegistryEntry } from './core/dispatch-registry.js';
40
40
  import { enableAutostart, disableAutostart, autostartStatus, refreshAutostart } from './autostart.js';
@@ -60,6 +60,7 @@ import { dispatchDeferredTopicSend, reusableDeferredTopicRoot } from './cli/defe
60
60
  import { readDeferredTopicBinding } from './core/deferred-topic-binding.js';
61
61
  import { resolveDaemonEnv } from './cli/daemon-lifecycle-env.js';
62
62
  import { buildPm2SpawnCommand } from './cli/pm2-command.js';
63
+ import { pm2ManagedExitConfig } from './pm2-graceful-exit.js';
63
64
  import { callDashboard } from './cli/dashboard-endpoint.js';
64
65
  import { globalInstallUpdateLockTargetIn, installLatestBotmuxSync } from './core/maintenance.js';
65
66
  import { withFileLockSync } from './utils/file-lock.js';
@@ -423,6 +424,7 @@ function ecosystemConfig(activationAppId) {
423
424
  const bots = loadBotsJson();
424
425
  ensureUniqueBotProcessNames(bots);
425
426
  const daemonEnv = resolveDaemonEnv(process.env, existsSync(ENV_FILE) ? readFileSync(ENV_FILE, 'utf-8') : undefined);
427
+ const managedExit = pm2ManagedExitConfig();
426
428
  const baseApp = {
427
429
  script: daemonScript,
428
430
  // Pin every managed core process to the Node that invoked this CLI. This
@@ -433,14 +435,14 @@ function ecosystemConfig(activationAppId) {
433
435
  autorestart: true,
434
436
  max_restarts: 10,
435
437
  restart_delay: 3000,
436
- // A graceful daemon shutdown exits 0 (SIGTERM/SIGINT drain → process.exit(0)).
437
- // Tell pm2 that exit 0 is intentional so it does NOT autorestart the daemon
438
+ // A graceful PM2-managed shutdown exits with a dedicated sentinel code.
439
+ // Tell pm2 that only this code is intentional so it does NOT autorestart the daemon
438
440
  // while `botmux restart` is tearing the fleet down — otherwise pm2 revives
439
441
  // each daemon (after restart_delay) the instant our parallel SIGTERM drains
440
442
  // it, and re-deleting those revivals one-by-one re-serializes the teardown
441
- // (~13s of churn for 31 bots). Crashes (non-zero exit / killed by signal)
442
- // are NOT in this list, so genuine crash-autorestart is preserved.
443
- stop_exit_codes: [0],
443
+ // (~13s of churn for 31 bots). Do not use 0 here: PM2 normalizes a signal
444
+ // exit's null code to 0, which would suppress autorestart after SIGKILL.
445
+ stop_exit_codes: managedExit.stopExitCodes,
444
446
  // pm2's default kill_timeout (1.6s) is SHORTER than the daemon's own
445
447
  // SHUTDOWN_GRACE_MS (3s), so any daemon pm2 has to signal directly gets
446
448
  // SIGKILL'd mid-drain → orphaned (ppid=1) workers. Give pm2 headroom past
@@ -490,6 +492,7 @@ function ecosystemConfig(activationAppId) {
490
492
  out_file: join(LOG_DIR, `daemon-${i}-out.log`),
491
493
  env: {
492
494
  ...daemonEnv,
495
+ ...managedExit.env,
493
496
  SESSION_DATA_DIR: DATA_DIR,
494
497
  BOTMUX_BOT_INDEX: String(i),
495
498
  BOTMUX_LARK_APP_ID: appId,
@@ -514,15 +517,16 @@ function ecosystemConfig(activationAppId) {
514
517
  autorestart: true,
515
518
  max_restarts: 10,
516
519
  restart_delay: 3000,
517
- // Same rationale as the bot daemons: don't let pm2 revive on graceful exit-0
520
+ // Same rationale as the bot daemons: don't let pm2 revive on graceful exit
518
521
  // during a fleet teardown, and don't SIGKILL mid-shutdown. (See baseApp.)
519
- stop_exit_codes: [0],
522
+ stop_exit_codes: managedExit.stopExitCodes,
520
523
  kill_timeout: 3500,
521
524
  error_file: join(LOG_DIR, 'dashboard-error.log'),
522
525
  out_file: join(LOG_DIR, 'dashboard-out.log'),
523
526
  merge_logs: true,
524
527
  env: {
525
528
  ...daemonEnv,
529
+ ...managedExit.env,
526
530
  // MUST match the bot daemons' SESSION_DATA_DIR: the dashboard shares
527
531
  // pairings/federations/memberships with them via {dataDir}/*.json. Without
528
532
  // it the dashboard falls back to an install-relative ../data and reads a
@@ -3461,16 +3465,34 @@ function sessionBackingInfo(s, snapshot) {
3461
3465
  if (s.backendType === 'pty') {
3462
3466
  return { backendType: 'pty', probe: 'missing', label: 'pty' };
3463
3467
  }
3464
- // Legacy rows predate backend stamping. Only tmux was externally attachable.
3465
- const target = sessionPersistentTarget(s);
3466
- const probe = backingProbe(snapshot, target);
3467
- return {
3468
- backendType: 'tmux',
3469
- target,
3470
- probe,
3471
- label: probe === 'exists' ? `tmux: ${target.sessionName}` : '-',
3472
- attachBackend: 'tmux',
3473
- };
3468
+ if (s.backendType === 'riff') {
3469
+ // Riff runs the CLI on a remote sandbox, not a local multiplexer pane: there
3470
+ // is nothing to probe, attach to, or name as a PersistentBackendTarget
3471
+ // (sessionPersistentTarget returns undefined for it, by design). Surface a
3472
+ // stable label and report the nonexistent local backing as missing — exactly
3473
+ // like pty — so it never slips into the legacy tmux branch and dereferences an
3474
+ // undefined target.
3475
+ return { backendType: 'riff', probe: 'missing', label: 'riff' };
3476
+ }
3477
+ if (s.backendType === undefined) {
3478
+ // Legacy rows predate backend stamping. Only tmux was externally attachable,
3479
+ // so its deterministic target remains the compatibility path.
3480
+ const target = sessionPersistentTarget(s);
3481
+ const probe = backingProbe(snapshot, target);
3482
+ return {
3483
+ backendType: 'tmux',
3484
+ target,
3485
+ probe,
3486
+ label: probe === 'exists' ? `tmux: ${target.sessionName}` : '-',
3487
+ attachBackend: 'tmux',
3488
+ };
3489
+ }
3490
+ // Exhaustiveness guard: every BackendType must be classified above. A future
3491
+ // non-suspendable backend added to BackendType will fail to compile here rather
3492
+ // than silently inheriting the legacy tmux target (the Riff crash's root cause).
3493
+ const _exhaustive = s.backendType;
3494
+ void _exhaustive;
3495
+ return { probe: 'missing', label: '-' };
3474
3496
  }
3475
3497
  function sessionTargetLabel(s, snapshot) {
3476
3498
  if (isAdoptedSession(s))
@@ -5042,7 +5064,7 @@ botmux v${getVersion()} — IM ↔ AI 编程 CLI 桥接
5042
5064
  v2 历史 run 私有静态归档;retire 在维护窗双验后原子迁入 quarantine
5043
5065
  (完整参数见 \`botmux workflow help\` / \`botmux template help\`)
5044
5066
  dispatch --bot <name> [...] 多话题编排:开子话题并把 bot 派进去(详见 \`botmux dispatch --help\`)
5045
- report [...] v3/编排场景向上汇报进度或结果(详见 \`botmux report --help\`)
5067
+ report [...] 交接 Review / 进展 / 结果并继承会话位置(详见 \`botmux report --help\`)
5046
5068
 
5047
5069
  新建飞书群:
5048
5070
  create-group --bot <name> [--bot ...] [--name "群名"]
@@ -8152,41 +8174,68 @@ async function cmdDispatch(rest) {
8152
8174
  }
8153
8175
  }
8154
8176
  /**
8155
- * `botmux report` — a dispatched sub-bot reports progress/completion back to the
8156
- * orchestrator that dispatched it.
8177
+ * `botmux report` — delivery / progress report, then hand Review/progress/results
8178
+ * back to the stable recipient.
8157
8179
  *
8158
- * In 多话题协作模式 the sub-bot lives in its own sub-topic, where the orchestrator
8159
- * has no session; @-ing the orchestrator there would spawn a fresh, context-less
8160
- * one (the reported #1 bug). Instead this routes the report INTO the orchestrator's own
8161
- * thread (recorded by `botmux dispatch` in orchestrate-dispatch.json) and @-s the
8162
- * orchestrator there, so its existing, context-rich session is the one that wakes.
8163
- *
8164
- * Coords: orchestrator open_id = the sub-bot session's quoteTargetSenderOpenId
8165
- * (the dispatcher of the turn that opened this sub-topic); orchestrator thread =
8166
- * the registry entry keyed by this sub-bot's session.rootMessageId (== the seed).
8180
+ * Two paths:
8181
+ * 1) Platform Issue 领取群:session 有活跃 issue binding enqueue+write `in_review`
8182
+ * (待验收). This is what kickoff means by 「完成后执行 botmux report」.
8183
+ * 2) 交接回报:recipient and placement are separate decisions. Registry-backed
8184
+ * multi-topic dispatches keep their exact orchestrator-session route. Ordinary
8185
+ * development handoffs inherit the executing turn's visible position with the
8186
+ * same turn-id gate as `botmux send`, so a later turn cannot reuse a stale
8187
+ * topic anchor.
8167
8188
  */
8168
8189
  async function cmdReport(rest) {
8169
8190
  if (rest.includes('--help') || rest.includes('-h')) {
8170
- console.log(`botmux report — 把子项目进展/完成回报给派活的主编排会话
8191
+ console.log(`botmux report — 交付回报(issue 待验收 / 交接 Review·进展·结果并保持自然会话位置)
8171
8192
 
8172
8193
  用法:
8173
- botmux report "子项目X 完成,产出在 …"
8174
- botmux report --dispatch-root <om_seed> "子项目X 完成,产出在 …"
8175
8194
  botmux report --content-file <path>
8195
+ botmux report --into <om_root> --content-file <path>
8196
+ botmux report --top-level "子项目X 完成,产出在 …"
8197
+ botmux report --dispatch-root <om_seed> "子项目X 完成,产出在 …"
8198
+ botmux report "子项目X 完成,产出在 …" --legacy-dispatch
8176
8199
 
8177
8200
  说明:
8178
- 「多话题协作模式」里你(子 bot)干完后不要在本话题 @ 主bot——本话题没有主bot的会话,
8179
- @ 会另起一个无上下文的新会话。本命令把回报发回主编排会话所在的话题、并 @ 主编排 bot,
8180
- 使其带完整上下文继续聚合。仅在被 botmux dispatch 派活的子项目会话里可用。
8201
+ 1) 平台 Issue 领取群:本会话绑定了平台 issue 时,把 issue 推到「待验收」(in_review)。
8202
+ kickoff 里「完成后执行 botmux report」指的就是这条路径。
8203
+ 2) 交接 / 协作回报:接收者与消息落点独立解析——接收者仍是原 Reviewer / orchestrator;
8204
+ 消息默认依次采用显式 --into / --top-level、dispatch 注册表、legacy dispatch 兼容回退、
8205
+ 当前轮次位置,最后才回退到会话默认位置。
8206
+ 当前轮次在群顶层就留在群顶层,在话题里就留在原话题;过期轮次的话题目标会被忽略。
8207
+ dispatch 注册表命中时仍回到原主编排会话,并唤醒其已有上下文。
8208
+ legacy / 跨机器 dispatch 没有本机注册表时仍回退群顶层,避免在子话题唤醒无上下文会话。
8209
+
8210
+ 代码 Review 交接建议明确写出:首次 Review / 复审、MR、本轮改动、验证、风险,
8211
+ 以及希望 Reviewer 采取的动作。
8181
8212
 
8182
8213
  选项:
8183
8214
  --content-file <path> 从文件读取回报内容
8215
+ --into <root_id> 显式发进指定话题(覆盖默认落点)
8216
+ --top-level 显式发到当前群顶层(覆盖默认落点)
8184
8217
  --dispatch-root <id> dispatch 注入的精确 seed;优先且不命中时 fail closed
8218
+ --legacy-dispatch legacy / 跨机器 dispatch 自动注入的兼容标记
8185
8219
  --session-id <id> 指定来源会话(默认自动推断)`);
8186
8220
  return;
8187
8221
  }
8188
8222
  process.env.SESSION_DATA_DIR ??= resolveDataDir();
8189
8223
  const sessionIdArg = argValue(rest, '--session-id');
8224
+ if (flagPresentButValueMissing(rest, '--into')) {
8225
+ console.error('--into 需要一个 om_ 话题根消息 id。');
8226
+ process.exit(1);
8227
+ }
8228
+ const explicitInto = argValue(rest, '--into')?.trim();
8229
+ if (explicitInto && !/^om_[A-Za-z0-9_-]{1,128}$/.test(explicitInto)) {
8230
+ console.error('--into 必须是有效的 om_ 话题根消息 id。');
8231
+ process.exit(1);
8232
+ }
8233
+ const explicitTopLevel = rest.includes('--top-level');
8234
+ const legacyDispatch = rest.includes('--legacy-dispatch');
8235
+ if (explicitInto && explicitTopLevel) {
8236
+ console.error('--into 与 --top-level 不能同时使用。');
8237
+ process.exit(1);
8238
+ }
8190
8239
  if (flagPresentButValueMissing(rest, '--dispatch-root')) {
8191
8240
  console.error('--dispatch-root 需要一个 om_ 消息 id。');
8192
8241
  process.exit(1);
@@ -8206,7 +8255,7 @@ async function cmdReport(rest) {
8206
8255
  content = readFileSync(contentFile, 'utf-8');
8207
8256
  }
8208
8257
  else {
8209
- const pos = positionals(rest);
8258
+ const pos = positionals(rest, ['--top-level', '--legacy-dispatch']);
8210
8259
  content = pos.length ? pos.join(' ') : await readStdin();
8211
8260
  }
8212
8261
  if (!contentFile)
@@ -8215,11 +8264,18 @@ async function cmdReport(rest) {
8215
8264
  console.error('没有回报内容。用法: botmux report "子项目X 完成 + 产出位置"');
8216
8265
  process.exit(1);
8217
8266
  }
8218
- const sid = sessionIdArg ?? findAncestorSessionId();
8267
+ // The process-tree marker carries the executing turn. Do not revive the
8268
+ // spawn-time BOTMUX_TURN_ID here: it is stale in a long-lived or detached
8269
+ // CLI and could make an old topic target look current.
8270
+ const reportContext = resolveSessionContext(resolveDataDir(), process.env.BOTMUX_SESSION_ID);
8271
+ const sid = sessionIdArg ?? reportContext?.sessionId;
8219
8272
  if (!sid) {
8220
- console.error('无法推断 session-id。请在被 dispatch 派活的会话里运行,或传 --session-id <id>。');
8273
+ console.error('无法推断 session-id。请在当前 Botmux 会话(issue 领取群 / 被 dispatch 派活的会话)里运行,或传 --session-id <id>。');
8221
8274
  process.exit(1);
8222
8275
  }
8276
+ const currentTurnId = reportContext?.sessionId === sid
8277
+ ? reportContext.turnId
8278
+ : undefined;
8223
8279
  const sessions = loadSessions();
8224
8280
  const s = sessions.get(sid);
8225
8281
  if (!s) {
@@ -8230,12 +8286,102 @@ async function cmdReport(rest) {
8230
8286
  console.error(`session ${sid} 缺少 larkAppId`);
8231
8287
  process.exit(1);
8232
8288
  }
8233
- // Resolve where the report goes + who to @. Same-machine: the dispatch registry
8234
- // (keyed by this sub-bot's thread root) carries the orchestrator's exact coords.
8235
- // CROSS-MACHINE: the orchestrator is on another machine, so its registry isn't
8236
- // on THIS one — resolveReportTarget falls back to this sub-bot's own session
8237
- // (report top-level into its chat, @ the dispatcher via creatorOpenId). See
8238
- // resolveReportTarget / Session.creatorOpenId.
8289
+ // ── Issue Board 交付:绑定了平台 issue 的领取群 in_review(待验收)────────
8290
+ // 优先于 dispatch 路径:领取群没有 creatorOpenId,走 dispatch 会硬失败。
8291
+ // 显式 --dispatch-root 时仍走协作回报(避免 issue 群里误 dispatch 被静默改道)。
8292
+ if (!explicitDispatchRoot) {
8293
+ try {
8294
+ const dataDir = resolveDataDir();
8295
+ const { findActiveBindingForSession, reportIssueInReview } = await import('./services/issue-report.js');
8296
+ const binding = findActiveBindingForSession(dataDir, {
8297
+ chatId: s.chatId,
8298
+ rootMessageId: s.rootMessageId,
8299
+ });
8300
+ if (binding) {
8301
+ const { writeIssueStatus, findIssueById } = await import('./platform/issue-client.js');
8302
+ const result = await reportIssueInReview({
8303
+ dataDir,
8304
+ writeStatus: (issueId, args) => writeIssueStatus(issueId, args),
8305
+ fetchIssue: (teamId, issueId) => findIssueById(teamId, issueId),
8306
+ }, binding.anchorId);
8307
+ if (!result.ok) {
8308
+ if (result.reason === 'platform') {
8309
+ console.error(result.permanent
8310
+ ? `issue 交付失败(${result.detail})。平台明确拒绝,重试不会好转——去平台看看这条任务还在不在、领取有没有被收回。`
8311
+ : `issue 交付失败(${result.detail})。可稍后重试同一 botmux report。`);
8312
+ }
8313
+ else if (result.reason === 'detached') {
8314
+ // 重试没有意义:平台上这条 claim 已经不是本机的了。
8315
+ console.error(`issue 交付失败:平台上这个任务的领取已不属于本机(被回收、租约过期或已被别人领走),`
8316
+ + `交付没有落地。去平台看看任务 ${binding.issueId} 的状态。`);
8317
+ }
8318
+ else {
8319
+ console.error(`issue 交付失败:${result.reason}`);
8320
+ }
8321
+ process.exit(1);
8322
+ }
8323
+ // 交付说明必须发回群里:平台的 /status 只收状态、不收正文(没有 note 字段),
8324
+ // 这段文字在平台上无处可放。不发的话验收的人只看到状态变成「待验收」,完全不知道
8325
+ // 交付了什么,而 stdout 只有 agent 自己看得到。
8326
+ let delivered = false;
8327
+ try {
8328
+ const { registerBot, loadBotConfigs } = await import('./bot-registry.js');
8329
+ await registerSelfFromCredFile();
8330
+ try {
8331
+ for (const cfg of loadBotConfigs())
8332
+ registerBot(cfg);
8333
+ }
8334
+ catch { /* 已注册/读不到 */ }
8335
+ const { buildIssueDeliveryCard } = await import('./im/lark/issue-card.js');
8336
+ const { issueDetailUrl } = await import('./services/issue-claim-flow.js');
8337
+ const { sendMessage: larkSend } = await import('./im/lark/client.js');
8338
+ const url = issueDetailUrl(binding.platformBaseUrl, result.issueId);
8339
+ await larkSend(s.larkAppId, binding.chatId ?? binding.anchorId, buildIssueDeliveryCard({
8340
+ issueId: result.issueId,
8341
+ report: content,
8342
+ alreadyInReview: result.alreadyInReview,
8343
+ ...(url ? { issueUrl: url } : {}),
8344
+ }), 'interactive');
8345
+ delivered = true;
8346
+ }
8347
+ catch (e) {
8348
+ // 状态已经写成功了,播报失败不该让整条命令失败——但要如实说出来,
8349
+ // 否则 agent 以为交付说明已经送达。
8350
+ console.error(`交付说明未能发回群里(状态已是待验收):${e?.message ?? e}`);
8351
+ }
8352
+ console.log(JSON.stringify({
8353
+ success: true,
8354
+ delivery: 'issue-in-review',
8355
+ issueId: result.issueId,
8356
+ anchorId: binding.anchorId,
8357
+ alreadyInReview: result.alreadyInReview,
8358
+ reportPostedToChat: delivered,
8359
+ reportPreview: content.trim().slice(0, 200),
8360
+ }));
8361
+ return;
8362
+ }
8363
+ }
8364
+ catch (err) {
8365
+ console.error(`issue 交付异常: ${err?.message ?? err}`);
8366
+ process.exit(1);
8367
+ }
8368
+ }
8369
+ // Recipient and visible placement are independent. creatorOpenId remains the
8370
+ // stable Reviewer/orchestrator identity; current-turn routing controls where
8371
+ // an ordinary report appears.
8372
+ const reportRecipient = resolveReportRecipient({
8373
+ creatorOpenId: s.creatorOpenId,
8374
+ ownerOpenId: s.ownerOpenId,
8375
+ quoteTargetSenderOpenId: s.quoteTargetSenderOpenId,
8376
+ });
8377
+ const turnReplyTarget = pickTurnReplyTarget(s, currentTurnId);
8378
+ const validatedTurnReplyTarget = currentTurnId
8379
+ && turnReplyTarget?.turnId === currentTurnId
8380
+ ? turnReplyTarget
8381
+ : undefined;
8382
+ // Same-machine dispatches retain their exact orchestrator registry route.
8383
+ // A chat-scope target may participate only when it belongs to this executing
8384
+ // turn; historical aliases have no turn id and are intentionally ignored.
8239
8385
  const regPath = join(resolveDataDir(), 'orchestrate-dispatch.json');
8240
8386
  let reg = {};
8241
8387
  try {
@@ -8246,21 +8392,36 @@ async function cmdReport(rest) {
8246
8392
  const registryMatch = findDispatchRegistryEntry({
8247
8393
  registry: reg,
8248
8394
  dispatchRootId: explicitDispatchRoot,
8395
+ sessionScope: s.scope ?? 'thread',
8249
8396
  rootMessageId: s.rootMessageId,
8250
- currentReplyTargetRootId: s.currentReplyTarget?.rootMessageId,
8251
- replyThreadAliases: s.replyThreadAliases,
8397
+ currentReplyTargetRootId: validatedTurnReplyTarget?.rootMessageId,
8398
+ currentReplyTargetTurnId: validatedTurnReplyTarget?.turnId,
8399
+ currentTurnId,
8252
8400
  });
8253
8401
  if (explicitDispatchRoot && registryMatch?.key !== explicitDispatchRoot) {
8254
8402
  console.error(`精确 dispatch root ${explicitDispatchRoot} 在本机注册表中不存在;为避免串到其他 PM 会话,本次回报已停止。`);
8255
8403
  process.exit(1);
8256
8404
  }
8257
8405
  const entry = registryMatch?.entry;
8406
+ const dispatchCoords = resolveReportTarget({
8407
+ registryEntry: entry,
8408
+ sessionChatId: s.chatId,
8409
+ });
8410
+ const registryTarget = registryMatch
8411
+ ? dispatchCoords.orchScope !== 'chat' && dispatchCoords.orchRoot
8412
+ ? { mode: 'thread', rootMessageId: dispatchCoords.orchRoot }
8413
+ : dispatchCoords.orchChatId
8414
+ ? { mode: 'plain', chatId: dispatchCoords.orchChatId }
8415
+ : undefined
8416
+ : undefined;
8417
+ const hasExplicitPlacement = !!explicitInto || explicitTopLevel;
8258
8418
  // Same-host dispatches carry the exact source session. Inject the report into
8259
8419
  // that live PM context through its own daemon instead of trying to make the
8260
8420
  // resident app post into the PM's source chat (which may be a P2P the
8261
8421
  // resident app cannot access). The report body remains untrusted envelope
8262
- // data; only the fixed consolidation instruction is trusted.
8263
- if (entry?.orchAppId && entry?.orchSessionId) {
8422
+ // data; only the fixed consolidation instruction is trusted. An explicit
8423
+ // visible placement overrides this registry delivery by design.
8424
+ if (!hasExplicitPlacement && entry?.orchAppId && entry?.orchSessionId) {
8264
8425
  const daemon = findDaemon(entry.orchAppId);
8265
8426
  if (!daemon) {
8266
8427
  console.error('主编排 Bot daemon 不在线;回报未发送,可稍后重试同一 botmux report。');
@@ -8312,22 +8473,40 @@ async function cmdReport(rest) {
8312
8473
  delivery: 'orchestrator-session',
8313
8474
  reportedTo: entry.orchSessionId,
8314
8475
  viaRegistry: true,
8476
+ recipient: {
8477
+ kind: 'orchestrator-session',
8478
+ botAppId: entry.orchAppId,
8479
+ sessionId: entry.orchSessionId,
8480
+ ...(reportRecipient ? { openId: reportRecipient } : {}),
8481
+ },
8482
+ placementSource: 'dispatch-registry',
8483
+ messageTarget: {
8484
+ mode: 'orchestrator-session',
8485
+ sessionId: entry.orchSessionId,
8486
+ botAppId: entry.orchAppId,
8487
+ },
8315
8488
  triggerId: triggerBody.triggerId,
8316
8489
  }));
8317
8490
  return;
8318
8491
  }
8319
- const tgt = resolveReportTarget({
8320
- registryEntry: entry,
8321
- sessionChatId: s.chatId,
8322
- creatorOpenId: s.creatorOpenId,
8323
- ownerOpenId: s.ownerOpenId,
8324
- quoteTargetSenderOpenId: s.quoteTargetSenderOpenId,
8325
- });
8326
- if (!tgt.orchOpenId || !tgt.orchChatId) {
8327
- console.error('找不到主编排坐标:本会话没记录派活者(creatorOpenId/ownerOpenId 都空)或缺 chatId——大概不是被 botmux dispatch 派活的会话。\n' +
8328
- '若确需回报,请改用 `botmux send` 或显式 @ 对应的人/ bot。');
8492
+ if (!reportRecipient) {
8493
+ console.error('找不到 Review / 回报接收者:本会话没有 creatorOpenId、ownerOpenId 或可用的历史发送者。\n' +
8494
+ '若确需交接,请改用 `botmux send --mention <open_id:名字>` 明确指定接收者。');
8329
8495
  process.exit(1);
8330
8496
  }
8497
+ const placement = resolveReportPlacement({
8498
+ into: explicitInto,
8499
+ topLevel: explicitTopLevel,
8500
+ registryTarget,
8501
+ legacyDispatch,
8502
+ chatScope: (s.scope ?? 'thread') === 'chat',
8503
+ chatId: s.chatId,
8504
+ rootMessageId: s.rootMessageId,
8505
+ replyTargetRootId: validatedTurnReplyTarget?.rootMessageId,
8506
+ replyTargetTurnId: validatedTurnReplyTarget?.turnId,
8507
+ replyTargetQuoteOnly: validatedTurnReplyTarget?.quoteOnly,
8508
+ currentTurnId,
8509
+ });
8331
8510
  const { registerBot, loadBotConfigs } = await import('./bot-registry.js');
8332
8511
  try {
8333
8512
  for (const cfg of loadBotConfigs())
@@ -8342,25 +8521,30 @@ async function cmdReport(rest) {
8342
8521
  }
8343
8522
  const { sendMessage, replyMessage } = await import('./im/lark/client.js');
8344
8523
  const appId = s.larkAppId;
8345
- const paras = buildReportContent({ orchOpenId: tgt.orchOpenId, content });
8524
+ const paras = buildReportContent({ orchOpenId: reportRecipient, content });
8346
8525
  const postJson = JSON.stringify({ zh_cn: { title: '', content: paras } });
8347
8526
  try {
8348
8527
  let msgId;
8349
- if (tgt.orchScope === 'chat' || !tgt.orchRoot) {
8350
- // Orchestrator at chat scope, or cross-machine fallback → post top-level
8351
- // into the chat (the sub-topic's chat = the orchestrator's chat).
8352
- msgId = await sendMessage(appId, tgt.orchChatId, postJson, 'post');
8528
+ if (placement.target.mode === 'plain') {
8529
+ msgId = await sendMessage(appId, placement.target.chatId, postJson, 'post');
8353
8530
  }
8354
8531
  else {
8355
- // Same-machine thread-scope orchestrator reply into its thread so its
8356
- // existing context-rich session (anchored on orchRoot) receives the report.
8357
- msgId = await replyMessage(appId, tgt.orchRoot, postJson, 'post', true);
8532
+ msgId = await replyMessage(appId, placement.target.rootMessageId, postJson, 'post', placement.target.mode === 'thread');
8358
8533
  }
8534
+ const messageTarget = placement.target.mode === 'plain'
8535
+ ? { mode: 'top-level', chatId: placement.target.chatId }
8536
+ : { mode: placement.target.mode, rootMessageId: placement.target.rootMessageId };
8359
8537
  console.log(JSON.stringify({
8360
8538
  success: true,
8361
- reportedTo: tgt.orchRoot || tgt.orchChatId,
8362
- orchestrator: tgt.orchOpenId,
8539
+ delivery: 'lark-message',
8540
+ reportedTo: placement.target.mode === 'plain'
8541
+ ? placement.target.chatId
8542
+ : placement.target.rootMessageId,
8543
+ orchestrator: reportRecipient,
8544
+ recipient: { kind: 'mention', openId: reportRecipient },
8363
8545
  viaRegistry: !!registryMatch,
8546
+ placementSource: placement.source,
8547
+ messageTarget,
8364
8548
  messageId: msgId,
8365
8549
  }));
8366
8550
  }