botmux 2.106.1-canary.0 → 2.107.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 (357) hide show
  1. package/README.en.md +10 -10
  2. package/README.md +10 -10
  3. package/dist/adapters/backend/sandbox.d.ts +6 -20
  4. package/dist/adapters/backend/sandbox.d.ts.map +1 -1
  5. package/dist/adapters/backend/sandbox.js +26 -150
  6. package/dist/adapters/backend/sandbox.js.map +1 -1
  7. package/dist/adapters/backend/tmux-pipe-backend.d.ts +1 -1
  8. package/dist/adapters/backend/tmux-pipe-backend.js +1 -1
  9. package/dist/adapters/backend/zellij-observe-backend.d.ts +1 -1
  10. package/dist/adapters/backend/zellij-observe-backend.js +1 -1
  11. package/dist/adapters/cli/read-isolation.d.ts +2 -1
  12. package/dist/adapters/cli/read-isolation.d.ts.map +1 -1
  13. package/dist/adapters/cli/read-isolation.js +51 -4
  14. package/dist/adapters/cli/read-isolation.js.map +1 -1
  15. package/dist/bot-registry.d.ts +90 -1
  16. package/dist/bot-registry.d.ts.map +1 -1
  17. package/dist/bot-registry.js +151 -0
  18. package/dist/bot-registry.js.map +1 -1
  19. package/dist/cli/vc-agent.d.ts +2 -0
  20. package/dist/cli/vc-agent.d.ts.map +1 -0
  21. package/dist/cli/vc-agent.js +331 -0
  22. package/dist/cli/vc-agent.js.map +1 -0
  23. package/dist/cli.d.ts.map +1 -1
  24. package/dist/cli.js +30 -4
  25. package/dist/cli.js.map +1 -1
  26. package/dist/config.d.ts +8 -0
  27. package/dist/config.d.ts.map +1 -1
  28. package/dist/config.js +13 -1
  29. package/dist/config.js.map +1 -1
  30. package/dist/core/command-handler.d.ts.map +1 -1
  31. package/dist/core/command-handler.js +7 -1
  32. package/dist/core/command-handler.js.map +1 -1
  33. package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
  34. package/dist/core/dashboard-ipc-server.js +74 -3
  35. package/dist/core/dashboard-ipc-server.js.map +1 -1
  36. package/dist/core/dashboard-rows.d.ts +6 -0
  37. package/dist/core/dashboard-rows.d.ts.map +1 -1
  38. package/dist/core/dashboard-rows.js +25 -0
  39. package/dist/core/dashboard-rows.js.map +1 -1
  40. package/dist/core/idle-worker-sweeper.d.ts +1 -1
  41. package/dist/core/idle-worker-sweeper.js +1 -1
  42. package/dist/core/passthrough-commands.d.ts.map +1 -1
  43. package/dist/core/passthrough-commands.js +2 -1
  44. package/dist/core/passthrough-commands.js.map +1 -1
  45. package/dist/core/pending-response.d.ts +1 -0
  46. package/dist/core/pending-response.d.ts.map +1 -1
  47. package/dist/core/pending-response.js +1 -0
  48. package/dist/core/pending-response.js.map +1 -1
  49. package/dist/core/resource-monitor/attribution.d.ts +70 -0
  50. package/dist/core/resource-monitor/attribution.d.ts.map +1 -0
  51. package/dist/core/resource-monitor/attribution.js +222 -0
  52. package/dist/core/resource-monitor/attribution.js.map +1 -0
  53. package/dist/core/resource-monitor/procfs.d.ts +22 -0
  54. package/dist/core/resource-monitor/procfs.d.ts.map +1 -0
  55. package/dist/core/resource-monitor/procfs.js +134 -0
  56. package/dist/core/resource-monitor/procfs.js.map +1 -0
  57. package/dist/core/resource-monitor/ring-buffer.d.ts +15 -0
  58. package/dist/core/resource-monitor/ring-buffer.d.ts.map +1 -0
  59. package/dist/core/resource-monitor/ring-buffer.js +61 -0
  60. package/dist/core/resource-monitor/ring-buffer.js.map +1 -0
  61. package/dist/core/resource-monitor/runtime.d.ts +31 -0
  62. package/dist/core/resource-monitor/runtime.d.ts.map +1 -0
  63. package/dist/core/resource-monitor/runtime.js +92 -0
  64. package/dist/core/resource-monitor/runtime.js.map +1 -0
  65. package/dist/core/resource-monitor/top-selector.d.ts +18 -0
  66. package/dist/core/resource-monitor/top-selector.d.ts.map +1 -0
  67. package/dist/core/resource-monitor/top-selector.js +57 -0
  68. package/dist/core/resource-monitor/top-selector.js.map +1 -0
  69. package/dist/core/resource-monitor/types.d.ts +181 -0
  70. package/dist/core/resource-monitor/types.d.ts.map +1 -0
  71. package/dist/core/resource-monitor/types.js +2 -0
  72. package/dist/core/resource-monitor/types.js.map +1 -0
  73. package/dist/core/session-manager.d.ts +4 -2
  74. package/dist/core/session-manager.d.ts.map +1 -1
  75. package/dist/core/session-manager.js +82 -7
  76. package/dist/core/session-manager.js.map +1 -1
  77. package/dist/core/trigger-session.d.ts.map +1 -1
  78. package/dist/core/trigger-session.js +7 -2
  79. package/dist/core/trigger-session.js.map +1 -1
  80. package/dist/core/types.d.ts +4 -3
  81. package/dist/core/types.d.ts.map +1 -1
  82. package/dist/core/types.js.map +1 -1
  83. package/dist/core/worker-pool.d.ts +4 -0
  84. package/dist/core/worker-pool.d.ts.map +1 -1
  85. package/dist/core/worker-pool.js +27 -9
  86. package/dist/core/worker-pool.js.map +1 -1
  87. package/dist/core/zellij-adopt-discovery.js +1 -1
  88. package/dist/core/zellij-adopt-discovery.js.map +1 -1
  89. package/dist/daemon.d.ts +145 -1
  90. package/dist/daemon.d.ts.map +1 -1
  91. package/dist/daemon.js +3441 -98
  92. package/dist/daemon.js.map +1 -1
  93. package/dist/dashboard/bot-payload.d.ts +1 -0
  94. package/dist/dashboard/bot-payload.d.ts.map +1 -1
  95. package/dist/dashboard/bot-payload.js +1 -0
  96. package/dist/dashboard/bot-payload.js.map +1 -1
  97. package/dist/dashboard/federated-group-core.js +1 -1
  98. package/dist/dashboard/federated-group-core.js.map +1 -1
  99. package/dist/dashboard/federation-api.js +1 -1
  100. package/dist/dashboard/resource-monitor-service.d.ts +56 -0
  101. package/dist/dashboard/resource-monitor-service.d.ts.map +1 -0
  102. package/dist/dashboard/resource-monitor-service.js +446 -0
  103. package/dist/dashboard/resource-monitor-service.js.map +1 -0
  104. package/dist/dashboard/settings-write-applier.d.ts +31 -1
  105. package/dist/dashboard/settings-write-applier.d.ts.map +1 -1
  106. package/dist/dashboard/settings-write-applier.js +47 -0
  107. package/dist/dashboard/settings-write-applier.js.map +1 -1
  108. package/dist/dashboard/web/bot-defaults.d.ts.map +1 -1
  109. package/dist/dashboard/web/bot-defaults.js +160 -1
  110. package/dist/dashboard/web/bot-defaults.js.map +1 -1
  111. package/dist/dashboard/web/dashboard-routes.d.ts.map +1 -1
  112. package/dist/dashboard/web/dashboard-routes.js +18 -0
  113. package/dist/dashboard/web/dashboard-routes.js.map +1 -1
  114. package/dist/dashboard/web/i18n.d.ts.map +1 -1
  115. package/dist/dashboard/web/i18n.js +296 -2
  116. package/dist/dashboard/web/i18n.js.map +1 -1
  117. package/dist/dashboard/web/insights.js +19 -19
  118. package/dist/dashboard/web/insights.js.map +1 -1
  119. package/dist/dashboard/web/monitor-room-store.d.ts +20 -0
  120. package/dist/dashboard/web/monitor-room-store.d.ts.map +1 -0
  121. package/dist/dashboard/web/monitor-room-store.js +80 -0
  122. package/dist/dashboard/web/monitor-room-store.js.map +1 -0
  123. package/dist/dashboard/web/monitor-room.d.ts +31 -0
  124. package/dist/dashboard/web/monitor-room.d.ts.map +1 -0
  125. package/dist/dashboard/web/monitor-room.js +393 -0
  126. package/dist/dashboard/web/monitor-room.js.map +1 -0
  127. package/dist/dashboard/web/monitoring-page.d.ts +155 -0
  128. package/dist/dashboard/web/monitoring-page.d.ts.map +1 -0
  129. package/dist/dashboard/web/monitoring-page.js +189 -0
  130. package/dist/dashboard/web/monitoring-page.js.map +1 -0
  131. package/dist/dashboard/web/overview-page.d.ts.map +1 -1
  132. package/dist/dashboard/web/overview-page.js +108 -1
  133. package/dist/dashboard/web/overview-page.js.map +1 -1
  134. package/dist/dashboard/web/preferences.d.ts +3 -0
  135. package/dist/dashboard/web/preferences.d.ts.map +1 -1
  136. package/dist/dashboard/web/preferences.js +18 -0
  137. package/dist/dashboard/web/preferences.js.map +1 -1
  138. package/dist/dashboard/web/session-terminal.d.ts +7 -0
  139. package/dist/dashboard/web/session-terminal.d.ts.map +1 -0
  140. package/dist/dashboard/web/session-terminal.js +17 -0
  141. package/dist/dashboard/web/session-terminal.js.map +1 -0
  142. package/dist/dashboard/web/sessions-page.d.ts.map +1 -1
  143. package/dist/dashboard/web/sessions-page.js +2 -1
  144. package/dist/dashboard/web/sessions-page.js.map +1 -1
  145. package/dist/dashboard/web/sessions.d.ts +4 -0
  146. package/dist/dashboard/web/sessions.d.ts.map +1 -1
  147. package/dist/dashboard/web/sessions.js +100 -19
  148. package/dist/dashboard/web/sessions.js.map +1 -1
  149. package/dist/dashboard/web/settings-page.d.ts.map +1 -1
  150. package/dist/dashboard/web/settings-page.js +101 -46
  151. package/dist/dashboard/web/settings-page.js.map +1 -1
  152. package/dist/dashboard/web/skills-page.js +1 -1
  153. package/dist/dashboard/web/skills-page.js.map +1 -1
  154. package/dist/dashboard/web/substitute-targets.d.ts +30 -0
  155. package/dist/dashboard/web/substitute-targets.d.ts.map +1 -0
  156. package/dist/dashboard/web/substitute-targets.js +99 -0
  157. package/dist/dashboard/web/substitute-targets.js.map +1 -0
  158. package/dist/dashboard/web/ui.d.ts +1 -1
  159. package/dist/dashboard/web/ui.d.ts.map +1 -1
  160. package/dist/dashboard/web/ui.js +4 -1
  161. package/dist/dashboard/web/ui.js.map +1 -1
  162. package/dist/dashboard-web/app.js +3 -3
  163. package/dist/dashboard-web/chunks/bot-defaults-page-OCIHPGEU.js +438 -0
  164. package/dist/dashboard-web/chunks/chunk-3N2PPQVD.js +1 -0
  165. package/dist/dashboard-web/chunks/chunk-3UJYRR2Q.js +37 -0
  166. package/dist/dashboard-web/chunks/{chunk-RRBSPQVK.js → chunk-PE6W3C2C.js} +1 -1
  167. package/dist/dashboard-web/chunks/chunk-QW54DWU3.js +325 -0
  168. package/dist/dashboard-web/chunks/{connectors-WZR7MAXE.js → connectors-IGETYWCP.js} +1 -1
  169. package/dist/dashboard-web/chunks/{groups-page-NK6U5JIU.js → groups-page-MYBS4ZYJ.js} +1 -1
  170. package/dist/dashboard-web/chunks/{insights-page-2TN3ZR33.js → insights-page-UPA32V2S.js} +1 -1
  171. package/dist/dashboard-web/chunks/monitor-room-RFX4HPS5.js +51 -0
  172. package/dist/dashboard-web/chunks/monitoring-page-7T3BESZ2.js +1 -0
  173. package/dist/dashboard-web/chunks/overview-page-LJSBCQW4.js +1 -0
  174. package/dist/dashboard-web/chunks/{roles-page-J6CRSIJ6.js → roles-page-ESURTVQH.js} +1 -1
  175. package/dist/dashboard-web/chunks/{schedules-6RONVOOV.js → schedules-LML2ISOT.js} +1 -1
  176. package/dist/dashboard-web/chunks/sessions-YB73XOTU.js +1 -0
  177. package/dist/dashboard-web/chunks/sessions-page-MCO5QR7Z.js +1 -0
  178. package/dist/dashboard-web/chunks/settings-page-OSDKNVS3.js +2 -0
  179. package/dist/dashboard-web/chunks/skills-page-PXBZJ6P6.js +2 -0
  180. package/dist/dashboard-web/chunks/{team-federation-page-QYAP7XJF.js → team-federation-page-TTPVHFPX.js} +1 -1
  181. package/dist/dashboard-web/chunks/{workflows-2L4DKNCK.js → workflows-FCPM4S4D.js} +1 -1
  182. package/dist/dashboard-web/index.html +2 -1
  183. package/dist/dashboard-web/style.css +940 -24
  184. package/dist/dashboard.js +404 -3
  185. package/dist/dashboard.js.map +1 -1
  186. package/dist/global-config.d.ts +23 -0
  187. package/dist/global-config.d.ts.map +1 -1
  188. package/dist/global-config.js +58 -1
  189. package/dist/global-config.js.map +1 -1
  190. package/dist/i18n/en.d.ts.map +1 -1
  191. package/dist/i18n/en.js +17 -6
  192. package/dist/i18n/en.js.map +1 -1
  193. package/dist/i18n/zh.d.ts.map +1 -1
  194. package/dist/i18n/zh.js +17 -6
  195. package/dist/i18n/zh.js.map +1 -1
  196. package/dist/im/lark/card-builder.d.ts +1 -1
  197. package/dist/im/lark/card-builder.d.ts.map +1 -1
  198. package/dist/im/lark/card-builder.js +19 -1
  199. package/dist/im/lark/card-builder.js.map +1 -1
  200. package/dist/im/lark/card-handler.d.ts +3 -0
  201. package/dist/im/lark/card-handler.d.ts.map +1 -1
  202. package/dist/im/lark/card-handler.js +20 -2
  203. package/dist/im/lark/card-handler.js.map +1 -1
  204. package/dist/im/lark/event-dispatcher.d.ts +13 -0
  205. package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
  206. package/dist/im/lark/event-dispatcher.js +141 -5
  207. package/dist/im/lark/event-dispatcher.js.map +1 -1
  208. package/dist/im/lark/grant-command.d.ts +1 -1
  209. package/dist/im/lark/grant-command.js +1 -1
  210. package/dist/im/lark/message-parser.d.ts +41 -0
  211. package/dist/im/lark/message-parser.d.ts.map +1 -1
  212. package/dist/im/lark/message-parser.js +70 -0
  213. package/dist/im/lark/message-parser.js.map +1 -1
  214. package/dist/im/lark/substitute-command.d.ts +2 -0
  215. package/dist/im/lark/substitute-command.d.ts.map +1 -0
  216. package/dist/im/lark/substitute-command.js +51 -0
  217. package/dist/im/lark/substitute-command.js.map +1 -0
  218. package/dist/mir-prompt.d.ts +16 -0
  219. package/dist/mir-prompt.d.ts.map +1 -0
  220. package/dist/mir-prompt.js +170 -0
  221. package/dist/mir-prompt.js.map +1 -0
  222. package/dist/mir-runner.js +1 -149
  223. package/dist/mir-runner.js.map +1 -1
  224. package/dist/services/deployment-identity.d.ts +1 -1
  225. package/dist/services/deployment-identity.d.ts.map +1 -1
  226. package/dist/services/deployment-identity.js +1 -1
  227. package/dist/services/deployment-identity.js.map +1 -1
  228. package/dist/services/doc-subs-store.js +1 -1
  229. package/dist/services/substitute-chat-toggle-store.d.ts +3 -0
  230. package/dist/services/substitute-chat-toggle-store.d.ts.map +1 -0
  231. package/dist/services/substitute-chat-toggle-store.js +58 -0
  232. package/dist/services/substitute-chat-toggle-store.js.map +1 -0
  233. package/dist/services/substitute-mode-normalize.d.ts +22 -0
  234. package/dist/services/substitute-mode-normalize.d.ts.map +1 -0
  235. package/dist/services/substitute-mode-normalize.js +56 -0
  236. package/dist/services/substitute-mode-normalize.js.map +1 -0
  237. package/dist/services/substitute-mode-store.d.ts +50 -0
  238. package/dist/services/substitute-mode-store.d.ts.map +1 -0
  239. package/dist/services/substitute-mode-store.js +115 -0
  240. package/dist/services/substitute-mode-store.js.map +1 -0
  241. package/dist/services/team-board-store.js +1 -1
  242. package/dist/services/team-board-store.js.map +1 -1
  243. package/dist/services/trigger-types.d.ts +1 -1
  244. package/dist/services/trigger-types.d.ts.map +1 -1
  245. package/dist/services/vc-meeting-runtime-store.d.ts +59 -0
  246. package/dist/services/vc-meeting-runtime-store.d.ts.map +1 -0
  247. package/dist/services/vc-meeting-runtime-store.js +339 -0
  248. package/dist/services/vc-meeting-runtime-store.js.map +1 -0
  249. package/dist/services/voice/index.d.ts +6 -1
  250. package/dist/services/voice/index.d.ts.map +1 -1
  251. package/dist/services/voice/index.js +12 -5
  252. package/dist/services/voice/index.js.map +1 -1
  253. package/dist/setup/lark-scopes.json +5 -0
  254. package/dist/setup/open-platform-automation.d.ts +20 -0
  255. package/dist/setup/open-platform-automation.d.ts.map +1 -1
  256. package/dist/setup/open-platform-automation.js +78 -1
  257. package/dist/setup/open-platform-automation.js.map +1 -1
  258. package/dist/setup/verify-permissions.d.ts +6 -0
  259. package/dist/setup/verify-permissions.d.ts.map +1 -1
  260. package/dist/setup/verify-permissions.js +17 -0
  261. package/dist/setup/verify-permissions.js.map +1 -1
  262. package/dist/types.d.ts +19 -0
  263. package/dist/types.d.ts.map +1 -1
  264. package/dist/utils/daemon-discovery.d.ts +2 -0
  265. package/dist/utils/daemon-discovery.d.ts.map +1 -1
  266. package/dist/utils/daemon-discovery.js +2 -0
  267. package/dist/utils/daemon-discovery.js.map +1 -1
  268. package/dist/vc-agent/cards.d.ts +49 -0
  269. package/dist/vc-agent/cards.d.ts.map +1 -0
  270. package/dist/vc-agent/cards.js +505 -0
  271. package/dist/vc-agent/cards.js.map +1 -0
  272. package/dist/vc-agent/meeting-state.d.ts +39 -0
  273. package/dist/vc-agent/meeting-state.d.ts.map +1 -0
  274. package/dist/vc-agent/meeting-state.js +186 -0
  275. package/dist/vc-agent/meeting-state.js.map +1 -0
  276. package/dist/vc-agent/normalizer.d.ts +13 -0
  277. package/dist/vc-agent/normalizer.d.ts.map +1 -0
  278. package/dist/vc-agent/normalizer.js +470 -0
  279. package/dist/vc-agent/normalizer.js.map +1 -0
  280. package/dist/vc-agent/polling-source.d.ts +64 -0
  281. package/dist/vc-agent/polling-source.d.ts.map +1 -0
  282. package/dist/vc-agent/polling-source.js +181 -0
  283. package/dist/vc-agent/polling-source.js.map +1 -0
  284. package/dist/vc-agent/push-source.d.ts +13 -0
  285. package/dist/vc-agent/push-source.d.ts.map +1 -0
  286. package/dist/vc-agent/push-source.js +109 -0
  287. package/dist/vc-agent/push-source.js.map +1 -0
  288. package/dist/vc-agent/realtime/audio-source.d.ts +6 -0
  289. package/dist/vc-agent/realtime/audio-source.d.ts.map +1 -0
  290. package/dist/vc-agent/realtime/audio-source.js +17 -0
  291. package/dist/vc-agent/realtime/audio-source.js.map +1 -0
  292. package/dist/vc-agent/realtime/endpoint.d.ts +6 -0
  293. package/dist/vc-agent/realtime/endpoint.d.ts.map +1 -0
  294. package/dist/vc-agent/realtime/endpoint.js +25 -0
  295. package/dist/vc-agent/realtime/endpoint.js.map +1 -0
  296. package/dist/vc-agent/realtime/errors.d.ts +9 -0
  297. package/dist/vc-agent/realtime/errors.d.ts.map +1 -0
  298. package/dist/vc-agent/realtime/errors.js +17 -0
  299. package/dist/vc-agent/realtime/errors.js.map +1 -0
  300. package/dist/vc-agent/realtime/events.d.ts +24 -0
  301. package/dist/vc-agent/realtime/events.d.ts.map +1 -0
  302. package/dist/vc-agent/realtime/events.js +190 -0
  303. package/dist/vc-agent/realtime/events.js.map +1 -0
  304. package/dist/vc-agent/realtime/frontier.d.ts +34 -0
  305. package/dist/vc-agent/realtime/frontier.d.ts.map +1 -0
  306. package/dist/vc-agent/realtime/frontier.js +40 -0
  307. package/dist/vc-agent/realtime/frontier.js.map +1 -0
  308. package/dist/vc-agent/realtime/index.d.ts +11 -0
  309. package/dist/vc-agent/realtime/index.d.ts.map +1 -0
  310. package/dist/vc-agent/realtime/index.js +11 -0
  311. package/dist/vc-agent/realtime/index.js.map +1 -0
  312. package/dist/vc-agent/realtime/pacer.d.ts +21 -0
  313. package/dist/vc-agent/realtime/pacer.d.ts.map +1 -0
  314. package/dist/vc-agent/realtime/pacer.js +80 -0
  315. package/dist/vc-agent/realtime/pacer.js.map +1 -0
  316. package/dist/vc-agent/realtime/protobuf.d.ts +33 -0
  317. package/dist/vc-agent/realtime/protobuf.d.ts.map +1 -0
  318. package/dist/vc-agent/realtime/protobuf.js +159 -0
  319. package/dist/vc-agent/realtime/protobuf.js.map +1 -0
  320. package/dist/vc-agent/realtime/protocol.d.ts +4 -0
  321. package/dist/vc-agent/realtime/protocol.d.ts.map +1 -0
  322. package/dist/vc-agent/realtime/protocol.js +59 -0
  323. package/dist/vc-agent/realtime/protocol.js.map +1 -0
  324. package/dist/vc-agent/realtime/session.d.ts +39 -0
  325. package/dist/vc-agent/realtime/session.d.ts.map +1 -0
  326. package/dist/vc-agent/realtime/session.js +221 -0
  327. package/dist/vc-agent/realtime/session.js.map +1 -0
  328. package/dist/vc-agent/realtime/transport.d.ts +23 -0
  329. package/dist/vc-agent/realtime/transport.d.ts.map +1 -0
  330. package/dist/vc-agent/realtime/transport.js +112 -0
  331. package/dist/vc-agent/realtime/transport.js.map +1 -0
  332. package/dist/vc-agent/realtime/types.d.ts +84 -0
  333. package/dist/vc-agent/realtime/types.d.ts.map +1 -0
  334. package/dist/vc-agent/realtime/types.js +5 -0
  335. package/dist/vc-agent/realtime/types.js.map +1 -0
  336. package/dist/vc-agent/types.d.ts +143 -0
  337. package/dist/vc-agent/types.d.ts.map +1 -0
  338. package/dist/vc-agent/types.js +2 -0
  339. package/dist/vc-agent/types.js.map +1 -0
  340. package/dist/worker.js +71 -12
  341. package/dist/worker.js.map +1 -1
  342. package/dist/workflows/definition.d.ts +14 -14
  343. package/dist/workflows/events/payloads.d.ts +8 -8
  344. package/dist/workflows/events/schema.d.ts +452 -452
  345. package/dist/workflows/v3/contract.d.ts +3 -3
  346. package/dist/workflows/v3/contract.js +3 -3
  347. package/dist/workflows/v3/runtime.js +1 -1
  348. package/dist/workflows/v3/runtime.js.map +1 -1
  349. package/package.json +1 -1
  350. package/dist/dashboard-web/chunks/bot-defaults-page-4IF5NB4O.js +0 -409
  351. package/dist/dashboard-web/chunks/chunk-2KX53XHS.js +0 -317
  352. package/dist/dashboard-web/chunks/chunk-NHI3SY2K.js +0 -31
  353. package/dist/dashboard-web/chunks/overview-page-TADULZBE.js +0 -1
  354. package/dist/dashboard-web/chunks/sessions-I4EZWL5Q.js +0 -1
  355. package/dist/dashboard-web/chunks/sessions-page-YTQC2EM6.js +0 -1
  356. package/dist/dashboard-web/chunks/settings-page-TRYWNJ5Y.js +0 -2
  357. package/dist/dashboard-web/chunks/skills-page-ZZLGLEEL.js +0 -2
