@songsid/agend 2.3.5-alpha.5 → 2.3.5-beta.1

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 (976) hide show
  1. package/README.md +0 -2
  2. package/README.zh-TW.md +0 -2
  3. package/THIRD_PARTY_NOTICES.md +0 -68
  4. package/dist/agent-endpoint.d.ts +1 -5
  5. package/dist/agent-endpoint.js +2 -12
  6. package/dist/agent-endpoint.js.map +1 -1
  7. package/dist/agent-file-read.js +1 -1
  8. package/dist/agent-file-read.js.map +1 -1
  9. package/dist/auth-api.d.ts +0 -48
  10. package/dist/auth-api.js +4 -250
  11. package/dist/auth-api.js.map +1 -1
  12. package/dist/authority/session-authorizations.d.ts +2 -0
  13. package/dist/authority/session-authorizations.js +7 -1
  14. package/dist/authority/session-authorizations.js.map +1 -1
  15. package/dist/authority/web-authority.d.ts +2 -12
  16. package/dist/authority/web-authority.js +4 -25
  17. package/dist/authority/web-authority.js.map +1 -1
  18. package/dist/backend/claude-code.d.ts +12 -15
  19. package/dist/backend/claude-code.js +133 -152
  20. package/dist/backend/claude-code.js.map +1 -1
  21. package/dist/backend/codex-footer-hints.d.ts +0 -3
  22. package/dist/backend/codex-footer-hints.js +0 -14
  23. package/dist/backend/codex-footer-hints.js.map +1 -1
  24. package/dist/backend/codex-package.d.ts +2 -5
  25. package/dist/backend/codex-package.js +5 -1
  26. package/dist/backend/codex-package.js.map +1 -1
  27. package/dist/backend/codex-quota-history.js +19 -4
  28. package/dist/backend/codex-quota-history.js.map +1 -1
  29. package/dist/backend/codex.d.ts +115 -142
  30. package/dist/backend/codex.js +1094 -1187
  31. package/dist/backend/codex.js.map +1 -1
  32. package/dist/backend/grok.d.ts +0 -2
  33. package/dist/backend/grok.js +0 -22
  34. package/dist/backend/grok.js.map +1 -1
  35. package/dist/backend/types.d.ts +2 -7
  36. package/dist/backend/types.js.map +1 -1
  37. package/dist/bundled-tmux-guard.d.ts +21 -0
  38. package/dist/bundled-tmux-guard.js +96 -0
  39. package/dist/bundled-tmux-guard.js.map +1 -0
  40. package/dist/channel/ipc-bridge.d.ts +0 -2
  41. package/dist/channel/mcp-tools.js +2 -2
  42. package/dist/channel/mcp-tools.js.map +1 -1
  43. package/dist/classic-channel-manager.d.ts +2 -0
  44. package/dist/classic-channel-manager.js +5 -1
  45. package/dist/classic-channel-manager.js.map +1 -1
  46. package/dist/cli.js +30 -127
  47. package/dist/cli.js.map +1 -1
  48. package/dist/config-validator.js +13 -74
  49. package/dist/config-validator.js.map +1 -1
  50. package/dist/config.js +3 -17
  51. package/dist/config.js.map +1 -1
  52. package/dist/daemon.d.ts +5 -72
  53. package/dist/daemon.js +275 -869
  54. package/dist/daemon.js.map +1 -1
  55. package/dist/delivery-consumed-watch.d.ts +3 -15
  56. package/dist/delivery-consumed-watch.js +1 -23
  57. package/dist/delivery-consumed-watch.js.map +1 -1
  58. package/dist/delivery-outbox.d.ts +0 -5
  59. package/dist/delivery-outbox.js +4 -32
  60. package/dist/delivery-outbox.js.map +1 -1
  61. package/dist/delivery-reconciliation.d.ts +42 -2
  62. package/dist/delivery-reconciliation.js +164 -2
  63. package/dist/delivery-reconciliation.js.map +1 -1
  64. package/dist/doctor.js +9 -20
  65. package/dist/doctor.js.map +1 -1
  66. package/dist/fleet-context.d.ts +2 -2
  67. package/dist/fleet-level-config.d.ts +1 -1
  68. package/dist/fleet-level-config.js +0 -2
  69. package/dist/fleet-level-config.js.map +1 -1
  70. package/dist/fleet-manager.d.ts +9 -498
  71. package/dist/fleet-manager.js +202 -2849
  72. package/dist/fleet-manager.js.map +1 -1
  73. package/dist/general-instance.d.ts +0 -7
  74. package/dist/general-instance.js +3 -20
  75. package/dist/general-instance.js.map +1 -1
  76. package/dist/general-knowledge/skills/concepts/SKILL.md +18 -50
  77. package/dist/general-knowledge/skills/credential-profiles/SKILL.md +2 -5
  78. package/dist/general-knowledge/skills/fleet-health/SKILL.md +2 -2
  79. package/dist/general-knowledge/skills/session-management/SKILL.md +1 -1
  80. package/dist/general-knowledge/skills/tui-effort/SKILL.md +10 -10
  81. package/dist/general-knowledge/skills/web-dashboard/SKILL.md +13 -23
  82. package/dist/instance-config-impact.js +4 -8
  83. package/dist/instance-config-impact.js.map +1 -1
  84. package/dist/instance-lifecycle.d.ts +3 -22
  85. package/dist/instance-lifecycle.js +176 -393
  86. package/dist/instance-lifecycle.js.map +1 -1
  87. package/dist/instructions.d.ts +0 -2
  88. package/dist/instructions.js +0 -6
  89. package/dist/instructions.js.map +1 -1
  90. package/dist/locale.js +2 -147
  91. package/dist/locale.js.map +1 -1
  92. package/dist/login-flows.d.ts +7 -8
  93. package/dist/login-flows.js +1 -24
  94. package/dist/login-flows.js.map +1 -1
  95. package/dist/ls-rows.js +4 -3
  96. package/dist/ls-rows.js.map +1 -1
  97. package/dist/muse-usage-relay.d.ts +2 -0
  98. package/dist/muse-usage-relay.js +5 -3
  99. package/dist/muse-usage-relay.js.map +1 -1
  100. package/dist/needs-you-hub.d.ts +0 -5
  101. package/dist/needs-you-hub.js +2 -18
  102. package/dist/needs-you-hub.js.map +1 -1
  103. package/dist/needs-you.d.ts +2 -45
  104. package/dist/needs-you.js +2 -26
  105. package/dist/needs-you.js.map +1 -1
  106. package/dist/office-share-page.js +3 -3
  107. package/dist/office-share-page.js.map +1 -1
  108. package/dist/office-share.d.ts +0 -11
  109. package/dist/office-share.js +0 -14
  110. package/dist/office-share.js.map +1 -1
  111. package/dist/outbound-handlers.d.ts +2 -30
  112. package/dist/outbound-handlers.js +4 -109
  113. package/dist/outbound-handlers.js.map +1 -1
  114. package/dist/outbound-schemas.d.ts +1 -71
  115. package/dist/outbound-schemas.js +14 -36
  116. package/dist/outbound-schemas.js.map +1 -1
  117. package/dist/pane-quota-history.d.ts +0 -2
  118. package/dist/pane-quota-history.js +0 -20
  119. package/dist/pane-quota-history.js.map +1 -1
  120. package/dist/pause-marker.d.ts +1 -1
  121. package/dist/pause-marker.js +1 -1
  122. package/dist/pause-marker.js.map +1 -1
  123. package/dist/public-web-gateway.js +0 -16
  124. package/dist/public-web-gateway.js.map +1 -1
  125. package/dist/public-web-link.d.ts +0 -11
  126. package/dist/public-web-link.js +0 -13
  127. package/dist/public-web-link.js.map +1 -1
  128. package/dist/quickstart-api.js +5 -9
  129. package/dist/quickstart-api.js.map +1 -1
  130. package/dist/quickstart.d.ts +0 -6
  131. package/dist/quickstart.js +6 -44
  132. package/dist/quickstart.js.map +1 -1
  133. package/dist/quota-notice-config.d.ts +22 -0
  134. package/dist/quota-notice-config.js +41 -0
  135. package/dist/quota-notice-config.js.map +1 -0
  136. package/dist/scheduler/task-board-text.js +1 -1
  137. package/dist/scheduler/task-board-text.js.map +1 -1
  138. package/dist/scheduler/task-board.d.ts +0 -4
  139. package/dist/scheduler/task-board.js +3 -9
  140. package/dist/scheduler/task-board.js.map +1 -1
  141. package/dist/service-installer.d.ts +2 -7
  142. package/dist/service-installer.js +10 -13
  143. package/dist/service-installer.js.map +1 -1
  144. package/dist/settings-api.d.ts +0 -12
  145. package/dist/settings-api.js +7 -487
  146. package/dist/settings-api.js.map +1 -1
  147. package/dist/settings-baseline.d.ts +0 -7
  148. package/dist/settings-baseline.js +1 -3
  149. package/dist/settings-baseline.js.map +1 -1
  150. package/dist/settings-change.js +7 -35
  151. package/dist/settings-change.js.map +1 -1
  152. package/dist/settings-confirmation.d.ts +1 -16
  153. package/dist/settings-confirmation.js +9 -47
  154. package/dist/settings-confirmation.js.map +1 -1
  155. package/dist/settings-effect.d.ts +0 -17
  156. package/dist/settings-effect.js +1 -155
  157. package/dist/settings-effect.js.map +1 -1
  158. package/dist/settings-http-confirmation.d.ts +0 -4
  159. package/dist/settings-http-confirmation.js +3 -43
  160. package/dist/settings-http-confirmation.js.map +1 -1
  161. package/dist/settings-instance-patch.js +1 -1
  162. package/dist/settings-instance-patch.js.map +1 -1
  163. package/dist/settings-request-capability.d.ts +0 -2
  164. package/dist/settings-request-capability.js +0 -4
  165. package/dist/settings-request-capability.js.map +1 -1
  166. package/dist/settings-transaction.d.ts +0 -4
  167. package/dist/settings-transaction.js +0 -9
  168. package/dist/settings-transaction.js.map +1 -1
  169. package/dist/setup-form.js +3 -6
  170. package/dist/setup-form.js.map +1 -1
  171. package/dist/setup-i18n.js +0 -3
  172. package/dist/setup-i18n.js.map +1 -1
  173. package/dist/setup-wizard.js +2 -6
  174. package/dist/setup-wizard.js.map +1 -1
  175. package/dist/task-board-tool.d.ts +1 -2
  176. package/dist/task-board-tool.js +6 -62
  177. package/dist/task-board-tool.js.map +1 -1
  178. package/dist/tmux-control.d.ts +1 -2
  179. package/dist/tmux-control.js +4 -4
  180. package/dist/tmux-control.js.map +1 -1
  181. package/dist/tmux-exec-helper.js +1 -32
  182. package/dist/tmux-exec-helper.js.map +1 -1
  183. package/dist/tmux-manager.d.ts +2 -3
  184. package/dist/tmux-manager.js +36 -45
  185. package/dist/tmux-manager.js.map +1 -1
  186. package/dist/tmux-read.js +3 -4
  187. package/dist/tmux-read.js.map +1 -1
  188. package/dist/tool-permissions.js +1 -2
  189. package/dist/tool-permissions.js.map +1 -1
  190. package/dist/topic-commands.js +5 -9
  191. package/dist/topic-commands.js.map +1 -1
  192. package/dist/transcript-delta-reader.d.ts +1 -1
  193. package/dist/transcript-delta-reader.js +1 -1
  194. package/dist/transcript-delta-reader.js.map +1 -1
  195. package/dist/transcript-monitor.d.ts +0 -3
  196. package/dist/transcript-monitor.js +51 -27
  197. package/dist/transcript-monitor.js.map +1 -1
  198. package/dist/transcript-sources.d.ts +0 -5
  199. package/dist/transcript-sources.js +79 -8
  200. package/dist/transcript-sources.js.map +1 -1
  201. package/dist/types.d.ts +3 -29
  202. package/dist/ui/app.html +8 -1
  203. package/dist/ui/backend-signin.js +21 -39
  204. package/dist/ui/chat-ambient.js +1 -1
  205. package/dist/ui/chat-md-strings.js +9 -3
  206. package/dist/ui/chat-render.js +670 -3
  207. package/dist/ui/chat-store.js +3 -14
  208. package/dist/ui/chat-strings.js +285 -3
  209. package/dist/ui/chat-thread.js +969 -3
  210. package/dist/ui/chat-time.js +80 -3
  211. package/dist/ui/chat-tour.js +1 -1
  212. package/dist/ui/fleet-office-pack.d.ts +0 -9
  213. package/dist/ui/fleet-office-pack.js +4 -76
  214. package/dist/ui/fleet-office-skin.js +5 -23
  215. package/dist/ui/fleet-office-store.js +0 -5
  216. package/dist/ui/fleet-office.js +6 -173
  217. package/dist/ui/fleet-task-card.js +4 -8
  218. package/dist/ui/fleet-task-common.js +2 -2
  219. package/dist/ui/fleet-tasks.js +39 -125
  220. package/dist/ui/html-attachment.js +40 -3
  221. package/dist/ui/office-share-page.js +2 -4
  222. package/dist/ui/panel-chat.js +75 -90
  223. package/dist/ui/panel-details.js +2 -3
  224. package/dist/ui/panel-fleet.js +18 -105
  225. package/dist/ui/panel-log.js +2 -2
  226. package/dist/ui/panel-needs.js +4 -162
  227. package/dist/ui/panel-notices.js +4 -3
  228. package/dist/ui/panel-settings.js +202 -281
  229. package/dist/ui/preview-pages.js +1 -1
  230. package/dist/ui/preview-panel.js +13 -21
  231. package/dist/ui/preview-versions.js +1 -1
  232. package/dist/ui/preview.js +476 -3
  233. package/dist/ui/search-dialog.js +3 -4
  234. package/dist/ui/settings-appearance.js +23 -122
  235. package/dist/ui/settings-catalog.js +10 -37
  236. package/dist/ui/settings-confirm.js +1 -3
  237. package/dist/ui/settings-dialogs.js +20 -48
  238. package/dist/ui/settings-guests.js +14 -27
  239. package/dist/ui/settings-model.js +1 -10
  240. package/dist/ui/settings-quota-notice.js +100 -0
  241. package/dist/ui/settings-registry.js +5 -15
  242. package/dist/ui/settings-strings.js +32 -105
  243. package/dist/ui/settings-web-authority.js +13 -18
  244. package/dist/ui/shared/app-i18n.js +2 -2
  245. package/dist/ui/shared/app-route.js +3 -12
  246. package/dist/ui/shared/app-session.js +2 -6
  247. package/dist/ui/shared/app-shell.js +26 -87
  248. package/dist/ui/shared/app-store.js +2 -3
  249. package/dist/ui/shared/app-stream.js +1 -3
  250. package/dist/ui/shared/app.css +5 -1368
  251. package/dist/ui/shared/app.js +5 -17
  252. package/dist/ui/shared/header-tools.js +9 -9
  253. package/dist/ui/shared/instance-nav.js +7 -34
  254. package/dist/ui/shared/instance-switch.js +3 -4
  255. package/dist/ui/shared/loading.css +37 -0
  256. package/dist/ui/shared/signin.js +6 -211
  257. package/dist/ui/shared/tokens.css +0 -1
  258. package/dist/ui/shared/ui-dialog.js +2 -2
  259. package/dist/ui/shared/ui-menu.js +10 -30
  260. package/dist/ui/shared/ui-states.js +14 -3
  261. package/dist/ui/shared/vendor/vendor.json +2 -19
  262. package/dist/ui/shared/view-strings.js +0 -8
  263. package/dist/ui/signin.html +5 -23
  264. package/dist/unattended-install.js +1 -2
  265. package/dist/unattended-install.js.map +1 -1
  266. package/dist/usage/providers.d.ts +5 -0
  267. package/dist/usage/providers.js +6 -2
  268. package/dist/usage/providers.js.map +1 -1
  269. package/dist/usage/quota-notices.d.ts +38 -0
  270. package/dist/usage/quota-notices.js +160 -0
  271. package/dist/usage/quota-notices.js.map +1 -0
  272. package/dist/usage/usage-api.d.ts +1 -0
  273. package/dist/usage/usage-api.js +16 -0
  274. package/dist/usage/usage-api.js.map +1 -1
  275. package/dist/view-api.js +7 -5
  276. package/dist/view-api.js.map +1 -1
  277. package/dist/web-api.d.ts +2 -80
  278. package/dist/web-api.js +10 -513
  279. package/dist/web-api.js.map +1 -1
  280. package/dist/web-backend-login.d.ts +1 -23
  281. package/dist/web-backend-login.js +17 -11
  282. package/dist/web-backend-login.js.map +1 -1
  283. package/dist/web-chat-history.d.ts +2 -19
  284. package/dist/web-chat-history.js +3 -72
  285. package/dist/web-chat-history.js.map +1 -1
  286. package/dist/web-office-skins.d.ts +0 -9
  287. package/dist/web-office-skins.js +1 -16
  288. package/dist/web-office-skins.js.map +1 -1
  289. package/dist/web-only-fleet.d.ts +0 -20
  290. package/dist/web-only-fleet.js +0 -21
  291. package/dist/web-only-fleet.js.map +1 -1
  292. package/dist/web-session.d.ts +0 -42
  293. package/dist/web-session.js +0 -9
  294. package/dist/web-session.js.map +1 -1
  295. package/dist/web-settings-patch.d.ts +1 -3
  296. package/dist/web-settings-patch.js +1 -4
  297. package/dist/web-settings-patch.js.map +1 -1
  298. package/dist/web-shell-routes.d.ts +1 -10
  299. package/dist/web-shell-routes.js +2 -14
  300. package/dist/web-shell-routes.js.map +1 -1
  301. package/dist/web-terminal.d.ts +30 -4
  302. package/dist/web-terminal.js +6 -9
  303. package/dist/web-terminal.js.map +1 -1
  304. package/dist/yaml-shared-nodes.js +3 -8
  305. package/dist/yaml-shared-nodes.js.map +1 -1
  306. package/launcher/agend-install.cjs +1 -8
  307. package/launcher/postinstall.cjs +2 -27
  308. package/package.json +3 -10
  309. package/templates/launchd.plist.ejs +1 -3
  310. package/dist/accounts-view.d.ts +0 -97
  311. package/dist/accounts-view.js +0 -116
  312. package/dist/accounts-view.js.map +0 -1
  313. package/dist/agent-runtime-api.d.ts +0 -4
  314. package/dist/agent-runtime-api.js +0 -59
  315. package/dist/agent-runtime-api.js.map +0 -1
  316. package/dist/agent-runtime-change.d.ts +0 -76
  317. package/dist/agent-runtime-change.js +0 -114
  318. package/dist/agent-runtime-change.js.map +0 -1
  319. package/dist/agent-workspace.d.ts +0 -93
  320. package/dist/agent-workspace.js +0 -353
  321. package/dist/agent-workspace.js.map +0 -1
  322. package/dist/backend/grok-model-cache.d.ts +0 -7
  323. package/dist/backend/grok-model-cache.js +0 -65
  324. package/dist/backend/grok-model-cache.js.map +0 -1
  325. package/dist/backend/native-pane.d.ts +0 -11
  326. package/dist/backend/native-pane.js +0 -59
  327. package/dist/backend/native-pane.js.map +0 -1
  328. package/dist/build-provenance-cli.d.ts +0 -3
  329. package/dist/build-provenance-cli.js +0 -11
  330. package/dist/build-provenance-cli.js.map +0 -1
  331. package/dist/build-provenance.d.ts +0 -20
  332. package/dist/build-provenance.js +0 -67
  333. package/dist/build-provenance.js.map +0 -1
  334. package/dist/build-provenance.json +0 -1
  335. package/dist/claude-auth-status.d.ts +0 -48
  336. package/dist/claude-auth-status.js +0 -149
  337. package/dist/claude-auth-status.js.map +0 -1
  338. package/dist/fleet-windows-runtime.d.ts +0 -98
  339. package/dist/fleet-windows-runtime.js +0 -467
  340. package/dist/fleet-windows-runtime.js.map +0 -1
  341. package/dist/general-binding.d.ts +0 -85
  342. package/dist/general-binding.js +0 -298
  343. package/dist/general-binding.js.map +0 -1
  344. package/dist/general-host-owner.d.ts +0 -8
  345. package/dist/general-host-owner.js +0 -26
  346. package/dist/general-host-owner.js.map +0 -1
  347. package/dist/general-role.d.ts +0 -5
  348. package/dist/general-role.js +0 -27
  349. package/dist/general-role.js.map +0 -1
  350. package/dist/hub/admission.d.ts +0 -28
  351. package/dist/hub/admission.js +0 -62
  352. package/dist/hub/admission.js.map +0 -1
  353. package/dist/hub/attachments/limits.d.ts +0 -20
  354. package/dist/hub/attachments/limits.js +0 -48
  355. package/dist/hub/attachments/limits.js.map +0 -1
  356. package/dist/hub/attachments/store.d.ts +0 -116
  357. package/dist/hub/attachments/store.js +0 -246
  358. package/dist/hub/attachments/store.js.map +0 -1
  359. package/dist/hub/audit/index.d.ts +0 -62
  360. package/dist/hub/audit/index.js +0 -344
  361. package/dist/hub/audit/index.js.map +0 -1
  362. package/dist/hub/browser-certificate.d.ts +0 -38
  363. package/dist/hub/browser-certificate.js +0 -247
  364. package/dist/hub/browser-certificate.js.map +0 -1
  365. package/dist/hub/buttons-model.d.ts +0 -9
  366. package/dist/hub/buttons-model.js +0 -42
  367. package/dist/hub/buttons-model.js.map +0 -1
  368. package/dist/hub/buttons.d.ts +0 -54
  369. package/dist/hub/buttons.js +0 -346
  370. package/dist/hub/buttons.js.map +0 -1
  371. package/dist/hub/catalog.d.ts +0 -74
  372. package/dist/hub/catalog.js +0 -195
  373. package/dist/hub/catalog.js.map +0 -1
  374. package/dist/hub/client.d.ts +0 -69
  375. package/dist/hub/client.js +0 -300
  376. package/dist/hub/client.js.map +0 -1
  377. package/dist/hub/compose/member.d.ts +0 -139
  378. package/dist/hub/compose/member.js +0 -450
  379. package/dist/hub/compose/member.js.map +0 -1
  380. package/dist/hub/compose/server.d.ts +0 -77
  381. package/dist/hub/compose/server.js +0 -349
  382. package/dist/hub/compose/server.js.map +0 -1
  383. package/dist/hub/compose/views.d.ts +0 -12
  384. package/dist/hub/compose/views.js +0 -4
  385. package/dist/hub/compose/views.js.map +0 -1
  386. package/dist/hub/db.d.ts +0 -56
  387. package/dist/hub/db.js +0 -188
  388. package/dist/hub/db.js.map +0 -1
  389. package/dist/hub/directory/config.d.ts +0 -39
  390. package/dist/hub/directory/config.js +0 -108
  391. package/dist/hub/directory/config.js.map +0 -1
  392. package/dist/hub/directory/directory.d.ts +0 -18
  393. package/dist/hub/directory/directory.js +0 -320
  394. package/dist/hub/directory/directory.js.map +0 -1
  395. package/dist/hub/directory/index.d.ts +0 -7
  396. package/dist/hub/directory/index.js +0 -4
  397. package/dist/hub/directory/index.js.map +0 -1
  398. package/dist/hub/directory/profiles.d.ts +0 -41
  399. package/dist/hub/directory/profiles.js +0 -90
  400. package/dist/hub/directory/profiles.js.map +0 -1
  401. package/dist/hub/directory/types.d.ts +0 -71
  402. package/dist/hub/directory/types.js +0 -14
  403. package/dist/hub/directory/types.js.map +0 -1
  404. package/dist/hub/execution/cli-provider.d.ts +0 -23
  405. package/dist/hub/execution/cli-provider.js +0 -341
  406. package/dist/hub/execution/cli-provider.js.map +0 -1
  407. package/dist/hub/execution/index.d.ts +0 -13
  408. package/dist/hub/execution/index.js +0 -8
  409. package/dist/hub/execution/index.js.map +0 -1
  410. package/dist/hub/execution/model-broker.d.ts +0 -24
  411. package/dist/hub/execution/model-broker.js +0 -208
  412. package/dist/hub/execution/model-broker.js.map +0 -1
  413. package/dist/hub/execution/provider-setup.d.ts +0 -11
  414. package/dist/hub/execution/provider-setup.js +0 -21
  415. package/dist/hub/execution/provider-setup.js.map +0 -1
  416. package/dist/hub/execution/sandbox-runner.d.ts +0 -1
  417. package/dist/hub/execution/sandbox-runner.js +0 -221
  418. package/dist/hub/execution/sandbox-runner.js.map +0 -1
  419. package/dist/hub/execution/service.d.ts +0 -136
  420. package/dist/hub/execution/service.js +0 -459
  421. package/dist/hub/execution/service.js.map +0 -1
  422. package/dist/hub/execution/store.d.ts +0 -61
  423. package/dist/hub/execution/store.js +0 -182
  424. package/dist/hub/execution/store.js.map +0 -1
  425. package/dist/hub/execution/views.d.ts +0 -20
  426. package/dist/hub/execution/views.js +0 -48
  427. package/dist/hub/execution/views.js.map +0 -1
  428. package/dist/hub/http/compose.d.ts +0 -20
  429. package/dist/hub/http/compose.js +0 -518
  430. package/dist/hub/http/compose.js.map +0 -1
  431. package/dist/hub/http/core.d.ts +0 -49
  432. package/dist/hub/http/core.js +0 -124
  433. package/dist/hub/http/core.js.map +0 -1
  434. package/dist/hub/http/deps.d.ts +0 -61
  435. package/dist/hub/http/deps.js +0 -2
  436. package/dist/hub/http/deps.js.map +0 -1
  437. package/dist/hub/http/schema.d.ts +0 -14
  438. package/dist/hub/http/schema.js +0 -80
  439. package/dist/hub/http/schema.js.map +0 -1
  440. package/dist/hub/identity.d.ts +0 -32
  441. package/dist/hub/identity.js +0 -80
  442. package/dist/hub/identity.js.map +0 -1
  443. package/dist/hub/init/browser-certificate.d.ts +0 -9
  444. package/dist/hub/init/browser-certificate.js +0 -78
  445. package/dist/hub/init/browser-certificate.js.map +0 -1
  446. package/dist/hub/init/browser-tls.d.ts +0 -18
  447. package/dist/hub/init/browser-tls.js +0 -62
  448. package/dist/hub/init/browser-tls.js.map +0 -1
  449. package/dist/hub/init/cli.d.ts +0 -3
  450. package/dist/hub/init/cli.js +0 -83
  451. package/dist/hub/init/cli.js.map +0 -1
  452. package/dist/hub/init/directory-certificate.d.ts +0 -24
  453. package/dist/hub/init/directory-certificate.js +0 -222
  454. package/dist/hub/init/directory-certificate.js.map +0 -1
  455. package/dist/hub/init/existing-fleet.d.ts +0 -6
  456. package/dist/hub/init/existing-fleet.js +0 -58
  457. package/dist/hub/init/existing-fleet.js.map +0 -1
  458. package/dist/hub/init/handoff.d.ts +0 -8
  459. package/dist/hub/init/handoff.js +0 -36
  460. package/dist/hub/init/handoff.js.map +0 -1
  461. package/dist/hub/init/identity.d.ts +0 -5
  462. package/dist/hub/init/identity.js +0 -24
  463. package/dist/hub/init/identity.js.map +0 -1
  464. package/dist/hub/init/initializer.d.ts +0 -24
  465. package/dist/hub/init/initializer.js +0 -385
  466. package/dist/hub/init/initializer.js.map +0 -1
  467. package/dist/hub/init/inventory.d.ts +0 -17
  468. package/dist/hub/init/inventory.js +0 -33
  469. package/dist/hub/init/inventory.js.map +0 -1
  470. package/dist/hub/init/layout.d.ts +0 -32
  471. package/dist/hub/init/layout.js +0 -53
  472. package/dist/hub/init/layout.js.map +0 -1
  473. package/dist/hub/init/network.d.ts +0 -18
  474. package/dist/hub/init/network.js +0 -104
  475. package/dist/hub/init/network.js.map +0 -1
  476. package/dist/hub/init/plan-digest.d.ts +0 -5
  477. package/dist/hub/init/plan-digest.js +0 -47
  478. package/dist/hub/init/plan-digest.js.map +0 -1
  479. package/dist/hub/init/prompt.d.ts +0 -26
  480. package/dist/hub/init/prompt.js +0 -110
  481. package/dist/hub/init/prompt.js.map +0 -1
  482. package/dist/hub/init/secret-file.d.ts +0 -1
  483. package/dist/hub/init/secret-file.js +0 -59
  484. package/dist/hub/init/secret-file.js.map +0 -1
  485. package/dist/hub/init/text.d.ts +0 -127
  486. package/dist/hub/init/text.js +0 -247
  487. package/dist/hub/init/text.js.map +0 -1
  488. package/dist/hub/init/types.d.ts +0 -114
  489. package/dist/hub/init/types.js +0 -9
  490. package/dist/hub/init/types.js.map +0 -1
  491. package/dist/hub/init/wizard.d.ts +0 -34
  492. package/dist/hub/init/wizard.js +0 -554
  493. package/dist/hub/init/wizard.js.map +0 -1
  494. package/dist/hub/initialization.d.ts +0 -23
  495. package/dist/hub/initialization.js +0 -28
  496. package/dist/hub/initialization.js.map +0 -1
  497. package/dist/hub/member/agent-mode.d.ts +0 -6
  498. package/dist/hub/member/agent-mode.js +0 -23
  499. package/dist/hub/member/agent-mode.js.map +0 -1
  500. package/dist/hub/member/attachments.d.ts +0 -29
  501. package/dist/hub/member/attachments.js +0 -107
  502. package/dist/hub/member/attachments.js.map +0 -1
  503. package/dist/hub/member/exposure-api.d.ts +0 -87
  504. package/dist/hub/member/exposure-api.js +0 -64
  505. package/dist/hub/member/exposure-api.js.map +0 -1
  506. package/dist/hub/member/exposures.d.ts +0 -123
  507. package/dist/hub/member/exposures.js +0 -282
  508. package/dist/hub/member/exposures.js.map +0 -1
  509. package/dist/hub/member/pairing-api.d.ts +0 -85
  510. package/dist/hub/member/pairing-api.js +0 -385
  511. package/dist/hub/member/pairing-api.js.map +0 -1
  512. package/dist/hub/member/quota.d.ts +0 -20
  513. package/dist/hub/member/quota.js +0 -98
  514. package/dist/hub/member/quota.js.map +0 -1
  515. package/dist/hub/member-journal.d.ts +0 -104
  516. package/dist/hub/member-journal.js +0 -336
  517. package/dist/hub/member-journal.js.map +0 -1
  518. package/dist/hub/member-reconciliation.d.ts +0 -14
  519. package/dist/hub/member-reconciliation.js +0 -97
  520. package/dist/hub/member-reconciliation.js.map +0 -1
  521. package/dist/hub/mount.d.ts +0 -39
  522. package/dist/hub/mount.js +0 -123
  523. package/dist/hub/mount.js.map +0 -1
  524. package/dist/hub/pairing-client.d.ts +0 -17
  525. package/dist/hub/pairing-client.js +0 -108
  526. package/dist/hub/pairing-client.js.map +0 -1
  527. package/dist/hub/pairing.d.ts +0 -65
  528. package/dist/hub/pairing.js +0 -211
  529. package/dist/hub/pairing.js.map +0 -1
  530. package/dist/hub/policy.d.ts +0 -63
  531. package/dist/hub/policy.js +0 -147
  532. package/dist/hub/policy.js.map +0 -1
  533. package/dist/hub/preview.d.ts +0 -32
  534. package/dist/hub/preview.js +0 -64
  535. package/dist/hub/preview.js.map +0 -1
  536. package/dist/hub/private-files.d.ts +0 -5
  537. package/dist/hub/private-files.js +0 -44
  538. package/dist/hub/private-files.js.map +0 -1
  539. package/dist/hub/profile.d.ts +0 -59
  540. package/dist/hub/profile.js +0 -73
  541. package/dist/hub/profile.js.map +0 -1
  542. package/dist/hub/protocol.d.ts +0 -779
  543. package/dist/hub/protocol.js +0 -93
  544. package/dist/hub/protocol.js.map +0 -1
  545. package/dist/hub/quota.d.ts +0 -24
  546. package/dist/hub/quota.js +0 -112
  547. package/dist/hub/quota.js.map +0 -1
  548. package/dist/hub/representative.d.ts +0 -141
  549. package/dist/hub/representative.js +0 -528
  550. package/dist/hub/representative.js.map +0 -1
  551. package/dist/hub/retention.d.ts +0 -17
  552. package/dist/hub/retention.js +0 -45
  553. package/dist/hub/retention.js.map +0 -1
  554. package/dist/hub/rooms.d.ts +0 -120
  555. package/dist/hub/rooms.js +0 -535
  556. package/dist/hub/rooms.js.map +0 -1
  557. package/dist/hub/runtime.d.ts +0 -106
  558. package/dist/hub/runtime.js +0 -298
  559. package/dist/hub/runtime.js.map +0 -1
  560. package/dist/hub/server.d.ts +0 -56
  561. package/dist/hub/server.js +0 -202
  562. package/dist/hub/server.js.map +0 -1
  563. package/dist/hub/service-start.d.ts +0 -17
  564. package/dist/hub/service-start.js +0 -109
  565. package/dist/hub/service-start.js.map +0 -1
  566. package/dist/hub/sessions.d.ts +0 -53
  567. package/dist/hub/sessions.js +0 -196
  568. package/dist/hub/sessions.js.map +0 -1
  569. package/dist/hub/socket.d.ts +0 -24
  570. package/dist/hub/socket.js +0 -79
  571. package/dist/hub/socket.js.map +0 -1
  572. package/dist/hub/store.d.ts +0 -77
  573. package/dist/hub/store.js +0 -88
  574. package/dist/hub/store.js.map +0 -1
  575. package/dist/hub/tls.d.ts +0 -31
  576. package/dist/hub/tls.js +0 -135
  577. package/dist/hub/tls.js.map +0 -1
  578. package/dist/hub/types.d.ts +0 -401
  579. package/dist/hub/types.js +0 -2
  580. package/dist/hub/types.js.map +0 -1
  581. package/dist/hub/validation.d.ts +0 -33
  582. package/dist/hub/validation.js +0 -136
  583. package/dist/hub/validation.js.map +0 -1
  584. package/dist/hub/version-floor.d.ts +0 -10
  585. package/dist/hub/version-floor.js +0 -45
  586. package/dist/hub/version-floor.js.map +0 -1
  587. package/dist/hub-browser-certificate-policy.d.ts +0 -31
  588. package/dist/hub-browser-certificate-policy.js +0 -25
  589. package/dist/hub-browser-certificate-policy.js.map +0 -1
  590. package/dist/hub-membership-settings.d.ts +0 -6
  591. package/dist/hub-membership-settings.js +0 -21
  592. package/dist/hub-membership-settings.js.map +0 -1
  593. package/dist/hub-mode.d.ts +0 -15
  594. package/dist/hub-mode.js +0 -17
  595. package/dist/hub-mode.js.map +0 -1
  596. package/dist/hub-pairing-summary.d.ts +0 -48
  597. package/dist/hub-pairing-summary.js +0 -36
  598. package/dist/hub-pairing-summary.js.map +0 -1
  599. package/dist/hub-report-target.d.ts +0 -32
  600. package/dist/hub-report-target.js +0 -33
  601. package/dist/hub-report-target.js.map +0 -1
  602. package/dist/hub-retention-policy.d.ts +0 -14
  603. package/dist/hub-retention-policy.js +0 -15
  604. package/dist/hub-retention-policy.js.map +0 -1
  605. package/dist/launchd-service-domain.d.ts +0 -5
  606. package/dist/launchd-service-domain.js +0 -21
  607. package/dist/launchd-service-domain.js.map +0 -1
  608. package/dist/local-pane-endpoint.d.ts +0 -46
  609. package/dist/local-pane-endpoint.js +0 -189
  610. package/dist/local-pane-endpoint.js.map +0 -1
  611. package/dist/local-pane-launcher.d.ts +0 -2
  612. package/dist/local-pane-launcher.js +0 -38
  613. package/dist/local-pane-launcher.js.map +0 -1
  614. package/dist/local-pane-stage.ps1 +0 -101
  615. package/dist/model-catalog-defaults.d.ts +0 -14
  616. package/dist/model-catalog-defaults.js +0 -20
  617. package/dist/model-catalog-defaults.js.map +0 -1
  618. package/dist/native-agent-admission.d.ts +0 -7
  619. package/dist/native-agent-admission.js +0 -26
  620. package/dist/native-agent-admission.js.map +0 -1
  621. package/dist/native-daemon-client.d.ts +0 -13
  622. package/dist/native-daemon-client.js +0 -28
  623. package/dist/native-daemon-client.js.map +0 -1
  624. package/dist/native-instance-api.d.ts +0 -13
  625. package/dist/native-instance-api.js +0 -217
  626. package/dist/native-instance-api.js.map +0 -1
  627. package/dist/native-instance-input.d.ts +0 -87
  628. package/dist/native-instance-input.js +0 -59
  629. package/dist/native-instance-input.js.map +0 -1
  630. package/dist/native-instance-registry.d.ts +0 -38
  631. package/dist/native-instance-registry.js +0 -129
  632. package/dist/native-instance-registry.js.map +0 -1
  633. package/dist/native-mcp.d.ts +0 -43
  634. package/dist/native-mcp.js +0 -291
  635. package/dist/native-mcp.js.map +0 -1
  636. package/dist/native-model-catalog.d.ts +0 -5
  637. package/dist/native-model-catalog.js +0 -76
  638. package/dist/native-model-catalog.js.map +0 -1
  639. package/dist/native-pane-crash-budget.d.ts +0 -20
  640. package/dist/native-pane-crash-budget.js +0 -60
  641. package/dist/native-pane-crash-budget.js.map +0 -1
  642. package/dist/native-pane-create.d.ts +0 -26
  643. package/dist/native-pane-create.js +0 -53
  644. package/dist/native-pane-create.js.map +0 -1
  645. package/dist/native-pane-lifecycle.d.ts +0 -73
  646. package/dist/native-pane-lifecycle.js +0 -239
  647. package/dist/native-pane-lifecycle.js.map +0 -1
  648. package/dist/native-pane-manager.d.ts +0 -59
  649. package/dist/native-pane-manager.js +0 -592
  650. package/dist/native-pane-manager.js.map +0 -1
  651. package/dist/native-pane-output-log.d.ts +0 -15
  652. package/dist/native-pane-output-log.js +0 -108
  653. package/dist/native-pane-output-log.js.map +0 -1
  654. package/dist/native-pane-reconciliation.d.ts +0 -4
  655. package/dist/native-pane-reconciliation.js +0 -40
  656. package/dist/native-pane-reconciliation.js.map +0 -1
  657. package/dist/native-pane-recovery.d.ts +0 -12
  658. package/dist/native-pane-recovery.js +0 -10
  659. package/dist/native-pane-recovery.js.map +0 -1
  660. package/dist/native-pane-tools.d.ts +0 -2
  661. package/dist/native-pane-tools.js +0 -14
  662. package/dist/native-pane-tools.js.map +0 -1
  663. package/dist/office-talk.d.ts +0 -26
  664. package/dist/office-talk.js +0 -50
  665. package/dist/office-talk.js.map +0 -1
  666. package/dist/pane-port.d.ts +0 -118
  667. package/dist/pane-port.js +0 -2
  668. package/dist/pane-port.js.map +0 -1
  669. package/dist/runtime-api.d.ts +0 -10
  670. package/dist/runtime-api.js +0 -189
  671. package/dist/runtime-api.js.map +0 -1
  672. package/dist/runtime-assets/@xterm/addon-serialize/LICENSE +0 -21
  673. package/dist/runtime-assets/@xterm/addon-serialize/lib/addon-serialize.js +0 -2
  674. package/dist/runtime-assets/@xterm/addon-serialize/lib/addon-serialize.mjs +0 -19
  675. package/dist/runtime-assets/@xterm/addon-serialize/package.json +0 -29
  676. package/dist/runtime-assets/@xterm/headless/LICENSE +0 -21
  677. package/dist/runtime-assets/@xterm/headless/lib-headless/xterm-headless.js +0 -2
  678. package/dist/runtime-assets/@xterm/headless/lib-headless/xterm-headless.mjs +0 -46
  679. package/dist/runtime-assets/@xterm/headless/package.json +0 -29
  680. package/dist/runtime-assets/node-pty/CONPTY-LICENSE +0 -21
  681. package/dist/runtime-assets/node-pty/CONPTY-NOTICE.md +0 -503
  682. package/dist/runtime-assets/node-pty/LICENSE +0 -69
  683. package/dist/runtime-assets/node-pty/lib/conpty_console_list_agent.js +0 -16
  684. package/dist/runtime-assets/node-pty/lib/eventEmitter2.js +0 -47
  685. package/dist/runtime-assets/node-pty/lib/index.js +0 -52
  686. package/dist/runtime-assets/node-pty/lib/interfaces.js +0 -7
  687. package/dist/runtime-assets/node-pty/lib/shared/conout.js +0 -11
  688. package/dist/runtime-assets/node-pty/lib/terminal.js +0 -190
  689. package/dist/runtime-assets/node-pty/lib/types.js +0 -7
  690. package/dist/runtime-assets/node-pty/lib/unixTerminal.js +0 -346
  691. package/dist/runtime-assets/node-pty/lib/utils.js +0 -39
  692. package/dist/runtime-assets/node-pty/lib/windowsConoutConnection.js +0 -125
  693. package/dist/runtime-assets/node-pty/lib/windowsPtyAgent.js +0 -320
  694. package/dist/runtime-assets/node-pty/lib/windowsTerminal.js +0 -199
  695. package/dist/runtime-assets/node-pty/lib/worker/conoutSocketWorker.js +0 -22
  696. package/dist/runtime-assets/node-pty/package.json +0 -64
  697. package/dist/runtime-assets/node-pty/prebuilds/win32-arm64/conpty/OpenConsole.exe +0 -0
  698. package/dist/runtime-assets/node-pty/prebuilds/win32-arm64/conpty/conpty.dll +0 -0
  699. package/dist/runtime-assets/node-pty/prebuilds/win32-arm64/conpty.node +0 -0
  700. package/dist/runtime-assets/node-pty/prebuilds/win32-arm64/conpty_console_list.node +0 -0
  701. package/dist/runtime-assets/node-pty/prebuilds/win32-x64/conpty/OpenConsole.exe +0 -0
  702. package/dist/runtime-assets/node-pty/prebuilds/win32-x64/conpty/conpty.dll +0 -0
  703. package/dist/runtime-assets/node-pty/prebuilds/win32-x64/conpty.node +0 -0
  704. package/dist/runtime-assets/node-pty/prebuilds/win32-x64/conpty_console_list.node +0 -0
  705. package/dist/runtime-build-info.d.ts +0 -9
  706. package/dist/runtime-build-info.js +0 -59
  707. package/dist/runtime-build-info.js.map +0 -1
  708. package/dist/runtime-bundle.d.ts +0 -22
  709. package/dist/runtime-bundle.js +0 -158
  710. package/dist/runtime-bundle.js.map +0 -1
  711. package/dist/runtime-cli.d.ts +0 -14
  712. package/dist/runtime-cli.js +0 -271
  713. package/dist/runtime-cli.js.map +0 -1
  714. package/dist/runtime-client-store.d.ts +0 -75
  715. package/dist/runtime-client-store.js +0 -372
  716. package/dist/runtime-client-store.js.map +0 -1
  717. package/dist/runtime-client.d.ts +0 -174
  718. package/dist/runtime-client.js +0 -1010
  719. package/dist/runtime-client.js.map +0 -1
  720. package/dist/runtime-connection.d.ts +0 -22
  721. package/dist/runtime-connection.js +0 -93
  722. package/dist/runtime-connection.js.map +0 -1
  723. package/dist/runtime-coordinator.d.ts +0 -98
  724. package/dist/runtime-coordinator.js +0 -1089
  725. package/dist/runtime-coordinator.js.map +0 -1
  726. package/dist/runtime-credential-profiles.d.ts +0 -78
  727. package/dist/runtime-credential-profiles.js +0 -280
  728. package/dist/runtime-credential-profiles.js.map +0 -1
  729. package/dist/runtime-general-protocol.d.ts +0 -22
  730. package/dist/runtime-general-protocol.js +0 -57
  731. package/dist/runtime-general-protocol.js.map +0 -1
  732. package/dist/runtime-general-workspace.d.ts +0 -17
  733. package/dist/runtime-general-workspace.js +0 -213
  734. package/dist/runtime-general-workspace.js.map +0 -1
  735. package/dist/runtime-install.d.ts +0 -50
  736. package/dist/runtime-install.js +0 -186
  737. package/dist/runtime-install.js.map +0 -1
  738. package/dist/runtime-pane-assets.d.ts +0 -17
  739. package/dist/runtime-pane-assets.js +0 -23
  740. package/dist/runtime-pane-assets.js.map +0 -1
  741. package/dist/runtime-pane-boot.d.ts +0 -9
  742. package/dist/runtime-pane-boot.js +0 -47
  743. package/dist/runtime-pane-boot.js.map +0 -1
  744. package/dist/runtime-pane-codex-index.d.ts +0 -10
  745. package/dist/runtime-pane-codex-index.js +0 -151
  746. package/dist/runtime-pane-codex-index.js.map +0 -1
  747. package/dist/runtime-pane-config.d.ts +0 -16
  748. package/dist/runtime-pane-config.js +0 -54
  749. package/dist/runtime-pane-config.js.map +0 -1
  750. package/dist/runtime-pane-host.d.ts +0 -63
  751. package/dist/runtime-pane-host.js +0 -467
  752. package/dist/runtime-pane-host.js.map +0 -1
  753. package/dist/runtime-pane-job-owner.d.ts +0 -1
  754. package/dist/runtime-pane-job-owner.js +0 -29
  755. package/dist/runtime-pane-job-owner.js.map +0 -1
  756. package/dist/runtime-pane-job.ps1 +0 -116
  757. package/dist/runtime-pane-link.d.ts +0 -47
  758. package/dist/runtime-pane-link.js +0 -337
  759. package/dist/runtime-pane-link.js.map +0 -1
  760. package/dist/runtime-pane-mcp-protocol.d.ts +0 -32
  761. package/dist/runtime-pane-mcp-protocol.js +0 -39
  762. package/dist/runtime-pane-mcp-protocol.js.map +0 -1
  763. package/dist/runtime-pane-mcp-relay.d.ts +0 -18
  764. package/dist/runtime-pane-mcp-relay.js +0 -80
  765. package/dist/runtime-pane-mcp-relay.js.map +0 -1
  766. package/dist/runtime-pane-mcp.d.ts +0 -55
  767. package/dist/runtime-pane-mcp.js +0 -153
  768. package/dist/runtime-pane-mcp.js.map +0 -1
  769. package/dist/runtime-pane-native.d.ts +0 -75
  770. package/dist/runtime-pane-native.js +0 -114
  771. package/dist/runtime-pane-native.js.map +0 -1
  772. package/dist/runtime-pane-output.d.ts +0 -19
  773. package/dist/runtime-pane-output.js +0 -53
  774. package/dist/runtime-pane-output.js.map +0 -1
  775. package/dist/runtime-pane-port.d.ts +0 -144
  776. package/dist/runtime-pane-port.js +0 -574
  777. package/dist/runtime-pane-port.js.map +0 -1
  778. package/dist/runtime-pane-private.d.ts +0 -14
  779. package/dist/runtime-pane-private.js +0 -51
  780. package/dist/runtime-pane-private.js.map +0 -1
  781. package/dist/runtime-pane-private.ps1 +0 -14
  782. package/dist/runtime-pane-process.d.ts +0 -4
  783. package/dist/runtime-pane-process.js +0 -117
  784. package/dist/runtime-pane-process.js.map +0 -1
  785. package/dist/runtime-pane-protocol.d.ts +0 -182
  786. package/dist/runtime-pane-protocol.js +0 -217
  787. package/dist/runtime-pane-protocol.js.map +0 -1
  788. package/dist/runtime-pane-quota-history.d.ts +0 -6
  789. package/dist/runtime-pane-quota-history.js +0 -44
  790. package/dist/runtime-pane-quota-history.js.map +0 -1
  791. package/dist/runtime-pane-screen.d.ts +0 -19
  792. package/dist/runtime-pane-screen.js +0 -76
  793. package/dist/runtime-pane-screen.js.map +0 -1
  794. package/dist/runtime-pane-service.d.ts +0 -16
  795. package/dist/runtime-pane-service.js +0 -256
  796. package/dist/runtime-pane-service.js.map +0 -1
  797. package/dist/runtime-pane-stdio-protocol.d.ts +0 -54
  798. package/dist/runtime-pane-stdio-protocol.js +0 -94
  799. package/dist/runtime-pane-stdio-protocol.js.map +0 -1
  800. package/dist/runtime-pane-stdio.d.ts +0 -3
  801. package/dist/runtime-pane-stdio.js +0 -123
  802. package/dist/runtime-pane-stdio.js.map +0 -1
  803. package/dist/runtime-pane-store.d.ts +0 -33
  804. package/dist/runtime-pane-store.js +0 -164
  805. package/dist/runtime-pane-store.js.map +0 -1
  806. package/dist/runtime-pane-transcript-protocol.d.ts +0 -43
  807. package/dist/runtime-pane-transcript-protocol.js +0 -58
  808. package/dist/runtime-pane-transcript-protocol.js.map +0 -1
  809. package/dist/runtime-pane-transcript.d.ts +0 -50
  810. package/dist/runtime-pane-transcript.js +0 -666
  811. package/dist/runtime-pane-transcript.js.map +0 -1
  812. package/dist/runtime-pane-worker.d.ts +0 -1
  813. package/dist/runtime-pane-worker.js +0 -167
  814. package/dist/runtime-pane-worker.js.map +0 -1
  815. package/dist/runtime-protocol.d.ts +0 -177
  816. package/dist/runtime-protocol.js +0 -49
  817. package/dist/runtime-protocol.js.map +0 -1
  818. package/dist/runtime-switches.d.ts +0 -79
  819. package/dist/runtime-switches.js +0 -90
  820. package/dist/runtime-switches.js.map +0 -1
  821. package/dist/runtime-transcript-delta-reader.d.ts +0 -23
  822. package/dist/runtime-transcript-delta-reader.js +0 -74
  823. package/dist/runtime-transcript-delta-reader.js.map +0 -1
  824. package/dist/runtime-transcript-source.d.ts +0 -36
  825. package/dist/runtime-transcript-source.js +0 -189
  826. package/dist/runtime-transcript-source.js.map +0 -1
  827. package/dist/runtime-update-activity.d.ts +0 -21
  828. package/dist/runtime-update-activity.js +0 -51
  829. package/dist/runtime-update-activity.js.map +0 -1
  830. package/dist/runtime-update-artifact.d.ts +0 -31
  831. package/dist/runtime-update-artifact.js +0 -252
  832. package/dist/runtime-update-artifact.js.map +0 -1
  833. package/dist/runtime-update-install.d.ts +0 -31
  834. package/dist/runtime-update-install.js +0 -205
  835. package/dist/runtime-update-install.js.map +0 -1
  836. package/dist/runtime-update-journal.d.ts +0 -44
  837. package/dist/runtime-update-journal.js +0 -121
  838. package/dist/runtime-update-journal.js.map +0 -1
  839. package/dist/runtime-update-lock.d.ts +0 -48
  840. package/dist/runtime-update-lock.js +0 -217
  841. package/dist/runtime-update-lock.js.map +0 -1
  842. package/dist/runtime-update-owners.d.ts +0 -29
  843. package/dist/runtime-update-owners.js +0 -240
  844. package/dist/runtime-update-owners.js.map +0 -1
  845. package/dist/runtime-update-protocol.d.ts +0 -15
  846. package/dist/runtime-update-protocol.js +0 -13
  847. package/dist/runtime-update-protocol.js.map +0 -1
  848. package/dist/runtime-windows-bridge.d.ts +0 -42
  849. package/dist/runtime-windows-bridge.js +0 -167
  850. package/dist/runtime-windows-bridge.js.map +0 -1
  851. package/dist/service-drain.d.ts +0 -19
  852. package/dist/service-drain.js +0 -64
  853. package/dist/service-drain.js.map +0 -1
  854. package/dist/settings-route-lifetime.d.ts +0 -14
  855. package/dist/settings-route-lifetime.js +0 -48
  856. package/dist/settings-route-lifetime.js.map +0 -1
  857. package/dist/tmux-binary.d.ts +0 -59
  858. package/dist/tmux-binary.js +0 -200
  859. package/dist/tmux-binary.js.map +0 -1
  860. package/dist/tmux-pane-host.d.ts +0 -26
  861. package/dist/tmux-pane-host.js +0 -25
  862. package/dist/tmux-pane-host.js.map +0 -1
  863. package/dist/transcript-needles.d.ts +0 -42
  864. package/dist/transcript-needles.js +0 -166
  865. package/dist/transcript-needles.js.map +0 -1
  866. package/dist/transcript-records.d.ts +0 -21
  867. package/dist/transcript-records.js +0 -141
  868. package/dist/transcript-records.js.map +0 -1
  869. package/dist/ui/account-identity.js +0 -27
  870. package/dist/ui/accounts-view.js +0 -214
  871. package/dist/ui/agent-proposals.js +0 -90
  872. package/dist/ui/agent-runtime-settings.js +0 -68
  873. package/dist/ui/agent-runtime.js +0 -124
  874. package/dist/ui/cli-picker.js +0 -42
  875. package/dist/ui/credential-profile-select.js +0 -54
  876. package/dist/ui/fleet-office-dialogue.d.ts +0 -30
  877. package/dist/ui/fleet-office-dialogue.js +0 -382
  878. package/dist/ui/fleet-task-menu.js +0 -188
  879. package/dist/ui/fleet-task-stats.js +0 -124
  880. package/dist/ui/fleet-task-view.js +0 -340
  881. package/dist/ui/general-location.js +0 -71
  882. package/dist/ui/hub-agent-copy.js +0 -23
  883. package/dist/ui/hub-button-actions.js +0 -65
  884. package/dist/ui/hub-chat-store.js +0 -158
  885. package/dist/ui/hub-chat-strings.js +0 -77
  886. package/dist/ui/hub-client.js +0 -329
  887. package/dist/ui/hub-owner-strings.js +0 -51
  888. package/dist/ui/hub-provider-guidance.js +0 -31
  889. package/dist/ui/hub-quota.js +0 -85
  890. package/dist/ui/hub-strings.js +0 -162
  891. package/dist/ui/hub-switcher.js +0 -27
  892. package/dist/ui/native-instance-settings.js +0 -44
  893. package/dist/ui/native-pane-recovery.js +0 -45
  894. package/dist/ui/panel-hub.js +0 -619
  895. package/dist/ui/panel-runtimes.js +0 -425
  896. package/dist/ui/panel-windows-agent.js +0 -86
  897. package/dist/ui/panel-windows-cli.js +0 -189
  898. package/dist/ui/provider-marks.js +0 -83
  899. package/dist/ui/runtime-catalog.js +0 -55
  900. package/dist/ui/runtime-commands.d.ts +0 -4
  901. package/dist/ui/runtime-commands.js +0 -59
  902. package/dist/ui/settings-access-strings.js +0 -42
  903. package/dist/ui/settings-agent-filters.js +0 -94
  904. package/dist/ui/settings-build-version.js +0 -35
  905. package/dist/ui/settings-devices.js +0 -253
  906. package/dist/ui/settings-hub-browser-certificate.js +0 -74
  907. package/dist/ui/settings-hub-membership.js +0 -72
  908. package/dist/ui/settings-hub-retention.js +0 -52
  909. package/dist/ui/settings-hub.js +0 -196
  910. package/dist/ui/settings-layout.js +0 -242
  911. package/dist/ui/settings-outside.js +0 -242
  912. package/dist/ui/settings-shared-strings.js +0 -143
  913. package/dist/ui/settings-shared.js +0 -345
  914. package/dist/ui/settings-shortcuts.js +0 -65
  915. package/dist/ui/shared/accounts.css +0 -15
  916. package/dist/ui/shared/chat-composer.js +0 -68
  917. package/dist/ui/shared/chat-md-strings.js +0 -9
  918. package/dist/ui/shared/chat-render.js +0 -682
  919. package/dist/ui/shared/chat-strings.js +0 -333
  920. package/dist/ui/shared/chat-thread.js +0 -969
  921. package/dist/ui/shared/chat-time.js +0 -80
  922. package/dist/ui/shared/html-attachment.js +0 -42
  923. package/dist/ui/shared/hub-chat.css +0 -85
  924. package/dist/ui/shared/hub-owner.css +0 -33
  925. package/dist/ui/shared/hub-quota.css +0 -8
  926. package/dist/ui/shared/hub.css +0 -71
  927. package/dist/ui/shared/machine-name.js +0 -13
  928. package/dist/ui/shared/page-head.js +0 -8
  929. package/dist/ui/shared/preview.js +0 -476
  930. package/dist/ui/shared/qrcode.module.js +0 -2237
  931. package/dist/ui/shared/runtime-install.css +0 -26
  932. package/dist/ui/shared/settings-width.js +0 -31
  933. package/dist/ui/shared/side-rail.js +0 -15
  934. package/dist/ui/shared/task-board.css +0 -95
  935. package/dist/ui/shared/vendor/qrcode-generator.LICENSE +0 -27
  936. package/dist/ui/shared/workspace.css +0 -20
  937. package/dist/ui/windows-agents-nav.js +0 -2
  938. package/dist/ui/windows-cli-catalog.js +0 -108
  939. package/dist/ui/workspace-panel.js +0 -189
  940. package/dist/ui/workspace-strings.js +0 -35
  941. package/dist/web-device-login.d.ts +0 -153
  942. package/dist/web-device-login.js +0 -278
  943. package/dist/web-device-login.js.map +0 -1
  944. package/dist/web-remote-access.d.ts +0 -152
  945. package/dist/web-remote-access.js +0 -368
  946. package/dist/web-remote-access.js.map +0 -1
  947. package/dist/windows-agents.d.ts +0 -127
  948. package/dist/windows-agents.js +0 -491
  949. package/dist/windows-agents.js.map +0 -1
  950. package/dist/windows-cli-api.d.ts +0 -34
  951. package/dist/windows-cli-api.js +0 -185
  952. package/dist/windows-cli-api.js.map +0 -1
  953. package/dist/windows-cli-providers.d.ts +0 -106
  954. package/dist/windows-cli-providers.js +0 -424
  955. package/dist/windows-cli-providers.js.map +0 -1
  956. package/dist/windows-cli-worker.d.ts +0 -83
  957. package/dist/windows-cli-worker.js +0 -570
  958. package/dist/windows-cli-worker.js.map +0 -1
  959. package/dist/windows-cli.d.ts +0 -126
  960. package/dist/windows-cli.js +0 -416
  961. package/dist/windows-cli.js.map +0 -1
  962. package/dist/windows-native-mcp.d.ts +0 -19
  963. package/dist/windows-native-mcp.js +0 -143
  964. package/dist/windows-native-mcp.js.map +0 -1
  965. package/dist/windows-pane-mcp.d.ts +0 -26
  966. package/dist/windows-pane-mcp.js +0 -187
  967. package/dist/windows-pane-mcp.js.map +0 -1
  968. package/launcher/launchd-session-type.cjs +0 -14
  969. package/launcher/tmux-bundle.cjs +0 -247
  970. package/templates/runtime-assets/conpty-LICENSE +0 -21
  971. package/templates/runtime-assets/conpty-NOTICE.md +0 -503
  972. package/templates/runtime-assets/local-pane-stage.ps1 +0 -101
  973. package/templates/runtime-assets/runtime-pane-job.ps1 +0 -116
  974. package/templates/runtime-assets/runtime-pane-private.ps1 +0 -14
  975. package/templates/runtime-assets/xterm-LICENSE +0 -21
  976. package/templates/runtime-install/install.ps1 +0 -270
