@songsid/agend 2.2.0 → 2.3.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (271) 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 +30 -0
  7. package/dist/agent-file-read.js +129 -0
  8. package/dist/agent-file-read.js.map +1 -0
  9. package/dist/agent-whats-new.js +13 -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/launch-effort.js +1 -1
  18. package/dist/backend/launch-effort.js.map +1 -1
  19. package/dist/backend/muse.js +10 -2
  20. package/dist/backend/muse.js.map +1 -1
  21. package/dist/channel/adapters/discord.d.ts +2 -0
  22. package/dist/channel/adapters/discord.js +17 -2
  23. package/dist/channel/adapters/discord.js.map +1 -1
  24. package/dist/channel/adapters/telegram.d.ts +8 -1
  25. package/dist/channel/adapters/telegram.js +74 -4
  26. package/dist/channel/adapters/telegram.js.map +1 -1
  27. package/dist/channel/mcp-tools.js +34 -0
  28. package/dist/channel/mcp-tools.js.map +1 -1
  29. package/dist/channel/types.d.ts +15 -0
  30. package/dist/config-validator.js +17 -1
  31. package/dist/config-validator.js.map +1 -1
  32. package/dist/daemon.js +244 -20
  33. package/dist/daemon.js.map +1 -1
  34. package/dist/fleet-context.d.ts +5 -0
  35. package/dist/fleet-manager.d.ts +89 -0
  36. package/dist/fleet-manager.js +401 -25
  37. package/dist/fleet-manager.js.map +1 -1
  38. package/dist/general-knowledge/skills/web-appearance/SKILL.md +258 -0
  39. package/dist/instance-avatar.js +3 -0
  40. package/dist/instance-avatar.js.map +1 -1
  41. package/dist/instance-config-impact.js +3 -0
  42. package/dist/instance-config-impact.js.map +1 -1
  43. package/dist/instance-lifecycle.js +9 -4
  44. package/dist/instance-lifecycle.js.map +1 -1
  45. package/dist/needs-you-hub.d.ts +4 -0
  46. package/dist/needs-you-hub.js +31 -6
  47. package/dist/needs-you-hub.js.map +1 -1
  48. package/dist/needs-you.d.ts +1 -13
  49. package/dist/needs-you.js +3 -37
  50. package/dist/needs-you.js.map +1 -1
  51. package/dist/outbound-handlers.d.ts +5 -0
  52. package/dist/outbound-handlers.js +30 -9
  53. package/dist/outbound-handlers.js.map +1 -1
  54. package/dist/outbound-schemas.d.ts +64 -0
  55. package/dist/outbound-schemas.js +50 -0
  56. package/dist/outbound-schemas.js.map +1 -1
  57. package/dist/public-web-gateway.js +14 -0
  58. package/dist/public-web-gateway.js.map +1 -1
  59. package/dist/repo-worktree-guard.d.ts +36 -0
  60. package/dist/repo-worktree-guard.js +143 -0
  61. package/dist/repo-worktree-guard.js.map +1 -0
  62. package/dist/scheduler/scheduler.d.ts +58 -1
  63. package/dist/scheduler/scheduler.js +176 -10
  64. package/dist/scheduler/scheduler.js.map +1 -1
  65. package/dist/settings-api.js +74 -1
  66. package/dist/settings-api.js.map +1 -1
  67. package/dist/settings-change.js +8 -0
  68. package/dist/settings-change.js.map +1 -1
  69. package/dist/settings-effect.js +16 -2
  70. package/dist/settings-effect.js.map +1 -1
  71. package/dist/settings-http-confirmation.js +5 -0
  72. package/dist/settings-http-confirmation.js.map +1 -1
  73. package/dist/tool-permissions.js +50 -0
  74. package/dist/tool-permissions.js.map +1 -1
  75. package/dist/topic-commands.d.ts +10 -6
  76. package/dist/topic-commands.js +21 -17
  77. package/dist/topic-commands.js.map +1 -1
  78. package/dist/topic-link.d.ts +128 -0
  79. package/dist/topic-link.js +269 -0
  80. package/dist/topic-link.js.map +1 -0
  81. package/dist/types.d.ts +13 -0
  82. package/dist/ui/app-effects.js +187 -0
  83. package/dist/ui/chat-effect-posters.js +42 -0
  84. package/dist/ui/chat-effects.js +72 -0
  85. package/dist/ui/chat-live-replies.js +58 -0
  86. package/dist/ui/chat-render.js +4 -4
  87. package/dist/ui/chat-store.js +9 -3
  88. package/dist/ui/chat-strings.js +15 -0
  89. package/dist/ui/chat-thread.js +47 -21
  90. package/dist/ui/chat-tour.js +1 -1
  91. package/dist/ui/effect-trial-controller.js +119 -0
  92. package/dist/ui/effect-trial-offer.js +31 -0
  93. package/dist/ui/effect-trial-panel.js +37 -0
  94. package/dist/ui/image-lightbox.js +1 -1
  95. package/dist/ui/panel-chat.js +85 -17
  96. package/dist/ui/panel-details.js +18 -5
  97. package/dist/ui/panel-fleet.js +3 -3
  98. package/dist/ui/panel-log.js +6 -6
  99. package/dist/ui/panel-needs.js +3 -3
  100. package/dist/ui/panel-settings.js +8 -5
  101. package/dist/ui/preview-panel.js +25 -9
  102. package/dist/ui/settings-appearance.js +325 -0
  103. package/dist/ui/settings-effects.js +201 -0
  104. package/dist/ui/settings-mods.js +257 -0
  105. package/dist/ui/settings-owner-effects.js +80 -0
  106. package/dist/ui/settings-strings.js +245 -0
  107. package/dist/ui/shared/agend-auth.js +27 -3
  108. package/dist/ui/shared/agent-widget.js +248 -0
  109. package/dist/ui/shared/app-i18n.js +2 -0
  110. package/dist/ui/shared/app-prefs.js +30 -10
  111. package/dist/ui/shared/app-route.js +23 -1
  112. package/dist/ui/shared/app-session.js +1 -1
  113. package/dist/ui/shared/app-shell.js +29 -16
  114. package/dist/ui/shared/app-store.js +2 -0
  115. package/dist/ui/shared/app-stream.js +12 -7
  116. package/dist/ui/shared/app-themes.js +188 -0
  117. package/dist/ui/shared/app.css +214 -1
  118. package/dist/ui/shared/app.js +6 -0
  119. package/dist/ui/shared/card-strings.js +28 -0
  120. package/dist/ui/shared/effect-app-runtime.js +248 -0
  121. package/dist/ui/shared/effect-baseline.js +64 -0
  122. package/dist/ui/shared/effect-chat-runtime.js +154 -0
  123. package/dist/ui/shared/effect-cursor.js +125 -0
  124. package/dist/ui/shared/effect-frame.js +127 -0
  125. package/dist/ui/shared/effect-geometry.js +122 -0
  126. package/dist/ui/shared/effect-host-style.js +10 -0
  127. package/dist/ui/shared/effect-owner-regions.js +74 -0
  128. package/dist/ui/shared/effect-owner-source.js +115 -0
  129. package/dist/ui/shared/effect-policy.js +137 -0
  130. package/dist/ui/shared/effect-poster-reader.js +98 -0
  131. package/dist/ui/shared/effect-posters.js +117 -0
  132. package/dist/ui/shared/effect-profiler.js +162 -0
  133. package/dist/ui/shared/effect-profiles.js +65 -0
  134. package/dist/ui/shared/effect-registry.js +496 -0
  135. package/dist/ui/shared/effect-runtime-loader.js +234 -0
  136. package/dist/ui/shared/effect-safety.js +153 -0
  137. package/dist/ui/shared/effect-stock-snapshot.js +34 -0
  138. package/dist/ui/shared/effect-stock-trust.js +165 -0
  139. package/dist/ui/shared/effect-trial-source.js +103 -0
  140. package/dist/ui/shared/effect-trial-stage.js +147 -0
  141. package/dist/ui/shared/header-tools.js +1 -1
  142. package/dist/ui/shared/identity-card.js +202 -0
  143. package/dist/ui/shared/identity-color.js +261 -0
  144. package/dist/ui/shared/instance-nav.js +22 -14
  145. package/dist/ui/shared/owner-css.js +221 -0
  146. package/dist/ui/shared/owner-effect-prefs.js +117 -0
  147. package/dist/ui/shared/panel-view.js +81 -8
  148. package/dist/ui/shared/signin.js +2 -0
  149. package/dist/ui/shared/ui-dialog.js +1 -1
  150. package/dist/ui/shared/ui-icons.js +2 -0
  151. package/dist/ui/shared/ui-menu.js +1 -1
  152. package/dist/ui/shared/ui-toast.js +1 -1
  153. package/dist/ui/shared/view-strings.js +30 -0
  154. package/dist/ui/signin.html +1 -0
  155. package/dist/view-api.d.ts +29 -0
  156. package/dist/view-api.js +188 -8
  157. package/dist/view-api.js.map +1 -1
  158. package/dist/web-api.d.ts +42 -0
  159. package/dist/web-api.js +896 -36
  160. package/dist/web-api.js.map +1 -1
  161. package/dist/web-appearance-limits.d.ts +82 -0
  162. package/dist/web-appearance-limits.js +83 -0
  163. package/dist/web-appearance-limits.js.map +1 -0
  164. package/dist/web-appearance-policy.d.ts +66 -0
  165. package/dist/web-appearance-policy.js +94 -0
  166. package/dist/web-appearance-policy.js.map +1 -0
  167. package/dist/web-appearance-tools.d.ts +50 -0
  168. package/dist/web-appearance-tools.js +105 -0
  169. package/dist/web-appearance-tools.js.map +1 -0
  170. package/dist/web-appearance-view.d.ts +99 -0
  171. package/dist/web-appearance-view.js +163 -0
  172. package/dist/web-appearance-view.js.map +1 -0
  173. package/dist/web-appearance.d.ts +79 -0
  174. package/dist/web-appearance.js +298 -0
  175. package/dist/web-appearance.js.map +1 -0
  176. package/dist/web-asset-parts.d.ts +98 -0
  177. package/dist/web-asset-parts.js +133 -0
  178. package/dist/web-asset-parts.js.map +1 -0
  179. package/dist/web-auth.js +17 -1
  180. package/dist/web-auth.js.map +1 -1
  181. package/dist/web-card.d.ts +96 -0
  182. package/dist/web-card.js +232 -0
  183. package/dist/web-card.js.map +1 -0
  184. package/dist/web-chat-history.d.ts +13 -0
  185. package/dist/web-chat-history.js +23 -2
  186. package/dist/web-chat-history.js.map +1 -1
  187. package/dist/web-effect-bundle.d.ts +28 -0
  188. package/dist/web-effect-bundle.js +126 -0
  189. package/dist/web-effect-bundle.js.map +1 -0
  190. package/dist/web-effect-canonical.d.ts +8 -0
  191. package/dist/web-effect-canonical.js +27 -0
  192. package/dist/web-effect-canonical.js.map +1 -0
  193. package/dist/web-effect-library.d.ts +114 -0
  194. package/dist/web-effect-library.js +530 -0
  195. package/dist/web-effect-library.js.map +1 -0
  196. package/dist/web-effect-poster.d.ts +8 -0
  197. package/dist/web-effect-poster.js +52 -0
  198. package/dist/web-effect-poster.js.map +1 -0
  199. package/dist/web-effect-profiles.d.ts +118 -0
  200. package/dist/web-effect-profiles.js +180 -0
  201. package/dist/web-effect-profiles.js.map +1 -0
  202. package/dist/web-effect-service.d.ts +86 -0
  203. package/dist/web-effect-service.js +312 -0
  204. package/dist/web-effect-service.js.map +1 -0
  205. package/dist/web-effect-tools.d.ts +47 -0
  206. package/dist/web-effect-tools.js +126 -0
  207. package/dist/web-effect-tools.js.map +1 -0
  208. package/dist/web-effect-trials.d.ts +86 -0
  209. package/dist/web-effect-trials.js +204 -0
  210. package/dist/web-effect-trials.js.map +1 -0
  211. package/dist/web-effect-upload.d.ts +29 -0
  212. package/dist/web-effect-upload.js +190 -0
  213. package/dist/web-effect-upload.js.map +1 -0
  214. package/dist/web-effect-worker.d.ts +8 -0
  215. package/dist/web-effect-worker.js +170 -0
  216. package/dist/web-effect-worker.js.map +1 -0
  217. package/dist/web-effect.d.ts +89 -0
  218. package/dist/web-effect.js +132 -0
  219. package/dist/web-effect.js.map +1 -0
  220. package/dist/web-identity-color.d.ts +87 -0
  221. package/dist/web-identity-color.js +209 -0
  222. package/dist/web-identity-color.js.map +1 -0
  223. package/dist/web-identity-palette.d.ts +113 -0
  224. package/dist/web-identity-palette.js +84 -0
  225. package/dist/web-identity-palette.js.map +1 -0
  226. package/dist/web-image-meta.d.ts +25 -0
  227. package/dist/web-image-meta.js +200 -0
  228. package/dist/web-image-meta.js.map +1 -0
  229. package/dist/web-mod-agent.d.ts +50 -0
  230. package/dist/web-mod-agent.js +203 -0
  231. package/dist/web-mod-agent.js.map +1 -0
  232. package/dist/web-mod-bundle.d.ts +144 -0
  233. package/dist/web-mod-bundle.js +464 -0
  234. package/dist/web-mod-bundle.js.map +1 -0
  235. package/dist/web-mod-export.d.ts +59 -0
  236. package/dist/web-mod-export.js +79 -0
  237. package/dist/web-mod-export.js.map +1 -0
  238. package/dist/web-mod-store.d.ts +283 -0
  239. package/dist/web-mod-store.js +624 -0
  240. package/dist/web-mod-store.js.map +1 -0
  241. package/dist/web-org.d.ts +3 -3
  242. package/dist/web-org.js +11 -17
  243. package/dist/web-org.js.map +1 -1
  244. package/dist/web-owner-css-store.d.ts +180 -0
  245. package/dist/web-owner-css-store.js +384 -0
  246. package/dist/web-owner-css-store.js.map +1 -0
  247. package/dist/web-owner-css.d.ts +58 -0
  248. package/dist/web-owner-css.js +552 -0
  249. package/dist/web-owner-css.js.map +1 -0
  250. package/dist/web-prefs.d.ts +48 -0
  251. package/dist/web-prefs.js +209 -33
  252. package/dist/web-prefs.js.map +1 -1
  253. package/dist/web-preview.d.ts +9 -1
  254. package/dist/web-preview.js +24 -7
  255. package/dist/web-preview.js.map +1 -1
  256. package/dist/web-settings-patch.d.ts +18 -0
  257. package/dist/web-settings-patch.js +51 -0
  258. package/dist/web-settings-patch.js.map +1 -1
  259. package/dist/web-shell-routes.d.ts +1 -1
  260. package/dist/web-shell-routes.js +1 -1
  261. package/dist/web-shell-routes.js.map +1 -1
  262. package/dist/web-theme-store.d.ts +218 -0
  263. package/dist/web-theme-store.js +516 -0
  264. package/dist/web-theme-store.js.map +1 -0
  265. package/dist/web-theme.d.ts +121 -0
  266. package/dist/web-theme.js +407 -0
  267. package/dist/web-theme.js.map +1 -0
  268. package/dist/web-widget.d.ts +72 -0
  269. package/dist/web-widget.js +245 -0
  270. package/dist/web-widget.js.map +1 -0
  271. package/package.json +1 -1
