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
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Session-group avatar branding (p2pMode='group').
3
+ *
4
+ * Zero-permission visual "tag": every session group gets a distinctive
5
+ * built-in avatar (purple gradient + white bot bubble), so bot session groups
6
+ * are recognizable at a glance in the chat list. This works with scopes
7
+ * botmux already holds (im image upload + chat update, and the bot owns its
8
+ * session groups) — no tenant tag catalog, no user OAuth, no console visit.
9
+ *
10
+ * The PNG ships inline (base64, ~3.4KB). It is uploaded once per bot with
11
+ * image_type='avatar' and the resulting image_key is cached in
12
+ * `${dataDir}/session-avatar-cache-${appId}.json`; every birth then only
13
+ * costs one chat.update. All paths are best-effort fire-and-forget.
14
+ */
15
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
16
+ import { join, dirname } from 'node:path';
17
+ import { getBot, getBotClient } from '../bot-registry.js';
18
+ import { config } from '../config.js';
19
+ import { logger } from '../utils/logger.js';
20
+ /** 360×360 official botmux "bm" gradient logo on white (user-picked option A). */
21
+ const AVATAR_PNG_BASE64 = 'iVBORw0KGgoAAAANSUhEUgAAAWgAAAFoCAIAAAD1h/aCAACIbElEQVR42u39ebzt+VUWCD/P+v723me8Q9WtuTJU5onMgQwGiAKCCKI2UUBJ+zqAgqitQIvS2AqCvP2+OL3qx6Eb0AalISAIhECCYBIImclcFEmqKjXm1q07n3P2/n3X03+s9f3tU8LbDEkl9576LkOsnDr33HvP2Xv91nrWM1ASevXq1ev3Uta/Bb169eqNo1evXr1x9OrVqzeOXr169cbRq1ev3jh69erVqzeOXr169cbRq1ev3jh69erVG0evXr164+jVq1ev3jh69erVG0evXr164+jVq1dvHL169eqNo1evXr164+jVq1dvHL169eqNo1evXr1x9OrVqzeOXr169cbRq1evXr1x9OrVqzeOXr169cbRq1ev3jh69erVG0evXr169cbRq1ev3jh69erVG0evXr164+jVq1dvHL169erVG0evXr164+jVq1dvHL169eqNo1evXr1x9OrVq1dvHL169eqNo1evXr1x9OrVqzeOXr169cbRq1ev3jh69erVqzeOXr169cbRq1ev3jh69erVG0evXr164+jVq1ev3jh69erVG0evXr164+jVq1dvHL169eqNo1evXr164+jVq1dvHL169eqNo1evXr1x9OrVqzeOXr169eqNo1evXr1x9OrVqzeOXr169cbRq1ev3jh69erVG0evXr169cbRq1ev3jh69erVG0evXr164+jVq1dvHL169erVG0evXr164+jVq1dvHL169eqNo1evXr1x9OrVq1dvHL169eqNo1evXr1x9OrVqzeOXr169cbRq1evXr1x9OrVqzeOXr169cbRq1ev3jh69ep1FGro34LfvgQd+m8AJACAIAD2b1Cv3jh6Tc1C7Z8JsrWJ31Lu+flW+net12OxqPV75THcMRwQWA5/RJfO6uyDdbmncQkzzRbcPDbsnOTGDqxEP5Gc7jAD+87Xq08cj6GWIchzcBiXungvP/xr/ok7ePounL5Pp+8fx5W8gjPOZhq2tH1itnUM19+ia59cn/nS2Y1P0mwBgHWElbbO9OrVJ44jPGWo7RoPfUR3vEW3/wpP/6ZOP6hLl1c00CSDKJhkEjBKdYnlPvYuiWW47pbhSc8ZXvhFevbn4tqbCgCvMOsISK/eOI5u14jl4qGP4Vd/SB96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jjdcz5tvwTXX6+Q1OHXjI36zsN5hFzP+lt6xVvy63j/yXUW/NvpHx/qwuCL2q/ZrlWFrMWwYjkE3ki8chucCzwRuapFYeqzqRHvj+LQuMnF+tUe+1qrLxfMXcfEyDvZxYQ+nH/az53h5r9YRCPYXsTXnsU0e27VrT2FrQ4sFt3cw30AZHsG9CISVhiMrk/hUby6pmHWBuEQ+JFwEHnQ/u6rFeGo+nAKOA9cAg5LlMUYK7WP4+9Ybx2fixSrgkA729+4P9QieVpiGonEf+zLy+/huTgMIf6cuo4zafKx/l3vjuDJWbj1iZMA0LDzyh5Nq/UfSLnqn+NRiH7/lu75uEv073RtHr169fv/VQbNevXr1xtGrV6/eOHr16tUbR69evXrj6NWrV28cvXr16tUbR69evXrj6NWrV28cvXr16o2jV69evXH06tWrV28cvXr16o2jV69evXH06tWrN45evXr1xtGrV69evXH06tWrN45evXr1xtGrV6/eOHr16tUbR69evXrj6NWrV6/eOHr16tUbR69evXrj6NWrV28cvXr16o2jV69evXrj6NWrV28cvXr16o2jV69evXH06tWrN45evXr16o2jV69evXH06tWrN45evXr1xtGrV6/eOHr16tWrN45evXr1xtGrV6/eOHr16tUbR69evXrj6NWrV28cvXr16tUbR69evXrj6NWrV28cvXr16o2jV69evXH06tWrV28cvXr16o2jV69evXH06tWrN45evXr1xtGrV69evXH06tWrN45evXr1xtGrV6/eOHr16tUbR69evXr1xtGrV6/eOHr16tUbR69evXrj6NWrV28cvXr16o2jV69evXrj6NWrV28cvXr16o2jV69evXH06tWrN45evXr16o2jV69evXH06tWrN45evXr1xtGrV6/eOHr16tWrN45evXr1xtGrV6/eOHr16tUbR69evXrj6NWrV6/eOHr16tUbR69evXrj6NWrV28cvXr16o2jV69ej836vwHadYXzPOgOmQAAAABJRU5ErkJggg==';
22
+ function cachePath(appId) {
23
+ return join(config.session.dataDir, `session-avatar-cache-${appId}.json`);
24
+ }
25
+ function loadCache(appId) {
26
+ try {
27
+ const fp = cachePath(appId);
28
+ if (existsSync(fp))
29
+ return JSON.parse(readFileSync(fp, 'utf-8'));
30
+ }
31
+ catch { /* corrupted cache → start fresh */ }
32
+ return {};
33
+ }
34
+ function saveCache(appId, cache) {
35
+ try {
36
+ const fp = cachePath(appId);
37
+ mkdirSync(dirname(fp), { recursive: true });
38
+ writeFileSync(fp, JSON.stringify(cache, null, 2), 'utf-8');
39
+ }
40
+ catch (err) {
41
+ logger.warn(`[session-avatar] cache persist failed: ${err}`);
42
+ }
43
+ }
44
+ /** Upload the built-in avatar once per bot; cached image_key thereafter. */
45
+ async function ensureAvatarImageKey(larkAppId) {
46
+ const cache = loadCache(larkAppId);
47
+ if (cache.imageKey)
48
+ return cache.imageKey;
49
+ try {
50
+ const client = getBotClient(larkAppId);
51
+ // SDK returns { image_key } directly (not wrapped in { code, data }) —
52
+ // same contract as client.ts uploadImage, but with image_type 'avatar'.
53
+ const res = await client.im.v1.image.create({
54
+ data: { image_type: 'avatar', image: Buffer.from(AVATAR_PNG_BASE64, 'base64') },
55
+ });
56
+ const imageKey = res?.image_key;
57
+ if (!imageKey)
58
+ throw new Error(`no image_key in response (${JSON.stringify(res)})`);
59
+ cache.imageKey = imageKey;
60
+ saveCache(larkAppId, cache);
61
+ logger.info(`[session-avatar] uploaded avatar for ${larkAppId} → ${imageKey}`);
62
+ return imageKey;
63
+ }
64
+ catch (err) {
65
+ logger.warn(`[session-avatar] avatar upload failed: ${err}`);
66
+ return null;
67
+ }
68
+ }
69
+ /**
70
+ * Apply the session-group avatar to a freshly-born group. Fire-and-forget —
71
+ * never throws; a failure just leaves the default Feishu group avatar.
72
+ */
73
+ export async function applySessionGroupAvatar(larkAppId, chatId) {
74
+ try {
75
+ const cfg = getBot(larkAppId).config;
76
+ if (cfg.sessionGroup?.avatar === 'off')
77
+ return;
78
+ const imageKey = await ensureAvatarImageKey(larkAppId);
79
+ if (!imageKey)
80
+ return;
81
+ const client = getBotClient(larkAppId);
82
+ const res = await client.im.v1.chat.update({
83
+ path: { chat_id: chatId },
84
+ data: { avatar: imageKey },
85
+ });
86
+ if (res?.code !== 0 && res?.code !== undefined) {
87
+ logger.warn(`[session-avatar] chat.update avatar failed for ${chatId.substring(0, 12)}: ${res?.msg} (code ${res?.code})`);
88
+ return;
89
+ }
90
+ logger.info(`[session-avatar] applied to ${chatId.substring(0, 12)}`);
91
+ }
92
+ catch (err) {
93
+ logger.warn(`[session-avatar] applying to ${chatId.substring(0, 12)} threw: ${err}`);
94
+ }
95
+ }
96
+ //# sourceMappingURL=session-group-avatar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-group-avatar.js","sourceRoot":"","sources":["../../src/services/session-group-avatar.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Child env for the one-shot title call — the SAME security boundary as every
3
+ * other CLI child the daemon spawns (PR review P2): `redactChildEnv` strips
4
+ * daemon-only secrets (LARK_APP_SECRET, GITHUB_TOKEN, tmux client vars, Claude
5
+ * session markers) and `sanitizePerBotEnv(cfg.env)` layers the bot's own
6
+ * provider environment (base URL / auth token) on top so multi-provider bots
7
+ * title through their own account instead of the daemon's. Exported for the
8
+ * env-boundary regression tests.
9
+ */
10
+ /**
11
+ * Resolve the one-shot launch with the SAME launcher semantics as the formal
12
+ * CLI spawn path (PR review): `wrapperCli` goes through buildWrappedLaunch —
13
+ * the shared builder that knows the gateway specifics (ttadk needs
14
+ * `-m <model> --skip-check` or it opens an interactive model selector /
15
+ * preflight and a non-TTY execFile hangs to timeout; aiden strips args it
16
+ * rejects; cjadk rewrites codex config args) — plus wrapperLaunchEnv for the
17
+ * wrapper's non-interactive env knobs (CJADK_INTERACTIVE=0). Without a
18
+ * wrapper, `cliPathOverride` (registerBot enforces it as an exact shadow of
19
+ * cliRuntime.executable, so runtime configs are covered transitively)
20
+ * replaces the template bin; otherwise the template runs verbatim. Exported
21
+ * for tests.
22
+ */
23
+ export declare function resolveOneShotCommand(cfg: {
24
+ wrapperCli?: string;
25
+ cliPathOverride?: string;
26
+ model?: string;
27
+ }, template: readonly string[]): {
28
+ argv: string[];
29
+ env?: Record<string, string>;
30
+ };
31
+ export declare function buildOneShotEnv(botEnv: unknown): NodeJS.ProcessEnv;
32
+ export declare function buildTitlePrompt(text: string, maxLen: number, locale: string): string;
33
+ /** Extract a plausible title from one-shot CLI stdout: last non-empty line
34
+ * (codex/opencode prepend progress logs; claude/gemini print the bare
35
+ * answer), stripped of quotes/markdown and length-capped. Two passes: a
36
+ * strict pass drops known log-line shapes; if that filters EVERYTHING (an
37
+ * output shape we didn't predict), a lenient pass takes the last line that
38
+ * still looks like prose — never let over-filtering blank a real answer. */
39
+ export declare function sanitizeTitleOutput(stdout: string, maxLen: number): string | null;
40
+ /** Fire-and-forget: generate an AI title for a freshly-born session group and
41
+ * rename the chat (+ session record) when it lands. */
42
+ export declare function scheduleSessionGroupTitle(opts: {
43
+ larkAppId: string;
44
+ chatId: string;
45
+ userText: string;
46
+ }): void;
47
+ //# sourceMappingURL=session-group-title.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-group-title.d.ts","sourceRoot":"","sources":["../../src/services/session-group-title.ts"],"names":[],"mappings":"AA8CA;;;;;;;;GAQG;AACH;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EACtE,QAAQ,EAAE,SAAS,MAAM,EAAE,GAC1B;IAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CASlD;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC,UAAU,CASlE;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAMrF;AAYD;;;;;6EAK6E;AAC7E,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAuBjF;AAED;wDACwD;AACxD,wBAAgB,yBAAyB,CAAC,IAAI,EAAE;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,IAAI,CAuFP"}
@@ -0,0 +1,226 @@
1
+ /**
2
+ * Async AI title for session groups (p2pMode='group', naming.mode='ai-summary').
3
+ *
4
+ * Two-phase naming: the group is created instantly with a truncated
5
+ * placeholder name; this module then runs ONE headless single-turn call
6
+ * through the bot's own CLI to produce a short title and renames the chat
7
+ * when it lands. Fire-and-forget — every failure path simply keeps the
8
+ * placeholder, never blocks or breaks the conversation.
9
+ *
10
+ * The one-shot command is a small per-cliId argv template (print/exec modes
11
+ * of the CLIs botmux already drives). CLIs without a known print mode
12
+ * degrade to the placeholder silently.
13
+ */
14
+ import { execFile } from 'node:child_process';
15
+ import { tmpdir } from 'node:os';
16
+ import { getBot } from '../bot-registry.js';
17
+ import { redactChildEnv } from '../utils/child-env.js';
18
+ import { sanitizePerBotEnv } from '../core/per-bot-env.js';
19
+ import { buildWrappedLaunch, wrapperLaunchEnv } from '../setup/cli-selection.js';
20
+ import { renameChat } from './groups-store.js';
21
+ import { getSessionGroup, markSessionGroupTitled, touchSessionGroup } from './session-groups-store.js';
22
+ import * as sessionStore from './session-store.js';
23
+ import { updateSessionTitle } from '../core/session-title.js';
24
+ import { localeForBot } from '../i18n/index.js';
25
+ import { logger } from '../utils/logger.js';
26
+ // Generous: one-shot CLIs pay cold-start + API latency (codex regularly
27
+ // exceeds 15s); the rename is async so a slow title costs nothing visible.
28
+ const TITLE_TIMEOUT_MS = 45_000;
29
+ const DEFAULT_MAX_LEN = 12;
30
+ /** Per-cliId one-shot print-mode argv template. `argv[0]` is replaced by
31
+ * `cliPathOverride` when configured. Prompt is appended as the last arg. */
32
+ const ONE_SHOT_ARGV = {
33
+ 'claude-code': ['claude', '-p'],
34
+ codex: ['codex', 'exec', '--skip-git-repo-check'],
35
+ // TRAE CLI is a codex fork — same exec surface and bare-answer stdout.
36
+ traex: ['traex', 'exec', '--skip-git-repo-check'],
37
+ opencode: ['opencode', 'run'],
38
+ gemini: ['gemini', '-p'],
39
+ };
40
+ /** One in-flight title job per chat — birth and the heal-on-activity path
41
+ * (handleThreadReply) can otherwise race duplicate CLI calls. */
42
+ const inFlightTitles = new Set();
43
+ /**
44
+ * Child env for the one-shot title call — the SAME security boundary as every
45
+ * other CLI child the daemon spawns (PR review P2): `redactChildEnv` strips
46
+ * daemon-only secrets (LARK_APP_SECRET, GITHUB_TOKEN, tmux client vars, Claude
47
+ * session markers) and `sanitizePerBotEnv(cfg.env)` layers the bot's own
48
+ * provider environment (base URL / auth token) on top so multi-provider bots
49
+ * title through their own account instead of the daemon's. Exported for the
50
+ * env-boundary regression tests.
51
+ */
52
+ /**
53
+ * Resolve the one-shot launch with the SAME launcher semantics as the formal
54
+ * CLI spawn path (PR review): `wrapperCli` goes through buildWrappedLaunch —
55
+ * the shared builder that knows the gateway specifics (ttadk needs
56
+ * `-m <model> --skip-check` or it opens an interactive model selector /
57
+ * preflight and a non-TTY execFile hangs to timeout; aiden strips args it
58
+ * rejects; cjadk rewrites codex config args) — plus wrapperLaunchEnv for the
59
+ * wrapper's non-interactive env knobs (CJADK_INTERACTIVE=0). Without a
60
+ * wrapper, `cliPathOverride` (registerBot enforces it as an exact shadow of
61
+ * cliRuntime.executable, so runtime configs are covered transitively)
62
+ * replaces the template bin; otherwise the template runs verbatim. Exported
63
+ * for tests.
64
+ */
65
+ export function resolveOneShotCommand(cfg, template) {
66
+ const wrapper = cfg.wrapperCli?.trim();
67
+ if (wrapper) {
68
+ const { bin, args } = buildWrappedLaunch(wrapper, template.slice(1), b => b, { ttadkModel: cfg.model });
69
+ return { argv: [bin, ...args], env: wrapperLaunchEnv(wrapper) };
70
+ }
71
+ const override = cfg.cliPathOverride?.trim();
72
+ if (override)
73
+ return { argv: [override, ...template.slice(1)] };
74
+ return { argv: [...template] };
75
+ }
76
+ export function buildOneShotEnv(botEnv) {
77
+ const env = {
78
+ ...redactChildEnv(process.env),
79
+ ...sanitizePerBotEnv(botEnv),
80
+ };
81
+ // Never let the one-shot inherit a botmux session identity (redundant with
82
+ // the marker scrub above, kept as an explicit invariant).
83
+ delete env.BOTMUX_SESSION_ID;
84
+ return env;
85
+ }
86
+ export function buildTitlePrompt(text, maxLen, locale) {
87
+ const excerpt = text.replace(/\s+/g, ' ').trim().slice(0, 500);
88
+ if (locale === 'en') {
89
+ return `Summarize the following request as a conversation title of at most ${maxLen} characters. Output ONLY the title itself — no quotes, no trailing period, no explanation:\n\n${excerpt}`;
90
+ }
91
+ return `用不超过${maxLen}个字总结下面这条请求,作为会话标题。只输出标题本身,不要引号、句号或任何解释:\n\n${excerpt}`;
92
+ }
93
+ /** Strip decoration from a candidate title line. */
94
+ function cleanTitleLine(raw) {
95
+ return raw
96
+ .replace(/^["'“”‘’`#*\s]+/, '')
97
+ // Trailing quotes/backticks and sentence punctuation interleave (e.g.
98
+ // `标题"。`) — strip them as one class so the order can't matter.
99
+ .replace(/["'“”‘’`。.!!??\s]+$/, '')
100
+ .trim();
101
+ }
102
+ /** Extract a plausible title from one-shot CLI stdout: last non-empty line
103
+ * (codex/opencode prepend progress logs; claude/gemini print the bare
104
+ * answer), stripped of quotes/markdown and length-capped. Two passes: a
105
+ * strict pass drops known log-line shapes; if that filters EVERYTHING (an
106
+ * output shape we didn't predict), a lenient pass takes the last line that
107
+ * still looks like prose — never let over-filtering blank a real answer. */
108
+ export function sanitizeTitleOutput(stdout, maxLen) {
109
+ const all = stdout.split('\n').map(l => l.trim()).filter(Boolean);
110
+ // Obvious non-answers in ANY pass: dividers, bare numbers, hook chatter,
111
+ // lines with no letter/digit at all.
112
+ const junk = (l) => !/[\p{L}\p{N}]/u.test(l) || /^[-=—_\s]+$/.test(l) || /^\d[\d,.\s]*$/.test(l) || /^hook:/i.test(l);
113
+ const strict = all
114
+ // codex exec progress lines look like "[2026-08-05T…] tokens used: 123" —
115
+ // drop bracketed/log-ish lines so the answer line survives as the last one.
116
+ .filter(l => !junk(l) && !/^\[.*\]/.test(l) && !/^(tokens used|thinking|codex$|user$)/i.test(l));
117
+ // Lenient fallback: keep anything prose-like, including bracket-prefixed
118
+ // lines the strict pass dropped (unpredicted "[ts] answer" shapes).
119
+ const lenient = all.filter(l => !junk(l));
120
+ const raw = strict.length ? strict[strict.length - 1]
121
+ // The lenient pick may still carry a bracketed log prefix — strip it so a
122
+ // "[ts] answer" line yields the answer, not the timestamp.
123
+ : lenient.length ? lenient[lenient.length - 1].replace(/^\[[^\]]*\]\s*/, '') : '';
124
+ const cleaned = cleanTitleLine(raw);
125
+ if (!cleaned)
126
+ return null;
127
+ // Hard cap: maxLen is advisory to the model; enforce a generous ceiling so
128
+ // a slightly-long but good title still beats the placeholder.
129
+ const capped = Array.from(cleaned).slice(0, Math.max(maxLen * 2, 16)).join('');
130
+ return capped || null;
131
+ }
132
+ /** Fire-and-forget: generate an AI title for a freshly-born session group and
133
+ * rename the chat (+ session record) when it lands. */
134
+ export function scheduleSessionGroupTitle(opts) {
135
+ const { larkAppId, chatId, userText } = opts;
136
+ if (inFlightTitles.has(chatId))
137
+ return;
138
+ inFlightTitles.add(chatId);
139
+ void (async () => {
140
+ try {
141
+ const cfg = getBot(larkAppId).config;
142
+ const sg = cfg.sessionGroup ?? {};
143
+ if ((sg.naming?.mode ?? 'ai-summary') !== 'ai-summary')
144
+ return;
145
+ if (!userText.trim())
146
+ return;
147
+ const maxLen = sg.naming?.maxLen && sg.naming.maxLen > 0 ? sg.naming.maxLen : DEFAULT_MAX_LEN;
148
+ const template = ONE_SHOT_ARGV[cfg.cliId];
149
+ if (!template) {
150
+ logger.info(`[session-group] no one-shot template for cliId=${cfg.cliId}; keeping placeholder title`);
151
+ return;
152
+ }
153
+ const { argv, env: wrapperEnv } = resolveOneShotCommand(cfg, template);
154
+ const prompt = buildTitlePrompt(userText, maxLen, localeForBot(larkAppId));
155
+ const runOnce = () => new Promise((resolve, reject) => {
156
+ const env = { ...buildOneShotEnv(cfg.env), ...wrapperEnv };
157
+ const child = execFile(argv[0], [...argv.slice(1), prompt], {
158
+ timeout: TITLE_TIMEOUT_MS,
159
+ maxBuffer: 1024 * 1024,
160
+ cwd: tmpdir(),
161
+ env,
162
+ }, (err, out, errOut) => {
163
+ if (err && !out) {
164
+ // Surface stderr — execFile's bare "Command failed: …" hides the
165
+ // actual CLI error (API failures, auth, rate limits).
166
+ const detail = String(errOut ?? '').trim().split('\n').slice(-2).join(' ').slice(0, 200);
167
+ return reject(new Error(`${err.message.split('\n')[0]}${detail ? ` | stderr: ${detail}` : ''}`));
168
+ }
169
+ resolve(String(out ?? ''));
170
+ });
171
+ // CRITICAL: close stdin. codex-family CLIs (codex/traex) treat a piped
172
+ // stdin as "additional input" and BLOCK reading it until EOF — with
173
+ // execFile's default open pipe they hang to the timeout and get killed
174
+ // ("Reading additional input from stdin..."). A TTY stdin (manual
175
+ // testing) skips that path, which is why this only bites under the
176
+ // daemon. Closing stdin is a no-op for CLIs that never read it.
177
+ child.stdin?.end();
178
+ });
179
+ // One-shot CLI calls fail transiently (API hiccups, cold start races) —
180
+ // a single spaced retry recovers most of them without delaying much.
181
+ let stdout;
182
+ try {
183
+ stdout = await runOnce();
184
+ }
185
+ catch (firstErr) {
186
+ logger.info(`[session-group] AI title attempt 1 failed for chat=${chatId.substring(0, 12)} (retrying): ${firstErr}`);
187
+ await new Promise(r => setTimeout(r, 3000));
188
+ stdout = await runOnce();
189
+ }
190
+ const title = sanitizeTitleOutput(stdout, maxLen);
191
+ if (!title) {
192
+ // Log the raw head — an unpredicted output shape is invisible otherwise.
193
+ const rawHead = stdout.replace(/\s+/g, ' ').trim().slice(0, 200);
194
+ logger.info(`[session-group] AI title empty for chat=${chatId.substring(0, 12)}; keeping placeholder (raw: "${rawHead}")`);
195
+ return;
196
+ }
197
+ const prefix = sg.namePrefix ?? '';
198
+ const finalName = `${prefix}${title}`;
199
+ // Reuse the shared renameChat wrapper (membership precheck + error
200
+ // classification) instead of a bespoke chat.update call.
201
+ const r = await renameChat(larkAppId, chatId, finalName);
202
+ if (!r.ok) {
203
+ logger.warn(`[session-group] rename chat=${chatId.substring(0, 12)} failed: ${r.error}${r.detail ? ` (${r.detail})` : ''}`);
204
+ return;
205
+ }
206
+ markSessionGroupTitled(chatId);
207
+ // Best-effort: keep the botmux session title in sync so `botmux list` /
208
+ // dashboard show the same name as the chat (same path as /rename).
209
+ const entry = getSessionGroup(chatId);
210
+ if (entry?.lastSessionId) {
211
+ const session = sessionStore.getSession(entry.lastSessionId);
212
+ if (session)
213
+ updateSessionTitle(session, title, 'system');
214
+ touchSessionGroup(chatId);
215
+ }
216
+ logger.info(`[session-group] titled chat=${chatId.substring(0, 12)} "${finalName}"`);
217
+ }
218
+ catch (err) {
219
+ logger.info(`[session-group] AI title failed for chat=${chatId.substring(0, 12)} (placeholder kept): ${err}`);
220
+ }
221
+ finally {
222
+ inFlightTitles.delete(chatId);
223
+ }
224
+ })();
225
+ }
226
+ //# sourceMappingURL=session-group-title.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-group-title.js","sourceRoot":"","sources":["../../src/services/session-group-title.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ export interface SessionGroupEntry {
2
+ /** The DM user this group was born for (open_id in the bot's app scope). */
3
+ ownerOpenId: string;
4
+ /** Most recent session anchored in this group; same-group resume target. */
5
+ lastSessionId: string;
6
+ /** Epoch ms the group was created. */
7
+ createdAt: number;
8
+ /** Epoch ms of the last observed activity (birth, resume, new session). */
9
+ lastActiveAt: number;
10
+ /** True once the async AI title has been applied to the chat name. */
11
+ titled?: boolean;
12
+ }
13
+ export declare function initSessionGroups(appId: string): void;
14
+ /** Register a freshly-born session group (or overwrite after a re-birth). */
15
+ export declare function registerSessionGroup(chatId: string, entry: Omit<SessionGroupEntry, 'createdAt' | 'lastActiveAt'> & {
16
+ createdAt?: number;
17
+ }): void;
18
+ /** Typing check — the ONLY sanctioned way to tell a session group apart. */
19
+ export declare function isSessionGroup(chatId: string): boolean;
20
+ export declare function getSessionGroup(chatId: string): SessionGroupEntry | undefined;
21
+ /** Point the registry at the session currently living in this group. */
22
+ export declare function touchSessionGroup(chatId: string, lastSessionId?: string): void;
23
+ /** Mark the async AI title as applied (idempotent). */
24
+ export declare function markSessionGroupTitled(chatId: string): void;
25
+ /** Remove a registry entry (group disbanded / bot removed / gc). */
26
+ export declare function removeSessionGroup(chatId: string): void;
27
+ export declare function listSessionGroups(): Array<{
28
+ chatId: string;
29
+ } & SessionGroupEntry>;
30
+ //# sourceMappingURL=session-groups-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-groups-store.d.ts","sourceRoot":"","sources":["../../src/services/session-groups-store.ts"],"names":[],"mappings":"AA2BA,MAAM,WAAW,iBAAiB;IAChC,4EAA4E;IAC5E,WAAW,EAAE,MAAM,CAAC;IACpB,4EAA4E;IAC5E,aAAa,EAAE,MAAM,CAAC;IACtB,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,YAAY,EAAE,MAAM,CAAC;IACrB,sEAAsE;IACtE,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAMD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAIrD;AAyCD,6EAA6E;AAC7E,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,iBAAiB,EAAE,WAAW,GAAG,cAAc,CAAC,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAWhJ;AAED,4EAA4E;AAC5E,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAItD;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAI7E;AAED,wEAAwE;AACxE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAO9E;AAED,uDAAuD;AACvD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAM3D;AAED,oEAAoE;AACpE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAGvD;AAED,wBAAgB,iBAAiB,IAAI,KAAK,CAAC;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,iBAAiB,CAAC,CAIjF"}