@@ -1,4 +1,3 @@
1
- import { SettingsBuildVersion } from "./settings-build-version.js";
2
1
  // #1408 step 3: the Settings panel (/settings[/<section>]) — agents, connections, ClassicBot rooms, general defaults,
3
2
  // the developer YAML. Behind the session gate (/ui/js/), loaded the first time it is opened.
4
3
  //
@@ -26,73 +25,44 @@ import { Menu } from "/assets/ui-menu.js";
26
25
  import { toast } from "/assets/ui-toast.js";
27
26
  import { GroupMark, groupLabel, groupOf as navGroupOf, modelText } from "/assets/instance-nav.js";
28
27
  import "./settings-strings.js";
29
- import "./settings-shared-strings.js"; // see settings-shared.js: the words Shared agent settings added, which an older settings-strings.js in an open tab lacks
30
- import "./settings-access-strings.js"; // the words Access & security added (settings.webLoginQr…): an older settings-strings.js from a tab that visited Fleet first lacks them (#3061)
31
28
  import { api, attach, confirmedWrite, newKey } from "./settings-confirm.js";
32
29
  import { dismissOperation, operationActive, restartFleet, startOperation, takeLeftover } from "./settings-apply.js";
33
30
  import {
34
- ACCESS_MODES, DASHBOARD_FEATURES, SEPARATE_FEATURE_KEYS, DEFAULT_SCHEMA, ownChoiceImpact, HANG_TIMEOUT_DEFAULT_MINUTES, TOOL_PROGRESS, TOOL_SETS, VISIBILITY_MODES, batchImpact,
31
+ ACCESS_MODES, AGENT_MODES, DASHBOARD_FEATURES, SEPARATE_FEATURE_KEYS, DEFAULT_SCHEMA, ownChoiceImpact, HANG_TIMEOUT_DEFAULT_MINUTES, LOG_LEVELS, TOOL_PROGRESS, TOOL_SETS, VISIBILITY_MODES, batchImpact,
35
32
  changedFields, channelId, channelsOf, chLabel, connectionState, dashboardDefault, effectiveSummary, fleetModel, fromYaml, fullModelRequests, groupAgents,
36
- hasOwn, impactOf, defaultsImpact, requestImpact, nonNegative, positive, replyGuardSupported, sameValue, shortName, STATUS_ORDER, toYaml,
37
- visibilityDefault, worstImpact,
33
+ hasOwn, impactOf, localeOptions, defaultsImpact, requestImpact, nonNegative, positive, replyGuardSupported, sameValue, shortName, STATUS_ORDER, toYaml,
34
+ toolSetDefault, visibilityDefault, worstImpact,
38
35
  } from "./settings-model.js";
