botmux 3.13.0 → 3.14.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 (508) hide show
  1. package/README.en.md +1 -1
  2. package/README.md +25 -1
  3. package/dist/.runtime-build-id +1 -1
  4. package/dist/adapters/adopt-route.d.ts +58 -0
  5. package/dist/adapters/adopt-route.d.ts.map +1 -1
  6. package/dist/adapters/adopt-route.js +136 -0
  7. package/dist/adapters/adopt-route.js.map +1 -1
  8. package/dist/adapters/backend/capabilities.js +1 -1
  9. package/dist/adapters/backend/capabilities.js.map +1 -1
  10. package/dist/adapters/backend/herdr-backend.d.ts +1 -1
  11. package/dist/adapters/backend/herdr-backend.d.ts.map +1 -1
  12. package/dist/adapters/backend/herdr-backend.js +2 -1
  13. package/dist/adapters/backend/herdr-backend.js.map +1 -1
  14. package/dist/adapters/backend/riff-backend.d.ts +97 -0
  15. package/dist/adapters/backend/riff-backend.d.ts.map +1 -1
  16. package/dist/adapters/backend/riff-backend.js +380 -66
  17. package/dist/adapters/backend/riff-backend.js.map +1 -1
  18. package/dist/adapters/backend/sandbox.d.ts +8 -0
  19. package/dist/adapters/backend/sandbox.d.ts.map +1 -1
  20. package/dist/adapters/backend/sandbox.js +16 -2
  21. package/dist/adapters/backend/sandbox.js.map +1 -1
  22. package/dist/adapters/backend/tmux-backend.d.ts +12 -13
  23. package/dist/adapters/backend/tmux-backend.d.ts.map +1 -1
  24. package/dist/adapters/backend/tmux-backend.js +113 -53
  25. package/dist/adapters/backend/tmux-backend.js.map +1 -1
  26. package/dist/adapters/backend/tmux-pipe-backend.d.ts +4 -3
  27. package/dist/adapters/backend/tmux-pipe-backend.d.ts.map +1 -1
  28. package/dist/adapters/backend/tmux-pipe-backend.js +12 -9
  29. package/dist/adapters/backend/tmux-pipe-backend.js.map +1 -1
  30. package/dist/adapters/backend/zellij-backend.d.ts +2 -3
  31. package/dist/adapters/backend/zellij-backend.d.ts.map +1 -1
  32. package/dist/adapters/backend/zellij-backend.js +6 -13
  33. package/dist/adapters/backend/zellij-backend.js.map +1 -1
  34. package/dist/adapters/backend/zellij-observe-backend.d.ts +2 -1
  35. package/dist/adapters/backend/zellij-observe-backend.d.ts.map +1 -1
  36. package/dist/adapters/backend/zellij-observe-backend.js +6 -3
  37. package/dist/adapters/backend/zellij-observe-backend.js.map +1 -1
  38. package/dist/adapters/backend/zmx-backend.d.ts.map +1 -1
  39. package/dist/adapters/backend/zmx-backend.js +40 -18
  40. package/dist/adapters/backend/zmx-backend.js.map +1 -1
  41. package/dist/adapters/cli/claude-code.d.ts.map +1 -1
  42. package/dist/adapters/cli/claude-code.js +12 -1
  43. package/dist/adapters/cli/claude-code.js.map +1 -1
  44. package/dist/adapters/cli/codex.d.ts.map +1 -1
  45. package/dist/adapters/cli/codex.js +3 -2
  46. package/dist/adapters/cli/codex.js.map +1 -1
  47. package/dist/adapters/cli/dsh.d.ts +4 -0
  48. package/dist/adapters/cli/dsh.d.ts.map +1 -0
  49. package/dist/adapters/cli/dsh.js +96 -0
  50. package/dist/adapters/cli/dsh.js.map +1 -0
  51. package/dist/adapters/cli/fs-policy.d.ts.map +1 -1
  52. package/dist/adapters/cli/fs-policy.js +5 -0
  53. package/dist/adapters/cli/fs-policy.js.map +1 -1
  54. package/dist/adapters/cli/opencode.d.ts +52 -1
  55. package/dist/adapters/cli/opencode.d.ts.map +1 -1
  56. package/dist/adapters/cli/opencode.js +117 -76
  57. package/dist/adapters/cli/opencode.js.map +1 -1
  58. package/dist/adapters/cli/opencode2.d.ts +4 -0
  59. package/dist/adapters/cli/opencode2.d.ts.map +1 -0
  60. package/dist/adapters/cli/opencode2.js +137 -0
  61. package/dist/adapters/cli/opencode2.js.map +1 -0
  62. package/dist/adapters/cli/read-isolation.d.ts +1 -1
  63. package/dist/adapters/cli/read-isolation.d.ts.map +1 -1
  64. package/dist/adapters/cli/read-isolation.js +5 -2
  65. package/dist/adapters/cli/read-isolation.js.map +1 -1
  66. package/dist/adapters/cli/registry.d.ts +7 -1
  67. package/dist/adapters/cli/registry.d.ts.map +1 -1
  68. package/dist/adapters/cli/registry.js +19 -6
  69. package/dist/adapters/cli/registry.js.map +1 -1
  70. package/dist/adapters/cli/shared-hints.d.ts.map +1 -1
  71. package/dist/adapters/cli/shared-hints.js +13 -0
  72. package/dist/adapters/cli/shared-hints.js.map +1 -1
  73. package/dist/adapters/cli/types.d.ts +24 -3
  74. package/dist/adapters/cli/types.d.ts.map +1 -1
  75. package/dist/adapters/hook-command.d.ts +8 -0
  76. package/dist/adapters/hook-command.d.ts.map +1 -1
  77. package/dist/adapters/hook-command.js +11 -0
  78. package/dist/adapters/hook-command.js.map +1 -1
  79. package/dist/adapters/hook-installer.d.ts +16 -1
  80. package/dist/adapters/hook-installer.d.ts.map +1 -1
  81. package/dist/adapters/hook-installer.js +232 -2
  82. package/dist/adapters/hook-installer.js.map +1 -1
  83. package/dist/bot-registry.d.ts +116 -8
  84. package/dist/bot-registry.d.ts.map +1 -1
  85. package/dist/bot-registry.js +52 -4
  86. package/dist/bot-registry.js.map +1 -1
  87. package/dist/cli/pm2-start-transaction.d.ts +14 -0
  88. package/dist/cli/pm2-start-transaction.d.ts.map +1 -1
  89. package/dist/cli/pm2-start-transaction.js +25 -9
  90. package/dist/cli/pm2-start-transaction.js.map +1 -1
  91. package/dist/cli/restart-failure-notification.d.ts +54 -0
  92. package/dist/cli/restart-failure-notification.d.ts.map +1 -0
  93. package/dist/cli/restart-failure-notification.js +142 -0
  94. package/dist/cli/restart-failure-notification.js.map +1 -0
  95. package/dist/cli/restart-failure-owner.d.ts +20 -0
  96. package/dist/cli/restart-failure-owner.d.ts.map +1 -0
  97. package/dist/cli/restart-failure-owner.js +27 -0
  98. package/dist/cli/restart-failure-owner.js.map +1 -0
  99. package/dist/cli/restart-shutdown-preflight.d.ts +24 -0
  100. package/dist/cli/restart-shutdown-preflight.d.ts.map +1 -0
  101. package/dist/cli/restart-shutdown-preflight.js +105 -0
  102. package/dist/cli/restart-shutdown-preflight.js.map +1 -0
  103. package/dist/cli/send-dispatch.d.ts +26 -0
  104. package/dist/cli/send-dispatch.d.ts.map +1 -1
  105. package/dist/cli/send-dispatch.js +30 -0
  106. package/dist/cli/send-dispatch.js.map +1 -1
  107. package/dist/cli.d.ts +4 -1
  108. package/dist/cli.d.ts.map +1 -1
  109. package/dist/cli.js +665 -399
  110. package/dist/cli.js.map +1 -1
  111. package/dist/codex-app-runner.js +38 -15
  112. package/dist/codex-app-runner.js.map +1 -1
  113. package/dist/codex-rpc-lifecycle.d.ts +14 -2
  114. package/dist/codex-rpc-lifecycle.d.ts.map +1 -1
  115. package/dist/codex-rpc-lifecycle.js +13 -3
  116. package/dist/codex-rpc-lifecycle.js.map +1 -1
  117. package/dist/core/ask-broker.d.ts +3 -0
  118. package/dist/core/ask-broker.d.ts.map +1 -1
  119. package/dist/core/ask-broker.js +29 -7
  120. package/dist/core/ask-broker.js.map +1 -1
  121. package/dist/core/ask-hook/registry.d.ts.map +1 -1
  122. package/dist/core/ask-hook/registry.js +4 -0
  123. package/dist/core/ask-hook/registry.js.map +1 -1
  124. package/dist/core/ask-types.d.ts +5 -1
  125. package/dist/core/ask-types.d.ts.map +1 -1
  126. package/dist/core/ask-types.js.map +1 -1
  127. package/dist/core/browser-restart.d.ts +112 -0
  128. package/dist/core/browser-restart.d.ts.map +1 -0
  129. package/dist/core/browser-restart.js +233 -0
  130. package/dist/core/browser-restart.js.map +1 -0
  131. package/dist/core/command-handler.d.ts +19 -11
  132. package/dist/core/command-handler.d.ts.map +1 -1
  133. package/dist/core/command-handler.js +237 -43
  134. package/dist/core/command-handler.js.map +1 -1
  135. package/dist/core/current-turn-provenance.d.ts.map +1 -1
  136. package/dist/core/current-turn-provenance.js +7 -27
  137. package/dist/core/current-turn-provenance.js.map +1 -1
  138. package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
  139. package/dist/core/dashboard-ipc-server.js +317 -10
  140. package/dist/core/dashboard-ipc-server.js.map +1 -1
  141. package/dist/core/dispatch-registry.d.ts.map +1 -1
  142. package/dist/core/dispatch-registry.js +6 -0
  143. package/dist/core/dispatch-registry.js.map +1 -1
  144. package/dist/core/dispatch-report-binding.d.ts +31 -0
  145. package/dist/core/dispatch-report-binding.d.ts.map +1 -0
  146. package/dist/core/dispatch-report-binding.js +88 -0
  147. package/dist/core/dispatch-report-binding.js.map +1 -0
  148. package/dist/core/doc-comment-prompt.d.ts +2 -0
  149. package/dist/core/doc-comment-prompt.d.ts.map +1 -1
  150. package/dist/core/doc-comment-prompt.js +6 -0
  151. package/dist/core/doc-comment-prompt.js.map +1 -1
  152. package/dist/core/host-overload-alert.d.ts +25 -1
  153. package/dist/core/host-overload-alert.d.ts.map +1 -1
  154. package/dist/core/host-overload-alert.js +69 -8
  155. package/dist/core/host-overload-alert.js.map +1 -1
  156. package/dist/core/local-terminal-opener.js +1 -1
  157. package/dist/core/local-terminal-opener.js.map +1 -1
  158. package/dist/core/managed-origin-capability.d.ts +7 -6
  159. package/dist/core/managed-origin-capability.d.ts.map +1 -1
  160. package/dist/core/managed-origin-capability.js +32 -1
  161. package/dist/core/managed-origin-capability.js.map +1 -1
  162. package/dist/core/passthrough-commands.d.ts.map +1 -1
  163. package/dist/core/passthrough-commands.js +3 -2
  164. package/dist/core/passthrough-commands.js.map +1 -1
  165. package/dist/core/plugins/materializer.d.ts.map +1 -1
  166. package/dist/core/plugins/materializer.js +1 -0
  167. package/dist/core/plugins/materializer.js.map +1 -1
  168. package/dist/core/producer-quiescence.d.ts +70 -0
  169. package/dist/core/producer-quiescence.d.ts.map +1 -0
  170. package/dist/core/producer-quiescence.js +90 -0
  171. package/dist/core/producer-quiescence.js.map +1 -0
  172. package/dist/core/raw-command-write-options.d.ts +10 -0
  173. package/dist/core/raw-command-write-options.d.ts.map +1 -0
  174. package/dist/core/raw-command-write-options.js +23 -0
  175. package/dist/core/raw-command-write-options.js.map +1 -0
  176. package/dist/core/raw-command-writer.d.ts +4 -0
  177. package/dist/core/raw-command-writer.d.ts.map +1 -1
  178. package/dist/core/raw-command-writer.js +15 -6
  179. package/dist/core/raw-command-writer.js.map +1 -1
  180. package/dist/core/reply-target.d.ts +11 -0
  181. package/dist/core/reply-target.d.ts.map +1 -1
  182. package/dist/core/reply-target.js +22 -7
  183. package/dist/core/reply-target.js.map +1 -1
  184. package/dist/core/report-session-relay.d.ts +53 -0
  185. package/dist/core/report-session-relay.d.ts.map +1 -0
  186. package/dist/core/report-session-relay.js +116 -0
  187. package/dist/core/report-session-relay.js.map +1 -0
  188. package/dist/core/session-discovery.d.ts +5 -0
  189. package/dist/core/session-discovery.d.ts.map +1 -1
  190. package/dist/core/session-discovery.js +13 -0
  191. package/dist/core/session-discovery.js.map +1 -1
  192. package/dist/core/session-group-birth.d.ts +7 -0
  193. package/dist/core/session-group-birth.d.ts.map +1 -0
  194. package/dist/core/session-group-birth.js +145 -0
  195. package/dist/core/session-group-birth.js.map +1 -0
  196. package/dist/core/session-manager.d.ts +16 -21
  197. package/dist/core/session-manager.d.ts.map +1 -1
  198. package/dist/core/session-manager.js +140 -21
  199. package/dist/core/session-manager.js.map +1 -1
  200. package/dist/core/trigger-session.d.ts.map +1 -1
  201. package/dist/core/trigger-session.js +18 -3
  202. package/dist/core/trigger-session.js.map +1 -1
  203. package/dist/core/types.d.ts +18 -0
  204. package/dist/core/types.d.ts.map +1 -1
  205. package/dist/core/types.js.map +1 -1
  206. package/dist/core/worker-pool.d.ts +63 -11
  207. package/dist/core/worker-pool.d.ts.map +1 -1
  208. package/dist/core/worker-pool.js +241 -13
  209. package/dist/core/worker-pool.js.map +1 -1
  210. package/dist/daemon.d.ts +33 -0
  211. package/dist/daemon.d.ts.map +1 -1
  212. package/dist/daemon.js +900 -137
  213. package/dist/daemon.js.map +1 -1
  214. package/dist/dashboard/auth.d.ts +20 -0
  215. package/dist/dashboard/auth.d.ts.map +1 -1
  216. package/dist/dashboard/auth.js +86 -1
  217. package/dist/dashboard/auth.js.map +1 -1
  218. package/dist/dashboard/bot-payload.d.ts +5 -0
  219. package/dist/dashboard/bot-payload.d.ts.map +1 -1
  220. package/dist/dashboard/bot-payload.js +4 -1
  221. package/dist/dashboard/bot-payload.js.map +1 -1
  222. package/dist/dashboard/federation-spoke-api.d.ts.map +1 -1
  223. package/dist/dashboard/federation-spoke-api.js +27 -3
  224. package/dist/dashboard/federation-spoke-api.js.map +1 -1
  225. package/dist/dashboard/feedback-analytics-api.d.ts +6 -0
  226. package/dist/dashboard/feedback-analytics-api.d.ts.map +1 -0
  227. package/dist/dashboard/feedback-analytics-api.js +39 -0
  228. package/dist/dashboard/feedback-analytics-api.js.map +1 -0
  229. package/dist/dashboard/session-action-timeout.d.ts +3 -0
  230. package/dist/dashboard/session-action-timeout.d.ts.map +1 -0
  231. package/dist/dashboard/session-action-timeout.js +12 -0
  232. package/dist/dashboard/session-action-timeout.js.map +1 -0
  233. package/dist/dashboard/vc-consumer-profiles-api.d.ts +9 -3
  234. package/dist/dashboard/vc-consumer-profiles-api.d.ts.map +1 -1
  235. package/dist/dashboard/vc-consumer-profiles-api.js +2 -1
  236. package/dist/dashboard/vc-consumer-profiles-api.js.map +1 -1
  237. package/dist/dashboard/web/app.d.ts.map +1 -1
  238. package/dist/dashboard/web/app.js +48 -5
  239. package/dist/dashboard/web/app.js.map +1 -1
  240. package/dist/dashboard/web/bot-defaults-page.d.ts +4 -0
  241. package/dist/dashboard/web/bot-defaults-page.d.ts.map +1 -1
  242. package/dist/dashboard/web/bot-defaults-page.js +273 -36
  243. package/dist/dashboard/web/bot-defaults-page.js.map +1 -1
  244. package/dist/dashboard/web/bot-defaults.d.ts +6 -0
  245. package/dist/dashboard/web/bot-defaults.d.ts.map +1 -1
  246. package/dist/dashboard/web/bot-defaults.js.map +1 -1
  247. package/dist/dashboard/web/dashboard-routes.d.ts.map +1 -1
  248. package/dist/dashboard/web/dashboard-routes.js +1 -0
  249. package/dist/dashboard/web/dashboard-routes.js.map +1 -1
  250. package/dist/dashboard/web/feedback-page.d.ts +3 -0
  251. package/dist/dashboard/web/feedback-page.d.ts.map +1 -0
  252. package/dist/dashboard/web/feedback-page.js +34 -0
  253. package/dist/dashboard/web/feedback-page.js.map +1 -0
  254. package/dist/dashboard/web/groups-page.d.ts.map +1 -1
  255. package/dist/dashboard/web/groups-page.js +7 -2
  256. package/dist/dashboard/web/groups-page.js.map +1 -1
  257. package/dist/dashboard/web/i18n.d.ts.map +1 -1
  258. package/dist/dashboard/web/i18n.js +114 -22
  259. package/dist/dashboard/web/i18n.js.map +1 -1
  260. package/dist/dashboard/web/team-federation-page.d.ts.map +1 -1
  261. package/dist/dashboard/web/team-federation-page.js +26 -2
  262. package/dist/dashboard/web/team-federation-page.js.map +1 -1
  263. package/dist/dashboard/web/team-federation.d.ts +19 -0
  264. package/dist/dashboard/web/team-federation.d.ts.map +1 -1
  265. package/dist/dashboard/web/team-federation.js +3 -0
  266. package/dist/dashboard/web/team-federation.js.map +1 -1
  267. package/dist/dashboard/web/update-action.d.ts +8 -0
  268. package/dist/dashboard/web/update-action.d.ts.map +1 -1
  269. package/dist/dashboard/web/update-action.js +10 -0
  270. package/dist/dashboard/web/update-action.js.map +1 -1
  271. package/dist/dashboard/web/vc-consumer-profiles-section.d.ts.map +1 -1
  272. package/dist/dashboard/web/vc-consumer-profiles-section.js +58 -9
  273. package/dist/dashboard/web/vc-consumer-profiles-section.js.map +1 -1
  274. package/dist/dashboard-web/app.js +1 -1
  275. package/dist/dashboard-web/chunks/bot-defaults-page-4RENHE7J.js +10 -0
  276. package/dist/dashboard-web/chunks/chunk-2WQDS65D.js +1 -0
  277. package/dist/dashboard-web/chunks/{chunk-CU4SUKK3.js → chunk-6O7KXFD2.js} +1 -1
  278. package/dist/dashboard-web/chunks/chunk-G5XGBCM6.js +1 -0
  279. package/dist/dashboard-web/chunks/{chunk-6JTZJRQJ.js → chunk-Q2MT4VWH.js} +15 -15
  280. package/dist/dashboard-web/chunks/{chunk-5QJB24I2.js → chunk-U3ZFSO7E.js} +1 -1
  281. package/dist/dashboard-web/chunks/connectors-page-2KZO5KSJ.js +1 -0
  282. package/dist/dashboard-web/chunks/feedback-page-CLVTOLLO.js +1 -0
  283. package/dist/dashboard-web/chunks/groups-page-HLASRTSY.js +8 -0
  284. package/dist/dashboard-web/chunks/{insights-page-EVGGJI5L.js → insights-page-4RPU2CRU.js} +1 -1
  285. package/dist/dashboard-web/chunks/{monitor-room-HRGR2ENP.js → monitor-room-OTKQ2CXK.js} +1 -1
  286. package/dist/dashboard-web/chunks/monitoring-page-IJPUB6JT.js +2 -0
  287. package/dist/dashboard-web/chunks/office-page-QSR3J44Y.js +1 -0
  288. package/dist/dashboard-web/chunks/overview-page-6OK63V4V.js +1 -0
  289. package/dist/dashboard-web/chunks/roles-page-6NWJMOB5.js +1 -0
  290. package/dist/dashboard-web/chunks/schedules-page-6I3LNXD4.js +1 -0
  291. package/dist/dashboard-web/chunks/{sessions-page-DXBCDWCS.js → sessions-page-B2TXGJDO.js} +1 -1
  292. package/dist/dashboard-web/chunks/settings-page-6KJADSC6.js +2 -0
  293. package/dist/dashboard-web/chunks/{skills-page-2QAVB2SA.js → skills-page-M2Q6L5CB.js} +1 -1
  294. package/dist/dashboard-web/chunks/team-federation-page-7I7FDE3B.js +1 -0
  295. package/dist/dashboard-web/chunks/{v3-page-AY35LKCX.js → v3-page-HQXRL65L.js} +1 -1
  296. package/dist/dashboard-web/chunks/whiteboards-page-LQKC4TAZ.js +1 -0
  297. package/dist/dashboard-web/style.css +35 -0
  298. package/dist/dashboard.js +199 -12
  299. package/dist/dashboard.js.map +1 -1
  300. package/dist/desktop/shared/shell-path-probes.d.ts +1 -1
  301. package/dist/desktop/shared/shell-path-probes.js +2 -2
  302. package/dist/desktop/shared/shell-path-probes.js.map +1 -1
  303. package/dist/dsh-runner.d.ts +3 -0
  304. package/dist/dsh-runner.d.ts.map +1 -0
  305. package/dist/dsh-runner.js +666 -0
  306. package/dist/dsh-runner.js.map +1 -0
  307. package/dist/global-config.d.ts +24 -0
  308. package/dist/global-config.d.ts.map +1 -1
  309. package/dist/global-config.js +35 -0
  310. package/dist/global-config.js.map +1 -1
  311. package/dist/i18n/en.d.ts.map +1 -1
  312. package/dist/i18n/en.js +25 -6
  313. package/dist/i18n/en.js.map +1 -1
  314. package/dist/i18n/zh.d.ts.map +1 -1
  315. package/dist/i18n/zh.js +25 -6
  316. package/dist/i18n/zh.js.map +1 -1
  317. package/dist/im/lark/ask-card.d.ts +3 -1
  318. package/dist/im/lark/ask-card.d.ts.map +1 -1
  319. package/dist/im/lark/ask-card.js +61 -5
  320. package/dist/im/lark/ask-card.js.map +1 -1
  321. package/dist/im/lark/card-builder.d.ts.map +1 -1
  322. package/dist/im/lark/card-builder.js +13 -6
  323. package/dist/im/lark/card-builder.js.map +1 -1
  324. package/dist/im/lark/card-handler.d.ts +2 -1
  325. package/dist/im/lark/card-handler.d.ts.map +1 -1
  326. package/dist/im/lark/card-handler.js +145 -5
  327. package/dist/im/lark/card-handler.js.map +1 -1
  328. package/dist/im/lark/event-dispatcher.d.ts +18 -0
  329. package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
  330. package/dist/im/lark/event-dispatcher.js +36 -9
  331. package/dist/im/lark/event-dispatcher.js.map +1 -1
  332. package/dist/im/lark/md-card.d.ts +18 -0
  333. package/dist/im/lark/md-card.d.ts.map +1 -1
  334. package/dist/im/lark/md-card.js +21 -0
  335. package/dist/im/lark/md-card.js.map +1 -1
  336. package/dist/im/lark/relay-target-routing.d.ts.map +1 -1
  337. package/dist/im/lark/relay-target-routing.js +3 -2
  338. package/dist/im/lark/relay-target-routing.js.map +1 -1
  339. package/dist/im/lark/reply-mode-command.d.ts.map +1 -1
  340. package/dist/im/lark/reply-mode-command.js +19 -8
  341. package/dist/im/lark/reply-mode-command.js.map +1 -1
  342. package/dist/im/lark/skill-feedback-card.d.ts +15 -0
  343. package/dist/im/lark/skill-feedback-card.d.ts.map +1 -0
  344. package/dist/im/lark/skill-feedback-card.js +149 -0
  345. package/dist/im/lark/skill-feedback-card.js.map +1 -0
  346. package/dist/services/bot-config-store.d.ts +10 -1
  347. package/dist/services/bot-config-store.d.ts.map +1 -1
  348. package/dist/services/bot-config-store.js +103 -3
  349. package/dist/services/bot-config-store.js.map +1 -1
  350. package/dist/services/bridge-fallback-gate.d.ts +14 -0
  351. package/dist/services/bridge-fallback-gate.d.ts.map +1 -1
  352. package/dist/services/bridge-fallback-gate.js +15 -0
  353. package/dist/services/bridge-fallback-gate.js.map +1 -1
  354. package/dist/services/codex-reasoning-effort.d.ts +9 -0
  355. package/dist/services/codex-reasoning-effort.d.ts.map +1 -0
  356. package/dist/services/codex-reasoning-effort.js +23 -0
  357. package/dist/services/codex-reasoning-effort.js.map +1 -0
  358. package/dist/services/codex-service-tier.d.ts +1 -1
  359. package/dist/services/codex-service-tier.d.ts.map +1 -1
  360. package/dist/services/codex-transcript.d.ts +9 -0
  361. package/dist/services/codex-transcript.d.ts.map +1 -1
  362. package/dist/services/codex-transcript.js +13 -6
  363. package/dist/services/codex-transcript.js.map +1 -1
  364. package/dist/services/feed-group-tagger.d.ts +15 -0
  365. package/dist/services/feed-group-tagger.d.ts.map +1 -0
  366. package/dist/services/feed-group-tagger.js +348 -0
  367. package/dist/services/feed-group-tagger.js.map +1 -0
  368. package/dist/services/feedback-analytics.d.ts +82 -0
  369. package/dist/services/feedback-analytics.d.ts.map +1 -0
  370. package/dist/services/feedback-analytics.js +95 -0
  371. package/dist/services/feedback-analytics.js.map +1 -0
  372. package/dist/services/feedback-outbox.d.ts +24 -0
  373. package/dist/services/feedback-outbox.d.ts.map +1 -0
  374. package/dist/services/feedback-outbox.js +12 -0
  375. package/dist/services/feedback-outbox.js.map +1 -0
  376. package/dist/services/feedback-policy-resolver.d.ts +56 -0
  377. package/dist/services/feedback-policy-resolver.d.ts.map +1 -0
  378. package/dist/services/feedback-policy-resolver.js +156 -0
  379. package/dist/services/feedback-policy-resolver.js.map +1 -0
  380. package/dist/services/feedback-policy.d.ts +41 -0
  381. package/dist/services/feedback-policy.d.ts.map +1 -0
  382. package/dist/services/feedback-policy.js +102 -0
  383. package/dist/services/feedback-policy.js.map +1 -0
  384. package/dist/services/feedback-webhook-dispatcher.d.ts +76 -0
  385. package/dist/services/feedback-webhook-dispatcher.d.ts.map +1 -0
  386. package/dist/services/feedback-webhook-dispatcher.js +237 -0
  387. package/dist/services/feedback-webhook-dispatcher.js.map +1 -0
  388. package/dist/services/grant-prefs-store.d.ts +3 -0
  389. package/dist/services/grant-prefs-store.d.ts.map +1 -1
  390. package/dist/services/grant-prefs-store.js +30 -1
  391. package/dist/services/grant-prefs-store.js.map +1 -1
  392. package/dist/services/groups-store.d.ts +14 -0
  393. package/dist/services/groups-store.d.ts.map +1 -1
  394. package/dist/services/groups-store.js +23 -0
  395. package/dist/services/groups-store.js.map +1 -1
  396. package/dist/services/local-cli-opener.d.ts +1 -1
  397. package/dist/services/local-cli-opener.d.ts.map +1 -1
  398. package/dist/services/local-cli-opener.js +2 -0
  399. package/dist/services/local-cli-opener.js.map +1 -1
  400. package/dist/services/prompt-context-store.d.ts +29 -0
  401. package/dist/services/prompt-context-store.d.ts.map +1 -0
  402. package/dist/services/prompt-context-store.js +205 -0
  403. package/dist/services/prompt-context-store.js.map +1 -0
  404. package/dist/services/session-group-avatar.d.ts +6 -0
  405. package/dist/services/session-group-avatar.d.ts.map +1 -0
  406. package/dist/services/session-group-avatar.js +96 -0
  407. package/dist/services/session-group-avatar.js.map +1 -0
  408. package/dist/services/session-group-title.d.ts +47 -0
  409. package/dist/services/session-group-title.d.ts.map +1 -0
  410. package/dist/services/session-group-title.js +226 -0
  411. package/dist/services/session-group-title.js.map +1 -0
  412. package/dist/services/session-groups-store.d.ts +30 -0
  413. package/dist/services/session-groups-store.d.ts.map +1 -0
  414. package/dist/services/session-groups-store.js +132 -0
  415. package/dist/services/session-groups-store.js.map +1 -0
  416. package/dist/services/session-store.d.ts +58 -0
  417. package/dist/services/session-store.d.ts.map +1 -1
  418. package/dist/services/session-store.js +174 -0
  419. package/dist/services/session-store.js.map +1 -1
  420. package/dist/services/skill-feedback-store.d.ts +252 -0
  421. package/dist/services/skill-feedback-store.d.ts.map +1 -0
  422. package/dist/services/skill-feedback-store.js +795 -0
  423. package/dist/services/skill-feedback-store.js.map +1 -0
  424. package/dist/services/skill-registry-store.d.ts +23 -0
  425. package/dist/services/skill-registry-store.d.ts.map +1 -1
  426. package/dist/services/skill-registry-store.js +93 -7
  427. package/dist/services/skill-registry-store.js.map +1 -1
  428. package/dist/services/team-store.d.ts +4 -0
  429. package/dist/services/team-store.d.ts.map +1 -1
  430. package/dist/services/team-store.js +16 -0
  431. package/dist/services/team-store.js.map +1 -1
  432. package/dist/services/traex-transcript.d.ts +32 -4
  433. package/dist/services/traex-transcript.d.ts.map +1 -1
  434. package/dist/services/traex-transcript.js +116 -8
  435. package/dist/services/traex-transcript.js.map +1 -1
  436. package/dist/services/trigger-types.d.ts +1 -1
  437. package/dist/services/trigger-types.d.ts.map +1 -1
  438. package/dist/services/trigger-types.js +2 -2
  439. package/dist/services/trigger-types.js.map +1 -1
  440. package/dist/services/turn-completion-events.d.ts +57 -0
  441. package/dist/services/turn-completion-events.d.ts.map +1 -0
  442. package/dist/services/turn-completion-events.js +179 -0
  443. package/dist/services/turn-completion-events.js.map +1 -0
  444. package/dist/services/vc-meeting-consumer-isolation.d.ts +21 -12
  445. package/dist/services/vc-meeting-consumer-isolation.d.ts.map +1 -1
  446. package/dist/services/vc-meeting-consumer-isolation.js +25 -19
  447. package/dist/services/vc-meeting-consumer-isolation.js.map +1 -1
  448. package/dist/services/vc-meeting-consumer-profile-bootstrap.d.ts +8 -2
  449. package/dist/services/vc-meeting-consumer-profile-bootstrap.d.ts.map +1 -1
  450. package/dist/services/vc-meeting-consumer-profile-bootstrap.js +18 -10
  451. package/dist/services/vc-meeting-consumer-profile-bootstrap.js.map +1 -1
  452. package/dist/setup/bot-config-editor.d.ts.map +1 -1
  453. package/dist/setup/bot-config-editor.js +6 -0
  454. package/dist/setup/bot-config-editor.js.map +1 -1
  455. package/dist/setup/cli-availability.d.ts +2 -1
  456. package/dist/setup/cli-availability.d.ts.map +1 -1
  457. package/dist/setup/cli-availability.js +2 -1
  458. package/dist/setup/cli-availability.js.map +1 -1
  459. package/dist/setup/cli-selection.d.ts +8 -0
  460. package/dist/setup/cli-selection.d.ts.map +1 -1
  461. package/dist/setup/cli-selection.js +31 -0
  462. package/dist/setup/cli-selection.js.map +1 -1
  463. package/dist/setup/ensure-fonts.d.ts +5 -0
  464. package/dist/setup/ensure-fonts.d.ts.map +1 -1
  465. package/dist/setup/ensure-fonts.js +26 -1
  466. package/dist/setup/ensure-fonts.js.map +1 -1
  467. package/dist/setup/lark-scopes.json +3 -1
  468. package/dist/setup/open-platform-automation.d.ts +1 -1
  469. package/dist/setup/open-platform-automation.d.ts.map +1 -1
  470. package/dist/setup/open-platform-automation.js +15 -3
  471. package/dist/setup/open-platform-automation.js.map +1 -1
  472. package/dist/skills/definitions.d.ts +1 -1
  473. package/dist/skills/definitions.d.ts.map +1 -1
  474. package/dist/skills/definitions.js +9 -2
  475. package/dist/skills/definitions.js.map +1 -1
  476. package/dist/types.d.ts +10 -4
  477. package/dist/types.d.ts.map +1 -1
  478. package/dist/utils/user-token.d.ts +38 -0
  479. package/dist/utils/user-token.d.ts.map +1 -1
  480. package/dist/utils/user-token.js +76 -1
  481. package/dist/utils/user-token.js.map +1 -1
  482. package/dist/utils/web-terminal-scroll.d.ts +27 -0
  483. package/dist/utils/web-terminal-scroll.d.ts.map +1 -0
  484. package/dist/utils/web-terminal-scroll.js +60 -0
  485. package/dist/utils/web-terminal-scroll.js.map +1 -0
  486. package/dist/vc-agent/polling-source.d.ts +70 -0
  487. package/dist/vc-agent/polling-source.d.ts.map +1 -1
  488. package/dist/vc-agent/polling-source.js +115 -0
  489. package/dist/vc-agent/polling-source.js.map +1 -1
  490. package/dist/worker.js +237 -76
  491. package/dist/worker.js.map +1 -1
  492. package/dist/workflows/definition.d.ts +22 -22
  493. package/dist/workflows/events/payloads.d.ts +8 -8
  494. package/dist/workflows/events/schema.d.ts +20 -20
  495. package/dist/workflows/migration/v2-run-archive-schema.d.ts +20 -20
  496. package/package.json +1 -1
  497. package/dist/dashboard-web/chunks/bot-defaults-page-NQJFJ45Z.js +0 -10
  498. package/dist/dashboard-web/chunks/chunk-KEEYQ3WF.js +0 -1
  499. package/dist/dashboard-web/chunks/connectors-page-HADHZXXZ.js +0 -1
  500. package/dist/dashboard-web/chunks/groups-page-5TYF46RS.js +0 -8
  501. package/dist/dashboard-web/chunks/monitoring-page-LBU7TTTW.js +0 -2
  502. package/dist/dashboard-web/chunks/office-page-DF6RRBMN.js +0 -1
  503. package/dist/dashboard-web/chunks/overview-page-ZB6QH2EX.js +0 -1
  504. package/dist/dashboard-web/chunks/roles-page-ZBZGHIIF.js +0 -1
  505. package/dist/dashboard-web/chunks/schedules-page-NQVQC3QY.js +0 -1
  506. package/dist/dashboard-web/chunks/settings-page-E7NN4NVQ.js +0 -2
  507. package/dist/dashboard-web/chunks/team-federation-page-VGWL53AE.js +0 -1
  508. package/dist/dashboard-web/chunks/whiteboards-page-BNWUU4KG.js +0 -1