@@ -0,0 +1,163 @@
1
+ /**
2
+ * #1629 r4 §1: the agent's read-only view of how it appears on the dashboard — `get_web_appearance` (what the page
3
+ * draws now, resolved exactly as the status frame resolves it) and `preview_web_appearance` (an SVG per mode, built
4
+ * from the page's own layout numbers). Pure: the fleet passes in what it already resolved; nothing here reads a file,
5
+ * a path or another instance.
6
+ *
7
+ * The SVG names only this instance's pictures, as side files next to it (`avatar.png`, …: #1890 review — an SVG with a
8
+ * picture inside outgrew what an agent's Read takes); text is XML-escaped; colours are checked again; fonts are generic
9
+ * families. No browser, no live session, no other instance's content.
10
+ */
11
+ import { autoIdentityColor, identityColorValue, resolveIdentityColor, resolvePlacements } from "./web-identity-color.js";
12
+ import { effectivePalette, THEME_DEFAULTS } from "./web-theme.js";
13
+ /**
14
+ * #1958: the identity colour drawn for this instance while agents' themes are shown, where it comes from, its value on
15
+ * a light and a dark page, where it shows (and whose choice that is), and whether the host turned colours off — what
16
+ * the agent needs to know: a person's choice wins over its own (theme.identity), field by field.
17
+ */
18
+ export function resolvedIdentityColor(e, host = {}) {
19
+ const r = resolveIdentityColor(e.color ?? { auto: autoIdentityColor(e.name) }, { showThemes: true });
20
+ const p = resolvePlacements(e.color_show ?? {}, { showThemes: true, hostDefault: host.show });
21
+ return { color: r.color, source: r.source, light: identityColorValue(r.color, "light"), dark: identityColorValue(r.color, "dark"), show: p.show, show_source: p.source, off: host.off === true };
22
+ }
23
+ /** The face the page draws while agents' themes are shown (the default), and where it comes from. */
24
+ export function resolvedAvatar(e) {
25
+ if (e.theme_avatar?.kind === "image" && e.theme_avatar.src)
26
+ return { source: "theme", url: e.theme_avatar.src };
27
+ const a = e.avatar;
28
+ if (a?.kind === "image" && a.src?.startsWith("/ui/img/avatar/"))
29
+ return { source: "profile", url: a.src };
30
+ if (a?.kind === "image" && a.src?.startsWith("/ui/img/bot/"))
31
+ return { source: "bot", url: a.src };
32
+ if (a?.kind === "emoji")
33
+ return { source: "emoji", ...(a.src ? { url: a.src } : {}), ...(a.text ? { text: a.text } : {}) };
34
+ return { source: "initial", text: a?.text ?? (e.display_name || e.name).slice(0, 1).toUpperCase() };
35
+ }
36
+ /** The ring the page draws round a picture face: the theme's colour, else an own bot's; none for an emoji or initial. */
37
+ export function resolvedRing(e) {
38
+ const pictured = e.theme_avatar?.kind === "image" || e.avatar?.kind === "image";
39
+ if (!pictured)
40
+ return null;
41
+ if (e.theme_accent)
42
+ return { color: e.theme_accent, source: "theme" };
43
+ if (e.accent)
44
+ return { color: e.accent, source: "bot" };
45
+ return null;
46
+ }
47
+ /** The effective look per mode: the palette over the token defaults, and the fixed choices. */
48
+ export function effectiveTheme(theme) {
49
+ const one = (mode) => ({ ...effectivePalette(theme, mode), font: theme.font ?? "inter", bubbleRadius: theme.bubble?.radius ?? 18, bubbleBorder: theme.bubble?.border ?? "none" });
50
+ return { light: one("light"), dark: one("dark") };
51
+ }
52
+ /** get_web_appearance's answer. Effects: none can be applied yet (they wait on the effects runtime). */
53
+ export function appearanceView(i) {
54
+ const card = {};
55
+ for (const k of ["portrait", "banner"])
56
+ if (i.card[k])
57
+ card[k] = { id: i.card[k].id, by: i.card[k].by, url: i.card[k].src };
58
+ for (const k of ["tagline", "bio"])
59
+ if (i.card[k])
60
+ card[k] = { text: i.card[k].text, by: i.card[k].by };
61
+ return {
62
+ name: i.entry.name,
63
+ display_name: i.entry.display_name ?? null,
64
+ avatar: resolvedAvatar(i.entry),
65
+ ring: resolvedRing(i.entry),
66
+ identity_color: resolvedIdentityColor(i.entry, i.colorPrefs),
67
+ card,
68
+ theme: effectiveTheme(i.theme),
69
+ working_label: i.theme.workingLabel ?? null,
70
+ background: i.theme.background ? { image: i.theme.background.image, fit: i.theme.background.fit, opacity: i.theme.background.opacity } : null,
71
+ effects: [],
72
+ widgets: ["chat_header", "details"].flatMap(slot => { const w = i.widgets?.[slot]; return w ? [{ slot, by: w.by, spec: w.spec, data: w.data }] : []; }),
73
+ shown_when: "A viewer who turned off \"Show agents' themes, effects and widgets\", or a page opened with ?safe=1, sees the default look, the bot's face, no card colours and no widgets.",
74
+ locked: i.locked,
75
+ agent_edit: i.agentEdit,
76
+ limits: i.limits,
77
+ };
78
+ }
79
+ // ── The preview ── the page's numbers (app.css): a 720 px column, the M card (240 px portrait, banner half that), a
80
+ // 56 px chat header with a 32 px face, bubbles of the theme's radius and border.
81
+ const W = 720, PAD = 16, PORTRAIT_H = 240, BANNER_H = 120, HEADER_H = 56;
82
+ const esc = (s) => s.replace(/[&<>"']/g, c => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" }[c]));
83
+ const FONT = { inter: "sans-serif", system: "sans-serif", mono: "monospace" };
84
+ export const PICTURE_ROLES = ["avatar", "portrait", "banner", "background"];
85
+ const PICTURE_EXT = { "image/png": "png", "image/jpeg": "jpg", "image/webp": "webp", "image/gif": "gif" };
86
+ /** A side file's name for a picture of this role and type, or null for a type no page shows. */
87
+ export function pictureFileName(role, mime) {
88
+ return Object.hasOwn(PICTURE_EXT, mime) ? `${role}.${PICTURE_EXT[mime]}` : null;
89
+ }
90
+ /** Every name a preview writes: an SVG per mode, and the pictures it names. */
91
+ export const PREVIEW_FILE = /^(?:(?:light|dark)\.svg|(?:avatar|portrait|banner|background)\.(?:png|jpg|webp|gif))$/;
92
+ const COLOR = /^#[0-9a-f]{6}$/;
93
+ /** One mode's SVG. Every picture is one of `pics` (this instance's), inline; nothing else is referenced. */
94
+ export function previewSvg(i, mode, pics) {
95
+ const raw = effectiveTheme(i.theme)[mode];
96
+ // Colours go into attributes: each is checked again here (a file someone may open in a browser), else the default's.
97
+ const t = { ...raw };
98
+ for (const k of ["bg", "surface", "text", "text2", "accent", "userBubble", "agentBubble"])
99
+ if (!COLOR.test(t[k]))
100
+ t[k] = THEME_DEFAULTS[mode][k];
101
+ const font = FONT[t.font] ?? "sans-serif";
102
+ const img = (name, x, y, w, h, extra = "") => name && PREVIEW_FILE.test(name) && !name.endsWith(".svg") ? `<image href="${name}" x="${x}" y="${y}" width="${w}" height="${h}" preserveAspectRatio="xMidYMid slice"${extra}/>` : "";
103
+ const out = [];
104
+ let y = 0;
105
+ // The card, as Details draws it at M.
106
+ const hasCard = Object.keys(i.card).length > 0;
107
+ if (hasCard) {
108
+ if (i.card.banner) {
109
+ out.push(img(pics.banner, 0, y, W, BANNER_H));
110
+ y += BANNER_H;
111
+ }
112
+ const top = y + PAD;
113
+ let textX = PAD;
114
+ if (i.card.portrait && pics.portrait) {
115
+ out.push(img(pics.portrait, PAD, top, PORTRAIT_H * 0.75, PORTRAIT_H));
116
+ textX = PAD + PORTRAIT_H * 0.75 + PAD;
117
+ }
118
+ let ty = top + 18;
119
+ if (i.card.tagline) {
120
+ out.push(`<text x="${textX}" y="${ty}" font-family="${font}" font-size="15" font-weight="600" fill="${t.text}">${esc(i.card.tagline.text)}</text>`);
121
+ ty += 24;
122
+ }
123
+ if (i.card.bio)
124
+ for (const line of i.card.bio.text.split("\n")) {
125
+ out.push(`<text x="${textX}" y="${ty}" font-family="${font}" font-size="13" fill="${t.text2}">${esc(line)}</text>`);
126
+ ty += 18;
127
+ }
128
+ y = Math.max(top + (i.card.portrait && pics.portrait ? PORTRAIT_H : 0), ty) + PAD;
129
+ }
130
+ // The chat header: the face (and its ring) and the name.
131
+ const hy = y;
132
+ out.push(`<rect x="0" y="${hy}" width="${W}" height="${HEADER_H}" fill="${t.surface}"/>`);
133
+ const cx = PAD + 16, cy = hy + HEADER_H / 2;
134
+ const ring = resolvedRing(i.entry), face = resolvedAvatar(i.entry);
135
+ if (ring && COLOR.test(ring.color))
136
+ out.push(`<circle cx="${cx}" cy="${cy}" r="18" fill="none" stroke="${ring.color}" stroke-width="2"/>`);
137
+ out.push(`<clipPath id="face"><circle cx="${cx}" cy="${cy}" r="16"/></clipPath>`);
138
+ if (pics.avatar && (face.source === "theme" || face.source === "profile" || face.source === "bot"))
139
+ out.push(img(pics.avatar, cx - 16, cy - 16, 32, 32, ` clip-path="url(#face)"`));
140
+ else {
141
+ out.push(`<circle cx="${cx}" cy="${cy}" r="16" fill="${t.surface}" stroke="${t.text2}" stroke-width="1"/>`);
142
+ out.push(`<text x="${cx}" y="${cy + 5}" text-anchor="middle" font-family="${font}" font-size="14" fill="${t.text}">${esc(face.text ?? "")}</text>`);
143
+ }
144
+ out.push(`<text x="${cx + 28}" y="${cy + 5}" font-family="${font}" font-size="15" font-weight="600" fill="${t.text}">${esc(i.entry.display_name || i.entry.name)}</text>`);
145
+ y = hy + HEADER_H;
146
+ // The thread: the theme's background picture under a pair of bubbles, then the working label.
147
+ const threadTop = y, threadH = 200;
148
+ out.push(`<rect x="0" y="${threadTop}" width="${W}" height="${threadH}" fill="${t.bg}"/>`);
149
+ if (i.theme.background && pics.background)
150
+ out.push(img(pics.background, 0, threadTop, W, threadH, ` opacity="${i.theme.background.opacity}"`));
151
+ const stroke = t.bubbleBorder === "thin" ? ` stroke="${t.text2}" stroke-width="1"` : t.bubbleBorder === "accent" ? ` stroke="${t.accent}" stroke-width="1.5"` : "";
152
+ out.push(`<rect x="${W - PAD - 300}" y="${threadTop + PAD}" width="300" height="44" rx="${t.bubbleRadius}" fill="${t.userBubble}"${stroke}/>`);
153
+ out.push(`<text x="${W - PAD - 286}" y="${threadTop + PAD + 27}" font-family="${font}" font-size="14" fill="${t.text}">A message from a person</text>`);
154
+ out.push(`<rect x="${PAD}" y="${threadTop + PAD + 60}" width="380" height="64" rx="${t.bubbleRadius}" fill="${t.agentBubble}"${stroke}/>`);
155
+ out.push(`<text x="${PAD + 14}" y="${threadTop + PAD + 88}" font-family="${font}" font-size="14" fill="${t.text}">Your reply, in your colours.</text>`);
156
+ out.push(`<text x="${PAD + 14}" y="${threadTop + PAD + 110}" font-family="${font}" font-size="13" fill="${t.accent}">A link in the accent colour</text>`);
157
+ out.push(`<circle cx="${PAD + 6}" cy="${threadTop + threadH - 24}" r="4" fill="${t.accent}"/>`);
158
+ out.push(`<text x="${PAD + 18}" y="${threadTop + threadH - 19}" font-family="${font}" font-size="13" fill="${t.text2}">${esc(i.theme.workingLabel ?? "Working")}…</text>`);
159
+ y = threadTop + threadH;
160
+ return `<?xml version="1.0" encoding="UTF-8"?>\n<svg xmlns="http://www.w3.org/2000/svg" width="${W}" height="${y}" viewBox="0 0 ${W} ${y}">`
161
+ + `<title>${esc(`${i.entry.display_name || i.entry.name}: ${mode} mode`)}</title><rect width="${W}" height="${y}" fill="${t.bg}"/>${out.join("")}</svg>\n`;
162
+ }
163
+ //# sourceMappingURL=web-appearance-view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-appearance-view.js","sourceRoot":"","sources":["../src/web-appearance-view.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * #1629 (first design §4, §6; r2 (a)–(c); r4-4): the agent's own theme tools — get_web_theme, set_web_theme,
3
+ * set_web_theme_asset, reset_web_theme, set_web_widget, remove_web_widget — and a person's reset, lock and widget removal. None takes a target: the caller is the
4
+ * instance its IPC connection or agent token belongs to, and only that instance's record is ever read or written.
5
+ *
6
+ * Every agent write: the fleet-wide switch (web.themes.agent_edit), then the person's lock, then the shared limiter's
7
+ * check, then validation and the write, then — only once it is on disk — the limiter's record. A refused, invalid or
8
+ * failed call costs nothing. A person's reset and lock are never limited.
9
+ */
10
+ import { type AppearanceBucket, AppearanceLimiter } from "./web-appearance-policy.js";
11
+ import { type ThemeStore } from "./web-theme-store.js";
12
+ /** An upload in parts with no new part for this long is dropped (monotonic clock). */
13
+ export declare const ASSET_UPLOAD_IDLE_MS = 60000;
14
+ export type ToolAnswer = Record<string, unknown>;
15
+ type WebConfigView = {
16
+ themes?: {
17
+ agent_edit?: boolean;
18
+ };
19
+ } | undefined | null;
20
+ export declare class WebAppearance {
21
+ private readonly store;
22
+ private readonly webConfig;
23
+ private readonly changed;
24
+ private readonly clock;
25
+ readonly limiter: AppearanceLimiter;
26
+ /** At most one upload in parts per instance (a new part 0 replaces it). */
27
+ private readonly uploads;
28
+ constructor(store: ThemeStore, webConfig: () => WebConfigView, changed?: () => void, limiter?: AppearanceLimiter, clock?: () => number);
29
+ /** Why an agent may not write now, or null. */
30
+ private refusal;
31
+ /** The effect tools share this exact switch/lock/limiter policy; no parallel gate or bucket. */
32
+ authorizeEffect(instance: string, buckets: readonly AppearanceBucket[]): ToolAnswer | null;
33
+ /** get_web_theme: the caller's theme and everything an agent needs to write a good one. */
34
+ getTheme(instance: string): ToolAnswer;
35
+ /** The upload limits in force now (r4.1 Q3 (b): the card's come from web.appearance), so an agent can size its files. */
36
+ private assetLimits;
37
+ /** set_web_theme { set?, clear? }: all or nothing. `{}` is a no-op (and counts as nothing). */
38
+ setTheme(instance: string, patch: unknown): ToolAnswer;
39
+ /**
40
+ * set_web_theme_asset { slot, data_b64, part? }: the bytes the daemon or the CLI read on the agent's side — whole, or
41
+ * in parts (web-asset-parts.ts). The switch, the lock and the limit are asked at the first part and again before the
42
+ * picture is stored; only a stored picture counts as an upload.
43
+ */
44
+ setAsset(instance: string, args: {
45
+ slot?: unknown;
46
+ data_b64?: unknown;
47
+ part?: unknown;
48
+ }): ToolAnswer;
49
+ private storeAsset;
50
+ private setAssetPart;
51
+ /** reset_web_theme: the agent can always undo itself (a change for the limit). */
52
+ resetTheme(instance: string): ToolAnswer;
53
+ /** A person's reset (Details, the chat menu): theme, placements and pictures go; the lock stays. Not limited. */
54
+ humanReset(instance: string): ToolAnswer;
55
+ /** A person's lock (r2 (a)). Not limited. */
56
+ humanLock(instance: string, locked: boolean): ToolAnswer;
57
+ /**
58
+ * set_web_widget { slot, spec?, data? } (r4-4): place a widget in one of its own slots (`spec`, a change), or give
59
+ * the one there new values (`data` alone: merged, null removes a key — its own budget, 10 s apart). A widget a person
60
+ * placed takes the agent's values but is never replaced by it. `sidebar` is the person's: owner_slot.
61
+ */
62
+ setWidget(instance: string, args: {
63
+ slot?: unknown;
64
+ spec?: unknown;
65
+ data?: unknown;
66
+ }): ToolAnswer;
67
+ /** remove_web_widget { slot? } (r4-4): its own widgets, from one slot or both; a person's placement stays (a change). */
68
+ removeWidget(instance: string, args: {
69
+ slot?: unknown;
70
+ }): ToolAnswer;
71
+ private agentSlot;
72
+ /** A person's removal of an agent's widget (Details, an admin session). Not limited; the lock is not needed. */
73
+ humanRemoveWidget(instance: string, slot: unknown): ToolAnswer;
74
+ /** An instance was removed: its counters and any upload in progress go. */
75
+ forget(instance: string): void;
76
+ /** The tool dispatcher both doors share (typed IPC from the daemon, the agent endpoint for agend-agent). */
77
+ handleTool(instance: string, tool: string, args: Record<string, unknown>): ToolAnswer;
78
+ }
79
+ export {};
@@ -0,0 +1,298 @@
1
+ /**
2
+ * #1629 (first design §4, §6; r2 (a)–(c); r4-4): the agent's own theme tools — get_web_theme, set_web_theme,
3
+ * set_web_theme_asset, reset_web_theme, set_web_widget, remove_web_widget — and a person's reset, lock and widget removal. None takes a target: the caller is the
4
+ * instance its IPC connection or agent token belongs to, and only that instance's record is ever read or written.
5
+ *
6
+ * Every agent write: the fleet-wide switch (web.themes.agent_edit), then the person's lock, then the shared limiter's
7
+ * check, then validation and the write, then — only once it is on disk — the limiter's record. A refused, invalid or
8
+ * failed call costs nothing. A person's reset and lock are never limited.
9
+ */
10
+ import { AppearanceLimiter, agentAppearanceEditAllowed } from "./web-appearance-policy.js";
11
+ import { applyThemePatch, THEME_DEFAULTS } from "./web-theme.js";
12
+ import { createHash, randomBytes } from "node:crypto";
13
+ import { slotLimit, THEME_ASSET_SLOTS } from "./web-theme-store.js";
14
+ import { ASSET_PART_BYTES, ASSET_UPLOAD_MAX_BYTES } from "./web-asset-parts.js";
15
+ import { AGENT_WIDGET_SLOTS, carryWidgetData, checkWidgetData, checkWidgetSpec, mergeWidgetData, WIDGET_SLOTS } from "./web-widget.js";
16
+ /** An upload in parts with no new part for this long is dropped (monotonic clock). */
17
+ export const ASSET_UPLOAD_IDLE_MS = 60_000;
18
+ export class WebAppearance {
19
+ store;
20
+ webConfig;
21
+ changed;
22
+ clock;
23
+ limiter;
24
+ /** At most one upload in parts per instance (a new part 0 replaces it). */
25
+ uploads = new Map();
26
+ constructor(store, webConfig, changed = () => { }, limiter, clock = () => performance.now()) {
27
+ this.store = store;
28
+ this.webConfig = webConfig;
29
+ this.changed = changed;
30
+ this.clock = clock;
31
+ this.limiter = limiter ?? new AppearanceLimiter();
32
+ }
33
+ /** Why an agent may not write now, or null. */
34
+ refusal(instance, buckets) {
35
+ if (!agentAppearanceEditAllowed(this.webConfig()))
36
+ return { error: "theme_editing_off", message: "Agent theme and effect changes are turned off for this fleet (web.themes.agent_edit: false)." };
37
+ if (!this.store.readable())
38
+ return { error: "themes_unreadable", message: "The fleet's theme file cannot be read; nothing can be changed until it is fixed." };
39
+ if (this.store.get(instance).locked)
40
+ return { error: "locked", message: "Theme and effects are locked by a person." };
41
+ const limit = this.limiter.check(instance, buckets);
42
+ return limit.ok ? null : { ...limit, message: `Too many changes; try again in ${limit.retry_after_s} s.` };
43
+ }
44
+ /** The effect tools share this exact switch/lock/limiter policy; no parallel gate or bucket. */
45
+ authorizeEffect(instance, buckets) { return this.refusal(instance, buckets); }
46
+ /** get_web_theme: the caller's theme and everything an agent needs to write a good one. */
47
+ getTheme(instance) {
48
+ const r = this.store.get(instance);
49
+ return {
50
+ effects: r.placements.effects,
51
+ theme: r.theme, by: r.by, locked: r.locked, agent_edit: agentAppearanceEditAllowed(this.webConfig()),
52
+ defaults: THEME_DEFAULTS,
53
+ assets: r.assets.map(a => ({ id: a.id, slot: a.slot, bytes: a.bytes })),
54
+ widgets: Object.fromEntries(AGENT_WIDGET_SLOTS.flatMap(slot => { const w = r.placements.widgets[slot]; return w ? [[slot, { spec: w.spec, data: w.data, by: w.by }]] : []; })),
55
+ limits: { ...this.limiter.remaining(instance), ...this.assetLimits() },
56
+ };
57
+ }
58
+ /** The upload limits in force now (r4.1 Q3 (b): the card's come from web.appearance), so an agent can size its files. */
59
+ assetLimits() {
60
+ const limits = this.store.limits();
61
+ const asset_slots = {};
62
+ for (const slot of THEME_ASSET_SLOTS) {
63
+ const l = slotLimit(slot, limits);
64
+ asset_slots[slot] = { max_width: l.maxWidth, max_height: l.maxHeight, max_bytes: l.maxBytes };
65
+ }
66
+ return { asset_slots, asset_quota: { ...limits.quota } };
67
+ }
68
+ /** set_web_theme { set?, clear? }: all or nothing. `{}` is a no-op (and counts as nothing). */
69
+ setTheme(instance, patch) {
70
+ const isNoop = !!patch && typeof patch === "object" && !Array.isArray(patch) && Object.keys(patch).length === 0;
71
+ if (isNoop)
72
+ return { theme: this.store.get(instance).theme, rev: this.store.rev() };
73
+ const refused = this.refusal(instance, ["change"]);
74
+ if (refused)
75
+ return refused;
76
+ const current = this.store.get(instance);
77
+ const next = applyThemePatch(current.theme, patch, { assets: new Set(current.assets.map(a => a.id)), slotOf: id => current.assets.find(a => a.id === id)?.slot });
78
+ if (!next.ok)
79
+ return { errors: next.errors };
80
+ const w = this.store.setTheme(instance, next.theme, "agent");
81
+ if (!w.ok)
82
+ return { error: w.error, ...(w.detail ? { detail: w.detail } : {}) };
83
+ this.limiter.record(instance, ["change"]);
84
+ this.changed();
85
+ return { theme: w.theme, rev: w.rev };
86
+ }
87
+ /**
88
+ * set_web_theme_asset { slot, data_b64, part? }: the bytes the daemon or the CLI read on the agent's side — whole, or
89
+ * in parts (web-asset-parts.ts). The switch, the lock and the limit are asked at the first part and again before the
90
+ * picture is stored; only a stored picture counts as an upload.
91
+ */
92
+ setAsset(instance, args) {
93
+ if (typeof args.data_b64 !== "string" || !/^[A-Za-z0-9+/]*={0,2}$/.test(args.data_b64))
94
+ return { error: "data", message: "The picture's bytes are missing." };
95
+ if (args.part !== undefined)
96
+ return this.setAssetPart(instance, args.slot, args.data_b64, args.part);
97
+ const refused = this.refusal(instance, ["upload"]);
98
+ if (refused)
99
+ return refused;
100
+ return this.storeAsset(instance, args.slot, Buffer.from(args.data_b64, "base64"));
101
+ }
102
+ storeAsset(instance, slot, bytes) {
103
+ const w = this.store.addAsset(instance, slot, bytes);
104
+ if (!w.ok)
105
+ return { error: w.error, ...(w.detail ? { detail: w.detail } : {}) };
106
+ this.limiter.record(instance, ["upload"]);
107
+ return { id: w.id };
108
+ }
109
+ setAssetPart(instance, slot, data, raw) {
110
+ const fail = (error, message) => { this.uploads.delete(instance); return { error, message }; };
111
+ const p = raw;
112
+ if (!p || typeof p !== "object" || Array.isArray(p))
113
+ return fail("part", "part: { index, count, bytes, sha256, upload? }");
114
+ const { index, count, bytes, sha256 } = p;
115
+ if (!Number.isSafeInteger(index) || !Number.isSafeInteger(count) || !Number.isSafeInteger(bytes) || typeof sha256 !== "string" || !/^[0-9a-f]{64}$/.test(sha256))
116
+ return fail("part", "part: { index, count, bytes, sha256, upload? }");
117
+ const chunk = Buffer.from(data, "base64");
118
+ if (chunk.length < 1 || chunk.length > ASSET_PART_BYTES)
119
+ return fail("part", `each part is 1..${ASSET_PART_BYTES} bytes`);
120
+ const now = this.clock();
121
+ // Uploads left idle by any instance go, so at most one picture's parts per active upload stay in memory.
122
+ for (const [name, u] of this.uploads)
123
+ if (now - u.last > ASSET_UPLOAD_IDLE_MS && name !== instance)
124
+ this.uploads.delete(name);
125
+ if (index === 0) {
126
+ const refused = this.refusal(instance, ["upload"]);
127
+ if (refused) {
128
+ this.uploads.delete(instance);
129
+ return refused;
130
+ }
131
+ if (!THEME_ASSET_SLOTS.includes(slot))
132
+ return fail("slot", THEME_ASSET_SLOTS.join(", "));
133
+ const max = Math.min(ASSET_UPLOAD_MAX_BYTES, slotLimit(slot, this.store.limits()).maxBytes);
134
+ if (bytes < 1 || bytes > max)
135
+ return fail("asset_too_large", `at most ${max / 1024} KiB for ${String(slot)}`);
136
+ if (count !== Math.ceil(bytes / ASSET_PART_BYTES))
137
+ return fail("part", "count does not match bytes");
138
+ this.uploads.set(instance, { id: randomBytes(8).toString("hex"), slot: slot, count: count, next: 0, bytes: bytes, sha256, parts: [], received: 0, last: now });
139
+ }
140
+ const up = this.uploads.get(instance);
141
+ if (!up || (index !== 0 && p.upload !== up.id))
142
+ return fail("upload", "No such upload in progress: start again from part 0.");
143
+ if (now - up.last > ASSET_UPLOAD_IDLE_MS)
144
+ return fail("upload", "The upload waited too long between parts: start again from part 0.");
145
+ if (index !== up.next || count !== up.count || bytes !== up.bytes || sha256 !== up.sha256 || slot !== up.slot)
146
+ return fail("part", `expected part ${up.next} of the same upload`);
147
+ if (up.received + chunk.length > up.bytes)
148
+ return fail("part", "more bytes than declared");
149
+ up.parts.push(chunk);
150
+ up.received += chunk.length;
151
+ up.next += 1;
152
+ up.last = now;
153
+ if (up.next < up.count)
154
+ return { upload: up.id, received: up.received };
155
+ this.uploads.delete(instance);
156
+ const all = Buffer.concat(up.parts);
157
+ if (all.length !== up.bytes || createHash("sha256").update(all).digest("hex") !== up.sha256)
158
+ return { error: "part", message: "The parts do not add up to the declared picture." };
159
+ const refused = this.refusal(instance, ["upload"]);
160
+ if (refused)
161
+ return refused;
162
+ return this.storeAsset(instance, up.slot, all);
163
+ }
164
+ /** reset_web_theme: the agent can always undo itself (a change for the limit). */
165
+ resetTheme(instance) {
166
+ const refused = this.refusal(instance, ["change"]);
167
+ if (refused)
168
+ return refused;
169
+ const w = this.store.reset(instance, "agent");
170
+ if (!w.ok)
171
+ return { error: w.error };
172
+ this.limiter.record(instance, ["change"]);
173
+ this.changed();
174
+ return { theme: { v: 1 } };
175
+ }
176
+ /** A person's reset (Details, the chat menu): theme, placements and pictures go; the lock stays. Not limited. */
177
+ humanReset(instance) {
178
+ this.uploads.delete(instance);
179
+ const w = this.store.reset(instance, "human");
180
+ if (!w.ok)
181
+ return { error: w.error, status: w.status };
182
+ this.changed();
183
+ return { ok: true, rev: w.rev };
184
+ }
185
+ /** A person's lock (r2 (a)). Not limited. */
186
+ humanLock(instance, locked) {
187
+ const w = this.store.setLocked(instance, locked);
188
+ if (!w.ok)
189
+ return { error: w.error, status: w.status };
190
+ this.changed();
191
+ return { ok: true, locked, rev: w.rev };
192
+ }
193
+ /**
194
+ * set_web_widget { slot, spec?, data? } (r4-4): place a widget in one of its own slots (`spec`, a change), or give
195
+ * the one there new values (`data` alone: merged, null removes a key — its own budget, 10 s apart). A widget a person
196
+ * placed takes the agent's values but is never replaced by it. `sidebar` is the person's: owner_slot.
197
+ */
198
+ setWidget(instance, args) {
199
+ const slot = this.agentSlot(args.slot);
200
+ if (typeof slot !== "string")
201
+ return slot;
202
+ if (args.spec === undefined && args.data === undefined)
203
+ return { error: "args", message: "Give spec (to place a widget) or data (new values for the one placed)." };
204
+ const current = this.store.get(instance).placements.widgets[slot];
205
+ if (args.spec === undefined) {
206
+ const refused = this.refusal(instance, ["data"]);
207
+ if (refused)
208
+ return refused;
209
+ if (!current)
210
+ return { error: "no_widget", message: `Nothing is placed in ${slot}: give a spec first.` };
211
+ const data = mergeWidgetData(current.data, args.data, current.spec);
212
+ if (!data.ok)
213
+ return { errors: data.errors };
214
+ const w = this.store.setWidgetData(instance, slot, data.value, "agent");
215
+ if (!w.ok)
216
+ return { error: w.error, ...(w.detail ? { detail: w.detail } : {}) };
217
+ this.limiter.record(instance, ["data"]);
218
+ this.changed();
219
+ return { slot, widget: { spec: w.widget.spec, data: w.widget.data, by: w.widget.by }, rev: w.rev };
220
+ }
221
+ const refused = this.refusal(instance, ["change"]);
222
+ if (refused)
223
+ return refused;
224
+ if (current?.by === "human")
225
+ return { error: "person_placed", message: `A person placed the widget in ${slot}: you can give it values (data), but not replace or remove it.` };
226
+ const spec = checkWidgetSpec(args.spec, slot);
227
+ if (!spec.ok)
228
+ return { errors: spec.errors };
229
+ const data = args.data === undefined ? { ok: true, value: carryWidgetData(current?.data ?? {}, spec.value) } : checkWidgetData(args.data, spec.value);
230
+ if (!data.ok)
231
+ return { errors: data.errors };
232
+ const w = this.store.setWidget(instance, slot, spec.value, data.value, "agent");
233
+ if (!w.ok)
234
+ return { error: w.error, ...(w.detail ? { detail: w.detail } : {}) };
235
+ this.limiter.record(instance, ["change"]);
236
+ this.changed();
237
+ return { slot, widget: { spec: w.widget.spec, data: w.widget.data, by: w.widget.by }, rev: w.rev };
238
+ }
239
+ /** remove_web_widget { slot? } (r4-4): its own widgets, from one slot or both; a person's placement stays (a change). */
240
+ removeWidget(instance, args) {
241
+ let slots = [...AGENT_WIDGET_SLOTS];
242
+ if (args.slot !== undefined) {
243
+ const slot = this.agentSlot(args.slot);
244
+ if (typeof slot !== "string")
245
+ return slot;
246
+ slots = [slot];
247
+ }
248
+ const refused = this.refusal(instance, ["change"]);
249
+ if (refused)
250
+ return refused;
251
+ const placed = this.store.get(instance).placements.widgets;
252
+ const kept = slots.filter(s => placed[s]?.by === "human");
253
+ if (args.slot !== undefined && kept.length)
254
+ return { error: "person_placed", message: `A person placed the widget in ${kept[0]}; only a person removes it.` };
255
+ const mine = slots.filter(s => placed[s]?.by === "agent");
256
+ if (!mine.length)
257
+ return { removed: [], ...(kept.length ? { kept } : {}) };
258
+ const w = this.store.removeWidgets(instance, mine, "agent");
259
+ if (!w.ok)
260
+ return { error: w.error, ...(w.detail ? { detail: w.detail } : {}) };
261
+ this.limiter.record(instance, ["change"]);
262
+ this.changed();
263
+ return { removed: w.removed, ...(kept.length ? { kept } : {}), rev: w.rev };
264
+ }
265
+ agentSlot(raw) {
266
+ if (raw === "sidebar")
267
+ return { error: "owner_slot", message: "The sidebar is a person's; place your widget in chat_header or details." };
268
+ if (!WIDGET_SLOTS.includes(raw))
269
+ return { error: "slot", message: AGENT_WIDGET_SLOTS.join(" or ") };
270
+ return raw;
271
+ }
272
+ /** A person's removal of an agent's widget (Details, an admin session). Not limited; the lock is not needed. */
273
+ humanRemoveWidget(instance, slot) {
274
+ if (!AGENT_WIDGET_SLOTS.includes(slot))
275
+ return { error: "slot", status: 400 };
276
+ const w = this.store.removeWidgets(instance, [slot], "human");
277
+ if (!w.ok)
278
+ return { error: w.error, status: w.status };
279
+ if (w.removed.length)
280
+ this.changed(); // nothing placed there: nothing written, nothing announced
281
+ return { ok: true, removed: w.removed, rev: w.rev };
282
+ }
283
+ /** An instance was removed: its counters and any upload in progress go. */
284
+ forget(instance) { this.uploads.delete(instance); this.limiter.forget(instance); }
285
+ /** The tool dispatcher both doors share (typed IPC from the daemon, the agent endpoint for agend-agent). */
286
+ handleTool(instance, tool, args) {
287
+ switch (tool) {
288
+ case "get_web_theme": return this.getTheme(instance);
289
+ case "set_web_theme": return this.setTheme(instance, args);
290
+ case "set_web_theme_asset": return this.setAsset(instance, args);
291
+ case "reset_web_theme": return this.resetTheme(instance);
292
+ case "set_web_widget": return this.setWidget(instance, args);
293
+ case "remove_web_widget": return this.removeWidget(instance, args);
294
+ default: return { error: "unknown_tool" };
295
+ }
296
+ }
297
+ }
298
+ //# sourceMappingURL=web-appearance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-appearance.js","sourceRoot":"","sources":["../src/web-appearance.ts"],"names":[],"mappings":"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"}