cli-jaw 2.17.62 → 2.17.63

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 (360) hide show
  1. package/README.ja.md +17 -17
  2. package/README.ko.md +17 -17
  3. package/README.md +17 -17
  4. package/README.zh-CN.md +17 -17
  5. package/dist/bin/commands/tui/input-handler.js +19 -0
  6. package/dist/bin/commands/tui/input-handler.js.map +1 -1
  7. package/dist/bin/commands/tui/overlays.js +8 -4
  8. package/dist/bin/commands/tui/overlays.js.map +1 -1
  9. package/dist/bin/star-prompt.js +1 -1
  10. package/dist/bin/star-prompt.js.map +1 -1
  11. package/dist/server.js +14 -1
  12. package/dist/server.js.map +1 -1
  13. package/dist/src/agent/claude-runtime-pool.js +2 -1
  14. package/dist/src/agent/claude-runtime-pool.js.map +1 -1
  15. package/dist/src/agent/claude-runtime-run.js +28 -7
  16. package/dist/src/agent/claude-runtime-run.js.map +1 -1
  17. package/dist/src/agent/lifecycle-handler.js +34 -6
  18. package/dist/src/agent/lifecycle-handler.js.map +1 -1
  19. package/dist/src/agent/runtime/claude-sdk-events.js +136 -9
  20. package/dist/src/agent/runtime/claude-sdk-events.js.map +1 -1
  21. package/dist/src/agent/runtime/claude-sdk-history-loader.js +24 -0
  22. package/dist/src/agent/runtime/claude-sdk-history-loader.js.map +1 -0
  23. package/dist/src/agent/runtime/claude-sdk-hooks.js +10 -4
  24. package/dist/src/agent/runtime/claude-sdk-hooks.js.map +1 -1
  25. package/dist/src/agent/runtime/claude-sdk-messages.js +25 -2
  26. package/dist/src/agent/runtime/claude-sdk-messages.js.map +1 -1
  27. package/dist/src/agent/runtime/claude-sdk-options.js +36 -3
  28. package/dist/src/agent/runtime/claude-sdk-options.js.map +1 -1
  29. package/dist/src/agent/runtime/claude-sdk-permissions.js +32 -9
  30. package/dist/src/agent/runtime/claude-sdk-permissions.js.map +1 -1
  31. package/dist/src/agent/runtime/claude-sdk-session.js +165 -17
  32. package/dist/src/agent/runtime/claude-sdk-session.js.map +1 -1
  33. package/dist/src/agent/runtime/claude-sdk-version.js +8 -0
  34. package/dist/src/agent/runtime/claude-sdk-version.js.map +1 -0
  35. package/dist/src/agent/spawn/backend-codex-app.js +619 -0
  36. package/dist/src/agent/spawn/backend-codex-app.js.map +1 -0
  37. package/dist/src/agent/spawn/backend-context.js +2 -0
  38. package/dist/src/agent/spawn/backend-context.js.map +1 -0
  39. package/dist/src/agent/spawn/backend-copilot.js +385 -0
  40. package/dist/src/agent/spawn/backend-copilot.js.map +1 -0
  41. package/dist/src/agent/spawn/backend-native-acp.js +379 -0
  42. package/dist/src/agent/spawn/backend-native-acp.js.map +1 -0
  43. package/dist/src/agent/spawn/backend-pi.js +565 -0
  44. package/dist/src/agent/spawn/backend-pi.js.map +1 -0
  45. package/dist/src/agent/spawn/types.js +2 -0
  46. package/dist/src/agent/spawn/types.js.map +1 -0
  47. package/dist/src/agent/spawn.js +44 -1858
  48. package/dist/src/agent/spawn.js.map +1 -1
  49. package/dist/src/cli/claude-default-model-boot.js +36 -0
  50. package/dist/src/cli/claude-default-model-boot.js.map +1 -0
  51. package/dist/src/cli/claude-model-discovery.js +13 -1
  52. package/dist/src/cli/claude-model-discovery.js.map +1 -1
  53. package/dist/src/cli/claude-models.js +7 -1
  54. package/dist/src/cli/claude-models.js.map +1 -1
  55. package/dist/src/cli/commands.js +5 -15
  56. package/dist/src/cli/commands.js.map +1 -1
  57. package/dist/src/cli/tui/composer.js +3 -3
  58. package/dist/src/cli/tui/composer.js.map +1 -1
  59. package/dist/src/cli/tui/skill-mention.js +15 -0
  60. package/dist/src/cli/tui/skill-mention.js.map +1 -0
  61. package/dist/src/code-mode/manager.js +174 -9
  62. package/dist/src/code-mode/manager.js.map +1 -1
  63. package/dist/src/code-mode/providers/catalog.js +5 -3
  64. package/dist/src/code-mode/providers/catalog.js.map +1 -1
  65. package/dist/src/code-mode/providers/claude-history.js +132 -0
  66. package/dist/src/code-mode/providers/claude-history.js.map +1 -0
  67. package/dist/src/code-mode/providers/claude.js +74 -7
  68. package/dist/src/code-mode/providers/claude.js.map +1 -1
  69. package/dist/src/code-mode/providers/codex-app.js +7 -1
  70. package/dist/src/code-mode/providers/codex-app.js.map +1 -1
  71. package/dist/src/code-mode/session.js +158 -11
  72. package/dist/src/code-mode/session.js.map +1 -1
  73. package/dist/src/code-mode/store.js +416 -28
  74. package/dist/src/code-mode/store.js.map +1 -1
  75. package/dist/src/command-contract/catalog.js +3 -22
  76. package/dist/src/command-contract/catalog.js.map +1 -1
  77. package/dist/src/core/codex-config.js +3 -62
  78. package/dist/src/core/codex-config.js.map +1 -1
  79. package/dist/src/core/config.js +116 -14
  80. package/dist/src/core/config.js.map +1 -1
  81. package/dist/src/core/runtime-settings.js +20 -10
  82. package/dist/src/core/runtime-settings.js.map +1 -1
  83. package/dist/src/core/settings-watch.js +1 -0
  84. package/dist/src/core/settings-watch.js.map +1 -1
  85. package/dist/src/core/skill-mentions.js +83 -0
  86. package/dist/src/core/skill-mentions.js.map +1 -0
  87. package/dist/src/manager/registry.js +5 -1
  88. package/dist/src/manager/registry.js.map +1 -1
  89. package/dist/src/manager/routes/desktop-status.js +1 -1
  90. package/dist/src/manager/routes/desktop-status.js.map +1 -1
  91. package/dist/src/orchestrator/pipeline.js +11 -1
  92. package/dist/src/orchestrator/pipeline.js.map +1 -1
  93. package/dist/src/prompt/builder.js +10 -4
  94. package/dist/src/prompt/builder.js.map +1 -1
  95. package/dist/src/prompt/templates/a1-system.md +1 -1
  96. package/dist/src/routes/code-native.js +51 -3
  97. package/dist/src/routes/code-native.js.map +1 -1
  98. package/dist/src/routes/settings.js +1 -4
  99. package/dist/src/routes/settings.js.map +1 -1
  100. package/dist/src/routes/skills.js +7 -0
  101. package/dist/src/routes/skills.js.map +1 -1
  102. package/dist/src/shared/skill-mention.js +61 -0
  103. package/dist/src/shared/skill-mention.js.map +1 -0
  104. package/dist/src/shared/tool-input.js +137 -0
  105. package/dist/src/shared/tool-input.js.map +1 -0
  106. package/package.json +7 -5
  107. package/public/css/activity.css +83 -20
  108. package/public/css/layout.css +2 -2
  109. package/public/css/sidebar.css +18 -0
  110. package/public/css/variables.css +23 -2
  111. package/public/dist/.vite/manifest.json +302 -334
  112. package/public/dist/assets/Activity-DPLlOJ46.js +1 -0
  113. package/public/dist/assets/AdvancedExport-BgOgGvc5.js +1 -0
  114. package/public/dist/assets/Agent-O_U8ny90.js +1 -0
  115. package/public/dist/assets/Browser-m6VynQXV.js +1 -0
  116. package/public/dist/assets/BrowserPanel-Bb-Bge6B.js +3 -0
  117. package/public/dist/assets/ChannelEnablementControl-BSuKQhTW.js +85 -0
  118. package/public/dist/assets/ChannelSetupEntry-DHLoZEzJ.js +1 -0
  119. package/public/dist/assets/ChannelsDiscord-B-G8vsYy.js +1 -0
  120. package/public/dist/assets/ChannelsSlack-oPuh922z.js +1 -0
  121. package/public/dist/assets/ChannelsTelegram-PmTv43KQ.js +1 -0
  122. package/public/dist/assets/CodeCanvas-CVbdp0S-.js +3 -0
  123. package/public/dist/assets/DashboardMeta-BqEiJrvr.js +1 -0
  124. package/public/dist/assets/DesignPanel-BOb-HMbl.js +2 -0
  125. package/public/dist/assets/{Developer-BdKPcw8Z.js → Developer-CbySB7_Z.js} +1 -1
  126. package/public/dist/assets/{DiffPanel-DtJuvU5y.js → DiffPanel-D9Cch5FG.js} +1 -1
  127. package/public/dist/assets/Display-C0Zdamcb.js +1 -0
  128. package/public/dist/assets/Display-DU4_76cS.js +1 -0
  129. package/public/dist/assets/DocPanel-DvtFw8AP.js +1 -0
  130. package/public/dist/assets/{Embedding-DvdTj1BF.js → Embedding-CCFMOB_2.js} +1 -1
  131. package/public/dist/assets/Employees-BanvF58d.js +1 -0
  132. package/public/dist/assets/FolderPanel-CJvwRwIV.js +3 -0
  133. package/public/dist/assets/Heartbeat-uyi_MpUd.js +1 -0
  134. package/public/dist/assets/InlineWarn-Cq4z28F3.js +1 -0
  135. package/public/dist/assets/MarkdownRenderer-Cc3DeHvm.js +1 -0
  136. package/public/dist/assets/{MarkdownRenderer-DhonsAPC.js → MarkdownRenderer-DzN66XVb.js} +1 -1
  137. package/public/dist/assets/Mcp-rjPoL_Zo.js +4 -0
  138. package/public/dist/assets/Memory-C9I33pIi.js +1 -0
  139. package/public/dist/assets/{MilkdownWysiwygEditor-D6JaLDE4.js → MilkdownWysiwygEditor-xObhviw7.js} +1 -1
  140. package/public/dist/assets/ModelProvider-fiUktMaO.js +1 -0
  141. package/public/dist/assets/Network-CuqFrOvR.js +1 -0
  142. package/public/dist/assets/NotesGraphWorkspace-DO9LtVGF.js +1 -0
  143. package/public/dist/assets/PanelLayoutProvider-DRZ4QkBC.js +1 -0
  144. package/public/dist/assets/Permissions-BltXiZnz.js +1 -0
  145. package/public/dist/assets/{Permissions-BwiMEoTV.js → Permissions-DcCbFMIq.js} +1 -1
  146. package/public/dist/assets/Profile-DUL7-RE_.js +1 -0
  147. package/public/dist/assets/Prompts-C9vY8ivQ.js +1 -0
  148. package/public/dist/assets/SpeechKeys-BJ8V7U5E.js +1 -0
  149. package/public/dist/assets/TelegramHub-DtyjLGFR.js +1 -0
  150. package/public/dist/assets/{TerminalPanel-Bu9i-P2f.js → TerminalPanel-c1xhiy53.js} +1 -1
  151. package/public/dist/assets/app-BjKzqXCv.css +1 -0
  152. package/public/dist/assets/app-CZwx0V6K.js +59 -0
  153. package/public/dist/assets/bgtask-badge-CnVkcp3c.js +1 -0
  154. package/public/dist/assets/{bgtask-badge-DfiHuzxT.js → bgtask-badge-Cp26S8Uq.js} +1 -1
  155. package/public/dist/assets/client-platform-WO8m6kPQ.js +1 -0
  156. package/public/dist/assets/{employees-BQaJNp-u.js → employees-CsvI0_5V.js} +1 -1
  157. package/public/dist/assets/error-normalize-clOi-AAA.js +1 -0
  158. package/public/dist/assets/fields-CicOWY-X.js +1 -0
  159. package/public/dist/assets/iframe-renderer-DWx9v2Iz.js +1 -0
  160. package/public/dist/assets/iframe-renderer-DmHYOI1A.js +142 -0
  161. package/public/dist/assets/{react-C_pPTFsM.js → jsx-runtime-CkEUZM6i.js} +1 -1
  162. package/public/dist/assets/manager-CCXm5Yfe.js +5 -0
  163. package/public/dist/assets/manager-D9rhKFKc.css +1 -0
  164. package/public/dist/assets/manager-shortcuts-Cqmr0mEq.js +1 -0
  165. package/public/dist/assets/{memory-EG1B51up.js → memory-C6qtAMdJ.js} +1 -1
  166. package/public/dist/assets/memory-PPofQPeB.js +1 -0
  167. package/public/dist/assets/message-history-DcjBuubA.js +4 -0
  168. package/public/dist/assets/message-history-bw4qF01Z.js +1 -0
  169. package/public/dist/assets/page-shell-DfinU3mb.js +1 -0
  170. package/public/dist/assets/react-dom-URBLzV3w.js +1 -0
  171. package/public/dist/assets/{render-Dp07lZAJ.js → render-DfYro-fG.js} +1 -1
  172. package/public/dist/assets/{settings-jlI4X-zt.js → settings-CvsLWlJn.js} +38 -30
  173. package/public/dist/assets/settings-DMiQe469.js +1 -0
  174. package/public/dist/assets/settings-DgAlohx9.js +1 -0
  175. package/public/dist/assets/settings-core-BH7J_Rbm.js +1 -0
  176. package/public/dist/assets/{settings-core-B5Uf_lWY.js → settings-core-pnpw-eZv.js} +1 -1
  177. package/public/dist/assets/{settings-embedding-BfWzWKMM.js → settings-embedding-BRW0WZvh.js} +3 -3
  178. package/public/dist/assets/{settings-embedding-DhEdT86W.css → settings-embedding-CUQ8Is3y.css} +1 -1
  179. package/public/dist/assets/settings-types-CYKy0xz4.js +1 -0
  180. package/public/dist/assets/shared-D1begqvi.js +1 -0
  181. package/public/dist/assets/{sidebar-BUemG2ZN.js → sidebar-C_80w4iY.js} +3 -3
  182. package/public/dist/assets/{skills-CKUcEN9m.js → skills-D_2adqge.js} +1 -1
  183. package/public/dist/assets/skills-DeNVAVgt.js +1 -0
  184. package/public/dist/assets/{slash-commands-D34GgHFX.js → slash-commands-B_Hq5RkC.js} +2 -2
  185. package/public/dist/assets/slash-commands-Cj5qoRWc.js +1 -0
  186. package/public/dist/assets/tool-input-DI7uu8Ah.js +2 -0
  187. package/public/dist/assets/{trace-drawer-DBmK-5F_.js → trace-drawer-B6XuPodh.js} +1 -1
  188. package/public/dist/assets/ui-BbR_fFiK.js +1 -0
  189. package/public/dist/assets/{ui-vm2iuLcS.js → ui-D8xzm7DN.js} +1 -1
  190. package/public/dist/index.html +11 -3
  191. package/public/dist/manager/index.html +3 -3
  192. package/public/dist/settings/index.html +2 -2
  193. package/public/index.html +9 -1
  194. package/public/js/features/activity-history.ts +50 -21
  195. package/public/js/features/activity-rows.ts +158 -10
  196. package/public/js/features/activity-view.ts +5 -5
  197. package/public/js/features/chat.ts +2 -0
  198. package/public/js/features/employees.ts +1 -0
  199. package/public/js/features/resize-guard.ts +39 -0
  200. package/public/js/features/settings-cli-status.ts +49 -17
  201. package/public/js/features/settings-types.ts +39 -1
  202. package/public/js/features/skill-mentions.ts +143 -0
  203. package/public/js/main.ts +15 -0
  204. package/public/js/virtual-scroll.ts +67 -1
  205. package/public/locales/en.json +2 -0
  206. package/public/locales/ja.json +2 -0
  207. package/public/locales/ko.json +2 -0
  208. package/public/locales/zh.json +2 -0
  209. package/public/manager/src/AppChrome.tsx +2 -0
  210. package/public/manager/src/InstancePreview.tsx +1 -1
  211. package/public/manager/src/SidebarRailRouter.tsx +3 -1
  212. package/public/manager/src/browser-panel/BrowserPanel.tsx +47 -12
  213. package/public/manager/src/browser-panel/browser-address-state.ts +11 -0
  214. package/public/manager/src/client-platform.ts +18 -0
  215. package/public/manager/src/code/CodeCanvas.tsx +4 -2
  216. package/public/manager/src/code/CodeComposer.tsx +22 -10
  217. package/public/manager/src/code/CodeDraftEmptyState.tsx +64 -0
  218. package/public/manager/src/code/CodeSessionList.tsx +154 -40
  219. package/public/manager/src/code/CodeTranscript.tsx +104 -16
  220. package/public/manager/src/code/CodeWorkbench.tsx +21 -11
  221. package/public/manager/src/code/CodeWorkspaceHeader.tsx +5 -10
  222. package/public/manager/src/code/ComposerFooter.tsx +9 -1
  223. package/public/manager/src/code/code-composer.css +1 -1
  224. package/public/manager/src/code/code-controller-draft-storage.ts +16 -8
  225. package/public/manager/src/code/code-controller-drafts.ts +33 -6
  226. package/public/manager/src/code/code-controller-runtime.ts +189 -17
  227. package/public/manager/src/code/code-controller-types.ts +19 -1
  228. package/public/manager/src/code/code-recent-workspaces.ts +25 -0
  229. package/public/manager/src/code/code-session-client.ts +19 -1
  230. package/public/manager/src/code/code-session-sidebar.css +38 -0
  231. package/public/manager/src/code/code-session-state.ts +2 -0
  232. package/public/manager/src/code/code-types.ts +47 -0
  233. package/public/manager/src/code/code-workbench.css +36 -1
  234. package/public/manager/src/code/code.css +171 -7
  235. package/public/manager/src/code/session-order.ts +80 -0
  236. package/public/manager/src/code/tool-summary.ts +45 -11
  237. package/public/manager/src/folder-panel/folder-shortcuts.ts +5 -9
  238. package/public/manager/src/hooks/useCommandPalette.ts +3 -7
  239. package/public/manager/src/main.tsx +1 -0
  240. package/public/manager/src/manager-components.css +25 -23
  241. package/public/manager/src/manager-dashboard-reminders.css +2 -2
  242. package/public/manager/src/manager-layout.css +1 -1
  243. package/public/manager/src/manager-shortcut-runner.ts +9 -2
  244. package/public/manager/src/manager-shortcuts.ts +83 -21
  245. package/public/manager/src/panels/desktop-bridge.ts +4 -1
  246. package/public/manager/src/panels/panels.css +9 -0
  247. package/public/manager/src/preview.ts +19 -4
  248. package/public/manager/src/settings/pages/AdvancedExport.tsx +28 -30
  249. package/public/manager/src/settings/pages/Browser.tsx +45 -47
  250. package/public/manager/src/settings/pages/ChannelsDiscord.tsx +51 -26
  251. package/public/manager/src/settings/pages/ChannelsSlack.tsx +59 -17
  252. package/public/manager/src/settings/pages/ChannelsTelegram.tsx +51 -26
  253. package/public/manager/src/settings/pages/Display.tsx +2 -1
  254. package/public/manager/src/settings/pages/Employees.tsx +3 -3
  255. package/public/manager/src/settings/pages/Mcp.tsx +220 -200
  256. package/public/manager/src/settings/pages/Memory.tsx +35 -41
  257. package/public/manager/src/settings/pages/ModelProvider.tsx +23 -98
  258. package/public/manager/src/settings/pages/Network.tsx +5 -4
  259. package/public/manager/src/settings/pages/Permissions.tsx +38 -16
  260. package/public/manager/src/settings/pages/Prompts.tsx +12 -9
  261. package/public/manager/src/settings/pages/SpeechKeys.tsx +132 -139
  262. package/public/manager/src/settings/pages/TelegramHub.tsx +67 -20
  263. package/public/manager/src/settings/pages/components/AvatarCard.tsx +9 -8
  264. package/public/manager/src/settings/pages/components/ChannelSetupEntry.tsx +2 -2
  265. package/public/manager/src/settings/pages/components/EmployeeRow.tsx +6 -12
  266. package/public/manager/src/settings/pages/components/HealthBadge.tsx +11 -6
  267. package/public/manager/src/settings/pages/components/HeartbeatJobRow.tsx +35 -16
  268. package/public/manager/src/settings/pages/components/HeartbeatJobsSection.tsx +11 -11
  269. package/public/manager/src/settings/pages/components/HeartbeatMarkdownSection.tsx +7 -7
  270. package/public/manager/src/settings/pages/components/InlineWarn.tsx +4 -9
  271. package/public/manager/src/settings/pages/components/McpServerCard.tsx +39 -27
  272. package/public/manager/src/settings/pages/components/MemoryRow.tsx +21 -16
  273. package/public/manager/src/settings/pages/components/PerCliRow.tsx +122 -121
  274. package/public/manager/src/settings/pages/components/PiProfileDialog.tsx +9 -6
  275. package/public/manager/src/settings/pages/components/SlackSetup.tsx +8 -8
  276. package/public/manager/src/settings/pages/components/TransportStatusChips.tsx +14 -10
  277. package/public/manager/src/settings/pages/components/agent/AgentEmployeesSection.tsx +26 -26
  278. package/public/manager/src/settings/pages/components/agent/PermissionQuickSection.tsx +5 -5
  279. package/public/manager/src/settings/pages/components/agent/RuntimeEmployeeRow.tsx +14 -11
  280. package/public/manager/src/settings/pages/components/agent/RuntimeHeader.tsx +1 -3
  281. package/public/manager/src/settings/pages/components/agent/agent-meta.ts +0 -2
  282. package/public/manager/src/settings/pages/components/runtime-transport-field.tsx +2 -2
  283. package/public/manager/src/settings/pages/manager/Activity.tsx +6 -2
  284. package/public/manager/src/settings/pages/manager/Display.tsx +3 -8
  285. package/public/manager/src/settings/pages/manager/shared.tsx +44 -33
  286. package/public/manager/src/settings/pages/page-shell.tsx +66 -0
  287. package/public/manager/src/settings-agent.css +185 -36
  288. package/public/manager/src/settings-standalone.tsx +1 -0
  289. package/public/manager/src/settings-surface.css +96 -0
  290. package/public/manager/src/types.ts +1 -0
  291. package/scripts/ci/install-ripgrep.sh +35 -0
  292. package/scripts/collect-fresh-install-evidence.sh +2 -2
  293. package/scripts/install-risk-gate.mjs +2 -3
  294. package/scripts/install-wsl.sh +1 -1
  295. package/scripts/install.ps1 +1 -1
  296. package/scripts/install.sh +1 -1
  297. package/scripts/release-1.6.0.sh +1 -1
  298. package/scripts/release-gates.mjs +48 -13
  299. package/scripts/release-preview.sh +2 -2
  300. package/scripts/restack-pr.sh +88 -0
  301. package/scripts/verify-electron-update-metadata.mjs +1 -1
  302. package/scripts/windows-support-contract.json +1 -1
  303. package/public/dist/assets/Activity-BUrp73Re.js +0 -1
  304. package/public/dist/assets/AdvancedExport-B7h_ZvBu.js +0 -1
  305. package/public/dist/assets/Agent-DnbZJP7b.js +0 -1
  306. package/public/dist/assets/Browser-CiBoK5Qx.js +0 -1
  307. package/public/dist/assets/BrowserPanel-SZAUc9T2.js +0 -3
  308. package/public/dist/assets/ChannelEnablementControl-Dl0uYx38.js +0 -85
  309. package/public/dist/assets/ChannelSetupEntry-DxtOrN01.js +0 -1
  310. package/public/dist/assets/ChannelsDiscord-BEGGwd_3.js +0 -1
  311. package/public/dist/assets/ChannelsSlack-BryC2Ahr.js +0 -1
  312. package/public/dist/assets/ChannelsTelegram-CGSpaImJ.js +0 -1
  313. package/public/dist/assets/CodeCanvas-DpkFi5Au.js +0 -2
  314. package/public/dist/assets/DashboardMeta-Dh-tasbY.js +0 -1
  315. package/public/dist/assets/DesignPanel-NLNK9wCo.js +0 -2
  316. package/public/dist/assets/Display-BHGFX3O0.js +0 -1
  317. package/public/dist/assets/Display-BW-_pKRf.js +0 -1
  318. package/public/dist/assets/DocPanel-BM41cYpS.js +0 -1
  319. package/public/dist/assets/Employees-BuFw6-fT.js +0 -1
  320. package/public/dist/assets/FolderPanel-C-eQT3Yq.js +0 -3
  321. package/public/dist/assets/Heartbeat-CIVtKWNc.js +0 -1
  322. package/public/dist/assets/InlineWarn-DIMbcbzk.js +0 -1
  323. package/public/dist/assets/MarkdownRenderer-DyVx6DxM.js +0 -1
  324. package/public/dist/assets/Mcp-uKjor7vh.js +0 -4
  325. package/public/dist/assets/Memory-BSDIXT0B.js +0 -1
  326. package/public/dist/assets/ModelProvider-DMh2tXUx.js +0 -1
  327. package/public/dist/assets/Network-4Pa6JkhK.js +0 -1
  328. package/public/dist/assets/NotesGraphWorkspace-CgdC-fM6.js +0 -1
  329. package/public/dist/assets/PanelLayoutProvider-mn8sI0h-.js +0 -1
  330. package/public/dist/assets/Permissions-CodIW-Yd.js +0 -1
  331. package/public/dist/assets/Profile-DPqrYA44.js +0 -1
  332. package/public/dist/assets/Prompts-CvAx7QqR.js +0 -1
  333. package/public/dist/assets/SpeechKeys-CVBCqoBn.js +0 -1
  334. package/public/dist/assets/TelegramHub-4zKwpk0P.js +0 -1
  335. package/public/dist/assets/app-ByMfeXp-.js +0 -55
  336. package/public/dist/assets/app-DAJWqs33.css +0 -1
  337. package/public/dist/assets/bgtask-badge-Ch88fnhf.js +0 -1
  338. package/public/dist/assets/error-normalize-CL69Bl7z.js +0 -1
  339. package/public/dist/assets/fields-mlGpofqQ.js +0 -1
  340. package/public/dist/assets/iframe-renderer-Bj1JolO8.js +0 -142
  341. package/public/dist/assets/iframe-renderer-DWnvUSrx.js +0 -1
  342. package/public/dist/assets/jsx-runtime-NZYk81nU.js +0 -1
  343. package/public/dist/assets/manager-Bi_xw7TW.js +0 -5
  344. package/public/dist/assets/manager-BnQHAKk6.css +0 -1
  345. package/public/dist/assets/manager-shortcuts-BDOzd8zm.js +0 -1
  346. package/public/dist/assets/memory-Bk_cb3sw.js +0 -1
  347. package/public/dist/assets/message-history-D2vniu04.js +0 -4
  348. package/public/dist/assets/message-history-GAtF_wbZ.js +0 -1
  349. package/public/dist/assets/page-shell-BeGD0rRQ.js +0 -1
  350. package/public/dist/assets/react-dom-DyUOYpVL.js +0 -1
  351. package/public/dist/assets/settings-W4KG9ivu.js +0 -1
  352. package/public/dist/assets/settings-WVGhtneN.js +0 -1
  353. package/public/dist/assets/settings-client-CmwRsVd1.js +0 -1
  354. package/public/dist/assets/settings-core-CgKGnMA5.js +0 -1
  355. package/public/dist/assets/settings-types-D3cd6SWy.js +0 -1
  356. package/public/dist/assets/shared-CiNP20HB.js +0 -1
  357. package/public/dist/assets/skills-Co7Mr-qP.js +0 -1
  358. package/public/dist/assets/slash-commands-BEr-vmIr.js +0 -1
  359. package/public/dist/assets/ui-TUyJsMUf.js +0 -1
  360. package/public/manager/src/settings/pages/components/EngineSubsection.tsx +0 -25
