@songsid/agend 2.2.1 → 2.2.5

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 (447) hide show
  1. package/dist/agent-cli-instructions.md +5 -2
  2. package/dist/agent-cli.js +284 -2
  3. package/dist/agent-cli.js.map +1 -1
  4. package/dist/agent-endpoint.d.ts +2 -0
  5. package/dist/agent-endpoint.js +29 -0
  6. package/dist/agent-endpoint.js.map +1 -1
  7. package/dist/agent-file-read.d.ts +38 -0
  8. package/dist/agent-file-read.js +317 -0
  9. package/dist/agent-file-read.js.map +1 -0
  10. package/dist/agent-whats-new.d.ts +11 -0
  11. package/dist/agent-whats-new.js +34 -2
  12. package/dist/agent-whats-new.js.map +1 -1
  13. package/dist/atomic-write.js +9 -1
  14. package/dist/atomic-write.js.map +1 -1
  15. package/dist/auth-api.d.ts +30 -1
  16. package/dist/auth-api.js +61 -12
  17. package/dist/auth-api.js.map +1 -1
  18. package/dist/authority/authority-state.d.ts +38 -0
  19. package/dist/authority/authority-state.js +114 -0
  20. package/dist/authority/authority-state.js.map +1 -0
  21. package/dist/authority/session-authorizations.d.ts +43 -0
  22. package/dist/authority/session-authorizations.js +102 -0
  23. package/dist/authority/session-authorizations.js.map +1 -0
  24. package/dist/authority/web-authority.d.ts +120 -0
  25. package/dist/authority/web-authority.js +157 -0
  26. package/dist/authority/web-authority.js.map +1 -0
  27. package/dist/backend/antigravity.js +3 -3
  28. package/dist/backend/antigravity.js.map +1 -1
  29. package/dist/backend/claude-code.d.ts +2 -2
  30. package/dist/backend/claude-code.js +10 -5
  31. package/dist/backend/claude-code.js.map +1 -1
  32. package/dist/backend/launch-effort.js +1 -1
  33. package/dist/backend/launch-effort.js.map +1 -1
  34. package/dist/backend/muse.js +10 -2
  35. package/dist/backend/muse.js.map +1 -1
  36. package/dist/backend/types.d.ts +14 -0
  37. package/dist/backend/types.js +25 -0
  38. package/dist/backend/types.js.map +1 -1
  39. package/dist/backend-availability.d.ts +120 -0
  40. package/dist/backend-availability.js +396 -0
  41. package/dist/backend-availability.js.map +1 -0
  42. package/dist/backend-command.d.ts +21 -3
  43. package/dist/backend-command.js +23 -4
  44. package/dist/backend-command.js.map +1 -1
  45. package/dist/bundled-skills.d.ts +14 -0
  46. package/dist/bundled-skills.js +29 -0
  47. package/dist/bundled-skills.js.map +1 -0
  48. package/dist/cache-analysis.d.ts +47 -1
  49. package/dist/cache-analysis.js +68 -8
  50. package/dist/cache-analysis.js.map +1 -1
  51. package/dist/cache-ledger.d.ts +16 -3
  52. package/dist/cache-ledger.js +33 -13
  53. package/dist/cache-ledger.js.map +1 -1
  54. package/dist/cache-report-tool.d.ts +17 -0
  55. package/dist/cache-report-tool.js +40 -0
  56. package/dist/cache-report-tool.js.map +1 -0
  57. package/dist/cache-service.d.ts +70 -3
  58. package/dist/cache-service.js +178 -17
  59. package/dist/cache-service.js.map +1 -1
  60. package/dist/channel/adapters/discord-client-retirement.d.ts +5 -0
  61. package/dist/channel/adapters/discord-client-retirement.js +57 -0
  62. package/dist/channel/adapters/discord-client-retirement.js.map +1 -0
  63. package/dist/channel/adapters/discord.d.ts +11 -0
  64. package/dist/channel/adapters/discord.js +66 -6
  65. package/dist/channel/adapters/discord.js.map +1 -1
  66. package/dist/channel/adapters/telegram.d.ts +8 -1
  67. package/dist/channel/adapters/telegram.js +74 -4
  68. package/dist/channel/adapters/telegram.js.map +1 -1
  69. package/dist/channel/mcp-tools.js +48 -2
  70. package/dist/channel/mcp-tools.js.map +1 -1
  71. package/dist/channel/types.d.ts +21 -0
  72. package/dist/classic-channel-manager.d.ts +10 -5
  73. package/dist/classic-channel-manager.js +12 -9
  74. package/dist/classic-channel-manager.js.map +1 -1
  75. package/dist/cli.js +142 -110
  76. package/dist/cli.js.map +1 -1
  77. package/dist/config-validator.js +119 -4
  78. package/dist/config-validator.js.map +1 -1
  79. package/dist/daemon.d.ts +8 -0
  80. package/dist/daemon.js +298 -22
  81. package/dist/daemon.js.map +1 -1
  82. package/dist/decision-list.d.ts +25 -0
  83. package/dist/decision-list.js +30 -0
  84. package/dist/decision-list.js.map +1 -0
  85. package/dist/delivery-outbox.d.ts +10 -0
  86. package/dist/delivery-outbox.js +12 -1
  87. package/dist/delivery-outbox.js.map +1 -1
  88. package/dist/fleet-context.d.ts +15 -0
  89. package/dist/fleet-manager.d.ts +514 -12
  90. package/dist/fleet-manager.js +1885 -163
  91. package/dist/fleet-manager.js.map +1 -1
  92. package/dist/fleet-process-handlers.d.ts +18 -0
  93. package/dist/fleet-process-handlers.js +69 -0
  94. package/dist/fleet-process-handlers.js.map +1 -0
  95. package/dist/fleet-traffic.d.ts +74 -0
  96. package/dist/fleet-traffic.js +196 -0
  97. package/dist/fleet-traffic.js.map +1 -0
  98. package/dist/general-knowledge/skills/credential-profiles/SKILL.md +20 -5
  99. package/dist/general-knowledge/skills/cross-instance-messaging/SKILL.md +6 -1
  100. package/dist/general-knowledge/skills/multi-channel/SKILL.md +3 -2
  101. package/dist/general-knowledge/skills/persona-emoji/SKILL.md +1 -1
  102. package/dist/general-knowledge/skills/web-appearance/SKILL.md +492 -0
  103. package/dist/general-knowledge/skills/web-dashboard/SKILL.md +482 -0
  104. package/dist/general-knowledge/skills/worker-collaboration/SKILL.md +1 -1
  105. package/dist/human-delivery-receipts.d.ts +24 -1
  106. package/dist/human-delivery-receipts.js +64 -11
  107. package/dist/human-delivery-receipts.js.map +1 -1
  108. package/dist/instance-avatar.js +3 -0
  109. package/dist/instance-avatar.js.map +1 -1
  110. package/dist/instance-config-impact.js +6 -1
  111. package/dist/instance-config-impact.js.map +1 -1
  112. package/dist/instance-lifecycle.d.ts +2 -0
  113. package/dist/instance-lifecycle.js +20 -10
  114. package/dist/instance-lifecycle.js.map +1 -1
  115. package/dist/instance-names.d.ts +4 -0
  116. package/dist/instance-names.js +12 -0
  117. package/dist/instance-names.js.map +1 -0
  118. package/dist/instructions.d.ts +12 -1
  119. package/dist/instructions.js +13 -2
  120. package/dist/instructions.js.map +1 -1
  121. package/dist/locale.js +100 -8
  122. package/dist/locale.js.map +1 -1
  123. package/dist/ls-attach-resolve.d.ts +95 -0
  124. package/dist/ls-attach-resolve.js +174 -0
  125. package/dist/ls-attach-resolve.js.map +1 -0
  126. package/dist/memory-hogs.d.ts +27 -0
  127. package/dist/memory-hogs.js +124 -0
  128. package/dist/memory-hogs.js.map +1 -0
  129. package/dist/needs-you-hub.d.ts +4 -0
  130. package/dist/needs-you-hub.js +31 -6
  131. package/dist/needs-you-hub.js.map +1 -1
  132. package/dist/needs-you.d.ts +1 -13
  133. package/dist/needs-you.js +3 -37
  134. package/dist/needs-you.js.map +1 -1
  135. package/dist/outbound-handlers.d.ts +15 -0
  136. package/dist/outbound-handlers.js +152 -11
  137. package/dist/outbound-handlers.js.map +1 -1
  138. package/dist/outbound-schemas.d.ts +228 -4
  139. package/dist/outbound-schemas.js +147 -1
  140. package/dist/outbound-schemas.js.map +1 -1
  141. package/dist/public-web-gateway.js +21 -1
  142. package/dist/public-web-gateway.js.map +1 -1
  143. package/dist/public-web-link.d.ts +9 -0
  144. package/dist/public-web-link.js +8 -0
  145. package/dist/public-web-link.js.map +1 -1
  146. package/dist/quickstart-api.d.ts +10 -1
  147. package/dist/quickstart-api.js +12 -4
  148. package/dist/quickstart-api.js.map +1 -1
  149. package/dist/reply-buttons-controller.d.ts +4 -0
  150. package/dist/reply-buttons-controller.js +2 -2
  151. package/dist/reply-buttons-controller.js.map +1 -1
  152. package/dist/repo-worktree-guard.d.ts +36 -0
  153. package/dist/repo-worktree-guard.js +143 -0
  154. package/dist/repo-worktree-guard.js.map +1 -0
  155. package/dist/restart-progress.d.ts +65 -1
  156. package/dist/restart-progress.js +236 -10
  157. package/dist/restart-progress.js.map +1 -1
  158. package/dist/rollout-index.d.ts +5 -0
  159. package/dist/rollout-index.js +26 -5
  160. package/dist/rollout-index.js.map +1 -1
  161. package/dist/scheduler/scheduler.d.ts +70 -1
  162. package/dist/scheduler/scheduler.js +256 -17
  163. package/dist/scheduler/scheduler.js.map +1 -1
  164. package/dist/service-installer.d.ts +2 -1
  165. package/dist/service-installer.js +18 -3
  166. package/dist/service-installer.js.map +1 -1
  167. package/dist/settings-api.d.ts +23 -0
  168. package/dist/settings-api.js +233 -2
  169. package/dist/settings-api.js.map +1 -1
  170. package/dist/settings-change.js +112 -0
  171. package/dist/settings-change.js.map +1 -1
  172. package/dist/settings-effect.js +32 -2
  173. package/dist/settings-effect.js.map +1 -1
  174. package/dist/settings-http-confirmation.js +5 -0
  175. package/dist/settings-http-confirmation.js.map +1 -1
  176. package/dist/tmux-manager.d.ts +5 -0
  177. package/dist/tmux-manager.js +16 -0
  178. package/dist/tmux-manager.js.map +1 -1
  179. package/dist/tool-permissions.d.ts +4 -6
  180. package/dist/tool-permissions.js +100 -2
  181. package/dist/tool-permissions.js.map +1 -1
  182. package/dist/topic-commands.d.ts +17 -7
  183. package/dist/topic-commands.js +39 -21
  184. package/dist/topic-commands.js.map +1 -1
  185. package/dist/topic-link.d.ts +128 -0
  186. package/dist/topic-link.js +269 -0
  187. package/dist/topic-link.js.map +1 -0
  188. package/dist/types.d.ts +61 -1
  189. package/dist/ui/app-effects.js +245 -0
  190. package/dist/ui/chat-ambient.js +307 -0
  191. package/dist/ui/chat-effect-posters.js +42 -0
  192. package/dist/ui/chat-effects.js +160 -0
  193. package/dist/ui/chat-live-replies.js +58 -0
  194. package/dist/ui/chat-render.js +25 -7
  195. package/dist/ui/chat-store.js +41 -13
  196. package/dist/ui/chat-strings.js +86 -2
  197. package/dist/ui/chat-thread.js +204 -37
  198. package/dist/ui/chat-tour.js +1 -1
  199. package/dist/ui/effect-trial-controller.js +124 -0
  200. package/dist/ui/effect-trial-offer.js +31 -0
  201. package/dist/ui/effect-trial-panel.js +40 -0
  202. package/dist/ui/fleet-cache.js +23 -1
  203. package/dist/ui/fleet-canvas-layout.js +111 -0
  204. package/dist/ui/fleet-canvas.js +525 -0
  205. package/dist/ui/fleet-org.js +27 -12
  206. package/dist/ui/fleet-traffic.js +343 -0
  207. package/dist/ui/fleet-usage.js +401 -0
  208. package/dist/ui/image-lightbox.js +1 -1
  209. package/dist/ui/panel-chat.js +252 -58
  210. package/dist/ui/panel-details.js +20 -6
  211. package/dist/ui/panel-fleet.js +45 -19
  212. package/dist/ui/panel-log.js +6 -6
  213. package/dist/ui/panel-needs.js +3 -3
  214. package/dist/ui/panel-settings.js +58 -13
  215. package/dist/ui/preview-panel.js +25 -9
  216. package/dist/ui/preview.js +3 -2
  217. package/dist/ui/settings-appearance.js +349 -0
  218. package/dist/ui/settings-catalog.js +92 -0
  219. package/dist/ui/settings-dialogs.js +40 -12
  220. package/dist/ui/settings-effects.js +202 -0
  221. package/dist/ui/settings-guests.js +117 -0
  222. package/dist/ui/settings-learn.js +25 -0
  223. package/dist/ui/settings-model.js +15 -6
  224. package/dist/ui/settings-mods.js +271 -0
  225. package/dist/ui/settings-owner-effects.js +80 -0
  226. package/dist/ui/settings-strings.js +335 -10
  227. package/dist/ui/settings-web-authority.js +91 -0
  228. package/dist/ui/shared/agend-auth.js +28 -4
  229. package/dist/ui/shared/agent-widget.js +248 -0
  230. package/dist/ui/shared/app-i18n.js +6 -2
  231. package/dist/ui/shared/app-prefs.js +34 -13
  232. package/dist/ui/shared/app-route.js +42 -2
  233. package/dist/ui/shared/app-session.js +3 -1
  234. package/dist/ui/shared/app-shell.js +119 -41
  235. package/dist/ui/shared/app-store.js +28 -1
  236. package/dist/ui/shared/app-stream.js +14 -7
  237. package/dist/ui/shared/app-themes.js +206 -0
  238. package/dist/ui/shared/app.css +566 -5
  239. package/dist/ui/shared/app.js +23 -10
  240. package/dist/ui/shared/card-strings.js +32 -0
  241. package/dist/ui/shared/effect-app-runtime.js +297 -0
  242. package/dist/ui/shared/effect-baseline.js +64 -0
  243. package/dist/ui/shared/effect-chat-runtime.js +167 -0
  244. package/dist/ui/shared/effect-cursor.js +125 -0
  245. package/dist/ui/shared/effect-frame.js +146 -0
  246. package/dist/ui/shared/effect-geometry.js +137 -0
  247. package/dist/ui/shared/effect-host-style.js +10 -0
  248. package/dist/ui/shared/effect-owner-regions.js +74 -0
  249. package/dist/ui/shared/effect-owner-source.js +122 -0
  250. package/dist/ui/shared/effect-policy.js +151 -0
  251. package/dist/ui/shared/effect-poster-reader.js +98 -0
  252. package/dist/ui/shared/effect-posters.js +117 -0
  253. package/dist/ui/shared/effect-profiler.js +184 -0
  254. package/dist/ui/shared/effect-profiles.js +65 -0
  255. package/dist/ui/shared/effect-registry.js +543 -0
  256. package/dist/ui/shared/effect-runtime-loader.js +234 -0
  257. package/dist/ui/shared/effect-safety.js +153 -0
  258. package/dist/ui/shared/effect-stock-snapshot.js +43 -0
  259. package/dist/ui/shared/effect-stock-trust.js +217 -0
  260. package/dist/ui/shared/effect-trial-shadow.js +62 -0
  261. package/dist/ui/shared/effect-trial-source.js +103 -0
  262. package/dist/ui/shared/effect-trial-stage.js +170 -0
  263. package/dist/ui/shared/effect-trial.css +40 -0
  264. package/dist/ui/shared/fx-motion.js +67 -0
  265. package/dist/ui/shared/header-tools.js +1 -1
  266. package/dist/ui/shared/identity-card.js +273 -0
  267. package/dist/ui/shared/identity-color.js +261 -0
  268. package/dist/ui/shared/instance-nav.js +215 -41
  269. package/dist/ui/shared/owner-css.js +250 -0
  270. package/dist/ui/shared/owner-effect-prefs.js +117 -0
  271. package/dist/ui/shared/panel-view.js +103 -10
  272. package/dist/ui/shared/signin.js +2 -0
  273. package/dist/ui/shared/tokens.css +9 -3
  274. package/dist/ui/shared/ui-dialog.js +1 -1
  275. package/dist/ui/shared/ui-icons.js +3 -0
  276. package/dist/ui/shared/ui-menu.js +1 -1
  277. package/dist/ui/shared/ui-toast.js +1 -1
  278. package/dist/ui/shared/usage-dialog.js +22 -2
  279. package/dist/ui/shared/view-strings.js +98 -2
  280. package/dist/ui/shared/web-authorize.js +151 -0
  281. package/dist/ui/signin.html +1 -0
  282. package/dist/ui/web-terminal/terminal.css +4 -4
  283. package/dist/usage/providers.d.ts +28 -0
  284. package/dist/usage/providers.js +126 -36
  285. package/dist/usage/providers.js.map +1 -1
  286. package/dist/usage-report.d.ts +158 -0
  287. package/dist/usage-report.js +226 -0
  288. package/dist/usage-report.js.map +1 -0
  289. package/dist/usage-rollup.d.ts +51 -0
  290. package/dist/usage-rollup.js +168 -0
  291. package/dist/usage-rollup.js.map +1 -0
  292. package/dist/view-api.d.ts +68 -0
  293. package/dist/view-api.js +249 -8
  294. package/dist/view-api.js.map +1 -1
  295. package/dist/web-ambient.d.ts +72 -0
  296. package/dist/web-ambient.js +161 -0
  297. package/dist/web-ambient.js.map +1 -0
  298. package/dist/web-api.d.ts +117 -7
  299. package/dist/web-api.js +1283 -70
  300. package/dist/web-api.js.map +1 -1
  301. package/dist/web-appearance-limits.d.ts +82 -0
  302. package/dist/web-appearance-limits.js +83 -0
  303. package/dist/web-appearance-limits.js.map +1 -0
  304. package/dist/web-appearance-policy.d.ts +64 -0
  305. package/dist/web-appearance-policy.js +87 -0
  306. package/dist/web-appearance-policy.js.map +1 -0
  307. package/dist/web-appearance-tools.d.ts +53 -0
  308. package/dist/web-appearance-tools.js +124 -0
  309. package/dist/web-appearance-tools.js.map +1 -0
  310. package/dist/web-appearance-view.d.ts +124 -0
  311. package/dist/web-appearance-view.js +278 -0
  312. package/dist/web-appearance-view.js.map +1 -0
  313. package/dist/web-appearance.d.ts +93 -0
  314. package/dist/web-appearance.js +373 -0
  315. package/dist/web-appearance.js.map +1 -0
  316. package/dist/web-asset-parts.d.ts +93 -0
  317. package/dist/web-asset-parts.js +133 -0
  318. package/dist/web-asset-parts.js.map +1 -0
  319. package/dist/web-auth.js +20 -2
  320. package/dist/web-auth.js.map +1 -1
  321. package/dist/web-card.d.ts +110 -0
  322. package/dist/web-card.js +266 -0
  323. package/dist/web-card.js.map +1 -0
  324. package/dist/web-channel-echo.d.ts +7 -1
  325. package/dist/web-channel-echo.js +6 -2
  326. package/dist/web-channel-echo.js.map +1 -1
  327. package/dist/web-chat-history.d.ts +63 -0
  328. package/dist/web-chat-history.js +109 -6
  329. package/dist/web-chat-history.js.map +1 -1
  330. package/dist/web-commands.d.ts +1 -0
  331. package/dist/web-effect-bootstrap.d.ts +12 -0
  332. package/dist/web-effect-bootstrap.js +49 -0
  333. package/dist/web-effect-bootstrap.js.map +1 -0
  334. package/dist/web-effect-bundle.d.ts +28 -0
  335. package/dist/web-effect-bundle.js +171 -0
  336. package/dist/web-effect-bundle.js.map +1 -0
  337. package/dist/web-effect-canonical.d.ts +8 -0
  338. package/dist/web-effect-canonical.js +27 -0
  339. package/dist/web-effect-canonical.js.map +1 -0
  340. package/dist/web-effect-library.d.ts +114 -0
  341. package/dist/web-effect-library.js +530 -0
  342. package/dist/web-effect-library.js.map +1 -0
  343. package/dist/web-effect-playback.d.ts +30 -0
  344. package/dist/web-effect-playback.js +71 -0
  345. package/dist/web-effect-playback.js.map +1 -0
  346. package/dist/web-effect-poster.d.ts +8 -0
  347. package/dist/web-effect-poster.js +52 -0
  348. package/dist/web-effect-poster.js.map +1 -0
  349. package/dist/web-effect-profiles.d.ts +118 -0
  350. package/dist/web-effect-profiles.js +180 -0
  351. package/dist/web-effect-profiles.js.map +1 -0
  352. package/dist/web-effect-service.d.ts +93 -0
  353. package/dist/web-effect-service.js +335 -0
  354. package/dist/web-effect-service.js.map +1 -0
  355. package/dist/web-effect-tools.d.ts +48 -0
  356. package/dist/web-effect-tools.js +129 -0
  357. package/dist/web-effect-tools.js.map +1 -0
  358. package/dist/web-effect-trials.d.ts +86 -0
  359. package/dist/web-effect-trials.js +204 -0
  360. package/dist/web-effect-trials.js.map +1 -0
  361. package/dist/web-effect-upload.d.ts +27 -0
  362. package/dist/web-effect-upload.js +185 -0
  363. package/dist/web-effect-upload.js.map +1 -0
  364. package/dist/web-effect-worker.d.ts +8 -0
  365. package/dist/web-effect-worker.js +170 -0
  366. package/dist/web-effect-worker.js.map +1 -0
  367. package/dist/web-effect.d.ts +103 -0
  368. package/dist/web-effect.js +153 -0
  369. package/dist/web-effect.js.map +1 -0
  370. package/dist/web-guest-access.d.ts +125 -0
  371. package/dist/web-guest-access.js +234 -0
  372. package/dist/web-guest-access.js.map +1 -0
  373. package/dist/web-guest-rooms.d.ts +82 -0
  374. package/dist/web-guest-rooms.js +135 -0
  375. package/dist/web-guest-rooms.js.map +1 -0
  376. package/dist/web-identity-color.d.ts +87 -0
  377. package/dist/web-identity-color.js +209 -0
  378. package/dist/web-identity-color.js.map +1 -0
  379. package/dist/web-identity-palette.d.ts +113 -0
  380. package/dist/web-identity-palette.js +84 -0
  381. package/dist/web-identity-palette.js.map +1 -0
  382. package/dist/web-image-meta.d.ts +38 -0
  383. package/dist/web-image-meta.js +262 -0
  384. package/dist/web-image-meta.js.map +1 -0
  385. package/dist/web-login.d.ts +47 -0
  386. package/dist/web-login.js +115 -0
  387. package/dist/web-login.js.map +1 -1
  388. package/dist/web-mod-agent.d.ts +50 -0
  389. package/dist/web-mod-agent.js +207 -0
  390. package/dist/web-mod-agent.js.map +1 -0
  391. package/dist/web-mod-bundle.d.ts +157 -0
  392. package/dist/web-mod-bundle.js +529 -0
  393. package/dist/web-mod-bundle.js.map +1 -0
  394. package/dist/web-mod-export.d.ts +68 -0
  395. package/dist/web-mod-export.js +100 -0
  396. package/dist/web-mod-export.js.map +1 -0
  397. package/dist/web-mod-store.d.ts +289 -0
  398. package/dist/web-mod-store.js +638 -0
  399. package/dist/web-mod-store.js.map +1 -0
  400. package/dist/web-org.d.ts +3 -3
  401. package/dist/web-org.js +11 -17
  402. package/dist/web-org.js.map +1 -1
  403. package/dist/web-owner-css-store.d.ts +222 -0
  404. package/dist/web-owner-css-store.js +440 -0
  405. package/dist/web-owner-css-store.js.map +1 -0
  406. package/dist/web-owner-css.d.ts +58 -0
  407. package/dist/web-owner-css.js +552 -0
  408. package/dist/web-owner-css.js.map +1 -0
  409. package/dist/web-prefs.d.ts +62 -0
  410. package/dist/web-prefs.js +232 -36
  411. package/dist/web-prefs.js.map +1 -1
  412. package/dist/web-preview.d.ts +15 -3
  413. package/dist/web-preview.js +28 -9
  414. package/dist/web-preview.js.map +1 -1
  415. package/dist/web-returning-device.d.ts +41 -0
  416. package/dist/web-returning-device.js +57 -5
  417. package/dist/web-returning-device.js.map +1 -1
  418. package/dist/web-session-authorization.d.ts +132 -0
  419. package/dist/web-session-authorization.js +193 -0
  420. package/dist/web-session-authorization.js.map +1 -0
  421. package/dist/web-session.d.ts +70 -10
  422. package/dist/web-session.js +137 -22
  423. package/dist/web-session.js.map +1 -1
  424. package/dist/web-settings-patch.d.ts +67 -2
  425. package/dist/web-settings-patch.js +196 -1
  426. package/dist/web-settings-patch.js.map +1 -1
  427. package/dist/web-settings-tools.d.ts +89 -0
  428. package/dist/web-settings-tools.js +273 -0
  429. package/dist/web-settings-tools.js.map +1 -0
  430. package/dist/web-shell-routes.d.ts +2 -2
  431. package/dist/web-shell-routes.js +2 -2
  432. package/dist/web-shell-routes.js.map +1 -1
  433. package/dist/web-theme-store.d.ts +257 -0
  434. package/dist/web-theme-store.js +627 -0
  435. package/dist/web-theme-store.js.map +1 -0
  436. package/dist/web-theme.d.ts +123 -0
  437. package/dist/web-theme.js +416 -0
  438. package/dist/web-theme.js.map +1 -0
  439. package/dist/web-upload.d.ts +13 -0
  440. package/dist/web-upload.js +39 -3
  441. package/dist/web-upload.js.map +1 -1
  442. package/dist/web-widget.d.ts +72 -0
  443. package/dist/web-widget.js +245 -0
  444. package/dist/web-widget.js.map +1 -0
  445. package/dist/workflow-templates/default.md +1 -1
  446. package/package.json +1 -1
  447. package/templates/systemd.service.ejs +8 -0
