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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (670) hide show
  1. package/README.md +0 -2
  2. package/README.zh-TW.md +0 -2
  3. package/THIRD_PARTY_NOTICES.md +12 -28
  4. package/dist/agent-cli-instructions.md +1 -1
  5. package/dist/agent-credentials.d.ts +24 -0
  6. package/dist/agent-credentials.js +66 -0
  7. package/dist/agent-credentials.js.map +1 -0
  8. package/dist/agent-endpoint.d.ts +4 -6
  9. package/dist/agent-endpoint.js +15 -12
  10. package/dist/agent-endpoint.js.map +1 -1
  11. package/dist/auth-api.d.ts +0 -21
  12. package/dist/auth-api.js +8 -93
  13. package/dist/auth-api.js.map +1 -1
  14. package/dist/authority/session-authorizations.d.ts +30 -4
  15. package/dist/authority/session-authorizations.js +69 -17
  16. package/dist/authority/session-authorizations.js.map +1 -1
  17. package/dist/authority/web-authority.d.ts +2 -12
  18. package/dist/authority/web-authority.js +4 -25
  19. package/dist/authority/web-authority.js.map +1 -1
  20. package/dist/backend/antigravity.js +3 -1
  21. package/dist/backend/antigravity.js.map +1 -1
  22. package/dist/backend/claude-code.d.ts +12 -15
  23. package/dist/backend/claude-code.js +133 -152
  24. package/dist/backend/claude-code.js.map +1 -1
  25. package/dist/backend/codex-metadata.d.ts +14 -0
  26. package/dist/backend/codex-metadata.js +45 -0
  27. package/dist/backend/codex-metadata.js.map +1 -1
  28. package/dist/backend/codex-package.d.ts +2 -5
  29. package/dist/backend/codex-package.js +5 -1
  30. package/dist/backend/codex-package.js.map +1 -1
  31. package/dist/backend/codex-quota-history.d.ts +7 -0
  32. package/dist/backend/codex-quota-history.js +72 -0
  33. package/dist/backend/codex-quota-history.js.map +1 -0
  34. package/dist/backend/codex-session-lookup.d.ts +6 -0
  35. package/dist/backend/codex-session-lookup.js +1 -1
  36. package/dist/backend/codex-session-lookup.js.map +1 -1
  37. package/dist/backend/codex-speed.d.ts +14 -0
  38. package/dist/backend/codex-speed.js +35 -0
  39. package/dist/backend/codex-speed.js.map +1 -0
  40. package/dist/backend/codex.d.ts +116 -136
  41. package/dist/backend/codex.js +912 -942
  42. package/dist/backend/codex.js.map +1 -1
  43. package/dist/backend/grok-weekly-reset.d.ts +24 -0
  44. package/dist/backend/grok-weekly-reset.js +95 -0
  45. package/dist/backend/grok-weekly-reset.js.map +1 -0
  46. package/dist/backend/grok.d.ts +30 -3
  47. package/dist/backend/grok.js +301 -76
  48. package/dist/backend/grok.js.map +1 -1
  49. package/dist/backend/kiro.d.ts +3 -0
  50. package/dist/backend/kiro.js +50 -2
  51. package/dist/backend/kiro.js.map +1 -1
  52. package/dist/backend/muse.js +5 -3
  53. package/dist/backend/muse.js.map +1 -1
  54. package/dist/backend/types.d.ts +15 -8
  55. package/dist/backend/types.js +3 -0
  56. package/dist/backend/types.js.map +1 -1
  57. package/dist/bundled-tmux-guard.d.ts +21 -0
  58. package/dist/bundled-tmux-guard.js +96 -0
  59. package/dist/bundled-tmux-guard.js.map +1 -0
  60. package/dist/cache-ledger.d.ts +95 -0
  61. package/dist/cache-ledger.js +276 -4
  62. package/dist/cache-ledger.js.map +1 -1
  63. package/dist/cache-service.d.ts +5 -0
  64. package/dist/cache-service.js +16 -4
  65. package/dist/cache-service.js.map +1 -1
  66. package/dist/channel/adapters/discord.js +11 -3
  67. package/dist/channel/adapters/discord.js.map +1 -1
  68. package/dist/channel/adapters/telegram.d.ts +51 -0
  69. package/dist/channel/adapters/telegram.js +235 -17
  70. package/dist/channel/adapters/telegram.js.map +1 -1
  71. package/dist/channel/ipc-bridge.d.ts +0 -2
  72. package/dist/channel/mcp-tools.js +3 -3
  73. package/dist/channel/mcp-tools.js.map +1 -1
  74. package/dist/channel/types.d.ts +2 -0
  75. package/dist/classic-channel-manager.d.ts +2 -0
  76. package/dist/classic-channel-manager.js +5 -1
  77. package/dist/classic-channel-manager.js.map +1 -1
  78. package/dist/cli.js +14 -10
  79. package/dist/cli.js.map +1 -1
  80. package/dist/config-validator.js +30 -71
  81. package/dist/config-validator.js.map +1 -1
  82. package/dist/config.js +3 -17
  83. package/dist/config.js.map +1 -1
  84. package/dist/cross-instance-notice.d.ts +10 -0
  85. package/dist/cross-instance-notice.js +67 -5
  86. package/dist/cross-instance-notice.js.map +1 -1
  87. package/dist/daemon.d.ts +70 -68
  88. package/dist/daemon.js +774 -846
  89. package/dist/daemon.js.map +1 -1
  90. package/dist/dashboard-permissions.d.ts +8 -0
  91. package/dist/dashboard-permissions.js +16 -0
  92. package/dist/dashboard-permissions.js.map +1 -1
  93. package/dist/delivery-consumed-watch.d.ts +26 -16
  94. package/dist/delivery-consumed-watch.js +31 -26
  95. package/dist/delivery-consumed-watch.js.map +1 -1
  96. package/dist/delivery-outbox.d.ts +0 -5
  97. package/dist/delivery-outbox.js +4 -32
  98. package/dist/delivery-outbox.js.map +1 -1
  99. package/dist/delivery-reconciliation.d.ts +42 -2
  100. package/dist/delivery-reconciliation.js +164 -2
  101. package/dist/delivery-reconciliation.js.map +1 -1
  102. package/dist/export-import.d.ts +7 -0
  103. package/dist/export-import.js +44 -10
  104. package/dist/export-import.js.map +1 -1
  105. package/dist/fleet-context.d.ts +4 -2
  106. package/dist/fleet-level-config.d.ts +1 -1
  107. package/dist/fleet-level-config.js +0 -2
  108. package/dist/fleet-level-config.js.map +1 -1
  109. package/dist/fleet-manager.d.ts +108 -245
  110. package/dist/fleet-manager.js +656 -2028
  111. package/dist/fleet-manager.js.map +1 -1
  112. package/dist/general-instance.d.ts +0 -7
  113. package/dist/general-instance.js +3 -20
  114. package/dist/general-instance.js.map +1 -1
  115. package/dist/general-knowledge/skills/concepts/SKILL.md +393 -0
  116. package/dist/general-knowledge/skills/cross-instance-messaging/SKILL.md +1 -0
  117. package/dist/general-knowledge/skills/instance-lifecycle/SKILL.md +3 -1
  118. package/dist/general-knowledge/skills/kiro-engine-migration/SKILL.md +41 -4
  119. package/dist/general-knowledge/skills/web-dashboard/SKILL.md +9 -3
  120. package/dist/general-knowledge/skills/worker-collaboration/SKILL.md +1 -1
  121. package/dist/instance-config-impact.js +6 -7
  122. package/dist/instance-config-impact.js.map +1 -1
  123. package/dist/instance-lifecycle.d.ts +19 -23
  124. package/dist/instance-lifecycle.js +216 -383
  125. package/dist/instance-lifecycle.js.map +1 -1
  126. package/dist/instance-topic-delete.d.ts +77 -0
  127. package/dist/instance-topic-delete.js +123 -0
  128. package/dist/instance-topic-delete.js.map +1 -0
  129. package/dist/instructions.d.ts +1 -3
  130. package/dist/instructions.js +1 -7
  131. package/dist/instructions.js.map +1 -1
  132. package/dist/kiro-engine-status.d.ts +11 -0
  133. package/dist/kiro-engine-status.js +6 -0
  134. package/dist/kiro-engine-status.js.map +1 -1
  135. package/dist/locale.js +63 -86
  136. package/dist/locale.js.map +1 -1
  137. package/dist/log-service.d.ts +28 -0
  138. package/dist/log-service.js +29 -0
  139. package/dist/log-service.js.map +1 -1
  140. package/dist/log-steps.d.ts +4 -3
  141. package/dist/log-steps.js +32 -7
  142. package/dist/log-steps.js.map +1 -1
  143. package/dist/logger.d.ts +16 -2
  144. package/dist/logger.js +346 -66
  145. package/dist/logger.js.map +1 -1
  146. package/dist/login-flows.d.ts +7 -0
  147. package/dist/login-flows.js +5 -2
  148. package/dist/login-flows.js.map +1 -1
  149. package/dist/login-manager.js +25 -4
  150. package/dist/login-manager.js.map +1 -1
  151. package/dist/missed-offline.d.ts +25 -0
  152. package/dist/missed-offline.js +79 -0
  153. package/dist/missed-offline.js.map +1 -0
  154. package/dist/muse-usage-relay.d.ts +2 -0
  155. package/dist/muse-usage-relay.js +5 -3
  156. package/dist/muse-usage-relay.js.map +1 -1
  157. package/dist/needs-you-hub.d.ts +6 -3
  158. package/dist/needs-you-hub.js +31 -9
  159. package/dist/needs-you-hub.js.map +1 -1
  160. package/dist/needs-you.d.ts +20 -18
  161. package/dist/needs-you.js +18 -14
  162. package/dist/needs-you.js.map +1 -1
  163. package/dist/office-share-page.js +1 -1
  164. package/dist/office-share-page.js.map +1 -1
  165. package/dist/outbound-handlers.d.ts +2 -16
  166. package/dist/outbound-handlers.js +10 -72
  167. package/dist/outbound-handlers.js.map +1 -1
  168. package/dist/outbound-schemas.d.ts +0 -38
  169. package/dist/outbound-schemas.js +5 -14
  170. package/dist/outbound-schemas.js.map +1 -1
  171. package/dist/pane-quota-history.d.ts +7 -0
  172. package/dist/pane-quota-history.js +47 -0
  173. package/dist/pane-quota-history.js.map +1 -0
  174. package/dist/platform-general.d.ts +46 -0
  175. package/dist/platform-general.js +91 -0
  176. package/dist/platform-general.js.map +1 -0
  177. package/dist/public-web-gateway.js +0 -9
  178. package/dist/public-web-gateway.js.map +1 -1
  179. package/dist/public-web-link.d.ts +0 -11
  180. package/dist/public-web-link.js +0 -13
  181. package/dist/public-web-link.js.map +1 -1
  182. package/dist/queued-handoffs.d.ts +33 -0
  183. package/dist/queued-handoffs.js +75 -0
  184. package/dist/queued-handoffs.js.map +1 -0
  185. package/dist/quickstart-api.js +5 -9
  186. package/dist/quickstart-api.js.map +1 -1
  187. package/dist/quickstart.d.ts +8 -1
  188. package/dist/quickstart.js +42 -4
  189. package/dist/quickstart.js.map +1 -1
  190. package/dist/quota-notice-config.d.ts +22 -0
  191. package/dist/quota-notice-config.js +41 -0
  192. package/dist/quota-notice-config.js.map +1 -0
  193. package/dist/quota-notice.d.ts +7 -0
  194. package/dist/quota-notice.js +40 -0
  195. package/dist/quota-notice.js.map +1 -1
  196. package/dist/reply-buttons-controller.js +10 -6
  197. package/dist/reply-buttons-controller.js.map +1 -1
  198. package/dist/reply-polls.d.ts +2 -2
  199. package/dist/reply-polls.js +3 -3
  200. package/dist/reply-polls.js.map +1 -1
  201. package/dist/scheduler/db.d.ts +2 -1
  202. package/dist/scheduler/db.js +23 -9
  203. package/dist/scheduler/db.js.map +1 -1
  204. package/dist/scheduler/task-board.d.ts +9 -0
  205. package/dist/scheduler/task-board.js +19 -0
  206. package/dist/scheduler/task-board.js.map +1 -1
  207. package/dist/settings-api.d.ts +13 -5
  208. package/dist/settings-api.js +26 -96
  209. package/dist/settings-api.js.map +1 -1
  210. package/dist/settings-baseline.d.ts +0 -1
  211. package/dist/settings-baseline.js +1 -1
  212. package/dist/settings-baseline.js.map +1 -1
  213. package/dist/settings-change.js +23 -28
  214. package/dist/settings-change.js.map +1 -1
  215. package/dist/settings-confirmation.d.ts +1 -16
  216. package/dist/settings-confirmation.js +9 -47
  217. package/dist/settings-confirmation.js.map +1 -1
  218. package/dist/settings-effect.d.ts +0 -4
  219. package/dist/settings-effect.js +1 -58
  220. package/dist/settings-effect.js.map +1 -1
  221. package/dist/settings-http-confirmation.d.ts +0 -4
  222. package/dist/settings-http-confirmation.js +3 -31
  223. package/dist/settings-http-confirmation.js.map +1 -1
  224. package/dist/settings-instance-patch.js +28 -1
  225. package/dist/settings-instance-patch.js.map +1 -1
  226. package/dist/settings-request-capability.d.ts +0 -2
  227. package/dist/settings-request-capability.js +0 -4
  228. package/dist/settings-request-capability.js.map +1 -1
  229. package/dist/settings-transaction.d.ts +0 -4
  230. package/dist/settings-transaction.js +0 -9
  231. package/dist/settings-transaction.js.map +1 -1
  232. package/dist/setup-form.js +3 -6
  233. package/dist/setup-form.js.map +1 -1
  234. package/dist/setup-i18n.js +0 -3
  235. package/dist/setup-i18n.js.map +1 -1
  236. package/dist/task-board-tool.d.ts +11 -0
  237. package/dist/task-board-tool.js +44 -0
  238. package/dist/task-board-tool.js.map +1 -1
  239. package/dist/task-board-waker.d.ts +6 -0
  240. package/dist/task-board-waker.js +4 -0
  241. package/dist/task-board-waker.js.map +1 -1
  242. package/dist/tmux-control.d.ts +1 -2
  243. package/dist/tmux-control.js.map +1 -1
  244. package/dist/tmux-manager.d.ts +1 -2
  245. package/dist/tmux-manager.js.map +1 -1
  246. package/dist/tool-permissions.d.ts +5 -2
  247. package/dist/tool-permissions.js +7 -7
  248. package/dist/tool-permissions.js.map +1 -1
  249. package/dist/tool-progress.d.ts +2 -0
  250. package/dist/tool-progress.js +19 -3
  251. package/dist/tool-progress.js.map +1 -1
  252. package/dist/topic-commands.js +4 -3
  253. package/dist/topic-commands.js.map +1 -1
  254. package/dist/transcript-delta-reader.d.ts +1 -1
  255. package/dist/transcript-delta-reader.js +1 -1
  256. package/dist/transcript-delta-reader.js.map +1 -1
  257. package/dist/transcript-monitor.d.ts +20 -3
  258. package/dist/transcript-monitor.js +92 -24
  259. package/dist/transcript-monitor.js.map +1 -1
  260. package/dist/transcript-sources.d.ts +0 -5
  261. package/dist/transcript-sources.js +79 -8
  262. package/dist/transcript-sources.js.map +1 -1
  263. package/dist/types.d.ts +3 -23
  264. package/dist/ui/app.html +8 -1
  265. package/dist/ui/backend-signin.js +21 -36
  266. package/dist/ui/chat-md-strings.js +9 -0
  267. package/dist/ui/chat-store.js +2 -13
  268. package/dist/ui/chat-strings.js +2 -50
  269. package/dist/ui/chat-thread.js +53 -3
  270. package/dist/ui/fleet-task-card.js +3 -3
  271. package/dist/ui/fleet-task-common.js +10 -0
  272. package/dist/ui/fleet-tasks.js +7 -5
  273. package/dist/ui/fleet-usage.js +90 -27
  274. package/dist/ui/panel-chat.js +37 -66
  275. package/dist/ui/panel-details.js +1 -2
  276. package/dist/ui/panel-fleet.js +88 -107
  277. package/dist/ui/panel-needs.js +21 -163
  278. package/dist/ui/panel-notices.js +4 -3
  279. package/dist/ui/panel-settings.js +149 -239
  280. package/dist/ui/preview-panel.js +84 -6
  281. package/dist/ui/search-dialog.js +3 -2
  282. package/dist/ui/settings-appearance.js +23 -122
  283. package/dist/ui/settings-catalog.js +10 -37
  284. package/dist/ui/settings-codex-copy.js +19 -0
  285. package/dist/ui/settings-confirm.js +1 -3
  286. package/dist/ui/settings-dialogs.js +20 -27
  287. package/dist/ui/settings-guests.js +14 -27
  288. package/dist/ui/settings-model.js +17 -12
  289. package/dist/ui/settings-quota-notice.js +100 -0
  290. package/dist/ui/settings-registry.js +4 -11
  291. package/dist/ui/settings-strings.js +4 -113
  292. package/dist/ui/settings-web-authority.js +13 -15
  293. package/dist/ui/shared/app-i18n.js +2 -2
  294. package/dist/ui/shared/app-needs.js +1 -1
  295. package/dist/ui/shared/app-route.js +2 -6
  296. package/dist/ui/shared/app-shell.js +18 -23
  297. package/dist/ui/shared/app-store.js +2 -3
  298. package/dist/ui/shared/app-stream.js +1 -3
  299. package/dist/ui/shared/app.css +40 -1312
  300. package/dist/ui/shared/app.js +2 -5
  301. package/dist/ui/shared/header-tools.js +4 -6
  302. package/dist/ui/shared/instance-nav.js +7 -34
  303. package/dist/ui/shared/instance-switch.js +3 -4
  304. package/dist/ui/shared/loading.css +37 -0
  305. package/dist/ui/shared/panel-view.js +77 -4
  306. package/dist/ui/shared/signin.js +6 -39
  307. package/dist/ui/shared/tokens.css +0 -1
  308. package/dist/ui/shared/ui-dialog.js +2 -2
  309. package/dist/ui/shared/ui-menu.js +10 -30
  310. package/dist/ui/shared/ui-states.js +14 -3
  311. package/dist/ui/shared/usage-dialog.js +18 -1
  312. package/dist/ui/shared/vendor/vendor.json +2 -19
  313. package/dist/ui/shared/view-history.css +17 -0
  314. package/dist/ui/shared/view-history.js +438 -0
  315. package/dist/ui/shared/view-strings.js +16 -8
  316. package/dist/ui/signin.html +5 -2
  317. package/dist/unattended-install.d.ts +11 -2
  318. package/dist/unattended-install.js +39 -5
  319. package/dist/unattended-install.js.map +1 -1
  320. package/dist/usage/capacity.d.ts +69 -0
  321. package/dist/usage/capacity.js +119 -0
  322. package/dist/usage/capacity.js.map +1 -0
  323. package/dist/usage/i18n-keys.d.ts +1 -1
  324. package/dist/usage/i18n-keys.js +3 -0
  325. package/dist/usage/i18n-keys.js.map +1 -1
  326. package/dist/usage/profile-timeline.d.ts +16 -0
  327. package/dist/usage/profile-timeline.js +58 -0
  328. package/dist/usage/profile-timeline.js.map +1 -0
  329. package/dist/usage/providers.d.ts +5 -0
  330. package/dist/usage/providers.js +5 -0
  331. package/dist/usage/providers.js.map +1 -1
  332. package/dist/usage/quota-history.d.ts +43 -0
  333. package/dist/usage/quota-history.js +168 -0
  334. package/dist/usage/quota-history.js.map +1 -0
  335. package/dist/usage/quota-notices.d.ts +38 -0
  336. package/dist/usage/quota-notices.js +160 -0
  337. package/dist/usage/quota-notices.js.map +1 -0
  338. package/dist/usage/usage-api.d.ts +32 -0
  339. package/dist/usage/usage-api.js +96 -1
  340. package/dist/usage/usage-api.js.map +1 -1
  341. package/dist/usage-report.d.ts +25 -1
  342. package/dist/usage-report.js +55 -4
  343. package/dist/usage-report.js.map +1 -1
  344. package/dist/usage-rollup.d.ts +6 -1
  345. package/dist/usage-rollup.js +16 -4
  346. package/dist/usage-rollup.js.map +1 -1
  347. package/dist/view-api.d.ts +16 -0
  348. package/dist/view-api.js +100 -16
  349. package/dist/view-api.js.map +1 -1
  350. package/dist/view-history.d.ts +84 -0
  351. package/dist/view-history.js +116 -0
  352. package/dist/view-history.js.map +1 -0
  353. package/dist/web-api.d.ts +6 -38
  354. package/dist/web-api.js +20 -255
  355. package/dist/web-api.js.map +1 -1
  356. package/dist/web-chat-history.d.ts +2 -19
  357. package/dist/web-chat-history.js +3 -72
  358. package/dist/web-chat-history.js.map +1 -1
  359. package/dist/web-only-fleet.d.ts +0 -20
  360. package/dist/web-only-fleet.js +0 -21
  361. package/dist/web-only-fleet.js.map +1 -1
  362. package/dist/web-session-authorization.d.ts +13 -2
  363. package/dist/web-session-authorization.js +10 -3
  364. package/dist/web-session-authorization.js.map +1 -1
  365. package/dist/web-session.d.ts +0 -7
  366. package/dist/web-session.js +0 -2
  367. package/dist/web-session.js.map +1 -1
  368. package/dist/web-shell-routes.d.ts +1 -4
  369. package/dist/web-shell-routes.js +2 -7
  370. package/dist/web-shell-routes.js.map +1 -1
  371. package/launcher/private-home.cjs +1 -1
  372. package/package.json +3 -9
  373. package/dist/agent-runtime-api.d.ts +0 -4
  374. package/dist/agent-runtime-api.js +0 -59
  375. package/dist/agent-runtime-api.js.map +0 -1
  376. package/dist/agent-runtime-change.d.ts +0 -74
  377. package/dist/agent-runtime-change.js +0 -102
  378. package/dist/agent-runtime-change.js.map +0 -1
  379. package/dist/backend/grok-model-cache.d.ts +0 -7
  380. package/dist/backend/grok-model-cache.js +0 -65
  381. package/dist/backend/grok-model-cache.js.map +0 -1
  382. package/dist/backend/native-pane.d.ts +0 -9
  383. package/dist/backend/native-pane.js +0 -59
  384. package/dist/backend/native-pane.js.map +0 -1
  385. package/dist/fleet-windows-runtime.d.ts +0 -97
  386. package/dist/fleet-windows-runtime.js +0 -449
  387. package/dist/fleet-windows-runtime.js.map +0 -1
  388. package/dist/general-binding.d.ts +0 -85
  389. package/dist/general-binding.js +0 -298
  390. package/dist/general-binding.js.map +0 -1
  391. package/dist/general-host-owner.d.ts +0 -8
  392. package/dist/general-host-owner.js +0 -26
  393. package/dist/general-host-owner.js.map +0 -1
  394. package/dist/general-role.d.ts +0 -5
  395. package/dist/general-role.js +0 -26
  396. package/dist/general-role.js.map +0 -1
  397. package/dist/local-pane-endpoint.d.ts +0 -46
  398. package/dist/local-pane-endpoint.js +0 -189
  399. package/dist/local-pane-endpoint.js.map +0 -1
  400. package/dist/local-pane-launcher.d.ts +0 -2
  401. package/dist/local-pane-launcher.js +0 -38
  402. package/dist/local-pane-launcher.js.map +0 -1
  403. package/dist/local-pane-stage.ps1 +0 -101
  404. package/dist/model-catalog-defaults.d.ts +0 -14
  405. package/dist/model-catalog-defaults.js +0 -20
  406. package/dist/model-catalog-defaults.js.map +0 -1
  407. package/dist/native-agent-admission.d.ts +0 -7
  408. package/dist/native-agent-admission.js +0 -26
  409. package/dist/native-agent-admission.js.map +0 -1
  410. package/dist/native-daemon-client.d.ts +0 -13
  411. package/dist/native-daemon-client.js +0 -28
  412. package/dist/native-daemon-client.js.map +0 -1
  413. package/dist/native-instance-api.d.ts +0 -14
  414. package/dist/native-instance-api.js +0 -205
  415. package/dist/native-instance-api.js.map +0 -1
  416. package/dist/native-instance-input.d.ts +0 -84
  417. package/dist/native-instance-input.js +0 -54
  418. package/dist/native-instance-input.js.map +0 -1
  419. package/dist/native-instance-registry.d.ts +0 -32
  420. package/dist/native-instance-registry.js +0 -105
  421. package/dist/native-instance-registry.js.map +0 -1
  422. package/dist/native-mcp.d.ts +0 -40
  423. package/dist/native-mcp.js +0 -278
  424. package/dist/native-mcp.js.map +0 -1
  425. package/dist/native-model-catalog.d.ts +0 -5
  426. package/dist/native-model-catalog.js +0 -76
  427. package/dist/native-model-catalog.js.map +0 -1
  428. package/dist/native-pane-crash-budget.d.ts +0 -20
  429. package/dist/native-pane-crash-budget.js +0 -60
  430. package/dist/native-pane-crash-budget.js.map +0 -1
  431. package/dist/native-pane-create.d.ts +0 -26
  432. package/dist/native-pane-create.js +0 -53
  433. package/dist/native-pane-create.js.map +0 -1
  434. package/dist/native-pane-lifecycle.d.ts +0 -65
  435. package/dist/native-pane-lifecycle.js +0 -230
  436. package/dist/native-pane-lifecycle.js.map +0 -1
  437. package/dist/native-pane-manager.d.ts +0 -59
  438. package/dist/native-pane-manager.js +0 -584
  439. package/dist/native-pane-manager.js.map +0 -1
  440. package/dist/native-pane-output-log.d.ts +0 -15
  441. package/dist/native-pane-output-log.js +0 -108
  442. package/dist/native-pane-output-log.js.map +0 -1
  443. package/dist/native-pane-reconciliation.d.ts +0 -4
  444. package/dist/native-pane-reconciliation.js +0 -40
  445. package/dist/native-pane-reconciliation.js.map +0 -1
  446. package/dist/native-pane-recovery.d.ts +0 -12
  447. package/dist/native-pane-recovery.js +0 -10
  448. package/dist/native-pane-recovery.js.map +0 -1
  449. package/dist/native-pane-tools.d.ts +0 -2
  450. package/dist/native-pane-tools.js +0 -14
  451. package/dist/native-pane-tools.js.map +0 -1
  452. package/dist/pane-port.d.ts +0 -118
  453. package/dist/pane-port.js +0 -2
  454. package/dist/pane-port.js.map +0 -1
  455. package/dist/runtime-api.d.ts +0 -8
  456. package/dist/runtime-api.js +0 -171
  457. package/dist/runtime-api.js.map +0 -1
  458. package/dist/runtime-assets/@xterm/addon-serialize/LICENSE +0 -21
  459. package/dist/runtime-assets/@xterm/addon-serialize/lib/addon-serialize.js +0 -2
  460. package/dist/runtime-assets/@xterm/addon-serialize/lib/addon-serialize.mjs +0 -19
  461. package/dist/runtime-assets/@xterm/addon-serialize/package.json +0 -29
  462. package/dist/runtime-assets/@xterm/headless/LICENSE +0 -21
  463. package/dist/runtime-assets/@xterm/headless/lib-headless/xterm-headless.js +0 -2
  464. package/dist/runtime-assets/@xterm/headless/lib-headless/xterm-headless.mjs +0 -46
  465. package/dist/runtime-assets/@xterm/headless/package.json +0 -29
  466. package/dist/runtime-assets/node-pty/CONPTY-LICENSE +0 -21
  467. package/dist/runtime-assets/node-pty/CONPTY-NOTICE.md +0 -503
  468. package/dist/runtime-assets/node-pty/LICENSE +0 -69
  469. package/dist/runtime-assets/node-pty/lib/conpty_console_list_agent.js +0 -16
  470. package/dist/runtime-assets/node-pty/lib/eventEmitter2.js +0 -47
  471. package/dist/runtime-assets/node-pty/lib/index.js +0 -52
  472. package/dist/runtime-assets/node-pty/lib/interfaces.js +0 -7
  473. package/dist/runtime-assets/node-pty/lib/shared/conout.js +0 -11
  474. package/dist/runtime-assets/node-pty/lib/terminal.js +0 -190
  475. package/dist/runtime-assets/node-pty/lib/types.js +0 -7
  476. package/dist/runtime-assets/node-pty/lib/unixTerminal.js +0 -346
  477. package/dist/runtime-assets/node-pty/lib/utils.js +0 -39
  478. package/dist/runtime-assets/node-pty/lib/windowsConoutConnection.js +0 -125
  479. package/dist/runtime-assets/node-pty/lib/windowsPtyAgent.js +0 -320
  480. package/dist/runtime-assets/node-pty/lib/windowsTerminal.js +0 -199
  481. package/dist/runtime-assets/node-pty/lib/worker/conoutSocketWorker.js +0 -22
  482. package/dist/runtime-assets/node-pty/package.json +0 -64
  483. package/dist/runtime-assets/node-pty/prebuilds/win32-arm64/conpty/OpenConsole.exe +0 -0
  484. package/dist/runtime-assets/node-pty/prebuilds/win32-arm64/conpty/conpty.dll +0 -0
  485. package/dist/runtime-assets/node-pty/prebuilds/win32-arm64/conpty.node +0 -0
  486. package/dist/runtime-assets/node-pty/prebuilds/win32-arm64/conpty_console_list.node +0 -0
  487. package/dist/runtime-assets/node-pty/prebuilds/win32-x64/conpty/OpenConsole.exe +0 -0
  488. package/dist/runtime-assets/node-pty/prebuilds/win32-x64/conpty/conpty.dll +0 -0
  489. package/dist/runtime-assets/node-pty/prebuilds/win32-x64/conpty.node +0 -0
  490. package/dist/runtime-assets/node-pty/prebuilds/win32-x64/conpty_console_list.node +0 -0
  491. package/dist/runtime-build-info.d.ts +0 -9
  492. package/dist/runtime-build-info.js +0 -57
  493. package/dist/runtime-build-info.js.map +0 -1
  494. package/dist/runtime-bundle.d.ts +0 -19
  495. package/dist/runtime-bundle.js +0 -156
  496. package/dist/runtime-bundle.js.map +0 -1
  497. package/dist/runtime-cli.d.ts +0 -7
  498. package/dist/runtime-cli.js +0 -152
  499. package/dist/runtime-cli.js.map +0 -1
  500. package/dist/runtime-client-store.d.ts +0 -68
  501. package/dist/runtime-client-store.js +0 -344
  502. package/dist/runtime-client-store.js.map +0 -1
  503. package/dist/runtime-client.d.ts +0 -112
  504. package/dist/runtime-client.js +0 -736
  505. package/dist/runtime-client.js.map +0 -1
  506. package/dist/runtime-connection.d.ts +0 -22
  507. package/dist/runtime-connection.js +0 -93
  508. package/dist/runtime-connection.js.map +0 -1
  509. package/dist/runtime-coordinator.d.ts +0 -91
  510. package/dist/runtime-coordinator.js +0 -911
  511. package/dist/runtime-coordinator.js.map +0 -1
  512. package/dist/runtime-general-protocol.d.ts +0 -22
  513. package/dist/runtime-general-protocol.js +0 -57
  514. package/dist/runtime-general-protocol.js.map +0 -1
  515. package/dist/runtime-general-workspace.d.ts +0 -17
  516. package/dist/runtime-general-workspace.js +0 -213
  517. package/dist/runtime-general-workspace.js.map +0 -1
  518. package/dist/runtime-pane-assets.d.ts +0 -17
  519. package/dist/runtime-pane-assets.js +0 -23
  520. package/dist/runtime-pane-assets.js.map +0 -1
  521. package/dist/runtime-pane-boot.d.ts +0 -9
  522. package/dist/runtime-pane-boot.js +0 -47
  523. package/dist/runtime-pane-boot.js.map +0 -1
  524. package/dist/runtime-pane-codex-index.d.ts +0 -1
  525. package/dist/runtime-pane-codex-index.js +0 -47
  526. package/dist/runtime-pane-codex-index.js.map +0 -1
  527. package/dist/runtime-pane-config.d.ts +0 -16
  528. package/dist/runtime-pane-config.js +0 -54
  529. package/dist/runtime-pane-config.js.map +0 -1
  530. package/dist/runtime-pane-host.d.ts +0 -44
  531. package/dist/runtime-pane-host.js +0 -424
  532. package/dist/runtime-pane-host.js.map +0 -1
  533. package/dist/runtime-pane-job-owner.d.ts +0 -1
  534. package/dist/runtime-pane-job-owner.js +0 -29
  535. package/dist/runtime-pane-job-owner.js.map +0 -1
  536. package/dist/runtime-pane-job.ps1 +0 -116
  537. package/dist/runtime-pane-link.d.ts +0 -40
  538. package/dist/runtime-pane-link.js +0 -246
  539. package/dist/runtime-pane-link.js.map +0 -1
  540. package/dist/runtime-pane-mcp-protocol.d.ts +0 -32
  541. package/dist/runtime-pane-mcp-protocol.js +0 -39
  542. package/dist/runtime-pane-mcp-protocol.js.map +0 -1
  543. package/dist/runtime-pane-mcp-relay.d.ts +0 -17
  544. package/dist/runtime-pane-mcp-relay.js +0 -70
  545. package/dist/runtime-pane-mcp-relay.js.map +0 -1
  546. package/dist/runtime-pane-mcp.d.ts +0 -51
  547. package/dist/runtime-pane-mcp.js +0 -150
  548. package/dist/runtime-pane-mcp.js.map +0 -1
  549. package/dist/runtime-pane-native.d.ts +0 -45
  550. package/dist/runtime-pane-native.js +0 -65
  551. package/dist/runtime-pane-native.js.map +0 -1
  552. package/dist/runtime-pane-output.d.ts +0 -19
  553. package/dist/runtime-pane-output.js +0 -53
  554. package/dist/runtime-pane-output.js.map +0 -1
  555. package/dist/runtime-pane-port.d.ts +0 -139
  556. package/dist/runtime-pane-port.js +0 -558
  557. package/dist/runtime-pane-port.js.map +0 -1
  558. package/dist/runtime-pane-private.d.ts +0 -14
  559. package/dist/runtime-pane-private.js +0 -51
  560. package/dist/runtime-pane-private.js.map +0 -1
  561. package/dist/runtime-pane-private.ps1 +0 -14
  562. package/dist/runtime-pane-process.d.ts +0 -4
  563. package/dist/runtime-pane-process.js +0 -108
  564. package/dist/runtime-pane-process.js.map +0 -1
  565. package/dist/runtime-pane-protocol.d.ts +0 -172
  566. package/dist/runtime-pane-protocol.js +0 -195
  567. package/dist/runtime-pane-protocol.js.map +0 -1
  568. package/dist/runtime-pane-screen.d.ts +0 -19
  569. package/dist/runtime-pane-screen.js +0 -76
  570. package/dist/runtime-pane-screen.js.map +0 -1
  571. package/dist/runtime-pane-service.d.ts +0 -11
  572. package/dist/runtime-pane-service.js +0 -221
  573. package/dist/runtime-pane-service.js.map +0 -1
  574. package/dist/runtime-pane-stdio-protocol.d.ts +0 -54
  575. package/dist/runtime-pane-stdio-protocol.js +0 -94
  576. package/dist/runtime-pane-stdio-protocol.js.map +0 -1
  577. package/dist/runtime-pane-stdio.d.ts +0 -3
  578. package/dist/runtime-pane-stdio.js +0 -123
  579. package/dist/runtime-pane-stdio.js.map +0 -1
  580. package/dist/runtime-pane-store.d.ts +0 -33
  581. package/dist/runtime-pane-store.js +0 -164
  582. package/dist/runtime-pane-store.js.map +0 -1
  583. package/dist/runtime-pane-transcript-protocol.d.ts +0 -43
  584. package/dist/runtime-pane-transcript-protocol.js +0 -58
  585. package/dist/runtime-pane-transcript-protocol.js.map +0 -1
  586. package/dist/runtime-pane-transcript.d.ts +0 -45
  587. package/dist/runtime-pane-transcript.js +0 -605
  588. package/dist/runtime-pane-transcript.js.map +0 -1
  589. package/dist/runtime-pane-worker.d.ts +0 -1
  590. package/dist/runtime-pane-worker.js +0 -154
  591. package/dist/runtime-pane-worker.js.map +0 -1
  592. package/dist/runtime-protocol.d.ts +0 -162
  593. package/dist/runtime-protocol.js +0 -37
  594. package/dist/runtime-protocol.js.map +0 -1
  595. package/dist/runtime-switches.d.ts +0 -79
  596. package/dist/runtime-switches.js +0 -90
  597. package/dist/runtime-switches.js.map +0 -1
  598. package/dist/runtime-transcript-delta-reader.d.ts +0 -23
  599. package/dist/runtime-transcript-delta-reader.js +0 -74
  600. package/dist/runtime-transcript-delta-reader.js.map +0 -1
  601. package/dist/runtime-transcript-source.d.ts +0 -36
  602. package/dist/runtime-transcript-source.js +0 -189
  603. package/dist/runtime-transcript-source.js.map +0 -1
  604. package/dist/runtime-windows-bridge.d.ts +0 -41
  605. package/dist/runtime-windows-bridge.js +0 -157
  606. package/dist/runtime-windows-bridge.js.map +0 -1
  607. package/dist/settings-route-lifetime.d.ts +0 -14
  608. package/dist/settings-route-lifetime.js +0 -48
  609. package/dist/settings-route-lifetime.js.map +0 -1
  610. package/dist/tmux-pane-host.d.ts +0 -26
  611. package/dist/tmux-pane-host.js +0 -25
  612. package/dist/tmux-pane-host.js.map +0 -1
  613. package/dist/transcript-needles.d.ts +0 -35
  614. package/dist/transcript-needles.js +0 -158
  615. package/dist/transcript-needles.js.map +0 -1
  616. package/dist/transcript-records.d.ts +0 -21
  617. package/dist/transcript-records.js +0 -140
  618. package/dist/transcript-records.js.map +0 -1
  619. package/dist/ui/agent-proposals.js +0 -90
  620. package/dist/ui/agent-runtime-settings.js +0 -67
  621. package/dist/ui/agent-runtime.js +0 -124
  622. package/dist/ui/cli-picker.js +0 -42
  623. package/dist/ui/general-location.js +0 -71
  624. package/dist/ui/native-instance-settings.js +0 -44
  625. package/dist/ui/native-pane-recovery.js +0 -45
  626. package/dist/ui/panel-runtimes.js +0 -334
  627. package/dist/ui/panel-windows-agent.js +0 -86
  628. package/dist/ui/panel-windows-cli.js +0 -179
  629. package/dist/ui/provider-marks.js +0 -83
  630. package/dist/ui/runtime-catalog.js +0 -55
  631. package/dist/ui/settings-agent-filters.js +0 -94
  632. package/dist/ui/settings-layout.js +0 -245
  633. package/dist/ui/settings-outside.js +0 -176
  634. package/dist/ui/settings-shortcuts.js +0 -65
  635. package/dist/ui/shared/machine-name.js +0 -13
  636. package/dist/ui/shared/qrcode.module.js +0 -2237
  637. package/dist/ui/shared/settings-width.js +0 -31
  638. package/dist/ui/shared/vendor/qrcode-generator.LICENSE +0 -27
  639. package/dist/ui/windows-agents-nav.js +0 -2
  640. package/dist/ui/windows-cli-catalog.js +0 -108
  641. package/dist/web-remote-access.d.ts +0 -152
  642. package/dist/web-remote-access.js +0 -368
  643. package/dist/web-remote-access.js.map +0 -1
  644. package/dist/windows-agents.d.ts +0 -126
  645. package/dist/windows-agents.js +0 -490
  646. package/dist/windows-agents.js.map +0 -1
  647. package/dist/windows-cli-api.d.ts +0 -23
  648. package/dist/windows-cli-api.js +0 -159
  649. package/dist/windows-cli-api.js.map +0 -1
  650. package/dist/windows-cli-providers.d.ts +0 -115
  651. package/dist/windows-cli-providers.js +0 -429
  652. package/dist/windows-cli-providers.js.map +0 -1
  653. package/dist/windows-cli-worker.d.ts +0 -59
  654. package/dist/windows-cli-worker.js +0 -479
  655. package/dist/windows-cli-worker.js.map +0 -1
  656. package/dist/windows-cli.d.ts +0 -116
  657. package/dist/windows-cli.js +0 -407
  658. package/dist/windows-cli.js.map +0 -1
  659. package/dist/windows-native-mcp.d.ts +0 -19
  660. package/dist/windows-native-mcp.js +0 -143
  661. package/dist/windows-native-mcp.js.map +0 -1
  662. package/dist/windows-pane-mcp.d.ts +0 -26
  663. package/dist/windows-pane-mcp.js +0 -187
  664. package/dist/windows-pane-mcp.js.map +0 -1
  665. package/templates/runtime-assets/conpty-LICENSE +0 -21
  666. package/templates/runtime-assets/conpty-NOTICE.md +0 -503
  667. package/templates/runtime-assets/local-pane-stage.ps1 +0 -101
  668. package/templates/runtime-assets/runtime-pane-job.ps1 +0 -116
  669. package/templates/runtime-assets/runtime-pane-private.ps1 +0 -14
  670. package/templates/runtime-assets/xterm-LICENSE +0 -21
