@songsid/agend 2.3.4-beta.7 → 2.3.5-alpha.3

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 (457) hide show
  1. package/README.md +2 -0
  2. package/README.zh-TW.md +2 -0
  3. package/THIRD_PARTY_NOTICES.md +53 -0
  4. package/dist/agent-endpoint.d.ts +5 -1
  5. package/dist/agent-endpoint.js +12 -2
  6. package/dist/agent-endpoint.js.map +1 -1
  7. package/dist/auth-api.d.ts +21 -0
  8. package/dist/auth-api.js +89 -2
  9. package/dist/auth-api.js.map +1 -1
  10. package/dist/authority/web-authority.d.ts +12 -2
  11. package/dist/authority/web-authority.js +25 -4
  12. package/dist/authority/web-authority.js.map +1 -1
  13. package/dist/backend/claude-code.d.ts +15 -12
  14. package/dist/backend/claude-code.js +152 -133
  15. package/dist/backend/claude-code.js.map +1 -1
  16. package/dist/backend/codex-package.d.ts +5 -2
  17. package/dist/backend/codex-package.js +1 -5
  18. package/dist/backend/codex-package.js.map +1 -1
  19. package/dist/backend/codex.d.ts +136 -113
  20. package/dist/backend/codex.js +1281 -1219
  21. package/dist/backend/codex.js.map +1 -1
  22. package/dist/backend/grok-model-cache.d.ts +7 -0
  23. package/dist/backend/grok-model-cache.js +65 -0
  24. package/dist/backend/grok-model-cache.js.map +1 -0
  25. package/dist/backend/grok.d.ts +2 -0
  26. package/dist/backend/grok.js +22 -0
  27. package/dist/backend/grok.js.map +1 -1
  28. package/dist/backend/native-pane.d.ts +9 -0
  29. package/dist/backend/native-pane.js +59 -0
  30. package/dist/backend/native-pane.js.map +1 -0
  31. package/dist/backend/types.d.ts +7 -0
  32. package/dist/backend/types.js.map +1 -1
  33. package/dist/channel/ipc-bridge.d.ts +2 -0
  34. package/dist/channel/mcp-tools.js +1 -1
  35. package/dist/channel/mcp-tools.js.map +1 -1
  36. package/dist/cli.js +3 -0
  37. package/dist/cli.js.map +1 -1
  38. package/dist/config-validator.js +71 -1
  39. package/dist/config-validator.js.map +1 -1
  40. package/dist/config.js +16 -0
  41. package/dist/config.js.map +1 -1
  42. package/dist/daemon.d.ts +67 -5
  43. package/dist/daemon.js +823 -266
  44. package/dist/daemon.js.map +1 -1
  45. package/dist/delivery-consumed-watch.d.ts +15 -3
  46. package/dist/delivery-consumed-watch.js +23 -1
  47. package/dist/delivery-consumed-watch.js.map +1 -1
  48. package/dist/delivery-outbox.d.ts +5 -0
  49. package/dist/delivery-outbox.js +32 -4
  50. package/dist/delivery-outbox.js.map +1 -1
  51. package/dist/delivery-reconciliation.d.ts +2 -35
  52. package/dist/delivery-reconciliation.js +2 -156
  53. package/dist/delivery-reconciliation.js.map +1 -1
  54. package/dist/fleet-context.d.ts +2 -2
  55. package/dist/fleet-level-config.d.ts +1 -1
  56. package/dist/fleet-level-config.js +2 -0
  57. package/dist/fleet-level-config.js.map +1 -1
  58. package/dist/fleet-manager.d.ts +238 -3
  59. package/dist/fleet-manager.js +1826 -104
  60. package/dist/fleet-manager.js.map +1 -1
  61. package/dist/fleet-windows-runtime.d.ts +92 -0
  62. package/dist/fleet-windows-runtime.js +380 -0
  63. package/dist/fleet-windows-runtime.js.map +1 -0
  64. package/dist/general-binding.d.ts +85 -0
  65. package/dist/general-binding.js +298 -0
  66. package/dist/general-binding.js.map +1 -0
  67. package/dist/general-host-owner.d.ts +8 -0
  68. package/dist/general-host-owner.js +26 -0
  69. package/dist/general-host-owner.js.map +1 -0
  70. package/dist/general-instance.d.ts +7 -0
  71. package/dist/general-instance.js +20 -3
  72. package/dist/general-instance.js.map +1 -1
  73. package/dist/general-role.d.ts +5 -0
  74. package/dist/general-role.js +26 -0
  75. package/dist/general-role.js.map +1 -0
  76. package/dist/instance-config-impact.js +4 -0
  77. package/dist/instance-config-impact.js.map +1 -1
  78. package/dist/instance-lifecycle.d.ts +21 -3
  79. package/dist/instance-lifecycle.js +378 -162
  80. package/dist/instance-lifecycle.js.map +1 -1
  81. package/dist/instructions.d.ts +2 -0
  82. package/dist/instructions.js +6 -0
  83. package/dist/instructions.js.map +1 -1
  84. package/dist/local-pane-endpoint.d.ts +46 -0
  85. package/dist/local-pane-endpoint.js +189 -0
  86. package/dist/local-pane-endpoint.js.map +1 -0
  87. package/dist/local-pane-launcher.d.ts +2 -0
  88. package/dist/local-pane-launcher.js +38 -0
  89. package/dist/local-pane-launcher.js.map +1 -0
  90. package/dist/local-pane-stage.ps1 +101 -0
  91. package/dist/locale.js +85 -0
  92. package/dist/locale.js.map +1 -1
  93. package/dist/model-catalog-defaults.d.ts +14 -0
  94. package/dist/model-catalog-defaults.js +20 -0
  95. package/dist/model-catalog-defaults.js.map +1 -0
  96. package/dist/native-agent-admission.d.ts +7 -0
  97. package/dist/native-agent-admission.js +26 -0
  98. package/dist/native-agent-admission.js.map +1 -0
  99. package/dist/native-daemon-client.d.ts +13 -0
  100. package/dist/native-daemon-client.js +28 -0
  101. package/dist/native-daemon-client.js.map +1 -0
  102. package/dist/native-instance-api.d.ts +14 -0
  103. package/dist/native-instance-api.js +205 -0
  104. package/dist/native-instance-api.js.map +1 -0
  105. package/dist/native-instance-input.d.ts +84 -0
  106. package/dist/native-instance-input.js +54 -0
  107. package/dist/native-instance-input.js.map +1 -0
  108. package/dist/native-instance-registry.d.ts +32 -0
  109. package/dist/native-instance-registry.js +105 -0
  110. package/dist/native-instance-registry.js.map +1 -0
  111. package/dist/native-mcp.d.ts +40 -0
  112. package/dist/native-mcp.js +278 -0
  113. package/dist/native-mcp.js.map +1 -0
  114. package/dist/native-model-catalog.d.ts +5 -0
  115. package/dist/native-model-catalog.js +76 -0
  116. package/dist/native-model-catalog.js.map +1 -0
  117. package/dist/native-pane-crash-budget.d.ts +20 -0
  118. package/dist/native-pane-crash-budget.js +60 -0
  119. package/dist/native-pane-crash-budget.js.map +1 -0
  120. package/dist/native-pane-create.d.ts +26 -0
  121. package/dist/native-pane-create.js +53 -0
  122. package/dist/native-pane-create.js.map +1 -0
  123. package/dist/native-pane-lifecycle.d.ts +65 -0
  124. package/dist/native-pane-lifecycle.js +230 -0
  125. package/dist/native-pane-lifecycle.js.map +1 -0
  126. package/dist/native-pane-manager.d.ts +59 -0
  127. package/dist/native-pane-manager.js +584 -0
  128. package/dist/native-pane-manager.js.map +1 -0
  129. package/dist/native-pane-output-log.d.ts +15 -0
  130. package/dist/native-pane-output-log.js +108 -0
  131. package/dist/native-pane-output-log.js.map +1 -0
  132. package/dist/native-pane-reconciliation.d.ts +4 -0
  133. package/dist/native-pane-reconciliation.js +40 -0
  134. package/dist/native-pane-reconciliation.js.map +1 -0
  135. package/dist/native-pane-recovery.d.ts +12 -0
  136. package/dist/native-pane-recovery.js +10 -0
  137. package/dist/native-pane-recovery.js.map +1 -0
  138. package/dist/native-pane-tools.d.ts +2 -0
  139. package/dist/native-pane-tools.js +14 -0
  140. package/dist/native-pane-tools.js.map +1 -0
  141. package/dist/needs-you-hub.d.ts +2 -0
  142. package/dist/needs-you-hub.js +2 -1
  143. package/dist/needs-you-hub.js.map +1 -1
  144. package/dist/needs-you.d.ts +19 -1
  145. package/dist/needs-you.js +12 -2
  146. package/dist/needs-you.js.map +1 -1
  147. package/dist/outbound-handlers.d.ts +16 -2
  148. package/dist/outbound-handlers.js +67 -3
  149. package/dist/outbound-handlers.js.map +1 -1
  150. package/dist/outbound-schemas.d.ts +38 -0
  151. package/dist/outbound-schemas.js +12 -0
  152. package/dist/outbound-schemas.js.map +1 -1
  153. package/dist/pane-port.d.ts +118 -0
  154. package/dist/pane-port.js +2 -0
  155. package/dist/pane-port.js.map +1 -0
  156. package/dist/public-web-gateway.js +9 -0
  157. package/dist/public-web-gateway.js.map +1 -1
  158. package/dist/public-web-link.d.ts +5 -0
  159. package/dist/public-web-link.js +4 -0
  160. package/dist/public-web-link.js.map +1 -1
  161. package/dist/quickstart-api.js +9 -5
  162. package/dist/quickstart-api.js.map +1 -1
  163. package/dist/quickstart.d.ts +1 -0
  164. package/dist/quickstart.js +4 -1
  165. package/dist/quickstart.js.map +1 -1
  166. package/dist/runtime-api.d.ts +8 -0
  167. package/dist/runtime-api.js +96 -0
  168. package/dist/runtime-api.js.map +1 -0
  169. package/dist/runtime-assets/@xterm/addon-serialize/LICENSE +21 -0
  170. package/dist/runtime-assets/@xterm/addon-serialize/lib/addon-serialize.js +2 -0
  171. package/dist/runtime-assets/@xterm/addon-serialize/lib/addon-serialize.mjs +19 -0
  172. package/dist/runtime-assets/@xterm/addon-serialize/package.json +29 -0
  173. package/dist/runtime-assets/@xterm/headless/LICENSE +21 -0
  174. package/dist/runtime-assets/@xterm/headless/lib-headless/xterm-headless.js +2 -0
  175. package/dist/runtime-assets/@xterm/headless/lib-headless/xterm-headless.mjs +46 -0
  176. package/dist/runtime-assets/@xterm/headless/package.json +29 -0
  177. package/dist/runtime-assets/node-pty/CONPTY-LICENSE +21 -0
  178. package/dist/runtime-assets/node-pty/CONPTY-NOTICE.md +503 -0
  179. package/dist/runtime-assets/node-pty/LICENSE +69 -0
  180. package/dist/runtime-assets/node-pty/lib/conpty_console_list_agent.js +16 -0
  181. package/dist/runtime-assets/node-pty/lib/eventEmitter2.js +47 -0
  182. package/dist/runtime-assets/node-pty/lib/index.js +52 -0
  183. package/dist/runtime-assets/node-pty/lib/interfaces.js +7 -0
  184. package/dist/runtime-assets/node-pty/lib/shared/conout.js +11 -0
  185. package/dist/runtime-assets/node-pty/lib/terminal.js +190 -0
  186. package/dist/runtime-assets/node-pty/lib/types.js +7 -0
  187. package/dist/runtime-assets/node-pty/lib/unixTerminal.js +346 -0
  188. package/dist/runtime-assets/node-pty/lib/utils.js +39 -0
  189. package/dist/runtime-assets/node-pty/lib/windowsConoutConnection.js +125 -0
  190. package/dist/runtime-assets/node-pty/lib/windowsPtyAgent.js +320 -0
  191. package/dist/runtime-assets/node-pty/lib/windowsTerminal.js +199 -0
  192. package/dist/runtime-assets/node-pty/lib/worker/conoutSocketWorker.js +22 -0
  193. package/dist/runtime-assets/node-pty/package.json +64 -0
  194. package/dist/runtime-assets/node-pty/prebuilds/win32-arm64/conpty/OpenConsole.exe +0 -0
  195. package/dist/runtime-assets/node-pty/prebuilds/win32-arm64/conpty/conpty.dll +0 -0
  196. package/dist/runtime-assets/node-pty/prebuilds/win32-arm64/conpty.node +0 -0
  197. package/dist/runtime-assets/node-pty/prebuilds/win32-arm64/conpty_console_list.node +0 -0
  198. package/dist/runtime-assets/node-pty/prebuilds/win32-x64/conpty/OpenConsole.exe +0 -0
  199. package/dist/runtime-assets/node-pty/prebuilds/win32-x64/conpty/conpty.dll +0 -0
  200. package/dist/runtime-assets/node-pty/prebuilds/win32-x64/conpty.node +0 -0
  201. package/dist/runtime-assets/node-pty/prebuilds/win32-x64/conpty_console_list.node +0 -0
  202. package/dist/runtime-bundle.d.ts +17 -0
  203. package/dist/runtime-bundle.js +150 -0
  204. package/dist/runtime-bundle.js.map +1 -0
  205. package/dist/runtime-cli.d.ts +2 -0
  206. package/dist/runtime-cli.js +117 -0
  207. package/dist/runtime-cli.js.map +1 -0
  208. package/dist/runtime-client-store.d.ts +49 -0
  209. package/dist/runtime-client-store.js +292 -0
  210. package/dist/runtime-client-store.js.map +1 -0
  211. package/dist/runtime-client.d.ts +100 -0
  212. package/dist/runtime-client.js +700 -0
  213. package/dist/runtime-client.js.map +1 -0
  214. package/dist/runtime-coordinator.d.ts +82 -0
  215. package/dist/runtime-coordinator.js +864 -0
  216. package/dist/runtime-coordinator.js.map +1 -0
  217. package/dist/runtime-general-protocol.d.ts +22 -0
  218. package/dist/runtime-general-protocol.js +57 -0
  219. package/dist/runtime-general-protocol.js.map +1 -0
  220. package/dist/runtime-general-workspace.d.ts +17 -0
  221. package/dist/runtime-general-workspace.js +213 -0
  222. package/dist/runtime-general-workspace.js.map +1 -0
  223. package/dist/runtime-pane-assets.d.ts +17 -0
  224. package/dist/runtime-pane-assets.js +23 -0
  225. package/dist/runtime-pane-assets.js.map +1 -0
  226. package/dist/runtime-pane-boot.d.ts +2 -0
  227. package/dist/runtime-pane-boot.js +24 -0
  228. package/dist/runtime-pane-boot.js.map +1 -0
  229. package/dist/runtime-pane-codex-index.d.ts +1 -0
  230. package/dist/runtime-pane-codex-index.js +47 -0
  231. package/dist/runtime-pane-codex-index.js.map +1 -0
  232. package/dist/runtime-pane-config.d.ts +16 -0
  233. package/dist/runtime-pane-config.js +54 -0
  234. package/dist/runtime-pane-config.js.map +1 -0
  235. package/dist/runtime-pane-host.d.ts +44 -0
  236. package/dist/runtime-pane-host.js +424 -0
  237. package/dist/runtime-pane-host.js.map +1 -0
  238. package/dist/runtime-pane-job-owner.d.ts +1 -0
  239. package/dist/runtime-pane-job-owner.js +29 -0
  240. package/dist/runtime-pane-job-owner.js.map +1 -0
  241. package/dist/runtime-pane-job.ps1 +116 -0
  242. package/dist/runtime-pane-link.d.ts +40 -0
  243. package/dist/runtime-pane-link.js +246 -0
  244. package/dist/runtime-pane-link.js.map +1 -0
  245. package/dist/runtime-pane-mcp-protocol.d.ts +32 -0
  246. package/dist/runtime-pane-mcp-protocol.js +39 -0
  247. package/dist/runtime-pane-mcp-protocol.js.map +1 -0
  248. package/dist/runtime-pane-mcp-relay.d.ts +17 -0
  249. package/dist/runtime-pane-mcp-relay.js +70 -0
  250. package/dist/runtime-pane-mcp-relay.js.map +1 -0
  251. package/dist/runtime-pane-mcp.d.ts +51 -0
  252. package/dist/runtime-pane-mcp.js +150 -0
  253. package/dist/runtime-pane-mcp.js.map +1 -0
  254. package/dist/runtime-pane-native.d.ts +45 -0
  255. package/dist/runtime-pane-native.js +65 -0
  256. package/dist/runtime-pane-native.js.map +1 -0
  257. package/dist/runtime-pane-output.d.ts +19 -0
  258. package/dist/runtime-pane-output.js +53 -0
  259. package/dist/runtime-pane-output.js.map +1 -0
  260. package/dist/runtime-pane-port.d.ts +139 -0
  261. package/dist/runtime-pane-port.js +558 -0
  262. package/dist/runtime-pane-port.js.map +1 -0
  263. package/dist/runtime-pane-private.d.ts +14 -0
  264. package/dist/runtime-pane-private.js +51 -0
  265. package/dist/runtime-pane-private.js.map +1 -0
  266. package/dist/runtime-pane-private.ps1 +14 -0
  267. package/dist/runtime-pane-process.d.ts +4 -0
  268. package/dist/runtime-pane-process.js +108 -0
  269. package/dist/runtime-pane-process.js.map +1 -0
  270. package/dist/runtime-pane-protocol.d.ts +172 -0
  271. package/dist/runtime-pane-protocol.js +195 -0
  272. package/dist/runtime-pane-protocol.js.map +1 -0
  273. package/dist/runtime-pane-screen.d.ts +19 -0
  274. package/dist/runtime-pane-screen.js +76 -0
  275. package/dist/runtime-pane-screen.js.map +1 -0
  276. package/dist/runtime-pane-service.d.ts +11 -0
  277. package/dist/runtime-pane-service.js +221 -0
  278. package/dist/runtime-pane-service.js.map +1 -0
  279. package/dist/runtime-pane-stdio-protocol.d.ts +54 -0
  280. package/dist/runtime-pane-stdio-protocol.js +94 -0
  281. package/dist/runtime-pane-stdio-protocol.js.map +1 -0
  282. package/dist/runtime-pane-stdio.d.ts +3 -0
  283. package/dist/runtime-pane-stdio.js +123 -0
  284. package/dist/runtime-pane-stdio.js.map +1 -0
  285. package/dist/runtime-pane-store.d.ts +33 -0
  286. package/dist/runtime-pane-store.js +164 -0
  287. package/dist/runtime-pane-store.js.map +1 -0
  288. package/dist/runtime-pane-transcript-protocol.d.ts +43 -0
  289. package/dist/runtime-pane-transcript-protocol.js +58 -0
  290. package/dist/runtime-pane-transcript-protocol.js.map +1 -0
  291. package/dist/runtime-pane-transcript.d.ts +45 -0
  292. package/dist/runtime-pane-transcript.js +605 -0
  293. package/dist/runtime-pane-transcript.js.map +1 -0
  294. package/dist/runtime-pane-worker.d.ts +1 -0
  295. package/dist/runtime-pane-worker.js +154 -0
  296. package/dist/runtime-pane-worker.js.map +1 -0
  297. package/dist/runtime-protocol.d.ts +149 -0
  298. package/dist/runtime-protocol.js +19 -0
  299. package/dist/runtime-protocol.js.map +1 -0
  300. package/dist/runtime-switches.d.ts +79 -0
  301. package/dist/runtime-switches.js +90 -0
  302. package/dist/runtime-switches.js.map +1 -0
  303. package/dist/runtime-transcript-delta-reader.d.ts +23 -0
  304. package/dist/runtime-transcript-delta-reader.js +74 -0
  305. package/dist/runtime-transcript-delta-reader.js.map +1 -0
  306. package/dist/runtime-transcript-source.d.ts +36 -0
  307. package/dist/runtime-transcript-source.js +189 -0
  308. package/dist/runtime-transcript-source.js.map +1 -0
  309. package/dist/runtime-windows-bridge.d.ts +41 -0
  310. package/dist/runtime-windows-bridge.js +157 -0
  311. package/dist/runtime-windows-bridge.js.map +1 -0
  312. package/dist/settings-api.d.ts +5 -0
  313. package/dist/settings-api.js +95 -1
  314. package/dist/settings-api.js.map +1 -1
  315. package/dist/settings-baseline.d.ts +1 -0
  316. package/dist/settings-baseline.js +1 -1
  317. package/dist/settings-baseline.js.map +1 -1
  318. package/dist/settings-change.js +28 -0
  319. package/dist/settings-change.js.map +1 -1
  320. package/dist/settings-confirmation.d.ts +16 -1
  321. package/dist/settings-confirmation.js +47 -9
  322. package/dist/settings-confirmation.js.map +1 -1
  323. package/dist/settings-effect.d.ts +4 -0
  324. package/dist/settings-effect.js +58 -1
  325. package/dist/settings-effect.js.map +1 -1
  326. package/dist/settings-http-confirmation.d.ts +1 -0
  327. package/dist/settings-http-confirmation.js +15 -2
  328. package/dist/settings-http-confirmation.js.map +1 -1
  329. package/dist/settings-request-capability.d.ts +2 -0
  330. package/dist/settings-request-capability.js +4 -0
  331. package/dist/settings-request-capability.js.map +1 -1
  332. package/dist/settings-route-lifetime.d.ts +14 -0
  333. package/dist/settings-route-lifetime.js +48 -0
  334. package/dist/settings-route-lifetime.js.map +1 -0
  335. package/dist/settings-transaction.d.ts +4 -0
  336. package/dist/settings-transaction.js +9 -0
  337. package/dist/settings-transaction.js.map +1 -1
  338. package/dist/setup-form.js +6 -3
  339. package/dist/setup-form.js.map +1 -1
  340. package/dist/setup-i18n.js +3 -0
  341. package/dist/setup-i18n.js.map +1 -1
  342. package/dist/tmux-control.d.ts +2 -1
  343. package/dist/tmux-control.js.map +1 -1
  344. package/dist/tmux-manager.d.ts +2 -1
  345. package/dist/tmux-manager.js.map +1 -1
  346. package/dist/tmux-pane-host.d.ts +26 -0
  347. package/dist/tmux-pane-host.js +25 -0
  348. package/dist/tmux-pane-host.js.map +1 -0
  349. package/dist/tool-permissions.js +2 -1
  350. package/dist/tool-permissions.js.map +1 -1
  351. package/dist/topic-commands.js +3 -0
  352. package/dist/topic-commands.js.map +1 -1
  353. package/dist/transcript-delta-reader.d.ts +1 -1
  354. package/dist/transcript-delta-reader.js +1 -1
  355. package/dist/transcript-delta-reader.js.map +1 -1
  356. package/dist/transcript-monitor.d.ts +3 -0
  357. package/dist/transcript-monitor.js +22 -46
  358. package/dist/transcript-monitor.js.map +1 -1
  359. package/dist/transcript-needles.d.ts +35 -0
  360. package/dist/transcript-needles.js +158 -0
  361. package/dist/transcript-needles.js.map +1 -0
  362. package/dist/transcript-records.d.ts +21 -0
  363. package/dist/transcript-records.js +140 -0
  364. package/dist/transcript-records.js.map +1 -0
  365. package/dist/transcript-sources.d.ts +5 -0
  366. package/dist/transcript-sources.js +8 -79
  367. package/dist/transcript-sources.js.map +1 -1
  368. package/dist/types.d.ts +23 -0
  369. package/dist/ui/agent-proposals.js +90 -0
  370. package/dist/ui/agent-runtime.js +106 -0
  371. package/dist/ui/chat-store.js +13 -2
  372. package/dist/ui/chat-strings.js +48 -0
  373. package/dist/ui/cli-picker.js +42 -0
  374. package/dist/ui/general-location.js +71 -0
  375. package/dist/ui/native-instance-settings.js +47 -0
  376. package/dist/ui/native-pane-recovery.js +45 -0
  377. package/dist/ui/panel-chat.js +63 -32
  378. package/dist/ui/panel-details.js +2 -1
  379. package/dist/ui/panel-fleet.js +99 -18
  380. package/dist/ui/panel-needs.js +154 -3
  381. package/dist/ui/panel-runtimes.js +231 -0
  382. package/dist/ui/panel-settings.js +19 -9
  383. package/dist/ui/panel-windows-agent.js +86 -0
  384. package/dist/ui/panel-windows-cli.js +143 -0
  385. package/dist/ui/provider-marks.js +83 -0
  386. package/dist/ui/runtime-catalog.js +55 -0
  387. package/dist/ui/settings-catalog.js +37 -10
  388. package/dist/ui/settings-confirm.js +3 -1
  389. package/dist/ui/settings-dialogs.js +22 -7
  390. package/dist/ui/settings-model.js +2 -1
  391. package/dist/ui/settings-outside.js +176 -0
  392. package/dist/ui/settings-registry.js +6 -0
  393. package/dist/ui/settings-strings.js +16 -0
  394. package/dist/ui/shared/app-i18n.js +2 -2
  395. package/dist/ui/shared/app-route.js +6 -2
  396. package/dist/ui/shared/app-shell.js +3 -2
  397. package/dist/ui/shared/app-store.js +1 -0
  398. package/dist/ui/shared/app-stream.js +3 -1
  399. package/dist/ui/shared/app.css +301 -0
  400. package/dist/ui/shared/app.js +4 -0
  401. package/dist/ui/shared/header-tools.js +6 -4
  402. package/dist/ui/shared/instance-nav.js +33 -7
  403. package/dist/ui/shared/instance-switch.js +4 -3
  404. package/dist/ui/shared/qrcode.module.js +2237 -0
  405. package/dist/ui/shared/signin.js +39 -5
  406. package/dist/ui/shared/ui-menu.js +28 -8
  407. package/dist/ui/shared/vendor/qrcode-generator.LICENSE +27 -0
  408. package/dist/ui/shared/vendor/vendor.json +19 -2
  409. package/dist/ui/shared/view-strings.js +8 -0
  410. package/dist/ui/windows-agents-nav.js +2 -0
  411. package/dist/ui/windows-cli-catalog.js +79 -0
  412. package/dist/web-api.d.ts +37 -0
  413. package/dist/web-api.js +248 -6
  414. package/dist/web-api.js.map +1 -1
  415. package/dist/web-chat-history.d.ts +19 -2
  416. package/dist/web-chat-history.js +72 -3
  417. package/dist/web-chat-history.js.map +1 -1
  418. package/dist/web-only-fleet.d.ts +20 -0
  419. package/dist/web-only-fleet.js +21 -0
  420. package/dist/web-only-fleet.js.map +1 -1
  421. package/dist/web-remote-access.d.ts +152 -0
  422. package/dist/web-remote-access.js +368 -0
  423. package/dist/web-remote-access.js.map +1 -0
  424. package/dist/web-session.d.ts +7 -0
  425. package/dist/web-session.js +2 -0
  426. package/dist/web-session.js.map +1 -1
  427. package/dist/web-shell-routes.d.ts +4 -1
  428. package/dist/web-shell-routes.js +7 -2
  429. package/dist/web-shell-routes.js.map +1 -1
  430. package/dist/windows-agents.d.ts +124 -0
  431. package/dist/windows-agents.js +487 -0
  432. package/dist/windows-agents.js.map +1 -0
  433. package/dist/windows-cli-api.d.ts +23 -0
  434. package/dist/windows-cli-api.js +158 -0
  435. package/dist/windows-cli-api.js.map +1 -0
  436. package/dist/windows-cli-providers.d.ts +115 -0
  437. package/dist/windows-cli-providers.js +429 -0
  438. package/dist/windows-cli-providers.js.map +1 -0
  439. package/dist/windows-cli-worker.d.ts +58 -0
  440. package/dist/windows-cli-worker.js +479 -0
  441. package/dist/windows-cli-worker.js.map +1 -0
  442. package/dist/windows-cli.d.ts +115 -0
  443. package/dist/windows-cli.js +402 -0
  444. package/dist/windows-cli.js.map +1 -0
  445. package/dist/windows-native-mcp.d.ts +19 -0
  446. package/dist/windows-native-mcp.js +143 -0
  447. package/dist/windows-native-mcp.js.map +1 -0
  448. package/dist/windows-pane-mcp.d.ts +26 -0
  449. package/dist/windows-pane-mcp.js +187 -0
  450. package/dist/windows-pane-mcp.js.map +1 -0
  451. package/package.json +9 -3
  452. package/templates/runtime-assets/conpty-LICENSE +21 -0
  453. package/templates/runtime-assets/conpty-NOTICE.md +503 -0
  454. package/templates/runtime-assets/local-pane-stage.ps1 +101 -0
  455. package/templates/runtime-assets/runtime-pane-job.ps1 +116 -0
  456. package/templates/runtime-assets/runtime-pane-private.ps1 +14 -0
  457. package/templates/runtime-assets/xterm-LICENSE +21 -0
