@songsid/agend 2.3.3-beta.1 → 2.3.3-beta.10

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 (355) hide show
  1. package/dist/agent-cli.js +13 -112
  2. package/dist/agent-cli.js.map +1 -1
  3. package/dist/agent-endpoint.d.ts +0 -1
  4. package/dist/agent-endpoint.js +1 -9
  5. package/dist/agent-endpoint.js.map +1 -1
  6. package/dist/agent-whats-new.d.ts +3 -6
  7. package/dist/agent-whats-new.js +7 -18
  8. package/dist/agent-whats-new.js.map +1 -1
  9. package/dist/auth-api.d.ts +0 -7
  10. package/dist/auth-api.js +1 -15
  11. package/dist/auth-api.js.map +1 -1
  12. package/dist/authority/authority-state.js +1 -1
  13. package/dist/authority/authority-state.js.map +1 -1
  14. package/dist/authority/web-authority.d.ts +9 -4
  15. package/dist/authority/web-authority.js +10 -5
  16. package/dist/authority/web-authority.js.map +1 -1
  17. package/dist/backend/antigravity.js +6 -1
  18. package/dist/backend/antigravity.js.map +1 -1
  19. package/dist/backend/claude-code.d.ts +7 -0
  20. package/dist/backend/claude-code.js +34 -28
  21. package/dist/backend/claude-code.js.map +1 -1
  22. package/dist/backend/claude-transcript-errors.d.ts +18 -0
  23. package/dist/backend/claude-transcript-errors.js +19 -0
  24. package/dist/backend/claude-transcript-errors.js.map +1 -0
  25. package/dist/backend/codex-session-lookup.d.ts +16 -3
  26. package/dist/backend/codex-session-lookup.js +45 -11
  27. package/dist/backend/codex-session-lookup.js.map +1 -1
  28. package/dist/backend/codex.d.ts +16 -0
  29. package/dist/backend/codex.js +184 -35
  30. package/dist/backend/codex.js.map +1 -1
  31. package/dist/backend/grok.js +58 -12
  32. package/dist/backend/grok.js.map +1 -1
  33. package/dist/backend/kiro.js +2 -0
  34. package/dist/backend/kiro.js.map +1 -1
  35. package/dist/backend/muse.js +2 -1
  36. package/dist/backend/muse.js.map +1 -1
  37. package/dist/backend/types.d.ts +46 -0
  38. package/dist/backend/types.js.map +1 -1
  39. package/dist/bundled-skills.d.ts +4 -6
  40. package/dist/bundled-skills.js +10 -14
  41. package/dist/bundled-skills.js.map +1 -1
  42. package/dist/channel/adapters/discord.js +60 -17
  43. package/dist/channel/adapters/discord.js.map +1 -1
  44. package/dist/channel/mcp-server.js +5 -5
  45. package/dist/channel/mcp-server.js.map +1 -1
  46. package/dist/channel/mcp-tools.d.ts +1 -3
  47. package/dist/channel/mcp-tools.js +4 -58
  48. package/dist/channel/mcp-tools.js.map +1 -1
  49. package/dist/classic-channel-manager.d.ts +4 -1
  50. package/dist/classic-channel-manager.js +21 -7
  51. package/dist/classic-channel-manager.js.map +1 -1
  52. package/dist/cli.js +21 -4
  53. package/dist/cli.js.map +1 -1
  54. package/dist/config-history.d.ts +50 -0
  55. package/dist/config-history.js +263 -0
  56. package/dist/config-history.js.map +1 -0
  57. package/dist/config-validator.js +7 -7
  58. package/dist/config-validator.js.map +1 -1
  59. package/dist/config.d.ts +3 -0
  60. package/dist/config.js +11 -4
  61. package/dist/config.js.map +1 -1
  62. package/dist/daemon.d.ts +73 -3
  63. package/dist/daemon.js +334 -121
  64. package/dist/daemon.js.map +1 -1
  65. package/dist/daily-summary.d.ts +8 -1
  66. package/dist/daily-summary.js +8 -5
  67. package/dist/daily-summary.js.map +1 -1
  68. package/dist/dashboard-live.d.ts +1 -1
  69. package/dist/dashboard-live.js +3 -3
  70. package/dist/dashboard-live.js.map +1 -1
  71. package/dist/dashboard-permissions.d.ts +1 -1
  72. package/dist/dashboard-permissions.js +1 -3
  73. package/dist/dashboard-permissions.js.map +1 -1
  74. package/dist/delivery-outbox.d.ts +4 -0
  75. package/dist/delivery-outbox.js +12 -2
  76. package/dist/delivery-outbox.js.map +1 -1
  77. package/dist/doctor.d.ts +4 -0
  78. package/dist/doctor.js +16 -1
  79. package/dist/doctor.js.map +1 -1
  80. package/dist/fleet-level-config.js +1 -1
  81. package/dist/fleet-level-config.js.map +1 -1
  82. package/dist/fleet-manager.d.ts +70 -54
  83. package/dist/fleet-manager.js +257 -322
  84. package/dist/fleet-manager.js.map +1 -1
  85. package/dist/fleet-process-handlers.d.ts +5 -0
  86. package/dist/fleet-process-handlers.js +21 -0
  87. package/dist/fleet-process-handlers.js.map +1 -1
  88. package/dist/fleet-service-owner.d.ts +11 -0
  89. package/dist/fleet-service-owner.js +3 -0
  90. package/dist/fleet-service-owner.js.map +1 -0
  91. package/dist/general-knowledge/skills/credential-profiles/SKILL.md +11 -1
  92. package/dist/general-knowledge/skills/session-management/SKILL.md +6 -0
  93. package/dist/general-knowledge/skills/web-appearance/SKILL.md +13 -204
  94. package/dist/general-knowledge/skills/web-dashboard/SKILL.md +29 -67
  95. package/dist/instance-lifecycle.d.ts +19 -0
  96. package/dist/instance-lifecycle.js +52 -10
  97. package/dist/instance-lifecycle.js.map +1 -1
  98. package/dist/locale.js +92 -42
  99. package/dist/locale.js.map +1 -1
  100. package/dist/needs-you-hub.d.ts +1 -0
  101. package/dist/needs-you-hub.js +6 -3
  102. package/dist/needs-you-hub.js.map +1 -1
  103. package/dist/needs-you-live.d.ts +3 -1
  104. package/dist/needs-you-live.js +24 -2
  105. package/dist/needs-you-live.js.map +1 -1
  106. package/dist/needs-you.d.ts +13 -2
  107. package/dist/needs-you.js +11 -1
  108. package/dist/needs-you.js.map +1 -1
  109. package/dist/notify-socket.d.ts +10 -0
  110. package/dist/notify-socket.js +45 -0
  111. package/dist/notify-socket.js.map +1 -0
  112. package/dist/outbound-handlers.js +19 -7
  113. package/dist/outbound-handlers.js.map +1 -1
  114. package/dist/outbound-schemas.d.ts +0 -62
  115. package/dist/outbound-schemas.js +3 -42
  116. package/dist/outbound-schemas.js.map +1 -1
  117. package/dist/parked-notices.d.ts +87 -0
  118. package/dist/parked-notices.js +194 -0
  119. package/dist/parked-notices.js.map +1 -0
  120. package/dist/public-link-progress.d.ts +5 -2
  121. package/dist/public-link-progress.js +4 -3
  122. package/dist/public-link-progress.js.map +1 -1
  123. package/dist/public-web-gateway.js +0 -9
  124. package/dist/public-web-gateway.js.map +1 -1
  125. package/dist/public-web-link.d.ts +12 -0
  126. package/dist/public-web-link.js +29 -5
  127. package/dist/public-web-link.js.map +1 -1
  128. package/dist/quota-notice.d.ts +23 -0
  129. package/dist/quota-notice.js +22 -0
  130. package/dist/quota-notice.js.map +1 -0
  131. package/dist/scheduler/task-board.d.ts +0 -13
  132. package/dist/scheduler/task-board.js +0 -14
  133. package/dist/scheduler/task-board.js.map +1 -1
  134. package/dist/sd-notify.d.ts +10 -1
  135. package/dist/sd-notify.js +27 -2
  136. package/dist/sd-notify.js.map +1 -1
  137. package/dist/search/search-docs.d.ts +1 -1
  138. package/dist/search/search-docs.js +2 -2
  139. package/dist/search/search-docs.js.map +1 -1
  140. package/dist/settings-api.d.ts +16 -0
  141. package/dist/settings-api.js +55 -2
  142. package/dist/settings-api.js.map +1 -1
  143. package/dist/settings-change.js +3 -1
  144. package/dist/settings-change.js.map +1 -1
  145. package/dist/settings-confirmation.d.ts +17 -3
  146. package/dist/settings-confirmation.js +8 -5
  147. package/dist/settings-confirmation.js.map +1 -1
  148. package/dist/settings-http-confirmation.js +31 -1
  149. package/dist/settings-http-confirmation.js.map +1 -1
  150. package/dist/setup-wizard.d.ts +3 -0
  151. package/dist/setup-wizard.js +4 -2
  152. package/dist/setup-wizard.js.map +1 -1
  153. package/dist/task-board-waker.d.ts +4 -1
  154. package/dist/task-board-waker.js +13 -2
  155. package/dist/task-board-waker.js.map +1 -1
  156. package/dist/tool-permissions.js +3 -10
  157. package/dist/tool-permissions.js.map +1 -1
  158. package/dist/topic-commands.d.ts +27 -7
  159. package/dist/topic-commands.js +95 -36
  160. package/dist/topic-commands.js.map +1 -1
  161. package/dist/transcript-monitor.d.ts +7 -0
  162. package/dist/transcript-monitor.js +48 -3
  163. package/dist/transcript-monitor.js.map +1 -1
  164. package/dist/tunnel/cloudflared.d.ts +5 -0
  165. package/dist/tunnel/cloudflared.js +32 -1
  166. package/dist/tunnel/cloudflared.js.map +1 -1
  167. package/dist/tunnel/named-diagnostics.d.ts +2 -1
  168. package/dist/tunnel/named-diagnostics.js +4 -1
  169. package/dist/tunnel/named-diagnostics.js.map +1 -1
  170. package/dist/tunnel/named-link-test.d.ts +90 -0
  171. package/dist/tunnel/named-link-test.js +270 -0
  172. package/dist/tunnel/named-link-test.js.map +1 -0
  173. package/dist/tunnel/purpose-lane.d.ts +3 -1
  174. package/dist/tunnel/purpose-lane.js +2 -0
  175. package/dist/tunnel/purpose-lane.js.map +1 -1
  176. package/dist/types.d.ts +8 -6
  177. package/dist/ui/chat-ambient.js +4 -4
  178. package/dist/ui/chat-commands.js +3 -2
  179. package/dist/ui/chat-store.js +4 -1
  180. package/dist/ui/chat-strings.js +12 -46
  181. package/dist/ui/chat-thread.js +51 -59
  182. package/dist/ui/fleet-office-skin.js +37 -14
  183. package/dist/ui/fleet-office.js +31 -7
  184. package/dist/ui/html-attachment.js +22 -8
  185. package/dist/ui/panel-chat.js +21 -50
  186. package/dist/ui/panel-needs.js +11 -9
  187. package/dist/ui/panel-settings.js +5 -3
  188. package/dist/ui/preview-panel.js +12 -21
  189. package/dist/ui/preview.js +10 -3
  190. package/dist/ui/search-dialog.js +30 -14
  191. package/dist/ui/settings-appearance.js +1 -3
  192. package/dist/ui/settings-confirm.js +18 -0
  193. package/dist/ui/settings-guests.js +13 -4
  194. package/dist/ui/settings-learn.js +1 -1
  195. package/dist/ui/settings-mods.js +5 -12
  196. package/dist/ui/settings-named-test.js +144 -0
  197. package/dist/ui/settings-registry.js +0 -1
  198. package/dist/ui/settings-strings.js +14 -14
  199. package/dist/ui/settings-web-authority.js +4 -3
  200. package/dist/ui/shared/app-i18n.js +15 -4
  201. package/dist/ui/shared/app-needs.js +5 -1
  202. package/dist/ui/shared/app-prefs.js +17 -17
  203. package/dist/ui/shared/app-shell.js +47 -9
  204. package/dist/ui/shared/app-store.js +6 -2
  205. package/dist/ui/shared/app.css +33 -39
  206. package/dist/ui/shared/app.js +5 -4
  207. package/dist/ui/shared/instance-nav.js +9 -9
  208. package/dist/ui/shared/instance-switch.js +8 -2
  209. package/dist/ui/shared/panel-view.js +22 -8
  210. package/dist/ui/shared/view-strings.js +6 -0
  211. package/dist/ui/shared/web-authorize.js +35 -13
  212. package/dist/usage/usage-api.d.ts +3 -0
  213. package/dist/usage/usage-api.js +5 -1
  214. package/dist/usage/usage-api.js.map +1 -1
  215. package/dist/view-api.d.ts +2 -0
  216. package/dist/view-api.js +64 -0
  217. package/dist/view-api.js.map +1 -1
  218. package/dist/web-api.d.ts +9 -17
  219. package/dist/web-api.js +257 -371
  220. package/dist/web-api.js.map +1 -1
  221. package/dist/web-appearance-tools.d.ts +0 -2
  222. package/dist/web-appearance-tools.js +2 -5
  223. package/dist/web-appearance-tools.js.map +1 -1
  224. package/dist/web-appearance-view.d.ts +0 -6
  225. package/dist/web-appearance-view.js +0 -1
  226. package/dist/web-appearance-view.js.map +1 -1
  227. package/dist/web-appearance.d.ts +14 -7
  228. package/dist/web-appearance.js +5 -6
  229. package/dist/web-appearance.js.map +1 -1
  230. package/dist/web-asset-parts.d.ts +1 -17
  231. package/dist/web-asset-parts.js +1 -15
  232. package/dist/web-asset-parts.js.map +1 -1
  233. package/dist/web-auth.js +1 -7
  234. package/dist/web-auth.js.map +1 -1
  235. package/dist/web-chat-history.d.ts +3 -7
  236. package/dist/web-chat-history.js +10 -17
  237. package/dist/web-chat-history.js.map +1 -1
  238. package/dist/web-commands.d.ts +9 -1
  239. package/dist/web-commands.js +13 -0
  240. package/dist/web-commands.js.map +1 -1
  241. package/dist/web-experimental.d.ts +2 -11
  242. package/dist/web-experimental.js +8 -36
  243. package/dist/web-experimental.js.map +1 -1
  244. package/dist/web-guest-access.d.ts +40 -2
  245. package/dist/web-guest-access.js +50 -14
  246. package/dist/web-guest-access.js.map +1 -1
  247. package/dist/web-mod-bundle.d.ts +2 -45
  248. package/dist/web-mod-bundle.js +15 -63
  249. package/dist/web-mod-bundle.js.map +1 -1
  250. package/dist/web-mod-store.d.ts +3 -48
  251. package/dist/web-mod-store.js +30 -97
  252. package/dist/web-mod-store.js.map +1 -1
  253. package/dist/web-prefs.d.ts +13 -0
  254. package/dist/web-prefs.js +38 -0
  255. package/dist/web-prefs.js.map +1 -1
  256. package/dist/web-preview.d.ts +6 -13
  257. package/dist/web-preview.js +12 -23
  258. package/dist/web-preview.js.map +1 -1
  259. package/dist/web-session.d.ts +11 -3
  260. package/dist/web-session.js +22 -11
  261. package/dist/web-session.js.map +1 -1
  262. package/dist/web-settings-patch.d.ts +1 -0
  263. package/dist/web-settings-patch.js +6 -3
  264. package/dist/web-settings-patch.js.map +1 -1
  265. package/dist/web-settings-tools.d.ts +0 -13
  266. package/dist/web-settings-tools.js +12 -84
  267. package/dist/web-settings-tools.js.map +1 -1
  268. package/launcher/agend-install.cjs +7 -1
  269. package/launcher/fleet-service-owner.cjs +150 -0
  270. package/package.json +1 -1
  271. package/dist/general-knowledge/skills/web-appearance/SKILL.canvas-worker-off.md +0 -376
  272. package/dist/general-knowledge/skills/web-dashboard/SKILL.canvas-worker-off.md +0 -673
  273. package/dist/task-board-summary.d.ts +0 -101
  274. package/dist/task-board-summary.js +0 -177
  275. package/dist/task-board-summary.js.map +0 -1
  276. package/dist/ui/app-effects.js +0 -251
  277. package/dist/ui/chat-effect-posters.js +0 -42
  278. package/dist/ui/chat-effects.js +0 -167
  279. package/dist/ui/effect-trial-controller.js +0 -124
  280. package/dist/ui/effect-trial-offer.js +0 -2
  281. package/dist/ui/effect-trial-panel.js +0 -40
  282. package/dist/ui/effects-waker.js +0 -2
  283. package/dist/ui/settings-effects.js +0 -202
  284. package/dist/ui/settings-owner-effects.js +0 -82
  285. package/dist/ui/shared/effect-app-runtime.js +0 -299
  286. package/dist/ui/shared/effect-baseline.js +0 -64
  287. package/dist/ui/shared/effect-chat-runtime.js +0 -162
  288. package/dist/ui/shared/effect-cursor.js +0 -126
  289. package/dist/ui/shared/effect-display-metadata.js +0 -39
  290. package/dist/ui/shared/effect-frame.js +0 -146
  291. package/dist/ui/shared/effect-geometry.js +0 -137
  292. package/dist/ui/shared/effect-host-style.js +0 -10
  293. package/dist/ui/shared/effect-owner-regions.js +0 -74
  294. package/dist/ui/shared/effect-owner-source.js +0 -122
  295. package/dist/ui/shared/effect-policy.js +0 -151
  296. package/dist/ui/shared/effect-poster-reader.js +0 -98
  297. package/dist/ui/shared/effect-posters.js +0 -117
  298. package/dist/ui/shared/effect-profiler.js +0 -184
  299. package/dist/ui/shared/effect-profiles.js +0 -65
  300. package/dist/ui/shared/effect-registry.js +0 -545
  301. package/dist/ui/shared/effect-runtime-loader.js +0 -236
  302. package/dist/ui/shared/effect-safety.js +0 -153
  303. package/dist/ui/shared/effect-stock-snapshot.js +0 -43
  304. package/dist/ui/shared/effect-stock-trust.js +0 -217
  305. package/dist/ui/shared/effect-trial-shadow.js +0 -62
  306. package/dist/ui/shared/effect-trial-source.js +0 -103
  307. package/dist/ui/shared/effect-trial-stage.js +0 -170
  308. package/dist/ui/shared/effect-trial.css +0 -40
  309. package/dist/ui/shared/feature-flags.js +0 -127
  310. package/dist/ui/shared/owner-effect-prefs.js +0 -117
  311. package/dist/web-effect-bootstrap.d.ts +0 -12
  312. package/dist/web-effect-bootstrap.js +0 -49
  313. package/dist/web-effect-bootstrap.js.map +0 -1
  314. package/dist/web-effect-bundle.d.ts +0 -28
  315. package/dist/web-effect-bundle.js +0 -171
  316. package/dist/web-effect-bundle.js.map +0 -1
  317. package/dist/web-effect-canonical.d.ts +0 -8
  318. package/dist/web-effect-canonical.js +0 -27
  319. package/dist/web-effect-canonical.js.map +0 -1
  320. package/dist/web-effect-library.d.ts +0 -114
  321. package/dist/web-effect-library.js +0 -530
  322. package/dist/web-effect-library.js.map +0 -1
  323. package/dist/web-effect-playback.d.ts +0 -30
  324. package/dist/web-effect-playback.js +0 -71
  325. package/dist/web-effect-playback.js.map +0 -1
  326. package/dist/web-effect-poster.d.ts +0 -8
  327. package/dist/web-effect-poster.js +0 -52
  328. package/dist/web-effect-poster.js.map +0 -1
  329. package/dist/web-effect-profiles.d.ts +0 -118
  330. package/dist/web-effect-profiles.js +0 -181
  331. package/dist/web-effect-profiles.js.map +0 -1
  332. package/dist/web-effect-service.d.ts +0 -93
  333. package/dist/web-effect-service.js +0 -335
  334. package/dist/web-effect-service.js.map +0 -1
  335. package/dist/web-effect-tools.d.ts +0 -48
  336. package/dist/web-effect-tools.js +0 -129
  337. package/dist/web-effect-tools.js.map +0 -1
  338. package/dist/web-effect-trials.d.ts +0 -86
  339. package/dist/web-effect-trials.js +0 -204
  340. package/dist/web-effect-trials.js.map +0 -1
  341. package/dist/web-effect-upload.d.ts +0 -27
  342. package/dist/web-effect-upload.js +0 -185
  343. package/dist/web-effect-upload.js.map +0 -1
  344. package/dist/web-effect-worker.d.ts +0 -8
  345. package/dist/web-effect-worker.js +0 -170
  346. package/dist/web-effect-worker.js.map +0 -1
  347. package/dist/web-effect.d.ts +0 -103
  348. package/dist/web-effect.js +0 -153
  349. package/dist/web-effect.js.map +0 -1
  350. package/dist/web-experimental-http.d.ts +0 -2
  351. package/dist/web-experimental-http.js +0 -12
  352. package/dist/web-experimental-http.js.map +0 -1
  353. package/dist/web-mod-agent.d.ts +0 -50
  354. package/dist/web-mod-agent.js +0 -207
  355. package/dist/web-mod-agent.js.map +0 -1
