botmux 2.104.0 → 2.105.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 (329) hide show
  1. package/README.en.md +10 -10
  2. package/README.md +10 -10
  3. package/dist/adapters/backend/sandbox.d.ts +5 -1
  4. package/dist/adapters/backend/sandbox.d.ts.map +1 -1
  5. package/dist/adapters/backend/sandbox.js +54 -5
  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/claude-code.d.ts +1 -1
  12. package/dist/adapters/cli/relay.d.ts +2 -2
  13. package/dist/adapters/cli/relay.js +2 -2
  14. package/dist/adapters/cli/seed.d.ts +2 -2
  15. package/dist/adapters/cli/seed.js +2 -2
  16. package/dist/adapters/cli/shared-hints.d.ts.map +1 -1
  17. package/dist/adapters/cli/shared-hints.js +1 -0
  18. package/dist/adapters/cli/shared-hints.js.map +1 -1
  19. package/dist/bot-registry.d.ts +65 -1
  20. package/dist/bot-registry.d.ts.map +1 -1
  21. package/dist/bot-registry.js +145 -0
  22. package/dist/bot-registry.js.map +1 -1
  23. package/dist/cli/send-dispatch.d.ts +44 -0
  24. package/dist/cli/send-dispatch.d.ts.map +1 -1
  25. package/dist/cli/send-dispatch.js +79 -0
  26. package/dist/cli/send-dispatch.js.map +1 -1
  27. package/dist/cli/vc-agent.d.ts +2 -0
  28. package/dist/cli/vc-agent.d.ts.map +1 -0
  29. package/dist/cli/vc-agent.js +331 -0
  30. package/dist/cli/vc-agent.js.map +1 -0
  31. package/dist/cli.d.ts.map +1 -1
  32. package/dist/cli.js +106 -24
  33. package/dist/cli.js.map +1 -1
  34. package/dist/config.d.ts +8 -0
  35. package/dist/config.d.ts.map +1 -1
  36. package/dist/config.js +13 -1
  37. package/dist/config.js.map +1 -1
  38. package/dist/core/auto-start.d.ts +2 -2
  39. package/dist/core/auto-start.js +2 -2
  40. package/dist/core/command-handler.d.ts.map +1 -1
  41. package/dist/core/command-handler.js +2 -1
  42. package/dist/core/command-handler.js.map +1 -1
  43. package/dist/core/dashboard-events.d.ts +5 -0
  44. package/dist/core/dashboard-events.d.ts.map +1 -1
  45. package/dist/core/dashboard-events.js.map +1 -1
  46. package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
  47. package/dist/core/dashboard-ipc-server.js +47 -2
  48. package/dist/core/dashboard-ipc-server.js.map +1 -1
  49. package/dist/core/idle-worker-sweeper.d.ts +1 -1
  50. package/dist/core/idle-worker-sweeper.js +1 -1
  51. package/dist/core/passthrough-commands.d.ts.map +1 -1
  52. package/dist/core/passthrough-commands.js +1 -0
  53. package/dist/core/passthrough-commands.js.map +1 -1
  54. package/dist/core/scheduler.d.ts +12 -0
  55. package/dist/core/scheduler.d.ts.map +1 -1
  56. package/dist/core/scheduler.js +67 -7
  57. package/dist/core/scheduler.js.map +1 -1
  58. package/dist/core/session-discovery.js +1 -1
  59. package/dist/core/session-discovery.js.map +1 -1
  60. package/dist/core/session-manager.d.ts.map +1 -1
  61. package/dist/core/session-manager.js +33 -7
  62. package/dist/core/session-manager.js.map +1 -1
  63. package/dist/core/trigger-session.d.ts.map +1 -1
  64. package/dist/core/trigger-session.js +78 -23
  65. package/dist/core/trigger-session.js.map +1 -1
  66. package/dist/core/worker-pool.d.ts +4 -1
  67. package/dist/core/worker-pool.d.ts.map +1 -1
  68. package/dist/core/worker-pool.js +4 -0
  69. package/dist/core/worker-pool.js.map +1 -1
  70. package/dist/core/zellij-adopt-discovery.js +1 -1
  71. package/dist/core/zellij-adopt-discovery.js.map +1 -1
  72. package/dist/daemon.d.ts +121 -0
  73. package/dist/daemon.d.ts.map +1 -1
  74. package/dist/daemon.js +2644 -2
  75. package/dist/daemon.js.map +1 -1
  76. package/dist/dashboard/federated-group-core.js +1 -1
  77. package/dist/dashboard/federated-group-core.js.map +1 -1
  78. package/dist/dashboard/federation-api.js +1 -1
  79. package/dist/dashboard/schedule-card-model.d.ts +4 -3
  80. package/dist/dashboard/schedule-card-model.d.ts.map +1 -1
  81. package/dist/dashboard/schedule-card-model.js +5 -4
  82. package/dist/dashboard/schedule-card-model.js.map +1 -1
  83. package/dist/dashboard/settings-write-applier.d.ts +37 -3
  84. package/dist/dashboard/settings-write-applier.d.ts.map +1 -1
  85. package/dist/dashboard/settings-write-applier.js +63 -0
  86. package/dist/dashboard/settings-write-applier.js.map +1 -1
  87. package/dist/dashboard/web/i18n.d.ts.map +1 -1
  88. package/dist/dashboard/web/i18n.js +28 -0
  89. package/dist/dashboard/web/i18n.js.map +1 -1
  90. package/dist/dashboard/web/insights.js +19 -19
  91. package/dist/dashboard/web/insights.js.map +1 -1
  92. package/dist/dashboard/web/overview-page.d.ts.map +1 -1
  93. package/dist/dashboard/web/overview-page.js +7 -4
  94. package/dist/dashboard/web/overview-page.js.map +1 -1
  95. package/dist/dashboard/web/schedules-page.d.ts +1 -1
  96. package/dist/dashboard/web/schedules-page.d.ts.map +1 -1
  97. package/dist/dashboard/web/schedules-page.js +7 -3
  98. package/dist/dashboard/web/schedules-page.js.map +1 -1
  99. package/dist/dashboard/web/sessions.js +2 -2
  100. package/dist/dashboard/web/settings-page.d.ts +9 -0
  101. package/dist/dashboard/web/settings-page.d.ts.map +1 -1
  102. package/dist/dashboard/web/settings-page.js +132 -43
  103. package/dist/dashboard/web/settings-page.js.map +1 -1
  104. package/dist/dashboard/web/store.d.ts +6 -0
  105. package/dist/dashboard/web/store.d.ts.map +1 -1
  106. package/dist/dashboard/web/store.js +18 -1
  107. package/dist/dashboard/web/store.js.map +1 -1
  108. package/dist/dashboard/webhook-routes.d.ts.map +1 -1
  109. package/dist/dashboard/webhook-routes.js +24 -0
  110. package/dist/dashboard/webhook-routes.js.map +1 -1
  111. package/dist/dashboard-web/app.js +3 -3
  112. package/dist/dashboard-web/chunks/{bot-defaults-page-Z36I5CKM.js → bot-defaults-page-3OIY7N76.js} +1 -1
  113. package/dist/dashboard-web/chunks/{chunk-2BBCKWNO.js → chunk-BNEXMNQD.js} +3 -3
  114. package/dist/dashboard-web/chunks/{chunk-QDKIUULH.js → chunk-DKKOGZCG.js} +1 -1
  115. package/dist/dashboard-web/chunks/chunk-LXIK7OUJ.js +1 -0
  116. package/dist/dashboard-web/chunks/{chunk-BAMNP73K.js → chunk-VFCACTRF.js} +1 -1
  117. package/dist/dashboard-web/chunks/{connectors-I3MGERCM.js → connectors-VDOAKUW3.js} +1 -1
  118. package/dist/dashboard-web/chunks/{groups-page-DTP2L4FQ.js → groups-page-CX5AN4XG.js} +1 -1
  119. package/dist/dashboard-web/chunks/{insights-page-FNI24WYF.js → insights-page-DOMRL4S6.js} +1 -1
  120. package/dist/dashboard-web/chunks/overview-page-AZBAXVZ7.js +1 -0
  121. package/dist/dashboard-web/chunks/{roles-page-A5DZ7Q6U.js → roles-page-3FEAH6S4.js} +1 -1
  122. package/dist/dashboard-web/chunks/schedules-CTQEA7IE.js +1 -0
  123. package/dist/dashboard-web/chunks/{sessions-YJ735IH4.js → sessions-LVZCXO2Z.js} +1 -1
  124. package/dist/dashboard-web/chunks/{sessions-page-2REIJ56C.js → sessions-page-NHBJDSBC.js} +1 -1
  125. package/dist/dashboard-web/chunks/settings-page-CRDIHRNE.js +2 -0
  126. package/dist/dashboard-web/chunks/{skills-page-ZCCLHWMJ.js → skills-page-VUG3EPWX.js} +1 -1
  127. package/dist/dashboard-web/chunks/{team-federation-page-4FCGO3WW.js → team-federation-page-ZKL3YMGN.js} +1 -1
  128. package/dist/dashboard-web/chunks/{workflows-KFJ7O57L.js → workflows-4BYQQBFP.js} +1 -1
  129. package/dist/dashboard-web/index.html +1 -1
  130. package/dist/dashboard-web/style.css +111 -16
  131. package/dist/dashboard.js +196 -2
  132. package/dist/dashboard.js.map +1 -1
  133. package/dist/global-config.d.ts +30 -0
  134. package/dist/global-config.d.ts.map +1 -1
  135. package/dist/global-config.js +64 -1
  136. package/dist/global-config.js.map +1 -1
  137. package/dist/i18n/en.d.ts.map +1 -1
  138. package/dist/i18n/en.js +10 -7
  139. package/dist/i18n/en.js.map +1 -1
  140. package/dist/i18n/zh.d.ts.map +1 -1
  141. package/dist/i18n/zh.js +10 -7
  142. package/dist/i18n/zh.js.map +1 -1
  143. package/dist/im/lark/card-builder.d.ts +1 -1
  144. package/dist/im/lark/card-builder.js +1 -1
  145. package/dist/im/lark/card-handler.d.ts +3 -0
  146. package/dist/im/lark/card-handler.d.ts.map +1 -1
  147. package/dist/im/lark/card-handler.js +8 -0
  148. package/dist/im/lark/card-handler.js.map +1 -1
  149. package/dist/im/lark/client.d.ts +1 -0
  150. package/dist/im/lark/client.d.ts.map +1 -1
  151. package/dist/im/lark/client.js +19 -0
  152. package/dist/im/lark/client.js.map +1 -1
  153. package/dist/im/lark/event-dispatcher.d.ts +10 -0
  154. package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
  155. package/dist/im/lark/event-dispatcher.js +100 -21
  156. package/dist/im/lark/event-dispatcher.js.map +1 -1
  157. package/dist/im/lark/grant-command.d.ts +1 -1
  158. package/dist/im/lark/grant-command.js +1 -1
  159. package/dist/im/lark/workflow-slash-command.js +4 -0
  160. package/dist/im/lark/workflow-slash-command.js.map +1 -1
  161. package/dist/mir-prompt.d.ts +16 -0
  162. package/dist/mir-prompt.d.ts.map +1 -0
  163. package/dist/mir-prompt.js +170 -0
  164. package/dist/mir-prompt.js.map +1 -0
  165. package/dist/mir-runner.js +1 -149
  166. package/dist/mir-runner.js.map +1 -1
  167. package/dist/platform/bind.d.ts.map +1 -1
  168. package/dist/platform/bind.js +3 -11
  169. package/dist/platform/bind.js.map +1 -1
  170. package/dist/platform/binding.d.ts +4 -5
  171. package/dist/platform/binding.d.ts.map +1 -1
  172. package/dist/platform/binding.js +0 -11
  173. package/dist/platform/binding.js.map +1 -1
  174. package/dist/platform/tunnel-client.d.ts.map +1 -1
  175. package/dist/platform/tunnel-client.js +37 -28
  176. package/dist/platform/tunnel-client.js.map +1 -1
  177. package/dist/services/deployment-identity.d.ts +1 -1
  178. package/dist/services/deployment-identity.d.ts.map +1 -1
  179. package/dist/services/deployment-identity.js +1 -1
  180. package/dist/services/deployment-identity.js.map +1 -1
  181. package/dist/services/doc-subs-store.js +1 -1
  182. package/dist/services/team-board-store.js +1 -1
  183. package/dist/services/team-board-store.js.map +1 -1
  184. package/dist/services/trigger-types.d.ts +2 -1
  185. package/dist/services/trigger-types.d.ts.map +1 -1
  186. package/dist/services/trigger-types.js +11 -2
  187. package/dist/services/trigger-types.js.map +1 -1
  188. package/dist/services/vc-meeting-runtime-store.d.ts +55 -0
  189. package/dist/services/vc-meeting-runtime-store.d.ts.map +1 -0
  190. package/dist/services/vc-meeting-runtime-store.js +313 -0
  191. package/dist/services/vc-meeting-runtime-store.js.map +1 -0
  192. package/dist/services/voice/index.d.ts +6 -1
  193. package/dist/services/voice/index.d.ts.map +1 -1
  194. package/dist/services/voice/index.js +12 -5
  195. package/dist/services/voice/index.js.map +1 -1
  196. package/dist/services/voice/sami.js +1 -1
  197. package/dist/setup/lark-scopes.json +5 -0
  198. package/dist/setup/verify-permissions.d.ts +6 -0
  199. package/dist/setup/verify-permissions.d.ts.map +1 -1
  200. package/dist/setup/verify-permissions.js +17 -0
  201. package/dist/setup/verify-permissions.js.map +1 -1
  202. package/dist/skills/definitions.d.ts.map +1 -1
  203. package/dist/skills/definitions.js +10 -0
  204. package/dist/skills/definitions.js.map +1 -1
  205. package/dist/utils/daemon-discovery.d.ts +2 -0
  206. package/dist/utils/daemon-discovery.d.ts.map +1 -1
  207. package/dist/utils/daemon-discovery.js +2 -0
  208. package/dist/utils/daemon-discovery.js.map +1 -1
  209. package/dist/utils/timezone.d.ts +51 -0
  210. package/dist/utils/timezone.d.ts.map +1 -0
  211. package/dist/utils/timezone.js +110 -0
  212. package/dist/utils/timezone.js.map +1 -0
  213. package/dist/vc-agent/cards.d.ts +47 -0
  214. package/dist/vc-agent/cards.d.ts.map +1 -0
  215. package/dist/vc-agent/cards.js +489 -0
  216. package/dist/vc-agent/cards.js.map +1 -0
  217. package/dist/vc-agent/meeting-state.d.ts +39 -0
  218. package/dist/vc-agent/meeting-state.d.ts.map +1 -0
  219. package/dist/vc-agent/meeting-state.js +186 -0
  220. package/dist/vc-agent/meeting-state.js.map +1 -0
  221. package/dist/vc-agent/normalizer.d.ts +13 -0
  222. package/dist/vc-agent/normalizer.d.ts.map +1 -0
  223. package/dist/vc-agent/normalizer.js +411 -0
  224. package/dist/vc-agent/normalizer.js.map +1 -0
  225. package/dist/vc-agent/polling-source.d.ts +36 -0
  226. package/dist/vc-agent/polling-source.d.ts.map +1 -0
  227. package/dist/vc-agent/polling-source.js +129 -0
  228. package/dist/vc-agent/polling-source.js.map +1 -0
  229. package/dist/vc-agent/push-source.d.ts +13 -0
  230. package/dist/vc-agent/push-source.d.ts.map +1 -0
  231. package/dist/vc-agent/push-source.js +109 -0
  232. package/dist/vc-agent/push-source.js.map +1 -0
  233. package/dist/vc-agent/realtime/audio-source.d.ts +6 -0
  234. package/dist/vc-agent/realtime/audio-source.d.ts.map +1 -0
  235. package/dist/vc-agent/realtime/audio-source.js +17 -0
  236. package/dist/vc-agent/realtime/audio-source.js.map +1 -0
  237. package/dist/vc-agent/realtime/endpoint.d.ts +6 -0
  238. package/dist/vc-agent/realtime/endpoint.d.ts.map +1 -0
  239. package/dist/vc-agent/realtime/endpoint.js +25 -0
  240. package/dist/vc-agent/realtime/endpoint.js.map +1 -0
  241. package/dist/vc-agent/realtime/errors.d.ts +9 -0
  242. package/dist/vc-agent/realtime/errors.d.ts.map +1 -0
  243. package/dist/vc-agent/realtime/errors.js +17 -0
  244. package/dist/vc-agent/realtime/errors.js.map +1 -0
  245. package/dist/vc-agent/realtime/events.d.ts +24 -0
  246. package/dist/vc-agent/realtime/events.d.ts.map +1 -0
  247. package/dist/vc-agent/realtime/events.js +190 -0
  248. package/dist/vc-agent/realtime/events.js.map +1 -0
  249. package/dist/vc-agent/realtime/frontier.d.ts +34 -0
  250. package/dist/vc-agent/realtime/frontier.d.ts.map +1 -0
  251. package/dist/vc-agent/realtime/frontier.js +40 -0
  252. package/dist/vc-agent/realtime/frontier.js.map +1 -0
  253. package/dist/vc-agent/realtime/index.d.ts +11 -0
  254. package/dist/vc-agent/realtime/index.d.ts.map +1 -0
  255. package/dist/vc-agent/realtime/index.js +11 -0
  256. package/dist/vc-agent/realtime/index.js.map +1 -0
  257. package/dist/vc-agent/realtime/pacer.d.ts +21 -0
  258. package/dist/vc-agent/realtime/pacer.d.ts.map +1 -0
  259. package/dist/vc-agent/realtime/pacer.js +80 -0
  260. package/dist/vc-agent/realtime/pacer.js.map +1 -0
  261. package/dist/vc-agent/realtime/protobuf.d.ts +33 -0
  262. package/dist/vc-agent/realtime/protobuf.d.ts.map +1 -0
  263. package/dist/vc-agent/realtime/protobuf.js +159 -0
  264. package/dist/vc-agent/realtime/protobuf.js.map +1 -0
  265. package/dist/vc-agent/realtime/protocol.d.ts +4 -0
  266. package/dist/vc-agent/realtime/protocol.d.ts.map +1 -0
  267. package/dist/vc-agent/realtime/protocol.js +59 -0
  268. package/dist/vc-agent/realtime/protocol.js.map +1 -0
  269. package/dist/vc-agent/realtime/session.d.ts +39 -0
  270. package/dist/vc-agent/realtime/session.d.ts.map +1 -0
  271. package/dist/vc-agent/realtime/session.js +221 -0
  272. package/dist/vc-agent/realtime/session.js.map +1 -0
  273. package/dist/vc-agent/realtime/transport.d.ts +23 -0
  274. package/dist/vc-agent/realtime/transport.d.ts.map +1 -0
  275. package/dist/vc-agent/realtime/transport.js +112 -0
  276. package/dist/vc-agent/realtime/transport.js.map +1 -0
  277. package/dist/vc-agent/realtime/types.d.ts +84 -0
  278. package/dist/vc-agent/realtime/types.d.ts.map +1 -0
  279. package/dist/vc-agent/realtime/types.js +5 -0
  280. package/dist/vc-agent/realtime/types.js.map +1 -0
  281. package/dist/vc-agent/types.d.ts +142 -0
  282. package/dist/vc-agent/types.d.ts.map +1 -0
  283. package/dist/vc-agent/types.js +2 -0
  284. package/dist/vc-agent/types.js.map +1 -0
  285. package/dist/worker.js +3 -3
  286. package/dist/worker.js.map +1 -1
  287. package/dist/workflows/attempt-resume.d.ts +4 -0
  288. package/dist/workflows/attempt-resume.d.ts.map +1 -1
  289. package/dist/workflows/attempt-resume.js +2 -0
  290. package/dist/workflows/attempt-resume.js.map +1 -1
  291. package/dist/workflows/attempt-terminal.d.ts +4 -0
  292. package/dist/workflows/attempt-terminal.d.ts.map +1 -1
  293. package/dist/workflows/attempt-terminal.js.map +1 -1
  294. package/dist/workflows/daemon-spawn.d.ts.map +1 -1
  295. package/dist/workflows/daemon-spawn.js +7 -0
  296. package/dist/workflows/daemon-spawn.js.map +1 -1
  297. package/dist/workflows/events/payloads.d.ts +32 -0
  298. package/dist/workflows/events/payloads.d.ts.map +1 -1
  299. package/dist/workflows/events/payloads.js +4 -0
  300. package/dist/workflows/events/payloads.js.map +1 -1
  301. package/dist/workflows/events/schema.d.ts +56 -0
  302. package/dist/workflows/events/schema.d.ts.map +1 -1
  303. package/dist/workflows/runtime.d.ts +4 -0
  304. package/dist/workflows/runtime.d.ts.map +1 -1
  305. package/dist/workflows/runtime.js.map +1 -1
  306. package/dist/workflows/spawn-policy.d.ts +14 -0
  307. package/dist/workflows/spawn-policy.d.ts.map +1 -0
  308. package/dist/workflows/spawn-policy.js +9 -0
  309. package/dist/workflows/spawn-policy.js.map +1 -0
  310. package/dist/workflows/v3/bot-resolve.d.ts.map +1 -1
  311. package/dist/workflows/v3/bot-resolve.js +4 -0
  312. package/dist/workflows/v3/bot-resolve.js.map +1 -1
  313. package/dist/workflows/v3/cli-run.d.ts.map +1 -1
  314. package/dist/workflows/v3/cli-run.js +4 -0
  315. package/dist/workflows/v3/cli-run.js.map +1 -1
  316. package/dist/workflows/v3/contract.d.ts +9 -3
  317. package/dist/workflows/v3/contract.d.ts.map +1 -1
  318. package/dist/workflows/v3/contract.js +3 -3
  319. package/dist/workflows/v3/contract.js.map +1 -1
  320. package/dist/workflows/v3/ephemeral-pool.d.ts.map +1 -1
  321. package/dist/workflows/v3/ephemeral-pool.js +2 -0
  322. package/dist/workflows/v3/ephemeral-pool.js.map +1 -1
  323. package/dist/workflows/v3/runtime.js +1 -1
  324. package/dist/workflows/v3/runtime.js.map +1 -1
  325. package/package.json +1 -1
  326. package/dist/dashboard-web/chunks/chunk-76J7PNZI.js +0 -1
  327. package/dist/dashboard-web/chunks/overview-page-EHCZJBWY.js +0 -1
  328. package/dist/dashboard-web/chunks/schedules-RSXALJU4.js +0 -1
  329. package/dist/dashboard-web/chunks/settings-page-XKFTXTDE.js +0 -2