@@ -285,6 +285,14 @@ html:has(.shell), html:has(.shell) body { overflow: hidden; }
285
285
  .panel-title { flex: 1; min-width: 0; display: flex; align-items: center; gap: var(--s-3); min-height: calc(var(--header-h) - 2 * var(--s-1)); }
286
286
  .panel-title h1 { font-size: var(--fs-lg); line-height: var(--lh-lg); font-weight: var(--fw-semibold); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; outline: none; }
287
287
  .panel-sub { color: var(--text-2); font-size: var(--fs-sm); white-space: nowrap; }
288
+ /* S-30: on a phone the chat's state and chips (Windows, computer, model…) left the agent's name two letters. There the
289
+ header keeps the name (at least ~10 characters) and the state ("idle", "閒置"); the chips are on the sidebar row and
290
+ in Details. */
291
+ @media (max-width: 479px) {
292
+ .p-chat .panel-title h1 { flex: 0 1 auto; min-width: min(10ch, 45%); }
293
+ .p-chat .panel-sub { flex: 0 0 auto; }
294
+ .p-chat .panel-sub > :not(.status) { display: none; }
295
+ }
288
296
  .status { display: inline-flex; align-items: center; gap: 6px; }
289
297
  /* #2015: the largest processes, after the host memory chip's text. */
