@wallarm-org/claude-design 0.0.0-stage → 4.9.0

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 (963) hide show
  1. package/README.md +114 -2
  2. package/bin/claude-design.js +347 -0
  3. package/dist/SETUP.md +130 -0
  4. package/dist/UPDATE.md +84 -0
  5. package/dist/assets/Icons/activity.svg +1 -0
  6. package/dist/assets/Icons/alt.svg +1 -0
  7. package/dist/assets/Icons/android-neutral.svg +1 -0
  8. package/dist/assets/Icons/android.svg +1 -0
  9. package/dist/assets/Icons/api.svg +1 -0
  10. package/dist/assets/Icons/apple-music-neutral.svg +1 -0
  11. package/dist/assets/Icons/apple-music.svg +1 -0
  12. package/dist/assets/Icons/apple-neutral.svg +1 -0
  13. package/dist/assets/Icons/apple-podcasts-neutral.svg +1 -0
  14. package/dist/assets/Icons/apple-podcasts.svg +1 -0
  15. package/dist/assets/Icons/apple.svg +1 -0
  16. package/dist/assets/Icons/archive.svg +1 -0
  17. package/dist/assets/Icons/arrow-big-up-dash.svg +1 -0
  18. package/dist/assets/Icons/arrow-big-up.svg +1 -0
  19. package/dist/assets/Icons/arrow-down-left.svg +1 -0
  20. package/dist/assets/Icons/arrow-down-right.svg +1 -0
  21. package/dist/assets/Icons/arrow-down.svg +1 -0
  22. package/dist/assets/Icons/arrow-left.svg +1 -0
  23. package/dist/assets/Icons/arrow-right-alt.svg +1 -0
  24. package/dist/assets/Icons/arrow-right.svg +1 -0
  25. package/dist/assets/Icons/arrow-up-down.svg +1 -0
  26. package/dist/assets/Icons/arrow-up-left.svg +1 -0
  27. package/dist/assets/Icons/arrow-up-right.svg +1 -0
  28. package/dist/assets/Icons/arrow-up.svg +1 -0
  29. package/dist/assets/Icons/artstation-neutral.svg +1 -0
  30. package/dist/assets/Icons/artstation.svg +1 -0
  31. package/dist/assets/Icons/asterisk.svg +1 -0
  32. package/dist/assets/Icons/audio-waveform.svg +1 -0
  33. package/dist/assets/Icons/aws-neutral.svg +1 -0
  34. package/dist/assets/Icons/aws.svg +1 -0
  35. package/dist/assets/Icons/badge-check.svg +1 -0
  36. package/dist/assets/Icons/baidu-neutral.svg +1 -0
  37. package/dist/assets/Icons/baidu.svg +1 -0
  38. package/dist/assets/Icons/bandage.svg +1 -0
  39. package/dist/assets/Icons/behance-neutral.svg +1 -0
  40. package/dist/assets/Icons/behance.svg +1 -0
  41. package/dist/assets/Icons/bell-cog.svg +1 -0
  42. package/dist/assets/Icons/bell.svg +1 -0
  43. package/dist/assets/Icons/binary.svg +1 -0
  44. package/dist/assets/Icons/book-open.svg +1 -0
  45. package/dist/assets/Icons/book.svg +1 -0
  46. package/dist/assets/Icons/boosty-neutral.svg +1 -0
  47. package/dist/assets/Icons/boosty.svg +1 -0
  48. package/dist/assets/Icons/bot.svg +1 -0
  49. package/dist/assets/Icons/brain.svg +1 -0
  50. package/dist/assets/Icons/braze-neutral.svg +1 -0
  51. package/dist/assets/Icons/braze.svg +1 -0
  52. package/dist/assets/Icons/brevo-neutral.svg +1 -0
  53. package/dist/assets/Icons/brevo.svg +1 -0
  54. package/dist/assets/Icons/bug-off.svg +1 -0
  55. package/dist/assets/Icons/bug-play.svg +1 -0
  56. package/dist/assets/Icons/bug.svg +1 -0
  57. package/dist/assets/Icons/building.svg +1 -0
  58. package/dist/assets/Icons/building2.svg +1 -0
  59. package/dist/assets/Icons/calendar-check.svg +1 -0
  60. package/dist/assets/Icons/calendar-check2.svg +1 -0
  61. package/dist/assets/Icons/calendar-clock.svg +1 -0
  62. package/dist/assets/Icons/calendar-cog.svg +1 -0
  63. package/dist/assets/Icons/calendar-days.svg +1 -0
  64. package/dist/assets/Icons/calendar-fold.svg +1 -0
  65. package/dist/assets/Icons/calendar-heart.svg +1 -0
  66. package/dist/assets/Icons/calendar-minus.svg +1 -0
  67. package/dist/assets/Icons/calendar-minus2.svg +1 -0
  68. package/dist/assets/Icons/calendar-off.svg +1 -0
  69. package/dist/assets/Icons/calendar-plus.svg +1 -0
  70. package/dist/assets/Icons/calendar-plus2.svg +1 -0
  71. package/dist/assets/Icons/calendar-range.svg +1 -0
  72. package/dist/assets/Icons/calendar-search.svg +1 -0
  73. package/dist/assets/Icons/calendar-x.svg +1 -0
  74. package/dist/assets/Icons/calendar-x2.svg +1 -0
  75. package/dist/assets/Icons/calendar.svg +1 -0
  76. package/dist/assets/Icons/chart-area.svg +1 -0
  77. package/dist/assets/Icons/chart-bar.svg +1 -0
  78. package/dist/assets/Icons/chart-column.svg +1 -0
  79. package/dist/assets/Icons/chart-no-axes-column.svg +1 -0
  80. package/dist/assets/Icons/check-check.svg +1 -0
  81. package/dist/assets/Icons/check.svg +1 -0
  82. package/dist/assets/Icons/checkbox-indeterminate.svg +1 -0
  83. package/dist/assets/Icons/chevron-down.svg +1 -0
  84. package/dist/assets/Icons/chevron-first.svg +1 -0
  85. package/dist/assets/Icons/chevron-last.svg +1 -0
  86. package/dist/assets/Icons/chevron-left.svg +1 -0
  87. package/dist/assets/Icons/chevron-right.svg +1 -0
  88. package/dist/assets/Icons/chevron-up-down.svg +1 -0
  89. package/dist/assets/Icons/chevron-up.svg +1 -0
  90. package/dist/assets/Icons/chevrons-down-up.svg +1 -0
  91. package/dist/assets/Icons/chevrons-down.svg +1 -0
  92. package/dist/assets/Icons/chevrons-left-right.svg +1 -0
  93. package/dist/assets/Icons/chevrons-left.svg +1 -0
  94. package/dist/assets/Icons/chevrons-right-left.svg +1 -0
  95. package/dist/assets/Icons/chevrons-right.svg +1 -0
  96. package/dist/assets/Icons/chevrons-up-down.svg +1 -0
  97. package/dist/assets/Icons/chevrons-up.svg +1 -0
  98. package/dist/assets/Icons/circle-arrow-down.svg +1 -0
  99. package/dist/assets/Icons/circle-arrow-left.svg +1 -0
  100. package/dist/assets/Icons/circle-arrow-out-down-left.svg +1 -0
  101. package/dist/assets/Icons/circle-arrow-out-down-right.svg +1 -0
  102. package/dist/assets/Icons/circle-arrow-out-up-left.svg +1 -0
  103. package/dist/assets/Icons/circle-arrow-out-up-right.svg +1 -0
  104. package/dist/assets/Icons/circle-arrow-right.svg +1 -0
  105. package/dist/assets/Icons/circle-arrow-up.svg +1 -0
  106. package/dist/assets/Icons/circle-check-big.svg +1 -0
  107. package/dist/assets/Icons/circle-check.svg +1 -0
  108. package/dist/assets/Icons/circle-chevron-down.svg +1 -0
  109. package/dist/assets/Icons/circle-chevron-left.svg +1 -0
  110. package/dist/assets/Icons/circle-chevron-right.svg +1 -0
  111. package/dist/assets/Icons/circle-chevron-up.svg +1 -0
  112. package/dist/assets/Icons/circle-dashed.svg +1 -0
  113. package/dist/assets/Icons/circle-dot-dashed.svg +1 -0
  114. package/dist/assets/Icons/circle-ellipsis.svg +1 -0
  115. package/dist/assets/Icons/circle-gauge.svg +1 -0
  116. package/dist/assets/Icons/circle-help.svg +1 -0
  117. package/dist/assets/Icons/circle-minus.svg +1 -0
  118. package/dist/assets/Icons/circle-plus.svg +1 -0
  119. package/dist/assets/Icons/circle-slash.svg +1 -0
  120. package/dist/assets/Icons/circle-slash2.svg +1 -0
  121. package/dist/assets/Icons/circle-stop.svg +1 -0
  122. package/dist/assets/Icons/circle.svg +1 -0
  123. package/dist/assets/Icons/clipboard-check.svg +1 -0
  124. package/dist/assets/Icons/clipboard-x.svg +1 -0
  125. package/dist/assets/Icons/clipboard.svg +1 -0
  126. package/dist/assets/Icons/clock-fading.svg +1 -0
  127. package/dist/assets/Icons/clock.svg +1 -0
  128. package/dist/assets/Icons/cloud-off.svg +1 -0
  129. package/dist/assets/Icons/cloud-sync.svg +1 -0
  130. package/dist/assets/Icons/cloud.svg +1 -0
  131. package/dist/assets/Icons/code.svg +1 -0
  132. package/dist/assets/Icons/collapse.svg +1 -0
  133. package/dist/assets/Icons/columns3-cog.svg +1 -0
  134. package/dist/assets/Icons/command.svg +1 -0
  135. package/dist/assets/Icons/compass.svg +1 -0
  136. package/dist/assets/Icons/copy-slash.svg +1 -0
  137. package/dist/assets/Icons/copy.svg +1 -0
  138. package/dist/assets/Icons/corner-down-left.svg +1 -0
  139. package/dist/assets/Icons/corner-down-right.svg +1 -0
  140. package/dist/assets/Icons/corner-left-down.svg +1 -0
  141. package/dist/assets/Icons/corner-left-up.svg +1 -0
  142. package/dist/assets/Icons/corner-right-down.svg +1 -0
  143. package/dist/assets/Icons/corner-right-up.svg +1 -0
  144. package/dist/assets/Icons/corner-up-left.svg +1 -0
  145. package/dist/assets/Icons/corner-up-right.svg +1 -0
  146. package/dist/assets/Icons/cpu.svg +1 -0
  147. package/dist/assets/Icons/credit-card.svg +1 -0
  148. package/dist/assets/Icons/crosshair.svg +1 -0
  149. package/dist/assets/Icons/ctrl.svg +1 -0
  150. package/dist/assets/Icons/database.svg +1 -0
  151. package/dist/assets/Icons/devianart-neutral.svg +1 -0
  152. package/dist/assets/Icons/devianart.svg +1 -0
  153. package/dist/assets/Icons/discord-neutral.svg +1 -0
  154. package/dist/assets/Icons/discord.svg +1 -0
  155. package/dist/assets/Icons/dollar-sign.svg +1 -0
  156. package/dist/assets/Icons/dot.svg +1 -0
  157. package/dist/assets/Icons/download.svg +1 -0
  158. package/dist/assets/Icons/dprofile-neutral.svg +1 -0
  159. package/dist/assets/Icons/dprofile.svg +1 -0
  160. package/dist/assets/Icons/dribbble-neutral.svg +1 -0
  161. package/dist/assets/Icons/dribbble.svg +1 -0
  162. package/dist/assets/Icons/droplet.svg +1 -0
  163. package/dist/assets/Icons/duplicate.svg +1 -0
  164. package/dist/assets/Icons/dzen-neutral.svg +1 -0
  165. package/dist/assets/Icons/dzen.svg +1 -0
  166. package/dist/assets/Icons/earth-lock.svg +1 -0
  167. package/dist/assets/Icons/earth.svg +1 -0
  168. package/dist/assets/Icons/ellipsis.svg +1 -0
  169. package/dist/assets/Icons/expand.svg +1 -0
  170. package/dist/assets/Icons/external-link.svg +1 -0
  171. package/dist/assets/Icons/eye-off.svg +1 -0
  172. package/dist/assets/Icons/eye.svg +1 -0
  173. package/dist/assets/Icons/facebook-neutral.svg +1 -0
  174. package/dist/assets/Icons/facebook.svg +1 -0
  175. package/dist/assets/Icons/fast-forward.svg +1 -0
  176. package/dist/assets/Icons/figma-neutral.svg +1 -0
  177. package/dist/assets/Icons/figma.svg +1 -0
  178. package/dist/assets/Icons/file-down.svg +1 -0
  179. package/dist/assets/Icons/file-plus.svg +1 -0
  180. package/dist/assets/Icons/file-text.svg +1 -0
  181. package/dist/assets/Icons/file.svg +1 -0
  182. package/dist/assets/Icons/film.svg +1 -0
  183. package/dist/assets/Icons/filter-x.svg +1 -0
  184. package/dist/assets/Icons/filter.svg +1 -0
  185. package/dist/assets/Icons/fingerprint-pattern.svg +1 -0
  186. package/dist/assets/Icons/flag.svg +1 -0
  187. package/dist/assets/Icons/flask-conical.svg +1 -0
  188. package/dist/assets/Icons/folder.svg +1 -0
  189. package/dist/assets/Icons/funnel-plus.svg +1 -0
  190. package/dist/assets/Icons/ghost.svg +1 -0
  191. package/dist/assets/Icons/git-branch.svg +1 -0
  192. package/dist/assets/Icons/git-commit-horizontal.svg +1 -0
  193. package/dist/assets/Icons/git-commit-vertical.svg +1 -0
  194. package/dist/assets/Icons/git-compare-arrows-alt.svg +1 -0
  195. package/dist/assets/Icons/git-compare-arrows.svg +1 -0
  196. package/dist/assets/Icons/git-compare.svg +1 -0
  197. package/dist/assets/Icons/git-fork.svg +1 -0
  198. package/dist/assets/Icons/git-graph.svg +1 -0
  199. package/dist/assets/Icons/git-merge.svg +1 -0
  200. package/dist/assets/Icons/git-pull-request-arrow.svg +1 -0
  201. package/dist/assets/Icons/git-pull-request-closed.svg +1 -0
  202. package/dist/assets/Icons/git-pull-request-create-arrow.svg +1 -0
  203. package/dist/assets/Icons/git-pull-request-create.svg +1 -0
  204. package/dist/assets/Icons/git-pull-request-draft.svg +1 -0
  205. package/dist/assets/Icons/git-pull-request.svg +1 -0
  206. package/dist/assets/Icons/github-neutral.svg +1 -0
  207. package/dist/assets/Icons/github.svg +1 -0
  208. package/dist/assets/Icons/globe-lock.svg +1 -0
  209. package/dist/assets/Icons/globe.svg +1 -0
  210. package/dist/assets/Icons/gmail-neutral.svg +1 -0
  211. package/dist/assets/Icons/gmail.svg +1 -0
  212. package/dist/assets/Icons/google-meet-neutral.svg +1 -0
  213. package/dist/assets/Icons/google-meet.svg +1 -0
  214. package/dist/assets/Icons/google-neutral.svg +1 -0
  215. package/dist/assets/Icons/google-play-neutral.svg +1 -0
  216. package/dist/assets/Icons/google-play.svg +1 -0
  217. package/dist/assets/Icons/google-podcast-neutral.svg +1 -0
  218. package/dist/assets/Icons/google-podcast.svg +1 -0
  219. package/dist/assets/Icons/google.svg +1 -0
  220. package/dist/assets/Icons/grip-horizontal.svg +1 -0
  221. package/dist/assets/Icons/grip-vertical.svg +1 -0
  222. package/dist/assets/Icons/hammer.svg +1 -0
  223. package/dist/assets/Icons/heart-pulse.svg +1 -0
  224. package/dist/assets/Icons/history.svg +1 -0
  225. package/dist/assets/Icons/home.svg +1 -0
  226. package/dist/assets/Icons/imo-neutral.svg +1 -0
  227. package/dist/assets/Icons/imo.svg +1 -0
  228. package/dist/assets/Icons/infinity.svg +1 -0
  229. package/dist/assets/Icons/info.svg +1 -0
  230. package/dist/assets/Icons/infobip-neutral.svg +1 -0
  231. package/dist/assets/Icons/infobip.svg +1 -0
  232. package/dist/assets/Icons/instagram-neutral.svg +1 -0
  233. package/dist/assets/Icons/instagram.svg +1 -0
  234. package/dist/assets/Icons/key-round.svg +1 -0
  235. package/dist/assets/Icons/key-square.svg +1 -0
  236. package/dist/assets/Icons/keyboard.svg +1 -0
  237. package/dist/assets/Icons/kickstarter-neutral.svg +1 -0
  238. package/dist/assets/Icons/kickstarter.svg +1 -0
  239. package/dist/assets/Icons/laptop.svg +1 -0
  240. package/dist/assets/Icons/layers.svg +1 -0
  241. package/dist/assets/Icons/layers2.svg +1 -0
  242. package/dist/assets/Icons/layers3.svg +1 -0
  243. package/dist/assets/Icons/layout-dashboard.svg +1 -0
  244. package/dist/assets/Icons/layout-grid.svg +1 -0
  245. package/dist/assets/Icons/layout-list.svg +1 -0
  246. package/dist/assets/Icons/layout-panel-left.svg +1 -0
  247. package/dist/assets/Icons/layout-panel-top.svg +1 -0
  248. package/dist/assets/Icons/layout-template.svg +1 -0
  249. package/dist/assets/Icons/library-big.svg +1 -0
  250. package/dist/assets/Icons/life-buoy.svg +1 -0
  251. package/dist/assets/Icons/lightbulb-off.svg +1 -0
  252. package/dist/assets/Icons/lightbulb.svg +1 -0
  253. package/dist/assets/Icons/line-neutral.svg +1 -0
  254. package/dist/assets/Icons/line.svg +1 -0
  255. package/dist/assets/Icons/link.svg +1 -0
  256. package/dist/assets/Icons/link2-off.svg +1 -0
  257. package/dist/assets/Icons/link2.svg +1 -0
  258. package/dist/assets/Icons/linkedin-neutral.svg +1 -0
  259. package/dist/assets/Icons/linkedin.svg +1 -0
  260. package/dist/assets/Icons/list-checks.svg +1 -0
  261. package/dist/assets/Icons/list-collapse.svg +1 -0
  262. package/dist/assets/Icons/list-filter.svg +1 -0
  263. package/dist/assets/Icons/list-minus.svg +1 -0
  264. package/dist/assets/Icons/list-ordered.svg +1 -0
  265. package/dist/assets/Icons/list-plus.svg +1 -0
  266. package/dist/assets/Icons/list-restart.svg +1 -0
  267. package/dist/assets/Icons/list-start.svg +1 -0
  268. package/dist/assets/Icons/list-todo.svg +1 -0
  269. package/dist/assets/Icons/list-tree.svg +1 -0
  270. package/dist/assets/Icons/list-video.svg +1 -0
  271. package/dist/assets/Icons/list-x.svg +1 -0
  272. package/dist/assets/Icons/list.svg +1 -0
  273. package/dist/assets/Icons/loader-circle.svg +1 -0
  274. package/dist/assets/Icons/loader.svg +1 -0
  275. package/dist/assets/Icons/lock-open.svg +1 -0
  276. package/dist/assets/Icons/lock.svg +1 -0
  277. package/dist/assets/Icons/log-in.svg +1 -0
  278. package/dist/assets/Icons/log-out.svg +1 -0
  279. package/dist/assets/Icons/mail-check.svg +1 -0
  280. package/dist/assets/Icons/mail-minus.svg +1 -0
  281. package/dist/assets/Icons/mail-open.svg +1 -0
  282. package/dist/assets/Icons/mail-plus.svg +1 -0
  283. package/dist/assets/Icons/mail-question.svg +1 -0
  284. package/dist/assets/Icons/mail-search.svg +1 -0
  285. package/dist/assets/Icons/mail-warning.svg +1 -0
  286. package/dist/assets/Icons/mail-x.svg +1 -0
  287. package/dist/assets/Icons/mail.svg +1 -0
  288. package/dist/assets/Icons/mailbox.svg +1 -0
  289. package/dist/assets/Icons/mailersend-neutral.svg +1 -0
  290. package/dist/assets/Icons/mailersend.svg +1 -0
  291. package/dist/assets/Icons/mailgun-neutral.svg +1 -0
  292. package/dist/assets/Icons/mailgun.svg +1 -0
  293. package/dist/assets/Icons/mailjet-neutral.svg +1 -0
  294. package/dist/assets/Icons/mailjet.svg +1 -0
  295. package/dist/assets/Icons/mails.svg +1 -0
  296. package/dist/assets/Icons/mailtrap-neutral.svg +1 -0
  297. package/dist/assets/Icons/mailtrap.svg +1 -0
  298. package/dist/assets/Icons/mandrill-neutral.svg +1 -0
  299. package/dist/assets/Icons/mandrill.svg +1 -0
  300. package/dist/assets/Icons/map-pin.svg +1 -0
  301. package/dist/assets/Icons/maqsam-neutral.svg +1 -0
  302. package/dist/assets/Icons/maqsam.svg +1 -0
  303. package/dist/assets/Icons/mattermost-neutral.svg +1 -0
  304. package/dist/assets/Icons/mattermost.svg +1 -0
  305. package/dist/assets/Icons/maximize.svg +1 -0
  306. package/dist/assets/Icons/maximize2.svg +1 -0
  307. package/dist/assets/Icons/medium-neutral.svg +1 -0
  308. package/dist/assets/Icons/medium.svg +1 -0
  309. package/dist/assets/Icons/megaphone-off.svg +1 -0
  310. package/dist/assets/Icons/megaphone.svg +1 -0
  311. package/dist/assets/Icons/menu.svg +1 -0
  312. package/dist/assets/Icons/merge.svg +1 -0
  313. package/dist/assets/Icons/message-square-code.svg +1 -0
  314. package/dist/assets/Icons/message-square-dashed.svg +1 -0
  315. package/dist/assets/Icons/message-square-diff.svg +1 -0
  316. package/dist/assets/Icons/message-square-dot.svg +1 -0
  317. package/dist/assets/Icons/message-square-heart.svg +1 -0
  318. package/dist/assets/Icons/message-square-off.svg +1 -0
  319. package/dist/assets/Icons/message-square-plus.svg +1 -0
  320. package/dist/assets/Icons/message-square-quote.svg +1 -0
  321. package/dist/assets/Icons/message-square-reply.svg +1 -0
  322. package/dist/assets/Icons/message-square-share.svg +1 -0
  323. package/dist/assets/Icons/message-square-text.svg +1 -0
  324. package/dist/assets/Icons/message-square-warning.svg +1 -0
  325. package/dist/assets/Icons/message-square-x.svg +1 -0
  326. package/dist/assets/Icons/message-square.svg +1 -0
  327. package/dist/assets/Icons/messages-square.svg +1 -0
  328. package/dist/assets/Icons/messenger-neutral.svg +1 -0
  329. package/dist/assets/Icons/messenger.svg +1 -0
  330. package/dist/assets/Icons/microsoft-neutral.svg +1 -0
  331. package/dist/assets/Icons/microsoft-teams-neutral.svg +1 -0
  332. package/dist/assets/Icons/microsoft-teams.svg +1 -0
  333. package/dist/assets/Icons/microsoft.svg +1 -0
  334. package/dist/assets/Icons/minimize.svg +1 -0
  335. package/dist/assets/Icons/minimize2.svg +1 -0
  336. package/dist/assets/Icons/minus.svg +1 -0
  337. package/dist/assets/Icons/moon.svg +1 -0
  338. package/dist/assets/Icons/mouse-pointer-ban.svg +1 -0
  339. package/dist/assets/Icons/mouse-pointer-click.svg +1 -0
  340. package/dist/assets/Icons/mouse-pointer.svg +1 -0
  341. package/dist/assets/Icons/mouse-pointer2.svg +1 -0
  342. package/dist/assets/Icons/mouse.svg +1 -0
  343. package/dist/assets/Icons/move-diagonal.svg +1 -0
  344. package/dist/assets/Icons/move-diagonal2.svg +1 -0
  345. package/dist/assets/Icons/move-down-left.svg +1 -0
  346. package/dist/assets/Icons/move-down-right.svg +1 -0
  347. package/dist/assets/Icons/move-down.svg +1 -0
  348. package/dist/assets/Icons/move-horizontal.svg +1 -0
  349. package/dist/assets/Icons/move-left.svg +1 -0
  350. package/dist/assets/Icons/move-right.svg +1 -0
  351. package/dist/assets/Icons/move-up-left.svg +1 -0
  352. package/dist/assets/Icons/move-up-right.svg +1 -0
  353. package/dist/assets/Icons/move-up.svg +1 -0
  354. package/dist/assets/Icons/move-vertical.svg +1 -0
  355. package/dist/assets/Icons/move3-d.svg +1 -0
  356. package/dist/assets/Icons/netcore-neutral.svg +1 -0
  357. package/dist/assets/Icons/netcore.svg +1 -0
  358. package/dist/assets/Icons/notebook-pen.svg +1 -0
  359. package/dist/assets/Icons/notebook-tabs.svg +1 -0
  360. package/dist/assets/Icons/notebook-text.svg +1 -0
  361. package/dist/assets/Icons/notebook.svg +1 -0
  362. package/dist/assets/Icons/notepad-text-dashed.svg +1 -0
  363. package/dist/assets/Icons/notepad-text.svg +1 -0
  364. package/dist/assets/Icons/notion-neutral.svg +1 -0
  365. package/dist/assets/Icons/notion.svg +1 -0
  366. package/dist/assets/Icons/octagon-alert.svg +1 -0
  367. package/dist/assets/Icons/octagon-pause.svg +1 -0
  368. package/dist/assets/Icons/octagon-x.svg +1 -0
  369. package/dist/assets/Icons/octagon.svg +1 -0
  370. package/dist/assets/Icons/ok-neutral.svg +1 -0
  371. package/dist/assets/Icons/ok-only-sign-neutral.svg +1 -0
  372. package/dist/assets/Icons/ok-only-sign.svg +1 -0
  373. package/dist/assets/Icons/ok.svg +1 -0
  374. package/dist/assets/Icons/onlyfans-neutral.svg +1 -0
  375. package/dist/assets/Icons/onlyfans.svg +1 -0
  376. package/dist/assets/Icons/option.svg +1 -0
  377. package/dist/assets/Icons/outlook365-neutral.svg +1 -0
  378. package/dist/assets/Icons/outlook365.svg +1 -0
  379. package/dist/assets/Icons/paintbrush.svg +1 -0
  380. package/dist/assets/Icons/panel-bottom-open.svg +1 -0
  381. package/dist/assets/Icons/panel-bottom.svg +1 -0
  382. package/dist/assets/Icons/panel-left-close.svg +1 -0
  383. package/dist/assets/Icons/panel-left-dashed.svg +1 -0
  384. package/dist/assets/Icons/panel-left-open.svg +1 -0
  385. package/dist/assets/Icons/panel-left.svg +1 -0
  386. package/dist/assets/Icons/panel-right-animated.svg +1 -0
  387. package/dist/assets/Icons/panel-right-close.svg +1 -0
  388. package/dist/assets/Icons/panel-right-dashed.svg +1 -0
  389. package/dist/assets/Icons/panel-right-open.svg +1 -0
  390. package/dist/assets/Icons/panel-right.svg +1 -0
  391. package/dist/assets/Icons/panel-top-bottom-dashed.svg +1 -0
  392. package/dist/assets/Icons/panel-top-close.svg +1 -0
  393. package/dist/assets/Icons/panel-top-open.svg +1 -0
  394. package/dist/assets/Icons/panel-top.svg +1 -0
  395. package/dist/assets/Icons/panels-left-bottom.svg +1 -0
  396. package/dist/assets/Icons/panels-right-bottom.svg +1 -0
  397. package/dist/assets/Icons/panels-top-left.svg +1 -0
  398. package/dist/assets/Icons/paperclip.svg +1 -0
  399. package/dist/assets/Icons/patreon-neutral.svg +1 -0
  400. package/dist/assets/Icons/patreon.svg +1 -0
  401. package/dist/assets/Icons/paypal-neutral.svg +1 -0
  402. package/dist/assets/Icons/paypal.svg +1 -0
  403. package/dist/assets/Icons/pen-line.svg +1 -0
  404. package/dist/assets/Icons/pen-off.svg +1 -0
  405. package/dist/assets/Icons/pen-tool.svg +1 -0
  406. package/dist/assets/Icons/pen.svg +1 -0
  407. package/dist/assets/Icons/pencil-line.svg +1 -0
  408. package/dist/assets/Icons/pencil-off.svg +1 -0
  409. package/dist/assets/Icons/pencil-ruler.svg +1 -0
  410. package/dist/assets/Icons/pencil.svg +1 -0
  411. package/dist/assets/Icons/pentagon.svg +1 -0
  412. package/dist/assets/Icons/percentage.svg +1 -0
  413. package/dist/assets/Icons/phone.svg +1 -0
  414. package/dist/assets/Icons/pin-off.svg +1 -0
  415. package/dist/assets/Icons/pin.svg +1 -0
  416. package/dist/assets/Icons/pinterest-neutral.svg +1 -0
  417. package/dist/assets/Icons/pinterest.svg +1 -0
  418. package/dist/assets/Icons/play.svg +1 -0
  419. package/dist/assets/Icons/plug.svg +1 -0
  420. package/dist/assets/Icons/plunk-neutral.svg +1 -0
  421. package/dist/assets/Icons/plunk.svg +1 -0
  422. package/dist/assets/Icons/plus.svg +1 -0
  423. package/dist/assets/Icons/postmark-neutral.svg +1 -0
  424. package/dist/assets/Icons/postmark.svg +1 -0
  425. package/dist/assets/Icons/product-hunt-neutral.svg +1 -0
  426. package/dist/assets/Icons/product-hunt.svg +1 -0
  427. package/dist/assets/Icons/quora-neutral.svg +1 -0
  428. package/dist/assets/Icons/quora.svg +1 -0
  429. package/dist/assets/Icons/quote.svg +1 -0
  430. package/dist/assets/Icons/radar.svg +1 -0
  431. package/dist/assets/Icons/reddit-neutral.svg +1 -0
  432. package/dist/assets/Icons/reddit.svg +1 -0
  433. package/dist/assets/Icons/redo-dot.svg +1 -0
  434. package/dist/assets/Icons/redo.svg +1 -0
  435. package/dist/assets/Icons/redo2.svg +1 -0
  436. package/dist/assets/Icons/refresh-ccw.svg +1 -0
  437. package/dist/assets/Icons/refresh-cw-off.svg +1 -0
  438. package/dist/assets/Icons/resend-neutral.svg +1 -0
  439. package/dist/assets/Icons/resend.svg +1 -0
  440. package/dist/assets/Icons/rss.svg +1 -0
  441. package/dist/assets/Icons/rules.svg +1 -0
  442. package/dist/assets/Icons/scan-line.svg +1 -0
  443. package/dist/assets/Icons/scroll-text.svg +1 -0
  444. package/dist/assets/Icons/search-hint.svg +1 -0
  445. package/dist/assets/Icons/search-x.svg +1 -0
  446. package/dist/assets/Icons/search.svg +1 -0
  447. package/dist/assets/Icons/sendgrid-neutral.svg +1 -0
  448. package/dist/assets/Icons/sendgrid.svg +1 -0
  449. package/dist/assets/Icons/server.svg +1 -0
  450. package/dist/assets/Icons/ses-neutral.svg +1 -0
  451. package/dist/assets/Icons/ses.svg +1 -0
  452. package/dist/assets/Icons/settings.svg +1 -0
  453. package/dist/assets/Icons/settings2.svg +1 -0
  454. package/dist/assets/Icons/shapes.svg +1 -0
  455. package/dist/assets/Icons/share.svg +1 -0
  456. package/dist/assets/Icons/sheet.svg +1 -0
  457. package/dist/assets/Icons/shield-alert.svg +1 -0
  458. package/dist/assets/Icons/shield-ban.svg +1 -0
  459. package/dist/assets/Icons/shield-check.svg +1 -0
  460. package/dist/assets/Icons/shield-ellipsis.svg +1 -0
  461. package/dist/assets/Icons/shield-half.svg +1 -0
  462. package/dist/assets/Icons/shield-minus.svg +1 -0
  463. package/dist/assets/Icons/shield-off.svg +1 -0
  464. package/dist/assets/Icons/shield-plus.svg +1 -0
  465. package/dist/assets/Icons/shield-question.svg +1 -0
  466. package/dist/assets/Icons/shield-user.svg +1 -0
  467. package/dist/assets/Icons/shield-x.svg +1 -0
  468. package/dist/assets/Icons/shield.svg +1 -0
  469. package/dist/assets/Icons/shift.svg +1 -0
  470. package/dist/assets/Icons/signal-neutral.svg +1 -0
  471. package/dist/assets/Icons/signal.svg +1 -0
  472. package/dist/assets/Icons/signpost.svg +1 -0
  473. package/dist/assets/Icons/sina-weibo-neutral.svg +1 -0
  474. package/dist/assets/Icons/sina-weibo.svg +1 -0
  475. package/dist/assets/Icons/skull.svg +1 -0
  476. package/dist/assets/Icons/skype-neutral.svg +1 -0
  477. package/dist/assets/Icons/skype.svg +1 -0
  478. package/dist/assets/Icons/slack-neutral.svg +1 -0
  479. package/dist/assets/Icons/slack.svg +1 -0
  480. package/dist/assets/Icons/sliders-horizontal.svg +1 -0
  481. package/dist/assets/Icons/sliders-vertical.svg +1 -0
  482. package/dist/assets/Icons/smtp-neutral.svg +1 -0
  483. package/dist/assets/Icons/smtp.svg +1 -0
  484. package/dist/assets/Icons/snapchat-neutral.svg +1 -0
  485. package/dist/assets/Icons/snapchat.svg +1 -0
  486. package/dist/assets/Icons/soundcloud-neutral.svg +1 -0
  487. package/dist/assets/Icons/soundcloud.svg +1 -0
  488. package/dist/assets/Icons/space.svg +1 -0
  489. package/dist/assets/Icons/sparkpost-neutral.svg +1 -0
  490. package/dist/assets/Icons/sparkpost.svg +1 -0
  491. package/dist/assets/Icons/speed.svg +1 -0
  492. package/dist/assets/Icons/split.svg +1 -0
  493. package/dist/assets/Icons/spotify-neutral.svg +1 -0
  494. package/dist/assets/Icons/spotify.svg +1 -0
  495. package/dist/assets/Icons/square-arrow-out-up-right.svg +1 -0
  496. package/dist/assets/Icons/square-minus.svg +1 -0
  497. package/dist/assets/Icons/square-pen.svg +1 -0
  498. package/dist/assets/Icons/square-plus.svg +1 -0
  499. package/dist/assets/Icons/square-user-round.svg +1 -0
  500. package/dist/assets/Icons/stack-overflow-neutral.svg +1 -0
  501. package/dist/assets/Icons/stack-overflow.svg +1 -0
  502. package/dist/assets/Icons/star.svg +1 -0
  503. package/dist/assets/Icons/sun.svg +1 -0
  504. package/dist/assets/Icons/syringe.svg +1 -0
  505. package/dist/assets/Icons/tag.svg +1 -0
  506. package/dist/assets/Icons/target.svg +1 -0
  507. package/dist/assets/Icons/teams-neutral.svg +1 -0
  508. package/dist/assets/Icons/teams.svg +1 -0
  509. package/dist/assets/Icons/telegram-neutral.svg +1 -0
  510. package/dist/assets/Icons/telegram-only-sign-neutral.svg +1 -0
  511. package/dist/assets/Icons/telegram-only-sign.svg +1 -0
  512. package/dist/assets/Icons/telegram.svg +1 -0
  513. package/dist/assets/Icons/terminal.svg +1 -0
  514. package/dist/assets/Icons/test-policies.svg +1 -0
  515. package/dist/assets/Icons/threads-neutral.svg +1 -0
  516. package/dist/assets/Icons/threads.svg +1 -0
  517. package/dist/assets/Icons/thumbs-down.svg +1 -0
  518. package/dist/assets/Icons/thumbs-up.svg +1 -0
  519. package/dist/assets/Icons/tiktok-neutral.svg +1 -0
  520. package/dist/assets/Icons/tiktok.svg +1 -0
  521. package/dist/assets/Icons/tinder-neutral.svg +1 -0
  522. package/dist/assets/Icons/tinder.svg +1 -0
  523. package/dist/assets/Icons/trash.svg +1 -0
  524. package/dist/assets/Icons/trash2.svg +1 -0
  525. package/dist/assets/Icons/triangle-alert.svg +1 -0
  526. package/dist/assets/Icons/tumblr-neutral.svg +1 -0
  527. package/dist/assets/Icons/tumblr.svg +1 -0
  528. package/dist/assets/Icons/twitch-neutral.svg +1 -0
  529. package/dist/assets/Icons/twitch.svg +1 -0
  530. package/dist/assets/Icons/undo-dot.svg +1 -0
  531. package/dist/assets/Icons/undo.svg +1 -0
  532. package/dist/assets/Icons/undo2.svg +1 -0
  533. package/dist/assets/Icons/unplug.svg +1 -0
  534. package/dist/assets/Icons/user-check.svg +1 -0
  535. package/dist/assets/Icons/user-minus.svg +1 -0
  536. package/dist/assets/Icons/user-plus.svg +1 -0
  537. package/dist/assets/Icons/user-round-x.svg +1 -0
  538. package/dist/assets/Icons/user-round.svg +1 -0
  539. package/dist/assets/Icons/user.svg +1 -0
  540. package/dist/assets/Icons/username.svg +1 -0
  541. package/dist/assets/Icons/users-round.svg +1 -0
  542. package/dist/assets/Icons/users.svg +1 -0
  543. package/dist/assets/Icons/viber-neutral.svg +1 -0
  544. package/dist/assets/Icons/viber.svg +1 -0
  545. package/dist/assets/Icons/video.svg +1 -0
  546. package/dist/assets/Icons/vimeo-neutral.svg +1 -0
  547. package/dist/assets/Icons/vimeo.svg +1 -0
  548. package/dist/assets/Icons/vk-music-neutral.svg +1 -0
  549. package/dist/assets/Icons/vk-music.svg +1 -0
  550. package/dist/assets/Icons/vk-neutral.svg +1 -0
  551. package/dist/assets/Icons/vk-only-sign-neutral.svg +1 -0
  552. package/dist/assets/Icons/vk-only-sign.svg +1 -0
  553. package/dist/assets/Icons/vk.svg +1 -0
  554. package/dist/assets/Icons/webhook-neutral.svg +1 -0
  555. package/dist/assets/Icons/webhook.svg +1 -0
  556. package/dist/assets/Icons/wechat-neutral.svg +1 -0
  557. package/dist/assets/Icons/wechat.svg +1 -0
  558. package/dist/assets/Icons/whatsapp-badge-neutral.svg +1 -0
  559. package/dist/assets/Icons/whatsapp-badge.svg +1 -0
  560. package/dist/assets/Icons/whatsapp-neutral.svg +1 -0
  561. package/dist/assets/Icons/whatsapp.svg +1 -0
  562. package/dist/assets/Icons/workflow.svg +1 -0
  563. package/dist/assets/Icons/wrap-text.svg +1 -0
  564. package/dist/assets/Icons/wrench.svg +1 -0
  565. package/dist/assets/Icons/x-ex-twitter-neutral.svg +1 -0
  566. package/dist/assets/Icons/x-ex-twitter.svg +1 -0
  567. package/dist/assets/Icons/x.svg +1 -0
  568. package/dist/assets/Icons/xing-neutral.svg +1 -0
  569. package/dist/assets/Icons/xing.svg +1 -0
  570. package/dist/assets/Icons/yandex-music-neutral.svg +1 -0
  571. package/dist/assets/Icons/yandex-music.svg +1 -0
  572. package/dist/assets/Icons/yelp-neutral.svg +1 -0
  573. package/dist/assets/Icons/yelp.svg +1 -0
  574. package/dist/assets/Icons/youtube-music-neutral.svg +1 -0
  575. package/dist/assets/Icons/youtube-music.svg +1 -0
  576. package/dist/assets/Icons/youtube-neutral.svg +1 -0
  577. package/dist/assets/Icons/youtube-shorts-neutral.svg +1 -0
  578. package/dist/assets/Icons/youtube-shorts.svg +1 -0
  579. package/dist/assets/Icons/youtube.svg +1 -0
  580. package/dist/assets/Icons/zap.svg +1 -0
  581. package/dist/assets/Icons/zoom-in.svg +1 -0
  582. package/dist/assets/Icons/zoom-neutral.svg +1 -0
  583. package/dist/assets/Icons/zoom-out.svg +1 -0
  584. package/dist/assets/Icons/zoom.svg +1 -0
  585. package/dist/assets/Icons/zulip-neutral.svg +1 -0
  586. package/dist/assets/Icons/zulip.svg +1 -0
  587. package/dist/assets/Logos/wallarm.svg +1 -0
  588. package/dist/assets.json +4666 -0
  589. package/dist/project/README.md +265 -0
  590. package/dist/project/components/Accordion/README.md +354 -0
  591. package/dist/project/components/Accordion/preview.html +2 -0
  592. package/dist/project/components/Accordion/stories.js +12 -0
  593. package/dist/project/components/AgentAvatar/README.md +127 -0
  594. package/dist/project/components/AgentAvatar/preview.html +2 -0
  595. package/dist/project/components/AgentAvatar/stories.js +12 -0
  596. package/dist/project/components/AgentAvatar/stories.md +1805 -0
  597. package/dist/project/components/AgentGlyph/README.md +1182 -0
  598. package/dist/project/components/AgentGlyph/preview.html +2 -0
  599. package/dist/project/components/AgentGlyph/stories.js +12 -0
  600. package/dist/project/components/AgentLookBuilder/README.md +269 -0
  601. package/dist/project/components/AgentLookBuilder/preview.html +2 -0
  602. package/dist/project/components/AgentLookBuilder/stories.js +12 -0
  603. package/dist/project/components/Alert/README.md +492 -0
  604. package/dist/project/components/Alert/preview.html +2 -0
  605. package/dist/project/components/Alert/stories.js +12 -0
  606. package/dist/project/components/AnimatedBackground/README.md +124 -0
  607. package/dist/project/components/AnimatedBackground/preview.html +2 -0
  608. package/dist/project/components/AnimatedBackground/stories.js +12 -0
  609. package/dist/project/components/AppShell/README.md +75 -0
  610. package/dist/project/components/AppShell/preview.html +2 -0
  611. package/dist/project/components/AppShell/stories.js +28 -0
  612. package/dist/project/components/AppShell/stories.md +2878 -0
  613. package/dist/project/components/ApprovalCard/README.md +353 -0
  614. package/dist/project/components/ApprovalCard/preview.html +2 -0
  615. package/dist/project/components/ApprovalCard/stories.js +12 -0
  616. package/dist/project/components/AreaChart/README.md +673 -0
  617. package/dist/project/components/AreaChart/preview.html +2 -0
  618. package/dist/project/components/AreaChart/stories.js +12 -0
  619. package/dist/project/components/AssistantMessage/README.md +724 -0
  620. package/dist/project/components/AssistantMessage/preview.html +2 -0
  621. package/dist/project/components/AssistantMessage/stories.js +55 -0
  622. package/dist/project/components/Attribute/README.md +1174 -0
  623. package/dist/project/components/Attribute/preview.html +2 -0
  624. package/dist/project/components/Attribute/stories.js +12 -0
  625. package/dist/project/components/Avatar/README.md +416 -0
  626. package/dist/project/components/Avatar/preview.html +2 -0
  627. package/dist/project/components/Avatar/stories.js +12 -0
  628. package/dist/project/components/Badge/README.md +853 -0
  629. package/dist/project/components/Badge/preview.html +2 -0
  630. package/dist/project/components/Badge/stories.js +12 -0
  631. package/dist/project/components/Banner/README.md +341 -0
  632. package/dist/project/components/Banner/preview.html +2 -0
  633. package/dist/project/components/Banner/stories.js +12 -0
  634. package/dist/project/components/BarList/README.md +757 -0
  635. package/dist/project/components/BarList/preview.html +2 -0
  636. package/dist/project/components/BarList/stories.js +12 -0
  637. package/dist/project/components/Breadcrumbs/README.md +274 -0
  638. package/dist/project/components/Breadcrumbs/preview.html +2 -0
  639. package/dist/project/components/Breadcrumbs/stories.js +12 -0
  640. package/dist/project/components/BulkBar/README.md +19 -0
  641. package/dist/project/components/Button/README.md +467 -0
  642. package/dist/project/components/Button/preview.html +2 -0
  643. package/dist/project/components/Button/stories.js +12 -0
  644. package/dist/project/components/Calendar/README.md +654 -0
  645. package/dist/project/components/Calendar/preview.html +2 -0
  646. package/dist/project/components/Calendar/stories.js +12 -0
  647. package/dist/project/components/Card/README.md +367 -0
  648. package/dist/project/components/Card/preview.html +2 -0
  649. package/dist/project/components/Card/stories.js +12 -0
  650. package/dist/project/components/ChainOfThought/README.md +412 -0
  651. package/dist/project/components/ChainOfThought/preview.html +2 -0
  652. package/dist/project/components/ChainOfThought/stories.js +12 -0
  653. package/dist/project/components/Chart/README.md +224 -0
  654. package/dist/project/components/Chart/preview.html +2 -0
  655. package/dist/project/components/Chart/stories.js +12 -0
  656. package/dist/project/components/Chat/README.md +1244 -0
  657. package/dist/project/components/Chat/preview.html +2 -0
  658. package/dist/project/components/Chat/stories.js +12 -0
  659. package/dist/project/components/ChatInput/README.md +378 -0
  660. package/dist/project/components/ChatInput/preview.html +2 -0
  661. package/dist/project/components/ChatInput/stories.js +12 -0
  662. package/dist/project/components/ChatPermissions/README.md +218 -0
  663. package/dist/project/components/ChatPermissions/preview.html +2 -0
  664. package/dist/project/components/ChatPermissions/stories.js +12 -0
  665. package/dist/project/components/Checkbox/README.md +367 -0
  666. package/dist/project/components/Checkbox/preview.html +2 -0
  667. package/dist/project/components/Checkbox/stories.js +12 -0
  668. package/dist/project/components/Code/README.md +243 -0
  669. package/dist/project/components/Code/preview.html +2 -0
  670. package/dist/project/components/Code/stories.js +12 -0
  671. package/dist/project/components/CodeEditor/README.md +280 -0
  672. package/dist/project/components/CodeEditor/preview.html +2 -0
  673. package/dist/project/components/CodeEditor/stories.js +162 -0
  674. package/dist/project/components/CodeEditor/stories.md +1533 -0
  675. package/dist/project/components/CodeSnippet/README.md +1352 -0
  676. package/dist/project/components/CodeSnippet/preview.html +2 -0
  677. package/dist/project/components/CodeSnippet/stories.js +156 -0
  678. package/dist/project/components/ColumnChart/README.md +521 -0
  679. package/dist/project/components/ColumnChart/preview.html +2 -0
  680. package/dist/project/components/ColumnChart/stories.js +12 -0
  681. package/dist/project/components/Conversation/README.md +314 -0
  682. package/dist/project/components/Conversation/preview.html +2 -0
  683. package/dist/project/components/Conversation/stories.js +12 -0
  684. package/dist/project/components/Copyable/README.md +406 -0
  685. package/dist/project/components/Copyable/preview.html +2 -0
  686. package/dist/project/components/Copyable/stories.js +12 -0
  687. package/dist/project/components/Country/README.md +226 -0
  688. package/dist/project/components/Country/preview.html +2 -0
  689. package/dist/project/components/Country/stories.js +12 -0
  690. package/dist/project/components/Cover/preview.html +43 -0
  691. package/dist/project/components/DateInput/README.md +458 -0
  692. package/dist/project/components/DateInput/preview.html +2 -0
  693. package/dist/project/components/DateInput/stories.js +12 -0
  694. package/dist/project/components/DateRangeInput/README.md +412 -0
  695. package/dist/project/components/DateRangeInput/preview.html +2 -0
  696. package/dist/project/components/DateRangeInput/stories.js +12 -0
  697. package/dist/project/components/Dialog/README.md +1140 -0
  698. package/dist/project/components/Dialog/preview.html +2 -0
  699. package/dist/project/components/Dialog/stories.js +12 -0
  700. package/dist/project/components/Drawer/README.md +1163 -0
  701. package/dist/project/components/Drawer/preview.html +2 -0
  702. package/dist/project/components/Drawer/stories.js +12 -0
  703. package/dist/project/components/DropdownMenu/README.md +678 -0
  704. package/dist/project/components/DropdownMenu/preview.html +2 -0
  705. package/dist/project/components/DropdownMenu/stories.js +12 -0
  706. package/dist/project/components/EmptyState/README.md +276 -0
  707. package/dist/project/components/EmptyState/preview.html +2 -0
  708. package/dist/project/components/EmptyState/stories.js +12 -0
  709. package/dist/project/components/FeedbackPulse/README.md +125 -0
  710. package/dist/project/components/FeedbackPulse/preview.html +2 -0
  711. package/dist/project/components/FeedbackPulse/stories.js +12 -0
  712. package/dist/project/components/Field/README.md +676 -0
  713. package/dist/project/components/Field/preview.html +2 -0
  714. package/dist/project/components/Field/stories.js +12 -0
  715. package/dist/project/components/FileUpload/README.md +544 -0
  716. package/dist/project/components/FileUpload/preview.html +2 -0
  717. package/dist/project/components/FileUpload/stories.js +12 -0
  718. package/dist/project/components/FilterCascade/README.md +348 -0
  719. package/dist/project/components/FilterCascade/preview.html +2 -0
  720. package/dist/project/components/FilterCascade/stories.js +12 -0
  721. package/dist/project/components/FilterDropdown/README.md +542 -0
  722. package/dist/project/components/FilterDropdown/preview.html +2 -0
  723. package/dist/project/components/FilterDropdown/stories.js +12 -0
  724. package/dist/project/components/FilterInput/README.md +416 -0
  725. package/dist/project/components/FilterInput/preview.html +2 -0
  726. package/dist/project/components/FilterInput/stories.js +12 -0
  727. package/dist/project/components/FilterInput/stories.md +6682 -0
  728. package/dist/project/components/Flex/README.md +225 -0
  729. package/dist/project/components/Flex/preview.html +2 -0
  730. package/dist/project/components/Flex/stories.js +12 -0
  731. package/dist/project/components/FormatDateTime/README.md +315 -0
  732. package/dist/project/components/FormatDateTime/preview.html +2 -0
  733. package/dist/project/components/FormatDateTime/stories.js +12 -0
  734. package/dist/project/components/FormatNumber/README.md +317 -0
  735. package/dist/project/components/FormatNumber/preview.html +2 -0
  736. package/dist/project/components/FormatNumber/stories.js +12 -0
  737. package/dist/project/components/Heading/README.md +240 -0
  738. package/dist/project/components/Heading/preview.html +2 -0
  739. package/dist/project/components/Heading/stories.js +12 -0
  740. package/dist/project/components/HorizontalBarStack/README.md +281 -0
  741. package/dist/project/components/HorizontalBarStack/preview.html +2 -0
  742. package/dist/project/components/HorizontalBarStack/stories.js +12 -0
  743. package/dist/project/components/HttpMethod/README.md +137 -0
  744. package/dist/project/components/HttpMethod/preview.html +2 -0
  745. package/dist/project/components/HttpMethod/stories.js +12 -0
  746. package/dist/project/components/ImageCropper/README.md +332 -0
  747. package/dist/project/components/ImageCropper/preview.html +2 -0
  748. package/dist/project/components/ImageCropper/stories.js +33 -0
  749. package/dist/project/components/Indicator/README.md +110 -0
  750. package/dist/project/components/Indicator/preview.html +2 -0
  751. package/dist/project/components/Indicator/stories.js +12 -0
  752. package/dist/project/components/InlineEdit/README.md +977 -0
  753. package/dist/project/components/InlineEdit/preview.html +2 -0
  754. package/dist/project/components/InlineEdit/stories.js +12 -0
  755. package/dist/project/components/Input/README.md +187 -0
  756. package/dist/project/components/Input/preview.html +2 -0
  757. package/dist/project/components/Input/stories.js +12 -0
  758. package/dist/project/components/InputGroup/README.md +423 -0
  759. package/dist/project/components/InputGroup/preview.html +2 -0
  760. package/dist/project/components/InputGroup/stories.js +12 -0
  761. package/dist/project/components/InputOTP/README.md +201 -0
  762. package/dist/project/components/InputOTP/preview.html +2 -0
  763. package/dist/project/components/InputOTP/stories.js +12 -0
  764. package/dist/project/components/Ip/README.md +226 -0
  765. package/dist/project/components/Ip/preview.html +2 -0
  766. package/dist/project/components/Ip/stories.js +12 -0
  767. package/dist/project/components/Kbd/README.md +126 -0
  768. package/dist/project/components/Kbd/preview.html +2 -0
  769. package/dist/project/components/Kbd/stories.js +12 -0
  770. package/dist/project/components/LineChart/README.md +1479 -0
  771. package/dist/project/components/LineChart/preview.html +2 -0
  772. package/dist/project/components/LineChart/stories.js +12 -0
  773. package/dist/project/components/Link/README.md +160 -0
  774. package/dist/project/components/Link/preview.html +2 -0
  775. package/dist/project/components/Link/stories.js +12 -0
  776. package/dist/project/components/List/README.md +181 -0
  777. package/dist/project/components/List/preview.html +2 -0
  778. package/dist/project/components/List/stories.js +12 -0
  779. package/dist/project/components/Loader/README.md +145 -0
  780. package/dist/project/components/Loader/preview.html +2 -0
  781. package/dist/project/components/Loader/stories.js +12 -0
  782. package/dist/project/components/Logo/README.md +183 -0
  783. package/dist/project/components/Logo/preview.html +2 -0
  784. package/dist/project/components/Logo/stories.js +12 -0
  785. package/dist/project/components/MessageActions/README.md +255 -0
  786. package/dist/project/components/MessageActions/preview.html +2 -0
  787. package/dist/project/components/MessageActions/stories.js +12 -0
  788. package/dist/project/components/Metric/README.md +324 -0
  789. package/dist/project/components/Metric/preview.html +2 -0
  790. package/dist/project/components/Metric/stories.js +12 -0
  791. package/dist/project/components/NavRail/README.md +25 -0
  792. package/dist/project/components/NotificationCenter/README.md +91 -0
  793. package/dist/project/components/NotificationCenter/preview.html +2 -0
  794. package/dist/project/components/NotificationCenter/stories.js +12 -0
  795. package/dist/project/components/NotificationCenter/stories.md +2170 -0
  796. package/dist/project/components/NumberInput/README.md +177 -0
  797. package/dist/project/components/NumberInput/preview.html +2 -0
  798. package/dist/project/components/NumberInput/stories.js +12 -0
  799. package/dist/project/components/NumericBadge/README.md +252 -0
  800. package/dist/project/components/NumericBadge/preview.html +2 -0
  801. package/dist/project/components/NumericBadge/stories.js +12 -0
  802. package/dist/project/components/OverflowList/README.md +324 -0
  803. package/dist/project/components/OverflowList/preview.html +2 -0
  804. package/dist/project/components/OverflowList/stories.js +12 -0
  805. package/dist/project/components/OverflowTooltip/README.md +421 -0
  806. package/dist/project/components/OverflowTooltip/preview.html +2 -0
  807. package/dist/project/components/OverflowTooltip/stories.js +12 -0
  808. package/dist/project/components/Overlay/README.md +95 -0
  809. package/dist/project/components/Overlay/preview.html +2 -0
  810. package/dist/project/components/Overlay/stories.js +12 -0
  811. package/dist/project/components/Overview/README.md +445 -0
  812. package/dist/project/components/Overview/preview.html +2 -0
  813. package/dist/project/components/Overview/stories.js +12 -0
  814. package/dist/project/components/Page/README.md +215 -0
  815. package/dist/project/components/Page/preview.html +2 -0
  816. package/dist/project/components/Page/stories.js +12 -0
  817. package/dist/project/components/Pagination/README.md +302 -0
  818. package/dist/project/components/Pagination/preview.html +2 -0
  819. package/dist/project/components/Pagination/stories.js +12 -0
  820. package/dist/project/components/ParameterPath/README.md +284 -0
  821. package/dist/project/components/ParameterPath/preview.html +2 -0
  822. package/dist/project/components/ParameterPath/stories.js +12 -0
  823. package/dist/project/components/PasswordComplexity/README.md +171 -0
  824. package/dist/project/components/PasswordComplexity/preview.html +2 -0
  825. package/dist/project/components/PasswordComplexity/stories.js +12 -0
  826. package/dist/project/components/PasswordInput/README.md +254 -0
  827. package/dist/project/components/PasswordInput/preview.html +2 -0
  828. package/dist/project/components/PasswordInput/stories.js +12 -0
  829. package/dist/project/components/PieChart/README.md +895 -0
  830. package/dist/project/components/PieChart/preview.html +2 -0
  831. package/dist/project/components/PieChart/stories.js +12 -0
  832. package/dist/project/components/Popover/README.md +282 -0
  833. package/dist/project/components/Popover/preview.html +2 -0
  834. package/dist/project/components/Popover/stories.js +12 -0
  835. package/dist/project/components/Progress/README.md +174 -0
  836. package/dist/project/components/Progress/preview.html +2 -0
  837. package/dist/project/components/Progress/stories.js +12 -0
  838. package/dist/project/components/Radio/README.md +264 -0
  839. package/dist/project/components/Radio/preview.html +2 -0
  840. package/dist/project/components/Radio/stories.js +12 -0
  841. package/dist/project/components/RemoteShell/README.md +1758 -0
  842. package/dist/project/components/RemoteShell/preview.html +2 -0
  843. package/dist/project/components/RemoteShell/stories.js +28 -0
  844. package/dist/project/components/Resizable/README.md +290 -0
  845. package/dist/project/components/Resizable/preview.html +2 -0
  846. package/dist/project/components/Resizable/stories.js +12 -0
  847. package/dist/project/components/ResponseCode/README.md +205 -0
  848. package/dist/project/components/ResponseCode/preview.html +2 -0
  849. package/dist/project/components/ResponseCode/stories.js +12 -0
  850. package/dist/project/components/ScrollArea/README.md +234 -0
  851. package/dist/project/components/ScrollArea/preview.html +2 -0
  852. package/dist/project/components/ScrollArea/stories.js +12 -0
  853. package/dist/project/components/SearchInput/README.md +158 -0
  854. package/dist/project/components/SearchInput/preview.html +2 -0
  855. package/dist/project/components/SearchInput/stories.js +12 -0
  856. package/dist/project/components/SearchModal/README.md +836 -0
  857. package/dist/project/components/SearchModal/preview.html +2 -0
  858. package/dist/project/components/SearchModal/stories.js +12 -0
  859. package/dist/project/components/SegmentedControl/README.md +382 -0
  860. package/dist/project/components/SegmentedControl/preview.html +2 -0
  861. package/dist/project/components/SegmentedControl/stories.js +12 -0
  862. package/dist/project/components/SegmentedTabs/README.md +390 -0
  863. package/dist/project/components/SegmentedTabs/preview.html +2 -0
  864. package/dist/project/components/SegmentedTabs/stories.js +12 -0
  865. package/dist/project/components/Select/README.md +1311 -0
  866. package/dist/project/components/Select/preview.html +2 -0
  867. package/dist/project/components/Select/stories.js +12 -0
  868. package/dist/project/components/Selection/README.md +648 -0
  869. package/dist/project/components/Selection/preview.html +2 -0
  870. package/dist/project/components/Selection/stories.js +12 -0
  871. package/dist/project/components/Separator/README.md +77 -0
  872. package/dist/project/components/Separator/preview.html +2 -0
  873. package/dist/project/components/Separator/stories.js +12 -0
  874. package/dist/project/components/Skeleton/README.md +358 -0
  875. package/dist/project/components/Skeleton/preview.html +2 -0
  876. package/dist/project/components/Skeleton/stories.js +12 -0
  877. package/dist/project/components/Slider/README.md +433 -0
  878. package/dist/project/components/Slider/preview.html +2 -0
  879. package/dist/project/components/Slider/stories.js +12 -0
  880. package/dist/project/components/SplashScreen/README.md +192 -0
  881. package/dist/project/components/SplashScreen/preview.html +2 -0
  882. package/dist/project/components/SplashScreen/stories.js +12 -0
  883. package/dist/project/components/SplitButton/README.md +402 -0
  884. package/dist/project/components/SplitButton/preview.html +2 -0
  885. package/dist/project/components/SplitButton/stories.js +12 -0
  886. package/dist/project/components/Stack/README.md +269 -0
  887. package/dist/project/components/Stack/preview.html +2 -0
  888. package/dist/project/components/Stack/stories.js +12 -0
  889. package/dist/project/components/Stepper/README.md +682 -0
  890. package/dist/project/components/Stepper/preview.html +2 -0
  891. package/dist/project/components/Stepper/stories.js +12 -0
  892. package/dist/project/components/Switch/README.md +236 -0
  893. package/dist/project/components/Switch/preview.html +2 -0
  894. package/dist/project/components/Switch/stories.js +12 -0
  895. package/dist/project/components/Table/README.md +471 -0
  896. package/dist/project/components/Table/preview.html +2 -0
  897. package/dist/project/components/Table/stories.js +12 -0
  898. package/dist/project/components/Table/stories.md +3697 -0
  899. package/dist/project/components/Tabs/README.md +443 -0
  900. package/dist/project/components/Tabs/preview.html +2 -0
  901. package/dist/project/components/Tabs/stories.js +12 -0
  902. package/dist/project/components/Tag/README.md +324 -0
  903. package/dist/project/components/Tag/preview.html +2 -0
  904. package/dist/project/components/Tag/stories.js +12 -0
  905. package/dist/project/components/Text/README.md +200 -0
  906. package/dist/project/components/Text/preview.html +2 -0
  907. package/dist/project/components/Text/stories.js +12 -0
  908. package/dist/project/components/Textarea/README.md +273 -0
  909. package/dist/project/components/Textarea/preview.html +2 -0
  910. package/dist/project/components/Textarea/stories.js +12 -0
  911. package/dist/project/components/TimeInput/README.md +359 -0
  912. package/dist/project/components/TimeInput/preview.html +2 -0
  913. package/dist/project/components/TimeInput/stories.js +12 -0
  914. package/dist/project/components/Timeline/README.md +204 -0
  915. package/dist/project/components/Timeline/preview.html +2 -0
  916. package/dist/project/components/Timeline/stories.js +12 -0
  917. package/dist/project/components/Toast/README.md +718 -0
  918. package/dist/project/components/Toast/preview.html +2 -0
  919. package/dist/project/components/Toast/stories.js +12 -0
  920. package/dist/project/components/ToggleButton/README.md +292 -0
  921. package/dist/project/components/ToggleButton/preview.html +2 -0
  922. package/dist/project/components/ToggleButton/stories.js +12 -0
  923. package/dist/project/components/Tooltip/README.md +199 -0
  924. package/dist/project/components/Tooltip/preview.html +2 -0
  925. package/dist/project/components/Tooltip/stories.js +12 -0
  926. package/dist/project/components/TopHeader/README.md +21 -0
  927. package/dist/project/components/Tour/README.md +532 -0
  928. package/dist/project/components/Tour/preview.html +2 -0
  929. package/dist/project/components/Tour/stories.js +12 -0
  930. package/dist/project/components/Tree/README.md +450 -0
  931. package/dist/project/components/Tree/preview.html +2 -0
  932. package/dist/project/components/Tree/stories.js +12 -0
  933. package/dist/project/components/TreeView/README.md +531 -0
  934. package/dist/project/components/TreeView/preview.html +2 -0
  935. package/dist/project/components/TreeView/stories.js +12 -0
  936. package/dist/project/components/UTILITIES.md +647 -0
  937. package/dist/project/components/UserMessage/README.md +166 -0
  938. package/dist/project/components/UserMessage/preview.html +2 -0
  939. package/dist/project/components/UserMessage/stories.js +12 -0
  940. package/dist/project/components/UtilityPage/README.md +147 -0
  941. package/dist/project/components/UtilityPage/preview.html +2 -0
  942. package/dist/project/components/UtilityPage/stories.js +12 -0
  943. package/dist/project/components/WallyAssistant/README.md +1380 -0
  944. package/dist/project/components/WallyAssistant/preview.html +2 -0
  945. package/dist/project/components/WallyAssistant/stories.js +12 -0
  946. package/dist/project/components/WallyIcon/README.md +130 -0
  947. package/dist/project/components/WallyIcon/preview.html +2 -0
  948. package/dist/project/components/WallyIcon/stories.js +12 -0
  949. package/dist/project/components/WallySkeleton/README.md +96 -0
  950. package/dist/project/components/WallySkeleton/preview.html +2 -0
  951. package/dist/project/components/WallySkeleton/stories.js +12 -0
  952. package/dist/project/components/bundle.css +18734 -0
  953. package/dist/project/components/bundle.js +167 -0
  954. package/dist/project/components/index.d.ts +27226 -0
  955. package/dist/project/design-system.json +35 -0
  956. package/dist/project/fonts/Geist-Variable.woff2 +0 -0
  957. package/dist/project/fonts/GeistMono-Variable.woff2 +0 -0
  958. package/dist/project/fonts/GeistPixel-Square.woff2 +0 -0
  959. package/dist/project/sampler.dc.html +238 -0
  960. package/dist/project/tokens.css +1395 -0
  961. package/dist/project/tokens.json +5235 -0
  962. package/dist/wallarm-sampler.dc.html +239 -0
  963. package/package.json +67 -3
