botmux 3.7.1 → 3.8.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 (622) hide show
  1. package/dist/.runtime-build-id +1 -1
  2. package/dist/adapters/backend/capabilities.d.ts +17 -0
  3. package/dist/adapters/backend/capabilities.d.ts.map +1 -0
  4. package/dist/adapters/backend/capabilities.js +22 -0
  5. package/dist/adapters/backend/capabilities.js.map +1 -0
  6. package/dist/adapters/backend/critical-control-key.d.ts +19 -0
  7. package/dist/adapters/backend/critical-control-key.d.ts.map +1 -0
  8. package/dist/adapters/backend/critical-control-key.js +34 -0
  9. package/dist/adapters/backend/critical-control-key.js.map +1 -0
  10. package/dist/adapters/backend/herdr-backend.d.ts +9 -0
  11. package/dist/adapters/backend/herdr-backend.d.ts.map +1 -1
  12. package/dist/adapters/backend/herdr-backend.js +23 -4
  13. package/dist/adapters/backend/herdr-backend.js.map +1 -1
  14. package/dist/adapters/backend/riff-backend.d.ts.map +1 -1
  15. package/dist/adapters/backend/riff-backend.js +3 -2
  16. package/dist/adapters/backend/riff-backend.js.map +1 -1
  17. package/dist/adapters/backend/session-backend-selector.d.ts +61 -6
  18. package/dist/adapters/backend/session-backend-selector.d.ts.map +1 -1
  19. package/dist/adapters/backend/session-backend-selector.js +173 -9
  20. package/dist/adapters/backend/session-backend-selector.js.map +1 -1
  21. package/dist/adapters/backend/tmux-backend.d.ts +10 -3
  22. package/dist/adapters/backend/tmux-backend.d.ts.map +1 -1
  23. package/dist/adapters/backend/tmux-backend.js +25 -8
  24. package/dist/adapters/backend/tmux-backend.js.map +1 -1
  25. package/dist/adapters/backend/tmux-pipe-backend.d.ts.map +1 -1
  26. package/dist/adapters/backend/tmux-pipe-backend.js +3 -2
  27. package/dist/adapters/backend/tmux-pipe-backend.js.map +1 -1
  28. package/dist/adapters/backend/types.d.ts +45 -4
  29. package/dist/adapters/backend/types.d.ts.map +1 -1
  30. package/dist/adapters/backend/types.js +11 -0
  31. package/dist/adapters/backend/types.js.map +1 -1
  32. package/dist/adapters/backend/zellij-backend.d.ts.map +1 -1
  33. package/dist/adapters/backend/zellij-backend.js +3 -2
  34. package/dist/adapters/backend/zellij-backend.js.map +1 -1
  35. package/dist/adapters/backend/zmx-backend.d.ts +286 -0
  36. package/dist/adapters/backend/zmx-backend.d.ts.map +1 -0
  37. package/dist/adapters/backend/zmx-backend.js +2396 -0
  38. package/dist/adapters/backend/zmx-backend.js.map +1 -0
  39. package/dist/adapters/cli/claude-code.d.ts.map +1 -1
  40. package/dist/adapters/cli/claude-code.js +3 -0
  41. package/dist/adapters/cli/claude-code.js.map +1 -1
  42. package/dist/adapters/cli/codex-app.d.ts.map +1 -1
  43. package/dist/adapters/cli/codex-app.js +5 -1
  44. package/dist/adapters/cli/codex-app.js.map +1 -1
  45. package/dist/adapters/cli/codex.d.ts.map +1 -1
  46. package/dist/adapters/cli/codex.js +26 -1
  47. package/dist/adapters/cli/codex.js.map +1 -1
  48. package/dist/adapters/cli/fs-policy.d.ts +79 -1
  49. package/dist/adapters/cli/fs-policy.d.ts.map +1 -1
  50. package/dist/adapters/cli/fs-policy.js +290 -13
  51. package/dist/adapters/cli/fs-policy.js.map +1 -1
  52. package/dist/adapters/cli/grok.d.ts.map +1 -1
  53. package/dist/adapters/cli/grok.js +4 -1
  54. package/dist/adapters/cli/grok.js.map +1 -1
  55. package/dist/adapters/cli/oh-my-pi.d.ts.map +1 -1
  56. package/dist/adapters/cli/oh-my-pi.js +5 -3
  57. package/dist/adapters/cli/oh-my-pi.js.map +1 -1
  58. package/dist/adapters/cli/shared-hints.d.ts +7 -4
  59. package/dist/adapters/cli/shared-hints.d.ts.map +1 -1
  60. package/dist/adapters/cli/shared-hints.js +52 -35
  61. package/dist/adapters/cli/shared-hints.js.map +1 -1
  62. package/dist/adapters/cli/strict-input-handle.d.ts +13 -0
  63. package/dist/adapters/cli/strict-input-handle.d.ts.map +1 -0
  64. package/dist/adapters/cli/strict-input-handle.js +39 -0
  65. package/dist/adapters/cli/strict-input-handle.js.map +1 -0
  66. package/dist/adapters/cli/traex.d.ts.map +1 -1
  67. package/dist/adapters/cli/traex.js +6 -4
  68. package/dist/adapters/cli/traex.js.map +1 -1
  69. package/dist/adapters/cli/types.d.ts +16 -0
  70. package/dist/adapters/cli/types.d.ts.map +1 -1
  71. package/dist/bot-registry.d.ts +137 -8
  72. package/dist/bot-registry.d.ts.map +1 -1
  73. package/dist/bot-registry.js +298 -12
  74. package/dist/bot-registry.js.map +1 -1
  75. package/dist/cli/session-list-liveness.d.ts +1 -1
  76. package/dist/cli/session-list-liveness.js +1 -1
  77. package/dist/cli/zmx-managed-attach.d.ts +41 -0
  78. package/dist/cli/zmx-managed-attach.d.ts.map +1 -0
  79. package/dist/cli/zmx-managed-attach.js +72 -0
  80. package/dist/cli/zmx-managed-attach.js.map +1 -0
  81. package/dist/cli.d.ts.map +1 -1
  82. package/dist/cli.js +780 -131
  83. package/dist/cli.js.map +1 -1
  84. package/dist/codex-app-runner.js +90 -2
  85. package/dist/codex-app-runner.js.map +1 -1
  86. package/dist/codex-rpc-engine.d.ts.map +1 -1
  87. package/dist/codex-rpc-engine.js +22 -6
  88. package/dist/codex-rpc-engine.js.map +1 -1
  89. package/dist/config.d.ts +5 -0
  90. package/dist/config.d.ts.map +1 -1
  91. package/dist/config.js +29 -1
  92. package/dist/config.js.map +1 -1
  93. package/dist/core/ask-broker.d.ts +22 -1
  94. package/dist/core/ask-broker.d.ts.map +1 -1
  95. package/dist/core/ask-broker.js +12 -5
  96. package/dist/core/ask-broker.js.map +1 -1
  97. package/dist/core/botmux-wrapper.d.ts +18 -0
  98. package/dist/core/botmux-wrapper.d.ts.map +1 -1
  99. package/dist/core/botmux-wrapper.js +25 -1
  100. package/dist/core/botmux-wrapper.js.map +1 -1
  101. package/dist/core/chat-rename.d.ts +27 -0
  102. package/dist/core/chat-rename.d.ts.map +1 -0
  103. package/dist/core/chat-rename.js +53 -0
  104. package/dist/core/chat-rename.js.map +1 -0
  105. package/dist/core/command-handler.d.ts.map +1 -1
  106. package/dist/core/command-handler.js +160 -12
  107. package/dist/core/command-handler.js.map +1 -1
  108. package/dist/core/cost-calculator.d.ts +25 -1
  109. package/dist/core/cost-calculator.d.ts.map +1 -1
  110. package/dist/core/cost-calculator.js +102 -4
  111. package/dist/core/cost-calculator.js.map +1 -1
  112. package/dist/core/dashboard-ipc-server.d.ts +16 -2
  113. package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
  114. package/dist/core/dashboard-ipc-server.js +611 -62
  115. package/dist/core/dashboard-ipc-server.js.map +1 -1
  116. package/dist/core/dashboard-rows.d.ts +22 -1
  117. package/dist/core/dashboard-rows.d.ts.map +1 -1
  118. package/dist/core/dashboard-rows.js +61 -0
  119. package/dist/core/dashboard-rows.js.map +1 -1
  120. package/dist/core/dashboard-url.d.ts +6 -0
  121. package/dist/core/dashboard-url.d.ts.map +1 -1
  122. package/dist/core/dashboard-url.js +11 -1
  123. package/dist/core/dashboard-url.js.map +1 -1
  124. package/dist/core/device-isolation-daemon.d.ts +28 -6
  125. package/dist/core/device-isolation-daemon.d.ts.map +1 -1
  126. package/dist/core/device-isolation-daemon.js +96 -13
  127. package/dist/core/device-isolation-daemon.js.map +1 -1
  128. package/dist/core/host-overload-alert.d.ts +75 -0
  129. package/dist/core/host-overload-alert.d.ts.map +1 -1
  130. package/dist/core/host-overload-alert.js +103 -0
  131. package/dist/core/host-overload-alert.js.map +1 -1
  132. package/dist/core/idle-worker-sweeper.js +1 -1
  133. package/dist/core/idle-worker-sweeper.js.map +1 -1
  134. package/dist/core/inflight-input-tracker.d.ts +3 -0
  135. package/dist/core/inflight-input-tracker.d.ts.map +1 -1
  136. package/dist/core/inflight-input-tracker.js +9 -0
  137. package/dist/core/inflight-input-tracker.js.map +1 -1
  138. package/dist/core/passthrough-commands.d.ts.map +1 -1
  139. package/dist/core/passthrough-commands.js +10 -0
  140. package/dist/core/passthrough-commands.js.map +1 -1
  141. package/dist/core/persistent-backend.d.ts +32 -4
  142. package/dist/core/persistent-backend.d.ts.map +1 -1
  143. package/dist/core/persistent-backend.js +75 -6
  144. package/dist/core/persistent-backend.js.map +1 -1
  145. package/dist/core/plugins/mcp/gateway.js +2 -2
  146. package/dist/core/plugins/mcp/gateway.js.map +1 -1
  147. package/dist/core/plugins/runtime.d.ts +3 -0
  148. package/dist/core/plugins/runtime.d.ts.map +1 -1
  149. package/dist/core/plugins/runtime.js.map +1 -1
  150. package/dist/core/plugins/service-manager.d.ts +4 -1
  151. package/dist/core/plugins/service-manager.d.ts.map +1 -1
  152. package/dist/core/plugins/service-manager.js +11 -6
  153. package/dist/core/plugins/service-manager.js.map +1 -1
  154. package/dist/core/role-library.d.ts +48 -1
  155. package/dist/core/role-library.d.ts.map +1 -1
  156. package/dist/core/role-library.js +111 -3
  157. package/dist/core/role-library.js.map +1 -1
  158. package/dist/core/role-resolver.d.ts +14 -2
  159. package/dist/core/role-resolver.d.ts.map +1 -1
  160. package/dist/core/role-resolver.js +47 -4
  161. package/dist/core/role-resolver.js.map +1 -1
  162. package/dist/core/session-activity.d.ts +14 -0
  163. package/dist/core/session-activity.d.ts.map +1 -1
  164. package/dist/core/session-activity.js +46 -1
  165. package/dist/core/session-activity.js.map +1 -1
  166. package/dist/core/session-board.d.ts +5 -2
  167. package/dist/core/session-board.d.ts.map +1 -1
  168. package/dist/core/session-board.js +5 -2
  169. package/dist/core/session-board.js.map +1 -1
  170. package/dist/core/session-liveness.d.ts +6 -5
  171. package/dist/core/session-liveness.d.ts.map +1 -1
  172. package/dist/core/session-liveness.js +34 -13
  173. package/dist/core/session-liveness.js.map +1 -1
  174. package/dist/core/session-manager.d.ts +3 -2
  175. package/dist/core/session-manager.d.ts.map +1 -1
  176. package/dist/core/session-manager.js +397 -103
  177. package/dist/core/session-manager.js.map +1 -1
  178. package/dist/core/session-marker.d.ts +11 -2
  179. package/dist/core/session-marker.d.ts.map +1 -1
  180. package/dist/core/session-marker.js +50 -11
  181. package/dist/core/session-marker.js.map +1 -1
  182. package/dist/core/session-message-preview.d.ts +20 -0
  183. package/dist/core/session-message-preview.d.ts.map +1 -0
  184. package/dist/core/session-message-preview.js +188 -0
  185. package/dist/core/session-message-preview.js.map +1 -0
  186. package/dist/core/session-title.d.ts +5 -1
  187. package/dist/core/session-title.d.ts.map +1 -1
  188. package/dist/core/session-title.js +20 -3
  189. package/dist/core/session-title.js.map +1 -1
  190. package/dist/core/startup-commands.d.ts +1 -1
  191. package/dist/core/startup-commands.js +1 -1
  192. package/dist/core/terminal-url.d.ts.map +1 -1
  193. package/dist/core/terminal-url.js +3 -2
  194. package/dist/core/terminal-url.js.map +1 -1
  195. package/dist/core/trigger-session.d.ts.map +1 -1
  196. package/dist/core/trigger-session.js +75 -12
  197. package/dist/core/trigger-session.js.map +1 -1
  198. package/dist/core/types.d.ts +35 -0
  199. package/dist/core/types.d.ts.map +1 -1
  200. package/dist/core/types.js +23 -0
  201. package/dist/core/types.js.map +1 -1
  202. package/dist/core/worker-ipc.d.ts +11 -0
  203. package/dist/core/worker-ipc.d.ts.map +1 -0
  204. package/dist/core/worker-ipc.js +26 -0
  205. package/dist/core/worker-ipc.js.map +1 -0
  206. package/dist/core/worker-pool.d.ts +179 -29
  207. package/dist/core/worker-pool.d.ts.map +1 -1
  208. package/dist/core/worker-pool.js +2118 -331
  209. package/dist/core/worker-pool.js.map +1 -1
  210. package/dist/daemon.d.ts +132 -3
  211. package/dist/daemon.d.ts.map +1 -1
  212. package/dist/daemon.js +1327 -449
  213. package/dist/daemon.js.map +1 -1
  214. package/dist/dashboard/auth.d.ts +2 -0
  215. package/dist/dashboard/auth.d.ts.map +1 -1
  216. package/dist/dashboard/auth.js +9 -0
  217. package/dist/dashboard/auth.js.map +1 -1
  218. package/dist/dashboard/bot-payload.d.ts +4 -0
  219. package/dist/dashboard/bot-payload.d.ts.map +1 -1
  220. package/dist/dashboard/bot-payload.js +5 -0
  221. package/dist/dashboard/bot-payload.js.map +1 -1
  222. package/dist/dashboard/federation-api.d.ts.map +1 -1
  223. package/dist/dashboard/federation-api.js +4 -0
  224. package/dist/dashboard/federation-api.js.map +1 -1
  225. package/dist/dashboard/federation-spoke-api.d.ts.map +1 -1
  226. package/dist/dashboard/federation-spoke-api.js +32 -5
  227. package/dist/dashboard/federation-spoke-api.js.map +1 -1
  228. package/dist/dashboard/public-redact.d.ts +8 -2
  229. package/dist/dashboard/public-redact.d.ts.map +1 -1
  230. package/dist/dashboard/public-redact.js +34 -7
  231. package/dist/dashboard/public-redact.js.map +1 -1
  232. package/dist/dashboard/session-card-model.d.ts.map +1 -1
  233. package/dist/dashboard/session-card-model.js +10 -2
  234. package/dist/dashboard/session-card-model.js.map +1 -1
  235. package/dist/dashboard/settings-write-applier.d.ts +35 -1
  236. package/dist/dashboard/settings-write-applier.d.ts.map +1 -1
  237. package/dist/dashboard/settings-write-applier.js +88 -1
  238. package/dist/dashboard/settings-write-applier.js.map +1 -1
  239. package/dist/dashboard/web/app.d.ts.map +1 -1
  240. package/dist/dashboard/web/app.js +0 -1
  241. package/dist/dashboard/web/app.js.map +1 -1
  242. package/dist/dashboard/web/bot-defaults-page.d.ts +15 -0
  243. package/dist/dashboard/web/bot-defaults-page.d.ts.map +1 -1
  244. package/dist/dashboard/web/bot-defaults-page.js +212 -58
  245. package/dist/dashboard/web/bot-defaults-page.js.map +1 -1
  246. package/dist/dashboard/web/bot-defaults.d.ts +3 -0
  247. package/dist/dashboard/web/bot-defaults.d.ts.map +1 -1
  248. package/dist/dashboard/web/bot-defaults.js.map +1 -1
  249. package/dist/dashboard/web/bot-onboarding.d.ts +2 -1
  250. package/dist/dashboard/web/bot-onboarding.d.ts.map +1 -1
  251. package/dist/dashboard/web/bot-onboarding.js.map +1 -1
  252. package/dist/dashboard/web/clipboard.d.ts +2 -0
  253. package/dist/dashboard/web/clipboard.d.ts.map +1 -0
  254. package/dist/dashboard/web/clipboard.js +42 -0
  255. package/dist/dashboard/web/clipboard.js.map +1 -0
  256. package/dist/dashboard/web/connectors-page.d.ts.map +1 -1
  257. package/dist/dashboard/web/connectors-page.js +12 -8
  258. package/dist/dashboard/web/connectors-page.js.map +1 -1
  259. package/dist/dashboard/web/dashboard-components.d.ts +17 -16
  260. package/dist/dashboard/web/dashboard-components.d.ts.map +1 -1
  261. package/dist/dashboard/web/dashboard-components.js.map +1 -1
  262. package/dist/dashboard/web/groups-page.d.ts.map +1 -1
  263. package/dist/dashboard/web/groups-page.js +7 -3
  264. package/dist/dashboard/web/groups-page.js.map +1 -1
  265. package/dist/dashboard/web/i18n.d.ts.map +1 -1
  266. package/dist/dashboard/web/i18n.js +205 -12
  267. package/dist/dashboard/web/i18n.js.map +1 -1
  268. package/dist/dashboard/web/icon-tooltip.d.ts.map +1 -1
  269. package/dist/dashboard/web/icon-tooltip.js +16 -1
  270. package/dist/dashboard/web/icon-tooltip.js.map +1 -1
  271. package/dist/dashboard/web/listener-filters.d.ts +23 -0
  272. package/dist/dashboard/web/listener-filters.d.ts.map +1 -0
  273. package/dist/dashboard/web/listener-filters.js +36 -0
  274. package/dist/dashboard/web/listener-filters.js.map +1 -0
  275. package/dist/dashboard/web/overview-page.d.ts.map +1 -1
  276. package/dist/dashboard/web/overview-page.js.map +1 -1
  277. package/dist/dashboard/web/plugin-page.d.ts.map +1 -1
  278. package/dist/dashboard/web/plugin-page.js.map +1 -1
  279. package/dist/dashboard/web/preview-markdown.d.ts +5 -0
  280. package/dist/dashboard/web/preview-markdown.d.ts.map +1 -0
  281. package/dist/dashboard/web/preview-markdown.js +52 -0
  282. package/dist/dashboard/web/preview-markdown.js.map +1 -0
  283. package/dist/dashboard/web/roles-page.d.ts.map +1 -1
  284. package/dist/dashboard/web/roles-page.js +535 -10
  285. package/dist/dashboard/web/roles-page.js.map +1 -1
  286. package/dist/dashboard/web/roles.d.ts +77 -0
  287. package/dist/dashboard/web/roles.d.ts.map +1 -1
  288. package/dist/dashboard/web/roles.js +98 -0
  289. package/dist/dashboard/web/roles.js.map +1 -1
  290. package/dist/dashboard/web/session-terminal.d.ts.map +1 -1
  291. package/dist/dashboard/web/session-terminal.js +6 -4
  292. package/dist/dashboard/web/session-terminal.js.map +1 -1
  293. package/dist/dashboard/web/sessions-kanban.d.ts +4 -1
  294. package/dist/dashboard/web/sessions-kanban.d.ts.map +1 -1
  295. package/dist/dashboard/web/sessions-kanban.js +1 -1
  296. package/dist/dashboard/web/sessions-kanban.js.map +1 -1
  297. package/dist/dashboard/web/sessions-page.d.ts +3 -2
  298. package/dist/dashboard/web/sessions-page.d.ts.map +1 -1
  299. package/dist/dashboard/web/sessions-page.js +163 -28
  300. package/dist/dashboard/web/sessions-page.js.map +1 -1
  301. package/dist/dashboard/web/sessions.d.ts +25 -0
  302. package/dist/dashboard/web/sessions.d.ts.map +1 -1
  303. package/dist/dashboard/web/sessions.js +58 -7
  304. package/dist/dashboard/web/sessions.js.map +1 -1
  305. package/dist/dashboard/web/settings-page.d.ts +28 -3
  306. package/dist/dashboard/web/settings-page.d.ts.map +1 -1
  307. package/dist/dashboard/web/settings-page.js +61 -1
  308. package/dist/dashboard/web/settings-page.js.map +1 -1
  309. package/dist/dashboard/web/skills-page.d.ts +6 -5
  310. package/dist/dashboard/web/skills-page.d.ts.map +1 -1
  311. package/dist/dashboard/web/skills-page.js +2 -0
  312. package/dist/dashboard/web/skills-page.js.map +1 -1
  313. package/dist/dashboard/web/v3-components.d.ts +3 -2
  314. package/dist/dashboard/web/v3-components.d.ts.map +1 -1
  315. package/dist/dashboard/web/v3-components.js.map +1 -1
  316. package/dist/dashboard/web/vc-consumer-profiles-section.d.ts +12 -2
  317. package/dist/dashboard/web/vc-consumer-profiles-section.d.ts.map +1 -1
  318. package/dist/dashboard/web/vc-consumer-profiles-section.js +0 -9
  319. package/dist/dashboard/web/vc-consumer-profiles-section.js.map +1 -1
  320. package/dist/dashboard/web/webhook-logs-page.d.ts +2 -1
  321. package/dist/dashboard/web/webhook-logs-page.d.ts.map +1 -1
  322. package/dist/dashboard/web/webhook-logs-page.js +4 -1
  323. package/dist/dashboard/web/webhook-logs-page.js.map +1 -1
  324. package/dist/dashboard-web/app.js +1 -1
  325. package/dist/dashboard-web/chunks/bot-defaults-page-FAPIMQV3.js +10 -0
  326. package/dist/dashboard-web/chunks/{chunk-QFMH6ITB.js → chunk-5CJMHTT4.js} +1 -1
  327. package/dist/dashboard-web/chunks/{chunk-KQB42ML5.js → chunk-DLZK52JU.js} +14 -12
  328. package/dist/dashboard-web/chunks/chunk-FDZ7WOBW.js +16 -0
  329. package/dist/dashboard-web/chunks/{chunk-3QAUJXAS.js → chunk-GTAJV5YC.js} +1 -1
  330. package/dist/dashboard-web/chunks/{chunk-FNPGOZMX.js → chunk-IHNG6KE6.js} +1 -1
  331. package/dist/dashboard-web/chunks/{chunk-FLGXZJTD.js → chunk-VA6QWSGQ.js} +1 -1
  332. package/dist/dashboard-web/chunks/chunk-XJ7BGPJH.js +1 -0
  333. package/dist/dashboard-web/chunks/chunk-ZJVTGU5X.js +1 -0
  334. package/dist/dashboard-web/chunks/connectors-page-LKWRT3GS.js +1 -0
  335. package/dist/dashboard-web/chunks/groups-page-V6654ICQ.js +8 -0
  336. package/dist/dashboard-web/chunks/insights-page-237RMFQ5.js +7 -0
  337. package/dist/dashboard-web/chunks/{monitor-room-7IVIS75W.js → monitor-room-OO5Y4FRQ.js} +1 -1
  338. package/dist/dashboard-web/chunks/{monitoring-page-5SSJRQZF.js → monitoring-page-OUEITM5P.js} +1 -1
  339. package/dist/dashboard-web/chunks/{office-page-EOND3L5D.js → office-page-4KNAHQ4Q.js} +1 -1
  340. package/dist/dashboard-web/chunks/{overview-page-NISBVBBJ.js → overview-page-QDP4YK2S.js} +1 -1
  341. package/dist/dashboard-web/chunks/{plugin-page-JXC5F5YV.js → plugin-page-VEGTCEAS.js} +1 -1
  342. package/dist/dashboard-web/chunks/roles-page-PGXNZZNP.js +1 -0
  343. package/dist/dashboard-web/chunks/{schedules-page-AVOOKLUH.js → schedules-page-BJNC5TID.js} +1 -1
  344. package/dist/dashboard-web/chunks/sessions-page-M2ZYYCMO.js +6 -0
  345. package/dist/dashboard-web/chunks/settings-page-IJFZKUUW.js +2 -0
  346. package/dist/dashboard-web/chunks/{skills-page-5MW54PCC.js → skills-page-YRAIRZOQ.js} +3 -3
  347. package/dist/dashboard-web/chunks/{team-federation-page-2SNIMVXI.js → team-federation-page-DEU27GRU.js} +1 -1
  348. package/dist/dashboard-web/chunks/{v3-page-W6SBXXQC.js → v3-page-6KHEW2YL.js} +5 -5
  349. package/dist/dashboard-web/chunks/{whiteboards-page-STC54KTP.js → whiteboards-page-VDECAALH.js} +1 -1
  350. package/dist/dashboard-web/style.css +12545 -11432
  351. package/dist/dashboard.js +215 -36
  352. package/dist/dashboard.js.map +1 -1
  353. package/dist/global-config.d.ts +41 -2
  354. package/dist/global-config.d.ts.map +1 -1
  355. package/dist/global-config.js +47 -0
  356. package/dist/global-config.js.map +1 -1
  357. package/dist/i18n/en.d.ts.map +1 -1
  358. package/dist/i18n/en.js +71 -19
  359. package/dist/i18n/en.js.map +1 -1
  360. package/dist/i18n/zh.d.ts.map +1 -1
  361. package/dist/i18n/zh.js +71 -19
  362. package/dist/i18n/zh.js.map +1 -1
  363. package/dist/im/lark/callback-button-marker.d.ts +34 -0
  364. package/dist/im/lark/callback-button-marker.d.ts.map +1 -0
  365. package/dist/im/lark/callback-button-marker.js +99 -0
  366. package/dist/im/lark/callback-button-marker.js.map +1 -0
  367. package/dist/im/lark/card-builder.d.ts +46 -10
  368. package/dist/im/lark/card-builder.d.ts.map +1 -1
  369. package/dist/im/lark/card-builder.js +299 -78
  370. package/dist/im/lark/card-builder.js.map +1 -1
  371. package/dist/im/lark/card-handler.d.ts +3 -4
  372. package/dist/im/lark/card-handler.d.ts.map +1 -1
  373. package/dist/im/lark/card-handler.js +380 -148
  374. package/dist/im/lark/card-handler.js.map +1 -1
  375. package/dist/im/lark/client.d.ts +24 -1
  376. package/dist/im/lark/client.d.ts.map +1 -1
  377. package/dist/im/lark/client.js +101 -8
  378. package/dist/im/lark/client.js.map +1 -1
  379. package/dist/im/lark/doc-comment.d.ts.map +1 -1
  380. package/dist/im/lark/doc-comment.js +6 -1
  381. package/dist/im/lark/doc-comment.js.map +1 -1
  382. package/dist/im/lark/event-dispatcher.d.ts +115 -3
  383. package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
  384. package/dist/im/lark/event-dispatcher.js +534 -147
  385. package/dist/im/lark/event-dispatcher.js.map +1 -1
  386. package/dist/im/lark/grant-command.d.ts +16 -12
  387. package/dist/im/lark/grant-command.d.ts.map +1 -1
  388. package/dist/im/lark/grant-command.js +48 -151
  389. package/dist/im/lark/grant-command.js.map +1 -1
  390. package/dist/im/lark/grant-pending.d.ts +12 -4
  391. package/dist/im/lark/grant-pending.d.ts.map +1 -1
  392. package/dist/im/lark/grant-pending.js +31 -8
  393. package/dist/im/lark/grant-pending.js.map +1 -1
  394. package/dist/im/lark/invite-command.d.ts +20 -0
  395. package/dist/im/lark/invite-command.d.ts.map +1 -0
  396. package/dist/im/lark/invite-command.js +239 -0
  397. package/dist/im/lark/invite-command.js.map +1 -0
  398. package/dist/im/lark/md-card.d.ts +66 -4
  399. package/dist/im/lark/md-card.d.ts.map +1 -1
  400. package/dist/im/lark/md-card.js +201 -31
  401. package/dist/im/lark/md-card.js.map +1 -1
  402. package/dist/im/lark/mention-targets.d.ts +43 -0
  403. package/dist/im/lark/mention-targets.d.ts.map +1 -0
  404. package/dist/im/lark/mention-targets.js +190 -0
  405. package/dist/im/lark/mention-targets.js.map +1 -0
  406. package/dist/im/lark/message-parser.d.ts +31 -0
  407. package/dist/im/lark/message-parser.d.ts.map +1 -1
  408. package/dist/im/lark/message-parser.js +305 -32
  409. package/dist/im/lark/message-parser.js.map +1 -1
  410. package/dist/im/lark/reply-card-footer-signature.d.ts +7 -0
  411. package/dist/im/lark/reply-card-footer-signature.d.ts.map +1 -0
  412. package/dist/im/lark/reply-card-footer-signature.js +7 -0
  413. package/dist/im/lark/reply-card-footer-signature.js.map +1 -0
  414. package/dist/im/lark/sessions-card.d.ts.map +1 -1
  415. package/dist/im/lark/sessions-card.js +4 -1
  416. package/dist/im/lark/sessions-card.js.map +1 -1
  417. package/dist/im/lark/substitute-command.d.ts.map +1 -1
  418. package/dist/im/lark/substitute-command.js +8 -0
  419. package/dist/im/lark/substitute-command.js.map +1 -1
  420. package/dist/im/lark/topic-root-context.d.ts +35 -0
  421. package/dist/im/lark/topic-root-context.d.ts.map +1 -0
  422. package/dist/im/lark/topic-root-context.js +37 -0
  423. package/dist/im/lark/topic-root-context.js.map +1 -0
  424. package/dist/im/lark/v3-blocked-card.d.ts.map +1 -1
  425. package/dist/im/lark/v3-blocked-card.js +2 -1
  426. package/dist/im/lark/v3-blocked-card.js.map +1 -1
  427. package/dist/im/lark/v3-gate-card.d.ts.map +1 -1
  428. package/dist/im/lark/v3-gate-card.js +2 -1
  429. package/dist/im/lark/v3-gate-card.js.map +1 -1
  430. package/dist/im/lark/v3-loop-grant-card.d.ts.map +1 -1
  431. package/dist/im/lark/v3-loop-grant-card.js +2 -1
  432. package/dist/im/lark/v3-loop-grant-card.js.map +1 -1
  433. package/dist/im/lark/v3-progress-card.d.ts.map +1 -1
  434. package/dist/im/lark/v3-progress-card.js +2 -1
  435. package/dist/im/lark/v3-progress-card.js.map +1 -1
  436. package/dist/im/lark/v3-revisit-grant-card.d.ts.map +1 -1
  437. package/dist/im/lark/v3-revisit-grant-card.js +2 -1
  438. package/dist/im/lark/v3-revisit-grant-card.js.map +1 -1
  439. package/dist/index-core-only.d.ts +3 -0
  440. package/dist/index-core-only.d.ts.map +1 -0
  441. package/dist/index-core-only.js +107 -0
  442. package/dist/index-core-only.js.map +1 -0
  443. package/dist/services/async-trigger-state.d.ts +8 -0
  444. package/dist/services/async-trigger-state.d.ts.map +1 -1
  445. package/dist/services/async-trigger-state.js +3 -2
  446. package/dist/services/async-trigger-state.js.map +1 -1
  447. package/dist/services/async-trigger-store.d.ts +10 -2
  448. package/dist/services/async-trigger-store.d.ts.map +1 -1
  449. package/dist/services/async-trigger-store.js +3 -2
  450. package/dist/services/async-trigger-store.js.map +1 -1
  451. package/dist/services/backend-availability.d.ts +3 -1
  452. package/dist/services/backend-availability.d.ts.map +1 -1
  453. package/dist/services/backend-availability.js +14 -1
  454. package/dist/services/backend-availability.js.map +1 -1
  455. package/dist/services/backend-type-store.d.ts.map +1 -1
  456. package/dist/services/backend-type-store.js +1 -1
  457. package/dist/services/backend-type-store.js.map +1 -1
  458. package/dist/services/bot-config-store.d.ts.map +1 -1
  459. package/dist/services/bot-config-store.js +2 -1
  460. package/dist/services/bot-config-store.js.map +1 -1
  461. package/dist/services/bridge-fallback-gate.d.ts +14 -1
  462. package/dist/services/bridge-fallback-gate.d.ts.map +1 -1
  463. package/dist/services/bridge-fallback-gate.js +65 -1
  464. package/dist/services/bridge-fallback-gate.js.map +1 -1
  465. package/dist/services/card-prefs-store.d.ts +7 -2
  466. package/dist/services/card-prefs-store.d.ts.map +1 -1
  467. package/dist/services/card-prefs-store.js +30 -4
  468. package/dist/services/card-prefs-store.js.map +1 -1
  469. package/dist/services/codex-app-runner-protocol.d.ts +9 -0
  470. package/dist/services/codex-app-runner-protocol.d.ts.map +1 -1
  471. package/dist/services/codex-app-runner-protocol.js +17 -0
  472. package/dist/services/codex-app-runner-protocol.js.map +1 -1
  473. package/dist/services/codex-app-token-usage.d.ts +93 -0
  474. package/dist/services/codex-app-token-usage.d.ts.map +1 -0
  475. package/dist/services/codex-app-token-usage.js +190 -0
  476. package/dist/services/codex-app-token-usage.js.map +1 -0
  477. package/dist/services/codex-transcript.d.ts +6 -1
  478. package/dist/services/codex-transcript.d.ts.map +1 -1
  479. package/dist/services/codex-transcript.js +103 -32
  480. package/dist/services/codex-transcript.js.map +1 -1
  481. package/dist/services/federation-roster.d.ts +4 -0
  482. package/dist/services/federation-roster.d.ts.map +1 -1
  483. package/dist/services/federation-roster.js +3 -0
  484. package/dist/services/federation-roster.js.map +1 -1
  485. package/dist/services/federation-store.d.ts +6 -0
  486. package/dist/services/federation-store.d.ts.map +1 -1
  487. package/dist/services/federation-store.js.map +1 -1
  488. package/dist/services/grant-policy.d.ts +13 -0
  489. package/dist/services/grant-policy.d.ts.map +1 -0
  490. package/dist/services/grant-policy.js +40 -0
  491. package/dist/services/grant-policy.js.map +1 -0
  492. package/dist/services/grant-store.d.ts +24 -3
  493. package/dist/services/grant-store.d.ts.map +1 -1
  494. package/dist/services/grant-store.js +196 -12
  495. package/dist/services/grant-store.js.map +1 -1
  496. package/dist/services/groups-store.d.ts +36 -0
  497. package/dist/services/groups-store.d.ts.map +1 -1
  498. package/dist/services/groups-store.js +123 -1
  499. package/dist/services/groups-store.js.map +1 -1
  500. package/dist/services/jsonl-cursor.d.ts.map +1 -1
  501. package/dist/services/jsonl-cursor.js +8 -2
  502. package/dist/services/jsonl-cursor.js.map +1 -1
  503. package/dist/services/local-cli-opener.d.ts.map +1 -1
  504. package/dist/services/local-cli-opener.js +32 -0
  505. package/dist/services/local-cli-opener.js.map +1 -1
  506. package/dist/services/message-listener-run-preview-store.d.ts +43 -0
  507. package/dist/services/message-listener-run-preview-store.d.ts.map +1 -0
  508. package/dist/services/message-listener-run-preview-store.js +152 -0
  509. package/dist/services/message-listener-run-preview-store.js.map +1 -0
  510. package/dist/services/message-listener-store.d.ts +26 -0
  511. package/dist/services/message-listener-store.d.ts.map +1 -0
  512. package/dist/services/message-listener-store.js +138 -0
  513. package/dist/services/message-listener-store.js.map +1 -0
  514. package/dist/services/message-listener.d.ts +112 -0
  515. package/dist/services/message-listener.d.ts.map +1 -0
  516. package/dist/services/message-listener.js +391 -0
  517. package/dist/services/message-listener.js.map +1 -0
  518. package/dist/services/overload-alert-migration.d.ts +15 -0
  519. package/dist/services/overload-alert-migration.d.ts.map +1 -0
  520. package/dist/services/overload-alert-migration.js +115 -0
  521. package/dist/services/overload-alert-migration.js.map +1 -0
  522. package/dist/services/send-policy.d.ts +38 -0
  523. package/dist/services/send-policy.d.ts.map +1 -1
  524. package/dist/services/send-policy.js +34 -0
  525. package/dist/services/send-policy.js.map +1 -1
  526. package/dist/services/session-store.d.ts +12 -1
  527. package/dist/services/session-store.d.ts.map +1 -1
  528. package/dist/services/session-store.js +44 -2
  529. package/dist/services/session-store.js.map +1 -1
  530. package/dist/services/skill-registry-store.d.ts.map +1 -1
  531. package/dist/services/skill-registry-store.js +87 -12
  532. package/dist/services/skill-registry-store.js.map +1 -1
  533. package/dist/services/substitute-mode-normalize.d.ts +3 -0
  534. package/dist/services/substitute-mode-normalize.d.ts.map +1 -1
  535. package/dist/services/substitute-mode-normalize.js +8 -0
  536. package/dist/services/substitute-mode-normalize.js.map +1 -1
  537. package/dist/services/substitute-mode-store.d.ts.map +1 -1
  538. package/dist/services/substitute-mode-store.js +8 -1
  539. package/dist/services/substitute-mode-store.js.map +1 -1
  540. package/dist/services/transcript-resolver.d.ts +6 -1
  541. package/dist/services/transcript-resolver.d.ts.map +1 -1
  542. package/dist/services/transcript-resolver.js +145 -29
  543. package/dist/services/transcript-resolver.js.map +1 -1
  544. package/dist/services/trigger-types.d.ts +16 -0
  545. package/dist/services/trigger-types.d.ts.map +1 -1
  546. package/dist/services/trigger-types.js +6 -0
  547. package/dist/services/trigger-types.js.map +1 -1
  548. package/dist/setup/bot-config-editor.js +2 -2
  549. package/dist/setup/bot-config-editor.js.map +1 -1
  550. package/dist/setup/ensure-zmx.d.ts +31 -0
  551. package/dist/setup/ensure-zmx.d.ts.map +1 -0
  552. package/dist/setup/ensure-zmx.js +161 -0
  553. package/dist/setup/ensure-zmx.js.map +1 -0
  554. package/dist/setup/index.d.ts +1 -1
  555. package/dist/setup/index.js +1 -1
  556. package/dist/setup/open-platform-automation.d.ts +9 -0
  557. package/dist/setup/open-platform-automation.d.ts.map +1 -1
  558. package/dist/setup/open-platform-automation.js +15 -2
  559. package/dist/setup/open-platform-automation.js.map +1 -1
  560. package/dist/setup/setup-args.d.ts +1 -1
  561. package/dist/setup/setup-args.d.ts.map +1 -1
  562. package/dist/setup/setup-args.js +1 -1
  563. package/dist/skills/definitions.d.ts.map +1 -1
  564. package/dist/skills/definitions.js +32 -0
  565. package/dist/skills/definitions.js.map +1 -1
  566. package/dist/skills/injection-mode.d.ts +6 -2
  567. package/dist/skills/injection-mode.d.ts.map +1 -1
  568. package/dist/skills/injection-mode.js +10 -5
  569. package/dist/skills/injection-mode.js.map +1 -1
  570. package/dist/types.d.ts +79 -3
  571. package/dist/types.d.ts.map +1 -1
  572. package/dist/utils/child-env.d.ts +1 -1
  573. package/dist/utils/child-env.d.ts.map +1 -1
  574. package/dist/utils/child-env.js +4 -0
  575. package/dist/utils/child-env.js.map +1 -1
  576. package/dist/utils/effort-confirm-dialog.d.ts +40 -0
  577. package/dist/utils/effort-confirm-dialog.d.ts.map +1 -0
  578. package/dist/utils/effort-confirm-dialog.js +74 -0
  579. package/dist/utils/effort-confirm-dialog.js.map +1 -0
  580. package/dist/utils/pending-input-queue.d.ts +56 -0
  581. package/dist/utils/pending-input-queue.d.ts.map +1 -1
  582. package/dist/utils/pending-input-queue.js +80 -0
  583. package/dist/utils/pending-input-queue.js.map +1 -1
  584. package/dist/utils/render-dimensions.d.ts +8 -0
  585. package/dist/utils/render-dimensions.d.ts.map +1 -1
  586. package/dist/utils/render-dimensions.js +10 -0
  587. package/dist/utils/render-dimensions.js.map +1 -1
  588. package/dist/utils/stuck-key-guard.d.ts +3 -2
  589. package/dist/utils/stuck-key-guard.d.ts.map +1 -1
  590. package/dist/utils/stuck-key-guard.js +3 -3
  591. package/dist/utils/stuck-key-guard.js.map +1 -1
  592. package/dist/utils/terminal-renderer.d.ts +6 -0
  593. package/dist/utils/terminal-renderer.d.ts.map +1 -1
  594. package/dist/utils/terminal-renderer.js +15 -0
  595. package/dist/utils/terminal-renderer.js.map +1 -1
  596. package/dist/utils/tui-input-delivery.d.ts +32 -0
  597. package/dist/utils/tui-input-delivery.d.ts.map +1 -0
  598. package/dist/utils/tui-input-delivery.js +53 -0
  599. package/dist/utils/tui-input-delivery.js.map +1 -0
  600. package/dist/utils/xml.d.ts +19 -0
  601. package/dist/utils/xml.d.ts.map +1 -0
  602. package/dist/utils/xml.js +26 -0
  603. package/dist/utils/xml.js.map +1 -0
  604. package/dist/worker.js +1852 -374
  605. package/dist/worker.js.map +1 -1
  606. package/dist/workflows/definition.d.ts +8 -8
  607. package/dist/workflows/events/payloads.d.ts +8 -8
  608. package/dist/workflows/events/schema.d.ts +160 -160
  609. package/dist/workflows/v3/session-relay-client.js +1 -1
  610. package/dist/workflows/v3/session-relay-client.js.map +1 -1
  611. package/dist/workflows/v3/worker-fence.d.ts.map +1 -1
  612. package/dist/workflows/v3/worker-fence.js +15 -10
  613. package/dist/workflows/v3/worker-fence.js.map +1 -1
  614. package/package.json +1 -1
  615. package/dist/dashboard-web/chunks/bot-defaults-page-UKA7K4JV.js +0 -10
  616. package/dist/dashboard-web/chunks/chunk-DFLNXQNT.js +0 -1
  617. package/dist/dashboard-web/chunks/connectors-page-A77YAB5Y.js +0 -1
  618. package/dist/dashboard-web/chunks/groups-page-RUZNVXQB.js +0 -8
  619. package/dist/dashboard-web/chunks/insights-page-RF7U7RTA.js +0 -22
  620. package/dist/dashboard-web/chunks/roles-page-BUMKD7Y4.js +0 -1
  621. package/dist/dashboard-web/chunks/sessions-page-6HLSEAB7.js +0 -2
  622. package/dist/dashboard-web/chunks/settings-page-MJDZHQ4X.js +0 -2