package/README.en.md CHANGED
@@ -15,14 +15,14 @@
15
15
  <a href="#design-philosophy">Design</a> &middot;
16
16
  <a href="#key-advantages">Advantages</a> &middot;
17
17
  <a href="#5-minute-setup">Quick Start</a> &middot;
18
- <a href="https://bytedance.aiforce.cloud/app/app_4k9smq6rdxher/"><b>📖 Docs</b></a>
18
+ <a href="https://github.com/deepcoldy/botmux/tree/master/docs-site/docs/en"><b>📖 Docs</b></a>
19
19
  </p>
20
20
 
21
21
  [中文](README.md) | English
22
22
 
23
23
  **Plug any AI coding CLI into Feishu/Lark — every DM, group or topic gets its own CLI session, with live-streaming cards, a web terminal, and zero glue code.**
24
24
 
25
- > 📖 **Full docs** (commands / config / best practices / troubleshooting): **<https://bytedance.aiforce.cloud/app/app_4k9smq6rdxher/>** — this README only covers why and how to get started fast.
25
+ > 📖 **Full docs** (commands / config / best practices / troubleshooting): **<https://github.com/deepcoldy/botmux/tree/master/docs-site/docs/en>** — this README only covers why and how to get started fast.
26
26
 
27
27
  | Lark Streaming Cards | Web Terminal | tmux Session Management | Multi-Bot Collaboration |