@@ -0,0 +1,1805 @@
1
+ # AgentAvatar story sources
2
+
3
+ ### AgentAvatar/AgentAvatar.stories.tsx
4
+
5
+ ```tsx
6
+ import { useEffect, useRef, useState } from 'react';
7
+ import type { Meta, StoryFn } from 'storybook-react-rsbuild';
8
+ import { CAST } from '../../lib/agent-characters/data.gen';
9
+ import { defaultLook } from '../../lib/agent-characters/look';
10
+ import { PLACES } from '../../lib/agent-characters/places';
11
+ import { Button } from '../Button';
12
+ import { HStack, VStack } from '../Stack';
13
+ import { Text } from '../Text';
14
+ import { AgentAvatar, type AgentAvatarProps, type AgentAvatarState } from './AgentAvatar';
15
+ import { AgentAvatarGroup } from './AgentAvatarGroup';
16
+ import { FrameMeter } from './stories/FrameMeter';
17
+ import { type AgentAvatarHandle, setAgentMotion, useAgentMotion } from './useCharacter';
18
+
19
+ const DESCRIPTION = [
20
+ 'The character of an AI agent from 40 px up: a soft felt body baked in the browser from its silhouette, a glass visor and two light eyes that carry its state, and the prop that tells its job. Below 40 px use `AgentGlyph`.',
21
+ 'The body is baked once per outline, colour and size, off the main thread, and cached; until a layer is ready its flat fill shows.',
22
+ 'With `live` the character moves as the reference does: it blinks, glances, breathes and, on duty, now and then plays with its prop or looks at its neighbours (at most two on the page at once). Hello and Done are beats played through `handleRef`; they play in full, then the character shows `state` again. Reduced motion, or `setAgentMotion(false)` for the user’s setting, shows every state’s static frame.',
23
+ 'Size, liveness and the contact shadow are set by the place the character sits in (Overview rows 40 px, headers and toasts 48, beside people 56, the team card and the drawer 72, the empty chat 120); only the drawer header, the empty chat and 96 px and up get the shadow. Next to the agent’s visible name the character is decorative; give it a `label` only when it stands alone.',
24
+ ].join(' ');
25
+
26
+ const STATES: AgentAvatarState[] = [
27
+ 'idle',
28
+ 'working',
29
+ 'needs',
30
+ 'failed',
31
+ 'off',
32
+ 'box',
33
+ 'invite',
34
+ 'hello',
35
+ 'done',
36
+ ];
37
+ const STATE_LABELS: Record<AgentAvatarState, string> = {
38
+ idle: 'On duty',
39
+ working: 'Working',
40
+ needs: 'Needs you',
41
+ failed: 'Failed',
42
+ off: 'Deactivated',
43
+ box: 'Not set up',
44
+ invite: 'Inviting',
45
+ hello: 'Hello',
46
+ done: 'Done',
47
+ };
48
+
49
+ const meta = {
50
+ title: 'AI/AgentAvatar',
51
+ component: AgentAvatar,
52
+ parameters: {
53
+ layout: 'centered',
54
+ docs: { description: { component: DESCRIPTION } },
55
+ },
56
+ argTypes: {
57
+ agent: {
58
+ control: 'select',
59
+ options: CAST.map(p => p.id),
60
+ description: 'Preset character of a Wallarm agent.',
61
+ },
62
+ size: {
63
+ control: 'select',
64
+ options: [40, 48, 56, 72, 120],
65
+ description: 'Set by the place the character sits in.',
66
+ },
67
+ state: { control: 'select', options: STATES, description: 'State frame.' },
68
+ shadow: {
69
+ control: 'boolean',
70
+ description: 'Contact shadow: drawer header, empty chat, 96 px and up.',
71
+ },
72
+ hasApplications: { control: 'boolean', description: 'The agent’s template has applications.' },
73
+ coverage: {
74
+ control: 'inline-radio',
75
+ options: ['full', 'partial'],
76
+ description: '`partial` keeps the top of the head in grey felt.',
77
+ },
78
+ label: {
79
+ control: 'text',
80
+ description: 'Set only when the character stands alone without its name.',
81
+ },
82
+ seed: { control: 'text', description: 'The agent’s uid.' },
83
+ live: { control: 'boolean', description: 'Animated; set by the place the character sits in.' },
84
+ },
85
+ } satisfies Meta<typeof AgentAvatar>;
86
+
87
+ export default meta;
88
+
89
+ /** Radar on duty in the agent drawer header: 72 px with the contact shadow. */
90
+ export const Basic: StoryFn<AgentAvatarProps> = args => (
91
+ <AgentAvatar data-testid='agent-avatar' {...args} />
92
+ );
93
+
94
+ Basic.args = { agent: 'radar', seed: 'radar', size: 72, state: 'idle', shadow: true };
95
+
96
+ /** The six agents on duty at the team-card size. Each is told apart by its shape, colour and prop. */
97
+ export const Cast: StoryFn = () => (
98
+ <HStack gap={24} align='end'>
99
+ {CAST.map(p => (
100
+ <VStack key={p.id} gap={8} align='center'>
101
+ <AgentAvatar data-testid={`agent-avatar-${p.id}`} agent={p.id} seed={p.id} size={72} />
102
+ <Text size='sm'>{p.name}</Text>
103
+ </VStack>
104
+ ))}
105
+ </HStack>
106
+ );
107
+
108
+ /** Every state frame of one agent. The eyes and a few body cues carry the state; red and crosses never appear. */
109
+ export const States: StoryFn = () => (
110
+ <HStack gap={24} align='end' wrap='wrap'>
111
+ {STATES.map(state => (
112
+ <VStack key={state} gap={8} align='center'>
113
+ <AgentAvatar
114
+ data-testid={`agent-avatar-${state}`}
115
+ agent='sift'
116
+ seed='sift'
117
+ size={72}
118
+ state={state}
119
+ />
120
+ <Text size='sm'>{STATE_LABELS[state]}</Text>
121
+ </VStack>
122
+ ))}
123
+ </HStack>
124
+ );
125
+
126
+ /** Each place in the product with its size and shadow. */
127
+ export const Places: StoryFn = () => (
128
+ <HStack gap={32} align='end'>
129
+ {Object.entries(PLACES)
130
+ .filter(([, p]) => p.renderer === '3d')
131
+ .map(([name, p]) => (
132
+ <VStack key={name} gap={8} align='center'>
133
+ <AgentAvatar
134
+ data-testid={`agent-avatar-place-${name}`}
135
+ agent='trim'
136
+ seed='trim'
137
+ size={p.size as AgentAvatarProps['size']}
138
+ shadow={p.shadow}
139
+ />
140
+ <span className='sb-annotation'>{name}</span>
141
+ </VStack>
142
+ ))}
143
+ </HStack>
144
+ );
145
+
146
+ /** Partial coverage: the agent covers only some of its applications, so the top of its head stays in grey felt. */
147
+ export const PartialCoverage: StoryFn = () => (
148
+ <HStack gap={24}>
149
+ {CAST.filter(p => p.id === 'radar' || p.id === 'sift' || p.id === 'mend').map(p => (
150
+ <AgentAvatar
151
+ key={p.id}
152
+ data-testid={`agent-avatar-partial-${p.id}`}
153
+ agent={p.id}
154
+ seed={p.id}
155
+ size={72}
156
+ hasApplications
157
+ coverage='partial'
158
+ />
159
+ ))}
160
+ </HStack>
161
+ );
162
+
163
+ const CUSTOM_AGENTS = [
164
+ '3f2a9c1e-7b4d-4e8a-9c21-5d6e7f8a9b0c',
165
+ '8c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
166
+ 'b7e6d5c4-b3a2-4918-8776-655443322110',
167
+ ];
168
+
169
+ /** Agents without a preset get a deterministic look from their uid, the same one their glyph shows. */
170
+ export const CustomAgent: StoryFn = () => (
171
+ <HStack gap={24}>
172
+ {CUSTOM_AGENTS.map(uid => (
173
+ <AgentAvatar
174
+ key={uid}
175
+ data-testid={`agent-avatar-custom-${uid.slice(0, 8)}`}
176
+ look={defaultLook(uid)}
177
+ seed={uid}
178
+ size={72}
179
+ />
180
+ ))}
181
+ </HStack>
182
+ );
183
+
184
+ // The six presets plus ten custom agents, as stored looks.
185
+ const TEAM = [
186
+ ...CAST.map(p => ({
187
+ id: p.id,
188
+ look: { v: 1 as const, shape: p.shape, color: p.color, eyes: p.eyes, prop: p.prop },
189
+ })),
190
+ ...Array.from({ length: 10 }, (_, i) => ({
191
+ id: `custom-${i}`,
192
+ look: defaultLook(`team-agent-${i}`),
193
+ })),
194
+ ];
195
+
196
+ /** A full Agent team page: 16 cards opened with cold caches, the case the first-draw budget is set for. */
197
+ export const Team: StoryFn = () => (
198
+ <div className='grid grid-cols-4 gap-24'>
199
+ {TEAM.map(m => (
200
+ <AgentAvatar
201
+ key={m.id}
202
+ data-testid={`agent-avatar-team-${m.id}`}
203
+ look={m.look}
204
+ seed={m.id}
205
+ size={72}
206
+ />
207
+ ))}
208
+ </div>
209
+ );
210
+
211
+ const LIVE_STATES: AgentAvatarState[] = [
212
+ 'idle',
213
+ 'working',
214
+ 'needs',
215
+ 'failed',
216
+ 'off',
217
+ 'box',
218
+ 'invite',
219
+ ];
220
+
221
+ /** Every persistent state, live. On duty plays its idle repertoire; Needs you is the only one that hops. */
222
+ export const LiveStates: StoryFn = () => (
223
+ <HStack gap={24} align='end' wrap='wrap'>
224
+ {LIVE_STATES.map(state => (
225
+ <VStack key={state} gap={8} align='center'>
226
+ <AgentAvatar
227
+ data-testid={`agent-avatar-live-${state}`}
228
+ agent='radar'
229
+ seed={`radar-${state}`}
230
+ size={72}
231
+ state={state}
232
+ live
233
+ />
234
+ <Text size='sm'>{STATE_LABELS[state]}</Text>
235
+ </VStack>
236
+ ))}
237
+ </HStack>
238
+ );
239
+
240
+ /** Hello (from On duty) and Done are one-shots: they play in full, then the character shows its state again. */
241
+ export const Beats: StoryFn = () => {
242
+ const handle = useRef<AgentAvatarHandle>(null);
243
+ const [ended, setEnded] = useState('');
244
+ const sayHello = () => handle.current?.play('hello');
245
+ const finishRun = () => handle.current?.play('done');
246
+ const onBeatEnd = (beat: string) => setEnded(beat);
247
+ return (
248
+ <VStack gap={16} align='center'>
249
+ <AgentAvatar
250
+ data-testid='agent-avatar-beats'
251
+ agent='wally'
252
+ seed='wally'
253
+ size={120}
254
+ shadow
255
+ live
256
+ handleRef={handle}
257
+ onBeatEnd={onBeatEnd}
258
+ />
259
+ <HStack gap={8}>
260
+ <Button
261
+ data-testid='agent-avatar-beats-hello'
262
+ variant='outline'
263
+ size='small'
264
+ onClick={sayHello}
265
+ >
266
+ Hello
267
+ </Button>
268
+ <Button
269
+ data-testid='agent-avatar-beats-done'
270
+ variant='outline'
271
+ size='small'
272
+ onClick={finishRun}
273
+ >
274
+ Done
275
+ </Button>
276
+ </HStack>
277
+ <span className='sb-annotation' data-testid='agent-avatar-beats-ended'>
278
+ {ended ? `${ended} ended` : ' '}
279
+ </span>
280
+ </VStack>
281
+ );
282
+ };
283
+
284
+ /** Not set up, inviting: one agent on the page invites at a time, glancing at Set up; hover or focus on it and the
285
+ * agent turns to it. */
286
+ export const Inviting: StoryFn = () => {
287
+ const cue = useRef<HTMLButtonElement>(null);
288
+ return (
289
+ <VStack gap={24} align='center'>
290
+ <HStack gap={24}>
291
+ <AgentAvatar
292
+ data-testid='agent-avatar-invite-mend'
293
+ agent='mend'
294
+ seed='mend'
295
+ size={72}
296
+ state='invite'
297
+ live
298
+ cueRef={cue}
299
+ />
300
+ <AgentAvatar
301
+ data-testid='agent-avatar-invite-sift'
302
+ agent='sift'
303
+ seed='sift'
304
+ size={72}
305
+ state='invite'
306
+ live
307
+ cueRef={cue}
308
+ />
309
+ </HStack>
310
+ <Button ref={cue} data-testid='agent-avatar-invite-setup' size='small'>
311
+ Set up
312
+ </Button>
313
+ </VStack>
314
+ );
315
+ };
316
+
317
+ /** Activate: from Not set up the ghost lands, the colour fills from the floor and the eyes power on (1.15 s). */
318
+ export const Activation: StoryFn = () => {
319
+ const [state, setState] = useState<AgentAvatarState>('box');
320
+ const toggle = () => setState(state === 'box' ? 'idle' : 'box');
321
+ return (
322
+ <VStack gap={16} align='center'>
323
+ <AgentAvatar
324
+ data-testid='agent-avatar-activation'
325
+ agent='probe'
326
+ seed='probe'
327
+ size={120}
328
+ shadow
329
+ live
330
+ state={state}
331
+ />
332
+ <Button data-testid='agent-avatar-activation-toggle' size='small' onClick={toggle}>
333
+ {state === 'box' ? 'Activate' : 'Reset'}
334
+ </Button>
335
+ </VStack>
336
+ );
337
+ };
338
+
339
+ /** Cover all applications: the grey crown fills to the top in 480 ms and the agent plays Done. Hover or focus on the
340
+ * button raises the line first. */
341
+ export const Coverage: StoryFn = () => {
342
+ const handle = useRef<AgentAvatarHandle>(null);
343
+ const cue = useRef<HTMLButtonElement>(null);
344
+ const [coverage, setCoverage] = useState<'full' | 'partial'>('partial');
345
+ const coverAll = () => handle.current?.coverAll();
346
+ const onBeatEnd = () => setCoverage('full');
347
+ const reset = () => setCoverage('partial');
348
+ return (
349
+ <VStack gap={16} align='center'>
350
+ <AgentAvatar
351
+ data-testid='agent-avatar-coverage'
352
+ agent='radar'
353
+ seed='radar'
354
+ size={120}
355
+ shadow
356
+ live
357
+ hasApplications
358
+ coverage={coverage}
359
+ handleRef={handle}
360
+ cueRef={cue}
361
+ onBeatEnd={onBeatEnd}
362
+ />
363
+ <HStack gap={8}>
364
+ <Button ref={cue} data-testid='agent-avatar-coverage-all' size='small' onClick={coverAll}>
365
+ Cover all applications
366
+ </Button>
367
+ <Button
368
+ data-testid='agent-avatar-coverage-reset'
369
+ variant='outline'
370
+ size='small'
371
+ onClick={reset}
372
+ >
373
+ Reset
374
+ </Button>
375
+ </HStack>
376
+ </VStack>
377
+ );
378
+ };
379
+
380
+ /** Fifteen live agents at 120 px, as on a full team page, with the engine's frame rate and JavaScript per frame. */
381
+ export const ManyOnScreen: StoryFn = () => (
382
+ <VStack gap={16}>
383
+ <FrameMeter />
384
+ <AgentAvatarGroup>
385
+ <div className='grid grid-cols-5 gap-16'>
386
+ {TEAM.slice(0, 15).map(m => (
387
+ <AgentAvatar
388
+ key={m.id}
389
+ data-testid={`agent-avatar-many-${m.id}`}
390
+ look={m.look}
391
+ seed={m.id}
392
+ size={120}
393
+ live
394
+ />
395
+ ))}
396
+ </div>
397
+ </AgentAvatarGroup>
398
+ </VStack>
399
+ );
400
+
401
+ /** With motion off (the user's setting, or reduced motion in the system) every live agent shows its static frame. */
402
+ export const ReducedMotion: StoryFn = () => {
403
+ const motion = useAgentMotion();
404
+ const [off, setOff] = useState(false);
405
+ useEffect(() => {
406
+ setAgentMotion(!off);
407
+ return () => setAgentMotion(true);
408
+ }, [off]);
409
+ const toggle = () => setOff(!off);
410
+ return (
411
+ <VStack gap={16} align='center'>
412
+ <HStack gap={24}>
413
+ {LIVE_STATES.slice(0, 4).map(state => (
414
+ <AgentAvatar
415
+ key={state}
416
+ data-testid={`agent-avatar-motion-${state}`}
417
+ agent='trim'
418
+ seed={`trim-${state}`}
419
+ size={72}
420
+ state={state}
421
+ live
422
+ />
423
+ ))}
424
+ </HStack>
425
+ <Button
426
+ data-testid='agent-avatar-motion-toggle'
427
+ variant='outline'
428
+ size='small'
429
+ onClick={toggle}
430
+ >
431
+ {off ? 'Turn motion on' : 'Turn motion off'}
432
+ </Button>
433
+ <span className='sb-annotation'>{motion ? 'Motion on' : 'Motion off (static frames)'}</span>
434
+ </VStack>
435
+ );
436
+ };
437
+ ```
438
+
439
+ ### ../lib/agent-characters/data.gen.ts
440
+
441
+ ```tsx
442
+ // GENERATED by scripts/agent-avatars/export-data.ts from the handoff data (reference look v14). Do not edit.
443
+ // Source export: 2026-11-04, Playwright (playwright-core 1.58.2) with Chrome 156 headless, 1440 x 900 viewport, deviceScaleFactor 2; values read from the page's own constants and functions at runtime
444
+
445
+ // Id unions: the page's own ids (07 §6.2). `cyan` is labelled «teal».
446
+ export type AgentShapeId = 'dome' | 'gumdrop' | 'cushion' | 'pebble' | 'capsule' | 'cloud' | 'egg' | 'mochi' | 'kettle' | 'mug' | 'padlock' | 'safe';
447
+ export type AgentColorId = 'coral' | 'cobalt' | 'sky' | 'cyan' | 'lilac' | 'heather' | 'pink' | 'sand' | 'toffee' | 'powder' | 'lavender' | 'blush' | 'butter' | 'mint' | 'sage' | 'petrol' | 'plum' | 'cocoa' | 'olive' | 'graphite' | 'stone' | 'oat';
448
+ export type AgentEyeStyle = 'round' | 'oval' | 'tall' | 'sleepy';
449
+ export type AgentPropId = 'antennae' | 'dish' | 'glasses' | 'seam' | 'beanie' | 'headlamp' | 'periscope' | 'magnifier' | 'pennant' | 'flowerclip' | 'plaster' | 'sprout' | 'badge' | 'windkey' | 'monocle' | 'none';
450
+ export type AgentCharacterId = 'wally' | 'radar' | 'sift' | 'mend' | 'trim' | 'probe';
451
+ export type AgentToneId = 'metal' | 'ink' | 'leaf' | 'wood' | 'oat' | 'honey' | 'brass' | 'cocoa' | 'glass' | 'beige';
452
+
453
+ /** A stored look: four ids and a schema version, so a later kit change can migrate stored looks. */
454
+ export interface AgentLook {
455
+ v: 1;
456
+ shape: AgentShapeId;
457
+ color: AgentColorId;
458
+ eyes: AgentEyeStyle;
459
+ prop: AgentPropId;
460
+ }
461
+
462
+ /** A preset: a look plus its default name, role and template (null: Wally, and Probe until its template exists). */
463
+ export interface AgentPreset extends Omit<AgentLook, 'v'> {
464
+ id: AgentCharacterId;
465
+ name: string;
466
+ role: string;
467
+ templateId: string | null;
468
+ }
469
+
470
+ export interface AgentShapeDef {
471
+ id: AgentShapeId;
472
+ fam: 'soft' | 'object';
473
+ name: string;
474
+ /** body outline on the 120-unit grid */
475
+ d: string;
476
+ /** visor [x, y, width, height] */
477
+ v: [number, number, number, number];
478
+ /** declared top anchor; otherwise measured */
479
+ top?: [number, number];
480
+ parts?: { d: string; tone: AgentToneId; z: 'b' | 'f' }[];
481
+ }
482
+ export interface AgentColorDef {
483
+ id: AgentColorId;
484
+ name: string;
485
+ hex: string;
486
+ g: 'brand' | 'cool' | 'warm' | 'pastel' | 'deep' | 'neutral';
487
+ brand?: boolean;
488
+ }
489
+ export interface PropLayer {
490
+ d: string;
491
+ col: string;
492
+ mat: 'vinyl' | 'felt' | null;
493
+ }
494
+ export interface PropDeco {
495
+ s: string;
496
+ clip?: boolean;
497
+ }
498
+ export interface PropDef {
499
+ layers: PropLayer[];
500
+ deco: PropDeco[];
501
+ anim: { type: string; px: number; py: number } | null;
502
+ fid: { k: string; px: number; py: number };
503
+ }
504
+ export interface EyeBase { w: number; ht: number; hb: number; kt: number; kb: number; lid: number }
505
+
506
+ export const SHAPE_IDS: AgentShapeId[] = [
507
+ "dome",
508
+ "gumdrop",
509
+ "cushion",
510
+ "pebble",
511
+ "capsule",
512
+ "cloud",
513
+ "egg",
514
+ "mochi",
515
+ "kettle",
516
+ "mug",
517
+ "padlock",
518
+ "safe"
519
+ ];
520
+ export const COLOR_IDS: AgentColorId[] = [
521
+ "coral",
522
+ "cobalt",
523
+ "sky",
524
+ "cyan",
525
+ "lilac",
526
+ "heather",
527
+ "pink",
528
+ "sand",
529
+ "toffee",
530
+ "powder",
531
+ "lavender",
532
+ "blush",
533
+ "butter",
534
+ "mint",
535
+ "sage",
536
+ "petrol",
537
+ "plum",
538
+ "cocoa",
539
+ "olive",
540
+ "graphite",
541
+ "stone",
542
+ "oat"
543
+ ];
544
+ export const EYE_STYLES: AgentEyeStyle[] = [
545
+ "round",
546
+ "oval",
547
+ "tall",
548
+ "sleepy"
549
+ ];
550
+ export const PROP_IDS: AgentPropId[] = [
551
+ "antennae",
552
+ "dish",
553
+ "glasses",
554
+ "seam",
555
+ "beanie",
556
+ "headlamp",
557
+ "periscope",
558
+ "magnifier",
559
+ "pennant",
560
+ "flowerclip",
561
+ "plaster",
562
+ "sprout",
563
+ "badge",
564
+ "windkey",
565
+ "monocle",
566
+ "none"
567
+ ];
568
+
569
+ export const SHAPES: AgentShapeDef[] = [
570
+ {
571
+ "id": "dome",
572
+ "fam": "soft",
573
+ "name": "Dome",
574
+ "d": "M16 100C16 56 36 30 60 30C84 30 104 56 104 100Q104 108 96 108H24Q16 108 16 100Z",
575
+ "v": [
576
+ 28,
577
+ 64,
578
+ 64,
579
+ 28
580
+ ]
581
+ },
582
+ {
583
+ "id": "gumdrop",
584
+ "fam": "soft",
585
+ "name": "Gumdrop",
586
+ "d": "M60 16C72 16 106 82 106 97C106 105 100 108 91 108H29C20 108 14 105 14 97C14 82 48 16 60 16Z",
587
+ "v": [
588
+ 34,
589
+ 70,
590
+ 52,
591
+ 26
592
+ ]
593
+ },
594
+ {
595
+ "id": "cushion",
596
+ "fam": "soft",
597
+ "name": "Cushion",
598
+ "d": "M24 32C40 26 80 26 96 32C104 35 106 42 106 58V92C106 104 100 108 88 108H32C20 108 14 104 14 92V58C14 42 16 35 24 32Z",
599
+ "v": [
600
+ 28,
601
+ 60,
602
+ 64,
603
+ 28
604
+ ]
605
+ },
606
+ {
607
+ "id": "pebble",
608
+ "fam": "soft",
609
+ "name": "Pebble",
610
+ "d": "M60 40C90 40 108 62 108 84C108 100 96 108 80 108H40C24 108 12 100 12 84C12 62 30 40 60 40Z",
611
+ "v": [
612
+ 28,
613
+ 66,
614
+ 64,
615
+ 26
616
+ ]
617
+ },
618
+ {
619
+ "id": "capsule",
620
+ "fam": "soft",
621
+ "name": "Capsule",
622
+ "d": "M60 20C80 20 90 34 90 54V96C90 104 84 108 76 108H44C36 108 30 104 30 96V54C30 34 40 20 60 20Z",
623
+ "v": [
624
+ 36,
625
+ 58,
626
+ 48,
627
+ 28
628
+ ]
629
+ },
630
+ {
631
+ "id": "cloud",
632
+ "fam": "soft",
633
+ "name": "Cloud",
634
+ "d": "M30 108C16 108 10 98 13 88C8 76 18 63 31 66C31 50 46 40 60 46C72 36 92 44 92 60C104 60 112 72 107 85C112 98 104 108 92 108Z",
635
+ "v": [
636
+ 30,
637
+ 72,
638
+ 60,
639
+ 26
640
+ ],
641
+ "top": [
642
+ 60,
643
+ 45
644
+ ]
645
+ },
646
+ {
647
+ "id": "egg",
648
+ "fam": "soft",
649
+ "name": "Egg",
650
+ "d": "M60 20C84 20 98 54 98 78C98 98 82 108 60 108C38 108 22 98 22 78C22 54 36 20 60 20Z",
651
+ "v": [
652
+ 32,
653
+ 62,
654
+ 56,
655
+ 26
656
+ ]
657
+ },
658
+ {
659
+ "id": "mochi",
660
+ "fam": "soft",
661
+ "name": "Mochi",
662
+ "d": "M60 50C92 50 112 70 112 88C112 102 100 108 84 108H36C20 108 8 102 8 88C8 70 28 50 60 50Z",
663
+ "v": [
664
+ 26,
665
+ 70,
666
+ 68,
667
+ 24
668
+ ]
669
+ },
670
+ {
671
+ "id": "kettle",
672
+ "fam": "object",
673
+ "name": "Kettle",
674
+ "d": "M18 100C18 66 36 44 60 44C84 44 102 66 102 100Q102 108 94 108H26Q18 108 18 100ZM24 80C14 74 8 64 5 56L9 53C13 61 20 69 28 74Z",
675
+ "v": [
676
+ 30,
677
+ 68,
678
+ 60,
679
+ 26
680
+ ],
681
+ "top": [
682
+ 60,
683
+ 44
684
+ ],
685
+ "parts": [
686
+ {
687
+ "d": "M31 64.07L30.87 57.86L31.66 52.01L33.32 46.78L35.74 42.21L38.82 38.31L42.44 35.13L46.48 32.66L50.83 30.9L55.36 29.85L60 29.5L64.64 29.85L69.17 30.9L73.52 32.66L77.56 35.13L81.18 38.31L84.26 42.21L86.68 46.78L88.34 52.01L89.13 57.86L89 64.07A3 3 0 0 1 83 63.93L83.14 58.17L82.48 53.31L81.14 49.09L79.23 45.47L76.82 42.44L74 39.95L70.82 38.01L67.37 36.62L63.73 35.78L60 35.5L56.27 35.78L52.63 36.62L49.18 38.01L46 39.95L43.18 42.44L40.77 45.47L38.86 49.09L37.52 53.31L36.86 58.17L37 63.93A3 3 0 0 1 31 64.07Z",
688
+ "tone": "ink",
689
+ "z": "b"
690
+ },
691
+ {
692
+ "d": "M55 42A5 4 0 1 1 65 42A5 4 0 1 1 55 42Z",
693
+ "tone": "ink",
694
+ "z": "f"
695
+ }
696
+ ]
697
+ },
698
+ {
699
+ "id": "mug",
700
+ "fam": "object",
701
+ "name": "Mug",
702
+ "d": "M28 34H74A12 12 0 0 1 86 46V96A12 12 0 0 1 74 108H28A12 12 0 0 1 16 96V46A12 12 0 0 1 28 34ZM77 70A15 19 0 1 1 107 70A15 19 0 1 1 77 70ZM87.5 70A6.5 9.5 0 1 0 100.5 70A6.5 9.5 0 1 0 87.5 70Z",
703
+ "v": [
704
+ 22,
705
+ 56,
706
+ 58,
707
+ 28
708
+ ]
709
+ },
710
+ {
711
+ "id": "padlock",
712
+ "fam": "object",
713
+ "name": "Padlock",
714
+ "d": "M36 52H84A16 16 0 0 1 100 68V92A16 16 0 0 1 84 108H36A16 16 0 0 1 20 92V68A16 16 0 0 1 36 52Z",
715
+ "v": [
716
+ 30,
717
+ 66,
718
+ 60,
719
+ 26
720
+ ],
721
+ "top": [
722
+ 60,
723
+ 14
724
+ ],
725
+ "parts": [
726
+ {
727
+ "d": "M34 58V40A26 26 0 0 1 86 40V58H74V40A14 14 0 0 0 46 40V58Z",
728
+ "tone": "metal",
729
+ "z": "b"
730
+ }
731
+ ]
732
+ },
733
+ {
734
+ "id": "safe",
735
+ "fam": "object",
736
+ "name": "Safe",
737
+ "d": "M28 30H92A14 14 0 0 1 106 44V86A14 14 0 0 1 92 100H28A14 14 0 0 1 14 86V44A14 14 0 0 1 28 30Z",
738
+ "v": [
739
+ 26,
740
+ 44,
741
+ 68,
742
+ 26
743
+ ],
744
+ "parts": [
745
+ {
746
+ "d": "M26 96H32A4 4 0 0 1 36 100V104A4 4 0 0 1 32 108H26A4 4 0 0 1 22 104V100A4 4 0 0 1 26 96ZM88 96H94A4 4 0 0 1 98 100V104A4 4 0 0 1 94 108H88A4 4 0 0 1 84 104V100A4 4 0 0 1 88 96Z",
747
+ "tone": "ink",
748
+ "z": "b"
749
+ },
750
+ {
751
+ "d": "M53 86A7 7 0 1 1 67 86A7 7 0 1 1 53 86ZM73.5 83.5H87.5A2.5 2.5 0 0 1 90 86V86A2.5 2.5 0 0 1 87.5 88.5H73.5A2.5 2.5 0 0 1 71 86V86A2.5 2.5 0 0 1 73.5 83.5Z",
752
+ "tone": "metal",
753
+ "z": "f"
754
+ }
755
+ ]
756
+ }
757
+ ];
758
+
759
+ export const COLORS: AgentColorDef[] = [
760
+ {
761
+ "id": "coral",
762
+ "name": "coral, Wally only",
763
+ "hex": "#FF4D2E",
764
+ "g": "brand",
765
+ "brand": true
766
+ },
767
+ {
768
+ "id": "cobalt",
769
+ "name": "cobalt",
770
+ "hex": "#3F63DB",
771
+ "g": "cool"
772
+ },
773
+ {
774
+ "id": "sky",
775
+ "name": "sky",
776
+ "hex": "#62AEEB",
777
+ "g": "cool"
778
+ },
779
+ {
780
+ "id": "cyan",
781
+ "name": "teal",
782
+ "hex": "#2BA6BF",
783
+ "g": "cool"
784
+ },
785
+ {
786
+ "id": "lilac",
787
+ "name": "lilac",
788
+ "hex": "#9A7FE0",
789
+ "g": "cool"
790
+ },
791
+ {
792
+ "id": "heather",
793
+ "name": "heather",
794
+ "hex": "#9E86A8",
795
+ "g": "cool"
796
+ },
797
+ {
798
+ "id": "pink",
799
+ "name": "pink",
800
+ "hex": "#E373A8",
801
+ "g": "warm"
802
+ },
803
+ {
804
+ "id": "sand",
805
+ "name": "sand",
806
+ "hex": "#D8B68A",
807
+ "g": "warm"
808
+ },
809
+ {
810
+ "id": "toffee",
811
+ "name": "toffee",
812
+ "hex": "#A87A62",
813
+ "g": "warm"
814
+ },
815
+ {
816
+ "id": "powder",
817
+ "name": "powder",
818
+ "hex": "#B9D7F0",
819
+ "g": "pastel"
820
+ },
821
+ {
822
+ "id": "lavender",
823
+ "name": "lavender",
824
+ "hex": "#D3C6F3",
825
+ "g": "pastel"
826
+ },
827
+ {
828
+ "id": "blush",
829
+ "name": "blush",
830
+ "hex": "#F2B8C8",
831
+ "g": "pastel"
832
+ },
833
+ {
834
+ "id": "butter",
835
+ "name": "butter",
836
+ "hex": "#F2D57E",
837
+ "g": "pastel"
838
+ },
839
+ {
840
+ "id": "mint",
841
+ "name": "mint",
842
+ "hex": "#A8DCC8",
843
+ "g": "pastel"
844
+ },
845
+ {
846
+ "id": "sage",
847
+ "name": "sage",
848
+ "hex": "#9BAE8C",
849
+ "g": "pastel"
850
+ },
851
+ {
852
+ "id": "petrol",
853
+ "name": "petrol",
854
+ "hex": "#2D6E8E",
855
+ "g": "deep"
856
+ },
857
+ {
858
+ "id": "plum",
859
+ "name": "plum",
860
+ "hex": "#7C4485",
861
+ "g": "deep"
862
+ },
863
+ {
864
+ "id": "cocoa",
865
+ "name": "cocoa",
866
+ "hex": "#6B4C3F",
867
+ "g": "deep"
868
+ },
869
+ {
870
+ "id": "olive",
871
+ "name": "olive",
872
+ "hex": "#7E7C48",
873
+ "g": "deep"
874
+ },
875
+ {
876
+ "id": "graphite",
877
+ "name": "graphite",
878
+ "hex": "#4C5463",
879
+ "g": "neutral"
880
+ },
881
+ {
882
+ "id": "stone",
883
+ "name": "stone",
884
+ "hex": "#A9A59D",
885
+ "g": "neutral"
886
+ },
887
+ {
888
+ "id": "oat",
889
+ "name": "oat",
890
+ "hex": "#E9E0D0",
891
+ "g": "neutral"
892
+ }
893
+ ];
894
+
895
+ export const TONE: Record<AgentToneId, string> = {
896
+ "metal": "#A3ABBB",
897
+ "ink": "#262A36",
898
+ "leaf": "#7F9E66",
899
+ "wood": "#8E6447",
900
+ "oat": "#EEE5D6",
901
+ "honey": "#E8B54E",
902
+ "brass": "#C8A35E",
903
+ "cocoa": "#5B3E33",
904
+ "glass": "#CFE3F2",
905
+ "beige": "#E9D2B5"
906
+ };
907
+
908
+ export const HARD: ReadonlySet<string> = new Set([
909
+ "metal",
910
+ "brass",
911
+ "ink",
912
+ "glass"
913
+ ]);
914
+
915
+ export const EYE_BASE: Record<AgentEyeStyle, EyeBase> = {
916
+ "round": {
917
+ "w": 1.05,
918
+ "ht": 1,
919
+ "hb": 1,
920
+ "kt": 0.55,
921
+ "kb": 0.55,
922
+ "lid": 0
923
+ },
924
+ "oval": {
925
+ "w": 1,
926
+ "ht": 1.25,
927
+ "hb": 1.25,
928
+ "kt": 0.55,
929
+ "kb": 0.55,
930
+ "lid": 0
931
+ },
932
+ "tall": {
933
+ "w": 0.8,
934
+ "ht": 1.6,
935
+ "hb": 1.6,
936
+ "kt": 0.6,
937
+ "kb": 0.6,
938
+ "lid": 0
939
+ },
940
+ "sleepy": {
941
+ "w": 1.05,
942
+ "ht": 1.15,
943
+ "hb": 1.15,
944
+ "kt": 0.55,
945
+ "kb": 0.55,
946
+ "lid": 0.5
947
+ }
948
+ };
949
+
950
+ export const PROPS: [AgentPropId, string][] = [
951
+ [
952
+ "antennae",
953
+ "Antennae"
954
+ ],
955
+ [
956
+ "dish",
957
+ "Dish antenna"
958
+ ],
959
+ [
960
+ "glasses",
961
+ "Glasses"
962
+ ],
963
+ [
964
+ "seam",
965
+ "Seam"
966
+ ],
967
+ [
968
+ "beanie",
969
+ "Beanie"
970
+ ],
971
+ [
972
+ "headlamp",
973
+ "Headlamp"
974
+ ],
975
+ [
976
+ "periscope",
977
+ "Periscope"
978
+ ],
979
+ [
980
+ "magnifier",
981
+ "Magnifier"
982
+ ],
983
+ [
984
+ "pennant",
985
+ "Pennant"
986
+ ],
987
+ [
988
+ "flowerclip",
989
+ "Flower clip"
990
+ ],
991
+ [
992
+ "plaster",
993
+ "Plaster"
994
+ ],
995
+ [
996
+ "sprout",
997
+ "Sprout"
998
+ ],
999
+ [
1000
+ "badge",
1001
+ "Badge"
1002
+ ],
1003
+ [
1004
+ "windkey",
1005
+ "Wind-up key"
1006
+ ],
1007
+ [
1008
+ "monocle",
1009
+ "Monocle"
1010
+ ],
1011
+ [
1012
+ "none",
1013
+ "No prop"
1014
+ ]
1015
+ ];
1016
+
1017
+ export const GLYPH_PROPS: ReadonlySet<string> = new Set([
1018
+ "antennae",
1019
+ "dish",
1020
+ "beanie",
1021
+ "periscope",
1022
+ "pennant",
1023
+ "sprout",
1024
+ "windkey"
1025
+ ]);
1026
+
1027
+ export const CAST: AgentPreset[] = [
1028
+ {
1029
+ "id": "wally",
1030
+ "name": "Wally",
1031
+ "role": "Assistant",
1032
+ "templateId": null,
1033
+ "shape": "dome",
1034
+ "color": "coral",
1035
+ "eyes": "oval",
1036
+ "prop": "antennae"
1037
+ },
1038
+ {
1039
+ "id": "radar",
1040
+ "name": "Radar",
1041
+ "role": "Attack Anomaly Investigator",
1042
+ "templateId": "attack-anomaly-investigation",
1043
+ "shape": "gumdrop",
1044
+ "color": "cobalt",
1045
+ "eyes": "tall",
1046
+ "prop": "dish"
1047
+ },
1048
+ {
1049
+ "id": "sift",
1050
+ "name": "Sift",
1051
+ "role": "False Positives Analyzer",
1052
+ "templateId": "fp-marking",
1053
+ "shape": "cushion",
1054
+ "color": "lilac",
1055
+ "eyes": "round",
1056
+ "prop": "glasses"
1057
+ },
1058
+ {
1059
+ "id": "mend",
1060
+ "name": "Mend",
1061
+ "role": "False Positive Resolver",
1062
+ "templateId": "fp-resolver",
1063
+ "shape": "pebble",
1064
+ "color": "sand",
1065
+ "eyes": "sleepy",
1066
+ "prop": "seam"
1067
+ },
1068
+ {
1069
+ "id": "trim",
1070
+ "name": "Trim",
1071
+ "role": "Ruleset Optimizer",
1072
+ "templateId": "ruleset-optimizer",
1073
+ "shape": "capsule",
1074
+ "color": "cyan",
1075
+ "eyes": "oval",
1076
+ "prop": "windkey"
1077
+ },
1078
+ {
1079
+ "id": "probe",
1080
+ "name": "Probe",
1081
+ "role": "Exploitability Verifier",
1082
+ "templateId": null,
1083
+ "shape": "egg",
1084
+ "color": "olive",
1085
+ "eyes": "round",
1086
+ "prop": "headlamp"
1087
+ }
1088
+ ];
1089
+
1090
+ /** propDef() for the six presets, keyed `shape|hex|prop`; any other look needs the AgentLookBuilder entry. */
1091
+ export const PRESET_PROPS: Partial<Record<string, PropDef>> = {
1092
+ "dome|#FF4D2E|antennae": {
1093
+ "layers": [
1094
+ {
1095
+ "d": "M49.69 35.73L48.83 34.18L47.97 32.67L47.1 31.2L46.21 29.75L45.32 28.33L44.42 26.95L43.51 25.6L42.59 24.27L41.66 22.98L40.72 21.72L39.77 20.49L38.82 19.29L37.85 18.13L36.86 16.98A1.5 1.5 0 0 1 39.14 15.02L40.14 16.19L41.14 17.4L42.13 18.64L43.11 19.91L44.08 21.21L45.04 22.54L45.99 23.9L46.92 25.29L47.85 26.72L48.76 28.17L49.67 29.65L50.56 31.16L51.44 32.71L52.31 34.27A1.5 1.5 0 0 1 49.69 35.73ZM33.1 14.5A4.4 4.4 0 1 1 41.9 14.5A4.4 4.4 0 1 1 33.1 14.5ZM67.69 34.27L68.56 32.71L69.44 31.16L70.33 29.65L71.24 28.17L72.15 26.72L73.08 25.29L74.01 23.9L74.96 22.54L75.92 21.21L76.89 19.91L77.87 18.64L78.86 17.4L79.86 16.19L80.86 15.02A1.5 1.5 0 0 1 83.14 16.98L82.15 18.13L81.18 19.29L80.23 20.49L79.28 21.72L78.34 22.98L77.41 24.27L76.49 25.6L75.58 26.95L74.68 28.33L73.79 29.75L72.9 31.2L72.03 32.67L71.17 34.18L70.31 35.73A1.5 1.5 0 0 1 67.69 34.27ZM78.1 14.5A4.4 4.4 0 1 1 86.9 14.5A4.4 4.4 0 1 1 78.1 14.5Z",
1096
+ "col": "#262A36",
1097
+ "mat": "vinyl"
1098
+ }
1099
+ ],
1100
+ "deco": [],
1101
+ "anim": {
1102
+ "type": "twitch",
1103
+ "px": 60,
1104
+ "py": 34
1105
+ },
1106
+ "fid": {
1107
+ "k": "twitch",
1108
+ "px": 60,
1109
+ "py": 34
1110
+ }
1111
+ },
1112
+ "gumdrop|#3F63DB|dish": {
1113
+ "layers": [
1114
+ {
1115
+ "d": "M60.73 19.71L63.73 6.71A1.3 1.3 0 0 1 66.27 7.29L63.27 20.29A1.3 1.3 0 0 1 60.73 19.71Z",
1116
+ "col": "#262A36",
1117
+ "mat": "vinyl"
1118
+ },
1119
+ {
1120
+ "d": "M52 0Q65 15 79 2Z",
1121
+ "col": "#a9b9ef",
1122
+ "mat": null
1123
+ },
1124
+ {
1125
+ "d": "M64.13 3.76L67.13 -7.24A0.9 0.9 0 0 1 68.87 -6.76L65.87 4.24A0.9 0.9 0 0 1 64.13 3.76ZM65.6 -8A2.4 2.4 0 1 1 70.4 -8A2.4 2.4 0 1 1 65.6 -8Z",
1126
+ "col": "#262A36",
1127
+ "mat": "vinyl"
1128
+ }
1129
+ ],
1130
+ "deco": [],
1131
+ "anim": {
1132
+ "type": "dish",
1133
+ "px": 63,
1134
+ "py": 18
1135
+ },
1136
+ "fid": {
1137
+ "k": "scan",
1138
+ "px": 63,
1139
+ "py": 18
1140
+ }
1141
+ },
1142
+ "cushion|#9A7FE0|glasses": {
1143
+ "layers": [
1144
+ {
1145
+ "d": "M36.7 74A10.5 10.5 0 1 1 57.7 74A10.5 10.5 0 1 1 36.7 74ZM38.8 74A8.4 8.4 0 1 0 55.6 74A8.4 8.4 0 1 0 38.8 74ZM62.3 74A10.5 10.5 0 1 1 83.3 74A10.5 10.5 0 1 1 62.3 74ZM64.4 74A8.4 8.4 0 1 0 81.2 74A8.4 8.4 0 1 0 64.4 74ZM56.07 71.86L56.57 71.37L57.1 70.93L57.65 70.55L58.21 70.25L58.8 70.03L59.39 69.9L60 69.85L60.61 69.9L61.2 70.03L61.79 70.25L62.35 70.55L62.9 70.93L63.43 71.37L63.93 71.86A0.9 0.9 0 0 1 62.67 73.14L62.22 72.7L61.81 72.36L61.42 72.09L61.04 71.89L60.68 71.75L60.34 71.68L60 71.65L59.66 71.68L59.32 71.75L58.96 71.89L58.58 72.09L58.19 72.36L57.78 72.7L57.33 73.14A0.9 0.9 0 0 1 56.07 71.86Z",
1146
+ "col": "#EEE5D6",
1147
+ "mat": "vinyl"
1148
+ }
1149
+ ],
1150
+ "deco": [
1151
+ {
1152
+ "s": "<path class=\"glint\" d=\"M75.3 67.5l3.2 3.2M49.7 67.5l3.2 3.2\" stroke=\"#fff\" stroke-width=\"1.5\" stroke-linecap=\"round\" opacity=\".55\"/>"
1153
+ }
1154
+ ],
1155
+ "anim": null,
1156
+ "fid": {
1157
+ "k": "bob",
1158
+ "px": 60,
1159
+ "py": 27.5
1160
+ }
1161
+ },
1162
+ "pebble|#D8B68A|seam": {
1163
+ "layers": [],
1164
+ "deco": [
1165
+ {
1166
+ "clip": true,
1167
+ "s": "<path d=\"M26.5 57Q60 47 93.5 57\" stroke=\"#877258\" stroke-width=\"1.3\" fill=\"none\"/><path class=\"stitch\" d=\"M26.5 57Q60 47 93.5 57\" stroke=\"#F4EEE4\" stroke-width=\"3.4\" stroke-dasharray=\"1.6 4.4\" stroke-linecap=\"round\" fill=\"none\"/>"
1168
+ }
1169
+ ],
1170
+ "anim": null,
1171
+ "fid": {
1172
+ "k": "none",
1173
+ "px": 60,
1174
+ "py": 40
1175
+ }
1176
+ },
1177
+ "capsule|#2BA6BF|windkey": {
1178
+ "layers": [
1179
+ {
1180
+ "d": "M59.5 11H60.5A1.5 1.5 0 0 1 62 12.5V21.5A1.5 1.5 0 0 1 60.5 23H59.5A1.5 1.5 0 0 1 58 21.5V12.5A1.5 1.5 0 0 1 59.5 11Z",
1181
+ "col": "#C8A35E",
1182
+ "mat": "vinyl"
1183
+ },
1184
+ {
1185
+ "d": "M47 6A6.5 5.5 0 1 1 60 6A6.5 5.5 0 1 1 47 6ZM50.9 6A2.6 2.2 0 1 0 56.1 6A2.6 2.2 0 1 0 50.9 6ZM60 6A6.5 5.5 0 1 1 73 6A6.5 5.5 0 1 1 60 6ZM63.9 6A2.6 2.2 0 1 0 69.1 6A2.6 2.2 0 1 0 63.9 6Z",
1186
+ "col": "#C8A35E",
1187
+ "mat": "vinyl"
1188
+ }
1189
+ ],
1190
+ "deco": [],
1191
+ "anim": {
1192
+ "type": "wind",
1193
+ "px": 60,
1194
+ "py": 10
1195
+ },
1196
+ "fid": {
1197
+ "k": "spin",
1198
+ "px": 60,
1199
+ "py": 10
1200
+ }
1201
+ },
1202
+ "egg|#7E7C48|headlamp": {
1203
+ "layers": [
1204
+ {
1205
+ "d": "M34.62 33.55L38.22 32.61L41.85 31.81L45.48 31.16L49.11 30.65L52.74 30.29L56.37 30.07L60 30L63.63 30.07L67.26 30.29L70.89 30.65L74.52 31.16L78.15 31.81L81.78 32.61L85.38 33.55A1.5 1.5 0 0 1 84.62 36.45L81.08 35.53L77.56 34.76L74.05 34.12L70.54 33.63L67.02 33.28L63.51 33.07L60 33L56.49 33.07L52.98 33.28L49.46 33.63L45.95 34.12L42.44 34.76L38.92 35.53L35.38 36.45A1.5 1.5 0 0 1 34.62 33.55Z",
1206
+ "col": "#262A36",
1207
+ "mat": "vinyl"
1208
+ },
1209
+ {
1210
+ "d": "M57 25H63A4 4 0 0 1 67 29V32A4 4 0 0 1 63 36H57A4 4 0 0 1 53 32V29A4 4 0 0 1 57 25Z",
1211
+ "col": "#A3ABBB",
1212
+ "mat": "vinyl"
1213
+ },
1214
+ {
1215
+ "d": "M55.4 30.5A4.6 3.8 0 1 1 64.6 30.5A4.6 3.8 0 1 1 55.4 30.5Z",
1216
+ "col": "#EEE5D6",
1217
+ "mat": "vinyl"
1218
+ }
1219
+ ],
1220
+ "deco": [
1221
+ {
1222
+ "s": "<path class=\"beam\" d=\"M56 28L44 -6L76 -6L64 28Z\" fill=\"#FFF6D6\" opacity=\"0\"/>"
1223
+ }
1224
+ ],
1225
+ "anim": null,
1226
+ "fid": {
1227
+ "k": "flicker",
1228
+ "px": 60,
1229
+ "py": 30
1230
+ }
1231
+ }
1232
+ };
1233
+
1234
+ export const STATES: { key: string; label: string; product: string; engine: string }[] = [
1235
+ {
1236
+ "key": "idle",
1237
+ "label": "On duty",
1238
+ "product": "Active, waiting for work",
1239
+ "engine": "idle"
1240
+ },
1241
+ {
1242
+ "key": "hello",
1243
+ "label": "Hello",
1244
+ "product": "Chat or drawer opened",
1245
+ "engine": "hello"
1246
+ },
1247
+ {
1248
+ "key": "working",
1249
+ "label": "Working",
1250
+ "product": "Run in progress",
1251
+ "engine": "working"
1252
+ },
1253
+ {
1254
+ "key": "needs",
1255
+ "label": "Needs you",
1256
+ "product": "N pending approval",
1257
+ "engine": "needs"
1258
+ },
1259
+ {
1260
+ "key": "done",
1261
+ "label": "Done",
1262
+ "product": "Run finished, change applied",
1263
+ "engine": "done"
1264
+ },
1265
+ {
1266
+ "key": "failed",
1267
+ "label": "Failed",
1268
+ "product": "Run failed",
1269
+ "engine": "failed"
1270
+ },
1271
+ {
1272
+ "key": "off",
1273
+ "label": "Deactivated",
1274
+ "product": "Deactivated",
1275
+ "engine": "off"
1276
+ },
1277
+ {
1278
+ "key": "box",
1279
+ "label": "Not set up",
1280
+ "product": "Not set up",
1281
+ "engine": "box"
1282
+ },
1283
+ {
1284
+ "key": "invite",
1285
+ "label": "Inviting",
1286
+ "product": "Not set up, inviting",
1287
+ "engine": "invite"
1288
+ },
1289
+ {
1290
+ "key": "partly",
1291
+ "label": "Partial coverage",
1292
+ "product": "Active in some applications",
1293
+ "engine": "idle with the cover flag (setCover(true))"
1294
+ }
1295
+ ];
1296
+
1297
+ export const SPRINGS: Record<string, { T: number; zeta: number }> = {
1298
+ "P_SHAPE": {
1299
+ "T": 0.28,
1300
+ "zeta": 0.8
1301
+ },
1302
+ "P_POP": {
1303
+ "T": 0.32,
1304
+ "zeta": 0.45
1305
+ },
1306
+ "P_DART": {
1307
+ "T": 0.12,
1308
+ "zeta": 0.65
1309
+ },
1310
+ "P_PURSUIT": {
1311
+ "T": 0.3,
1312
+ "zeta": 0.85
1313
+ },
1314
+ "P_BRIGHT": {
1315
+ "T": 0.2,
1316
+ "zeta": 1
1317
+ },
1318
+ "P_SQ": {
1319
+ "T": 0.22,
1320
+ "zeta": 0.3
1321
+ },
1322
+ "P_LAND": {
1323
+ "T": 0.35,
1324
+ "zeta": 0.4
1325
+ },
1326
+ "P_W": {
1327
+ "T": 0.6,
1328
+ "zeta": 1
1329
+ }
1330
+ };
1331
+
1332
+ export const OPTY: Record<AgentShapeId, number> = {
1333
+ "dome": 21.4242,
1334
+ "gumdrop": 17.1466,
1335
+ "cushion": 18.1068,
1336
+ "pebble": 25.1939,
1337
+ "capsule": 15.0188,
1338
+ "cloud": 27.6431,
1339
+ "egg": 15.2563,
1340
+ "mochi": 30.1353,
1341
+ "kettle": 27.8453,
1342
+ "mug": 20.8761,
1343
+ "padlock": 20.3776,
1344
+ "safe": 16.8761
1345
+ };
1346
+
1347
+ /** geom() per shape as the page measures it (top anchor, half-width per row at y = i / 2, footprint at y 104). */
1348
+ export const GEOMS: Record<AgentShapeId, { top: [number, number]; HW: number[]; foot: [number, number] }> = {"dome":{"top":[60,30],"HW":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4.5,6.5,9,10.5,11.5,13,14,15,16,17,18,18.5,19.5,20,21,21.5,22,22.5,23,23.5,24,25,25,25.5,26,26.5,27,27.5,28,28.5,28.5,29,29.5,30,30,30.5,31,31.5,31.5,32,32,32.5,33,33,33.5,33.5,34,34,34.5,34.5,35,35,35.5,35.5,36,36,36.5,36.5,37,37,37,37.5,37.5,38,38,38,38.5,38.5,38.5,39,39,39,39.5,39.5,39.5,40,40,40,40,40.5,40.5,40.5,41,41,41,41,41,41.5,41.5,41.5,41.5,42,42,42,42,42,42,42.5,42.5,42.5,42.5,42.5,42.5,43,43,43,43,43,43,43,43.5,43.5,43.5,43.5,43.5,43.5,43.5,43.5,43.5,43.5,43.5,43.5,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,43.5,43.5,43.5,43,43,42.5,42.5,42,41,40.5,39,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"foot":[17,103]},"gumdrop":{"top":[60,16],"HW":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.5,2.5,3.5,4,5,5.5,6,6.5,7,7.5,8,8.5,9,9.5,9.5,10,10.5,11,11.5,12,12,12.5,13,13.5,13.5,14,14.5,14.5,15,15.5,16,16,16.5,17,17,17.5,18,18,18.5,19,19,19.5,19.5,20,20.5,20.5,21,21,21.5,22,22,22.5,23,23,23.5,23.5,24,24,24.5,25,25,25.5,25.5,26,26,26.5,27,27,27.5,27.5,28,28,28.5,28.5,29,29,29.5,29.5,30,30,30.5,31,31,31.5,31.5,32,32,32.5,32.5,33,33,33.5,33.5,34,34,34.5,34.5,34.5,35,35,35.5,35.5,36,36,36.5,36.5,37,37,37.5,37.5,38,38,38,38.5,38.5,39,39,39.5,39.5,39.5,40,40,40.5,40.5,40.5,41,41,41.5,41.5,41.5,42,42,42.5,42.5,42.5,43,43,43,43.5,43.5,43.5,44,44,44,44.5,44.5,44.5,45,45,45,45,45.5,45.5,45.5,45.5,45.5,46,46,46,46,46,46,46,46,46,46,46,45.5,45.5,45.5,45,45,45,44.5,44,44,43.5,43,42.5,41.5,40.5,39.5,38,35.5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"foot":[16.5,103]},"cushion":{"top":[60,27.5],"HW":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10.5,17,21.5,25,27.5,30,32,33.5,35,36.5,37.5,38.5,39.5,40,40.5,41,41.5,42,42.5,43,43,43.5,43.5,43.5,44,44,44.5,44.5,44.5,44.5,45,45,45,45,45,45.5,45.5,45.5,45.5,45.5,45.5,45.5,45.5,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,45.5,45.5,45.5,45.5,45,45,45,45,44.5,44.5,44,44,43.5,43,42.5,42.5,42,41.5,40.5,40,39,37.5,36,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"foot":[18,101.5]},"pebble":{"top":[60,40],"HW":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5.5,9,12,14,16,17,18.5,20,21,22.5,23.5,24.5,25.5,26,27,28,28.5,29.5,30,30.5,31.5,32,32.5,33,33.5,34.5,35,35.5,36,36.5,36.5,37,37.5,38,38.5,39,39.5,39.5,40,40.5,40.5,41,41.5,41.5,42,42.5,42.5,43,43,43.5,43.5,44,44,44.5,44.5,45,45,45,45.5,45.5,45.5,46,46,46,46.5,46.5,46.5,47,47,47,47,47.5,47.5,47.5,47.5,47.5,47.5,47.5,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,47.5,47.5,47.5,47.5,47.5,47,47,47,46.5,46.5,46.5,46,46,46,45.5,45,45,44.5,44.5,44,43.5,43.5,43,42.5,42,41.5,41,40.5,40,39,38.5,37.5,37,36,35,33.5,32,30.5,28.5,25.5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"foot":[23,96]},"capsule":{"top":[60,20],"HW":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4.5,7.5,9.5,11,12.5,13.5,14.5,15.5,16.5,17.5,18,18.5,19.5,20,20.5,21,21.5,22,22.5,23,23,23.5,24,24.5,24.5,25,25,25.5,26,26,26.5,26.5,27,27,27,27.5,27.5,27.5,28,28,28,28.5,28.5,28.5,29,29,29,29,29,29.5,29.5,29.5,29.5,29.5,29.5,29.5,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,29.5,29.5,29.5,29.5,29,29,28.5,28.5,28,28,27.5,27,26.5,26,25,24.5,23,22,19.5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"foot":[33,86.5]},"cloud":{"top":[60,45],"HW":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24.5,25,25.5,26,26.5,27,27.5,28,28.5,28.5,29,29,29.5,29.5,30,30,30.5,30.5,30.5,31,31,31,31,31.5,31.5,31.5,31.5,31.5,31.5,35,37,38,39,40,41,41.5,42,42.5,43,43.5,44,44.5,45,45,45.5,46,46,46.5,46.5,46.5,47,47,47,47.5,47.5,47.5,47.5,48,48,48,48,48,48,48,48,48,48,48,48.5,48.5,48.5,48.5,48.5,48.5,48.5,48.5,48,48,48,48,48,47.5,47.5,47.5,47.5,47.5,47.5,47.5,48,48,48,48,48,48,48,48,48,48,48,48,48,47.5,47.5,47.5,47.5,47,47,46.5,46.5,46,46,45.5,45,45,44.5,44,43.5,43,42,41.5,40.5,39.5,38.5,37,34.5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"foot":[17.5,103]},"egg":{"top":[60,20],"HW":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.5,6,7.5,9,10,11.5,12.5,13,14,14.5,15.5,16.5,17,17.5,18,18.5,19,19.5,20,20.5,21,21.5,22,22.5,23,23.5,23.5,24,24.5,24.5,25,25.5,26,26,26.5,27,27,27.5,27.5,28,28.5,28.5,29,29,29.5,29.5,30,30,30.5,30.5,31,31,31,31.5,31.5,32,32,32.5,32.5,32.5,33,33,33,33.5,33.5,33.5,34,34,34,34.5,34.5,34.5,35,35,35,35,35.5,35.5,35.5,36,36,36,36,36,36.5,36.5,36.5,36.5,36.5,37,37,37,37,37,37,37.5,37.5,37.5,37.5,37.5,37.5,37.5,37.5,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,37.5,37.5,37.5,37.5,37.5,37.5,37,37,37,37,36.5,36.5,36.5,36,36,35.5,35.5,35.5,35,35,34.5,34.5,34,33.5,33.5,33,32.5,32.5,32,31.5,31,30.5,30,29.5,29,28.5,27.5,27,26.5,25.5,25,24,23,22,21,19.5,18.5,17,15,13,10.5,6.5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"foot":[39,80]},"mochi":{"top":[60,50],"HW":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6.5,10.5,13.5,15.5,17.5,19.5,21,22.5,24,25,26.5,27.5,28.5,29.5,30.5,31.5,32,33,34,34.5,35.5,36,36.5,37.5,38,38.5,39,40,40.5,41,41.5,42,42.5,43,43.5,44,44.5,44.5,45,45.5,46,46,46.5,47,47,47.5,48,48,48.5,48.5,49,49,49.5,49.5,50,50,50,50.5,50.5,50.5,51,51,51,51.5,51.5,51.5,51.5,51.5,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,51.5,51.5,51.5,51.5,51,51,51,50.5,50.5,50.5,50,50,49.5,49,49,48.5,48,47.5,47,46.5,46,45.5,45,44,43.5,42.5,41.5,40.5,39,37.5,36,33.5,30,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"foot":[17.5,102]},"kettle":{"top":[60,44],"HW":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4.5,7.5,9.5,11,13,14,15,16,17,18,19,20,20.5,21.5,22,22.5,23.5,24,24.5,25,25.5,26,26.5,27,27.5,28,28.5,29,29.5,29.5,30,30.5,31,31,31.5,32,32,32.5,33,33,33.5,33.5,34,34.5,34.5,35,35,35.5,35.5,36,36,36.5,36.5,46.5,46,46,45.5,45,44.5,44,43.5,43,42.5,42,41.5,40.5,40,39.5,39.5,39.5,39.5,39.5,40,40,40,40,40.5,40.5,40.5,40.5,40.5,40.5,41,41,41,41,41,41.5,41.5,41.5,41.5,41.5,41.5,41.5,41.5,41.5,41.5,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,41.5,41.5,41.5,41,41,40.5,40.5,40,39,38.5,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"foot":[19,101]},"mug":{"top":[60,34],"HW":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,34.5,36,37.5,38,39,39.5,40.5,41,41,41.5,42,42.5,42.5,43,43,43.5,43.5,43.5,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44.5,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44.5,44.5,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,43.5,43.5,43.5,43,43,43,42.5,42,42,41.5,41,41,40.5,39.5,39,38.5,37.5,36.5,35,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"foot":[19,82.5]},"padlock":{"top":[60,14],"HW":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,28.5,30,31,32,33,33.5,34.5,35,35.5,36,36.5,36.5,37,37.5,38,38,38.5,38.5,39,39,39,39.5,39.5,39.5,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,39.5,39.5,39.5,39,39,39,38.5,38.5,38,38,37.5,37.5,37,36.5,36.5,36,35.5,35,34.5,33.5,33,32.5,31.5,30.5,29,27.5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"foot":[25.5,94]},"safe":{"top":[60,30],"HW":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,34.5,36.5,37.5,38.5,39.5,40.5,41,41.5,42,42.5,43,43.5,44,44,44.5,44.5,45,45,45,45.5,45.5,45.5,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,45.5,45.5,45.5,45.5,45,45,44.5,44.5,44,44,43.5,43.5,43,42.5,42,41.5,41,40.5,40,39,38,36.5,35,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"foot":[22,97.5]}};
1349
+ ```
1350
+
1351
+ ### ../lib/agent-characters/places.ts
1352
+
1353
+ ```tsx
1354
+ // Places in the product and how a character is drawn there (handoff 05 §2.1; D1, D2, D3, D9, D26).
1355
+ // Size picks only the renderer: 16–32 px is the flat glyph, 40 px and up the 3D character.
1356
+ // Liveness and the contact shadow are set per place; a new place gets them from design.
1357
+
1358
+ export type AgentGlyphSize = 16 | 20 | 24 | 32;
1359
+ export type AgentAvatarSize = 40 | 48 | 56 | 72 | 120;
1360
+
1361
+ interface GlyphPlace {
1362
+ size: AgentGlyphSize;
1363
+ renderer: 'glyph';
1364
+ live: false;
1365
+ shadow: false;
1366
+ }
1367
+ interface AvatarPlace {
1368
+ size: AgentAvatarSize;
1369
+ renderer: '3d';
1370
+ live: boolean;
1371
+ shadow: boolean;
1372
+ }
1373
+
1374
+ export const PLACES = {
1375
+ /** in text, chips, history and principal names, beside text-sm or larger (D3) */
1376
+ inline: { size: 20, renderer: 'glyph', live: false, shadow: false },
1377
+ /** in text beside text-xs (D3, D26: 16 px is the floor) */
1378
+ inlineXs: { size: 16, renderer: 'glyph', live: false, shadow: false },
1379
+ /** table rows: «Found by», «Agent», run rows */
1380
+ tableRow: { size: 20, renderer: 'glyph', live: false, shadow: false },
1381
+ /** Overview and Agent team rows of active agents, with the idle repertoire and the look-around (D2) */
1382
+ overviewRow: { size: 40, renderer: '3d', live: true, shadow: false },
1383
+ /** Overview: a Not set up or «Soon» row, static */
1384
+ overviewSetup: { size: 40, renderer: '3d', live: false, shadow: false },
1385
+ /** Approval policy full-screen header, toasts, run headers */
1386
+ header: { size: 48, renderer: '3d', live: false, shadow: false },
1387
+ /** a row beside people's avatars */
1388
+ peopleRow: { size: 56, renderer: '3d', live: false, shadow: false },
1389
+ /** Agent team card */
1390
+ teamCard: { size: 72, renderer: '3d', live: true, shadow: false },
1391
+ /** Agent drawer header */
1392
+ drawerHeader: { size: 72, renderer: '3d', live: true, shadow: true },
1393
+ /** Wally's empty chat (D9) */
1394
+ emptyChat: { size: 120, renderer: '3d', live: true, shadow: true },
1395
+ } as const satisfies Record<string, GlyphPlace | AvatarPlace>;
1396
+
1397
+ export type AgentPlace = keyof typeof PLACES;
1398
+
1399
+ export const rendererFor = (size: number): 'glyph' | '3d' => (size <= 32 ? 'glyph' : '3d');
1400
+ ```
1401
+
1402
+ ### AgentAvatar/stories/FrameMeter.tsx
1403
+
1404
+ ```tsx
1405
+ import { type FC, useEffect, useState } from 'react';
1406
+ import { subscribeFrames } from './subscribeFrames';
1407
+
1408
+ /** Story-only: engine frames per second and JavaScript per frame, refreshed every second. */
1409
+ export const FrameMeter: FC = () => {
1410
+ const [meter, setMeter] = useState({ fps: 0, js: 0, max: 0 });
1411
+ useEffect(() => {
1412
+ const acc = { n: 0, sum: 0, max: 0 };
1413
+ const stop = subscribeFrames(js => {
1414
+ acc.n++;
1415
+ acc.sum += js;
1416
+ acc.max = Math.max(acc.max, js);
1417
+ });
1418
+ const id = setInterval(() => {
1419
+ setMeter({ fps: acc.n, js: acc.n ? acc.sum / acc.n : 0, max: acc.max });
1420
+ acc.n = 0;
1421
+ acc.sum = 0;
1422
+ acc.max = 0;
1423
+ }, 1000);
1424
+ return () => {
1425
+ clearInterval(id);
1426
+ stop();
1427
+ };
1428
+ }, []);
1429
+ return (
1430
+ <span
1431
+ className='sb-annotation'
1432
+ data-testid='agent-avatar-meter'
1433
+ data-fps={meter.fps}
1434
+ data-js={meter.js.toFixed(3)}
1435
+ data-max={meter.max.toFixed(3)}
1436
+ >
1437
+ {`${meter.fps} fps · ${meter.js.toFixed(2)} ms JS per frame (max ${meter.max.toFixed(2)})`}
1438
+ </span>
1439
+ );
1440
+ };
1441
+ ```
1442
+
1443
+ ### AgentAvatar/stories/subscribeFrames.ts
1444
+
1445
+ ```tsx
1446
+ // Story-only: the engine's frame meter for ManyOnScreen (excluded from the build). It reads the runtime's dev timing
1447
+ // hook, which is not public API, through one dispatcher so meters can mount and unmount in any order.
1448
+ import { getRuntime } from '../../../lib/agent-characters/runtime';
1449
+
1450
+ const meters = new Set<(jsMs: number) => void>();
1451
+ const dispatch = (jsMs: number) => {
1452
+ for (const m of meters) m(jsMs);
1453
+ };
1454
+
1455
+ /** Calls `fn` with the loop's JavaScript time on every engine frame; returns how to stop. */
1456
+ export function subscribeFrames(fn: (jsMs: number) => void) {
1457
+ const rt = getRuntime();
1458
+ meters.add(fn);
1459
+ rt.onFrame = dispatch;
1460
+ return () => {
1461
+ meters.delete(fn);
1462
+ if (!meters.size && rt.onFrame === dispatch) rt.onFrame = undefined;
1463
+ };
1464
+ }
1465
+ ```
1466
+
1467
+ ### ../lib/agent-characters/runtime.ts
1468
+
1469
+ ```tsx
1470
+ // The document runtime (07 §6.5, D7): the reference page's page-level state — the frame loop and `LIVE`, the
1471
+ // behaviour budget `ACT`, the inviter slot `INV`, the rect epoch, the IntersectionObserver, the
1472
+ // bake queue and caches, the id counter — gathered in one object per document. It sits on
1473
+ // `globalThis[Symbol.for('wallarm.agent-characters')]`, so every bundled copy of the design system on the page
1474
+ // (a Module Federation remote inside the host) joins the same loop, budget and caches. It holds DOM nodes and data,
1475
+ // never React objects. `frame()` is the page's `frame` (reference lines 2003–2007), line for line. No cursor follow
1476
+ // (D10) and so no pointer tracking; listeners and the observer exist only while a character is live.
1477
+ import type { Baked, BakeRunner } from './bake';
1478
+ import { createQueue, Lru } from './queue';
1479
+
1480
+ /** Bumped only when the contract below changes. */
1481
+ export const PROTOCOL = 1;
1482
+ export const RUNTIME_KEY = Symbol.for('wallarm.agent-characters');
1483
+
1484
+ /** What the runtime and other characters read from a live character (the page reads these off `LIVE` members). */
1485
+ export interface LiveChar {
1486
+ svg: Element;
1487
+ visible: boolean;
1488
+ rectDirty: boolean;
1489
+ st: string;
1490
+ clips: readonly { act?: number; inv?: number; perk?: number; kind?: string; rel?: number }[];
1491
+ tick(now: number, dt: number, beat: boolean): void;
1492
+ }
1493
+
1494
+ export interface Runtime {
1495
+ protocol: number;
1496
+ /** the page's LIVE */
1497
+ live: Set<LiveChar>;
1498
+ /** at most `cap` idle behaviours at once on the document, starts at least 700 ms apart */
1499
+ act: { last: number; cap: number };
1500
+ /** one inviter per document, at least 6 s between invites */
1501
+ inv: { last: number; owner: LiveChar | null };
1502
+ rectEpoch: number;
1503
+ /** reduced: the system setting (followed live while subscribed); enabled: the off switch (P7) */
1504
+ motion: { reduced: boolean; enabled: boolean };
1505
+ queue: ReturnType<typeof createQueue>;
1506
+ caches: {
1507
+ /** height fields per outline */
1508
+ hc: Lru<Float32Array>;
1509
+ /** baked layers; an entry a mounted <image> still shows is never evicted */
1510
+ bc: Lru<Baked>;
1511
+ retain: Map<string, number>;
1512
+ inflight: Map<string, Promise<Baked>>;
1513
+ /** region() per outline, and its measuring path */
1514
+ reg: Map<string, [number, number, number]>;
1515
+ measure: SVGPathElement | null;
1516
+ };
1517
+ /** the bake worker runner, created on first use */
1518
+ worker: BakeRunner | null;
1519
+ /** Dev and test timing hook (03 §10.5): the loop's JavaScript per frame, in ms. One slot, not a public API:
1520
+ * only measurement code (tests, the Storybook frame meter) sets it. */
1521
+ onFrame?: (jsMs: number) => void;
1522
+ motionOn(): boolean;
1523
+ setMotionEnabled(on: boolean): void;
1524
+ /** called on any change of `motion` */
1525
+ subscribe(fn: () => void): () => void;
1526
+ register(ch: LiveChar): void;
1527
+ unregister(ch: LiveChar): void;
1528
+ kick(): void;
1529
+ frame(t: number): void;
1530
+ nextId(): string;
1531
+ }
1532
+
1533
+ function createRuntime(): Runtime {
1534
+ const hasDom = typeof document !== 'undefined';
1535
+ const RM =
1536
+ hasDom && typeof window.matchMedia === 'function'
1537
+ ? window.matchMedia('(prefers-reduced-motion: reduce)')
1538
+ : null;
1539
+ const subs = new Set<() => void>();
1540
+ const notify = () => {
1541
+ for (const fn of [...subs]) fn();
1542
+ };
1543
+ let uid = 0;
1544
+ let lastT = 0;
1545
+ let lastBeat = 0;
1546
+ let looping = false;
1547
+ let raf = 0;
1548
+ const retain = new Map<string, number>();
1549
+ const byNode = new WeakMap<Element, LiveChar>();
1550
+ const stop = () => {
1551
+ looping = false;
1552
+ lastT = 0;
1553
+ if (raf && typeof cancelAnimationFrame === 'function') cancelAnimationFrame(raf);
1554
+ raf = 0;
1555
+ };
1556
+
1557
+ // Document listeners and the IntersectionObserver exist only while a character is live (07 §6.4).
1558
+ let io: IntersectionObserver | null = null;
1559
+ const bump = () => {
1560
+ rt.rectEpoch++;
1561
+ };
1562
+ const onVisibility = () => {
1563
+ lastT = 0;
1564
+ lastBeat = 0;
1565
+ if (!document.hidden) rt.kick();
1566
+ };
1567
+ // capture: a scroll inside a container (a list, a drawer) moves the characters too
1568
+ const scrollOpts: AddEventListenerOptions = { capture: true, passive: true };
1569
+ const attach = () => {
1570
+ if (!hasDom) return;
1571
+ if (typeof IntersectionObserver !== 'undefined')
1572
+ io = new IntersectionObserver(
1573
+ es => {
1574
+ for (const e of es) {
1575
+ const c = byNode.get(e.target);
1576
+ if (c) {
1577
+ c.visible = e.isIntersecting;
1578
+ c.rectDirty = true;
1579
+ if (e.isIntersecting) rt.kick();
1580
+ }
1581
+ }
1582
+ },
1583
+ { rootMargin: '100px' },
1584
+ );
1585
+ window.addEventListener('scroll', bump, scrollOpts);
1586
+ window.addEventListener('resize', bump, { passive: true });
1587
+ document.addEventListener('visibilitychange', onVisibility);
1588
+ };
1589
+ const detach = () => {
1590
+ stop();
1591
+ if (!hasDom) return;
1592
+ io?.disconnect();
1593
+ io = null;
1594
+ window.removeEventListener('scroll', bump, scrollOpts);
1595
+ window.removeEventListener('resize', bump);
1596
+ document.removeEventListener('visibilitychange', onVisibility);
1597
+ };
1598
+ const drop = (ch: LiveChar) => {
1599
+ rt.live.delete(ch);
1600
+ io?.unobserve(ch.svg);
1601
+ if (rt.inv.owner === ch) rt.inv.owner = null;
1602
+ if (!rt.live.size) detach();
1603
+ };
1604
+ // The system setting is followed only while someone subscribes; otherwise it is read when asked.
1605
+ const onReduced = (e: MediaQueryListEvent) => {
1606
+ rt.motion.reduced = e.matches;
1607
+ if (rt.motionOn()) rt.kick();
1608
+ else stop();
1609
+ notify();
1610
+ };
1611
+
1612
+ const rt: Runtime = {
1613
+ protocol: PROTOCOL,
1614
+ live: new Set(),
1615
+ act: { last: 0, cap: 2 },
1616
+ inv: { last: -1e9, owner: null },
1617
+ rectEpoch: 0,
1618
+ motion: { reduced: !!RM?.matches, enabled: true },
1619
+ queue: createQueue(),
1620
+ caches: {
1621
+ hc: new Lru<Float32Array>(64),
1622
+ bc: new Lru<Baked>(
1623
+ 256,
1624
+ b => URL.revokeObjectURL(b.url),
1625
+ k => retain.has(k),
1626
+ ),
1627
+ retain,
1628
+ inflight: new Map(),
1629
+ reg: new Map(),
1630
+ measure: null,
1631
+ },
1632
+ worker: null,
1633
+ motionOn: () => {
1634
+ if (!subs.size && RM) rt.motion.reduced = RM.matches;
1635
+ return rt.motion.enabled && !rt.motion.reduced;
1636
+ },
1637
+ setMotionEnabled(on) {
1638
+ if (rt.motion.enabled === on) return;
1639
+ rt.motion.enabled = on;
1640
+ if (on) rt.kick();
1641
+ else stop();
1642
+ notify();
1643
+ },
1644
+ subscribe(fn) {
1645
+ if (!subs.size && RM) {
1646
+ rt.motion.reduced = RM.matches;
1647
+ RM.addEventListener?.('change', onReduced);
1648
+ }
1649
+ subs.add(fn);
1650
+ return () => {
1651
+ if (subs.delete(fn) && !subs.size) RM?.removeEventListener?.('change', onReduced);
1652
+ };
1653
+ },
1654
+ register(ch) {
1655
+ if (rt.live.has(ch)) return;
1656
+ if (!rt.live.size) attach();
1657
+ rt.live.add(ch);
1658
+ byNode.set(ch.svg, ch);
1659
+ io?.observe(ch.svg);
1660
+ rt.kick();
1661
+ },
1662
+ unregister(ch) {
1663
+ if (rt.live.has(ch)) drop(ch);
1664
+ else if (rt.inv.owner === ch) rt.inv.owner = null;
1665
+ },
1666
+ /** the loop runs only while a live character is in view */
1667
+ kick() {
1668
+ if (
1669
+ !looping &&
1670
+ rt.motionOn() &&
1671
+ rt.live.size &&
1672
+ typeof requestAnimationFrame === 'function'
1673
+ ) {
1674
+ looping = true;
1675
+ lastT = 0;
1676
+ raf = requestAnimationFrame(rt.frame);
1677
+ }
1678
+ },
1679
+ frame(t) {
1680
+ raf = 0;
1681
+ if (!rt.motionOn()) return stop();
1682
+ const t0 = rt.onFrame ? performance.now() : 0;
1683
+ const dt = Math.min(0.05, lastT ? (t - lastT) / 1000 : 0.016);
1684
+ lastT = t;
1685
+ const beat = t - lastBeat >= 40;
1686
+ if (beat) lastBeat = t; // one shared ~20–25 Hz beat, whatever the refresh rate
1687
+ let any = false;
1688
+ for (const c of rt.live) {
1689
+ if (!c.svg.isConnected) {
1690
+ drop(c);
1691
+ continue;
1692
+ }
1693
+ if (c.visible) {
1694
+ any = true;
1695
+ if (!document.hidden) c.tick(t, dt, beat);
1696
+ }
1697
+ }
1698
+ rt.onFrame?.(performance.now() - t0);
1699
+ if (any) raf = requestAnimationFrame(rt.frame);
1700
+ else stop();
1701
+ },
1702
+ nextId: () => `k${(++uid).toString(36)}`,
1703
+ };
1704
+ return rt;
1705
+ }
1706
+
1707
+ /** The document's runtime: the first copy to ask creates it, later copies join it. */
1708
+ export function getRuntime(): Runtime {
1709
+ const g = globalThis as { [RUNTIME_KEY]?: Runtime };
1710
+ // ponytail: protocol 1 only. A bump must keep one runtime per document: the newer copy adapts the older
1711
+ // registrations instead of starting a second loop (07 §6.5).
1712
+ g[RUNTIME_KEY] ??= createRuntime();
1713
+ return g[RUNTIME_KEY];
1714
+ }
1715
+ ```
1716
+
1717
+ ### ../lib/agent-characters/queue.ts
1718
+
1719
+ ```tsx
1720
+ // The page's bake queue (enqueue/pump): jobs run in 14 ms slices, 16 ms apart, so a cold view never blocks a frame
1721
+ // for long. Jobs whose node left the document are dropped.
1722
+
1723
+ export interface Job {
1724
+ alive: () => boolean;
1725
+ run: () => void;
1726
+ }
1727
+
1728
+ export function createQueue() {
1729
+ const queue: Job[] = [];
1730
+ let busy = false;
1731
+ const pump = () => {
1732
+ const t0 = performance.now();
1733
+ while (queue.length && performance.now() - t0 < 14) {
1734
+ const j = queue.shift() as Job;
1735
+ if (!j.alive()) continue;
1736
+ try {
1737
+ j.run();
1738
+ } catch (e) {
1739
+ console.error(e);
1740
+ }
1741
+ }
1742
+ if (queue.length) setTimeout(pump, 16);
1743
+ else busy = false;
1744
+ };
1745
+ return {
1746
+ enqueue(job: Job, front = false) {
1747
+ if (front) queue.unshift(job);
1748
+ else queue.push(job);
1749
+ if (!busy) {
1750
+ busy = true;
1751
+ setTimeout(pump, 0);
1752
+ }
1753
+ },
1754
+ };
1755
+ }
1756
+
1757
+ /** A Map in insertion order, refreshed on read: the first key is the least recently used. */
1758
+ export class Lru<V> {
1759
+ private readonly map = new Map<string, V>();
1760
+ constructor(
1761
+ private readonly cap: number,
1762
+ private readonly onEvict: (v: V) => void = () => undefined,
1763
+ /** a pinned entry is never evicted (a mounted character still shows it) */
1764
+ private readonly isPinned: (k: string) => boolean = () => false,
1765
+ ) {}
1766
+ has(k: string) {
1767
+ return this.map.has(k);
1768
+ }
1769
+ get(k: string) {
1770
+ const v = this.map.get(k);
1771
+ if (v !== undefined) {
1772
+ this.map.delete(k);
1773
+ this.map.set(k, v);
1774
+ }
1775
+ return v;
1776
+ }
1777
+ set(k: string, v: V) {
1778
+ const prev = this.map.get(k);
1779
+ if (prev !== undefined && prev !== v) this.onEvict(prev); // a replaced value is gone too
1780
+ this.map.delete(k);
1781
+ this.map.set(k, v);
1782
+ if (this.map.size <= this.cap) return;
1783
+ // oldest first, skipping pinned entries; past the cap only while everything left is pinned
1784
+ for (const [key, value] of [...this.map]) {
1785
+ if (this.map.size <= this.cap) break;
1786
+ if (key === k || this.isPinned(key)) continue; // never the entry just set
1787
+ this.map.delete(key);
1788
+ this.onEvict(value);
1789
+ }
1790
+ }
1791
+ }
1792
+
1793
+ /** Runs a runner's jobs through the queue, so main-thread bakes come in 14 ms slices instead of one long task. */
1794
+ export const queuedRunner =
1795
+ <J, R>(run: (job: J) => Promise<R>, q: ReturnType<typeof createQueue>) =>
1796
+ (job: J): Promise<R> =>
1797
+ new Promise((ok, fail) =>
1798
+ q.enqueue({
1799
+ alive: () => true,
1800
+ run: () => {
1801
+ run(job).then(ok, fail); // the synchronous part (mask, solve, shade) runs inside the slice
1802
+ },
1803
+ }),
1804
+ );
1805
+ ```