39
36
  import {
40
- AgentDialog, BackendSelect, BotDialog, ChipList, ClassicDialog, DefaultMark, Feedback, Impact, InEffect, Inherited, Label,
37
+ AgentDialog, BackendSelect, BotDialog, ChipList, ClassicDialog, DefaultMark, Drawer, Feedback, Impact, InEffect, Inherited, Label, ModelSelect,
41
38
  NewBotDialog, Override, Select, ask, impactText, inAgentDefaults, valueText,
42
39
  } from "./settings-dialogs.js";
43
- import { SharedAgentSettings, sharedNotes } from "./settings-shared.js";
40
+ import { QuotaNoticeSettings, quotaNoticeText } from "./settings-quota-notice.js";
44
41
  import { SetupWizard } from "./settings-wizard.js";
45
42
  import { CreateInstanceDialog } from "./panel-fleet.js";
46
- import { RuntimesPanel } from "./panel-runtimes.js";
47
- import { NativeInstanceSettings } from "./native-instance-settings.js";
48
43
  import { FirstRunCard, takeWizardRequest } from "./first-run.js";
49
44
  import { takeAgentRequest } from "./settings-request.js";
50
45
  // #1604: This device — the preview opt-in (one path: the app's confirm, then preview.js) and the tour, from the chat.