@@ -31,10 +31,10 @@ import {
31
31
  PageError,
32
32
  PageLoading,
33
33
  PageOffline,
34
+ SettingsNote,
34
35
  usePageSnapshot,
35
36
  } from './page-shell';
36
37
  import { expandPatch } from './path-utils';
37
- import { EngineSubsection } from './components/EngineSubsection';
38
38
 
39
39
  export const STT_ENGINES = ['auto', 'gemini', 'openai', 'whisper', 'vertex'] as const;
40
40
  export type SttEngine = (typeof STT_ENGINES)[number];
@@ -231,43 +231,41 @@ export default function SpeechKeys({ port, client, dirty, registerSave }: Settin
231
231
  title="Gemini"
232
232
  hint="Google AI Studio key. Used by the Gemini transcription path."
233
233
  >
234
- <EngineSubsection title="Credentials">
235
- <SecretField
236
- id="stt-gemini-key"
237
- label="API key"
238
- value={geminiApiKey}
239
- placeholder={geminiPlaceholder}
240
- onChange={(next) => {
241
- setGeminiApiKey(next);
242
- if (next.length === 0) {
243
- dirty.remove('stt.geminiApiKey');
244
- return;
245
- }
246
- setEntry('stt.geminiApiKey', {
247
- value: next,
248
- // Server doesn't echo the secret back, so
249
- // we use empty-string as the original. Any
250
- // typed value is a real change.
251
- original: '',
252
- valid: true,
253
- });
254
- }}
255
- />
256
- <TextField
257
- id="stt-gemini-model"
258
- label="Model"
259
- value={geminiModel}
260
- placeholder="gemini-2.5-flash-lite"
261
- onChange={(next) => {
262
- setGeminiModel(next);
263
- setEntry('stt.geminiModel', {
264
- value: next,
265
- original: original.geminiModel ?? '',
266
- valid: true,
267
- });
268
- }}
269
- />
270
- </EngineSubsection>
234
+ <SecretField
235
+ id="stt-gemini-key"
236
+ label="API key"
237
+ value={geminiApiKey}
238
+ placeholder={geminiPlaceholder}
239
+ onChange={(next) => {
240
+ setGeminiApiKey(next);
241
+ if (next.length === 0) {
242
+ dirty.remove('stt.geminiApiKey');
243
+ return;
244
+ }
245
+ setEntry('stt.geminiApiKey', {
246
+ value: next,
247
+ // Server doesn't echo the secret back, so
248
+ // we use empty-string as the original. Any
249
+ // typed value is a real change.
250
+ original: '',
251
+ valid: true,
252
+ });
253
+ }}
254
+ />
255
+ <TextField
256
+ id="stt-gemini-model"
257
+ label="Model"
258
+ value={geminiModel}
259
+ placeholder="gemini-2.5-flash-lite"
260
+ onChange={(next) => {
261
+ setGeminiModel(next);
262
+ setEntry('stt.geminiModel', {
263
+ value: next,
264
+ original: original.geminiModel ?? '',
265
+ valid: true,
266
+ });
267
+ }}
268
+ />
271
269
  </SettingsSection>
272
270
  ) : null}
