botmux 3.10.0 → 3.11.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 (539) hide show
  1. package/dist/.runtime-build-id +1 -1
  2. package/dist/adapters/backend/herdr-backend.d.ts +4 -3
  3. package/dist/adapters/backend/herdr-backend.d.ts.map +1 -1
  4. package/dist/adapters/backend/herdr-backend.js +11 -8
  5. package/dist/adapters/backend/herdr-backend.js.map +1 -1
  6. package/dist/adapters/backend/pty-backend.d.ts +1 -1
  7. package/dist/adapters/backend/pty-backend.d.ts.map +1 -1
  8. package/dist/adapters/backend/pty-backend.js +4 -1
  9. package/dist/adapters/backend/pty-backend.js.map +1 -1
  10. package/dist/adapters/backend/riff-backend.d.ts +29 -5
  11. package/dist/adapters/backend/riff-backend.d.ts.map +1 -1
  12. package/dist/adapters/backend/riff-backend.js +302 -31
  13. package/dist/adapters/backend/riff-backend.js.map +1 -1
  14. package/dist/adapters/backend/sandbox.d.ts +6 -0
  15. package/dist/adapters/backend/sandbox.d.ts.map +1 -1
  16. package/dist/adapters/backend/sandbox.js +7 -0
  17. package/dist/adapters/backend/sandbox.js.map +1 -1
  18. package/dist/adapters/backend/tmux-backend.d.ts +1 -1
  19. package/dist/adapters/backend/tmux-backend.d.ts.map +1 -1
  20. package/dist/adapters/backend/tmux-backend.js +4 -1
  21. package/dist/adapters/backend/tmux-backend.js.map +1 -1
  22. package/dist/adapters/backend/tmux-pipe-backend.d.ts +1 -1
  23. package/dist/adapters/backend/tmux-pipe-backend.d.ts.map +1 -1
  24. package/dist/adapters/backend/tmux-pipe-backend.js +1 -1
  25. package/dist/adapters/backend/tmux-pipe-backend.js.map +1 -1
  26. package/dist/adapters/backend/types.d.ts +37 -3
  27. package/dist/adapters/backend/types.d.ts.map +1 -1
  28. package/dist/adapters/backend/types.js.map +1 -1
  29. package/dist/adapters/backend/zellij-backend.d.ts +3 -3
  30. package/dist/adapters/backend/zellij-backend.d.ts.map +1 -1
  31. package/dist/adapters/backend/zellij-backend.js +9 -3
  32. package/dist/adapters/backend/zellij-backend.js.map +1 -1
  33. package/dist/adapters/backend/zellij-observe-backend.d.ts +3 -3
  34. package/dist/adapters/backend/zellij-observe-backend.d.ts.map +1 -1
  35. package/dist/adapters/backend/zellij-observe-backend.js +12 -7
  36. package/dist/adapters/backend/zellij-observe-backend.js.map +1 -1
  37. package/dist/adapters/cli/codex-app.d.ts.map +1 -1
  38. package/dist/adapters/cli/codex-app.js +11 -2
  39. package/dist/adapters/cli/codex-app.js.map +1 -1
  40. package/dist/adapters/cli/read-isolation.d.ts +35 -2
  41. package/dist/adapters/cli/read-isolation.d.ts.map +1 -1
  42. package/dist/adapters/cli/read-isolation.js +88 -7
  43. package/dist/adapters/cli/read-isolation.js.map +1 -1
  44. package/dist/adapters/cli/runner-input.d.ts +15 -14
  45. package/dist/adapters/cli/runner-input.d.ts.map +1 -1
  46. package/dist/adapters/cli/runner-input.js +64 -26
  47. package/dist/adapters/cli/runner-input.js.map +1 -1
  48. package/dist/adapters/cli/types.d.ts +20 -5
  49. package/dist/adapters/cli/types.d.ts.map +1 -1
  50. package/dist/bot-registry.d.ts +24 -0
  51. package/dist/bot-registry.d.ts.map +1 -1
  52. package/dist/bot-registry.js +110 -5
  53. package/dist/bot-registry.js.map +1 -1
  54. package/dist/cli/fleet-shutdown.d.ts +47 -0
  55. package/dist/cli/fleet-shutdown.d.ts.map +1 -0
  56. package/dist/cli/fleet-shutdown.js +387 -0
  57. package/dist/cli/fleet-shutdown.js.map +1 -0
  58. package/dist/cli/pm2-descriptor-guard.d.ts +19 -0
  59. package/dist/cli/pm2-descriptor-guard.d.ts.map +1 -0
  60. package/dist/cli/pm2-descriptor-guard.js +122 -0
  61. package/dist/cli/pm2-descriptor-guard.js.map +1 -0
  62. package/dist/cli/pm2-exact-start.d.ts +16 -0
  63. package/dist/cli/pm2-exact-start.d.ts.map +1 -0
  64. package/dist/cli/pm2-exact-start.js +63 -0
  65. package/dist/cli/pm2-exact-start.js.map +1 -0
  66. package/dist/cli/pm2-god-admission.d.ts +8 -0
  67. package/dist/cli/pm2-god-admission.d.ts.map +1 -0
  68. package/dist/cli/pm2-god-admission.js +25 -0
  69. package/dist/cli/pm2-god-admission.js.map +1 -0
  70. package/dist/cli/pm2-jlist.d.ts +13 -0
  71. package/dist/cli/pm2-jlist.d.ts.map +1 -0
  72. package/dist/cli/pm2-jlist.js +108 -0
  73. package/dist/cli/pm2-jlist.js.map +1 -0
  74. package/dist/cli/pm2-preflight.d.ts +10 -0
  75. package/dist/cli/pm2-preflight.d.ts.map +1 -0
  76. package/dist/cli/pm2-preflight.js +23 -0
  77. package/dist/cli/pm2-preflight.js.map +1 -0
  78. package/dist/cli/pm2-shutdown-capability.d.ts +27 -0
  79. package/dist/cli/pm2-shutdown-capability.d.ts.map +1 -0
  80. package/dist/cli/pm2-shutdown-capability.js +161 -0
  81. package/dist/cli/pm2-shutdown-capability.js.map +1 -0
  82. package/dist/cli/pm2-start-transaction.d.ts +55 -0
  83. package/dist/cli/pm2-start-transaction.d.ts.map +1 -0
  84. package/dist/cli/pm2-start-transaction.js +220 -0
  85. package/dist/cli/pm2-start-transaction.js.map +1 -0
  86. package/dist/cli/send-dispatch.d.ts +12 -0
  87. package/dist/cli/send-dispatch.d.ts.map +1 -1
  88. package/dist/cli/send-dispatch.js +31 -4
  89. package/dist/cli/send-dispatch.js.map +1 -1
  90. package/dist/cli/session-list-liveness.d.ts +1 -0
  91. package/dist/cli/session-list-liveness.d.ts.map +1 -1
  92. package/dist/cli/session-list-liveness.js +6 -0
  93. package/dist/cli/session-list-liveness.js.map +1 -1
  94. package/dist/cli/session-picker-layout.d.ts +26 -0
  95. package/dist/cli/session-picker-layout.d.ts.map +1 -0
  96. package/dist/cli/session-picker-layout.js +123 -0
  97. package/dist/cli/session-picker-layout.js.map +1 -0
  98. package/dist/cli/session-picker-viewport.d.ts +49 -0
  99. package/dist/cli/session-picker-viewport.d.ts.map +1 -0
  100. package/dist/cli/session-picker-viewport.js +46 -0
  101. package/dist/cli/session-picker-viewport.js.map +1 -0
  102. package/dist/cli/supervisor-shutdown-client.d.ts +31 -0
  103. package/dist/cli/supervisor-shutdown-client.d.ts.map +1 -0
  104. package/dist/cli/supervisor-shutdown-client.js +146 -0
  105. package/dist/cli/supervisor-shutdown-client.js.map +1 -0
  106. package/dist/cli/terminal-width.d.ts +48 -0
  107. package/dist/cli/terminal-width.d.ts.map +1 -0
  108. package/dist/cli/terminal-width.js +119 -0
  109. package/dist/cli/terminal-width.js.map +1 -0
  110. package/dist/cli/vc-agent.d.ts.map +1 -1
  111. package/dist/cli/vc-agent.js +1 -1
  112. package/dist/cli/vc-agent.js.map +1 -1
  113. package/dist/cli.d.ts.map +1 -1
  114. package/dist/cli.js +2269 -716
  115. package/dist/cli.js.map +1 -1
  116. package/dist/codex-app-runner.js +1630 -125
  117. package/dist/codex-app-runner.js.map +1 -1
  118. package/dist/core/ask-api.d.ts +8 -1
  119. package/dist/core/ask-api.d.ts.map +1 -1
  120. package/dist/core/ask-api.js +18 -0
  121. package/dist/core/ask-api.js.map +1 -1
  122. package/dist/core/ask-broker.d.ts +20 -0
  123. package/dist/core/ask-broker.d.ts.map +1 -1
  124. package/dist/core/ask-broker.js +467 -47
  125. package/dist/core/ask-broker.js.map +1 -1
  126. package/dist/core/ask-persist-store.d.ts +126 -0
  127. package/dist/core/ask-persist-store.d.ts.map +1 -0
  128. package/dist/core/ask-persist-store.js +188 -0
  129. package/dist/core/ask-persist-store.js.map +1 -0
  130. package/dist/core/ask-types.d.ts +80 -0
  131. package/dist/core/ask-types.d.ts.map +1 -1
  132. package/dist/core/ask-types.js +62 -0
  133. package/dist/core/ask-types.js.map +1 -1
  134. package/dist/core/cli-session-id-publisher.d.ts +20 -0
  135. package/dist/core/cli-session-id-publisher.d.ts.map +1 -0
  136. package/dist/core/cli-session-id-publisher.js +21 -0
  137. package/dist/core/cli-session-id-publisher.js.map +1 -0
  138. package/dist/core/command-handler.d.ts.map +1 -1
  139. package/dist/core/command-handler.js +427 -255
  140. package/dist/core/command-handler.js.map +1 -1
  141. package/dist/core/cost-calculator.d.ts +13 -0
  142. package/dist/core/cost-calculator.d.ts.map +1 -1
  143. package/dist/core/cost-calculator.js +385 -26
  144. package/dist/core/cost-calculator.js.map +1 -1
  145. package/dist/core/dashboard-ipc-server.d.ts +9 -0
  146. package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
  147. package/dist/core/dashboard-ipc-server.js +842 -288
  148. package/dist/core/dashboard-ipc-server.js.map +1 -1
  149. package/dist/core/explicit-session-backing-cleanup.d.ts +49 -0
  150. package/dist/core/explicit-session-backing-cleanup.d.ts.map +1 -0
  151. package/dist/core/explicit-session-backing-cleanup.js +76 -0
  152. package/dist/core/explicit-session-backing-cleanup.js.map +1 -0
  153. package/dist/core/idle-worker-sweeper.d.ts +20 -0
  154. package/dist/core/idle-worker-sweeper.d.ts.map +1 -1
  155. package/dist/core/idle-worker-sweeper.js +18 -0
  156. package/dist/core/idle-worker-sweeper.js.map +1 -1
  157. package/dist/core/inflight-input-tracker.d.ts +10 -0
  158. package/dist/core/inflight-input-tracker.d.ts.map +1 -1
  159. package/dist/core/inflight-input-tracker.js +7 -0
  160. package/dist/core/inflight-input-tracker.js.map +1 -1
  161. package/dist/core/managed-origin-attestation.d.ts +51 -0
  162. package/dist/core/managed-origin-attestation.d.ts.map +1 -0
  163. package/dist/core/managed-origin-attestation.js +208 -0
  164. package/dist/core/managed-origin-attestation.js.map +1 -0
  165. package/dist/core/managed-origin-capability.d.ts +62 -3
  166. package/dist/core/managed-origin-capability.d.ts.map +1 -1
  167. package/dist/core/managed-origin-capability.js +419 -9
  168. package/dist/core/managed-origin-capability.js.map +1 -1
  169. package/dist/core/pending-repo-journal.d.ts +6 -0
  170. package/dist/core/pending-repo-journal.d.ts.map +1 -0
  171. package/dist/core/pending-repo-journal.js +85 -0
  172. package/dist/core/pending-repo-journal.js.map +1 -0
  173. package/dist/core/persistent-backend.d.ts +6 -1
  174. package/dist/core/persistent-backend.d.ts.map +1 -1
  175. package/dist/core/persistent-backend.js +12 -6
  176. package/dist/core/persistent-backend.js.map +1 -1
  177. package/dist/core/process-start-identity.d.ts +3 -0
  178. package/dist/core/process-start-identity.d.ts.map +1 -0
  179. package/dist/core/process-start-identity.js +62 -0
  180. package/dist/core/process-start-identity.js.map +1 -0
  181. package/dist/core/raw-command-writer.d.ts +34 -0
  182. package/dist/core/raw-command-writer.d.ts.map +1 -0
  183. package/dist/core/raw-command-writer.js +48 -0
  184. package/dist/core/raw-command-writer.js.map +1 -0
  185. package/dist/core/reply-target.d.ts +85 -22
  186. package/dist/core/reply-target.d.ts.map +1 -1
  187. package/dist/core/reply-target.js +267 -32
  188. package/dist/core/reply-target.js.map +1 -1
  189. package/dist/core/resource-monitor/runtime.d.ts.map +1 -1
  190. package/dist/core/resource-monitor/runtime.js +4 -1
  191. package/dist/core/resource-monitor/runtime.js.map +1 -1
  192. package/dist/core/restart-report.d.ts +6 -1
  193. package/dist/core/restart-report.d.ts.map +1 -1
  194. package/dist/core/restart-report.js +22 -4
  195. package/dist/core/restart-report.js.map +1 -1
  196. package/dist/core/riff-shutdown-detach.d.ts +164 -0
  197. package/dist/core/riff-shutdown-detach.d.ts.map +1 -0
  198. package/dist/core/riff-shutdown-detach.js +787 -0
  199. package/dist/core/riff-shutdown-detach.js.map +1 -0
  200. package/dist/core/riff-worker-shutdown-readiness.d.ts +17 -0
  201. package/dist/core/riff-worker-shutdown-readiness.d.ts.map +1 -0
  202. package/dist/core/riff-worker-shutdown-readiness.js +21 -0
  203. package/dist/core/riff-worker-shutdown-readiness.js.map +1 -0
  204. package/dist/core/session-manager.d.ts +6 -6
  205. package/dist/core/session-manager.d.ts.map +1 -1
  206. package/dist/core/session-manager.js +1227 -594
  207. package/dist/core/session-manager.js.map +1 -1
  208. package/dist/core/session-marker.d.ts +1 -1
  209. package/dist/core/session-marker.d.ts.map +1 -1
  210. package/dist/core/session-marker.js +2 -2
  211. package/dist/core/session-marker.js.map +1 -1
  212. package/dist/core/session-mutation-guard.d.ts +17 -0
  213. package/dist/core/session-mutation-guard.d.ts.map +1 -0
  214. package/dist/core/session-mutation-guard.js +33 -0
  215. package/dist/core/session-mutation-guard.js.map +1 -0
  216. package/dist/core/shutdown-budgets.d.ts +27 -0
  217. package/dist/core/shutdown-budgets.d.ts.map +1 -0
  218. package/dist/core/shutdown-budgets.js +47 -0
  219. package/dist/core/shutdown-budgets.js.map +1 -0
  220. package/dist/core/supervisor-shutdown-ipc.d.ts +10 -0
  221. package/dist/core/supervisor-shutdown-ipc.d.ts.map +1 -0
  222. package/dist/core/supervisor-shutdown-ipc.js +10 -0
  223. package/dist/core/supervisor-shutdown-ipc.js.map +1 -0
  224. package/dist/core/supervisor-shutdown-protocol.d.ts +16 -0
  225. package/dist/core/supervisor-shutdown-protocol.d.ts.map +1 -0
  226. package/dist/core/supervisor-shutdown-protocol.js +16 -0
  227. package/dist/core/supervisor-shutdown-protocol.js.map +1 -0
  228. package/dist/core/trigger-final-suppression.d.ts +4 -0
  229. package/dist/core/trigger-final-suppression.d.ts.map +1 -1
  230. package/dist/core/trigger-final-suppression.js +6 -11
  231. package/dist/core/trigger-final-suppression.js.map +1 -1
  232. package/dist/core/trigger-session.d.ts +70 -0
  233. package/dist/core/trigger-session.d.ts.map +1 -1
  234. package/dist/core/trigger-session.js +923 -145
  235. package/dist/core/trigger-session.js.map +1 -1
  236. package/dist/core/types.d.ts +94 -1
  237. package/dist/core/types.d.ts.map +1 -1
  238. package/dist/core/types.js +9 -0
  239. package/dist/core/types.js.map +1 -1
  240. package/dist/core/worker-pool.d.ts +194 -13
  241. package/dist/core/worker-pool.d.ts.map +1 -1
  242. package/dist/core/worker-pool.js +2597 -547
  243. package/dist/core/worker-pool.js.map +1 -1
  244. package/dist/daemon.d.ts +76 -2
  245. package/dist/daemon.d.ts.map +1 -1
  246. package/dist/daemon.js +2255 -773
  247. package/dist/daemon.js.map +1 -1
  248. package/dist/dashboard/bot-payload.d.ts +20 -0
  249. package/dist/dashboard/bot-payload.d.ts.map +1 -1
  250. package/dist/dashboard/bot-payload.js +24 -0
  251. package/dist/dashboard/bot-payload.js.map +1 -1
  252. package/dist/dashboard/feed-groups.d.ts +17 -0
  253. package/dist/dashboard/feed-groups.d.ts.map +1 -0
  254. package/dist/dashboard/feed-groups.js +75 -0
  255. package/dist/dashboard/feed-groups.js.map +1 -0
  256. package/dist/dashboard/session-card-model.d.ts +1 -1
  257. package/dist/dashboard/session-card-model.d.ts.map +1 -1
  258. package/dist/dashboard/session-card-model.js +8 -5
  259. package/dist/dashboard/session-card-model.js.map +1 -1
  260. package/dist/dashboard/web/bot-defaults-page.d.ts +4 -0
  261. package/dist/dashboard/web/bot-defaults-page.d.ts.map +1 -1
  262. package/dist/dashboard/web/bot-defaults-page.js +139 -46
  263. package/dist/dashboard/web/bot-defaults-page.js.map +1 -1
  264. package/dist/dashboard/web/bot-defaults.d.ts +4 -0
  265. package/dist/dashboard/web/bot-defaults.d.ts.map +1 -1
  266. package/dist/dashboard/web/bot-defaults.js.map +1 -1
  267. package/dist/dashboard/web/connectors-page.d.ts.map +1 -1
  268. package/dist/dashboard/web/connectors-page.js +40 -3
  269. package/dist/dashboard/web/connectors-page.js.map +1 -1
  270. package/dist/dashboard/web/groups-page.d.ts.map +1 -1
  271. package/dist/dashboard/web/groups-page.js +95 -2
  272. package/dist/dashboard/web/groups-page.js.map +1 -1
  273. package/dist/dashboard/web/i18n.d.ts.map +1 -1
  274. package/dist/dashboard/web/i18n.js +86 -40
  275. package/dist/dashboard/web/i18n.js.map +1 -1
  276. package/dist/dashboard/web/kanban-model.js +1 -1
  277. package/dist/dashboard/web/kanban-model.js.map +1 -1
  278. package/dist/dashboard/web/overview-page.d.ts.map +1 -1
  279. package/dist/dashboard/web/overview-page.js +3 -2
  280. package/dist/dashboard/web/overview-page.js.map +1 -1
  281. package/dist/dashboard/web/overview.d.ts +3 -0
  282. package/dist/dashboard/web/overview.d.ts.map +1 -1
  283. package/dist/dashboard/web/overview.js +2 -0
  284. package/dist/dashboard/web/overview.js.map +1 -1
  285. package/dist/dashboard/web/sessions-kanban.d.ts.map +1 -1
  286. package/dist/dashboard/web/sessions-kanban.js +2 -0
  287. package/dist/dashboard/web/sessions-kanban.js.map +1 -1
  288. package/dist/dashboard/web/sessions-page.d.ts.map +1 -1
  289. package/dist/dashboard/web/sessions-page.js +103 -2
  290. package/dist/dashboard/web/sessions-page.js.map +1 -1
  291. package/dist/dashboard/web/sessions.d.ts.map +1 -1
  292. package/dist/dashboard/web/sessions.js +3 -2
  293. package/dist/dashboard/web/sessions.js.map +1 -1
  294. package/dist/dashboard/web/ui.d.ts +8 -0
  295. package/dist/dashboard/web/ui.d.ts.map +1 -1
  296. package/dist/dashboard/web/ui.js +15 -0
  297. package/dist/dashboard/web/ui.js.map +1 -1
  298. package/dist/dashboard-web/app.js +1 -1
  299. package/dist/dashboard-web/chunks/bot-defaults-page-GED4FEMS.js +10 -0
  300. package/dist/dashboard-web/chunks/chunk-6J5LS5AU.js +51 -0
  301. package/dist/dashboard-web/chunks/{chunk-ZU3UUKAR.js → chunk-HK7NIBJG.js} +1 -1
  302. package/dist/dashboard-web/chunks/{chunk-3UE7S77S.js → chunk-KRHWZEXU.js} +1 -1
  303. package/dist/dashboard-web/chunks/chunk-VBXJOJFH.js +1 -0
  304. package/dist/dashboard-web/chunks/connectors-page-EELM66G3.js +1 -0
  305. package/dist/dashboard-web/chunks/groups-page-WKUV6E42.js +8 -0
  306. package/dist/dashboard-web/chunks/{insights-page-T2ZX2RWL.js → insights-page-54UBPPOC.js} +1 -1
  307. package/dist/dashboard-web/chunks/{monitor-room-YNVBAGR6.js → monitor-room-PORHVKRH.js} +1 -1
  308. package/dist/dashboard-web/chunks/{monitoring-page-LHM55YWN.js → monitoring-page-XGA7AXNL.js} +1 -1
  309. package/dist/dashboard-web/chunks/{office-page-ATXVP7PW.js → office-page-AO3AFG45.js} +1 -1
  310. package/dist/dashboard-web/chunks/overview-page-F5BUTYR6.js +1 -0
  311. package/dist/dashboard-web/chunks/{roles-page-56VWM6CD.js → roles-page-M5GIASJU.js} +1 -1
  312. package/dist/dashboard-web/chunks/{schedules-page-S5K6U4EO.js → schedules-page-O232WQRR.js} +1 -1
  313. package/dist/dashboard-web/chunks/sessions-page-YFRPSTIL.js +6 -0
  314. package/dist/dashboard-web/chunks/{settings-page-QUZDQARR.js → settings-page-OJAZLZQT.js} +1 -1
  315. package/dist/dashboard-web/chunks/{skills-page-IFY7AEND.js → skills-page-EFZQPWV4.js} +1 -1
  316. package/dist/dashboard-web/chunks/{team-federation-page-C7FJQPFZ.js → team-federation-page-ZJVAP7HW.js} +1 -1
  317. package/dist/dashboard-web/chunks/{v3-page-2LMF3WWR.js → v3-page-GYWTRGO2.js} +1 -1
  318. package/dist/dashboard-web/chunks/{whiteboards-page-3XC6QRMY.js → whiteboards-page-MSDAG6P7.js} +1 -1
  319. package/dist/dashboard-web/style.css +255 -0
  320. package/dist/dashboard.js +172 -7
  321. package/dist/dashboard.js.map +1 -1
  322. package/dist/desktop/renderer/app.js +21 -0
  323. package/dist/desktop/renderer/app.js.map +1 -1
  324. package/dist/i18n/en.d.ts.map +1 -1
  325. package/dist/i18n/en.js +35 -9
  326. package/dist/i18n/en.js.map +1 -1
  327. package/dist/i18n/zh.d.ts.map +1 -1
  328. package/dist/i18n/zh.js +35 -9
  329. package/dist/i18n/zh.js.map +1 -1
  330. package/dist/im/lark/ask-card.d.ts +23 -0
  331. package/dist/im/lark/ask-card.d.ts.map +1 -1
  332. package/dist/im/lark/ask-card.js +94 -4
  333. package/dist/im/lark/ask-card.js.map +1 -1
  334. package/dist/im/lark/card-builder.d.ts +6 -1
  335. package/dist/im/lark/card-builder.d.ts.map +1 -1
  336. package/dist/im/lark/card-builder.js +112 -15
  337. package/dist/im/lark/card-builder.js.map +1 -1
  338. package/dist/im/lark/card-handler.d.ts +1 -1
  339. package/dist/im/lark/card-handler.d.ts.map +1 -1
  340. package/dist/im/lark/card-handler.js +496 -310
  341. package/dist/im/lark/card-handler.js.map +1 -1
  342. package/dist/im/lark/client.d.ts +7 -0
  343. package/dist/im/lark/client.d.ts.map +1 -1
  344. package/dist/im/lark/client.js +39 -26
  345. package/dist/im/lark/client.js.map +1 -1
  346. package/dist/im/lark/doc-comment.d.ts +7 -4
  347. package/dist/im/lark/doc-comment.d.ts.map +1 -1
  348. package/dist/im/lark/doc-comment.js +19 -6
  349. package/dist/im/lark/doc-comment.js.map +1 -1
  350. package/dist/im/lark/event-dispatcher.d.ts +16 -0
  351. package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
  352. package/dist/im/lark/event-dispatcher.js +88 -23
  353. package/dist/im/lark/event-dispatcher.js.map +1 -1
  354. package/dist/im/lark/forward-followup-content.d.ts.map +1 -1
  355. package/dist/im/lark/forward-followup-content.js +9 -1
  356. package/dist/im/lark/forward-followup-content.js.map +1 -1
  357. package/dist/im/lark/grant-command.d.ts.map +1 -1
  358. package/dist/im/lark/grant-command.js +7 -4
  359. package/dist/im/lark/grant-command.js.map +1 -1
  360. package/dist/im/lark/md-card.d.ts +11 -0
  361. package/dist/im/lark/md-card.d.ts.map +1 -1
  362. package/dist/im/lark/md-card.js +46 -0
  363. package/dist/im/lark/md-card.js.map +1 -1
  364. package/dist/im/lark/message-parser.d.ts +23 -2
  365. package/dist/im/lark/message-parser.d.ts.map +1 -1
  366. package/dist/im/lark/message-parser.js +58 -3
  367. package/dist/im/lark/message-parser.js.map +1 -1
  368. package/dist/im/lark/overview-card.d.ts.map +1 -1
  369. package/dist/im/lark/overview-card.js +2 -1
  370. package/dist/im/lark/overview-card.js.map +1 -1
  371. package/dist/services/async-trigger-state.d.ts +6 -1
  372. package/dist/services/async-trigger-state.d.ts.map +1 -1
  373. package/dist/services/async-trigger-state.js +21 -0
  374. package/dist/services/async-trigger-state.js.map +1 -1
  375. package/dist/services/async-trigger-store.d.ts +23 -1
  376. package/dist/services/async-trigger-store.d.ts.map +1 -1
  377. package/dist/services/async-trigger-store.js +96 -13
  378. package/dist/services/async-trigger-store.js.map +1 -1
  379. package/dist/services/bridge-fallback-gate.d.ts +40 -0
  380. package/dist/services/bridge-fallback-gate.d.ts.map +1 -1
  381. package/dist/services/bridge-fallback-gate.js +124 -24
  382. package/dist/services/bridge-fallback-gate.js.map +1 -1
  383. package/dist/services/codex-app-runner-protocol.d.ts +8 -0
  384. package/dist/services/codex-app-runner-protocol.d.ts.map +1 -1
  385. package/dist/services/codex-app-runner-protocol.js +9 -2
  386. package/dist/services/codex-app-runner-protocol.js.map +1 -1
  387. package/dist/services/codex-bridge-queue.d.ts +1 -0
  388. package/dist/services/codex-bridge-queue.d.ts.map +1 -1
  389. package/dist/services/codex-bridge-queue.js +1 -0
  390. package/dist/services/codex-bridge-queue.js.map +1 -1
  391. package/dist/services/codex-service-tier.d.ts +2 -0
  392. package/dist/services/codex-service-tier.d.ts.map +1 -1
  393. package/dist/services/codex-service-tier.js +1 -0
  394. package/dist/services/codex-service-tier.js.map +1 -1
  395. package/dist/services/codex-transcript.d.ts +27 -0
  396. package/dist/services/codex-transcript.d.ts.map +1 -1
  397. package/dist/services/codex-transcript.js +340 -2
  398. package/dist/services/codex-transcript.js.map +1 -1
  399. package/dist/services/grant-policy.d.ts +3 -0
  400. package/dist/services/grant-policy.d.ts.map +1 -1
  401. package/dist/services/grant-policy.js +5 -0
  402. package/dist/services/grant-policy.js.map +1 -1
  403. package/dist/services/grant-prefs-store.d.ts +6 -3
  404. package/dist/services/grant-prefs-store.d.ts.map +1 -1
  405. package/dist/services/grant-prefs-store.js +42 -12
  406. package/dist/services/grant-prefs-store.js.map +1 -1
  407. package/dist/services/hook-runner.d.ts +20 -1
  408. package/dist/services/hook-runner.d.ts.map +1 -1
  409. package/dist/services/hook-runner.js +17 -13
  410. package/dist/services/hook-runner.js.map +1 -1
  411. package/dist/services/idempotency-store.d.ts +134 -0
  412. package/dist/services/idempotency-store.d.ts.map +1 -0
  413. package/dist/services/idempotency-store.js +299 -0
  414. package/dist/services/idempotency-store.js.map +1 -0
  415. package/dist/services/jsonl-cursor.d.ts +7 -3
  416. package/dist/services/jsonl-cursor.d.ts.map +1 -1
  417. package/dist/services/jsonl-cursor.js +55 -31
  418. package/dist/services/jsonl-cursor.js.map +1 -1
  419. package/dist/services/open-platform-rename.d.ts.map +1 -1
  420. package/dist/services/open-platform-rename.js +1 -108
  421. package/dist/services/open-platform-rename.js.map +1 -1
  422. package/dist/services/restart-intent-store.d.ts +22 -2
  423. package/dist/services/restart-intent-store.d.ts.map +1 -1
  424. package/dist/services/restart-intent-store.js +160 -18
  425. package/dist/services/restart-intent-store.js.map +1 -1
  426. package/dist/services/sandbox-store.d.ts +22 -0
  427. package/dist/services/sandbox-store.d.ts.map +1 -1
  428. package/dist/services/sandbox-store.js +37 -8
  429. package/dist/services/sandbox-store.js.map +1 -1
  430. package/dist/services/send-policy.d.ts +41 -33
  431. package/dist/services/send-policy.d.ts.map +1 -1
  432. package/dist/services/send-policy.js +39 -40
  433. package/dist/services/send-policy.js.map +1 -1
  434. package/dist/services/session-store.d.ts +66 -0
  435. package/dist/services/session-store.d.ts.map +1 -1
  436. package/dist/services/session-store.js +403 -67
  437. package/dist/services/session-store.js.map +1 -1
  438. package/dist/services/submit-notification.d.ts +3 -0
  439. package/dist/services/submit-notification.d.ts.map +1 -0
  440. package/dist/services/submit-notification.js +15 -0
  441. package/dist/services/submit-notification.js.map +1 -0
  442. package/dist/services/traex-transcript.d.ts +25 -2
  443. package/dist/services/traex-transcript.d.ts.map +1 -1
  444. package/dist/services/traex-transcript.js +133 -1
  445. package/dist/services/traex-transcript.js.map +1 -1
  446. package/dist/services/trigger-types.d.ts +13 -1
  447. package/dist/services/trigger-types.d.ts.map +1 -1
  448. package/dist/services/trigger-types.js +39 -0
  449. package/dist/services/trigger-types.js.map +1 -1
  450. package/dist/services/voice/index.d.ts +3 -2
  451. package/dist/services/voice/index.d.ts.map +1 -1
  452. package/dist/services/voice/index.js +5 -5
  453. package/dist/services/voice/index.js.map +1 -1
  454. package/dist/services/voice/openai.d.ts +2 -1
  455. package/dist/services/voice/openai.d.ts.map +1 -1
  456. package/dist/services/voice/openai.js +2 -1
  457. package/dist/services/voice/openai.js.map +1 -1
  458. package/dist/services/voice/sami.d.ts +5 -2
  459. package/dist/services/voice/sami.d.ts.map +1 -1
  460. package/dist/services/voice/sami.js +19 -4
  461. package/dist/services/voice/sami.js.map +1 -1
  462. package/dist/setup/bots-store.d.ts.map +1 -1
  463. package/dist/setup/bots-store.js +10 -4
  464. package/dist/setup/bots-store.js.map +1 -1
  465. package/dist/setup/lark-scopes.json +2 -0
  466. package/dist/setup/open-platform-automation.d.ts +9 -1
  467. package/dist/setup/open-platform-automation.d.ts.map +1 -1
  468. package/dist/setup/open-platform-automation.js +44 -15
  469. package/dist/setup/open-platform-automation.js.map +1 -1
  470. package/dist/setup/open-platform-visibility.d.ts +42 -0
  471. package/dist/setup/open-platform-visibility.d.ts.map +1 -0
  472. package/dist/setup/open-platform-visibility.js +133 -0
  473. package/dist/setup/open-platform-visibility.js.map +1 -0
  474. package/dist/setup/verify-permissions.d.ts.map +1 -1
  475. package/dist/setup/verify-permissions.js +6 -0
  476. package/dist/setup/verify-permissions.js.map +1 -1
  477. package/dist/skills/definitions.js +2 -2
  478. package/dist/types.d.ts +290 -13
  479. package/dist/types.d.ts.map +1 -1
  480. package/dist/utils/bot-routing.d.ts +1 -0
  481. package/dist/utils/bot-routing.d.ts.map +1 -1
  482. package/dist/utils/bot-routing.js +1 -1
  483. package/dist/utils/bot-routing.js.map +1 -1
  484. package/dist/utils/child-env.d.ts +1 -1
  485. package/dist/utils/child-env.d.ts.map +1 -1
  486. package/dist/utils/child-env.js +9 -0
  487. package/dist/utils/child-env.js.map +1 -1
  488. package/dist/utils/codex-app-control.d.ts +438 -0
  489. package/dist/utils/codex-app-control.d.ts.map +1 -0
  490. package/dist/utils/codex-app-control.js +2336 -0
  491. package/dist/utils/codex-app-control.js.map +1 -0
  492. package/dist/utils/codex-app-dispatch-ledger.d.ts +78 -0
  493. package/dist/utils/codex-app-dispatch-ledger.d.ts.map +1 -0
  494. package/dist/utils/codex-app-dispatch-ledger.js +149 -0
  495. package/dist/utils/codex-app-dispatch-ledger.js.map +1 -0
  496. package/dist/utils/codex-app-turn-dispatch.d.ts +77 -0
  497. package/dist/utils/codex-app-turn-dispatch.d.ts.map +1 -0
  498. package/dist/utils/codex-app-turn-dispatch.js +141 -0
  499. package/dist/utils/codex-app-turn-dispatch.js.map +1 -0
  500. package/dist/utils/codex-app-turn-liveness.d.ts +125 -0
  501. package/dist/utils/codex-app-turn-liveness.d.ts.map +1 -0
  502. package/dist/utils/codex-app-turn-liveness.js +301 -0
  503. package/dist/utils/codex-app-turn-liveness.js.map +1 -0
  504. package/dist/utils/idle-detector.d.ts +12 -0
  505. package/dist/utils/idle-detector.d.ts.map +1 -1
  506. package/dist/utils/idle-detector.js +19 -0
  507. package/dist/utils/idle-detector.js.map +1 -1
  508. package/dist/utils/input-gate.d.ts +87 -0
  509. package/dist/utils/input-gate.d.ts.map +1 -1
  510. package/dist/utils/input-gate.js +86 -0
  511. package/dist/utils/input-gate.js.map +1 -1
  512. package/dist/utils/lark-upload.d.ts.map +1 -1
  513. package/dist/utils/lark-upload.js +52 -1
  514. package/dist/utils/lark-upload.js.map +1 -1
  515. package/dist/utils/pending-input-queue.d.ts +15 -0
  516. package/dist/utils/pending-input-queue.d.ts.map +1 -1
  517. package/dist/utils/pending-input-queue.js +5 -1
  518. package/dist/utils/pending-input-queue.js.map +1 -1
  519. package/dist/utils/user-token.d.ts.map +1 -1
  520. package/dist/utils/user-token.js +53 -2
  521. package/dist/utils/user-token.js.map +1 -1
  522. package/dist/worker-ipc-preload.d.ts +12 -0
  523. package/dist/worker-ipc-preload.d.ts.map +1 -0
  524. package/dist/worker-ipc-preload.js +44 -0
  525. package/dist/worker-ipc-preload.js.map +1 -0
  526. package/dist/worker.js +2604 -325
  527. package/dist/worker.js.map +1 -1
  528. package/dist/workflows/v3/session-relay-client.d.ts +1 -0
  529. package/dist/workflows/v3/session-relay-client.d.ts.map +1 -1
  530. package/dist/workflows/v3/session-relay-client.js +12 -3
  531. package/dist/workflows/v3/session-relay-client.js.map +1 -1
  532. package/package.json +1 -1
  533. package/dist/dashboard-web/chunks/bot-defaults-page-LTVOUDIS.js +0 -10
  534. package/dist/dashboard-web/chunks/chunk-DCS35UMD.js +0 -1
  535. package/dist/dashboard-web/chunks/chunk-MFQPCVHY.js +0 -51
  536. package/dist/dashboard-web/chunks/connectors-page-5KWDIMKC.js +0 -1
  537. package/dist/dashboard-web/chunks/groups-page-FHOKYXMW.js +0 -8
  538. package/dist/dashboard-web/chunks/overview-page-QYI3KBDD.js +0 -1
  539. package/dist/dashboard-web/chunks/sessions-page-WBP4N7D2.js +0 -6