@@ -5,17 +5,13 @@
5
5
  // Opening a tab reads its list: a person's navigation, so it counts as use, as the old tab click did (#1374 — no timer
6
6
  // here re-reads anything). Every read is under the navigation's lease: a list that arrives after the person moved on
7
7
  // is dropped (#1408 §4).
8
- import { html, useEffect, useRef, useState } from "/assets/app-html.js";
8
+ import { html, useEffect, useLayoutEffect, useRef, useState } from "/assets/app-html.js";
9
9
  import { t, register, lang } from "/assets/app-i18n.js";
10
10
  import { appStore, useStore } from "/assets/app-store.js";
11
11
  import { useLease } from "/assets/app-ctx.js";
12
12
  import { PanelHeader, setTitle } from "/assets/app-shell.js";
13
13
  import { HeaderTools } from "/assets/header-tools.js";
14
- import { navigate, renavigate } from "/assets/app-nav.js";
15
- import { RuntimePicker, AgentDraftAssistant, NativeAgendToolsHint, tr } from "./agent-runtime.js";
16
- import { CliPicker, cliLabel as productLabel } from "./cli-picker.js";
17
- import { useWindowsCliCatalog, WindowsCliDiscoveryStatus, detectionText } from "./windows-cli-catalog.js";
18
- import { useRuntimeCatalog } from "./runtime-catalog.js";
14
+ import { renavigate } from "/assets/app-nav.js";
19
15
  import { chatPath, fleetPath, FLEET_TABS, rememberFleetTab } from "/assets/app-route.js";