273
271
 
@@ -276,54 +274,52 @@ export default function SpeechKeys({ port, client, dirty, registerSave }: Settin
276
274
  title="OpenAI"
277
275
  hint="Compatible with OpenAI-style transcription endpoints (incl. self-hosted)."
278
276
  >
279
- <EngineSubsection title="Credentials">
280
- <SecretField
281
- id="stt-openai-key"
282
- label="API key"
283
- value={openaiApiKey}
284
- placeholder={openaiPlaceholder}
285
- onChange={(next) => {
286
- setOpenaiApiKey(next);
287
- if (next.length === 0) {
288
- dirty.remove('stt.openaiApiKey');
289
- return;
290
- }
291
- setEntry('stt.openaiApiKey', {
292
- value: next,
293
- original: '',
294
- valid: true,
295
- });
296
- }}
297
- />
298
- <TextField
299
- id="stt-openai-base-url"
300
- label="Base URL (optional)"
301
- value={openaiBaseUrl}
302
- placeholder="https://api.openai.com/v1"
303
- onChange={(next) => {
304
- setOpenaiBaseUrl(next);
305
- setEntry('stt.openaiBaseUrl', {
306
- value: next,
307
- original: original.openaiBaseUrl ?? '',
308
- valid: true,
309
- });
310
- }}
311
- />
312
- <TextField
313
- id="stt-openai-model"
314
- label="Model"
315
- value={openaiModel}
316
- placeholder="whisper-1"
317
- onChange={(next) => {
318
- setOpenaiModel(next);
319
- setEntry('stt.openaiModel', {
320
- value: next,
321
- original: original.openaiModel ?? '',
322
- valid: true,
323
- });
324
- }}
325
- />
326
- </EngineSubsection>
277
+ <SecretField
278
+ id="stt-openai-key"
279
+ label="API key"
280
+ value={openaiApiKey}
281
+ placeholder={openaiPlaceholder}
282
+ onChange={(next) => {
283
+ setOpenaiApiKey(next);
284
+ if (next.length === 0) {
285
+ dirty.remove('stt.openaiApiKey');
286
+ return;
287
+ }
288
+ setEntry('stt.openaiApiKey', {
289
+ value: next,
290
+ original: '',
291
+ valid: true,
292
+ });
293
+ }}
294
+ />
295
+ <TextField
296
+ id="stt-openai-base-url"
297
+ label="Base URL (optional)"
298
+ value={openaiBaseUrl}
299
+ placeholder="https://api.openai.com/v1"
300
+ onChange={(next) => {
301
+ setOpenaiBaseUrl(next);
302
+ setEntry('stt.openaiBaseUrl', {
303
+ value: next,
304
+ original: original.openaiBaseUrl ?? '',
305
+ valid: true,
306
+ });
307
+ }}
308
+ />
309
+ <TextField
310
+ id="stt-openai-model"
311
+ label="Model"
312
+ value={openaiModel}
313
+ placeholder="whisper-1"
314
+ onChange={(next) => {
315
+ setOpenaiModel(next);
316
+ setEntry('stt.openaiModel', {
317
+ value: next,
318
+ original: original.openaiModel ?? '',
319
+ valid: true,
320
+ });
321
+ }}
322
+ />
327
323
  </SettingsSection>
328
324
  ) : null}