51
46
  import { setPreviewOptIn } from "./panel-chat.js";
52
47
  import { startTour } from "./chat-tour.js";
53
- import "/assets/chat-strings.js";
48
+ import "./chat-strings.js";
54
49
  import { AppearanceSection } from "./settings-appearance.js";
55
50
  import { GuestsCard } from "./settings-guests.js";
56
51
  import { OfficeSharesCard } from "./office-share-dialog.js";
57
52
  import { PageSharesCard } from "./page-share-dialog.js";
58
53
  import { syncStage, useDraft } from "./settings-draft.js";
59
54
  import { WebAuthorityCard } from "./settings-web-authority.js";
60
- import { OutsideCard } from "./settings-outside.js";
61
- import { DevicesCard } from "./settings-devices.js";
62
- /** The pure owner Settings switch is available while off; its pairing UI remains lazy and member-mark gated. */
63
- function HubCardSlot() {
64
- const [Card, setCard] = useState(null);
65
- useEffect(() => { let live = true; import("./settings-hub-membership.js").then((m) => { if (live) setCard(() => m.HubMembershipSettings); }, () => {}); return () => { live = false; }; }, []);
66
- return Card ? html`<${Card} />` : null;
67
- }
68
- function HubBrowserCertificateSlot() {
69
- const [Card, setCard] = useState(null);
70
- useEffect(() => { let live = true; import("./settings-hub-browser-certificate.js").then(m => { if (live) setCard(() => m.HubBrowserCertificateSettings); }, () => {}); return () => { live = false; }; }, []);
71
- return Card ? html`<${Card} />` : null;
72
- }
73
- function HubRetentionSlot() {
74
- const [Card, setCard] = useState(null);
75
- useEffect(() => { let live = true; import("./settings-hub-retention.js").then(m => { if (live) setCard(() => m.HubRetentionSettings); }, () => {}); return () => { live = false; }; }, []);
76
- return Card ? html`<${Card} />` : null;
77
- }
78
55
  import { NamedLinkTest, setTypedTunnelToken } from "./settings-named-test.js";
79
56
  import { SignInList } from "./backend-signin.js";
80
- import { AccountsView, defaultsBackendOptions } from "./accounts-view.js"; // #3212: SignInList stays exported for a page that still imports it
81
- import { ProviderMark } from "./provider-marks.js";
82
- import { CliProductMark, cliLabel } from "./cli-picker.js";
83
- import { SettingsPageHead, SettingsTabs, SettingsTabPanel, useSettingsTabs, revealSettingsTarget, layoutText } from "./settings-layout.js";
84
- import { AgentFilters, agentFilterText, agentRuntime, agentRuntimeOffline, agentStatus, filterAgentGroups } from "./settings-agent-filters.js";
85
- import { useRuntimeCatalog } from "./runtime-catalog.js";
86
- import { ShortcutsHelpRow } from "./settings-shortcuts.js";
87
- import { GeneralLocation } from "./general-location.js";
88
57
 
89
- const tn = (k, ...v) => t(`settings.${k}`, ...v);
58
+ const tn = (k, ...v) => k === "sec_notifications" ? quotaNoticeText().title : t(`settings.${k}`, ...v);
90
59
  /** What a refused change says to a person: the server's code in words (the code itself only for one not listed). */
91
60
  const APPLY_ERRORS = new Set(["unsupported_sensitive_effect", "confirmation_diff_too_large", "session_required", "admin_required", "settings_changed",
92
61
  "request_no_longer_current", "too_many_pending_changes", "fleet_unavailable", "invalid_settings_effect", "settings_confirmation_unavailable", "failed"]);
93
62
  // #2726: a code or words of the setup host (the wizard's commit) in the page's language; anything else as it came.
94
63
  export const applyErrorText = (code) => (APPLY_ERRORS.has(code) ? tn(`applyError_${code}`) : tn("applyErrorOther", hostText(String(code), lang())));
95
- const ICONS = { preferences: "user", look: "palette", agents: "bot", runtimes: "view", "agent-defaults": "sliders", chat: "chat", "web-dashboard": "globe", access: "key", advanced: "code" };
64
+ const ICONS = { preferences: "user", look: "palette", agents: "bot", notifications: "sliders", "agent-defaults": "sliders", chat: "chat", "web-dashboard": "globe", access: "key", advanced: "code" };
65
+ const RELEASES = "https://github.com/songsid/AgEnD/releases";
96
66
 
97
67
  /** GET under the panel's lease → { ok, status, body }. */