@@ -24,6 +24,7 @@ import { fallbackTurnId, frozenReplyContextForTurn, isSubstituteTurn } from './r
24
24
  import { updateMessage, deleteMessage, sendEphemeralCard, sendUserMessage, addReaction, removeReaction, getMessageChatId, MessageWithdrawnError } from '../im/lark/client.js';
25
25
  import { buildStreamingCard, buildPrivateSnapshotCard, buildSessionCard, buildTuiPromptCard, buildTuiPromptResolvedCard, buildTuiPromptFailedCard, buildRelayedFrozenCard, getCliDisplayName } from '../im/lark/card-builder.js';
26
26
  import { codexServiceTierBadge } from '../services/codex-service-tier.js';
27
+ import { codexModelSupportsReasoningEffort, isCodexReasoningCliId } from '../services/codex-reasoning-effort.js';
27
28
  import { loadFrozenCards, saveFrozenCards } from '../services/frozen-card-store.js';
28
29
  import { hashUrlForLog } from '../adapters/backend/riff-backend.js';
29
30
  import { logger } from '../utils/logger.js';
@@ -33,7 +34,7 @@ import { traeHome } from '../services/traex-paths.js';
33
34
  import { botLocale, localeForBot, t as tr } from '../i18n/index.js';
34
35
  import { claudeJsonlPathForSession } from '../adapters/cli/claude-code.js';