329
325
 
@@ -332,22 +328,20 @@ export default function SpeechKeys({ port, client, dirty, registerSave }: Settin
332
328
  title="Whisper (local MLX)"
333
329
  hint="Runs on-device via mlx-whisper. No API key required."
334
330
  >
335
- <EngineSubsection title="Model">
336
- <TextField
337
- id="stt-whisper-model"
338
- label="Model identifier"
339
- value={whisperModel}
340
- placeholder="mlx-community/whisper-large-v3-mlx"
341
- onChange={(next) => {
342
- setWhisperModel(next);
343
- setEntry('stt.whisperModel', {
344
- value: next,
345
- original: original.whisperModel ?? '',
346
- valid: true,
347
- });
348
- }}
349
- />
350
- </EngineSubsection>
331
+ <TextField
332
+ id="stt-whisper-model"
333
+ label="Model identifier"
334
+ value={whisperModel}
335
+ placeholder="mlx-community/whisper-large-v3-mlx"
336
+ onChange={(next) => {
337
+ setWhisperModel(next);
338
+ setEntry('stt.whisperModel', {
339
+ value: next,
340
+ original: original.whisperModel ?? '',
341
+ valid: true,
342
+ });
343
+ }}
344
+ />
351
345
  </SettingsSection>
352
346
  ) : null}