290
298
  .host-mem-top { margin-left: var(--s-2); opacity: 0.8; overflow-wrap: anywhere; }
@@ -425,6 +433,9 @@ html:has(.shell), html:has(.shell) body { overflow: hidden; }
425
433
  /* #2072: a model field — the list, and the text box "Other…" opens under it. */
426
434
  .model-pick { display: flex; flex-direction: column; gap: var(--s-1); min-width: 0; }
427
435
  .model-pick > select, .model-pick > input { width: 100%; }
436
+ .model-catalog-status { display: flex; gap: var(--s-2); align-items: center; justify-content: space-between; }
437
+ .model-catalog-status > .note { line-height: 1.5; }
438
+ .model-catalog-status > button { flex-shrink: 0; }
428
439
  .note { font-size: var(--fs-xs); color: var(--text-3); }
429
440
  .checks { display: flex; flex-direction: column; gap: var(--s-1); max-height: 180px; overflow-y: auto; }
430
441
  .check { display: flex; gap: var(--s-2); align-items: center; font-size: var(--fs-sm); }
@@ -936,6 +947,8 @@ img.amb-p { object-fit: contain; }
936
947
  .failed-send { padding: var(--s-2) var(--s-3); border-radius: var(--r-md); font-size: var(--fs-xs); background: var(--danger-bg); border: 1px solid var(--danger-line); display: flex; gap: var(--s-2); align-items: center; flex-wrap: wrap; }
