@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
@@ -14,11 +14,20 @@ register("fusage", {
14
14
  en: {
15
15
  range: "Range", today: "Today", r7d: "7 days", month: "This month", all: "All", custom: "Custom", from: "From", to: "To", apply: "Apply",
16
16
  group: "Group by", g_instance: "Agent", g_backend: "Backend", g_model: "Model", g_profile: "Credential profile", g_team: "Team (as configured now)",
17
- csv: "Download CSV", basis: "API-equivalent at list price (checked {0}) — not money spent. Subscriptions are not billed per token.",
17
+ csv: "Download CSV", basis: "API-equivalent at list price ({0}) — not money spent.", basisMore: "Subscriptions are not billed per token.",
18
18
  amount: "API-equivalent", input: "Input", output: "Output", reasoning: "Reasoning", read: "Cache read", write: "Cache write", total: "Total tokens", requests: "Requests", messages: "Messages",
19
19
  notPriced: "not priced", partial: "partial", noTeam: "(no team)", unknown: "unknown",
20
- f_cache_write_not_reported: "cache writes not reported (Codex, Muse) — an estimate", f_not_priced: "not priced: {0}", f_source_unknown: "read before backend and profile were recorded",
21
- f_estimated: "estimated from text size — Kiro records no token counts", f_includes_estimates: "includes estimates (Kiro)", f_cost_reported: "amount as the CLI reported it (no list price for this model)", estimatedPart: "of which estimated: {0}",
20
+ // #3066 §3: what a row's numbers are, said once each as a small mark with its tooltip (never a pill per row).
21
+ t_not_priced: "Not priced: {0}", t_partial: "Part of this row's models have no price", t_write_unreported: "Codex/Muse don't report cache writes",
22
+ t_cost_reported: "Amount as the CLI reported it", t_estimated: "Estimated from text size (Kiro records no token counts)", t_reasoning_none: "Not reported by this CLI",
23
+ sourceNote: "Some hours were read before AgEnD recorded their backend and profile.", profileUnrecorded: "profile not recorded",
24
+ l_partial: "◐ partly priced", l_cost_reported: "† amount from the CLI", l_estimated: "≈ estimated",
25
+ // #3066 §2: output speed (Claude after the first token, Codex over the response window).
26
+ speed: "Speed", speedUnit: "{0} tok/s", speedCoverage: "{0} of {1} requests timed", speedSpread: "p10–p90: {0}–{1} tok/s",
27
+ speedNone: "no timing in its transcripts", speedByModel: "Speed by model",
28
+ speedBasis: "Output tokens ÷ the model's own response time (tool time excluded); method after tokdash.",
29
+
30
+ f_includes_estimates: "includes estimates (Kiro)", estimatedPart: "of which estimated: {0}",
22
31
  scanning: "Scanning — totals may still grow.", updated: "Updated {0} · read every 10 min", since: "Collected since {0}", notYet: "Not collected yet",
23
32
  refresh: "Refresh",
24
33
  notMeasured: "Not measured", nm_credit_billed: "Kiro is credit-billed and records no tokens", nm_unsupported: "AgEnD can't read this CLI's usage yet", nm_no_data: "nothing read yet",
@@ -42,11 +51,18 @@ register("fusage", {
42
51
  "zh-TW": {
43
52
  range: "期間", today: "今天", r7d: "7 天", month: "本月", all: "全部", custom: "自訂", from: "從", to: "到", apply: "套用",
44
53
  group: "分組", g_instance: "Agent", g_backend: "Backend", g_model: "模型", g_profile: "憑證 profile", g_team: "Team(依目前設定)",
45
- csv: "下載 CSV", basis: "依牌價換算的 API 等值(查證日期 {0})——不是實際花費。訂閱方案不按 token 計費。",
54
+ csv: "下載 CSV", basis: "依牌價換算的 API 等值({0})——不是實際花費。", basisMore: "訂閱方案不按 token 計費。",
46
55
  amount: "API 等值", input: "輸入", output: "輸出", reasoning: "推理", read: "快取讀取", write: "快取寫入", total: "token 總計", requests: "請求數", messages: "訊息數",
47
56
  notPriced: "未定價", partial: "部分", noTeam: "(不屬於任何 team)", unknown: "未知",
48
- f_cache_write_not_reported: "未回報快取寫入(Codex、Muse)——是估算", f_not_priced: "未定價:{0}", f_source_unknown: "讀取時尚未記錄 backend 與 profile",
49
- f_estimated: "依文字長度估算——Kiro 不記錄 token 數", f_includes_estimates: "含估算值(Kiro)", f_cost_reported: "金額為 CLI 自行回報(價目表沒有此模型)", estimatedPart: "其中估算:{0}",
57
+ t_not_priced: "未定價:{0}", t_partial: "這一列有部分模型沒有價格", t_write_unreported: "Codex/Muse 不回報快取寫入",
58
+ t_cost_reported: "金額為 CLI 自行回報", t_estimated: "依文字長度估算(Kiro 不記錄 token 數)", t_reasoning_none: "這個 CLI 不回報",
59
+ sourceNote: "部分時段在 AgEnD 記錄 backend 與 profile 之前就已讀取。", profileUnrecorded: "未記錄 profile",
60
+ l_partial: "◐ 部分定價", l_cost_reported: "† 金額由 CLI 回報", l_estimated: "≈ 估算值",
61
+ speed: "速度", speedUnit: "{0} token/秒", speedCoverage: "{1} 個請求中有 {0} 個可計時", speedSpread: "p10–p90:{0}–{1} token/秒",
62
+ speedNone: "transcript 沒有計時資訊", speedByModel: "各模型速度",
63
+ speedBasis: "輸出 token ÷ 模型本身的回應時間(不含工具執行時間);方法參考 tokdash。",
64
+
65
+ f_includes_estimates: "含估算值(Kiro)", estimatedPart: "其中估算:{0}",
50
66
  scanning: "掃描中——總數可能還會增加。", updated: "更新於 {0} · 每 10 分鐘讀取一次", since: "自 {0} 起收集", notYet: "尚未收集",
51
67
  refresh: "重新整理",
52
68
  notMeasured: "未量測", nm_credit_billed: "Kiro 以 credit 計費,不記錄 token", nm_unsupported: "AgEnD 目前還讀不到這個 CLI 的用量", nm_no_data: "尚未讀到任何資料",
@@ -95,10 +111,6 @@ export function keyText(group, key) {
95
111
  return key;
96
112
  }
97
113
  const writes = (r) => (r.cacheWrite5m || 0) + (r.cacheWrite1h || 0) + (r.cacheWrite || 0);
98
- function flagText(f, r) {
99
- if (f === "not_priced") return tu("f_not_priced", (r.unpriced || []).join(", "));
100
- return ["cache_write_not_reported", "source_unknown", "estimated", "includes_estimates", "cost_reported"].includes(f) ? tu(`f_${f}`) : f;
101
- }
102
114
 
103
115
  // ── CSV (design §4): the daily rows of this same answer; messages on their own rows (they are per agent, not per model).
104
116
  const CSV_COLUMNS = ["date", "zone", "instance", "backend", "model", "tier", "profile", "input", "output", "reasoning", "cache_read", "cache_write_5m", "cache_write_1h", "cache_write", "requests", "messages", "amount", "basis", "flags", "estimated"];
@@ -318,25 +330,73 @@ function Heatmap({ report, dates }) {
318
330
  </section>`;
319
331
  }
320
332
 
321
- function Row({ r, group, max, measure }) {
333
+ /**
334
+ * A mark with what it means: shown as its sign, said (title, and aria-label for readers) as words. role="img" makes it
335
+ * nameable (#3067 review, Prism P3: aria-label is not allowed on a generic span).
336
+ */
337
+ const mark = (sign, words, cls = "us-mark") => html`<span class=${cls} role="img" title=${words} aria-label=${words}>${sign}</span>`;
338
+ /** "—" that says why there is no number (nameable the same way). */
339
+ const dash = (words) => html`<span class="us-none" role="img" title=${words} aria-label=${words}>—</span>`;
340
+ /** The marks a row's numbers carry (#3066 §3): ◐ partly priced, † the CLI's own amount, ≈ estimated. */
341
+ export function rowMarks(r) {
342
+ const flags = r.flags || [];
343
+ return { partial: r.priced === "partial", cost: flags.includes("cost_reported"), est: flags.includes("estimated") || r.estimated === true,
344
+ writeUnreported: flags.includes("cache_write_not_reported") && writes(r) === 0, unpriced: r.amount === null || r.amount === undefined };
345
+ }
346
+ /** A profile as shown: Codex's older hours were never tagged with one. */
347
+ const profileText = (p) => (p === "unrecorded" ? tu("profileUnrecorded") : p);
348
+
349
+ function Row({ r, group, max, measure, cols }) {
322
350
  const share = max > 0 ? Math.max(0.01, measure(r) / max) : 0;
323
- const meta = [r.backends.join(", "), r.models.join(", "), r.profiles.join(", ")].filter(Boolean).join(" · ");
351
+ const meta = [r.backends.join(", "), r.models.join(", "), r.profiles.map(profileText).join(", ")].filter(Boolean).join(" · ");
352
+ const m = rowMarks(r);
353
+ // Estimated rows (Kiro): every number is an estimate — "≈" before each, the reason in its tooltip.
354
+ const num = (text) => (m.est ? html`${mark("≈", tu("t_estimated"), "us-mark us-approx")}${text}` : text);
355
+ const key = group === "profile" ? profileText(keyText(group, r.key)) : keyText(group, r.key);
324
356
  return html`<tr class="us-row">
325
- <th scope="row" class="us-name"><span class="mono">${keyText(group, r.key)}</span>
357
+ <th scope="row" class="us-name"><span class="mono">${key}</span>
326
358
  <svg class="us-bar" aria-hidden="true"><rect class="us-bar-bg" width="100%" height="6" rx="3" /><rect class="us-bar-fg" width=${`${Math.round(share * 100)}%`} height="6" rx="3" /></svg>
327
- ${group !== "instance" || meta ? html`<span class="us-meta">${meta}</span>` : null}
328
- ${r.flags.length ? html`<span class="us-flags">${r.flags.map((f) => html`<span key=${f} class="ch-tag">${flagText(f, r)}</span>`)}</span>` : null}</th>
329
- <td data-label=${tu("amount")} class=${`num${r.amount === null ? " muted" : ""}`}>${amountText(r)}</td>
330
- <td data-label=${tu("input")} class="num">${tokens(r.input)}</td>
331
- <td data-label=${tu("output")} class="num">${tokens(r.output)}</td>
332
- <td data-label=${tu("reasoning")} class="num">${r.reasoningReported === false ? "—" : tokens(r.reasoning || 0)}</td>
333
- <td data-label=${tu("read")} class="num">${tokens(r.cacheRead)}</td>
334
- <td data-label=${tu("write")} class="num">${r.flags.includes("cache_write_not_reported") && writes(r) === 0 ? "—" : tokens(writes(r))}</td>
335
- <td data-label=${tu("total")} class="num">${tokens(r.total)}</td>
359
+ ${group !== "instance" || meta ? html`<span class="us-meta">${meta}</span>` : null}</th>
360
+ <td data-label=${tu("amount")} class=${`num${m.unpriced ? " muted" : ""}`}>${m.unpriced ? dash(tu("t_not_priced", (r.unpriced || []).join(", "))) : html`${num(money(r.amount))}${m.partial ? mark("◐", tu("t_partial")) : null}${m.cost ? mark("†", tu("t_cost_reported")) : null}`}</td>
361
+ <td data-label=${tu("input")} class="num">${num(tokens(r.input))}</td>
362
+ <td data-label=${tu("output")} class="num">${num(tokens(r.output))}</td>
363
+ ${cols.reasoning ? html`<td data-label=${tu("reasoning")} class="num">${r.reasoningReported === false ? dash(tu("t_reasoning_none")) : num(tokens(r.reasoning || 0))}</td>` : null}
364
+ <td data-label=${tu("read")} class="num">${num(tokens(r.cacheRead))}</td>
365
+ <td data-label=${tu("write")} class="num">${m.writeUnreported ? dash(tu("t_write_unreported")) : num(tokens(writes(r)))}</td>
366
+ <td data-label=${tu("total")} class="num">${num(tokens(r.total))}</td>
336
367
  <td data-label=${tu("requests")} class="num">${n(r.requests)}</td>
337
- <td data-label=${tu("messages")} class="num">${r.messages === null ? "—" : n(r.messages)}</td>
368
+ ${cols.messages ? html`<td data-label=${tu("messages")} class="num">${r.messages === null ? "—" : n(r.messages)}</td>` : null}
369
+ ${cols.speed ? html`<td data-label=${tu("speed")} class="num">${r.speed ? speedText(r.speed) : dash(tu("speedNone"))}</td>` : null}
338
370
  </tr>`;
339
371
  }
372
+ /** #3066 §2: a rate as shown — whole tok/s, one decimal below 10. */
373
+ export const speedText = (s) => tu("speedUnit", s.tokPerSec >= 10 ? Math.round(s.tokPerSec).toLocaleString("en-US") : s.tokPerSec.toFixed(1));
374
+ /** Columns worth a place (#3066 §3): Reasoning only when some row reports it; Messages only when some row has them; Speed (§2) only when some response was timed. */
375
+ export function usageColumns(rows) {
376
+ return { reasoning: rows.some((r) => r.reasoningReported !== false), messages: rows.some((r) => r.messages !== null && r.messages !== undefined),
377
+ speed: rows.some((r) => !!r.speed) };
378
+ }
379
+ /** #3066 §2: each model's speed — rate · requests timed (coverage) · p10–p90 from 30 timed. */
380
+ function SpeedCard({ report }) {
381
+ const list = report.speedByModel || [];
382
+ if (!list.length) return null;
383
+ return html`<section class="us-speed card" aria-labelledby="us-speed-h">
384
+ <h3 id="us-speed-h">${tu("speedByModel")}</h3>
385
+ <ul class="rows">${list.map((m) => html`<li key=${m.model} class="row-item"><span class="grow strong mono">${m.model}</span>
386
+ <span class="num">${speedText(m.speed)}</span>
387
+ <span class="muted">${[m.requests > 0 ? tu("speedCoverage", n(m.speed.timedRequests), n(m.requests)) : null,
388
+ m.speed.p10 !== null && m.speed.p90 !== null ? tu("speedSpread", Math.round(m.speed.p10), Math.round(m.speed.p90)) : null].filter(Boolean).join(" · ")}</span></li>`)}</ul>
389
+ <p class="note">${tu("speedBasis")}</p>
390
+ </section>`;
391
+ }
392
+ /** The legend under the table: only the marks that appear, and the one footnote when an hour's source was not recorded. */
393
+ function Legend({ rows }) {
394
+ const marks = rows.map(rowMarks);
395
+ const parts = [marks.some((m) => m.partial) && tu("l_partial"), marks.some((m) => m.cost) && tu("l_cost_reported"), marks.some((m) => m.est) && tu("l_estimated")].filter(Boolean);
396
+ const source = rows.some((r) => (r.flags || []).includes("source_unknown"));
397
+ if (!parts.length && !source) return null;
398
+ return html`<p class="note us-key">${parts.join(" · ")}${parts.length && source ? html`<br />` : null}${source ? tu("sourceNote") : null}</p>`;
399
+ }
340
400
 
341
401
  /** The tab's body for one answer of GET /ui/usage-report. */
342
402
  export function UsageReport({ report, choice, setChoice, refresh, fetchedAt }) {
@@ -355,6 +415,7 @@ export function UsageReport({ report, choice, setChoice, refresh, fetchedAt }) {
355
415
  const zones = zonesChanged(report);
356
416
  const csvFrom = report.dailyTruncated ? report.dailyFrom : report.range.kind === "all" ? "all" : report.range.from;
357
417
  const rows = report.rows.filter((r) => r.total > 0 || (r.messages || 0) > 0);
418
+ const cols = usageColumns(rows);
358
419
  const anyAmount = rows.some((r) => r.amount !== null && r.amount > 0);
359
420
  const measure = (r) => (anyAmount ? r.amount || 0 : r.total);
360
421
  const max = Math.max(0, ...rows.map(measure));
@@ -375,7 +436,7 @@ export function UsageReport({ report, choice, setChoice, refresh, fetchedAt }) {
375
436
  <label>${tu("from")} <input type="date" value=${draft.from} max=${draft.to} onInput=${(e) => setDraft({ ...draft, from: e.target.value })} /></label>
376
437
  <label>${tu("to")} <input type="date" value=${draft.to} min=${draft.from} onInput=${(e) => setDraft({ ...draft, to: e.target.value })} /></label>
377
438
  <button type="submit" class="btn btn-sm">${tu("apply")}</button></form>` : null}
378
- <p class="us-basis" role="note">${tu("basis", report.pricesChecked)}</p>
439
+ <p class="us-basis" role="note" title=${tu("basisMore")}>${tu("basis", report.pricesChecked)}</p>
379
440
  ${noDaily ? html`<p class="us-partial" role="status">${tu("noDaily")}</p>` : report.dailyTruncated ? html`<p class="us-partial" role="status">${tu("partialDays", report.dailyFrom)}</p>` : null}
380
441
  ${zones ? html`<p class="us-partial" role="status">${tu("zoneChanged", zones.join(", "), report.zone)}</p>` : null}
381
442
  <p class="note us-fresh">${tu("updated", new Date(fetchedAt).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }))} · ${Number.isFinite(since) ? tu("since", new Date(since).toLocaleDateString()) : tu("notYet")} · ${tu("zoneNote", report.zone)}${group === "team" ? ` ${tu("teamsNote")}` : ""}
@@ -389,10 +450,12 @@ export function UsageReport({ report, choice, setChoice, refresh, fetchedAt }) {
389
450
  <div class="ch-metric"><dt>${tu("messages")}</dt><dd>${report.totals.messages === null ? "—" : n(report.totals.messages)}</dd></div>
390
451
  </dl>
391
452
  ${rows.length ? html`<table class="us-table"><thead><tr><th scope="col">${tu(`g_${group}`)}</th><th scope="col" class="num">${tu("amount")}</th>
392
- <th scope="col" class="num">${tu("input")}</th><th scope="col" class="num">${tu("output")}</th><th scope="col" class="num">${tu("reasoning")}</th><th scope="col" class="num">${tu("read")}</th><th scope="col" class="num">${tu("write")}</th>
393
- <th scope="col" class="num">${tu("total")}</th><th scope="col" class="num">${tu("requests")}</th><th scope="col" class="num">${tu("messages")}</th></tr></thead>
394
- <tbody>${rows.map((r) => html`<${Row} key=${r.key} r=${r} group=${group} max=${max} measure=${measure} />`)}</tbody></table>`
453
+ <th scope="col" class="num">${tu("input")}</th><th scope="col" class="num">${tu("output")}</th>${cols.reasoning ? html`<th scope="col" class="num">${tu("reasoning")}</th>` : null}<th scope="col" class="num">${tu("read")}</th><th scope="col" class="num">${tu("write")}</th>
454
+ <th scope="col" class="num">${tu("total")}</th><th scope="col" class="num">${tu("requests")}</th>${cols.messages ? html`<th scope="col" class="num">${tu("messages")}</th>` : null}${cols.speed ? html`<th scope="col" class="num">${tu("speed")}</th>` : null}</tr></thead>
455
+ <tbody>${rows.map((r) => html`<${Row} key=${r.key} r=${r} group=${group} max=${max} measure=${measure} cols=${cols} />`)}</tbody></table>
456
+ <${Legend} rows=${rows} />`
395
457
  : html`<p class="note">${tu("noRows")}</p>`}
458
+ <${SpeedCard} report=${report} />
396
459
  <${Trend} report=${report} dates=${dates} />
397
460
  <${Heatmap} report=${report} dates=${dates} />`}
398
461
  ${report.notMeasured.length || report.shared.length ? html`<section class="us-rest" aria-labelledby="us-rest-h"><h3 id="us-rest-h">${tu("notMeasured")}</h3>
@@ -1,5 +1,3 @@
1
- import { NativePaneRecovery } from "./native-pane-recovery.js";
2
- import { GeneralLocation } from "./general-location.js";
3
1
  // #1408 step 1: the chat panel. Behind the session gate (/ui/js/), loaded by the app with a dynamic import in "full"
4
2
  // mode only. boot() runs once per page (the chat store must hear the stream from the first frame); <ChatPanel> mounts
5
3
  // for /ui and /ui/chat/<name>.
@@ -13,10 +11,9 @@ import { lang, t } from "/assets/app-i18n.js";
13
11
  import { appStore, createStore, guestPage, guestTrusted, useStore } from "/assets/app-store.js";
14
12
  import { ComposerAuth } from "/assets/web-authorize.js";
15
13
  import { useLease } from "/assets/app-ctx.js";
16
- import { modelText, namesOf, namesStore, navStore as instanceNavStore, supportsInstanceFeature } from "/assets/instance-nav.js";
17
- import { machineName } from "/assets/machine-name.js";
14
+ import { modelText, namesOf, namesStore, navStore as instanceNavStore } from "/assets/instance-nav.js";
18
15
  import { PanelHeader, onPanelKey, setTitle, statusClass, statusLabel, openDrawer, requestNewInstance } from "/assets/app-shell.js";
19
- import { detailsPath, textLinkSegments, sectionPath } from "/assets/app-route.js";
16
+ import { detailsPath, textLinkSegments } from "/assets/app-route.js";
20
17
  import { InstanceSwitch } from "/assets/instance-switch.js";
21
18
  import { HeaderTools } from "/assets/header-tools.js";
22
19
  import { navigate, navStore } from "/assets/app-nav.js";
@@ -32,6 +29,7 @@ import { applyTheme, clearAmbient, resolvedMode, themeFor, themeImageUrl, themeM
32
29
  import { colorMenuItem } from "/assets/identity-color.js";
33
30
  import { brokenPictures, cardFoldable, IdentityCard, useCard } from "/assets/identity-card.js";
34
31
  import { AgentWidget, instanceBinds, widgetFor } from "/assets/agent-widget.js";
32
+
35
33
  // #1629 r4 §1: the identity card under the chat's header — hidden by default; shown or not is this device's choice.
36
34
  // #2217 (the user, 2026-10-19): no row of its own; its picture and bio can be folded away (the banner stays) — this
37
35
  // device's choice too, kept the same way. The user (2026-10-20): no control on the card — one card button in the header
@@ -79,7 +77,7 @@ import { createEmojiIndex } from "./chat-emojis.js";
79
77
  import { pollPublicPreview } from "./preview-status.js";
80
78
  import { createMentionIndex } from "./chat-mentions.js";
81
79
  import { setPanelFeedback } from "./preview-panel-actions.js";
82
- import { PreviewPanel, claimPanel, openPanel, panelClaims, panelStore, panelVersion, shownKey } from "./preview-panel.js";
80
+ import { PreviewPanel, claimPanel, openMarkdown, openPanel, panelClaims, panelStore, panelVersion, shownKey } from "./preview-panel.js";
83
81
  import { needsArgument, paletteFor, parseCommandLine } from "./chat-commands.js";
84
82
  import { installTour, refreshTourSpot } from "./chat-tour.js";
85
83
  import { LightboxHost, openLightbox } from "./image-lightbox.js";
@@ -216,7 +214,7 @@ export function ChatPanel({ route, navKey }) {
216
214
  store.setCurrent(name && inst ? name : null);
217
215
  return () => store.setCurrent(null);
218
216
  }, [name, !!inst]);
219
- useEffect(() => { setTitle(inst?.runtime === "windows" ? inst.display_name || name : name || t("app.chat")); }, [name, navKey, inst?.runtime, inst?.display_name]);
217
+ useEffect(() => { setTitle(name || t("app.chat")); }, [name, navKey]);
220
218
  if (!name) {
221
219
  // #1854 (rank 7): one instruction — pick an agent, or with none at all, the one way to make one. Connecting a chat
222
220
  // app (the first-run card, #1519 P7) is offered in Settings, not here: it competed with the first agent.
@@ -261,7 +259,6 @@ function useResolvedMode(lease) {
261
259
  }
262
260
 
263
261
  function ChatView({ name, inst, lease, navKey, exec, awaiting }) {
264
- const attachmentsSupported = supportsInstanceFeature(inst,"attachments");
265
262
  const names = useStore(namesStore); // #1722: which name leads (the title)
266
263
  // #1629: this agent's theme, on this surface only; redrawn when the themes, the viewer's switch or the mode move.
267
264
  useStore(themesStore);
@@ -270,17 +267,6 @@ function ChatView({ name, inst, lease, navKey, exec, awaiting }) {
270
267
  const themeKey = JSON.stringify(theme);
271
268
  const card = useCard(name, inst.card_v);
272
269
  const [dialog, setDialog] = useState(null); // "delete" | null
273
- const [recovering,setRecovering] = useState(false);
274
- const recoverNative = async () => {
275
- if (recovering) return;
276
- setRecovering(true);
277
- try {
278
- const response = await lease.fetch(`/ui/instances/${encodeURIComponent(name)}/recover`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({confirmedStopped:true})});
279
- const result = await response.json();
280
- if (lease.current() && (!response.ok || result.error)) toast(result.error || t("chat.disconnected"),false);
281
- } catch(error) { if (lease.current()) toast(error.message || t("chat.disconnected"),false); }
282
- finally { if (lease.current()) setRecovering(false); }
283
- };
284
270
  const [wrap, setWrap] = useState(codeWrap);
285
271
  const wide = useStore(chatWide).on;
286
272
  const view = useRef(null), split = useRef(null), thread = useRef(null), bg = useRef(null), effectSurface = useRef(null);
@@ -303,14 +289,12 @@ function ChatView({ name, inst, lease, navKey, exec, awaiting }) {
303
289
  const el = view.current; if (!el) return undefined;
304
290
  let depth = 0;
305
291
  const hasFiles = (e) => !!(e.dataTransfer && [...e.dataTransfer.types].includes("Files"));
306
- const offs = [
307
- lease.on(el, "dragenter", (e) => { if (attachmentsSupported && hasFiles(e)) { depth++; el.classList.add("dragging"); } }),
308
- lease.on(el, "dragover", (e) => { if (hasFiles(e)) e.preventDefault(); }),
309
- lease.on(el, "dragleave", (e) => { if (hasFiles(e) && --depth <= 0) { depth = 0; el.classList.remove("dragging"); } }),
310
- lease.on(el, "drop", (e) => { depth = 0; el.classList.remove("dragging"); if (e.dataTransfer && e.dataTransfer.files.length) { e.preventDefault(); if (attachmentsSupported) store.addFiles(name, e.dataTransfer.files); else toast(t("chat.runtimeNoAttachments"),false); } }),
311
- ];
312
- return () => offs.forEach(off => off());
313
- }, [lease,attachmentsSupported]);
292
+ lease.on(el, "dragenter", (e) => { if (hasFiles(e)) { depth++; el.classList.add("dragging"); } });
293
+ lease.on(el, "dragover", (e) => { if (hasFiles(e)) e.preventDefault(); });
294
+ lease.on(el, "dragleave", (e) => { if (hasFiles(e) && --depth <= 0) { depth = 0; el.classList.remove("dragging"); } });
295
+ lease.on(el, "drop", (e) => { depth = 0; el.classList.remove("dragging"); if (e.dataTransfer && e.dataTransfer.files.length) { e.preventDefault(); store.addFiles(name, e.dataTransfer.files); } });
296
+ return undefined;
297
+ }, [lease]);
314
298
  // Esc stops the agent's reply (as Esc in its terminal would): from the chat, while it works, and only when nothing
315
299
  // else that Esc would close is open (a dialog, a menu, the Session menu).
316
300
  useEffect(() => lease.hold(onPanelKey((e) => {
@@ -333,11 +317,10 @@ function ChatView({ name, inst, lease, navKey, exec, awaiting }) {
333
317
  };
334
318
  const items = [
335
319
  // #1523 N2: Details is a page now (the Fleet side of this instance), not a dialog.
336
- supportsInstanceFeature(inst,"details") ? { key: "details", label: t("chat.details"), icon: "info", onSelect: () => navigate(detailsPath(name)) } : null,
337
- inst.runtime === "windows" ? {key:"settings",label:t("app.settings"),icon:"settings",onSelect:() => navigate(sectionPath("agents"))} : null,
338
- running || !supportsInstanceFeature(inst,"lifecycle") ? null : { key: "start", label: t("chat.start"), icon: "play", onSelect: () => action("start") },
339
- running && supportsInstanceFeature(inst,"lifecycle") ? { key: "restart", label: t("chat.restart"), icon: "restart", onSelect: () => action("restart") } : null,
340
- running && supportsInstanceFeature(inst,"lifecycle") ? { key: "stop", label: t("chat.stopInstance"), icon: "stop", onSelect: () => action("stop") } : null,
320
+ { key: "details", label: t("chat.details"), icon: "info", onSelect: () => navigate(detailsPath(name)) },
321
+ running ? null : { key: "start", label: t("chat.start"), icon: "play", onSelect: () => action("start") },
322
+ running ? { key: "restart", label: t("chat.restart"), icon: "restart", onSelect: () => action("restart") } : null,
323
+ running ? { key: "stop", label: t("chat.stopInstance"), icon: "stop", onSelect: () => action("stop") } : null,
341
324
  // #1958: its identity colour and where it shows (the public link too, as profile edits).
342
325
  colorMenuItem(name, inst),
343
326
  // #1629: a person's control over this agent's theme — not over the public link (it only views themes).
@@ -354,12 +337,10 @@ function ChatView({ name, inst, lease, navKey, exec, awaiting }) {
354
337
  // #1269 quick actions: the model and effort it runs, each a way to /model or /effort (the same pick list).
355
338
  const pick = (command) => store.runCommand(name, command, "", { alive: () => lease.current() });
356
339
  const sub = html`<span class="status"><span class=${`dot ${cls}`} aria-hidden="true"></span>${statusLabel(inst, exec, awaiting)}</span>
357
- ${inst.runtime === "windows" ? html`<span class="tag">Windows</span>` : null}
358
- ${inst.machine_id ? html`<span class="tag runtime-machine-tag" title=${t("chat.machineName",machineName(inst.machine_id,inst.machine_name))}>${machineName(inst.machine_id,inst.machine_name)}</span>${inst.machine_status !== "online" ? html`<span class="tag runtime-machine-offline">${t(inst.machine_status === "revoked" ? "chat.machineRevoked" : "chat.machineOffline")}</span>` : null}` : null}
359
- ${inst.model ? html`<button type="button" class="hd-chip" title=${t("chat.chipModel", modelText(inst))} aria-label=${t("chat.chipModel", modelText(inst))} onClick=${() => supportsInstanceFeature(inst,"commands") ? pick("model") : navigate(sectionPath("agents"))}>${modelText(inst)}</button>` : null}
360
- ${inst.effort && supportsInstanceFeature(inst,"effort") ? html`<button type="button" class="hd-chip" title=${t("chat.chipEffort", inst.effort)} aria-label=${t("chat.chipEffort", inst.effort)} onClick=${() => pick("effort")}>${inst.effort}</button>` : null}`;
340
+ ${inst.model ? html`<button type="button" class="hd-chip" title=${t("chat.chipModel", modelText(inst))} aria-label=${t("chat.chipModel", modelText(inst))} onClick=${() => pick("model")}>${modelText(inst)}</button>` : null}
341
+ ${inst.effort ? html`<button type="button" class="hd-chip" title=${t("chat.chipEffort", inst.effort)} aria-label=${t("chat.chipEffort", inst.effort)} onClick=${() => pick("effort")}>${inst.effort}</button>` : null}`;
361
342
  return html`<div class=${`panel p-chat${wrap ? " wrap-code" : ""}`} data-width=${wide ? "full" : undefined} ref=${view}>
362
- <${PanelHeader} title=${inst.runtime === "windows" ? inst.display_name || name : headerName(namesOf(inst || { name }, names.primary))} sub=${sub} nav=${guest ? (guestTrusted() ? html`<${InstanceSwitch} name=${name} instance=${inst} current="chat" guest=${true} />` : null) : html`<${InstanceSwitch} name=${name} instance=${inst} current="chat" />`}><${CardMenu} card=${card} /><${HeaderTools} navKey=${navKey} usage=${supportsInstanceFeature(inst,"usage")} />${guest ? null : html`<${Menu} items=${items} label=${t("app.more")} />`}</${PanelHeader}>
343
+ <${PanelHeader} title=${headerName(namesOf(inst || { name }, names.primary))} sub=${sub} nav=${guest ? (guestTrusted() ? html`<${InstanceSwitch} name=${name} current="chat" guest=${true} />` : null) : html`<${InstanceSwitch} name=${name} current="chat" />`}><${CardMenu} card=${card} /><${HeaderTools} navKey=${navKey} />${guest ? null : html`<${Menu} items=${items} label=${t("app.more")} />`}</${PanelHeader}>
363
344
  <${ChatCard} key=${name} name=${name} card=${card} />
364
345
  <${AgentWidget} slot="chat_header" widget=${widgetFor(name, "chat_header")} binds=${instanceBinds(inst, exec, awaiting)} />
365
346
  <div class="chat-split" ref=${split}>
@@ -367,10 +348,7 @@ function ChatView({ name, inst, lease, navKey, exec, awaiting }) {
367
348
  ${theme && theme.background ? html`<img ref=${bg} class=${`th-bg th-bg-${theme.background.fit}`} src=${themeImageUrl(name, theme.background.image)} alt="" aria-hidden="true" decoding="async" />` : null}
368
349
  <${ChatAmbient} name=${name} surface=${effectSurface} part="layer" />
369
350
  <${AmbientMotionNote} name=${name} />
370
- ${inst.general_topic ? html`<${GeneralLocation} name=${name} attentionOnly=${true} />` : null}
371
- <${NativePaneRecovery} name=${name} inst=${inst} lease=${lease} />
372
- ${inst.native_blocked ? html`<div class="windows-agent-blocked" role="alert"><p>${t("chat.nativeBlocked")}</p><button type="button" class="btn" disabled=${recovering} onClick=${recoverNative}>${t("chat.nativeRecover")}</button></div>` : null}
373
- <${Thread} name=${name} label=${inst.runtime === "windows" ? inst.display_name || name : name} th=${thread} />
351
+ <${Thread} name=${name} th=${thread} />
374
352
  <${Dock} name=${name} inst=${inst} lease=${lease} exec=${exec} awaiting=${awaiting} workingLabel=${theme ? theme.workingLabel : undefined} />
375
353
  <${ChatAmbient} name=${name} surface=${effectSurface} part="front" />
376
354
  </div>
@@ -378,8 +356,8 @@ function ChatView({ name, inst, lease, navKey, exec, awaiting }) {
378
356
  keyOf=${msgKey} reveal=${(k) => thread.current && thread.current.reveal(k)} download=${downloadHtml} allow=${(commit) => setPreviewOptIn(true, commit)} />
379
357
  </div>
380
358
  <${LightboxHost} />
381
- ${attachmentsSupported ? html`<div data-trust="drop" class="drop-overlay" aria-hidden="true"><div class="drop-card"><${Icon} name="attach" size=${32} /><span>${t("chat.dropHere")}</span></div></div>` : null}
382
- ${dialog === "delete" ? html`<${DeleteDialog} name=${name} inst=${inst} onClose=${() => setDialog(null)} />` : null}
359
+ <div data-trust="drop" class="drop-overlay" aria-hidden="true"><div class="drop-card"><${Icon} name="attach" size=${32} /><span>${t("chat.dropHere")}</span></div></div>
360
+ ${dialog === "delete" ? html`<${DeleteDialog} name=${name} onClose=${() => setDialog(null)} />` : null}
383
361
  </div>`;
384
362
  }
385
363
 
@@ -460,7 +438,8 @@ function threadEntry(name, doc) {
460
438
  replyButtonBusy: (id) => store.state.rbBusy.has(id),
461
439
  pollMine: (id) => store.state.pollMine[id], // #1823: this device's own vote
462
440
  serverNow: () => Date.now() + store.state.clockSkew, // #1823: the deadline is the server's
463
- panel: { shown: shownKey, open: (spec, o) => openPanel(spec, o), version: panelVersion, claim: claimPanel, claims: panelClaims }, // #1481, #1704
441
+ panel: { shown: shownKey, open: (spec, o) => openPanel(spec, o), version: panelVersion, claim: claimPanel, claims: panelClaims, // #1481, #1704
442
+ openMarkdown: (spec) => openMarkdown(spec) }, // M-2448: a Markdown file in the side panel
464
443
  openImage: openLightbox, // an image, full size, in the page
465
444
  emojis: (id) => !!emojiIndex && emojiIndex.known(id), // #1630: the fleet's server emoji
466
445
  mentions: (kind, id) => (mentionIndex ? mentionIndex.name(kind, id) : null), // #1682: mention names
@@ -489,11 +468,10 @@ function follow(name, thread) {
489
468
  }
490
469
 
491
470
  /** The thread's view: Preact owns the scroller and the jump pill; the kept list (chat-thread.js) is put inside it. */
492
- function Thread({ name, label = name, th }) {
471
+ function Thread({ name, th }) {
493
472
  const scroller = useRef(null), host = useRef(null);
494
473
  const [jump, setJump] = useState({ show: false, unseen: 0 });
495
474
  const [empty, setEmpty] = useState(false);
496
- useLayoutEffect(() => { keptThreads.get(name)?.list.setAttribute("aria-label",t("chat.conversationWith",label)); },[name,label]);
497
475
  useLayoutEffect(() => {
498
476
  const doc = host.current.ownerDocument;
499
477
  let e = keptThreads.get(name);
@@ -507,7 +485,6 @@ function Thread({ name, label = name, th }) {
507
485
  if (kept) trimKept(name);
508
486
  const shownAt = now();
509
487
  const thread = e.thread, sc = scroller.current, ls = e.list;
510
- ls.setAttribute("aria-label",t("chat.conversationWith",label));
511
488
  e.sink = { setJump, setEmpty };
512
489
  host.current.append(ls);
513
490
  thread.attach(sc);
@@ -568,9 +545,9 @@ function Dock({ name, inst, lease, exec, awaiting, workingLabel }) {
568
545
  <${CommandCard} name=${name} lease=${lease} />
569
546
  <${QuickActions} name=${name} inst=${inst} lease=${lease} />
570
547
  ${s.waking[name] ? html`<p class="send-waking" role="status">${t("chat.waking", name)}</p>` : null}
571
- <${Composer} name=${name} inst=${inst} label=${composerLabel(inst, name)} lease=${lease} busy=${R().isBusy(exec)} />
548
+ <${Composer} name=${name} label=${composerLabel(inst, name)} lease=${lease} busy=${R().isBusy(exec)} />
572
549
  <div class="composer-row">${guestPage() ? html`<span class="guest-note" title=${t("chat.guestNote")}>${t("chat.guestNote")}</span>` : html`<${ComposerAuth} />`}<span
573
- class="hint" title=${t(guestPage() || !supportsInstanceFeature(inst,"commands") ? "chat.guestMore" : "chat.composerMore")}>${t(supportsInstanceFeature(inst,"commands") ? touchScreen() ? "chat.composerHintTouch" : "chat.composerHint" : touchScreen() ? "chat.nativeComposerHintTouch" : "chat.nativeComposerHint")}</span></div>
550
+ class="hint" title=${t(guestPage() ? "chat.guestMore" : "chat.composerMore")}>${t(touchScreen() ? "chat.composerHintTouch" : "chat.composerHint")}</span></div>
574
551
  </div></div>`;
575
552
  }
576
553
 
@@ -665,7 +642,7 @@ function replySnippet(r) {
665
642
  return text || (r.media === "photo" ? t("chat.replyPhoto") : r.media === "document" ? t("chat.replyFile") : "");
666
643
  }
667
644
 
668
- function Composer({ name, inst, label = name, lease, busy }) {
645
+ function Composer({ name, label = name, lease, busy }) {
669
646
  const s = store.state;
670
647
  const input = useRef(null), fileIn = useRef(null);
671
648
  const [, tick] = useState(0);
@@ -686,10 +663,7 @@ function Composer({ name, inst, label = name, lease, busy }) {
686
663
  const guest = guestPage();
687
664
  const app = useStore(appStore);
688
665
  const guestAllowed = guest ? (app.instances.find((i) => i.name === name)?.commands ?? []) : null;
689
- const attachmentsSupported = supportsInstanceFeature(inst,"attachments"), commandsSupported = supportsInstanceFeature(inst,"commands");
690
- const machineUnavailable = !!inst?.machine_id && inst.machine_status !== "online";
691
- const sendingBlocked = machineUnavailable || inst?.native_blocked || inst?.native_busy || (busy && !supportsInstanceFeature(inst,"send_while_busy"));
692
- const palette = !commandsSupported || files.length || closedFor === value || (guest && !guestAllowed.length) ? null : paletteFor(value, guestAllowed || undefined);
666
+ const palette = files.length || closedFor === value || (guest && !guestAllowed.length) ? null : paletteFor(value, guestAllowed || undefined);
693
667
  const pick = palette && palette.length ? palette[Math.min(sel, palette.length - 1)] : null;
694
668
  // Grow with the text, up to a limit: set through the CSSOM, never a style attribute (#1300). Empty, it is one line
695
669
  // (#2478 — a long name's placeholder made the box two lines tall).
@@ -711,9 +685,6 @@ function Composer({ name, inst, label = name, lease, busy }) {
711
685
  // #2342: a completion is a step Ctrl+Z goes back from (to what was typed); a command that runs consumes the line.
712
686
  const complete = (c) => { recordEdit(input.current); setValue(`/${c.name}${c.arg ? " " : ""}`); };
713
687
  const submit = () => {
714
- if (sendingBlocked) return;
715
- if (!attachmentsSupported && files.length) { toast(t("chat.runtimeNoAttachments"),false); return; }
716
- if (!commandsSupported && parseCommandLine(value)) { toast(t("chat.runtimeNoCommands"),false); return; }
717
688
  if (pick) {
718
689
  if (value === `/${pick.name}` && !needsArgument(pick.name)) runLine({ command: pick.name, args: "" });
719
690
  else complete(pick);
@@ -749,13 +720,11 @@ function Composer({ name, inst, label = name, lease, busy }) {
749
720
  const onPaste = (e) => {
750
721
  const list = e.clipboardData && e.clipboardData.files;
751
722
  const text = e.clipboardData ? e.clipboardData.getData("text") : "";
752
- if (list && list.length) { if (!attachmentsSupported) { if (!text) e.preventDefault(); toast(t("chat.runtimeNoAttachments"),false); return; } store.addFiles(name, list); if (!text) e.preventDefault(); return; }
753
- if (attachmentsSupported && R().isLongPaste(text) && store.attachPastedText(name, text)) e.preventDefault();
723
+ if (list && list.length) { store.addFiles(name, list); if (!text) e.preventDefault(); return; }
724
+ if (R().isLongPaste(text) && store.attachPastedText(name, text)) e.preventDefault();
754
725
  };
755
726
  const optId = (c) => `cmd-${c.name}`;
756
727
  return html`<div class="composer-box">
757
- ${machineUnavailable ? html`<p class="note runtime-machine-unavailable" role="status">${t(inst.machine_status === "revoked" ? "chat.machineRevokedHint" : "chat.machineUnavailable",machineName(inst.machine_id,inst.machine_name))}</p>` : null}
758
- ${inst?.native_busy && !busy && !inst?.native_blocked ? html`<p class="note" role="status">${t("chat.nativeBusy")}</p>` : null}
759
728
  ${palette ? html`<ul data-trust="palette" class="cmd-palette" id="cmdPalette" role="listbox" aria-label=${t("chat.cmdCommands")}>
760
729
  ${palette.length ? palette.map((c) => html`<li key=${c.name} id=${optId(c)} role="option" aria-selected=${c === pick ? "true" : "false"}
761
730
  class=${c === pick ? "on" : ""} onMouseDown=${(e) => { e.preventDefault(); complete(c); }}>
@@ -769,9 +738,9 @@ function Composer({ name, inst, label = name, lease, busy }) {
769
738
  </div>` : null}
770
739
  ${files.length ? html`<div class="pending-files">${files.map((f, i) => html`<${FileChip} key=${`${f.name}-${i}`} f=${f} i=${i} name=${name} />`)}</div>` : null}
771
740
  <div class="composer">
772
- ${attachmentsSupported ? html`<button id="attachBtn" type="button" class="icon-btn" title=${t("chat.attachTitle")} aria-label=${t("chat.attachTitle")} onClick=${() => fileIn.current && fileIn.current.click()}><${Icon} name="attach" /></button>
741
+ <button id="attachBtn" type="button" class="icon-btn" title=${t("chat.attachTitle")} aria-label=${t("chat.attachTitle")} onClick=${() => fileIn.current && fileIn.current.click()}><${Icon} name="attach" /></button>
773
742
  <input ref=${fileIn} type="file" multiple hidden
774
- onChange=${(e) => { store.addFiles(name, e.target.files); e.target.value = ""; }} />` : null}
743
+ onChange=${(e) => { store.addFiles(name, e.target.files); e.target.value = ""; }} />
775
744
  ${/* #2478: the placeholder is drawn beside the box, one line ending in "…" — a textarea's own placeholder is clipped,
776
745
  never ellipsized, and a long name wrapped it to two lines. The box keeps the words as its accessible name. Its own
777
746
  placeholder is one space: :placeholder-shown hides the drawn one (app.css) the moment the box holds text, an
@@ -783,7 +752,7 @@ function Composer({ name, inst, label = name, lease, busy }) {
783
752
  placeholder=" "></textarea><span class="composer-ph" aria-hidden="true">${t("chat.composerPlaceholder", label)}</span></span>
784
753
  <button id="stopBtn" type="button" class="btn btn-stop" hidden=${!busy} title=${t("chat.stopReplyTitle")}
785
754
  disabled=${!!s.cancelling[name]} onClick=${() => store.cancelReply(name)}><${Icon} name="stop" size=${14} /><span class="stop-label">${t("chat.stopReply")}</span></button>
786
- <button id="sendBtn" type="button" class="btn btn-primary btn-send" hidden=${busy && !content} disabled=${!content || sendingBlocked}
755
+ <button id="sendBtn" type="button" class="btn btn-primary btn-send" hidden=${busy && !content} disabled=${!content}
787
756
  onMouseDown=${(e) => e.preventDefault()}
788
757
  aria-label=${t("chat.send")} title=${t("chat.send")} onClick=${submit}><${Icon} name="send" size=${16} /><span class="send-label">${t("chat.send")}</span></button>
789
758
  </div></div>`;
@@ -807,7 +776,7 @@ function FileChip({ f, i, name }) {
807
776
 
808
777
  // ── Dialogs ──
809
778
 
810
- function DeleteDialog({ name, inst, onClose }) {
779
+ function DeleteDialog({ name, onClose }) {
811
780
  // The dialog's own lease: it ends when the dialog goes (closed, or the chat left for another page). The delete
812
781
  // may still finish on the server, and says so, but a dialog that is gone never closes or navigates the page the
813
782
  // person is on now (#1425 review).
@@ -823,12 +792,14 @@ function DeleteDialog({ name, inst, onClose }) {
823
792
  // follows the request. From then on the dialog is done: the decision is said in a toast, and it never closes or
824
793
  // navigates anything (the person may be anywhere by then).
825
794
  try {
826
- const res = await confirmedWrite(inst?.runtime === "windows" ? `/ui/instances/${encodeURIComponent(name)}` : `/ui/instances/${encodeURIComponent(name)}/delete`, { method: inst?.runtime === "windows" ? "DELETE" : "POST", body: inst?.runtime === "windows" ? {} : { confirm: typed }, label: t("chat.deleteTitle", name),
795
+ const res = await confirmedWrite(`/ui/instances/${encodeURIComponent(name)}/delete`, { method: "POST", body: { confirm: typed }, label: t("chat.deleteTitle", name),
827
796
  onPending: (_id, view) => { handedOver = true; toast(t(selfConfirmed(view) ? "app.pendingSelfSent" : "app.pendingSent")); if (lease.current()) { setBusy(false); onClose(); } } });
828
797
  r = res.ok ? res.body || {} : { error: (res.body && res.body.error) || `HTTP ${res.status}` };
829
798
  } catch (err) { r = { error: err && err.message ? err.message : t("chat.disconnected") }; }
830
799
  if (r && r.error) { toast(r.error, false); if (!handedOver && lease.current()) setBusy(false); return; }
831
800
  toast(t("chat.instanceDeleted", name));
801
+ // The agent's own topic went too, or stayed with the reason (the server's own words: no new string here).
802
+ if (r.topic_note) toast(r.topic_note, r.topic_deleted !== false);
832
803
  if (handedOver || !lease.current()) return;
833
804
  setBusy(false);
834
805
  onClose();
@@ -1,4 +1,3 @@
1
- import { NativePaneRecovery } from "./native-pane-recovery.js";
2
1
  // #1523 N2 (§3.3, Q1 = B): Details — "the Fleet side of one instance", at /ui/fleet/agent/<name>. Behind the session
3
2
  // gate (/ui/js/). What it holds:
4
3
  // - runtime and recent activity (what Chat's details dialog showed, now a page);
@@ -159,7 +158,7 @@ function DetailsView({ name, inst, navKey, exec, awaiting }) {
159
158
  }
160
159
  return html`<div data-effect-panel="details" class="panel p-details">
161
160
  <${PanelHeader} title=${name} sub=${sub} nav=${html`<${InstanceSwitch} name=${name} current="details" />`}><${HeaderTools} navKey=${navKey} /><${Menu} items=${items} label=${t("app.more")} /></${PanelHeader}>
162
- <div data-trust="panel-content" class="panel-body"><div class="col" ref=${body}><${NativePaneRecovery} name=${name} inst=${inst} lease=${lease} />${busy ? html`<p class="note" role="status">${t("chat.dWorking")}</p>` : null}<${IdentityCard} name=${name} card=${card} />
161
+ <div data-trust="panel-content" class="panel-body"><div class="col" ref=${body}>${busy ? html`<p class="note" role="status">${t("chat.dWorking")}</p>` : null}<${IdentityCard} name=${name} card=${card} />
163
162
  <${AgentWidget} slot="details" widget=${widgetFor(name, "details")} binds=${instanceBinds(inst, exec, awaiting)} />${content}</div></div>
164
163
  </div>`;
165
164
  }