botmux 3.16.0 → 3.17.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 (619) hide show
  1. package/dist/.runtime-build-id +1 -1
  2. package/dist/adapters/backend/riff-backend.d.ts +84 -1
  3. package/dist/adapters/backend/riff-backend.d.ts.map +1 -1
  4. package/dist/adapters/backend/riff-backend.js +202 -19
  5. package/dist/adapters/backend/riff-backend.js.map +1 -1
  6. package/dist/adapters/backend/sandbox.d.ts +8 -0
  7. package/dist/adapters/backend/sandbox.d.ts.map +1 -1
  8. package/dist/adapters/backend/sandbox.js +15 -0
  9. package/dist/adapters/backend/sandbox.js.map +1 -1
  10. package/dist/adapters/backend/tmux-backend.d.ts +61 -7
  11. package/dist/adapters/backend/tmux-backend.d.ts.map +1 -1
  12. package/dist/adapters/backend/tmux-backend.js +80 -9
  13. package/dist/adapters/backend/tmux-backend.js.map +1 -1
  14. package/dist/adapters/backend/tmux-pipe-backend.d.ts +62 -4
  15. package/dist/adapters/backend/tmux-pipe-backend.d.ts.map +1 -1
  16. package/dist/adapters/backend/tmux-pipe-backend.js +240 -27
  17. package/dist/adapters/backend/tmux-pipe-backend.js.map +1 -1
  18. package/dist/adapters/cli/claude-code.d.ts.map +1 -1
  19. package/dist/adapters/cli/claude-code.js +4 -2
  20. package/dist/adapters/cli/claude-code.js.map +1 -1
  21. package/dist/adapters/cli/coco.d.ts.map +1 -1
  22. package/dist/adapters/cli/coco.js +27 -0
  23. package/dist/adapters/cli/coco.js.map +1 -1
  24. package/dist/adapters/cli/codex-app.d.ts.map +1 -1
  25. package/dist/adapters/cli/codex-app.js +28 -0
  26. package/dist/adapters/cli/codex-app.js.map +1 -1
  27. package/dist/adapters/cli/codex.d.ts.map +1 -1
  28. package/dist/adapters/cli/codex.js +51 -23
  29. package/dist/adapters/cli/codex.js.map +1 -1
  30. package/dist/adapters/cli/dsh-tui.d.ts +24 -0
  31. package/dist/adapters/cli/dsh-tui.d.ts.map +1 -0
  32. package/dist/adapters/cli/dsh-tui.js +99 -0
  33. package/dist/adapters/cli/dsh-tui.js.map +1 -0
  34. package/dist/adapters/cli/dsh.d.ts.map +1 -1
  35. package/dist/adapters/cli/dsh.js +15 -9
  36. package/dist/adapters/cli/dsh.js.map +1 -1
  37. package/dist/adapters/cli/fs-policy.d.ts +98 -1
  38. package/dist/adapters/cli/fs-policy.d.ts.map +1 -1
  39. package/dist/adapters/cli/fs-policy.js +182 -7
  40. package/dist/adapters/cli/fs-policy.js.map +1 -1
  41. package/dist/adapters/cli/grok.js +16 -18
  42. package/dist/adapters/cli/grok.js.map +1 -1
  43. package/dist/adapters/cli/model-catalog-json.d.ts +17 -0
  44. package/dist/adapters/cli/model-catalog-json.d.ts.map +1 -0
  45. package/dist/adapters/cli/model-catalog-json.js +43 -0
  46. package/dist/adapters/cli/model-catalog-json.js.map +1 -0
  47. package/dist/adapters/cli/oh-my-pi.d.ts +2 -0
  48. package/dist/adapters/cli/oh-my-pi.d.ts.map +1 -1
  49. package/dist/adapters/cli/oh-my-pi.js +45 -13
  50. package/dist/adapters/cli/oh-my-pi.js.map +1 -1
  51. package/dist/adapters/cli/opencode.js +1 -1
  52. package/dist/adapters/cli/opencode.js.map +1 -1
  53. package/dist/adapters/cli/registry.d.ts +2 -1
  54. package/dist/adapters/cli/registry.d.ts.map +1 -1
  55. package/dist/adapters/cli/registry.js +6 -1
  56. package/dist/adapters/cli/registry.js.map +1 -1
  57. package/dist/adapters/cli/relay.d.ts.map +1 -1
  58. package/dist/adapters/cli/relay.js +7 -0
  59. package/dist/adapters/cli/relay.js.map +1 -1
  60. package/dist/adapters/cli/seed.d.ts.map +1 -1
  61. package/dist/adapters/cli/seed.js +6 -0
  62. package/dist/adapters/cli/seed.js.map +1 -1
  63. package/dist/adapters/cli/shared-hints.d.ts.map +1 -1
  64. package/dist/adapters/cli/shared-hints.js +20 -14
  65. package/dist/adapters/cli/shared-hints.js.map +1 -1
  66. package/dist/adapters/cli/traex.d.ts +4 -0
  67. package/dist/adapters/cli/traex.d.ts.map +1 -1
  68. package/dist/adapters/cli/traex.js +153 -0
  69. package/dist/adapters/cli/traex.js.map +1 -1
  70. package/dist/adapters/cli/types.d.ts +42 -1
  71. package/dist/adapters/cli/types.d.ts.map +1 -1
  72. package/dist/autostart.d.ts +6 -0
  73. package/dist/autostart.d.ts.map +1 -1
  74. package/dist/autostart.js +21 -1
  75. package/dist/autostart.js.map +1 -1
  76. package/dist/bot-registry.d.ts +27 -0
  77. package/dist/bot-registry.d.ts.map +1 -1
  78. package/dist/bot-registry.js +62 -2
  79. package/dist/bot-registry.js.map +1 -1
  80. package/dist/cli/vc-agent.d.ts.map +1 -1
  81. package/dist/cli/vc-agent.js +21 -3
  82. package/dist/cli/vc-agent.js.map +1 -1
  83. package/dist/cli.d.ts.map +1 -1
  84. package/dist/cli.js +92 -1
  85. package/dist/cli.js.map +1 -1
  86. package/dist/codex-app-runner.js +28 -0
  87. package/dist/codex-app-runner.js.map +1 -1
  88. package/dist/core/bot-steer-directive.d.ts +25 -0
  89. package/dist/core/bot-steer-directive.d.ts.map +1 -0
  90. package/dist/core/bot-steer-directive.js +47 -0
  91. package/dist/core/bot-steer-directive.js.map +1 -0
  92. package/dist/core/command-handler.d.ts.map +1 -1
  93. package/dist/core/command-handler.js +102 -18
  94. package/dist/core/command-handler.js.map +1 -1
  95. package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
  96. package/dist/core/dashboard-ipc-server.js +53 -13
  97. package/dist/core/dashboard-ipc-server.js.map +1 -1
  98. package/dist/core/dashboard-rows.d.ts +3 -0
  99. package/dist/core/dashboard-rows.d.ts.map +1 -1
  100. package/dist/core/dashboard-rows.js +26 -5
  101. package/dist/core/dashboard-rows.js.map +1 -1
  102. package/dist/core/dashboard-url.d.ts +10 -1
  103. package/dist/core/dashboard-url.d.ts.map +1 -1
  104. package/dist/core/dashboard-url.js +12 -2
  105. package/dist/core/dashboard-url.js.map +1 -1
  106. package/dist/core/dispatch.d.ts.map +1 -1
  107. package/dist/core/dispatch.js +5 -4
  108. package/dist/core/dispatch.js.map +1 -1
  109. package/dist/core/existing-app-server.d.ts +22 -0
  110. package/dist/core/existing-app-server.d.ts.map +1 -0
  111. package/dist/core/existing-app-server.js +85 -0
  112. package/dist/core/existing-app-server.js.map +1 -0
  113. package/dist/core/native-topic-id.d.ts +9 -0
  114. package/dist/core/native-topic-id.d.ts.map +1 -0
  115. package/dist/core/native-topic-id.js +14 -0
  116. package/dist/core/native-topic-id.js.map +1 -0
  117. package/dist/core/per-bot-env.d.ts.map +1 -1
  118. package/dist/core/per-bot-env.js +10 -0
  119. package/dist/core/per-bot-env.js.map +1 -1
  120. package/dist/core/plugins/mcp/gateway.d.ts +27 -3
  121. package/dist/core/plugins/mcp/gateway.d.ts.map +1 -1
  122. package/dist/core/plugins/mcp/gateway.js +272 -26
  123. package/dist/core/plugins/mcp/gateway.js.map +1 -1
  124. package/dist/core/plugins/mcp/host.d.ts +18 -0
  125. package/dist/core/plugins/mcp/host.d.ts.map +1 -1
  126. package/dist/core/plugins/mcp/host.js +80 -16
  127. package/dist/core/plugins/mcp/host.js.map +1 -1
  128. package/dist/core/plugins/mcp/launch-record.d.ts +14 -0
  129. package/dist/core/plugins/mcp/launch-record.d.ts.map +1 -0
  130. package/dist/core/plugins/mcp/launch-record.js +63 -0
  131. package/dist/core/plugins/mcp/launch-record.js.map +1 -0
  132. package/dist/core/session-activity.d.ts +11 -0
  133. package/dist/core/session-activity.d.ts.map +1 -1
  134. package/dist/core/session-activity.js +23 -0
  135. package/dist/core/session-activity.js.map +1 -1
  136. package/dist/core/session-group-birth.d.ts.map +1 -1
  137. package/dist/core/session-group-birth.js +23 -8
  138. package/dist/core/session-group-birth.js.map +1 -1
  139. package/dist/core/session-manager.d.ts +1 -4
  140. package/dist/core/session-manager.d.ts.map +1 -1
  141. package/dist/core/session-manager.js +16 -20
  142. package/dist/core/session-manager.js.map +1 -1
  143. package/dist/core/shared-adopt.d.ts +20 -0
  144. package/dist/core/shared-adopt.d.ts.map +1 -0
  145. package/dist/core/shared-adopt.js +26 -0
  146. package/dist/core/shared-adopt.js.map +1 -0
  147. package/dist/core/skills/customize-command.d.ts +7 -0
  148. package/dist/core/skills/customize-command.d.ts.map +1 -0
  149. package/dist/core/skills/customize-command.js +303 -0
  150. package/dist/core/skills/customize-command.js.map +1 -0
  151. package/dist/core/terminal-write-auth.d.ts +15 -0
  152. package/dist/core/terminal-write-auth.d.ts.map +1 -1
  153. package/dist/core/terminal-write-auth.js +15 -0
  154. package/dist/core/terminal-write-auth.js.map +1 -1
  155. package/dist/core/terminal-write-frame.d.ts +30 -0
  156. package/dist/core/terminal-write-frame.d.ts.map +1 -0
  157. package/dist/core/terminal-write-frame.js +44 -0
  158. package/dist/core/terminal-write-frame.js.map +1 -0
  159. package/dist/core/types.d.ts +14 -4
  160. package/dist/core/types.d.ts.map +1 -1
  161. package/dist/core/types.js +6 -8
  162. package/dist/core/types.js.map +1 -1
  163. package/dist/core/worker-pool.d.ts +31 -6
  164. package/dist/core/worker-pool.d.ts.map +1 -1
  165. package/dist/core/worker-pool.js +444 -102
  166. package/dist/core/worker-pool.js.map +1 -1
  167. package/dist/core/worker-startup-retry.d.ts +52 -0
  168. package/dist/core/worker-startup-retry.d.ts.map +1 -0
  169. package/dist/core/worker-startup-retry.js +68 -0
  170. package/dist/core/worker-startup-retry.js.map +1 -0
  171. package/dist/daemon.d.ts +9 -8
  172. package/dist/daemon.d.ts.map +1 -1
  173. package/dist/daemon.js +467 -171
  174. package/dist/daemon.js.map +1 -1
  175. package/dist/dashboard/autostart-api.d.ts +26 -0
  176. package/dist/dashboard/autostart-api.d.ts.map +1 -0
  177. package/dist/dashboard/autostart-api.js +88 -0
  178. package/dist/dashboard/autostart-api.js.map +1 -0
  179. package/dist/dashboard/bot-payload.d.ts +5 -0
  180. package/dist/dashboard/bot-payload.d.ts.map +1 -1
  181. package/dist/dashboard/bot-payload.js +2 -0
  182. package/dist/dashboard/bot-payload.js.map +1 -1
  183. package/dist/dashboard/control-csrf.d.ts +29 -1
  184. package/dist/dashboard/control-csrf.d.ts.map +1 -1
  185. package/dist/dashboard/control-csrf.js +49 -10
  186. package/dist/dashboard/control-csrf.js.map +1 -1
  187. package/dist/dashboard/customization-api.d.ts +23 -0
  188. package/dist/dashboard/customization-api.d.ts.map +1 -0
  189. package/dist/dashboard/customization-api.js +198 -0
  190. package/dist/dashboard/customization-api.js.map +1 -0
  191. package/dist/dashboard/debug-terminal.d.ts +13 -1
  192. package/dist/dashboard/debug-terminal.d.ts.map +1 -1
  193. package/dist/dashboard/debug-terminal.js +18 -4
  194. package/dist/dashboard/debug-terminal.js.map +1 -1
  195. package/dist/dashboard/settings-write-applier.d.ts +0 -23
  196. package/dist/dashboard/settings-write-applier.d.ts.map +1 -1
  197. package/dist/dashboard/settings-write-applier.js +7 -28
  198. package/dist/dashboard/settings-write-applier.js.map +1 -1
  199. package/dist/dashboard/terminal-control-route.d.ts +32 -0
  200. package/dist/dashboard/terminal-control-route.d.ts.map +1 -0
  201. package/dist/dashboard/terminal-control-route.js +70 -0
  202. package/dist/dashboard/terminal-control-route.js.map +1 -0
  203. package/dist/dashboard/terminal-control.d.ts +64 -13
  204. package/dist/dashboard/terminal-control.d.ts.map +1 -1
  205. package/dist/dashboard/terminal-control.js +77 -14
  206. package/dist/dashboard/terminal-control.js.map +1 -1
  207. package/dist/dashboard/terminal-front-proxy.d.ts.map +1 -1
  208. package/dist/dashboard/terminal-front-proxy.js +41 -9
  209. package/dist/dashboard/terminal-front-proxy.js.map +1 -1
  210. package/dist/dashboard/vc-consumer-profiles-api.d.ts +69 -18
  211. package/dist/dashboard/vc-consumer-profiles-api.d.ts.map +1 -1
  212. package/dist/dashboard/vc-consumer-profiles-api.js +149 -29
  213. package/dist/dashboard/vc-consumer-profiles-api.js.map +1 -1
  214. package/dist/dashboard/web/agent-workbench-api.d.ts +34 -2
  215. package/dist/dashboard/web/agent-workbench-api.d.ts.map +1 -1
  216. package/dist/dashboard/web/agent-workbench-api.js +39 -4
  217. package/dist/dashboard/web/agent-workbench-api.js.map +1 -1
  218. package/dist/dashboard/web/agent-workbench-appearance.d.ts +6 -3
  219. package/dist/dashboard/web/agent-workbench-appearance.d.ts.map +1 -1
  220. package/dist/dashboard/web/agent-workbench-appearance.js +7 -4
  221. package/dist/dashboard/web/agent-workbench-appearance.js.map +1 -1
  222. package/dist/dashboard/web/agent-workbench-model.d.ts +2 -0
  223. package/dist/dashboard/web/agent-workbench-model.d.ts.map +1 -1
  224. package/dist/dashboard/web/agent-workbench-model.js.map +1 -1
  225. package/dist/dashboard/web/agent-workbench-page.js +2 -2
  226. package/dist/dashboard/web/agent-workbench-page.js.map +1 -1
  227. package/dist/dashboard/web/agent-workbench-panes.d.ts +59 -4
  228. package/dist/dashboard/web/agent-workbench-panes.d.ts.map +1 -1
  229. package/dist/dashboard/web/agent-workbench-panes.js +493 -85
  230. package/dist/dashboard/web/agent-workbench-panes.js.map +1 -1
  231. package/dist/dashboard/web/agent-workbench-session-list.d.ts +11 -7
  232. package/dist/dashboard/web/agent-workbench-session-list.d.ts.map +1 -1
  233. package/dist/dashboard/web/agent-workbench-session-list.js +24 -31
  234. package/dist/dashboard/web/agent-workbench-session-list.js.map +1 -1
  235. package/dist/dashboard/web/agent-workbench-terminal-control.d.ts +198 -0
  236. package/dist/dashboard/web/agent-workbench-terminal-control.d.ts.map +1 -0
  237. package/dist/dashboard/web/agent-workbench-terminal-control.js +292 -0
  238. package/dist/dashboard/web/agent-workbench-terminal-control.js.map +1 -0
  239. package/dist/dashboard/web/agent-workbench-view.d.ts +3 -2
  240. package/dist/dashboard/web/agent-workbench-view.d.ts.map +1 -1
  241. package/dist/dashboard/web/agent-workbench-view.js +69 -50
  242. package/dist/dashboard/web/agent-workbench-view.js.map +1 -1
  243. package/dist/dashboard/web/app.d.ts.map +1 -1
  244. package/dist/dashboard/web/app.js +58 -7
  245. package/dist/dashboard/web/app.js.map +1 -1
  246. package/dist/dashboard/web/bot-defaults-page.d.ts +24 -0
  247. package/dist/dashboard/web/bot-defaults-page.d.ts.map +1 -1
  248. package/dist/dashboard/web/bot-defaults-page.js +191 -16
  249. package/dist/dashboard/web/bot-defaults-page.js.map +1 -1
  250. package/dist/dashboard/web/bot-defaults.d.ts +17 -0
  251. package/dist/dashboard/web/bot-defaults.d.ts.map +1 -1
  252. package/dist/dashboard/web/bot-defaults.js +51 -2
  253. package/dist/dashboard/web/bot-defaults.js.map +1 -1
  254. package/dist/dashboard/web/bot-onboarding.d.ts.map +1 -1
  255. package/dist/dashboard/web/bot-onboarding.js +32 -8
  256. package/dist/dashboard/web/bot-onboarding.js.map +1 -1
  257. package/dist/dashboard/web/confirm-modal.d.ts +35 -0
  258. package/dist/dashboard/web/confirm-modal.d.ts.map +1 -0
  259. package/dist/dashboard/web/confirm-modal.js +111 -0
  260. package/dist/dashboard/web/confirm-modal.js.map +1 -0
  261. package/dist/dashboard/web/connectors-page.d.ts.map +1 -1
  262. package/dist/dashboard/web/connectors-page.js +2 -1
  263. package/dist/dashboard/web/connectors-page.js.map +1 -1
  264. package/dist/dashboard/web/customization-page.d.ts +3 -0
  265. package/dist/dashboard/web/customization-page.d.ts.map +1 -0
  266. package/dist/dashboard/web/customization-page.js +315 -0
  267. package/dist/dashboard/web/customization-page.js.map +1 -0
  268. package/dist/dashboard/web/dashboard-routes.d.ts.map +1 -1
  269. package/dist/dashboard/web/dashboard-routes.js +1 -0
  270. package/dist/dashboard/web/dashboard-routes.js.map +1 -1
  271. package/dist/dashboard/web/groups-page.d.ts.map +1 -1
  272. package/dist/dashboard/web/groups-page.js +11 -9
  273. package/dist/dashboard/web/groups-page.js.map +1 -1
  274. package/dist/dashboard/web/i18n.d.ts.map +1 -1
  275. package/dist/dashboard/web/i18n.js +226 -42
  276. package/dist/dashboard/web/i18n.js.map +1 -1
  277. package/dist/dashboard/web/monitor-room.d.ts.map +1 -1
  278. package/dist/dashboard/web/monitor-room.js +3 -2
  279. package/dist/dashboard/web/monitor-room.js.map +1 -1
  280. package/dist/dashboard/web/overview-page.d.ts.map +1 -1
  281. package/dist/dashboard/web/overview-page.js +98 -63
  282. package/dist/dashboard/web/overview-page.js.map +1 -1
  283. package/dist/dashboard/web/roles-page.d.ts.map +1 -1
  284. package/dist/dashboard/web/roles-page.js +4 -3
  285. package/dist/dashboard/web/roles-page.js.map +1 -1
  286. package/dist/dashboard/web/schedules-page.d.ts.map +1 -1
  287. package/dist/dashboard/web/schedules-page.js +165 -18
  288. package/dist/dashboard/web/schedules-page.js.map +1 -1
  289. package/dist/dashboard/web/sessions-kanban.d.ts +2 -0
  290. package/dist/dashboard/web/sessions-kanban.d.ts.map +1 -1
  291. package/dist/dashboard/web/sessions-kanban.js +142 -24
  292. package/dist/dashboard/web/sessions-kanban.js.map +1 -1
  293. package/dist/dashboard/web/sessions-page.d.ts.map +1 -1
  294. package/dist/dashboard/web/sessions-page.js +177 -94
  295. package/dist/dashboard/web/sessions-page.js.map +1 -1
  296. package/dist/dashboard/web/sessions.d.ts.map +1 -1
  297. package/dist/dashboard/web/sessions.js +5 -4
  298. package/dist/dashboard/web/sessions.js.map +1 -1
  299. package/dist/dashboard/web/settings-page.d.ts +0 -8
  300. package/dist/dashboard/web/settings-page.d.ts.map +1 -1
  301. package/dist/dashboard/web/settings-page.js +185 -65
  302. package/dist/dashboard/web/settings-page.js.map +1 -1
  303. package/dist/dashboard/web/skills/skill-library-tab.d.ts +2 -0
  304. package/dist/dashboard/web/skills/skill-library-tab.d.ts.map +1 -1
  305. package/dist/dashboard/web/skills/skill-library-tab.js +15 -1
  306. package/dist/dashboard/web/skills/skill-library-tab.js.map +1 -1
  307. package/dist/dashboard/web/skills-page.d.ts.map +1 -1
  308. package/dist/dashboard/web/skills-page.js +5 -4
  309. package/dist/dashboard/web/skills-page.js.map +1 -1
  310. package/dist/dashboard/web/store.d.ts +5 -0
  311. package/dist/dashboard/web/store.d.ts.map +1 -1
  312. package/dist/dashboard/web/store.js +4 -0
  313. package/dist/dashboard/web/store.js.map +1 -1
  314. package/dist/dashboard/web/team-federation-page.d.ts.map +1 -1
  315. package/dist/dashboard/web/team-federation-page.js +3 -2
  316. package/dist/dashboard/web/team-federation-page.js.map +1 -1
  317. package/dist/dashboard/web/toast.d.ts +15 -0
  318. package/dist/dashboard/web/toast.d.ts.map +1 -0
  319. package/dist/dashboard/web/toast.js +70 -0
  320. package/dist/dashboard/web/toast.js.map +1 -0
  321. package/dist/dashboard/web/v3-components.d.ts.map +1 -1
  322. package/dist/dashboard/web/v3-components.js +2 -1
  323. package/dist/dashboard/web/v3-components.js.map +1 -1
  324. package/dist/dashboard/web/vc-consumer-profiles-section.d.ts +10 -12
  325. package/dist/dashboard/web/vc-consumer-profiles-section.d.ts.map +1 -1
  326. package/dist/dashboard/web/vc-consumer-profiles-section.js +219 -200
  327. package/dist/dashboard/web/vc-consumer-profiles-section.js.map +1 -1
  328. package/dist/dashboard/web/whiteboards-page.d.ts.map +1 -1
  329. package/dist/dashboard/web/whiteboards-page.js +2 -1
  330. package/dist/dashboard/web/whiteboards-page.js.map +1 -1
  331. package/dist/dashboard-web/app.js +1 -1
  332. package/dist/dashboard-web/chunks/agent-workbench-dock-page-LZSUOCEQ.js +1 -0
  333. package/dist/dashboard-web/chunks/agent-workbench-page-YONDRJU7.js +1 -0
  334. package/dist/dashboard-web/chunks/bot-defaults-page-X7LV6373.js +1 -0
  335. package/dist/dashboard-web/chunks/chunk-2PVRDXEL.js +1 -0
  336. package/dist/dashboard-web/chunks/chunk-53JUKBU2.js +10 -0
  337. package/dist/dashboard-web/chunks/{chunk-5CJMHTT4.js → chunk-5QX4OYOR.js} +1 -1
  338. package/dist/dashboard-web/chunks/{chunk-NACP7BMR.js → chunk-5VRVJFQR.js} +1 -1
  339. package/dist/dashboard-web/chunks/{chunk-FDZ7WOBW.js → chunk-6ROOZWYV.js} +1 -1
  340. package/dist/dashboard-web/chunks/{chunk-F6KNPF4R.js → chunk-CK22743G.js} +15 -19
  341. package/dist/dashboard-web/chunks/chunk-CVNIMUPY.js +25 -0
  342. package/dist/dashboard-web/chunks/chunk-GJC2TMWS.js +2 -0
  343. package/dist/dashboard-web/chunks/chunk-OT6L6G7R.js +1 -0
  344. package/dist/dashboard-web/chunks/chunk-QITAMHW6.js +1 -0
  345. package/dist/dashboard-web/chunks/chunk-RHVFZC5Z.js +1 -0
  346. package/dist/dashboard-web/chunks/chunk-SOBMN2VY.js +1 -0
  347. package/dist/dashboard-web/chunks/chunk-SZOB6VK2.js +1 -0
  348. package/dist/dashboard-web/chunks/chunk-XVIXNQGC.js +44 -0
  349. package/dist/dashboard-web/chunks/chunk-YUJF34ME.js +1 -0
  350. package/dist/dashboard-web/chunks/connectors-page-LB2HEJ7F.js +1 -0
  351. package/dist/dashboard-web/chunks/customization-page-4GXBYLG6.js +105 -0
  352. package/dist/dashboard-web/chunks/feedback-page-IZQ7VLDG.js +1 -0
  353. package/dist/dashboard-web/chunks/groups-page-4WCP5OEV.js +8 -0
  354. package/dist/dashboard-web/chunks/{insights-page-HJFDYR5N.js → insights-page-TXQHIPQL.js} +1 -1
  355. package/dist/dashboard-web/chunks/{monitor-room-V7PCP47V.js → monitor-room-VBRVWXCM.js} +8 -8
  356. package/dist/dashboard-web/chunks/monitoring-page-QDDZWERE.js +2 -0
  357. package/dist/dashboard-web/chunks/office-page-PENFNYPG.js +1 -0
  358. package/dist/dashboard-web/chunks/overview-page-BZQDP6MP.js +1 -0
  359. package/dist/dashboard-web/chunks/plugin-page-JX4GSWZS.js +1 -0
  360. package/dist/dashboard-web/chunks/roles-page-VPNINZNK.js +1 -0
  361. package/dist/dashboard-web/chunks/schedules-page-BITO6HEA.js +1 -0
  362. package/dist/dashboard-web/chunks/sessions-page-ZKCOVTD2.js +8 -0
  363. package/dist/dashboard-web/chunks/settings-page-UT6JDTS6.js +2 -0
  364. package/dist/dashboard-web/chunks/skills-page-GULXVAJY.js +4 -0
  365. package/dist/dashboard-web/chunks/team-federation-page-CUUJWGEG.js +1 -0
  366. package/dist/dashboard-web/chunks/v3-page-5WVJ5AUR.js +94 -0
  367. package/dist/dashboard-web/chunks/whiteboards-page-FZ2CME4H.js +1 -0
  368. package/dist/dashboard-web/design-tokens.css +236 -0
  369. package/dist/dashboard-web/index.html +1 -0
  370. package/dist/dashboard-web/style.css +1930 -114
  371. package/dist/dashboard.js +360 -279
  372. package/dist/dashboard.js.map +1 -1
  373. package/dist/desktop/renderer/app.js +6 -0
  374. package/dist/desktop/renderer/app.js.map +1 -1
  375. package/dist/dsh-runner.js +139 -17
  376. package/dist/dsh-runner.js.map +1 -1
  377. package/dist/global-config.d.ts +33 -2
  378. package/dist/global-config.d.ts.map +1 -1
  379. package/dist/global-config.js +62 -0
  380. package/dist/global-config.js.map +1 -1
  381. package/dist/i18n/en.d.ts.map +1 -1
  382. package/dist/i18n/en.js +13 -4
  383. package/dist/i18n/en.js.map +1 -1
  384. package/dist/i18n/index.d.ts +27 -3
  385. package/dist/i18n/index.d.ts.map +1 -1
  386. package/dist/i18n/index.js +33 -4
  387. package/dist/i18n/index.js.map +1 -1
  388. package/dist/i18n/zh.d.ts.map +1 -1
  389. package/dist/i18n/zh.js +13 -4
  390. package/dist/i18n/zh.js.map +1 -1
  391. package/dist/im/lark/card-builder.d.ts +2 -0
  392. package/dist/im/lark/card-builder.d.ts.map +1 -1
  393. package/dist/im/lark/card-builder.js +7 -4
  394. package/dist/im/lark/card-builder.js.map +1 -1
  395. package/dist/im/lark/card-handler.d.ts.map +1 -1
  396. package/dist/im/lark/card-handler.js +135 -20
  397. package/dist/im/lark/card-handler.js.map +1 -1
  398. package/dist/im/lark/event-dispatcher.d.ts +38 -3
  399. package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
  400. package/dist/im/lark/event-dispatcher.js +163 -13
  401. package/dist/im/lark/event-dispatcher.js.map +1 -1
  402. package/dist/im/lark/v3-blocked-card-handler.d.ts.map +1 -1
  403. package/dist/im/lark/v3-blocked-card-handler.js +2 -1
  404. package/dist/im/lark/v3-blocked-card-handler.js.map +1 -1
  405. package/dist/im/lark/v3-blocked-card.d.ts +1 -1
  406. package/dist/im/lark/v3-blocked-card.d.ts.map +1 -1
  407. package/dist/im/lark/v3-blocked-card.js +14 -0
  408. package/dist/im/lark/v3-blocked-card.js.map +1 -1
  409. package/dist/index-core-only.js +2 -0
  410. package/dist/index-core-only.js.map +1 -1
  411. package/dist/index-daemon.js +3 -0
  412. package/dist/index-daemon.js.map +1 -1
  413. package/dist/platform/binding.d.ts +37 -0
  414. package/dist/platform/binding.d.ts.map +1 -1
  415. package/dist/platform/binding.js +15 -0
  416. package/dist/platform/binding.js.map +1 -1
  417. package/dist/services/bridge-turn-journal.d.ts +63 -0
  418. package/dist/services/bridge-turn-journal.d.ts.map +1 -0
  419. package/dist/services/bridge-turn-journal.js +149 -0
  420. package/dist/services/bridge-turn-journal.js.map +1 -0
  421. package/dist/services/bridge-turn-queue.d.ts +8 -1
  422. package/dist/services/bridge-turn-queue.d.ts.map +1 -1
  423. package/dist/services/bridge-turn-queue.js +2 -1
  424. package/dist/services/bridge-turn-queue.js.map +1 -1
  425. package/dist/services/codex-app-runner-protocol.d.ts +5 -0
  426. package/dist/services/codex-app-runner-protocol.d.ts.map +1 -1
  427. package/dist/services/codex-app-runner-protocol.js +5 -0
  428. package/dist/services/codex-app-runner-protocol.js.map +1 -1
  429. package/dist/services/customization-store.d.ts +93 -0
  430. package/dist/services/customization-store.d.ts.map +1 -0
  431. package/dist/services/customization-store.js +542 -0
  432. package/dist/services/customization-store.js.map +1 -0
  433. package/dist/services/file-bridge-path.d.ts.map +1 -1
  434. package/dist/services/file-bridge-path.js +3 -0
  435. package/dist/services/file-bridge-path.js.map +1 -1
  436. package/dist/services/grok-transcript.d.ts.map +1 -1
  437. package/dist/services/grok-transcript.js +44 -9
  438. package/dist/services/grok-transcript.js.map +1 -1
  439. package/dist/services/local-cli-opener.d.ts.map +1 -1
  440. package/dist/services/local-cli-opener.js +12 -3
  441. package/dist/services/local-cli-opener.js.map +1 -1
  442. package/dist/services/model-catalog.d.ts +54 -0
  443. package/dist/services/model-catalog.d.ts.map +1 -0
  444. package/dist/services/model-catalog.js +147 -0
  445. package/dist/services/model-catalog.js.map +1 -0
  446. package/dist/services/omp-transcript.d.ts +27 -0
  447. package/dist/services/omp-transcript.d.ts.map +1 -0
  448. package/dist/services/omp-transcript.js +214 -0
  449. package/dist/services/omp-transcript.js.map +1 -0
  450. package/dist/services/platform-team-store.d.ts +16 -8
  451. package/dist/services/platform-team-store.d.ts.map +1 -1
  452. package/dist/services/platform-team-store.js +17 -10
  453. package/dist/services/platform-team-store.js.map +1 -1
  454. package/dist/services/project-scanner.d.ts.map +1 -1
  455. package/dist/services/project-scanner.js +13 -8
  456. package/dist/services/project-scanner.js.map +1 -1
  457. package/dist/services/resumable-session-discovery.d.ts.map +1 -1
  458. package/dist/services/resumable-session-discovery.js +117 -35
  459. package/dist/services/resumable-session-discovery.js.map +1 -1
  460. package/dist/services/structured-bridge-clis.d.ts +5 -3
  461. package/dist/services/structured-bridge-clis.d.ts.map +1 -1
  462. package/dist/services/structured-bridge-clis.js +5 -1
  463. package/dist/services/structured-bridge-clis.js.map +1 -1
  464. package/dist/services/vc-meeting-action-gate.d.ts.map +1 -1
  465. package/dist/services/vc-meeting-action-gate.js +15 -4
  466. package/dist/services/vc-meeting-action-gate.js.map +1 -1
  467. package/dist/services/vc-meeting-consumer-profile-bootstrap.d.ts +46 -66
  468. package/dist/services/vc-meeting-consumer-profile-bootstrap.d.ts.map +1 -1
  469. package/dist/services/vc-meeting-consumer-profile-bootstrap.js +33 -292
  470. package/dist/services/vc-meeting-consumer-profile-bootstrap.js.map +1 -1
  471. package/dist/services/vc-meeting-consumer-profile-templates.js +3 -3
  472. package/dist/services/vc-meeting-consumer-profile-templates.js.map +1 -1
  473. package/dist/services/vc-meeting-delivery-store.d.ts +18 -0
  474. package/dist/services/vc-meeting-delivery-store.d.ts.map +1 -1
  475. package/dist/services/vc-meeting-delivery-store.js +55 -0
  476. package/dist/services/vc-meeting-delivery-store.js.map +1 -1
  477. package/dist/services/vc-meeting-send-policy.d.ts +21 -1
  478. package/dist/services/vc-meeting-send-policy.d.ts.map +1 -1
  479. package/dist/services/vc-meeting-send-policy.js +30 -2
  480. package/dist/services/vc-meeting-send-policy.js.map +1 -1
  481. package/dist/services/vc-meeting-shared-consumer-catalog-store.d.ts +78 -0
  482. package/dist/services/vc-meeting-shared-consumer-catalog-store.d.ts.map +1 -0
  483. package/dist/services/vc-meeting-shared-consumer-catalog-store.js +227 -0
  484. package/dist/services/vc-meeting-shared-consumer-catalog-store.js.map +1 -0
  485. package/dist/services/vc-meeting-shared-consumer-catalog.d.ts +53 -0
  486. package/dist/services/vc-meeting-shared-consumer-catalog.d.ts.map +1 -0
  487. package/dist/services/vc-meeting-shared-consumer-catalog.js +161 -0
  488. package/dist/services/vc-meeting-shared-consumer-catalog.js.map +1 -0
  489. package/dist/setup/bot-config-editor.d.ts.map +1 -1
  490. package/dist/setup/bot-config-editor.js +1 -0
  491. package/dist/setup/bot-config-editor.js.map +1 -1
  492. package/dist/setup/open-platform-automation.d.ts +20 -0
  493. package/dist/setup/open-platform-automation.d.ts.map +1 -1
  494. package/dist/setup/open-platform-automation.js +27 -0
  495. package/dist/setup/open-platform-automation.js.map +1 -1
  496. package/dist/skills/customization-bundle.d.ts +83 -0
  497. package/dist/skills/customization-bundle.d.ts.map +1 -0
  498. package/dist/skills/customization-bundle.js +214 -0
  499. package/dist/skills/customization-bundle.js.map +1 -0
  500. package/dist/skills/definitions.d.ts.map +1 -1
  501. package/dist/skills/definitions.js +10 -3
  502. package/dist/skills/definitions.js.map +1 -1
  503. package/dist/skills/effective-builtins.d.ts +38 -0
  504. package/dist/skills/effective-builtins.d.ts.map +1 -0
  505. package/dist/skills/effective-builtins.js +96 -0
  506. package/dist/skills/effective-builtins.js.map +1 -0
  507. package/dist/skills/injection-mode.d.ts +4 -1
  508. package/dist/skills/injection-mode.d.ts.map +1 -1
  509. package/dist/skills/injection-mode.js +11 -3
  510. package/dist/skills/injection-mode.js.map +1 -1
  511. package/dist/skills/installer.d.ts.map +1 -1
  512. package/dist/skills/installer.js +24 -1
  513. package/dist/skills/installer.js.map +1 -1
  514. package/dist/skills/prompt-fragments.d.ts +58 -0
  515. package/dist/skills/prompt-fragments.d.ts.map +1 -0
  516. package/dist/skills/prompt-fragments.js +88 -0
  517. package/dist/skills/prompt-fragments.js.map +1 -0
  518. package/dist/types.d.ts +51 -0
  519. package/dist/types.d.ts.map +1 -1
  520. package/dist/utils/cli-usage-limit.d.ts +50 -0
  521. package/dist/utils/cli-usage-limit.d.ts.map +1 -1
  522. package/dist/utils/cli-usage-limit.js +43 -0
  523. package/dist/utils/cli-usage-limit.js.map +1 -1
  524. package/dist/utils/idle-detector.d.ts +12 -0
  525. package/dist/utils/idle-detector.d.ts.map +1 -1
  526. package/dist/utils/idle-detector.js +88 -2
  527. package/dist/utils/idle-detector.js.map +1 -1
  528. package/dist/utils/stuck-detector.d.ts +5 -0
  529. package/dist/utils/stuck-detector.d.ts.map +1 -1
  530. package/dist/utils/stuck-detector.js +41 -0
  531. package/dist/utils/stuck-detector.js.map +1 -1
  532. package/dist/utils/usage-limit-tracker.d.ts +46 -0
  533. package/dist/utils/usage-limit-tracker.d.ts.map +1 -0
  534. package/dist/utils/usage-limit-tracker.js +91 -0
  535. package/dist/utils/usage-limit-tracker.js.map +1 -0
  536. package/dist/utils/user-token.js +1 -1
  537. package/dist/utils/user-token.js.map +1 -1
  538. package/dist/worker.js +812 -125
  539. package/dist/worker.js.map +1 -1
  540. package/dist/workflows/definition.d.ts +14 -14
  541. package/dist/workflows/events/payloads.d.ts +12 -12
  542. package/dist/workflows/events/schema.d.ts +164 -164
  543. package/dist/workflows/migration/v2-to-v3.js +1 -1
  544. package/dist/workflows/migration/v2-to-v3.js.map +1 -1
  545. package/dist/workflows/v3/architect.d.ts.map +1 -1
  546. package/dist/workflows/v3/architect.js +11 -5
  547. package/dist/workflows/v3/architect.js.map +1 -1
  548. package/dist/workflows/v3/artifact-contract-declarations.d.ts +22 -0
  549. package/dist/workflows/v3/artifact-contract-declarations.d.ts.map +1 -0
  550. package/dist/workflows/v3/artifact-contract-declarations.js +95 -0
  551. package/dist/workflows/v3/artifact-contract-declarations.js.map +1 -0
  552. package/dist/workflows/v3/contract.d.ts +1 -0
  553. package/dist/workflows/v3/contract.d.ts.map +1 -1
  554. package/dist/workflows/v3/contract.js.map +1 -1
  555. package/dist/workflows/v3/daemon-run.d.ts +2 -2
  556. package/dist/workflows/v3/daemon-run.d.ts.map +1 -1
  557. package/dist/workflows/v3/daemon-run.js +4 -0
  558. package/dist/workflows/v3/daemon-run.js.map +1 -1
  559. package/dist/workflows/v3/dag.d.ts +7 -0
  560. package/dist/workflows/v3/dag.d.ts.map +1 -1
  561. package/dist/workflows/v3/dag.js +69 -8
  562. package/dist/workflows/v3/dag.js.map +1 -1
  563. package/dist/workflows/v3/ephemeral-pool.js +1 -1
  564. package/dist/workflows/v3/ephemeral-pool.js.map +1 -1
  565. package/dist/workflows/v3/event-contract.d.ts +3 -1
  566. package/dist/workflows/v3/event-contract.d.ts.map +1 -1
  567. package/dist/workflows/v3/host.d.ts.map +1 -1
  568. package/dist/workflows/v3/host.js +5 -1
  569. package/dist/workflows/v3/host.js.map +1 -1
  570. package/dist/workflows/v3/journal.d.ts +1 -1
  571. package/dist/workflows/v3/journal.d.ts.map +1 -1
  572. package/dist/workflows/v3/journal.js.map +1 -1
  573. package/dist/workflows/v3/library-materialize.d.ts.map +1 -1
  574. package/dist/workflows/v3/library-materialize.js +9 -1
  575. package/dist/workflows/v3/library-materialize.js.map +1 -1
  576. package/dist/workflows/v3/library-schema.d.ts +3 -1
  577. package/dist/workflows/v3/library-schema.d.ts.map +1 -1
  578. package/dist/workflows/v3/library-schema.js +20 -4
  579. package/dist/workflows/v3/library-schema.js.map +1 -1
  580. package/dist/workflows/v3/library-store.d.ts.map +1 -1
  581. package/dist/workflows/v3/library-store.js +15 -3
  582. package/dist/workflows/v3/library-store.js.map +1 -1
  583. package/dist/workflows/v3/run-envelope.d.ts +16 -16
  584. package/dist/workflows/v3/shared-node-runtime.d.ts +2 -1
  585. package/dist/workflows/v3/shared-node-runtime.d.ts.map +1 -1
  586. package/dist/workflows/v3/shared-node-runtime.js +48 -7
  587. package/dist/workflows/v3/shared-node-runtime.js.map +1 -1
  588. package/package.json +2 -1
  589. package/dist/dashboard-web/chunks/agent-workbench-dock-page-IKAC5CFL.js +0 -1
  590. package/dist/dashboard-web/chunks/agent-workbench-page-M53UN5EB.js +0 -1
  591. package/dist/dashboard-web/chunks/bot-defaults-page-YKE5SDZF.js +0 -10
  592. package/dist/dashboard-web/chunks/chunk-22WIADUT.js +0 -2
  593. package/dist/dashboard-web/chunks/chunk-24ONYQMR.js +0 -1
  594. package/dist/dashboard-web/chunks/chunk-2W6SCN3M.js +0 -1
  595. package/dist/dashboard-web/chunks/chunk-4XNJX6B3.js +0 -1
  596. package/dist/dashboard-web/chunks/chunk-5THX4DI2.js +0 -66
  597. package/dist/dashboard-web/chunks/chunk-7SZRL6FY.js +0 -1
  598. package/dist/dashboard-web/chunks/chunk-AGCPF6MT.js +0 -1
  599. package/dist/dashboard-web/chunks/chunk-FXW3V4JR.js +0 -1
  600. package/dist/dashboard-web/chunks/chunk-SYC6D5XU.js +0 -1
  601. package/dist/dashboard-web/chunks/connectors-page-VOISXXII.js +0 -1
  602. package/dist/dashboard-web/chunks/feedback-page-RN6HRZMS.js +0 -1
  603. package/dist/dashboard-web/chunks/groups-page-UQT6DCB7.js +0 -8
  604. package/dist/dashboard-web/chunks/monitoring-page-NKEKVQAP.js +0 -2
  605. package/dist/dashboard-web/chunks/office-page-GVJF73XW.js +0 -1
  606. package/dist/dashboard-web/chunks/overview-page-KHLV6VTI.js +0 -1
  607. package/dist/dashboard-web/chunks/plugin-page-J3OF5IY4.js +0 -1
  608. package/dist/dashboard-web/chunks/roles-page-WQIRSOLZ.js +0 -1
  609. package/dist/dashboard-web/chunks/schedules-page-J2DEY2X6.js +0 -1
  610. package/dist/dashboard-web/chunks/sessions-page-7BQFEA5P.js +0 -8
  611. package/dist/dashboard-web/chunks/settings-page-BJEIOFJH.js +0 -2
  612. package/dist/dashboard-web/chunks/skills-page-HGIFR3IU.js +0 -4
  613. package/dist/dashboard-web/chunks/team-federation-page-MR5ZPL4B.js +0 -1
  614. package/dist/dashboard-web/chunks/v3-page-GBR5JWPE.js +0 -94
  615. package/dist/dashboard-web/chunks/whiteboards-page-QAZM4BN3.js +0 -1
  616. package/dist/services/vc-meeting-consumer-profile-store.d.ts +0 -39
  617. package/dist/services/vc-meeting-consumer-profile-store.d.ts.map +0 -1
  618. package/dist/services/vc-meeting-consumer-profile-store.js +0 -191
  619. package/dist/services/vc-meeting-consumer-profile-store.js.map +0 -1