@@ -5,8 +5,141 @@ import { agentSelectionKey, cliIdOf, createRefreshGate, displayCliId, fallbackCl
5
5
  import { mountReactPage } from './react-mount.js';
6
6
  import { useT } from './react-hooks.js';
7
7
  import { store } from './store.js';
8
- import { CreateActionButton, DropdownMenu, Html, InfoTip as BaseInfoTip, LoadingState, RefreshIconButton, dropdownLabel, } from './dashboard-components.js';
8
+ import { CreateActionButton, DropdownMenu, Html, InfoTip as BaseInfoTip, LoadingState, OverflowText, RefreshIconButton, dropdownLabel, } from './dashboard-components.js';
9
9
  import { botAvatarHtml, loadNameMaps, overrideBotAvatar, ui } from './ui.js';
10
+ export const BOT_DEFAULTS_TABS = [
11
+ 'common',
12
+ 'sessions',
13
+ 'security',
14
+ 'cards',
15
+ 'advanced',
16
+ ];
17
+ export function BotDefaultsTabs(props) {
18
+ const tr = useT();
19
+ const tabRefs = useRef([]);
20
+ const labels = {
21
+ common: tr('botDefaults.tabCommon'),
22
+ sessions: tr('botDefaults.tabSessions'),
23
+ security: tr('botDefaults.tabSecurity'),
24
+ cards: tr('botDefaults.tabCards'),
25
+ advanced: tr('botDefaults.tabAdvanced'),
26
+ };
27
+ function selectAt(index) {
28
+ const nextIndex = (index + BOT_DEFAULTS_TABS.length) % BOT_DEFAULTS_TABS.length;
29
+ const next = BOT_DEFAULTS_TABS[nextIndex];
30
+ props.onChange(next);
31
+ tabRefs.current[nextIndex]?.focus();
32
+ }
33
+ return (_jsxs("nav", { className: "bd-tab-bar", "aria-label": tr('botDefaults.tabNavigation'), children: [_jsx("div", { className: "bd-tabs", role: "tablist", children: BOT_DEFAULTS_TABS.map((tab, index) => (_jsx("button", { ref: node => { tabRefs.current[index] = node; }, id: `bd-tab-${tab}`, type: "button", role: "tab", className: `bd-tab${props.active === tab ? ' active' : ''}`, "aria-selected": props.active === tab, "aria-controls": `bd-panel-${tab}`, tabIndex: props.active === tab ? 0 : -1, "data-bd-tab": tab, onClick: () => props.onChange(tab), onKeyDown: event => {
34
+ if (event.key === 'ArrowRight') {
35
+ event.preventDefault();
36
+ selectAt(index + 1);
37
+ }
38
+ else if (event.key === 'ArrowLeft') {
39
+ event.preventDefault();
40
+ selectAt(index - 1);
41
+ }
42
+ else if (event.key === 'Home') {
43
+ event.preventDefault();
44
+ selectAt(0);
45
+ }
46
+ else if (event.key === 'End') {
47
+ event.preventDefault();
48
+ selectAt(BOT_DEFAULTS_TABS.length - 1);
49
+ }
50
+ }, children: labels[tab] }, tab))) }), _jsx("small", { className: "bd-tab-hint", children: tr('botDefaults.tabHint') })] }));
51
+ }
52
+ // Two-column waterfall (masonry) for the task panels. A plain row-major grid
53
+ // locks each row to its tallest tile, stranding a short tile beside a tall one
54
+ // with a dead gap below. This lays tiles out by greedily dropping each into the
55
+ // currently shortest column and writing back an inline grid-column /
56
+ // grid-row-start over the CSS 1px row track. Tiles stay direct grid children —
57
+ // never reparented into per-column wrappers — so their unsaved form drafts
58
+ // (the whole point of the focused editor) never remount. Degrades to the plain
59
+ // auto-fill grid when there is only one column (mobile / narrow) or before the
60
+ // first measure.
61
+ const BD_GRID_ROW_PX = 1; // must match grid-auto-rows in style.css
62
+ const BD_GRID_GAP_PX = 14; // must match .bd-tab-grid gap
63
+ export function BdTabGrid(props) {
64
+ const ref = useRef(null);
65
+ useEffect(() => {
66
+ const grid = ref.current;
67
+ if (!grid || typeof window === 'undefined')
68
+ return undefined;
69
+ const clearPlacement = (tiles) => {
70
+ for (const tile of tiles) {
71
+ tile.style.gridColumn = '';
72
+ tile.style.gridRowStart = '';
73
+ tile.style.gridRowEnd = '';
74
+ }
75
+ };
76
+ const layout = () => {
77
+ const tiles = Array.from(grid.children).filter((n) => n instanceof HTMLElement);
78
+ if (!tiles.length)
79
+ return;
80
+ // A hidden panel (display:none) reports 0 width — skip; the ResizeObserver
81
+ // re-fires with real geometry the moment the tab becomes visible.
82
+ const gridWidth = grid.clientWidth;
83
+ if (gridWidth <= 0)
84
+ return;
85
+ // Decide the column count from the SAME width the CSS @container rule keys
86
+ // off (the .bd-detail container), instead of parsing
87
+ // getComputedStyle().gridTemplateColumns — that value contains spaces
88
+ // inside minmax(...) and, once we write an inline grid-column, can report a
89
+ // stale/implicit extra track, which previously produced a rogue 3rd column.
90
+ // Reading the container keeps JS placement and the CSS track count in lockstep.
91
+ const container = grid.closest('.bd-detail');
92
+ const decideWidth = container?.clientWidth ?? gridWidth;
93
+ const columns = decideWidth >= 1024 ? 2 : 1;
94
+ // Single column (mobile / narrow): normal flow already stacks with no gap.
95
+ if (columns < 2) {
96
+ clearPlacement(tiles);
97
+ return;
98
+ }
99
+ const rowStep = BD_GRID_ROW_PX + BD_GRID_GAP_PX;
100
+ const colBottom = new Array(columns).fill(0); // running bottom, row units
101
+ for (const tile of tiles) {
102
+ const spanRows = Math.max(1, Math.ceil((tile.getBoundingClientRect().height + BD_GRID_GAP_PX) / rowStep));
103
+ if (tile.classList.contains('bd-tile-wide')) {
104
+ // full-width tile: start below the tallest column, then level every
105
+ // column to its bottom so following tiles pack beneath it evenly.
106
+ const start = Math.max(...colBottom);
107
+ tile.style.gridColumn = '1 / -1';
108
+ tile.style.gridRowStart = String(start + 1);
109
+ tile.style.gridRowEnd = String(start + 1 + spanRows);
110
+ colBottom.fill(start + spanRows);
111
+ continue;
112
+ }
113
+ // drop into the currently shortest column (true waterfall)
114
+ let target = 0;
115
+ for (let c = 1; c < columns; c++)
116
+ if (colBottom[c] < colBottom[target])
117
+ target = c;
118
+ const start = colBottom[target];
119
+ tile.style.gridColumn = String(target + 1);
120
+ tile.style.gridRowStart = String(start + 1);
121
+ tile.style.gridRowEnd = String(start + 1 + spanRows);
122
+ colBottom[target] = start + spanRows;
123
+ }
124
+ };
125
+ // Measure after paint; re-run on any tile resize (content toggles, textarea
126
+ // growth, async loads, tab becoming visible) and on viewport resize.
127
+ const raf = window.requestAnimationFrame(layout);
128
+ const ro = typeof ResizeObserver !== 'undefined' ? new ResizeObserver(() => layout()) : null;
129
+ if (ro) {
130
+ ro.observe(grid);
131
+ for (const child of Array.from(grid.children))
132
+ ro.observe(child);
133
+ }
134
+ window.addEventListener('resize', layout);
135
+ return () => {
136
+ window.cancelAnimationFrame(raf);
137
+ ro?.disconnect();
138
+ window.removeEventListener('resize', layout);
139
+ };
140
+ });
141
+ return (_jsx("div", { ref: ref, className: props.className ? `bd-tab-grid ${props.className}` : 'bd-tab-grid', children: props.children }));
142
+ }
10
143
  function statusClass(status, extra = '') {
11
144
  const suffix = status ? ` ${status.ok ? 'hint-ok' : 'hint-warn-inline'}` : '';
12
145
  return `oncall-status${extra ? ` ${extra}` : ''}${suffix}`;
@@ -118,6 +251,7 @@ function sessionCapStateLabel(cap, tr) {
118
251
  function patchCardPrefsFromBody(bot, body) {
119
252
  return {
120
253
  ...bot,
254
+ usageDisplay: body.usageDisplay,
121
255
  disableStreamingCard: body.disableStreamingCard,
122
256
  silentTurnReactions: body.silentTurnReactions,
123
257
  codexAppCleanInput: body.codexAppCleanInput,
@@ -149,6 +283,7 @@ export function BotDefaultsPage() {
149
283
  const [profileRoleVersion, setProfileRoleVersion] = useState(0);
150
284
  const [, setAvatarVersion] = useState(0);
151
285
  const [onboardingBusy, setOnboardingBusy] = useState(false);
286
+ const [activeTab, setActiveTab] = useState('common');
152
287
  const refresh = useCallback(async (clearProfileRoles = false) => {
153
288
  if (clearProfileRoles)
154
289
  setProfileRoleVersion(version => version + 1);
@@ -236,7 +371,7 @@ export function BotDefaultsPage() {
236
371
  detail = _jsx("p", { className: "empty", children: tr('botDefaults.empty') });
237
372
  }
238
373
  else if (selectedBot) {
239
- detail = (_jsx(BotDefaultsCard, { bot: selectedBot, cliState: cliState, patchBot: patchBot }, `${selectedBot.larkAppId}:${profileRoleVersion}`));
374
+ detail = (_jsx(BotDefaultsCard, { bot: selectedBot, cliState: cliState, patchBot: patchBot, activeTab: activeTab, onTabChange: setActiveTab }, `${selectedBot.larkAppId}:${profileRoleVersion}`));
240
375
  }
241
376
  else {
242
377
  detail = null;
@@ -244,7 +379,7 @@ export function BotDefaultsPage() {
244
379
  return (_jsxs("section", { className: "page bot-defaults-page", children: [_jsxs("div", { className: "page-heading", children: [_jsxs("div", { children: [_jsx("p", { className: "eyebrow", children: tr('nav.botDefaults') }), _jsx("h1", { children: tr('botDefaults.title') })] }), _jsxs("div", { className: "page-heading-actions", children: [_jsx(RefreshIconButton, { id: "bd-refresh", label: tr('botDefaults.refresh'), busy: refreshing, disabled: refreshing, onClick: () => void reload() }), ui.authed ? (_jsx(CreateActionButton, { className: "page-primary-action add-bot-btn", disabled: onboardingBusy, onClick: () => {
245
380
  setOnboardingBusy(true);
246
381
  void openBotOnboarding().finally(() => setOnboardingBusy(false));
247
- }, children: tr('botOnboarding.add') })) : null] })] }), _jsxs("div", { className: "bd-layout", children: [_jsxs("aside", { id: "bd-roster", className: "bd-roster", children: [_jsx("form", { id: "bd-filters", className: "filters dashboard-toolbar", onSubmit: event => event.preventDefault(), children: _jsx("input", { type: "search", name: "q", placeholder: tr('botDefaults.search'), value: query, onChange: event => setQuery(event.currentTarget.value) }) }), _jsx("div", { className: "bd-roster-list", children: !loadError && filtered.map(bot => (_jsx(RosterItem, { bot: bot, selected: bot.larkAppId === selectedAppId, onSelect: () => setSelectedAppId(bot.larkAppId) }, bot.larkAppId))) })] }), _jsx("div", { id: "bd-list", className: "bd-detail", children: detail })] })] }));
382
+ }, children: tr('botOnboarding.add') })) : null] })] }), _jsxs("div", { className: "bd-layout", children: [_jsxs("aside", { id: "bd-roster", className: "bd-roster", children: [_jsx("form", { id: "bd-filters", className: "filters dashboard-toolbar", onSubmit: event => event.preventDefault(), children: _jsx("input", { type: "search", name: "q", placeholder: tr('botDefaults.search'), value: query, onChange: event => setQuery(event.currentTarget.value) }) }), _jsxs("div", { className: "bd-roster-meta", children: [_jsx("span", { children: tr('botDefaults.rosterCount', { count: filtered.length }) }), query.trim() && filtered.length !== bots.length ? (_jsx("span", { children: tr('botDefaults.rosterFiltered', { total: bots.length }) })) : null] }), _jsx("div", { className: "bd-roster-list", children: !loadError && filtered.map(bot => (_jsx(RosterItem, { bot: bot, selected: bot.larkAppId === selectedAppId, onSelect: () => setSelectedAppId(bot.larkAppId) }, bot.larkAppId))) })] }), _jsx("div", { id: "bd-list", className: "bd-detail", children: detail })] })] }));
248
383
  }