@@ -0,0 +1,492 @@
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, set an ambient effect (falling petals, click stars), play Canvas Worker effects in your chat (and offer a Try), preview the result, share it as a mod; and, for General, changing Settings → Web appearance for the user
4
+ roles: [general, worker, classic]
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
+ | An ambient effect in your chat | falling petals, snow, rising lanterns, twinkles, stars where a person clicks — data only, drawn by the dashboard | `set_web_ambient`, `clear_web_ambient` |
22
+ | A file of your look | a mod: export yours, or propose one for a person | `export_web_mod`, `propose_web_mod` |
23
+ | Effects in your chat | Canvas Worker animations, and Try cards an admin outside the public link may start | `upload_web_effect`, `apply_web_effect`, `preview_web_effect`, … (see Effects) |
24
+
25
+ None of these tools takes a target: they always act on you. You can't change another instance, the dashboard's own
26
+ chrome, a person's sidebar widget, or a person's custom CSS.
27
+
28
+ ## For the user: Settings → Web appearance (General, coordinators, full)
29
+
30
+ If you are General (or a coordinator or full profile), you can change the user's **Settings → Web appearance** for
31
+ them, exactly as the page changes it: the same checks, the same refusals. Custom CSS keeps its safe rules: no remote
32
+ URLs, assets only as `url("asset:<id>")`, at most 64 KiB. Other instances can't; they shape only their own look (the rest
33
+ of this skill).
34
+
35
+ 1. **Read first:** `get_web_settings` returns a `summary` in plain words (tell the user from it), the values, and
36
+ `people`: the host operator and everyone who has signed in. Host settings are everyone's on this host. Custom CSS and
37
+ effect slots are one person's own: pass `person` as the entry whose id is the user's (`person:<adapter>:<their id>`),
38
+ else the host operator's are changed.
39
+ 2. **One change per call:** `set_web_settings({ person?, change })`, where `change.what` is one of:
40
+
41
+ | `what` | Changes | Example |
42
+ |---|---|---|
43
+ | `host` | `themes_shown`, `card_size` (s/m/l), `card_sizes` ({instance: s/m/l}), `colour_places` (name/bar/ring), `colours_off`, `sidebar_widget` ({spec, data}) — null puts one back to its default | `{ what: "host", set: { colour_places: ["name","ring"] } }` |
44
+ | `agent_colour` | one agent's colour (`preset:<name>` or `#rrggbb`) and places; null resets each | `{ what: "agent_colour", instance: "atlas", colour: "preset:teal" }` |
45
+ | `banner_focus` | which part of one agent's cropped card banner stays in view: `focus` 0 (top) … 100 (bottom), 50 the centre; it wins over the agent's own `card.bannerFocus`; null follows the agent's again | `{ what: "banner_focus", instance: "atlas", focus: 20 }` |
46
+ | `custom_css` | `save` (with `text`): goes **on trial**. It waits until they open the dashboard (up to 10 minutes; never opened, it goes back unseen), then goes back by itself 20 s after it is on their screen unless kept (#2198). `keep` (the trial; or, kept after that 20 s ran out, it is put back in force as `use` of it), `revert` (the trial), `use` (with `version`: an earlier saved one, at once), `off` | `{ what: "custom_css", action: "save", text: "…" }`; tell them to open the dashboard and look, then `keep` only when they say so — a `keep` that comes too late (`not_on_trial`) means use `use` with the version from `get_web_settings` |
47
+ | `mod` | an agent's proposal: `review` (instance → `stage`, `plan`, `plan_hash`), then `install` (stage, plan_hash, `include`: the parts, `target`: the agent); `cancel`, `dismiss`, `uninstall` (id) | review, show the user the plan, install only what they asked for — never custom CSS unasked. A person has one review open at a time: while theirs is open (`mod_review_open`) ask them to finish it; a mod they imported from a file is theirs to install (`mod_not_from_an_agent`) |
48
+ | `effect` | `apply` (instance, id, params?) or `remove` (instance, id?) an effect on a chat | |
49
+ | `ambient` | one agent's ambient effect, set for the user: `ambient` is the same spec as `set_web_ambient`'s (it replaces the one of its kind, and the agent can't change it after); `ambient: null` clears (`which`: `loop` or `click`, default both) | `{ what: "ambient", instance: "atlas", ambient: { preset: "fall", glyphs: ["🌸","❀","✿"] } }` |
50
+ | `effect_slot` | a person's `sidebar` / `header` / `page` / `box` / `cursor` effect (an id, or null) | |
51
+ | `restore_defaults` | the host settings back to their defaults, and the person's custom CSS off | |
52
+
53
+ 3. **Say what changed** in the user's words (read again if unsure). A refusal says why: the same words the page would
54
+ show.
55
+
56
+ **Only the person can do these, on the page:**
57
+ - choose a file from their computer: import a mod file, upload an effect folder, add a CSS asset or a card picture;
58
+ - this browser's own switches: custom CSS off on this device, pausing effect playback;
59
+ - download an export;
60
+ - the card upload limits (fleet configuration; a raise waits for an admin's confirmation).
61
+
62
+ ## Look first
63
+
64
+ - `get_web_appearance` — how you appear **now**, resolved exactly as the dashboard resolves it: your face and where it
65
+ comes from (`profile`, `theme`, `bot`, `emoji` or `initial`), your ring colour, your **identity colour**
66
+ (`identity_color`: the colour people find you by in the sidebar, its `source` — `person`, `agent` (your theme's
67
+ `identity.color`, else its `accent`), `role` (your own bot's Discord role) or `auto` — its `light` / `dark` values,
68
+ where it shows (`show`: `name`, `bar`, `ring`) and whose choice that is (`show_source`: `person`, `agent` or `host`),
69
+ and `off` when the host turned colours off), your card field by field
70
+ (each marked `human` or `agent`), your theme per light/dark mode after the defaults, whether a person locked it, and
71
+ your limits.
72
+ - `preview_web_appearance` (`modes`: `["light"]`, `["dark"]` or both) — draws that as an SVG per mode into
73
+ `.agend/appearance/<mode>.svg` in your working directory, with the pictures it shows written beside it
74
+ (`avatar.png`, `portrait.png`, …), and returns both lists of paths. Read the SVGs for exact colours, geometry and
75
+ text, and the pictures as images. Only your own pictures are there.
76
+ - `get_web_theme` — your stored theme, the token defaults it is drawn over, your uploaded pictures (`id`, `slot`), and
77
+ `limits` (changes left, each picture slot's size limits, your picture quota).
78
+
79
+ ## What wins over what
80
+
81
+ - **A person's choices win.** A picture uploaded for you in View beats your theme picture. A person's card field (from
82
+ View's Edit profile) beats yours, field by field — leave it to them. A person can **Lock** your theme (every change
83
+ you try is refused with `locked`) or **Reset** it (your theme, card and pictures go; a lock stays).
84
+ - A widget **a person placed** in one of your slots takes your values (`data`), but you can't replace or remove it
85
+ (`person_placed`).
86
+ - **Each viewer decides what they see.** Anyone can turn agents' themes and widgets off for their own screens, and
87
+ `?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
88
+ picture — a picture a person uploaded for you, else your bot's avatar, your persona emoji or your first letter.
89
+ Don't rely on your theme to say something important.
90
+ - The fleet can turn agent changes off entirely (`web.themes.agent_edit: false`): every change is refused with
91
+ `theme_editing_off`; what you stored stays.
92
+
93
+ ## Change your theme
94
+
95
+ `set_web_theme { set?, clear? }` — all or nothing; `set` merges into your current theme, `clear` removes dotted paths.
96
+ Typed values only; anything else is refused with `{ errors: [{ path, problem }] }`:
97
+
98
+ - `colors.light` / `colors.dark`: any of `bg`, `surface`, `text`, `text2`, `accent`, `userBubble`, `agentBubble` as
99
+ `#rrggbb` (or `#rgb`). **Contrast is checked per mode**: `text` at least 4.5:1 on `bg`, `surface` and both bubbles;
100
+ `text2` at least 4.5:1 on `bg` and `surface`; `accent` at least 3:1 on `bg` — a palette that fails is refused, naming
101
+ the pair.
102
+ - `accent`: `#rrggbb` for both modes (a mode's own `accent` wins). Without `identity.color`, it is also your identity
103
+ colour.
104
+ - `identity`: `{ color?, show? }`: your identity colour and where it shows.
105
+ - `color` is a preset (`red`, `orange`, `amber`, `lime`, `green`, `teal`, `cyan`, `blue`, `indigo`, `violet`, `pink`,
106
+ `slate`, each readable in light and dark) or `#rrggbb`.
107
+ - `show` is a list of `name`, `bar` and `ring` (`[]` for nowhere). Left out, the host's default applies (name, bar and ring).
108
+ - A person's choice for you in the dashboard always wins, field by field, and their Reset brings yours back.
109
+ `get_web_appearance` says which is in force.
110
+ - `bubble`: `{ radius: 0..24, border: "none" | "thin" | "accent" }`.
111
+ - `font`: `"inter"`, `"system"` or `"mono"`.
112
+ - `background`: `{ image: <asset id>, fit: "cover" | "contain", opacity: 0.05..1 }`.
113
+ - `avatar`: an asset id — your face (below a person's upload).
114
+ - `workingLabel`: 1..24 characters on one line, shown while you work instead of "is working…".
115
+ - `card`: `{ portrait?, banner?, tagline?, bio?, bannerFocus? }` — see below.
116
+
117
+ Example:
118
+
119
+ ```json
120
+ { "set": { "accent": "#7c3aed", "colors": { "dark": { "bg": "#14121f" } }, "bubble": { "radius": 12, "border": "accent" },
121
+ "font": "inter", "workingLabel": "Reviewing" } }
122
+ ```
123
+
124
+ `reset_web_theme` puts your theme back to the default (it counts as a change).
125
+
126
+ ## Pictures
127
+
128
+ `set_web_theme_asset { slot, file }` — `file` is a picture in **your working directory** (no symlinks; read on your side,
129
+ never by path on the fleet). It returns `{ id }`; name that id in `set_web_theme`. Metadata such as GPS is removed, and
130
+ the id is the hash of what is kept, so the same picture is the same id.
131
+
132
+ | Slot | Types | Limits |
133
+ |---|---|---|
134
+ | `background` | png, jpeg, webp, gif | 512 KiB, 4096 px a side |
135
+ | `avatar` | png, jpeg, webp, gif | 256 KiB, 4096 px a side |
136
+ | `portrait` | png, jpeg, webp | set by the fleet (default 1024×1536, 1.5 MiB) |
137
+ | `banner` | png, jpeg, webp | set by the fleet (default 1600×600, 768 KiB) |
138
+ | `glyph` | png, webp, gif | 64 KiB, 128 px a side; at most 4 (for `set_web_ambient`'s `glyphs`) |
139
+
140
+ A picture holds one slot: upload it again for another slot only if it is a different picture. `get_web_theme`'s
141
+ `limits.asset_slots` has the limits in force and `limits.asset_quota` how many pictures you may keep. A picture your
142
+ theme stops naming is deleted.
143
+
144
+ ## Your identity card
145
+
146
+ `card.tagline` (one line, 1..60 characters), `card.bio` (1..280 characters, at most 3 line breaks), `card.portrait` and
147
+ `card.banner` (asset ids uploaded for those slots). Text is shown as text — never markup or links. A person may set
148
+ their own version of any field; theirs is shown instead of yours.
149
+
150
+ The card goes **inside `set`**: `set_web_theme({ set: { card: { tagline, bio, portrait, banner } } })` (a top-level
151
+ `card` argument is refused).
152
+
153
+ **Your banner is cropped: never drawn wider than 5 : 1** (on a wider screen it is centred over a blurred copy) **nor
154
+ narrower than 9 : 4** (which crops the sides). Make it **1600×600** (the default limit) and keep faces and text
155
+ inside the **safe area: the middle 84% of the width × 53% of the height — 1350×320** — which every card shows on every
156
+ screen and layout. `card.bannerFocus` (0 top … 100 bottom; default 50, the centre) moves that area up or down: put a face
157
+ near the top at `bannerFocus: 0`. A person's focus (Edit profile, or General's `set_web_settings { what: "banner_focus" }`)
158
+ wins over yours. `preview_web_appearance` draws the banner cropped at its focus, as the page does (an M card).
159
+
160
+ ## Your identity colour
161
+
162
+ 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
163
+ your picture. Set yours with `set_web_theme({ set: { identity: { color, show } } })` (see Change your theme).
164
+
165
+ - **Which colour shows**, first match wins: a **person's** pick for you (⋯ → Colour… or View's Edit profile, also from a
166
+ temporary public link) > **yours** (`identity.color`, else your theme's `accent`; only for a viewer who shows agents'
167
+ themes) > your own bot's Discord **role** colour > an **automatic** soft colour chosen from your name (two instances
168
+ may share one).
169
+ - **Where it shows**: a person's choice for you > yours (`identity.show`; again only while themes are shown) > the
170
+ host's default (Settings → Web appearance; name, bar and ring unless changed).
171
+ - The host can **turn colours off** for everyone: nothing is drawn, and every pick, yours included, is kept for when
172
+ they come back.
173
+ - `get_web_appearance`'s `identity_color` shows what is in force: `color`, `source` (`person`, `agent`, `role`, `auto`),
174
+ `light` / `dark`, `show`, `show_source` (`person`, `agent`, `host`) and `off`.
175
+
176
+ ## Widgets
177
+
178
+ A widget is a small panel of facts the dashboard draws **with its own components**: you send what to show and the
179
+ values, never HTML, script, links or CSS. It takes your theme's colours and always carries a `✦ <title>` chip. Nothing
180
+ in it can be clicked or focused.
181
+
182
+ `set_web_widget { slot, spec?, data? }`:
183
+
184
+ - `slot`: `chat_header` (a strip under your chat header: at most **4** items, of `stat`, `progress`, `text`, `badge`)
185
+ or `details` (a card on your Details page: at most **8** items, any type). `sidebar` is a person's: `owner_slot`.
186
+ - `spec` places or replaces the widget (a change):
187
+ `{ v: 1, title: 1..24 characters, items: [item, …] }`, where each item is `{ type, label?, key | bind, … }`:
188
+
189
+ | Type | Shows | Value | Extra |
190
+ |---|---|---|---|
191
+ | `stat` | a label and a number or short word | number, or 1..24 characters | `unit` (1..8 characters) |
192
+ | `progress` | a bar and its percentage | number, 0..`max` | `max` (default 100) |
193
+ | `text` | one line | 1..120 characters | |
194
+ | `list` | a short list | 1..6 lines of 1..60 characters | |
195
+ | `badge` | a coloured word | 1..24 characters | `tone`, or `tones: { word: tone }` (`ok`, `warn`, `bad`, `info`, `muted`) |
196
+ | `spark` | a sparkline and its last number | 2..48 numbers | |
197
+
198
+ `label` (1..24 characters) is required for `stat`, `progress` and `spark`. `key` (`a-z`, `0-9`, `_`) names a value
199
+ in your `data`. `bind` shows a value the page already has: `state` (`working`, `idle`, `needs`, `stopped`,
200
+ `crashed`) on `text` or `badge`, `context_pct` on `stat` or `progress`, `cost_usd` on `stat`. Exactly one of the
201
+ two. A missing value shows `—`.
202
+ - `data` alone updates the placed widget's values: merged, `null` removes a key. Values must fit every item that shows
203
+ them; a key no item shows is refused. Data has **its own budget**, separate from theme changes: at least **10 s**
204
+ apart, at most **180 an hour**.
205
+ - The spec is at most 2048 bytes and the data at most 4096.
206
+
207
+ `remove_web_widget { slot? }` takes your widget out of one slot, or both (a change). `get_web_theme` and
208
+ `get_web_appearance` list your widgets.
209
+
210
+ ```json
211
+ { "slot": "chat_header", "spec": { "v": 1, "title": "Build", "items": [
212
+ { "type": "progress", "label": "Tests", "key": "tests" },
213
+ { "type": "badge", "label": "State", "bind": "state", "tones": { "working": "info", "needs": "warn" } },
214
+ { "type": "text", "key": "step" } ] },
215
+ "data": { "tests": 40, "step": "Running unit tests" } }
216
+ ```
217
+
218
+ Then, as you go: `set_web_widget { "slot": "chat_header", "data": { "tests": 75 } }`.
219
+
220
+ ## Ambient effects
221
+
222
+ An ambient effect is **data only**: you choose a preset and its glyphs, the dashboard draws them. No code runs, so it
223
+ needs no Try, no preview consent and no measurement — use it for petals, snow, lanterns, sparkles and stars on a click.
224
+ Use a Canvas Worker effect (below) only for what a preset can't express.
225
+
226
+ `set_web_ambient { preset, glyphs, colors?, count?, duration?, size?, sway?, spread?, rotate?, opacity? }`:
227
+
228
+ | `preset` | What it draws | `count` | `duration` (seconds, [min, max]) |
229
+ |---|---|---|---|
230
+ | `fall` | glyphs drifting down behind your chat, endlessly | 1..24 particles (default 12) | 4..30 (default [9, 19]) |
231
+ | `rise` | the same, drifting up | 1..24 (12) | 4..30 ([9, 19]) |
232
+ | `twinkle` | glyphs pulsing in place | 1..24 (12) | 1..10 ([2, 5]) |
233
+ | `burst-on-click` | glyphs scattering from where a person clicks or taps in your chat | 4..16 per click (10) | 0.3..2 ([0.5, 0.9]) |
234
+
235
+ - `glyphs`: 1..4, picked at random per particle — a string of 1..2 characters (an emoji, `✦`, `❀`), or `{ "asset": id }`,
236
+ a picture you uploaded with `set_web_theme_asset` to the `glyph` slot.
237
+ - `colors`: 0..5 `#rrggbb` for text glyphs (default: your accent). `size`: [min, max] px, 10..40 (default [14, 22]).
238
+ `sway`: sideways drift for fall and rise, 0..80 px (40). `spread`: how far a burst scatters, [min, max] 20..120 px
239
+ ([34, 90]). `rotate`: 0..720 degrees over a run (300). `opacity`: [start, peak, end], each 0..1 ([0, 0.85, 0.15]).
240
+ - Your chat holds **one looping ambient** (`fall`, `rise` or `twinkle`) **and one `burst-on-click`**: setting one
241
+ replaces only its own kind. `clear_web_ambient { which? }` clears `loop`, `click`, or both.
242
+ - It is drawn **behind your messages** and never takes a click (a burst shows over them for a moment, then is gone).
243
+ - Who sees it: everyone who shows agents' looks, the public link included. Not with "Show agents' themes, effects and
244
+ widgets" off, `?safe=1`, or on a device that chose to follow the system's reduced-motion setting while
245
+ the system asks for it. A hidden tab pauses it.
246
+ - Like a theme: a change for the rate limit, refused while a person locked your look; one a person set is theirs
247
+ (`person_placed`). A person's Reset of your theme clears it. `get_web_appearance` shows it, and
248
+ `preview_web_appearance` draws the looping one, still, behind the bubbles.
249
+
250
+ ```json
251
+ { "preset": "fall", "glyphs": ["🌸", "❀", "✿"], "colors": ["#f4a7b9", "#ffd1dc"], "count": 12, "duration": [9, 19] }
252
+ ```
253
+
254
+ Then stars on a click, alongside: `set_web_ambient { "preset": "burst-on-click", "glyphs": ["✦", "✧"] }`.
255
+
256
+ ## Mods
257
+
258
+ A mod is one file, `<name>-<version>.agendmod.json`, that carries a look: a theme with its pictures, card text,
259
+ widgets and effects. People import mods in **Settings → Web appearance → Mods**. **You never import**: a person reviews
260
+ everything in a mod and ticks what to apply.
261
+
262
+ - `export_web_mod { name, version, title? }` writes **your own** look to `.agend/mods/<name>-<version>.agendmod.json`
263
+ in your working directory and returns `{ path, bytes }`. It carries your theme with its pictures, the effects your
264
+ theme places (with their params) when they are yours or shared with you, your own card text (not a person's card
265
+ fields), the widgets and ambient effects you set yourself. A person's private effect placed on you stays out (`effects_omitted` counts it).
266
+ It never carries custom CSS or the sidebar widget, which are a person's. `name` is a-z, 0-9 and -, `version` is
267
+ MAJOR.MINOR.PATCH.
268
+ - `propose_web_mod { file }` sends a mod file from your working directory (at most 8 MiB) for a person to review. It
269
+ is checked whole and answers with its problems if it isn't valid. **A mod carrying custom CSS is refused**
270
+ (`owner_css_not_from_agent`). A muted line in your chat says it was proposed. Nothing changes until a person
271
+ installs it. One proposal at a time: a new one replaces yours.
272
+ - A widget a person placed from a mod is theirs: you may give it values (`set_web_widget` with `data`), but not replace
273
+ or remove it (`person_placed`).
274
+
275
+ The file format: `{ "format": "agend-mod", "v": 1, "manifest": { name, version, title, description?, author?,
276
+ requires?: { agend: ">=X.Y.Z" }, contents: { theme?, identity?, widgets?: { chat_header?, details? }, ambient?, effects? } },
277
+ "files": { "<path>": { "sha256", "b64" } } }`. Every file is listed with its sha256 and used by exactly one part, paths
278
+ are lowercase with no `..`, and a theme names its pictures by path (an ambient's glyph pictures too: `{ "asset": "<path>" }`). The easiest way to get one right is to set your look
279
+ with the tools above, then `export_web_mod`.
280
+
281
+ ## Limits
282
+
283
+ - At least **30 s** between changes, at most **10 changes an hour** — refused with `rate_limited` and
284
+ `retry_after_s`. Only an accepted change counts; a refused or invalid one costs nothing.
285
+ - Uploads (pictures, effects, proposed mods) are not counted. Each picture slot's size limits, your picture quota and
286
+ each file's own caps still apply; using a picture in your theme is a change.
287
+ - Widget values (`set_web_widget` with `data` only): at least **10 s** apart, at most **180 an hour**, apart from the
288
+ above.
289
+ - `set_web_ambient` and `clear_web_ambient` are changes.
290
+ - Effects: `apply_web_effect` and `remove_web_effect` are changes; `upload_web_effect` and `propose_web_mod` are not
291
+ counted.
292
+ At most 10 effects and 8 MiB of your own, at most two placed in your chat.
293
+ - Plan the whole look, check it in one `set_web_theme`, then preview — don't iterate change by change.
294
+
295
+ ## A good workflow
296
+
297
+ 1. `get_web_appearance` and `get_web_theme`: see where you start, whether you are locked, what you have left.
298
+ 2. Upload the pictures you need (`set_web_theme_asset`), one per slot.
299
+ 3. One `set_web_theme` with everything; fix any `errors` it names.
300
+ 4. `preview_web_appearance` and Read the SVGs for both modes. Check contrast and that your card reads well.
301
+
302
+ From a shell: `agend-agent theme get|set key=value…|set --json '<patch>'|clear <path>…|asset <slot> <file>|reset`,
303
+ `agend-agent appearance`, `agend-agent appearance preview [light|dark]`, and
304
+ `agend-agent widget set <slot> '<spec json>' ['<data json>']|data <slot> '<data json>'|remove [slot]`,
305
+ `agend-agent ambient set '<spec json>'|clear [loop|click]`, and
306
+ `agend-agent mod export <name> <version> [title]|propose <file>`.
307
+
308
+ ## Files in your working directory
309
+
310
+ Asset uploads, effect directories and mod proposals must be inside your working directory. For an external project,
311
+ use files there as before. For your own AgEnD-managed workspace under `~/.agend/workspaces/`, ordinary files there
312
+ also work; no staging folder is required. This includes the standard `<your-instance-name>` folder (ClassicBot and
313
+ instances without a project directory) and an exclusively configured folder with another name, such as instance
314
+ `alpha` with `working_directory: ~/.agend/workspaces/alpha-home` in `fleet.yaml`. Its canonical configured path must
315
+ not overlap another instance's configured or standard workspace, including persisted ClassicBot peers that are
316
+ stopped or paused. The `workspaces/` root itself is not a workspace.
317
+
318
+ General, adapter-specific General (such as `general-telegram`), and other configured working directories elsewhere
319
+ inside the AgEnD state directory must stage inputs under **`web-assets/` or `web-effects/`**. For example, put a banner at
320
+ `web-assets/banner.png` or an effect package at `web-effects/sparks/`, relative to that working directory. Its root
321
+ and backend configuration folders are not upload areas. Generated previews and exported mods still use the fixed
322
+ `.agend/appearance/` and `.agend/mods/` directories and can be read back or proposed there.
323
+
324
+ The daemon uses its launch identity and configuration; the CLI resolves `AGEND_INSTANCE_NAME` against `fleet.yaml`.
325
+ These checks require a canonical, exclusively owned directory: the state root, shared or overlapping configured
326
+ working directories, another instance's directory, and the host's state stores never qualify. No tool argument can
327
+ select an identity or working directory. Missing or unreadable ownership evidence refuses in-state access.
328
+
329
+ Inside all admitted in-state areas, `.env`, databases and their WAL/SHM/journal files, `instances/`,
330
+ `credential-profiles/`, `inbox/`, `web-files/`, `web-chat.json`, `chat-logs/`, backend credential/session/config files,
331
+ and hidden files or folders are refused. The only hidden-directory exception is the two generated `.agend/`
332
+ output directories above; their contents still undergo the sensitive-name checks. Hard-linked state files are also
333
+ refused. Copy an intended asset into staging as a new regular file; do not link a private state file there.
334
+
335
+ Paths are checked after resolving symlinks. A symlink named after General or a workspace, or in its managed parent
336
+ path, cannot widen access; uploaded files themselves must not be symlinks. Containment still applies to relative and
337
+ absolute paths and to each file in an effect package. The CLI name and current directory are controlled by its shell:
338
+ these local checks prevent accidental uploads, but do not isolate shells running as the same OS user.
339
+
340
+ ## Effects
341
+
342
+ A Canvas Worker effect is a small animation drawn by code that runs in an isolated Worker: no page, no DOM, no
343
+ network. For petals, snow or stars on a click, an ambient effect (above) is simpler and plays without a Try. You place
344
+ effects **only in your own chat**; a person can place them in the regions an effect's manifest
345
+ allows. None of these tools takes a target.
346
+
347
+ **The package** (CW1): a directory in your working directory with `effect.json` and `worker.js`, optionally
348
+ `poster.png`, `cursor.png` and `assets/*.png|jpg|jpeg|webp|gif`. No HTML or CSS, at most 20 files and 16 assets. The
349
+ smallest valid `effect.json`:
350
+
351
+ ```json
352
+ { "v": 1, "kind": "effect", "runtime": "canvas-worker-v1", "worker": "worker.js", "name": "spark", "title": "Spark", "regions": ["chat"], "layer": "behind", "wants": [] }
353
+ ```
354
+
355
+ - Optional fields: `description`, `poster` (`"poster.png"`), `box`, `cursor` (its `hotspot` inside the image) and
356
+ `params`.
357
+ - `name`: 1..32 characters, starting with a-z or 0-9, then a-z, 0-9 and -.
358
+ - `title` (1..40) and `description` (up to 200): one line each, counted in characters as people see them.
359
+ - `regions`: 1–5 of `chat`, `sidebar`, `header`, `page`, `box`. **Include `chat` to place it in a chat**: applying
360
+ one without it is refused (`effect_region`), and so is a mod placing it. The other regions are ones a person may
361
+ choose it for.
362
+ - `layer`: `behind` (under the content) or `front` (over it).
363
+ - `wants`: up to 5 of `pointer`, `state`, `reply`, `mention`, `theme`. **`mention` is reserved and never fires in
364
+ 2.3.0** (see Effect event availability).
365
+ - `params`: up to 16 typed parameters (`number`, `int`, `bool`, `enum`, `color`) a placement may set.
366
+ - `worker.js` (at most 1 MiB, a classic script: static `import` / `export` are refused) draws through the `agend` API:
367
+ `canvas`, `params`, `asset()`, `on()`, `frame()` and `ready()`. Call `ready()` within 10 s, or it is stopped. Network
368
+ and dynamic imports are blocked at run time; the upload may warn `network_or_import_api_unsupported`, but don't rely
369
+ on the warning to catch every use.
370
+ - Size: `effect.json` at most 64 KiB; the whole effect at most 8 MiB as uploaded and **1 MiB normalized**. Pictures:
371
+ at most 4096 px a side, and **8,388,608 pixels in total** across the assets, poster and cursor together. A cursor is
372
+ a square PNG of at most 64 px and 32 KiB (after metadata is stripped).
373
+
374
+ **Reusable pointer example:** [`docs/examples/click-sparks`](https://github.com/songsid/AgEnD/blob/main/docs/examples/click-sparks.md) has a small two-file CW1 package: click for a burst, hold the primary button and move for a trail. Copy it into your working directory before uploading. Protected controls receive no pointer input; samples are coalesced (up to 60 Hz, 30 at reduced quality), so do not use it as a required click or drag control.
375
+
376
+ **The tools:**
377
+
378
+ - `upload_web_effect { dir }` → `{ id, warnings }`. Uploads are not counted; the effect's own size caps apply.
379
+ **Your own** copies are at most **10 effects and 8 MiB**; effects a person shared with you don't count.
380
+ - `list_web_effects` — your own effects and those a person shared with you: `id`, `name`, `title`, `regions`, `layer`,
381
+ `bytes`, `latest_profile`. A currently placed effect also has `playback`: `status: "reported_blocked"` with closed
382
+ `reasons`, or `status: "unknown"`. `get_web_appearance.effects` lists your current placements with the same projection.
383
+ This means **some recent viewers reported blocked**, not all viewers and not a live permission or health check.
384
+ Observations expire after five minutes and stay in memory. Agents receive no viewer identifiers, counts, device/OS,
385
+ text, URLs or observation timestamps. Unknown means unknown; do not keep reapplying to bypass a viewer's choice.
386
+ - `apply_web_effect { id, params? }` places one in your chat, **at most two at a time**, with the declared `params`
387
+ (unknown or out of range → `effect_params`; regions without `chat` → `effect_region`). `remove_web_effect { id? }`
388
+ takes one out, or all of them. Both are changes (30 s apart, 10 an hour), and are refused while a person has locked
389
+ your theme (`locked`) or when the fleet turned agent changes off (`theme_editing_off`).
390
+ - `delete_web_effect { id }` deletes your own copy once nothing uses it; a placement, mod, stage or Try offer gives
391
+ `effect_in_use`. Another's copy is never removed.
392
+ - `profile_web_effect { id }` — how it ran on viewers' pages, per device class: `unmeasured`, or `reported` with
393
+ records carrying a `verdict` (`ok`, `degraded`, `paused`, `off`) and a `reason` (`host_budget`, `hidden`,
394
+ `reduced_motion`, `save_data`, `viewer_off`, `clock_unavailable`, `gates_unknown`, or none).
395
+ `list_web_effects`' `latest_profile` has the latest one. These are best-effort reports of what happened, not live
396
+ notices. No measurement means unknown, never healthy.
397
+ - `preview_web_effect { id }` offers a Try card in your chat (see Try below).
398
+ - **Sharing is a person's act.** You can't share an effect. You may use one a person shared with you (list, apply,
399
+ Try, profile, put in a mod) while it is shared. When they unshare it, a placement already in your chat stays
400
+ eligible for playback (subject to the viewer's and the safety rules); applying, Try, listing, profiling or exporting
401
+ it again needs your own copy or another share, else `not_found`. A placement is never a grant to export it.
402
+
403
+ **On a viewer's page:**
404
+
405
+ - At most **3** effects play at once, at most **2** of them `front` (1 and 1 on a constrained device); the rest wait
406
+ (`frame_limit`, `front_limit`).
407
+ - CW uses an opaque isolated document on the dashboard listener: no HTML-preview consent, separate preview port or
408
+ localhost requirement. Signed-in public/guest viewers may read and play only current effects in chats they can see;
409
+ this grants no library management, personal-slot, private-image, Trial or profile access. Their Chat header has a
410
+ browser-local show/off switch, including on phones, and an inline recovery action. It never writes host preferences.
411
+ - Playback starts without an empty-page FPS calibration. Safe mode, hidden tabs and the viewer's show switch still
412
+ stop it. **Effects: follow the system's reduced-motion setting** is device-local and **off by default**, shared with
413
+ ambient effects. The OS request alone does not block playback; data saver is informational. A one-time chat note
414
+ offers to follow reduced motion, and a motion refusal offers **Play effects anyway** right there, including public/guest
415
+ viewers. Safe mode offers **Leave safe mode**. A poster may replace unsupported playback or a chosen motion block
416
+ (see Static Chat fallback). Menus/dialogs stop `front` effects temporarily.
417
+ - A layout refusal keeps its local code in the Chat notice and Effects dialog (for example `stock_order_unknown`);
418
+ the browser console also names it. Report that code rather than repeatedly applying the effect. A failed Try leaves
419
+ its stop code on the offer card. Pointer-leave does not stop Try; window blur, closing, navigation or lost stage proof do.
420
+ Agent playback summaries still contain only the closed reporting reasons, never raw local diagnostics.
421
+ - **Safety pause** — it measures the page's responsiveness, not your Worker's CPU. Host rAF observations learn a live
422
+ cadence during warm-up, then fix the mount's floor at 90% of a faster observed cadence, capped at 55 fps (50 on a
423
+ constrained device). A steady 30 Hz display has a 27 fps floor. This is not an empty-page health certificate; uniformly
424
+ slow startup can look like a low-refresh display. Where reported, long tasks may take at most 50 ms a second (25 ms
425
+ constrained); unknown observations never count as free. Overlapping 2-second windows are judged at most once a second
426
+ after warm-up, and three bad judgements in a row pause the effect (`host_budget`).
427
+ - Only a viewer's explicit **Resume** restarts a safety-paused effect, and it doesn't clear the history: three such
428
+ pauses within 24 hours turn the effect **off** for that viewer's browser and device class, across tabs and reloads,
429
+ and Resume then refuses. It doesn't come back by itself after 24 hours.
430
+ - **Your `front` effects are paused while the viewer's custom CSS is on, loading or unknown**; `behind` effects play
431
+ once the page's stock layout is proven. A person's placement is exempt. Don't keep re-applying (see below).
432
+
433
+ ## Owner-level effect selections
434
+
435
+ The five owner keys `fx.sidebar`, `fx.header`, `fx.page`, `fx.box` and `fx.cursor` are a signed-in person's web
436
+ preferences, never agent tool targets. Platform-bound sessions use separate adapter/user buckets (no account merge).
437
+ A web-only `agend web --code` session uses the explicit **host-wide operator** bucket, shared by everyone signed in
438
+ as that host operator. Header tokens cannot read or write these five keys. Existing visible host preferences are
439
+ unchanged; there is no local-key migration. Profile/custom-CSS internal pointers keep their existing identity rules.
440
+
441
+ When a shared effect is unshared, a personal selection remains stored but becomes unavailable at its next resource
442
+ authorization. It supplies no further code or cursor image; the person can clear it. Its reference keeps the blob
443
+ from being collected until cleared. This is deliberately stricter than chat placements' retained-runtime reads:
444
+ a personal choice keeps following its person's current own/shared access, while a chat preserves the exact effect
445
+ placed there. A reference is not a sharing or export grant. Do not keep retrying a denied personal selection.
446
+
447
+ Owner selectors are available in Settings → Web appearance. With effects enabled, personal page/header/sidebar/box choices play across supported stock pages in the same pool
448
+ as signed-in Chat. HTML-preview consent and its service are not involved.
449
+ Web appearance offers slot Pause/Resume and unavailable/Clear controls. The personal cursor uses a static PNG on the host shell without HTML-preview 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
450
+ ordering and trust paint coverage. Agent front effects must remain paused when custom CSS is active, loading or
451
+ unknown; a person sees the reason and can open the causing setting. Human placements retain their exemption from
452
+ that agent restriction, and behind effects still require proven ordering. Saving a placement alone is not proof of
453
+ playback.
454
+
455
+ Visible menus, dialogs and Keep/tour notices suppress foreground effects; a human placement does not bypass them.
456
+ Editable focus suppresses pointer signals, not unrelated drawing. Protected controls stay clipped out of front paint;
457
+ keyboard events never enter the Worker. Unknown stock layout refuses admission. A trusted foreground plane is
458
+ deferred to #1940; do not keep reapplying an agent front while custom CSS is on, loading or unknown.
459
+
460
+ ### Try: offer first, signed-in admin click to start
461
+
462
+ `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
463
+ click by a signed-in **admin outside the public link** may start it (localhost is not required); never an agent, public link, header token or automatic action.
464
+ The host owns a visible Trial label and Stop control. Closing the panel/sheet, navigating, window blur, or another
465
+ menu/dialog stops it. The explicit Try click consents to this sample only; no global HTML-preview opt-in is needed or changed.
466
+ The host isolates the Trial controls and clipped stage in a closed Shadow DOM with fixed styles and reset typography.
467
+ Custom CSS stays active elsewhere. The same caps, profiler and safety 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
468
+ rechecks the originating agent's current own/shared access, with the trial bound to the admin's session and epoch.
469
+ 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
470
+ as permission to run or fetch an effect, and do not keep retrying an unavailable Try.
471
+
472
+
473
+ ## Static Chat fallback
474
+
475
+ When Worker/transport support is unavailable, the chosen motion preference prevents playback, or the page has no playback session,
476
+ a current chat placement with a poster can show its static PNG **behind** the content; a front declaration does not
477
+ make its poster foreground. No poster means nothing is drawn. Safe mode and the viewer's show switch hide posters
478
+ too; unknown stock ordering refuses paint. Explicit Pause, queued effects and a failed live read are not replaced by
479
+ this surface fallback. A failed static read/decode stops its poster pool until a changed revision or page reload;
480
+ there is no automatic network retry. Public viewers can read current Chat Worker code, with fresh session/exposure/placement checks; they acquire no library or personal-slot grant. They have no placement-management or Try controls.
481
+
482
+ The public-link show switch is this browser's choice, kept separately from boot-cached host defaults; it never writes
483
+ a host preference. The ordinary signed-in switch keeps its existing host preference. Do not depend on decoration to
484
+ carry an important message.
485
+
486
+ ## Effect event availability
487
+
488
+ Canvas Worker manifests may reserve `wants: ["mention"]`, but **mention is reserved and never emitted in 2.3.0**.
489
+ Do not build an effect that depends on it, infer mentions from reply text, or retry to obtain that signal. Provider-confirmed,
490
+ viewer-scoped direct-ID mention pulses are deferred to [#1963](https://github.com/songsid/AgEnD/issues/1963).
491
+ Reply pulses are transient: only a newly accepted live SSE agent reply can qualify. History, reconnect replay and polling
492
+ never create a pulse; a live receipt delayed over five seconds is dropped. No reply text, author or mention targets reach effects.