@@ -12,12 +12,39 @@ const ACTIVITY_TYPES = [
12
12
  ];
13
13
  const INSTRUCTIONS_MAX = 8000;
14
14
  const PROFILE_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
15
- /**
16
- * Pre-provenance migration target. Keep this byte-for-byte aligned with the
17
- * v2 generated minutes profile: the old seed has no marker, so the explicit
18
- * Dashboard CTA is the only authority allowed to replace its instructions.
19
- */
20
- const V2_DEFAULT_MINUTES_INSTRUCTIONS = '持续整理会议纪要,重点记录已确认的决策、待办事项(含负责人和截止时间)以及未解决风险;字幕修订时更新已有条目,不重复记录同一事项。仅在出现新的关键决策、明确待办或风险,或被用户点名时,才在监听群输出简洁增量;无实质增量时保持静默,不发送确认或心跳。需要向会议内发送文字或语音时,必须通过 botmux 受管 request-output/action gate 提交,不得绕过权限、所有权与审核策略。';
15
+ function policyBaseline(vcEnabled, text, voice, rtv, catalogDefaultConsumerId) {
16
+ return `${vcEnabled ? '1' : '0'}|${text ?? ''}|${voice ?? ''}|${rtv ? '1' : '0'}|${catalogDefaultConsumerId ?? ''}`;
17
+ }
18
+ function rowBaseline(row) {
19
+ return policyBaseline(row.vcEnabled, row.textOutputPolicy, row.voiceOutputPolicy, row.realtimeVoiceEnabled, row.catalogDefaultConsumerId);
20
+ }
21
+ function toBotPolicyDrafts(agentOptions) {
22
+ return agentOptions.map(agent => {
23
+ const text = agent.textOutputPolicy ?? null;
24
+ const voice = agent.voiceOutputPolicy ?? null;
25
+ const rtv = agent.realtimeVoiceEnabled === true;
26
+ const catalogDefaultConsumerId = agent.catalogDefaultConsumerId ?? null;
27
+ const vcEligible = agent.vcEligible !== false;
28
+ const vcEnabled = vcEligible && agent.vcEnabled !== false;
29
+ return {
30
+ appId: agent.appId,
31
+ label: agent.label || agent.appId,
32
+ ...(agent.cliId ? { cliId: agent.cliId } : {}),
33
+ online: agent.online,
34
+ workingDirReady: agent.workingDirReady,
35
+ reliableTurnTerminal: agent.reliableTurnTerminal,
36
+ managedSideEffectEligible: agent.managedSideEffectEligible,
37
+ sandboxIsolated: agent.sandboxIsolated,
38
+ vcEligible,
39
+ vcEnabled,
40
+ textOutputPolicy: text,
41
+ voiceOutputPolicy: voice,
42
+ realtimeVoiceEnabled: rtv,
43
+ catalogDefaultConsumerId,
44
+ baseline: policyBaseline(vcEnabled, text, voice, rtv, catalogDefaultConsumerId),
45
+ };
46
+ });
47
+ }
21
48
  let uiKeySeq = 0;
