botmux 2.107.0 → 2.108.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 (515) hide show
  1. package/README.en.md +17 -14
  2. package/README.md +19 -14
  3. package/dist/adapters/backend/sandbox.d.ts +3 -1
  4. package/dist/adapters/backend/sandbox.d.ts.map +1 -1
  5. package/dist/adapters/backend/sandbox.js +19 -3
  6. package/dist/adapters/backend/sandbox.js.map +1 -1
  7. package/dist/adapters/backend/tmux-backend.d.ts.map +1 -1
  8. package/dist/adapters/backend/tmux-backend.js +16 -1
  9. package/dist/adapters/backend/tmux-backend.js.map +1 -1
  10. package/dist/adapters/backend/tmux-pipe-backend.d.ts +24 -15
  11. package/dist/adapters/backend/tmux-pipe-backend.d.ts.map +1 -1
  12. package/dist/adapters/backend/tmux-pipe-backend.js +75 -43
  13. package/dist/adapters/backend/tmux-pipe-backend.js.map +1 -1
  14. package/dist/adapters/cli/genius.d.ts.map +1 -1
  15. package/dist/adapters/cli/genius.js +9 -15
  16. package/dist/adapters/cli/genius.js.map +1 -1
  17. package/dist/adapters/cli/grok.d.ts +73 -0
  18. package/dist/adapters/cli/grok.d.ts.map +1 -0
  19. package/dist/adapters/cli/grok.js +298 -0
  20. package/dist/adapters/cli/grok.js.map +1 -0
  21. package/dist/adapters/cli/oh-my-pi.d.ts.map +1 -1
  22. package/dist/adapters/cli/oh-my-pi.js +133 -12
  23. package/dist/adapters/cli/oh-my-pi.js.map +1 -1
  24. package/dist/adapters/cli/registry.d.ts +2 -1
  25. package/dist/adapters/cli/registry.d.ts.map +1 -1
  26. package/dist/adapters/cli/registry.js +3 -1
  27. package/dist/adapters/cli/registry.js.map +1 -1
  28. package/dist/adapters/cli/shared-hints.d.ts +8 -4
  29. package/dist/adapters/cli/shared-hints.d.ts.map +1 -1
  30. package/dist/adapters/cli/shared-hints.js +8 -4
  31. package/dist/adapters/cli/shared-hints.js.map +1 -1
  32. package/dist/adapters/cli/types.d.ts +18 -16
  33. package/dist/adapters/cli/types.d.ts.map +1 -1
  34. package/dist/adapters/hook-installer.d.ts +5 -4
  35. package/dist/adapters/hook-installer.d.ts.map +1 -1
  36. package/dist/adapters/hook-installer.js +42 -0
  37. package/dist/adapters/hook-installer.js.map +1 -1
  38. package/dist/cli/send-dispatch.d.ts +21 -0
  39. package/dist/cli/send-dispatch.d.ts.map +1 -1
  40. package/dist/cli/send-dispatch.js +159 -0
  41. package/dist/cli/send-dispatch.js.map +1 -1
  42. package/dist/cli/session-list-liveness.d.ts +22 -0
  43. package/dist/cli/session-list-liveness.d.ts.map +1 -0
  44. package/dist/cli/session-list-liveness.js +22 -0
  45. package/dist/cli/session-list-liveness.js.map +1 -0
  46. package/dist/cli.d.ts.map +1 -1
  47. package/dist/cli.js +182 -33
  48. package/dist/cli.js.map +1 -1
  49. package/dist/core/ask-types.d.ts +4 -0
  50. package/dist/core/ask-types.d.ts.map +1 -1
  51. package/dist/core/ask-types.js +10 -0
  52. package/dist/core/ask-types.js.map +1 -1
  53. package/dist/core/cost-calculator.d.ts.map +1 -1
  54. package/dist/core/cost-calculator.js +35 -13
  55. package/dist/core/cost-calculator.js.map +1 -1
  56. package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
  57. package/dist/core/dashboard-ipc-server.js +89 -16
  58. package/dist/core/dashboard-ipc-server.js.map +1 -1
  59. package/dist/core/dashboard-rows.d.ts.map +1 -1
  60. package/dist/core/dashboard-rows.js +6 -2
  61. package/dist/core/dashboard-rows.js.map +1 -1
  62. package/dist/core/dashboard-url.d.ts +6 -5
  63. package/dist/core/dashboard-url.d.ts.map +1 -1
  64. package/dist/core/dashboard-url.js +11 -8
  65. package/dist/core/dashboard-url.js.map +1 -1
  66. package/dist/core/maintenance.d.ts +11 -8
  67. package/dist/core/maintenance.d.ts.map +1 -1
  68. package/dist/core/maintenance.js +45 -20
  69. package/dist/core/maintenance.js.map +1 -1
  70. package/dist/core/per-bot-env.d.ts.map +1 -1
  71. package/dist/core/per-bot-env.js +4 -0
  72. package/dist/core/per-bot-env.js.map +1 -1
  73. package/dist/core/session-discovery.d.ts.map +1 -1
  74. package/dist/core/session-discovery.js +4 -0
  75. package/dist/core/session-discovery.js.map +1 -1
  76. package/dist/core/skills/cli-admin-command.d.ts.map +1 -1
  77. package/dist/core/skills/cli-admin-command.js +8 -2
  78. package/dist/core/skills/cli-admin-command.js.map +1 -1
  79. package/dist/core/skills/im-command.d.ts.map +1 -1
  80. package/dist/core/skills/im-command.js +3 -1
  81. package/dist/core/skills/im-command.js.map +1 -1
  82. package/dist/core/skills/sources.d.ts +33 -1
  83. package/dist/core/skills/sources.d.ts.map +1 -1
  84. package/dist/core/skills/sources.js +97 -0
  85. package/dist/core/skills/sources.js.map +1 -1
  86. package/dist/core/skills/types.d.ts +8 -0
  87. package/dist/core/skills/types.d.ts.map +1 -1
  88. package/dist/core/terminal-url.d.ts.map +1 -1
  89. package/dist/core/terminal-url.js +12 -2
  90. package/dist/core/terminal-url.js.map +1 -1
  91. package/dist/core/terminal-write-auth.d.ts +34 -0
  92. package/dist/core/terminal-write-auth.d.ts.map +1 -0
  93. package/dist/core/terminal-write-auth.js +76 -0
  94. package/dist/core/terminal-write-auth.js.map +1 -0
  95. package/dist/core/tmux-recovery.d.ts +11 -0
  96. package/dist/core/tmux-recovery.d.ts.map +1 -0
  97. package/dist/core/tmux-recovery.js +19 -0
  98. package/dist/core/tmux-recovery.js.map +1 -0
  99. package/dist/core/types.d.ts +10 -4
  100. package/dist/core/types.d.ts.map +1 -1
  101. package/dist/core/types.js.map +1 -1
  102. package/dist/core/update-check.d.ts +2 -2
  103. package/dist/core/update-check.js +2 -2
  104. package/dist/core/worker-pool.d.ts +3 -0
  105. package/dist/core/worker-pool.d.ts.map +1 -1
  106. package/dist/core/worker-pool.js +70 -3
  107. package/dist/core/worker-pool.js.map +1 -1
  108. package/dist/daemon.d.ts.map +1 -1
  109. package/dist/daemon.js +15 -8
  110. package/dist/daemon.js.map +1 -1
  111. package/dist/dashboard/auth.d.ts +1 -1
  112. package/dist/dashboard/auth.d.ts.map +1 -1
  113. package/dist/dashboard/auth.js +7 -2
  114. package/dist/dashboard/auth.js.map +1 -1
  115. package/dist/dashboard/bot-payload.d.ts +3 -0
  116. package/dist/dashboard/bot-payload.d.ts.map +1 -1
  117. package/dist/dashboard/bot-payload.js +3 -0
  118. package/dist/dashboard/bot-payload.js.map +1 -1
  119. package/dist/dashboard/connector-api.d.ts.map +1 -1
  120. package/dist/dashboard/connector-api.js +39 -13
  121. package/dist/dashboard/connector-api.js.map +1 -1
  122. package/dist/dashboard/history-senders.d.ts +37 -0
  123. package/dist/dashboard/history-senders.d.ts.map +1 -0
  124. package/dist/dashboard/history-senders.js +60 -0
  125. package/dist/dashboard/history-senders.js.map +1 -0
  126. package/dist/dashboard/roles-batch.d.ts +31 -0
  127. package/dist/dashboard/roles-batch.d.ts.map +1 -0
  128. package/dist/dashboard/roles-batch.js +87 -0
  129. package/dist/dashboard/roles-batch.js.map +1 -0
  130. package/dist/dashboard/settings-card-model.d.ts +4 -2
  131. package/dist/dashboard/settings-card-model.d.ts.map +1 -1
  132. package/dist/dashboard/settings-card-model.js +13 -5
  133. package/dist/dashboard/settings-card-model.js.map +1 -1
  134. package/dist/dashboard/settings-write-applier.d.ts +4 -1
  135. package/dist/dashboard/settings-write-applier.d.ts.map +1 -1
  136. package/dist/dashboard/settings-write-applier.js +6 -1
  137. package/dist/dashboard/settings-write-applier.js.map +1 -1
  138. package/dist/dashboard/skill-install-request.d.ts +4 -0
  139. package/dist/dashboard/skill-install-request.d.ts.map +1 -1
  140. package/dist/dashboard/skill-install-request.js +11 -1
  141. package/dist/dashboard/skill-install-request.js.map +1 -1
  142. package/dist/dashboard/trigger-api.d.ts +9 -1
  143. package/dist/dashboard/trigger-api.d.ts.map +1 -1
  144. package/dist/dashboard/trigger-api.js +48 -10
  145. package/dist/dashboard/trigger-api.js.map +1 -1
  146. package/dist/dashboard/web/app.d.ts.map +1 -1
  147. package/dist/dashboard/web/app.js +286 -271
  148. package/dist/dashboard/web/app.js.map +1 -1
  149. package/dist/dashboard/web/bot-defaults-page.d.ts +26 -0
  150. package/dist/dashboard/web/bot-defaults-page.d.ts.map +1 -1
  151. package/dist/dashboard/web/bot-defaults-page.js +1408 -12
  152. package/dist/dashboard/web/bot-defaults-page.js.map +1 -1
  153. package/dist/dashboard/web/bot-defaults.d.ts +91 -4
  154. package/dist/dashboard/web/bot-defaults.d.ts.map +1 -1
  155. package/dist/dashboard/web/bot-defaults.js +43 -2141
  156. package/dist/dashboard/web/bot-defaults.js.map +1 -1
  157. package/dist/dashboard/web/bot-onboarding.d.ts +6 -1
  158. package/dist/dashboard/web/bot-onboarding.d.ts.map +1 -1
  159. package/dist/dashboard/web/bot-onboarding.js +261 -306
  160. package/dist/dashboard/web/bot-onboarding.js.map +1 -1
  161. package/dist/dashboard/web/connectors-page.d.ts +4 -0
  162. package/dist/dashboard/web/connectors-page.d.ts.map +1 -1
  163. package/dist/dashboard/web/connectors-page.js +228 -48
  164. package/dist/dashboard/web/connectors-page.js.map +1 -1
  165. package/dist/dashboard/web/dashboard-api.d.ts +9 -0
  166. package/dist/dashboard/web/dashboard-api.d.ts.map +1 -0
  167. package/dist/dashboard/web/dashboard-api.js +18 -0
  168. package/dist/dashboard/web/dashboard-api.js.map +1 -0
  169. package/dist/dashboard/web/dashboard-components.d.ts +92 -0
  170. package/dist/dashboard/web/dashboard-components.d.ts.map +1 -0
  171. package/dist/dashboard/web/dashboard-components.js +250 -0
  172. package/dist/dashboard/web/dashboard-components.js.map +1 -0
  173. package/dist/dashboard/web/dashboard-routes.d.ts.map +1 -1
  174. package/dist/dashboard/web/dashboard-routes.js +30 -183
  175. package/dist/dashboard/web/dashboard-routes.js.map +1 -1
  176. package/dist/dashboard/web/floating-scrollbars.d.ts +2 -0
  177. package/dist/dashboard/web/floating-scrollbars.d.ts.map +1 -0
  178. package/dist/dashboard/web/floating-scrollbars.js +264 -0
  179. package/dist/dashboard/web/floating-scrollbars.js.map +1 -0
  180. package/dist/dashboard/web/groups-api.d.ts +36 -0
  181. package/dist/dashboard/web/groups-api.d.ts.map +1 -0
  182. package/dist/dashboard/web/groups-api.js +44 -0
  183. package/dist/dashboard/web/groups-api.js.map +1 -0
  184. package/dist/dashboard/web/groups-page.d.ts.map +1 -1
  185. package/dist/dashboard/web/groups-page.js +746 -15
  186. package/dist/dashboard/web/groups-page.js.map +1 -1
  187. package/dist/dashboard/web/groups.d.ts +51 -18
  188. package/dist/dashboard/web/groups.d.ts.map +1 -1
  189. package/dist/dashboard/web/groups.js +145 -1096
  190. package/dist/dashboard/web/groups.js.map +1 -1
  191. package/dist/dashboard/web/i18n.d.ts.map +1 -1
  192. package/dist/dashboard/web/i18n.js +545 -255
  193. package/dist/dashboard/web/i18n.js.map +1 -1
  194. package/dist/dashboard/web/insights-page.d.ts.map +1 -1
  195. package/dist/dashboard/web/insights-page.js +1047 -14
  196. package/dist/dashboard/web/insights-page.js.map +1 -1
  197. package/dist/dashboard/web/insights.d.ts +177 -7
  198. package/dist/dashboard/web/insights.d.ts.map +1 -1
  199. package/dist/dashboard/web/insights.js +187 -1926
  200. package/dist/dashboard/web/insights.js.map +1 -1
  201. package/dist/dashboard/web/legacy-workflow-page.d.ts +3 -0
  202. package/dist/dashboard/web/legacy-workflow-page.d.ts.map +1 -0
  203. package/dist/dashboard/web/legacy-workflow-page.js +717 -0
  204. package/dist/dashboard/web/legacy-workflow-page.js.map +1 -0
  205. package/dist/dashboard/web/monitor-room.d.ts.map +1 -1
  206. package/dist/dashboard/web/monitor-room.js +10 -8
  207. package/dist/dashboard/web/monitor-room.js.map +1 -1
  208. package/dist/dashboard/web/monitoring-page.d.ts.map +1 -1
  209. package/dist/dashboard/web/monitoring-page.js +188 -14
  210. package/dist/dashboard/web/monitoring-page.js.map +1 -1
  211. package/dist/dashboard/web/office-page.d.ts.map +1 -1
  212. package/dist/dashboard/web/office-page.js +11 -23
  213. package/dist/dashboard/web/office-page.js.map +1 -1
  214. package/dist/dashboard/web/overview-page.d.ts.map +1 -1
  215. package/dist/dashboard/web/overview-page.js +141 -147
  216. package/dist/dashboard/web/overview-page.js.map +1 -1
  217. package/dist/dashboard/web/overview.d.ts +0 -1
  218. package/dist/dashboard/web/overview.d.ts.map +1 -1
  219. package/dist/dashboard/web/overview.js +3 -275
  220. package/dist/dashboard/web/overview.js.map +1 -1
  221. package/dist/dashboard/web/preferences.d.ts +1 -6
  222. package/dist/dashboard/web/preferences.d.ts.map +1 -1
  223. package/dist/dashboard/web/preferences.js +0 -21
  224. package/dist/dashboard/web/preferences.js.map +1 -1
  225. package/dist/dashboard/web/role-batch.d.ts +9 -0
  226. package/dist/dashboard/web/role-batch.d.ts.map +1 -0
  227. package/dist/dashboard/web/role-batch.js +42 -0
  228. package/dist/dashboard/web/role-batch.js.map +1 -0
  229. package/dist/dashboard/web/roles-page.d.ts.map +1 -1
  230. package/dist/dashboard/web/roles-page.js +538 -13
  231. package/dist/dashboard/web/roles-page.js.map +1 -1
  232. package/dist/dashboard/web/roles.d.ts +98 -1
  233. package/dist/dashboard/web/roles.d.ts.map +1 -1
  234. package/dist/dashboard/web/roles.js +117 -903
  235. package/dist/dashboard/web/roles.js.map +1 -1
  236. package/dist/dashboard/web/schedules-page.d.ts.map +1 -1
  237. package/dist/dashboard/web/schedules-page.js +82 -24
  238. package/dist/dashboard/web/schedules-page.js.map +1 -1
  239. package/dist/dashboard/web/sessions-kanban.d.ts +67 -0
  240. package/dist/dashboard/web/sessions-kanban.d.ts.map +1 -0
  241. package/dist/dashboard/web/sessions-kanban.js +481 -0
  242. package/dist/dashboard/web/sessions-kanban.js.map +1 -0
  243. package/dist/dashboard/web/sessions-page.d.ts +4 -0
  244. package/dist/dashboard/web/sessions-page.d.ts.map +1 -1
  245. package/dist/dashboard/web/sessions-page.js +1633 -18
  246. package/dist/dashboard/web/sessions-page.js.map +1 -1
  247. package/dist/dashboard/web/sessions.d.ts +45 -4
  248. package/dist/dashboard/web/sessions.d.ts.map +1 -1
  249. package/dist/dashboard/web/sessions.js +53 -2535
  250. package/dist/dashboard/web/sessions.js.map +1 -1
  251. package/dist/dashboard/web/settings-page.d.ts +0 -2
  252. package/dist/dashboard/web/settings-page.d.ts.map +1 -1
  253. package/dist/dashboard/web/settings-page.js +127 -117
  254. package/dist/dashboard/web/settings-page.js.map +1 -1
  255. package/dist/dashboard/web/skills-page.d.ts +10 -1
  256. package/dist/dashboard/web/skills-page.d.ts.map +1 -1
  257. package/dist/dashboard/web/skills-page.js +235 -93
  258. package/dist/dashboard/web/skills-page.js.map +1 -1
  259. package/dist/dashboard/web/team-federation-page.d.ts.map +1 -1
  260. package/dist/dashboard/web/team-federation-page.js +446 -28
  261. package/dist/dashboard/web/team-federation-page.js.map +1 -1
  262. package/dist/dashboard/web/team-federation.d.ts +91 -2
  263. package/dist/dashboard/web/team-federation.d.ts.map +1 -1
  264. package/dist/dashboard/web/team-federation.js +87 -474
  265. package/dist/dashboard/web/team-federation.js.map +1 -1
  266. package/dist/dashboard/web/theme-menu.d.ts +1 -0
  267. package/dist/dashboard/web/theme-menu.d.ts.map +1 -1
  268. package/dist/dashboard/web/theme-menu.js +79 -20
  269. package/dist/dashboard/web/theme-menu.js.map +1 -1
  270. package/dist/dashboard/web/ui.d.ts +1 -2
  271. package/dist/dashboard/web/ui.d.ts.map +1 -1
  272. package/dist/dashboard/web/ui.js +8 -20
  273. package/dist/dashboard/web/ui.js.map +1 -1
  274. package/dist/dashboard/web/v3-api.d.ts +16 -0
  275. package/dist/dashboard/web/v3-api.d.ts.map +1 -0
  276. package/dist/dashboard/web/v3-api.js +21 -0
  277. package/dist/dashboard/web/v3-api.js.map +1 -0
  278. package/dist/dashboard/web/v3-components.d.ts +2 -0
  279. package/dist/dashboard/web/v3-components.d.ts.map +1 -0
  280. package/dist/dashboard/web/v3-components.js +290 -0
  281. package/dist/dashboard/web/v3-components.js.map +1 -0
  282. package/dist/dashboard/web/v3-model.d.ts +80 -0
  283. package/dist/dashboard/web/v3-model.d.ts.map +1 -0
  284. package/dist/dashboard/web/v3-model.js +240 -0
  285. package/dist/dashboard/web/v3-model.js.map +1 -0
  286. package/dist/dashboard/web/v3-page.d.ts.map +1 -1
  287. package/dist/dashboard/web/v3-page.js +2 -22
  288. package/dist/dashboard/web/v3-page.js.map +1 -1
  289. package/dist/dashboard/web/v3-terminal.d.ts +14 -0
  290. package/dist/dashboard/web/v3-terminal.d.ts.map +1 -1
  291. package/dist/dashboard/web/v3-terminal.js +31 -19
  292. package/dist/dashboard/web/v3-terminal.js.map +1 -1
  293. package/dist/dashboard/web/webhook-logs-page.d.ts +16 -0
  294. package/dist/dashboard/web/webhook-logs-page.d.ts.map +1 -0
  295. package/dist/dashboard/web/webhook-logs-page.js +195 -0
  296. package/dist/dashboard/web/webhook-logs-page.js.map +1 -0
  297. package/dist/dashboard/web/whiteboards-page.d.ts.map +1 -1
  298. package/dist/dashboard/web/whiteboards-page.js +18 -23
  299. package/dist/dashboard/web/whiteboards-page.js.map +1 -1
  300. package/dist/dashboard/web/workflow-version-switch.d.ts +8 -0
  301. package/dist/dashboard/web/workflow-version-switch.d.ts.map +1 -0
  302. package/dist/dashboard/web/workflow-version-switch.js +9 -0
  303. package/dist/dashboard/web/workflow-version-switch.js.map +1 -0
  304. package/dist/dashboard/web/workflows.d.ts +272 -1
  305. package/dist/dashboard/web/workflows.d.ts.map +1 -1
  306. package/dist/dashboard/web/workflows.js +211 -1397
  307. package/dist/dashboard/web/workflows.js.map +1 -1
  308. package/dist/dashboard/webhook-routes.d.ts.map +1 -1
  309. package/dist/dashboard/webhook-routes.js +92 -39
  310. package/dist/dashboard/webhook-routes.js.map +1 -1
  311. package/dist/dashboard-web/app.js +1 -65
  312. package/dist/dashboard-web/brand-logo.png +0 -0
  313. package/dist/dashboard-web/chunks/bot-defaults-page-HSQ6HR3R.js +1 -0
  314. package/dist/dashboard-web/chunks/chunk-6TPODDDC.js +1 -0
  315. package/dist/dashboard-web/chunks/chunk-73EJP2MO.js +1 -0
  316. package/dist/dashboard-web/chunks/chunk-BRTZFELS.js +1 -0
  317. package/dist/dashboard-web/chunks/chunk-EVK77ASG.js +1 -0
  318. package/dist/dashboard-web/chunks/chunk-R3FXBFQH.js +1 -0
  319. package/dist/dashboard-web/chunks/chunk-VRLL7SNU.js +1 -0
  320. package/dist/dashboard-web/chunks/chunk-XCPSHD3G.js +37 -0
  321. package/dist/dashboard-web/chunks/chunk-XJ7BGPJH.js +1 -0
  322. package/dist/dashboard-web/chunks/chunk-YVRWYGXR.js +1 -0
  323. package/dist/dashboard-web/chunks/chunk-ZJING6FY.js +66 -0
  324. package/dist/dashboard-web/chunks/connectors-page-ODUA5UCW.js +1 -0
  325. package/dist/dashboard-web/chunks/groups-page-OYX5M6NK.js +8 -0
  326. package/dist/dashboard-web/chunks/insights-page-YCQO6OCR.js +22 -0
  327. package/dist/dashboard-web/chunks/legacy-workflow-page-XJAUNONP.js +2 -0
  328. package/dist/dashboard-web/chunks/{monitor-room-RFX4HPS5.js → monitor-room-WTZNYAFV.js} +17 -15
  329. package/dist/dashboard-web/chunks/monitoring-page-R6LJUK7G.js +2 -0
  330. package/dist/dashboard-web/chunks/office-page-4OXK3GNR.js +1 -0
  331. package/dist/dashboard-web/chunks/overview-page-4MVEJY6U.js +1 -0
  332. package/dist/dashboard-web/chunks/roles-page-NQDW27VV.js +1 -0
  333. package/dist/dashboard-web/chunks/schedules-page-JRNKYHOX.js +1 -0
  334. package/dist/dashboard-web/chunks/sessions-page-LF7UVI7B.js +3 -0
  335. package/dist/dashboard-web/chunks/settings-page-WGW7KQQS.js +2 -0
  336. package/dist/dashboard-web/chunks/skills-page-AMD4XP3T.js +3 -0
  337. package/dist/dashboard-web/chunks/team-federation-page-SYG3K4GG.js +1 -0
  338. package/dist/dashboard-web/chunks/v3-page-6NFFWNUK.js +94 -0
  339. package/dist/dashboard-web/chunks/whiteboards-page-FBRUK2AS.js +1 -0
  340. package/dist/dashboard-web/favicon.png +0 -0
  341. package/dist/dashboard-web/index.html +5 -69
  342. package/dist/dashboard-web/style.css +18835 -7211
  343. package/dist/dashboard.js +150 -32
  344. package/dist/dashboard.js.map +1 -1
  345. package/dist/global-config.d.ts +2 -2
  346. package/dist/global-config.d.ts.map +1 -1
  347. package/dist/i18n/en.d.ts.map +1 -1
  348. package/dist/i18n/en.js +3 -0
  349. package/dist/i18n/en.js.map +1 -1
  350. package/dist/i18n/zh.d.ts.map +1 -1
  351. package/dist/i18n/zh.js +3 -0
  352. package/dist/i18n/zh.js.map +1 -1
  353. package/dist/im/lark/card-builder.d.ts +7 -5
  354. package/dist/im/lark/card-builder.d.ts.map +1 -1
  355. package/dist/im/lark/card-builder.js +10 -7
  356. package/dist/im/lark/card-builder.js.map +1 -1
  357. package/dist/im/lark/card-handler.d.ts.map +1 -1
  358. package/dist/im/lark/card-handler.js +25 -1
  359. package/dist/im/lark/card-handler.js.map +1 -1
  360. package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
  361. package/dist/im/lark/event-dispatcher.js +84 -0
  362. package/dist/im/lark/event-dispatcher.js.map +1 -1
  363. package/dist/platform/binding.d.ts +9 -0
  364. package/dist/platform/binding.d.ts.map +1 -1
  365. package/dist/platform/binding.js +14 -0
  366. package/dist/platform/binding.js.map +1 -1
  367. package/dist/platform/tunnel-client.d.ts.map +1 -1
  368. package/dist/platform/tunnel-client.js +9 -0
  369. package/dist/platform/tunnel-client.js.map +1 -1
  370. package/dist/services/bot-config-store.d.ts +1 -1
  371. package/dist/services/bot-config-store.d.ts.map +1 -1
  372. package/dist/services/bot-config-store.js +11 -5
  373. package/dist/services/bot-config-store.js.map +1 -1
  374. package/dist/services/file-bridge-path.d.ts +8 -0
  375. package/dist/services/file-bridge-path.d.ts.map +1 -0
  376. package/dist/services/file-bridge-path.js +75 -0
  377. package/dist/services/file-bridge-path.js.map +1 -0
  378. package/dist/services/grok-paths.d.ts +27 -0
  379. package/dist/services/grok-paths.d.ts.map +1 -0
  380. package/dist/services/grok-paths.js +106 -0
  381. package/dist/services/grok-paths.js.map +1 -0
  382. package/dist/services/grok-transcript.d.ts +67 -0
  383. package/dist/services/grok-transcript.d.ts.map +1 -0
  384. package/dist/services/grok-transcript.js +630 -0
  385. package/dist/services/grok-transcript.js.map +1 -0
  386. package/dist/services/hermes-session-filter.d.ts +28 -0
  387. package/dist/services/hermes-session-filter.d.ts.map +1 -0
  388. package/dist/services/hermes-session-filter.js +53 -0
  389. package/dist/services/hermes-session-filter.js.map +1 -0
  390. package/dist/services/hermes-transcript.d.ts +3 -0
  391. package/dist/services/hermes-transcript.d.ts.map +1 -1
  392. package/dist/services/hermes-transcript.js +20 -2
  393. package/dist/services/hermes-transcript.js.map +1 -1
  394. package/dist/services/resumable-session-discovery.d.ts +3 -0
  395. package/dist/services/resumable-session-discovery.d.ts.map +1 -1
  396. package/dist/services/resumable-session-discovery.js +6 -1
  397. package/dist/services/resumable-session-discovery.js.map +1 -1
  398. package/dist/services/skill-registry-store.d.ts +9 -0
  399. package/dist/services/skill-registry-store.d.ts.map +1 -1
  400. package/dist/services/skill-registry-store.js +304 -1
  401. package/dist/services/skill-registry-store.js.map +1 -1
  402. package/dist/services/structured-bridge-clis.d.ts +29 -0
  403. package/dist/services/structured-bridge-clis.d.ts.map +1 -0
  404. package/dist/services/structured-bridge-clis.js +76 -0
  405. package/dist/services/structured-bridge-clis.js.map +1 -0
  406. package/dist/services/trigger-log-store.d.ts +59 -0
  407. package/dist/services/trigger-log-store.d.ts.map +1 -1
  408. package/dist/services/trigger-log-store.js +81 -10
  409. package/dist/services/trigger-log-store.js.map +1 -1
  410. package/dist/services/usage-ledger.d.ts +4 -1
  411. package/dist/services/usage-ledger.d.ts.map +1 -1
  412. package/dist/services/usage-ledger.js +48 -10
  413. package/dist/services/usage-ledger.js.map +1 -1
  414. package/dist/services/webhook-audit.d.ts +10 -0
  415. package/dist/services/webhook-audit.d.ts.map +1 -0
  416. package/dist/services/webhook-audit.js +116 -0
  417. package/dist/services/webhook-audit.js.map +1 -0
  418. package/dist/setup/bot-config-editor.d.ts.map +1 -1
  419. package/dist/setup/bot-config-editor.js +2 -0
  420. package/dist/setup/bot-config-editor.js.map +1 -1
  421. package/dist/setup/ensure-tmux.d.ts +26 -12
  422. package/dist/setup/ensure-tmux.d.ts.map +1 -1
  423. package/dist/setup/ensure-tmux.js +85 -18
  424. package/dist/setup/ensure-tmux.js.map +1 -1
  425. package/dist/skills/definitions.d.ts.map +1 -1
  426. package/dist/skills/definitions.js +14 -1
  427. package/dist/skills/definitions.js.map +1 -1
  428. package/dist/skills/injection-mode.d.ts +16 -0
  429. package/dist/skills/injection-mode.d.ts.map +1 -1
  430. package/dist/skills/injection-mode.js +25 -0
  431. package/dist/skills/injection-mode.js.map +1 -1
  432. package/dist/types.d.ts +9 -0
  433. package/dist/types.d.ts.map +1 -1
  434. package/dist/utils/global-install.d.ts +22 -0
  435. package/dist/utils/global-install.d.ts.map +1 -0
  436. package/dist/utils/global-install.js +106 -0
  437. package/dist/utils/global-install.js.map +1 -0
  438. package/dist/utils/install-diagnostics.d.ts +1 -1
  439. package/dist/utils/install-diagnostics.d.ts.map +1 -1
  440. package/dist/utils/install-diagnostics.js +6 -4
  441. package/dist/utils/install-diagnostics.js.map +1 -1
  442. package/dist/utils/install-info.d.ts +2 -0
  443. package/dist/utils/install-info.d.ts.map +1 -1
  444. package/dist/utils/install-info.js +10 -4
  445. package/dist/utils/install-info.js.map +1 -1
  446. package/dist/worker.js +293 -172
  447. package/dist/worker.js.map +1 -1
  448. package/dist/workflows/events/payloads.d.ts +10 -10
  449. package/dist/workflows/events/schema.d.ts +28 -28
  450. package/package.json +8 -7
  451. package/dist/dashboard/web/connectors.d.ts +0 -2
  452. package/dist/dashboard/web/connectors.d.ts.map +0 -1
  453. package/dist/dashboard/web/connectors.js +0 -2
  454. package/dist/dashboard/web/connectors.js.map +0 -1
  455. package/dist/dashboard/web/office.d.ts +0 -2
  456. package/dist/dashboard/web/office.d.ts.map +0 -1
  457. package/dist/dashboard/web/office.js +0 -2
  458. package/dist/dashboard/web/office.js.map +0 -1
  459. package/dist/dashboard/web/schedules.d.ts +0 -2
  460. package/dist/dashboard/web/schedules.d.ts.map +0 -1
  461. package/dist/dashboard/web/schedules.js +0 -2
  462. package/dist/dashboard/web/schedules.js.map +0 -1
  463. package/dist/dashboard/web/settings.d.ts +0 -2
  464. package/dist/dashboard/web/settings.d.ts.map +0 -1
  465. package/dist/dashboard/web/settings.js +0 -2
  466. package/dist/dashboard/web/settings.js.map +0 -1
  467. package/dist/dashboard/web/skills.d.ts +0 -2
  468. package/dist/dashboard/web/skills.d.ts.map +0 -1
  469. package/dist/dashboard/web/skills.js +0 -2
  470. package/dist/dashboard/web/skills.js.map +0 -1
  471. package/dist/dashboard/web/skin-intro.d.ts +0 -4
  472. package/dist/dashboard/web/skin-intro.d.ts.map +0 -1
  473. package/dist/dashboard/web/skin-intro.js +0 -49
  474. package/dist/dashboard/web/skin-intro.js.map +0 -1
  475. package/dist/dashboard/web/v3.d.ts +0 -3
  476. package/dist/dashboard/web/v3.d.ts.map +0 -1
  477. package/dist/dashboard/web/v3.js +0 -539
  478. package/dist/dashboard/web/v3.js.map +0 -1
  479. package/dist/dashboard/web/whiteboards.d.ts +0 -2
  480. package/dist/dashboard/web/whiteboards.d.ts.map +0 -1
  481. package/dist/dashboard/web/whiteboards.js +0 -2
  482. package/dist/dashboard/web/whiteboards.js.map +0 -1
  483. package/dist/dashboard-web/chunks/bot-defaults-page-OCIHPGEU.js +0 -438
  484. package/dist/dashboard-web/chunks/chunk-3N2PPQVD.js +0 -1
  485. package/dist/dashboard-web/chunks/chunk-3UJYRR2Q.js +0 -37
  486. package/dist/dashboard-web/chunks/chunk-5E3MJJL4.js +0 -1
  487. package/dist/dashboard-web/chunks/chunk-7SZRL6FY.js +0 -1
  488. package/dist/dashboard-web/chunks/chunk-JTSE5VP6.js +0 -54
  489. package/dist/dashboard-web/chunks/chunk-LXIK7OUJ.js +0 -1
  490. package/dist/dashboard-web/chunks/chunk-PE6W3C2C.js +0 -1
  491. package/dist/dashboard-web/chunks/chunk-QW54DWU3.js +0 -325
  492. package/dist/dashboard-web/chunks/connectors-IGETYWCP.js +0 -1
  493. package/dist/dashboard-web/chunks/groups-page-MYBS4ZYJ.js +0 -207
  494. package/dist/dashboard-web/chunks/insights-page-UPA32V2S.js +0 -309
  495. package/dist/dashboard-web/chunks/monitoring-page-7T3BESZ2.js +0 -1
  496. package/dist/dashboard-web/chunks/office-page-6DXYOG55.js +0 -1
  497. package/dist/dashboard-web/chunks/overview-page-LJSBCQW4.js +0 -1
  498. package/dist/dashboard-web/chunks/roles-page-ESURTVQH.js +0 -98
  499. package/dist/dashboard-web/chunks/schedules-LML2ISOT.js +0 -1
  500. package/dist/dashboard-web/chunks/sessions-YB73XOTU.js +0 -1
  501. package/dist/dashboard-web/chunks/sessions-page-MCO5QR7Z.js +0 -1
  502. package/dist/dashboard-web/chunks/settings-page-OSDKNVS3.js +0 -2
  503. package/dist/dashboard-web/chunks/skills-page-PXBZJ6P6.js +0 -2
  504. package/dist/dashboard-web/chunks/team-federation-page-TTPVHFPX.js +0 -10
  505. package/dist/dashboard-web/chunks/v3-page-FVPUL665.js +0 -149
  506. package/dist/dashboard-web/chunks/whiteboards-page-HLCTYSSV.js +0 -1
  507. package/dist/dashboard-web/chunks/workflows-FCPM4S4D.js +0 -184
  508. package/dist/dashboard-web/skins/bluearchive-hero.webp +0 -0
  509. package/dist/dashboard-web/skins/dragonball-goku.webp +0 -0
  510. package/dist/dashboard-web/skins/dragonball-wukong.webp +0 -0
  511. package/dist/dashboard-web/skins/genshin-breeze.webp +0 -0
  512. package/dist/dashboard-web/skins/ikun-hero.webp +0 -0
  513. package/dist/dashboard-web/skins/prts-priestess.webp +0 -0
  514. package/dist/dashboard-web/skins/zzz-hero.webp +0 -0
  515. package/dist/dashboard-web/skins/zzz-pattern.svg +0 -25
