@songsid/agend 2.2.0 → 2.3.0-beta.2

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 (298) hide show
  1. package/dist/agent-cli.js +248 -2
  2. package/dist/agent-cli.js.map +1 -1
  3. package/dist/agent-endpoint.d.ts +2 -0
  4. package/dist/agent-endpoint.js +25 -0
  5. package/dist/agent-endpoint.js.map +1 -1
  6. package/dist/agent-file-read.d.ts +35 -0
  7. package/dist/agent-file-read.js +144 -0
  8. package/dist/agent-file-read.js.map +1 -0
  9. package/dist/agent-whats-new.js +8 -0
  10. package/dist/agent-whats-new.js.map +1 -1
  11. package/dist/atomic-write.js +9 -1
  12. package/dist/atomic-write.js.map +1 -1
  13. package/dist/auth-api.js +17 -0
  14. package/dist/auth-api.js.map +1 -1
  15. package/dist/backend/antigravity.js +3 -3
  16. package/dist/backend/antigravity.js.map +1 -1
  17. package/dist/backend/claude-code.js +5 -1
  18. package/dist/backend/claude-code.js.map +1 -1
  19. package/dist/backend/launch-effort.js +1 -1
  20. package/dist/backend/launch-effort.js.map +1 -1
  21. package/dist/backend/muse.js +10 -2
  22. package/dist/backend/muse.js.map +1 -1
  23. package/dist/backend/types.d.ts +8 -0
  24. package/dist/backend/types.js +10 -0
  25. package/dist/backend/types.js.map +1 -1
  26. package/dist/cache-analysis.d.ts +47 -1
  27. package/dist/cache-analysis.js +68 -8
  28. package/dist/cache-analysis.js.map +1 -1
  29. package/dist/cache-report-tool.d.ts +17 -0
  30. package/dist/cache-report-tool.js +40 -0
  31. package/dist/cache-report-tool.js.map +1 -0
  32. package/dist/cache-service.d.ts +15 -0
  33. package/dist/cache-service.js +26 -1
  34. package/dist/cache-service.js.map +1 -1
  35. package/dist/channel/adapters/discord.d.ts +2 -0
  36. package/dist/channel/adapters/discord.js +17 -2
  37. package/dist/channel/adapters/discord.js.map +1 -1
  38. package/dist/channel/adapters/telegram.d.ts +8 -1
  39. package/dist/channel/adapters/telegram.js +74 -4
  40. package/dist/channel/adapters/telegram.js.map +1 -1
  41. package/dist/channel/mcp-tools.js +36 -0
  42. package/dist/channel/mcp-tools.js.map +1 -1
  43. package/dist/channel/types.d.ts +15 -0
  44. package/dist/cli.js +7 -3
  45. package/dist/cli.js.map +1 -1
  46. package/dist/config-validator.js +22 -2
  47. package/dist/config-validator.js.map +1 -1
  48. package/dist/daemon.js +244 -20
  49. package/dist/daemon.js.map +1 -1
  50. package/dist/fleet-context.d.ts +5 -0
  51. package/dist/fleet-manager.d.ts +92 -0
  52. package/dist/fleet-manager.js +410 -29
  53. package/dist/fleet-manager.js.map +1 -1
  54. package/dist/general-knowledge/skills/credential-profiles/SKILL.md +7 -0
  55. package/dist/general-knowledge/skills/web-appearance/SKILL.md +367 -0
  56. package/dist/instance-avatar.js +3 -0
  57. package/dist/instance-avatar.js.map +1 -1
  58. package/dist/instance-config-impact.js +3 -0
  59. package/dist/instance-config-impact.js.map +1 -1
  60. package/dist/instance-lifecycle.js +9 -4
  61. package/dist/instance-lifecycle.js.map +1 -1
  62. package/dist/needs-you-hub.d.ts +4 -0
  63. package/dist/needs-you-hub.js +31 -6
  64. package/dist/needs-you-hub.js.map +1 -1
  65. package/dist/needs-you.d.ts +1 -13
  66. package/dist/needs-you.js +3 -37
  67. package/dist/needs-you.js.map +1 -1
  68. package/dist/outbound-handlers.d.ts +7 -0
  69. package/dist/outbound-handlers.js +65 -10
  70. package/dist/outbound-handlers.js.map +1 -1
  71. package/dist/outbound-schemas.d.ts +74 -0
  72. package/dist/outbound-schemas.js +56 -0
  73. package/dist/outbound-schemas.js.map +1 -1
  74. package/dist/public-web-gateway.js +14 -0
  75. package/dist/public-web-gateway.js.map +1 -1
  76. package/dist/repo-worktree-guard.d.ts +36 -0
  77. package/dist/repo-worktree-guard.js +143 -0
  78. package/dist/repo-worktree-guard.js.map +1 -0
  79. package/dist/scheduler/scheduler.d.ts +70 -1
  80. package/dist/scheduler/scheduler.js +256 -17
  81. package/dist/scheduler/scheduler.js.map +1 -1
  82. package/dist/service-installer.d.ts +2 -1
  83. package/dist/service-installer.js +18 -3
  84. package/dist/service-installer.js.map +1 -1
  85. package/dist/settings-api.js +74 -1
  86. package/dist/settings-api.js.map +1 -1
  87. package/dist/settings-change.js +8 -0
  88. package/dist/settings-change.js.map +1 -1
  89. package/dist/settings-effect.js +16 -2
  90. package/dist/settings-effect.js.map +1 -1
  91. package/dist/settings-http-confirmation.js +5 -0
  92. package/dist/settings-http-confirmation.js.map +1 -1
  93. package/dist/tool-permissions.d.ts +5 -0
  94. package/dist/tool-permissions.js +61 -2
  95. package/dist/tool-permissions.js.map +1 -1
  96. package/dist/topic-commands.d.ts +10 -6
  97. package/dist/topic-commands.js +21 -17
  98. package/dist/topic-commands.js.map +1 -1
  99. package/dist/topic-link.d.ts +128 -0
  100. package/dist/topic-link.js +269 -0
  101. package/dist/topic-link.js.map +1 -0
  102. package/dist/types.d.ts +13 -0
  103. package/dist/ui/app-effects.js +187 -0
  104. package/dist/ui/chat-effect-posters.js +42 -0
  105. package/dist/ui/chat-effects.js +72 -0
  106. package/dist/ui/chat-live-replies.js +58 -0
  107. package/dist/ui/chat-render.js +4 -4
  108. package/dist/ui/chat-store.js +9 -3
  109. package/dist/ui/chat-strings.js +15 -0
  110. package/dist/ui/chat-thread.js +47 -21
  111. package/dist/ui/chat-tour.js +1 -1
  112. package/dist/ui/effect-trial-controller.js +119 -0
  113. package/dist/ui/effect-trial-offer.js +31 -0
  114. package/dist/ui/effect-trial-panel.js +37 -0
  115. package/dist/ui/fleet-cache.js +23 -1
  116. package/dist/ui/image-lightbox.js +1 -1
  117. package/dist/ui/panel-chat.js +85 -17
  118. package/dist/ui/panel-details.js +18 -5
  119. package/dist/ui/panel-fleet.js +3 -3
  120. package/dist/ui/panel-log.js +6 -6
  121. package/dist/ui/panel-needs.js +3 -3
  122. package/dist/ui/panel-settings.js +8 -5
  123. package/dist/ui/preview-panel.js +25 -9
  124. package/dist/ui/settings-appearance.js +325 -0
  125. package/dist/ui/settings-effects.js +201 -0
  126. package/dist/ui/settings-mods.js +257 -0
  127. package/dist/ui/settings-owner-effects.js +80 -0
  128. package/dist/ui/settings-strings.js +245 -0
  129. package/dist/ui/shared/agend-auth.js +27 -3
  130. package/dist/ui/shared/agent-widget.js +248 -0
  131. package/dist/ui/shared/app-i18n.js +2 -0
  132. package/dist/ui/shared/app-prefs.js +30 -10
  133. package/dist/ui/shared/app-route.js +23 -1
  134. package/dist/ui/shared/app-session.js +1 -1
  135. package/dist/ui/shared/app-shell.js +29 -16
  136. package/dist/ui/shared/app-store.js +2 -0
  137. package/dist/ui/shared/app-stream.js +12 -7
  138. package/dist/ui/shared/app-themes.js +188 -0
  139. package/dist/ui/shared/app.css +225 -3
  140. package/dist/ui/shared/app.js +6 -0
  141. package/dist/ui/shared/card-strings.js +28 -0
  142. package/dist/ui/shared/effect-app-runtime.js +248 -0
  143. package/dist/ui/shared/effect-baseline.js +64 -0
  144. package/dist/ui/shared/effect-chat-runtime.js +154 -0
  145. package/dist/ui/shared/effect-cursor.js +125 -0
  146. package/dist/ui/shared/effect-frame.js +127 -0
  147. package/dist/ui/shared/effect-geometry.js +122 -0
  148. package/dist/ui/shared/effect-host-style.js +10 -0
  149. package/dist/ui/shared/effect-owner-regions.js +74 -0
  150. package/dist/ui/shared/effect-owner-source.js +115 -0
  151. package/dist/ui/shared/effect-policy.js +137 -0
  152. package/dist/ui/shared/effect-poster-reader.js +98 -0
  153. package/dist/ui/shared/effect-posters.js +117 -0
  154. package/dist/ui/shared/effect-profiler.js +162 -0
  155. package/dist/ui/shared/effect-profiles.js +65 -0
  156. package/dist/ui/shared/effect-registry.js +496 -0
  157. package/dist/ui/shared/effect-runtime-loader.js +234 -0
  158. package/dist/ui/shared/effect-safety.js +153 -0
  159. package/dist/ui/shared/effect-stock-snapshot.js +34 -0
  160. package/dist/ui/shared/effect-stock-trust.js +165 -0
  161. package/dist/ui/shared/effect-trial-source.js +103 -0
  162. package/dist/ui/shared/effect-trial-stage.js +147 -0
  163. package/dist/ui/shared/header-tools.js +1 -1
  164. package/dist/ui/shared/identity-card.js +202 -0
  165. package/dist/ui/shared/identity-color.js +261 -0
  166. package/dist/ui/shared/instance-nav.js +37 -19
  167. package/dist/ui/shared/owner-css.js +221 -0
  168. package/dist/ui/shared/owner-effect-prefs.js +117 -0
  169. package/dist/ui/shared/panel-view.js +81 -8
  170. package/dist/ui/shared/signin.js +2 -0
  171. package/dist/ui/shared/ui-dialog.js +1 -1
  172. package/dist/ui/shared/ui-icons.js +2 -0
  173. package/dist/ui/shared/ui-menu.js +1 -1
  174. package/dist/ui/shared/ui-toast.js +1 -1
  175. package/dist/ui/shared/usage-dialog.js +14 -2
  176. package/dist/ui/shared/view-strings.js +36 -2
  177. package/dist/ui/signin.html +1 -0
  178. package/dist/usage/providers.d.ts +3 -0
  179. package/dist/usage/providers.js +4 -3
  180. package/dist/usage/providers.js.map +1 -1
  181. package/dist/view-api.d.ts +29 -0
  182. package/dist/view-api.js +188 -8
  183. package/dist/view-api.js.map +1 -1
  184. package/dist/web-api.d.ts +42 -0
  185. package/dist/web-api.js +898 -36
  186. package/dist/web-api.js.map +1 -1
  187. package/dist/web-appearance-limits.d.ts +82 -0
  188. package/dist/web-appearance-limits.js +83 -0
  189. package/dist/web-appearance-limits.js.map +1 -0
  190. package/dist/web-appearance-policy.d.ts +66 -0
  191. package/dist/web-appearance-policy.js +94 -0
  192. package/dist/web-appearance-policy.js.map +1 -0
  193. package/dist/web-appearance-tools.d.ts +50 -0
  194. package/dist/web-appearance-tools.js +105 -0
  195. package/dist/web-appearance-tools.js.map +1 -0
  196. package/dist/web-appearance-view.d.ts +99 -0
  197. package/dist/web-appearance-view.js +163 -0
  198. package/dist/web-appearance-view.js.map +1 -0
  199. package/dist/web-appearance.d.ts +79 -0
  200. package/dist/web-appearance.js +298 -0
  201. package/dist/web-appearance.js.map +1 -0
  202. package/dist/web-asset-parts.d.ts +93 -0
  203. package/dist/web-asset-parts.js +133 -0
  204. package/dist/web-asset-parts.js.map +1 -0
  205. package/dist/web-auth.js +17 -1
  206. package/dist/web-auth.js.map +1 -1
  207. package/dist/web-card.d.ts +96 -0
  208. package/dist/web-card.js +232 -0
  209. package/dist/web-card.js.map +1 -0
  210. package/dist/web-chat-history.d.ts +13 -0
  211. package/dist/web-chat-history.js +23 -2
  212. package/dist/web-chat-history.js.map +1 -1
  213. package/dist/web-effect-bundle.d.ts +28 -0
  214. package/dist/web-effect-bundle.js +126 -0
  215. package/dist/web-effect-bundle.js.map +1 -0
  216. package/dist/web-effect-canonical.d.ts +8 -0
  217. package/dist/web-effect-canonical.js +27 -0
  218. package/dist/web-effect-canonical.js.map +1 -0
  219. package/dist/web-effect-library.d.ts +114 -0
  220. package/dist/web-effect-library.js +530 -0
  221. package/dist/web-effect-library.js.map +1 -0
  222. package/dist/web-effect-poster.d.ts +8 -0
  223. package/dist/web-effect-poster.js +52 -0
  224. package/dist/web-effect-poster.js.map +1 -0
  225. package/dist/web-effect-profiles.d.ts +118 -0
  226. package/dist/web-effect-profiles.js +180 -0
  227. package/dist/web-effect-profiles.js.map +1 -0
  228. package/dist/web-effect-service.d.ts +86 -0
  229. package/dist/web-effect-service.js +314 -0
  230. package/dist/web-effect-service.js.map +1 -0
  231. package/dist/web-effect-tools.d.ts +47 -0
  232. package/dist/web-effect-tools.js +129 -0
  233. package/dist/web-effect-tools.js.map +1 -0
  234. package/dist/web-effect-trials.d.ts +86 -0
  235. package/dist/web-effect-trials.js +204 -0
  236. package/dist/web-effect-trials.js.map +1 -0
  237. package/dist/web-effect-upload.d.ts +27 -0
  238. package/dist/web-effect-upload.js +185 -0
  239. package/dist/web-effect-upload.js.map +1 -0
  240. package/dist/web-effect-worker.d.ts +8 -0
  241. package/dist/web-effect-worker.js +170 -0
  242. package/dist/web-effect-worker.js.map +1 -0
  243. package/dist/web-effect.d.ts +103 -0
  244. package/dist/web-effect.js +153 -0
  245. package/dist/web-effect.js.map +1 -0
  246. package/dist/web-identity-color.d.ts +87 -0
  247. package/dist/web-identity-color.js +209 -0
  248. package/dist/web-identity-color.js.map +1 -0
  249. package/dist/web-identity-palette.d.ts +113 -0
  250. package/dist/web-identity-palette.js +84 -0
  251. package/dist/web-identity-palette.js.map +1 -0
  252. package/dist/web-image-meta.d.ts +25 -0
  253. package/dist/web-image-meta.js +200 -0
  254. package/dist/web-image-meta.js.map +1 -0
  255. package/dist/web-mod-agent.d.ts +50 -0
  256. package/dist/web-mod-agent.js +205 -0
  257. package/dist/web-mod-agent.js.map +1 -0
  258. package/dist/web-mod-bundle.d.ts +149 -0
  259. package/dist/web-mod-bundle.js +470 -0
  260. package/dist/web-mod-bundle.js.map +1 -0
  261. package/dist/web-mod-export.d.ts +59 -0
  262. package/dist/web-mod-export.js +79 -0
  263. package/dist/web-mod-export.js.map +1 -0
  264. package/dist/web-mod-store.d.ts +283 -0
  265. package/dist/web-mod-store.js +625 -0
  266. package/dist/web-mod-store.js.map +1 -0
  267. package/dist/web-org.d.ts +3 -3
  268. package/dist/web-org.js +11 -17
  269. package/dist/web-org.js.map +1 -1
  270. package/dist/web-owner-css-store.d.ts +180 -0
  271. package/dist/web-owner-css-store.js +384 -0
  272. package/dist/web-owner-css-store.js.map +1 -0
  273. package/dist/web-owner-css.d.ts +58 -0
  274. package/dist/web-owner-css.js +552 -0
  275. package/dist/web-owner-css.js.map +1 -0
  276. package/dist/web-prefs.d.ts +48 -0
  277. package/dist/web-prefs.js +209 -33
  278. package/dist/web-prefs.js.map +1 -1
  279. package/dist/web-preview.d.ts +9 -1
  280. package/dist/web-preview.js +24 -7
  281. package/dist/web-preview.js.map +1 -1
  282. package/dist/web-settings-patch.d.ts +18 -0
  283. package/dist/web-settings-patch.js +51 -0
  284. package/dist/web-settings-patch.js.map +1 -1
  285. package/dist/web-shell-routes.d.ts +1 -1
  286. package/dist/web-shell-routes.js +1 -1
  287. package/dist/web-shell-routes.js.map +1 -1
  288. package/dist/web-theme-store.d.ts +218 -0
  289. package/dist/web-theme-store.js +516 -0
  290. package/dist/web-theme-store.js.map +1 -0
  291. package/dist/web-theme.d.ts +121 -0
  292. package/dist/web-theme.js +407 -0
  293. package/dist/web-theme.js.map +1 -0
  294. package/dist/web-widget.d.ts +72 -0
  295. package/dist/web-widget.js +245 -0
  296. package/dist/web-widget.js.map +1 -0
  297. package/package.json +1 -1
  298. package/templates/systemd.service.ejs +8 -0