22
49
  function nextUiKey() {
23
50
  uiKeySeq += 1;
@@ -36,28 +63,16 @@ function toDto(draft) {
36
63
  return dto;
37
64
  }
38
65
  /**
39
- * A meeting-consumer agent is SELECTABLE only when it can actually spawn and
40
- * reply: it needs a working dir, reliable turn receipts, and (plan B) must not
41
- * be a bot whose explicit sandbox request is undeliverable. Offline is transient
42
- * and unsandboxed is an informed opt-out, so neither blocks selection. This is
43
- * the single source of truth shared by the dropdown's `disabled` flag and the
44
- * new-profile default seeder, so the two can never drift apart. Anything else —
45
- * including seeding agentOptions[0] blindly — can silently persist an agent that
46
- * joins meetings but never replies (the server PUT only checks the id is a
47
- * non-empty string, not that it is eligible).
66
+ * 一个 bot 只有同时满足「有工作目录 + CLI 支持可靠回执 + 显式沙盒请求在本平台/
67
+ * 后端可交付」才真的能执行一个会议角色。离线是暂态、未开沙盒是知情选择,都不算
68
+ * 结构性阻塞。预设本身与 bot 解耦,所以这个判定只用来在按 bot 那张表上给出提示
69
+ * ——不再拦着用户编辑预设。
48
70
  */
49
71
  function isAgentSelectable(agent) {
50
72
  return agent.workingDirReady
51
73
  && agent.reliableTurnTerminal
52
74
  && agent.managedSideEffectEligible;
53
75
  }
54
- /** appId of the first selectable agent (see {@link isAgentSelectable}), or ''
55
- * when none qualifies — callers must not seed a disabled agent as the default. */
56
- function firstSelectableAgentAppId(agents) {
57
- return agents.find(isAgentSelectable)?.appId ?? '';
58
- }
59
- /** settings 页挂载门:预设 API 是私有端点,公共只读访客请求必 401——
60
- * canWrite=false 时完全不挂载编辑器(一次 GET 都不发),只显示提示。 */
61
76
  /** 字段标题 + hover 帮助气泡:把配置语义讲清,避免用户对着裸表单猜。 */
62
77
  function FieldHead(props) {
63
78
  return (_jsxs("span", { className: "vc-profile-field-head", children: [props.title, _jsx(InfoTip, { label: props.title, children: _jsx("span", { className: "vc-profile-help", children: props.help }) })] }));
@@ -78,20 +93,20 @@ function VcProfileDialog(props) {
78
93
  }, []);
79
94
  return (_jsxs("dialog", { ref: ref, className: ['vc-profile-dialog', props.className].filter(Boolean).join(' '), onClose: props.onClose, onCancel: (event) => { event.preventDefault(); props.onClose(); }, children: [_jsxs("header", { className: "vc-profile-dialog-head", children: [_jsxs("div", { children: [props.eyebrow ? _jsx("span", { children: props.eyebrow }) : null, _jsx("h3", { children: props.title })] }), _jsx("button", { type: "button", className: "vc-profile-dialog-close", "aria-label": tr('settings.vcProfiles.close'), onClick: props.onClose })] }), _jsx("div", { className: "vc-profile-dialog-body", children: props.children })] }));
80
95
  }
