@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
@@ -56,7 +56,8 @@ if (mode === "full") {
56
56
  // A chat that loaded late catches up on what is open now; the shell shows that while it is not done, with Retry.
57
57
  stream.on("hydration", (hydration) => appStore.set({ hydration }));
58
58
  appStore.set({ retryHydration: () => stream.catchUp() });
59
- stream.on("needs", (d) => appStore.set({ needs: Array.isArray(d && d.items) ? d.items : [] }));
59
+ appStore.set({ needsLoaded: false });
60
+ stream.on("needs", (d) => appStore.set({ needsLoaded: true, needs: Array.isArray(d && d.items) ? d.items : [] }));
60
61
  // #1218: a panel's way to hear one stream event (the Log's steps_tick), unsubscribed by its lease.
61
62
  appStore.set({ streamOn: (name, fn) => stream.on(name, fn) });
62
63
  appStore.set({ connection: stream.connection() });
@@ -85,8 +86,6 @@ if (mode === "full") {
85
86
  let chatLoads = 0;
86
87
  panels.set("chat", { load: () => (chatLoads++ === 0 ? chatBoot : loadChat()).then((m) => m.ChatPanel) });
87
88
  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) });
90
89
  panels.set("fleet", { load: () => loadFleet().then((m) => m.FleetPanel) });
91
90
  panels.set("settings", { load: () => loadSettings().then((m) => m.SettingsPanel) });
92
91
  // #2347: the restart banner's Restart now, in any panel — the Settings runner (behind the session) does it.
@@ -122,8 +121,6 @@ if (mode === "full") {
122
121
  startNeedsNotifier({ open: (instance) => navigate(chatPath(instance)) });
123
122
  // #2233: a backend sign-in running anywhere is shown on every admin page (the module lives behind the session gate).
124
123
  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(), () => {});
127
124
  }
128
125
  // #1665: this device's first upload of its own choices (once), then another device's changes at each status frame.
129
126
  // 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 { appStore, createStore, useStore } from "./app-store.js";
