botmux 3.13.0 → 3.15.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 (541) 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 +34 -3
  27. package/dist/adapters/backend/tmux-pipe-backend.d.ts.map +1 -1
  28. package/dist/adapters/backend/tmux-pipe-backend.js +72 -9
  29. package/dist/adapters/backend/tmux-pipe-backend.js.map +1 -1
  30. package/dist/adapters/backend/types.d.ts +7 -0
  31. package/dist/adapters/backend/types.d.ts.map +1 -1
  32. package/dist/adapters/backend/types.js.map +1 -1
  33. package/dist/adapters/backend/zellij-backend.d.ts +2 -3
  34. package/dist/adapters/backend/zellij-backend.d.ts.map +1 -1
  35. package/dist/adapters/backend/zellij-backend.js +6 -13
  36. package/dist/adapters/backend/zellij-backend.js.map +1 -1
  37. package/dist/adapters/backend/zellij-observe-backend.d.ts +2 -1
  38. package/dist/adapters/backend/zellij-observe-backend.d.ts.map +1 -1
  39. package/dist/adapters/backend/zellij-observe-backend.js +6 -3
  40. package/dist/adapters/backend/zellij-observe-backend.js.map +1 -1
  41. package/dist/adapters/backend/zmx-backend.d.ts.map +1 -1
  42. package/dist/adapters/backend/zmx-backend.js +40 -18
  43. package/dist/adapters/backend/zmx-backend.js.map +1 -1
  44. package/dist/adapters/cli/claude-code.d.ts.map +1 -1
  45. package/dist/adapters/cli/claude-code.js +12 -1
  46. package/dist/adapters/cli/claude-code.js.map +1 -1
  47. package/dist/adapters/cli/codex.d.ts.map +1 -1
  48. package/dist/adapters/cli/codex.js +3 -2
  49. package/dist/adapters/cli/codex.js.map +1 -1
  50. package/dist/adapters/cli/cursor.d.ts.map +1 -1
  51. package/dist/adapters/cli/cursor.js +13 -1
  52. package/dist/adapters/cli/cursor.js.map +1 -1
  53. package/dist/adapters/cli/dsh.d.ts +4 -0
  54. package/dist/adapters/cli/dsh.d.ts.map +1 -0
  55. package/dist/adapters/cli/dsh.js +100 -0
  56. package/dist/adapters/cli/dsh.js.map +1 -0
  57. package/dist/adapters/cli/fs-policy.d.ts.map +1 -1
  58. package/dist/adapters/cli/fs-policy.js +5 -0
  59. package/dist/adapters/cli/fs-policy.js.map +1 -1
  60. package/dist/adapters/cli/opencode.d.ts +52 -1
  61. package/dist/adapters/cli/opencode.d.ts.map +1 -1
  62. package/dist/adapters/cli/opencode.js +117 -76
  63. package/dist/adapters/cli/opencode.js.map +1 -1
  64. package/dist/adapters/cli/opencode2.d.ts +4 -0
  65. package/dist/adapters/cli/opencode2.d.ts.map +1 -0
  66. package/dist/adapters/cli/opencode2.js +137 -0
  67. package/dist/adapters/cli/opencode2.js.map +1 -0
  68. package/dist/adapters/cli/pi.d.ts +14 -1
  69. package/dist/adapters/cli/pi.d.ts.map +1 -1
  70. package/dist/adapters/cli/pi.js +21 -1
  71. package/dist/adapters/cli/pi.js.map +1 -1
  72. package/dist/adapters/cli/read-isolation.d.ts +1 -1
  73. package/dist/adapters/cli/read-isolation.d.ts.map +1 -1
  74. package/dist/adapters/cli/read-isolation.js +5 -2
  75. package/dist/adapters/cli/read-isolation.js.map +1 -1
  76. package/dist/adapters/cli/registry.d.ts +7 -1
  77. package/dist/adapters/cli/registry.d.ts.map +1 -1
  78. package/dist/adapters/cli/registry.js +19 -6
  79. package/dist/adapters/cli/registry.js.map +1 -1
  80. package/dist/adapters/cli/shared-hints.d.ts.map +1 -1
  81. package/dist/adapters/cli/shared-hints.js +41 -23
  82. package/dist/adapters/cli/shared-hints.js.map +1 -1
  83. package/dist/adapters/cli/types.d.ts +28 -3
  84. package/dist/adapters/cli/types.d.ts.map +1 -1
  85. package/dist/adapters/hook-command.d.ts +8 -0
  86. package/dist/adapters/hook-command.d.ts.map +1 -1
  87. package/dist/adapters/hook-command.js +11 -0
  88. package/dist/adapters/hook-command.js.map +1 -1
  89. package/dist/adapters/hook-installer.d.ts +16 -1
  90. package/dist/adapters/hook-installer.d.ts.map +1 -1
  91. package/dist/adapters/hook-installer.js +232 -2
  92. package/dist/adapters/hook-installer.js.map +1 -1
  93. package/dist/bot-registry.d.ts +138 -8
  94. package/dist/bot-registry.d.ts.map +1 -1
  95. package/dist/bot-registry.js +76 -4
  96. package/dist/bot-registry.js.map +1 -1
  97. package/dist/cli/pm2-start-transaction.d.ts +14 -0
  98. package/dist/cli/pm2-start-transaction.d.ts.map +1 -1
  99. package/dist/cli/pm2-start-transaction.js +25 -9
  100. package/dist/cli/pm2-start-transaction.js.map +1 -1
  101. package/dist/cli/restart-failure-notification.d.ts +54 -0
  102. package/dist/cli/restart-failure-notification.d.ts.map +1 -0
  103. package/dist/cli/restart-failure-notification.js +142 -0
  104. package/dist/cli/restart-failure-notification.js.map +1 -0
  105. package/dist/cli/restart-failure-owner.d.ts +20 -0
  106. package/dist/cli/restart-failure-owner.d.ts.map +1 -0
  107. package/dist/cli/restart-failure-owner.js +27 -0
  108. package/dist/cli/restart-failure-owner.js.map +1 -0
  109. package/dist/cli/restart-shutdown-preflight.d.ts +24 -0
  110. package/dist/cli/restart-shutdown-preflight.d.ts.map +1 -0
  111. package/dist/cli/restart-shutdown-preflight.js +105 -0
  112. package/dist/cli/restart-shutdown-preflight.js.map +1 -0
  113. package/dist/cli/send-dispatch.d.ts +26 -0
  114. package/dist/cli/send-dispatch.d.ts.map +1 -1
  115. package/dist/cli/send-dispatch.js +30 -0
  116. package/dist/cli/send-dispatch.js.map +1 -1
  117. package/dist/cli.d.ts +4 -1
  118. package/dist/cli.d.ts.map +1 -1
  119. package/dist/cli.js +673 -402
  120. package/dist/cli.js.map +1 -1
  121. package/dist/codex-app-runner.js +38 -15
  122. package/dist/codex-app-runner.js.map +1 -1
  123. package/dist/codex-rpc-lifecycle.d.ts +14 -2
  124. package/dist/codex-rpc-lifecycle.d.ts.map +1 -1
  125. package/dist/codex-rpc-lifecycle.js +13 -3
  126. package/dist/codex-rpc-lifecycle.js.map +1 -1
  127. package/dist/core/ask-broker.d.ts +3 -0
  128. package/dist/core/ask-broker.d.ts.map +1 -1
  129. package/dist/core/ask-broker.js +29 -7
  130. package/dist/core/ask-broker.js.map +1 -1
  131. package/dist/core/ask-hook/registry.d.ts.map +1 -1
  132. package/dist/core/ask-hook/registry.js +4 -0
  133. package/dist/core/ask-hook/registry.js.map +1 -1
  134. package/dist/core/ask-types.d.ts +5 -1
  135. package/dist/core/ask-types.d.ts.map +1 -1
  136. package/dist/core/ask-types.js.map +1 -1
  137. package/dist/core/browser-restart.d.ts +112 -0
  138. package/dist/core/browser-restart.d.ts.map +1 -0
  139. package/dist/core/browser-restart.js +233 -0
  140. package/dist/core/browser-restart.js.map +1 -0
  141. package/dist/core/command-discovery.d.ts.map +1 -1
  142. package/dist/core/command-discovery.js +4 -1
  143. package/dist/core/command-discovery.js.map +1 -1
  144. package/dist/core/command-handler.d.ts +19 -11
  145. package/dist/core/command-handler.d.ts.map +1 -1
  146. package/dist/core/command-handler.js +237 -43
  147. package/dist/core/command-handler.js.map +1 -1
  148. package/dist/core/current-turn-provenance.d.ts.map +1 -1
  149. package/dist/core/current-turn-provenance.js +7 -27
  150. package/dist/core/current-turn-provenance.js.map +1 -1
  151. package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
  152. package/dist/core/dashboard-ipc-server.js +359 -11
  153. package/dist/core/dashboard-ipc-server.js.map +1 -1
  154. package/dist/core/dispatch-registry.d.ts.map +1 -1
  155. package/dist/core/dispatch-registry.js +6 -0
  156. package/dist/core/dispatch-registry.js.map +1 -1
  157. package/dist/core/dispatch-report-binding.d.ts +31 -0
  158. package/dist/core/dispatch-report-binding.d.ts.map +1 -0
  159. package/dist/core/dispatch-report-binding.js +88 -0
  160. package/dist/core/dispatch-report-binding.js.map +1 -0
  161. package/dist/core/doc-comment-prompt.d.ts +2 -0
  162. package/dist/core/doc-comment-prompt.d.ts.map +1 -1
  163. package/dist/core/doc-comment-prompt.js +6 -0
  164. package/dist/core/doc-comment-prompt.js.map +1 -1
  165. package/dist/core/host-overload-alert.d.ts +25 -1
  166. package/dist/core/host-overload-alert.d.ts.map +1 -1
  167. package/dist/core/host-overload-alert.js +69 -8
  168. package/dist/core/host-overload-alert.js.map +1 -1
  169. package/dist/core/local-terminal-opener.js +1 -1
  170. package/dist/core/local-terminal-opener.js.map +1 -1
  171. package/dist/core/managed-origin-capability.d.ts +7 -6
  172. package/dist/core/managed-origin-capability.d.ts.map +1 -1
  173. package/dist/core/managed-origin-capability.js +32 -1
  174. package/dist/core/managed-origin-capability.js.map +1 -1
  175. package/dist/core/passthrough-commands.d.ts.map +1 -1
  176. package/dist/core/passthrough-commands.js +3 -2
  177. package/dist/core/passthrough-commands.js.map +1 -1
  178. package/dist/core/plugins/materializer.d.ts.map +1 -1
  179. package/dist/core/plugins/materializer.js +1 -0
  180. package/dist/core/plugins/materializer.js.map +1 -1
  181. package/dist/core/producer-quiescence.d.ts +70 -0
  182. package/dist/core/producer-quiescence.d.ts.map +1 -0
  183. package/dist/core/producer-quiescence.js +90 -0
  184. package/dist/core/producer-quiescence.js.map +1 -0
  185. package/dist/core/raw-command-write-options.d.ts +10 -0
  186. package/dist/core/raw-command-write-options.d.ts.map +1 -0
  187. package/dist/core/raw-command-write-options.js +23 -0
  188. package/dist/core/raw-command-write-options.js.map +1 -0
  189. package/dist/core/raw-command-writer.d.ts +4 -0
  190. package/dist/core/raw-command-writer.d.ts.map +1 -1
  191. package/dist/core/raw-command-writer.js +15 -6
  192. package/dist/core/raw-command-writer.js.map +1 -1
  193. package/dist/core/reply-target.d.ts +11 -0
  194. package/dist/core/reply-target.d.ts.map +1 -1
  195. package/dist/core/reply-target.js +22 -7
  196. package/dist/core/reply-target.js.map +1 -1
  197. package/dist/core/report-session-relay.d.ts +53 -0
  198. package/dist/core/report-session-relay.d.ts.map +1 -0
  199. package/dist/core/report-session-relay.js +116 -0
  200. package/dist/core/report-session-relay.js.map +1 -0
  201. package/dist/core/session-discovery.d.ts +5 -0
  202. package/dist/core/session-discovery.d.ts.map +1 -1
  203. package/dist/core/session-discovery.js +13 -0
  204. package/dist/core/session-discovery.js.map +1 -1
  205. package/dist/core/session-group-birth.d.ts +7 -0
  206. package/dist/core/session-group-birth.d.ts.map +1 -0
  207. package/dist/core/session-group-birth.js +145 -0
  208. package/dist/core/session-group-birth.js.map +1 -0
  209. package/dist/core/session-manager.d.ts +16 -21
  210. package/dist/core/session-manager.d.ts.map +1 -1
  211. package/dist/core/session-manager.js +140 -21
  212. package/dist/core/session-manager.js.map +1 -1
  213. package/dist/core/skills/frontmatter.d.ts.map +1 -1
  214. package/dist/core/skills/frontmatter.js +6 -1
  215. package/dist/core/skills/frontmatter.js.map +1 -1
  216. package/dist/core/trigger-session.d.ts.map +1 -1
  217. package/dist/core/trigger-session.js +18 -3
  218. package/dist/core/trigger-session.js.map +1 -1
  219. package/dist/core/types.d.ts +18 -0
  220. package/dist/core/types.d.ts.map +1 -1
  221. package/dist/core/types.js.map +1 -1
  222. package/dist/core/worker-pool.d.ts +63 -11
  223. package/dist/core/worker-pool.d.ts.map +1 -1
  224. package/dist/core/worker-pool.js +262 -21
  225. package/dist/core/worker-pool.js.map +1 -1
  226. package/dist/daemon.d.ts +33 -0
  227. package/dist/daemon.d.ts.map +1 -1
  228. package/dist/daemon.js +904 -147
  229. package/dist/daemon.js.map +1 -1
  230. package/dist/dashboard/auth.d.ts +20 -0
  231. package/dist/dashboard/auth.d.ts.map +1 -1
  232. package/dist/dashboard/auth.js +86 -1
  233. package/dist/dashboard/auth.js.map +1 -1
  234. package/dist/dashboard/bot-payload.d.ts +9 -0
  235. package/dist/dashboard/bot-payload.d.ts.map +1 -1
  236. package/dist/dashboard/bot-payload.js +5 -1
  237. package/dist/dashboard/bot-payload.js.map +1 -1
  238. package/dist/dashboard/federation-spoke-api.d.ts.map +1 -1
  239. package/dist/dashboard/federation-spoke-api.js +27 -3
  240. package/dist/dashboard/federation-spoke-api.js.map +1 -1
  241. package/dist/dashboard/feedback-analytics-api.d.ts +6 -0
  242. package/dist/dashboard/feedback-analytics-api.d.ts.map +1 -0
  243. package/dist/dashboard/feedback-analytics-api.js +39 -0
  244. package/dist/dashboard/feedback-analytics-api.js.map +1 -0
  245. package/dist/dashboard/session-action-timeout.d.ts +3 -0
  246. package/dist/dashboard/session-action-timeout.d.ts.map +1 -0
  247. package/dist/dashboard/session-action-timeout.js +12 -0
  248. package/dist/dashboard/session-action-timeout.js.map +1 -0
  249. package/dist/dashboard/vc-consumer-profiles-api.d.ts +9 -3
  250. package/dist/dashboard/vc-consumer-profiles-api.d.ts.map +1 -1
  251. package/dist/dashboard/vc-consumer-profiles-api.js +2 -1
  252. package/dist/dashboard/vc-consumer-profiles-api.js.map +1 -1
  253. package/dist/dashboard/web/app.d.ts.map +1 -1
  254. package/dist/dashboard/web/app.js +48 -5
  255. package/dist/dashboard/web/app.js.map +1 -1
  256. package/dist/dashboard/web/bot-defaults-page.d.ts +11 -0
  257. package/dist/dashboard/web/bot-defaults-page.d.ts.map +1 -1
  258. package/dist/dashboard/web/bot-defaults-page.js +368 -36
  259. package/dist/dashboard/web/bot-defaults-page.js.map +1 -1
  260. package/dist/dashboard/web/bot-defaults.d.ts +8 -0
  261. package/dist/dashboard/web/bot-defaults.d.ts.map +1 -1
  262. package/dist/dashboard/web/bot-defaults.js.map +1 -1
  263. package/dist/dashboard/web/dashboard-routes.d.ts.map +1 -1
  264. package/dist/dashboard/web/dashboard-routes.js +1 -0
  265. package/dist/dashboard/web/dashboard-routes.js.map +1 -1
  266. package/dist/dashboard/web/feedback-page.d.ts +3 -0
  267. package/dist/dashboard/web/feedback-page.d.ts.map +1 -0
  268. package/dist/dashboard/web/feedback-page.js +34 -0
  269. package/dist/dashboard/web/feedback-page.js.map +1 -0
  270. package/dist/dashboard/web/groups-page.d.ts.map +1 -1
  271. package/dist/dashboard/web/groups-page.js +7 -2
  272. package/dist/dashboard/web/groups-page.js.map +1 -1
  273. package/dist/dashboard/web/i18n.d.ts.map +1 -1
  274. package/dist/dashboard/web/i18n.js +122 -22
  275. package/dist/dashboard/web/i18n.js.map +1 -1
  276. package/dist/dashboard/web/skills-page.d.ts.map +1 -1
  277. package/dist/dashboard/web/skills-page.js +4 -2
  278. package/dist/dashboard/web/skills-page.js.map +1 -1
  279. package/dist/dashboard/web/team-federation-page.d.ts.map +1 -1
  280. package/dist/dashboard/web/team-federation-page.js +26 -2
  281. package/dist/dashboard/web/team-federation-page.js.map +1 -1
  282. package/dist/dashboard/web/team-federation.d.ts +19 -0
  283. package/dist/dashboard/web/team-federation.d.ts.map +1 -1
  284. package/dist/dashboard/web/team-federation.js +3 -0
  285. package/dist/dashboard/web/team-federation.js.map +1 -1
  286. package/dist/dashboard/web/update-action.d.ts +8 -0
  287. package/dist/dashboard/web/update-action.d.ts.map +1 -1
  288. package/dist/dashboard/web/update-action.js +10 -0
  289. package/dist/dashboard/web/update-action.js.map +1 -1
  290. package/dist/dashboard/web/vc-consumer-profiles-section.d.ts.map +1 -1
  291. package/dist/dashboard/web/vc-consumer-profiles-section.js +58 -9
  292. package/dist/dashboard/web/vc-consumer-profiles-section.js.map +1 -1
  293. package/dist/dashboard-web/app.js +1 -1
  294. package/dist/dashboard-web/chunks/bot-defaults-page-65SMZ4QY.js +10 -0
  295. package/dist/dashboard-web/chunks/chunk-G5XGBCM6.js +1 -0
  296. package/dist/dashboard-web/chunks/chunk-IKN6WURK.js +1 -0
  297. package/dist/dashboard-web/chunks/{chunk-6JTZJRQJ.js → chunk-VMWNR3SV.js} +15 -15
  298. package/dist/dashboard-web/chunks/{chunk-CU4SUKK3.js → chunk-Z7B3E3US.js} +1 -1
  299. package/dist/dashboard-web/chunks/{chunk-5QJB24I2.js → chunk-Z7DO42GJ.js} +1 -1
  300. package/dist/dashboard-web/chunks/connectors-page-CPH6VVFY.js +1 -0
  301. package/dist/dashboard-web/chunks/feedback-page-J2FKQ3LK.js +1 -0
  302. package/dist/dashboard-web/chunks/groups-page-VDOOLS4M.js +8 -0
  303. package/dist/dashboard-web/chunks/{insights-page-EVGGJI5L.js → insights-page-A2LWTKJD.js} +1 -1
  304. package/dist/dashboard-web/chunks/{monitor-room-HRGR2ENP.js → monitor-room-2YR752E3.js} +1 -1
  305. package/dist/dashboard-web/chunks/monitoring-page-BGYSKZGM.js +2 -0
  306. package/dist/dashboard-web/chunks/office-page-ZZHTEAE4.js +1 -0
  307. package/dist/dashboard-web/chunks/overview-page-7NYPKQSB.js +1 -0
  308. package/dist/dashboard-web/chunks/roles-page-YUC4YLJG.js +1 -0
  309. package/dist/dashboard-web/chunks/schedules-page-2L2NKTDJ.js +1 -0
  310. package/dist/dashboard-web/chunks/{sessions-page-DXBCDWCS.js → sessions-page-DYZZMKFL.js} +1 -1
  311. package/dist/dashboard-web/chunks/settings-page-LIULUSMH.js +2 -0
  312. package/dist/dashboard-web/chunks/{skills-page-2QAVB2SA.js → skills-page-DQPBBI3T.js} +2 -2
  313. package/dist/dashboard-web/chunks/team-federation-page-LQKLDV4K.js +1 -0
  314. package/dist/dashboard-web/chunks/{v3-page-AY35LKCX.js → v3-page-RVKQIMAP.js} +1 -1
  315. package/dist/dashboard-web/chunks/whiteboards-page-S5K55HRZ.js +1 -0
  316. package/dist/dashboard-web/style.css +35 -0
  317. package/dist/dashboard.js +210 -13
  318. package/dist/dashboard.js.map +1 -1
  319. package/dist/desktop/shared/shell-path-probes.d.ts +1 -1
  320. package/dist/desktop/shared/shell-path-probes.js +2 -2
  321. package/dist/desktop/shared/shell-path-probes.js.map +1 -1
  322. package/dist/dsh-runner.d.ts +3 -0
  323. package/dist/dsh-runner.d.ts.map +1 -0
  324. package/dist/dsh-runner.js +673 -0
  325. package/dist/dsh-runner.js.map +1 -0
  326. package/dist/global-config.d.ts +24 -0
  327. package/dist/global-config.d.ts.map +1 -1
  328. package/dist/global-config.js +35 -0
  329. package/dist/global-config.js.map +1 -1
  330. package/dist/i18n/en.d.ts.map +1 -1
  331. package/dist/i18n/en.js +39 -31
  332. package/dist/i18n/en.js.map +1 -1
  333. package/dist/i18n/zh.d.ts.map +1 -1
  334. package/dist/i18n/zh.js +39 -31
  335. package/dist/i18n/zh.js.map +1 -1
  336. package/dist/im/lark/ask-card.d.ts +3 -1
  337. package/dist/im/lark/ask-card.d.ts.map +1 -1
  338. package/dist/im/lark/ask-card.js +61 -5
  339. package/dist/im/lark/ask-card.js.map +1 -1
  340. package/dist/im/lark/card-builder.d.ts.map +1 -1
  341. package/dist/im/lark/card-builder.js +13 -6
  342. package/dist/im/lark/card-builder.js.map +1 -1
  343. package/dist/im/lark/card-handler.d.ts +2 -1
  344. package/dist/im/lark/card-handler.d.ts.map +1 -1
  345. package/dist/im/lark/card-handler.js +145 -5
  346. package/dist/im/lark/card-handler.js.map +1 -1
  347. package/dist/im/lark/event-dispatcher.d.ts +18 -0
  348. package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
  349. package/dist/im/lark/event-dispatcher.js +41 -28
  350. package/dist/im/lark/event-dispatcher.js.map +1 -1
  351. package/dist/im/lark/md-card.d.ts +18 -0
  352. package/dist/im/lark/md-card.d.ts.map +1 -1
  353. package/dist/im/lark/md-card.js +21 -0
  354. package/dist/im/lark/md-card.js.map +1 -1
  355. package/dist/im/lark/relay-target-routing.d.ts.map +1 -1
  356. package/dist/im/lark/relay-target-routing.js +3 -2
  357. package/dist/im/lark/relay-target-routing.js.map +1 -1
  358. package/dist/im/lark/reply-mode-command.d.ts.map +1 -1
  359. package/dist/im/lark/reply-mode-command.js +19 -8
  360. package/dist/im/lark/reply-mode-command.js.map +1 -1
  361. package/dist/im/lark/skill-feedback-card.d.ts +15 -0
  362. package/dist/im/lark/skill-feedback-card.d.ts.map +1 -0
  363. package/dist/im/lark/skill-feedback-card.js +149 -0
  364. package/dist/im/lark/skill-feedback-card.js.map +1 -0
  365. package/dist/services/bot-config-store.d.ts +10 -1
  366. package/dist/services/bot-config-store.d.ts.map +1 -1
  367. package/dist/services/bot-config-store.js +103 -3
  368. package/dist/services/bot-config-store.js.map +1 -1
  369. package/dist/services/bridge-fallback-gate.d.ts +29 -7
  370. package/dist/services/bridge-fallback-gate.d.ts.map +1 -1
  371. package/dist/services/bridge-fallback-gate.js +58 -16
  372. package/dist/services/bridge-fallback-gate.js.map +1 -1
  373. package/dist/services/codex-reasoning-effort.d.ts +9 -0
  374. package/dist/services/codex-reasoning-effort.d.ts.map +1 -0
  375. package/dist/services/codex-reasoning-effort.js +23 -0
  376. package/dist/services/codex-reasoning-effort.js.map +1 -0
  377. package/dist/services/codex-service-tier.d.ts +1 -1
  378. package/dist/services/codex-service-tier.d.ts.map +1 -1
  379. package/dist/services/codex-transcript.d.ts +9 -0
  380. package/dist/services/codex-transcript.d.ts.map +1 -1
  381. package/dist/services/codex-transcript.js +13 -6
  382. package/dist/services/codex-transcript.js.map +1 -1
  383. package/dist/services/feed-group-tagger.d.ts +15 -0
  384. package/dist/services/feed-group-tagger.d.ts.map +1 -0
  385. package/dist/services/feed-group-tagger.js +348 -0
  386. package/dist/services/feed-group-tagger.js.map +1 -0
  387. package/dist/services/feedback-analytics.d.ts +82 -0
  388. package/dist/services/feedback-analytics.d.ts.map +1 -0
  389. package/dist/services/feedback-analytics.js +95 -0
  390. package/dist/services/feedback-analytics.js.map +1 -0
  391. package/dist/services/feedback-outbox.d.ts +24 -0
  392. package/dist/services/feedback-outbox.d.ts.map +1 -0
  393. package/dist/services/feedback-outbox.js +12 -0
  394. package/dist/services/feedback-outbox.js.map +1 -0
  395. package/dist/services/feedback-policy-resolver.d.ts +56 -0
  396. package/dist/services/feedback-policy-resolver.d.ts.map +1 -0
  397. package/dist/services/feedback-policy-resolver.js +156 -0
  398. package/dist/services/feedback-policy-resolver.js.map +1 -0
  399. package/dist/services/feedback-policy.d.ts +41 -0
  400. package/dist/services/feedback-policy.d.ts.map +1 -0
  401. package/dist/services/feedback-policy.js +102 -0
  402. package/dist/services/feedback-policy.js.map +1 -0
  403. package/dist/services/feedback-webhook-dispatcher.d.ts +76 -0
  404. package/dist/services/feedback-webhook-dispatcher.d.ts.map +1 -0
  405. package/dist/services/feedback-webhook-dispatcher.js +237 -0
  406. package/dist/services/feedback-webhook-dispatcher.js.map +1 -0
  407. package/dist/services/grant-prefs-store.d.ts +3 -0
  408. package/dist/services/grant-prefs-store.d.ts.map +1 -1
  409. package/dist/services/grant-prefs-store.js +30 -1
  410. package/dist/services/grant-prefs-store.js.map +1 -1
  411. package/dist/services/groups-store.d.ts +14 -0
  412. package/dist/services/groups-store.d.ts.map +1 -1
  413. package/dist/services/groups-store.js +23 -0
  414. package/dist/services/groups-store.js.map +1 -1
  415. package/dist/services/local-cli-opener.d.ts +1 -1
  416. package/dist/services/local-cli-opener.d.ts.map +1 -1
  417. package/dist/services/local-cli-opener.js +2 -0
  418. package/dist/services/local-cli-opener.js.map +1 -1
  419. package/dist/services/peer-cross-ref-store.d.ts +8 -0
  420. package/dist/services/peer-cross-ref-store.d.ts.map +1 -0
  421. package/dist/services/peer-cross-ref-store.js +95 -0
  422. package/dist/services/peer-cross-ref-store.js.map +1 -0
  423. package/dist/services/pi-transcript.d.ts.map +1 -1
  424. package/dist/services/pi-transcript.js +10 -6
  425. package/dist/services/pi-transcript.js.map +1 -1
  426. package/dist/services/prompt-context-store.d.ts +29 -0
  427. package/dist/services/prompt-context-store.d.ts.map +1 -0
  428. package/dist/services/prompt-context-store.js +205 -0
  429. package/dist/services/prompt-context-store.js.map +1 -0
  430. package/dist/services/session-group-avatar.d.ts +6 -0
  431. package/dist/services/session-group-avatar.d.ts.map +1 -0
  432. package/dist/services/session-group-avatar.js +96 -0
  433. package/dist/services/session-group-avatar.js.map +1 -0
  434. package/dist/services/session-group-title.d.ts +47 -0
  435. package/dist/services/session-group-title.d.ts.map +1 -0
  436. package/dist/services/session-group-title.js +226 -0
  437. package/dist/services/session-group-title.js.map +1 -0
  438. package/dist/services/session-groups-store.d.ts +30 -0
  439. package/dist/services/session-groups-store.d.ts.map +1 -0
  440. package/dist/services/session-groups-store.js +132 -0
  441. package/dist/services/session-groups-store.js.map +1 -0
  442. package/dist/services/session-store.d.ts +58 -0
  443. package/dist/services/session-store.d.ts.map +1 -1
  444. package/dist/services/session-store.js +174 -0
  445. package/dist/services/session-store.js.map +1 -1
  446. package/dist/services/skill-feedback-store.d.ts +252 -0
  447. package/dist/services/skill-feedback-store.d.ts.map +1 -0
  448. package/dist/services/skill-feedback-store.js +795 -0
  449. package/dist/services/skill-feedback-store.js.map +1 -0
  450. package/dist/services/skill-registry-store.d.ts +23 -0
  451. package/dist/services/skill-registry-store.d.ts.map +1 -1
  452. package/dist/services/skill-registry-store.js +93 -7
  453. package/dist/services/skill-registry-store.js.map +1 -1
  454. package/dist/services/structured-bridge-clis.d.ts +13 -4
  455. package/dist/services/structured-bridge-clis.d.ts.map +1 -1
  456. package/dist/services/structured-bridge-clis.js +13 -3
  457. package/dist/services/structured-bridge-clis.js.map +1 -1
  458. package/dist/services/team-store.d.ts +4 -0
  459. package/dist/services/team-store.d.ts.map +1 -1
  460. package/dist/services/team-store.js +16 -0
  461. package/dist/services/team-store.js.map +1 -1
  462. package/dist/services/traex-transcript.d.ts +32 -4
  463. package/dist/services/traex-transcript.d.ts.map +1 -1
  464. package/dist/services/traex-transcript.js +116 -8
  465. package/dist/services/traex-transcript.js.map +1 -1
  466. package/dist/services/trigger-types.d.ts +1 -1
  467. package/dist/services/trigger-types.d.ts.map +1 -1
  468. package/dist/services/trigger-types.js +2 -2
  469. package/dist/services/trigger-types.js.map +1 -1
  470. package/dist/services/turn-completion-events.d.ts +57 -0
  471. package/dist/services/turn-completion-events.d.ts.map +1 -0
  472. package/dist/services/turn-completion-events.js +179 -0
  473. package/dist/services/turn-completion-events.js.map +1 -0
  474. package/dist/services/vc-meeting-consumer-isolation.d.ts +21 -12
  475. package/dist/services/vc-meeting-consumer-isolation.d.ts.map +1 -1
  476. package/dist/services/vc-meeting-consumer-isolation.js +25 -19
  477. package/dist/services/vc-meeting-consumer-isolation.js.map +1 -1
  478. package/dist/services/vc-meeting-consumer-profile-bootstrap.d.ts +8 -2
  479. package/dist/services/vc-meeting-consumer-profile-bootstrap.d.ts.map +1 -1
  480. package/dist/services/vc-meeting-consumer-profile-bootstrap.js +18 -10
  481. package/dist/services/vc-meeting-consumer-profile-bootstrap.js.map +1 -1
  482. package/dist/setup/bot-config-editor.d.ts.map +1 -1
  483. package/dist/setup/bot-config-editor.js +6 -0
  484. package/dist/setup/bot-config-editor.js.map +1 -1
  485. package/dist/setup/cli-availability.d.ts +2 -1
  486. package/dist/setup/cli-availability.d.ts.map +1 -1
  487. package/dist/setup/cli-availability.js +2 -1
  488. package/dist/setup/cli-availability.js.map +1 -1
  489. package/dist/setup/cli-selection.d.ts +8 -0
  490. package/dist/setup/cli-selection.d.ts.map +1 -1
  491. package/dist/setup/cli-selection.js +31 -0
  492. package/dist/setup/cli-selection.js.map +1 -1
  493. package/dist/setup/ensure-fonts.d.ts +5 -0
  494. package/dist/setup/ensure-fonts.d.ts.map +1 -1
  495. package/dist/setup/ensure-fonts.js +26 -1
  496. package/dist/setup/ensure-fonts.js.map +1 -1
  497. package/dist/setup/lark-scopes.json +3 -1
  498. package/dist/setup/open-platform-automation.d.ts +1 -1
  499. package/dist/setup/open-platform-automation.d.ts.map +1 -1
  500. package/dist/setup/open-platform-automation.js +15 -3
  501. package/dist/setup/open-platform-automation.js.map +1 -1
  502. package/dist/skills/definitions.d.ts +1 -1
  503. package/dist/skills/definitions.d.ts.map +1 -1
  504. package/dist/skills/definitions.js +9 -2
  505. package/dist/skills/definitions.js.map +1 -1
  506. package/dist/types.d.ts +11 -4
  507. package/dist/types.d.ts.map +1 -1
  508. package/dist/utils/bot-routing.d.ts +1 -1
  509. package/dist/utils/bot-routing.d.ts.map +1 -1
  510. package/dist/utils/bot-routing.js.map +1 -1
  511. package/dist/utils/user-token.d.ts +38 -0
  512. package/dist/utils/user-token.d.ts.map +1 -1
  513. package/dist/utils/user-token.js +76 -1
  514. package/dist/utils/user-token.js.map +1 -1
  515. package/dist/utils/web-terminal-scroll.d.ts +27 -0
  516. package/dist/utils/web-terminal-scroll.d.ts.map +1 -0
  517. package/dist/utils/web-terminal-scroll.js +60 -0
  518. package/dist/utils/web-terminal-scroll.js.map +1 -0
  519. package/dist/vc-agent/polling-source.d.ts +70 -0
  520. package/dist/vc-agent/polling-source.d.ts.map +1 -1
  521. package/dist/vc-agent/polling-source.js +115 -0
  522. package/dist/vc-agent/polling-source.js.map +1 -1
  523. package/dist/worker.js +469 -86
  524. package/dist/worker.js.map +1 -1
  525. package/dist/workflows/definition.d.ts +22 -22
  526. package/dist/workflows/events/payloads.d.ts +8 -8
  527. package/dist/workflows/events/schema.d.ts +20 -20
  528. package/dist/workflows/migration/v2-run-archive-schema.d.ts +20 -20
  529. package/package.json +5 -1
  530. package/dist/dashboard-web/chunks/bot-defaults-page-NQJFJ45Z.js +0 -10
  531. package/dist/dashboard-web/chunks/chunk-KEEYQ3WF.js +0 -1
  532. package/dist/dashboard-web/chunks/connectors-page-HADHZXXZ.js +0 -1
  533. package/dist/dashboard-web/chunks/groups-page-5TYF46RS.js +0 -8
  534. package/dist/dashboard-web/chunks/monitoring-page-LBU7TTTW.js +0 -2
  535. package/dist/dashboard-web/chunks/office-page-DF6RRBMN.js +0 -1
  536. package/dist/dashboard-web/chunks/overview-page-ZB6QH2EX.js +0 -1
  537. package/dist/dashboard-web/chunks/roles-page-ZBZGHIIF.js +0 -1
  538. package/dist/dashboard-web/chunks/schedules-page-NQVQC3QY.js +0 -1
  539. package/dist/dashboard-web/chunks/settings-page-E7NN4NVQ.js +0 -2
  540. package/dist/dashboard-web/chunks/team-federation-page-VGWL53AE.js +0 -1
  541. package/dist/dashboard-web/chunks/whiteboards-page-BNWUU4KG.js +0 -1