@@ -1,12 +1,14 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
+ import { createPortal } from 'react-dom';
3
4
  import { openBotOnboarding } from './bot-onboarding.js';
4
5
  import { agentSelectionKey, cliIdOf, createRefreshGate, displayCliId, fallbackCliOptionsState, fetchBotDefaults, fetchCliOptions, fmtSince, modelSuggestionsForOption, resolveSubstituteTarget, selectedCliOption, } from './bot-defaults.js';
5
6
  import { mountReactPage } from './react-mount.js';
6
7
  import { useT } from './react-hooks.js';
7
8
  import { store } from './store.js';
8
9
  import { CreateActionButton, DropdownMenu, Html, InfoTip as BaseInfoTip, LoadingState, OverflowText, RefreshIconButton, dropdownLabel, } from './dashboard-components.js';
9
- import { botAvatarHtml, loadNameMaps, overrideBotAvatar, ui } from './ui.js';
10
+ import { botAvatarHtml, larkConsoleUrl, loadNameMaps, overrideBotAvatar, ui } from './ui.js';
11
+ import { DEFAULT_GRANT_DURATION_MS, DEFAULT_GRANT_QUOTA, GRANT_DURATION_OPTIONS, MAX_GRANT_QUOTA, } from '../../services/grant-policy.js';
10
12
  function runtimeDraftFromBot(bot) {
11
13
  const runtime = bot.cliRuntime;
12
14
  if (!runtime || typeof runtime !== 'object') {
@@ -177,7 +179,7 @@ function statusClass(status, extra = '') {
177
179
  return `oncall-status${extra ? ` ${extra}` : ''}${suffix}`;
178
180
  }
179
181
  function StatusSpan(props) {
180
- return _jsx("span", { className: statusClass(props.status), ...(props.attr ?? {}), children: props.status?.text ?? '' });
182
+ return _jsx("span", { role: "status", "aria-live": "polite", className: statusClass(props.status), ...(props.attr ?? {}), children: props.status?.text ?? '' });
181
183
  }
182
184
  function InfoTip(props) {
183
185
  const ariaLabel = typeof props.children === 'string' ? props.children : undefined;
@@ -191,7 +193,7 @@ function DropdownField(props) {
191
193
  return (_jsxs(_Fragment, { children: [_jsx(DropdownMenu, { id: `bd-menu-${props.dataInput}`, className: ['bd-field-menu', props.className].filter(Boolean).join(' '), ariaLabel: props.ariaLabel, disabled: props.disabled, label: dropdownLabel(props.options, props.value), value: props.value, options: props.options, searchable: props.searchable, searchPlaceholder: props.searchable ? tr('common.dropdownSearch') : undefined, searchEmptyLabel: props.searchable ? tr('common.dropdownSearchEmpty') : undefined, onChange: props.onChange }), _jsx("input", { type: "hidden", "data-input": props.dataInput, value: props.value, readOnly: true })] }));
192
194
  }
193
195
  function ToggleRow(props) {
194
- return (_jsxs("label", { className: "toggle-row", children: [_jsx("input", { type: "checkbox", "data-action": props.dataAction, checked: props.checked, disabled: props.disabled, onChange: event => props.onChange(event.currentTarget.checked) }), _jsx("span", { className: "switch", "aria-hidden": "true" }), _jsx("span", { className: "toggle-tx", children: _jsx("strong", { children: _jsx(FieldTitle, { help: props.help, children: props.title }) }) })] }));
196
+ return (_jsxs("label", { className: props.className ? `toggle-row ${props.className}` : 'toggle-row', children: [_jsx("input", { type: "checkbox", "data-action": props.dataAction, checked: props.checked, disabled: props.disabled, onChange: event => props.onChange(event.currentTarget.checked) }), _jsx("span", { className: "switch", "aria-hidden": "true" }), _jsxs("span", { className: "toggle-tx", children: [_jsx("strong", { children: _jsx(FieldTitle, { help: props.help, children: props.title }) }), props.description ? _jsx("small", { children: props.description }) : null] })] }));
195
197
  }
196
198
  async function sendJson(method, url, body) {
197
199
  const r = await fetch(url, {
@@ -270,11 +272,7 @@ function brandStateLabel(brand, tr) {
270
272
  return tr('botDefaults.brandStateDefault');
271
273
  return brand.trim() === '' ? tr('botDefaults.brandStateOff') : tr('botDefaults.brandStateCustom');
272
274
  }
273
- function quotaStateLabel(quota, tr) {
274
- return quota == null
275
- ? tr('botDefaults.quotaStateOff')
276
- : tr('botDefaults.quotaStateOn', { count: quota });
277
- }
275
+ const GRANT_DURATION_VALUES = GRANT_DURATION_OPTIONS;
278
276
  function sessionCapStateLabel(cap, tr) {
279
277
  return cap == null
280
278
  ? tr('botDefaults.maxLiveWorkersStateDefault')
@@ -442,7 +440,7 @@ function BotDefaultsCard(props) {
442
440
  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] })] }));
443
441
  }