package/dist/dashboard.js CHANGED
@@ -33,11 +33,12 @@ import { invalidateGlobalConfigCache, mergeGlobalConfig, readGlobalConfig } from
33
33
  import { hostLocalTimeZone, scheduleTimeZone } from './utils/timezone.js';
34
34
  import { buildDashboardUrls } from './core/dashboard-url.js';
35
35
  import { deleteWhiteboard, listWhiteboards, readWhiteboard, whiteboardEnabled } from './services/whiteboard-store.js';
36
- import { isLocalDevInstall, botmuxVersion, botmuxCliEntry } from './utils/install-info.js';
36
+ import { isLocalDevInstall, botmuxVersionAt, botmuxCliEntry, botmuxInstallRoot } from './utils/install-info.js';
37
37
  import { checkNode, detectBotmuxInstalls, resolveCurrentVersion } from './utils/install-diagnostics.js';
38
38
  import { fetchLatestVersion, fetchReleasesSince, isNewerVersion } from './core/update-check.js';
39
39
  import { GITHUB_REPO } from './core/restart-report.js';
40
- import { spawnDetachedRestart, npmGlobalUpdateLockTarget, npmGlobalUpdateCwd } from './core/maintenance.js';
40
+ import { spawnDetachedRestart, globalInstallUpdateLockTarget, globalInstallUpdateCwd } from './core/maintenance.js';
41
+ import { detectGlobalInstallManager, formatGlobalInstallCommand, resolveGlobalInstallPlan, tryResolveGlobalInstallPlan, UnsupportedGlobalInstallError, } from './utils/global-install.js';
41
42
  import { writeRestartIntent } from './services/restart-intent-store.js';