353
347
 
@@ -356,41 +350,40 @@ export default function SpeechKeys({ port, client, dirty, registerSave }: Settin
356
350
  title="Vertex AI"
357
351
  hint="Service-account credentials JSON for Google Cloud Vertex transcription."
358
352
  >
359
- <EngineSubsection
360
- title="Service account"
361
- hint="Paste the service-account credentials JSON. Treated as a secret — invalid JSON refuses to save."
362
- >
363
- <JsonEditorField
364
- id="stt-vertex-config"
365
- label="Credentials JSON"
366
- value={vertexConfig}
367
- onChange={(next, valid) => {
368
- // JsonEditorField stores either parsed JSON
369
- // (valid) or the draft string (invalid). We
370
- // need a string for the dirty entry so the
371
- // server receives the raw JSON it expects.
372
- const asString =
373
- typeof next === 'string'
374
- ? next
375
- : next === null || next === undefined
376
- ? ''
377
- : JSON.stringify(next);
378
- setVertexConfig(asString);
379
- const validity = validateVertexConfig(asString);
380
- setVertexError(valid ? null : validity.error);
381
- setEntry('stt.vertexConfig', {
382
- value: asString,
383
- original: original.vertexConfig ?? '',
384
- valid: valid && validity.valid,
385
- });
386
- }}
387
- />
388
- {vertexError ? (
389
- <p className="settings-field-error" role="alert">
390
- {vertexError}
391
- </p>
392
- ) : null}
393
- </EngineSubsection>
353
+ <SettingsNote>
354
+ Paste the service-account credentials JSON. Treated as a
355
+ secret — invalid JSON refuses to save.
356
+ </SettingsNote>
357
+ <JsonEditorField
358
+ id="stt-vertex-config"
359
+ label="Credentials JSON"
360
+ value={vertexConfig}
361
+ onChange={(next, valid) => {
362
+ // JsonEditorField stores either parsed JSON
363
+ // (valid) or the draft string (invalid). We
364
+ // need a string for the dirty entry so the
365
+ // server receives the raw JSON it expects.
366
+ const asString =
367
+ typeof next === 'string'
368
+ ? next
369
+ : next === null || next === undefined
370
+ ? ''
371
+ : JSON.stringify(next);
372
+ setVertexConfig(asString);
373
+ const validity = validateVertexConfig(asString);
374
+ setVertexError(valid ? null : validity.error);
375
+ setEntry('stt.vertexConfig', {
376
+ value: asString,
377
+ original: original.vertexConfig ?? '',
378
+ valid: valid && validity.valid,
379
+ });
380
+ }}
381
+ />
382
+ {vertexError ? (
383
+ <SettingsNote tone="error" role="alert">
384
+ {vertexError}
385
+ </SettingsNote>
386
+ ) : null}
394
387
  </SettingsSection>
395
388
  ) : null}