@@ -7,11 +7,14 @@ import { logger } from '../utils/logger.js';
7
7
  import { cliAuthBind, verifyHmac } from '../dashboard/auth.js';
8
8
  import { WORKFLOW_DAEMON_IPC_ROUTE_PREFIX } from '../workflows/v3/daemon-ipc-auth.js';
9
9
  import { V3_SESSION_RUN_MUTATION_ROUTE_PREFIX } from '../workflows/v3/session-relay.js';
10
+ import { REPORT_SESSION_RELAY_ROUTE } from './report-session-relay.js';
11
+ import { DISPATCH_REPORT_REGISTER_ROUTE } from './dispatch-report-binding.js';
10
12
  import { listenWithProbe } from '../utils/listen-with-probe.js';
11
13
  import { dashboardSecretPath } from './dashboard-secret.js';
12
14
  import { MANAGED_ORIGIN_ATTEST_ROUTE, MANAGED_ORIGIN_PROOF_DOMAIN, MANAGED_ORIGIN_PROOF_TTL_MS, writeManagedOriginAttestationProof, } from './managed-origin-attestation.js';
13
15
  import * as sessionStore from '../services/session-store.js';
14
16
  import { cliSupportsNativeUsage } from '../services/transcript-resolver.js';
17
+ import { codexModelSupportsReasoningEffort, isCodexReasoningCliId, isCodexReasoningEffort, } from '../services/codex-reasoning-effort.js';
15
18
  import * as asyncTriggerStore from '../services/async-trigger-store.js';