249
384
  function RosterItem(props) {
250
385
  const { bot } = props;
@@ -255,7 +390,7 @@ function RosterItem(props) {
255
390
  event.preventDefault();
256
391
  props.onSelect();
257
392
  }
258
- }, children: [_jsx(Html, { html: botAvatarHtml({ name, larkAppId: bot.larkAppId, size: 'sm' }) }), _jsxs("div", { className: "bd-roster-tx", children: [_jsx("b", { children: name }), _jsx("span", { children: cli || bot.larkAppId.slice(0, 14) })] }), bot.defaultOncall?.enabled ? _jsx("span", { className: "bd-roster-flag", children: "oncall" }) : null] }));
393
+ }, children: [_jsx(Html, { html: botAvatarHtml({ name, larkAppId: bot.larkAppId, size: 'sm' }) }), _jsxs("div", { className: "bd-roster-tx", children: [_jsx("b", { children: _jsx(OverflowText, { text: name, showPopover: false, textClassName: "bd-roster-name" }) }), _jsx("span", { children: cli || bot.larkAppId.slice(0, 14) })] }), bot.defaultOncall?.enabled ? _jsx("span", { className: "bd-roster-flag", children: "oncall" }) : null] }));
259
394
  }
260
395
  function BotDefaultsCard(props) {
261
396
  const tr = useT();
@@ -273,11 +408,11 @@ function BotDefaultsCard(props) {
273
408
  return (_jsxs("article", { className: "bd-card bd-profile", "data-appid": bot.larkAppId, children: [_jsxs("header", { className: "bd-profile-head", children: [_jsx(Html, { html: botAvatarHtml({ name, larkAppId: bot.larkAppId }) }), _jsxs("div", { className: "bd-profile-id", children: [_jsx("strong", { children: name }), _jsx("code", { children: bot.larkAppId })] })] }), _jsxs("p", { className: "hint-warn-inline", children: ["\u67E5\u8BE2\u5931\u8D25\uFF1A", bot.error] })] }));
274
409
  }
275
410
  const def = bot.defaultOncall ?? { enabled: false, workingDir: '', since: 0 };
276
- return (_jsxs("article", { className: "bd-card bd-profile", "data-appid": bot.larkAppId, children: [_jsxs("header", { className: "bd-profile-head", children: [_jsx(BotAvatarControl, { bot: bot, name: name, patchBot: patchBot }), _jsx("div", { className: "bd-profile-main", children: _jsx(BotProfileIdentity, { bot: bot, cli: cli, patchBot: patchBot, meta: (_jsxs(_Fragment, { children: [_jsxs("small", { className: "bd-meta-ok", children: ["\u25CF ", tr('botDefaults.metaOnline')] }), _jsxs("small", { "data-oncall-since": true, children: [tr('botDefaults.lastEnabled'), ": ", fmtSince(def.since ?? 0)] }), _jsx("small", { children: tr('botDefaults.autobound', { count: bot.autoboundChatCount ?? 0 }) })] })) }) })] }), _jsxs("div", { className: "bd-body bd-grid", children: [_jsxs("div", { className: "bd-column", children: [_jsxs("section", { className: "bd-tile", children: [_jsx(BotAgentSection, { bot: bot, sessionFallback: cli, cliState: cliState, patchBot: patchBot }), _jsx(WorkingDirSection, { bot: bot, patchBot: patchBot, putCardPref: putCardPref }), bot.cliId !== 'riff' && _jsx(SandboxSection, { bot: bot, patchBot: patchBot }), bot.cliId !== 'riff' && bot.sandbox === true && _jsx(SandboxPathsSection, { bot: bot, patchBot: patchBot }), bot.cliId !== 'riff' && _jsx(BackendTypeSection, { bot: bot, patchBot: patchBot })] }), _jsx("section", { className: "bd-tile", children: _jsx(RuntimeEnvironmentSection, { bot: bot, patchBot: patchBot }) }), _jsx("section", { className: "bd-tile", children: _jsx(GrantSection, { bot: bot, patchBot: patchBot }) }), _jsx("section", { className: "bd-tile", children: _jsx(SlashCommandPermissionsSection, { bot: bot, patchBot: patchBot }) })] }), _jsxs("div", { className: "bd-column", children: [_jsxs("section", { className: "bd-tile", children: [_jsx(SessionModeSection, { bot: bot, patchBot: patchBot, putCardPref: putCardPref }), _jsx(SubstituteModeSection, { bot: bot, patchBot: patchBot }), _jsx(CrossBotSection, { bot: bot, putCardPref: putCardPref }), _jsx(SessionCapSection, { bot: bot, patchBot: patchBot, putCardPref: putCardPref })] }), _jsxs("section", { className: "bd-tile", children: [_jsx(CardBehaviorSection, { bot: bot, putCardPref: putCardPref }), _jsx(CodexAppDisplaySection, { bot: bot, putCardPref: putCardPref }), _jsx(SummaryTriggerSection, { bot: bot, patchBot: patchBot }), _jsx(BrandSection, { bot: bot, patchBot: patchBot })] }), _jsx("section", { className: "bd-tile", children: _jsx(RoleSection, { bot: bot, patchBot: patchBot }) })] })] })] }));
411
+ return (_jsxs("article", { className: "bd-card bd-profile", "data-appid": bot.larkAppId, children: [_jsxs("div", { className: "bd-profile-chrome", children: [_jsxs("header", { className: "bd-profile-head", children: [_jsx(BotAvatarControl, { bot: bot, name: name, patchBot: patchBot }), _jsx("div", { className: "bd-profile-main", children: _jsx(BotProfileIdentity, { bot: bot, cli: cli, patchBot: patchBot, meta: (_jsxs(_Fragment, { children: [_jsxs("small", { className: "bd-meta-ok", children: ["\u25CF ", tr('botDefaults.metaOnline')] }), (def.since ?? 0) > 0 ? _jsxs("small", { "data-oncall-since": true, children: [tr('botDefaults.lastEnabled'), ": ", fmtSince(def.since ?? 0)] }) : null, (bot.autoboundChatCount ?? 0) > 0 ? _jsx("small", { children: tr('botDefaults.autobound', { count: bot.autoboundChatCount ?? 0 }) }) : null] })) }) })] }), _jsx(BotDefaultsTabs, { active: props.activeTab, onChange: props.onTabChange })] }), _jsxs("div", { className: "bd-body bd-tab-panels", children: [_jsx("div", { id: "bd-panel-common", role: "tabpanel", "aria-labelledby": "bd-tab-common", className: "bd-tab-panel", hidden: props.activeTab !== 'common', children: _jsxs(BdTabGrid, { children: [_jsx("section", { className: "bd-tile", children: _jsx(BotAgentSection, { bot: bot, sessionFallback: cli, cliState: cliState, patchBot: patchBot }) }), _jsx("section", { className: "bd-tile", children: _jsx(WorkingDirSection, { bot: bot, patchBot: patchBot, putCardPref: putCardPref }) }), _jsx("section", { className: "bd-tile", children: _jsx(RoleSection, { bot: bot, patchBot: patchBot }) })] }) }), _jsx("div", { id: "bd-panel-sessions", role: "tabpanel", "aria-labelledby": "bd-tab-sessions", className: "bd-tab-panel", hidden: props.activeTab !== 'sessions', children: _jsxs(BdTabGrid, { children: [_jsx("section", { className: "bd-tile", children: _jsx(SessionModeSection, { bot: bot, patchBot: patchBot, putCardPref: putCardPref }) }), _jsx("section", { className: "bd-tile", children: _jsx(SubstituteModeSection, { bot: bot, patchBot: patchBot }) }), _jsx("section", { className: "bd-tile", children: _jsx(CrossBotSection, { bot: bot, putCardPref: putCardPref }) }), _jsx("section", { className: "bd-tile", children: _jsx(SessionCapSection, { bot: bot, patchBot: patchBot }) }), _jsx("section", { className: "bd-tile", children: _jsx(StartupCommandsSection, { bot: bot, patchBot: patchBot }) }), _jsx("section", { className: "bd-tile", children: _jsx(SummaryTriggerSection, { bot: bot, patchBot: patchBot }) })] }) }), _jsx("div", { id: "bd-panel-security", role: "tabpanel", "aria-labelledby": "bd-tab-security", className: "bd-tab-panel", hidden: props.activeTab !== 'security', children: _jsxs(BdTabGrid, { children: [bot.cliId !== 'riff' ? (_jsx("section", { className: "bd-tile", children: _jsx(SandboxSection, { bot: bot, patchBot: patchBot }) })) : null, bot.cliId !== 'riff' && bot.sandbox === true ? (_jsx("section", { className: "bd-tile bd-tile-wide", children: _jsx(SandboxPathsSection, { bot: bot, patchBot: patchBot }) })) : null, _jsx("section", { className: "bd-tile", children: _jsx(GrantSection, { bot: bot, patchBot: patchBot }) }), _jsx("section", { className: "bd-tile", children: _jsx(SlashCommandPermissionsSection, { bot: bot, patchBot: patchBot }) })] }) }), _jsx("div", { id: "bd-panel-cards", role: "tabpanel", "aria-labelledby": "bd-tab-cards", className: "bd-tab-panel", hidden: props.activeTab !== 'cards', children: _jsxs(BdTabGrid, { children: [_jsx("section", { className: "bd-tile", children: _jsx(CardBehaviorSection, { bot: bot, putCardPref: putCardPref }) }), _jsx("section", { className: "bd-tile", children: _jsx(BrandSection, { bot: bot, patchBot: patchBot }) })] }) }), _jsx("div", { id: "bd-panel-advanced", role: "tabpanel", "aria-labelledby": "bd-tab-advanced", className: "bd-tab-panel", hidden: props.activeTab !== 'advanced', children: _jsxs(BdTabGrid, { children: [bot.cliId !== 'riff' ? (_jsx("section", { className: "bd-tile", children: _jsx(BackendTypeSection, { bot: bot, patchBot: patchBot }) })) : null, bot.cliId === 'codex-app' ? (_jsx("section", { className: "bd-tile", children: _jsx(CodexAppDisplaySection, { bot: bot, putCardPref: putCardPref }) })) : null, _jsx("section", { className: "bd-tile", children: _jsx(RuntimeEnvironmentSection, { bot: bot, patchBot: patchBot }) })] }) })] })] }));
277
412
  }