package/dist/dashboard.js CHANGED
@@ -30,6 +30,7 @@ import { FeishuLoginManager } from './dashboard/feishu-login.js';
30
30
  import { CLI_SELECT_OPTIONS, resolveCliSelection, isTtadkWrapper, ttadkAcceptsModel, TTADK_DEFAULT_MODEL, TTADK_MODEL_SUGGESTIONS, } from './setup/cli-selection.js';
31
31
  import { invalidWorkingDirs } from './utils/working-dir.js';
32
32
  import { invalidateGlobalConfigCache, mergeGlobalConfig, readGlobalConfig } from './global-config.js';
33
+ import { hostLocalTimeZone, scheduleTimeZone } from './utils/timezone.js';
33
34
  import { buildDashboardUrls } from './core/dashboard-url.js';
34
35
  import { deleteWhiteboard, listWhiteboards, readWhiteboard, whiteboardEnabled } from './services/whiteboard-store.js';
35
36
  import { isLocalDevInstall, botmuxVersion, botmuxCliEntry } from './utils/install-info.js';
@@ -49,7 +50,8 @@ import { listTeamReports, readTeamBoard, setTeamBoardEntry } from './services/te
49
50
  import { hd2dAssetPath, hd2dStatus, startHd2dDownload } from './dashboard/hd2d-assets.js';