16
19
  import { resolveAsyncTriggerState, decideAsyncOwnership } from '../services/async-trigger-state.js';
17
20
  import * as scheduleStore from '../services/schedule-store.js';
@@ -26,6 +29,7 @@ import { ensureBackendAvailable } from '../services/backend-availability.js';
26
29
  import * as persistentBackend from './persistent-backend.js';
27
30
  import * as cardPrefsStore from '../services/card-prefs-store.js';
28
31
  import * as substituteModeStore from '../services/substitute-mode-store.js';
32
+ import { claimPromptContext } from '../services/prompt-context-store.js';
29
33
  import { createCliAdapterSync } from '../adapters/cli/registry.js';
30
34
  import { normalizeCliRuntimeConfig } from '../adapters/cli/runtime.js';
31
35
  import { evaluateReadIsolationGate } from '../adapters/cli/read-isolation.js';
@@ -61,7 +65,8 @@ import { getDeploymentIdentity } from '../services/deployment-identity.js';
61
65
  import { getBotUnionId } from '../services/bot-union-ids-store.js';
62
66
  import * as grantPrefsStore from '../services/grant-prefs-store.js';
63
67
  import { applyExactChatGrantRequest } from '../services/exact-chat-grant.js';
64
- import { findConfigField, applyConfigField, coerceConfigValue } from '../services/bot-config-store.js';
68
+ import { findConfigField, applyConfigField, coerceConfigValue, setChatFeedbackPolicy } from '../services/bot-config-store.js';
69
+ import { traceFeedbackPolicyForDelivery } from '../services/feedback-policy-resolver.js';
65
70
  import { globalBuiltinSkillInjectionDefault, resolveSkillInjectionSupport } from '../skills/injection-mode.js';