28
28
  |:-:|:-:|:-:|:-:|
@@ -223,7 +223,7 @@ On mobile/tablet, a floating shortcut toolbar provides Esc, Ctrl+C, Tab, arrow k
223
223
 
224
224
  ### Multi-Bot Collaboration
225
225
 
226
- Run multiple Lark bots on a single machine, each mapped to a different CLI. In the same group chat, messages are routed via @mention — each bot gets its own isolated CLI process. With a single bot in the group, it responds automatically without @. In a regular (non-topic) group, `@<bot1> @<bot2> /t xxx` spawns one independent thread per mentioned bot anchored at the same message. Send `@<bot1> @<bot2> /introduce` once so they register each other's open_id; afterwards each bot can explicitly @-mention the others from within its own session (commands: [📖 Docs · Slash Commands](https://bytedance.aiforce.cloud/app/app_4k9smq6rdxher/slash-commands)).
226
+ Run multiple Lark bots on a single machine, each mapped to a different CLI. In the same group chat, messages are routed via @mention — each bot gets its own isolated CLI process. With a single bot in the group, it responds automatically without @. In a regular (non-topic) group, `@<bot1> @<bot2> /t xxx` spawns one independent thread per mentioned bot anchored at the same message. Send `@<bot1> @<bot2> /introduce` once so they register each other's open_id; afterwards each bot can explicitly @-mention the others from within its own session (commands: [📖 Docs · Slash Commands](https://github.com/deepcoldy/botmux/blob/master/docs-site/docs/en/slash-commands.md)).
227
227
 