396
389
 
@@ -398,10 +391,10 @@ export default function SpeechKeys({ port, client, dirty, registerSave }: Settin
398
391
  title="Probe"
399
392
  hint="A live mic-test isn't available yet — verify by triggering speech-to-text from the active channel."
400
393
  >
401
- <p className="settings-section-hint">
394
+ <SettingsNote>
402
395
  No backend self-test endpoint is exposed for speech today;
403
396
  this lands as a Phase 9 polish.
404
- </p>
397
+ </SettingsNote>
405
398
  </SettingsSection>
406
399
  </form>
407
400
  );
@@ -7,7 +7,16 @@
7
7
  import { useCallback, useEffect, useState } from 'react';
8
8
  import type { SettingsPageProps } from '../types';
9
9
  import { ToggleField, SecretField, TextField } from '../fields';
10
- import { SettingsSection, PageError, PageLoading, usePageSnapshot } from './page-shell';
10
+ import {
11
+ SettingsSection,
12
+ PageError,
13
+ PageLoading,
14
+ usePageSnapshot,
15
+ SettingsKeyValue,
16
+ SettingsNote,
17
+ StatusBadge,
18
+ } from './page-shell';
19
+ import type { StatusTone } from './page-shell';
11
20
 
12
21
  // Local mirror of MANAGED_INSTANCE_PORT_FROM/TO (src/manager/constants.ts). The frontend