444
442
  const def = bot.defaultOncall ?? { enabled: false, workingDir: '', since: 0 };
445
- 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, putCardPref: putCardPref }) })] }) }), _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 }) })] }) })] })] }));
443
+ 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, putCardPref: putCardPref }) })] }) }), _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 bd-tile-wide", 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 }) })] }) })] })] }));
446
444
  }
447
445
  function RuntimeEnvironmentSection(props) {
448
446
  const tr = useT();
@@ -626,7 +624,7 @@ function BotProfileIdentity(props) {
626
624
  else if (event.key === 'Escape') {
627
625
  setEditMode(false);
628
626
  }
629
- } }), _jsx("button", { type: "button", className: "primary", "data-action": "save-bot-name", disabled: busy, onClick: () => void submitRename(), children: tr('botDefaults.renameSave') }), _jsx("button", { type: "button", "data-action": "cancel-bot-name", disabled: busy, onClick: () => setEditMode(false), children: tr('botDefaults.renameCancel') })] })), _jsx("code", { children: bot.larkAppId }), _jsx("small", { className: statusClass(status, 'bd-name-status'), "data-name-status": true, children: status?.text ?? '' }), _jsx("button", { type: "button", className: "bd-feishu-login", "data-action": "feishu-login", hidden: !loginVisible, onClick: () => setLoginOpen(true), children: tr('feishuLogin.entry') }), loginOpen ? (_jsx(FeishuLoginModal, { onClose: () => setLoginOpen(false), onSuccess: () => {
627
+ } }), _jsx("button", { type: "button", className: "primary", "data-action": "save-bot-name", disabled: busy, onClick: () => void submitRename(), children: tr('botDefaults.renameSave') }), _jsx("button", { type: "button", "data-action": "cancel-bot-name", disabled: busy, onClick: () => setEditMode(false), children: tr('botDefaults.renameCancel') })] })), _jsxs("div", { className: "bd-profile-appid-row", children: [_jsx("code", { children: bot.larkAppId }), larkConsoleUrl(bot.larkAppId, bot.brand) ? (_jsxs("a", { className: "bd-console-link", href: larkConsoleUrl(bot.larkAppId, bot.brand), target: "_blank", rel: "noopener noreferrer", children: [tr('botDefaults.openConsole'), _jsx("svg", { viewBox: "0 0 24 24", width: "12", height: "12", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: _jsx("path", { d: "M7 17 17 7M9 7h8v8" }) })] })) : null] }), _jsx("small", { className: statusClass(status, 'bd-name-status'), "data-name-status": true, children: status?.text ?? '' }), _jsx("button", { type: "button", className: "bd-feishu-login", "data-action": "feishu-login", hidden: !loginVisible, onClick: () => setLoginOpen(true), children: tr('feishuLogin.entry') }), loginOpen ? (_jsx(FeishuLoginModal, { onClose: () => setLoginOpen(false), onSuccess: () => {
630
628
  setLoginVisible(false);
631
629
  setLoginOpen(false);
632
630
  void submitRename();
@@ -713,10 +711,20 @@ function FeishuLoginModal(props) {
713
711
  window.clearTimeout(successTimerRef.current);
714
712
  };
715
713
  }, [begin, stopTimer]);
716
- return (_jsx("div", { className: "feishu-login-overlay", onClick: event => {
714
+ if (typeof document === 'undefined')
715
+ return null;
716
+ // Portal 到 body:此弹层内联渲染在头像组件(位于 .page 页面容器)的 DOM 里。
717
+ // 祖先 .page 有 `animation: dashboard-page-enter … both`,其关键帧动画 transform
718
+ // (translateY→none);fill-mode:both 下动画结束后持续「填充」,浏览器把 .page 的
719
+ // computed transform 算成 identity matrix(而非关键字 none)——「非 none 的 transform」
720
+ // 会为后代 position:fixed 建立包含块,于是弹层不再相对视口、被约束进 .page 的几何
721
+ // 范围,顶到视口下方,用户得滚动才看得到二维码(与主题无关,light/dark 均复现;
722
+ // 注意不是 .app-shell 的 overflow:hidden——overflow 不建立 fixed 包含块)。挂到
723
+ // body 顶层后逃出任何祖先包含块,与 auth-expired-overlay 一致,稳定居中。
724
+ return createPortal(_jsx("div", { className: "feishu-login-overlay", onClick: event => {
717
725
  if (event.currentTarget === event.target)
718
726
  onClose();
719
- }, children: _jsxs("div", { className: "feishu-login-modal", role: "dialog", "aria-modal": "true", children: [_jsx("button", { type: "button", className: "feishu-login-close", "data-close": true, "aria-label": tr('feishuLogin.close'), onClick: onClose, children: "x" }), _jsx("h3", { className: "feishu-login-title", children: tr('feishuLogin.title') }), _jsx("p", { className: "feishu-login-hint", "data-hint": true, children: hint }), _jsx("div", { className: "feishu-login-qr", "data-qr": true, children: qrDataUrl ? _jsx("img", { className: "qr-image", src: qrDataUrl, alt: tr('feishuLogin.qrAlt') }) : null }), _jsx("div", { className: "feishu-login-actions", children: _jsx("button", { type: "button", className: "primary", "data-retry": true, hidden: !retry, onClick: () => void begin(), children: tr('feishuLogin.retry') }) })] }) }));
727
+ }, children: _jsxs("div", { className: "feishu-login-modal", role: "dialog", "aria-modal": "true", children: [_jsx("button", { type: "button", className: "feishu-login-close", "data-close": true, "aria-label": tr('feishuLogin.close'), onClick: onClose, children: "x" }), _jsx("h3", { className: "feishu-login-title", children: tr('feishuLogin.title') }), _jsx("p", { className: "feishu-login-hint", "data-hint": true, children: hint }), _jsx("div", { className: "feishu-login-qr", "data-qr": true, children: qrDataUrl ? _jsx("img", { className: "qr-image", src: qrDataUrl, alt: tr('feishuLogin.qrAlt') }) : null }), _jsx("div", { className: "feishu-login-actions", children: _jsx("button", { type: "button", className: "primary", "data-retry": true, hidden: !retry, onClick: () => void begin(), children: tr('feishuLogin.retry') }) })] }) }), document.body);
720
728
  }
721
729
  export function BotAgentSection(props) {
722
730
  const tr = useT();
@@ -1572,23 +1580,29 @@ export function CardBehaviorSection(props) {
1572
1580
  { value: 'footer', label: tr('botDefaults.usageDisplayFooter') },
1573
1581
  { value: 'off', label: tr('botDefaults.usageDisplayOff') },
1574
1582
  ];
1575
- 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 => {
1576
- const previous = usageDisplay;
1577
- setUsageDisplay(next);
1578
- void savePatch({ usageDisplay: next }, 'usage', () => setUsageDisplay(previous));
1579
- } })] }) })), _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 => {
1580
- setDisableStreaming(checked);
1581
- void savePatch({ disableStreamingCard: checked }, 'streaming');
1582
- } }), _jsx(ToggleRow, { checked: silentReactions, disabled: !disableStreaming || busy === 'silent', dataAction: "toggle-silent-reactions", title: tr('botDefaults.silentTurnReactions'), help: tr('botDefaults.silentTurnReactionsHelp'), onChange: checked => {
1583
- setSilentReactions(checked);
1584
- void savePatch({ silentTurnReactions: checked }, 'silent');
1585
- } }), _jsx(ToggleRow, { checked: writableLink, disabled: disableStreaming || busy === 'writable', dataAction: "toggle-writable-link", title: tr('botDefaults.writableLink'), help: tr('botDefaults.writableLinkHelp'), onChange: checked => {
1586
- setWritableLink(checked);
1587
- void savePatch({ writableTerminalLinkInCard: checked }, 'writable');
1588
- } }), _jsx(ToggleRow, { checked: privateCard, disabled: busy === 'private', dataAction: "toggle-private-card", title: tr('botDefaults.privateCard'), help: tr('botDefaults.privateCardHelp'), onChange: checked => {
1589
- setPrivateCard(checked);
1590
- void savePatch({ privateCard: checked }, 'private');
1591
- } })] }), _jsxs("div", { className: "actions", children: [_jsx("small", { "data-card-pref-moot": true, className: "hint-warn-inline", hidden: !disableStreaming, children: tr('botDefaults.writableLinkMoot') }), _jsx(StatusSpan, { status: status, attr: { 'data-card-pref-status': '' } })] })] }));
1583
+ return (_jsxs("section", { className: "bd-section", "aria-busy": busy !== null, children: [_jsx("h3", { className: "bd-section-title", children: tr('botDefaults.sectionCard') }), _jsxs("div", { className: "bd-card-settings", children: [_jsxs("section", { className: "bd-card-setting-group", "data-card-feedback-group": true, children: [_jsx("h4", { className: "bd-card-setting-heading", children: tr('botDefaults.cardFeedbackGroup') }), _jsx(ToggleRow, { className: "bd-card-primary-toggle", checked: !disableStreaming, disabled: busy !== null, dataAction: "toggle-disable-streaming", title: tr('botDefaults.autoStreaming'), description: tr('botDefaults.autoStreamingDescription'), help: tr('botDefaults.autoStreamingHelp'), onChange: checked => {
1584
+ const previous = disableStreaming;
1585
+ const nextDisabled = !checked;
1586
+ setDisableStreaming(nextDisabled);
1587
+ void savePatch({ disableStreamingCard: nextDisabled }, 'streaming', () => setDisableStreaming(previous));
1588
+ } }), _jsxs("div", { className: "bd-card-dependent", "data-card-off-options": true, hidden: !disableStreaming, children: [_jsx(ToggleRow, { checked: !silentReactions, disabled: busy !== null, dataAction: "toggle-silent-reactions", title: tr('botDefaults.silentTurnReactions'), description: tr('botDefaults.silentTurnReactionsDescription'), help: tr('botDefaults.silentTurnReactionsHelp'), onChange: checked => {
1589
+ const previous = silentReactions;
1590
+ const nextSilent = !checked;
1591
+ setSilentReactions(nextSilent);
1592
+ void savePatch({ silentTurnReactions: nextSilent }, 'silent', () => setSilentReactions(previous));
1593
+ } }), _jsx("p", { role: "status", "data-card-pref-moot": true, className: "bd-card-mode-note", children: tr('botDefaults.manualCardHint') })] })] }), _jsxs("section", { className: "bd-card-setting-group", "data-card-content-group": true, children: [_jsx("h4", { className: "bd-card-setting-heading", children: tr('botDefaults.cardContentGroup') }), 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 !== null, options: usageDisplayOptions, onChange: next => {
1594
+ const previous = usageDisplay;
1595
+ setUsageDisplay(next);
1596
+ void savePatch({ usageDisplay: next }, 'usage', () => setUsageDisplay(previous));
1597
+ } })] }) })), _jsx("div", { className: "bd-card-control-list", children: _jsx(ToggleRow, { checked: writableLink, disabled: busy !== null, dataAction: "toggle-writable-link", title: tr('botDefaults.writableLink'), description: tr('botDefaults.writableLinkDescription'), help: tr('botDefaults.writableLinkHelp'), onChange: checked => {
1598
+ const previous = writableLink;
1599
+ setWritableLink(checked);
1600
+ void savePatch({ writableTerminalLinkInCard: checked }, 'writable', () => setWritableLink(previous));
1601
+ } }) })] }), _jsxs("section", { className: "bd-card-setting-group", "data-card-manual-group": true, children: [_jsx("h4", { className: "bd-card-setting-heading", children: tr('botDefaults.cardManualGroup') }), _jsx("p", { className: "bd-card-setting-copy", children: tr('botDefaults.manualCardIntro') }), _jsx("div", { className: "bd-card-control-list", children: _jsx(ToggleRow, { checked: privateCard, disabled: busy !== null, dataAction: "toggle-private-card", title: tr('botDefaults.privateCard'), description: tr('botDefaults.privateCardDescription'), help: tr('botDefaults.privateCardHelp'), onChange: checked => {
1602
+ const previous = privateCard;
1603
+ setPrivateCard(checked);
1604
+ void savePatch({ privateCard: checked }, 'private', () => setPrivateCard(previous));
1605
+ } }) })] })] }), _jsx("div", { className: "actions", children: _jsx(StatusSpan, { status: status, attr: { 'data-card-pref-status': '' } }) })] }));
1592
1606
  }