278
413
  function RuntimeEnvironmentSection(props) {
279
414
  const tr = useT();
280
- return (_jsxs("section", { className: "bd-section bd-runtime-env", children: [_jsx("h3", { className: "bd-section-title", children: tr('botDefaults.sectionRuntimeEnv') }), _jsx(StartupCommandsSection, { bot: props.bot, patchBot: props.patchBot }), _jsx(LaunchShellSection, { bot: props.bot, patchBot: props.patchBot }), _jsx(EnvSection, { bot: props.bot, patchBot: props.patchBot })] }));
415
+ return (_jsxs("section", { className: "bd-section bd-runtime-env", children: [_jsx("h3", { className: "bd-section-title", children: tr('botDefaults.sectionRuntimeEnv') }), _jsx(LaunchShellSection, { bot: props.bot, patchBot: props.patchBot }), _jsx(EnvSection, { bot: props.bot, patchBot: props.patchBot })] }));
281
416
  }
282
417
  /** console 头像上传只实测过 512×512 PNG,前端统一归一化成这一形态再上传。 */
283
418
  const AVATAR_UPLOAD_SIDE = 512;
@@ -370,16 +505,16 @@ function BotAvatarControl(props) {
370
505
  pendingRef.current = dataUrl;
371
506
  await upload(dataUrl);
372
507
  }