42
43
  import { withFileLock } from './utils/file-lock.js';
43
44
  import { spawn } from 'node:child_process';
@@ -63,6 +64,7 @@ import { startPlatformTunnelClient } from './platform/tunnel-client.js';
63
64
  import { applyPlatformTeamSync, getPlatformTeamSyncRev, listPlatformTeams } from './services/platform-team-store.js';
64
65
  import { getBotUnionId } from './services/bot-union-ids-store.js';
65
66
  import { cleanupIdleSessions, parseIdleCleanupHours } from './dashboard/session-cleanup.js';
67
+ import { aggregateRoleBatch, parseRoleBatchTargets } from './dashboard/roles-batch.js';
66
68
  import { automateOpenPlatformSetup } from './setup/open-platform-automation.js';
67
69
  import { VC_MEETING_FEATURE_SCOPES, VC_MEETING_REALTIME_VOICE_SCOPES } from './setup/verify-permissions.js';
68
70
  import { checkLarkCliVersion, MIN_LARK_CLI_VERSION_FOR_VC_BOT } from './vc-agent/polling-source.js';
@@ -200,9 +202,9 @@ function spawnStartBotLive(appId) {
200
202
  stdio: ['ignore', 'pipe', 'pipe'],
201
203
  env: process.env,
202
204
  // Run from HOME, not the dashboard's cwd (pm2 `cwd: PKG_ROOT`): a global
203
- // npm update replaces that dir, so a still-running dashboard would spawn
204
- // start-bot in a deleted directory (uv_cwd/ENOENT). See npmGlobalUpdateCwd.
205
- cwd: npmGlobalUpdateCwd(),
205
+ // package update replaces that dir, so a still-running dashboard would spawn
206
+ // start-bot in a deleted directory (uv_cwd/ENOENT). See globalInstallUpdateCwd.
207
+ cwd: globalInstallUpdateCwd(),
206
208
  });