96
+ /** settings 页挂载门:预设 API 是私有端点,公共只读访客请求必 401——
97
+ * canWrite=false 时完全不挂载编辑器(一次 GET 都不发),只显示提示。 */
81
98
  export function VcConsumerProfilesGate(props) {
82
99
  const tr = useT();
83
100
  if (!props.enabled)
84
101
  return null;
85
102
  if (!props.canWrite)
86
103
  return _jsx("p", { className: "hint", children: tr('settings.vcProfiles.needAuth') });
87
- return (_jsx(VcConsumerProfilesSection, { canWrite: props.canWrite, listenerBotAppId: props.listenerBotAppId, listenerBotOptions: props.listenerBotOptions }));
104
+ return _jsx(VcConsumerProfilesSection, { canWrite: props.canWrite, onFeishuLoginQr: props.onFeishuLoginQr });
88
105
  }
89
106
  export function VcConsumerProfilesSection(props) {
90
107
  const tr = useT();
91
108
  const locale = useDashboardLocale();
92
109
  const mountedRef = useRef(false);
93
- const options = props.listenerBotOptions;
94
- const [targetBot, setTargetBot] = useState(props.listenerBotAppId ?? options[0]?.larkAppId ?? '');
95
110
  const [catalog, setCatalog] = useState(null);
96
111
  const [loadError, setLoadError] = useState(null);
97
112
  const [loading, setLoading] = useState(false);
@@ -102,39 +117,30 @@ export function VcConsumerProfilesSection(props) {
102
117
  const [savedTick, setSavedTick] = useState(false);
103
118
  const [selectedProfileKey, setSelectedProfileKey] = useState(null);
104
119
  const [selectedTemplateId, setSelectedTemplateId] = useState(null);
120
+ /** 正在跑开放平台前置配置的 bot(一次只允许一个:automateOpenPlatformSetup 共用
121
+ * 同一份开放平台会话,并发跑会互相抢 csrf/session)。 */
122
+ const [preflightBusyAppId, setPreflightBusyAppId] = useState(null);
123
+ const [preflightResults, setPreflightResults] = useState({});
124
+ const [botPolicyQuery, setBotPolicyQuery] = useState('');
105
125
  useEffect(() => {
106
126
  mountedRef.current = true;
107
127
  return () => {
108
128
  mountedRef.current = false;
109
129
  };
110
130
  }, []);
111
- /** 单调 load token:只有「最新一次 load」的响应才允许提交状态——
112
- * A→B 快速切换时,慢 A 响应到达后被丢弃,不会覆盖 B 的 catalog。 */
131
+ /** 单调 load token:只有「最新一次 load」的响应才允许提交状态——重复点刷新时,
132
+ * 慢响应到达后被丢弃,不会覆盖新响应。 */
113
133
  const loadSeqRef = useRef(0);
114
- useEffect(() => {
115
- // 全局监听 bot 变化时跟随;正在编辑时先保留旧 catalog,允许用户
116
- // 保存当前修改。保存/清 dirty 后本 effect 会再次运行并收敛到新的
117
- // listener,避免显式 Listener 模式(无切换下拉)永久卡在旧目标。
118
- if (props.listenerBotAppId && props.listenerBotAppId !== targetBot && !dirty) {
119
- setTargetBot(props.listenerBotAppId);
120
- }
121
- }, [dirty, props.listenerBotAppId, targetBot]);
122
- const load = useCallback(async (bot) => {
134
+ const load = useCallback(async () => {
123
135
  const token = ++loadSeqRef.current;
124
- // 切换目标立即清空编辑器:旧 bot 的 catalog 一刻也不能挂在新 target 下。
125
- setCatalog(null);
126
136
  setDirty(false);
127
137
  setConflict(false);
128
138
  setFieldErrors({});
129
139
  setSelectedProfileKey(null);
130
140
  setSelectedTemplateId(null);
131
- if (!bot) {
132
- setLoadError(null);
133
- return;
134
- }
135
141
  setLoading(true);
136
142
  try {
137
- const r = await fetch(`/api/vc-meeting/consumer-profiles?listenerBotAppId=${encodeURIComponent(bot)}`);
143
+ const r = await fetch('/api/vc-meeting/consumer-profiles');
138
144
  const body = await r.json().catch(() => ({}));
139
145
  if (!mountedRef.current || loadSeqRef.current !== token)
140
146
  return;
@@ -143,26 +149,7 @@ export function VcConsumerProfilesSection(props) {
143
149
  setLoadError(typeof body?.error === 'string' ? body.error : `HTTP ${r.status}`);
144
150
  }
145
151
  else {
146
- setCatalog({
147
- forBot: bot,
148
- revision: body.revision,
149
- catalogState: body.catalogState === 'explicit_empty'
150
- || body.catalogState === 'legacy_or_partial'
151
- || body.catalogState === 'profiles'
152
- ? body.catalogState
153
- : 'uninitialized',
154
- defaultMode: body.defaultMode === 'agents' ? 'agents' : 'listenOnly',
155
- defaultConsumerIds: Array.isArray(body.defaultConsumerIds) ? body.defaultConsumerIds : [],
156
- profiles: (Array.isArray(body.profiles) ? body.profiles : []).map(toDraft),
157
- agentOptions: Array.isArray(body.agentOptions) ? body.agentOptions : [],
158
- templateCatalog: body.templateCatalog?.schemaVersion === 1
159
- && Array.isArray(body.templateCatalog.templates)
160
- ? body.templateCatalog
161
- : { schemaVersion: 1, templates: [] },
162
- ...(body.migrationOffer === 'enable_seeded_minutes_default'
163
- ? { migrationOffer: body.migrationOffer }
164
- : {}),
165
- });
152
+ setCatalog(catalogFromBody(body));
166
153
  setLoadError(null);
167
154
  setDirty(false);
168
155
  }
@@ -179,8 +166,8 @@ export function VcConsumerProfilesSection(props) {
179
166
  }
180
167
  }, []);
181
168
  useEffect(() => {
182
- void load(targetBot);
183
- }, [load, targetBot]);
169
+ void load();
170
+ }, [load]);
184
171
  const mutate = useCallback((fn) => {
185
172
  setCatalog(current => (current ? fn(current) : current));
186
173
  setDirty(true);
@@ -193,9 +180,7 @@ export function VcConsumerProfilesSection(props) {
193
180
  }));
194
181
  }, [mutate]);
195
182
  const save = useCallback(async () => {
196
- // 提交目标取 catalog 自己记录的 bot:编辑器里的数据永远只能写回它来自的
197
- // bot;若与当前下拉不一致(切换中的窗口),直接拒绝。
198
- if (!catalog || saving || loading || !catalog.forBot || catalog.forBot !== targetBot)
183
+ if (!catalog || saving || loading)
199
184
  return;
200
185
  // 客户端预检仅拦截明显格式问题;权威校验在服务端(含 defaultConsumerIds 组合)。
201
186
  const localErrors = {};
@@ -219,15 +204,24 @@ export function VcConsumerProfilesSection(props) {
219
204
  method: 'PUT',
220
205
  headers: { 'content-type': 'application/json' },
221
206
  body: JSON.stringify({
222
- listenerBotAppId: catalog.forBot,
223
207
  expectedRevision: catalog.revision,
224
208
  defaultMode: catalog.defaultMode,
225
209
  defaultConsumerIds: catalog.defaultConsumerIds,
226
210
  profiles: catalog.profiles.map(toDto),
211
+ botOutputPolicies: catalog.botPolicies
212
+ .filter(row => rowBaseline(row) !== row.baseline)
213
+ .map(row => ({
214
+ appId: row.appId,
215
+ vcEnabled: row.vcEnabled,
216
+ textOutputPolicy: row.textOutputPolicy,
217
+ voiceOutputPolicy: row.voiceOutputPolicy,
218
+ realtimeVoiceEnabled: row.realtimeVoiceEnabled,
219
+ catalogDefaultConsumerId: row.catalogDefaultConsumerId,
220
+ })),
227
221
  }),
228
222
  });
229
223
  const body = await r.json().catch(() => ({}));
230
- if (!mountedRef.current || catalog.forBot !== targetBot)
224
+ if (!mountedRef.current)
231
225
  return;
232
226
  if (r.status === 409) {
233
227
  setConflict(true);
@@ -249,26 +243,7 @@ export function VcConsumerProfilesSection(props) {
249
243
  setFieldErrors({ profiles: typeof body?.error === 'string' ? body.error : `HTTP ${r.status}` });
250
244
  return;
251
245
  }
252
- setCatalog({
253
- forBot: catalog.forBot,
254
- revision: body.revision,
255
- catalogState: body.catalogState === 'explicit_empty'
256
- || body.catalogState === 'legacy_or_partial'
257
- || body.catalogState === 'profiles'
258
- ? body.catalogState
259
- : 'uninitialized',
260
- defaultMode: body.defaultMode === 'agents' ? 'agents' : 'listenOnly',
261
- defaultConsumerIds: Array.isArray(body.defaultConsumerIds) ? body.defaultConsumerIds : [],
262
- profiles: (Array.isArray(body.profiles) ? body.profiles : []).map(toDraft),
263
- agentOptions: Array.isArray(body.agentOptions) ? body.agentOptions : [],
264
- templateCatalog: body.templateCatalog?.schemaVersion === 1
265
- && Array.isArray(body.templateCatalog.templates)
266
- ? body.templateCatalog
267
- : { schemaVersion: 1, templates: [] },
268
- ...(body.migrationOffer === 'enable_seeded_minutes_default'
269
- ? { migrationOffer: body.migrationOffer }
270
- : {}),
271
- });
246
+ setCatalog(catalogFromBody(body));
272
247
  setDirty(false);
273
248
  setSavedTick(true);
274
249
  }
@@ -281,53 +256,62 @@ export function VcConsumerProfilesSection(props) {
281
256
  if (mountedRef.current)
282
257
  setSaving(false);
283
258
  }
284
- }, [catalog, saving, targetBot, tr]);
285
- const botOptions = useMemo(() => options.map(bot => ({
286
- value: bot.larkAppId,
287
- label: bot.botName || bot.larkAppId,
288
- })), [options]);
289
- const targetBotLabel = botOptions.find(option => option.value === targetBot)?.label ?? targetBot;
290
- const agentOptionItems = useMemo(() => {
291
- if (!catalog)
292
- return [];
293
- return catalog.agentOptions.map((agent) => {
294
- const warnings = [
295
- agent.online ? undefined : tr('settings.vcProfiles.agentOffline'),
296
- agent.workingDirReady ? undefined : tr('settings.vcProfiles.agentNoWorkingDir'),
297
- agent.reliableTurnTerminal ? undefined : tr('settings.vcProfiles.agentNoReliableTerminal'),
298
- agent.managedSideEffectEligible ? undefined : tr('settings.vcProfiles.agentNoManagedIsolation'),
299
- // Plan B: unsandboxed is allowed but the bot credential is exposed to
300
- // untrusted meeting input — surface it as an informational note, not a
301
- // blocking warning (the agent stays selectable).
302
- agent.managedSideEffectEligible && !agent.sandboxIsolated
303
- ? tr('settings.vcProfiles.agentUnsandboxedRisk')
304
- : undefined,
305
- ].filter(Boolean);
306
- // Hard blockers make the consumer un-spawnable, so disable selection
307
- // outright rather than let the user pick a bot that will silently never
308
- // reply. Offline is transient (a daemon may come back) and unsandboxed is
309
- // an informed opt-out, so neither disables. Shares isAgentSelectable with
310
- // the default seeder so a disabled bot can never sneak in as the default.
311
- const blocked = !isAgentSelectable(agent);
259
+ }, [catalog, loading, saving, tr]);
260
+ const updateBotPolicy = useCallback((appId, patch) => {
261
+ setCatalog(prev => {
262
+ if (!prev)
263
+ return prev;
312
264
  return {
313
- value: agent.appId,
314
- disabled: blocked,
315
- label: (_jsxs("span", { className: "vc-agent-option", children: [_jsxs("span", { className: "vc-agent-option-name", children: [agent.label, agent.cliId ? _jsx("em", { className: "vc-agent-option-cli", children: agent.cliId }) : null] }), warnings.length > 0 ? (_jsxs("span", { className: "vc-agent-option-warn", children: ["\u26A0 ", warnings.join(' · ')] })) : null] })),
265
+ ...prev,
266
+ botPolicies: prev.botPolicies.map(row => (row.appId === appId ? { ...row, ...patch } : row)),
316
267
  };
317
268
  });
318
- }, [catalog, tr]);
319
- // 触发按钮只放得下一行:显示 agent 名字,有告警时加 ⚠ 前缀提示展开看详情。
320
- const agentTriggerLabel = (appId) => {
321
- const agent = catalog?.agentOptions.find(item => item.appId === appId);
322
- if (!agent)
323
- return appId;
324
- const warn = !agent.online
325
- || !agent.workingDirReady
326
- || !agent.reliableTurnTerminal
327
- || !agent.managedSideEffectEligible
328
- || !agent.sandboxIsolated;
329
- return warn ? `⚠ ${agent.label}` : agent.label;
330
- };
269
+ setDirty(true);
270
+ setSavedTick(false);
271
+ }, []);
272
+ /** 「配置权限」:给这个 bot VC scope、订阅会议事件、补 larkCliProfile。
273
+ * 刻意不在成功后 reload——preflight 写的是 bots.json,与预设草稿无关,reload 会
274
+ * 把用户还没保存的策略编辑一起冲掉。 */
275
+ const runPreflight = useCallback(async (appId) => {
276
+ if (preflightBusyAppId)
277
+ return;
278
+ setPreflightBusyAppId(appId);
279
+ setPreflightResults(prev => ({ ...prev, [appId]: { ok: true, text: tr('settings.vcProfiles.botPolicies.preflightRunning') } }));
280
+ try {
281
+ const r = await fetch('/api/vc-meeting/bot-preflight', {
282
+ method: 'POST',
283
+ headers: { 'content-type': 'application/json' },
284
+ body: JSON.stringify({ appId }),
285
+ });
286
+ const body = await r.json().catch(() => ({}));
287
+ if (!mountedRef.current)
288
+ return;
289
+ if (r.ok && body?.ok === true) {
290
+ props.onFeishuLoginQr?.(null);
291
+ setPreflightResults(prev => ({ ...prev, [appId]: { ok: true, text: tr('settings.vcProfiles.botPolicies.preflightOk') } }));
292
+ return;
293
+ }
294
+ if (typeof body?.feishuLoginQr === 'string' && body.feishuLoginQr) {
295
+ props.onFeishuLoginQr?.(body.feishuLoginQr);
296
+ }
297
+ setPreflightResults(prev => ({
298
+ ...prev,
299
+ [appId]: { ok: false, text: typeof body?.error === 'string' ? body.error : `HTTP ${r.status}` },
300
+ }));
301
+ }
302
+ catch (e) {
303
+ if (!mountedRef.current)
304
+ return;
305
+ setPreflightResults(prev => ({
306
+ ...prev,
307
+ [appId]: { ok: false, text: e instanceof Error ? e.message : String(e) },
308
+ }));
309
+ }
310
+ finally {
311
+ if (mountedRef.current)
312
+ setPreflightBusyAppId(null);
313
+ }
314
+ }, [preflightBusyAppId, props, tr]);
331
315
  const presetOptions = useCallback((profile) => {
332
316
  const presets = ['observe_only', 'meeting_text', 'meeting_voice', 'meeting_text_voice'];
333
317
  const items = presets.map(preset => ({
@@ -347,12 +331,6 @@ export function VcConsumerProfilesSection(props) {
347
331
  uiKey,
348
332
  isNew: true,
349
333
  id: '',
350
- // Seed the first SELECTABLE agent, not agentOptions[0]. The [0] entry is
351
- // the appId-sorted first bot, which may be a disabled (un-spawnable) one
352
- // — a hardcoded [0] default silently bypasses the dropdown disable and
353
- // saves an agent that will never reply (server PUT only checks the id is
354
- // a non-empty string). '' when none is eligible → validation catches it.
355
- agentAppId: firstSelectableAgentAppId(state.agentOptions),
356
334
  responseMode: 'silent',
357
335
  listenerPlacement: 'auto',
358
336
  permissionPreset: 'observe_only',
@@ -375,8 +353,6 @@ export function VcConsumerProfilesSection(props) {
375
353
  isNew: true,
376
354
  id,
377
355
  label: template.profileLabel[locale],
378
- // Same as addProfile: first selectable agent, never the disabled [0].
379
- agentAppId: firstSelectableAgentAppId(state.agentOptions),
380
356
  instructions: template.instructions[locale],
381
357
  activityTypes: [...template.activityTypes],
382
358
  responseMode: template.responseMode,
@@ -389,15 +365,34 @@ export function VcConsumerProfilesSection(props) {
389
365
  setSelectedProfileKey(uiKey);
390
366
  }, [locale, mutate]);
391
367
  const removeProfile = useCallback((uiKey) => {
392
- mutate(state => ({
393
- ...state,
394
- profiles: state.profiles.filter(profile => profile.uiKey !== uiKey),
395
- defaultConsumerIds: state.defaultConsumerIds.filter(id => state.profiles.some(profile => profile.uiKey !== uiKey && profile.id === id)),
396
- }));
368
+ mutate((state) => {
369
+ const defaultConsumerIds = state.defaultConsumerIds.filter(id => state.profiles.some(profile => profile.uiKey !== uiKey && profile.id === id));
370
+ return {
371
+ ...state,
372
+ profiles: state.profiles.filter(profile => profile.uiKey !== uiKey),
373
+ defaultConsumerIds,
374
+ // 删掉的正是那条默认角色时,必须一并退回「仅监听」:agents + 空 ids 是
375
+ // 服务端明确拒绝的组合,留着会让用户在保存时才吃到一个 422。
376
+ defaultMode: defaultConsumerIds.length > 0 ? state.defaultMode : 'listenOnly',
377
+ };
378
+ });
397
379
  setSelectedProfileKey(current => current === uiKey ? null : current);
398
380
  }, [mutate]);
399
- if (options.length === 0)
400
- return null;
381
+ const sortedBotPolicies = useMemo(() => {
382
+ if (!catalog)
383
+ return [];
384
+ const q = botPolicyQuery.trim().toLowerCase();
385
+ const rows = q
386
+ ? catalog.botPolicies.filter(row => row.label.toLowerCase().includes(q) || row.appId.toLowerCase().includes(q))
387
+ : catalog.botPolicies;
388
+ return [...rows].sort((a, b) => {
389
+ if (a.vcEnabled !== b.vcEnabled)
390
+ return a.vcEnabled ? -1 : 1;
391
+ if (a.online !== b.online)
392
+ return a.online ? -1 : 1;
393
+ return a.label.localeCompare(b.label);
394
+ });
395
+ }, [catalog, botPolicyQuery]);
401
396
  const err = (path) => fieldErrors[path];
402
397
  // 保存/加载期间冻结全部编辑控件:PUT 用提交时的闭包,成功响应会整份
403
398
  // setCatalog + 清 dirty——若允许 pending 窗口内继续编辑,这些修改会被
@@ -407,13 +402,14 @@ export function VcConsumerProfilesSection(props) {
407
402
  const selectedProfileIndex = catalog?.profiles.findIndex(profile => profile.uiKey === selectedProfileKey) ?? -1;
408
403
  const selectedProfile = selectedProfileIndex >= 0 ? catalog?.profiles[selectedProfileIndex] ?? null : null;
409
404
  const selectedTemplate = catalog?.templateCatalog.templates.find(template => template.templateId === selectedTemplateId) ?? null;
410
- const setProfileDefault = (profile, enabled) => {
405
+ /** 默认角色是单选:一个 bot 进会后只跑一个角色(服务端也这么校验),
406
+ * 再点一次已选中的那个即取消,回到「仅监听」。 */
407
+ const setProfileDefault = (profile) => {
411
408
  if (!profile.id)
412
409
  return;
413
410
  mutate(state => {
414
- const ids = enabled
415
- ? [...new Set([...state.defaultConsumerIds, profile.id])]
416
- : state.defaultConsumerIds.filter(id => id !== profile.id);
411
+ const already = state.defaultConsumerIds.length === 1 && state.defaultConsumerIds[0] === profile.id;
412
+ const ids = already ? [] : [profile.id];
417
413
  return {
418
414
  ...state,
419
415
  defaultMode: ids.length > 0 ? 'agents' : 'listenOnly',
@@ -421,45 +417,49 @@ export function VcConsumerProfilesSection(props) {
421
417
  };
422
418
  });
423
419
  };
424
- return (_jsxs("div", { className: "vc-profiles-section", children: [_jsxs("div", { className: "settings-field-row", children: [_jsx(FieldTitle, { help: tr('settings.vcProfiles.help'), children: tr('settings.vcProfiles.title') }), props.listenerBotAppId === null && botOptions.length > 1 ? (_jsxs("div", { className: "vc-profile-field", children: [_jsx("span", { children: tr('settings.vcProfiles.listenerOwner') }), _jsx(DropdownMenu, { className: "settings-field-menu", ariaLabel: tr('settings.vcProfiles.listenerOwner'), disabled: loading || saving, value: targetBot, label: dropdownLabel(botOptions, targetBot), options: botOptions, onChange: (value) => {
425
- if (value === targetBot)
426
- return;
427
- if (dirty && !window.confirm(tr('settings.vcProfiles.discardConfirm')))
428
- return;
429
- setTargetBot(value);
430
- } })] })) : (_jsx("span", { className: "vc-profile-config-target", children: tr('settings.vcProfiles.configuringBot', { bot: targetBotLabel }) }))] }), _jsx("p", { className: "hint vc-profiles-freeze", children: tr('settings.vcProfiles.freezeNotice') }), loading ? _jsx("p", { className: "hint", children: tr('settings.vcProfiles.loading') }) : null, loadError ? (_jsx("p", { className: "hint-warn", children: loadError === 'bot_not_in_config'
431
- ? tr('settings.vcProfiles.botNotInConfig')
432
- : `${tr('settings.vcProfiles.loadFailed')}: ${loadError}` })) : null, conflict ? (_jsxs("p", { className: "hint-warn", children: [tr('settings.vcProfiles.conflict'), ' ', _jsx("button", { type: "button", className: "vc-profiles-link", onClick: () => void load(targetBot), children: tr('settings.vcProfiles.reload') })] })) : null, err('profiles') ? _jsx("p", { className: "hint-warn", children: err('profiles') }) : null, catalog ? (_jsxs(_Fragment, { children: [catalog.migrationOffer === 'enable_seeded_minutes_default' ? (_jsxs("p", { className: "hint-warn vc-profile-migration-offer", children: [tr('settings.vcProfiles.migrationOffer'), ' ', _jsx("button", { type: "button", className: "vc-profiles-link", disabled: frozen || dirty, onClick: () => mutate(state => ({
433
- ...state,
434
- defaultMode: 'agents',
435
- defaultConsumerIds: ['minutes'],
436
- profiles: state.profiles.map(profile => profile.id === 'minutes'
437
- ? {
438
- ...profile,
439
- instructions: V2_DEFAULT_MINUTES_INSTRUCTIONS,
440
- responseMode: 'listener_thread',
441
- permissionPreset: 'meeting_text_voice',
442
- }
443
- : profile),
444
- migrationOffer: undefined,
445
- })), children: tr('settings.vcProfiles.migrationEnable') })] })) : null, catalog.catalogState === 'uninitialized'
446
- && catalog.profiles.length === 0
447
- && !hasStructurallyEligibleAgent ? (_jsx("p", { className: "hint-warn", children: tr('settings.vcProfiles.noEligibleDefaultAgent') })) : null, catalog.catalogState === 'legacy_or_partial' ? (_jsx("p", { className: "hint", children: tr('settings.vcProfiles.legacyCatalog') })) : null, _jsxs("section", { className: "vc-profile-library-section", children: [_jsxs("div", { className: "vc-profile-list-heading", children: [_jsxs("div", { children: [_jsx("strong", { children: tr('settings.vcProfiles.list.title') }), _jsx("p", { children: tr('settings.vcProfiles.list.help') })] }), props.canWrite ? (_jsx("button", { type: "button", className: "vc-profiles-link vc-profile-add",
448
- // No selectable agent ⇒ a new profile could only be seeded with
449
- // '' (or, before the fix, a disabled bot). Disable adding rather
450
- // than create a profile that can never spawn a replying consumer.
451
- disabled: saving || loading || !hasStructurallyEligibleAgent, title: !hasStructurallyEligibleAgent
452
- ? tr('settings.vcProfiles.noEligibleDefaultAgent')
453
- : undefined, onClick: addProfile, children: tr('settings.vcProfiles.add') })) : null] }), catalog.profiles.length > 0 ? (_jsx("div", { className: "vc-profile-card-grid", children: catalog.profiles.map(profile => {
454
- const agent = catalog.agentOptions.find(item => item.appId === profile.agentAppId);
420
+ return (_jsxs("div", { className: "vc-profiles-section", children: [_jsx("div", { className: "settings-field-row", children: _jsx(FieldTitle, { help: tr('settings.vcProfiles.help'), children: tr('settings.vcProfiles.title') }) }), _jsx("p", { className: "hint vc-profiles-shared", children: tr('settings.vcProfiles.sharedNotice') }), _jsx("p", { className: "hint vc-profiles-freeze", children: tr('settings.vcProfiles.freezeNotice') }), loading ? _jsx("p", { className: "hint", children: tr('settings.vcProfiles.loading') }) : null, loadError ? (_jsxs("p", { className: "hint-warn", children: [tr('settings.vcProfiles.loadFailed'), ": ", loadError] })) : null, conflict ? (_jsxs("p", { className: "hint-warn", children: [tr('settings.vcProfiles.conflict'), ' ', _jsx("button", { type: "button", className: "vc-profiles-link", onClick: () => void load(), children: tr('settings.vcProfiles.reload') })] })) : null, err('profiles') ? _jsx("p", { className: "hint-warn", children: err('profiles') }) : null, catalog ? (_jsxs(_Fragment, { children: [!hasStructurallyEligibleAgent ? (_jsx("p", { className: "hint-warn", children: tr('settings.vcProfiles.noEligibleDefaultAgent') })) : null, _jsxs("section", { className: "vc-profile-library-section", children: [_jsxs("div", { className: "vc-profile-list-heading", children: [_jsxs("div", { children: [_jsx("strong", { children: tr('settings.vcProfiles.list.title') }), _jsx("p", { children: tr('settings.vcProfiles.list.help') })] }), props.canWrite ? (_jsx("button", { type: "button", className: "vc-profiles-link vc-profile-add", disabled: saving || loading, onClick: addProfile, children: tr('settings.vcProfiles.add') })) : null] }), catalog.profiles.length > 0 ? (_jsx("div", { className: "vc-profile-card-grid", children: catalog.profiles.map(profile => {
455
421
  const isDefault = catalog.defaultMode === 'agents' && catalog.defaultConsumerIds.includes(profile.id);
456
422
  return (_jsxs("article", { className: "vc-profile-summary-card", role: "button", tabIndex: 0, onClick: () => setSelectedProfileKey(profile.uiKey), onKeyDown: (event) => {
457
423
  if (event.key === 'Enter' || event.key === ' ') {
458
424
  event.preventDefault();
459
425
  setSelectedProfileKey(profile.uiKey);
460
426
  }
461
- }, children: [_jsxs("div", { className: "vc-profile-summary-top", children: [_jsx("span", { className: "vc-profile-summary-icon", "aria-hidden": "true", children: (profile.label || profile.id || '?').slice(0, 1) }), _jsxs("div", { children: [_jsx("strong", { children: profile.label || profile.id || tr('settings.vcProfiles.untitled') }), _jsx("code", { children: profile.id || tr('settings.vcProfiles.newBadge') })] }), profile.isNew ? _jsx("em", { children: tr('settings.vcProfiles.newBadge') }) : null] }), _jsx("p", { children: (profile.instructions ?? '').trim() || tr('settings.vcProfiles.noInstructions') }), _jsxs("div", { className: "vc-profile-summary-meta", children: [_jsx("span", { children: agent?.label ?? profile.agentAppId }), _jsx("span", { children: profile.responseMode === 'listener_thread' ? tr('settings.vcProfiles.responseListener') : tr('settings.vcProfiles.responseSilent') })] }), _jsxs("label", { className: "vc-profile-default-toggle", onClick: event => event.stopPropagation(), children: [_jsx("input", { type: "checkbox", checked: isDefault, disabled: frozen || !profile.id, onChange: event => setProfileDefault(profile, event.currentTarget.checked) }), _jsx("span", { children: tr('settings.vcProfiles.setDefault') })] })] }, profile.uiKey));
462
- }) })) : _jsx("p", { className: "vc-profile-empty", children: tr('settings.vcProfiles.list.empty') })] }), catalog.templateCatalog.templates.length > 0 ? (_jsxs("section", { className: "vc-profile-template-catalog", children: [_jsxs("div", { className: "vc-profile-template-heading", children: [_jsxs("div", { children: [_jsx("strong", { children: tr('settings.vcProfiles.templates.title') }), _jsx("p", { children: tr('settings.vcProfiles.templates.help') })] }), _jsx("span", { children: tr('settings.vcProfiles.templates.builtinBadge') })] }), _jsx("div", { className: "vc-profile-template-grid", children: catalog.templateCatalog.templates.map(template => (_jsxs("button", { type: "button", className: "vc-profile-template-card", onClick: () => setSelectedTemplateId(template.templateId), children: [_jsx("span", { "aria-hidden": "true", children: "\u2726" }), _jsx("strong", { children: template.title[locale] }), _jsx("p", { children: template.description[locale] }), _jsxs("em", { children: [tr('settings.vcProfiles.viewDetails'), " \u2192"] })] }, `${template.templateId}@${template.version}`))) })] })) : null, _jsxs("div", { className: "settings-field-row vc-profile-default-mode-row", children: [_jsx(FieldTitle, { help: tr('settings.vcProfiles.defaultModeHelp'), children: tr('settings.vcProfiles.defaultMode') }), _jsx(DropdownMenu, { className: "settings-field-menu", ariaLabel: tr('settings.vcProfiles.defaultMode'), disabled: frozen, value: catalog.defaultMode, label: catalog.defaultMode === 'agents'
427
+ }, children: [_jsxs("div", { className: "vc-profile-summary-top", children: [_jsx("span", { className: "vc-profile-summary-icon", "aria-hidden": "true", children: (profile.label || profile.id || '?').slice(0, 1) }), _jsxs("div", { children: [_jsx("strong", { children: profile.label || profile.id || tr('settings.vcProfiles.untitled') }), _jsx("code", { children: profile.id || tr('settings.vcProfiles.newBadge') })] }), profile.isNew ? _jsx("em", { children: tr('settings.vcProfiles.newBadge') }) : null] }), _jsx("p", { children: (profile.instructions ?? '').trim() || tr('settings.vcProfiles.noInstructions') }), _jsxs("div", { className: "vc-profile-summary-meta", children: [_jsx("span", { children: profile.responseMode === 'listener_thread' ? tr('settings.vcProfiles.responseListener') : tr('settings.vcProfiles.responseSilent') }), _jsx("span", { children: tr(`settings.vcProfiles.preset.${profile.permissionPreset}`) })] }), _jsxs("label", { className: "vc-profile-default-toggle", onClick: event => event.stopPropagation(), children: [_jsx("input", { type: "radio", name: "vc-profile-default", checked: isDefault, disabled: frozen || !profile.id, onChange: () => setProfileDefault(profile), onClick: () => { if (isDefault)
428
+ setProfileDefault(profile); } }), _jsx("span", { children: tr('settings.vcProfiles.setDefault') })] })] }, profile.uiKey));
429
+ }) })) : _jsx("p", { className: "vc-profile-empty", children: tr('settings.vcProfiles.list.empty') }), _jsx("p", { className: "hint vc-profile-default-single", children: tr('settings.vcProfiles.defaultSingleHint') })] }), catalog.templateCatalog.templates.length > 0 ? (_jsxs("section", { className: "vc-profile-template-catalog", children: [_jsxs("div", { className: "vc-profile-template-heading", children: [_jsxs("div", { children: [_jsx("strong", { children: tr('settings.vcProfiles.templates.title') }), _jsx("p", { children: tr('settings.vcProfiles.templates.help') })] }), _jsx("span", { children: tr('settings.vcProfiles.templates.builtinBadge') })] }), _jsx("div", { className: "vc-profile-template-grid", children: catalog.templateCatalog.templates.map(template => (_jsxs("button", { type: "button", className: "vc-profile-template-card", onClick: () => setSelectedTemplateId(template.templateId), children: [_jsx("span", { "aria-hidden": "true", children: "\u2726" }), _jsx("strong", { children: template.title[locale] }), _jsx("p", { children: template.description[locale] }), _jsxs("em", { children: [tr('settings.vcProfiles.viewDetails'), " \u2192"] })] }, `${template.templateId}@${template.version}`))) })] })) : null, _jsxs("section", { className: "vc-profile-library-section vc-bot-policy-section", children: [_jsxs("div", { className: "vc-profile-list-heading", children: [_jsxs("div", { children: [_jsx("strong", { children: tr('settings.vcProfiles.botPolicies.title') }), _jsx("p", { children: tr('settings.vcProfiles.botPolicies.help') })] }), _jsx("input", { type: "search", className: "vc-bot-policy-search", placeholder: tr('settings.vcProfiles.botPolicies.searchPlaceholder'), value: botPolicyQuery, disabled: frozen, onChange: (event) => setBotPolicyQuery(event.target.value) })] }), _jsxs("div", { className: "vc-bot-policy-table", style: { maxHeight: 320, overflowY: 'auto' }, children: [sortedBotPolicies.length === 0 ? (_jsx("p", { className: "vc-bot-policy-empty hint", children: tr('settings.vcProfiles.botPolicies.noMatch') })) : null, sortedBotPolicies.map(row => {
430
+ const effectiveText = row.textOutputPolicy ?? 'allow';
431
+ const effectiveVoice = !row.realtimeVoiceEnabled ? 'deny' : (row.voiceOutputPolicy ?? 'allow');
432
+ const policyLabel = (value) => tr(`settings.vcProfiles.botPolicies.${value}`);
433
+ // 只在这里提示能力缺口:预设与 bot 解耦后,这张表是唯一能解释
434
+ // 「为什么拉这个 bot 进会没反应」的地方。逐条文案很长(尤其沙盒那条),
435
+ // 一行 bot 后面平铺会喧宾夺主——收成一个 ⚠,详情放 hover title。
436
+ const warnings = [
437
+ row.vcEligible ? undefined : tr('settings.vcProfiles.botPolicies.vcIneligible'),
438
+ row.online ? undefined : tr('settings.vcProfiles.agentOffline'),
439
+ row.workingDirReady ? undefined : tr('settings.vcProfiles.agentNoWorkingDir'),
440
+ row.reliableTurnTerminal ? undefined : tr('settings.vcProfiles.agentNoReliableTerminal'),
441
+ row.managedSideEffectEligible ? undefined : tr('settings.vcProfiles.agentNoManagedIsolation'),
442
+ row.managedSideEffectEligible && !row.sandboxIsolated
443
+ ? tr('settings.vcProfiles.agentUnsandboxedRisk')
444
+ : undefined,
445
+ ].filter((w) => !!w);
446
+ const rowFrozen = !props.canWrite || saving || loading;
447
+ const renderSelect = (field, value) => (_jsxs("select", { className: "vc-bot-policy-select", value: value ?? 'default', disabled: rowFrozen || !row.vcEnabled, onChange: (event) => {
448
+ const raw = event.target.value;
449
+ updateBotPolicy(row.appId, {
450
+ [field]: raw === 'default' ? null : raw,
451
+ });
452
+ }, children: [_jsx("option", { value: "default", children: tr('settings.vcProfiles.botPolicies.default') }), _jsx("option", { value: "allow", children: policyLabel('allow') }), _jsx("option", { value: "approval", children: policyLabel('approval') }), _jsx("option", { value: "deny", children: policyLabel('deny') })] }));
453
+ const preflight = preflightResults[row.appId];
454
+ return (_jsxs("div", { className: "vc-bot-policy-row", children: [_jsxs("span", { className: "vc-bot-policy-name", title: row.appId, children: [row.online ? '' : '⚪ ', row.label, warnings.length > 0 ? (_jsx(InfoTip, { className: "vc-bot-policy-warn-tip", label: warnings.join(' · '), trigger: _jsx("em", { className: "vc-bot-policy-warn", "aria-hidden": "true", children: "\u26A0" }), children: _jsx("span", { className: "vc-bot-policy-warn-pop", children: warnings.map((w, i) => _jsx("div", { children: w }, i)) }) })) : null, preflight ? (_jsx("em", { className: preflight.ok ? 'vc-bot-policy-preflight' : 'vc-bot-policy-warn', children: preflight.text })) : null] }), _jsxs("label", { className: "vc-bot-policy-cell vc-bot-policy-enabled", children: [_jsx("input", { type: "checkbox", checked: row.vcEnabled, disabled: rowFrozen || !row.vcEligible, onChange: (event) => updateBotPolicy(row.appId, { vcEnabled: event.target.checked }) }), _jsx("span", { children: tr('settings.vcProfiles.botPolicies.vcEnabled') })] }), _jsxs("label", { className: "vc-bot-policy-cell", children: [_jsx("span", { children: tr('settings.vcProfiles.botPolicies.defaultProfile') }), _jsxs("select", { className: "vc-bot-policy-select", value: row.catalogDefaultConsumerId ?? '', disabled: rowFrozen || !row.vcEnabled, onChange: (event) => {
455
+ const raw = event.target.value;
456
+ updateBotPolicy(row.appId, { catalogDefaultConsumerId: raw === '' ? null : raw });
457
+ }, children: [_jsx("option", { value: "", children: tr('settings.vcProfiles.botPolicies.defaultProfileFollowGlobal') }), catalog.profiles.map(profile => (_jsx("option", { value: profile.id, children: profile.label || profile.id }, profile.id)))] })] }), _jsxs("label", { className: "vc-bot-policy-cell", children: [_jsx("span", { children: tr('settings.vcProfiles.botPolicies.text') }), renderSelect('textOutputPolicy', row.textOutputPolicy)] }), _jsxs("label", { className: "vc-bot-policy-cell", children: [_jsx("span", { children: tr('settings.vcProfiles.botPolicies.voice') }), renderSelect('voiceOutputPolicy', row.voiceOutputPolicy)] }), _jsxs("label", { className: "vc-bot-policy-cell vc-bot-policy-rtv", children: [_jsx("input", { type: "checkbox", checked: row.realtimeVoiceEnabled, disabled: rowFrozen || !row.vcEnabled, onChange: (event) => updateBotPolicy(row.appId, { realtimeVoiceEnabled: event.target.checked }) }), _jsx("span", { children: tr('settings.vcProfiles.botPolicies.realtimeVoice') })] }), _jsxs("span", { className: "vc-bot-policy-effective hint", children: [tr('settings.vcProfiles.botPolicies.effective'), ' ', row.vcEnabled
458
+ ? `${policyLabel(effectiveText)} / ${policyLabel(effectiveVoice)}`
459
+ : tr('settings.vcProfiles.botPolicies.vcOff')] }), _jsx("button", { type: "button", className: "bd-btn bd-btn-ghost vc-bot-policy-preflight-btn", disabled: !props.canWrite || !row.vcEligible || preflightBusyAppId !== null, title: tr('settings.vcProfiles.botPolicies.preflightHelp'), onClick: () => void runPreflight(row.appId), children: preflightBusyAppId === row.appId
460
+ ? tr('settings.vcProfiles.botPolicies.preflightRunning')
461
+ : tr('settings.vcProfiles.botPolicies.preflight') })] }, row.appId));
462
+ })] })] }), _jsxs("div", { className: "settings-field-row vc-profile-default-mode-row", children: [_jsx(FieldTitle, { help: tr('settings.vcProfiles.defaultModeHelp'), children: tr('settings.vcProfiles.defaultMode') }), _jsx(DropdownMenu, { className: "settings-field-menu", ariaLabel: tr('settings.vcProfiles.defaultMode'), disabled: frozen, value: catalog.defaultMode, label: catalog.defaultMode === 'agents'
463
463
  ? tr('settings.vcProfiles.defaultModeAgents')
464
464
  : tr('settings.vcProfiles.defaultModeListenOnly'), options: [
465
465
  { value: 'listenOnly', label: tr('settings.vcProfiles.defaultModeListenOnly') },
@@ -467,25 +467,44 @@ export function VcConsumerProfilesSection(props) {
467
467
  ], onChange: value => mutate(state => ({
468
468
  ...state,
469
469
  defaultMode: value === 'agents' ? 'agents' : 'listenOnly',
470
- })) })] }), err('defaultConsumerIds') ? _jsx("em", { className: "vc-profile-err", children: err('defaultConsumerIds') }) : null, err('defaultMode') ? _jsx("em", { className: "vc-profile-err", children: err('defaultMode') }) : null, props.canWrite ? (_jsxs("div", { className: "vc-profiles-actions", children: [_jsx("button", { type: "button", className: "vc-profiles-save", disabled: !dirty || saving || conflict, onClick: () => void save(), children: saving ? tr('settings.vcProfiles.saving') : tr('settings.vcProfiles.save') }), savedTick ? _jsx("span", { className: "vc-profile-hint", children: tr('settings.vcProfiles.saved') }) : null, dirty && !saving ? _jsx("span", { className: "vc-profile-hint", children: tr('settings.vcProfiles.unsaved') }) : null] })) : null, selectedProfile ? (_jsx(ProfileEditorDialog, { profile: selectedProfile, index: selectedProfileIndex, frozen: frozen, canWrite: props.canWrite, agentOptions: agentOptionItems, agentLabel: agentTriggerLabel(selectedProfile.agentAppId), presetOptions: presetOptions(selectedProfile), error: err, onClose: () => setSelectedProfileKey(null), onUpdate: patch => updateProfile(selectedProfile.uiKey, patch), onIdChange: (nextId) => {
470
+ })) })] }), err('defaultConsumerIds') ? _jsx("em", { className: "vc-profile-err", children: err('defaultConsumerIds') }) : null, err('defaultMode') ? _jsx("em", { className: "vc-profile-err", children: err('defaultMode') }) : null, props.canWrite ? (_jsxs("div", { className: "vc-profiles-actions", children: [_jsx("button", { type: "button", className: "vc-profiles-save", disabled: !dirty || saving || conflict, onClick: () => void save(), children: saving ? tr('settings.vcProfiles.saving') : tr('settings.vcProfiles.save') }), savedTick ? _jsx("span", { className: "vc-profile-hint", children: tr('settings.vcProfiles.saved') }) : null, dirty && !saving ? _jsx("span", { className: "vc-profile-hint", children: tr('settings.vcProfiles.unsaved') }) : null] })) : null, selectedProfile ? (_jsx(ProfileEditorDialog, { profile: selectedProfile, index: selectedProfileIndex, frozen: frozen, canWrite: props.canWrite, presetOptions: presetOptions(selectedProfile), error: err, onClose: () => setSelectedProfileKey(null), onUpdate: patch => updateProfile(selectedProfile.uiKey, patch), onIdChange: (nextId) => {
471
471
  const oldId = selectedProfile.id;
472
- mutate(state => ({
473
- ...state,
474
- profiles: state.profiles.map(candidate => candidate.uiKey === selectedProfile.uiKey
475
- ? { ...candidate, id: nextId }
476
- : candidate),
477
- defaultConsumerIds: state.defaultConsumerIds.map(id => (id === oldId && oldId ? nextId : id)).filter(Boolean),
478
- }));
479
- }, onRemove: () => removeProfile(selectedProfile.uiKey) })) : null, selectedTemplate ? (_jsx(TemplateDetailsDialog, { template: selectedTemplate, locale: locale,
480
- // Applying a template also seeds an agent; gate it on a selectable
481
- // agent existing, not merely a non-empty (possibly all-disabled)
482
- // agent list, so it can't seed '' / a disabled bot either.
483
- disabled: frozen || !hasStructurallyEligibleAgent, onClose: () => setSelectedTemplateId(null), onUse: () => addProfileFromTemplate(selectedTemplate) })) : null] })) : null] }));
472
+ mutate((state) => {
473
+ const defaultConsumerIds = state.defaultConsumerIds.map(id => (id === oldId && oldId ? nextId : id)).filter(Boolean);
474
+ return {
475
+ ...state,
476
+ profiles: state.profiles.map(candidate => candidate.uiKey === selectedProfile.uiKey
477
+ ? { ...candidate, id: nextId }
478
+ : candidate),
479
+ defaultConsumerIds,
480
+ // 清空 id 会让默认角色随之消失;同上,不能留下 agents + ids。
481
+ defaultMode: defaultConsumerIds.length > 0 ? state.defaultMode : 'listenOnly',
482
+ };
483
+ });
484
+ }, onRemove: () => removeProfile(selectedProfile.uiKey) })) : null, selectedTemplate ? (_jsx(TemplateDetailsDialog, { template: selectedTemplate, locale: locale, disabled: frozen, onClose: () => setSelectedTemplateId(null), onUse: () => addProfileFromTemplate(selectedTemplate) })) : null] })) : null] }));
485
+ }
486
+ function catalogFromBody(body) {
487
+ const agentOptions = Array.isArray(body.agentOptions) ? body.agentOptions : [];
488
+ return {
489
+ revision: body.revision,
490
+ catalogState: body.catalogState === 'explicit_empty' || body.catalogState === 'profiles'
491
+ ? body.catalogState
492
+ : 'uninitialized',
493
+ defaultMode: body.defaultMode === 'agents' ? 'agents' : 'listenOnly',
494
+ defaultConsumerIds: Array.isArray(body.defaultConsumerIds) ? body.defaultConsumerIds : [],
495
+ profiles: (Array.isArray(body.profiles) ? body.profiles : []).map(toDraft),
496
+ agentOptions,
497
+ botPolicies: toBotPolicyDrafts(agentOptions),
498
+ templateCatalog: body.templateCatalog?.schemaVersion === 1
499
+ && Array.isArray(body.templateCatalog.templates)
500
+ ? body.templateCatalog
501
+ : { schemaVersion: 1, templates: [] },
502
+ };
484
503
  }
485
504
  function ProfileEditorDialog(props) {
486
505
  const tr = useT();
487
506
  const { profile, index } = props;
488
- return (_jsxs(VcProfileDialog, { className: "vc-profile-editor-dialog", eyebrow: tr('settings.vcProfiles.list.title'), title: profile.label || profile.id || tr('settings.vcProfiles.untitled'), onClose: props.onClose, children: [_jsxs("div", { className: "vc-profile-grid", children: [_jsxs("label", { className: "vc-profile-field", children: [_jsx("span", { children: _jsx(FieldHead, { title: tr('settings.vcProfiles.fieldId'), help: tr('settings.vcProfiles.idHelp') }) }), _jsx("input", { type: "text", value: profile.id, disabled: props.frozen || !profile.isNew, placeholder: "minutes", onChange: event => props.onIdChange(event.currentTarget.value) }), props.error(`profiles[${index}].id`) ? _jsx("em", { className: "vc-profile-err", children: props.error(`profiles[${index}].id`) }) : null] }), _jsxs("label", { className: "vc-profile-field", children: [_jsx("span", { children: _jsx(FieldHead, { title: tr('settings.vcProfiles.fieldLabel'), help: tr('settings.vcProfiles.labelHelp') }) }), _jsx("input", { type: "text", value: profile.label ?? '', disabled: props.frozen, onChange: event => props.onUpdate({ label: event.currentTarget.value || undefined }) }), props.error(`profiles[${index}].label`) ? _jsx("em", { className: "vc-profile-err", children: props.error(`profiles[${index}].label`) }) : null] }), _jsxs("div", { className: "vc-profile-field", children: [_jsx("span", { children: _jsx(FieldHead, { title: tr('settings.vcProfiles.fieldAgent'), help: tr('settings.vcProfiles.agentHelp') }) }), _jsx(DropdownMenu, { className: "vc-profile-agent-menu", ariaLabel: tr('settings.vcProfiles.fieldAgent'), disabled: props.frozen, value: profile.agentAppId, label: props.agentLabel, options: props.agentOptions, onChange: value => props.onUpdate({ agentAppId: value }) }), props.error(`profiles[${index}].agentAppId`) ? _jsx("em", { className: "vc-profile-err", children: props.error(`profiles[${index}].agentAppId`) }) : null] }), _jsxs("div", { className: "vc-profile-field", children: [_jsx("span", { children: _jsx(FieldHead, { title: tr('settings.vcProfiles.fieldResponseMode'), help: tr('settings.vcProfiles.responseModeHelp') }) }), _jsx(DropdownMenu, { ariaLabel: tr('settings.vcProfiles.fieldResponseMode'), disabled: props.frozen, value: profile.responseMode, label: profile.responseMode === 'listener_thread' ? tr('settings.vcProfiles.responseListener') : tr('settings.vcProfiles.responseSilent'), options: [
507
+ return (_jsxs(VcProfileDialog, { className: "vc-profile-editor-dialog", eyebrow: tr('settings.vcProfiles.list.title'), title: profile.label || profile.id || tr('settings.vcProfiles.untitled'), onClose: props.onClose, children: [_jsxs("div", { className: "vc-profile-grid", children: [_jsxs("label", { className: "vc-profile-field", children: [_jsx("span", { children: _jsx(FieldHead, { title: tr('settings.vcProfiles.fieldId'), help: tr('settings.vcProfiles.idHelp') }) }), _jsx("input", { type: "text", value: profile.id, disabled: props.frozen || !profile.isNew, placeholder: "minutes", onChange: event => props.onIdChange(event.currentTarget.value) }), props.error(`profiles[${index}].id`) ? _jsx("em", { className: "vc-profile-err", children: props.error(`profiles[${index}].id`) }) : null] }), _jsxs("label", { className: "vc-profile-field", children: [_jsx("span", { children: _jsx(FieldHead, { title: tr('settings.vcProfiles.fieldLabel'), help: tr('settings.vcProfiles.labelHelp') }) }), _jsx("input", { type: "text", value: profile.label ?? '', disabled: props.frozen, onChange: event => props.onUpdate({ label: event.currentTarget.value || undefined }) }), props.error(`profiles[${index}].label`) ? _jsx("em", { className: "vc-profile-err", children: props.error(`profiles[${index}].label`) }) : null] }), _jsxs("div", { className: "vc-profile-field", children: [_jsx("span", { children: _jsx(FieldHead, { title: tr('settings.vcProfiles.fieldResponseMode'), help: tr('settings.vcProfiles.responseModeHelp') }) }), _jsx(DropdownMenu, { ariaLabel: tr('settings.vcProfiles.fieldResponseMode'), disabled: props.frozen, value: profile.responseMode, label: profile.responseMode === 'listener_thread' ? tr('settings.vcProfiles.responseListener') : tr('settings.vcProfiles.responseSilent'), options: [
489
508
  { value: 'silent', label: tr('settings.vcProfiles.responseSilent') },
490
509
  { value: 'listener_thread', label: tr('settings.vcProfiles.responseListener') },
491
510
  ], onChange: value => props.onUpdate({ responseMode: value }) }), props.error(`profiles[${index}].responseMode`) ? _jsx("em", { className: "vc-profile-err", children: props.error(`profiles[${index}].responseMode`) }) : null] }), _jsxs("div", { className: "vc-profile-field", children: [_jsx("span", { children: _jsx(FieldHead, { title: tr('settings.vcProfiles.fieldListenerPlacement'), help: tr('settings.vcProfiles.listenerPlacementHelp') }) }), _jsx(DropdownMenu, { ariaLabel: tr('settings.vcProfiles.fieldListenerPlacement'), disabled: props.frozen || profile.responseMode === 'silent', value: profile.listenerPlacement ?? 'auto', label: tr(`settings.vcProfiles.listenerPlacement.${profile.listenerPlacement ?? 'auto'}`), options: ['auto', 'chat', 'topic'].map(value => ({ value, label: tr(`settings.vcProfiles.listenerPlacement.${value}`) })), onChange: value => props.onUpdate({ listenerPlacement: value }) }), props.error(`profiles[${index}].listenerPlacement`) ? _jsx("em", { className: "vc-profile-err", children: props.error(`profiles[${index}].listenerPlacement`) }) : null] }), _jsxs("div", { className: "vc-profile-field", children: [_jsx("span", { children: _jsx(FieldHead, { title: tr('settings.vcProfiles.fieldPreset'), help: tr('settings.vcProfiles.presetHelp') }) }), _jsx(DropdownMenu, { ariaLabel: tr('settings.vcProfiles.fieldPreset'), disabled: props.frozen, value: profile.permissionPreset, label: dropdownLabel(props.presetOptions, profile.permissionPreset), options: props.presetOptions, onChange: value => props.onUpdate({ permissionPreset: value }) }), props.error(`profiles[${index}].permissionPreset`) ? _jsx("em", { className: "vc-profile-err", children: props.error(`profiles[${index}].permissionPreset`) }) : null] })] }), _jsxs("label", { className: "vc-profile-field vc-profile-instructions", children: [_jsxs("span", { children: [_jsx(FieldHead, { title: tr('settings.vcProfiles.fieldInstructions'), help: tr('settings.vcProfiles.instructionsHelp') }), _jsxs("em", { className: "vc-profile-count", children: [(profile.instructions ?? '').length, "/", INSTRUCTIONS_MAX] })] }), _jsx("textarea", { rows: 7, maxLength: INSTRUCTIONS_MAX, value: profile.instructions ?? '', disabled: props.frozen, placeholder: tr('settings.vcProfiles.instructionsPlaceholder'), onChange: event => props.onUpdate({ instructions: event.currentTarget.value || undefined }) }), props.error(`profiles[${index}].instructions`) ? _jsx("em", { className: "vc-profile-err", children: props.error(`profiles[${index}].instructions`) }) : null] }), _jsxs("div", { className: "vc-profile-field", children: [_jsx("span", { children: _jsx(FieldHead, { title: tr('settings.vcProfiles.fieldActivityTypes'), help: tr('settings.vcProfiles.activityHelp') }) }), _jsx("div", { className: "vc-profile-activity", children: ACTIVITY_TYPES.map(type => {