373
- return (_jsxs("div", { className: "bd-profile-avatar bd-avatar-editable", "data-avatar-control": true, children: [_jsxs("button", { type: "button", className: "bd-avatar-btn", "data-action": "edit-bot-avatar", title: tr('botDefaults.avatarTitle'), "aria-label": tr('botDefaults.avatarTitle'), disabled: busy, onClick: () => inputRef.current?.click(), children: [_jsx(Html, { html: botAvatarHtml({ name, larkAppId: bot.larkAppId, dot: 'ok' }) }), _jsx("span", { className: "bd-avatar-edit-badge", "aria-hidden": "true", children: busy ? '⏳' : '✎' })] }), _jsx("input", { ref: inputRef, type: "file", accept: "image/*", hidden: true, "data-input": "botAvatarFile", onChange: event => {
374
- const file = event.currentTarget.files?.[0];
375
- event.currentTarget.value = ''; // 允许再次选择同一文件
376
- void handleFile(file);
377
- } }), status ? (_jsxs("small", { className: statusClass(status, 'bd-avatar-status'), "data-avatar-status": true, children: [status.text, loginVisible ? (_jsx("button", { type: "button", className: "bd-feishu-login", "data-action": "feishu-login-avatar", onClick: () => setLoginOpen(true), children: tr('feishuLogin.entry') })) : null] })) : null, loginOpen ? (_jsx(FeishuLoginModal, { onClose: () => setLoginOpen(false), onSuccess: () => {
378
- setLoginVisible(false);
379
- setLoginOpen(false);
380
- if (pendingRef.current)
381
- void upload(pendingRef.current);
382
- } })) : null] }));
508
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "bd-profile-avatar bd-avatar-editable", "data-avatar-control": true, children: [_jsxs("button", { type: "button", className: "bd-avatar-btn", "data-action": "edit-bot-avatar", title: tr('botDefaults.avatarTitle'), "aria-label": tr('botDefaults.avatarTitle'), disabled: busy, onClick: () => inputRef.current?.click(), children: [_jsx(Html, { html: botAvatarHtml({ name, larkAppId: bot.larkAppId, dot: 'ok' }) }), _jsx("span", { className: "bd-avatar-edit-badge", "aria-hidden": "true", children: busy ? '⏳' : '✎' })] }), _jsx("input", { ref: inputRef, type: "file", accept: "image/*", hidden: true, "data-input": "botAvatarFile", onChange: event => {
509
+ const file = event.currentTarget.files?.[0];
510
+ event.currentTarget.value = ''; // 允许再次选择同一文件
511
+ void handleFile(file);
512
+ } }), loginOpen ? (_jsx(FeishuLoginModal, { onClose: () => setLoginOpen(false), onSuccess: () => {
513
+ setLoginVisible(false);
514
+ setLoginOpen(false);
515
+ if (pendingRef.current)
516
+ void upload(pendingRef.current);
517
+ } })) : null] }), status ? (_jsxs("small", { className: statusClass(status, 'bd-avatar-status'), "data-avatar-status": true, children: [status.text, loginVisible ? (_jsx("button", { type: "button", className: "bd-feishu-login", "data-action": "feishu-login-avatar", onClick: () => setLoginOpen(true), children: tr('feishuLogin.entry') })) : null] })) : null] }));
383
518
  }