228
228
  ### Multi-Topic Collaboration
229
229
 
@@ -387,16 +387,16 @@ Notes:
387
387
 
388
388
  The full reference — commands, config, best practices, troubleshooting — lives in the docs site; not duplicated here —
389
389
 
390
- ### 👉 https://bytedance.aiforce.cloud/app/app_4k9smq6rdxher/
390
+ ### 👉 https://github.com/deepcoldy/botmux/tree/master/docs-site/docs/en
391
391
 
392
392
  | Topic | Docs |
393
393
  |-------|------|
394
- | Slash commands / CLI commands / agent-facing subcommands | [Commands](https://bytedance.aiforce.cloud/app/app_4k9smq6rdxher/slash-commands) |
395
- | `bots.json` fields / env vars / file locations | [Configuration](https://bytedance.aiforce.cloud/app/app_4k9smq6rdxher/bots-json) |
396
- | Multi-CLI adapters (incl. wrapper / gateway integration) | [Adapters](https://bytedance.aiforce.cloud/app/app_4k9smq6rdxher/adapters) |
397
- | Scenario-based best practices (Oncall / alerting-ops / solo dev / team) | [Best Practices](https://bytedance.aiforce.cloud/app/app_4k9smq6rdxher/best-practices) |
398
- | Common pitfalls / FAQ | [Pitfalls](https://bytedance.aiforce.cloud/app/app_4k9smq6rdxher/pitfalls) · [FAQ](https://bytedance.aiforce.cloud/app/app_4k9smq6rdxher/faq) |
399
- | Features: scheduled tasks / Oncall / Dashboard / multi-bot / session relay | [Schedule](https://bytedance.aiforce.cloud/app/app_4k9smq6rdxher/schedule) · [Oncall](https://bytedance.aiforce.cloud/app/app_4k9smq6rdxher/oncall) · [Dashboard](https://bytedance.aiforce.cloud/app/app_4k9smq6rdxher/dashboard) · [Multi-bot](https://bytedance.aiforce.cloud/app/app_4k9smq6rdxher/multi-bot) · [Relay](https://bytedance.aiforce.cloud/app/app_4k9smq6rdxher/relay) |
394
+ | Slash commands / CLI commands / agent-facing subcommands | [Commands](https://github.com/deepcoldy/botmux/blob/master/docs-site/docs/en/slash-commands.md) |
395
+ | `bots.json` fields / env vars / file locations | [Configuration](https://github.com/deepcoldy/botmux/blob/master/docs-site/docs/en/bots-json.md) |
396
+ | Multi-CLI adapters (incl. wrapper / gateway integration) | [Adapters](https://github.com/deepcoldy/botmux/blob/master/docs-site/docs/en/adapters.md) |
397
+ | Scenario-based best practices (Oncall / alerting-ops / solo dev / team) | [Best Practices](https://github.com/deepcoldy/botmux/blob/master/docs-site/docs/en/best-practices.md) |
398
+ | Common pitfalls / FAQ | [Pitfalls](https://github.com/deepcoldy/botmux/blob/master/docs-site/docs/en/pitfalls.md) · [FAQ](https://github.com/deepcoldy/botmux/blob/master/docs-site/docs/en/faq.md) |
399
+ | Features: scheduled tasks / Oncall / Dashboard / multi-bot / session relay | [Schedule](https://github.com/deepcoldy/botmux/blob/master/docs-site/docs/en/schedule.md) · [Oncall](https://github.com/deepcoldy/botmux/blob/master/docs-site/docs/en/oncall.md) · [Dashboard](https://github.com/deepcoldy/botmux/blob/master/docs-site/docs/en/dashboard.md) · [Multi-bot](https://github.com/deepcoldy/botmux/blob/master/docs-site/docs/en/multi-bot.mdx) · [Relay](https://github.com/deepcoldy/botmux/blob/master/docs-site/docs/en/relay.md) |
400
400
 
401
401
  ## Contributing
402
402
 
package/README.md CHANGED
@@ -12,7 +12,7 @@
12
12
  </p>
13
13
 
14
14
  <p align="center">
15
- <a href="#设计理念">设计理念</a> · <a href="#核心优势">核心优势</a> · <a href="#5-分钟快速接入">快速接入</a> · <a href="https://bytedance.aiforce.cloud/app/app_4k9smq6rdxher/"><b>📖 文档</b></a>
15
+ <a href="#设计理念">设计理念</a> · <a href="#核心优势">核心优势</a> · <a href="#5-分钟快速接入">快速接入</a> · <a href="https://github.com/deepcoldy/botmux/tree/master/docs-site/docs/zh"><b>📖 文档</b></a>
16
16
  </p>
17
17
 
18
18
  <p align="center">
@@ -23,7 +23,7 @@
23
23
 
24
24
  **飞书 + AI 编程 CLI——私聊 / 群聊 / 话题,每个会话一个独立 CLI 进程,实时流式回传。** Daemon 监听飞书消息,为每个新会话自动启动独立 CLI 进程(Claude Code / Codex / Cursor / Gemini / OpenCode / Antigravity / GitHub Copilot / Kimi Code),提供实时流式卡片和可交互 Web 终端。
25
25
 
26
- > 📖 **完整文档**(命令 / 配置 / 最佳实践 / 排错):**<https://bytedance.aiforce.cloud/app/app_4k9smq6rdxher/>** ——本 README 只讲为什么用它和怎么快速上手。
26
+ > 📖 **完整文档**(命令 / 配置 / 最佳实践 / 排错):**<https://github.com/deepcoldy/botmux/tree/master/docs-site/docs/zh>** ——本 README 只讲为什么用它和怎么快速上手。
27
27
 
28
28
  ## 演示
29
29
 
@@ -92,7 +92,7 @@ botmux 可以管理 CLI 无关的自定义 Skill Registry,并按 bot 配置在
92
92
 
93
93
  ### 多机器人协作
94
94
 
95
- 同一台机器上可运行多个飞书机器人,每个机器人可对应不同的 CLI。同一群聊中通过 @mention 路由消息,仅有一个机器人时无需 @ 自动响应;多机器人时 `@<bot1> @<bot2> /t xxx` 可让每个被 @ 的机器人在同一条消息上各自独立开新话题。先发一次 `@<bot1> @<bot2> /introduce` 让它们互相登记 open_id,之后各 bot 就能在自己的会话里显式 @mention 对方协作(命令详见 [📖 文档 · 斜杠命令](https://bytedance.aiforce.cloud/app/app_4k9smq6rdxher/slash-commands))。
95
+ 同一台机器上可运行多个飞书机器人,每个机器人可对应不同的 CLI。同一群聊中通过 @mention 路由消息,仅有一个机器人时无需 @ 自动响应;多机器人时 `@<bot1> @<bot2> /t xxx` 可让每个被 @ 的机器人在同一条消息上各自独立开新话题。先发一次 `@<bot1> @<bot2> /introduce` 让它们互相登记 open_id,之后各 bot 就能在自己的会话里显式 @mention 对方协作(命令详见 [📖 文档 · 斜杠命令](https://github.com/deepcoldy/botmux/blob/master/docs-site/docs/zh/slash-commands.md))。
96
96
 
97
97
  ### 多话题协作模式
98
98
 
@@ -384,16 +384,16 @@ PersonalAgent 默认配好事件订阅 + bot 能力,正常情况下不用动
384
384
 
385
385
  命令、配置、最佳实践、排错的完整内容都在文档站,这里不再重复 ——
386
386
 
387
- ### 👉 https://bytedance.aiforce.cloud/app/app_4k9smq6rdxher/
387
+ ### 👉 https://github.com/deepcoldy/botmux/tree/master/docs-site/docs/zh
388
388
 
389
389
  | 主题 | 文档 |
390
390
  |------|------|
391
- | 斜杠命令 / CLI 命令 / 会话内子命令 | [命令参考](https://bytedance.aiforce.cloud/app/app_4k9smq6rdxher/slash-commands) |
392
- | `bots.json` 字段 / 环境变量 / 文件位置 | [配置参考](https://bytedance.aiforce.cloud/app/app_4k9smq6rdxher/bots-json) |
393
- | 多 CLI 适配器(含 wrapper / 网关接入) | [适配器](https://bytedance.aiforce.cloud/app/app_4k9smq6rdxher/adapters) |
394
- | 按场景的最佳实践(Oncall / 报警运维 / 个人研发 / 多人协作) | [最佳实践](https://bytedance.aiforce.cloud/app/app_4k9smq6rdxher/best-practices) |
395
- | 常见踩坑 / FAQ 排错 | [踩坑](https://bytedance.aiforce.cloud/app/app_4k9smq6rdxher/pitfalls) · [FAQ](https://bytedance.aiforce.cloud/app/app_4k9smq6rdxher/faq) |
396
- | 功能详解:定时任务 / Oncall / Dashboard / 多机器人协作 / 会话接力 | [定时](https://bytedance.aiforce.cloud/app/app_4k9smq6rdxher/schedule) · [Oncall](https://bytedance.aiforce.cloud/app/app_4k9smq6rdxher/oncall) · [Dashboard](https://bytedance.aiforce.cloud/app/app_4k9smq6rdxher/dashboard) · [多 bot](https://bytedance.aiforce.cloud/app/app_4k9smq6rdxher/multi-bot) · [接力](https://bytedance.aiforce.cloud/app/app_4k9smq6rdxher/relay) |
391
+ | 斜杠命令 / CLI 命令 / 会话内子命令 | [命令参考](https://github.com/deepcoldy/botmux/blob/master/docs-site/docs/zh/slash-commands.md) |
392
+ | `bots.json` 字段 / 环境变量 / 文件位置 | [配置参考](https://github.com/deepcoldy/botmux/blob/master/docs-site/docs/zh/bots-json.md) |
393
+ | 多 CLI 适配器(含 wrapper / 网关接入) | [适配器](https://github.com/deepcoldy/botmux/blob/master/docs-site/docs/zh/adapters.md) |
394
+ | 按场景的最佳实践(Oncall / 报警运维 / 个人研发 / 多人协作) | [最佳实践](https://github.com/deepcoldy/botmux/blob/master/docs-site/docs/zh/best-practices.md) |
395
+ | 常见踩坑 / FAQ 排错 | [踩坑](https://github.com/deepcoldy/botmux/blob/master/docs-site/docs/zh/pitfalls.md) · [FAQ](https://github.com/deepcoldy/botmux/blob/master/docs-site/docs/zh/faq.md) |
396
+ | 功能详解:定时任务 / Oncall / Dashboard / 多机器人协作 / 会话接力 | [定时](https://github.com/deepcoldy/botmux/blob/master/docs-site/docs/zh/schedule.md) · [Oncall](https://github.com/deepcoldy/botmux/blob/master/docs-site/docs/zh/oncall.md) · [Dashboard](https://github.com/deepcoldy/botmux/blob/master/docs-site/docs/zh/dashboard.md) · [多 bot](https://github.com/deepcoldy/botmux/blob/master/docs-site/docs/zh/multi-bot.mdx) · [接力](https://github.com/deepcoldy/botmux/blob/master/docs-site/docs/zh/relay.md) |
397
397
 
398
398
  ## 贡献
399
399
 
@@ -1,4 +1,3 @@
1
- export declare function sandboxVartmpRoot(): string;
2
1
  /**
3
2
  * Mount an overlayfs: reads fall through to `lower` (real, zero copy); writes
4
3
  * copy-up into `upper` (the landable changeset). `work` is overlayfs scratch on
@@ -124,7 +123,7 @@ export interface SandboxSpawn {
124
123
  outbox: string;
125
124
  /** Project overlay UPPER dir — THE LANDABLE CHANGESET (used by sandbox-land). */
126
125
  workDir: string;
127
- /** HOME overlay UPPER dir (/var/tmp/botmux-sbx-<uid>/<sid>/home-upper). The sandboxed
126
+ /** HOME overlay UPPER dir (/var/tmp/botmux-sbx/<sid>/home-upper). The sandboxed
128
127
  * CLI's $HOME writes — INCLUDING its session jsonl under CLAUDE_CONFIG_DIR —
129
128
  * land here (invisible at the real path). The worker redirects its bridge/idle
130
129
  * watch into this via sandboxedClaudeDataDir() so it sees the CLI's turns. */
@@ -150,12 +149,10 @@ export declare function sandboxedClaudeDataDir(sessionId: string, realDataDir: s
150
149
  * is off / unsupported / a required overlay mount fails (fail-safe = the worker
151
150
  * treats null as a hard error and does NOT silently run unsandboxed).
152
151
  *
153
- * Layout under <dataDir>/sandboxes/<sessionId>/: shimbin, proj-upper (the
154
- * landable changeset), proj-work, proj-merged, home-merged. The HOME overlay's
155
- * upper/work and the daemon-mediated outbox live under
156
- * /var/tmp/botmux-sbx-<uid>/<sessionId>/ because overlayfs forbids upper/work inside
157
- * the lower (= the real home), and keeping the outbox outside HOME avoids a
158
- * nested bind under the HOME overlay on bwrap hosts that hang on that pattern.
152
+ * Layout under <dataDir>/sandboxes/<sessionId>/: outbox, shimbin, proj-upper
153
+ * (the landable changeset), proj-work, proj-merged, home-merged. The HOME
154
+ * overlay's upper/work live under /var/tmp/botmux-sbx/<sessionId>/ because
155
+ * overlayfs forbids upper/work inside the lower (= the real home).
159
156
  */
160
157
  export declare function prepareSandbox(opts: {
161
158
  /** Whether the sandbox is on for THIS session (per-bot BotConfig.sandbox OR
@@ -197,10 +194,7 @@ export declare function prepareSandbox(opts: {
197
194
  * path back so the watcher can keep servicing the live CLI's `botmux send`, plus
198
195
  * the workDir (upper changeset for landing) and a cleanup that tears the residue
199
196
  * down at close/exit. Returns null if the session has no sandbox tree on disk
200
- * (never sandboxed). Linux-only, mirrors prepareSandbox's layout. New sessions
201
- * keep outbox under /var/tmp/botmux-sbx-<uid>/<sid>/outbox; fall back to legacy
202
- * /var/tmp/botmux-sbx/<sid>/outbox or <dataDir>/sandboxes/<sid>/outbox for
203
- * sessions that were already running before the layout changed.
197
+ * (never sandboxed). Linux-only, mirrors prepareSandbox's layout.
204
198
  */
205
199
  export declare function attachSandboxOutbox(opts: {
206
200
  sessionId: string;
@@ -275,14 +269,6 @@ export declare function validateRelayRequest(req: RelayRequest): {
275
269
  * be swapped under us. Returns false (reject) on symlink / non-regular / any error.
276
270
  */
277
271
  export declare function materializeOutboxFile(outbox: string, name: string, dest: string): boolean;
278
- /**
279
- * TOCTOU-safe read of the `.req.json` trigger file itself. The request file is
280
- * also sandbox-controlled input, so it needs the same hardening as content and
281
- * attachments: no symlinks, no FIFO/device files, no blocking opens, and a small
282
- * size cap before JSON.parse. Returns null on any unsafe/non-regular/oversized
283
- * input so the watcher can reject and keep its event loop moving.
284
- */
285
- export declare function readRelayRequestFile(reqPath: string): string | null;
286
272
  /**
287
273
  * Daemon/worker-side outbox watcher. The sandboxed `botmux send` (relay mode)
288
274
  * drops `<id>.req.json`; we validate (validateRelayRequest) and then MATERIALIZE
@@ -1 +1 @@
1
- {"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../../../src/adapters/backend/sandbox.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../../../src/adapters/backend/sandbox.ts"],"names":[],"mappings":"AAkCA;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAqB1G;AAED,mFAAmF;AACnF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE/C;AAED;gFACgF;AAChF,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAQnD;AAqCD,MAAM,WAAW,WAAW;IAC1B;0FACsF;IACtF,YAAY,EAAE,MAAM,CAAC;IACrB,gFAAgF;IAChF,aAAa,EAAE,MAAM,CAAC;IACtB;2DACuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,kFAAkF;IAClF,MAAM,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,+EAA+E;IAC/E,SAAS,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC7C;;sEAEkE;IAClE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB;;sDAEkD;IAClD,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB;;6DAEyD;IACzD,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,8EAA8E;IAC9E,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,EAAE,CA6B5D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,GAAG,MAAM,EAAE,CAU7E;AAoCD;;;8DAG8D;AAC9D,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GACvE,MAAM,EAAE,CAaV;AAUD;+DAC+D;AAC/D,wBAAgB,cAAc,IAAI,OAAO,CAExC;AAED,MAAM,WAAW,YAAY;IAC3B,yDAAyD;IACzD,GAAG,EAAE,MAAM,CAAC;IACZ,mDAAmD;IACnD,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,qFAAqF;IACrF,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,kDAAkD;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAC;IAChB;;;mFAG+E;IAC/E,SAAS,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;;;;;;mDAWmD;AACnD,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAIrF;AAMD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE;IACnC;;sFAEkF;IAClF,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB;2EACuE;IACvE,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB;+EAC2E;IAC3E,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B;;oEAEgE;IAChE,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC;qEACiE;IACjE,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC;;iDAE6C;IAC7C,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,yEAAyE;IACzE,GAAG,CAAC,EAAE,OAAO,CAAC;CACf,GAAG,YAAY,GAAG,IAAI,CAqJtB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,GAAG,IAAI,CAsBjJ;AAiCD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAoCzF;AAOD,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AASD,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,YAAY,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,cAAc,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAsC1H;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAiBzF;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,UAAU,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,IAAI,CAuF5G"}
@@ -20,61 +20,14 @@
20
20
  * sandbox-exec approach and is handled elsewhere.
21
21
  */
22
22
  import { homedir } from 'node:os';
23
- import { mkdirSync, existsSync, writeFileSync, chmodSync, readdirSync, readFileSync, rmSync, statSync, lstatSync, realpathSync, openSync, fstatSync, readSync, writeSync, closeSync, constants as fsConstants } from 'node:fs';
23
+ import { mkdirSync, existsSync, writeFileSync, chmodSync, readdirSync, readFileSync, rmSync, statSync, realpathSync, openSync, fstatSync, readSync, writeSync, closeSync, constants as fsConstants } from 'node:fs';
24
24
  import { atomicWriteFileSync } from '../../utils/atomic-write.js';
25
25
  import { join, dirname, relative, resolve } from 'node:path';
26
26
  import { fileURLToPath } from 'node:url';
27
27
  import { spawn, spawnSync } from 'node:child_process';
28
28
  /** Host root for the HOME overlay's upper/work — MUST be OUTSIDE the home lower
29
- * (overlayfs forbids upper/work inside lower). Keep it per-uid: /var/tmp is a
30
- * shared multi-user surface, and a global 0700 root would let the first user
31
- * that starts sandbox block every other Unix user on the same machine. */
32
- const LEGACY_VARTMP_ROOT = '/var/tmp/botmux-sbx';
33
- export function sandboxVartmpRoot() {
34
- const uid = process.getuid?.() ?? 0;
35
- return `/var/tmp/botmux-sbx-${uid}`;
36
- }
37
- function legacySandboxVartmpDir(sessionId) {
38
- return join(LEGACY_VARTMP_ROOT, sessionId);
39
- }
40
- function sandboxVartmpDir(sessionId) {
41
- return join(sandboxVartmpRoot(), sessionId);
42
- }
43
- function sandboxHomeUpperDir(sessionId) {
44
- const next = join(sandboxVartmpDir(sessionId), 'home-upper');
45
- const legacy = join(legacySandboxVartmpDir(sessionId), 'home-upper');
46
- // Published versions stored HOME upper under the global /var/tmp/botmux-sbx.
47
- // A daemon upgrade may reattach a still-running tmux sandbox whose bwrap
48
- // namespace continues writing that old overlay upper. If the new per-uid upper
49
- // does not exist, keep the bridge pointed at the legacy path.
50
- if (existsSync(legacy) && !existsSync(next))
51
- return legacy;
52
- return next;
53
- }
54
- /** Create a daemon-private directory and repair legacy/default mkdir modes.
55
- * Anything under /var/tmp is on a shared multi-user surface, while the outbox
56
- * carries in-flight Lark message bodies/attachments. Refuse to proceed unless
57
- * the path is a real directory owned by this daemon user, and group/other bits
58
- * are gone after chmod. */
59
- function ensurePrivateDir(dir) {
60
- try {
61
- mkdirSync(dir, { recursive: true, mode: 0o700 });
62
- const lst = lstatSync(dir);
63
- if (lst.isSymbolicLink() || !lst.isDirectory())
64
- return false;
65
- const stBefore = statSync(dir);
66
- const uid = process.getuid?.();
67
- if (typeof uid === 'number' && stBefore.uid !== uid)
68
- return false;
69
- chmodSync(dir, 0o700); // repair dirs created before this hardening or under a loose umask
70
- const st = statSync(dir);
71
- return st.isDirectory() && (typeof uid !== 'number' || st.uid === uid) && (st.mode & 0o077) === 0;
72
- }
73
- catch (err) {
74
- console.error(`[sandbox] failed to prepare private dir ${dir}: ${err instanceof Error ? err.message : String(err)}`);
75
- return false;
76
- }
77
- }
29
+ * (overlayfs forbids upper/work inside lower). */
30
+ const VARTMP_ROOT = '/var/tmp/botmux-sbx';
78
31
  // ───────────────────────────── overlay primitives ────────────────────────────
79
32
  /**
80
33
  * Mount an overlayfs: reads fall through to `lower` (real, zero copy); writes
@@ -349,7 +302,7 @@ export function sandboxEnabled() {
349
302
  export function sandboxedClaudeDataDir(sessionId, realDataDir) {
350
303
  const raw = relative(homedir(), realDataDir);
351
304
  const rel = raw.startsWith('..') ? relative(resolveSandboxMountPath(homedir()), realDataDir) : raw;
352
- return join(sandboxHomeUpperDir(sessionId), rel);
305
+ return join(VARTMP_ROOT, sessionId, 'home-upper', rel);
353
306
  }
354
307
  /** Proxy env vars forwarded into the sandbox so the CLI reaches the API even on
355
308
  * the tmux backend (which otherwise only forwards a fixed whitelist). */
@@ -359,12 +312,10 @@ const PROXY_ENV_KEYS = ['http_proxy', 'https_proxy', 'HTTP_PROXY', 'HTTPS_PROXY'
359
312
  * is off / unsupported / a required overlay mount fails (fail-safe = the worker
360
313
  * treats null as a hard error and does NOT silently run unsandboxed).
361
314
  *
362
- * Layout under <dataDir>/sandboxes/<sessionId>/: shimbin, proj-upper (the
363
- * landable changeset), proj-work, proj-merged, home-merged. The HOME overlay's
364
- * upper/work and the daemon-mediated outbox live under
365
- * /var/tmp/botmux-sbx-<uid>/<sessionId>/ because overlayfs forbids upper/work inside
366
- * the lower (= the real home), and keeping the outbox outside HOME avoids a
367
- * nested bind under the HOME overlay on bwrap hosts that hang on that pattern.
315
+ * Layout under <dataDir>/sandboxes/<sessionId>/: outbox, shimbin, proj-upper
316
+ * (the landable changeset), proj-work, proj-merged, home-merged. The HOME
317
+ * overlay's upper/work live under /var/tmp/botmux-sbx/<sessionId>/ because
318
+ * overlayfs forbids upper/work inside the lower (= the real home).
368
319
  */
369
320
  export function prepareSandbox(opts) {
370
321
  if (!opts.enabled)
@@ -378,6 +329,7 @@ export function prepareSandbox(opts) {
378
329
  return null;
379
330
  const dataDir = resolveSandboxMountPath(opts.dataDir);
380
331
  const sessionRoot = join(dataDir, 'sandboxes', opts.sessionId);
332
+ const outbox = join(sessionRoot, 'outbox');
381
333
  const shimBin = join(sessionRoot, 'shimbin');
382
334
  const empties = join(sessionRoot, 'empties');
383
335
  const projUpper = join(sessionRoot, 'proj-upper'); // THE LANDABLE CHANGESET
@@ -385,12 +337,9 @@ export function prepareSandbox(opts) {
385
337
  const projMerged = join(sessionRoot, 'proj-merged');
386
338
  const homeMerged = join(sessionRoot, 'home-merged'); // merged may live under sessionRoot
387
339
  // HOME overlay upper/work MUST be OUTSIDE the home lower (overlayfs constraint).
388
- const vartmp = sandboxVartmpDir(opts.sessionId);
389
- const outbox = join(vartmp, 'outbox');
340
+ const vartmp = join(VARTMP_ROOT, opts.sessionId);
390
341
  const homeUpper = join(vartmp, 'home-upper');
391
342
  const homeWork = join(vartmp, 'home-work');
392
- if (!ensurePrivateDir(sandboxVartmpRoot()) || !ensurePrivateDir(vartmp) || !ensurePrivateDir(outbox))
393
- return null;
394
343
  for (const d of [outbox, shimBin, empties])
395
344
  mkdirSync(d, { recursive: true });
396
345
  const home = resolveSandboxMountPath(homedir());
@@ -526,10 +475,6 @@ export function prepareSandbox(opts) {
526
475
  rmSync(vartmp, { recursive: true, force: true });
527
476
  }
528
477
  catch { /* */ }
529
- try {
530
- rmSync(legacySandboxVartmpDir(opts.sessionId), { recursive: true, force: true });
531
- }
532
- catch { /* */ }
533
478
  },
534
479
  };
535
480
  }
@@ -542,37 +487,25 @@ export function prepareSandbox(opts) {
542
487
  * path back so the watcher can keep servicing the live CLI's `botmux send`, plus
543
488
  * the workDir (upper changeset for landing) and a cleanup that tears the residue
544
489
  * down at close/exit. Returns null if the session has no sandbox tree on disk
545
- * (never sandboxed). Linux-only, mirrors prepareSandbox's layout. New sessions
546
- * keep outbox under /var/tmp/botmux-sbx-<uid>/<sid>/outbox; fall back to legacy
547
- * /var/tmp/botmux-sbx/<sid>/outbox or <dataDir>/sandboxes/<sid>/outbox for
548
- * sessions that were already running before the layout changed.
490
+ * (never sandboxed). Linux-only, mirrors prepareSandbox's layout.
549
491
  */
550
492
  export function attachSandboxOutbox(opts) {
551
493
  if (process.platform !== 'linux')
552
494
  return null;
553
495
  const dataDir = resolveSandboxMountPath(opts.dataDir);
554
496
  const sessionRoot = join(dataDir, 'sandboxes', opts.sessionId);
555
- const vartmp = sandboxVartmpDir(opts.sessionId);
556
- const newOutbox = join(vartmp, 'outbox');
557
- const legacyVartmpOutbox = join(legacySandboxVartmpDir(opts.sessionId), 'outbox');
558
- const legacyOutbox = join(sessionRoot, 'outbox');
497
+ const outbox = join(sessionRoot, 'outbox');
559
498
  const projUpper = join(sessionRoot, 'proj-upper');
560
- if (!existsSync(newOutbox) && !existsSync(legacyVartmpOutbox) && !existsSync(legacyOutbox) && !existsSync(projUpper))
499
+ if (!existsSync(outbox) && !existsSync(projUpper))
561
500
  return null; // never sandboxed
562
- const outbox = existsSync(newOutbox) ? newOutbox : (existsSync(legacyVartmpOutbox) ? legacyVartmpOutbox : (existsSync(legacyOutbox) ? legacyOutbox : newOutbox));
563
501
  // Ensure the outbox exists (the watcher reads it); never (re)mount here.
564
- if (outbox === newOutbox) {
565
- if (!ensurePrivateDir(sandboxVartmpRoot()) || !ensurePrivateDir(vartmp) || !ensurePrivateDir(outbox))
566
- return null;
567
- }
568
- else if (outbox === legacyVartmpOutbox) {
569
- if (!ensurePrivateDir(legacySandboxVartmpDir(opts.sessionId)) || !ensurePrivateDir(outbox))
570
- return null;
502
+ try {
503
+ mkdirSync(outbox, { recursive: true });
571
504
  }
572
- else if (!ensurePrivateDir(outbox))
573
- return null;
505
+ catch { /* */ }
574
506
  const projMerged = join(sessionRoot, 'proj-merged');
575
507
  const homeMerged = join(sessionRoot, 'home-merged');
508
+ const vartmp = join(VARTMP_ROOT, opts.sessionId);
576
509
  return {
577
510
  outbox,
578
511
  workDir: projUpper,
@@ -587,10 +520,6 @@ export function attachSandboxOutbox(opts) {
587
520
  rmSync(vartmp, { recursive: true, force: true });
588
521
  }
589
522
  catch { /* */ }
590
- try {
591
- rmSync(legacySandboxVartmpDir(opts.sessionId), { recursive: true, force: true });
592
- }
593
- catch { /* */ }
594
523
  },
595
524
  };
596
525
  }
@@ -605,17 +534,13 @@ function reclaimSandbox(dataDir, sid) {
605
534
  }
606
535
  catch { /* */ }
607
536
  try {
608
- rmSync(join(sandboxVartmpRoot(), sid), { recursive: true, force: true });
609
- }
610
- catch { /* */ }
611
- try {
612
- rmSync(legacySandboxVartmpDir(sid), { recursive: true, force: true });
537
+ rmSync(join(VARTMP_ROOT, sid), { recursive: true, force: true });
613
538
  }
614
539
  catch { /* */ }
615
540
  }
616
541
  /** Scan the process table for sandbox session-ids referenced by any running
617
542
  * process's argv. A live bwrap's bind/overlay paths contain `sandboxes/<sid>`
618
- * and `botmux-sbx-<uid>/<sid>`, so this physically detects which sandbox dirs are
543
+ * and `botmux-sbx/<sid>`, so this physically detects which sandbox dirs are
619
544
  * still in use — by overlay sessions AND old clone-model sessions alike. Used as
620
545
  * a hard guard so the sweep never deletes a dir out from under a live CLI. */
621
546
  function liveSandboxSids() {
@@ -627,7 +552,7 @@ function liveSandboxSids() {
627
552
  catch {
628
553
  return live;
629
554
  }
630
- const re = /(?:sandboxes|botmux-sbx(?:-[^/\0]+)?)\/([^/\0]+)/g;
555
+ const re = /(?:sandboxes|botmux-sbx)\/([^/\0]+)/g;
631
556
  for (const pid of pids) {
632
557
  if (!/^\d+$/.test(pid))
633
558
  continue;
@@ -677,9 +602,9 @@ export function sweepOrphanSandboxes(dataDir, activeSessionIds) {
677
602
  return;
678
603
  } // no sandboxes dir yet
679
604
  // Grace before reclaiming an ACTIVE-but-unmounted sandbox: a worker that just
680
- // (re)spawned creates the sandbox dirs a few syscalls BEFORE it mounts the
681
- // overlay. Without this, a sweep firing in that tiny window would nuke an
682
- // in-progress session's shimbin/project tree. Non-active orphans are reclaimed immediately
605
+ // (re)spawned creates the outbox/shimbin dirs a few syscalls BEFORE it mounts
606
+ // the overlay. Without this, a sweep firing in that tiny window would nuke an
607
+ // in-progress session's outbox. Non-active orphans are reclaimed immediately
683
608
  // (no live worker can be mid-spawn for a session that isn't active).
684
609
  const ACTIVE_DEAD_GRACE_MS = 60_000;
685
610
  const now = Date.now();
@@ -824,49 +749,6 @@ export function materializeOutboxFile(outbox, name, dest) {
824
749
  closeSync(outFd);
825
750
  }
826
751
  }
827
- const RELAY_REQUEST_MAX_BYTES = 64 * 1024;
828
- /**
829
- * TOCTOU-safe read of the `.req.json` trigger file itself. The request file is
830
- * also sandbox-controlled input, so it needs the same hardening as content and
831
- * attachments: no symlinks, no FIFO/device files, no blocking opens, and a small
832
- * size cap before JSON.parse. Returns null on any unsafe/non-regular/oversized
833
- * input so the watcher can reject and keep its event loop moving.
834
- */
835
- export function readRelayRequestFile(reqPath) {
836
- let fd;
837
- try {
838
- fd = openSync(reqPath, fsConstants.O_RDONLY | fsConstants.O_NOFOLLOW | fsConstants.O_NONBLOCK);
839
- }
840
- catch {
841
- return null;
842
- }
843
- try {
844
- const st = fstatSync(fd);
845
- if (!st.isFile())
846
- return null;
847
- if (st.size > RELAY_REQUEST_MAX_BYTES)
848
- return null;
849
- const chunks = [];
850
- let total = 0;
851
- const buf = Buffer.alloc(Math.min(8192, RELAY_REQUEST_MAX_BYTES));
852
- for (;;) {
853
- const n = readSync(fd, buf, 0, buf.length, null);
854
- if (n <= 0)
855
- break;
856
- total += n;
857
- if (total > RELAY_REQUEST_MAX_BYTES)
858
- return null;
859
- chunks.push(Buffer.from(buf.subarray(0, n)));
860
- }
861
- return Buffer.concat(chunks, total).toString('utf8');
862
- }
863
- catch {
864
- return null;
865
- }
866
- finally {
867
- closeSync(fd);
868
- }
869
- }
870
752
  /**
871
753
  * Daemon/worker-side outbox watcher. The sandboxed `botmux send` (relay mode)
872
754
  * drops `<id>.req.json`; we validate (validateRelayRequest) and then MATERIALIZE
@@ -886,7 +768,7 @@ export function startOutboxWatcher(outbox, baseEnv, sessionId) {
886
768
  const finish = (id, reqPath, name, staged, code, stdout, stderr) => {
887
769
  // 原子写:沙盒侧 CLI 在 existsSync 轮询这个 res.json,rename 保证它读到完整 JSON。
888
770
  try {
889
- atomicWriteFileSync(join(outbox, `${id}.res.json`), JSON.stringify({ code, stdout, stderr }), { mode: 0o600 });
771
+ atomicWriteFileSync(join(outbox, `${id}.res.json`), JSON.stringify({ code, stdout, stderr }));
890
772
  }
891
773
  catch { /* */ }
892
774
  try {
@@ -917,13 +799,8 @@ export function startOutboxWatcher(outbox, baseEnv, sessionId) {
917
799
  const id = name.slice(0, -'.req.json'.length);
918
800
  const staged = [];
919
801
  let req;
920
- const reqText = readRelayRequestFile(reqPath);
921
- if (reqText === null) {
922
- finish(id, reqPath, name, staged, 1, '', 'relay rejected: request not a regular file or too large');
923
- continue;
924
- }
925
802
  try {
926
- req = JSON.parse(reqText);
803
+ req = JSON.parse(readFileSync(reqPath, 'utf8'));
927
804
  }
928
805
  catch {
929
806
  finish(id, reqPath, name, staged, 1, '', 'relay: bad json');
@@ -935,8 +812,7 @@ export function startOutboxWatcher(outbox, baseEnv, sessionId) {
935
812
  continue;
936
813
  }
937
814
  try {
938
- mkdirSync(staging, { recursive: true, mode: 0o700 });
939
- chmodSync(staging, 0o700);
815
+ mkdirSync(staging, { recursive: true });
940
816
  }
941
817
  catch { /* */ }
942
818
  // Materialize content (TOCTOU-safe) into the private staging dir.