98
68
  async function read(lease, path) {
@@ -134,7 +104,7 @@ async function loadLive(lease) {
134
104
  if (!lease.current()) return null;
135
105
  const live = {}, classicLive = {};
136
106
  if (f.ok && f.body && Array.isArray(f.body.instances)) for (const i of f.body.instances) {
137
- live[i.name] = { status: i.status, state: i.state, backend: i.backend, model: i.model, model_display: modelText(i, i.model_display), effort: i.effort, effort_supported: i.effort_supported, runtime:i.runtime, capabilities:i.capabilities, machine_id:i.machine_id, machine_name:i.machine_name, machine_status:i.machine_status };
107
+ live[i.name] = { status: i.status, state: i.state, backend: i.backend, model: i.model, model_display: modelText(i, i.model_display), effort: i.effort, effort_supported: i.effort_supported };
138
108
  if (i.classic) classicLive[i.name] = { status: i.status, state: i.state };
139
109
  }
140
110
  // /api/fleet carries live state for ClassicBot rooms; the profiles are the fallback for one not listed there yet.
@@ -142,7 +112,7 @@ async function loadLive(lease) {
142
112
  if (!lease.current()) return null;
143
113
  const classicStatus = {};
144
114
  if (pr.ok && Array.isArray(pr.body)) for (const r of pr.body) classicStatus[r.instance_name] = r.status;
145
- return { live, classicLive, classicStatus, fleetUp: f.ok, version: (f.ok && f.body && f.body.version) || "", build: f.ok && f.body ? f.body.build : null };
115
+ return { live, classicLive, classicStatus, fleetUp: f.ok, version: (f.ok && f.body && f.body.version) || "" };
146
116
  }
147
117
 
148
118
  export function SettingsPanel({ route, navKey }) {
@@ -408,30 +378,20 @@ export function SettingsPanel({ route, navKey }) {
408
378
  const formKey = data && !data.error ? `${data.loadedAt}:${draftEpoch}` : "";
409
379
  // #2347 regrouping: each card where the person looks for it (the IA in #2347 §3); a form split across sections (the
410
380
  // defaults, Web) is one form with one draft, shown a part at a time.
411
- const sectionBody = section === "preferences" ? html`<${DeviceSection} key=${you.key} />`
381
+ const sectionBody = section === "preferences" ? html`<${DeviceSection} key=${you.key} /><${AppearanceSection} ...${you} part="device" />`
412
382
  : section === "look" ? html`<${AppearanceSection} ...${you} part="look" />`
413
- : section === "runtimes" ? html`<${RuntimesPanel} navKey=${navKey} />`
414
383
  : !data ? html`<${Skeleton} lines=${6} />`
415
384
  : data.error ? html`<${ErrorState} message=${tn("configLoadFailed")} onRetry=${reload} />`
416
- : section === "agents" ? html`<${YamlLock} staged=${staged}><${Agents} ctx=${ctx} search=${search} clearSearch=${() => setSearch("")} openDialog=${toDialog} /></${YamlLock}><details class="s-ui-disclosure s-ai-accounts"><summary><span>${layoutText("aiAccounts")}</span><small>${layoutText("aiAccountsSummary")}</small></summary><div class="s-disclosure-body s-auth-body">
417
- <div class="s-auth-scope"><${Icon} name="view" size=${18} /><div><strong>${layoutText("aiHostScope")}</strong><p>${layoutText("aiAccountsHint")}</p><a href=${settingsPath("runtimes")}>${layoutText("aiWindowsLink")}<span aria-hidden="true">→</span></a></div></div>
418
- <${AccountsView} instances=${ctx.fleet.instances || {}} stageAgent=${ctx.stageAgent}
419
- stageDefault=${(backend, profile) => {
420
- // One change for every CLI's fleet default, carrying the whole map (the write replaces it whole).
421
- const opts = defaultsBackendOptions((ctx.fleet.defaults || {}).backend_options, stagedRef.current.get("defaults:account")?.request?.body?.backend_options, backend, profile);
422
- if (!opts) { ctx.unstage("defaults:account"); return; }
423
- ctx.stage("defaults:account", { label: tn("updateDefaults"), count: 1, impact: defaultsImpact(ctx.schema, "backend_options"),
424
- request: { method: "PUT", url: "/api/settings/fleet/defaults", body: { backend_options: opts } } });
425
- }} />${ctx.providerOk ? html`<${ProviderKeys} ctx=${ctx} />` : html`<section class="s-auth-section s-api-unavailable"><header class="s-auth-section-head"><div><h3>${layoutText("apiKeysTitle")}</h3><p>${layoutText("apiKeysHint")}</p></div><span class="s-auth-state">${layoutText("apiKeysUnavailableState")}</span></header><p class="note">${layoutText("apiKeysUnavailable")}</p></section>`}
426
- </div></details>`
427
- : section === "agent-defaults" ? html`<${GeneralLocation} /><${YamlLock} staged=${staged}><${General} key=${formKey} ctx=${ctx} part="fleet" /></${YamlLock}>`
385
+ : section === "agents" ? html`<${YamlLock} staged=${staged}><${Agents} ctx=${ctx} search=${search} openDialog=${toDialog} /></${YamlLock}>${ctx.providerOk ? html`<${ProviderKeys} ctx=${ctx} />` : null}`
386
+ : section === "agent-defaults" ? html`<${YamlLock} staged=${staged}><${General} key=${formKey} ctx=${ctx} part="fleet" />${!SETTINGS_SECTIONS.includes("notifications") ? html`<${QuotaNoticeSettings} key=${`quota:${formKey}`} ctx=${ctx} />` : null}</${YamlLock}>`
387
+ : section === "notifications" ? html`<${YamlLock} staged=${staged}><${QuotaNoticeSettings} key=${formKey} ctx=${ctx} /></${YamlLock}>`
428
388
  : section === "chat" ? html`<${YamlLock} staged=${staged}><${Bots} ctx=${ctx} search=${search} openDialog=${toDialog} /></${YamlLock}>
429
389
  <${WebSection} key=${formKey} ctx=${ctx} staged=${staged} part="chat" />
430
- <div id="classicbot" class="s-anchor s-classic-area"><section class="card s-chat-classic"><h2 class="s-ap-group">ClassicBot</h2><${Classic} ctx=${ctx} search=${search} openDialog=${toDialog} /></section>
431
- <details class="s-ui-disclosure s-classic-defaults"><summary>${layoutText("classicDefaults")}</summary><div class="s-disclosure-body"><${General} key=${formKey} ctx=${ctx} part="classic" /></div></details></div>`
390
+ <div id="classicbot" class="s-anchor"><h2 class="s-ap-group">ClassicBot</h2><${Classic} ctx=${ctx} search=${search} openDialog=${toDialog} />
391
+ <${General} key=${formKey} ctx=${ctx} part="classic" /></div>`
432
392
  : section === "web-dashboard" ? html`<${WebSection} key=${formKey} ctx=${ctx} staged=${staged} part="dashboard" /><${AppearanceSection} ...${you} part="dashboard" />`
433
393
  : section === "access" ? html`<${WebSection} key=${formKey} ctx=${ctx} staged=${staged} part="access" />`
434
- : html`<${AdvancedSettings} ctx=${ctx} staged=${staged} formKey=${formKey} draftEpoch=${draftEpoch} />`;
394
+ : html`<${Developer} key=${`dev:${draftEpoch}`} ctx=${ctx} /><${WebSection} key=${formKey} ctx=${ctx} staged=${staged} part="readonly" />`;
435
395
  // #2347 §6: the setting a search result opened — brought into view once its section is drawn (its data may still be
436
396
  // on its way), focused, and flashed for 2 s.
437
397
  const wanted = useRef(null);
@@ -450,7 +410,6 @@ export function SettingsPanel({ route, navKey }) {
450
410
  if (++tries < 40) timer = setTimeout(find, 50); else wanted.current = null;
451
411
  return;
452
412
  }
453
- if (revealSettingsTarget(el)) { timer = setTimeout(find, 0); return; }
454
413
  wanted.current = null;
455
414
  // #2347 §10: a setting in a closed drawer (Advanced) is shown — every drawer around it opens first.
456
415
  for (let d = el.closest && el.closest("details"); d; d = d.parentElement && d.parentElement.closest("details")) d.open = true;
@@ -491,14 +450,7 @@ export function SettingsPanel({ route, navKey }) {
491
450
  if (!id) return;
492
451
  let el = null;
493
452
  try { el = document.getElementById(decodeURIComponent(id)); } catch { el = null; }
494
- if (!el) return;
495
- const show = () => {
496
- // Hash links, like settings-search targets, must reveal every enclosing disclosure before scrolling.
497
- for (let d = el.closest && el.closest("details"); d; d = d.parentElement && d.parentElement.closest("details")) d.open = true;
498
- if (typeof el.scrollIntoView === "function") el.scrollIntoView({ block: "start" });
499
- };
500
- if (revealSettingsTarget(el)) { const timer = setTimeout(show, 0); return () => clearTimeout(timer); }
501
- show();
453
+ if (el && typeof el.scrollIntoView === "function") el.scrollIntoView({ block: "start" });
502
454
  }, [section, navKey, !!data]);
503
455
  // A dialog belongs to the navigation that opened it (its draft names one object, never another).
504
456
  const open = dialog && dialog.key === navKey ? dialog : null;
@@ -509,7 +461,7 @@ export function SettingsPanel({ route, navKey }) {
509
461
  // Which one is shown is the root's data-view: its class stays exactly the effects producer's ("panel p-settings", #1629).
510
462
  const atList = typeof location !== "undefined" && location.pathname === "/settings";
511
463
  return html`<div data-effect-panel="settings" class="panel p-settings" data-view=${atList ? "index" : "section"}>
512
- <${PanelHeader} title=${tn("title")} sub=${data ? html`<${SettingsBuildVersion} version=${data.version} build=${data.build} />` : null}>
464
+ <${PanelHeader} title=${tn("title")} sub=${data && data.version ? html`<a class="pill ver" href=${data.version.includes("-") ? `${RELEASES}/latest` : `${RELEASES}/tag/v${data.version}`} target="_blank" rel="noopener">v${data.version}</a>` : null}>
513
465
  <button type="button" class="btn btn-ghost btn-sm" disabled=${!ctx || yamlStaged(staged)} title=${ctx && yamlStaged(staged) ? tn("yamlUnsaved") : undefined} onClick=${openWizard}><${Icon} name="wand" size=${16} /><span class="hide-narrow">${tn("wizardButton")}</span></button>
514
466
  <button type="button" class="icon-btn" aria-label=${tn("helpButton")} title=${tn("helpButton")} onClick=${() => setDialog({ kind: "help", key: navKey })}><${Icon} name="info" /></button>
515
467
  </${PanelHeader}>
@@ -517,15 +469,14 @@ export function SettingsPanel({ route, navKey }) {
517
469
  <span class="s-nav-head" id=${`s-grp-${g.id}`}>${tn(`grp_${g.id}`)}</span>
518
470
  ${g.sections.map((k) => html`<a key=${k} href=${sectionPath(k)} class=${`seg-item${k === section ? " active" : ""}`}
519
471
  aria-current=${k === section ? "page" : undefined}><${Icon} name=${ICONS[k]} size=${16} /><span>${tn(`sec_${k}`)}</span></a>`)}</div>`)}</div></nav>
520
- <div data-trust="panel-content" class="panel-body"><div class="col" data-settings-section=${section}>
472
+ <div data-trust="panel-content" class="panel-body"><div class="col">
521
473
  <a class="s-back" href=${settingsPath()}><${Icon} name="back" size=${16} /><span>${tn("title")}</span><span class="s-back-here">${tn(`sec_${section}`)}</span></a>
522
- ${section !== "runtimes" ? html`<${SettingsPageHead} section=${section}>${section === "agents" && ctx ? html`<button type="button" id="newAgentBtn" class="btn btn-primary" disabled=${yamlStaged(staged)} onClick=${() => toDialog({ kind: "create" })}><${Icon} name="plus" size=${16} />${tn("newAgent")}</button>` : null}</${SettingsPageHead}>` : null}
523
474
  ${searchable ? html`<div class="s-toolbar"><label class="s-search"><${Icon} name="search" size=${14} /><span class="sr-only">${tn("searchAll")}</span>
524
475
  <input type="search" value=${search} placeholder=${tn("searchAll")} onInput=${(e) => setSearch(e.target.value)} /></label></div>` : null}
525
476
  ${op ? html`<${OperationCard} op=${op} schema=${data && data.schema} />` : null}
526
477
  <${PendingChanges} inline=${true} />
527
478
  ${ctx && (section === "agents" || section === "chat") ? html`<${FirstRunCard} onConnect=${openWizard} />` : null}
528
- <div class="s-section-layout" data-section=${section}>${sectionBody}</div>
479
+ ${sectionBody}
529
480
  </div></div>
530
481
  ${staged.size ? html`<${PendingBar} staged=${staged} busy=${opBusy(op)} onApply=${apply} onDiscard=${discard} section=${section} />` : null}
531
482
  ${open && ctx ? renderDialog(open, ctx, close) : null}
@@ -533,14 +484,6 @@ export function SettingsPanel({ route, navKey }) {
533
484
  </div>`;
534
485
  }
535
486
 
536
- function AdvancedSettings({ ctx, staged, formKey, draftEpoch }) {
537
- const [tab, setTab] = useSettingsTabs("advanced", "editor");
538
- return html`<div class="s-advanced-layout"><${SettingsTabs} id="advanced" value=${tab} onChange=${setTab} items=${[{ id: "editor", label: layoutText("editor") }, { id: "effective", label: layoutText("effective") }]} />
539
- <${SettingsTabPanel} group="advanced" id="editor" active=${tab === "editor"}><${Developer} key=${`dev:${draftEpoch}`} ctx=${ctx} /></${SettingsTabPanel}>
540
- <${SettingsTabPanel} group="advanced" id="effective" active=${tab === "effective"}><${WebSection} key=${formKey} ctx=${ctx} staged=${staged} part="readonly" /></${SettingsTabPanel}>
541
- </div>`;
542
- }
543
-
544
487
  /**
545
488
  * #1604, #1665: Preferences. Synced across the person's devices (kept on the host, app-prefs.js): theme (theme.js),
546
489
  * language (app-i18n.js) and HTML previews (preview.js, through the app's confirm). On the public link they are
@@ -662,23 +605,17 @@ export function DeviceSection() {
662
605
  setTimeout(go, 0);
663
606
  };
664
607
  const publicLink = typeof document !== "undefined" && document.body && document.body.dataset.publicLink === "1";
665
- return html`<div class="s-pref-stack">
666
- <section class="card s-device s-pref-personal"><h3>${tn("prefsProfileGroup")}</h3>
667
- <${ProfileCard} embedded=${true} />
668
- <div class="s-pref-name-format"><${DevicePrefs} labels=${true} fields=${["names"]} /></div>
669
- </section>
670
- <section class="card s-device s-synced s-pref-content"><div class="s-pref-group-head"><h3>${tn("prefsContentGroup")}</h3><span class="s-scope" title=${publicLink ? tn("syncedPublicLink") : tn("syncedLead")}>${tn("prefsAccountScope")}</span></div>
671
- ${publicLink ? html`<p class="sub">${tn("syncedPublicLink")}</p>` : null}
672
- <${DevicePrefs} labels=${true} fields=${["language"]} />
673
- ${P() ? html`<label class="check s-pref-preview"><span>${t("chat.previews")}</span><input id="pref-previews" class="s-ui-toggle" type="checkbox" checked=${on} onChange=${(e) => { const want = e.target.checked; setPreviewOptIn(want).then(setOn); }} /><small>${layoutText("previewsPersonalHint")}</small></label>` : null}
674
- </section>
675
- <section class="card s-device s-local s-pref-help"><h3>${tn("prefsHelpGroup")}</h3>
676
- <div class="s-pref-help-row"><div><strong>${t("chat.tour")}</strong><p class="sub">${tn("prefsTourHint")}</p></div>
677
- <button type="button" id="tourBtn" class="btn" title=${t("chat.tourBtnTitle")} onClick=${replay}><${Icon} name="info" size=${16} />${tn("prefsReplayTour")}</button></div>
678
- <${ShortcutsHelpRow} />
679
- </section>
680
- <a class="s-pref-look-link" href=${settingsPath("look")}>${tn("prefsLookHint")}<${Icon} name="chevron" size=${16} /></a>
681
- </div>`;
608
+ return html`<${ProfileCard} />
609
+ <section class="card s-device s-synced"><h3>${tn("syncedTitle")}</h3>
610
+ <p class="sub">${publicLink ? tn("syncedPublicLink") : tn("syncedLead")}</p>
611
+ <${DevicePrefs} labels=${true} />
612
+ ${P() ? html`<label class="check"><input id="pref-previews" type="checkbox" checked=${on} onChange=${(e) => { const want = e.target.checked; setPreviewOptIn(want).then(setOn); }} />
613
+ <span>${t("chat.previews")}</span></label>` : null}
614
+ </section>
615
+ <section class="card s-device s-local"><h3>${tn("deviceTitle")}</h3>
616
+ <p class="sub">${tn("deviceLead")}</p>
617
+ <div class="s-device-row"><button type="button" id="tourBtn" class="btn" title=${t("chat.tourBtnTitle")} onClick=${replay}><${Icon} name="info" size=${16} />${t("chat.tour")}</button></div>
618
+ </section>`;
682
619
  }
683
620
 
684
621
  /**
@@ -688,7 +625,7 @@ export function DeviceSection() {
688
625
  * refuses one; this only shows what it says.
689
626
  */
690
627
  const view = (b) => ({ phase: "ready", name: b.name || "", shown: b.shown || "", id: b.id || "", bound: b.bound === true, platform: b.platform_name || "", error: "" });
691
- export function ProfileCard({ embedded = false } = {}) {
628
+ export function ProfileCard() {
692
629
  const [state, setState] = useState({ phase: "loading", name: "", shown: "", id: "", bound: false, platform: "", error: "" });
693
630
  const [draft, setDraft] = useState("");
694
631
  const lease = useLease();
@@ -715,22 +652,19 @@ export function ProfileCard({ embedded = false } = {}) {
715
652
  };
716
653
  const busy = state.phase !== "ready";
717
654
  const changed = draft.trim() !== state.name;
718
- const initial = [...(state.shown || state.name || "web-user")][0]?.toUpperCase() || "W";
719
- const fields = html`<div class="s-pref-profile-layout">
720
- ${embedded ? html`<span class="s-pref-avatar" aria-hidden="true">${initial}</span>` : null}
721
- <div class="s-pref-profile-main"><div class="field"><label for="profile-name">${tn("profileName")}</label>
722
- <div class="s-pref-name-action"><input id="profile-name" type="text" maxlength="200" autocomplete="nickname" value=${draft} disabled=${busy}
655
+ const loading = state.phase === "loading";
656
+ return html`<section class="card s-device s-profile"><h3>${tn("profileTitle")}</h3>
657
+ ${loading ? html`<div class="sk-profile-cover"><${Skeleton} variant="form" lines=${4} /></div>` : null}
658
+ <div class=${`s-profile-fields${loading ? " sk-reserve" : ""}`} aria-hidden=${loading ? "true" : undefined} inert=${loading || undefined}>
659
+ <p class="sub">${state.bound ? tn("profileLeadBound") : tn("profileLeadUnbound")}</p>
660
+ <div class="field"><label for="profile-name">${tn("profileName")}</label>
661
+ <input id="profile-name" type="text" maxlength="200" autocomplete="nickname" value=${draft} disabled=${busy}
723
662
  placeholder=${state.platform || "web-user"} aria-invalid=${state.error ? "true" : "false"} aria-describedby="profile-help"
724
663
  onInput=${(e) => setDraft(e.target.value)} onKeyDown=${(e) => { if (e.key === "Enter" && changed && draft.trim()) save(false); }} />
725
- <button type="button" class="btn primary" disabled=${busy || !changed || !draft.trim()} onClick=${() => save(false)}>${embedded ? tn("prefsSaveName") : tn("profileSave")}</button></div>
726
- <p class="sub" id="profile-help">${state.error ? html`<span class="err" role="alert">${state.error}</span>` : tn("profileHelp", state.shown || "web-user", state.id)}</p>
727
- </div>
728
- <p class="sub s-pref-immediate">${tn("prefsNameImmediate")}</p>
729
- ${state.name ? html`<div class="s-device-row"><button type="button" class="btn btn-ghost btn-sm" disabled=${busy} onClick=${() => save(true)}>${state.bound ? tn("profileUseAccount", state.platform || "web-user") : tn("profileClear")}</button></div>` : null}
730
- <details class="s-pref-identity-details"><summary>${layoutText("profileIdentityDetails")}</summary><p class="sub">${state.bound ? tn("profileLeadBound") : tn("profileLeadUnbound")}</p></details>
731
- </div></div>`;
732
- return embedded ? html`<div class="s-profile s-pref-profile-fields">${fields}</div>`
733
- : html`<section class="card s-device s-profile"><h3>${tn("profileTitle")}</h3>${fields}</section>`;
664
+ <p class="sub" id="profile-help">${state.error ? html`<span class="err" role="alert">${state.error}</span>` : tn("profileHelp", state.shown || "web-user", state.id)}</p></div>
665
+ <div class="s-device-row"><button type="button" class="btn primary" disabled=${busy || !changed || !draft.trim()} onClick=${() => save(false)}>${tn("profileSave")}</button>
666
+ ${state.name ? html`<button type="button" class="btn" disabled=${busy} onClick=${() => save(true)}>${state.bound ? tn("profileUseAccount", state.platform || "web-user") : tn("profileClear")}</button>` : null}</div>
667
+ </div></section>`;
734
668
  }
735
669
 
736
670
  /** The operation in hand still owns Apply: its writes and job, or a restart of AgEnD from the press to its end. */
@@ -738,7 +672,7 @@ const opBusy = (op) => !!op && (["writing", "posting", "watching"].includes(op.p
738
672
  function dropSecrets(staged) { for (const c of staged.values()) if (c.connectionSecret) c.connectionSecret.secret = ""; }
739
673
 
740
674
  function renderDialog(d, ctx, close) {
741
- if (d.kind === "agent") return d.inst.runtime === "windows" ? html`<${NativeInstanceSettings} name=${d.name} inst=${d.inst} ctx=${ctx} onClose=${close} />` : html`<${AgentDialog} name=${d.name} inst=${d.inst} ctx=${ctx} onClose=${close} />`;
675
+ if (d.kind === "agent") return html`<${AgentDialog} name=${d.name} inst=${d.inst} ctx=${ctx} onClose=${close} />`;
742
676
  if (d.kind === "bot") return html`<${BotDialog} key=${d.id} id=${d.id} ctx=${ctx} onClose=${close} />`;
743
677
  if (d.kind === "newBot") return html`<${NewBotDialog} ctx=${ctx} onClose=${close} />`;
744
678
  if (d.kind === "classic") return html`<${ClassicDialog} room=${d.room} ctx=${ctx} onClose=${close} />`;
@@ -772,17 +706,16 @@ function makeCtx(data, setData, stage, unstage, reload, reloadLive, alive, extra
772
706
  });
773
707
  stage(`agent:${name}`, {
774
708
  label: tn("updateAgent", shortName(name, { ...inst, ...patch })),
775
- impact: inst.runtime === "windows" ? "now" : batchImpact(schema, Object.keys(patch), (k) => impactOf(schema, `instance.${k}`)),
776
- request: { method: "PATCH", url: inst.runtime === "windows" ? `/ui/instances/${encodeURIComponent(name)}` : `/api/settings/fleet/instances/${encodeURIComponent(name)}`, body: patch },
709
+ impact: batchImpact(schema, Object.keys(patch), (k) => impactOf(schema, `instance.${k}`)),
710
+ request: { method: "PATCH", url: `/api/settings/fleet/instances/${encodeURIComponent(name)}`, body: patch },
777
711
  });
778
712
  },
779
713
  async deleteAgent(name) {
780
714
  if (!(await ask(tn("deleteAgent", name), { confirmLabel: tn("deleteAgentMenu"), danger: true }))) return;
781
715
  if (!alive()) return; // the panel went while it asked: nothing staged, nothing said
782
- const native = fleet.instances?.[name]?.runtime === "windows";
783
716
  edit((d) => { delete d.fleet.instances[name]; });
784
- stage(`agent:${name}`, { label: tn("deleteAgentLabel", name), impact: native ? "now" : impactOf(schema, "instance.delete"),
785
- request: { method: "DELETE", url: native ? `/ui/instances/${encodeURIComponent(name)}` : `/api/settings/fleet/instances/${encodeURIComponent(name)}` } });
717
+ stage(`agent:${name}`, { label: tn("deleteAgentLabel", name), impact: impactOf(schema, "instance.delete"),
718
+ request: { method: "DELETE", url: `/api/settings/fleet/instances/${encodeURIComponent(name)}` } });
786
719
  },
787
720
  stageChannels(key, nextChannels, meta) {
788
721
  edit((d) => { d.fleet.channels = nextChannels; delete d.fleet.channel; });
@@ -827,67 +760,58 @@ function agentChannelLabel(inst, chs) {
827
760
  return idx >= 0 ? `${chs[idx].type} (${chLabel(idx)})` : inst.channel_id;
828
761
  }
829
762
 
830
- function Agents({ ctx, search, clearSearch, openDialog }) {
763
+ function Agents({ ctx, search, openDialog }) {
831
764
  const insts = ctx.fleet.instances || {};
832
765
  const [collapsed, setCollapsed] = useState(() => new Set());
833
766
  const [busy, setBusy] = useState(() => new Map()); // name → the action under way
834
- const [runtime, setRuntime] = useState("");
835
- const [status, setStatus] = useState("");
836
- // The computers' names come from the same list as the Runtime page (revoked ones included, so an Agent still bound to one can say so).
837
- const catalog = useRuntimeCatalog(Object.values(insts).some((inst) => inst?.machine_id));
838
- // A fleet with remote Runtimes off answers { enabled: false, machines: [] }: that is no list, not an empty one.
839
- const machines = catalog.data && catalog.data.enabled !== false ? new Map(catalog.data.machines.map((machine) => [machine.id, { name: machine.name, status: machine.status }])) : null;
840
767
  const chs = channelsOf(ctx.fleet);
841
768
  // #2172: the sidebar's grouping — an agent in a team under its team, else under its first tag.
842
769
  const teamsOf = (name) => Object.keys(ctx.fleet.teams || {}).filter((t) => Array.isArray(ctx.fleet.teams[t]?.members) && ctx.fleet.teams[t].members.includes(name));
843
- const groups = filterAgentGroups(groupAgents(insts, ctx.live, search, (name) => navGroupOf({ tags: insts[name]?.tags, teams: teamsOf(name) }), groupLabel), insts, ctx.live, { runtime, status });
844
- const active = !!(runtime || status || search.trim());
770
+ const groups = groupAgents(insts, ctx.live, search, (name) => navGroupOf({ tags: insts[name]?.tags, teams: teamsOf(name) }), groupLabel);
845
771
  // One action per agent at a time: the whole row is off (Settings and ⋯ too), and the pressed button says it is working.
846
772
  const run = async (name, action, work) => {
847
773
  if (busy.has(name)) return;
848
774
  setBusy((b) => new Map(b).set(name, action));
849
775
  try { await work(); } finally { setBusy((b) => { const n = new Map(b); n.delete(name); return n; }); }
850
776
  };
851
- const head = html`<${AgentFilters} instances=${insts} live=${ctx.live} machines=${machines} runtime=${runtime} status=${status} active=${active}
852
- matched=${groups.reduce((count, group) => count + group.names.length, 0)} total=${Object.keys(insts).length} onRuntime=${setRuntime} onStatus=${setStatus}
853
- onClear=${() => { setRuntime(""); setStatus(""); clearSearch(); }} />`;
854
- if (!Object.keys(insts).length) return html`${head}<${Empty} icon="bot" title=${tn("noAgents")} />`;
855
- if (!groups.length) return html`${head}<${Empty} icon="search" title=${search.trim() ? tn("noAgentMatch", search.trim()) : agentFilterText("noMatch")} hint=${agentFilterText("noMatchHint")} />`;
856
- return html`${head}<div class="s-list s-agents-list">
857
- <div class="s-list-columns s-agent-columns" aria-hidden="true"><span>${tn("uiAgentColumnName")}</span><span>${agentFilterText("runtime")}</span><span>${tn("uiAgentColumnCli")}</span><span>${tn("uiListColumnState")}</span><span>${tn("uiListColumnActions")}</span></div>${groups.map(({ group, names }) => {
858
- const folded = collapsed.has(group) && !active; // searching/filtering opens every matching group
777
+ const head = html`<div class="list-head"><span>${Object.keys(insts).length === 1 ? tn("countAgent") : tn("countAgents", Object.keys(insts).length)}</span>
778
+ <button type="button" id="newAgentBtn" class="btn btn-primary" onClick=${() => openDialog({ kind: "create" })}><${Icon} name="plus" size=${16} />${tn("newAgent")}</button></div>`;
779
+ // #2233: after the agents, each login on this machine with Sign in (backend-signin.js).
780
+ const signIns = html`<${SignInList} />`;
781
+ if (!Object.keys(insts).length) return html`${head}<${Empty} icon="bot" title=${tn("noAgents")} />${signIns}`;
782
+ if (!groups.length) return html`${head}<${Empty} icon="search" title=${tn("noAgentMatch", search.trim())} />${signIns}`;
783
+ return html`${head}<div class="s-list">${groups.map(({ group, names }) => {
784
+ const folded = collapsed.has(group) && !search.trim(); // searching opens every group
859
785
  return html`<section key=${group} class="s-group">
860
786
  <button type="button" class="s-group-head" aria-expanded=${folded ? "false" : "true"}
861
787
  onClick=${() => setCollapsed((c) => { const n = new Set(c); n.has(group) ? n.delete(group) : n.add(group); return n; })}>
862
788
  <${Icon} name="chevron" size=${14} cls=${folded ? "caret folded" : "caret"} /><${GroupMark} group=${group} /><span class="grow">${groupLabel(group)}</span><span class="count">${names.length}</span></button>
863
789
  ${folded ? null : names.map((name) => {
864
790
  const inst = insts[name];
865
- const st = agentStatus(ctx.live[name]);
791
+ const st = (ctx.live[name] && ctx.live[name].status) || "stopped";
866
792
  const sum = effectiveSummary(ctx.live[name] || {}, inst, ctx.fleet.defaults || {});
867
793
  const ch = agentChannelLabel(inst, chs);
868
794
  const working = busy.has(name), doing = busy.get(name);
869
795
  const label = (action, text) => (doing === action ? tn("working") : text);
870
- const runtimeTarget = agentRuntime(inst, ctx.live[name], machines);
871
- return html`<div key=${name} class="s-row s-agent-row">
872
- <div class="s-agent-identity"><span class="s-name" title=${name}>${shortName(name, inst)}</span>
873
- <div class="s-agent-context">${inst.runtime !== "windows" || ctx.live[name]?.capabilities?.effort === true ? html`<span class="tag">${tn("effortTag", sum.effort)}</span>` : null}
874
- ${ch ? html`<span class=${`tag${ch.includes("persona") ? " persona" : ""}`}>${ch}</span>` : null}</div>
875
- </div>
876
- <div class="s-agent-runtime"><span class=${`tag${runtimeTarget.gone ? " warn" : ""}`} title=${runtimeTarget.title || runtimeTarget.label}>${runtimeTarget.label}</span></div>
877
- <div class="s-agent-cli"><${CliProductMark} id=${sum.backend} size=${20} /><span><strong>${cliLabel(sum.backend)}</strong><span class="s-meta" title=${sum.model}>${sum.model}</span></span></div>
878
- <span class="s-agent-status"><span class=${dotClass(agentStatus(ctx.live[name]))} aria-hidden="true"></span><span>${agentFilterText(agentStatus(ctx.live[name]))}${agentRuntimeOffline(inst, ctx.live[name]) ? html`<small class="s-agent-runtime-state">${agentFilterText("offline")}</small>` : null}</span></span>
796
+ return html`<div key=${name} class="s-row">
797
+ <span class=${dotClass(st)} title=${tn(STATUS_KEY[st] || "stStopped")} aria-hidden="true"></span>
798
+ <span class="s-name" title=${name}>${shortName(name, inst)}</span>
799
+ <span class="s-meta" title=${sum.backend}>${sum.model}</span>
800
+ <span class="s-br" aria-hidden="true"></span>
801
+ <span class="tag">${tn("effortTag", sum.effort)}</span>
802
+ ${ch ? html`<span class=${`tag${ch.includes("persona") ? " persona" : ""}`}>${ch}</span>` : null}
803
+ <span class="sr-only">${tn(STATUS_KEY[st] || "stStopped")}</span>
879
804
  <span class="s-actions">
880
- ${inst.runtime === "windows" ? html`<a class="btn btn-sm" href=${chatPath(name)}>${t("app.chat")}</a>` : null}
881
805
  <button type="button" class="btn btn-sm" disabled=${working} onClick=${() => openDialog({ kind: "agent", name, inst })}>${tn("settingsButton")}</button>
882
806
  ${st === "running" ? html`<button type="button" class="btn btn-sm" disabled=${working} onClick=${() => run(name, "pause", () => ctx.pauseWake(name, "pause"))}>${label("pause", tn("pause"))}</button>` : null}
883
807
  ${st === "paused" ? html`<button type="button" class="btn btn-sm" disabled=${working} onClick=${() => run(name, "wake", () => ctx.pauseWake(name, "wake"))}>${label("wake", tn("wake"))}</button>` : null}
884
- ${["running", "stopped", "crashed"].includes(st) ? html`<button type="button" class="btn btn-sm" disabled=${working} onClick=${() => run(name, "startStop", () => ctx.startStop(name, st === "running"))}>${label("startStop", st === "running" ? tn("stop") : tn("start"))}</button>` : null}
885
- <${Menu} cls="s-agent-menu" fit=${true} label=${t("app.more")} items=${[{ key: "delete", label: tn("deleteAgentMenu"), icon: "trash", danger: true, disabled: working, onSelect: () => ctx.deleteAgent(name) }]} />
808
+ ${st !== "paused" ? html`<button type="button" class="btn btn-sm" disabled=${working} onClick=${() => run(name, "startStop", () => ctx.startStop(name, st === "running"))}>${label("startStop", st === "running" ? tn("stop") : tn("start"))}</button>` : null}
809
+ <${Menu} label=${t("app.more")} items=${[{ key: "delete", label: tn("deleteAgentMenu"), icon: "trash", danger: true, disabled: working, onSelect: () => ctx.deleteAgent(name) }]} />
886
810
  </span>
887
811
  </div>`;
888
812
  })}
889
813
  </section>`;
890
- })}</div>`;
814
+ })}</div>${signIns}`;
891
815
  }
892
816
 
893
817
  function ConnectionRetry({ id, ctx }) {
@@ -917,10 +841,10 @@ function Bots({ ctx, search, openDialog }) {
917
841
  const all = channelsOf(ctx.fleet);
918
842
  const needle = search.trim().toLowerCase();
919
843
  const rows = all.map((ch, i) => ({ ch, i })).filter(({ ch }) => !needle || [ch.id, ch.type, ch.group_id, ch.bot_token_env].some((v) => String(v ?? "").toLowerCase().includes(needle)));
920
- const head = html`<div class="list-head s-list-toolbar"><span>${all.length === 1 ? tn("countBot") : tn("countBots", all.length)}</span>
844
+ const head = html`<div class="list-head"><span>${all.length === 1 ? tn("countBot") : tn("countBots", all.length)}</span>
921
845
  <button type="button" id="newBotBtn" class="btn btn-primary" onClick=${() => openDialog({ kind: "newBot" })}><${Icon} name="plus" size=${16} />${tn("newBot")}</button></div>`;
922
- return html`<section class="card s-chat-connections"><div class="s-chat-section-head"><h3>${layoutText("chatConnections")}</h3>${head}</div>
923
- ${!rows.length ? html`<div class="s-chat-empty"><${Icon} name="plug" size=${22} /><p>${needle ? tn("noAgentMatch", search.trim()) : tn("noBots")}</p></div>` : html`<div class="s-list s-connections-list"><div class="s-list-columns s-connection-columns" aria-hidden="true"><span>${tn("uiConnectionColumnService")}</span><span>${tn("uiConnectionColumnInfo")}</span><span>${tn("uiListColumnActions")}</span></div>${rows.map(({ ch, i }) => {
846
+ return html`${head}
847
+ ${!rows.length ? html`<${Empty} icon="plug" title=${needle ? tn("noAgentMatch", search.trim()) : tn("noBots")} />` : html`<div class="s-list">${rows.map(({ ch, i }) => {
924
848
  const users = (ch.access && ch.access.allowed_users) || [];
925
849
  const meta = ctx.connections.find((c, j) => channelId(c, j) === channelId(ch, i)) || {};
926
850
  const token = meta.token_present;
@@ -945,7 +869,7 @@ function Bots({ ctx, search, openDialog }) {
945
869
  ${!overPublicLink && ctx.fleetUp && meta.status !== "connected" ? html`<${ConnectionRetry} id=${channelId(ch, i)} ctx=${ctx} />` : null}
946
870
  <button type="button" class="btn btn-sm" onClick=${() => openDialog({ kind: "bot", id: channelId(ch, i) })}>${tn("settingsButton")}</button></span>
947
871
  </div>`;
948
- })}</div>`}</section>`;
872
+ })}</div>`}`;
949
873
  }
950
874
 
951
875
  /**
@@ -995,40 +919,40 @@ function ProviderKeys({ ctx }) {
995
919
  } catch { say(spec.id, { error: tn("failed") }); }
996
920
  finally { inFlight.current.delete(spec.id); if (lease.current()) setBusy(new Set(inFlight.current)); }
997
921
  };
998
- return html`<section class="card s-provider-keys s-auth-section"><header class="s-auth-section-head"><div><h3>${layoutText("apiKeysTitle")}</h3><p>${layoutText("apiKeysHint")}</p></div></header>
999
- ${!ctx.providerSecrets.length ? html`<p class="note">${tn("noProviderVerifiers")}</p>` : html`<div class="s-api-key-list">${ctx.providerSecrets.map((spec) => {
1000
- const provider = spec.id.split(".")[0], mark = ["openai", "anthropic"].includes(provider) ? provider : null;
1001
- return html`<div key=${spec.id} class="s-key s-api-key-row">
1002
- <div class="s-api-key-heading"><span class="s-provider-symbol">${mark ? html`<${ProviderMark} provider=${mark} size=${22} />` : html`<${Icon} name="key" size=${22} />`}</span><strong>${spec.display_name}</strong><span class=${`s-auth-state${spec.token_present ? " is-usable" : ""}`}>${spec.token_present ? tn("keyConfigured") : tn("keyNotConfigured")}</span></div>
1003
- ${spec.verifier === "available" ? html`<div class="s-api-key-form"><label><span>${tn("providerKeyInput", spec.display_name)}</span><input type="password" autocomplete="new-password" aria-label=${tn("providerKeyInput", spec.display_name)}
1004
- placeholder=${layoutText(spec.token_present ? "apiReplacePlaceholder" : "apiNewPlaceholder")} value=${keys[spec.id] || ""} onInput=${(e) => setKeys((k) => ({ ...k, [spec.id]: e.target.value }))} /></label>
1005
- <button type="button" class="btn btn-sm btn-primary" disabled=${busy.has(spec.id)} onClick=${() => go(spec)}>${tn("verifyApply")}</button></div>`
1006
- : html`<div class="s-api-key-unsupported"><span class="s-auth-state">${tn("unsupportedVerifier")}</span><p class="note">${tn("unsupportedVerifierHint")}</p></div>`}
1007
- ${notes[spec.id] ? html`<p class=${`feedback${notes[spec.id].error ? " error" : ""}`} role="status">${notes[spec.id].error || notes[spec.id].text}</p>` : null}
1008
- </div>`;
1009
- })}</div>`}
1010
- <p class="note s-api-action-note">${tn("uiProviderKeyActionHint")}</p>
922
+ return html`<section class="card s-provider-keys"><h3>${tn("providerKeys")}</h3>
923
+ ${!ctx.providerSecrets.length ? html`<p class="note">${tn("noProviderVerifiers")}</p>` : ctx.providerSecrets.map((spec) => html`<div key=${spec.id} class="s-key">
924
+ <div class="s-key-row"><strong>${spec.display_name}</strong><span class="tag">${spec.token_present ? tn("keyConfigured") : tn("keyNotConfigured")}</span>
925
+ ${spec.verifier === "available" ? html`<input type="password" autocomplete="new-password" aria-label=${tn("providerKeyInput", spec.display_name)}
926
+ placeholder=${spec.token_present ? tn("keyConfigured") : tn("keyNotConfigured")} value=${keys[spec.id] || ""} onInput=${(e) => setKeys((k) => ({ ...k, [spec.id]: e.target.value }))} />
927
+ <button type="button" class="btn btn-sm btn-primary" disabled=${busy.has(spec.id)} onClick=${() => go(spec)}>${tn("verifyApply")}</button>`
928
+ : html`<span class="tag">${tn("unsupportedVerifier")}</span>`}</div>
929
+ ${spec.verifier === "available" ? null : html`<p class="note">${tn("unsupportedVerifierHint")}</p>`}
930
+ ${notes[spec.id] ? html`<p class=${`feedback${notes[spec.id].error ? " error" : ""}`} role="status">${notes[spec.id].error || notes[spec.id].text}</p>` : null}
931
+ </div>`)}
1011
932
  </section>`;
1012
933
  }
1013
934
 
1014
935
  function Classic({ ctx, search, openDialog }) {
1015
936
  const rooms = Object.entries((ctx.classic && ctx.classic.channels) || {}).map(([key, ch]) => ({ key, ...ch }));
1016
- if (!rooms.length) return html`<div class="s-chat-empty"><${Icon} name="room" size=${22} /><p>${tn("noClassic")}</p></div>`;
937
+ if (!rooms.length) return html`<${Empty} icon="room" title=${tn("noClassic")} />`;
1017
938
  const needle = search.trim().toLowerCase();
1018
939
  const list = rooms.filter((c) => !needle || String(c.name || "").toLowerCase().includes(needle) || String(c.instanceName || "").toLowerCase().includes(needle))
1019
940
  .sort((a, b) => ((STATUS_ORDER[ctx.classicRuntime(a.instanceName).status] ?? 9) - (STATUS_ORDER[ctx.classicRuntime(b.instanceName).status] ?? 9))
1020
941
  || String(a.name || "").localeCompare(String(b.name || "")));
1021
- if (!list.length) return html`<div class="s-chat-empty"><${Icon} name="search" size=${22} /><p>${tn("noAgentMatch", search.trim())}</p></div>`;
1022
- return html`<div class="list-head s-list-toolbar"><span>${rooms.length === 1 ? tn("countRoom") : tn("countRooms", rooms.length)}</span></div><div class="s-list s-classic-list"><div class="s-list-columns s-classic-columns" aria-hidden="true"><span>${tn("uiClassicColumnRoom")}</span><span>${tn("uiAgentColumnCli")}</span><span>${tn("uiListColumnState")}</span><span>${tn("uiListColumnActions")}</span></div>${list.map((c) => {
942
+ if (!list.length) return html`<${Empty} icon="search" title=${tn("noAgentMatch", search.trim())} />`;
943
+ return html`<div class="list-head"><span>${rooms.length === 1 ? tn("countRoom") : tn("countRooms", rooms.length)}</span></div><div class="s-list">${list.map((c) => {
1023
944
  const rt = ctx.classicRuntime(c.instanceName);
1024
945
  const sum = effectiveSummary(ctx.live[c.instanceName] || {}, c, ctx.fleet.defaults || {}, (ctx.classic && ctx.classic.defaults) || {});
1025
946
  const adapter = c.adapterId || "discord";
1026
- return html`<div key=${c.key} class="s-row s-classic-row">
1027
- <div class="s-classic-identity"><span class="s-name" title=${c.instanceName || ""}>${shortName(c.name || c.instanceName || "?", { display_name: c.display_name })}</span>
1028
- <div class="s-agent-context"><span class="tag">${tn("effortTag", sum.effort)}</span><span class=${`tag${adapter !== "discord" ? " persona" : ""}`}>${adapter}</span>${c.collab ? html`<span class="tag">collab</span>` : null}</div>
1029
- </div>
1030
- <div class="s-classic-cli"><${CliProductMark} id=${sum.backend} size=${20} /><span><strong>${cliLabel(sum.backend)}</strong><span class="s-meta" title=${sum.model}>${sum.model}</span></span></div>
1031
- <span class="s-classic-status"><span class=${dotClass(rt.execution)} aria-hidden="true"></span><span>${tn(`exec_${rt.execution}`)}</span></span>
947
+ return html`<div key=${c.key} class="s-row">
948
+ <span class=${dotClass(rt.execution)} title=${tn(`exec_${rt.execution}`)} aria-hidden="true"></span>
949
+ <span class="s-name" title=${c.instanceName || ""}>${shortName(c.name || c.instanceName || "?", { display_name: c.display_name })}</span>
950
+ <span class="s-meta" title=${sum.backend}>${sum.model}</span>
951
+ <span class="s-br" aria-hidden="true"></span>
952
+ <span class="tag">${tn("effortTag", sum.effort)}</span>
953
+ <span class=${`tag${adapter !== "discord" ? " persona" : ""}`}>${adapter}</span>
954
+ ${c.collab ? html`<span class="tag">collab</span>` : null}
955
+ <span class="tag">${tn(`exec_${rt.execution}`)}</span>
1032
956
  <span class="s-actions">
1033
957
  <button type="button" class="btn btn-sm" onClick=${() => openDialog({ kind: "classic", room: c })}>${tn("settingsButton")}</button>
1034
958
  ${rt.status === "running" ? html`<button type="button" class="btn btn-sm" onClick=${() => ctx.pauseWake(c.instanceName, "pause")}>${tn("pause")}</button>` : null}
@@ -1078,6 +1002,7 @@ function General({ ctx, part = "all" }) {
1078
1002
  const { schema } = ctx;
1079
1003
  const d = ctx.fleet.defaults || {}, c = (ctx.classic && ctx.classic.defaults) || {};
1080
1004
  const hang = d.hang_detector || {}, startup = d.startup || {};
1005
+ const primary = channelsOf(ctx.fleet)[0];
1081
1006
  const original = useMemo(() => ({ c: structuredClone(c) }), []);
1082
1007
  const base = useMemo(() => generalForm(d, c, ctx.fleet, schema), []);
1083
1008
  const [f, setF] = useDraft(ctx, "general", () => base);
@@ -1093,9 +1018,6 @@ function General({ ctx, part = "all" }) {
1093
1018
  const warnings = { concurrency: f.concurrency.trim() !== "" && num(f.concurrency) > 4 ? "concurrencyWarning" : "", stagger: num(f.stagger) < 100 ? "staggerWarning" : "" };
1094
1019
  const ready = !Object.values(errors).some(Boolean);
1095
1020
  const firstError = Object.values(errors).find(Boolean);
1096
- // What saving the edited fields costs (the schema's impact, the agents that set the field themselves): shown under each
1097
- // edited field, and added up on the Save bar.
1098
- const notes = sharedNotes({ schema, fleet: ctx.fleet, classic: ctx.classic, classicStatus: (name) => ctx.classicRuntime(name).status, live: ctx.live, fleetUp: ctx.fleetUp, f, base, errors });
1099
1021
  // #2347: every edit, staged as it is made (the first render included: a draft kept from before is staged again).
1100
1022
  useEffect(() => {
1101
1023
  if (!ready) {
@@ -1142,12 +1064,10 @@ function General({ ctx, part = "all" }) {
1142
1064
  // that sets it (POST /ui/config; a change to it waits for a fleet admin's OK, as it did there).
1143
1065
  const roots = f.roots.map((r) => String(r).trim()).filter(Boolean); // ChipList keeps "2024" as a number; paths are text
1144
1066
  syncStage(ctx, "fleet:project_roots", sameValue(roots, base.roots) ? null : { label: tn("projectRootsTitle"), count: 1,
1145
- impact: impactOf(schema, "fleet.project_roots"), notes: notes.bar.roots,
1146
- request: { method: "POST", url: "/ui/config", body: { project_roots: roots } } });
1067
+ impact: impactOf(schema, "fleet.project_roots"), request: { method: "POST", url: "/ui/config", body: { project_roots: roots } } });
1147
1068
  const dKeys = Object.keys(defaultsPatch), cKeys = Object.keys(classicPatch);
1148
- // The bar says what this Save costs in the page's own words (how many agents restart), not a bare impact label.
1149
1069
  syncStage(ctx, "defaults:fleet", dKeys.length ? { label: tn("updateDefaults"), count: dKeys.length,
1150
- impact: batchImpact(schema, dKeys, (k) => defaultsImpact(schema, k)), notes: notes.bar.defaults,
1070
+ impact: batchImpact(schema, dKeys, (k) => defaultsImpact(schema, k)),
1151
1071
  request: { method: "PUT", url: "/api/settings/fleet/defaults", body: defaultsPatch } } : null);
1152
1072
  syncStage(ctx, "defaults:classic", cKeys.length ? { label: tn("updateClassicDefaults"), count: cKeys.length,
1153
1073
  impact: cKeys.every((k) => impactOf(schema, `classic_defaults.${k}`) === "now") ? "now" : "fleet",
@@ -1161,17 +1081,39 @@ function General({ ctx, part = "all" }) {
1161
1081
  log_level: !d.log_level, agent_mode: !d.agent_mode, hangOn: !hasOwn(hang, "enabled"), hang: !hasOwn(hang, "timeout_minutes"),
1162
1082
  concurrency: !hasOwn(startup, "concurrency"), stagger: !hasOwn(startup, "stagger_delay_ms"),
1163
1083
  };
1084
+ const dm = (k) => (unset[k] && sameValue(f[k], base[k]) ? html`<${DefaultMark} />` : null);
1164
1085
  const fromDefaults = (k, value, target) => ({ text: valueText(value), builtin: !hasOwn(d, k), from: inAgentDefaults(target) });
1165
- const L = (text, field, id) => html`<${Label} text=${text} schema=${schema} field=${field} htmlFor=${id} />`;
1086
+ const L = (text, field, id, k) => html`<${Label} text=${text} schema=${schema} field=${field} htmlFor=${id} mark=${k ? dm(k) : null} />`;
1166
1087
  const fleetReply = replyGuardSupported(f.backend, f.agent_mode, d.kiro_ui) ? tn("replyGuardSupported") : tn("replyGuardUnsupported", f.backend, f.agent_mode);
1167
1088
  const classicReply = replyGuardSupported(f.classicBackend, f.agent_mode, d.kiro_ui) ? tn("replyGuardSupported") : tn("replyGuardUnsupported", f.classicBackend, f.agent_mode);
1168
1089
  // #2347: Agent defaults show the fleet's part; Chat & connections ClassicBot's. One form, one draft either way.
1169
1090
  const fleetPart = part !== "classic", classicPart = part !== "fleet";
1170
- return html`<div class=${fleetPart ? "s-defaults-layout" : "s-classic-layout"}><div class=${`form s-general s-part-${part}`}>
1171
- ${fleetPart ? html`<${SharedAgentSettings} ctx=${ctx} form=${{ f, set, base, errors, warnings, unset, fc, notes, replyNote: fleetReply }} />` : null}
1172
- ${classicPart ? html`<section class="card s-classic-defaults-card"><h3>${tn("classicDefaultsTitle")}</h3>
1091
+ return html`<div class=${`form s-general s-part-${part}`}>
1092
+ ${fleetPart ? html`<section class="card"><h3>${tn("defaultsTitle")}</h3>
1093
+ <div class="grid2">
1094
+ <div class=${fc("field", "locale")}>${L(tn("language"), "defaults.locale", "g-locale", "locale")}<${Select} id="g-locale" value=${f.locale} onChange=${set("locale")}
1095
+ options=${localeOptions(f.locale).map((o) => (o.auto ? { value: "", label: tn("localeAuto") } : o))} /></div>
1096
+ <div class=${fc("field", "backend")}>${L(tn("defaultBackend"), "defaults.backend", "g-be", "backend")}<${BackendSelect} id="g-be" value=${f.backend} onChange=${set("backend")} /></div>
1097
+ <div class=${fc("field", "model")}>${L(tn("defaultModel"), "defaults.model", "g-model", "model")}<${ModelSelect} id="g-model" value=${f.model} onChange=${set("model")}
1098
+ backend=${f.backend || "claude-code"} inherit=${tn("modelCliDefault")} /></div>
1099
+ <div class=${fc("field", "auto")}>${L(`${tn("autoPause")} (${tn("minutes")})`, "defaults.auto_pause_after", "g-auto", "auto")}<input id="g-auto" type="number" min="0" step="1" class=${errors.auto ? "invalid" : ""} value=${f.auto} onInput=${(e) => set("auto")(e.target.value)} /><${Feedback} error=${errors.auto} /></div>
1100
+ <div class=${fc("field", "tool_progress")}>${L(tn("toolProgress"), "defaults.tool_progress", "g-tp", "tool_progress")}<${Select} id="g-tp" value=${f.tool_progress} onChange=${set("tool_progress")} options=${TOOL_PROGRESS} /></div>
1101
+ <div class=${fc("field", "visibility")}>${L(tn("crossInstanceVisibility"), "defaults.cross_instance_visibility", "g-vis", "visibility")}<${Select} id="g-vis" value=${f.visibility} onChange=${set("visibility")} options=${VISIBILITY_MODES} />
1102
+ <p class="note">${tn("crossInstanceVisibilityHint")}</p></div>
1103
+ <div class=${fc("field", "tips")}>${L(tn("dailyTips"), "defaults.tips", "g-tips", "tips")}<${Select} id="g-tips" value=${f.tips} onChange=${set("tips")} options=${noticeChoices()} /><${InEffect} text=${noticeLabel(noticeMode(f.tips))} /><p class="note">${tn("dailyTipsHint")}</p></div>
1104
+ <div class=${fc("field", "replyTriggers")}><label class="check"><input id="g-reply-triggers" type="checkbox" checked=${f.replyTriggers} onChange=${(e) => set("replyTriggers")(e.target.checked)} /><span>${tn("replyTriggers")}</span>${dm("replyTriggers")}<${Impact} schema=${schema} field="defaults.reply_triggers" /></label><p class="note">${tn("replyTriggersHint")}</p></div>
1105
+ <div class=${fc("field", "reply")}><label class="check"><input id="g-reply" type="checkbox" checked=${f.reply} onChange=${(e) => set("reply")(e.target.checked)} /><span>${tn("replyCompletionGuard")}</span>${dm("reply")}<${Impact} schema=${schema} field="defaults.reply_completion_guard" /></label>
1106
+ <p class="note">${fleetReply}</p></div>
1107
+ </div>
1108
+ <fieldset id="g-dash" class=${fc("field dash-perms", ...DASHBOARD_FEATURES.map((k) => `dash_${k}`))}><legend>${L(tn("dashboardAccess"), "defaults.dashboard")}</legend>
1109
+ <p class="note">${tn("dashboardDefaultsHint")}</p>
1110
+ ${DASHBOARD_FEATURES.map((k) => html`<label key=${k} class="check"><input type="checkbox" checked=${f[`dash_${k}`]}
1111
+ onChange=${(e) => set(`dash_${k}`)(e.target.checked)} /><span>${tn(`dashboard_${k}`)}</span></label>`)}
1112
+ </fieldset>
1113
+ </section>` : null}
1114
+ ${classicPart ? html`<section class="card"><h3>${tn("classicDefaultsTitle")}</h3>
1173
1115
  <div class="grid2">
1174
- <div class=${fc("field", "classicBackend")}>${L(tn("classicBackend"), "classic_defaults.backend", "g-cbe")}<${BackendSelect} id="g-cbe" value=${f.classicBackend} onChange=${set("classicBackend")} hostOnly />
1116
+ <div class=${fc("field", "classicBackend")}>${L(tn("classicBackend"), "classic_defaults.backend", "g-cbe")}<${BackendSelect} id="g-cbe" value=${f.classicBackend} onChange=${set("classicBackend")} />
1175
1117
  ${!c.backend && f.classicBackend === base.classicBackend ? html`<${Inherited} text=${valueText(f.classicBackend, "backend")} builtin=${!d.backend} from=${inAgentDefaults("#g-be")} />` : null}</div>
1176
1118
  <div class=${fc("field", "classicToolProgress", "classicToolProgressInherit")}>${L(tn("toolProgress"), "classic_defaults.tool_progress", "g-ctp")}
1177
1119
  <${Override} inherit=${f.classicToolProgressInherit} onInherit=${set("classicToolProgressInherit")} inherited=${fromDefaults("tool_progress", d.tool_progress ?? "off", "#g-tp")}>
@@ -1190,7 +1132,31 @@ function General({ ctx, part = "all" }) {
1190
1132
  <div id="g-guilds" class=${fc("field", "guilds")}>${L(tn("allowedGuilds"), "classic.allowed_guilds")}<${ChipList} items=${f.guilds} onChange=${set("guilds")} placeholder=${tn("guildIdPlaceholder")} label=${tn("allowedGuilds")} /></div>
1191
1133
  </div>
1192
1134
  </section>` : null}
1193
- </div></div>`;
1135
+ ${fleetPart ? html`<section class="card" id="project-roots"><h3>${tn("projectRootsTitle")}</h3>
1136
+ <p class="note">${tn("projectRootsHint")}</p>
1137
+ <div id="g-roots" class=${fc("field", "roots")}>${L(tn("projectRootsTitle"), "fleet.project_roots")}<${ChipList} items=${f.roots} onChange=${set("roots")} placeholder="/path/to/projects" label=${tn("projectRootsTitle")} />
1138
+ ${f.roots.length ? null : html`<${InEffect} text=${tn("projectRootsAnywhere")} />`}</div>
1139
+ </section>` : null}
1140
+ ${fleetPart ? html`<${Drawer} title=${tn("advancedSection")}>
1141
+ <section class="card"><h3>${tn("runtimeResources")}</h3><div class="grid2">
1142
+ <div class=${fc("field", "tool_set")}>${L(tn("toolSet"), "defaults.tool_set", "g-ts", "tool_set")}<${Select} id="g-ts" value=${f.tool_set} onChange=${set("tool_set")}
1143
+ options=${[{ value: "", label: tn("toolSetUnset", toolSetDefault({}, {}), toolSetDefault({}, { general_topic: true })) }, ...TOOL_SETS]} /></div>
1144
+ <div class=${fc("field", "log_level")}>${L(tn("logLevel"), "defaults.log_level", "g-ll", "log_level")}<${Select} id="g-ll" value=${f.log_level} onChange=${set("log_level")} options=${LOG_LEVELS} /></div>
1145
+ <div class=${fc("field", "agent_mode")}>${L(tn("agentMode"), "defaults.agent_mode", "g-am", "agent_mode")}<${Select} id="g-am" value=${f.agent_mode} onChange=${set("agent_mode")} options=${AGENT_MODES} /></div>
1146
+ </div></section>
1147
+ <section class="card"><h3>${tn("detection")}</h3><div class="grid2">
1148
+ <label class=${fc("check", "hangOn")}><input id="g-hang-on" type="checkbox" checked=${f.hangOn} onChange=${(e) => set("hangOn")(e.target.checked)} /><span>${tn("hangEnabled")}</span>${dm("hangOn")}<${Impact} schema=${schema} field="defaults.hang_detector" /></label>
1149
+ <div class=${fc("field", "hang")}>${L(`${tn("hangTimeout")} (${tn("minutes")})`, "defaults.hang_detector", "g-hang", "hang")}<input id="g-hang" type="number" min="0.1" step="0.5" class=${errors.hang ? "invalid" : ""} value=${f.hang} onInput=${(e) => set("hang")(e.target.value)} /><${Feedback} error=${errors.hang} /></div>
1150
+ </div></section>
1151
+ <section class="card"><h3>${tn("startup")}</h3><div class="grid2">
1152
+ <div class=${fc("field", "concurrency")}>${L(tn("concurrency"), "fleet.spawn_concurrency", "g-conc")}<input id="g-conc" type="number" min="1" max="20" step="1" class=${errors.concurrency ? "invalid" : ""} value=${f.concurrency} onInput=${(e) => set("concurrency")(e.target.value)} /><${Feedback} error=${errors.concurrency} warning=${warnings.concurrency} />
1153
+ ${f.concurrency.trim() === "" ? html`<${InEffect} text=${tn("concurrencyAuto")} />` : null}</div>
1154
+ <div class=${fc("field", "stagger")}>${L(`${tn("staggerDelay")} (ms)`, "fleet.spawn_stagger_ms", "g-stag", "stagger")}<input id="g-stag" type="number" min="0" max="30000" step="100" class=${errors.stagger ? "invalid" : ""} value=${f.stagger} onInput=${(e) => set("stagger")(e.target.value)} /><${Feedback} error=${errors.stagger} warning=${warnings.stagger} /></div>
1155
+ </div></section>
1156
+ <section class="card"><h3>${tn("accessTitle")}</h3>
1157
+ <p class="note">${primary ? tn("accessMovedHint", primary.id || chLabel(0)) : tn("noBots")}</p></section>
1158
+ </${Drawer}>` : null}
1159
+ </div>`;
1194
1160
  }
1195
1161
 
1196
1162
  /**
@@ -1230,7 +1196,6 @@ export function uploadMbInEffect(web) {
1230
1196
  }
1231
1197
  function WebSection({ ctx, staged, part = "all" }) {
1232
1198
  const { schema } = ctx;
1233
- const [accessTab, setAccessTab] = useSettingsTabs("access", "login");
1234
1199
  const web = ctx.fleet.web || {}, local = (web.session && web.session.local) || {}, term = ctx.fleet.web_terminal || {};
1235
1200
  // Over the public link the fields read only; the Guests and Web authority cards are not offered (the server never
1236
1201
  // serves their reads there).
@@ -1242,14 +1207,13 @@ function WebSection({ ctx, staged, part = "all" }) {
1242
1207
  usagePub: web.usage_report_on_public_link === true, // #2122: off by default
1243
1208
  levels: web.office_levels !== false, // #2661: on by default
1244
1209
  cdn: web.preview_cdn === true, // #2911 (7): off by default
1245
- loginQr: web.login_qr === true, // #3061 (P2b): off by default
1246
1210
  pub: { allow_public: (web.public_link && web.public_link.allow_public) ?? true, ttl_minutes: (web.public_link && web.public_link.ttl_minutes) ?? 120, protocol: (web.public_link && web.public_link.protocol) ?? "http2", hostname: (web.public_link && web.public_link.hostname) ?? "", tunnel_token_env: (web.public_link && web.public_link.tunnel_token_env) ?? "", origin_port: (web.public_link && web.public_link.origin_port) ?? 19282, auto_open: (web.public_link && web.public_link.auto_open) ?? false },
1247
1211
  session: { absolute_hours: local.absolute_hours ?? null, idle_hours: local.idle_hours ?? null },
1248
1212
  terminal: { enabled: term.enabled ?? null, ttl_minutes: term.ttl_minutes ?? null },
1249
1213
  }), []);
1250
1214
  const text = (v) => (v === null || v === undefined ? "" : String(v));
1251
1215
  /** #2347: a field's row class: `s-dirty` while it differs from what is saved (the draft may come from before). */
1252
- const savedForm = useMemo(() => ({ notify: String(original.notify), echo: original.echo, log: original.log, usagePub: original.usagePub, levels: original.levels, cdn: original.cdn, loginQr: original.loginQr, pub: original.pub.allow_public,
1216
+ const savedForm = useMemo(() => ({ notify: String(original.notify), echo: original.echo, log: original.log, usagePub: original.usagePub, levels: original.levels, cdn: original.cdn, pub: original.pub.allow_public,
1253
1217
  ttl: String(original.pub.ttl_minutes), protocol: original.pub.protocol, hostname: original.pub.hostname, originPort: String(original.pub.origin_port),
1254
1218
  abs: text(original.session.absolute_hours), idle: text(original.session.idle_hours), termOn: original.terminal.enabled !== false,
1255
1219
  termTtl: text(original.terminal.ttl_minutes), autoOpen: original.pub.auto_open }), []);
@@ -1263,7 +1227,7 @@ function WebSection({ ctx, staged, part = "all" }) {
1263
1227
  return {
1264
1228
  notify: String(pick(pending, "notify_login", original.notify)),
1265
1229
  echo: pick(pending, "echo_to_channel", original.echo), log: pick(pending, "log_tab", original.log), usagePub: pick(pending, "usage_report_on_public_link", original.usagePub),
1266
- levels: pick(pending, "office_levels", original.levels), cdn: pick(pending, "preview_cdn", original.cdn), loginQr: pick(pending, "login_qr", original.loginQr),
1230
+ levels: pick(pending, "office_levels", original.levels), cdn: pick(pending, "preview_cdn", original.cdn),
1267
1231
  pub: pick(pub, "allow_public", original.pub.allow_public), ttl: String(pick(pub, "ttl_minutes", original.pub.ttl_minutes)), protocol: pick(pub, "protocol", original.pub.protocol),
1268
1232
  hostname: pick(pub, "hostname", original.pub.hostname), originPort: String(pick(pub, "origin_port", original.pub.origin_port)), autoOpen: pick(pub, "auto_open", original.pub.auto_open),
1269
1233
  abs: text(pick(session, "absolute_hours", original.session.absolute_hours)), idle: text(pick(session, "idle_hours", original.session.idle_hours)),
@@ -1317,7 +1281,6 @@ function WebSection({ ctx, staged, part = "all" }) {
1317
1281
  ...(f.usagePub !== original.usagePub ? { usage_report_on_public_link: f.usagePub } : {}),
1318
1282
  ...(f.levels !== original.levels ? { office_levels: f.levels } : {}),
1319
1283
  ...(f.cdn !== original.cdn ? { preview_cdn: f.cdn } : {}),
1320
- ...(f.loginQr !== original.loginQr ? { login_qr: f.loginQr } : {}),
1321
1284
  ...(Object.keys(publicPatch).length ? { public_link: publicPatch } : {}),
1322
1285
  ...(Object.keys(sessionPatch).length ? { session: { local: sessionPatch } } : {}),
1323
1286
  ...(Object.keys(terminalPatch).length ? { web_terminal: terminalPatch } : {}),
@@ -1329,7 +1292,6 @@ function WebSection({ ctx, staged, part = "all" }) {
1329
1292
  ...(body.usage_report_on_public_link !== undefined ? ["web.usage_report_on_public_link"] : []),
1330
1293
  ...(body.office_levels !== undefined ? ["web.office_levels"] : []),
1331
1294
  ...(body.preview_cdn !== undefined ? ["web.preview_cdn"] : []),
1332
- ...(body.login_qr !== undefined ? ["web.login_qr"] : []),
1333
1295
  ...Object.keys(publicPatch).map((k) => `web.public_link.${k}`),
1334
1296
  ...Object.keys(sessionPatch).map((k) => `web.session.local.${k}`),
1335
1297
  ...Object.keys(terminalPatch).map((k) => `web_terminal.${k}`),
@@ -1364,35 +1326,17 @@ function WebSection({ ctx, staged, part = "all" }) {
1364
1326
  if (v === undefined) return html`${roText(webReadOnlyDefault(path, ctx.fleet))} <${DefaultMark} />${capped ? html` <span class="tag">${tn("cappedByTotal")}</span>` : null}`;
1365
1327
  return applies === v ? roText(v) : html`${roText(v)} <span class="tag">${tn("inEffectShort", roText(applies))}</span>`;
1366
1328
  };
1367
- // One Web draft remains mounted across the Access tabs. A tab only changes what is visible;
1368
- // validation, confirmation and staged writes continue to belong to the existing form.
1329
+ // #2347: one form, one draft, shown where each part belongs — Access & security (sessions, the browser terminal, the
1330
+ // public link and its fixed address, guests, web authority), Chat & connections (web echo), Web dashboard (the Log tab,
1331
+ // usage over the public link), Advanced (what only fleet.yaml sets).
1369
1332
  const has = (p) => part === "all" || part === p;
1370
1333
  const lock = (body) => html`<fieldset class="s-web-fields" disabled=${overPublicLink}>${body}</fieldset>`;
1371
- const tabs = [
1372
- { id: "login", label: layoutText("accessLogin") },
1373
- { id: "guests", label: layoutText("accessGuests") },
1374
- { id: "sharing", label: layoutText("accessSharing") },
1375
- ];
1376
- const toggleRow = (key, id, label, hint, impact) => html`<div class=${fc("s-setting-row", key)}>
1377
- <div class="s-setting-copy"><label for=${id}>${part === "dashboard" ? layoutText(`revDashboard_${key}`) : tn(label)}<${Impact} schema=${schema} field=${impact} /></label>
1378
- <p class="note" id=${`${id}-hint`}>${part === "dashboard" ? layoutText(`revDashboardHint_${key}`) : tn(hint)}</p>
1379
- ${part === "dashboard" ? html`<details class="s-setting-details"><summary>${layoutText("revDetails")}</summary><p class="note"><strong>${tn(label)}</strong> ${tn(hint)}</p></details>` : null}
1380
- </div>
1381
- <input class="s-ui-toggle" id=${id} type="checkbox" checked=${f[key]} aria-describedby=${`${id}-hint`} onChange=${(e) => set(key)(e.target.checked)} />
1382
- </div>`;
1383
- const configured = (path) => { const [top, key] = path.split("."); return (top === "web" ? web : term)[key] !== undefined; };
1384
1334
  return html`<div class=${`form s-web s-part-${part}`}>
1385
- ${overPublicLink && part !== "readonly" ? html`<p class="note s-access-notice" role="status" id="webPublicRefused">${tn("webPublicRefused")}</p>` : null}
1386
- ${has("access") ? html`<${SettingsTabs} id="access" value=${accessTab} onChange=${setAccessTab} items=${tabs} />
1387
- <div class="s-access-banner"><${Icon} name="info" size=${18} /><p>${layoutText("revAccessPolicy")}</p><details class="s-access-policy"><summary>${layoutText("revDetails")}</summary><p class="note">${tn("webLead")}</p></details></div>
1388
- <${SettingsTabPanel} group="access" id="login" active=${accessTab === "login"}>
1389
- <div class="s-access-login-layout"><div class="s-access-stack">
1390
- ${/* #3008: a web-only fleet's connections from outside — changed on this computer only, shown (read-only) elsewhere. */ ""}
1391
- <${OutsideCard} />
1392
- ${/* Refs #3061 (P2a): sign a new device in with its 8-character code — approved here by the verified owner. */ ""}
1393
- <${DevicesCard} />
1394
- ${lock(html`<section class="card s-access-session"><h3>${layoutText("revLoginSessions")}</h3>
1395
- <div class=${fc("field", "notify")}><label for="webNotifyLogin">${tn("webNotifyLogin")}<${Impact} schema=${schema} field="web.notify_login" /></label><${Select} id="webNotifyLogin" value=${f.notify} onChange=${set("notify")} options=${noticeChoices()} /><${InEffect} text=${noticeLabel(noticeMode(f.notify))} /></div>
1335
+ ${has("access") ? html`<p class="sub">${tn("webLead")}</p>` : null}
1336
+ ${overPublicLink && part !== "readonly" ? html`<p class="note" role="status" id="webPublicRefused">${tn("webPublicRefused")}</p>` : null}
1337
+ ${has("access") ? lock(html`<section class="card"><h3>${tn("webSessionTitle")}</h3>
1338
+ <p class="note">${tn("webSessionHint")}</p>
1339
+ <div class=${fc("field", "notify")}><label for="webNotifyLogin">${tn("webNotifyLogin")}<${Impact} schema=${schema} field="web.notify_login" /></label><${Select} id="webNotifyLogin" value=${f.notify} onChange=${set("notify")} options=${noticeChoices()} /><${InEffect} text=${noticeLabel(noticeMode(f.notify))} />${web.notify_login === undefined ? html`<${DefaultMark} />` : null}<p class="note">${tn("webNotifyLoginHint")}</p></div>
1396
1340
  <div class="grid2">
1397
1341
  <div class=${fc("field", "abs")}><label for="webSessionAbsolute">${tn("sessionAbsolute")}</label><input id="webSessionAbsolute" type="number" min="1" max="720" step="any"
1398
1342
  class=${errors.abs ? "invalid" : ""} value=${f.abs} onInput=${(e) => set("abs")(e.target.value)} /><${Feedback} error=${errors.abs} />
@@ -1401,16 +1345,8 @@ function WebSection({ ctx, staged, part = "all" }) {
1401
1345
  class=${errors.idle ? "invalid" : ""} value=${f.idle} onInput=${(e) => set("idle")(e.target.value)} /><${Feedback} error=${errors.idle} />
1402
1346
  ${value(f.idle) === null && !errors.abs ? html`<${InEffect} text=${tn("hoursValue", idle)} why=${idle < 48 ? tn("cappedBySession") : null} />` : null}</div>
1403
1347
  </div>
1404
- <p class="note s-session-ceiling">${layoutText("revPublicSessionLimit")}</p>
1405
- ${/* Refs #3061 (P2b): the QR code on a new device's sign-in page (a web-only fleet's "Sign in with another device"). */ ""}
1406
- <label class=${fc("check", "loginQr")}><input id="webLoginQr" type="checkbox" checked=${f.loginQr} aria-describedby="webLoginQr-hint" onChange=${(e) => set("loginQr")(e.target.checked)} /><span>${tn("webLoginQr")}</span><${Impact} schema=${schema} field="web.login_qr" /></label>
1407
- <p class="note" id="webLoginQr-hint">${tn("webLoginQrHint")}</p>
1408
- <details class="s-setting-details"><summary>${layoutText("revSessionDetails")}</summary><p class="note">${tn("webSessionHint")}</p><p class="note">${tn("webNotifyLoginHint")}</p></details>
1409
- </section>`)}
1410
- ${!overPublicLink ? html`<${WebAuthorityCard} ctx=${ctx} staged=${staged} />` : null}
1411
- ${!overPublicLink ? html`<${HubCardSlot} />` : null}
1412
- ${!overPublicLink && ctx.fleet.hub?.hubId ? html`<${HubRetentionSlot} /><${HubBrowserCertificateSlot} />` : null}
1413
- <details class="drawer s-terminal-disclosure"><summary>${tn("webTerminalTitle")}</summary><div class="drawer-body">${lock(html`<section class="card s-access-terminal"><h3>${tn("webTerminalTitle")}</h3>
1348
+ </section>
1349
+ <section class="card"><h3>${tn("webTerminalTitle")}</h3>
1414
1350
  <p class="note">${tn("webTerminalHint")}</p>
1415
1351
  <label class=${fc("check", "termOn")}><input id="webTerminalEnabled" type="checkbox" checked=${f.termOn} onChange=${(e) => set("termOn")(e.target.checked)} /><span>${tn("webTerminalEnabled")}</span><${Impact} schema=${schema} field="web_terminal.enabled" /></label>
1416
1352
  <div class="grid2">
@@ -1418,18 +1354,8 @@ function WebSection({ ctx, staged, part = "all" }) {
1418
1354
  class=${errors.termTtl ? "invalid" : ""} value=${f.termTtl} onInput=${(e) => set("termTtl")(e.target.value)} /><${Feedback} error=${errors.termTtl} />
1419
1355
  ${value(f.termTtl) === null ? html`<${InEffect} text=${tn("minutesValue", 10)} />` : null}</div>
1420
1356
  </div>
1421
- </section>`)}</div></details>
1422
- </div><aside class="card s-access-related"><h3>${layoutText("revRelatedAccess")}</h3>
1423
- <button type="button" onClick=${() => setAccessTab("guests")}><${Icon} name="user" size=${18} /><span><strong>${layoutText("accessGuests")}</strong><small>${layoutText("revRelatedGuests")}</small></span><${Icon} name="chevron" size=${16} /></button>
1424
- <button type="button" onClick=${() => setAccessTab("sharing")}><${Icon} name="globe" size=${18} /><span><strong>${layoutText("accessSharing")}</strong><small>${layoutText("revRelatedSharing")}</small></span><${Icon} name="chevron" size=${16} /></button>
1425
- </aside></div>
1426
- </${SettingsTabPanel}>
1427
- <${SettingsTabPanel} group="access" id="guests" active=${accessTab === "guests"}>
1428
- ${!overPublicLink ? html`<${GuestsCard} ctx=${ctx} staged=${staged} />` : html`<p class="note">${tn("webPublicRefused")}</p>`}
1429
- </${SettingsTabPanel}>
1430
- <${SettingsTabPanel} group="access" id="sharing" active=${accessTab === "sharing"}>
1431
- <div class="s-access-stack">
1432
- ${lock(html`<section class="card s-public-entry"><h3>${layoutText("revPublicEntry")}</h3>
1357
+ </section>
1358
+ <section class="card"><h3>${tn("publicLinkTitle")}</h3>
1433
1359
  <label class=${fc("check", "pub")}><input id="publicWebLink" type="checkbox" checked=${f.pub} onChange=${(e) => set("pub")(e.target.checked)} /><span>${tn("publicLink")}</span><${Impact} schema=${schema} field="web.public_link.allow_public" /></label>
1434
1360
  <p class="note">${tn("publicLinkHint")}</p>
1435
1361
  <div class="grid2">
@@ -1445,31 +1371,33 @@ function WebSection({ ctx, staged, part = "all" }) {
1445
1371
  ${named ? html`<p class="note" id="publicTtlNamedHint">${tn("publicTtlNamedHint")}</p>` : null}
1446
1372
  ${named || f.autoOpen ? html`<label class=${fc("check", "autoOpen")}><input id="publicAutoOpen" type="checkbox" checked=${f.autoOpen} onChange=${(e) => set("autoOpen")(e.target.checked)} /><span>${tn("publicAutoOpen")}</span><${Impact} schema=${schema} field="web.public_link.auto_open" /></label>
1447
1373
  <p class="note">${tn("publicAutoOpenHint")}</p><${Feedback} error=${errors.autoOpen} />` : null}
1448
-
1449
- ${!overPublicLink ? html`<div class="s-public-credentials"><${PublicTunnelToken} /></div>` : null}
1450
- </section>`)}
1451
- <div class="s-sharing-list"><h3>${layoutText("revReadOnlySharing")}</h3><p class="note">${layoutText("revSharingOrigin")}</p><${OfficeSharesCard} /><${PageSharesCard} /></div>
1452
- </div>
1453
- </${SettingsTabPanel}>` : null}
1454
- ${has("chat") ? lock(html`<section class="card s-web-chat"><h3>${layoutText("messageBehavior")}</h3>
1455
- ${toggleRow("echo", "webEchoToChannel", "webEcho", "webEchoHint", "web.echo_to_channel")}
1456
1374
  </section>`) : null}
1457
- ${has("dashboard") ? lock(html`<section class="card s-dashboard-features"><h3>${layoutText("dashboardFeatures")}</h3>
1458
- ${toggleRow("log", "webLogTab", "webLogTab", "webLogTabHint", "web.log_tab")}
1459
- ${toggleRow("usagePub", "webUsagePublic", "webUsagePublic", "webUsagePublicHint", "web.usage_report_on_public_link")}
1460
- ${toggleRow("levels", "webOfficeLevels", "webOfficeLevels", "webOfficeLevelsHint", "web.office_levels")}
1461
- ${toggleRow("cdn", "webPreviewCdn", "webPreviewCdn", "webPreviewCdnHint", "web.preview_cdn")}
1375
+ ${has("access") && !overPublicLink ? html`<${PublicTunnelToken} />` : null}
1376
+ ${has("access") ? html`<${OfficeSharesCard} />` : null}
1377
+ ${has("access") ? html`<${PageSharesCard} />` : null}
1378
+ ${has("access") && !overPublicLink ? html`<${GuestsCard} ctx=${ctx} staged=${staged} /><${WebAuthorityCard} ctx=${ctx} staged=${staged} />` : null}
1379
+ ${has("chat") ? lock(html`<section class="card"><h3>${tn("webChat")}</h3>
1380
+ <label class=${fc("check", "echo")}><input id="webEchoToChannel" type="checkbox" checked=${f.echo} onChange=${(e) => set("echo")(e.target.checked)} /><span>${tn("webEcho")}</span><${Impact} schema=${schema} field="web.echo_to_channel" /></label>
1381
+ <p class="note">${tn("webEchoHint")}</p>
1462
1382
  </section>`) : null}
1463
- ${has("readonly") ? html`<div class="s-effective-view"><p class="s-effective-notice"><${Icon} name="info" size=${18} />${layoutText("revEffectiveHint")}</p>
1464
- <section class="card s-web-readonly"><h3 class="sr-only">${tn("webReadOnlyTitle")}</h3>
1465
- <div class="s-ro-columns" aria-hidden="true"><span>${layoutText("effectiveKey")}</span><span>${layoutText("effectiveValue")}</span><span>${layoutText("effectiveSource")}</span></div>
1466
- ${["web", "web_terminal"].map(group => html`<h4 class="s-ro-group">${group === "web" ? tn("sec_web-dashboard") : tn("webTerminalTitle")}</h4>
1467
- <dl class="s-web-ro">${WEB_READ_ONLY.filter(k => k.startsWith(`${group}.`)).map((k) => html`<div key=${k}><dt><code>${k}</code></dt><dd class="s-ro-value">${shown(k)}</dd><dd class="s-ro-source" aria-label=${layoutText("effectiveSource")}><span class="tag">${layoutText(configured(k) ? "effectiveSourceConfig" : "effectiveSourceDefault")}</span></dd></div>`)}</dl>`)}
1468
- </section><div class="s-effective-footnotes"><p class="note">${tn("webReadOnlyLead")}</p><p class="note">${tn("webSearchHint")}</p></div>
1469
- <div class="s-effective-actions"><button type="button" class="btn" onClick=${() => revealSettingsTarget(document.getElementById("advanced-panel-editor"))}><${Icon} name="edit" size=${16} />${layoutText("revGoEditor")}</button></div>
1470
- </div>` : null}
1383
+ ${has("dashboard") ? lock(html`<section class="card"><h3>${tn("webDashboardTitle")}</h3>
1384
+ <label class=${fc("check", "log")}><input id="webLogTab" type="checkbox" checked=${f.log} onChange=${(e) => set("log")(e.target.checked)} /><span>${tn("webLogTab")}</span><${Impact} schema=${schema} field="web.log_tab" /></label>
1385
+ <p class="note">${tn("webLogTabHint")}</p>
1386
+ <label class=${fc("check", "usagePub")}><input id="webUsagePublic" type="checkbox" checked=${f.usagePub} onChange=${(e) => set("usagePub")(e.target.checked)} /><span>${tn("webUsagePublic")}</span><${Impact} schema=${schema} field="web.usage_report_on_public_link" /></label>
1387
+ <p class="note">${tn("webUsagePublicHint")}</p>
1388
+ <label class=${fc("check", "levels")}><input id="webOfficeLevels" type="checkbox" checked=${f.levels} onChange=${(e) => set("levels")(e.target.checked)} /><span>${tn("webOfficeLevels")}</span><${Impact} schema=${schema} field="web.office_levels" /></label>
1389
+ <p class="note">${tn("webOfficeLevelsHint")}</p>
1390
+ <label class=${fc("check", "cdn")}><input id="webPreviewCdn" type="checkbox" checked=${f.cdn} onChange=${(e) => set("cdn")(e.target.checked)} /><span>${tn("webPreviewCdn")}</span><${Impact} schema=${schema} field="web.preview_cdn" /></label>
1391
+ <p class="note">${tn("webPreviewCdnHint")}</p>
1392
+ </section>`) : null}
1393
+ ${has("readonly") ? html`<section class="card s-web-readonly"><h3>${tn("webReadOnlyTitle")}</h3>
1394
+ <p class="note">${tn("webReadOnlyLead")}</p>
1395
+ <dl class="s-web-ro">${WEB_READ_ONLY.map((k) => html`<div key=${k}><dt><code>${k}</code></dt><dd>${shown(k)}</dd></div>`)}</dl>
1396
+ <p class="note">${tn("webSearchHint")}</p>
1397
+ </section>` : null}
1471
1398
  </div>`;
1472
1399
  }
1400
+
1473
1401
  /**
1474
1402
  * Developer: the fleet model as YAML or JSON, to read, copy, download — or edit. #2347: an edit's Apply stages its
1475
1403
  * writes in the Save bar like every form's change (Save writes them, in order, then one apply; Discard drops them),
@@ -1523,15 +1451,14 @@ function Developer({ ctx }) {
1523
1451
  return html`<section class="card s-dev">
1524
1452
  <div class="s-dev-bar">
1525
1453
  <div class="seg-inline" role="group" aria-label=${tn("format")}>
1526
- ${["yaml", "json"].map((k) => html`<button key=${k} type="button" class=${`btn btn-sm${fmt === k ? " on" : ""}`} aria-pressed=${fmt === k ? "true" : "false"} onClick=${() => setFmt(k)}>${k.toUpperCase()}</button>`)}</div><p class="s-dev-context"><${Icon} name="info" size=${15} />${layoutText("revEditorContext")}</p>
1527
- <div class="s-dev-actions"><button type="button" class="btn btn-sm" disabled=${blocked && !editing} title=${blocked && !editing ? tn("devFormsUnsaved") : undefined} onClick=${() => setEditing(!editing)}>${editing ? tn("viewMode") : tn("editMode")}</button>
1454
+ ${["yaml", "json"].map((k) => html`<button key=${k} type="button" class=${`btn btn-sm${fmt === k ? " on" : ""}`} aria-pressed=${fmt === k ? "true" : "false"} onClick=${() => setFmt(k)}>${k.toUpperCase()}</button>`)}</div>
1455
+ <button type="button" class="btn btn-sm" disabled=${blocked && !editing} title=${blocked && !editing ? tn("devFormsUnsaved") : undefined} onClick=${() => setEditing(!editing)}>${editing ? tn("viewMode") : tn("editMode")}</button>
1528
1456
  <button type="button" class="btn btn-sm" title=${tn("copy")} onClick=${copy}><${Icon} name="copy" size=${14} /><span class="lbl">${tn("copy")}</span></button>
1529
- <button type="button" class="btn btn-sm" title=${tn("devDownload")} onClick=${download}><${Icon} name="download" size=${14} /><span class="lbl">${tn("devDownload")}</span></button></div>
1457
+ <button type="button" class="btn btn-sm" title=${tn("devDownload")} onClick=${download}><${Icon} name="download" size=${14} /><span class="lbl">${tn("devDownload")}</span></button>
1530
1458
  </div>
1531
1459
  ${editing ? html`<textarea class="s-yaml" aria-label=${tn("devEditor")} spellcheck=${false} wrap="off" value=${draft} onInput=${(e) => setDraft(e.target.value)}></textarea>
1532
1460
  <div class="save-row"><button type="button" class="btn btn-primary" disabled=${blocked} onClick=${save}>${tn("devApply")}</button><span class="note">${tn("devApplyHint")}</span></div>`
1533
- : html`<pre class="s-yaml" tabindex="0">${text}</pre>`}
1534
- <div class="s-dev-state"><span class="s-dev-file">fleet.yaml</span><${Icon} name=${editing ? "edit" : "view"} size=${14} /><span>${layoutText(editing ? "developerEditing" : "developerReadOnly")}</span></div>
1461
+ : html`<pre class="s-yaml">${text}</pre>`}
1535
1462
  ${blocked ? html`<p class="note s-dev-blocked" role="status">${tn("devFormsUnsaved")}</p>`
1536
1463
  : held && !msg ? html`<p class="note s-dev-held" role="status">${tn("devStaged", heldCount)}</p>` : null}
1537
1464
  ${msg ? html`<p class=${`feedback${msg.error ? " error" : ""}`} role="status">${msg.error || msg.text}</p>` : null}
@@ -1544,23 +1471,16 @@ function Developer({ ctx }) {
1544
1471
  */
1545
1472
  function PendingBar({ staged, busy, onApply, onDiscard, section }) {
1546
1473
  const changes = [...staged.values()];
1547
- // What Save will cost, one line each: a change that knows its own words (the shared agent settings: how many agents
1548
- // restart) says them; any other says its impact label.
1549
- const costs = [];
1550
- for (const c of changes) {
1551
- if (c.invalid) continue;
1552
- for (const line of Array.isArray(c.notes) && c.notes.length ? c.notes : [impactText(c.impact)]) if (!costs.includes(line)) costs.push(line);
1553
- }
1474
+ const kinds = [...new Set(changes.filter((c) => !c.invalid).map((c) => c.impact))];
1554
1475
  const invalid = changes.filter((c) => c.invalid).length;
1555
1476
  // #2382 review: a field to fix in another section is named, and the message goes there (its field focused).
1556
1477
  const elsewhere = changes.find((c) => c.invalid && c.section && c.section !== section);
1557
- const problem = elsewhere || changes.find((c) => c.invalid && c.target);
1558
1478
  const count = changes.reduce((n, c) => n + (Number.isInteger(c.count) && c.count > 0 ? c.count : 1), 0);
1559
1479
  return html`<div data-trust="panel-controls" class="s-pending" role="region" aria-label=${tn("pendingRegion")}>
1560
1480
  <strong>${tn("changesPending", count)}</strong>
1561
- <span class="note">${costs.join(" · ")}</span>
1481
+ <span class="note">${kinds.map(impactText).join(" · ")}</span>
1562
1482
  <span class="s-pending-actions">
1563
- ${!invalid ? null : problem ? html`<button type="button" class="link-btn feedback error s-fix" role="status" onClick=${() => goToTarget(problem.section || section, problem.target)}>${elsewhere ? tn("fixToSaveIn", invalid, tn(`sec_${elsewhere.section}`)) : tn("fixToSave", invalid)}</button>`
1483
+ ${!invalid ? null : elsewhere ? html`<button type="button" class="link-btn feedback error s-fix" role="status" onClick=${() => goToTarget(elsewhere.section, elsewhere.target)}>${tn("fixToSaveIn", invalid, tn(`sec_${elsewhere.section}`))}</button>`
1564
1484
  : html`<span class="feedback error s-fix" role="status">${tn("fixToSave", invalid)}</span>`}
1565
1485
  <button type="button" class="btn" onClick=${onDiscard} disabled=${busy}>${tn("discard")}</button>
1566
1486
  <button type="button" class="btn btn-primary" onClick=${onApply} disabled=${busy || invalid > 0} title=${busy ? tn("applyBusyLocal") : undefined}>${tn("applyChanges")}</button>
@@ -1667,11 +1587,12 @@ function PublicTunnelToken() {
1667
1587
  } catch { if (lease.current()) setMessage(tn("applyFailed")); }
1668
1588
  finally { inFlight.current = false; if (lease.current()) setBusy(false); }
1669
1589
  };
1670
- return html`<section class="card s-tunnel-token"><div class="s-token-head"><h3>${tn("namedToken")}</h3><span class="tag">${present ? tn("keyConfigured") : tn("keyNotConfigured")}</span></div>
1590
+ return html`<section class="card"><h3>${tn("namedToken")}</h3>
1671
1591
  <p class="note">${tn("namedTokenHint")}</p>
1672
- <details class="s-token-editor"><summary>${layoutText(present ? "revUpdateCredential" : "revSetCredential")}</summary><div class="s-token-editor-body"><input class="s-token-input" id="publicTunnelToken" type="password" autocomplete="new-password" aria-label=${tn("namedToken")} value=${secret} onInput=${e => { setSecret(e.target.value); setTypedTunnelToken(e.target.value); }} />
1673
- <div class="s-token-actions"><button type="button" class="btn btn-sm" disabled=${busy || !secret} onClick=${() => go(false)}>${tn("namedTokenSet")}</button>
1674
- <button type="button" class="btn btn-sm" disabled=${busy || !present} onClick=${() => go(true)}>${tn("namedTokenClear")}</button></div></div></details>
1592
+ <span class="tag">${present ? tn("keyConfigured") : tn("keyNotConfigured")}</span>
1593
+ <input id="publicTunnelToken" type="password" autocomplete="new-password" aria-label=${tn("namedToken")} value=${secret} onInput=${e => { setSecret(e.target.value); setTypedTunnelToken(e.target.value); }} />
1594
+ <button type="button" class="btn btn-sm" disabled=${busy || !secret} onClick=${() => go(false)}>${tn("namedTokenSet")}</button>
1595
+ <button type="button" class="btn btn-sm" disabled=${busy || !present} onClick=${() => go(true)}>${tn("namedTokenClear")}</button>
1675
1596
  ${message ? html`<p class="note" role="status">${message}</p>` : null}
1676
1597
  </section>`;
1677
1598
  }