384
519
  function BotProfileIdentity(props) {
385
520
  const tr = useT();
@@ -449,7 +584,7 @@ function BotProfileIdentity(props) {
449
584
  setBusy(false);
450
585
  }
451
586
  }, [bot.larkAppId, draft, patchBot, tr]);
452
- return (_jsxs("div", { className: "bd-profile-id", children: [!editing ? (_jsxs("div", { className: "bd-profile-title-row", "data-name-row": true, children: [_jsxs("div", { className: "bd-profile-title-content", children: [_jsx("strong", { "data-bot-name": true, children: name }), cli ? _jsx("span", { className: "mate-role bd-profile-cli-tag", children: cli }) : null, props.meta ? _jsx("span", { className: "bd-profile-meta bd-meta", children: props.meta }) : null] }), _jsx("button", { type: "button", className: "bd-name-edit", "data-action": "edit-bot-name", title: tr('botDefaults.renameTitle'), "aria-label": tr('botDefaults.renameTitle'), onClick: () => setEditMode(true), children: tr('botDefaults.renameAction') })] })) : (_jsxs("span", { className: "bd-name-editor", "data-name-editor": true, children: [_jsx("input", { type: "text", className: "bd-name-input", "data-input": "botRename", maxLength: 64, value: draft, disabled: busy, autoFocus: true, onChange: event => setDraft(event.currentTarget.value), onKeyDown: event => {
587
+ return (_jsxs("div", { className: "bd-profile-id", children: [!editing ? (_jsxs("div", { className: "bd-profile-title-row", "data-name-row": true, children: [_jsxs("div", { className: "bd-profile-title-content", children: [_jsx("strong", { "data-bot-name": true, children: name }), cli ? _jsx("span", { className: "mate-role bd-profile-cli-tag", children: cli }) : null, props.meta ? _jsx("span", { className: "bd-profile-meta bd-meta", children: props.meta }) : null] }), _jsx("button", { type: "button", className: "bd-name-edit", "data-action": "edit-bot-name", title: tr('botDefaults.renameTitle'), "aria-label": tr('botDefaults.renameTitle'), onClick: () => setEditMode(true), children: _jsx("svg", { viewBox: "0 0 16 16", width: "14", height: "14", fill: "none", stroke: "currentColor", strokeWidth: "1.6", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: _jsx("path", { d: "M11.5 2.5l2 2L6 12l-2.5.5L4 10z" }) }) })] })) : (_jsxs("span", { className: "bd-name-editor", "data-name-editor": true, children: [_jsx("input", { type: "text", className: "bd-name-input", "data-input": "botRename", maxLength: 64, value: draft, disabled: busy, autoFocus: true, onChange: event => setDraft(event.currentTarget.value), onKeyDown: event => {
453
588
  if (event.key === 'Enter') {
454
589
  event.preventDefault();
455
590
  void submitRename();
@@ -1036,6 +1171,7 @@ const BACKEND_TYPE_OPTIONS = [
1036
1171
  { value: 'tmux', labelKey: 'botDefaults.backendTmux' },
1037
1172
  { value: 'herdr', labelKey: 'botDefaults.backendHerdr' },
1038
1173
  { value: 'zellij', labelKey: 'botDefaults.backendZellij' },
1174
+ { value: 'zmx', labelKey: 'botDefaults.backendZmx' },
1039
1175
  { value: 'pty', labelKey: 'botDefaults.backendPty' },
1040
1176
  ];
1041
1177
  function BackendTypeSection(props) {
@@ -1077,6 +1213,7 @@ function RoleSection(props) {
1077
1213
  const { bot, patchBot } = props;
1078
1214
  const [loaded, setLoaded] = useState(typeof bot.teamRole === 'string');
1079
1215
  const [role, setRole] = useState(typeof bot.teamRole === 'string' ? bot.teamRole : '');
1216
+ const [injectMode, setInjectMode] = useState('every');
1080
1217
  const [status, setStatus] = useState(null);
1081
1218
  const [busy, setBusy] = useState(false);
1082
1219
  useEffect(() => {
@@ -1102,6 +1239,7 @@ function RoleSection(props) {
1102
1239
  if (r.ok && body.ok) {
1103
1240
  const next = body.role ?? '';
1104
1241
  setRole(next);
1242
+ setInjectMode(body.injectMode === 'once' ? 'once' : 'every');
1105
1243
  setLoaded(true);
1106
1244
  patchBot(bot.larkAppId, { teamRole: next });
1107
1245
  }
@@ -1116,16 +1254,35 @@ function RoleSection(props) {
1116
1254
  })();
1117
1255
  return () => { active = false; };
1118
1256
  }, [bot.larkAppId, bot.teamRole, patchBot, tr]);
1119
- async function putRole(nextRole, deleted) {
1257
+ // injectMode isn't cached on the bot row, so when the team role is already
1258
+ // resolved (cache hit above skips the GET) fetch just the mode once per bot.
1259
+ useEffect(() => {
1260
+ let active = true;
1261
+ if (typeof bot.teamRole !== 'string')
1262
+ return () => { active = false; };
1263
+ void (async () => {
1264
+ try {
1265
+ const r = await fetch(`/api/team/local-bots/${encodeURIComponent(bot.larkAppId)}/role`);
1266
+ const body = await r.json().catch(() => ({}));
1267
+ if (active && r.ok && body.ok)
1268
+ setInjectMode(body.injectMode === 'once' ? 'once' : 'every');
1269
+ }
1270
+ catch { /* keep default 'every' */ }
1271
+ })();
1272
+ return () => { active = false; };
1273
+ }, [bot.larkAppId]);
1274
+ async function putRole(nextRole, deleted, mode = injectMode) {
1120
1275
  if (!loaded)
1121
1276
  return;
1122
1277
  setStatus(null);
1123
1278
  setBusy(true);
1124
1279
  try {
1125
- const res = await sendJson('PUT', `/api/team/local-bots/${encodeURIComponent(bot.larkAppId)}/role`, { role: nextRole });
1280
+ const res = await sendJson('PUT', `/api/team/local-bots/${encodeURIComponent(bot.larkAppId)}/role`, { role: nextRole, injectMode: mode });
1126
1281
  if (res.ok && res.body.ok) {
1127
1282
  const stored = nextRole.trim();
1128
1283
  setRole(stored);
1284
+ if (res.body.injectMode === 'once' || res.body.injectMode === 'every')
1285
+ setInjectMode(res.body.injectMode);
1129
1286
  patchBot(bot.larkAppId, { teamRole: stored });
1130
1287
  setStatus({ text: `✓ ${deleted ? tr('botDefaults.roleDeleted') : tr('botDefaults.roleSaved')}`, ok: true });
1131
1288
  }
@@ -1140,7 +1297,11 @@ function RoleSection(props) {
1140
1297
  setBusy(false);
1141
1298
  }
1142
1299
  }
1143
- return (_jsxs("section", { className: "bd-section", children: [_jsx("h3", { className: "bd-section-title", children: _jsx(FieldTitle, { help: tr('botDefaults.roleHelp'), children: tr('botDefaults.sectionRole') }) }), _jsx("textarea", { "data-input": "teamRole", rows: 6, placeholder: tr('botDefaults.rolePlaceholder'), disabled: !loaded || busy, value: role, onChange: event => setRole(event.currentTarget.value) }), _jsxs("div", { className: "actions", children: [_jsx("button", { type: "button", className: "primary", "data-action": "save-role", disabled: !loaded || busy, onClick: () => void putRole(role, role.trim() === ''), children: tr('botDefaults.roleSave') }), _jsx(StatusSpan, { status: status, attr: { 'data-role-status': '' } })] }), _jsx(ProfileRoles, { appId: bot.larkAppId })] }));
1300
+ const injectOptions = [
1301
+ { value: 'every', label: tr('roles.injectModeEvery') },
1302
+ { value: 'once', label: tr('roles.injectModeOnce') },
1303
+ ];
1304
+ return (_jsxs("section", { className: "bd-section", children: [_jsx("h3", { className: "bd-section-title", children: _jsx(FieldTitle, { help: tr('botDefaults.roleHelp'), children: tr('botDefaults.sectionRole') }) }), _jsx("textarea", { "data-input": "teamRole", rows: 6, placeholder: tr('botDefaults.rolePlaceholder'), disabled: !loaded || busy, value: role, onChange: event => setRole(event.currentTarget.value) }), _jsxs("div", { className: "bd-role-inject", children: [_jsx("span", { className: "bd-subsection-title", children: _jsx(FieldTitle, { help: tr('roles.injectModeHint'), children: tr('roles.injectModeLabel') }) }), _jsx(DropdownMenu, { id: `bd-role-inject-${bot.larkAppId}`, className: "bd-role-inject-menu", ariaLabel: tr('roles.injectModeLabel'), disabled: !loaded || busy, label: dropdownLabel(injectOptions, injectMode), value: injectMode, options: injectOptions, onChange: mode => { const next = mode === 'once' ? 'once' : 'every'; setInjectMode(next); void putRole(role, role.trim() === '', next); } })] }), _jsxs("div", { className: "actions", children: [_jsx("button", { type: "button", className: "primary", "data-action": "save-role", disabled: !loaded || busy, onClick: () => void putRole(role, role.trim() === ''), children: tr('botDefaults.roleSave') }), _jsx(StatusSpan, { status: status, attr: { 'data-role-status': '' } })] }), _jsx(ProfileRoles, { appId: bot.larkAppId })] }));
1144
1305
  }
1145
1306
  function ProfileRoles(props) {
1146
1307
  const tr = useT();
@@ -1215,9 +1376,10 @@ function ProfileRoles(props) {
1215
1376
  }
1216
1377
  return (_jsxs("div", { className: "bd-profile-roles", "data-profile-roles": true, children: [_jsx("h4", { className: "bd-subsection-title", children: _jsx(FieldTitle, { help: tr('botDefaults.profileRolesHelp'), children: tr('botDefaults.profileRoles') }) }), _jsx("div", { className: "bd-profile-role-list", "data-profile-role-list": true, children: body })] }));
1217
1378
  }
1218
- function CardBehaviorSection(props) {
1379
+ export function CardBehaviorSection(props) {
1219
1380
  const tr = useT();
1220
1381
  const { bot, putCardPref } = props;
1382
+ const [usageDisplay, setUsageDisplay] = useState(bot.usageDisplay ?? 'streaming');
1221
1383
  const [disableStreaming, setDisableStreaming] = useState(bot.disableStreamingCard === true);
1222
1384
  const [silentReactions, setSilentReactions] = useState(bot.silentTurnReactions === true);
1223
1385
  const [writableLink, setWritableLink] = useState(bot.writableTerminalLinkInCard === true);
@@ -1225,26 +1387,43 @@ function CardBehaviorSection(props) {
1225
1387
  const [status, setStatus] = useState(null);
1226
1388
  const [busy, setBusy] = useState(null);
1227
1389
  useEffect(() => {
1390
+ setUsageDisplay(bot.usageDisplay ?? 'streaming');
1228
1391
  setDisableStreaming(bot.disableStreamingCard === true);
1229
1392
  setSilentReactions(bot.silentTurnReactions === true);
1230
1393
  setWritableLink(bot.writableTerminalLinkInCard === true);
1231
1394
  setPrivateCard(bot.privateCard === true);
1232
- }, [bot.disableStreamingCard, bot.privateCard, bot.silentTurnReactions, bot.writableTerminalLinkInCard]);
1233
- async function savePatch(patch, key) {
1395
+ }, [bot.disableStreamingCard, bot.privateCard, bot.usageDisplay, bot.silentTurnReactions, bot.writableTerminalLinkInCard]);
1396
+ async function savePatch(patch, key, rollback) {
1234
1397
  setBusy(key);
1235
1398
  setStatus(null);
1236
1399
  try {
1237
1400
  const res = await putCardPref(patch);
1238
- setStatus(res.ok ? { text: `✓ ${tr('botDefaults.cardPrefSaved')}`, ok: true } : { text: `✗ ${responseErrorText(res)}` });
1401
+ if (res.ok) {
1402
+ setStatus({ text: `✓ ${tr('botDefaults.cardPrefSaved')}`, ok: true });
1403
+ }
1404
+ else {
1405
+ rollback?.();
1406
+ setStatus({ text: `✗ ${responseErrorText(res)}` });
1407
+ }
1239
1408
  }
1240
1409
  catch (e) {
1410
+ rollback?.();
1241
1411
  setStatus({ text: `✗ ${caughtErrorText(e)}` });
1242
1412
  }
1243
1413
  finally {
1244
1414
  setBusy(null);
1245
1415
  }
1246
1416
  }
1247
- return (_jsxs("section", { className: "bd-section", children: [_jsx("h3", { className: "bd-section-title", children: tr('botDefaults.sectionCard') }), _jsxs("div", { className: "bd-toggle-grid bd-card-behavior-grid", children: [_jsx(ToggleRow, { checked: disableStreaming, disabled: busy === 'streaming', dataAction: "toggle-disable-streaming", title: tr('botDefaults.disableStreaming'), help: tr('botDefaults.disableStreamingHelp'), onChange: checked => {
1417
+ const usageDisplayOptions = [
1418
+ { value: 'streaming', label: tr('botDefaults.usageDisplayStreaming') },
1419
+ { value: 'footer', label: tr('botDefaults.usageDisplayFooter') },
1420
+ { value: 'off', label: tr('botDefaults.usageDisplayOff') },
1421
+ ];
1422
+ return (_jsxs("section", { className: "bd-section", children: [_jsx("h3", { className: "bd-section-title", children: tr('botDefaults.sectionCard') }), bot.usageSupported === true && (_jsx("div", { className: "bd-row", children: _jsxs("div", { className: "bd-field", children: [_jsx(FieldTitle, { help: tr('botDefaults.usageDisplayHelp'), children: tr('botDefaults.usageDisplay') }), _jsx(DropdownField, { dataInput: "usageDisplay", ariaLabel: tr('botDefaults.usageDisplay'), value: usageDisplay, disabled: busy === 'usage', options: usageDisplayOptions, onChange: next => {
1423
+ const previous = usageDisplay;
1424
+ setUsageDisplay(next);
1425
+ void savePatch({ usageDisplay: next }, 'usage', () => setUsageDisplay(previous));
1426
+ } })] }) })), _jsxs("div", { className: "bd-toggle-grid bd-card-behavior-grid", children: [_jsx(ToggleRow, { checked: disableStreaming, disabled: busy === 'streaming', dataAction: "toggle-disable-streaming", title: tr('botDefaults.disableStreaming'), help: tr('botDefaults.disableStreamingHelp'), onChange: checked => {
1248
1427
  setDisableStreaming(checked);
1249
1428
  void savePatch({ disableStreamingCard: checked }, 'streaming');
1250
1429
  } }), _jsx(ToggleRow, { checked: silentReactions, disabled: !disableStreaming || busy === 'silent', dataAction: "toggle-silent-reactions", title: tr('botDefaults.silentTurnReactions'), help: tr('botDefaults.silentTurnReactionsHelp'), onChange: checked => {
@@ -1472,6 +1651,7 @@ function SubstituteModeSection(props) {
1472
1651
  const [replyMode, setReplyMode] = useState(initial?.replyMode === 'quote' ? 'quote' : 'thread');
1473
1652
  const [controlCard, setControlCard] = useState(initial?.disableControlCard !== true);
1474
1653
  const [chatsText, setChatsText] = useState(() => formatSubstituteChats(initial?.chats));
1654
+ const [excludedChatsText, setExcludedChatsText] = useState(() => formatSubstituteChats(initial?.excludedChats));
1475
1655
  // 话题群相关开关缺省开:只有显式 false 才是关(与 normalize 语义一致)。
1476
1656
  const [topicGroups, setTopicGroups] = useState(initial?.topicGroups !== false);
1477
1657
  const [topicActiveSessionTrigger, setTopicActiveSessionTrigger] = useState(initial?.topicActiveSessionTrigger !== false);
@@ -1570,6 +1750,7 @@ function SubstituteModeSection(props) {
1570
1750
  setReplyMode(next?.replyMode === 'quote' ? 'quote' : 'thread');
1571
1751
  setControlCard(next?.disableControlCard !== true);
1572
1752
  setChatsText(formatSubstituteChats(next?.chats));
1753
+ setExcludedChatsText(formatSubstituteChats(next?.excludedChats));
1573
1754
  setTopicGroups(next?.topicGroups !== false);
1574
1755
  setTopicActiveSessionTrigger(next?.topicActiveSessionTrigger !== false);
1575
1756
  const targets = next?.targets ?? [];
@@ -1596,6 +1777,7 @@ function SubstituteModeSection(props) {
1596
1777
  setReplyMode(next?.replyMode === 'quote' ? 'quote' : 'thread');
1597
1778
  setControlCard(next?.disableControlCard !== true);
1598
1779
  setChatsText(formatSubstituteChats(next?.chats));
1780
+ setExcludedChatsText(formatSubstituteChats(next?.excludedChats));
1599
1781
  setTopicGroups(next?.topicGroups !== false);
1600
1782
  setTopicActiveSessionTrigger(next?.topicActiveSessionTrigger !== false);
1601
1783
  if (resolution.length) {
@@ -1675,7 +1857,7 @@ function SubstituteModeSection(props) {
1675
1857
  setStatus({ text: `✗ ${tr('botDefaults.substituteTargetsInvalid')}` });
1676
1858
  return;
1677
1859
  }
1678
- void save({ enabled, targets, disclosure, chats: parseSubstituteChats(chatsText), replyMode, disableControlCard: !controlCard, topicGroups, topicActiveSessionTrigger });
1860
+ void save({ enabled, targets, disclosure, chats: parseSubstituteChats(chatsText), excludedChats: parseSubstituteChats(excludedChatsText), replyMode, disableControlCard: !controlCard, topicGroups, topicActiveSessionTrigger });
1679
1861
  }
1680
1862
  const disclosureOptions = [
1681
1863
  { value: 'prefix', label: tr('botDefaults.substituteDisclosurePrefix') },
@@ -1685,7 +1867,7 @@ function SubstituteModeSection(props) {
1685
1867
  { value: 'thread', label: tr('botDefaults.substituteReplyModeThread') },
1686
1868
  { value: 'quote', label: tr('botDefaults.substituteReplyModeQuote') },
1687
1869
  ];
1688
- return (_jsxs("section", { className: "bd-section bd-substitute-section", children: [_jsx("h3", { className: "bd-section-title", children: tr('botDefaults.sectionSubstitute') }), _jsx(ToggleRow, { checked: enabled, disabled: busy, dataAction: "toggle-substitute-mode", title: tr('botDefaults.substituteEnabled'), help: tr('botDefaults.substituteHelp'), onChange: setEnabled }), _jsx(ToggleRow, { checked: topicGroups, disabled: busy, dataAction: "toggle-substitute-topic-groups", title: tr('botDefaults.substituteTopicGroups'), help: tr('botDefaults.substituteTopicGroupsHelp'), onChange: setTopicGroups }), _jsx(ToggleRow, { checked: topicActiveSessionTrigger, disabled: busy || !topicGroups, dataAction: "toggle-substitute-topic-active", title: tr('botDefaults.substituteTopicActive'), help: tr('botDefaults.substituteTopicActiveHelp'), onChange: setTopicActiveSessionTrigger }), _jsx("div", { className: "bd-row", children: _jsxs("div", { className: "bd-field", children: [_jsx(FieldTitle, { children: tr('botDefaults.substituteDisclosure') }), _jsx(DropdownField, { dataInput: "substituteDisclosure", ariaLabel: tr('botDefaults.substituteDisclosure'), value: disclosure, disabled: busy, options: disclosureOptions, onChange: value => setDisclosure(value) })] }) }), _jsx("div", { className: "bd-row", children: _jsxs("div", { className: "bd-field", children: [_jsx(FieldTitle, { help: tr('botDefaults.substituteReplyModeHelp'), children: tr('botDefaults.substituteReplyMode') }), _jsx(DropdownField, { dataInput: "substituteReplyMode", ariaLabel: tr('botDefaults.substituteReplyMode'), value: replyMode, disabled: busy, options: replyModeOptions, onChange: value => setReplyMode(value) })] }) }), _jsx(ToggleRow, { checked: controlCard, disabled: busy, dataAction: "toggle-substitute-control-card", title: tr('botDefaults.substituteControlCard'), help: tr('botDefaults.substituteControlCardHelp'), onChange: setControlCard }), _jsx("div", { className: "bd-row", children: _jsxs("label", { children: [_jsx(FieldTitle, { help: tr('botDefaults.substituteChatsHelp'), children: tr('botDefaults.substituteChats') }), _jsx("textarea", { "data-input": "substituteChats", rows: 3, placeholder: tr('botDefaults.substituteChatsPlaceholder'), value: chatsText, disabled: busy, onChange: event => setChatsText(event.currentTarget.value) })] }) }), _jsxs("div", { className: "bd-row bd-substitute-targets", children: [_jsx(FieldTitle, { help: tr('botDefaults.substituteTargetsHelp'), children: tr('botDefaults.substituteTargets') }), _jsxs("div", { className: "bd-substitute-target-list", "data-input": "substituteTargets", children: [targetRows.map((target, index) => (_jsxs("div", { className: "bd-substitute-target-row", children: [_jsx(DropdownField, { dataInput: `substituteTargetType-${target.key}`, className: "bd-substitute-target-type", ariaLabel: `${tr('botDefaults.substituteTargetType')} ${index + 1}`, value: target.idField, disabled: busy, options: substituteTargetIdFields.map(value => ({
1870
+ return (_jsxs("section", { className: "bd-section bd-substitute-section", children: [_jsx("h3", { className: "bd-section-title", children: tr('botDefaults.sectionSubstitute') }), _jsx(ToggleRow, { checked: enabled, disabled: busy, dataAction: "toggle-substitute-mode", title: tr('botDefaults.substituteEnabled'), help: tr('botDefaults.substituteHelp'), onChange: setEnabled }), _jsx(ToggleRow, { checked: topicGroups, disabled: busy, dataAction: "toggle-substitute-topic-groups", title: tr('botDefaults.substituteTopicGroups'), help: tr('botDefaults.substituteTopicGroupsHelp'), onChange: setTopicGroups }), _jsx(ToggleRow, { checked: topicActiveSessionTrigger, disabled: busy || !topicGroups, dataAction: "toggle-substitute-topic-active", title: tr('botDefaults.substituteTopicActive'), help: tr('botDefaults.substituteTopicActiveHelp'), onChange: setTopicActiveSessionTrigger }), _jsx("div", { className: "bd-row", children: _jsxs("div", { className: "bd-field", children: [_jsx(FieldTitle, { children: tr('botDefaults.substituteDisclosure') }), _jsx(DropdownField, { dataInput: "substituteDisclosure", ariaLabel: tr('botDefaults.substituteDisclosure'), value: disclosure, disabled: busy, options: disclosureOptions, onChange: value => setDisclosure(value) })] }) }), _jsx("div", { className: "bd-row", children: _jsxs("div", { className: "bd-field", children: [_jsx(FieldTitle, { help: tr('botDefaults.substituteReplyModeHelp'), children: tr('botDefaults.substituteReplyMode') }), _jsx(DropdownField, { dataInput: "substituteReplyMode", ariaLabel: tr('botDefaults.substituteReplyMode'), value: replyMode, disabled: busy, options: replyModeOptions, onChange: value => setReplyMode(value) })] }) }), _jsx(ToggleRow, { checked: controlCard, disabled: busy, dataAction: "toggle-substitute-control-card", title: tr('botDefaults.substituteControlCard'), help: tr('botDefaults.substituteControlCardHelp'), onChange: setControlCard }), _jsx("div", { className: "bd-row", children: _jsxs("label", { children: [_jsx(FieldTitle, { help: tr('botDefaults.substituteChatsHelp'), children: tr('botDefaults.substituteChats') }), _jsx("textarea", { "data-input": "substituteChats", rows: 3, placeholder: tr('botDefaults.substituteChatsPlaceholder'), value: chatsText, disabled: busy, onChange: event => setChatsText(event.currentTarget.value) })] }) }), _jsx("div", { className: "bd-row", children: _jsxs("label", { children: [_jsx(FieldTitle, { help: tr('botDefaults.substituteExcludedChatsHelp'), children: tr('botDefaults.substituteExcludedChats') }), _jsx("textarea", { "data-input": "substituteExcludedChats", rows: 3, placeholder: tr('botDefaults.substituteExcludedChatsPlaceholder'), value: excludedChatsText, disabled: busy, onChange: event => setExcludedChatsText(event.currentTarget.value) })] }) }), _jsxs("div", { className: "bd-row bd-substitute-targets", children: [_jsx(FieldTitle, { help: tr('botDefaults.substituteTargetsHelp'), children: tr('botDefaults.substituteTargets') }), _jsxs("div", { className: "bd-substitute-target-list", "data-input": "substituteTargets", children: [targetRows.map((target, index) => (_jsxs("div", { className: "bd-substitute-target-row", children: [_jsx(DropdownField, { dataInput: `substituteTargetType-${target.key}`, className: "bd-substitute-target-type", ariaLabel: `${tr('botDefaults.substituteTargetType')} ${index + 1}`, value: target.idField, disabled: busy, options: substituteTargetIdFields.map(value => ({
1689
1871
  value,
1690
1872
  label: tr(`botDefaults.substituteTarget${value[0].toUpperCase()}${value.slice(1)}`),
1691
1873
  })), onChange: idField => {
@@ -1729,39 +1911,11 @@ function SessionCapSection(props) {
1729
1911
  const [input, setInput] = useState(initial == null ? '' : String(initial));
1730
1912
  const [status, setStatus] = useState(null);
1731
1913
  const [busy, setBusy] = useState(false);
1732
- const [overloadAlert, setOverloadAlert] = useState(props.bot.overloadAlert === true);
1733
- const [overloadBusy, setOverloadBusy] = useState(false);
1734
1914
  useEffect(() => {
1735
1915
  const next = typeof props.bot.maxLiveWorkers === 'number' ? props.bot.maxLiveWorkers : null;
1736
1916
  setCap(next);
1737
1917
  setInput(next == null ? '' : String(next));
1738
1918
  }, [props.bot.maxLiveWorkers]);
1739
- useEffect(() => {
1740
- setOverloadAlert(props.bot.overloadAlert === true);
1741
- }, [props.bot.overloadAlert]);
1742
- async function saveOverloadAlert(next) {
1743
- setOverloadBusy(true);
1744
- setStatus(null);
1745
- setOverloadAlert(next); // optimistic
1746
- try {
1747
- const res = await props.putCardPref({ overloadAlert: next });
1748
- if (res.ok && res.body.ok) {
1749
- props.patchBot(props.bot.larkAppId, { overloadAlert: next });
1750
- setStatus({ text: `✓ ${tr('botDefaults.cardPrefSaved')}`, ok: true });
1751
- }
1752
- else {
1753
- setOverloadAlert(!next); // revert
1754
- setStatus({ text: `✗ ${responseErrorText(res)}` });
1755
- }
1756
- }
1757
- catch (e) {
1758
- setOverloadAlert(!next); // revert
1759
- setStatus({ text: `✗ ${caughtErrorText(e)}` });
1760
- }
1761
- finally {
1762
- setOverloadBusy(false);
1763
- }
1764
- }
1765
1919
  async function save(value) {
1766
1920
  setStatus(null);
1767
1921
  setBusy(true);
@@ -1793,12 +1947,12 @@ function SessionCapSection(props) {
1793
1947
  }
1794
1948
  void save(parsed);
1795
1949
  }
1796
- return (_jsxs("div", { className: "bd-subsection", children: [_jsx("h4", { className: "bd-subsection-title", children: tr('botDefaults.sectionSessionCap') }), _jsxs("div", { className: "bd-row bd-quota", children: [_jsxs("label", { children: [_jsx(FieldTitle, { help: tr('botDefaults.maxLiveWorkersHelp'), children: tr('botDefaults.maxLiveWorkers') }), _jsx("input", { type: "number", min: 1, step: 1, "data-input": "maxLiveWorkers", placeholder: tr('botDefaults.maxLiveWorkersPlaceholder'), value: input, disabled: busy, onChange: event => setInput(event.currentTarget.value) })] }), _jsx("small", { "data-session-cap-state": true, children: sessionCapStateLabel(cap, tr) }), _jsx("small", { className: "bd-help bd-session-residency", children: tr('botDefaults.maxLiveWorkersUsage', {
1950
+ return (_jsxs("section", { className: "bd-section", children: [_jsx("h3", { className: "bd-section-title", children: tr('botDefaults.sectionSessionCap') }), _jsxs("div", { className: "bd-row bd-quota", children: [_jsxs("label", { children: [_jsx(FieldTitle, { help: tr('botDefaults.maxLiveWorkersHelp'), children: tr('botDefaults.maxLiveWorkers') }), _jsx("input", { type: "number", min: 1, step: 1, "data-input": "maxLiveWorkers", placeholder: tr('botDefaults.maxLiveWorkersPlaceholder'), value: input, disabled: busy, onChange: event => setInput(event.currentTarget.value) })] }), _jsx("small", { "data-session-cap-state": true, children: sessionCapStateLabel(cap, tr) }), _jsx("small", { className: "bd-help bd-session-residency", children: tr('botDefaults.maxLiveWorkersUsage', {
1797
1951
  resident,
1798
1952
  cap: effectiveCap,
1799
1953
  dormant,
1800
1954
  logical,
1801
- }) })] }), _jsxs("div", { className: "actions", children: [_jsx("button", { type: "button", className: "primary", "data-action": "save-session-cap", disabled: busy, onClick: saveInput, children: tr('botDefaults.maxLiveWorkersSave') }), _jsx("button", { type: "button", "data-action": "off-session-cap", disabled: busy, onClick: () => { setInput(''); void save(null); }, children: tr('botDefaults.maxLiveWorkersOff') }), _jsx(StatusSpan, { status: status, attr: { 'data-session-cap-status': '' } })] }), _jsx(ToggleRow, { checked: overloadAlert, disabled: overloadBusy, dataAction: "toggle-overload-alert", title: tr('botDefaults.overloadAlert'), help: tr('botDefaults.overloadAlertHelp'), onChange: checked => void saveOverloadAlert(checked) })] }));
1955
+ }) })] }), _jsxs("div", { className: "actions", children: [_jsx("button", { type: "button", className: "primary", "data-action": "save-session-cap", disabled: busy, onClick: saveInput, children: tr('botDefaults.maxLiveWorkersSave') }), _jsx("button", { type: "button", "data-action": "off-session-cap", disabled: busy, onClick: () => { setInput(''); void save(null); }, children: tr('botDefaults.maxLiveWorkersOff') }), _jsx(StatusSpan, { status: status, attr: { 'data-session-cap-status': '' } })] })] }));
1802
1956
  }
1803
1957
  function StartupCommandsSection(props) {
1804
1958
  const tr = useT();
@@ -1828,7 +1982,7 @@ function StartupCommandsSection(props) {
1828
1982
  setBusy(false);
1829
1983
  }
1830
1984
  }
1831
- return (_jsxs("div", { className: "bd-subsection", children: [_jsx("h4", { className: "bd-subsection-title", children: _jsx(FieldTitle, { help: tr('botDefaults.startupCommandsHelp'), children: tr('botDefaults.sectionStartupCommands') }) }), _jsx("textarea", { "data-input": "startupCommands", rows: 3, placeholder: tr('botDefaults.startupCommandsPlaceholder'), value: value, disabled: busy, onChange: event => setValue(event.currentTarget.value) }), _jsxs("div", { className: "actions", children: [_jsx("button", { type: "button", className: "primary", "data-action": "save-startup-commands", disabled: busy, onClick: () => void save(), children: tr('botDefaults.startupCommandsSave') }), _jsx(StatusSpan, { status: status, attr: { 'data-startup-commands-status': '' } })] })] }));
1985
+ return (_jsxs("section", { className: "bd-section", children: [_jsx("h3", { className: "bd-section-title", children: _jsx(FieldTitle, { help: tr('botDefaults.startupCommandsHelp'), children: tr('botDefaults.sectionStartupCommands') }) }), _jsx("textarea", { "data-input": "startupCommands", rows: 3, placeholder: tr('botDefaults.startupCommandsPlaceholder'), value: value, disabled: busy, onChange: event => setValue(event.currentTarget.value) }), _jsxs("div", { className: "actions", children: [_jsx("button", { type: "button", className: "primary", "data-action": "save-startup-commands", disabled: busy, onClick: () => void save(), children: tr('botDefaults.startupCommandsSave') }), _jsx(StatusSpan, { status: status, attr: { 'data-startup-commands-status': '' } })] })] }));
1832
1986
  }
1833
1987
  // Slash 命令权限:把 /botconfig 的 customPassthroughCommands(透传给 CLI)与
1834
1988
  // canTalkDaemonCommands(daemon 命令降到 canTalk)搬到 Dashboard 可视化编辑。