207
209
  const timer = setTimeout(() => {
208
210
  try {
@@ -612,6 +614,7 @@ function resolveDashboardSettings() {
612
614
  repoPickerMode: global.repoPickerMode ?? 'all',
613
615
  maintenance: global.maintenance ?? {},
614
616
  localDevInstall: isLocalDevInstall(),
617
+ autoUpdateSupported: lastSuccessfulUpdatePlan !== undefined || tryResolveGlobalInstallPlan() !== null,
615
618
  whiteboard: { enabled: global.whiteboard?.enabled === true },
616
619
  remoteAccess: global.remoteAccess === true,
617
620
  scheduleTimeZone: global.scheduleTimeZone ?? null,
@@ -691,6 +694,10 @@ async function readJsonBody(req) {
691
694
  * Cross-process serialization against the maintenance auto-update (a different
692
695
  * process) is handled separately by the shared file lock in the run route. */
693
696
  let updateInFlight = false;
697
+ // The dashboard process survives while pnpm swaps its versioned realpath. Keep
698
+ // the successful plan (including its stable package root) so follow-up status,
699
+ // update, and restart requests do not reuse the removed old runtime realpath.
700
+ let lastSuccessfulUpdatePlan;
694
701
  // Cache the upstream version/changelog lookups so the nav-badge check + the
695
702
  // Settings card don't hammer the npm registry / GitHub on every page load.
696
703
  // GitHub's unauthenticated API is only 60 req/h per IP, so caching the changelog
@@ -717,19 +724,19 @@ async function cachedChangelog(current, now = Date.now()) {
717
724
  return value;
718
725
  }
719
726
  /**
720
- * Run `npm install -g botmux@latest` for the manual-update flow WITHOUT blocking
727
+ * Run the ownership-aware npm/pnpm update for the manual-update flow WITHOUT blocking
721
728
  * the event loop (async spawn, not execSync — the dashboard must keep serving
722
729
  * during the ~10-30s install). Resolves on exit 0; rejects with the tail of
723
730
  * stdout/stderr on a non-zero exit, spawn error, or 3-minute timeout. Args are
724
731
  * a fixed literal — no shell interpolation of untrusted input.
725
732
  */
726
- function runNpmInstallLatest() {
733
+ function runGlobalInstallLatest(plan) {
727
734
  return new Promise((resolve, reject) => {
728
- const child = spawn('npm', ['install', '-g', 'botmux@latest'], {
729
- cwd: npmGlobalUpdateCwd(),
735
+ const child = spawn(plan.command, plan.args, {
736
+ cwd: globalInstallUpdateCwd(),
730
737
  env: process.env,
731
738
  stdio: ['ignore', 'pipe', 'pipe'],
732
- shell: process.platform === 'win32', // resolve npm.cmd on Windows
739
+ shell: process.platform === 'win32', // resolve npm.cmd / pnpm.cmd
733
740
  });
734
741
  let tail = '';
735
742
  const capture = (d) => { tail = (tail + d.toString()).slice(-2000); };
@@ -737,7 +744,7 @@ function runNpmInstallLatest() {
737
744
  child.stderr?.on('data', capture);
738
745
  const timer = setTimeout(() => {
739
746
  child.kill('SIGKILL');
740
- reject(new Error('npm install timed out after 180s'));
747
+ reject(new Error(`${plan.manager} install timed out after 180s`));
741
748
  }, 180_000);
742
749
  child.on('error', (e) => { clearTimeout(timer); reject(e); });
743
750
  child.on('exit', (code) => {
@@ -745,7 +752,7 @@ function runNpmInstallLatest() {
745
752
  if (code === 0)
746
753
  resolve();
747
754
  else
748
- reject(new Error(`npm exited ${code}: ${tail.trim().slice(-500)}`));
755
+ reject(new Error(`${plan.manager} exited ${code}: ${tail.trim().slice(-500)}`));
749
756
  });
750
757
  });
751
758
  }
@@ -830,6 +837,8 @@ resourceMonitor.start();
830
837
  // Path to the bundled frontend (sibling of dist/dashboard.js)
831
838
  const __dirname = dirname(fileURLToPath(import.meta.url));
832
839
  const WEB_DIR = join(__dirname, 'dashboard-web');
840
+ const DEV_RELOAD_MARKER = join(WEB_DIR, '.botmux-dashboard-dev');
841
+ const DEV_RELOAD_VERSION = join(WEB_DIR, '.botmux-dashboard-reload');
833
842
  const MIME = {
834
843
  '.html': 'text/html; charset=utf-8',
835
844
  '.js': 'application/javascript',
@@ -862,6 +871,36 @@ function serveFileAbs(res, fp) {
862
871
  createReadStream(fp).pipe(res);
863
872
  return true;
864
873
  }
874
+ function dashboardDevReloadEnabled() {
875
+ return process.env.BOTMUX_DASHBOARD_DEV_RELOAD === '1' || existsSync(DEV_RELOAD_MARKER);
876
+ }
877
+ function dashboardDevReloadVersion() {
878
+ try {
879
+ const st = statSync(DEV_RELOAD_VERSION);
880
+ if (!st.isFile())
881
+ return null;
882
+ return `${st.size}:${Math.floor(st.mtimeMs)}`;
883
+ }
884
+ catch {
885
+ return null;
886
+ }
887
+ }
888
+ function devReloadSnippet() {
889
+ return `
890
+ <script type="module">
891
+ (() => {
892
+ if (!('__BOTMUX_DASHBOARD_DEV_RELOAD__' in window)) {
893
+ Object.defineProperty(window, '__BOTMUX_DASHBOARD_DEV_RELOAD__', { value: true });
894
+ const source = new EventSource('/__dev/reload');
895
+ source.addEventListener('reload', () => location.reload());
896
+ }
897
+ })();
898
+ </script>`;
899
+ }
900
+ function injectDevReload(html) {
901
+ const snippet = devReloadSnippet();
902
+ return html.includes('</body>') ? html.replace('</body>', `${snippet}\n</body>`) : `${html}\n${snippet}`;
903
+ }
865
904
  function serveStatic(req, res, pathname) {
866
905
  const rel = pathname === '/' ? 'index.html' : pathname.replace(/^\/+/, '');
867
906
  const fp = resolve(WEB_DIR, rel);
@@ -879,18 +918,28 @@ function serveStatic(req, res, pathname) {
879
918
  // and can be cached immutably once the current app.js points at them.
880
919
  const immutableChunk = relToRoot.startsWith('chunks/') || relToRoot.startsWith('chunks\\');
881
920
  const etag = `W/"${st.size.toString(16)}-${Math.floor(st.mtimeMs).toString(16)}"`;
921
+ const devIndex = relToRoot === 'index.html' && dashboardDevReloadEnabled();
882
922
  const headers = {
883
923
  'content-type': MIME[extname(fp)] ?? 'application/octet-stream',
884
- 'cache-control': immutableChunk ? 'public, max-age=31536000, immutable' : 'no-cache',
924
+ 'cache-control': devIndex ? 'no-store' : immutableChunk ? 'public, max-age=31536000, immutable' : 'no-cache',
885
925
  etag,
886
926
  };
887
- if (req.headers['if-none-match'] === etag) {
927
+ if (!devIndex && req.headers['if-none-match'] === etag) {
888
928
  res.writeHead(304, headers);
889
929
  res.end();
890
930
  return true;
891
931
  }
892
932
  res.writeHead(200, headers);
893
- res.end(readFileSync(fp));
933
+ if (req.method === 'HEAD') {
934
+ res.end();
935
+ return true;
936
+ }
937
+ if (devIndex) {
938
+ res.end(injectDevReload(readFileSync(fp, 'utf8')));
939
+ }
940
+ else {
941
+ res.end(readFileSync(fp));
942
+ }
894
943
  return true;
895
944
  }
896
945
  catch {
@@ -1473,9 +1522,34 @@ const server = createServer(async (req, res) => {
1473
1522
  res.end();
1474
1523
  return;
1475
1524
  }
1476
- // ─── Static frontend (index.html + /assets/* + /game/*) ────────────────
1477
- if (req.method === 'GET' &&
1478
- (url.pathname === '/' || url.pathname.startsWith('/assets/') || url.pathname.startsWith('/game/'))) {
1525
+ if (req.method === 'GET' && url.pathname === '/__dev/reload') {
1526
+ if (!dashboardDevReloadEnabled())
1527
+ return jsonRes(res, 404, { error: 'dev_reload_disabled' });
1528
+ res.writeHead(200, {
1529
+ 'content-type': 'text/event-stream; charset=utf-8',
1530
+ 'cache-control': 'no-cache, no-transform',
1531
+ connection: 'keep-alive',
1532
+ });
1533
+ let last = dashboardDevReloadVersion();
1534
+ res.write(`event: ready\ndata: ${JSON.stringify({ version: last })}\n\n`);
1535
+ const timer = setInterval(() => {
1536
+ const next = dashboardDevReloadVersion();
1537
+ if (!next || next === last)
1538
+ return;
1539
+ last = next;
1540
+ res.write(`event: reload\ndata: ${JSON.stringify({ version: next })}\n\n`);
1541
+ }, 500);
1542
+ req.on('close', () => clearInterval(timer));
1543
+ return;
1544
+ }
1545
+ // ─── Static frontend (index.html + /assets/* + /game/* + root icons) ───
1546
+ if ((req.method === 'GET' || req.method === 'HEAD') &&
1547
+ (url.pathname === '/' ||
1548
+ url.pathname === '/favicon.ico' ||
1549
+ url.pathname === '/favicon.png' ||
1550
+ url.pathname === '/apple-touch-icon.png' ||
1551
+ url.pathname.startsWith('/assets/') ||
1552
+ url.pathname.startsWith('/game/'))) {
1479
1553
  // HD2D runtime binaries (index.wasm / index.pck) are NOT shipped — they
1480
1554
  // are downloaded on demand into the cache dir and served from there.
1481
1555
  // Everything else under /game/ is the small shell shipped in dist.
@@ -1487,10 +1561,12 @@ const server = createServer(async (req, res) => {
1487
1561
  res.end();
1488
1562
  return;
1489
1563
  }
1490
- // Map /assets/foo.js → WEB_DIR/foo.js; /game/* is served as-is.
1564
+ // Map /assets/foo.js → WEB_DIR/foo.js; /favicon.ico is an alias for the PNG favicon.
1491
1565
  const lookupPath = url.pathname.startsWith('/assets/')
1492
1566
  ? '/' + url.pathname.slice(8)
1493
- : url.pathname;
1567
+ : url.pathname === '/favicon.ico'
1568
+ ? '/favicon.png'
1569
+ : url.pathname;
1494
1570
  if (serveStatic(req, res, lookupPath))
1495
1571
  return;
1496
1572
  }
@@ -1653,12 +1729,15 @@ const server = createServer(async (req, res) => {
1653
1729
  return jsonRes(res, 200, { ok: true, settings: result.settings });
1654
1730
  }
1655
1731
  // ─── Version & manual update ─────────────────────────────────────────────
1656
- // `npm install -g` and a host restart are privileged: none of these paths
1732
+ // Global package updates and a host restart are privileged: none of these paths
1657
1733
  // are on PUBLIC_READ_PATHS, so decideDashboardAuth already 401s an
1658
1734
  // unauthenticated caller (in both normal and public-read mode). The explicit
1659
1735
  // `authed` guards on the two mutations are defense-in-depth for host actions.
1660
1736
  if (req.method === 'GET' && url.pathname === '/api/update/status') {
1661
1737
  const current = resolveCurrentVersion();
1738
+ const packageRoot = botmuxInstallRoot();
1739
+ const installManager = detectGlobalInstallManager(packageRoot);
1740
+ const installPlan = lastSuccessfulUpdatePlan ?? tryResolveGlobalInstallPlan(packageRoot);
1662
1741
  // Compare against the npm `latest` dist-tag (always stable; the update
1663
1742
  // button installs `@latest`). isNewerVersion uses semver precedence, so a
1664
1743
  // canary running AHEAD of the latest stable (e.g. 2.87.0-canary.0 vs
@@ -1669,6 +1748,9 @@ const server = createServer(async (req, res) => {
1669
1748
  latest,
1670
1749
  behind: !!latest && isNewerVersion(latest, current),
1671
1750
  localDevInstall: isLocalDevInstall(),
1751
+ updateSupported: installPlan !== null,
1752
+ updateManager: installPlan?.manager ?? installManager,
1753
+ updateCommand: installPlan ? formatGlobalInstallCommand(installPlan) : null,
1672
1754
  node: checkNode(),
1673
1755
  installs: detectBotmuxInstalls(),
1674
1756
  });
@@ -1689,35 +1771,56 @@ const server = createServer(async (req, res) => {
1689
1771
  return jsonRes(res, 401, { ok: false, error: 'unauthorized' });
1690
1772
  if (isLocalDevInstall())
1691
1773
  return jsonRes(res, 400, { ok: false, error: 'local_dev_no_update' });
1774
+ let installPlan;
1775
+ try {
1776
+ installPlan = lastSuccessfulUpdatePlan ?? resolveGlobalInstallPlan();
1777
+ }
1778
+ catch (error) {
1779
+ if (error instanceof UnsupportedGlobalInstallError) {
1780
+ return jsonRes(res, 400, {
1781
+ ok: false,
1782
+ error: 'unsupported_install_method',
1783
+ manager: error.manager,
1784
+ });
1785
+ }
1786
+ throw error;
1787
+ }
1692
1788
  const node = checkNode();
1693
1789
  if (!node.ok)
1694
1790
  return jsonRes(res, 400, { ok: false, error: 'node_too_old', node });
1695
1791
  if (updateInFlight)
1696
1792
  return jsonRes(res, 409, { ok: false, error: 'update_in_flight' });
1697
1793
  updateInFlight = true;
1698
- const oldVersion = botmuxVersion();
1794
+ const oldVersion = botmuxVersionAt(installPlan.activePackageRoot);
1699
1795
  // Acquire the shared cross-process lock so a scheduled maintenance
1700
- // auto-update (running in the bot-0 daemon) can't `npm install -g` at the
1701
- // same time. `acquired` distinguishes "lock held by maintenance" (409)
1702
- // from "npm itself failed" (500). Short wait: don't block the request on a
1703
- // full in-progress install — report busy fast.
1796
+ // auto-update (running in the bot-0 daemon) can't update the same global
1797
+ // install concurrently. `acquired` distinguishes "lock held by
1798
+ // maintenance" (409) from "the package manager failed" (500). Short wait:
1799
+ // don't block the request on a full in-progress install — report busy fast.
1704
1800
  let acquired = false;
1705
1801
  try {
1706
- await withFileLock(npmGlobalUpdateLockTarget(), async () => {
1802
+ await withFileLock(globalInstallUpdateLockTarget(), async () => {
1707
1803
  acquired = true;
1708
- await runNpmInstallLatest();
1804
+ await runGlobalInstallLatest(installPlan);
1709
1805
  }, { maxWaitMs: 2_000 });
1710
1806
  }
1711
1807
  catch (e) {
1712
1808
  if (!acquired)
1713
1809
  return jsonRes(res, 409, { ok: false, error: 'update_in_flight' });
1714
- return jsonRes(res, 500, { ok: false, error: 'npm_failed', detail: e instanceof Error ? e.message : String(e) });
1810
+ return jsonRes(res, 500, { ok: false, error: 'install_failed', detail: e instanceof Error ? e.message : String(e) });
1715
1811
  }
1716
1812
  finally {
1717
1813
  updateInFlight = false;
1718
1814
  }
1719
- const newVersion = botmuxVersion();
1720
- return jsonRes(res, 200, { ok: true, oldVersion, newVersion, changed: newVersion !== oldVersion });
1815
+ const newVersion = botmuxVersionAt(installPlan.activePackageRoot);
1816
+ lastSuccessfulUpdatePlan = installPlan;
1817
+ return jsonRes(res, 200, {
1818
+ ok: true,
1819
+ oldVersion,
1820
+ newVersion,
1821
+ changed: newVersion !== oldVersion,
1822
+ manager: installPlan.manager,
1823
+ });
1721
1824
  }
1722
1825
  if (req.method === 'POST' && url.pathname === '/api/update/restart') {
1723
1826
  if (!authed)
@@ -1739,7 +1842,7 @@ const server = createServer(async (req, res) => {
1739
1842
  }
1740
1843
  catch { /* breadcrumb is best-effort */ }
1741
1844
  }
1742
- spawnDetachedRestart('dashboard');
1845
+ spawnDetachedRestart('dashboard', lastSuccessfulUpdatePlan?.activePackageRoot);
1743
1846
  return jsonRes(res, 200, { ok: true });
1744
1847
  }
1745
1848
  if (req.method === 'GET' && url.pathname === '/api/skills') {
@@ -2193,9 +2296,24 @@ const server = createServer(async (req, res) => {
2193
2296
  });
2194
2297
  }
2195
2298
  // ─── Roles (proxy to daemon) ────────────────────────────────────────────
2299
+ // POST /api/roles/batch → collapse role reads to one request per daemon
2196
2300
  // GET /api/roles/:larkAppId/:chatId → read role file
2197
2301
  // PUT /api/roles/:larkAppId/:chatId → write role file
2198
2302
  // DELETE /api/roles/:larkAppId/:chatId → delete role file
2303
+ if (req.method === 'POST' && url.pathname === '/api/roles/batch') {
2304
+ let body;
2305
+ try {
2306
+ body = await readJsonBody(req);
2307
+ }
2308
+ catch {
2309
+ return jsonRes(res, 400, { ok: false, error: 'bad_json' });
2310
+ }
2311
+ const parsed = parseRoleBatchTargets(body);
2312
+ if (!parsed.ok)
2313
+ return jsonRes(res, 400, { ok: false, error: parsed.error });
2314
+ const result = await aggregateRoleBatch(parsed.targets, proxyToDaemon);
2315
+ return jsonRes(res, 200, result);
2316
+ }
2199
2317
  let mRole;
2200
2318
  if ((mRole = url.pathname.match(/^\/api\/roles\/([^/]+)\/([^/]+)$/))) {
2201
2319
  const larkAppId = decodeURIComponent(mRole[1]);