66
71
  import { summaryRangeFromBotConfig, updateDashboardSummaryRange } from '../services/summary-range-store.js';
67
72
  import { config } from '../config.js';
@@ -123,7 +128,9 @@ export function setSupervisorShutdownHandler(registration) {
123
128
  supervisorShutdownRegistration = registration;
124
129
  }
125
130
  import { composeRowFromActive, composeRowFromClosed, composeRowFromPersistedActive, feishuChatLink, setBotName as setRowsBotName, getBotName, } from './dashboard-rows.js';
126
- import { getBotBrand, getBot, getBotOpenId, loadBotConfigs, readBotSkillPolicy, getBotTuiSlashAllow } from '../bot-registry.js';
131
+ import { getBotBrand, getBot, getBotOpenId, loadBotConfigs, readBotSkillPolicy, getBotTuiSlashAllow, MAX_TURN_TIMEOUT_MS } from '../bot-registry.js';
132
+ import { generateAuthUrl, tryHandleCallbackUrl, getFeedGroupAuthStatus, FEED_GROUP_OAUTH_SCOPES } from '../utils/user-token.js';
133
+ import { normalizeBrand } from '../im/lark/lark-hosts.js';
127
134
  import { normalizeKanbanColumn, normalizeKanbanPosition, normalizeSessionTitle } from './session-board.js';