937
948
  .failed-send .txt { flex: 1; min-width: 120px; white-space: pre-wrap; overflow-wrap: anywhere; max-height: 4.5em; overflow: hidden; }
938
949
  .composer-box { background: var(--surface); border-radius: var(--r-xl); box-shadow: var(--shadow-1); }
950
+ /* S-30: a state note above the composer ("Connection revoked…", "still working") sat flush on the box's edge. */
951
+ .composer-box > .note { margin: 0; padding: var(--s-2) var(--s-3) 0; }
939
952
  .composer-box:focus-within { box-shadow: 0 0 0 1px var(--border-strong), var(--shadow-1); }
940
953
  .composer { display: flex; align-items: flex-end; gap: var(--s-1); padding: var(--s-2); }
941
954
  .composer textarea {
@@ -2673,3 +2686,291 @@ html.oo-immersive .p-fleet > .panel-body { z-index: 50; }
2673
2686
  .os-none { margin: 0; }
2674
2687
  .os-form .os-err { grid-column: 1 / -1; margin: 0; padding: var(--s-2) var(--s-3); border: 1px solid var(--danger); border-radius: var(--r-sm); }
2675
2688
  @media (max-width: 480px) { .os-form { grid-template-columns: 1fr; } }
2689
+ /* Windows CLI preview: local providers, a task composer and a compact execution history. */
2690
+ .p-windows-cli .windows-cli-content { width: 100%; max-width: 1160px; margin: 0 auto; padding: 28px 28px 48px; }
2691
+ .p-windows-cli .windows-cli-intro { display: flex; align-items: center; justify-content: space-between; gap: 20px; margin-bottom: 24px; }
2692
+ .p-windows-cli .windows-cli-eyebrow { display: inline-flex; align-items: center; gap: 6px; color: var(--text-2); font-size: 11px; font-weight: 600; letter-spacing: .06em; }
2693
+ .p-windows-cli .windows-cli-intro h2 { margin-top: 7px; font-size: 26px; font-weight: 600; line-height: 1.3; letter-spacing: -.04em; }
2694
+ .p-windows-cli .windows-cli-intro p { margin-top: 7px; font-size: 13px; color: var(--text-2); line-height: 1.7; }
2695
+ .p-windows-cli .windows-cli-probe { flex-shrink: 0; min-height: 38px; border-radius: 9px; }
2696
+ .p-windows-cli .windows-cli-cards { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; margin-bottom: 24px; }
2697
+ .p-windows-cli .windows-cli-provider { min-width: 0; padding: 20px 20px 0; border: 1px solid var(--border); border-radius: 14px; background: var(--bg); }
2698
+ .p-windows-cli .windows-cli-provider-head { display: flex; align-items: center; gap: 12px; }
2699
+ .p-windows-cli .windows-cli-brand { width: 48px; height: 48px; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; border-radius: 12px; }
2700
+ .p-windows-cli .brand-openai { color: #fff; background: #141413; }
2701
+ .p-windows-cli .brand-anthropic { color: #141413; background: #f0e9df; }
2702
+ .p-windows-cli .windows-cli-provider-name { flex: 1; min-width: 0; }
2703
+ .p-windows-cli .windows-cli-provider-name > span { font-size: 11px; color: var(--text-2); }
2704
+ .p-windows-cli .windows-cli-provider-name h3 { font-size: 18px; line-height: 1.4; font-weight: 600; letter-spacing: -.025em; }
2705
+ .p-windows-cli .windows-cli-badge { display: inline-flex; align-items: center; flex-shrink: 0; padding: 3px 8px; border-radius: 6px; font-size: 11px; font-weight: 600; }
2706
+ .p-windows-cli .tone-ready { color: var(--ok); }
2707
+ .p-windows-cli .tone-neutral { color: var(--text-2); }
2708
+ .p-windows-cli .tone-failed { color: var(--danger); }
2709
+ .p-windows-cli .tone-working { color: var(--accent); }
2710
+ .p-windows-cli .windows-cli-badge.tone-ready { background: var(--ok-bg); }
2711
+ .p-windows-cli .windows-cli-badge.tone-neutral { background: var(--surface); }
2712
+ .p-windows-cli .windows-cli-provider-status { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 6px 14px; margin: 17px 0 14px; font-size: 12px; }
2713
+ .p-windows-cli .windows-cli-auth, .p-windows-cli .windows-cli-readiness, .p-windows-cli .windows-cli-task-state { display: inline-flex; align-items: center; gap: 7px; }
2714
+ .p-windows-cli .windows-cli-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex-shrink: 0; }
2715
+ .p-windows-cli .windows-cli-version { color: var(--text-3); font-family: var(--font-mono); font-size: 11px; overflow-wrap: anywhere; }
2716
+ .p-windows-cli .windows-cli-location { border-top: 1px solid var(--border); }
2717
+ .p-windows-cli summary { cursor: pointer; list-style: none; }
2718
+ .p-windows-cli summary::-webkit-details-marker { display: none; }
2719
+ .p-windows-cli .windows-cli-location summary { display: flex; justify-content: space-between; align-items: center; min-height: 37px; color: var(--text-2); font-size: 11px; }
2720
+ .p-windows-cli details[open] > summary > .icon:last-child { transform: rotate(180deg); }
2721
+ .p-windows-cli .windows-cli-path { display: block; white-space: pre-wrap; overflow-wrap: anywhere; font: 11px/1.7 var(--font-mono); color: var(--text-2); }
2722
+ .p-windows-cli .windows-cli-location .windows-cli-path { padding: 0 0 12px; }
2723
+ .p-windows-cli .windows-cli-workbench { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); align-items: start; gap: 20px; }
2724
+ .p-windows-cli .windows-cli-card { min-width: 0; border: 1px solid var(--border); border-radius: 14px; background: var(--bg); }
2725
+ .p-windows-cli .windows-cli-composer { padding: 22px; }
2726
+ .p-windows-cli .windows-cli-section-head { display: flex; align-items: center; gap: 10px; margin-bottom: 22px; }
2727
+ .p-windows-cli .windows-cli-section-icon { display: flex; align-items: center; justify-content: center; flex-shrink: 0; width: 34px; height: 34px; border-radius: 9px; background: var(--surface); color: var(--text-2); }
2728
+ .p-windows-cli .windows-cli-section-head > div { flex: 1; min-width: 0; }
2729
+ .p-windows-cli .windows-cli-section-head h2 { display: flex; align-items: center; gap: 7px; font-size: 15px; line-height: 1.4; font-weight: 600; letter-spacing: -.02em; }
2730
+ .p-windows-cli .windows-cli-section-head p { margin-top: 4px; color: var(--text-2); font-size: 11px; line-height: 1.6; }
2731
+ .p-windows-cli .windows-cli-field { margin-bottom: 18px; }
2732
+ .p-windows-cli .windows-cli-field > label, .p-windows-cli .windows-cli-access > legend { display: block; margin-bottom: 8px; font-size: 12px; font-weight: 600; }
2733
+ .p-windows-cli .windows-cli-field > input, .p-windows-cli .windows-cli-field > textarea { display: block; width: 100%; max-width: 100%; padding: 10px 12px; border: 1px solid var(--border-strong); border-radius: 8px; background: var(--bg); color: var(--text); font-size: var(--fs-sm); line-height: 1.6; }
2734
+ .p-windows-cli .windows-cli-field > input:focus, .p-windows-cli .windows-cli-field > textarea:focus { border-color: var(--focus); outline: none; box-shadow: 0 0 0 3px var(--accent-dim); }
2735
+ .p-windows-cli .windows-cli-field > textarea { min-height: 120px; resize: vertical; }
2736
+ .p-windows-cli .windows-cli-field .windows-cli-directory { font-family: var(--font-mono); font-size: var(--fs-xs); }
2737
+ .p-windows-cli .windows-cli-field > p { margin-top: 6px; font-size: 11px; line-height: 1.6; color: var(--text-3); }
2738
+ .p-windows-cli .windows-cli-field ::placeholder { color: var(--text-3); }
2739
+ .p-windows-cli .windows-cli-access-options { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
2740
+ .p-windows-cli .windows-cli-access-option { display: flex; align-items: flex-start; gap: 8px; padding: 11px 10px; border: 1px solid var(--border); border-radius: 9px; cursor: pointer; }
2741
+ .p-windows-cli .windows-cli-access-option.selected { background: var(--accent-dim); border-color: var(--focus); }
2742
+ .p-windows-cli .windows-cli-access-option input { margin: 3px 0 0; accent-color: var(--accent); width: 13px; height: 13px; flex-shrink: 0; }
2743
+ .p-windows-cli .windows-cli-access-option strong { display: flex; align-items: center; gap: 5px; font-size: 12px; line-height: 1.6; font-weight: 600; }
2744
+ .p-windows-cli .windows-cli-access-option small { display: block; margin-top: 3px; font-size: 10px; line-height: 1.6; color: var(--text-2); }
2745
+ .p-windows-cli .windows-cli-policy { margin-top: 14px; color: var(--text-2); font-size: 11px; }
2746
+ .p-windows-cli .windows-cli-policy summary { display: flex; align-items: center; gap: 6px; min-height: 28px; }
2747
+ .p-windows-cli .windows-cli-policy p { padding: 4px 0 10px; line-height: 1.8; }
2748
+ .p-windows-cli .windows-cli-submit { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 12px; padding-top: 16px; margin-top: 10px; border-top: 1px solid var(--border); }
2749
+ .p-windows-cli .windows-cli-readiness { font-size: 11px; line-height: 1.6; }
2750
+ .p-windows-cli .windows-cli-submit .btn { min-height: 40px; border-radius: 8px; }
2751
+ .p-windows-cli .windows-cli-limits { display: flex; align-items: center; gap: 5px; margin-top: 10px; color: var(--text-3); font-size: 10px; line-height: 1.6; }
2752
+ .p-windows-cli .windows-cli-history { padding: 22px 20px 0; }
2753
+ .p-windows-cli .windows-cli-history .windows-cli-section-head { margin-bottom: 18px; }
2754
+ .p-windows-cli .windows-cli-history .icon-btn { width: 30px; height: 30px; }
2755
+ .p-windows-cli .windows-cli-count { color: var(--text-2); background: var(--surface); padding: 1px 6px; border-radius: 5px; font-size: 10px; font-weight: 500; }
2756
+ .p-windows-cli .windows-cli-task { margin-top: 10px; border: 1px solid var(--border); border-radius: 9px; overflow: hidden; }
2757
+ .p-windows-cli .windows-cli-task > summary { display: flex; align-items: center; gap: 10px; padding: 12px; font-size: 12px; }
2758
+ .p-windows-cli .windows-cli-task > summary:hover { background: var(--surface); }
2759
+ .p-windows-cli .windows-cli-task-state { flex: 1; font-weight: 600; }
2760
+ .p-windows-cli .windows-cli-task time { font-size: 10px; color: var(--text-3); font-variant-numeric: tabular-nums; }
2761
+ .p-windows-cli .windows-cli-task-cwd { padding: 0 12px 12px; font-size: 10px; }
2762
+ .p-windows-cli .windows-cli-task-detail { padding: 0 12px 12px; }
2763
+ .p-windows-cli .windows-cli-output-label { display: flex; align-items: center; gap: 5px; padding: 9px 10px; border-radius: 6px 6px 0 0; background: var(--code-head); color: var(--text-2); font-size: 10px; }
2764
+ .p-windows-cli .windows-cli-output { padding: 12px; margin: 0; max-height: 320px; overflow: auto; border-radius: 0 0 6px 6px; background: var(--code-bg); white-space: pre-wrap; overflow-wrap: anywhere; font: 11px/1.8 var(--font-mono); }
2765
+ .p-windows-cli .windows-cli-task-detail > .btn { margin-top: 10px; }
2766
+ .p-windows-cli .windows-cli-history-note { margin-top: 18px; padding: 12px 0; border-top: 1px solid var(--border); color: var(--text-3); text-align: center; font-size: 10px; }
2767
+ .p-windows-cli .windows-cli-empty { display: flex; flex-direction: column; align-items: center; padding: 42px 16px; text-align: center; }
2768
+ .p-windows-cli .windows-cli-empty > span { display: grid; place-items: center; width: 58px; height: 58px; border-radius: 16px; background: var(--surface); color: var(--text-3); margin-bottom: 16px; }
2769
+ .p-windows-cli .windows-cli-empty h3 { font-size: 13px; font-weight: 600; }
2770
+ .p-windows-cli .windows-cli-empty p { max-width: 220px; margin-top: 7px; font-size: 12px; line-height: 1.8; color: var(--text-3); }
2771
+ .p-windows-cli .error { white-space: pre-wrap; overflow-wrap: anywhere; color: var(--danger); font-size: 12px; }
2772
+ .p-windows-cli .windows-cli-error { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 20px; padding: 14px; border-radius: 10px; background: var(--danger-bg); }
2773
+ .p-windows-cli .windows-cli-error .icon { margin-top: 2px; }
2774
+ .p-windows-cli .windows-cli-spin { animation: windows-cli-rotate 1.4s linear infinite; }
2775
+ @keyframes windows-cli-rotate { to { transform: rotate(360deg); } }
2776
+ @media (max-width: 1130px) { .p-windows-cli .windows-cli-workbench { grid-template-columns: minmax(0, 1fr); } }
2777
+ @media (max-width: 620px) {
2778
+ .p-windows-cli .windows-cli-content { padding: 20px 16px 32px; }
2779
+ .p-windows-cli .windows-cli-intro { flex-direction: column; align-items: flex-start; gap: 14px; margin-bottom: 20px; }
2780
+ .p-windows-cli .windows-cli-intro h2 { font-size: 23px; }
2781
+ .p-windows-cli .windows-cli-cards { grid-template-columns: minmax(0, 1fr); gap: 12px; margin-bottom: 20px; }
2782
+ .p-windows-cli .windows-cli-provider { padding: 16px 16px 0; }
2783
+ .p-windows-cli .windows-cli-composer, .p-windows-cli .windows-cli-history { padding: 18px 16px; }
2784
+ .p-windows-cli .windows-cli-history { padding-bottom: 0; }
2785
+ .p-windows-cli .windows-cli-field > input, .p-windows-cli .windows-cli-field > textarea { font-size: 16px; }
2786
+ .p-windows-cli .windows-cli-submit { flex-direction: column; align-items: stretch; }
2787
+ .p-windows-cli .windows-cli-access-option { padding: 10px 8px; }
2788
+ .p-windows-cli .windows-cli-access-option strong { font-size: 11px; }
2789
+ }
2790
+ @media (prefers-reduced-motion: reduce) { .p-windows-cli .windows-cli-spin { animation: none; } }
2791
+ .p-windows-cli.windows-cli-settings .windows-cli-content { padding: 0; }
2792
+ .p-settings .col:has(> .windows-cli-settings) { max-width: 1160px; }
2793
+ .p-settings .windows-cli-settings .windows-cli-workbench { grid-template-columns: minmax(0, 1fr); }
2794
+ @media (min-width: 1500px) { .p-settings .windows-cli-settings .windows-cli-workbench { grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); } }
2795
+ /* Runtime-first agent creation and native Windows conversations. */
2796
+ .agent-runtime-picker > legend, .agent-runtime-fields > legend { font-size: 13px; font-weight: 600; margin-bottom: 12px; }
2797
+ .agent-runtime-picker > div { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: 10px; }
2798
+ .agent-runtime-choice { display: flex; align-items: center; gap: 9px; padding: 14px 11px; border: 1px solid var(--border); border-radius: 10px; cursor: pointer; }
2799
+ .agent-runtime-choice.selected { border-color: var(--focus); background: var(--accent-dim); }
2800
+ .agent-runtime-choice > input { width: 13px; height: 13px; margin: 0; accent-color: var(--accent); flex-shrink: 0; }
2801
+ .agent-runtime-choice > span { min-width: 0; }
2802
+ .agent-runtime-choice strong { display: block; font-size: 12px; line-height: 1.6; }
2803
+ .agent-runtime-choice small { display: block; margin-top: 3px; color: var(--text-2); font-size: 10px; line-height: 1.6; }
2804
+ .agent-runtime-fields { border-top: 1px solid var(--border); padding-top: 14px; }
2805
+ .agent-draft-assistant { padding: 12px; border: 1px solid var(--border); border-radius: 9px; background: var(--surface); }
2806
+ .agent-draft-assistant > summary { display: flex; align-items: center; gap: 7px; font-size: 12px; font-weight: 600; cursor: pointer; }
2807
+ .agent-draft-assistant > .note { margin: 10px 0; font-size: 11px; }
2808
+ .agent-draft-assistant .btn { margin-top: 10px; }
2809
+ .agent-draft-assistant textarea { resize: vertical; }
2810
+ .windows-agent-nav { flex-shrink: 0; padding: 8px; border-top: 1px solid var(--border); max-height: 25vh; overflow: auto; }
2811
+ .windows-agent-nav h3 { padding: 0 12px 5px; color: var(--text-3); font-size: 11px; font-weight: 500; }
2812
+ .windows-agent-nav svg { flex-shrink: 0; }
2813
+ .p-windows-agent .windows-agent-conversation { max-width: 960px; }
2814
+ .windows-agent-identity { display: flex; align-items: center; gap: 12px; padding: 16px 0; border-bottom: 1px solid var(--border); margin-bottom: 16px; }
2815
+ .windows-agent-identity > span:first-child { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 10px; color: white; background: #141413; flex-shrink: 0; }
2816
+ .windows-agent-identity > div { flex: 1; min-width: 0; }
2817
+ .windows-agent-identity strong { font-size: 13px; }
2818
+ .windows-agent-identity code { display: block; overflow-wrap: anywhere; color: var(--text-2); font: 11px/1.7 var(--font-mono); }
2819
+ .windows-agent-empty { display: flex; flex-direction: column; align-items: center; text-align: center; padding: 60px 12px; color: var(--text-2); }
2820
+ .windows-agent-empty h2 { margin: 18px 0 8px; color: var(--text); font-size: 20px; }
2821
+ .windows-agent-empty p { max-width: 400px; font-size: 13px; line-height: 1.8; }
2822
+ .windows-agent-turn { margin-bottom: 26px; }
2823
+ .windows-agent-human { padding: 14px 18px; margin-left: 15%; border-radius: 12px; background: var(--surface); }
2824
+ .windows-agent-human strong { font-size: 12px; }
2825
+ .windows-agent-human p { white-space: pre-wrap; overflow-wrap: anywhere; margin-top: 6px; }
2826
+ .windows-agent-reply { padding: 20px 0 0; }
2827
+ .windows-agent-reply > strong { display: flex; gap: 8px; align-items: center; font-size: 13px; }
2828
+ .windows-agent-reply pre { margin: 14px 0 7px; white-space: pre-wrap; overflow-wrap: anywhere; font: 13px/1.8 var(--font-mono); }
2829
+ .windows-agent-reply small { color: var(--text-3); font-size: 11px; }
2830
+ .windows-agent-composer { padding: 12px 24px 18px; border-top: 1px solid var(--border); }
2831
+ .windows-agent-composer > div, .windows-agent-composer > p { max-width: 900px; margin-left: auto; margin-right: auto; }
2832
+ .windows-agent-input { padding: 12px; background: var(--surface); border: 1px solid var(--border); border-radius: 12px; }
2833
+ .windows-agent-input > textarea { display: block; width: 100%; border: 0; resize: vertical; padding: 4px; background: transparent; color: var(--text); font-family: var(--font-ui); font-size: var(--fs-md); min-height: 60px; max-height: 180px; }
2834
+ .runtime-settings { max-width: 1080px; }
2835
+ .runtime-heading, .runtime-heading > div:last-child, .runtime-machine > header, .runtime-machine-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
2836
+ .runtime-heading { justify-content: space-between; margin-bottom: 20px; }
2837
+ .runtime-heading h2, .runtime-machine h3 { margin: 0; }
2838
+ .runtime-local, .runtime-machine, .runtime-pairing { padding: 18px; margin: 16px 0; border: 1px solid var(--border); border-radius: 12px; background: var(--surface); }
2839
+ .runtime-local h3 { display: flex; align-items: center; gap: 8px; }
2840
+ /* M-2255: Settings → Runtime's switches. */
2841
+ .runtime-switches { padding: 18px; margin: 16px 0; border: 1px solid var(--border); border-radius: 12px; background: var(--surface); }
2842
+ .runtime-switches > h3 { margin: 0 0 6px; }
2843
+ .runtime-switch { padding: 12px 0; border-bottom: 1px solid var(--border); }
2844
+ .runtime-switch-row { display: flex; align-items: flex-start; gap: 12px; cursor: pointer; }
2845
+ .runtime-switch-row input { flex: none; width: 20px; height: 20px; margin: 2px 0 0; accent-color: var(--accent); }
2846
+ .runtime-switch-row input:disabled { cursor: not-allowed; }
2847
+ .runtime-switch-row > span { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
2848
+ .runtime-switch-row small { color: var(--text-3); font-size: var(--fs-sm); line-height: 1.5; overflow-wrap: anywhere; }
2849
+ .runtime-switch-env, .runtime-switch-pending { display: block; margin: 8px 0 0 32px; font-size: var(--fs-sm); }
2850
+ .runtime-switch-env { color: var(--warn); }
2851
+ .runtime-switches > .note { margin: 12px 0 0; font-size: var(--fs-sm); color: var(--text-3); }
2852
+ .runtime-guide { margin: 10px 0 0 32px; font-size: var(--fs-sm); }
2853
+ .runtime-guide > summary { cursor: pointer; font-weight: 600; padding: 4px 0; }
2854
+ .runtime-guide p { margin: 8px 0; line-height: 1.5; }
2855
+ /* A command wraps only between its words (never inside an address), so all of it is in view, on a phone too. */
2856
+ .runtime-guide pre { margin: 6px 0 10px; padding: 8px 10px; border-radius: 8px; background: var(--bg); overflow-x: auto; white-space: pre-wrap; overflow-wrap: normal; word-break: normal; max-width: 100%; }
2857
+ .runtime-guide-link { display: inline-flex; align-items: center; gap: 4px; color: var(--accent); text-decoration: underline; text-underline-offset: 2px; }
2858
+ .runtime-guide-warn { color: var(--warn); }
2859
+ .runtime-limit { display: flex; flex-direction: column; gap: 8px; padding: 12px 0; border-bottom: 1px solid var(--border); }
2860
+ .runtime-limit label { display: flex; flex-direction: column; gap: 4px; }
2861
+ .runtime-limit small { color: var(--text-3); font-size: var(--fs-sm); line-height: 1.5; }
2862
+ .runtime-limit > div { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
2863
+ .runtime-limit input { width: 6em; font-size: var(--fs-md); }
2864
+ @media (max-width: 600px) { .runtime-guide, .runtime-switch-env, .runtime-switch-pending { margin-left: 0; } }
2865
+ .runtime-machine > header > div { flex: 1; min-width: 140px; }
2866
+ .runtime-machine > header p, .runtime-machine .note { margin: 7px 0; font-size: var(--fs-sm); color: var(--text-3); }
2867
+ .runtime-machine-icon { display: grid; place-items: center; width: 42px; height: 42px; border-radius: 10px; background: var(--bg); }
2868
+ .runtime-status { padding: 4px 10px; border: 1px solid var(--border); border-radius: 20px; font-size: var(--fs-sm); }
2869
+ .runtime-status.is-online { color: var(--ok); }
2870
+ .runtime-status.is-pending { color: var(--warn); }
2871
+ .runtime-status.is-offline, .runtime-status.is-revoked { color: var(--text-3); }
2872
+ .runtime-machine-id { display: block; margin: 8px 0; overflow-wrap: anywhere; }
2873
+ .runtime-cli-list { padding: 0; margin: 14px 0; list-style: none; }
2874
+ .runtime-cli-list li { display: flex; align-items: center; gap: 10px; padding: 10px 0; border-bottom: 1px solid var(--border); }
2875
+ .runtime-cli-list li > span:nth-child(2) { flex: 1; }
2876
+ .runtime-cli-list small { display: block; color: var(--text-3); font-size: var(--fs-sm); }
2877
+ .runtime-machine-actions { margin-top: 14px; }
2878
+ /* S-30: the ZIP step is a button with its hint beside it (wrapping under it on a phone), not text flush against it. */
2879
+ .runtime-bundle-step { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin: 12px 0; }
2880
+ .runtime-bundle-step .note { margin: 0; flex: 1 1 220px; }
2881
+ .runtime-pairing label, .runtime-rename label { display: flex; flex-direction: column; gap: 7px; margin: 12px 0; }
2882
+ .runtime-pairing input, .runtime-rename input { width: 100%; min-width: 0; font-family: var(--font-ui); font-size: var(--fs-md); }
2883
+ .runtime-pair-code { letter-spacing: .14em; }
2884
+ .runtime-error { border: 1px solid var(--danger); padding: 12px; border-radius: 10px; overflow-wrap: anywhere; }
2885
+ .runtime-local-diagnostics { margin-top: 22px; }
2886
+ .runtime-local-diagnostics > summary { cursor: pointer; font-weight: 600; padding: 12px 0; }
2887
+ .runtime-remote-targets { display: grid; gap: 8px; margin-top: 16px; }
2888
+ .runtime-remote-targets h4 { margin: 0 0 4px; font-size: var(--fs-md); }
2889
+ .runtime-remote-targets .agent-runtime-choice { min-width: 0; width: 100%; }
2890
+ .runtime-manage-link { display: inline-block; margin-top: 12px; }
2891
+ .inst-machine { display: flex; gap: 5px; overflow: hidden; white-space: nowrap; font-size: var(--fs-xs); color: var(--text-3); }
2892
+ /* S-30: the machine name gives way; "Connection revoked" / "Offline" always stays readable. */
2893
+ .inst-machine-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
2894
+ .inst-machine-status { flex: none; }
2895
+ .inst-machine.offline, .runtime-machine-offline { color: var(--warn); }
2896
+ .runtime-machine-tag { max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
2897
+ @media (max-width: 600px) {
2898
+ .runtime-heading > div:last-child { width: 100%; }
2899
+ .runtime-machine, .runtime-pairing, .runtime-local { padding: 14px; }
2900
+ .runtime-cli-list li { flex-wrap: wrap; }
2901
+ .runtime-cli-list li > .note { width: 100%; }
2902
+ }
2903
+ .windows-agent-input > div { display: flex; justify-content: flex-end; gap: 8px; align-items: center; }
2904
+ .windows-agent-composer > .note { margin-top: 8px; font-size: 10px; }
2905
+ .p-windows-agent .error, .agent-draft-assistant .error { color: var(--danger); font-size: 12px; overflow-wrap: anywhere; }
2906
+ .windows-agent-blocked { padding: 16px; background: var(--warn-bg); border-radius: 10px; }
2907
+ .windows-agent-blocked p { margin-bottom: 12px; }
2908
+ @media (max-width: 620px) {
2909
+ .agent-runtime-choice { flex-wrap: wrap; padding: 12px; }
2910
+ .agent-runtime-choice > span { flex-basis: 100%; }
2911
+ .windows-agent-composer { padding: 10px 12px; }
2912
+ .windows-agent-identity { flex-wrap: wrap; }
2913
+ }
2914
+ /* Agent creation wizard: one active stage per screen, with persistent navigation actions. */
2915
+ .agent-create-wizard { display: flex; flex-direction: column; gap: 24px; }
2916
+ /* S-30: the body's top padding scrolled content through above the sticky steps (a phone showed card edges there); a
2917
+ background-coloured copy of the bar, shifted up, covers that strip. */
2918
+ .agent-create-steps { position: sticky; top: 0; z-index: 2; background: var(--bg); box-shadow: 0 calc(-1 * var(--s-5)) 0 var(--bg); display: flex; align-items: center; gap: 8px; padding-bottom: 20px; margin: 0; list-style: none; border-bottom: 1px solid var(--border); }
2919
+ .agent-create-steps > li { display: flex; align-items: center; gap: 7px; color: var(--text-3); font-size: 12px; min-width: 0; }
2920
+ .agent-create-steps > li:not(:last-child)::after { content: ""; width: 28px; height: 1px; background: var(--border); margin: 0 6px; }
2921
+ .agent-create-steps > li.current { color: var(--text); font-weight: 600; }
2922
+ .agent-create-step-number { display: grid; place-items: center; width: 22px; height: 22px; flex-shrink: 0; border: 1px solid var(--border-strong); border-radius: 50%; font-size: 11px; }
2923
+ .agent-create-steps .current .agent-create-step-number { color: var(--on-accent); background: var(--accent-fill); border-color: var(--accent-fill); }
2924
+ .agent-create-steps .complete .agent-create-step-number { color: var(--ok); border-color: var(--ok); background: var(--ok-bg); }
2925
+ .agent-create-stage { display: flex; flex-direction: column; gap: 18px; min-width: 0; }
2926
+ .agent-create-stage > h3 { margin: 0; font-size: 21px; font-weight: 600; line-height: 1.4; letter-spacing: -.025em; }
2927
+ .agent-create-stage > h3:focus { outline: none; }
2928
+ .agent-create-stage > .note { margin-top: -12px; font-size: 12px; line-height: 1.8; }
2929
+ .agent-create-cli { padding: 16px; background: var(--surface); border: 1px solid var(--border); border-radius: 10px; }
2930
+ .agent-create-cli .field { margin: 0; }
2931
+ .agent-create-selection { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); }
2932
+ .agent-create-selection > div { flex: 1; min-width: 0; }
2933
+ .agent-create-selection strong { display: block; font-size: 12px; }
2934
+ .agent-create-selection span { display: block; color: var(--text-2); font-size: 11px; overflow-wrap: anywhere; }
2935
+ .agent-create-wizard .agent-runtime-fields { padding-top: 0; border-top: 0; }
2936
+ .agent-create-success { align-items: center; text-align: center; padding: 18px 0 8px; }
2937
+ .agent-create-success-icon { display: grid; place-items: center; width: 64px; height: 64px; color: var(--ok); background: var(--ok-bg); border-radius: 50%; }
2938
+ .agent-create-success dl { display: grid; grid-template-columns: max-content minmax(0,1fr); gap: 12px 20px; width: 100%; margin: 0; padding: 18px; border: 1px solid var(--border); border-radius: 10px; text-align: left; font-size: 13px; }
2939
+ .agent-create-success dt { color: var(--text-2); }
2940
+ .agent-create-success dd { margin: 0; overflow-wrap: anywhere; }
2941
+ .agent-create-success code { font-family: var(--font-mono); font-size: 12px; }
2942
+ @media (max-width: 620px) {
2943
+ .agent-create-steps { gap: 6px; }
2944
+ .agent-create-steps > li { gap: 5px; font-size: 11px; }
2945
+ .agent-create-steps > li:not(:last-child)::after { width: 12px; margin: 0 2px; }
2946
+ .agent-create-selection { gap: 8px; padding: 10px; }
2947
+ .agent-create-selection .btn { padding: 0 8px; }
2948
+ .agent-create-stage > h3 { font-size: 20px; }
2949
+ }
2950
+ .cli-picker { width: 100%; min-width: 0; }
2951
+ .cli-picker-trigger { display: flex; align-items: center; gap: 10px; width: 100%; min-height: 40px; padding: 8px 12px; border: 1px solid var(--border-strong); border-radius: var(--r-sm); background: var(--surface); color: var(--text); font: inherit; text-align: left; cursor: pointer; }
2952
+ .cli-picker-trigger:hover:not(:disabled) { border-color: var(--accent); }
2953
+ .cli-picker-trigger:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
2954
+ .cli-picker-trigger:disabled { opacity: .5; cursor: not-allowed; }
2955
+ .cli-product-mark { display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; line-height: 0; }
2956
+ .cli-product-mark svg, .cli-product-mark img { display: block; flex-shrink: 0; }
2957
+ .cli-picker-value { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
2958
+ .cli-picker-chevron { display: inline-flex; color: var(--text-3); }
2959
+ .cli-picker .menu-list { left: 0; right: 0; min-width: 0; max-height: 280px; overflow-y: auto; }
2960
+ .cli-picker .menu-list.menu-up { top: auto; bottom: calc(100% + 6px); }
2961
+ .cli-picker .menu-list.menu-compact { max-height: 180px; }
2962
+ .cli-picker .menu-list.menu-short { max-height: 96px; }
2963
+ .cli-picker .menu-item { padding-top: 8px; padding-bottom: 8px; }
2964
+ .cli-picker .menu-radio > span:last-child { flex: 1; min-width: 0; }
2965
+ .cli-picker-option { display: flex; align-items: center; gap: 10px; min-width: 0; }
2966
+ .cli-picker-copy { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
2967
+ .cli-picker-description { color: var(--text-2); font-size: var(--fs-xs); line-height: 1.4; }
2968
+ .cli-discovery-heading { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 32px; }
2969
+ .cli-discovery-status { display: flex; align-items: flex-start; gap: 12px; padding: 14px; border: 1px solid var(--border); border-radius: var(--r-sm); background: var(--surface); }
2970
+ .cli-discovery-status > .out-spin { flex: 0 0 16px; width: 16px; height: 16px; margin-top: 3px; color: var(--accent); }
2971
+ .cli-discovery-status > div { min-width: 0; }
2972
+ .cli-discovery-status strong { display: block; font-size: var(--fs-sm); line-height: 1.5; }
2973
+ .cli-discovery-status p, .cli-discovery-status small { display: block; color: var(--text-2); font-size: var(--fs-xs); line-height: 1.6; margin: 4px 0 0; overflow-wrap: anywhere; }
2974
+ .cli-discovery-status .btn { margin-top: 10px; }
2975
+ .cli-discovery-status.is-error { border-color: var(--border-strong); }
2976
+ .cli-discovery-status.is-error > svg { flex: 0 0 auto; margin-top: 2px; }
@@ -85,6 +85,8 @@ if (mode === "full") {
85
85
  let chatLoads = 0;
86
86
  panels.set("chat", { load: () => (chatLoads++ === 0 ? chatBoot : loadChat()).then((m) => m.ChatPanel) });
87
87
  if (!guest) {
88
+ const loadWindowsAgent = retryable((a) => import(retryUrl("/ui/js/panel-windows-agent.js", a)));
89
+ panels.set("windows-agent", { load: () => loadWindowsAgent().then((m) => m.WindowsAgentPanel) });
88
90
  panels.set("fleet", { load: () => loadFleet().then((m) => m.FleetPanel) });
89
91
  panels.set("settings", { load: () => loadSettings().then((m) => m.SettingsPanel) });
90
92
  // #2347: the restart banner's Restart now, in any panel — the Settings runner (behind the session) does it.
@@ -120,6 +122,8 @@ if (mode === "full") {
120
122
  startNeedsNotifier({ open: (instance) => navigate(chatPath(instance)) });
121
123
  // #2233: a backend sign-in running anywhere is shown on every admin page (the module lives behind the session gate).
122
124
  import("/ui/js/backend-signin.js").then((m) => m.installSignIn(), () => {});
125
+ // alpha.2 (M-2300): an agent's Windows request waiting for a web-only fleet's owner — counted in Needs you everywhere.
126
+ import("/ui/js/agent-proposals.js").then((m) => m.installProposals(), () => {});
123
127
  }
124
128
  // #1665: this device's first upload of its own choices (once), then another device's changes at each status frame.
125
129
  // A guest's page (#2855) uploads and saves only its own keys (prefsWritable(key)); another device's changes reach it at
@@ -7,7 +7,7 @@
7
7
  // Fleet read (#1300: no style attribute). View's terminal multiplies its fitted size by VIEW_SCALE, as its density did.
8
8
  import { html, useEffect, useState } from "./app-html.js";
9
9
  import { t } from "./app-i18n.js";
10
- import { createStore, useStore } from "./app-store.js";
10
+ import { appStore, createStore, useStore } from "./app-store.js";
11
11
  import { Icon } from "./ui-icons.js";
12
12
  import { UsageBody, UsageCompactToggle, UsageDialog } from "./usage-dialog.js";
13
13
 
@@ -124,7 +124,9 @@ export function useRailWidth() {
124
124
  export function UsageRail({ route }) {
125
125
  const wide = useRailWidth();
126
126
  const { open } = useStore(usageRailStore);
127
- if (!wide || !open || !route || !RAIL_PANELS.includes(route.panel) || !usageOffered()) return null;
127
+ const { instances = [] } = useStore(appStore);
128
+ const instance = instances.find(item => item.name === route?.instance);
129
+ if (!wide || !open || !route || !RAIL_PANELS.includes(route.panel) || !usageOffered() || instance?.capabilities?.usage === false) return null;
128
130
  return html`<aside data-trust="usage" class="u-rail" aria-label=${t("view.usage.title_plain")}>
129
131
  <div class="u-rail-head"><h2>${t("view.usage.title")}</h2><${UsageCompactToggle} />
130
132
  <button type="button" class="icon-btn" onClick=${() => setUsageRail(false)} aria-label=${t("app.usageHide")} title=${t("app.usageHide")}><${Icon} name="close" size=${16} /></button></div>
@@ -154,8 +156,8 @@ export function UsageButton({ navKey }) {
154
156
  }
155
157
 
156
158
  /** The shared controls, in the one order every page uses. `navKey`: the page's navigation (the usage dialog's owner). */
157
- export function HeaderTools({ view = false, navKey }) {
158
- return html`<${TextSizeButton} view=${view} /><${UsageButton} navKey=${navKey} />`;
159
+ export function HeaderTools({ view = false, navKey, usage = true }) {
160
+ return html`<${TextSizeButton} view=${view} />${usage ? html`<${UsageButton} navKey=${navKey} />` : null}`;
159
161
  }
160
162
  /** Where a page with no control of its own after the shared ones (Log) keeps the room Chat's ⋯ takes: the same box on every tab. */
161
163
  export function HeaderSlot() {
@@ -79,6 +79,14 @@ export function modelText(it, raw = it && it.model) {
79
79
  }
80
80
  const BACKEND_LABELS = { "claude-code": "Claude Code", "kiro-cli": "Kiro CLI", codex: "Codex", grok: "Grok Build", antigravity: "Antigravity", opencode: "OpenCode" };
81
81
  export function backendLabel(backend) { return BACKEND_LABELS[backend] || backend || "Unknown"; }
82
+ export function runtimeLabel(runtime) { return runtime === "windows" ? "Windows" : runtime === "wsl" ? "WSL / Linux" : runtime || ""; }
83
+ /** Missing capabilities preserve the existing Linux UI; native runtimes expose only implemented controls. */
84
+ export function supportsInstanceFeature(instance, feature) {
85
+ const key = feature === "view" ? "terminal" : feature;
86
+ if (typeof instance?.capabilities?.[key] === "boolean") return instance.capabilities[key];
87
+ if (feature === "log" && typeof instance?.capabilities?.terminal === "boolean") return instance.capabilities.terminal;
88
+ return instance?.runtime !== "windows" || !["terminal","view","log","details","attachments","commands","effort","send_while_busy"].includes(feature);
89
+ }
82
90
  export const KNOWN_BACKENDS = new Set(Object.keys(BACKEND_LABELS));
83
91
  export const STATUS_KEYS = { running: "statusRunning", paused: "statusPaused", stopped: "statusStopped", crashed: "statusCrashed" };
84
92
 
@@ -97,7 +105,7 @@ export function normalizeFilter(query) { return String(query == null ? "" : quer
97
105
  /** Case-insensitive substring on name (incl. display name), model and backend. */
98
106
  export function instanceMatchesFilter(it, needle, labelOf) {
99
107
  if (!needle) return true;
100
- const fields = [nameOf(it), it.display_name, it.model, it.backend, labelOf ? labelOf(it.backend) : null];
108
+ const fields = [nameOf(it), it.display_name, it.model, it.backend, it.machine_name, it.machine_id, runtimeLabel(it.runtime), labelOf ? labelOf(it.backend) : null];
101
109
  return fields.some((value) => typeof value === "string" && value.toLowerCase().includes(needle));
102
110
  }
103
111
  /**
@@ -136,6 +144,9 @@ export function instanceTooltip(it) {
136
144
  if (it.display_name && it.display_name !== name) lines.push(it.display_name, `(${name})`);
137
145
  else lines.push(name);
138
146
  lines.push(line("tooltipBackend", backendLabel(it.backend)));
147
+ if (it.runtime) lines.push(`Runtime: ${runtimeLabel(it.runtime)}`);
148
+ if (it.machine_id) lines.push(line("tooltipMachine",it.machine_name || it.machine_id));
149
+ if (it.machine_id && it.machine_status !== "online") lines.push(tn(it.machine_status === "revoked" ? "machineRevoked" : "machineOffline"));
139
150
  const src = (s) => (s === "instance" || s === "classic" ? tn("srcConfigured") : s === "fleet-default" ? tn("srcFleetDefault") : "");
140
151
  lines.push(line("tooltipModel", (modelText(it) || tn("tooltipUnavailable")) + src(it.model_source)));
141
152
  lines.push(line("tooltipStatus", status));
@@ -283,6 +294,8 @@ function writeFacetsOpen(open) { try { localStorage.setItem(FACETS_KEY, JSON.str
283
294
 
284
295
  /** The Favorites group's key among the tag groups: no tag can be it (a group name is never a control character). */
285
296
  const FAV_GROUP = "\u0000favorites";
297
+ /** #3008 G2: a web-only fleet's General (its status row says `general: true`), pinned first under its own head. */
298
+ const GENERAL_GROUP = "\u0000general";
286
299
  /** #1936: the open instance, pinned on top while a filter is on. */
287
300
  const PINNED_GROUP = "\u0000pinned";
288
301
  function persistOrder(groupNames, instByGroup) {
@@ -490,9 +503,11 @@ export function InstanceNav({ route, items, loaded = true, exec = {}, awaiting =
490
503
  const [editing, setEditing] = useState(false);
491
504
  // Where a row goes: the view the page is in (#1523 §3.1). View → View; Details → Details; everywhere else, a Fleet tab
492
505
  // included (#1917: the user's call, replacing Q4 = A), → Chat. The anonymous reader only ever has View.
493
- const rowPath = viewOnly || (route && route.panel === "view") ? viewPath
506
+ const panelPath = viewOnly || (route && route.panel === "view") ? viewPath
494
507
  : route && route.panel === "log" ? logPath // #1218: Log → Log
495
508
  : route && route.panel === "details" ? detailsPath : chatPath;
509
+ const rowPath = (name) => byName.get(name)?.runtime === "windows" && ["view", "log", "details"].includes(route?.panel)
510
+ ? chatPath(name) : panelPath(name);
496
511
  const active = route && (route.panel === "chat" || route.panel === "view" || route.panel === "log" || route.panel === "details") ? route.instance : null;
497
512
  const own = (map, name) => Object.prototype.hasOwnProperty.call(map, name);
498
513
  const byName = new Map(items.map((it) => [nameOf(it), it]));
@@ -502,7 +517,10 @@ export function InstanceNav({ route, items, loaded = true, exec = {}, awaiting =
502
517
  // their order. Changing them: a signed-in page that may write preferences (not the public link, not the anonymous
503
518
  // reader — they still see the list).
504
519
  const known = new Set(byName.keys());
505
- const favs = nav.favorites.filter((n) => known.has(n));
520
+ // #3008 G2: the General, when the server marks one (a web-only fleet), comes first — out of every other group.
521
+ const general = items.find((it) => it && it.general === true);
522
+ const generalName = general ? nameOf(general) : null;
523
+ const favs = nav.favorites.filter((n) => known.has(n) && n !== generalName);
506
524
  const favSet = new Set(favs);
507
525
  const canStar = !viewOnly && prefsWritable("nav.favorites");
508
526
  // #1920: a guest's list is not reordered (the order is the host's). #2855: it stars, sorts and filters as its own
@@ -520,14 +538,15 @@ export function InstanceNav({ route, items, loaded = true, exec = {}, awaiting =
520
538
  let shownGroups, shownInsts;
521
539
  if (recent) {
522
540
  const sortRecent = byRecentReply(ageOf);
523
- const rest = groupNames.flatMap((g) => instByGroup.get(g) || []).filter((n) => !favSet.has(n)).sort(sortRecent);
541
+ const rest = groupNames.flatMap((g) => instByGroup.get(g) || []).filter((n) => !favSet.has(n) && n !== generalName).sort(sortRecent);
524
542
  shownGroups = [...(favs.length ? [FAV_GROUP] : []), ...(rest.length ? [RECENT_GROUP] : [])];
525
543
  shownInsts = new Map([[FAV_GROUP, favsSorted ? [...favs].sort(sortRecent) : favs], [RECENT_GROUP, rest]]);
526
544
  } else {
527
545
  shownGroups = favs.length ? [FAV_GROUP, ...groupNames] : groupNames;
528
- shownInsts = new Map([...instByGroup].map(([g, names]) => [g, names.filter((n) => !favSet.has(n))]));
546
+ shownInsts = new Map([...instByGroup].map(([g, names]) => [g, names.filter((n) => !favSet.has(n) && n !== generalName)]));
529
547
  if (favs.length) shownInsts.set(FAV_GROUP, favs);
530
548
  }
549
+ if (generalName) { shownGroups = [GENERAL_GROUP, ...shownGroups]; shownInsts.set(GENERAL_GROUP, [generalName]); }
531
550
  const f = nav.filter;
532
551
  const shown = filterSidebar(shownGroups, shownInsts, byName, f.q, backendLabel, { status: f.status, cli: f.cli, statusOf: facetOf });
533
552
  // #1936: while a filter is on, the instance you have open stays on top, pinned and marked "Current", whether or not
@@ -589,7 +608,9 @@ export function InstanceNav({ route, items, loaded = true, exec = {}, awaiting =
589
608
  const row = (name, g, i, count) => {
590
609
  const it = byName.get(name);
591
610
  // #1722: both names, the preferred one first; one line when there is no other.
592
- const { primary: label, secondary } = namesOf(it, names.primary);
611
+ const preferred = namesOf(it, names.primary);
612
+ const label = it.runtime === "windows" ? it.display_name || preferred.primary : preferred.primary;
613
+ const secondary = it.runtime === "windows" ? backendLabel(it.backend) : preferred.secondary;
593
614
  const facet = facetOf(name);
594
615
  const waiting = own(awaiting, name) ? awaiting[name] : null;
595
616
  const on = name === active;
@@ -606,9 +627,10 @@ export function InstanceNav({ route, items, loaded = true, exec = {}, awaiting =
606
627
  aria-current=${on ? "page" : undefined} onClick=${onPick} ...${fav ? {} : dragProps({ type: "instance", name, group: g })}>
607
628
  <${InstanceAvatar} it=${it} state=${dotState(it, own(exec, name) ? exec[name] : null, waiting)} cli=${true} />
608
629
  <span class="inst-text"><span class="inst-line"><span class="inst-name" title=${label}>${label}</span>
609
- <span class="v-meta">${it.context_pct != null ? `${Math.round(it.context_pct)}%` : ""}</span></span>
630
+ <span class="v-meta">${it.runtime === "windows" ? "Windows" : it.context_pct != null ? `${Math.round(it.context_pct)}%` : ""}</span></span>
610
631
  ${two ? html`<span class="inst-line inst-line2"><span class="inst-alt" title=${secondary || undefined}>${secondary || ""}</span>
611
632
  ${mins != null ? html`<span class=${`inst-when${fade > 0 ? " fresh" : ""}`} title=${tn("replyTitle", { time: new Date(Date.parse(it.last_reply)).toLocaleString() })}>${replyText(mins)}</span>` : null}</span>` : null}
633
+ ${it.machine_id ? html`<span class=${`inst-machine${it.machine_status !== "online" ? " offline" : ""}`} title=${tn("tooltipMachine",{value:it.machine_name || it.machine_id})}><span class="inst-machine-name">${it.machine_name || it.machine_id}</span>${it.machine_status !== "online" ? html`<span class="inst-machine-status">${tn(it.machine_status === "revoked" ? "machineRevoked" : "machineOffline")}</span>` : null}</span>` : null}
612
634
  ${facet === "needs" ? html`<span class="inst-sub"><span class="badge-await" title=${waiting || t("app.approxNote")}>${t("app.needsYou")}</span></span>` : null}
613
635
  <span class="sr-only">${tn("tooltipBackend", { value: backendLabel(it.backend) })}</span></span>
614
636
  </a>${fav && editing && canStar ? html`<button type="button" class="icon-btn inst-move" aria-label=${tn("favUp", { name: label })}
@@ -639,6 +661,10 @@ export function InstanceNav({ route, items, loaded = true, exec = {}, awaiting =
639
661
  if (g === RECENT_GROUP) return html`<div key=${g} class="v-group v-recent" role="group" aria-label=${tn("recentOthers")}>
640
662
  <div class="v-group-head recent-head"><${Icon} name="clock" size=${14} /><span class="grow">${tn("recentOthers")}</span><span class="count">${names.length}</span></div>
641
663
  <ul class="inst-list">${names.map((name, i) => row(name, g, i, names.length))}</ul></div>`;
664
+ // #3008 G2: the General — always open, first, not dragged or starred into another place.
665
+ if (g === GENERAL_GROUP) return html`<div key=${g} class="v-group v-general" role="group" aria-label=${tn("generalGroup")}>
666
+ <div class="v-group-head general-head"><span class="grow">${tn("generalGroup")}</span></div>
667
+ <ul class="inst-list">${names.map((name, i) => row(name, g, i, names.length))}</ul></div>`;
642
668
  // #1664: Favorites — always open, not dragged (↑ ↓ in Edit), named in the page's language.
643
669
  if (g === FAV_GROUP) return html`<div key=${g} class="v-group v-fav" role="group" aria-label=${tn("favorites")}>
644
670
  <div class="v-group-head fav-head"><${Icon} name="star" size=${14} cls="fav-mark" /><span class="grow">${tn("favorites")}</span><span class="count">${names.length}</span></div>
@@ -7,19 +7,20 @@ import { html } from "./app-html.js";
7
7
  import { openSearch } from "./app-shell.js";
8
8
  import { t } from "./app-i18n.js";
9
9
  import { chatPath, detailsPath, logPath, viewPath } from "./app-route.js";
10
+ import { supportsInstanceFeature } from "./instance-nav.js";
10
11
 
11
12
  /**
12
13
  * current: "chat" | "view" | "log" | "details". #1218: Log sits between View and Details. `data-label`: each tab is as
13
14
  * wide as its label in the current tab's weight (app.css), so the bar keeps its size whichever tab is current.
14
15
  */
15
- export function InstanceSwitch({ name, current, guest = false }) {
16
+ export function InstanceSwitch({ name, current, guest = false, instance }) {
16
17
  const seg = (key, href, label) => html`<a key=${key} class=${`seg-item${current === key ? " active" : ""}`} href=${href}
17
18
  aria-current=${current === key ? "page" : undefined} data-label=${label}>${label}</a>`;
18
19
  if (guest) return html`<nav class="inst-switch seg" aria-label=${t("app.instanceViews", name)}>
19
- ${seg("chat", chatPath(name), t("app.chat"))}${seg("view", viewPath(name), t("app.view"))}<button key="search" type="button" class="seg-item"
20
+ ${seg("chat", chatPath(name), t("app.chat"))}${supportsInstanceFeature(instance,"view") ? seg("view", viewPath(name), t("app.view")) : null}<button key="search" type="button" class="seg-item"
20
21
  data-label=${t("app.search")} onClick=${() => openSearch({ instance: name })}>${t("app.search")}</button>
21
22
  </nav>`;
22
23
  return html`<nav class="inst-switch seg" aria-label=${t("app.instanceViews", name)}>
23
- ${seg("chat", chatPath(name), t("app.chat"))}${seg("view", viewPath(name), t("app.view"))}${seg("log", logPath(name), t("app.log"))}${seg("details", detailsPath(name), t("app.details"))}
24
+ ${seg("chat", chatPath(name), t("app.chat"))}${supportsInstanceFeature(instance,"view") ? seg("view", viewPath(name), t("app.view")) : null}${supportsInstanceFeature(instance,"log") ? seg("log", logPath(name), t("app.log")) : null}${supportsInstanceFeature(instance,"details") ? seg("details", detailsPath(name), t("app.details")) : null}
24
25
  </nav>`;
25
26
  }