@@ -189,6 +189,13 @@ A kiro profile that is configured but has never been logged in still gets a row,
189
189
  reading **Signed out — run `kiro-cli` to log in**. That is the reminder to go
190
190
  and log it in, so report it as such rather than as a missing subscription.
191
191
 
192
+ ## "Is the prompt cache costing us?"
193
+
194
+ `get_cache_report({ window?, instance?, top? })` is the dashboard's **Fleet → cache** report.
195
+ - **What a row has:** each instance's cache TTL as written and its 5m/1h write mix, the TTL it really behaves as (`effective_ttl`, with the gap-miss rate it is measured from), its expiry cost, and the keep-warm simulation and recommendation.
196
+ - **When to look:** when someone asks why costs rose, whether to keep caches warm, or whether to set `backend_options.claude-code.prompt_cache_ttl: "1h"`. A row recommending `switch_to_1h` is the answer to the last one.
197
+ - **What you can see:** as General you see every instance and the fleet summary.
198
+
192
199
  ## What to tell the user
193
200
 
194
201
  - Two agents with the same profile name share one login and one quota.
@@ -0,0 +1,367 @@
1
+ ---
2
+ name: web-appearance
3
+ description: How you look on the AgEnD web dashboard — check it, change your own theme, identity card, identity colour and widgets, play Canvas Worker effects in your chat (and offer a Try), preview the result, share it as a mod
4
+ roles: [worker]
5
+ ---
6
+
7
+ ## What it is
8
+
9
+ People see you on the web dashboard: in the sidebar, at the top of your chat, on your Details page and in View. You
10
+ can shape how you look there — **only your own look, and only on the surfaces that are yours**:
11
+
12
+ | Surface | What you set | Tools |
13
+ |---|---|---|
14
+ | Your name and role line | display name, description | `set_display_name`, `set_description` |
15
+ | Your status stamp | persona emoji | `set_persona_emoji` (see the `persona-emoji` skill) |
16
+ | Your chat | theme: colours, accent, bubbles, font, background picture, working label | `set_web_theme`, `set_web_theme_asset` |
17
+ | Your face and ring | theme picture and accent | `set_web_theme`, `set_web_theme_asset` |
18
+ | Your identity card | portrait, banner, tagline, bio | `set_web_theme` (`card.*`), `set_web_theme_asset` |
19
+ | Your identity colour | the colour people find you by in the sidebar, and where it shows (name, bar, ring) | `set_web_theme` (`identity`) |
20
+ | Your chat header strip and Details page | widgets: small panels of facts the dashboard draws | `set_web_widget`, `remove_web_widget` |
21
+ | A file of your look | a mod: export yours, or propose one for a person | `export_web_mod`, `propose_web_mod` |
22
+ | Effects in your chat | Canvas Worker animations, and Try cards a local admin may start | `upload_web_effect`, `apply_web_effect`, `preview_web_effect`, … (see Effects) |
23
+
24
+ None of these tools takes a target: they always act on you. You can't change another instance, the dashboard's own
25
+ chrome, a person's sidebar widget, or a person's custom CSS.
26
+
27
+ ## Look first
28
+
29
+ - `get_web_appearance` — how you appear **now**, resolved exactly as the dashboard resolves it: your face and where it
30
+ comes from (`profile`, `theme`, `bot`, `emoji` or `initial`), your ring colour, your **identity colour**
31
+ (`identity_color`: the colour people find you by in the sidebar, its `source` — `person`, `agent` (your theme's
32
+ `identity.color`, else its `accent`), `role` (your own bot's Discord role) or `auto` — its `light` / `dark` values,
33
+ where it shows (`show`: `name`, `bar`, `ring`) and whose choice that is (`show_source`: `person`, `agent` or `host`),
34
+ and `off` when the host turned colours off), your card field by field
35
+ (each marked `human` or `agent`), your theme per light/dark mode after the defaults, whether a person locked it, and
36
+ your limits.
37
+ - `preview_web_appearance` (`modes`: `["light"]`, `["dark"]` or both) — draws that as an SVG per mode into
38
+ `.agend/appearance/<mode>.svg` in your working directory, with the pictures it shows written beside it
39
+ (`avatar.png`, `portrait.png`, …), and returns both lists of paths. Read the SVGs for exact colours, geometry and
40
+ text, and the pictures as images. Only your own pictures are there.
41
+ - `get_web_theme` — your stored theme, the token defaults it is drawn over, your uploaded pictures (`id`, `slot`), and
42
+ `limits` (changes and uploads left, each picture slot's size limits, your picture quota).
43
+
44
+ ## What wins over what
45
+
46
+ - **A person's choices win.** A picture uploaded for you in View beats your theme picture. A person's card field (from
47
+ View's Edit profile) beats yours, field by field — leave it to them. A person can **Lock** your theme (every change
48
+ you try is refused with `locked`) or **Reset** it (your theme, card and pictures go; a lock stays).
49
+ - A widget **a person placed** in one of your slots takes your values (`data`), but you can't replace or remove it
50
+ (`person_placed`).
51
+ - **Each viewer decides what they see.** Anyone can turn agents' themes and widgets off for their own screens, and
52
+ `?safe=1` loads a page without them; they then see the default look, no widgets, and your face follows the usual order without your theme
53
+ picture — a picture a person uploaded for you, else your bot's avatar, your persona emoji or your first letter.
54
+ Don't rely on your theme to say something important.
55
+ - The fleet can turn agent changes off entirely (`web.themes.agent_edit: false`): every change is refused with
56
+ `theme_editing_off`; what you stored stays.
57
+
58
+ ## Change your theme
59
+
60
+ `set_web_theme { set?, clear? }` — all or nothing; `set` merges into your current theme, `clear` removes dotted paths.
61
+ Typed values only; anything else is refused with `{ errors: [{ path, problem }] }`:
62
+
63
+ - `colors.light` / `colors.dark`: any of `bg`, `surface`, `text`, `text2`, `accent`, `userBubble`, `agentBubble` as
64
+ `#rrggbb` (or `#rgb`). **Contrast is checked per mode**: `text` at least 4.5:1 on `bg`, `surface` and both bubbles;
65
+ `text2` at least 4.5:1 on `bg` and `surface`; `accent` at least 3:1 on `bg` — a palette that fails is refused, naming
66
+ the pair.
67
+ - `accent`: `#rrggbb` for both modes (a mode's own `accent` wins). Without `identity.color`, it is also your identity
68
+ colour.
69
+ - `identity`: `{ color?, show? }`: your identity colour and where it shows.
70
+ - `color` is a preset (`red`, `orange`, `amber`, `lime`, `green`, `teal`, `cyan`, `blue`, `indigo`, `violet`, `pink`,
71
+ `slate`, each readable in light and dark) or `#rrggbb`.
72
+ - `show` is a list of `name`, `bar` and `ring` (`[]` for nowhere). Left out, the host's default applies (ring and bar).
73
+ - A person's choice for you in the dashboard always wins, field by field, and their Reset brings yours back.
74
+ `get_web_appearance` says which is in force.
75
+ - `bubble`: `{ radius: 0..24, border: "none" | "thin" | "accent" }`.
76
+ - `font`: `"inter"`, `"system"` or `"mono"`.
77
+ - `background`: `{ image: <asset id>, fit: "cover" | "contain", opacity: 0.05..1 }`.
78
+ - `avatar`: an asset id — your face (below a person's upload).
79
+ - `workingLabel`: 1..24 characters on one line, shown while you work instead of "is working…".
80
+ - `card`: `{ portrait?, banner?, tagline?, bio? }` — see below.
81
+
82
+ Example:
83
+
84
+ ```json
85
+ { "set": { "accent": "#7c3aed", "colors": { "dark": { "bg": "#14121f" } }, "bubble": { "radius": 12, "border": "accent" },
86
+ "font": "inter", "workingLabel": "Reviewing" } }
87
+ ```
88
+
89
+ `reset_web_theme` puts your theme back to the default (it counts as a change).
90
+
91
+ ## Pictures
92
+
93
+ `set_web_theme_asset { slot, file }` — `file` is a picture in **your working directory** (no symlinks; read on your side,
94
+ never by path on the fleet). It returns `{ id }`; name that id in `set_web_theme`. Metadata such as GPS is removed, and
95
+ the id is the hash of what is kept, so the same picture is the same id.
96
+
97
+ | Slot | Types | Limits |
98
+ |---|---|---|
99
+ | `background` | png, jpeg, webp, gif | 512 KiB, 4096 px a side |
100
+ | `avatar` | png, jpeg, webp, gif | 256 KiB, 4096 px a side |
101
+ | `portrait` | png, jpeg, webp | set by the fleet (default 1024×1536, 1.5 MiB) |
102
+ | `banner` | png, jpeg, webp | set by the fleet (default 1600×600, 768 KiB) |
103
+
104
+ A picture holds one slot: upload it again for another slot only if it is a different picture. `get_web_theme`'s
105
+ `limits.asset_slots` has the limits in force and `limits.asset_quota` how many pictures you may keep. A picture your
106
+ theme stops naming is deleted.
107
+
108
+ ## Your identity card
109
+
110
+ `card.tagline` (one line, 1..60 characters), `card.bio` (1..280 characters, at most 3 line breaks), `card.portrait` and
111
+ `card.banner` (asset ids uploaded for those slots). Text is shown as text — never markup or links. A person may set
112
+ their own version of any field; theirs is shown instead of yours.
113
+
114
+ The card goes **inside `set`**: `set_web_theme({ set: { card: { tagline, bio, portrait, banner } } })` (a top-level
115
+ `card` argument is refused).
116
+
117
+ ## Your identity colour
118
+
119
+ The colour people find you by in the sidebar, drawn on your name, a bar at your row's left edge and/or the ring around
120
+ your picture. Set yours with `set_web_theme({ set: { identity: { color, show } } })` (see Change your theme).
121
+
122
+ - **Which colour shows**, first match wins: a **person's** pick for you (⋯ → Colour… or View's Edit profile, also from a
123
+ temporary public link) > **yours** (`identity.color`, else your theme's `accent`; only for a viewer who shows agents'
124
+ themes) > your own bot's Discord **role** colour > an **automatic** soft colour chosen from your name (two instances
125
+ may share one).
126
+ - **Where it shows**: a person's choice for you > yours (`identity.show`; again only while themes are shown) > the
127
+ host's default (Settings → Web appearance; ring and bar unless changed).
128
+ - The host can **turn colours off** for everyone: nothing is drawn, and every pick, yours included, is kept for when
129
+ they come back.
130
+ - `get_web_appearance`'s `identity_color` shows what is in force: `color`, `source` (`person`, `agent`, `role`, `auto`),
131
+ `light` / `dark`, `show`, `show_source` (`person`, `agent`, `host`) and `off`.
132
+
133
+ ## Widgets
134
+
135
+ A widget is a small panel of facts the dashboard draws **with its own components**: you send what to show and the
136
+ values, never HTML, script, links or CSS. It takes your theme's colours and always carries a `✦ <title>` chip. Nothing
137
+ in it can be clicked or focused.
138
+
139
+ `set_web_widget { slot, spec?, data? }`:
140
+
141
+ - `slot`: `chat_header` (a strip under your chat header: at most **4** items, of `stat`, `progress`, `text`, `badge`)
142
+ or `details` (a card on your Details page: at most **8** items, any type). `sidebar` is a person's: `owner_slot`.
143
+ - `spec` places or replaces the widget (a change):
144
+ `{ v: 1, title: 1..24 characters, items: [item, …] }`, where each item is `{ type, label?, key | bind, … }`:
145
+
146
+ | Type | Shows | Value | Extra |
147
+ |---|---|---|---|
148
+ | `stat` | a label and a number or short word | number, or 1..24 characters | `unit` (1..8 characters) |
149
+ | `progress` | a bar and its percentage | number, 0..`max` | `max` (default 100) |
150
+ | `text` | one line | 1..120 characters | |
151
+ | `list` | a short list | 1..6 lines of 1..60 characters | |
152
+ | `badge` | a coloured word | 1..24 characters | `tone`, or `tones: { word: tone }` (`ok`, `warn`, `bad`, `info`, `muted`) |
153
+ | `spark` | a sparkline and its last number | 2..48 numbers | |
154
+
155
+ `label` (1..24 characters) is required for `stat`, `progress` and `spark`. `key` (`a-z`, `0-9`, `_`) names a value
156
+ in your `data`. `bind` shows a value the page already has: `state` (`working`, `idle`, `needs`, `stopped`,
157
+ `crashed`) on `text` or `badge`, `context_pct` on `stat` or `progress`, `cost_usd` on `stat`. Exactly one of the
158
+ two. A missing value shows `—`.
159
+ - `data` alone updates the placed widget's values: merged, `null` removes a key. Values must fit every item that shows
160
+ them; a key no item shows is refused. Data has **its own budget**, separate from theme changes: at least **10 s**
161
+ apart, at most **180 an hour**.
162
+ - The spec is at most 2048 bytes and the data at most 4096.
163
+
164
+ `remove_web_widget { slot? }` takes your widget out of one slot, or both (a change). `get_web_theme` and
165
+ `get_web_appearance` list your widgets.
166
+
167
+ ```json
168
+ { "slot": "chat_header", "spec": { "v": 1, "title": "Build", "items": [
169
+ { "type": "progress", "label": "Tests", "key": "tests" },
170
+ { "type": "badge", "label": "State", "bind": "state", "tones": { "working": "info", "needs": "warn" } },
171
+ { "type": "text", "key": "step" } ] },
172
+ "data": { "tests": 40, "step": "Running unit tests" } }
173
+ ```
174
+
175
+ Then, as you go: `set_web_widget { "slot": "chat_header", "data": { "tests": 75 } }`.
176
+
177
+ ## Mods
178
+
179
+ A mod is one file, `<name>-<version>.agendmod.json`, that carries a look: a theme with its pictures, card text,
180
+ widgets and effects. People import mods in **Settings → Web appearance → Mods**. **You never import**: a person reviews
181
+ everything in a mod and ticks what to apply.
182
+
183
+ - `export_web_mod { name, version, title? }` writes **your own** look to `.agend/mods/<name>-<version>.agendmod.json`
184
+ in your working directory and returns `{ path, bytes }`. It carries your theme with its pictures, the effects your
185
+ theme places (with their params) when they are yours or shared with you, your own card text (not a person's card
186
+ fields), and the widgets you placed. A person's private effect placed on you stays out (`effects_omitted` counts it).
187
+ It never carries custom CSS or the sidebar widget, which are a person's. `name` is a-z, 0-9 and -, `version` is
188
+ MAJOR.MINOR.PATCH.
189
+ - `propose_web_mod { file }` sends a mod file from your working directory (at most 8 MiB) for a person to review. It
190
+ is checked whole and answers with its problems if it isn't valid. **A mod carrying custom CSS is refused**
191
+ (`owner_css_not_from_agent`). A muted line in your chat says it was proposed. Nothing changes until a person
192
+ installs it. One proposal at a time: a new one replaces yours. It counts as an upload.
193
+ - A widget a person placed from a mod is theirs: you may give it values (`set_web_widget` with `data`), but not replace
194
+ or remove it (`person_placed`).
195
+
196
+ The file format: `{ "format": "agend-mod", "v": 1, "manifest": { name, version, title, description?, author?,
197
+ requires?: { agend: ">=X.Y.Z" }, contents: { theme?, identity?, widgets?: { chat_header?, details? }, effects? } },
198
+ "files": { "<path>": { "sha256", "b64" } } }`. Every file is listed with its sha256 and used by exactly one part, paths
199
+ are lowercase with no `..`, and a theme names its pictures by path. The easiest way to get one right is to set your look
200
+ with the tools above, then `export_web_mod`.
201
+
202
+ ## Limits
203
+
204
+ - At least **30 s** between changes, at most **10 changes an hour**, at most **3 picture uploads an hour** — refused
205
+ with `rate_limited` and `retry_after_s`. Only an accepted change counts; a refused or invalid one costs nothing.
206
+ - Widget values (`set_web_widget` with `data` only): at least **10 s** apart, at most **180 an hour**, apart from the
207
+ above.
208
+ - Effects: `apply_web_effect` and `remove_web_effect` are changes; `upload_web_effect` and `propose_web_mod` are uploads.
209
+ At most 10 effects and 8 MiB of your own, at most two placed in your chat.
210
+ - Plan the whole look, check it in one `set_web_theme`, then preview — don't iterate change by change.
211
+
212
+ ## A good workflow
213
+
214
+ 1. `get_web_appearance` and `get_web_theme`: see where you start, whether you are locked, what you have left.
215
+ 2. Upload the pictures you need (`set_web_theme_asset`), one per slot.
216
+ 3. One `set_web_theme` with everything; fix any `errors` it names.
217
+ 4. `preview_web_appearance` and Read the SVGs for both modes. Check contrast and that your card reads well.
218
+
219
+ From a shell: `agend-agent theme get|set key=value…|set --json '<patch>'|clear <path>…|asset <slot> <file>|reset`,
220
+ `agend-agent appearance`, `agend-agent appearance preview [light|dark]`, and
221
+ `agend-agent widget set <slot> '<spec json>' ['<data json>']|data <slot> '<data json>'|remove [slot]`, and
222
+ `agend-agent mod export <name> <version> [title]|propose <file>`.
223
+
224
+ ## Files in your working directory
225
+
226
+ Asset uploads, effect directories and mod proposals must be inside your working directory. This includes your own
227
+ AgEnD-managed workspace (`~/.agend/workspaces/<your-instance-name>`), used by ClassicBot and instances without a
228
+ project directory. `web-assets/` and `web-effects/` are convenient staging folders, not required names. Paths are
229
+ checked after resolving symlinks: for the supplied caller identity, another instance's workspace and all other AgEnD
230
+ state remain forbidden, including
231
+ `.env`, databases, `instances/`, `credential-profiles/` and `inbox/`. Symlinks cannot grant access outside your working
232
+ directory or into protected state; uploaded files themselves must not be symlinks. Generated appearance previews and
233
+ mod exports follow the same workspace boundary. The CLI takes its caller name from `AGEND_INSTANCE_NAME` and its
234
+ working directory from the shell; these local checks do not isolate shells running as the same OS user.
235
+
236
+ ## Effects
237
+
238
+ A Canvas Worker effect is a small animation drawn by code that runs in an isolated Worker: no page, no DOM, no
239
+ network. You place effects **only in your own chat**; a person can place them in the regions an effect's manifest
240
+ allows. None of these tools takes a target.
241
+
242
+ **The package** (CW1): a directory in your working directory with `effect.json` and `worker.js`, optionally
243
+ `poster.png`, `cursor.png` and `assets/*.png|jpg|jpeg|webp|gif`. No HTML or CSS, at most 20 files and 16 assets. The
244
+ smallest valid `effect.json`:
245
+
246
+ ```json
247
+ { "v": 1, "kind": "effect", "runtime": "canvas-worker-v1", "worker": "worker.js", "name": "spark", "title": "Spark", "regions": ["chat"], "layer": "behind", "wants": [] }
248
+ ```
249
+
250
+ - Optional fields: `description`, `poster` (`"poster.png"`), `box`, `cursor` (its `hotspot` inside the image) and
251
+ `params`.
252
+ - `name`: 1..32 characters, starting with a-z or 0-9, then a-z, 0-9 and -.
253
+ - `title` (1..40) and `description` (up to 200): one line each, counted in characters as people see them.
254
+ - `regions`: 1–5 of `chat`, `sidebar`, `header`, `page`, `box`. **Include `chat` to place it in a chat**: applying
255
+ one without it is refused (`effect_region`), and so is a mod placing it. The other regions are ones a person may
256
+ choose it for.
257
+ - `layer`: `behind` (under the content) or `front` (over it).
258
+ - `wants`: up to 5 of `pointer`, `state`, `reply`, `mention`, `theme`. **`mention` is reserved and never fires in
259
+ 2.3.0** (see Effect event availability).
260
+ - `params`: up to 16 typed parameters (`number`, `int`, `bool`, `enum`, `color`) a placement may set.
261
+ - `worker.js` (at most 1 MiB, a classic script: static `import` / `export` are refused) draws through the `agend` API:
262
+ `canvas`, `params`, `asset()`, `on()`, `frame()` and `ready()`. Call `ready()` within 10 s, or it is stopped. Network
263
+ and dynamic imports are blocked at run time; the upload may warn `network_or_import_api_unsupported`, but don't rely
264
+ on the warning to catch every use.
265
+ - Size: `effect.json` at most 64 KiB; the whole effect at most 8 MiB as uploaded and **1 MiB normalized**. Pictures:
266
+ at most 4096 px a side, and **8,388,608 pixels in total** across the assets, poster and cursor together. A cursor is
267
+ a square PNG of at most 64 px and 32 KiB (after metadata is stripped).
268
+
269
+ **The tools:**
270
+
271
+ - `upload_web_effect { dir }` → `{ id, warnings }`. It counts as an upload (3 an hour, shared with pictures and mods).
272
+ **Your own** copies are at most **10 effects and 8 MiB**; effects a person shared with you don't count.
273
+ - `list_web_effects` — your own effects and those a person shared with you: `id`, `name`, `title`, `regions`, `layer`,
274
+ `bytes`, `latest_profile`.
275
+ - `apply_web_effect { id, params? }` places one in your chat, **at most two at a time**, with the declared `params`
276
+ (unknown or out of range → `effect_params`; regions without `chat` → `effect_region`). `remove_web_effect { id? }`
277
+ takes one out, or all of them. Both are changes (30 s apart, 10 an hour), and are refused while a person has locked
278
+ your theme (`locked`) or when the fleet turned agent changes off (`theme_editing_off`).
279
+ - `delete_web_effect { id }` deletes your own copy once nothing uses it; a placement, mod, stage or Try offer gives
280
+ `effect_in_use`. Another's copy is never removed.
281
+ - `profile_web_effect { id }` — how it ran on viewers' pages, per device class: `unmeasured`, or `reported` with
282
+ records carrying a `verdict` (`ok`, `degraded`, `paused`, `off`) and a `reason` (`host_budget`, `hidden`,
283
+ `reduced_motion`, `save_data`, `viewer_off`, `clock_unavailable`, `gates_unknown`, or none).
284
+ `list_web_effects`' `latest_profile` has the latest one. These are best-effort reports of what happened, not live
285
+ notices. No measurement means unknown, never healthy.
286
+ - `preview_web_effect { id }` offers a Try card in your chat (see Try below).
287
+ - **Sharing is a person's act.** You can't share an effect. You may use one a person shared with you (list, apply,
288
+ Try, profile, put in a mod) while it is shared. When they unshare it, a placement already in your chat stays
289
+ eligible for playback (subject to the viewer's and the safety rules); applying, Try, listing, profiling or exporting
290
+ it again needs your own copy or another share, else `not_found`. A placement is never a grant to export it.
291
+
292
+ **On a viewer's page:**
293
+
294
+ - At most **3** effects play at once, at most **2** of them `front` (1 and 1 on a constrained device); the rest wait
295
+ (`frame_limit`, `front_limit`).
296
+ - Nothing plays in safe mode, over a temporary public link, with reduced motion or save-data, on a hidden page, while
297
+ the viewer has effects off, or before they consent to previews. A `poster.png` may then show behind the chat (see
298
+ Static Chat fallback). A visible menu or dialog stops `front` effects; these stops lift by themselves.
299
+ - **Safety pause** — it measures the page's responsiveness, not your Worker's CPU. The page's frame-rate floor is
300
+ 90% of what it measured before the effect started, capped at 55 fps (50 on a constrained device), so a 30 Hz screen
301
+ has a 27 fps floor. Where the browser reports them, long tasks may take at most 50 ms a second (25 ms constrained);
302
+ unknown timing doesn't count as free. Overlapping 2-second windows are judged at most once a second after a warm-up,
303
+ and three bad judgements in a row pause the effect (`host_budget`).
304
+ - Only a viewer's explicit **Resume** restarts a safety-paused effect, and it doesn't clear the history: three such
305
+ pauses within 24 hours turn the effect **off** for that viewer's browser and device class, across tabs and reloads,
306
+ and Resume then refuses. It doesn't come back by itself after 24 hours.
307
+ - **Your `front` effects are paused while the viewer's custom CSS is on, loading or unknown**; `behind` effects play
308
+ once the page's stock layout is proven. A person's placement is exempt. Don't keep re-applying (see below).
309
+
310
+ ## Owner-level effect selections
311
+
312
+ The five owner keys `fx.sidebar`, `fx.header`, `fx.page`, `fx.box` and `fx.cursor` are a signed-in person's web
313
+ preferences, never agent tool targets. Platform-bound sessions use separate adapter/user buckets (no account merge).
314
+ A web-only `agend web --code` session uses the explicit **host-wide operator** bucket, shared by everyone signed in
315
+ as that host operator. Header tokens cannot read or write these five keys. Existing visible host preferences are
316
+ unchanged; there is no local-key migration. Profile/custom-CSS internal pointers keep their existing identity rules.
317
+
318
+ When a shared effect is unshared, a personal selection remains stored but becomes unavailable at its next resource
319
+ authorization. It supplies no further code or cursor image; the person can clear it. Its reference keeps the blob
320
+ from being collected until cleared. This is deliberately stricter than chat placements' retained-runtime reads:
321
+ a personal choice keeps following its person's current own/shared access, while a chat preserves the exact effect
322
+ placed there. A reference is not a sharing or export grant. Do not keep retrying a denied personal selection.
323
+
324
+ Owner selectors are available in Settings → Web appearance. With effects and preview consent enabled, personal
325
+ page/header/sidebar/box choices play across supported stock pages in the same pool as local signed-in Chat.
326
+ Web appearance offers slot Pause/Resume and unavailable/Clear controls. The personal cursor uses a static PNG on the host shell after the same consent: no Worker/code read or frame slot. It preserves explicit pointer/text/resize cursors, falls back while dragging or on failure, and has status/Clear rather than Worker Pause/Resume. Before revealing paint, the host must prove stock content
327
+ ordering and trust paint coverage. Agent front effects must remain paused when custom CSS is active, loading or
328
+ unknown; a person sees the reason and can open the causing setting. Human placements retain their exemption from
329
+ that agent restriction, and behind effects still require proven ordering. Saving a placement alone is not proof of
330
+ playback.
331
+
332
+ Visible menus, dialogs, Keep/tour notices and focused inputs suppress all foreground effects; a human placement
333
+ does not bypass those host safety gates. Unknown stock layout refuses admission. A trusted foreground plane is
334
+ deferred to #1940; do not keep reapplying an agent front while custom CSS is on, loading or unknown.
335
+
336
+ ### Try: offer first, local admin click to start
337
+
338
+ `preview_web_effect({id})` posts a volatile Try card in your own web chat, using your current own/shared read rights. It starts nothing and changes no appearance. The sample is physically clipped inside its own host panel or sheet. Only an explicit
339
+ click by a signed-in **local admin** may start it; never an agent, public link, header token or automatic action.
340
+ The host owns a visible Trial label and Stop control. Closing the panel/sheet, navigating, window blur, or another
341
+ menu/dialog stops it. Custom CSS must be off (on/loading/unknown denies), and the same caps, profiler and safety
342
+ stops apply. Ordinary foreground effects stay suppressed. A volatile offer lasts at most ten minutes (offering the same effect again keeps that offer and its expiry; a different effect replaces it); every read
343
+ rechecks the originating agent's current own/shared access, with the trial bound to the admin's session and epoch.
344
+ There is no saved placement, claim, share, export or new saved profile record. Cards are memory-only and become inert when expired; a restart never restores them. Try uses manifest defaults and the existing app pool, not a second runtime. Do not treat an offer id or ordinary reply button
345
+ as permission to run or fetch an effect, and do not keep retrying an unavailable Try.
346
+
347
+
348
+ ## Static Chat fallback
349
+
350
+ When preview is unavailable, consent is missing, motion/data settings prevent playback, or the page is a public link,
351
+ a current chat placement with a poster can show its static PNG **behind** the content; a front declaration does not
352
+ make its poster foreground. No poster means nothing is drawn. Safe mode and the viewer's show switch hide posters
353
+ too; unknown stock ordering refuses paint. Explicit Pause, queued effects and a failed live read are not replaced by
354
+ this surface fallback. A failed static read/decode stops its poster pool until a changed revision or page reload;
355
+ there is no automatic network retry. The public link offers no Effects playback controls or Worker code.
356
+
357
+ The public-link show switch is this browser's choice, kept separately from boot-cached host defaults; it never writes
358
+ a host preference. The ordinary signed-in switch keeps its existing host preference. Do not depend on decoration to
359
+ carry an important message.
360
+
361
+ ## Effect event availability
362
+
363
+ Canvas Worker manifests may reserve `wants: ["mention"]`, but **mention is reserved and never emitted in 2.3.0**.
364
+ Do not build an effect that depends on it, infer mentions from reply text, or retry to obtain that signal. Provider-confirmed,
365
+ viewer-scoped direct-ID mention pulses are deferred to [#1963](https://github.com/songsid/AgEnD/issues/1963).
366
+ Reply pulses are transient: only a newly accepted live SSE agent reply can qualify. History, reconnect replay and polling
367
+ never create a pulse; a live receipt delayed over five seconds is dropped. No reply text, author or mention targets reach effects.
@@ -10,6 +10,9 @@
10
10
  * emoji through the emoji route (a Telegram custom emoji has no picture here and falls through);
11
11
  * 4. the first character of its display name, or of its name.
12
12
  * The accent ring (a Discord role colour) goes with an own bot's face only: a shared bot's would ring everyone alike.
13
+ * #1629: the agent's own web theme may name a picture and a ring colour. They rank right after a person's upload
14
+ * (never above it) and travel beside this descriptor in the status frame (`theme_avatar`, `theme_accent`): a viewer
15
+ * who does not show agents' themes, or a safe-mode load, keeps this one.
13
16
  * Images are same-origin `/ui/img/…` URLs only; the version makes a changed picture a new URL.
14
17
  */
15
18
  import { normalizeEmoji } from "./status-emojis.js";
@@ -1 +1 @@
1
- {"version":3,"file":"instance-avatar.js","sourceRoot":"","sources":["../src/instance-avatar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAQpD,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,CAAC;AAC7E,wGAAwG;AACxG,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAAE,OAAO,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAC7F,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KASzB;IACC,IAAI,KAAK,CAAC,cAAc;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,kBAAkB,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,kBAAkB,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,EAAE,CAAC;IAC1J,IAAI,KAAK,CAAC,GAAG;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,eAAe,kBAAkB,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,kBAAkB,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;IACnJ,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACjD,IAAI,KAAK,EAAE,IAAI,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC;IAC3E,IAAI,KAAK,EAAE,IAAI,KAAK,QAAQ;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB,KAAK,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,KAAK,CAAC,IAAI,GAAG,EAAE,CAAC;IACjH,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;AACpF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,WAAuF;IACvH,MAAM,KAAK,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC1C,KAAK,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,IAAI,WAAW,EAAE,CAAC;QACjD,IAAI,CAAC,UAAU;YAAE,SAAS;QAC1B,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACnC,IAAI,IAAI;YAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;;YAAM,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IACxE,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,GAAG,EAAkB,CAAC,CAAU,gCAAgC;IAChF,KAAK,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,IAAI,KAAK;QAAE,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;YAAE,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAE,EAAE,UAAU,CAAC,CAAC;IAC5G,OAAO,GAAG,CAAC;AACb,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,WAAW,CAAC,GAAY;IACtC,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,WAAW,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9H,CAAC"}
1
+ {"version":3,"file":"instance-avatar.js","sourceRoot":"","sources":["../src/instance-avatar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAQpD,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,CAAC;AAC7E,wGAAwG;AACxG,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAAE,OAAO,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAC7F,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KASzB;IACC,IAAI,KAAK,CAAC,cAAc;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,kBAAkB,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,kBAAkB,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,EAAE,CAAC;IAC1J,IAAI,KAAK,CAAC,GAAG;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,eAAe,kBAAkB,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,kBAAkB,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;IACnJ,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACjD,IAAI,KAAK,EAAE,IAAI,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC;IAC3E,IAAI,KAAK,EAAE,IAAI,KAAK,QAAQ;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB,KAAK,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,KAAK,CAAC,IAAI,GAAG,EAAE,CAAC;IACjH,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;AACpF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,WAAuF;IACvH,MAAM,KAAK,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC1C,KAAK,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,IAAI,WAAW,EAAE,CAAC;QACjD,IAAI,CAAC,UAAU;YAAE,SAAS;QAC1B,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACnC,IAAI,IAAI;YAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;;YAAM,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IACxE,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,GAAG,EAAkB,CAAC,CAAU,gCAAgC;IAChF,KAAK,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,IAAI,KAAK;QAAE,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;YAAE,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAE,EAAE,UAAU,CAAC,CAAC;IAC5G,OAAO,GAAG,CAAC;AACb,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,WAAW,CAAC,GAAY;IACtC,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,WAAW,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9H,CAAC"}
@@ -86,6 +86,9 @@ const FLEET_FIELD_IMPACTS = {
86
86
  // #1620: read at every session check, and by /login when it starts a terminal.
87
87
  "web.session.local.absolute_hours": "now",
88
88
  "web.session.local.idle_hours": "now",
89
+ // #1629 r4.1 Q3 (b): the identity card's upload limits and the picture quota — read at each upload.
90
+ ...Object.fromEntries(["portrait.max_width", "portrait.max_height", "portrait.max_kib", "banner.max_width", "banner.max_height", "banner.max_kib",
91
+ "instance_quota.files", "instance_quota.mib"].map((k) => [`web.appearance.${k}`, "now"])),
89
92
  "web_terminal.enabled": "now",
90
93
  "web_terminal.ttl_minutes": "now",
91
94
  "defaults.locale": "now",
@@ -1 +1 @@
1
- {"version":3,"file":"instance-config-impact.js","sourceRoot":"","sources":["../src/instance-config-impact.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"instance-config-impact.js","sourceRoot":"","sources":["../src/instance-config-impact.ts"],"names":[],"mappings":"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"}
@@ -23,7 +23,10 @@ import { CHAT_PROFILE_LOGIN_BACKENDS, credentialProfileEnv, credentialProfileLog
23
23
  import { fetchClaudeUsage, fetchCodexUsage } from "./usage/providers.js";
24
24
  import { assertExplicitInstanceRemoval, authorizeExplicitInstanceRemoval } from "./instance-removal.js";
25
25
  import { capturePendingTargetReconciliation, finishTargetReconciliation, reconcileTargetBeforeStart, RECONCILIATION_WRITE_DRAIN_TIMEOUT_MS, retireCapturedTargetWindows, } from "./delivery-reconciliation.js";
26
+ import { noPlaceMarkers, placeRef } from "./topic-link.js";
26
27
  export { isFleetStartCommandLine } from "./fleet-lock.js";
28
+ /** #1990: an instance's name in a fleet notice, linked to its topic where the notice is posted. */
29
+ const instancePlace = (name) => placeRef({ kind: "instance", name }, name);
27
30
  const localBin = (home) => join(home, ".local", "bin");
28
31
  /** Shared CLI metadata used by startup validation and ClassicBot onboarding. */
29
32
  export const BACKEND_INSTALLATION_INFO = {
@@ -848,9 +851,10 @@ export class InstanceLifecycle {
848
851
  // #1691: a prompt no table knows — what it asks (one sanitised, bounded line from the daemon, never the pane), and
849
852
  // that AgEnD will not press anything.
850
853
  if (data.unrecognised) {
851
- const asked = data.question ? t("inst.unrecognised_prompt_question", data.question) : "";
854
+ // #1990: the question is a pane line — it may not name a place of its own.
855
+ const asked = data.question ? t("inst.unrecognised_prompt_question", noPlaceMarkers(data.question)) : "";
852
856
  this.notifyIncident(name, "dialog_parked", t("inst.unrecognised_prompt", name, asked));
853
- this.ctx.notifyFleetError?.(t("fleet.unrecognised_prompt", name, asked));
857
+ this.ctx.notifyFleetError?.(t("fleet.unrecognised_prompt", instancePlace(name), asked));
854
858
  return;
855
859
  }
856
860
  const category = data.kind && data.kind !== "dialog" ? interactionCategory(data.kind, data.backend) : null;
@@ -858,7 +862,8 @@ export class InstanceLifecycle {
858
862
  ? t("inst.dialog_parked_hold", name, data.description)
859
863
  : t("inst.dialog_parked_stuck", name, data.description);
860
864
  this.notifyIncident(name, "dialog_parked", text);
861
- this.ctx.notifyFleetError?.(category ? t("fleet.interaction_parked", name, category) : t("fleet.dialog_parked", name, data.description));
865
+ // #1990: in General, the instance's name links to its topic.
866
+ this.ctx.notifyFleetError?.(category ? t("fleet.interaction_parked", instancePlace(name), category) : t("fleet.dialog_parked", instancePlace(name), data.description));
862
867
  }, this.ctx.logger, `daemon.dialog_parked[${name}]`));
863
868
  daemon.on("dialog_answer_ignored", safeHandler((data) => {
864
869
  // A runtime dialog the daemon DID answer, that did not go away. Same rule as dialog_parked: no assist
@@ -870,7 +875,7 @@ export class InstanceLifecycle {
870
875
  return;
871
876
  const text = t(data.holdsDeliveries ? "inst.dialog_answer_ignored_held" : "inst.dialog_answer_ignored", name, data.description, String(data.attempts));
872
877
  this.notifyIncident(name, "dialog_answer_ignored", text);
873
- this.ctx.notifyFleetError?.(t("fleet.dialog_answer_ignored", name, data.description, String(data.attempts)));
878
+ this.ctx.notifyFleetError?.(t("fleet.dialog_answer_ignored", instancePlace(name), data.description, String(data.attempts)));
874
879
  }, this.ctx.logger, `daemon.dialog_answer_ignored[${name}]`));
875
880
  daemon.on("instance_interaction", () => this.ctx.onAttentionChanged?.(name));
876
881
  daemon.on("interactive_prompt", safeHandler(async (data) => {