128
135
  import { validateSlashInjection } from './slash-inject.js';
129
136
  import { validateRoleLibraryPath } from './role-library.js';
@@ -136,6 +143,7 @@ import { sessionAnchorId, larkTransportEnabled } from './types.js';
136
143
  import { isRiffBackendSession } from './persistent-backend.js';
137
144
  import { attachSkillPolicy, detachSkillPolicy } from './skills/im-command.js';
138
145
  import { readSkillRegistry } from '../services/skill-registry-store.js';
146
+ import { isSessionGroup } from '../services/session-groups-store.js';
139
147
  import { commitDeviceIsolationActivation, DEVICE_ISOLATION_COMMIT_PATH, DEVICE_ISOLATION_PREPARE_PATH, DEVICE_ISOLATION_RELEASE_PATH, logDeviceIsolationActivationError, prepareDeviceIsolationActivation, releaseDeviceIsolationActivation, } from './device-isolation-daemon.js';
140
148
  // Daemon process start (module load ≈ daemon boot). Used by the SSE snapshot
141
149
  // replay to bound the "recently closed" set to sessions that flipped
@@ -530,10 +538,22 @@ function routeHasNarrowUntrustedAuth(method, pathname) {
530
538
  // 证明「我是这个会话当前这一轮的 CLI」,选不了别的会话。
531
539
  if (method === 'POST' && /^\/api\/sessions\/[^/]+\/(?:slash|cd|close|chat-rename)$/.test(pathname))
532
540
  return true;
541
+ // UserPromptSubmit hook 的 envelope claim:沙箱内 hook 读不到 host secret,
542
+ // 走 body 里的 per-turn capability;handler 内 sessionCliIpcAuth 绑定到 URL 的
543
+ // sessionId + 按 managedTurnOrigin.turnId 权威取(同 /close 姿势)。
544
+ if (method === 'POST' && /^\/api\/sessions\/[^/]+\/prompt-ctx\/claim$/.test(pathname))
545
+ return true;
533
546
  if (method === 'POST' && pathname === '/api/hooks/emit')
534
547
  return true;
535
548
  if (method === 'POST' && pathname === '/api/attention')
536
549
  return true;
550
+ // A sandboxed report cannot read the host HMAC secret. This narrow route
551
+ // validates the current session's rotating capability, binds the dispatch
552
+ // root server-side, then lets the trusted daemon relay to the orchestrator.
553
+ if (method === 'POST' && pathname === REPORT_SESSION_RELAY_ROUTE)
554
+ return true;
555
+ if (method === 'POST' && pathname === DISPATCH_REPORT_REGISTER_ROUTE)
556
+ return true;
537
557
  // macOS read-isolated `botmux send` presents a rotating worker capability;
538
558
  // the handler writes the authoritative tuple into a host-owned read-only
539
559
  // proof sidecar, so loopback response spoofing cannot confer authority.
@@ -889,6 +909,44 @@ ipcRoute('POST', '/api/sessions/:sessionId/close', async (req, res, params) => {
889
909
  jsonRes(res, r.ok ? 200 : 502, r);
890
910
  });
891
911
  });
912
+ /**
913
+ * Host-side atomic claim/pop for the UserPromptSubmit hook(#794 方向 B)。
914
+ *
915
+ * 沙箱内的 `botmux user-prompt-hook` 不能在 read-only 的 `prompt-ctx/<sid>` 里
916
+ * unlink(HIGH-2),同正文多轮也不能靠 FIFO 猜(HIGH-1:某轮漏 claim 会串轮到
917
+ * 后续轮)。hook 把 (session 凭据 + fingerprint) 提交到这里,宿主按
918
+ * **managedTurnOrigin.turnId 权威 turn 绑定**精确取该轮的 envelope,先删再返回。
919
+ * 漏 claim 只孤儿化自己那条,不污染后续轮;上一轮的 stale sidecar 永远不会被返回。
920
+ *
921
+ * 鉴权与 /close、/slash 同构:trusted-host HMAC,或本会话 rotating per-turn
922
+ * capability(沙箱内读 host secret 失败时的回退)。任何未命中/失败 → 404/403,
923
+ * hook 端空输出 exit 0(fail-open:reminder 丢失 < 卡住 prompt)。
924
+ */
925
+ ipcRoute('POST', '/api/sessions/:sessionId/prompt-ctx/claim', async (req, res, params) => {
926
+ const body = await readJsonBody(req).catch(() => ({}));
927
+ const ds = findActiveBySessionId(params.sessionId);
928
+ // claim 只读 daemon 自有本轮非凭证上下文(reminder/whiteboard),receiver 会话
929
+ // 也允许(allowReceiver: true);close/slash/cd 等 managed action 仍默认拒绝。
930
+ const auth = sessionCliIpcAuth(req, ds, params.sessionId, body, { allowReceiver: true });
931
+ if (!auth.ok)
932
+ return jsonRes(res, 403, { ok: false, error: auth.error });
933
+ const fingerprint = typeof body?.fingerprint === 'string' ? body.fingerprint : '';
934
+ if (!/^[a-f0-9]{64}$/.test(fingerprint)) {
935
+ return jsonRes(res, 400, { ok: false, error: 'invalid_fingerprint' });
936
+ }
937
+ // 权威 turnId:daemon 当前这轮的 turnId(worker 发布的 managed_turn_origin)。
938
+ // hook 不需要、也不应自己提供 turnId——daemon 只认自己的权威值,避免 FIFO 串轮。
939
+ const turnId = ds?.managedTurnOrigin?.turnId;
940
+ if (!turnId)
941
+ return jsonRes(res, 404, { ok: false, error: 'no_active_turn' });
942
+ const prefix = typeof body?.prefix === 'string' && body.prefix.length > 0
943
+ ? body.prefix.slice(0, 64)
944
+ : undefined;
945
+ const envelope = claimPromptContext(params.sessionId, turnId, fingerprint, prefix);
946
+ if (!envelope)
947
+ return jsonRes(res, 404, { ok: false, error: 'not_found' });
948
+ jsonRes(res, 200, { ok: true, envelope });
949
+ });
892
950
  // `botmux list` zombie pruning is maintenance, not explicit abandon. Serialize
893
951
  // against inbound admission and refuse if any backend-neutral durable owner
894
952
  // became unsettled after the CLI took its liveness snapshot.
@@ -1023,6 +1081,25 @@ ipcRoute('POST', '/api/sessions/:sessionId/suspend', async (_req, res, params) =
1023
1081
  // already reached, so report idempotent success without a live kill.
1024
1082
  return jsonRes(res, 200, { ok: true, sessionId: params.sessionId, suspended: false, reason: 'no_live_worker' });
1025
1083
  }