1593
1607
  export function CodexAppDisplaySection(props) {
1594
1608
  const tr = useT();
@@ -2419,66 +2433,145 @@ function BrandSection(props) {
2419
2433
  }
2420
2434
  return (_jsxs("section", { className: "bd-section", children: [_jsx("h3", { className: "bd-section-title", children: tr('botDefaults.sectionBrand') }), _jsxs("div", { className: "bd-row bd-brand", children: [_jsxs("label", { children: [_jsx(FieldTitle, { help: tr('botDefaults.brandLabelHelp'), children: tr('botDefaults.brandLabel') }), _jsx("input", { type: "text", "data-input": "brandLabel", placeholder: tr('botDefaults.brandLabelPlaceholder'), value: input, disabled: busy, onChange: event => setInput(event.currentTarget.value) })] }), _jsx("small", { "data-brand-state": true, children: brandStateLabel(brand, tr) })] }), _jsxs("div", { className: "actions", children: [_jsx("button", { type: "button", className: "primary", "data-action": "save-brand", disabled: busy, onClick: () => void save(input), children: tr('botDefaults.brandSave') }), _jsx("button", { type: "button", "data-action": "reset-brand", disabled: busy, onClick: () => void save(null), children: tr('botDefaults.brandReset') }), _jsx(StatusSpan, { status: status, attr: { 'data-brand-status': '' } })] })] }));
2421
2435
  }