10
+ import { 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,9 +124,7 @@ export function useRailWidth() {
124
124
  export function UsageRail({ route }) {
125
125
  const wide = useRailWidth();
126
126
  const { open } = useStore(usageRailStore);
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;
127
+ if (!wide || !open || !route || !RAIL_PANELS.includes(route.panel) || !usageOffered()) return null;
130
128
  return html`<aside data-trust="usage" class="u-rail" aria-label=${t("view.usage.title_plain")}>
131
129
  <div class="u-rail-head"><h2>${t("view.usage.title")}</h2><${UsageCompactToggle} />
132
130
  <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>
@@ -156,8 +154,8 @@ export function UsageButton({ navKey }) {
156
154
  }
157
155
 
158
156
  /** The shared controls, in the one order every page uses. `navKey`: the page's navigation (the usage dialog's owner). */
159
- export function HeaderTools({ view = false, navKey, usage = true }) {
160
- return html`<${TextSizeButton} view=${view} />${usage ? html`<${UsageButton} navKey=${navKey} />` : null}`;
157
+ export function HeaderTools({ view = false, navKey }) {
158
+ return html`<${TextSizeButton} view=${view} /><${UsageButton} navKey=${navKey} />`;
161
159
  }
162
160
  /** 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. */
163
161
  export function HeaderSlot() {
@@ -18,7 +18,6 @@ import { viewStore } from "./view-roster-store.js";
18
18
  import { onPrefsChanged, prefInForce, prefsWritable, savePref } from "./app-prefs.js";
19
19
  import "./view-strings.js";
20
20
  import { themesShown, themesStore } from "./app-themes.js";
21
- import { machineName } from "./machine-name.js";
22
21
  import { identityClasses, identityOf, paintIdentity, useIdentityColors } from "./identity-color.js";
23
22
 
24
23
  /** view.* text with named values. */
@@ -80,14 +79,6 @@ export function modelText(it, raw = it && it.model) {
80
79
  }
81
80
  const BACKEND_LABELS = { "claude-code": "Claude Code", "kiro-cli": "Kiro CLI", codex: "Codex", grok: "Grok Build", antigravity: "Antigravity", opencode: "OpenCode" };
82
81
  export function backendLabel(backend) { return BACKEND_LABELS[backend] || backend || "Unknown"; }
83
- export function runtimeLabel(runtime) { return runtime === "windows" ? "Windows" : runtime === "wsl" ? "WSL / Linux" : runtime || ""; }
84
- /** Missing capabilities preserve the existing Linux UI; native runtimes expose only implemented controls. */
85
- export function supportsInstanceFeature(instance, feature) {
86
- const key = feature === "view" ? "terminal" : feature;
87
- if (typeof instance?.capabilities?.[key] === "boolean") return instance.capabilities[key];
88
- if (feature === "log" && typeof instance?.capabilities?.terminal === "boolean") return instance.capabilities.terminal;
89
- return instance?.runtime !== "windows" || !["terminal","view","log","details","attachments","commands","effort","send_while_busy"].includes(feature);
90
- }
91
82
  export const KNOWN_BACKENDS = new Set(Object.keys(BACKEND_LABELS));
92
83
  export const STATUS_KEYS = { running: "statusRunning", paused: "statusPaused", stopped: "statusStopped", crashed: "statusCrashed" };
93
84
 
@@ -106,7 +97,7 @@ export function normalizeFilter(query) { return String(query == null ? "" : quer
106
97
  /** Case-insensitive substring on name (incl. display name), model and backend. */
107
98
  export function instanceMatchesFilter(it, needle, labelOf) {
108
99
  if (!needle) return true;
109
- 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];
100
+ const fields = [nameOf(it), it.display_name, it.model, it.backend, labelOf ? labelOf(it.backend) : null];
110
101
  return fields.some((value) => typeof value === "string" && value.toLowerCase().includes(needle));
111
102
  }
112
103
  /**
@@ -145,9 +136,6 @@ export function instanceTooltip(it) {
145
136
  if (it.display_name && it.display_name !== name) lines.push(it.display_name, `(${name})`);
146
137
  else lines.push(name);
147
138
  lines.push(line("tooltipBackend", backendLabel(it.backend)));
148
- if (it.runtime) lines.push(`Runtime: ${runtimeLabel(it.runtime)}`);
149
- if (it.machine_id) lines.push(line("tooltipMachine",machineName(it.machine_id,it.machine_name)));
150
- if (it.machine_id && it.machine_status !== "online") lines.push(tn(it.machine_status === "revoked" ? "machineRevoked" : "machineOffline"));
151
139
  const src = (s) => (s === "instance" || s === "classic" ? tn("srcConfigured") : s === "fleet-default" ? tn("srcFleetDefault") : "");
152
140
  lines.push(line("tooltipModel", (modelText(it) || tn("tooltipUnavailable")) + src(it.model_source)));
153
141
  lines.push(line("tooltipStatus", status));
@@ -295,8 +283,6 @@ function writeFacetsOpen(open) { try { localStorage.setItem(FACETS_KEY, JSON.str
295
283
 
296
284
  /** The Favorites group's key among the tag groups: no tag can be it (a group name is never a control character). */
297
285
  const FAV_GROUP = "\u0000favorites";
298
- /** #3008 G2: a web-only fleet's General (its status row says `general: true`), pinned first under its own head. */
299
- const GENERAL_GROUP = "\u0000general";
300
286
  /** #1936: the open instance, pinned on top while a filter is on. */
301
287
  const PINNED_GROUP = "\u0000pinned";
302
288
  function persistOrder(groupNames, instByGroup) {
@@ -504,11 +490,9 @@ export function InstanceNav({ route, items, loaded = true, exec = {}, awaiting =
504
490
  const [editing, setEditing] = useState(false);
505
491
  // Where a row goes: the view the page is in (#1523 §3.1). View → View; Details → Details; everywhere else, a Fleet tab
506
492
  // included (#1917: the user's call, replacing Q4 = A), → Chat. The anonymous reader only ever has View.
507
- const panelPath = viewOnly || (route && route.panel === "view") ? viewPath
493
+ const rowPath = viewOnly || (route && route.panel === "view") ? viewPath
508
494
  : route && route.panel === "log" ? logPath // #1218: Log → Log
509
495
  : route && route.panel === "details" ? detailsPath : chatPath;
510
- const rowPath = (name) => byName.get(name)?.runtime === "windows" && ["view", "log", "details"].includes(route?.panel)
511
- ? chatPath(name) : panelPath(name);
512
496
  const active = route && (route.panel === "chat" || route.panel === "view" || route.panel === "log" || route.panel === "details") ? route.instance : null;
513
497
  const own = (map, name) => Object.prototype.hasOwnProperty.call(map, name);
514
498
  const byName = new Map(items.map((it) => [nameOf(it), it]));
@@ -518,10 +502,7 @@ export function InstanceNav({ route, items, loaded = true, exec = {}, awaiting =
518
502
  // their order. Changing them: a signed-in page that may write preferences (not the public link, not the anonymous
519
503
  // reader — they still see the list).
520
504
  const known = new Set(byName.keys());
521
- // #3008 G2: the General, when the server marks one (a web-only fleet), comes first — out of every other group.
522
- const general = items.find((it) => it && it.general === true);
523
- const generalName = general ? nameOf(general) : null;
524
- const favs = nav.favorites.filter((n) => known.has(n) && n !== generalName);
505
+ const favs = nav.favorites.filter((n) => known.has(n));
525
506
  const favSet = new Set(favs);
526
507
  const canStar = !viewOnly && prefsWritable("nav.favorites");
527
508
  // #1920: a guest's list is not reordered (the order is the host's). #2855: it stars, sorts and filters as its own
@@ -539,15 +520,14 @@ export function InstanceNav({ route, items, loaded = true, exec = {}, awaiting =
539
520
  let shownGroups, shownInsts;
540
521
  if (recent) {
541
522
  const sortRecent = byRecentReply(ageOf);
542
- const rest = groupNames.flatMap((g) => instByGroup.get(g) || []).filter((n) => !favSet.has(n) && n !== generalName).sort(sortRecent);
523
+ const rest = groupNames.flatMap((g) => instByGroup.get(g) || []).filter((n) => !favSet.has(n)).sort(sortRecent);
543
524
  shownGroups = [...(favs.length ? [FAV_GROUP] : []), ...(rest.length ? [RECENT_GROUP] : [])];
544
525
  shownInsts = new Map([[FAV_GROUP, favsSorted ? [...favs].sort(sortRecent) : favs], [RECENT_GROUP, rest]]);
545
526
  } else {
546
527
  shownGroups = favs.length ? [FAV_GROUP, ...groupNames] : groupNames;
547
- shownInsts = new Map([...instByGroup].map(([g, names]) => [g, names.filter((n) => !favSet.has(n) && n !== generalName)]));
528
+ shownInsts = new Map([...instByGroup].map(([g, names]) => [g, names.filter((n) => !favSet.has(n))]));
548
529
  if (favs.length) shownInsts.set(FAV_GROUP, favs);
549
530
  }
550
- if (generalName) { shownGroups = [GENERAL_GROUP, ...shownGroups]; shownInsts.set(GENERAL_GROUP, [generalName]); }
551
531
  const f = nav.filter;
552
532
  const shown = filterSidebar(shownGroups, shownInsts, byName, f.q, backendLabel, { status: f.status, cli: f.cli, statusOf: facetOf });
553
533
  // #1936: while a filter is on, the instance you have open stays on top, pinned and marked "Current", whether or not
@@ -609,9 +589,7 @@ export function InstanceNav({ route, items, loaded = true, exec = {}, awaiting =
609
589
  const row = (name, g, i, count) => {
610
590
  const it = byName.get(name);
611
591
  // #1722: both names, the preferred one first; one line when there is no other.
612
- const preferred = namesOf(it, names.primary);
613
- const label = it.runtime === "windows" ? it.display_name || preferred.primary : preferred.primary;
614
- const secondary = it.runtime === "windows" ? backendLabel(it.backend) : preferred.secondary;
592
+ const { primary: label, secondary } = namesOf(it, names.primary);
615
593
  const facet = facetOf(name);
616
594
  const waiting = own(awaiting, name) ? awaiting[name] : null;
617
595
  const on = name === active;
@@ -628,10 +606,9 @@ export function InstanceNav({ route, items, loaded = true, exec = {}, awaiting =
628
606
  aria-current=${on ? "page" : undefined} onClick=${onPick} ...${fav ? {} : dragProps({ type: "instance", name, group: g })}>
629
607
  <${InstanceAvatar} it=${it} state=${dotState(it, own(exec, name) ? exec[name] : null, waiting)} cli=${true} />
630
608
  <span class="inst-text"><span class="inst-line"><span class="inst-name" title=${label}>${label}</span>
631
- <span class="v-meta">${it.runtime === "windows" ? "Windows" : it.context_pct != null ? `${Math.round(it.context_pct)}%` : ""}</span></span>
609
+ <span class="v-meta">${it.context_pct != null ? `${Math.round(it.context_pct)}%` : ""}</span></span>
632
610
  ${two ? html`<span class="inst-line inst-line2"><span class="inst-alt" title=${secondary || undefined}>${secondary || ""}</span>
633
611
  ${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}
634
- ${it.machine_id ? html`<span class=${`inst-machine${it.machine_status !== "online" ? " offline" : ""}`} title=${tn("tooltipMachine",{value:machineName(it.machine_id,it.machine_name)})}><span class="inst-machine-name">${machineName(it.machine_id,it.machine_name)}</span>${it.machine_status !== "online" ? html`<span class="inst-machine-status">${tn(it.machine_status === "revoked" ? "machineRevoked" : "machineOffline")}</span>` : null}</span>` : null}
635
612
  ${facet === "needs" ? html`<span class="inst-sub"><span class="badge-await" title=${waiting || t("app.approxNote")}>${t("app.needsYou")}</span></span>` : null}
636
613
  <span class="sr-only">${tn("tooltipBackend", { value: backendLabel(it.backend) })}</span></span>
637
614
  </a>${fav && editing && canStar ? html`<button type="button" class="icon-btn inst-move" aria-label=${tn("favUp", { name: label })}
@@ -662,10 +639,6 @@ export function InstanceNav({ route, items, loaded = true, exec = {}, awaiting =
662
639
  if (g === RECENT_GROUP) return html`<div key=${g} class="v-group v-recent" role="group" aria-label=${tn("recentOthers")}>
663
640
  <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>
664
641
  <ul class="inst-list">${names.map((name, i) => row(name, g, i, names.length))}</ul></div>`;
665
- // #3008 G2: the General — always open, first, not dragged or starred into another place.
666
- if (g === GENERAL_GROUP) return html`<div key=${g} class="v-group v-general" role="group" aria-label=${tn("generalGroup")}>
667
- <div class="v-group-head general-head"><span class="grow">${tn("generalGroup")}</span></div>
668
- <ul class="inst-list">${names.map((name, i) => row(name, g, i, names.length))}</ul></div>`;
669
642
  // #1664: Favorites — always open, not dragged (↑ ↓ in Edit), named in the page's language.
670
643
  if (g === FAV_GROUP) return html`<div key=${g} class="v-group v-fav" role="group" aria-label=${tn("favorites")}>
671
644
  <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,20 +7,19 @@ 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";
11
10
 
12
11
  /**
13
12
  * current: "chat" | "view" | "log" | "details". #1218: Log sits between View and Details. `data-label`: each tab is as
14
13
  * wide as its label in the current tab's weight (app.css), so the bar keeps its size whichever tab is current.
15
14
  */
16
- export function InstanceSwitch({ name, current, guest = false, instance }) {
15
+ export function InstanceSwitch({ name, current, guest = false }) {
17
16
  const seg = (key, href, label) => html`<a key=${key} class=${`seg-item${current === key ? " active" : ""}`} href=${href}
18
17
  aria-current=${current === key ? "page" : undefined} data-label=${label}>${label}</a>`;
19
18
  if (guest) return html`<nav class="inst-switch seg" aria-label=${t("app.instanceViews", name)}>
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"
19
+ ${seg("chat", chatPath(name), t("app.chat"))}${seg("view", viewPath(name), t("app.view"))}<button key="search" type="button" class="seg-item"
21
20
  data-label=${t("app.search")} onClick=${() => openSearch({ instance: name })}>${t("app.search")}</button>
22
21
  </nav>`;
23
22
  return html`<nav class="inst-switch seg" aria-label=${t("app.instanceViews", name)}>
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}
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"))}
25
24
  </nav>`;
26
25
  }
@@ -0,0 +1,37 @@
1
+ /* The shared Skeleton's calm content shapes, including before the app's modules arrive. No shimmer or spinner. */
2
+ .skeleton { box-sizing: border-box; width: 100%; min-width: 0; }
3
+ .skeleton > [aria-hidden] { display: flex; flex-direction: column; gap: 14px; width: 100%; }
4
+ .skeleton .sk-line { height: 14px; flex-shrink: 0; background: var(--surface-2, #e8e8eb); border-radius: 5px; }
5
+ .sk-row { display: flex; align-items: center; gap: 12px; min-height: 64px; padding: 8px 0; }
6
+ .sk-row .sk-thumb { width: 36px; height: 36px; border-radius: 9px; }
7
+ .sk-row .sk-copy { display: flex; flex: 1; min-width: 0; flex-direction: column; gap: 9px; }
8
+ .sk-row .sk-copy .sk-line { width: 76%; height: 12px; }
9
+ .sk-row .sk-copy .sk-line + .sk-line { width: 51%; height: 10px; }
10
+ .sk-row .sk-pill { width: 52px; height: 22px; border-radius: 99px; }
11
+ .sk-cards .sk-row { min-height: 104px; border-bottom: 1px solid var(--border, #ddd); }
12
+ .sk-inline { max-width: 140px; min-width: 90px; padding: 0; margin: 0; }
13
+ .s-profile { position: relative; }
14
+ .s-profile-fields { display: flex; flex-direction: column; gap: var(--s-3, 12px); }
15
+ .sk-reserve { visibility: hidden; pointer-events: none; }
16
+ .sk-profile-cover { position: absolute; inset: 52px 16px 16px; }
17
+ .s-pref-profile-fields > .sk-profile-cover { inset: 0; }
18
+ .sk-profile-cover .skeleton { padding: 0; margin: 0; max-width: none; }
19
+ .sk-form .sk-line:nth-child(3) { width: 100%; height: 40px; }
20
+ .sk-form .sk-line:nth-child(4) { width: 48%; height: 32px; border-radius: 99px; }
21
+ .sk-boot { display: flex; height: 100dvh; background: var(--bg, #f6f6f8); }
22
+ .sk-boot-side { width: var(--sidebar-w, 248px); padding: 28px 20px; border-right: 1px solid var(--border, #ddd); }
23
+ .sk-boot-main { flex: 1; min-width: 0; }
24
+ .sk-boot-head { height: 64px; border-bottom: 1px solid var(--border, #ddd); }
25
+ .sk-boot-head .sk-line { width: 160px; }
26
+ .sk-boot .skeleton { margin: 0; max-width: 760px; opacity: 1; animation: none; }
27
+ .sk-boot .sk-line { height: 14px; background: var(--surface-2, #e8e8eb); }
28
+ .signin-card { position: relative; }
29
+ /* Reserve the real, translated form's size while the session is checked; hidden fields cannot be focused. */
30
+ .signin-card:has(#checking:not([hidden])) #form[hidden] { display: block !important; visibility: hidden; pointer-events: none; }
31
+ .sk-signin { position: absolute; inset: 72px 24px 28px; width: auto; padding: 0; margin: 0; max-width: none; }
32
+ .sk-signin > [aria-hidden] { gap: 18px; }
33
+ .sk-signin .sk-line:first-child { width: 70%; height: 26px; }
34
+ .sk-signin .sk-line:nth-child(3) { width: 100%; height: 48px; }
35
+ .sk-signin .sk-line:nth-child(4) { width: 100%; height: 42px; border-radius: 99px; }
36
+ @media (max-width: 899px) { .sk-boot-side { display: none; } }
37
+ @media (prefers-reduced-motion: reduce) { .skeleton { animation: none; opacity: 1; } }
@@ -282,6 +282,13 @@ const REDRAWS_IN_PLACE = new Set(["grok"]);
282
282
  const FULL_SCREEN = new Set(["claude-code", "opencode", "grok"]); // agy: its chat UI unverified — found by the read
283
283
  /** The full-screen CLIs whose earlier output the Log tab shows (it reads their transcript: log-service.ts). */
284
284
  const LOG_HAS_HISTORY = new Set(["claude-code"]);
285
+ /**
286
+ * Claude history in the View (view-history.js): the full-screen CLIs whose View shows their earlier conversation from
287
+ * their transcript, above the live screen. A server without it (an older one) leaves them as before: no scrollback.
288
+ */
289
+ const TRANSCRIPT_HISTORY = new Set(["claude-code"]);
290
+ /** How near the top (px) a history being read asks for the page before it. */
291
+ const OLDER_AT_PX = 48;
285
292
  /**
286
293
  * M-2267 option (2), the leader's safe default: where a full-screen CLI's earlier output is — its Log tab (or that the
287
294
  * Log tab is off, and where to turn it on). Only for whom the Log tab is (a signed-in session on the full app; never a
@@ -304,8 +311,11 @@ function Terminal({ name, lease, density, every = 800, backend = "", signedIn =
304
311
  const [newBelow, setNewBelow] = useState(false);
305
312
  const [historyNote, setHistoryNoteState] = useState(null);
306
313
  // A CLI found to keep no scrollback (full screen): nothing is offered or read again for it; the note says why, briefly.
307
- const [noScrollback, setNoScrollback] = useState(FULL_SCREEN.has(backend));
308
- const noScrollbackRef = useRef(FULL_SCREEN.has(backend));
314
+ const keepsNone = FULL_SCREEN.has(backend) && !TRANSCRIPT_HISTORY.has(backend);
315
+ const [noScrollback, setNoScrollback] = useState(keepsNone);
316
+ const noScrollbackRef = useRef(keepsNone);
317
+ // Claude history in the View: the history shown while reading (view-history.js's createHistory), or null.
318
+ const transcript = useRef(null);
309
319
  const logLink = logLinkFor(name, backend, signedIn);
310
320
  const noteTimer = useRef(null);
311
321
  const setHistoryNote = (note, brief = false) => {
@@ -402,6 +412,7 @@ function Terminal({ name, lease, density, every = 800, backend = "", signedIn =
402
412
  // The person asked for what scrolled off: one bounded read, then reading (or why there is nothing to read).
403
413
  const loadEarlier = useRef(null);
404
414
  const follow = useRef(null);
415
+ const olderPage = useRef(null);
405
416
  useEffect(() => {
406
417
  const reads = readStream(lease);
407
418
  const refresh = async () => {
@@ -439,6 +450,7 @@ function Terminal({ name, lease, density, every = 800, backend = "", signedIn =
439
450
  const from = modeRef.current;
440
451
  if (from !== "follow" && !(from === "reading" && !screenAt.current.history)) return;
441
452
  if (noScrollbackRef.current) { setHistoryNote(tn("noEarlier"), true); return; } // known: nothing to read
453
+ if (TRANSCRIPT_HISTORY.has(backend)) { await loadTranscript(from); return; }
442
454
  const box0 = term.current;
443
455
  // Where the person is, measured from the end: the screen's lines stay where they are under the scrollback added.
444
456
  const fromEnd = box0 ? box0.scrollHeight - box0.scrollTop : 0;
@@ -477,8 +489,65 @@ function Terminal({ name, lease, density, every = 800, backend = "", signedIn =
477
489
  }
478
490
  } catch { if (lease.current()) { back(); setHistoryNote(tn("earlierFailed"), true); } }
479
491
  };
492
+ /**
493
+ * Claude history in the View: the conversation before the live screen, from the transcript (the renderer is its own
494
+ * lazy module), drawn above the screen as it is now — then reading, as for a scrollback. Older pages come as the
495
+ * person nears the top. A server without it: this CLI keeps no scrollback, as before.
496
+ */
497
+ const loadTranscript = async (from) => {
498
+ const back = () => { setMode(from); if (from === "follow") toBottom(); };
499
+ const screen = screenAt.current.drawn == null ? "" : screenAt.current.drawn;
500
+ setMode("loading"); setHistoryNote(tn("loadingEarlier"));
501
+ try {
502
+ const mod = await import("./view-history.js");
503
+ if (!lease.current() || modeRef.current !== "loading" || !pre.current) return;
504
+ let h = null;
505
+ h = mod.createHistory({ name, fetch: (u) => lease.fetch(u), alive: () => lease.current() && transcript.current === h,
506
+ doc: document, font: getComputedStyle(pre.current).fontFamily, cols: grid.current.cols });
507
+ transcript.current = h;
508
+ const got = await h.first(screen);
509
+ if (!lease.current() || modeRef.current !== "loading" || !pre.current || transcript.current !== h) return;
510
+ if (got.kind !== "ok") {
511
+ transcript.current = null;
512
+ if (got.kind === "unsupported") { noScrollbackRef.current = true; setNoScrollback(true); back(); setHistoryNote(tn("noEarlier"), true); return; }
513
+ back();
514
+ setHistoryNote(got.kind === "empty" ? tn("nothingEarlier") : got.status === 429 ? null : tn("earlierFailed"), true);
515
+ return;
516
+ }
517
+ screenAt.current.reading = screen; screenAt.current.history = true;
518
+ setNewBelow(screenAt.current.latest != null && !sameScreen(screen, screenAt.current.latest));
519
+ setMode("reading"); setHistoryNote(null);
520
+ draw(screen); // the screen as it is (the one frame write), then the history above it
521
+ pre.current.insertBefore(h.root, pre.current.firstChild);
522
+ fit();
523
+ const box = term.current;
524
+ if (box) {
525
+ const px = parseFloat(getComputedStyle(pre.current).fontSize);
526
+ const lineH = Number.isFinite(px) && px > 0 ? px * 1.2 : 16;
527
+ // The history's last lines and the divider right above the screen.
528
+ box.scrollTop = Math.max(0, box.scrollHeight - box.clientHeight - lineH * 3);
529
+ }
530
+ } catch { if (lease.current() && modeRef.current === "loading") { transcript.current = null; back(); setHistoryNote(tn("earlierFailed"), true); } }
531
+ };
532
+ /** The page before the history shown, above it — where the person is stays where it is. */
533
+ let olderBusy = false;
534
+ olderPage.current = async () => {
535
+ const h = transcript.current, box = term.current;
536
+ if (olderBusy || !h || !box || modeRef.current !== "reading" || !screenAt.current.history) return;
537
+ olderBusy = true;
538
+ const fromEnd = box.scrollHeight - box.scrollTop;
539
+ const capped = !h.hasOlder();
540
+ if (!capped) setHistoryNote(tn("loadingEarlier"));
541
+ try {
542
+ const got = await h.older();
543
+ if (!lease.current() || transcript.current !== h) return;
544
+ box.scrollTop = Math.max(0, box.scrollHeight - fromEnd);
545
+ if (!capped) setHistoryNote(got.kind === "failed" ? tn("earlierFailed") : null, got.kind === "failed");
546
+ } finally { olderBusy = false; }
547
+ };
480
548
  follow.current = () => {
481
549
  if (modeRef.current === "follow") return;
550
+ transcript.current = null;
482
551
  setMode("follow"); setNewBelow(false); setHistoryNote(null); screenAt.current.history = false;
483
552
  const latest = screenAt.current.latest;
484
553
  if (latest != null && pre.current) { draw(latest); fit(); }
@@ -501,7 +570,9 @@ function Terminal({ name, lease, density, every = 800, backend = "", signedIn =
501
570
  // Asking for the earlier output: from following, or from reading the screen as it was — at the top.
502
571
  const mayLoad = () => (modeRef.current === "follow" || (modeRef.current === "reading" && !screenAt.current.history)) && box.scrollTop <= 0;
503
572
  const gesture = () => { gestureAt.current = performance.now(); };
504
- lease.on(box, "wheel", (e) => { gesture(); if (e.deltaY < 0 && mayLoad()) loadEarlier.current(); }, { passive: true });
573
+ // Claude's history being read, at (or near) its top: the page before it.
574
+ const nearTop = () => modeRef.current === "reading" && screenAt.current.history && transcript.current && box.scrollTop <= OLDER_AT_PX;
575
+ lease.on(box, "wheel", (e) => { gesture(); if (e.deltaY < 0 && mayLoad()) loadEarlier.current(); else if (e.deltaY < 0 && nearTop()) olderPage.current(); }, { passive: true });
505
576
  let touchY = null;
506
577
  lease.on(box, "touchstart", (e) => { gesture(); touchY = e.touches && e.touches[0] ? e.touches[0].clientY : null; }, { passive: true });
507
578
  lease.on(box, "touchmove", (e) => {
@@ -509,15 +580,17 @@ function Terminal({ name, lease, density, every = 800, backend = "", signedIn =
509
580
  const y = e.touches && e.touches[0] ? e.touches[0].clientY : null;
510
581
  if (touchY == null || y == null) return;
511
582
  if (y - touchY > 24 && mayLoad()) { touchY = null; loadEarlier.current(); }
583
+ else if (y - touchY > 24 && nearTop()) { touchY = null; olderPage.current(); }
512
584
  }, { passive: true });
513
585
  lease.on(box, "pointerdown", gesture, { passive: true }); // the scrollbar, dragged
514
586
  lease.on(box, "keydown", (e) => {
515
587
  gesture();
516
588
  if ((e.key === "PageUp" || e.key === "ArrowUp" || e.key === "Home") && mayLoad()) { e.preventDefault(); loadEarlier.current(); }
589
+ else if ((e.key === "PageUp" || e.key === "ArrowUp" || e.key === "Home") && nearTop()) olderPage.current();
517
590
  else if (modeRef.current === "reading" && e.key === "End") { e.preventDefault(); follow.current(); }
518
591
  });
519
592
  lease.on(box, "scroll", () => {
520
- if (modeRef.current === "reading") { if (atBottom()) follow.current(); return; }
593
+ if (modeRef.current === "reading") { if (atBottom()) follow.current(); else if (nearTop()) olderPage.current(); return; }
521
594
  // #2969 review (Prism P2): a screen taller than its box (a larger Aa), moved up from the bottom by the person:
522
595
  // reading what is on it — the refresh no longer pulls them back down.
523
596
  if (modeRef.current === "follow" && recentGesture() && !atBottom()) startReading(screenAt.current.drawn, false);
@@ -27,12 +27,6 @@
27
27
  hint_web: "On the AgEnD computer, run agend web --code to get a sign-in code.",
28
28
  refused_web: "The code is invalid or no longer works. Run agend web --code on the AgEnD computer for a new one.",
29
29
  resend_refused_web: "A new code could not be sent. Run agend web --code on the AgEnD computer for one.",
30
- // #3008: through the link "Allow connections from outside" opened — the authenticator app's code (the leader's wording).
31
- label_outside: "Authenticator code", lead_outside: "Open your authenticator app and enter the 6-digit code for AgEnD.",
32
- hint_outside: "Lost your phone? On the AgEnD computer, choose \u201cSet up again\u201d.",
33
- refused_outside: "That code didn't work. Check that your phone's clock is right and try the newest code.",
34
- paused_outside: "Too many wrong codes. Try again in {duration}.",
35
- minutes: "{0} minutes", minute: "1 minute", hours: "{0} hours", hour: "1 hour",
36
30
  },
37
31
  "zh-TW": {
38
32
  checking: "正在確認登入狀態…", title: "登入 AgEnD", lead: "輸入登入碼。",
@@ -50,35 +44,16 @@
50
44
  hint_web: "在 AgEnD 電腦上執行 agend web --code 取得登入碼。",
51
45
  refused_web: "登入碼無效或已失效。請在 AgEnD 電腦上執行 agend web --code 取得新碼。",
52
46
  resend_refused_web: "無法傳送新的登入碼。請在 AgEnD 電腦上執行 agend web --code 取得。",
53
- label_outside: "驗證器代碼", lead_outside: "打開驗證器 App,輸入 AgEnD 的 6 位數代碼。",
54
- hint_outside: "手機遺失?請在 AgEnD 電腦上選「重新設定」。",
55
- refused_outside: "代碼不對。請確認手機時間正確,並輸入最新的代碼。",
56
- paused_outside: "錯誤次數太多,請 {duration} 後再試。",
57
- minutes: "{0} 分鐘", minute: "1 分鐘", hours: "{0} 小時", hour: "1 小時",
58
47
  },
59
48
  };
60
49
  const lang = /^zh/i.test(navigator.language || "") ? "zh-TW" : "en";
61
50
  // #2910 D5: the server marks a web-only fleet's page (<body data-web-only="1">): its own words where it has them.
62
51
  const webOnly = !!document.body && document.body.getAttribute("data-web-only") === "1";
63
- // #3008: …and one served through the link "Allow connections from outside" opened (<body data-outside="1">): signing in
64
- // is the authenticator app's code, posted to /auth/totp.
65
- const outside = webOnly && document.body.getAttribute("data-outside") === "1";
66
- const t = (k) => (outside && (T[lang][`${k}_outside`] || T.en[`${k}_outside`])) || (webOnly && (T[lang][`${k}_web`] || T.en[`${k}_web`])) || T[lang][k] || T.en[k] || k;
67
- /** A wait as words: "15 minutes" / 「15 分鐘」, "2 hours" / 「2 小時」 (rounded up). */
68
- const duration = (ms) => {
69
- const minutes = Math.max(1, Math.ceil(ms / 60000));
70
- if (minutes < 60) return minutes === 1 ? t("minute") : t("minutes").replace("{0}", String(minutes));
71
- const hours = Math.ceil(minutes / 60);
72
- return hours === 1 ? t("hour") : t("hours").replace("{0}", String(hours));
73
- };
52
+ const t = (k) => (webOnly && (T[lang][`${k}_web`] || T.en[`${k}_web`])) || T[lang][k] || T.en[k] || k;
74
53
  // …and no "No chat bot?" help: the hint above already is it.
75
54
  if (webOnly) document.querySelectorAll("details.help").forEach((d) => { if (d.querySelector && d.querySelector('[data-i18n="nobot"]')) d.hidden = true; });
76
55
  document.documentElement.lang = lang === "zh-TW" ? "zh-Hant" : "en";
77
- if (outside) {
78
- const input = $("code");
79
- input.setAttribute("inputmode", "numeric"); input.setAttribute("maxlength", "7"); input.setAttribute("placeholder", "123456");
80
- input.setAttribute("pattern", "[0-9 ]*");
81
- }
56
+ $("checking").setAttribute?.("aria-label", t("checking"));
82
57
 
83
58
  // An old dashboard link carries `?token=`. It is not a credential any more (the server ignored it and
84
59
  // answered with this page), but it is still the fleet's token: take it out of the address bar and
@@ -151,10 +126,8 @@
151
126
  offerResend();
152
127
  }
153
128
 
154
- // Only a returning device gets the button; the answer is a boolean and asking has no side effect. Never from outside
155
- // (#3008): the code there is the app's, nothing is sent.
129
+ // Only a returning device gets the button; the answer is a boolean and asking has no side effect.
156
130
  async function offerResend() {
157
- if (outside) return;
158
131
  try {
159
132
  const r = await fetch("/auth/device", { credentials: "same-origin", cache: "no-store" });
160
133
  if (r.ok && (await r.json()).returning === true) $("resend").hidden = false;
@@ -201,24 +174,18 @@
201
174
  button.disabled = true;
202
175
  button.textContent = t("working");
203
176
  try {
204
- const r = await fetch(outside ? "/auth/totp" : "/auth/login", {
177
+ const r = await fetch("/auth/login", {
205
178
  method: "POST",
206
179
  credentials: "same-origin",
207
180
  headers: { "Content-Type": "application/json" },
208
181
  body: JSON.stringify({ code: $("code").value }),
209
182
  });
210
183
  if (r.ok) { clearBounce(); location.replace(nextTarget()); return; }
211
- if (outside && r.status === 429) {
212
- let wait = Number(r.headers.get("Retry-After")) * 1000;
213
- try { const body = await r.json(); if (Number.isFinite(body && body.retryAfterMs)) wait = body.retryAfterMs; } catch { /* the header's */ }
214
- msg.textContent = t("paused").replace("{duration}", duration(Number.isFinite(wait) && wait > 0 ? wait : 60000));
215
- throw "shown";
216
- }
217
184
  // #1854: a 5xx is the server failing to confirm the sign-in (503: a public link's notice did not go out), not a
218
185
  // wrong code — say so. The code is spent either way: the way on is a new one.
219
186
  msg.textContent = r.status === 429 ? t("paused") : r.status >= 500 ? t("unconfirmed") : t("refused");
220
- } catch (err) {
221
- if (err !== "shown") msg.textContent = t("network");
187
+ } catch {
188
+ msg.textContent = t("network");
222
189
  }
223
190
  button.disabled = false;
224
191
  button.textContent = t("submit");
@@ -46,7 +46,6 @@
46
46
 
47
47
  /* ── Layout ── */
48
48
  --col: 768px; /* the conversation column */
49
- --settings-width: 1200px; /* settings workspace, including its horizontal padding */
50
49
  --sidebar-w: 260px;
51
50
  --header-h: 52px;
52
51
  --tap: 44px; /* the smallest touch target on a phone */
@@ -10,7 +10,7 @@ import { t } from "./app-i18n.js";
10
10
  * <${Dialog} title="Create task" onClose=${…} actions=${html`…`}>…body…</${Dialog}>
11
11
  * Rendered = open; the parent unmounts it to close. `busy` keeps Esc and the backdrop from closing it mid-request.
12
12
  */
13
- export function Dialog({ title, onClose, actions, children, busy = false, wide = false, drawer = false, label, tools = null, cls = "" }) {
13
+ export function Dialog({ title, onClose, actions, children, busy = false, wide = false, drawer = false, label, tools = null }) {
14
14
  const ref = useRef(null);
15
15
  const opener = useRef(null);
16
16
  const busyRef = useRef(busy);
@@ -41,7 +41,7 @@ export function Dialog({ title, onClose, actions, children, busy = false, wide =
41
41
  d.addEventListener("click", onClick);
42
42
  return () => { d.removeEventListener("cancel", onCancel); d.removeEventListener("click", onClick); };
43
43
  }, [onClose]);
44
- return html`<dialog data-trust="dialog" ref=${ref} class=${`dlg${wide ? " dlg-wide" : ""}${drawer ? " dlg-drawer" : ""}${cls ? ` ${cls}` : ""}`} aria-label=${label || title}>
44
+ return html`<dialog data-trust="dialog" ref=${ref} class=${`dlg${wide ? " dlg-wide" : ""}${drawer ? " dlg-drawer" : ""}`} aria-label=${label || title}>
45
45
  <div class="dlg-box" tabindex="-1">
46
46
  <div class="dlg-head"><h2 class="dlg-title">${title}</h2>${tools ? html`<span class="dlg-tools">${tools}</span>` : null}
47
47
  <button type="button" class="icon-btn dlg-x" aria-label=${t("app.close")} title=${t("app.close")} onClick=${() => { if (!busyRef.current) onClose(); }}><${Icon} name="close" /></button></div>
@@ -1,6 +1,6 @@
1
1
  // #1408 §7: the ⋯ menu — a button and a list of actions. Arrow keys move, Enter/Space choose, Esc closes and puts focus
2
2
  // back on the button. Esc inside the menu is the menu's: it never reaches the app (e.g. never stops an agent's reply).
3
- import { html, useEffect, useLayoutEffect, useRef, useState } from "./app-html.js";
3
+ import { html, useEffect, useRef, useState } from "./app-html.js";
4
4
  import { Icon } from "./ui-icons.js";
5
5
  import { t } from "./app-i18n.js";
6
6
 
@@ -8,54 +8,34 @@ import { t } from "./app-i18n.js";
8
8
  * items: [{ key, label, icon?, onSelect, danger?, disabled? }] (falsy entries are skipped). `checked` makes a radio item;
9
9
  * `checkbox: true` with `checked` a checkbox item (#2217 hotfix: the chat's card menu), which toggles and keeps the menu
10
10
  * open. `active`: the button shows a pressed look (what it controls is on), without changing its role.
11
- * Optional `trigger` and `triggerClass` customize the button content and styling; `label` remains its accessible name.
12
11
  */
13
- export function Menu({ items, label, icon = "more", cls = "", active = false, trigger, triggerClass = "icon-btn", disabled = false, fit = false }) {
12
+ export function Menu({ items, label, icon = "more", cls = "", active = false }) {
14
13
  const [open, setOpen] = useState(false);
15
- const [placement,setPlacement] = useState("");
16
14
  const btn = useRef(null), list = useRef(null);
17
15
  const shown = (items || []).filter(Boolean);
18
- useLayoutEffect(() => {
19
- if (!open || !fit || !btn.current?.getBoundingClientRect || !list.current) return;
20
- const place = () => {
21
- if (!btn.current || !list.current) return;
22
- const rect = btn.current.getBoundingClientRect();
23
- const boundary = btn.current.closest?.(".dlg-body")?.getBoundingClientRect();
24
- const top = Math.max(0,boundary?.top || 0), bottom = Math.min(window.innerHeight,boundary?.bottom || window.innerHeight);
25
- const above = rect.top-top-8, below = bottom-rect.bottom-8;
26
- const up = below < Math.min(list.current.scrollHeight || 280,280) && above > below;
27
- const available = up ? above : below;
28
- setPlacement(`${up ? " menu-up" : ""}${available < 180 ? " menu-short" : available < 280 ? " menu-compact" : ""}`);
29
- };
30
- place();
31
- window.addEventListener("resize",place);
32
- return () => window.removeEventListener("resize",place);
33
- },[open,fit]);
34
16
  useEffect(() => {
35
- if (!open || disabled) { if (open && disabled) setOpen(false); return undefined; }
17
+ if (!open) return undefined;
36
18
  const first = list.current && list.current.querySelector("[role=menuitem]:not([disabled]), [role=menuitemradio]:not([disabled]), [role=menuitemcheckbox]:not([disabled])");
37
- if (first) first.focus({ preventScroll: true });
19
+ if (first) first.focus();
38
20
  const outside = (e) => { if (list.current && !list.current.contains(e.target) && btn.current && !btn.current.contains(e.target)) setOpen(false); };
39
21
  document.addEventListener("pointerdown", outside, true);
40
22
  return () => document.removeEventListener("pointerdown", outside, true);
41
- }, [open, disabled]);
23
+ }, [open]);
42
24
  function onKey(e) {
43
25
  const all = [...list.current.querySelectorAll("[role=menuitem]:not([disabled]), [role=menuitemradio]:not([disabled]), [role=menuitemcheckbox]:not([disabled])")];
44
26
  const i = all.indexOf(document.activeElement);
45
- if (e.key === "Escape") { e.preventDefault(); e.stopPropagation(); setOpen(false); btn.current && btn.current.focus({ preventScroll: true }); }
46
- else if (e.key === "Enter" || e.key === " ") { e.preventDefault(); document.activeElement?.click(); }
27
+ if (e.key === "Escape") { e.preventDefault(); e.stopPropagation(); setOpen(false); btn.current && btn.current.focus(); }
47
28
  else if (e.key === "ArrowDown") { e.preventDefault(); (all[(i + 1) % all.length] || all[0])?.focus(); }
48
29
  else if (e.key === "ArrowUp") { e.preventDefault(); (all[(i - 1 + all.length) % all.length] || all[0])?.focus(); }
49
30
  else if (e.key === "Home") { e.preventDefault(); all[0]?.focus(); }
50
31
  else if (e.key === "End") { e.preventDefault(); all[all.length - 1]?.focus(); }
51
32
  else if (e.key === "Tab") setOpen(false);
52
33
  }
53
- function choose(item) { if (disabled || item.disabled) return; setOpen(false); btn.current && btn.current.focus({ preventScroll: true }); item.onSelect(); }
34
+ function choose(item) { setOpen(false); btn.current && btn.current.focus(); item.onSelect(); }
54
35
  return html`<div class=${`menu ${cls}`}>
55
- <button ref=${btn} type="button" class=${`${triggerClass}${active ? " active" : ""}`} aria-haspopup="menu" aria-expanded=${open ? "true" : "false"} disabled=${disabled}
56
- aria-label=${label || t("app.more")} title=${label || t("app.more")} onClick=${() => { if (!disabled) setOpen(!open); }}
57
- onKeyDown=${(e) => { if (!disabled && (e.key === "ArrowDown" || e.key === "ArrowUp")) { e.preventDefault(); setOpen(true); } }}>${trigger === undefined ? html`<${Icon} name=${icon} />` : trigger}</button>
58
- ${open && !disabled ? html`<div data-trust="menu" ref=${list} class=${`menu-list${fit ? placement : ""}`} role="menu" aria-label=${label || t("app.more")} onKeyDown=${onKey}>
36
+ <button ref=${btn} type="button" class=${`icon-btn${active ? " active" : ""}`} aria-haspopup="menu" aria-expanded=${open ? "true" : "false"}
37
+ aria-label=${label || t("app.more")} title=${label || t("app.more")} onClick=${() => setOpen(!open)}><${Icon} name=${icon} /></button>
38
+ ${open ? html`<div data-trust="menu" ref=${list} class="menu-list" role="menu" aria-label=${label || t("app.more")} onKeyDown=${onKey}>
59
39
  ${shown.map(item => item.heading
60
40
  ? html`<div key=${item.key} class="menu-heading" role="presentation">${item.label}</div>`
61
41
  : item.checkbox
@@ -3,9 +3,20 @@ import { html } from "./app-html.js";
3
3
  import { Icon } from "./ui-icons.js";
4
4
  import { t } from "./app-i18n.js";
5
5
 
6
- /** Placeholder lines while something loads. Shown only after 300 ms (CSS), so a fast load never flashes. */
7
- export function Skeleton({ lines = 3 }) {
8
- return html`<div class="skeleton" aria-busy="true" aria-label=${t("app.loading")}>${Array.from({ length: lines }, (_, i) => html`<div key=${i} class="sk-line"></div>`)}</div>`;
6
+ // Lazy panels can arrive in a shell with an older app.css. Keep the loading shapes in their own public stylesheet.
7
+ function loadingStyles() {
8
+ if (typeof document === "undefined" || !document.head || document.querySelector('link[href="/assets/loading.css"]')) return;
9
+ const link = document.createElement("link"); link.setAttribute("rel", "stylesheet"); link.setAttribute("href", "/assets/loading.css");
10
+ document.head.appendChild(link);
11
+ }
12
+ /** Initial data only: retain populated content on refresh. Existing callers still get simple text lines. */
13
+ export function Skeleton({ lines = 3, variant = "lines", label }) {
14
+ loadingStyles();
15
+ return html`<div class=${`skeleton sk-${variant}`} role="status" aria-busy="true" aria-label=${label || t("app.loading")}>
16
+ <div aria-hidden="true">${Array.from({ length: lines }, (_, i) => variant === "rows" || variant === "cards"
17
+ ? html`<div key=${i} class="sk-row"><div class="sk-line sk-thumb"></div><div class="sk-copy"><div class="sk-line"></div><div class="sk-line"></div></div><div class="sk-line sk-pill"></div></div>`
18
+ : html`<div key=${i} class="sk-line"></div>`)}</div>
19
+ </div>`;
9
20
  }
10
21
 
11
22
  export function Empty({ icon = "info", title, hint, action }) {