1084
+ // Producing a reply — killing the worker now would drop this turn. Queue
1085
+ // instead; worker-pool's runPendingSuspendIfSettled cashes it in on the
1086
+ // idle/limited edge. Ordering matters: the idempotent no-worker branch above
1087
+ // must win, so "worker was already gone" never reports as deferred.
1088
+ //
1089
+ // The suspendability check is part of the queueing condition, not a new guard
1090
+ // ahead of it: a non-suspendable (pty) backend must keep falling through to
1091
+ // suspendWorker's existing 409 rather than get a `deferred` that could only
1092
+ // fail silently at fulfillment time.
1093
+ if ((ds.lastScreenStatus === 'working' || ds.lastScreenStatus === 'analyzing')
1094
+ && isSuspendableBackendType(ds.initConfig?.backendType)) {
1095
+ ds.pendingSuspendReason = 'manual_suspend';
1096
+ // Bind the claim to the generation that is producing right now: it must not
1097
+ // outlive that worker (see clearPendingSuspendClaim).
1098
+ ds.pendingSuspendGeneration = ds.workerGeneration;
1099
+ return jsonRes(res, 200, {
1100
+ ok: true, sessionId: params.sessionId, suspended: false, reason: 'deferred',
1101
+ });
1102
+ }
1026
1103
  if (!suspendWorker(ds, 'manual_suspend')) {
1027
1104
  // Live worker but a non-suspendable (pty) backend: killing it would drop the
1028
1105
  // in-memory conversation with no persistent pane to resume from lazily.
@@ -1125,7 +1202,7 @@ ipcRoute('POST', '/api/host-overload/sweep', async (req, res) => {
1125
1202
  * capability 只证明「我是这个会话当前这一轮的 CLI」——绑定 URL sessionId,
1126
1203
  * 拿到别的 sessionId 也伪造不了它的 capability。会话不存在时对未签名调用方
1127
1204
  * 同样回 origin_unproven,不提供「哪些 sessionId 活跃」的探针。 */
1128
- function sessionCliIpcAuth(req, ds, sessionId, body) {
1205
+ function sessionCliIpcAuth(req, ds, sessionId, body, opts = {}) {
1129
1206
  const claimedAttempt = typeof body?.originDispatchAttempt === 'number'
1130
1207
  && Number.isSafeInteger(body.originDispatchAttempt)
1131
1208
  && body.originDispatchAttempt > 0
@@ -1135,7 +1212,9 @@ function sessionCliIpcAuth(req, ds, sessionId, body) {
1135
1212
  trustedHost: isTrustedHostIpcRequest(req),
1136
1213
  sessionExists: !!ds,
1137
1214
  receiverSession: !!ds?.session.vcMeetingReceiver,
1138
- allowReceiver: false,
1215
+ // close/slash/cd 是 managed action,默认拒绝 receiver;claim 只读 daemon 自有
1216
+ // 本轮非凭证上下文(reminder/whiteboard),读自己本轮 reminder 非提权,单独放开。
1217
+ allowReceiver: opts.allowReceiver === true,
1139
1218
  sessionId,
1140
1219
  liveOrigin: ds?.managedTurnOrigin,
1141
1220
  claimedCapability: typeof body?.originCapability === 'string' ? body.originCapability : undefined,
@@ -2679,7 +2758,17 @@ ipcRoute('GET', '/api/groups', async (_req, res) => {
2679
2758
  const observedBotNames = observedBotsStore
2680
2759
  .listObservedBots(config.session.dataDir, cachedLarkAppId, c.chatId)
2681
2760
  .map(b => b.name);
2682
- return { ...c, oncallChat: oncall ?? null, firstSeenAt: seenMap.get(c.chatId) ?? null, hasRole, hasMessageListener, observedBotNames };
2761
+ return {
2762
+ ...c,
2763
+ oncallChat: oncall ?? null,
2764
+ firstSeenAt: seenMap.get(c.chatId) ?? null,
2765
+ hasRole,
2766
+ hasMessageListener,
2767
+ observedBotNames,
2768
+ // 会话群分型(p2pMode=group 自动创建):dashboard 群面板据此把它们
2769
+ // 收进独立折叠区,避免淹没需要人工管理的常驻群。
2770
+ ...(isSessionGroup(c.chatId) ? { sessionGroup: true } : {}),
2771
+ };
2683
2772
  });
2684
2773
  jsonRes(res, 200, { chats: enriched });
2685
2774
  }
@@ -3369,10 +3458,17 @@ ipcRoute('GET', '/api/bot-default-oncall', async (_req, res) => {
3369
3458
  const grantPrefs = grantPrefsStore.getBotGrantPrefs(cachedLarkAppId);
3370
3459
  let p2pMode = 'chat';
3371
3460
  try {
3372
- if (getBot(cachedLarkAppId).config.p2pMode === 'thread')
3373
- p2pMode = 'thread';
3461
+ const configured = getBot(cachedLarkAppId).config.p2pMode;
3462
+ if (configured === 'thread' || configured === 'group')
3463
+ p2pMode = configured;
3374
3464
  }
3375
3465
  catch { /* default chat */ }
3466
+ let envelopeInjection = 'off';
3467
+ try {
3468
+ if (getBot(cachedLarkAppId).config.envelopeInjection === 'auto')
3469
+ envelopeInjection = 'auto';
3470
+ }
3471
+ catch { /* default off */ }
3376
3472
  let skillInjection = null;
3377
3473
  // How this bot's CLI delivers botmux skills, so the dashboard can render the
3378
3474
  // control correctly: 'dynamic' = per-session --plugin-dir (claude-family, not
@@ -3392,6 +3488,10 @@ ipcRoute('GET', '/api/bot-default-oncall', async (_req, res) => {
3392
3488
  let cliPathOverride = null;
3393
3489
  let wrapperCli = null;
3394
3490
  let model = null;
3491
+ let reasoningEffort = null;
3492
+ // dsh runner turn timeout (ms). Only meaningful for the dsh adapter; exposed
3493
+ // so the dashboard can render the dsh-only field with its current value.
3494
+ let turnTimeoutMs = null;
3395
3495
  let agentSelectionKey = '';
3396
3496
  try {
3397
3497
  const cfg = getBot(cachedLarkAppId).config;
@@ -3406,6 +3506,11 @@ ipcRoute('GET', '/api/bot-default-oncall', async (_req, res) => {
3406
3506
  : null;
3407
3507
  wrapperCli = typeof cfg.wrapperCli === 'string' && cfg.wrapperCli.trim() ? cfg.wrapperCli : null;
3408
3508
  model = typeof cfg.model === 'string' && cfg.model.trim() ? cfg.model : null;
3509
+ reasoningEffort = cfg.reasoningEffort ?? null;
3510
+ turnTimeoutMs = typeof cfg.turnTimeoutMs === 'number'
3511
+ && Number.isInteger(cfg.turnTimeoutMs) && cfg.turnTimeoutMs > 0
3512
+ ? cfg.turnTimeoutMs
3513
+ : null;
3409
3514
  agentSelectionKey = selectionKeyForBot(cliId, wrapperCli ?? undefined);
3410
3515
  }
3411
3516
  catch { /* no registered bot */ }
@@ -3493,6 +3598,8 @@ ipcRoute('GET', '/api/bot-default-oncall', async (_req, res) => {
3493
3598
  cliPathOverride,
3494
3599
  wrapperCli,
3495
3600
  model,
3601
+ reasoningEffort,
3602
+ turnTimeoutMs,
3496
3603
  agentSelectionKey,
3497
3604
  defaultOncall: defaultOncall ?? { enabled: false, workingDir: '', since: 0 },
3498
3605
  defaultWorkingDir,
@@ -3524,12 +3631,20 @@ ipcRoute('GET', '/api/bot-default-oncall', async (_req, res) => {
3524
3631
  regularGroupReplyMode: cardPrefs.regularGroupReplyMode,
3525
3632
  regularGroupMentionMode: cardPrefs.regularGroupMentionMode,
3526
3633
  substituteMode: substituteModeStore.getBotSubstituteMode(cachedLarkAppId) ?? null,
3634
+ feedback: (() => { try {
3635
+ return getBot(cachedLarkAppId).config.feedback ?? null;
3636
+ }
3637
+ catch {
3638
+ return null;
3639
+ } })(),
3527
3640
  docSubscribeDefaultMode: cardPrefs.docSubscribeDefaultMode,
3528
3641
  restrictGrantCommands: grantPrefs.restrictGrantCommands,
3529
3642
  autoGrantRequestCards: grantPrefs.autoGrantRequestCards,
3643
+ p2pOpen: grantPrefs.p2pOpen,
3530
3644
  messageQuotaDefaultLimit: grantPrefs.messageQuotaDefaultLimit,
3531
3645
  grantDefaultDurationMs: grantPrefs.grantDefaultDurationMs,
3532
3646
  p2pMode,
3647
+ envelopeInjection,
3533
3648
  skillInjection,
3534
3649
  skillInjectionSupport,
3535
3650
  // Resolved machine-wide default → the dashboard shows it as the pre-selected
@@ -3698,6 +3813,7 @@ ipcRoute('PUT', '/api/bot-summary-trigger', async (req, res) => {
3698
3813
  // Per-bot 授权偏好。Body 任意子集:
3699
3814
  // • restrictGrantCommands: boolean — 限制被授权人只能纯对话
3700
3815
  // • autoGrantRequestCards: boolean — 未授权 @ 被挡住时是否发 grant 申请卡
3816
+ // • p2pOpen: boolean — 私聊对话全开(talk-only;管理权仍只认 allowedUsers)
3701
3817
  // • messageQuotaDefaultLimit: number|null — 卡片/Oncall 额度覆盖(null = 卡片内置 3 条、Oncall 不限)
3702
3818
  // • grantDefaultDurationMs: number|null — 新授权默认有限时长(null = 产品默认 1 小时)
3703
3819
  ipcRoute('PUT', '/api/bot-grant-prefs', async (req, res) => {
@@ -3720,6 +3836,8 @@ ipcRoute('PUT', '/api/bot-grant-prefs', async (req, res) => {
3720
3836
  patch.restrictGrantCommands = body.restrictGrantCommands;
3721
3837
  if (typeof body.autoGrantRequestCards === 'boolean')
3722
3838
  patch.autoGrantRequestCards = body.autoGrantRequestCards;
3839
+ if (typeof body.p2pOpen === 'boolean')
3840
+ patch.p2pOpen = body.p2pOpen;
3723
3841
  // null(含 JSON null)= 恢复内置额度策略;number = 设定覆盖值(store 内校验 1–1000)。
3724
3842
  if (body.messageQuotaDefaultLimit === null)
3725
3843
  patch.messageQuotaDefaultLimit = null;
@@ -3876,7 +3994,29 @@ ipcRoute('PUT', '/api/bot-agent', async (req, res) => {
3876
3994
  return jsonRes(res, 400, { ok: false, error: 'invalid_cli', message: err?.message ?? String(err) });
3877
3995
  }
3878
3996
  const model = typeof body.model === 'string' ? body.model.trim() : '';
3997
+ const reasoningEffortFieldPresent = Object.prototype.hasOwnProperty.call(body, 'reasoningEffort');
3998
+ const reasoningEffort = isCodexReasoningEffort(body.reasoningEffort) ? body.reasoningEffort : null;
3999
+ if (body.reasoningEffort !== undefined && body.reasoningEffort !== '' && reasoningEffort === null) {
4000
+ return jsonRes(res, 400, { ok: false, error: 'invalid_reasoning_effort' });
4001
+ }
3879
4002
  const currentBotConfig = getBot(larkAppId).config;
4003
+ const supportsReasoningEffort = isCodexReasoningCliId(selected.cliId);
4004
+ // Per-bot dsh runner turn timeout. Only the dsh adapter forwards it
4005
+ // (`--turn-timeout-ms`); the dashboard exposes the field for dsh only. The
4006
+ // field is optional in the body, so distinguish absent (preserve) from
4007
+ // present-but-empty (clear → runner default) like reasoningEffort does.
4008
+ const supportsTurnTimeout = selected.cliId === 'dsh';
4009
+ const turnTimeoutFieldPresent = Object.prototype.hasOwnProperty.call(body, 'turnTimeoutMs');
4010
+ let nextTurnTimeoutMs;
4011
+ if (turnTimeoutFieldPresent && body.turnTimeoutMs !== null && body.turnTimeoutMs !== '') {
4012
+ const n = Number(body.turnTimeoutMs);
4013
+ // Positive integer within the arm-able bound; reject anything else so an
4014
+ // over-bound value can't wrap to ~1ms in the runner's setTimeout.
4015
+ if (!Number.isInteger(n) || n <= 0 || n > MAX_TURN_TIMEOUT_MS) {
4016
+ return jsonRes(res, 400, { ok: false, error: 'invalid_turn_timeout_ms' });
4017
+ }
4018
+ nextTurnTimeoutMs = n;
4019
+ }
3880
4020
  const runtimeFieldPresent = Object.prototype.hasOwnProperty.call(body, 'cliRuntime');
3881
4021
  const currentSelectionKey = selectionKeyForBot(currentBotConfig.cliId, currentBotConfig.wrapperCli);
3882
4022
  const selectionChanged = key !== currentSelectionKey;
@@ -3971,6 +4111,12 @@ ipcRoute('PUT', '/api/bot-agent', async (req, res) => {
3971
4111
  // is the other way a bot could end up configured-but-unenforceable.)
3972
4112
  let readIsolationCleared = false;
3973
4113
  const r = await rmwBotEntry(larkAppId, (entry) => {
4114
+ const nextReasoningEffort = supportsReasoningEffort
4115
+ ? (reasoningEffortFieldPresent ? reasoningEffort ?? undefined : entry.reasoningEffort)
4116
+ : undefined;
4117
+ if (nextReasoningEffort && !codexModelSupportsReasoningEffort(model || undefined, nextReasoningEffort)) {
4118
+ return { write: false, result: { error: 'reasoning_effort_not_supported_by_model' } };
4119
+ }
3974
4120
  entry.cliId = selected.cliId;
3975
4121
  if (selected.wrapperCli)
3976
4122
  entry.wrapperCli = selected.wrapperCli;
@@ -3994,6 +4140,24 @@ ipcRoute('PUT', '/api/bot-agent', async (req, res) => {
3994
4140
  entry.model = model;
3995
4141
  else
3996
4142
  delete entry.model;
4143
+ if (!supportsReasoningEffort)
4144
+ delete entry.reasoningEffort;
4145
+ else if (reasoningEffortFieldPresent) {
4146
+ if (reasoningEffort)
4147
+ entry.reasoningEffort = reasoningEffort;
4148
+ else
4149
+ delete entry.reasoningEffort;
4150
+ }
4151
+ // dsh-only turn timeout: non-dsh always drops it; on dsh, an explicit
4152
+ // field value writes/clears it, absence preserves the current value.
4153
+ if (!supportsTurnTimeout)
4154
+ delete entry.turnTimeoutMs;
4155
+ else if (turnTimeoutFieldPresent) {
4156
+ if (nextTurnTimeoutMs !== undefined)
4157
+ entry.turnTimeoutMs = nextTurnTimeoutMs;
4158
+ else
4159
+ delete entry.turnTimeoutMs;
4160
+ }
3997
4161
  if (entry.readIsolation === true &&
3998
4162
  !readIsolationEnforceableFor({ cliId: selected.cliId, cliPathOverride: effectivePath, wrapperCli: selected.wrapperCli })) {
3999
4163
  delete entry.readIsolation;
@@ -4009,10 +4173,17 @@ ipcRoute('PUT', '/api/bot-agent', async (req, res) => {
4009
4173
  // 任务)。手动的 pty/tmux/herdr/zellij override 不受影响(它们不会是 riff)。
4010
4174
  delete entry.backendType;
4011
4175
  }
4012
- return { write: true, result: null };
4176
+ return { write: true, result: { nextReasoningEffort } };
4013
4177
  });
4014
4178
  if (!r.ok)
4015
4179
  return jsonRes(res, 400, { ok: false, error: r.reason });
4180
+ if (r.result.error) {
4181
+ return jsonRes(res, 400, {
4182
+ ok: false,
4183
+ error: r.result.error,
4184
+ message: `模型 ${model || '(Codex 默认模型)'} 不支持当前思考强度`,
4185
+ });
4186
+ }
4016
4187
  const bot = getBot(larkAppId);
4017
4188
  bot.config.cliId = selected.cliId;
4018
4189
  bot.config.cliRuntime = nextRuntime;
@@ -4022,6 +4193,16 @@ ipcRoute('PUT', '/api/bot-agent', async (req, res) => {
4022
4193
  else
4023
4194
  bot.config.wrapperCli = undefined;
4024
4195
  bot.config.model = model || undefined;
4196
+ if (!supportsReasoningEffort)
4197
+ bot.config.reasoningEffort = undefined;
4198
+ else
4199
+ bot.config.reasoningEffort = r.result.nextReasoningEffort ?? undefined;
4200
+ // Mirror the entry write: non-dsh clears it, dsh with an explicit field
4201
+ // takes the parsed value, dsh without the field preserves the existing one.
4202
+ if (!supportsTurnTimeout)
4203
+ bot.config.turnTimeoutMs = undefined;
4204
+ else if (turnTimeoutFieldPresent)
4205
+ bot.config.turnTimeoutMs = nextTurnTimeoutMs;
4025
4206
  if (readIsolationCleared)
4026
4207
  bot.config.readIsolation = false;
4027
4208
  if (selected.cliId === 'riff') {
@@ -4041,6 +4222,8 @@ ipcRoute('PUT', '/api/bot-agent', async (req, res) => {
4041
4222
  cliPathOverride: nextRuntime ? null : nextLegacyPath ?? null,
4042
4223
  wrapperCli: selected.wrapperCli ?? null,
4043
4224
  model: model || null,
4225
+ reasoningEffort: supportsReasoningEffort ? bot.config.reasoningEffort ?? null : null,
4226
+ turnTimeoutMs: supportsTurnTimeout ? bot.config.turnTimeoutMs ?? null : null,
4044
4227
  selectionKey,
4045
4228
  closedMismatchedSessions,
4046
4229
  // Report the (possibly auto-cleared) read-isolation state + whether the new
@@ -4056,9 +4239,100 @@ ipcRoute('PUT', '/api/bot-agent', async (req, res) => {
4056
4239
  });
4057
4240
  });
4058
4241
  });
4059
- // Per-bot 私聊单聊模式 p2pMode。Body `{ p2pMode: 'chat' | 'thread' }`:
4242
+ // ─── 会话群标签授权(feed-group OAuth,Dashboard 一站式流程)────────────────
4243
+ // POST /api/oauth-callback {url} — dashboard 的 /oauth/callback 接收页把回调
4244
+ // URL 广播给各 daemon;state 在本进程 pendingLogins 里的那个完成 code→token
4245
+ // 交换,其它 daemon 返回 matched:false 让 dashboard 继续尝试下一个。
4246
+ ipcRoute('POST', '/api/oauth-callback', async (req, res) => {
4247
+ let body;
4248
+ try {
4249
+ body = await readJsonBody(req);
4250
+ }
4251
+ catch {
4252
+ return jsonRes(res, 400, { ok: false, error: 'bad_json' });
4253
+ }
4254
+ if (typeof body.url !== 'string' || !body.url.trim()) {
4255
+ return jsonRes(res, 400, { ok: false, error: 'url_required' });
4256
+ }
4257
+ const result = await tryHandleCallbackUrl(body.url.trim());
4258
+ if (!result)
4259
+ return jsonRes(res, 200, { ok: false, matched: false, message: 'not a callback url' });
4260
+ jsonRes(res, 200, { ok: result.ok, matched: result.matched, message: result.message });
4261
+ });
4262
+ // POST /api/session-group-tag-auth — 生成带 feed-group scope 的授权链接。
4263
+ // state 存本 daemon 进程内存,回调必须经由上面的 /api/oauth-callback 回到
4264
+ // 同一进程完成,故链接生成与回调处理都放 IPC 侧。
4265
+ ipcRoute('POST', '/api/session-group-tag-auth', async (_req, res) => {
4266
+ if (!cachedLarkAppId)
4267
+ return jsonRes(res, 503, { error: 'larkAppId_not_set' });
4268
+ try {
4269
+ const cfg = getBot(cachedLarkAppId).config;
4270
+ const { authUrl } = generateAuthUrl(cfg.larkAppId, cfg.larkAppSecret, normalizeBrand(cfg.brand), FEED_GROUP_OAUTH_SCOPES);
4271
+ jsonRes(res, 200, { ok: true, authUrl });
4272
+ }
4273
+ catch (e) {
4274
+ jsonRes(res, 500, { ok: false, error: e?.message ?? String(e) });
4275
+ }
4276
+ });
4277
+ // GET /api/session-group-tag-status — 标签授权状态(Dashboard 徽标)。
4278
+ ipcRoute('GET', '/api/session-group-tag-status', async (_req, res) => {
4279
+ if (!cachedLarkAppId)
4280
+ return jsonRes(res, 503, { error: 'larkAppId_not_set' });
4281
+ try {
4282
+ const cfg = getBot(cachedLarkAppId).config;
4283
+ const status = getFeedGroupAuthStatus(cfg.larkAppId, normalizeBrand(cfg.brand));
4284
+ jsonRes(res, 200, { ok: true, ...status, tagMode: cfg.sessionGroup?.tag?.mode ?? 'feed-group' });
4285
+ }
4286
+ catch (e) {
4287
+ jsonRes(res, 500, { ok: false, error: e?.message ?? String(e) });
4288
+ }
4289
+ });
4290
+ // PUT /api/session-group-tag-config — 会话群标签模式(Dashboard tag mode
4291
+ // selector,PR review:授权行必须与实际 tagMode 一致)。Body `{ mode }`:
4292
+ // 'feed-group'(默认,个人侧边栏分组,需一次 OAuth,任何租户可用)|
4293
+ // 'chat-tag'(应用租户身份,无需用户授权,但部分租户权限目录无该 scope)|
4294
+ // 'off'。写 bots.json 的 sessionGroup.tag.mode 并热更内存注册表,与
4295
+ // /botconfig 同一持久化通道。
4296
+ ipcRoute('PUT', '/api/session-group-tag-config', async (req, res) => {
4297
+ if (!cachedLarkAppId)
4298
+ return jsonRes(res, 503, { error: 'larkAppId_not_set' });
4299
+ let body;
4300
+ try {
4301
+ body = await readJsonBody(req);
4302
+ }
4303
+ catch {
4304
+ return jsonRes(res, 400, { ok: false, error: 'bad_json' });
4305
+ }
4306
+ const mode = body.mode === 'chat-tag' || body.mode === 'feed-group' || body.mode === 'off'
4307
+ ? body.mode : undefined;
4308
+ if (!mode)
4309
+ return jsonRes(res, 400, { ok: false, error: 'invalid_mode' });
4310
+ try {
4311
+ const bot = getBot(cachedLarkAppId);
4312
+ const r = await rmwBotEntry(cachedLarkAppId, (entry) => {
4313
+ if (!entry.sessionGroup || typeof entry.sessionGroup !== 'object')
4314
+ entry.sessionGroup = {};
4315
+ if (!entry.sessionGroup.tag || typeof entry.sessionGroup.tag !== 'object')
4316
+ entry.sessionGroup.tag = {};
4317
+ entry.sessionGroup.tag.mode = mode;
4318
+ return { write: true, result: mode };
4319
+ });
4320
+ if (!r.ok)
4321
+ return jsonRes(res, 400, { ok: false, error: r.reason });
4322
+ bot.config.sessionGroup = {
4323
+ ...(bot.config.sessionGroup ?? {}),
4324
+ tag: { ...(bot.config.sessionGroup?.tag ?? {}), mode },
4325
+ };
4326
+ jsonRes(res, 200, { ok: true, tagMode: mode });
4327
+ }
4328
+ catch (e) {
4329
+ jsonRes(res, 500, { ok: false, error: e?.message ?? String(e) });
4330
+ }
4331
+ });
4332
+ // Per-bot 私聊单聊模式 p2pMode。Body `{ p2pMode: 'chat' | 'thread' | 'group' }`:
4060
4333
  // • 'chat'(默认) → 私聊走扁平连续 chat-scope 会话
4061
4334
  // • 'thread' → 显式回到每条 DM 独立 thread-scope 会话
4335
+ // • 'group' → 每条顶层 DM 自动建专属会话群并把会话落进去
4062
4336
  // 走 applyConfigField(与 /botconfig 同一写盘 + 热更新路径),保证一致。
4063
4337
  ipcRoute('PUT', '/api/bot-p2p-mode', async (req, res) => {
4064
4338
  if (!cachedLarkAppId)
@@ -4073,13 +4347,37 @@ ipcRoute('PUT', '/api/bot-p2p-mode', async (req, res) => {
4073
4347
  const spec = findConfigField('p2pMode');
4074
4348
  if (!spec)
4075
4349
  return jsonRes(res, 500, { ok: false, error: 'spec_missing' });
4076
- // 只有 'thread' 有意义;其它(含 'chat',新默认)一律清回默认,bots.json 保持干净。
4077
- const value = body.p2pMode === 'thread' ? 'thread' : null;
4350
+ // 只有 'thread' / 'group' 有意义;其它(含 'chat',新默认)一律清回默认,bots.json 保持干净。
4351
+ const value = body.p2pMode === 'thread' ? 'thread' : body.p2pMode === 'group' ? 'group' : null;
4078
4352
  const r = await applyConfigField(cachedLarkAppId, spec, value);
4079
4353
  if (!r.ok)
4080
4354
  return jsonRes(res, 400, { ok: false, error: r.reason });
4081
4355
  jsonRes(res, 200, { ok: true, p2pMode: value ?? 'chat' });
4082
4356
  });
4357
+ // Per-bot 每轮上下文注入方式 envelopeInjection(#794)。Body `{ envelopeInjection: 'auto'|'off'|'' }`:
4358
+ // • 'auto' → 支持的 CLI(claude-code)把 reminder/whiteboard 经 UserPromptSubmit
4359
+ // hook 注入为 system-reminder,user turn 只留消息本身;不支持的自动回退内联
4360
+ // • 'off'/其它 → 内联 envelope(历史行为,默认)
4361
+ // 走 applyConfigField(与 /botconfig 同一写盘 + 热更新路径),下一个 follow-up turn 生效。
4362
+ ipcRoute('PUT', '/api/bot-envelope-injection', async (req, res) => {
4363
+ if (!cachedLarkAppId)
4364
+ return jsonRes(res, 503, { error: 'larkAppId_not_set' });
4365
+ let body;
4366
+ try {
4367
+ body = await readJsonBody(req);
4368
+ }
4369
+ catch {
4370
+ return jsonRes(res, 400, { ok: false, error: 'bad_json' });
4371
+ }
4372
+ const spec = findConfigField('envelopeInjection');
4373
+ if (!spec)
4374
+ return jsonRes(res, 500, { ok: false, error: 'spec_missing' });
4375
+ const value = body.envelopeInjection === 'auto' ? 'auto' : null;
4376
+ const r = await applyConfigField(cachedLarkAppId, spec, value);
4377
+ if (!r.ok)
4378
+ return jsonRes(res, 400, { ok: false, error: r.reason });
4379
+ jsonRes(res, 200, { ok: true, envelopeInjection: value ?? 'off' });
4380
+ });
4083
4381
  // Per-bot 内置技能注入模式 skillInjection。Body `{ skillInjection: 'global'|'prompt'|'off'|'' }`:
4084
4382
  // • 'global'|'prompt'|'off' → 显式覆盖本 bot
4085
4383
  // • ''/其它 → 清回机器级默认(config.json skills.builtinInjection)
@@ -4236,6 +4534,56 @@ ipcRoute('PUT', '/api/bot-launch-shell', async (req, res) => {
4236
4534
  return jsonRes(res, 400, { ok: false, error: r.reason });
4237
4535
  jsonRes(res, 200, { ok: true, launchShell: value ?? '' });
4238
4536
  });
4537
+ ipcRoute('PUT', '/api/bot-feedback', async (req, res) => {
4538
+ if (!cachedLarkAppId)
4539
+ return jsonRes(res, 503, { error: 'larkAppId_not_set' });
4540
+ let body;
4541
+ try {
4542
+ body = await readJsonBody(req);
4543
+ }
4544
+ catch {
4545
+ return jsonRes(res, 400, { ok: false, error: 'bad_json' });
4546
+ }
4547
+ const spec = findConfigField('feedback');
4548
+ if (!spec)
4549
+ return jsonRes(res, 500, { ok: false, error: 'spec_missing' });
4550
+ const raw = typeof body.feedback === 'string' ? body.feedback : '';
4551
+ let value = null;
4552
+ if (raw.trim()) {
4553
+ const coerced = coerceConfigValue(spec, raw);
4554
+ if (!coerced.ok)
4555
+ return jsonRes(res, 400, { ok: false, error: coerced.reason });
4556
+ value = coerced.value;
4557
+ }
4558
+ const r = await applyConfigField(cachedLarkAppId, spec, value);
4559
+ if (!r.ok)
4560
+ return jsonRes(res, 400, { ok: false, error: r.reason });
4561
+ jsonRes(res, 200, { ok: true, feedback: value });
4562
+ });
4563
+ ipcRoute('PUT', '/api/chat-feedback/:chatId', async (req, res, params) => {
4564
+ if (!cachedLarkAppId)
4565
+ return jsonRes(res, 503, { ok: false, error: 'larkAppId_not_set' });
4566
+ let body;
4567
+ try {
4568
+ body = await readJsonBody(req);
4569
+ }
4570
+ catch {
4571
+ return jsonRes(res, 400, { ok: false, error: 'bad_json' });
4572
+ }
4573
+ const feedback = body.feedback === null || body.feedback === undefined ? null : body.feedback;
4574
+ const result = await setChatFeedbackPolicy(cachedLarkAppId, decodeURIComponent(params.chatId), feedback);
4575
+ if (!result.ok)
4576
+ return jsonRes(res, result.reason === 'bot_not_registered' ? 404 : 400, { ok: false, error: result.reason });
4577
+ jsonRes(res, 200, { ok: true, feedback });
4578
+ });
4579
+ ipcRoute('GET', '/api/feedback-effective', async (req, res) => {
4580
+ if (!cachedLarkAppId)
4581
+ return jsonRes(res, 503, { ok: false, error: 'larkAppId_not_set' });
4582
+ const chatId = new URL(req.url ?? '/', 'http://localhost').searchParams.get('chatId') || undefined;
4583
+ jsonRes(res, 200, { ok: true, trace: traceFeedbackPolicyForDelivery({
4584
+ dataDir: config.session.dataDir, larkAppId: cachedLarkAppId, chatId, bot: getBot(cachedLarkAppId).config,
4585
+ }) });
4586
+ });
4239
4587
  // Per-bot 环境变量 env。Body `{ env: string }`(原始 JSON 文本,如
4240
4588
  // `{"ANTHROPIC_BASE_URL":"…","ANTHROPIC_AUTH_TOKEN":"…"}` 让本 bot 走 GLM/第三方
4241
4589
  // 服务商):空白 → 清除;否则按 json kind 解析 + sanitizePerBotEnv 过滤后落盘。