13
22
  // bundle must not import server modules; the backend validates the real range authoritatively.
@@ -119,8 +128,41 @@ export default function TelegramHub({ port, client, dirty, registerSave, manager
119
128
  if (loadError) return <PageError message={loadError} />;
120
129
  if (!config) return <PageLoading label="Loading Telegram hub…" />;
121
130
 
131
+ const runtimeTone: StatusTone =
132
+ runtime?.state === 'polling' ? 'ok'
133
+ : runtime?.state === 'starting' ? 'warn'
134
+ : runtime?.state === 'error' ? 'error'
135
+ : 'neutral';
136
+
122
137
  return (
123
138
  <form className="settings-page-form settings-form" onSubmit={(e) => { e.preventDefault(); void onSave(); }}>
139
+ <SettingsSection title="Status" hint="Live hub runtime reported by the manager.">
140
+ <SettingsKeyValue
141
+ items={[
142
+ {
143
+ label: 'Hub',
144
+ value: enabled ? (
145
+ <StatusBadge tone="ok">Enabled</StatusBadge>
146
+ ) : (
147
+ <StatusBadge tone="neutral">Disabled</StatusBadge>
148
+ ),
149
+ },
150
+ ...(runtime
151
+ ? [{
152
+ label: 'Runtime',
153
+ value: <StatusBadge tone={runtimeTone}>{runtime.state}</StatusBadge>,
154
+ }]
155
+ : []),
156
+ ...(runtime?.chatId
157
+ ? [{ label: 'Bound chat', value: runtime.chatId, mono: true }]
158
+ : []),
159
+ ]}
160
+ />
161
+ {runtime?.error ? (
162
+ <SettingsNote tone="error" role="alert">{runtime.error}</SettingsNote>
163
+ ) : null}
164
+ </SettingsSection>
165
+
124
166
  <SettingsSection title="Telegram hub" hint="One dashboard-owned bot routes Telegram chat topics to instances 3457–3506.">
125
167
  <ToggleField
126
168
  id="hub-enabled" label="Enable hub" value={enabled}
@@ -135,11 +177,6 @@ export default function TelegramHub({ port, client, dirty, registerSave, manager
135
177
  id="hub-chat-id" label="Hub chat ID" value={chatId} placeholder="823… or -100…"
136
178
  onChange={(next) => { setChatId(next); dirty.set('hub.chatId', { value: next, original: config.chatId, valid: true }); }}
137
179
  />
138
- {runtime ? (
139
- <p className="settings-help">
140
- Runtime: {runtime.state}{runtime.chatId ? ` · ${runtime.chatId}` : ''}{runtime.error ? ` · ${runtime.error}` : ''}
141
- </p>
142
- ) : null}
143
180
  <label className="settings-field" htmlFor="hub-default-port">
144
181
  <span className="settings-field-label">Default port</span>
145
182
  <input
@@ -155,21 +192,31 @@ export default function TelegramHub({ port, client, dirty, registerSave, manager
155
192
 
156
193
  <SettingsSection title="Topic routes" hint="(chatId, threadId) → instance port. Bind in a bot private topic or group topic with /setthread <port>.">
157
194
  {config.routes.length === 0 ? (
158
- <p className="settings-empty">No routes yet.</p>
195
+ <SettingsNote>No routes yet.</SettingsNote>
159
196
  ) : (
160
- <table className="settings-table">
161
- <thead><tr><th>Thread</th><th>Port</th><th>Label</th><th>Model</th><th>Prompt</th><th>On</th><th /></tr></thead>
162
- <tbody>
163
- {config.routes.map((r) => (
164
- <tr key={`${r.chatId}:${r.threadId}`}>
165
- <td>{r.threadId}</td><td>{r.port}</td><td>{r.label || '—'}</td>
166
- <td>{r.model || '—'}</td><td>{r.systemPrompt ? '✓' : '—'}</td>
167
- <td>{r.enabled ? '✓' : '—'}</td>
168
- <td><button type="button" onClick={() => void removeRoute(r)}>Delete</button></td>
169
- </tr>
170
- ))}
171
- </tbody>
172
- </table>
197
+ <div className="settings-card-scroll">
198
+ <table className="settings-overrides-table">
199
+ <thead><tr><th>Thread</th><th>Port</th><th>Label</th><th>Model</th><th>Prompt</th><th>On</th><th /></tr></thead>
200
+ <tbody>
201
+ {config.routes.map((r) => (
202
+ <tr key={`${r.chatId}:${r.threadId}`}>
203
+ <td>{r.threadId}</td><td>{r.port}</td><td>{r.label || '—'}</td>
204
+ <td>{r.model || '—'}</td><td>{r.systemPrompt ? '✓' : '—'}</td>
205
+ <td>{r.enabled ? '✓' : '—'}</td>
206
+ <td>
207
+ <button
208
+ type="button"
209
+ className="settings-action settings-action-danger"
210
+ onClick={() => void removeRoute(r)}
211
+ >
212
+ Delete
213
+ </button>
214
+ </td>
215
+ </tr>
216
+ ))}
217
+ </tbody>
218
+ </table>
219
+ </div>
173
220
  )}
174
221
  </SettingsSection>
175
222
  </form>
@@ -6,6 +6,7 @@
6
6
  // page-level dirty store: uploads are atomic side-effects, not pending edits.
7
7
 
8
8
  import { useEffect, useRef, useState } from 'react';
9
+ import { icon } from '../../../../../js/icons';
9
10
 
10
11
  type AvatarKind = 'agent' | 'user';
11
12
 
@@ -123,9 +124,11 @@ export function AvatarCard({ kind, port }: Props) {
123
124
  ) : kind === 'agent' ? (
124
125
  <img className="settings-avatar-mascot" src="/icons/mascot.png" alt="" aria-hidden="true" />
125
126
  ) : (
126
- <span className="settings-avatar-placeholder" aria-hidden="true">
127
- 👤
128
- </span>
127
+ <span
128
+ className="settings-avatar-placeholder"
129
+ aria-hidden="true"
130
+ dangerouslySetInnerHTML={{ __html: icon('user', 28) }}
131
+ />
129
132
  )}
130
133
  </div>
131
134
  <div className="settings-avatar-controls">
@@ -143,7 +146,7 @@ export function AvatarCard({ kind, port }: Props) {
143
146
  <div className="settings-avatar-buttons">
144
147
  <button
145
148
  type="button"
146
- className="settings-action settings-action-secondary"
149
+ className="settings-action"
147
150
  onClick={onPick}
148
151
  disabled={busy}
149
152
  >
@@ -152,7 +155,7 @@ export function AvatarCard({ kind, port }: Props) {
152
155
  {imageUrl ? (
153
156
  <button
154
157
  type="button"
155
- className="settings-action settings-action-discard"
158
+ className="settings-action settings-action-danger"
156
159
  onClick={() => void onClear()}
157
160
  disabled={busy}
158
161
  >
@@ -161,9 +164,7 @@ export function AvatarCard({ kind, port }: Props) {
161
164
  ) : null}
162
165
  </div>
163
166
  {error ? (
164
- <span className="settings-field-error" role="alert">
165
- {error}
166
- </span>
167
+ <p className="settings-field-error" role="alert">{error}</p>
167
168
  ) : null}
168
169
  </div>
169
170
  </div>
@@ -24,13 +24,13 @@ export function ChannelSetupEntry({ channel, client, dirty, open, onOpenChange,
24
24
  }, [client, dirty, key]);
25
25
  const pendingDraft = !open && dirty.isDirty();
26
26
  return <>
27
- <button ref={trigger} type="button" data-onboard-channel={channel}
27
+ <button ref={trigger} type="button" className="settings-action" data-onboard-channel={channel}
28
28
  disabled={disabled || open || pendingDraft} onClick={() => {
29
29
  if (disabled || dirty.isDirty()) return;
30
30
  dirty.set(key, { value: true, original: false, valid: false });
31
31
  onOpenChange(true);
32
32
  }}>{t('onboarding.open')}</button>
33
- {pendingDraft && <p className="settings-field-hint">Save or discard your changes before opening setup.</p>}
33
+ {pendingDraft && <span className="settings-field-hint">Save or discard your changes before opening setup.</span>}
34
34
  {open && <ChannelSetupDialog key={channel} channel={channel} client={client} t={t}
35
35
  initialDraft={{}} returnFocus={trigger.current}
36
36
  onBeforeSave={() => async () => {
@@ -5,6 +5,7 @@
5
5
 
6
6
  import { useId } from 'react';
7
7
  import { TextField, ToggleField, SelectField } from '../../fields';
8
+ import { SettingsSection, SettingsActions } from '../page-shell';
8
9
  import type { EmployeeRecord } from './employees-helpers';
9
10
  import { DEFAULT_CLI_OPTIONS } from './employees-helpers';
10
11
  import { metaFor } from './agent/agent-meta';
@@ -49,14 +50,7 @@ export function EmployeeRow({
49
50
  const renderedNameError = nameError ?? dupeError;
50
51
 
51
52
  return (
52
- <fieldset
53
- className="settings-employee-row"
54
- aria-label={`Employee ${index + 1}${employee.name ? ` (${employee.name})` : ''}`}
55
- >
56
- <legend className="settings-employee-legend">
57
- {employee.name || `Employee ${index + 1}`}
58
- </legend>
59
-
53
+ <SettingsSection title={employee.name || `Employee ${index + 1}`}>
60
54
  <ToggleField
61
55
  id={`${idBase}-active`}
62
56
  label="Active"
@@ -103,16 +97,16 @@ export function EmployeeRow({
103
97
  />
104
98
  </label>
105
99
 
106
- <div className="settings-employee-footer">
100
+ <SettingsActions>
107
101
  <button
108
102
  type="button"
109
- className="settings-action settings-action-discard"
103
+ className="settings-action settings-action-danger"
110
104
  onClick={onRemove}
111
105
  aria-label={`Remove employee ${employee.name || index + 1}`}
112
106
  >
113
107
  Remove
114
108
  </button>
115
- </div>
116
- </fieldset>
109
+ </SettingsActions>
110
+ </SettingsSection>
117
111
  );
118
112
  }
@@ -9,6 +9,8 @@
9
9
  import { useCallback, useEffect, useRef, useState } from 'react';
10
10
  import type { SettingsClient } from '../../types';
11
11
  import { SettingsRequestError } from '../../settings-client';
12
+ import { StatusBadge } from '../page-shell';
13
+ import type { StatusTone } from '../page-shell';
12
14
 
13
15
  export type HealthState =
14
16
  | { kind: 'idle' }
@@ -66,21 +68,24 @@ export function HealthBadge({ client, label, endpoint, method = 'GET', interpret
66
68
  };
67
69
  }, [auto, probe]);
68
70
 
71
+ const tone: StatusTone =
72
+ state.kind === 'ok' ? 'ok'
73
+ : state.kind === 'degraded' ? 'warn'
74
+ : state.kind === 'error' ? 'error'
75
+ : 'neutral';
69
76
  return (
70
- <div className="settings-health-badge" role="status" aria-live="polite">
77
+ <div className="settings-health-badge settings-card-toolbar" role="status" aria-live="polite">
71
78
  <button
72
79
  type="button"
73
- className="settings-action settings-action-discard"
80
+ className="settings-action"
74
81
  onClick={() => void probe()}
75
82
  disabled={state.kind === 'checking'}
76
83
  >
77
84
  {state.kind === 'checking' ? 'Checking…' : `Check ${label}`}
78
85
  </button>
79
- <span className={`settings-health-pill is-${state.kind}`}>
80
- {pillLabel(state)}
81
- </span>
86
+ <StatusBadge tone={tone}>{pillLabel(state)}</StatusBadge>
82
87
  {detailFor(state) ? (
83
- <span className="settings-health-detail">{detailFor(state)}</span>
88
+ <span className="settings-health-detail settings-field-hint">{detailFor(state)}</span>
84
89
  ) : null}
85
90
  </div>
86
91
  );