50
51
  import { installLocalSkillLinks, readSkillRegistry, removeInstalledSkill, updateInstalledSkillAsync, } from './services/skill-registry-store.js';
51
52
  import { redactGitUrlCredentials } from './core/skills/sources.js';
52
- import { loadBotConfigs } from './bot-registry.js';
53
+ import { getBot, loadBotConfigs } from './bot-registry.js';
54
+ import { findEntryIndex, readRawConfig, requireConfigPath, writeRawConfigAtomic } from './services/config-store.js';
53
55
  import { discoverNativeCliSkillGroups } from './core/skills/discovery.js';
54
56
  import { analyzeSkillReferences } from './core/skills/references.js';
55
57
  import { discoverDashboardSkills, installDashboardSkill, parseDashboardSkillInstallRequest, parseInstallLocalLinksSources, MAX_LOCAL_LINK_SOURCES } from './dashboard/skill-install-request.js';
@@ -61,6 +63,8 @@ import { startPlatformTunnelClient } from './platform/tunnel-client.js';
61
63
  import { applyPlatformTeamSync, getPlatformTeamSyncRev, listPlatformTeams } from './services/platform-team-store.js';
62
64
  import { getBotUnionId } from './services/bot-union-ids-store.js';
63
65
  import { cleanupIdleSessions, parseIdleCleanupHours } from './dashboard/session-cleanup.js';