@@ -11,14 +11,7 @@ English UI labels (the page also has 中文). Before you state a value the user
11
11
  it: `get_fleet_config` shows fleet.yaml; this skill gives defaults. Never invent a control that is not listed here.
12
12
  Never tell anyone to kill `wslrelay` or run `wsl --shutdown` (see Troubleshooting).
13
13
 
14
- During a cold start/full restart, an already signed-in browser can open the dashboard while agents start. **Fleet
15
- starting N/M** counts successful starts among runnable instances (persisted pauses excluded); queued/starting labels
16
- are visible in the sidebar, chat header and Org chart. Reads remain available; messages and changes are refused with
17
- a retry hint until startup finishes. Returning guests may wait for their connection scope without being signed out.
18
- Needs you may still be empty while its hub initializes. A brief reconnect gap
19
- is normal while a full restart replaces the process; the starting banner then replaces the unreachable message.
20
-
21
- For how *you* look on the dashboard (theme, identity card, colour, widgets, ambient effects, effects, mods), load `web-appearance`.
14
+ For how *you* look on the dashboard (theme, identity card, colour, widgets and ambient effects), load `web-appearance`.
22
15
 
23
16
  ## Index
24
17
 
@@ -34,7 +27,7 @@ For how *you* look on the dashboard (theme, identity card, colour, widgets, ambi
34
27
  | subscription meters, plan badges, profiles, keep-warm, prompt cache | [Usage and the cache report](#usage-and-the-cache-report) |
35
28
  | what an agent did step by step | [The Log tab](#the-log-tab) |
36
29
  | any Settings control | [Settings](#settings) |
37
- | themes, cards, widgets, ambient effects (petals, click stars), effects, mods | [Look](#look) |
30
+ | themes, cards, widgets, ambient effects (petals, click stars) | [Look](#look) |
38
31
  | blank page, preview refused, link fails, signed out, "live" missing | [Troubleshooting](#troubleshooting) |
39
32
 
40
33
  Addresses: the dashboard is served on the host at `http://localhost:<health_port>` (default 19280), on 127.0.0.1
@@ -67,14 +60,14 @@ hostname (named tunnel, `web.public_link.hostname`) the minutes go up to 10080,
67
60
  still needs a code).
68
61
  Close it with **Close public link** → **Close link (signs public browsers out)**, `/web revoke`, or let it expire.
69
62
  A public link is limited on purpose: no live stream (the page polls), no custom CSS, and Settings → Access & security, Look,
70
- mods, effect-library/personal-selection management, schedule edits and preference writes are refused. Current in-scope
71
- Chat effect metadata/code reads are allowed, with session/epoch/exposure checks; the public viewer’s show switch is browser-local. HTML previews work over it through a second tunnel
63
+ schedule edits and preference writes are refused. HTML previews work over it through a second tunnel
72
64
  of their own (`web.preview_on_public_link`, default on).
73
65
 
74
66
  **Sessions.**
75
67
  - Local: 48 h from sign-in and 48 h unused (`web.session.local.absolute_hours` / `idle_hours`, 1–720). Background
76
68
  polling and the live stream don't count as use. Sessions survive a fleet restart.
77
- - Public link: always 4 h / 30 min unused, and they end when the link closes.
69
+ - Public link: as long as the link, at most 8 h (never longer than the account's own limit: `web.session.local` for
70
+ an admin, `web.guests.session` for a guest), 30 min unused, and they end when the link closes.
78
71
  - At most 8 sessions; the least recently used is dropped.
79
72
  - The session menu (sidebar): "Signed in · …", "Ends by <time> at the latest, or after <span> unused". With more than
80
73
  one session it lists **Signed-in devices** (this one marked "· This device", others with **Sign out**) and **Sign
@@ -100,8 +93,12 @@ as their own Discord or Telegram account. What a guest sees:
100
93
  ClassicBot room, and ClassicBot group rooms while their membership is verified, minus any `web.guests.narrow`.
101
94
  **Start from today's guests** turns that into grants.
102
95
 
103
- They can chat there unless `web.guests.chat` is false, never send a command (text starting with `/` is refused), and the
104
- agent sees them as `via web (guest)`. A guest's app has no Fleet, View, Settings or Needs you. To invite someone: turn it
96
+ They can chat there unless `web.guests.chat` is false, run only the commands the command table lets anyone run in that
97
+ agent's channel (on the web: `/ctx`, `/steer`, `/btw`, `/cancel`; anything else is refused), open the usage panel, and the
98
+ agent sees them as `via web (guest)`. A guest's app has no Fleet, Settings or Needs you. Each person is **Chat** (the
99
+ default) or **Trusted** (#2855, `level: trusted` on the grant; Chat → Trusted waits for a fleet admin): a Trusted guest
100
+ also gets a read-only **View** of those agents (no typing; 2 reads a second, 2 agents at once) and **search** of the chat
101
+ messages it can already see (6 a minute, 20 results; no messages between agents, tasks or settings). To invite someone: turn it
105
102
  on, grant them their agents in Settings → Access & security → Guests, and press **Send sign-in code** (or tell them to
106
103
  send `/web`). The Guests section is not in Settings over the public link.
107
104
 
@@ -115,8 +112,8 @@ just **✓ Verified**, with the until-when in its tooltip, its accessible name a
115
112
  browser's messages then carry the account's authority in their delivery receipt for `max_session_hours` (default 48).
116
113
  Not me signs that browser out, also after Confirm, from the same card. At most one card waits per browser, and 3 an hour
117
114
  per account. Never for a guest. Over the admin's own named link (#2453) only with **Also over my named link**
118
- (`named_link`, off by default); over the temporary public link `/web` opens only with **Also over the temporary public
119
- link** (`quick_link`, off by default, §0.3). That authority ends with the link, and the card says "over your named link"
115
+ (`named_link`, off by default); over the temporary public link `/web` opens while **Also over the temporary public
116
+ link** is on (`quick_link`, on by default since #2819, §0.3; `quick_link: false` turns it off). That authority ends with the link, and the card says "over your named link"
120
117
  or "over the temporary public link". When a browser can't be authorized, the line says why (with a link to Settings when the switch, "Only
121
118
  this computer" or the named-link option is the reason). Settings → Access & security → **Web authority** (`web.verified_authority`, on
122
119
  by default) has the switch, **Only this computer can authorize** (`loopback_only`), **Also over my named link** (shown
@@ -152,8 +149,7 @@ workspace `inbox/`; an unused upload is deleted after 30 minutes.
152
149
 
153
150
  **In replies.** Images inline; video and audio play inline; Markdown, CSV, JSON, code and text files get a **Show**
154
151
  card (200 lines, then "Show all … lines"); other files download. Code blocks have a language tag, **Wrap** and
155
- **Copy**, and fold after 30 lines. **⋯ → Full width** (desk only, off by default, this browser's choice) widens the
156
- thread and the composer to the whole chat panel for wide tables and code; a person's bubbles keep their size. Each reply has **Copy this reply**. Markdown: headings, lists, quotes, bold/italic/
152
+ **Copy**, and fold after 30 lines. Each reply has **Copy this reply**. Markdown: headings, lists, quotes, bold/italic/
157
153
  strike, links, and tables (header row plus separator, alignment, up to 20 columns). Discord mentions show as names;
158
154
  a Discord server emoji (`<:name:id>`) of the fleet's servers shows as its picture, and any other (or one whose picture
159
155
  can't load) as `:name:`. Unicode emoji are drawn by the system's colour emoji font under every theme font (boxes on
@@ -203,8 +199,7 @@ A prompt shows its own answer buttons (first answer wins); a delivery has **Ackn
203
199
  "Paused: sign-in needed" has **Sign in** when the dashboard can run that login (#2233); every item has **Open chat**. **Notify me on this device** (Turn on / Turn off) gives desktop notifications while the
204
200
  tab is hidden — per browser, not on phones or plain-HTTP addresses. Config: `needs_you.live_message` (default on),
205
201
  `needs_you.dm` (default off), `needs_you.task_board` (default off: the task board's cards waiting
206
- for you — set `true` to list them). The task board's daily summary is `defaults.task_board.summary_at` (off unless set,
207
- e.g. `"09:00"`).
202
+ for you — set `true` to list them).
208
203
 
209
204
  ## Search
210
205
 
@@ -216,7 +211,7 @@ Board tasks — never a CLI's own transcript (that is the Log). Results come as
216
211
  first, badged Chat / Message / Task; 1–2 character words work (alone: the newest 5,000 entries, said in the dialog).
217
212
  ↑↓ / Enter / Esc / click outside; **Filters**: agent, team, time, kinds, **Only mine**; recent searches when empty.
218
213
  A chat result opens the chat at the message (flashed); a message between agents, a task or a chat row the history no
219
- longer keeps opens as the index's copy. Admins only, over the temporary public link and on a phone too (no guests). Config: `web.search.enabled`
214
+ longer keeps opens as the index's copy. Admins, over the temporary public link and on a phone too; a Trusted guest (#2855) searches only its own agents' chat messages it can see. Config: `web.search.enabled`
220
215
  (default on, off everywhere), `web.search.public_link` (default on; false keeps it off the public link), `web.search.retention_days` (unset and 0 = no age limit; 1–3650 days; daily prune still caps at 300,000). Secrets are masked; a hidden `cross_instance_visibility`
221
216
  agent's messages are not found. "Search is off or not available": `web.search.enabled: false`, or the index could not
222
217
  open (the fleet log says why); "Still indexing": the first fill after an upgrade.
@@ -247,9 +242,7 @@ The sidebar's **Fleet** (zh "Fleet 概覽", at the top) and the phone's Fleet ta
247
242
  delete: cancel. Alt+arrows on a card's title move it (no drag needed; the card's Position row on a phone). A main
248
243
  task's tile shows the sub task at work and who is on it; a card waiting for review that is not wrapped up says
249
244
  **To fill in** and Confirm asks first. A card's **Dispatched by** row: who handed it out (a blocked question goes
250
- to them first). Read-only over the public link. The cards you handed out that wait for your confirmation, or are
251
- blocked, are also **Needs you** items: on the web they open the card; in each bot's live message in General they
252
- have **Confirm** / **Send back** / **Answer** (the words are a reply to the bot's prompt).
245
+ to them first). Read-only over the public link.
253
246
  - **Schedules** — every schedule (silent ones included): when it runs in words, "next …", the target. **New
254
247
  schedule** (Repeat with a cron expression, or Once at a date and time; message, target, label, timezone),
255
248
  **Edit** (with an **Enabled** box — that is how you pause one), **Delete**. There is no "run now", and silent can't
@@ -281,8 +274,7 @@ activity line, **Find in office** and **Chat**. A double-click opens the chat di
281
274
  (lifetime work, docs/office.md § Levels; **Settings → Web dashboard → Office levels**, `web.office_levels`). **Find** dims
282
275
  the rest. **Show** picks a team or the Lobby and **People** pins chosen instances (both kept per browser); the
283
276
  **Office** switcher lists offices kept on the host (`web-offices.json`, `GET`/`PUT /ui/offices`). An admin session
284
- (never a read-only one, a guest or the public link) gets **Edit offices** (≥1200 px: a panel docked on the right in the
285
- usage rail's place, the Office in use beside it, × or Esc closes it and the rail returns; narrower: a centred dialog): add, rename and delete offices, pick who is
277
+ (never a read-only one, a guest or the public link) gets **Edit offices**: add, rename and delete offices, pick who is
286
278
  in each (Everyone, Picked: whole teams or single instances, or #2752 Nobody: its style's NPCs only; none picked = everyone) and its style, and upload or delete **skin packs** (an
287
279
  artist's pictures: `manifest.json` plus PNGs, format v1, kept in `web-office-skins/` in the AgEnD home; the host
288
280
  checks every rule — PNG only, each strip exactly frames·w × h, a 16:9 background, size caps — and never changes a
@@ -306,10 +298,7 @@ its own night place, **Back to the pack's night place** undoes it (#2665); a sel
306
298
  office's members, several allowed) and **Lend when away** (#2691) — whoever it is for sits there first when they come
307
299
  to its area, nobody else does unless it is lent while they are all away (a borrower moves off when one comes), and a
308
300
  reserved seat's handle is ringed; a pack can reserve seats as well; **Save layout** keeps the moves as that
309
- office's overrides (the pack stays as uploaded), **Reset** goes back to the pack's own. On a screen ≥1200 px its controls sit in the right-hand panel (the canvas whole for the
310
- handles); narrower, or in fullscreen, they are the bar along the canvas's bottom. Esc is Cancel. While either editor
311
- is docked the page beside it works, Ctrl+K search included; leaving the page with unsaved changes asks first
312
- ("Discard changes"). While it is open the office picker and Edit offices wait (**Cancel** closes it); if someone
301
+ office's overrides (the pack stays as uploaded), **Reset** goes back to the pack's own. While it is open the office picker and Edit offices wait (**Cancel** closes it); if someone
313
302
  saved the offices meanwhile, Save says so and keeps your layout — Save again puts it on the current list. A crowded area packs extra people into a tighter grid, then shows "+N" in its corner; there
314
303
  only calls and work get bubbles (a few at most) and name tags show on hover or focus. **Hide paused and stopped**
315
304
  (per browser, off by default) leaves the sleepers out. Now and then someone says a short line for their state in a
@@ -379,7 +368,8 @@ Each row (#2179): name and context % on the first line, the time of the agent's
379
368
  second ("2 min ago"; cross-instance messages don't count); a reply under 10 minutes old is highlighted, fading by itself
380
369
  (nothing to mark read). The sort button beside Edit: **Custom** (default; a reply never moves a row) or **Recent replies**
381
370
  (the rest by last reply, no groups, no dragging; favorites pinned in their order, or **Sorted by last reply too**); synced
382
- as `nav.sort`. Guests and the anonymous View reader: no times, no sort (always Custom).
371
+ as `nav.sort`. Guests sort, star and filter as their own preferences (kept on the host under their account; reply times
372
+ count only replies their channel showed; no dragging); the anonymous View reader: no times, no sort (always Custom).
383
373
  **Filter: name, model, backend** (Esc clears), facets **Status** and **CLI**, "N / M shown".
384
374
  While a filter is on, the instance you have open stays on top under **Current**. **Favorites**: the star on a row;
385
375
  **Edit** to reorder (at most 50; "Clear the filter to reorder favorites"). Drag to reorder the full list; groups fold.
@@ -556,11 +546,11 @@ ClassicBot (in **Chat & connections**, `/settings/chat#classicbot`) — per room
556
546
  Advanced **Context lines** (these restart the room's agent); Tool progress and Require a delivered reply (now).
557
547
 
558
548
  **Agent defaults** — **Project folders** (`project_roots`: where New agent may put an agent; empty = anywhere;
559
- changing it waits for a fleet admin's OK) and the fleet defaults (`defaults.*`): **Language (bot replies)** (`locale`: Auto / en / zh-TW; read at startup: restart AgEnD), default
549
+ changing it waits for a fleet admin's OK) and the fleet defaults (`defaults.*`): **Language (bot replies)** (`locale`: Auto / en / zh-TW), default
560
550
  backend and model, auto-pause, tool progress, bot-to-bot visibility, reply guard, **Native replies trigger ClassicBot**
561
551
  (`reply_triggers`: a native reply triggers a ClassicBot bot; off by default, #2576); Advanced: tool set, agent mode, log
562
552
  level, **Hang detector enabled** / **Stuck timeout** (`hang_detector.*`), **Startup concurrency** (1–20) and
563
- **Stagger delay** (`startup.*`, used from the next agent start, no restart). ClassicBot defaults (in Chat & connections; `classicBot.yaml defaults.*`): default backend, tool
553
+ **Stagger delay** (`startup.*`, restart AgEnD). ClassicBot defaults (in Chat & connections; `classicBot.yaml defaults.*`): default backend, tool
564
554
  progress, reply guard, **Native replies trigger ClassicBot** (`reply_triggers`, also per room), **ClassicBot admins**,
565
555
  **Allowed guilds**.
566
556
 
@@ -602,7 +592,7 @@ when the host confirms; a directory that is entered must be absolute.
602
592
  ## Look
603
593
 
604
594
  For an agent changing its *own* look, the `web-appearance` skill has the tools and limits. What a person sees in
605
- Settings → **Look**, card by card (the app icon, card upload limits and Canvas Worker effects are in **Web dashboard**; following reduced motion and custom CSS off here are in **Preferences**):
595
+ Settings → **Look**, card by card (the app icon and card upload limits are in **Web dashboard**; following reduced motion and custom CSS off here are in **Preferences**):
606
596
  - **Agents' themes** — **Show agents' themes, effects and widgets**; off, every chat looks the same and pictures and
607
597
  ring colours fall back to the bots' own (all devices).
608
598
  - **Ambient effects** — an agent's falling petals, snow, rising lanterns, twinkles or stars on a click, drawn behind
@@ -621,38 +611,21 @@ Settings → **Look**, card by card (the app icon, card upload limits and Canvas
621
611
  **Save and try**, then **Keep** within 15 s or it reverts; **Turn off (all devices)**; earlier versions **Use
622
612
  this**. If something is hidden or broken, open the page with `?safe=1`, or tick **Turn off custom CSS on this
623
613
  device** (in Preferences).
624
- - **Mods** — one `.agendmod.json` file carrying a look; importing shows everything first and applies only what you
625
- tick (custom CSS is never pre-ticked); agents can propose mods (**Review** / **Dismiss**); **Export a mod** writes one.
626
- Uninstalling removes the mod, not what it applied.
627
- - **Effects** — the effect library (upload a folder with `effect.json` and `worker.js`, up to 1 MiB), save one for a
628
- chat, share your copy; **Your effect choices** for Sidebar / Header / Page / Box (each with Pause / Resume and
629
- Clear) and a Cursor (its state, and Clear). CW uses the dashboard's opaque isolated document, independently of
630
- **Allow HTML previews**, its listener and port. Signed-in public/guest viewers can play current effects in chats they
631
- may see, without library, personal-slot, Trial or profile grants. Their Chat header offers a browser-local show/off
632
- switch and recovery, on desktop and phone; it never changes host preferences. A Try sample starts on a signed-in non-public admin's
633
- click, with no extra consent. The show switch, safe mode, hidden tab, browser support and live performance guard remain.
634
- No startup FPS calibration; data saver does not block. Reduced motion blocks only if this device chose to follow it.
635
- A blocked placement keeps an exact named notice. On ordinary dashboard sessions, Show/custom-CSS actions open
636
- **Look**. Public/guest Show-off has **Turn effects on here**; a guest CSS refusal offers Reload.
637
- An unavailable
638
- isolated transport offers Reload, never an HTML-preview setup step. A motion refusal offers **Play effects anyway**;
639
- safe mode offers **Leave safe mode**. The dialog names loading, safety and raw unknown codes. Codes stay local; agents get only closed recent blocked reasons without viewer identifiers or counts.
640
614
  - **Restore defaults** — resets this host's appearance settings (it lists what it resets first).
641
615
 
642
616
  Moved out of Look in 2.3.2 (#2347). **Preferences** (this device only): **Effects: follow the system's reduced-motion
643
- setting** (off by default): on, both ambient and Canvas Worker effects stay still while the system asks for reduced motion. Otherwise both play, with one shared one-time chat note and a local action to follow the system. And **Turn off custom CSS on this device**. **Web dashboard**: the **App icon**;
617
+ setting** (off by default): on, ambient effects stay still while the system asks for reduced motion. Otherwise they play, with one shared one-time chat note and a local action to follow the system. And **Turn off custom CSS on this device**. **Web dashboard**: the **App icon**;
644
618
  **Identity card upload limits** — portrait and banner size limits and per-agent picture quota (`web.appearance.*`);
645
- lowering applies at once, raising waits for an admin; and **Experimental: Canvas Worker effects**.
619
+ lowering applies at once, raising waits for an admin.
646
620
 
647
621
  **What an agent can change for the user.** A worker changes only its own look (the `web-appearance` tools); before
648
622
  #2064 everything on this page was the person's. Since #2064 (2.2.5) General, coordinators and
649
623
  full-profile instances get `get_web_settings` / `set_web_settings`, which go through the same checks as the page;
650
624
  workers don't. The `web-appearance` skill's **For the user** section has the details. In short: General can change
651
- the host's appearance settings, one agent's identity colour, mods (review, install, cancel, dismiss, uninstall),
652
- effects and the effect slots, and Restore defaults; for custom CSS it can save a version **on trial**, keep or revert
625
+ the host's appearance settings, one agent's identity colour, ambient effects and Restore defaults; for custom CSS it can save a version **on trial**, keep or revert
653
626
  the trial, switch to an earlier saved version, or turn CSS off — and it keeps a trial only once the user says they like
654
627
  it (the user's decision). Still the person's own click on the page: choosing files from their computer
655
- (import a mod, upload an effect folder or CSS assets), the per-browser switches (custom CSS off on this device, Pause/Resume), downloading an exported mod, and the
628
+ (upload CSS assets), the per-browser switches (custom CSS off on this device, Pause/Resume), and the
656
629
  card upload limits. The docs' "Asking General to change it for you" says the same for people.
657
630
 
658
631
  ## Troubleshooting
@@ -687,7 +660,7 @@ off).
687
660
  - "Cloudflare gave no public address in time" — only after a real 60 s wait;
688
661
  - no steps at all: `web.public_link.allow_public: false`, or the sender is not a fleet admin.
689
662
 
690
- **"Your session has ended."** It lasted its 48 h (or the idle limit), a public link closed or ran 4 h / 30 min idle,
663
+ **"Your session has ended."** It lasted its 48 h (or the idle limit), a public link closed or ran out (at most 8 h) or sat 30 min idle,
691
664
  or someone ran `/web revoke`, **Sign out everywhere** or `agend web-token rotate`. Get a new code: `/web`, **Send me
692
665
  a new code**, or `agend web` on the host. "No session — open the dashboard link again" means the browser keeps no
693
666
  cookies for the site.
@@ -703,14 +676,3 @@ no instance uses that provider.
703
676
  **Settings won't change something.** Over a public link, Web settings and appearance are read only; a loosening
704
677
  change waits for an admin's confirmation in General chat; a value in the "Set in fleet.yaml" list must be edited in
705
678
  fleet.yaml (Advanced, or the file) and `agend reload`.
706
-
707
- ### Canvas Worker playback diagnostics
708
-
709
- The effect player loads only when there is something to play: the open chat has a placed effect, the person chose a
710
- personal effect, or a Try card is shown (#2193). Before that, nothing of it is in the page, by design. Ambient effects
711
- and custom CSS never need it.
712
-
713
- If an effect cannot play, the Chat notice and Effects dialog show its local refusal code. A failed Try retains its stop
714
- code on the offer card; the browser console also names refusals. Include the code when reporting a problem. Long chat
715
- history is checked separately from the bounded set of current paint holes. Moving the pointer away does not stop Try;
716
- window blur, navigation, closing or loss of the verified stage does. Local raw codes are not sent in agent summaries.
@@ -149,6 +149,13 @@ export interface LifecycleContext {
149
149
  checkModelFailover(name: string, fiveHourPct: number): void;
150
150
  /** Retire (delete) any pending Cancel button for an instance. No-op if none. */
151
151
  clearCancelButton(name: string): void;
152
+ /**
153
+ * #2897: a held dialog's notices — the instance-topic one and the General one, each unless its text is null —
154
+ * edited in place on a re-report, never posted twice. Absent: each report is a fresh post (contexts without a ledger).
155
+ */
156
+ showParkedNotice?(name: string, topicText: string | null, generalText: string | null): void;
157
+ /** #2897: the held dialog is resolved, or the instance stopped/restarted: take its notices back. No-op if none. */
158
+ resolveParkedNotice?(name: string): void;
152
159
  /** Called after a replacement Daemon object is live, for generation fencing and post-resume notices. */
153
160
  onDaemonReady?(name: string, daemonBootId: string): void;
154
161
  /** Test/integration seam for the non-LLM Codex quota second opinion. */
@@ -255,6 +262,12 @@ export interface LifecycleReplaceArgs {
255
262
  name: string;
256
263
  reason?: string;
257
264
  }
265
+ /**
266
+ * #2872: a one-line notice ("⚠️ Grok weekly limit used up — paused") where it is posted. In the instance's own topic
267
+ * (`elsewhereName` null) as it is; anywhere else (General) it must say whose: "⚠️ <name>: Grok weekly limit used up —
268
+ * paused". A line without a leading emoji gets the name in front.
269
+ */
270
+ export declare function plainNoticeLine(line: string, elsewhereName: string | null): string;
258
271
  /**
259
272
  * What the live usage endpoint says about whether this Codex login can work:
260
273
  * available — no regular window is full: the usage-limit text is stale;
@@ -369,6 +382,12 @@ export declare class InstanceLifecycle {
369
382
  */
370
383
  /** @returns whether the notice was actually dispatched (false when suppressed). */
371
384
  private notifyIncident;
385
+ /**
386
+ * #2897: a held dialog's notice in the instance's topic and in General — through the fleet's notice ledger when it
387
+ * has one (one live message per place, edited in place, taken back on resolve), else as two fresh posts. The topic
388
+ * notice is suppressed as before; the General text skips notifyFleetError's text throttle, as the ledger keeps it to one.
389
+ */
390
+ private notifyParked;
372
391
  /**
373
392
  * Per-instance MCP incident fence. The mcp_died handler awaits an auth probe
374
393
  * (up to 5s) before it notifies; a recovery that lands inside that window
@@ -151,6 +151,17 @@ const AUTH_ALERT_COOLDOWN_MS = 5 * 60_000;
151
151
  * token-free check answers for all of them.
152
152
  */
153
153
  const AUTH_VERIFY_CACHE_MS = 60_000;
154
+ /**
155
+ * #2872: a one-line notice ("⚠️ Grok weekly limit used up — paused") where it is posted. In the instance's own topic
156
+ * (`elsewhereName` null) as it is; anywhere else (General) it must say whose: "⚠️ <name>: Grok weekly limit used up —
157
+ * paused". A line without a leading emoji gets the name in front.
158
+ */
159
+ export function plainNoticeLine(line, elsewhereName) {
160
+ if (!elsewhereName)
161
+ return line;
162
+ const m = /^(\p{Extended_Pictographic}\uFE0F?)\s*/u.exec(line);
163
+ return m ? t("inst.notice_named", m[1], elsewhereName, line.slice(m[0].length)) : t("inst.notice_named", "", elsewhereName, line).trimStart();
164
+ }
154
165
  const CODEX_QUOTA_VERIFY_TIMEOUT_MS = 5_000;
155
166
  const CLAUDE_QUOTA_VERIFY_TIMEOUT_MS = 5_000;
156
167
  /**
@@ -347,6 +358,27 @@ export class InstanceLifecycle {
347
358
  const dispatched = this.ctx.notifyInstanceTopic(name, text);
348
359
  return dispatched !== false;
349
360
  }
361
+ /**
362
+ * #2897: a held dialog's notice in the instance's topic and in General — through the fleet's notice ledger when it
363
+ * has one (one live message per place, edited in place, taken back on resolve), else as two fresh posts. The topic
364
+ * notice is suppressed as before; the General text skips notifyFleetError's text throttle, as the ledger keeps it to one.
365
+ */
366
+ notifyParked(name, kind, topicText, generalText) {
367
+ if (!this.ctx.showParkedNotice) {
368
+ this.notifyIncident(name, kind, topicText);
369
+ this.ctx.notifyFleetError?.(generalText);
370
+ return;
371
+ }
372
+ if (this.ctx.isPlannedRestart()) {
373
+ this.ctx.logger.info({ name, kind }, "Incident notification suppressed — planned restart in progress");
374
+ return;
375
+ }
376
+ // As before: a storm folds the topic notice into its summary; General's is not part of that.
377
+ const stormed = this.ctx.stormSuppressed?.(kind) === true;
378
+ if (stormed)
379
+ this.ctx.logger.info({ name, kind }, "Incident notification suppressed — included in tmux storm summary");
380
+ this.ctx.showParkedNotice(name, stormed ? null : topicText, generalText);
381
+ }
350
382
  /**
351
383
  * Per-instance MCP incident fence. The mcp_died handler awaits an auth probe
352
384
  * (up to 5s) before it notifies; a recovery that lands inside that window
@@ -922,18 +954,19 @@ export class InstanceLifecycle {
922
954
  if (data.unrecognised) {
923
955
  // #1990: the question is a pane line — it may not name a place of its own.
924
956
  const asked = data.question ? t("inst.unrecognised_prompt_question", noPlaceMarkers(data.question)) : "";
925
- this.notifyIncident(name, "dialog_parked", t("inst.unrecognised_prompt", name, asked));
926
- this.ctx.notifyFleetError?.(t("fleet.unrecognised_prompt", instancePlace(name), asked));
957
+ this.notifyParked(name, "dialog_parked", t("inst.unrecognised_prompt", name, asked), t("fleet.unrecognised_prompt", instancePlace(name), asked));
927
958
  return;
928
959
  }
929
960
  const category = data.kind && data.kind !== "dialog" ? interactionCategory(data.kind, data.backend) : null;
930
961
  const text = category ? t("inst.interaction_parked", name, category) : data.holdOnly
931
- ? t("inst.dialog_parked_hold", name, data.description)
932
- : t("inst.dialog_parked_stuck", name, data.description);
933
- this.notifyIncident(name, "dialog_parked", text);
962
+ // #2872: the Claude session-resume advice only for that prompt (it read as nonsense under a grok or kiro dialog).
963
+ ? t("inst.dialog_parked_hold", name, data.description) + (data.advice === "claude-resume" ? " " + t("inst.dialog_parked_hold_claude_resume") : "")
964
+ : t("inst.dialog_parked_stuck", name, data.description) + (data.advice === "claude-resume" ? " " + t("inst.dialog_parked_stuck_claude_resume") : "");
934
965
  // #1990: in General, the instance's name links to its topic.
935
- this.ctx.notifyFleetError?.(category ? t("fleet.interaction_parked", instancePlace(name), category) : t("fleet.dialog_parked", instancePlace(name), data.description));
966
+ this.notifyParked(name, "dialog_parked", text, category ? t("fleet.interaction_parked", instancePlace(name), category) : t("fleet.dialog_parked", instancePlace(name), data.description));
936
967
  }, this.ctx.logger, `daemon.dialog_parked[${name}]`));
968
+ // #2897: the held dialog is gone (closed, answered, auto-answered) — its notices go with it.
969
+ daemon.on("dialog_unparked", safeHandler(() => this.ctx.resolveParkedNotice?.(name), this.ctx.logger, `daemon.dialog_unparked[${name}]`));
937
970
  daemon.on("dialog_answer_ignored", safeHandler((data) => {
938
971
  // A runtime dialog the daemon DID answer, that did not go away. Same rule as dialog_parked: no assist
939
972
  // buttons (a one-tap Enter is exactly what just failed, and may be the wrong choice), and nothing from the
@@ -943,10 +976,11 @@ export class InstanceLifecycle {
943
976
  if (this.ctx.isPlannedRestart())
944
977
  return;
945
978
  const text = t(data.holdsDeliveries ? "inst.dialog_answer_ignored_held" : "inst.dialog_answer_ignored", name, data.description, String(data.attempts));
946
- this.notifyIncident(name, "dialog_answer_ignored", text);
947
- this.ctx.notifyFleetError?.(t("fleet.dialog_answer_ignored", instancePlace(name), data.description, String(data.attempts)));
979
+ this.notifyParked(name, "dialog_answer_ignored", text, t("fleet.dialog_answer_ignored", instancePlace(name), data.description, String(data.attempts)));
948
980
  }, this.ctx.logger, `daemon.dialog_answer_ignored[${name}]`));
949
981
  daemon.on("instance_interaction", () => this.ctx.onAttentionChanged?.(name));
982
+ // #2822: a usage-limit hold began or ended — Needs you lists it while it lasts.
983
+ daemon.on("usage_hold", () => this.ctx.onAttentionChanged?.(name));
950
984
  daemon.on("interactive_prompt", safeHandler(async (data) => {
951
985
  this.ctx.eventLog?.insert(name, "interactive_prompt", { kind: data.kind });
952
986
  this.ctx.logger.warn({ name, kind: data.kind, prompt: data.prompt }, "Instance is waiting for interactive terminal input");
@@ -988,7 +1022,7 @@ export class InstanceLifecycle {
988
1022
  // ChatGPT-plan feature, so an account that cannot be asked is almost
989
1023
  // always a plain one, and a wrongly paused reserve wakes with /wake while
990
1024
  // a missed pause fails silently forever.
991
- if (data.type === "quota" && data.action === "pause" && this.backendOf(name) === "codex") {
1025
+ if (data.type === "quota" && data.action === "pause" && !data.skipUsageVerify && this.backendOf(name) === "codex") {
992
1026
  const verdict = await this.verifyCodexQuota();
993
1027
  this.ctx.logger.info({ name, backend: "codex", decision: verdict === "available" || verdict === "reserve" ? "ignore" : "pause", evidence: `usage-${verdict}` }, `codex usage-limit decision: decision=${verdict === "available" || verdict === "reserve" ? "ignore" : "pause"} evidence=usage-${verdict}`);
994
1028
  if (verdict === "available") {
@@ -1074,7 +1108,11 @@ export class InstanceLifecycle {
1074
1108
  else if (notificationTarget && data.action !== "backoff_restart" && data.action !== "nudge_continue") {
1075
1109
  // backoff_restart / nudge_continue notifications are handled in the action branch below
1076
1110
  // with per-attempt context (attempt N/max, delay).
1077
- this.notifyIncident(notificationTarget, "pty_error", t("inst.notification", emoji, name, incidentMessage, data.action));
1111
+ // #2872: a notice the user asked to be one line (grok's weekly limit) is posted as it is: no "(action: …)", and no
1112
+ // name in the instance's own topic; elsewhere (a ClassicBot's go to General) the name follows its emoji.
1113
+ this.notifyIncident(notificationTarget, "pty_error", data.notice
1114
+ ? plainNoticeLine(data.notice, notificationTarget === name ? null : name)
1115
+ : t("inst.notification", emoji, name, incidentMessage, data.action));
1078
1116
  }
1079
1117
  this.ctx.webhookEmit("pty_error", name, { type: data.type, action: data.action, message: data.message });
1080
1118
  // The CLI interrupted itself on this error, so any pending Cancel button is
@@ -1505,6 +1543,8 @@ export class InstanceLifecycle {
1505
1543
  this.ctx.touchActivity(name);
1506
1544
  });
1507
1545
  this.attachIncidentHandlers(name, daemon);
1546
+ // #2897: a new daemon starts with no dialog held; a notice the last one left (a crash, a respawn) is out of date.
1547
+ this.ctx.resolveParkedNotice?.(name);
1508
1548
  daemon.on("pty_recovered", safeHandler((data) => {
1509
1549
  const mins = Math.floor(data.downtime_s / 60);
1510
1550
  const secs = data.downtime_s % 60;
@@ -1663,6 +1703,8 @@ export class InstanceLifecycle {
1663
1703
  this.invalidate(name);
1664
1704
  this.wokeAt.delete(name);
1665
1705
  this.ctx.setTopicIcon(name, "remove");
1706
+ // #2897: a stopped instance holds no dialog — its "needs a human" notices are out of date.
1707
+ this.ctx.resolveParkedNotice?.(name);
1666
1708
  // B1: cancel any pending capacity backoff timer so a stopped/removed
1667
1709
  // instance is not restarted behind the user's back.
1668
1710
  const pendingBackoff = this.capacityBackoffTimers.get(name);