2422
- function GrantSection(props) {
2436
+ export function GrantSection(props) {
2423
2437
  const tr = useT();
2424
2438
  const [autoCard, setAutoCard] = useState(props.bot.autoGrantRequestCards !== false);
2425
2439
  const [restrict, setRestrict] = useState(props.bot.restrictGrantCommands === true);
2440
+ const [duration, setDuration] = useState(typeof props.bot.grantDefaultDurationMs === 'number' ? props.bot.grantDefaultDurationMs : null);
2441
+ const [durationInput, setDurationInput] = useState(String(props.bot.grantDefaultDurationMs ?? DEFAULT_GRANT_DURATION_MS));
2426
2442
  const [quota, setQuota] = useState(typeof props.bot.messageQuotaDefaultLimit === 'number' ? props.bot.messageQuotaDefaultLimit : null);
2427
2443
  const [quotaInput, setQuotaInput] = useState(typeof props.bot.messageQuotaDefaultLimit === 'number' ? String(props.bot.messageQuotaDefaultLimit) : '');
2428
2444
  const [status, setStatus] = useState(null);
2445
+ const [quotaError, setQuotaError] = useState(null);
2429
2446
  const [busy, setBusy] = useState(null);
2430
2447
  useEffect(() => {
2431
2448
  setAutoCard(props.bot.autoGrantRequestCards !== false);
2449
+ }, [props.bot.autoGrantRequestCards]);
2450
+ useEffect(() => {
2432
2451
  setRestrict(props.bot.restrictGrantCommands === true);
2433
- const next = typeof props.bot.messageQuotaDefaultLimit === 'number' ? props.bot.messageQuotaDefaultLimit : null;
2434
- setQuota(next);
2435
- setQuotaInput(next == null ? '' : String(next));
2436
- }, [props.bot.autoGrantRequestCards, props.bot.messageQuotaDefaultLimit, props.bot.restrictGrantCommands]);
2437
- async function savePatch(patch, key) {
2452
+ }, [props.bot.restrictGrantCommands]);
2453
+ useEffect(() => {
2454
+ const nextDuration = typeof props.bot.grantDefaultDurationMs === 'number' ? props.bot.grantDefaultDurationMs : null;
2455
+ setDuration(nextDuration);
2456
+ setDurationInput(String(nextDuration ?? DEFAULT_GRANT_DURATION_MS));
2457
+ }, [props.bot.grantDefaultDurationMs]);
2458
+ useEffect(() => {
2459
+ const nextQuota = typeof props.bot.messageQuotaDefaultLimit === 'number' ? props.bot.messageQuotaDefaultLimit : null;
2460
+ setQuota(nextQuota);
2461
+ setQuotaInput(nextQuota === null ? '' : String(nextQuota));
2462
+ }, [props.bot.messageQuotaDefaultLimit]);
2463
+ async function savePatch(patch, key, rollback) {
2438
2464
  setBusy(key);
2439
2465
  setStatus(null);
2440
2466
  try {
2441
2467
  const res = await sendJson('PUT', `/api/bots/${encodeURIComponent(props.bot.larkAppId)}/grant-prefs`, patch);
2442
2468
  if (res.ok && res.body.ok) {
2469
+ const nextDuration = typeof res.body.grantDefaultDurationMs === 'number' ? res.body.grantDefaultDurationMs : null;
2443
2470
  const nextQuota = typeof res.body.messageQuotaDefaultLimit === 'number' ? res.body.messageQuotaDefaultLimit : null;
2444
2471
  setAutoCard(res.body.autoGrantRequestCards !== false);
2445
2472
  setRestrict(res.body.restrictGrantCommands === true);
2473
+ setDuration(nextDuration);
2446
2474
  setQuota(nextQuota);
2447
- if ('messageQuotaDefaultLimit' in patch)
2448
- setQuotaInput(nextQuota == null ? '' : String(nextQuota));
2475
+ if ('grantDefaultDurationMs' in patch)
2476
+ setDurationInput(String(nextDuration ?? DEFAULT_GRANT_DURATION_MS));
2477
+ if ('messageQuotaDefaultLimit' in patch) {
2478
+ setQuotaInput(nextQuota === null ? '' : String(nextQuota));
2479
+ }
2449
2480
  props.patchBot(props.bot.larkAppId, {
2450
2481
  autoGrantRequestCards: res.body.autoGrantRequestCards !== false,
2451
2482
  restrictGrantCommands: res.body.restrictGrantCommands === true,
2483
+ grantDefaultDurationMs: nextDuration,
2452
2484
  messageQuotaDefaultLimit: nextQuota,
2453
2485
  });
2486
+ if (key === 'defaults')
2487
+ setQuotaError(null);
2454
2488
  setStatus({ text: `✓ ${tr('botDefaults.cardPrefSaved')}`, ok: true });
2455
2489
  }
2456
2490
  else {
2491
+ rollback?.();
2457
2492
  setStatus({ text: `✗ ${responseErrorText(res)}` });
2458
2493
  }
2459
2494
  }
2460
2495
  catch (e) {
2496
+ rollback?.();
2461
2497
  setStatus({ text: `✗ ${caughtErrorText(e)}` });
2462
2498
  }
2463
2499
  finally {
2464
2500
  setBusy(null);
2465
2501
  }
2466
2502
  }
2467
- function saveQuota() {
2503
+ function saveDefaults() {
2468
2504
  const parsed = positiveIntegerOrNull(quotaInput);
2469
- if (parsed === 'invalid') {
2470
- setStatus({ text: `✗ ${tr('botDefaults.quotaInvalid')}` });
2505
+ const quotaChanged = parsed !== quota;
2506
+ setStatus(null);
2507
+ if (quotaChanged && (parsed === 'invalid'
2508
+ || (typeof parsed === 'number' && parsed > MAX_GRANT_QUOTA))) {
2509
+ setQuotaError(tr('botDefaults.quotaInvalid'));
2510
+ return;
2511
+ }
2512
+ setQuotaError(null);
2513
+ const durationMs = Number(durationInput);
2514
+ if (!GRANT_DURATION_VALUES.includes(durationMs)) {
2515
+ setStatus({ text: `✗ ${tr('botDefaults.grantDurationInvalid')}` });
2471
2516
  return;
2472
2517
  }
2473
- void savePatch({ messageQuotaDefaultLimit: parsed }, 'quota');
2518
+ const patch = {};
2519
+ if (durationMs !== (duration ?? DEFAULT_GRANT_DURATION_MS)) {
2520
+ patch.grantDefaultDurationMs = durationMs === DEFAULT_GRANT_DURATION_MS ? null : durationMs;
2521
+ }
2522
+ if (quotaChanged) {
2523
+ patch.messageQuotaDefaultLimit = parsed;
2524
+ }
2525
+ if (Object.keys(patch).length > 0)
2526
+ void savePatch(patch, 'defaults');
2474
2527
  }
2475
- return (_jsxs("section", { className: "bd-section", children: [_jsx("h3", { className: "bd-section-title", children: tr('botDefaults.sectionGrant') }), _jsxs("div", { className: "bd-toggle-grid bd-grant-toggle-grid", children: [_jsx(ToggleRow, { checked: autoCard, disabled: busy === 'autoGrant', dataAction: "toggle-auto-grant-card", title: tr('botDefaults.autoGrantCard'), help: tr('botDefaults.autoGrantCardHelp'), onChange: checked => {
2528
+ const durationOptions = [
2529
+ { value: String(DEFAULT_GRANT_DURATION_MS), label: tr('botDefaults.grantDuration1Hour') },
2530
+ { value: String(8 * 60 * 60 * 1000), label: tr('botDefaults.grantDuration8Hours') },
2531
+ { value: String(24 * 60 * 60 * 1000), label: tr('botDefaults.grantDuration1Day') },
2532
+ { value: String(7 * 24 * 60 * 60 * 1000), label: tr('botDefaults.grantDuration7Days') },
2533
+ ];
2534
+ const currentDuration = duration ?? DEFAULT_GRANT_DURATION_MS;
2535
+ const currentDurationLabel = currentDuration === DEFAULT_GRANT_DURATION_MS
2536
+ ? tr('botDefaults.grantDuration1HourValue')
2537
+ : String(durationOptions.find(option => option.value === String(currentDuration))?.label ?? '');
2538
+ const parsedQuotaInput = positiveIntegerOrNull(quotaInput);
2539
+ const quotaInputDirty = parsedQuotaInput === 'invalid' || parsedQuotaInput !== quota;
2540
+ const defaultsDirty = durationInput !== String(currentDuration) || quotaInputDirty;
2541
+ const currentState = quota === null
2542
+ ? tr('botDefaults.grantDefaultsCurrentBuiltIn', {
2543
+ duration: currentDurationLabel,
2544
+ count: DEFAULT_GRANT_QUOTA,
2545
+ })
2546
+ : quota > MAX_GRANT_QUOTA
2547
+ ? tr('botDefaults.grantDefaultsCurrentLegacy', {
2548
+ duration: currentDurationLabel,
2549
+ cardCount: MAX_GRANT_QUOTA,
2550
+ oncallCount: quota,
2551
+ })
2552
+ : tr('botDefaults.grantDefaultsCurrentCustom', {
2553
+ duration: currentDurationLabel,
2554
+ count: quota,
2555
+ });
2556
+ return (_jsxs("section", { className: "bd-section", children: [_jsx("h3", { className: "bd-section-title", children: tr('botDefaults.sectionGrant') }), _jsxs("div", { className: "bd-toggle-grid bd-grant-toggle-grid", children: [_jsx(ToggleRow, { checked: autoCard, disabled: busy !== null, dataAction: "toggle-auto-grant-card", title: tr('botDefaults.autoGrantCard'), help: tr('botDefaults.autoGrantCardHelp'), onChange: checked => {
2557
+ const previous = autoCard;
2476
2558
  setAutoCard(checked);
2477
- void savePatch({ autoGrantRequestCards: checked }, 'autoGrant');
2478
- } }), _jsx(ToggleRow, { checked: restrict, disabled: busy === 'restrict', dataAction: "toggle-restrict-grant", title: tr('botDefaults.restrictGrant'), help: tr('botDefaults.restrictGrantHelp'), onChange: checked => {
2559
+ void savePatch({ autoGrantRequestCards: checked }, 'autoGrant', () => setAutoCard(previous));
2560
+ } }), _jsx(ToggleRow, { checked: restrict, disabled: busy !== null, dataAction: "toggle-restrict-grant", title: tr('botDefaults.restrictGrant'), help: tr('botDefaults.restrictGrantHelp'), onChange: checked => {
2561
+ const previous = restrict;
2479
2562
  setRestrict(checked);
2480
- void savePatch({ restrictGrantCommands: checked }, 'restrict');
2481
- } })] }), _jsxs("div", { className: "bd-row bd-quota", children: [_jsxs("label", { children: [_jsx(FieldTitle, { help: tr('botDefaults.quotaHelp'), children: tr('botDefaults.quotaDefault') }), _jsx("input", { type: "number", min: 1, step: 1, "data-input": "quotaLimit", placeholder: tr('botDefaults.quotaPlaceholder'), value: quotaInput, disabled: busy === 'quota', onChange: event => setQuotaInput(event.currentTarget.value) })] }), _jsx("small", { "data-quota-state": true, children: quotaStateLabel(quota, tr) })] }), _jsxs("div", { className: "actions", children: [_jsx("button", { type: "button", className: "primary", "data-action": "save-quota", disabled: busy === 'quota', onClick: saveQuota, children: tr('botDefaults.quotaSave') }), _jsx(StatusSpan, { status: status, attr: { 'data-grant-status': '' } })] })] }));
2563
+ void savePatch({ restrictGrantCommands: checked }, 'restrict', () => setRestrict(previous));
2564
+ } })] }), _jsxs("form", { className: "bd-grant-defaults", noValidate: true, onSubmit: event => {
2565
+ event.preventDefault();
2566
+ saveDefaults();
2567
+ }, children: [_jsx("div", { className: "bd-row bd-grant-duration", children: _jsxs("div", { className: "bd-field", children: [_jsx(FieldTitle, { help: tr('botDefaults.grantDurationHelp'), children: tr('botDefaults.grantDurationDefault') }), _jsx(DropdownField, { dataInput: "grantDefaultDurationMs", value: durationInput, options: durationOptions, disabled: busy !== null, ariaLabel: tr('botDefaults.grantDurationDefault'), onChange: value => {
2568
+ setDurationInput(value);
2569
+ setStatus(null);
2570
+ } })] }) }), _jsxs("div", { className: "bd-row bd-quota", children: [_jsxs("label", { children: [_jsx(FieldTitle, { help: tr('botDefaults.quotaHelp'), children: tr('botDefaults.quotaDefault') }), _jsx("input", { type: "number", min: 1, max: MAX_GRANT_QUOTA, step: 1, "data-input": "quotaLimit", placeholder: tr('botDefaults.quotaPlaceholder'), value: quotaInput, disabled: busy !== null, "aria-label": tr('botDefaults.quotaDefault'), "aria-invalid": quotaError ? true : undefined, "aria-describedby": quotaError ? 'grant-defaults-state grant-default-quota-error' : 'grant-defaults-state', onChange: event => {
2571
+ setQuotaInput(event.currentTarget.value);
2572
+ setQuotaError(null);
2573
+ setStatus(null);
2574
+ } })] }), quotaError ? _jsx("small", { id: "grant-default-quota-error", className: "bd-field-error", role: "alert", children: quotaError }) : null, _jsx("small", { id: "grant-defaults-state", "data-grant-defaults-state": true, children: currentState })] }), _jsxs("div", { className: "actions", children: [_jsx("button", { type: "submit", className: "primary", "data-action": "save-grant-defaults", disabled: busy !== null || !defaultsDirty, children: busy === 'defaults' ? tr('botDefaults.grantDefaultsSaving') : tr('botDefaults.grantDefaultsSave') }), _jsx(StatusSpan, { status: status, attr: { 'data-grant-status': '' } })] })] })] }));
2482
2575
  }
2483
2576
  export function renderBotDefaultsPage(root) {
2484
2577
  return mountReactPage(root, _jsx(BotDefaultsPage, {}));