35
36
  import { findUniqueClaudeSessionByCwd } from './session-discovery.js';
36
- import { buildMarkdownCard, buildContextualReplyCard, } from '../im/lark/md-card.js';
37
+ import { buildCanonicalFinalReplyCard, buildContextualReplyCard, } from '../im/lark/md-card.js';
37
38
  import { getSessionUsageSnapshot } from './cost-calculator.js';
38
39
  import { renderBrandTemplate } from '../im/lark/brand-template.js';
39
40
  import { replyToDocComment, chunkCommentText, unsubscribeDocFile, removeCommentReaction } from '../im/lark/doc-comment.js';
@@ -50,6 +51,7 @@ import { getBot, getAllBots, resolveBrandLabel, getLoadedConfigPath, getLoadedCo
50
51
  import { RestartCoordinator } from './restart-coordinator.js';
51
52
  import { runtimeBuildIdentity } from '../utils/runtime-build-id.js';
52
53
  import { scrubWorkflowWorkerEnv } from '../utils/child-env.js';
54
+ import { resolveFeedbackPolicyForDelivery, resolveFeedbackTeamId } from '../services/feedback-policy-resolver.js';
53
55
  /** A random id minted once per daemon process (this lifetime). Stamped onto
54
56
  * isolated persistent panes so a suspend→resume reattach (same id) is
55
57
  * distinguishable from a pane surviving a daemon restart (different id). */
@@ -743,6 +745,9 @@ function sessionAgentConfig(ds, botCfg) {
743
745
  ?? botCfg.cliPathOverride;
744
746
  ds.session.wrapperCli = ds.session.wrapperCli ?? botCfg.wrapperCli;
745
747
  ds.session.model = ds.session.model ?? botCfg.model;
748
+ ds.session.reasoningEffort = isCodexReasoningCliId(ds.session.cliId)
749
+ ? ds.session.reasoningEffort ?? botCfg.reasoningEffort
750
+ : undefined;
746
751
  ds.session.agentFrozen = true;
747
752
  sessionStore.updateSession(ds.session);
748
753
  }
@@ -774,6 +779,11 @@ function sessionAgentConfig(ds, botCfg) {
774
779
  if (repaired)
775
780
  sessionStore.updateSession(ds.session);
776
781
  }
782
+ if (ds.session.reasoningEffort
783
+ && !codexModelSupportsReasoningEffort(ds.session.model, ds.session.reasoningEffort)) {
784
+ ds.session.reasoningEffort = undefined;
785
+ sessionStore.updateSession(ds.session);
786
+ }
777
787
  return {
778
788
  cliId: ds.session.cliId ?? botCfg.cliId,
779
789
  cliRuntime: ds.session.cliRuntime,
@@ -807,7 +817,7 @@ function loadKnownBotOpenIdsForApp(larkAppId) {
807
817
  * mircli runner). They can't @-trigger a peer bot themselves, so for bot-to-bot
808
818
  * handoffs the fallback card must carry the real <at> back to the dispatcher. */
809
819
  function isRunnerDeliveryCli(cliId) {
810
- return cliId === 'mira' || cliId === 'mir';
820
+ return cliId === 'mira' || cliId === 'mir' || cliId === 'dsh';
811
821
  }
812
822
  function daemonCardFooterRecipientOpenId(ds, effectiveCliId) {
813
823
  const owner = ds.session.ownerOpenId;
@@ -1410,17 +1420,23 @@ export async function deliverSubstituteControlCard(ds) {
1410
1420
  * reply (`reply`). `content` is the card JSON when msgType==='interactive',
1411
1421
  * otherwise the plain text. Topic-group / p2p behavior is unchanged.
1412
1422
  *
1413
- * IMPORTANT: ephemeral is only attempted for flat **chat-scope** sessions. The
1423
+ * IMPORTANT: ephemeral is only attempted for a flat **chat-scope** destination. The
1414
1424
  * ephemeral API (`ephemeral/v1/send`) takes a `chat_id` only — it has no
1415
1425
  * thread/root anchoring — so for a **thread-scope** session (a 话题 inside a
1416
1426
  * 普通群, or a 话题群 topic) an ephemeral card would escape the topic and land at
1417
- * the group top-level. 话题群 happened to reject ephemeral with 18053 and fall
1418
- * back to the in-thread reply, but a 话题 inside a 普通群 succeeds and leaks the
1419
- * card out of the thread. So thread-scope sessions always take the visible
1420
- * `reply()` path, which routes back into the thread (`reply_in_thread`).
1427
+ * the group top-level. The same applies when a chat-scope session is invoked
1428
+ * from a folded thread: callers pass its frozen reply target, and any explicit
1429
+ * thread/quote destination takes the visible `reply()` path.
1421
1430
  */
1422
- export async function deliverEphemeralOrReply(ds, operatorOpenId, content, msgType, reply) {
1423
- if (operatorOpenId && ds.chatType !== 'p2p' && ds.scope === 'chat') {
1431
+ export async function deliverEphemeralOrReply(ds, operatorOpenId, content, msgType, reply, replyTarget) {
1432
+ // A chat-scope session can still be invoked from a folded thread. The
1433
+ // ephemeral API has no root/thread field, so an explicitly frozen thread or
1434
+ // quote target must take the visible reply path even though the session
1435
+ // itself remains chat-scoped.
1436
+ const allowsEphemeral = replyTarget
1437
+ ? replyTarget.mode === 'plain'
1438
+ : ds.scope === 'chat';
1439
+ if (operatorOpenId && ds.chatType !== 'p2p' && allowsEphemeral) {
1424
1440
  try {
1425
1441
  // The ephemeral API is card-only (msg_type=text → 10003), so wrap a plain
1426
1442
  // confirmation line into a minimal markdown card.
@@ -2369,6 +2385,30 @@ function reclaimParkedCrashDiagnostic(ds) {
2369
2385
  }
2370
2386
  catch { /* absent — benign */ }
2371
2387
  }
2388
+ /**
2389
+ * Consume a queued suspend claim once its goal state is reached.
2390
+ *
2391
+ * A claim only ever means "suspend the generation that is producing right now".
2392
+ * It is therefore consumed the moment that generation stops running, by ANY
2393
+ * route — the deferred checkpoint itself, a `/cd` or read-isolation switch that
2394
+ * suspended first, or an outright crash. Leaving it set is not a harmless
2395
+ * no-op: `runPendingSuspendIfSettled` fires on the NEXT generation's first
2396
+ * screen checkpoint, and its `ownsGeneration` predicate passes there (that
2397
+ * worker legitimately owns the session), so the replacement gets suspended for
2398
+ * a request that was never about it.
2399
+ *
2400
+ * The old code did have a "worker already gone → drop the flag" branch, but it
2401
+ * lived inside the checkpoint — which by definition stops running once the
2402
+ * session goes quiet. The clear needs to hang off the lifecycle events instead.
2403
+ */
2404
+ function clearPendingSuspendClaim(ds, why) {
2405
+ if (ds.pendingSuspendReason === undefined && ds.pendingSuspendGeneration === undefined)
2406
+ return;
2407
+ const reason = ds.pendingSuspendReason;
2408
+ ds.pendingSuspendReason = undefined;
2409
+ ds.pendingSuspendGeneration = undefined;
2410
+ logger.debug(`[${tag(ds)}] Cleared queued suspend claim (${reason ?? 'none'}): ${why}`);
2411
+ }
2372
2412
  export function suspendWorker(ds, reason = 'suspended_idle') {
2373
2413
  if (hasProtectedSessionMutationOwnership(ds)) {
2374
2414
  logger.warn(`[${tag(ds)}] Refused worker suspend (${reason}) while Codex App dispatch ownership is non-empty`);
@@ -2444,9 +2484,99 @@ export function suspendWorker(ds, reason = 'suspended_idle') {
2444
2484
  },
2445
2485
  });
2446
2486
  }
2487
+ // Goal state reached. Whoever queued a suspend for this generation got what
2488
+ // they asked for — including the paths that never touch the deferred
2489
+ // checkpoint (`/cd`, read-isolation switch, sweepIdleWorkers).
2490
+ clearPendingSuspendClaim(ds, `suspended (${reason})`);
2447
2491
  logger.info(`[${tag(ds)}] Worker + CLI suspended (${reason}); session stays active, cold-resumes from transcript on next message`);
2448
2492
  return true;
2449
2493
  }
2494
+ /**
2495
+ * Cash in a queued suspend. Called once the session leaves the producing states
2496
+ * it was queued for; a no-op during working/analyzing — that IS why it queued.
2497
+ *
2498
+ * Callers MUST defer this out of the status handler's synchronous body
2499
+ * (queueMicrotask) — suspendWorker clears `ds.worker` and `ds.lastScreenStatus`,
2500
+ * and the rest of that handler still reads both to record the usage delta, flip
2501
+ * the turn reaction ✋→✅, emit the state-transition hook, and render the final
2502
+ * card. Running it inline would skip exactly the turn-completion bookkeeping
2503
+ * this whole feature exists to protect.
2504
+ *
2505
+ * `ownsGeneration` is the calling handler's generation check (`ownsWorkerSession`),
2506
+ * and it is **defense-in-depth** — not a guard against a race anyone has shown to
2507
+ * be reachable today. Two earlier drafts of this comment each claimed a concrete
2508
+ * race; both were wrong, so the reasoning is spelled out here to stop a third:
2509
+ *
2510
+ * - It is NOT "a stale worker's late `idle` reaches `screenshot_uploaded`":
2511
+ * the message handler's fence (`if (ds.worker !== worker) return`) sits
2512
+ * BEFORE the switch and already drops every message from a replaced worker.
2513
+ * - It is NOT "two microtasks in one tick, the first suspends + re-forks and
2514
+ * the second meets the replacement": `suspendWorker` only nulls `ds.worker`,
2515
+ * it never re-forks (a re-fork is driven by external input, i.e. a later
2516
+ * MACROtask), and the microtask queue drains without letting one in. The
2517
+ * second microtask therefore sees `ds.worker === null` and this predicate
2518
+ * early-returns on that — a replacement is not what it meets.
2519
+ *
2520
+ * What it does buy: a queued callback can only ever act while its own generation
2521
+ * still owns the session. That keeps this deferral safe against future callers,
2522
+ * new synchronous side effects between enqueue and drain, and any path that
2523
+ * starts re-forking earlier than today. Consuming the claim is a destructive act
2524
+ * on a live worker, so it is worth gating even without a demonstrated race.
2525
+ * A checkpoint from a generation that no longer owns the session keeps the flag
2526
+ * pending; only the owning generation may consume it.
2527
+ *
2528
+ * Deliberately the generation check ALONE, not `ownsLifecycleMutation` (which
2529
+ * also folds in "not transferring"): a routing transfer is a temporary refusal,
2530
+ * not a lost claim, and it is suspendWorker's own guard to make. Screen updates
2531
+ * stop once a session sits quiet, so treating transfer as "not ours" would park
2532
+ * the flag with no later checkpoint to revive it — hence the explicit
2533
+ * transfer-settled retry below.
2534
+ */
2535
+ function runPendingSuspendIfSettled(ds, ownsGeneration) {
2536
+ const reason = ds.pendingSuspendReason;
2537
+ if (!reason)
2538
+ return;
2539
+ if (ownsGeneration && !ownsGeneration())
2540
+ return;
2541
+ // A claim belongs to the generation that was producing when it was queued.
2542
+ // Reaching a LATER generation means its own fulfilment checkpoint never ran
2543
+ // (crash, or another path suspended first) — consume it rather than suspend a
2544
+ // worker the request never asked about. clearPendingSuspendClaim covers the
2545
+ // normal exits; this is the backstop for a claim that slipped past them.
2546
+ if (ds.pendingSuspendGeneration !== undefined
2547
+ && ds.workerGeneration !== undefined
2548
+ && ds.pendingSuspendGeneration !== ds.workerGeneration) {
2549
+ clearPendingSuspendClaim(ds, 'generation changed');
2550
+ return;
2551
+ }
2552
+ const st = ds.lastScreenStatus;
2553
+ if (st !== 'idle' && st !== 'limited')
2554
+ return;
2555
+ // Worker already gone (crash / suspended by another path): the goal state is
2556
+ // reached, so drop the flag. Falling through to suspendWorker would take its
2557
+ // no-worker branch and clear managedTurnOrigin/workerReady for a generation
2558
+ // this queued request never owned.
2559
+ if (!ds.worker || ds.worker.killed) {
2560
+ clearPendingSuspendClaim(ds, 'worker already gone');
2561
+ return;
2562
+ }
2563
+ // Clear only on success. suspendWorker refuses mid-routing-transfer (and for a
2564
+ // backend that stopped being suspendable), and that refusal is temporary —
2565
+ // eating the flag would silently drop the request until the next `suspend all`.
2566
+ if (suspendWorker(ds, reason)) {
2567
+ // suspendWorker already consumed the claim (goal state reached); logging
2568
+ // here keeps the "fulfilled by the deferred path" signal distinguishable
2569
+ // from a suspend that came from anywhere else.
2570
+ logger.info(`[${tag(ds)}] Deferred suspend fulfilled (${reason}) after turn completed`);
2571
+ return;
2572
+ }
2573
+ // Refused by an in-flight transfer: keeping the flag is not enough on its own.
2574
+ // A settled session emits no further screen updates, so there may be no next
2575
+ // checkpoint — re-run when the relay gate releases. Returns false when no
2576
+ // transfer is active (a non-transfer refusal, e.g. pty), which needs no retry.
2577
+ deferUntilSessionTransferSettled(ds, () => runPendingSuspendIfSettled(ds, ownsGeneration));
2578
+ }
2579
+ export const __testOnly_runPendingSuspendIfSettled = runPendingSuspendIfSettled;
2450
2580
  function armWorkerKillBackstop(w, label, sigtermMs = WORKER_SIGTERM_BACKSTOP_MS) {
2451
2581
  const sigterm = setTimeout(() => {
2452
2582
  if (w.exitCode === null && w.signalCode === null) {
@@ -4028,7 +4158,7 @@ export async function forkSession(sessionId, targetChatId, targetRootMessageId,
4028
4158
  // • model / reasoningEffort / cliPathOverride / wrapperCli / agentFrozen:
4029
4159
  // without these the child's sessionAgentConfig() sees !agentFrozen and
4030
4160
  // re-freezes from the CURRENT bot config, silently dropping any per-session
4031
- // /model or /effort override the source carried (reasoningEffort has no
4161
+ // model or effort override the source carried (reasoningEffort has no
4032
4162
  // botCfg fallback at all → drops to undefined). Copying the frozen tuple
4033
4163
  // keeps the clone's launch identity == the source's.
4034
4164
  // readIsolation is intentionally NOT copied: it is not a persisted Session
@@ -5523,6 +5653,8 @@ export function forkWorker(ds, promptInput, resumeOrTurnId = false) {
5523
5653
  });
5524
5654
  // Send init config — use per-bot settings
5525
5655
  const runtimeIdentity = runtimeBuildIdentity();
5656
+ const feedbackPolicy = resolveFeedbackPolicyForDelivery({ dataDir: config.session.dataDir, larkAppId: ds.larkAppId, chatId: ds.chatId, bot: botCfg });
5657
+ ds.feedbackPolicy = feedbackPolicy;
5526
5658
  initMsg = {
5527
5659
  type: 'init',
5528
5660
  sessionId: ds.session.sessionId,
@@ -5609,6 +5741,7 @@ export function forkWorker(ds, promptInput, resumeOrTurnId = false) {
5609
5741
  // Feishu (uploader/cred-write are also skipped downstream on the same test).
5610
5742
  larkAppSecret: larkTransportEnabled({ chatId: ds.chatId, apiOnly: botCfg.apiOnly }) ? botCfg.larkAppSecret : '',
5611
5743
  apiOnly: botCfg.apiOnly,
5744
+ feedback: feedbackPolicy,
5612
5745
  // Freeze the ACTUAL loaded bots-config path (getLoadedConfigPath) so a
5613
5746
  // no-transport worker's fs-policy denies it from a HOST-owned fact, not a
5614
5747
  // guess off BOTS_CONFIG env (which the agent could see/forge). When it lives
@@ -6583,6 +6716,11 @@ function setupWorkerHandlers(ds, worker, startupState = { ready: false, failureN
6583
6716
  updateUsageLimitState(ds, msg.usageLimit);
6584
6717
  ds.lastScreenContent = msg.content;
6585
6718
  ds.lastScreenStatus = (msg.usageLimit ?? ds.usageLimit) ? 'limited' : msg.status;
6719
+ // A suspend that arrived mid-turn parked itself here. Defer until this
6720
+ // screen_update has finished using process state — suspendWorker nulls
6721
+ // `worker` + `lastScreenStatus`, which everything below still reads
6722
+ // (usage ledger, turn reactions, transition hook, final card).
6723
+ queueMicrotask(() => runPendingSuspendIfSettled(ds, ownsWorkerSession));
6586
6724
  // State-boundary clear: the moment we leave `working` (→ idle/limited),
6587
6725
  // stop the periodic usage refresh immediately — BEFORE the aux-UI /
6588
6726
  // card-disabled / recovery early-breaks below, which would otherwise
@@ -6771,6 +6909,14 @@ function setupWorkerHandlers(ds, worker, startupState = { ready: false, failureN
6771
6909
  const prevStatus = ds.lastScreenStatus;
6772
6910
  updateUsageLimitState(ds, msg.usageLimit);
6773
6911
  ds.lastScreenStatus = (msg.usageLimit ?? ds.usageLimit) ? 'limited' : msg.status;
6912
+ // Same deferred-suspend checkpoint as the screen_update branch, and
6913
+ // deferred for the same reason (see runPendingSuspendIfSettled).
6914
+ // The predicate is defense-in-depth here: the handler's fence already
6915
+ // dropped every message from a replaced worker before the switch, so a
6916
+ // stale `idle` cannot reach this case at all. Passing it keeps the
6917
+ // deferred callback from acting on a generation that stopped owning the
6918
+ // session between enqueue and drain.
6919
+ queueMicrotask(() => runPendingSuspendIfSettled(ds, ownsWorkerSession));
6774
6920
  emitSessionStateTransitionHook(ds, prevStatus, ds.lastScreenStatus, {
6775
6921
  source: 'screenshot_uploaded',
6776
6922
  imageKey: msg.imageKey,
@@ -7538,12 +7684,13 @@ function setupWorkerHandlers(ds, worker, startupState = { ready: false, failureN
7538
7684
  logger.warn(`[${t}] Dropped managed_turn_origin with mismatched sessionId`);
7539
7685
  break;
7540
7686
  }
7541
- // macOS uses one stable per-session pathname visible inside Seatbelt.
7687
+ // Isolated children use one stable per-session pathname visible through
7688
+ // an exact Seatbelt/bwrap read carve-out.
7542
7689
  // Only the daemon handler for the CURRENT ChildProcess generation may
7543
7690
  // replace it. Stale workers can still emit IPC, but the identity guard
7544
7691
  // above drops them before filesystem mutation, so they cannot overwrite
7545
7692
  // a successor capability (or unlink it during teardown).
7546
- if (process.platform === 'darwin' && msg.originChannelId) {
7693
+ if (msg.originChannelId) {
7547
7694
  if (!/^[a-f0-9]{64}$/.test(msg.originChannelId)) {
7548
7695
  ds.managedTurnOrigin = undefined;
7549
7696
  logger.error(`[${t}] Refused managed origin publication with an invalid pane channel`);
@@ -7971,6 +8118,11 @@ function setupWorkerHandlers(ds, worker, startupState = { ready: false, failureN
7971
8118
  ds.worker = null;
7972
8119
  ds.workerReady = false;
7973
8120
  ds.workerPort = null;
8121
+ // A queued suspend for THIS generation is now moot — the worker it was
8122
+ // about is gone. Leaving it set would suspend the replacement on its
8123
+ // first idle (the deferred checkpoint's own "worker gone" branch cannot
8124
+ // help: it only runs on a screen update that will never arrive).
8125
+ clearPendingSuspendClaim(ds, 'worker exited');
7974
8126
  // Dead worker generation — stop the periodic usage refresh immediately
7975
8127
  // instead of waiting a tick for it to self-clear on !workerHasInitialized.
7976
8128
  clearUsageRefreshTimer(ds);
@@ -8038,6 +8190,25 @@ function setupWorkerHandlers(ds, worker, startupState = { ready: false, failureN
8038
8190
  // ─── Bridge final-output delivery (with retry) ──────────────────────────────
8039
8191
  const FINAL_OUTPUT_RETRY_BACKOFF_MS = [0, 5000, 15000]; // immediate, +5s, +15s
8040
8192
  const codexAppFinalSettlementInFlight = new Map();
8193
+ /**
8194
+ * Shutdown-only view of the in-flight Codex App final-settlement promises. Each
8195
+ * entry is a `deliverFinalOutput` awaited inside the IPC message handler that
8196
+ * has NOT yet reached its `cb.onTurnTerminal` call; a settlement resolving
8197
+ * enqueues the turn terminal. During graceful shutdown, after all worker IPC
8198
+ * channels have disconnected (so no NEW settlement can be created), the daemon
8199
+ * bounded-waits these to settle BEFORE closing the turn-terminal queue
8200
+ * admission — otherwise a settlement that resolves post-close would have its
8201
+ * terminal refused and lost. Returns a snapshot array (safe to Promise.all).
8202
+ */
8203
+ export function snapshotCodexAppFinalSettlements() {
8204
+ return [...codexAppFinalSettlementInFlight.values()];
8205
+ }
8206
+ /** Current in-flight Codex App final-settlement count. After all worker IPC has
8207
+ * disconnected the map cannot grow, so a re-read of 0 after awaiting the
8208
+ * snapshot confirms settlement quiescence. */
8209
+ export function codexAppFinalSettlementCount() {
8210
+ return codexAppFinalSettlementInFlight.size;
8211
+ }
8041
8212
  function finalOutputDedupeKey(ds, msg) {
8042
8213
  return `${msg.sessionId ?? ds.session.sessionId}:${msg.lastUuid || msg.turnId}`;
8043
8214
  }
@@ -8117,6 +8288,40 @@ async function finishTurnReactions(ds) {
8117
8288
  * same provider key; the daemon owns bounded transient retries. After 3 attempts we log
8118
8289
  * and give up — the user's answer is lost; better than leaking memory
8119
8290
  * via an unbounded retry loop. */
8291
+ async function persistFinalOutputFeedback(ds, msg, content, effectiveCliId, messageId, policy, baseCard, requesterSubjectId, webhookDestinations, logTag) {
8292
+ try {
8293
+ const { getSkillFeedbackStore } = await import('../services/skill-feedback-store.js');
8294
+ const feedbackStore = await getSkillFeedbackStore(config.session.dataDir);
8295
+ feedbackStore.recordTurnDelivery({
8296
+ botAppId: ds.larkAppId,
8297
+ sessionId: ds.session.sessionId,
8298
+ turnId: msg.turnId,
8299
+ nativeSessionId: msg.sourceHermesSessionId ?? ds.session.cliSessionId,
8300
+ platform: 'lark',
8301
+ platformAppId: ds.larkAppId,
8302
+ platformMessageId: messageId,
8303
+ chatId: ds.chatId,
8304
+ topicRootId: ds.session.rootMessageId,
8305
+ dispatchAttempt: msg.dispatchAttempt,
8306
+ content,
8307
+ cliId: effectiveCliId,
8308
+ cliVersion: ds.cliVersion,
8309
+ model: ds.session.model,
8310
+ reasoningEffort: ds.session.reasoningEffort,
8311
+ cardMode: 'feedback',
8312
+ status: 'delivered',
8313
+ usage: msg.usage,
8314
+ policy,
8315
+ baseCard,
8316
+ requesterSubjectId,
8317
+ webhookDestinations,
8318
+ context: { ...(resolveFeedbackTeamId({ dataDir: config.session.dataDir, chatId: ds.chatId }) ? { teamId: resolveFeedbackTeamId({ dataDir: config.session.dataDir, chatId: ds.chatId }) } : {}) },
8319
+ });
8320
+ }
8321
+ catch (error) {
8322
+ logger.warn(`[${logTag}] Failed to persist final-output feedback delivery: ${error instanceof Error ? error.message : String(error)}`);
8323
+ }
8324
+ }
8120
8325
  function deliverFinalOutput(ds, msg, t, attempt, onComplete, isStillOwned = () => true, frozenReplyTarget, frozenUsage) {
8121
8326
  if (!isStillOwned()) {
8122
8327
  onComplete?.(false);
@@ -8329,6 +8534,12 @@ function deliverFinalOutput(ds, msg, t, attempt, onComplete, isStillOwned = () =
8329
8534
  : imOrigin?.replyTargetSenderOpenId
8330
8535
  ?? daemonCardFooterRecipientOpenId(ds, effectiveCliId);
8331
8536
  const localHomeLinkMode = daemonCardLocalHomeLinkMode(ds);
8537
+ // forkWorker snapshots the effective policy for this worker lifetime.
8538
+ // Keep daemon fallback delivery aligned with the same frozen policy the
8539
+ // worker/Riff environment received; live config applies on the next fork.
8540
+ const feedbackPolicy = managedReceiver ? undefined : ds.feedbackPolicy;
8541
+ const feedbackRequesterSubjectId = recipientOpenId;
8542
+ const feedback = feedbackPolicy && feedbackRequesterSubjectId ? { policy: feedbackPolicy } : undefined;
8332
8543
  cardUsage ??= getDaemonReplyCardUsageSnapshot(ds, effectiveCliId);
8333
8544
  const cardJson = msg.kind === 'local-turn' || msg.kind === 'local-turn-headless'
8334
8545
  ? buildContextualReplyCard({
@@ -8344,8 +8555,19 @@ function deliverFinalOutput(ds, msg, t, attempt, onComplete, isStillOwned = () =
8344
8555
  workingDir: ds.workingDir,
8345
8556
  localHomeLinkMode,
8346
8557
  usage: cardUsage,
8558
+ ...(feedback ? { feedback } : {}),
8347
8559
  })
8348
- : buildMarkdownCard(safeAssistantText, recipientOpenId, renderBrandTemplate(resolveBrandLabel(ds.larkAppId), ds.workingDir), localeForBot(ds.larkAppId), ds.workingDir, localHomeLinkMode, cardUsage);
8560
+ : buildCanonicalFinalReplyCard({
8561
+ markdown: safeAssistantText,
8562
+ ...(feedback ? { feedback } : {}),
8563
+ recipientOpenId,
8564
+ brand: renderBrandTemplate(resolveBrandLabel(ds.larkAppId), ds.workingDir),
8565
+ locale: localeForBot(ds.larkAppId),
8566
+ workingDir: ds.workingDir,
8567
+ localHomeLinkMode,
8568
+ usage: cardUsage,
8569
+ });
8570
+ const baseFeedbackCard = feedback ? JSON.parse(cardJson) : undefined;
8349
8571
  const proposedOutput = {
8350
8572
  targetChatId: ds.chatId,
8351
8573
  ...(imOrigin ? { quoteTargetId: imOrigin.larkMessageId } : {}),
@@ -8421,6 +8643,9 @@ function deliverFinalOutput(ds, msg, t, attempt, onComplete, isStillOwned = () =
8421
8643
  };
8422
8644
  if (preparedListenerReply?.kind === 'succeeded' && preparedListenerReply.messageId) {
8423
8645
  recordPrimaryOutput(preparedListenerReply.messageId);
8646
+ if (feedbackPolicy && baseFeedbackCard) {
8647
+ await persistFinalOutputFeedback(ds, msg, safeAssistantText, effectiveCliId, preparedListenerReply.messageId, feedbackPolicy, baseFeedbackCard, feedbackRequesterSubjectId, getBot(ds.larkAppId).config.feedbackWebhooks?.destinations, t);
8648
+ }
8424
8649
  ds.lastBridgeEmittedUuid = finalOutputDedupeKey(ds, msg);
8425
8650
  logger.info(`[${t}] VC listener fallback replayed existing provider result `
8426
8651
  + `(turn ${msg.turnId.substring(0, 8)})`);
@@ -8471,6 +8696,9 @@ function deliverFinalOutput(ds, msg, t, attempt, onComplete, isStillOwned = () =
8471
8696
  }
8472
8697
  ds.lastBridgeEmittedUuid = finalOutputDedupeKey(ds, msg);
8473
8698
  logger.info(`[${t}] Bridge final_output forwarded (turn ${msg.turnId.substring(0, 8)}, ${msg.content.length} chars, kind=${msg.kind ?? 'bridge'}, attempt ${attempt + 1})`);
8699
+ if (feedbackPolicy && baseFeedbackCard && messageId) {
8700
+ await persistFinalOutputFeedback(ds, msg, safeAssistantText, effectiveCliId, messageId, feedbackPolicy, baseFeedbackCard, feedbackRequesterSubjectId, getBot(ds.larkAppId).config.feedbackWebhooks?.destinations, t);
8701
+ }
8474
8702
  onComplete?.(true);
8475
8703
  }
8476
8704
  catch (err) {