20
16
  import { Dialog } from "/assets/ui-dialog.js";
21
17
  import { Empty, ErrorState, Skeleton } from "/assets/ui-states.js";
@@ -136,6 +132,62 @@ function useLoad(lease, path, version) {
136
132
  return state;
137
133
  }
138
134
 
135
+ /**
136
+ * M-2542: whether the tab row goes in the header. Not on a phone (app.css's breakpoint — the query app-shell's narrow()
137
+ * asks). On a desktop only when the header's row holds everything at its natural width: the title (with any host
138
+ * memory warning), all six tabs and the header's tools. Otherwise the tabs are the row under the header, as before —
139
+ * never clipped, never squeezed. The natural widths are the same in either place, so the answer does not flip-flop.
140
+ */
141
+ const NARROW = "(max-width: 899px)";
142
+ export function tabsFit(m) { return m.title + m.tabs + m.tools + m.gaps <= m.room + 0.5; }
143
+ export function measureTabsFit(root) {
144
+ const head = root?.querySelector(".panel-head");
145
+ const title = head?.querySelector(".panel-title");
146
+ const nav = root?.querySelector("nav[data-trust='panel-navigation']");
147
+ if (!head || !title || !nav || typeof getComputedStyle !== "function") return true;
148
+ const w = (el) => el.getBoundingClientRect().width || 0;
149
+ const natural = (el) => Math.max(w(el), el.scrollWidth || 0); // an ellipsised title still counts its whole text
150
+ const px = (v) => parseFloat(v) || 0;
151
+ const sum = (els, f) => els.reduce((n, el) => n + f(el), 0);
152
+ const hs = getComputedStyle(head);
153
+ const parts = [...title.children], items = [...nav.children];
154
+ const others = [...head.children].filter(el => el !== title && el !== nav && w(el) > 0); // tools, sidebar buttons
155
+ return tabsFit({
156
+ room: w(head) - px(hs.paddingLeft) - px(hs.paddingRight),
157
+ // The warning is deliberately capped; its hidden process text must not keep the tabs on a separate row.
158
+ title: sum(parts, el => el.querySelector?.(".host-mem") ? w(el) : natural(el)) + px(getComputedStyle(title).columnGap) * Math.max(0, parts.length - 1),
159
+ tabs: sum(items, w) + px(getComputedStyle(nav).columnGap) * Math.max(0, items.length - 1),
160
+ tools: sum(others, w),
161
+ gaps: px(hs.columnGap) * (others.length + 1),
162
+ });
163
+ }
164
+ function useTabsInHeader(rootRef) {
165
+ const mq = () => (typeof matchMedia === "function" ? matchMedia(NARROW) : null);
166
+ const [inHeader, setInHeader] = useState(() => !(mq()?.matches ?? false));
167
+ const check = () => setInHeader(!(mq()?.matches ?? false) && measureTabsFit(rootRef.current));
168
+ useLayoutEffect(() => {
169
+ check(); // every render: the title's warning can come and go
170
+ // A lazy panel can meet app.css cached before this fix. Re-link once, using the existing same-origin policy.
171
+ const warning = rootRef.current?.querySelector(".host-mem");
172
+ if (!warning || typeof getComputedStyle !== "function" || !document.head || document.getElementById("fleet-memory-css")) return;
173
+ const rev = getComputedStyle(warning).getPropertyValue?.("--fleet-memory-header");
174
+ if (rev === undefined || rev.trim() === "1") return;
175
+ const link = document.createElement("link"); link.id = "fleet-memory-css"; link.rel = "stylesheet";
176
+ link.href = "/assets/app.css?fleet-memory=1";
177
+ link.addEventListener("load", () => { if (rootRef.current) check(); }, { once: true });
178
+ document.head.appendChild(link);
179
+ });
180
+ useEffect(() => {
181
+ const m = mq();
182
+ m?.addEventListener?.("change", check);
183
+ const ro = typeof ResizeObserver === "function" ? new ResizeObserver(check) : null;
184
+ if (ro && rootRef.current) ro.observe(rootRef.current);
185
+ document.fonts?.ready?.then(check, () => {});
186
+ return () => { m?.removeEventListener?.("change", check); ro?.disconnect(); };
187
+ }, []);
188
+ return inHeader;
189
+ }
190
+
139
191
  export function FleetPanel({ route, navKey }) {
140
192
  const lease = useLease(navKey);
141
193
  const tab = route.tab;
@@ -146,11 +198,19 @@ export function FleetPanel({ route, navKey }) {
146
198
  const { hostMemory, hostMemoryTop } = useStore(appStore);
147
199
  // #2015: and which processes hold the most, and whose — text only (never chat, #1712).
148
200
  const top = hostMemory && hostMemoryTop?.length ? t("fleet.hostMemory_top", hostMemoryTop.map(memoryHogText).join(" · ")) : "";
149
- const sub = hostMemory ? html`<span class=${`status host-mem ${hostMemory}`} role="status"><span class=${`dot ${hostMemory === "critical" ? "bad" : "warn"}`} aria-hidden="true"></span>${t(`fleet.hostMemory_${hostMemory}`)}${top ? html`<span class="host-mem-top">${top}</span>` : null}</span>` : null;
150
- return html`<div data-effect-panel="fleet" class="panel p-fleet">
151
- <${PanelHeader} title=${t("fleet.title")} sub=${sub}><${DocsLink} /><${HeaderTools} navKey=${navKey} /></${PanelHeader}>
152
- <nav data-trust="panel-navigation" class="seg" aria-label=${t("fleet.title")}>${FLEET_TABS.map(k => html`<a key=${k} href=${fleetPath(k)} class=${`seg-item${k === tab ? " active" : ""}`}
153
- aria-current=${k === tab ? "page" : undefined}><${Icon} name=${ICONS[k]} size=${16} /><span>${t(`fleet.${k}`)}</span></a>`)}</nav>
201
+ const sub = hostMemory ? html`<span class=${`status host-mem ${hostMemory}`} role="status"><span class=${`dot ${hostMemory === "critical" ? "bad" : "warn"}`} aria-hidden="true"></span>${t(`fleet.hostMemory_${hostMemory}`)}${top ? html`<span class="host-mem-top" title=${top}>${top}</span>` : null}</span>` : null;
202
+ const root = useRef(null);
203
+ const wide = useTabsInHeader(root);
204
+ const tabs = (cls) => html`<nav data-trust="panel-navigation" class=${cls} aria-label=${t("fleet.title")}>${FLEET_TABS.map(k => html`<a key=${k} href=${fleetPath(k)} class=${`seg-item${k === tab ? " active" : ""}`}
205
+ aria-current=${k === tab ? "page" : undefined}><${Icon} name=${ICONS[k]} size=${16} /><span>${t(`fleet.${k}`)}</span></a>`)}</nav>`;
206
+ return html`<div ref=${root} data-effect-panel="fleet" class="panel p-fleet">
207
+ ${/* M-2542: the tabs share the title row (PanelHeader's nav slot, as the instance tabs do) when everything fits
208
+ there (useTabsInHeader), saving a line; otherwise — a phone, a narrow window, a long host memory warning — they
209
+ stay the row under the header they always were (.seg, the same markup as before). Not ".seg" in the header,
210
+ and chosen here rather than by CSS: a previous release's app.css, cached in an open tab, has no rule for the
211
+ header slot — this way either stylesheet lays both out (smoke-2542 SKEW). */ ""}
212
+ <${PanelHeader} title=${t("fleet.title")} sub=${sub} nav=${wide ? tabs("fleet-tabs") : null}><${DocsLink} /><${HeaderTools} navKey=${navKey} /></${PanelHeader}>
213
+ ${wide ? null : tabs("seg")}
154
214
  <div data-trust="panel-content" class="panel-body"><div class=${`col${tab === "tasks" || tab === "org" || tab === "cache" || tab === "usage" ? " col-wide" : ""}`}><${Body} lease=${lease} /></div></div>
155
215
  </div>`;
156
216
  }
@@ -270,7 +330,7 @@ function Cache({ lease }) {
270
330
  * that finishes after that still reports its toast (it may have created something), but never closes or refreshes
271
331
  * whatever is on screen now (#1425 review). `ready` false keeps Create off until the form has what it needs.
272
332
  */
273
- export function FormDialog({ title, onClose, submit, children, ready = true, renderActions, onCreated, onSubmit, wide = false }) {
333
+ export function FormDialog({ title, onClose, submit, children, ready = true }) {
274
334
  const lease = useLease("form-dialog");
275
335
  const [busy, setBusy] = useState(false);
276
336
  async function go() {
@@ -291,15 +351,13 @@ export function FormDialog({ title, onClose, submit, children, ready = true, ren
291
351
  toast(submit.done);
292
352
  if (handedOver || !lease.current()) return;
293
353
  setBusy(false);
294
- if (onCreated) { onCreated(r); return; }
295
354
  onClose();
296
355
  if (submit.after) submit.after();
297
- if (submit.afterResult) submit.afterResult(r);
298
356
  }
299
- return html`<${Dialog} title=${title} onClose=${onClose} busy=${busy} wide=${wide}
300
- actions=${renderActions ? renderActions({ busy, go }) : html`<button type="button" class="btn" onClick=${onClose} disabled=${busy}>${t("fleet.cancel")}</button>
357
+ return html`<${Dialog} title=${title} onClose=${onClose} busy=${busy}
358
+ actions=${html`<button type="button" class="btn" onClick=${onClose} disabled=${busy}>${t("fleet.cancel")}</button>
301
359
  <button type="button" class="btn btn-primary" onClick=${go} disabled=${busy || !ready}>${busy ? t("fleet.creating") : submit.label || t("fleet.create")}</button>`}>
302
- <form class="form" onSubmit=${(e) => { e.preventDefault(); if (onSubmit) onSubmit({ busy, go }); else go(); }}><fieldset class="form" disabled=${busy}>${children}</fieldset></form></${Dialog}>`;
360
+ <form class="form" onSubmit=${(e) => { e.preventDefault(); go(); }}><fieldset class="form" disabled=${busy}>${children}</fieldset></form></${Dialog}>`;
303
361
  }
304
362
  const field = (label, input) => html`<label class="field"><span>${label}</span>${input}</label>`;
305
363
 
@@ -424,28 +482,9 @@ function CreateTeam({ onClose, onDone, team = null }) {
424
482
  export function CreateInstanceDialog({ onClose }) {
425
483
  const lease = useLease("create-instance");
426
484
  const [backends, setBackends] = useState(null);
427
- const { windowsCli } = useStore(appStore);
428
- const [runtime,setRuntime] = useState("");
429
- const [machineId,setMachineId] = useState("");
430
- const [nativeAdapter,setNativeAdapter]=useState("exec");
431
- const machineCatalog = useRuntimeCatalog();
432
- // A computer paired a moment ago must show up: ask for a fresh list whenever the dialog opens (the hook then keeps polling).
433
- useEffect(() => { void machineCatalog.refresh(); },[]);
434
- const machines = machineCatalog.data?.machines || [];
435
- const machine = machines.find(item => item.id === machineId);
436
- const [step,setStep] = useState(1), [created,setCreated] = useState(null);
437
- const drafts = useRef({}), draftGoals = useRef({}), heading = useRef(null);
438
- const discovery = useWindowsCliCatalog(windowsCli === true);
439
- const native = machineId ? machine?.inventory : discovery.data;
440
- const [assistBusy,setAssistBusy] = useState(false);
441
- const windows = runtime === "windows";
442
485
  // The backend "fleet default" means (#2098 review P3-3): its models are the ones the model list offers then.
443
486
  const [defaultBackend, setDefaultBackend] = useState("claude-code");
444
487
  const [f, setF] = useState({ dir: "", topic: "", desc: "", backend: "", model: "", branch: "", tags: "", prompt: "" });
445
- useEffect(() => {
446
- heading.current?.focus({ preventScroll:true });
447
- heading.current?.closest(".dlg-body")?.scrollTo?.({ top:0 });
448
- },[step]);
449
488
  useEffect(() => {
450
489
  (async () => {
451
490
  try {
@@ -455,43 +494,15 @@ export function CreateInstanceDialog({ onClose }) {
455
494
  const first = list.find(b => b.installed && !b.deprecated) || list.find(b => b.installed);
456
495
  if (typeof bd.defaultBackend === "string" && bd.defaultBackend) setDefaultBackend(bd.defaultBackend);
457
496
  setBackends(list);
458
- setF(x => ({ ...x, backend: x.backend || (first ? first.name : "") }));
497
+ setF(x => ({ ...x, backend: first ? first.name : "" }));
459
498
  } catch {
460
499
  // The list could not be read: offer the known backends, and keep the explicit choice "fleet default" selected.
461
- if (lease.current()) { setBackends(BACKENDS.map(name => ({ name, installed: true, fallback: true }))); setF(x => ({ ...x, backend: "" })); }
500
+ if (lease.current()) { setBackends(BACKENDS.map(name => ({ name, installed: true }))); setF(x => ({ ...x, backend: "" })); }
462
501
  }
463
502
  })();
464
503
  }, [lease]);
465
504
  const set = (k) => (e) => setF({ ...f, [k]: e.target.value });
466
- const targetKey = `${runtime}:${machineId || "local"}`;
467
- const chooseRuntime = (value, nextMachineId = "") => {
468
- if (value === runtime && nextMachineId === machineId) return;
469
- if (runtime) drafts.current[targetKey] = { form:{...f}, sandbox,nativeAdapter };
470
- const saved = drafts.current[`${value}:${nextMachineId || "local"}`];
471
- const nextInventory = nextMachineId ? machines.find(item => item.id === nextMachineId)?.inventory : discovery.data;
472
- const { sandbox: savedFileAccess } = saved || {};
473
- setRuntime(value);
474
- setMachineId(nextMachineId);
475
- setF(saved?.form || {dir:"",topic:"",desc:"",prompt:"",tags:"",branch:"",model:"",backend:value === "windows" ? nextInventory?.clis?.find(b => b.path && b.runnable)?.id || "codex" : backends?.find(b => b.installed && !b.deprecated && !b.fallback)?.name || ""});
476
- setSandbox(savedFileAccess || "read-only");setNativeAdapter(saved?.nativeAdapter||"exec");
477
- };
478
- const [sandbox,setSandbox] = useState("read-only");
479
- const nativeCli = native?.clis?.find(cli => cli.id === f.backend);
480
- const nativeChoices = (native?.clis || []).filter(cli => cli.path && cli.supports?.execution !== false && cli.supports?.resume !== false).map(cli => ({value:cli.id,label:productLabel(cli.id),disabled:!cli.runnable,description:cli.authenticated === false ? t("fleet.notSignedIn") : cli.version || "Windows"}));
481
- useEffect(() => {
482
- if(nativeAdapter==="pane"&&!['codex','claude-code'].includes(f.backend))setNativeAdapter("exec");
483
- if (windows && native && !nativeChoices.some(choice => choice.value === f.backend)) {
484
- const first = nativeChoices.find(choice => !choice.disabled) || nativeChoices[0];
485
- if (first) setF(current => ({...current,backend:first.value,model:""}));
486
- }
487
- },[native,runtime,machineId,f.backend,nativeAdapter]);
488
- const submit = { path: "/ui/instances", done: windows ? tr("created") : t("fleet.instanceCreated"),
489
- collect: () => {
490
- if (windows) {
491
- const name = f.topic.trim() || f.dir.trim().replace(/[\\/]+$/, "").split(/[\\/]/).pop();
492
- if (!name) { toast(tr("required"),false); return null; }
493
- return {runtime:"windows",...(nativeAdapter==="pane"?{native_adapter:"pane"}:{}),...(machineId ? {machineId} : {}),topic_name:name,backend:f.backend,...(f.model.trim() ? {model:f.model.trim()} : {}),...(f.dir.trim() ? {directory:f.dir.trim()} : {}),description:f.desc.trim(),systemPrompt:f.prompt.trim(),sandbox};
494
- }
505
+ const submit = { path: "/ui/instances", done: t("fleet.instanceCreated"), collect: () => {
495
506
  if (!f.dir.trim() && !f.topic.trim()) { toast(t("fleet.topicRequired"), false); return null; }
496
507
  const body = {};
497
508
  if (f.dir.trim()) body.directory = f.dir.trim();
@@ -504,48 +515,18 @@ export function CreateInstanceDialog({ onClose }) {
504
515
  if (f.prompt.trim()) body.systemPrompt = f.prompt.trim();
505
516
  return body;
506
517
  } };
507
- const canNext = !!runtime && (!machineId || machine?.status === "online") && (windows ? nativeCli?.runnable === true : backends !== null);
508
- const permissionReady = !windows || sandbox !== "read-only" || nativeCli?.readOnlySupport !== false;
509
- const canCreate = step === 2 && canNext && permissionReady && !assistBusy && (!windows || !!(f.topic.trim() || f.dir.trim()));
510
- const advance = () => { if (canNext && !assistBusy) setStep(2); };
511
- const destination = created?.name ? chatPath(created.name) : created?.agent?.id ? `/ui/windows-agents/${created.agent.id}` : null;
512
- const createdName = created?.agent?.name || created?.name || f.topic || f.dir.replace(/[\\/]+$/, "").split(/[\\/]/).pop();
513
- const runtimeLabel = machineId ? `${machine?.name || machineId} · ${machine?.platform || tr(runtime)}` : runtime ? tr(runtime) : "";
514
- const cliLabel = productLabel(f.backend) || `${t("fleet.fleetDefault")} (${productLabel(defaultBackend)})`;
515
- const backendField = windows ? html`<div class="field"><div class="cli-discovery-heading"><span>${tr("backend")}</span>${native && !machineId ? html`<button type="button" class="btn btn-ghost btn-sm" disabled=${discovery.loading} onClick=${discovery.refresh}><${Icon} name="restart" size=${14} />${detectionText("refresh")}</button>` : null}</div>
516
- <div aria-busy=${!machineId && discovery.loading ? "true" : "false"}>${native ? html`<${CliPicker} label=${tr("backend")} value=${f.backend} choices=${nativeChoices} onChange=${value => setF(x => ({...x,backend:value,model:""}))} disabled=${!nativeChoices.length || !!machineId && machine?.status !== "online"} />` : null}</div>
517
- ${machineId ? html`<p class="note">${tr(!nativeChoices.length ? "noRemoteCli" : "remotePolicy")}</p>${machine?.inventoryUpdatedAt ? html`<p class="note">${t("runtime.inventoryAt",new Date(machine.inventoryUpdatedAt).toLocaleString())}</p>` : null}` : html`<${WindowsCliDiscoveryStatus} state=${discovery} />`}
518
- ${!machineId && native && !discovery.loading && !discovery.error ? html`<p class="note">${!nativeChoices.length ? tr("noCli") : tr("nativeHint")}</p>` : null}</div>`
519
- : field(tr("backend"),backends ? html`<${CliPicker} label=${tr("backend")} value=${f.backend} choices=${[{value:"",label:t("fleet.fleetDefault")},...backends.filter(b => backendState(b) !== "not_installed" && !b.deprecated).map(b => ({value:b.name,label:productLabel(b.name),disabled:backendBlocked(b),description:backendNote(b)}))]} onChange=${value => setF(x => ({...x,backend:value,model:""}))} />` : html`<div role="status" aria-busy="true"><${Skeleton} lines=${1} /><span class="note">${tr("loadingClis")}</span></div>`);
520
- const actions = ({busy,go}) => step === 3 ? html`<button type="button" class="btn" onClick=${onClose}>${tr("finish")}</button><button type="button" class="btn btn-primary" onClick=${() => { onClose(); navigate(destination || "/settings/agents"); }}>${tr(destination ? "openChat" : "viewAgents")}<${Icon} name="forward" size=${16} /></button>`
521
- : html`<button type="button" class="btn" disabled=${busy || assistBusy} onClick=${step === 1 ? onClose : () => setStep(1)}>${step === 1 ? t("fleet.cancel") : tr("back")}</button>
522
- <button type="button" class="btn btn-primary" disabled=${busy || (step === 1 ? !canNext : !canCreate)} onClick=${step === 1 ? advance : go}>${step === 1 ? tr("next") : busy ? t("fleet.creating") : t("fleet.create")}${step === 1 ? html`<${Icon} name="forward" size=${16} />` : null}</button>`;
523
- return html`<${FormDialog} title=${tr("title")} onClose=${onClose} submit=${submit} ready=${canCreate} wide=${true} renderActions=${actions}
524
- onSubmit=${({busy,go}) => { if (!busy) { if (step === 1) advance(); else if (step === 2) go(); } }}
525
- onCreated=${result => { setCreated(result); setStep(3); }}>
526
- <div class="agent-create-wizard" data-step=${step}>
527
- <ol class="agent-create-steps" aria-label=${tr("progress")}>${["runtimeStep","configureStep","doneStep"].map((label,index) => html`<li key=${label} class=${index+1 === step ? "current" : index+1 < step ? "complete" : ""} aria-current=${index+1 === step ? "step" : undefined}><span class="agent-create-step-number">${index+1 < step ? html`<${Icon} name="check" size=${13} />` : index+1}</span><span>${tr(label)}</span></li>`)}</ol>
528
- ${step === 1 ? html`<section class="agent-create-stage"><h3 ref=${heading} tabindex="-1">${tr("where")}</h3><p class="note">${tr("runtimeLead")}</p>
529
- <${RuntimePicker} value=${runtime} onChange=${chooseRuntime} windowsEnabled=${windowsCli} legend=${tr("environment")} machineId=${machineId} machines=${machines} onMachineChange=${id => chooseRuntime("windows",id)} onRefresh=${machineCatalog.refresh} loaded=${!!machineCatalog.data && !machineCatalog.error} />
530
- ${machineCatalog.loading && !machineCatalog.data ? html`<p class="note" role="status">${tr("machineLoading")}</p>` : null}
531
- ${machineCatalog.error ? html`<p class="note" role="alert">${tr("machineFailed")}</p>` : null}
532
- <a class="note runtime-manage-link" href="/settings/runtimes">${tr("manage")}</a>
533
- ${runtime ? html`<div class="agent-create-cli">${backendField}</div>` : null}
534
- </section>` : step === 2 ? html`<section class="agent-create-stage"><h3 ref=${heading} tabindex="-1">${tr("configureStep")}</h3><p class="note">${tr("configureLead")}</p>
535
- <div class="agent-create-selection"><${Icon} name=${windows ? "view" : "code"} size=${19} /><div><strong>${runtimeLabel}</strong><span>${cliLabel}</span></div><button type="button" class="btn btn-ghost btn-sm" disabled=${assistBusy} onClick=${() => setStep(1)}>${tr("changeRuntime")}</button></div>
536
- ${machineId ? html`<p class="note">${tr("remoteDraft")}</p>` : windowsCli ? html`<${AgentDraftAssistant} key=${targetKey} runtime=${runtime} probe=${native} initialGoal=${draftGoals.current[targetKey] || ""} onGoalChange=${value => { draftGoals.current[targetKey] = value; }} onBusy=${setAssistBusy} onDraft=${draft => setF(x => ({...x,topic:draft.name,dir:draft.cwd,desc:draft.description,prompt:draft.instructions}))} />` : null}
537
- <fieldset class="form agent-runtime-fields" disabled=${assistBusy}>
538
- ${field(machineId ? t("runtime.remoteDirectory",machine?.name || machineId) : windows ? tr("directory") : t("fleet.directory"), html`<input value=${f.dir} onInput=${set("dir")} placeholder=${windows ? tr("directoryHint") : t("fleet.directoryHint")} />`)}
539
- ${field(`${t("fleet.topic")}${f.dir.trim() ? "" : " *"}`, html`<input value=${f.topic} onInput=${set("topic")} placeholder=${windows ? tr("nameHint") : t("fleet.topicHint")} />`)}
518
+ // Create waits for the backend list: a submission before it would go without a backend, and the list arriving
519
+ // afterwards would change the shown choice under a request already sent (#1425 review).
520
+ return html`<${FormDialog} title=${t("fleet.newInstance")} onClose=${onClose} submit=${submit} ready=${backends !== null}>
521
+ ${field(t("fleet.directory"), html`<input value=${f.dir} onInput=${set("dir")} placeholder=${t("fleet.directoryHint")} />`)}
522
+ ${field(`${t("fleet.topic")}${f.dir.trim() ? "" : " *"}`, html`<input value=${f.topic} onInput=${set("topic")} placeholder=${t("fleet.topicHint")} />`)}
540
523
  ${field(t("fleet.description"), html`<input value=${f.desc} onInput=${set("desc")} placeholder=${t("fleet.descriptionHint")} />`)}
541
- ${windows ? html`${field(tr("adapter"),html`<select id="native-create-adapter" value=${nativeAdapter} onChange=${e=>setNativeAdapter(e.target.value)}><option value="exec">${tr("adapterExec")}</option><option value="pane" disabled=${!["codex","claude-code"].includes(f.backend)}>${tr("adapterPane")}</option></select>`)}<p class="note">${tr(nativeAdapter==="pane"?"paneTopic":"execTopic")}</p>${field(t("fleet.model"),html`<${ModelSelect} key=${`${targetKey}:${f.backend}`} value=${f.model} onChange=${value => setF(x => ({...x,model:value}))} backend=${f.backend} runtime="windows" machineId=${machineId} inherit=${tr("model")} />`)}${field(tr("access"),html`<select id="native-create-sandbox" value=${sandbox} onChange=${e => setSandbox(e.target.value)}><option value="read-only" disabled=${nativeCli?.readOnlySupport === false}>${tr("read")}</option><option value="workspace-write">${tr("write")}</option></select>`)}<p class="note">${!permissionReady ? tr("noReadOnly") : sandbox === "workspace-write" ? tr(nativeAdapter==="pane"?"panePolicy":nativeCli?.id === "claude-code" ? "nativePolicyClaude" : "nativePolicy") : ""}</p><${NativeAgendToolsHint} cli=${nativeCli} sandbox=${sandbox} />` : html`
542
- ${field(t("fleet.model"), html`<${ModelSelect} value=${f.model} onChange=${(v) => setF(x => ({ ...x, model: v }))} backend=${f.backend || defaultBackend} inherit=${t("fleet.fleetDefault")} />`)}
543
- ${field(t("fleet.branch"), html`<input value=${f.branch} onInput=${set("branch")} placeholder=${t("fleet.branchHint")} />`)}
544
- ${field(t("fleet.tags"), html`<input value=${f.tags} onInput=${set("tags")} placeholder=${t("fleet.tagsHint")} />`)}
545
- `}
524
+ ${field(t("fleet.backend"), backends ? html`<select value=${f.backend} onChange=${set("backend")}><option value="">${t("fleet.fleetDefault")}</option>
525
+ ${backends.map(b => html`<option key=${b.name} value=${b.name} disabled=${backendBlocked(b)}>${b.name}${b.deprecated ? ` ${t("fleet.deprecated")}` : ""}${backendNote(b)}</option>`)}</select>` : html`<${Skeleton} lines=${1} />`)}
526
+ ${field(t("fleet.model"), html`<${ModelSelect} value=${f.model} onChange=${(v) => setF(x => ({ ...x, model: v }))} backend=${f.backend || defaultBackend} inherit=${t("fleet.fleetDefault")} />`)}
527
+ ${field(t("fleet.branch"), html`<input value=${f.branch} onInput=${set("branch")} placeholder=${t("fleet.branchHint")} />`)}
528
+ ${field(t("fleet.tags"), html`<input value=${f.tags} onInput=${set("tags")} placeholder=${t("fleet.tagsHint")} />`)}
546
529
  ${field(t("fleet.systemPrompt"), html`<textarea rows="3" value=${f.prompt} onInput=${set("prompt")} placeholder=${t("fleet.systemPromptHint")}></textarea>`)}
547
- </fieldset></section>` : html`<section class="agent-create-stage agent-create-success"><span class="agent-create-success-icon"><${Icon} name="check" size=${28} /></span><h3 ref=${heading} tabindex="-1">${tr("success")}</h3><p class="note">${tr("successLead")}</p><dl><dt>${t("fleet.topic")}</dt><dd>${createdName}</dd><dt>Runtime</dt><dd>${runtimeLabel} · ${cliLabel}</dd><dt>${t("fleet.directory")}</dt><dd><code>${created?.agent?.cwd || created?.worktree_path || f.dir || tr("autoWorkspace")}</code></dd></dl></section>`}
548
- </div>
549
530
  </${FormDialog}>`;
550
531
  }
551
532
 
@@ -9,9 +9,6 @@
9
9
  // - Acknowledge on a delivery (POST /ui/needs/ack), which clears it everywhere;
10
10
  // - Open: that instance's chat.
11
11
  // Something resolved anywhere (Discord, Telegram, the web) leaves the list by itself.
12
- // alpha.2 (M-2300): an agent's Windows request waiting for a web-only fleet's owner is the app store's `proposals`, read
13
- // by agent-proposals.js (owner only, on the stream's `agent_proposals` ping) — Approve / Reject POST its decision. Only
14
- // on a tab opened before an upgrade (app.js never installed it) does this panel install it, once.
15
12
  import { html, useEffect, useState } from "/assets/app-html.js";
16
13
  import { t, register } from "/assets/app-i18n.js";
17
14
  import { appStore, createStore, useStore } from "/assets/app-store.js";
@@ -19,18 +16,16 @@ import { useLease } from "/assets/app-ctx.js";
19
16
  import { PanelHeader, setTitle } from "/assets/app-shell.js";
20
17
  import { chatPath } from "/assets/app-route.js";
21
18
  import { namesOf, namesStore } from "/assets/instance-nav.js";
22
- import { Empty } from "/assets/ui-states.js";
19
+ import { Empty, Skeleton } from "/assets/ui-states.js";
23
20
  import { Icon } from "/assets/ui-icons.js";
24
21
  import { toast } from "/assets/ui-toast.js";
25
22
  import { notifyStore, notifySupport, configDetail, reasonText, refreshNotify, setNotify } from "/assets/app-needs.js";
26
23
  import { openSignIn, signInOffered } from "./backend-signin.js";
27
- import { decideProposal, installProposals } from "./agent-proposals.js";
28
- import { GeneralLocation } from "./general-location.js";
29
24
 
30
25
  register("needs", {
31
26
  en: {
32
27
  title: "Needs you", empty: "Nothing needs you right now", emptyHint: "When an agent waits for you, it shows here — and in your chat app's General.", emptyHintWeb: "When an agent waits for you, it shows here.",
33
- open: "Open chat", openCard: "Open the card", noAssignee: "Task board (nobody assigned)", fleetSignIns: "Fleet sign-ins", signIn: "Sign in",
28
+ open: "Open chat", kiroOpen: "Open agent", kiroMigration: "Migration instructions", openCard: "Open the card", noAssignee: "Task board (nobody assigned)", fleetSignIns: "Fleet sign-ins", signIn: "Sign in",
34
29
  gap: "not wrapped up: {0}", gapUnchecked: "{0} checklist item(s) unchecked", gapNoResult: "no result", gapJoin: ", ", acknowledge: "Acknowledge", acknowledging: "Acknowledging…", answering: "Answering…",
35
30
  ageNow: "just now", ageMin: "{0} min", ageHour: "{0} h", ageDay: "{0} d",
36
31
  notifyTitle: "Notify me on this device", notifyOn: "Notifications are on for this browser while a tab is open.",
@@ -39,23 +34,11 @@ register("needs", {
39
34
  notifyMobile: "On a phone, rely on your chat app's notification: a new item is a new post in General.", notifyMobileWeb: "On a phone, open this page to see what needs you.",
40
35
  notifyInsecure: "Notifications need a secure address (localhost or the HTTPS public link), not a plain-HTTP LAN address.",
41
36
  notifyUnsupported: "This browser cannot show notifications.", turnOn: "Turn on", turnOff: "Turn off",
42
- typePrompt: "Fleet prompt", typeAwaiting: "At its terminal", typeInstance: "Instance", typeDelivery: "Delivery",
43
- proposals: "Agent requests", proposalFrom: "Request from {0}", proposalHint: "Nothing is created or changed until you approve. When you do, AgEnD checks the request, the target machine and your sign-in again, then runs it once.",
44
- approve: "Approve", reject: "Reject", deciding: "Working…", expiresIn: "expires in {0} min", expiresSoon: "expires in under a minute",
45
- applying: "Being applied…", openAgent: "Open the new agent's chat", decided: "Decided here", failedReason: "Reason: {0}",
46
- f_runtime: "Runs on", f_machine: "Machine", f_thisPc: "This PC (Windows)", f_topic_name: "Name", f_backend: "CLI", f_model: "Model", f_directory: "Folder",
47
- f_sandbox: "Access", f_description: "Description", f_display_name: "Display name", f_tags: "Tags", sb_read_only: "read-only", sb_workspace_write: "can write in its folder",
48
- createWindows: "Create a Windows agent", changeAgent: "Change {0}",
49
- r_applied: "Approved: the change is applied.", r_rejected: "Rejected: nothing was changed.", r_withdrawn: "Withdrawn by the agent: nothing was changed.",
50
- r_expired: "This request ran out before it was decided: nothing was changed.", r_fleet_stopped: "The fleet stopped before it was applied: nothing was changed.",
51
- r_request_no_longer_current: "The request is no longer current (the fleet or the Windows switch changed): nothing was changed.",
52
- r_settings_changed: "The settings changed since the request: nothing was changed.", r_apply_failed: "It could not be applied.",
53
- e_owner_required: "Only this fleet's owner, signed in on the AgEnD computer itself, can decide an agent's request.",
54
- e_confirmation_not_pending: "This request was already decided or ran out.", e_not_found: "This request is no longer here.",
37
+ typePrompt: "Fleet prompt", typeAwaiting: "At its terminal", typeInstance: "Instance", typeDelivery: "Delivery", typeMissed: "Missed while offline",
55
38
  },
56
39
  "zh-TW": {
57
40
  title: "等你處理", empty: "目前沒有需要你處理的事", emptyHint: "agent 在等你時,會出現在這裡——也會出現在聊天 app 的 General。", emptyHintWeb: "agent 在等你時,會出現在這裡。",
58
- open: "開啟聊天", openCard: "打開卡片", noAssignee: "任務看板(沒有負責人)", fleetSignIns: "Fleet 登入", signIn: "登入",
41
+ open: "開啟聊天", kiroOpen: "開啟 Agent", kiroMigration: "遷移說明", openCard: "打開卡片", noAssignee: "任務看板(沒有負責人)", fleetSignIns: "Fleet 登入", signIn: "登入",
59
42
  gap: "還沒補齊:{0}", gapUnchecked: "還有 {0} 項沒勾", gapNoResult: "沒有產出總結", gapJoin: "、", acknowledge: "確認", acknowledging: "確認中…", answering: "回覆中…",
60
43
  ageNow: "剛剛", ageMin: "{0} 分鐘", ageHour: "{0} 小時", ageDay: "{0} 天",
61
44
  notifyTitle: "在這台裝置通知我", notifyOn: "這個瀏覽器的通知已開啟(需要開著分頁)。",
@@ -64,22 +47,18 @@ register("needs", {
64
47
  notifyMobile: "在手機上請以聊天 app 的通知為主:每個新項目都會在 General 發一則新訊息。", notifyMobileWeb: "在手機上請打開這個頁面查看等你處理的事。",
65
48
  notifyInsecure: "通知需要安全的網址(localhost 或 HTTPS 公開連結),區網的一般 HTTP 網址不行。",
66
49
  notifyUnsupported: "這個瀏覽器無法顯示通知。", turnOn: "開啟", turnOff: "關閉",
67
- typePrompt: "Fleet 提示", typeAwaiting: "在終端機上", typeInstance: "Instance", typeDelivery: "傳送",
68
- proposals: "代理人的請求", proposalFrom: "{0} 的請求", proposalHint: "在你核准之前,不會建立或修改任何東西。核准時,AgEnD 會再次檢查這個請求、目標電腦和你的登入,然後只執行一次。",
69
- approve: "核准", reject: "拒絕", deciding: "處理中…", expiresIn: "{0} 分鐘後過期", expiresSoon: "不到一分鐘後過期",
70
- applying: "正在套用…", openAgent: "開啟新 agent 的聊天", decided: "已在這裡決定", failedReason: "原因:{0}",
71
- f_runtime: "執行於", f_machine: "電腦", f_thisPc: "這台電腦(Windows)", f_topic_name: "名稱", f_backend: "CLI", f_model: "模型", f_directory: "資料夾",
72
- f_sandbox: "存取權限", f_description: "說明", f_display_name: "顯示名稱", f_tags: "標籤", sb_read_only: "唯讀", sb_workspace_write: "可寫入它的資料夾",
73
- createWindows: "建立 Windows agent", changeAgent: "修改 {0}",
74
- r_applied: "已核准:變更已套用。", r_rejected: "已拒絕:沒有任何變更。", r_withdrawn: "agent 已撤回:沒有任何變更。",
75
- r_expired: "這個請求在決定前就過期了:沒有任何變更。", r_fleet_stopped: "套用前 fleet 已停止:沒有任何變更。",
76
- r_request_no_longer_current: "這個請求已不再有效(fleet 或 Windows 開關已改變):沒有任何變更。",
77
- r_settings_changed: "提出請求後設定已變更:沒有任何變更。", r_apply_failed: "無法套用。",
78
- e_owner_required: "只有在 AgEnD 這台電腦上登入的 fleet 擁有者,才能決定 agent 的請求。",
79
- e_confirmation_not_pending: "這個請求已經被決定或已過期。", e_not_found: "這個請求已不在這裡。",
50
+ typePrompt: "Fleet 提示", typeAwaiting: "在終端機上", typeInstance: "Instance", typeDelivery: "傳送", typeMissed: "離線時錯過",
80
51
  },
81
52
  });
82
53
  const tn = (k, ...v) => t(`needs.${k}`, ...v);
54
+ /** Stale shells keep the old app-i18n.js; a missing key would otherwise show as app.needs_reason_*. */
55
+ function itemReason(item) {
56
+ const text = reasonText(item);
57
+ if (typeof text === "string" && text.startsWith("app.needs_reason_") && (item.type === "missed" || item.reason === "missed_offline")) {
58
+ return tn("typeMissed");
59
+ }
60
+ return text;
61
+ }
83
62
 
84
63
  /**
85
64
  * The page's claims on what Needs you writes, kept for the life of the page — not of a panel or a render (#1463
@@ -115,7 +94,7 @@ const setClaim = (kind, key, value) => claims.set((c) => {
115
94
  return { ...c, [kind]: next };
116
95
  });
117
96
 
118
- const ICON = { prompt: "chat", awaiting_input: "clock", instance: "alert", delivery: "send", task: "tasks" };
97
+ const ICON = { prompt: "chat", awaiting_input: "clock", instance: "alert", delivery: "send", task: "tasks", missed: "clock" };
119
98
  const BAD = new Set(["crashed", "delivery_failed", "hang", "exited"]);
120
99
 
121
100
  /**
@@ -152,21 +131,9 @@ export function groupNeeds(items) {
152
131
  return [...groups.values()];
153
132
  }
154
133
 
155
- /**
156
- * alpha.2 (M-2300): what this page decided, kept for the life of the page — the request's id → "busy" while its POST is
157
- * out, then the server's answer ({ view, agent, message }): it stays shown after the list drops the request.
158
- */
159
- export const decisions = createStore({});
160
-
161
134
  export function NeedsPanel({ navKey }) {
162
135
  const lease = useLease(navKey);
163
- const { needs, chatOwner: owner, instances, connections, proposals } = useStore(appStore);
164
- // A tab opened before an upgrade has this panel but not the app.js that installs the list (it never set `proposals`):
165
- // install it here then. On a current page app.js already did, and this panel reads nothing itself (#1374).
166
- useEffect(() => { if (appStore.get().proposals === undefined) installProposals(); }, []);
167
- const asks = Array.isArray(proposals) ? proposals : [];
168
- const done = useStore(decisions);
169
- const decidedHere = Object.entries(done).filter(([id, d]) => d && d !== "busy" && !asks.some((p) => p.id === id));
136
+ const { ready, needsLoaded, needs, chatOwner: owner, instances, connections } = useStore(appStore);
170
137
  // #1854: a fleet with no chat connection (web only, or not known yet) has no General to point at.
171
138
  const chatApp = connections > 0;
172
139
  const names = useStore(namesStore);
@@ -182,14 +149,9 @@ export function NeedsPanel({ navKey }) {
182
149
  const groups = groupNeeds(items);
183
150
  const nowMs = Date.now();
184
151
  return html`<div data-effect-panel="needs" class="panel p-needs">
185
- <${PanelHeader} title=${tn("title")} sub=${items.length + asks.length ? t("app.needsCount", items.length + asks.length) : null} />
152
+ <${PanelHeader} title=${tn("title")} sub=${items.length ? t("app.needsCount", items.length) : null} />
186
153
  <div data-trust="panel-content" class="panel-body"><div class="col">
187
- ${asks.length || decidedHere.length ? html`<section class="n-group n-proposals" aria-label=${tn("proposals")}>
188
- <h2 class="n-group-head">${tn("proposals")}</h2>
189
- ${asks.map((p) => html`<${ProposalItem} key=${p.id} proposal=${p} nowMs=${nowMs} />`)}
190
- ${decidedHere.map(([id, d]) => html`<${ProposalResult} key=${id} result=${d} />`)}
191
- </section>` : null}
192
- ${!items.length && !asks.length && !decidedHere.length ? html`<${Empty} icon="check" title=${tn("empty")} hint=${tn(chatApp ? "emptyHint" : "emptyHintWeb")} />`
154
+ ${(!ready || needsLoaded === false) && !items.length ? html`<${Skeleton} variant="rows" lines=${3} />` : !items.length ? html`<${Empty} icon="check" title=${tn("empty")} hint=${tn(chatApp ? "emptyHint" : "emptyHintWeb")} />`
193
155
  : groups.map((g) => html`<section key=${JSON.stringify([g.instance, g.items[0]?.type === "config"])} class="n-group" aria-label=${g.instance}>
194
156
  <h2 class="n-group-head">${g.instance ? html`<a href=${chatPath(g.instance)} title=${g.instance}>${nameFor(g.instance)}</a>` : g.items[0]?.type === "config" ? t("app.settings") : tn(g.items.some(i => i.type === "backend") ? "fleetSignIns" : "noAssignee")}</h2>
195
157
  ${g.items.map((item) => html`<${NeedsItem} key=${item.id} item=${item} nowMs=${nowMs} owner=${owner} />`)}
@@ -241,126 +203,22 @@ function NeedsItem({ item, nowMs, owner }) {
241
203
  return html`<article data-trust="permission" class=${`n-item${BAD.has(item.reason) ? " bad" : ""}`}>
242
204
  <span class="n-icon"><${Icon} name=${ICON[item.type] || "alert"} size=${18} /></span>
243
205
  <div class="n-body">
244
- <div class="n-title"><strong>${reasonText(item)}</strong><span class="n-age">${age(item.since, nowMs)}</span></div>
206
+ <div class="n-title"><strong>${itemReason(item)}</strong><span class="n-age">${age(item.since, nowMs)}</span></div>
245
207
  ${detailOf(item) ? html`<p class="n-detail">${detailOf(item)}</p>` : null}
246
- ${item.generalLocation ? html`<${GeneralLocation} name=${item.instance} attentionOnly=${true} />` : null}
247
208
  <div class="n-actions">
248
209
  ${item.type === "prompt" && Array.isArray(item.actions) ? item.actions.filter((a) => !a.input).map((a) => html`<button key=${a.id} type="button" class="btn btn-sm"
249
210
  disabled=${promptBusy} onClick=${() => answer(a.id)}>${(p ? p.busy : fallback === "busy") ? tn("answering") : a.label}</button>`) : null}
250
- ${item.type === "delivery" ? html`<button type="button" class="btn btn-sm" disabled=${!!ack} onClick=${acknowledge}>
211
+ ${item.type === "delivery" || item.type === "missed" ? html`<button type="button" class="btn btn-sm" disabled=${!!ack} onClick=${acknowledge}>
251
212
  <${Icon} name="check" size=${14} />${ack === "busy" ? tn("acknowledging") : tn("acknowledge")}</button>` : null}
252
213
  ${(item.reason === "auth_paused" || item.reason === "backend_signin") && item.signIn && signInOffered() ? html`<button type="button" class="btn btn-sm btn-primary" onClick=${() => openSignIn(item.signIn)}>${tn("signIn")}</button>` : null}
253
214
  ${item.type === "task" && item.card ? html`<a class="btn btn-sm" href=${`/ui/fleet?card=${encodeURIComponent(item.card.code)}`}>${tn("openCard")}</a>` : null}
254
- ${item.instance ? html`<a class="btn btn-sm btn-ghost" href=${chatPath(item.instance)}>${tn("open")}</a>` : null}
255
- </div>
256
- </div>
257
- </article>`;
258
- }
259
-
260
- /**
261
- * alpha.2 (M-2300): the request's summary as the owner reads it (junsion's §6: the machine, the CLI, the model, the
262
- * folder, the access). The server's lines are the settings diff, escaped for a chat's markdown ("new\_instance.directory:
263
- * absent → C:\\work"): here, unescaped and named — a create's fields as "Folder: C:\work", "Machine: This PC" when it
264
- * names none; a change's as "Model: a → b"; any other line as it is. Text only (rendered as text, never markup).
265
- */
266
- export function proposalLines(summary) {
267
- const unescape = (s) => String(s).replace(/\\([\\`*_~[\]()<>|])/g, "$1").replace(/\[at\]/g, "@");
268
- const lines = (Array.isArray(summary) ? summary : []).map(unescape);
269
- const create = lines.some((l) => /^POST \/ui\/instances$/.test(l));
270
- const out = [], label = (k) => { const key = `f_${k}`, s = tn(key); return s === `needs.${key}` ? k : s; };
271
- // The access field's values, in words (matched by value: the two the request's schema allows).
272
- const ACCESS = { "read-only": "sb_read_only", "workspace-write": "sb_workspace_write" };
273
- const value = (_k, v) => (Object.hasOwn(ACCESS, v) ? tn(ACCESS[v]) : v);
274
- let machine = false;
275
- for (const l of lines) {
276
- if (/^POST \/ui\/instances$/.test(l)) continue;
277
- const m = /^new_instance\.([A-Za-z_]+): absent → (.*)$/.exec(l);
278
- if (m) { if (m[1] === "machineId") machine = true; out.push(`${label(m[1] === "machineId" ? "machine" : m[1])}: ${value(m[1], m[2])}`); continue; }
279
- const ch = /^(\S+) ([A-Za-z_]+): (.*) → (.*)$/.exec(l);
280
- if (ch) { out.push(`${tn("changeAgent", ch[1])} · ${label(ch[2])}: ${ch[3]} → ${ch[4]}`); continue; }
281
- out.push(l);
282
- }
283
- if (create && !machine) out.splice(1, 0, `${label("machine")}: ${tn("f_thisPc")}`);
284
- return create ? [tn("createWindows"), ...out] : out;
285
- }
286
-
287
- /**
288
- * alpha.2 polish: a decided request's outcome in the PAGE's language (the server says it in the fleet's — an English page
289
- * read 「變更已套用。」): by its reason code, else its state; the server's words only for a code this page does not know.
290
- */
291
- export function outcomeText(outcome) {
292
- if (!outcome) return t("app.failed");
293
- for (const code of [outcome.reason_code, outcome.state]) {
294
- if (typeof code !== "string") continue;
295
- const key = `r_${code}`, s = tn(key);
296
- if (s !== `needs.${key}`) return s;
297
- }
298
- return outcome.message || t("app.failed");
299
- }
300
- /** Why a click decided nothing, in the page's language (by the server's error code; its words only as a fallback). */
301
- export function decideErrorText(r) {
302
- const key = r && r.error ? `e_${r.error}` : "";
303
- const s = key ? tn(key) : "";
304
- return key && s !== `needs.${key}` ? s : (r && r.message) || t("app.failed");
305
- }
306
-
307
- /**
308
- * alpha.2 (M-2300): one agent's request waiting for this web-only fleet's owner — what it would do (the server's own
309
- * summary: the machine, the CLI, the model, the folder, the access), when it runs out, and Approve / Reject. One click
310
- * per request on this page (claimed before the POST); the answer is the server's: applied, rejected, run out, already
311
- * decided elsewhere, or failed with its reason.
312
- */
313
- function ProposalItem({ proposal: p, nowMs }) {
314
- const d = useStore(decisions)[p.id];
315
- const busy = d === "busy" || p.state === "applying";
316
- const [failed, setFailed] = useState(null);
317
- const decide = async (decision) => {
318
- if (decisions.get()[p.id]) return; // one POST in flight per request on this page
319
- setFailed(null);
320
- decisions.set((s) => ({ ...s, [p.id]: "busy" }));
321
- const r = await decideProposal(p.id, decision);
322
- // #2997 review (Prism P2): nothing decided (the network failed, the owner was refused, a bad answer) and the request
323
- // still waits — the claim is released and why is said here, so the next click is taken; a decided one is kept.
324
- const decided = r.view && r.view.state !== "pending";
325
- if (!decided) {
326
- decisions.set((s) => { const next = { ...s }; delete next[p.id]; return next; });
327
- setFailed(decideErrorText(r));
328
- return;
329
- }
330
- decisions.set((s) => ({ ...s, [p.id]: { ...r, decision } }));
331
- toast(r.view.outcome ? outcomeText(r.view.outcome) : decideErrorText(r), r.view.state === "applied");
332
- };
333
- const minutes = Math.floor((p.remaining_ms || 0) / 60_000);
334
- return html`<article data-trust="permission" class="n-item">
335
- <span class="n-icon"><${Icon} name="alert" size=${18} /></span>
336
- <div class="n-body">
337
- <div class="n-title"><strong>${tn("proposalFrom", p.requested_by)}</strong><span class="n-age">${age(p.requested_at, nowMs)} · ${minutes >= 1 ? tn("expiresIn", minutes) : tn("expiresSoon")}</span></div>
338
- <ul class="n-detail">${proposalLines(p.summary).map((line, i) => html`<li key=${i}>${line}</li>`)}</ul>
339
- <p class="note">${tn("proposalHint")}</p>
340
- ${failed ? html`<p class="note n-proposal-error" role="alert">${failed}</p>` : null}
341
- <div class="n-actions">
342
- <button type="button" class="btn btn-sm btn-primary" disabled=${busy} onClick=${() => decide("confirm")}>${busy ? (p.state === "applying" ? tn("applying") : tn("deciding")) : tn("approve")}</button>
343
- <button type="button" class="btn btn-sm" disabled=${busy} onClick=${() => decide("reject")}>${tn("reject")}</button>
215
+ ${item.kiroChoice === true ? html`<a class="btn btn-sm" href="https://github.com/songsid/AgEnD/blob/main/src/general-knowledge/skills/kiro-engine-migration/SKILL.md" target="_blank" rel="noopener noreferrer">${tn("kiroMigration")}</a>` : null}
216
+ ${item.instance ? html`<a class="btn btn-sm btn-ghost" href=${chatPath(item.instance)}>${tn(item.kiroChoice === true ? "kiroOpen" : "open")}</a>` : null}
344
217
  </div>
345
218
  </div>
346
219
  </article>`;
347
220
  }
348
221
 
349
- /** A request decided on this page: the server's outcome (and its reason), and the new agent's chat when one was created. */
350
- function ProposalResult({ result: r }) {
351
- const v = r.view, outcome = v && v.outcome;
352
- const ok = !!(v && v.state === "applied");
353
- return html`<article data-trust="permission" class=${`n-item${ok || (v && v.state === "rejected") ? "" : " bad"}`}>
354
- <span class="n-icon"><${Icon} name=${ok ? "check" : "alert"} size=${18} /></span>
355
- <div class="n-body">
356
- <div class="n-title"><strong>${outcome ? outcomeText(outcome) : decideErrorText(r)}</strong><span class="n-age">${tn("decided")}</span></div>
357
- ${v ? html`<ul class="n-detail">${proposalLines(v.summary).map((line, i) => html`<li key=${i}>${line}</li>`)}</ul>` : null}
358
- ${outcome && outcome.detail ? html`<p class="note">${tn("failedReason", outcome.detail)}</p>` : null}
359
- ${ok && r.agent ? html`<div class="n-actions"><a class="btn btn-sm btn-primary" href=${chatPath(r.agent)} title=${r.agent}>${tn("openAgent")}</a></div>` : null}
360
- </div>
361
- </article>`;
362
- }
363
-
364
222
  /** The device's choice, as the page knows it (app-needs.js notifyStore): every mounted toggle shows the same. */
365
223
  function NotifyToggle() {
366
224
  const support = notifySupport();
@@ -8,7 +8,7 @@ import { appStore, applyNoticesSeen, useStore } from "/assets/app-store.js";
8
8
  import { useLease } from "/assets/app-ctx.js";
9
9
  import { PanelHeader, setTitle } from "/assets/app-shell.js";
10
10
  import { chatPath } from "/assets/app-route.js";
11
- import { Empty } from "/assets/ui-states.js";
11
+ import { Empty, ErrorState, Skeleton } from "/assets/ui-states.js";
12
12
  import { Icon } from "/assets/ui-icons.js";
13
13
 
14
14
  register("notices", {
@@ -64,7 +64,7 @@ function markShown() {
64
64
 
65
65
  export function NoticesPanel({ navKey }) {
66
66
  const lease = useLease(navKey);
67
- const { notices, instances } = useStore(appStore);
67
+ const { notices, noticesError, instances, connections } = useStore(appStore);
68
68
  const items = notices && Array.isArray(notices.items) ? notices.items : [];
69
69
  // What was unread when the page opened stays marked "New" while it is open (it is marked read on the server at once).
70
70
  const [seenAtOpen] = useState(() => (notices ? notices.seen | 0 : 0));
@@ -82,7 +82,8 @@ export function NoticesPanel({ navKey }) {
82
82
  <${PanelHeader} title=${tn("title")} />
83
83
  <div data-trust="panel-content" class="panel-body"><div class="col">
84
84
  ${items.length ? html`<p class="note notice-sub">${tn("sub")}</p>` : null}
85
- ${!items.length ? html`<${Empty} icon="bell" title=${tn("empty")} hint=${tn("emptyHint")} />`
85
+ ${!notices && noticesError ? html`<${ErrorState} onRetry=${() => appStore.get().readNotices?.()} />`
86
+ : !notices && (connections == null || connections === 0) ? html`<${Skeleton} variant="rows" lines=${3} />` : !items.length ? html`<${Empty} icon="bell" title=${tn("empty")} hint=${tn("emptyHint")} />`
86
87
  : items.map((n) => html`<article key=${n.id} class=${`n-item notice${n.id > seenAtOpen ? " unread" : ""}${n.kind === "fleet" ? " bad" : ""}`}>
87
88
  <span class="n-icon"><${Icon} name=${ICON[n.kind] || "info"} size=${18} /></span>
88
89
  <div class="n-body">