66
+ import { larkHosts } from './im/lark/lark-hosts.js';
67
+ import { VC_MEETING_FEATURE_SCOPES, VC_MEETING_REALTIME_VOICE_SCOPES, } from './setup/verify-permissions.js';
64
68
  const SECRET_PATH = join(homedir(), '.botmux', '.dashboard-secret');
65
69
  const TOKEN_PATH = join(homedir(), '.botmux', '.dashboard-token');
66
70
  /** Per-daemon budget for the cross-daemon insight overview fan-out — bounds
@@ -242,6 +246,183 @@ const botOnboarding = new BotOnboardingManager({
242
246
  const feishuLogin = new FeishuLoginManager();
243
247
  const subs = new Map();
244
248
  const attaching = new Set(); // dedup concurrent attaches per appId
249
+ function vcMeetingListenerBotOptions() {
250
+ try {
251
+ const onlineByAppId = new Map(registry.list().map(bot => [bot.larkAppId, bot]));
252
+ return loadBotConfigs().map(bot => ({
253
+ larkAppId: bot.larkAppId,
254
+ botName: bot.displayName ?? onlineByAppId.get(bot.larkAppId)?.botName ?? bot.name ?? null,
255
+ cliId: onlineByAppId.get(bot.larkAppId)?.cliId ?? bot.cliId,
256
+ vcMeetingAgentEnabled: bot.vcMeetingAgent?.enabled === true,
257
+ hasLarkCliProfile: typeof bot.vcMeetingAgent?.larkCliProfile === 'string' && bot.vcMeetingAgent.larkCliProfile.trim().length > 0,
258
+ }));
259
+ }
260
+ catch {
261
+ return [];
262
+ }
263
+ }
264
+ async function fetchGrantedScopesForBotConfig(bot) {
265
+ const brand = bot.brand === 'lark' ? 'lark' : 'feishu';
266
+ const openApi = larkHosts(brand).openApi;
267
+ const ac = new AbortController();
268
+ const timer = setTimeout(() => ac.abort(), 10_000);
269
+ try {
270
+ const tokenRes = await fetch(`${openApi}/open-apis/auth/v3/tenant_access_token/internal`, {
271
+ method: 'POST',
272
+ headers: { 'Content-Type': 'application/json' },
273
+ body: JSON.stringify({ app_id: bot.larkAppId, app_secret: bot.larkAppSecret }),
274
+ signal: ac.signal,
275
+ });
276
+ const tokenData = await tokenRes.json();
277
+ if (tokenData?.code !== 0 || typeof tokenData?.tenant_access_token !== 'string') {
278
+ return { ok: false, error: `vcMeetingAgent_listenerBot_invalid_credentials: code=${tokenData?.code ?? '?'} msg=${tokenData?.msg ?? ''}` };
279
+ }
280
+ const infoRes = await fetch(`${openApi}/open-apis/application/v6/applications/${bot.larkAppId}?lang=zh_cn`, { headers: { Authorization: `Bearer ${tokenData.tenant_access_token}` }, signal: ac.signal });
281
+ const infoData = await infoRes.json();
282
+ if (infoData?.code === 99991672) {
283
+ return { ok: false, error: 'vcMeetingAgent_listenerBot_scope_check_unavailable: missing application:application:self_manage' };
284
+ }
285
+ if (infoData?.code !== 0) {
286
+ return { ok: false, error: `vcMeetingAgent_listenerBot_scope_check_failed: code=${infoData?.code ?? '?'} msg=${infoData?.msg ?? ''}` };
287
+ }
288
+ const scopesRaw = infoData.data?.app?.scopes
289
+ ?? infoData.data?.application?.scopes
290
+ ?? infoData.data?.scopes
291
+ ?? [];
292
+ if (!Array.isArray(scopesRaw) || scopesRaw.length === 0) {
293
+ return { ok: false, error: 'vcMeetingAgent_listenerBot_scope_check_failed: empty scopes' };
294
+ }
295
+ const granted = new Set(scopesRaw.map(s => typeof s === 'string' ? s : s?.scope).filter(Boolean));
296
+ return { ok: true, granted };
297
+ }
298
+ catch (err) {
299
+ return {
300
+ ok: false,
301
+ error: ac.signal.aborted
302
+ ? 'vcMeetingAgent_listenerBot_scope_check_timeout'
303
+ : `vcMeetingAgent_listenerBot_scope_check_failed: ${err?.message ?? err}`,
304
+ };
305
+ }
306
+ finally {
307
+ clearTimeout(timer);
308
+ }
309
+ }
310
+ async function validateVcMeetingListenerBotAppId(appId) {
311
+ let bots;
312
+ try {
313
+ bots = loadBotConfigs();
314
+ }
315
+ catch (err) {
316
+ return { ok: false, error: `vcMeetingAgent_listenerBot_config_unavailable: ${err?.message ?? err}` };
317
+ }
318
+ const bot = bots.find(b => b.larkAppId === appId);
319
+ if (!bot)
320
+ return { ok: false, error: 'vcMeetingAgent_listenerBot_unknown' };
321
+ const cfg = bot.vcMeetingAgent ?? {};
322
+ if (!cfg.larkCliProfile)
323
+ return { ok: false, error: 'vcMeetingAgent_listenerBot_missing_larkCliProfile' };
324
+ const granted = await fetchGrantedScopesForBotConfig(bot);
325
+ if (!granted.ok)
326
+ return granted;
327
+ const required = cfg.realtimeVoice?.enabled === true
328
+ ? [...VC_MEETING_FEATURE_SCOPES, ...VC_MEETING_REALTIME_VOICE_SCOPES]
329
+ : VC_MEETING_FEATURE_SCOPES;
330
+ const missing = required.filter(scope => !granted.granted.has(scope.name));
331
+ if (missing.length > 0) {
332
+ return { ok: false, error: `vcMeetingAgent_listenerBot_missing_scopes: ${missing.map(s => s.name).join(',')}` };
333
+ }
334
+ return { ok: true };
335
+ }
336
+ function normalizeVcMeetingAgentRecord(raw) {
337
+ return raw && typeof raw === 'object' && !Array.isArray(raw)
338
+ ? { ...raw }
339
+ : {};
340
+ }
341
+ function compactVcMeetingAgentEntry(entry, next) {
342
+ if (Object.keys(next).length > 0)
343
+ entry.vcMeetingAgent = next;
344
+ else
345
+ delete entry.vcMeetingAgent;
346
+ }
347
+ function refreshLocalVcMeetingAgentConfig(appId) {
348
+ try {
349
+ const latest = loadBotConfigs().find(bot => bot.larkAppId === appId);
350
+ const live = getBot(appId);
351
+ live.config.vcMeetingAgent = latest?.vcMeetingAgent;
352
+ }
353
+ catch {
354
+ // This dashboard process may not host the target bot daemon.
355
+ }
356
+ }
357
+ async function reloadVcMeetingBotConfigOnDaemons(appIds) {
358
+ const unique = [...new Set(appIds.filter(Boolean))];
359
+ for (const appId of unique)
360
+ refreshLocalVcMeetingAgentConfig(appId);
361
+ await Promise.all(unique.map(async (appId) => {
362
+ const d = registry.getByAppId(appId);
363
+ if (!d)
364
+ return;
365
+ await fetch(`http://127.0.0.1:${d.ipcPort}/api/bot-config/reload`, {
366
+ method: 'POST',
367
+ signal: AbortSignal.timeout(10_000),
368
+ }).catch(() => undefined);
369
+ }));
370
+ }
371
+ async function syncVcMeetingListenerBotConfig(listenerBotAppId, previousListenerBotAppId) {
372
+ const nextAppId = listenerBotAppId?.trim() || null;
373
+ const prevAppId = previousListenerBotAppId?.trim() || null;
374
+ if (!nextAppId && !prevAppId)
375
+ return { ok: true };
376
+ const changedAppIds = new Set();
377
+ try {
378
+ const path = requireConfigPath();
379
+ await withFileLock(path, async () => {
380
+ const raw = await readRawConfig(path);
381
+ let changed = false;
382
+ if (nextAppId) {
383
+ const idx = findEntryIndex(raw, nextAppId);
384
+ if (idx < 0)
385
+ throw new Error('bot_not_in_config');
386
+ const entry = raw[idx];
387
+ const next = normalizeVcMeetingAgentRecord(entry.vcMeetingAgent);
388
+ let entryChanged = false;
389
+ if (next.enabled !== true) {
390
+ next.enabled = true;
391
+ next.dashboardManagedListener = true;
392
+ entryChanged = true;
393
+ }
394
+ if (entryChanged) {
395
+ compactVcMeetingAgentEntry(entry, next);
396
+ changed = true;
397
+ changedAppIds.add(nextAppId);
398
+ }
399
+ }
400
+ if (prevAppId && prevAppId !== nextAppId) {
401
+ const idx = findEntryIndex(raw, prevAppId);
402
+ if (idx >= 0) {
403
+ const entry = raw[idx];
404
+ const next = normalizeVcMeetingAgentRecord(entry.vcMeetingAgent);
405
+ if (next.dashboardManagedListener === true) {
406
+ delete next.dashboardManagedListener;
407
+ if (next.enabled === true)
408
+ delete next.enabled;
409
+ compactVcMeetingAgentEntry(entry, next);
410
+ changed = true;
411
+ changedAppIds.add(prevAppId);
412
+ }
413
+ }
414
+ }
415
+ if (changed)
416
+ await writeRawConfigAtomic(path, raw);
417
+ });
418
+ }
419
+ catch (err) {
420
+ return { ok: false, error: `vcMeetingAgent_listenerBot_config_write_failed: ${err?.message ?? err}` };
421
+ }
422
+ if (changedAppIds.size > 0)
423
+ await reloadVcMeetingBotConfigOnDaemons([...changedAppIds]);
424
+ return { ok: true };
425
+ }
245
426
  function resolveDashboardSettings() {
246
427
  const global = readGlobalConfig();
247
428
  const dashboard = global.dashboard ?? {};
@@ -249,11 +430,19 @@ function resolveDashboardSettings() {
249
430
  publicReadOnly: dashboard.publicReadOnly ?? config.dashboard.publicReadOnly,
250
431
  openTerminalInFeishu: dashboard.openTerminalInFeishu === true,
251
432
  chatBotDiscovery: dashboard.chatBotDiscovery !== false, // default ON
433
+ vcMeetingAgent: {
434
+ enabled: global.vcMeetingAgent?.enabled !== false,
435
+ listenerBotAppId: global.vcMeetingAgent?.listenerBotAppId ?? null,
436
+ listenerBotOptions: vcMeetingListenerBotOptions(),
437
+ },
252
438
  repoPickerMode: global.repoPickerMode ?? 'all',
253
439
  maintenance: global.maintenance ?? {},
254
440
  localDevInstall: isLocalDevInstall(),
255
441
  whiteboard: { enabled: global.whiteboard?.enabled === true },
256
442
  remoteAccess: global.remoteAccess === true,
443
+ scheduleTimeZone: global.scheduleTimeZone ?? null,
444
+ hostTimeZone: hostLocalTimeZone(),
445
+ effectiveScheduleTimeZone: scheduleTimeZone(),
257
446
  };
258
447
  }
259
448
  // Single shared deps object for `applySettingsWrite` — both the browser
@@ -263,6 +452,8 @@ async function reloadLocaleOnAllDaemons() {
263
452
  await Promise.all(registry.list().map(d => fetch(`http://127.0.0.1:${d.ipcPort}/api/locale/reload`, { method: 'POST' }).catch(() => undefined)));
264
453
  }
265
454
  const settingsWriteApplierDeps = defaultSettingsWriteApplierDeps(resolveDashboardSettings, reloadLocaleOnAllDaemons);
455
+ settingsWriteApplierDeps.syncVcMeetingListenerBotConfig = syncVcMeetingListenerBotConfig;
456
+ settingsWriteApplierDeps.validateVcMeetingListenerBotAppId = validateVcMeetingListenerBotAppId;
266
457
  /** Helper to render a {status, body} HandlerResult through `res`. */
267
458
  function writeHandlerResult(res, result) {
268
459
  const headers = { 'content-type': 'application/json', ...(result.headers ?? {}) };
@@ -1232,7 +1423,10 @@ const server = createServer(async (req, res) => {
1232
1423
  const schedules = authed
1233
1424
  ? aggregator.getSchedules()
1234
1425
  : redactSchedulesForPublic(aggregator.getSchedules());
1235
- return jsonRes(res, 200, { schedules });
1426
+ // Effective schedule timezone: nextRunAt/lastRunAt instants must be
1427
+ // rendered in the zone the scheduler fires in (not the viewer's browser
1428
+ // zone), so the web schedule/overview lists match cron/card/CLI displays.
1429
+ return jsonRes(res, 200, { schedules, timezone: scheduleTimeZone() });
1236
1430
  }
1237
1431
  if (req.method === 'GET' && url.pathname === '/api/settings') {
1238
1432
  // `authed` lets the Settings page disable toggles for read-only