synabun 2.1.0 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (332) hide show
  1. package/CHANGELOG.md +139 -0
  2. package/README.md +1 -1
  3. package/docs/whatsapp.md +11 -11
  4. package/lib/client-config-repair.js +13 -9
  5. package/lib/external-tools.js +6 -5
  6. package/lib/update-snapshot.js +77 -3
  7. package/lib/virustotal.mjs +12 -1
  8. package/mcp-server/dist/index.js +1 -1
  9. package/mcp-server/dist/index.js.map +1 -1
  10. package/mcp-server/dist/services/budget-judgments.d.ts +1 -1
  11. package/mcp-server/dist/services/budget-judgments.d.ts.map +1 -1
  12. package/mcp-server/dist/services/budget-judgments.js +5 -3
  13. package/mcp-server/dist/services/budget-judgments.js.map +1 -1
  14. package/mcp-server/dist/services/identity.d.ts +2 -2
  15. package/mcp-server/dist/services/identity.js +2 -2
  16. package/mcp-server/dist/services/memory-sessions.d.ts +1 -1
  17. package/mcp-server/dist/services/memory-sessions.d.ts.map +1 -1
  18. package/mcp-server/dist/services/memory-sessions.js +28 -2
  19. package/mcp-server/dist/services/memory-sessions.js.map +1 -1
  20. package/mcp-server/dist/services/neural-interface.d.ts +2 -1
  21. package/mcp-server/dist/services/neural-interface.d.ts.map +1 -1
  22. package/mcp-server/dist/services/neural-interface.js.map +1 -1
  23. package/mcp-server/dist/services/server-instructions.d.ts.map +1 -1
  24. package/mcp-server/dist/services/server-instructions.js +2 -1
  25. package/mcp-server/dist/services/server-instructions.js.map +1 -1
  26. package/mcp-server/dist/services/tool-catalog.js +1 -1
  27. package/mcp-server/dist/services/tool-catalog.js.map +1 -1
  28. package/mcp-server/dist/services/tool-list.d.ts +1 -1
  29. package/mcp-server/dist/services/tool-list.d.ts.map +1 -1
  30. package/mcp-server/dist/services/tool-runtime.d.ts +2 -2
  31. package/mcp-server/dist/services/tool-runtime.d.ts.map +1 -1
  32. package/mcp-server/dist/services/tool-runtime.js +1 -1
  33. package/mcp-server/dist/services/tool-runtime.js.map +1 -1
  34. package/mcp-server/dist/services/typesafe-config.js +1 -1
  35. package/mcp-server/dist/services/typesafe-config.js.map +1 -1
  36. package/mcp-server/dist/tools/agents.d.ts +8 -8
  37. package/mcp-server/dist/tools/agents.d.ts.map +1 -1
  38. package/mcp-server/dist/tools/agents.js +10 -9
  39. package/mcp-server/dist/tools/agents.js.map +1 -1
  40. package/mcp-server/dist/tools/choice.d.ts +6 -0
  41. package/mcp-server/dist/tools/choice.d.ts.map +1 -1
  42. package/mcp-server/dist/tools/choice.js +18 -13
  43. package/mcp-server/dist/tools/choice.js.map +1 -1
  44. package/mcp-server/dist/tools/git-tools.js +2 -2
  45. package/mcp-server/dist/tools/git-tools.js.map +1 -1
  46. package/mcp-server/dist/tools/morelogin.d.ts.map +1 -1
  47. package/mcp-server/dist/tools/morelogin.js +9 -6
  48. package/mcp-server/dist/tools/morelogin.js.map +1 -1
  49. package/mcp-server/dist/tools/skill-tools.d.ts +8 -8
  50. package/mcp-server/dist/tools/skill-tools.d.ts.map +1 -1
  51. package/mcp-server/dist/tools/skill-tools.js +11 -8
  52. package/mcp-server/dist/tools/skill-tools.js.map +1 -1
  53. package/mcp-server/package-lock.json +2 -2
  54. package/mcp-server/package.json +1 -1
  55. package/mcp-server/src/index.ts +1 -1
  56. package/mcp-server/src/services/budget-judgments.ts +5 -3
  57. package/mcp-server/src/services/identity.ts +2 -2
  58. package/mcp-server/src/services/memory-sessions.ts +24 -3
  59. package/mcp-server/src/services/neural-interface.ts +2 -1
  60. package/mcp-server/src/services/server-instructions.ts +2 -1
  61. package/mcp-server/src/services/tool-catalog.ts +1 -1
  62. package/mcp-server/src/services/tool-list.ts +1 -1
  63. package/mcp-server/src/services/tool-runtime.ts +2 -2
  64. package/mcp-server/src/services/typesafe-config.ts +1 -1
  65. package/mcp-server/src/tools/agents.ts +10 -9
  66. package/mcp-server/src/tools/choice.ts +17 -12
  67. package/mcp-server/src/tools/git-tools.ts +2 -2
  68. package/mcp-server/src/tools/morelogin.ts +6 -4
  69. package/mcp-server/src/tools/skill-tools.ts +11 -8
  70. package/neural-interface/i18n/en.json +504 -39
  71. package/neural-interface/i18n/pt-BR.json +504 -39
  72. package/neural-interface/lib/agent-sandbox-elevation.js +6 -0
  73. package/neural-interface/lib/antigravity/acp-client-host.js +554 -0
  74. package/neural-interface/lib/antigravity/acp-connection.js +299 -0
  75. package/neural-interface/lib/antigravity/bypass.js +100 -0
  76. package/neural-interface/lib/antigravity/catalog.js +273 -0
  77. package/neural-interface/lib/antigravity/home.js +260 -0
  78. package/neural-interface/lib/antigravity/migrate-gemini.js +139 -0
  79. package/neural-interface/lib/antigravity/panel-bridge.js +1058 -0
  80. package/neural-interface/lib/antigravity/policy-hook.mjs +78 -0
  81. package/neural-interface/lib/antigravity/policy.js +74 -0
  82. package/neural-interface/lib/antigravity/tool-call.js +178 -0
  83. package/neural-interface/lib/antigravity/transcripts.js +252 -0
  84. package/neural-interface/lib/antigravity/usage.js +43 -0
  85. package/neural-interface/lib/assistant-api.js +1 -0
  86. package/neural-interface/lib/assistant-brains/antigravity.js +423 -0
  87. package/neural-interface/lib/assistant-brains/codex.js +6 -1
  88. package/neural-interface/lib/assistant-budget-planner.js +7 -3
  89. package/neural-interface/lib/assistant-budget-split.js +42 -15
  90. package/neural-interface/lib/assistant-catalog.js +76 -9
  91. package/neural-interface/lib/assistant-config.js +6 -3
  92. package/neural-interface/lib/assistant-dispatch.js +211 -50
  93. package/neural-interface/lib/assistant-envelope.js +153 -1
  94. package/neural-interface/lib/assistant-evidence.js +80 -0
  95. package/neural-interface/lib/assistant-hidden-models.js +7 -5
  96. package/neural-interface/lib/assistant-persona.js +16 -11
  97. package/neural-interface/lib/assistant-plan-permissions.js +15 -0
  98. package/neural-interface/lib/assistant-router.js +237 -35
  99. package/neural-interface/lib/assistant-runtime.js +158 -12
  100. package/neural-interface/lib/assistant-task-prompt.js +10 -8
  101. package/neural-interface/lib/assistant-tools.js +2 -2
  102. package/neural-interface/lib/assistant-usage.js +29 -0
  103. package/neural-interface/lib/backup-service.js +6 -1
  104. package/neural-interface/lib/browser-guard-cdp.js +5 -4
  105. package/neural-interface/lib/browser-network-guard.js +274 -82
  106. package/neural-interface/lib/browser-tool-policy.js +12 -7
  107. package/neural-interface/lib/claude-agent-bridge.js +7 -0
  108. package/neural-interface/lib/claude-history-cache.js +210 -0
  109. package/neural-interface/lib/claude-model-catalog.js +5 -1
  110. package/neural-interface/lib/cli-install-api.js +1 -1
  111. package/neural-interface/lib/cli-install.js +160 -31
  112. package/neural-interface/lib/cli-resolver.js +9 -2
  113. package/neural-interface/lib/cli-update-planner.js +25 -15
  114. package/neural-interface/lib/codex-rollout-reader.js +52 -0
  115. package/neural-interface/lib/codex-worker-app-server.js +25 -6
  116. package/neural-interface/lib/editor-git-api.js +3 -20
  117. package/neural-interface/lib/exec-loop-command.js +9 -2
  118. package/neural-interface/lib/file-explorer-api.js +74 -40
  119. package/neural-interface/lib/file-explorer-watch.js +9 -3
  120. package/neural-interface/lib/git-bash/install.js +52 -6
  121. package/neural-interface/lib/git-bash/manager.js +59 -17
  122. package/neural-interface/lib/git-bash/pins.js +12 -0
  123. package/neural-interface/lib/git-read.js +2 -2
  124. package/neural-interface/lib/git-status-runner.js +390 -0
  125. package/neural-interface/lib/git-status-watchdog.js +40 -0
  126. package/neural-interface/lib/greeting/budgets.js +1 -0
  127. package/neural-interface/lib/greeting/engine.js +2 -2
  128. package/neural-interface/lib/greeting/sources.js +10 -12
  129. package/neural-interface/lib/greeting/writer.js +1 -1
  130. package/neural-interface/lib/mcp-client-config.js +37 -6
  131. package/neural-interface/lib/mcp-external-servers.js +40 -7
  132. package/neural-interface/lib/mcp-installer.js +2 -1
  133. package/neural-interface/lib/memory-session-capture.js +17 -3
  134. package/neural-interface/lib/morelogin.js +147 -25
  135. package/neural-interface/lib/native-loop-providers.js +423 -23
  136. package/neural-interface/lib/native-loop-runtime.js +23 -2
  137. package/neural-interface/lib/opencode-native-boundary.js +165 -22
  138. package/neural-interface/lib/owner-authority.js +1 -1
  139. package/neural-interface/lib/path-confine.js +12 -9
  140. package/neural-interface/lib/peer-identity.js +80 -6
  141. package/neural-interface/lib/pty-host/core.js +28 -1
  142. package/neural-interface/lib/pty-host/lifetime.js +12 -0
  143. package/neural-interface/lib/pty-host/manager.js +12 -1
  144. package/neural-interface/lib/remote-policy.js +1 -1
  145. package/neural-interface/lib/request-gate.js +3 -0
  146. package/neural-interface/lib/rulesets/api.js +6 -5
  147. package/neural-interface/lib/rulesets/fs-safe.js +1 -1
  148. package/neural-interface/lib/rulesets/installer.js +89 -10
  149. package/neural-interface/lib/rulesets/render.js +1 -1
  150. package/neural-interface/lib/session-cache-builder.js +64 -1
  151. package/neural-interface/lib/skills/catalog.js +5 -1
  152. package/neural-interface/lib/skills/creation-brief.js +1 -1
  153. package/neural-interface/lib/skills/creation-sources.js +19 -1
  154. package/neural-interface/lib/skills/deploy.js +9 -4
  155. package/neural-interface/lib/skills/draft-confinement.js +3 -1
  156. package/neural-interface/lib/skills/eval-confinement.js +3 -1
  157. package/neural-interface/lib/skills/eval-trace.js +16 -0
  158. package/neural-interface/lib/skills/export.js +5 -2
  159. package/neural-interface/lib/skills/known-bridge-digests.json +58 -4
  160. package/neural-interface/lib/skills/ownership.js +1 -1
  161. package/neural-interface/lib/skills/roots.js +10 -3
  162. package/neural-interface/lib/skills/runtime-checks.js +6 -3
  163. package/neural-interface/lib/skills/service.js +15 -7
  164. package/neural-interface/lib/skills/telemetry.js +6 -0
  165. package/neural-interface/lib/synabun-version.js +1 -1
  166. package/neural-interface/lib/system-activity.js +1 -1
  167. package/neural-interface/lib/whatsapp/brain.js +7 -3
  168. package/neural-interface/lib/whatsapp/cards.js +22 -9
  169. package/neural-interface/lib/whatsapp/config.js +1 -1
  170. package/neural-interface/lib/worker-confinement.js +77 -1
  171. package/neural-interface/lib/worker-question.js +74 -0
  172. package/neural-interface/lib/worker-resume.js +13 -4
  173. package/neural-interface/lib/worker-sandbox.js +46 -16
  174. package/neural-interface/package-lock.json +18 -2
  175. package/neural-interface/package.json +2 -1
  176. package/neural-interface/public/onboarding.html +1 -1
  177. package/neural-interface/public/shared/agent-runtime-options.js +89 -11
  178. package/neural-interface/public/shared/agy/agy-bypass.js +47 -0
  179. package/neural-interface/public/shared/agy/agy-client.js +266 -0
  180. package/neural-interface/public/shared/agy/agy-commands.js +120 -0
  181. package/neural-interface/public/shared/agy/agy-copy.js +326 -0
  182. package/neural-interface/public/shared/agy/agy-diff.js +161 -0
  183. package/neural-interface/public/shared/agy/agy-events.js +469 -0
  184. package/neural-interface/public/shared/agy/agy-greeting.js +26 -0
  185. package/neural-interface/public/shared/agy/agy-options.js +232 -0
  186. package/neural-interface/public/shared/agy/agy-panel.js +2543 -0
  187. package/neural-interface/public/shared/agy/agy-render.js +392 -0
  188. package/neural-interface/public/shared/agy/agy-setup.js +149 -0
  189. package/neural-interface/public/shared/agy/agy-styles.js +604 -0
  190. package/neural-interface/public/shared/agy/agy-tabs-logic.js +181 -0
  191. package/neural-interface/public/shared/api.js +4 -4
  192. package/neural-interface/public/shared/assistant/asst-agents-dock.js +3 -4
  193. package/neural-interface/public/shared/assistant/asst-api.js +15 -3
  194. package/neural-interface/public/shared/assistant/asst-brain-picker.js +56 -9
  195. package/neural-interface/public/shared/assistant/asst-budget.js +5 -4
  196. package/neural-interface/public/shared/assistant/asst-computer.js +26 -2
  197. package/neural-interface/public/shared/assistant/asst-control.js +48 -0
  198. package/neural-interface/public/shared/assistant/asst-hosts.js +16 -7
  199. package/neural-interface/public/shared/assistant/asst-limit-dock.js +6 -1
  200. package/neural-interface/public/shared/assistant/asst-limit-wait.js +38 -5
  201. package/neural-interface/public/shared/assistant/asst-motion-gate.js +80 -0
  202. package/neural-interface/public/shared/assistant/asst-panel.js +46 -9
  203. package/neural-interface/public/shared/assistant/asst-render.js +112 -18
  204. package/neural-interface/public/shared/assistant/asst-route.js +237 -57
  205. package/neural-interface/public/shared/assistant/asst-routes-editor.js +9 -8
  206. package/neural-interface/public/shared/assistant/asst-scene-styles.js +55 -23
  207. package/neural-interface/public/shared/assistant/asst-scenes.js +279 -80
  208. package/neural-interface/public/shared/assistant/asst-sidepanel-styles.js +4 -4
  209. package/neural-interface/public/shared/assistant/asst-sidepanel.js +51 -7
  210. package/neural-interface/public/shared/assistant/asst-slash.js +8 -2
  211. package/neural-interface/public/shared/assistant/asst-state.js +76 -9
  212. package/neural-interface/public/shared/assistant/asst-style-cache.js +44 -0
  213. package/neural-interface/public/shared/assistant/asst-styles.js +58 -4
  214. package/neural-interface/public/shared/assistant/asst-tool-kinds.js +34 -7
  215. package/neural-interface/public/shared/assistant/asst-usage.js +2 -1
  216. package/neural-interface/public/shared/cdx/cdx-output.js +26 -3
  217. package/neural-interface/public/shared/cdx/cdx-panel.js +14 -2
  218. package/neural-interface/public/shared/cdx/cdx-preview.js +12 -0
  219. package/neural-interface/public/shared/cdx/cdx-protocol.js +11 -10
  220. package/neural-interface/public/shared/cdx/cdx-render.js +10 -9
  221. package/neural-interface/public/shared/cdx/cdx-requests.js +11 -1
  222. package/neural-interface/public/shared/cdx/cdx-styles.js +4 -0
  223. package/neural-interface/public/shared/cdx/cdx-tabs.js +75 -5
  224. package/neural-interface/public/shared/cli-install-controller.js +218 -0
  225. package/neural-interface/public/shared/cli-install-view.js +7 -4
  226. package/neural-interface/public/shared/cli-status.js +9 -8
  227. package/neural-interface/public/shared/constants.js +3 -2
  228. package/neural-interface/public/shared/context-menu-model.js +1 -0
  229. package/neural-interface/public/shared/cp/cp-permissions.js +12 -0
  230. package/neural-interface/public/shared/cp/cp-restore.js +162 -0
  231. package/neural-interface/public/shared/cp/cp-tool-cards.js +10 -3
  232. package/neural-interface/public/shared/desktop-bridge.js +17 -0
  233. package/neural-interface/public/shared/desktop-titlebar-view.js +12 -0
  234. package/neural-interface/public/shared/desktop-titlebar.js +13 -4
  235. package/neural-interface/public/shared/desktop-update-view.js +1 -0
  236. package/neural-interface/public/shared/explorer/fx-api.js +4 -4
  237. package/neural-interface/public/shared/explorer/fx-links.js +3 -3
  238. package/neural-interface/public/shared/explorer/fx-logic.js +1 -1
  239. package/neural-interface/public/shared/explorer/fx-main.js +48 -16
  240. package/neural-interface/public/shared/explorer/fx-tree.js +1 -0
  241. package/neural-interface/public/shared/greeting/greeting-card.js +2 -2
  242. package/neural-interface/public/shared/greeting/greeting-view.js +1 -0
  243. package/neural-interface/public/shared/html-shell.js +21 -4
  244. package/neural-interface/public/shared/loading-teardown.js +34 -0
  245. package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +6 -1
  246. package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +28 -7
  247. package/neural-interface/public/shared/ocp-v2/ocp-v2-rehydrate.js +13 -4
  248. package/neural-interface/public/shared/ocp-v2/ocp-v2-render.js +17 -1
  249. package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +6 -0
  250. package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +101 -68
  251. package/neural-interface/public/shared/ocp-v2/ocp-v2-ws.js +46 -3
  252. package/neural-interface/public/shared/provider-icons.js +4 -2
  253. package/neural-interface/public/shared/settings/settings-rules.js +2 -2
  254. package/neural-interface/public/shared/settings/settings-skill-folders-pane.js +1 -1
  255. package/neural-interface/public/shared/settings/settings-skill-folders.js +2 -2
  256. package/neural-interface/public/shared/showcase-privacy.js +6 -1
  257. package/neural-interface/public/shared/sidepanel-session-status.js +3 -3
  258. package/neural-interface/public/shared/skills/ss-creation.js +6 -3
  259. package/neural-interface/public/shared/skills/ss-dialog.js +5 -2
  260. package/neural-interface/public/shared/skills/ss-lint.js +9 -1
  261. package/neural-interface/public/shared/skills/ss-profiles.js +44 -6
  262. package/neural-interface/public/shared/skills/ss-review-view.js +2 -2
  263. package/neural-interface/public/shared/skills/studio/sx-actions.js +1 -1
  264. package/neural-interface/public/shared/skills/studio/sx-create-ai-view.js +1 -1
  265. package/neural-interface/public/shared/skills/studio/sx-create-ai.js +2 -1
  266. package/neural-interface/public/shared/skills/studio/sx-dom.js +2 -1
  267. package/neural-interface/public/shared/skills/studio/sx-fixes-view.js +359 -0
  268. package/neural-interface/public/shared/skills/studio/sx-fixes.js +327 -0
  269. package/neural-interface/public/shared/skills/studio/sx-inspector.js +1 -1
  270. package/neural-interface/public/shared/skills/studio/sx-install-flow.js +9 -6
  271. package/neural-interface/public/shared/skills/studio/sx-install.js +20 -3
  272. package/neural-interface/public/shared/skills/studio/sx-library-view.js +144 -35
  273. package/neural-interface/public/shared/skills/studio/sx-library.js +6 -2
  274. package/neural-interface/public/shared/skills/studio/sx-main.js +11 -2
  275. package/neural-interface/public/shared/skills/studio/sx-review-view.js +1 -1
  276. package/neural-interface/public/shared/skills/studio/sx-subject.js +7 -6
  277. package/neural-interface/public/shared/skills/studio/sx-workspace-view.js +6 -5
  278. package/neural-interface/public/shared/state.js +1 -1
  279. package/neural-interface/public/shared/storage-retry.js +47 -0
  280. package/neural-interface/public/shared/storage.js +25 -4
  281. package/neural-interface/public/shared/streaming-markdown.js +58 -0
  282. package/neural-interface/public/shared/styles.css +362 -35
  283. package/neural-interface/public/shared/synabun-mascot.js +27 -8
  284. package/neural-interface/public/shared/synabun-ticker.js +147 -12
  285. package/neural-interface/public/shared/text-cache.js +29 -0
  286. package/neural-interface/public/shared/tool-list-picker.js +2 -2
  287. package/neural-interface/public/shared/tool-list-view.js +2 -2
  288. package/neural-interface/public/shared/topright-overflow-logic.js +54 -0
  289. package/neural-interface/public/shared/ui-antigravity-panel.js +19 -0
  290. package/neural-interface/public/shared/ui-assistant.js +2 -0
  291. package/neural-interface/public/shared/ui-automation-studio.js +20 -12
  292. package/neural-interface/public/shared/ui-claude-panel.js +374 -134
  293. package/neural-interface/public/shared/ui-cli-banner.js +23 -167
  294. package/neural-interface/public/shared/ui-file-explorer.js +48 -6
  295. package/neural-interface/public/shared/ui-file-links.js +2 -2
  296. package/neural-interface/public/shared/ui-games.js +2 -2
  297. package/neural-interface/public/shared/ui-judgments.js +1 -1
  298. package/neural-interface/public/shared/ui-keybinds.js +8 -2
  299. package/neural-interface/public/shared/ui-link.js +3 -3
  300. package/neural-interface/public/shared/ui-loading.js +5 -4
  301. package/neural-interface/public/shared/ui-menubar.js +2 -2
  302. package/neural-interface/public/shared/ui-native-loop-router.js +4 -0
  303. package/neural-interface/public/shared/ui-navbar.js +45 -0
  304. package/neural-interface/public/shared/ui-notifications.js +1 -0
  305. package/neural-interface/public/shared/ui-resume.js +9 -7
  306. package/neural-interface/public/shared/ui-schedules-studio.js +41 -10
  307. package/neural-interface/public/shared/ui-scroll-follow.js +16 -5
  308. package/neural-interface/public/shared/ui-sessions.js +22 -12
  309. package/neural-interface/public/shared/ui-settings.js +90 -65
  310. package/neural-interface/public/shared/ui-sidepanel-session-entry.js +9 -2
  311. package/neural-interface/public/shared/ui-sidepanel-sessions.js +3 -3
  312. package/neural-interface/public/shared/ui-sidepanel-tray.js +48 -7
  313. package/neural-interface/public/shared/ui-sidepanel-windows.js +3 -3
  314. package/neural-interface/public/shared/ui-terminal.js +146 -10
  315. package/neural-interface/public/shared/ui-tool-updates.js +3 -3
  316. package/neural-interface/public/shared/ui-tooltip.js +71 -46
  317. package/neural-interface/public/shared/ui-topright-overflow.js +233 -0
  318. package/neural-interface/public/shared/ui-whiteboard.js +1 -1
  319. package/neural-interface/public/shared/ui-worker-end.js +1 -1
  320. package/neural-interface/public/shared/whatsapp/wa-view.js +2 -2
  321. package/neural-interface/public/shared/worker-questions.js +34 -0
  322. package/neural-interface/public/sidepanel-session.html +1 -1
  323. package/neural-interface/server.js +731 -466
  324. package/neural-interface/templates/rulesets/README.md +1 -1
  325. package/neural-interface/templates/rulesets/legacy-hashes.json +5 -5
  326. package/neural-interface/templates/rulesets/manifest.json +1 -1
  327. package/npm-shrinkwrap.json +18 -2
  328. package/package.json +2 -1
  329. package/skills/skill-forge/SKILL.md +4 -4
  330. package/skills/synabun/SKILL.md +1 -1
  331. package/skills/synabun/modules/schedule.md +3 -3
  332. /package/neural-interface/templates/rulesets/{gemini.md → antigravity.md} +0 -0
@@ -116,6 +116,8 @@ export function runChip(run, t = tFallback) {
116
116
  }
117
117
  if (awaitsAnswer(run)) return { tone: 'action', label: t('assistant.run.waitingInput', 'waiting for your answer') };
118
118
  const tone = runTone(run);
119
+ // A held run whose card the user answered "here": the assistant does it, this worker never started.
120
+ if (run?.completionReason === 'route_here') return { tone, label: t('assistant.run.routedHere', 'not started: done here instead') };
119
121
  if (run?.turnState === 'awaiting_permission') return { tone, label: t('assistant.run.needsApproval', 'needs approval') };
120
122
  if (run?.turnState === 'needs_input') return { tone, label: t('assistant.run.needsInput', 'needs input') };
121
123
  // A Claude Code worker a server restart cut off, until the next start has resumed it (lib/assistant-dispatch.js).
@@ -169,6 +171,46 @@ export const CODEX_ITEM_EVENTS = Object.freeze({
169
171
  */
170
172
  export const OPENCODE_TOOL_STATES = Object.freeze(['running', 'completed', 'error']);
171
173
 
174
+ // The path-like fields of an Antigravity tool call's arguments (lib/worker-confinement.js reads the same ones).
175
+ const ACP_PATH_KEYS = ['path', 'file_path', 'filePath', 'Path', 'AbsolutePath', 'TargetFile', 'DirectoryPath', 'SearchPath'];
176
+
177
+ /**
178
+ * An Antigravity (ACP) tool call as an activity: its `kind` says what it does (read, edit, delete,
179
+ * move, search, execute, think, fetch, switch_mode, other), its `rawInput` holds the tool's own
180
+ * arguments and its `locations` the files it touches. Another tool (an MCP server's) is read by its
181
+ * name, as for the other providers. null for a mode switch.
182
+ */
183
+ function acpToolActivity(call) {
184
+ const args = obj(call.rawInput);
185
+ const kind = str(call.kind) || 'other';
186
+ const title = str(call.title).trim();
187
+ const paths = [...new Set([
188
+ ...(Array.isArray(call.locations) ? call.locations : []).map((location) => str(location?.path)),
189
+ ...ACP_PATH_KEYS.map((key) => (typeof args[key] === 'string' ? args[key] : '')),
190
+ ].filter(Boolean))];
191
+ const pick = (...values) => values.map((v) => (typeof v === 'string' ? v.trim() : '')).find(Boolean) || '';
192
+ switch (kind) {
193
+ case 'execute': {
194
+ const command = Array.isArray(args.command) ? args.command.map(str).join(' ') : pick(args.command, args.CommandLine, args.cmd);
195
+ return { kind: 'shell', name: 'exec_command', input: { command: command || title } };
196
+ }
197
+ case 'read': return { kind: 'read', name: 'read', input: { file_path: paths[0] || title } };
198
+ case 'edit': case 'delete': case 'move':
199
+ return { kind: 'edit', name: kind === 'edit' ? 'edit' : 'apply_patch', input: paths.length > 1 ? { changes: paths.map((path) => ({ path })) } : { file_path: paths[0] || title } };
200
+ case 'search': return { kind: 'search', name: 'grep', input: { pattern: pick(args.pattern, args.query, args.Query, args.Pattern) || title, path: paths[0] || '' } };
201
+ case 'fetch': {
202
+ const url = pick(args.url, args.Url, args.href);
203
+ return url ? { kind: 'web', name: 'WebFetch', input: { url } } : { kind: 'web', name: 'WebSearch', input: { query: pick(args.query, args.Query) || title } };
204
+ }
205
+ case 'think': return { kind: 'think', name: 'thinking', input: {} };
206
+ case 'switch_mode': return null;
207
+ default: {
208
+ const name = pick(call.name, args.toolName, title) || 'tool';
209
+ return { kind: kindOf(name, args), name, input: args };
210
+ }
211
+ }
212
+ }
213
+
172
214
  /**
173
215
  * A worker's provider event ({ provider, eventType?, event }, the payload of
174
216
  * sync:sidepanel:provider-event) as what it is doing: { kind, name, input }
@@ -177,7 +219,11 @@ export const OPENCODE_TOOL_STATES = Object.freeze(['running', 'completed', 'erro
177
219
  * stage and the tray keep only compactActivity() of it. OpenCode names its
178
220
  * tools bash, read, edit, write, patch, glob, grep, list, webfetch,
179
221
  * websearch, codesearch, task, todowrite, and MCP tools `<server>_<tool>`
180
- * (SynaBun_browser_navigate): kindOf() reads all of them.
222
+ * (SynaBun_browser_navigate): kindOf() reads all of them. An Antigravity
223
+ * worker's events are ACP session updates (eventType = their `sessionUpdate`):
224
+ * a tool call when it is announced (`tool_call`, or an update that starts it
225
+ * and names its kind), a thought chunk as thinking, a plan as planning; its
226
+ * message text is no activity, as for the others.
181
227
  */
182
228
  export function activityOf(payload) {
183
229
  const provider = str(payload?.provider);
@@ -222,6 +268,13 @@ export function activityOf(payload) {
222
268
  const input = obj(part.state?.input);
223
269
  return { kind: kindOf(name, input), name, input };
224
270
  }
271
+ if (provider === 'antigravity') {
272
+ const type = str(payload.eventType || event.sessionUpdate);
273
+ if (type === 'agent_thought_chunk') return { kind: 'think', name: 'thinking', input: {} };
274
+ if (type === 'plan') return { kind: 'plan', name: 'update_plan', input: { todos: Array.isArray(event.entries) ? event.entries : [] } };
275
+ if (type === 'tool_call' || (type === 'tool_call_update' && str(event.kind) && event.status === 'in_progress')) return acpToolActivity(event);
276
+ return null;
277
+ }
225
278
  return null;
226
279
  }
227
280
 
@@ -347,12 +400,77 @@ export function stageLabel({ scene = 'generic', phase = 'working', title = '', m
347
400
  // currentColor (the container's muted text); `sc-gold` is the one live part
348
401
  // (gold only means live). Every part sits where its still frame wants it:
349
402
  // with no animation (reduced motion, waiting, settled) the scene still reads.
403
+ //
404
+ // A scene is an HTML box (`.asst-scene`, sized by its holder) holding one SVG
405
+ // of everything that stands still (`.sc-base`) and, for every part that
406
+ // moves, an HTML layer of its own (`.sc-layer`: a box over the whole scene
407
+ // with an SVG of that part alone in the same viewBox, so the part sits
408
+ // exactly where it did). The CSS moves the layer box, transform and opacity
409
+ // only, never an SVG element: a box's animation runs on the compositor, and a
410
+ // frame the page draws anyway (a rig's) restyles one span and lays nothing
411
+ // out, where a moving SVG part re-lays its whole SVG out on every frame.
412
+ // Lengths are percentages of the box, since a scene is drawn at several sizes
413
+ // (boxPct); a part that turned round its own centre (the SVG's fill-box)
414
+ // turns round the same point here (`transform-origin`). Parts on the same
415
+ // beat share a layer (the image's tiles); a part that stood above a moving
416
+ // one stays above it in a still layer of its own (`.sc-top`: the playhead).
350
417
 
351
418
  /** The code scene's six lines, repeated twice so its stepped scroll loops seamlessly: [indent, keyword, rest]. */
352
419
  export const CODE_LINES = Object.freeze([[6, 8, 26], [12, 10, 42], [12, 6, 22], [18, 9, 35], [12, 12, 48], [6, 7, 14]]);
353
420
  export const CODE_STEP = 6; // one line, in viewBox units
421
+ /** The code scene's scrolling window and the video scene's film window (full) and the mini film's: [x, y, w, h]. */
422
+ export const CODE_WINDOW = Object.freeze([4, 4, 112, 32]);
423
+ export const FILM_WINDOW = Object.freeze([4, 4, 112, 32]);
424
+ export const FILM_MINI_WINDOW = Object.freeze([2, 2, 36, 16]);
425
+
426
+ /** The viewBox of a full scene and of a mini, in units. */
427
+ export const SCENE_BOX = Object.freeze({ full: Object.freeze({ w: 120, h: 40 }), mini: Object.freeze({ w: 40, h: 20 }) });
354
428
 
355
429
  const r1 = (v) => Math.round(v * 100) / 100;
430
+ const r3 = (v) => Math.round(v * 1000) / 1000;
431
+
432
+ /** A length in viewBox units as a percentage of the box's width or height: boxPct(14, 120) → '11.667%'. */
433
+ export function boxPct(v, of) {
434
+ return `${r3((Number(v) / of) * 100)}%`;
435
+ }
436
+
437
+ /**
438
+ * The centre of a polyline path's box (M L H V Z, absolute or relative):
439
+ * where an SVG part with transform-box: fill-box turned round (a tick, the
440
+ * zap, a triangle). Curves are not read (no moving part has one).
441
+ */
442
+ export function pathCentre(d) {
443
+ const tokens = String(d).match(/[MLHVZmlhvz]|-?\d*\.?\d+/g) || [];
444
+ const xs = [];
445
+ const ys = [];
446
+ let x = 0;
447
+ let y = 0;
448
+ let sx = 0;
449
+ let sy = 0;
450
+ let cmd = 'M';
451
+ let i = 0;
452
+ const num = () => Number(tokens[i++]);
453
+ while (i < tokens.length) {
454
+ if (/^[A-Za-z]$/.test(tokens[i])) {
455
+ cmd = tokens[i];
456
+ i += 1;
457
+ if (cmd === 'Z' || cmd === 'z') { x = sx; y = sy; continue; }
458
+ }
459
+ if (cmd === 'M') { x = num(); y = num(); sx = x; sy = y; cmd = 'L'; }
460
+ else if (cmd === 'm') { x += num(); y += num(); sx = x; sy = y; cmd = 'l'; }
461
+ else if (cmd === 'L') { x = num(); y = num(); }
462
+ else if (cmd === 'l') { x += num(); y += num(); }
463
+ else if (cmd === 'H') x = num();
464
+ else if (cmd === 'h') x += num();
465
+ else if (cmd === 'V') y = num();
466
+ else if (cmd === 'v') y += num();
467
+ else { i += 1; continue; }
468
+ xs.push(x);
469
+ ys.push(y);
470
+ }
471
+ if (!xs.length) return [0, 0];
472
+ return [r3((Math.min(...xs) + Math.max(...xs)) / 2), r3((Math.min(...ys) + Math.max(...ys)) / 2)];
473
+ }
356
474
 
357
475
  /** A gear outline: n trapezoid teeth between radius r and R round (cx, cy). */
358
476
  export function gearPath(cx, cy, r, R, n) {
@@ -373,93 +491,149 @@ export function codeCaretX(s) {
373
491
  return 4 + indent + key + 3 + rest + 2;
374
492
  }
375
493
 
376
- function codeFull() {
494
+ const SVG_ATTRS = 'fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" focusable="false"';
495
+ const svgOf = (viewBox, body) => `<svg viewBox="${viewBox}" ${SVG_ATTRS}>${body}</svg>`;
496
+
497
+ /** Everything of a scene that stands still: one SVG under the layers. */
498
+ function base(box, body) {
499
+ return `<svg class="sc-base" viewBox="0 0 ${box.w} ${box.h}" width="${box.w}" height="${box.h}" ${SVG_ATTRS}>${body}</svg>`;
500
+ }
501
+
502
+ /**
503
+ * One moving part's layer, over the whole box (or over a window: clipOf).
504
+ * `cls` names its motion (the CSS animates it); `body` is the part's SVG
505
+ * markup in the box's units, or `html` another layer inside it (a caret that
506
+ * blinks inside a caret that steps). `origin` [x, y]: what rotation and scale
507
+ * turn round (the old fill-box centre, or a view-box point); `still` [x, y,
508
+ * more]: the resting transform of a part drawn at 0,0; `i`: its beat.
509
+ */
510
+ function layerOf(box, cls, body, { origin = null, still = null, i = null, html = null } = {}) {
511
+ const style = [];
512
+ if (i != null) style.push(`--i:${i}`);
513
+ if (origin) style.push(`transform-origin:${boxPct(origin[0], box.w)} ${boxPct(origin[1], box.h)}`);
514
+ if (still) style.push(`transform:translate(${boxPct(still[0], box.w)},${boxPct(still[1], box.h)})${still[2] ? ` ${still[2]}` : ''}`);
515
+ const inner = html != null ? html : svgOf(`0 0 ${box.w} ${box.h}`, body);
516
+ return `<span class="sc-layer${cls ? ` ${cls}` : ''}"${style.length ? ` style="${style.join(';')}"` : ''}>${inner}</span>`;
517
+ }
518
+
519
+ /** A still part that stood above a moving one: it stays above it. */
520
+ const topOf = (box, body) => layerOf(box, 'sc-top', body);
521
+
522
+ /** A clipped window of the scene ([x, y, w, h] in units): what scrolls inside it is cut at its edges. */
523
+ function clipOf(box, [x, y, w, h], inner) {
524
+ return `<span class="sc-clip" style="left:${boxPct(x, box.w)};top:${boxPct(y, box.h)};width:${boxPct(w, box.w)};height:${boxPct(h, box.h)}">${inner}</span>`;
525
+ }
526
+
527
+ /** Parts that share a beat (`--i`) share one layer: [{ i, body }] → one layer per beat, in first-seen order. */
528
+ function beatLayers(box, cls, parts) {
529
+ const beats = new Map();
530
+ for (const { i, body } of parts) beats.set(i, (beats.get(i) || '') + body);
531
+ return [...beats].map(([i, body]) => layerOf(box, cls, body, { i })).join('');
532
+ }
533
+
534
+ function codeFull(box) {
377
535
  let lines = '';
378
536
  for (let i = 0; i < CODE_LINES.length * 2; i += 1) {
379
537
  const [indent, key, rest] = CODE_LINES[i % CODE_LINES.length];
380
538
  const y = 5 + CODE_STEP * i;
381
539
  lines += `<path class="sc-mid" d="M${indent} ${y}h${key}"/><path class="sc-dim" d="M${indent + key + 3} ${y}h${rest}"/>`;
382
540
  }
383
- return '<rect class="sc-dim" x="1" y="1.5" width="118" height="37" rx="5"/>'
384
- + `<svg x="4" y="4" width="112" height="32" overflow="hidden"><g class="sc-code-scroll">${lines}</g></svg>`
385
- + `<g class="sc-code-caret" style="transform:translateX(${codeCaretX(0)}px)"><rect class="sc-gold sc-fill sc-caret" x="0" y="30.5" width="2" height="5" rx="1"/></g>`;
541
+ const [, , w, h] = CODE_WINDOW;
542
+ const caret = layerOf(box, 'sc-caret', '<rect class="sc-gold sc-fill" x="0" y="30.5" width="2" height="5" rx="1"/>');
543
+ return base(box, '<rect class="sc-dim" x="1" y="1.5" width="118" height="37" rx="5"/>')
544
+ + clipOf(box, CODE_WINDOW, layerOf({ w, h }, 'sc-code-scroll', lines))
545
+ + layerOf(box, 'sc-code-caret', null, { still: [codeCaretX(0), 0], html: caret });
386
546
  }
387
547
 
388
548
  const GEAR_BIG = gearPath(66, 20, 9, 12.5, 8);
389
549
  const GEAR_SMALL = gearPath(86.5, 12.5, 5.5, 8, 6);
390
550
 
391
- function complexFull() {
392
- return '<path class="sc-dim" d="M14 7h13l5 5v21H14z"/><path class="sc-mid" d="M8 11h13l5 5v21H8zM21 11v5h5M12 23h9M12 28h11"/>'
393
- + `<g class="sc-gear-big sc-box"><path class="sc-mid" d="${GEAR_BIG}"/><circle class="sc-dim" cx="66" cy="20" r="3.2"/></g>`
394
- + `<g class="sc-gear-small sc-box"><path class="sc-gold" d="${GEAR_SMALL}"/><circle class="sc-gold" cx="86.5" cy="12.5" r="2"/></g>`
395
- + '<path class="sc-dim" d="M98 30h14M102 25h10"/>';
551
+ function complexFull(box) {
552
+ return base(box, '<path class="sc-dim" d="M14 7h13l5 5v21H14z"/><path class="sc-mid" d="M8 11h13l5 5v21H8zM21 11v5h5M12 23h9M12 28h11"/><path class="sc-dim" d="M98 30h14M102 25h10"/>')
553
+ + layerOf(box, 'sc-gear-big', `<path class="sc-mid" d="${GEAR_BIG}"/><circle class="sc-dim" cx="66" cy="20" r="3.2"/>`, { origin: [66, 20] })
554
+ + layerOf(box, 'sc-gear-small', `<path class="sc-gold" d="${GEAR_SMALL}"/><circle class="sc-gold" cx="86.5" cy="12.5" r="2"/>`, { origin: [86.5, 12.5] });
396
555
  }
397
556
 
398
- function reviewFull() {
557
+ /** A review tick, its own layer (it pops round its own centre). */
558
+ function tickLayer(box, d, i) {
559
+ return layerOf(box, 'sc-tick', `<path class="sc-gold" d="${d}"/>`, { origin: pathCentre(d), i });
560
+ }
561
+
562
+ function reviewFull(box) {
399
563
  const rows = [[9, '+', 52], [16, '-', 64], [23, '+', 40], [30, '+', 58]];
400
- let out = '<rect class="sc-dim" x="1" y="1.5" width="118" height="37" rx="5"/>';
564
+ let still = '<rect class="sc-dim" x="1" y="1.5" width="118" height="37" rx="5"/>';
565
+ let ticks = '';
401
566
  rows.forEach(([y, sign, len], i) => {
402
- out += sign === '+' ? `<path class="sc-mid" d="M6 ${y}h4M8 ${y - 2}v4"/>` : `<path class="sc-mid" d="M6 ${y}h4"/>`;
403
- out += `<path class="sc-dim" d="M15 ${y}h${len}"/>`;
404
- out += `<path class="sc-gold sc-tick sc-box" style="--i:${i}" d="M${95} ${y}l2.2 2.2 4.4-4.6"/>`;
567
+ still += sign === '+' ? `<path class="sc-mid" d="M6 ${y}h4M8 ${y - 2}v4"/>` : `<path class="sc-mid" d="M6 ${y}h4"/>`;
568
+ still += `<path class="sc-dim" d="M15 ${y}h${len}"/>`;
569
+ ticks += tickLayer(box, `M95 ${y}l2.2 2.2 4.4-4.6`, i);
405
570
  });
406
- return out;
571
+ return base(box, still) + ticks;
407
572
  }
408
573
 
409
- function researchFull() {
574
+ function researchFull(box) {
410
575
  const page = (x) => `<rect class="sc-dim" x="${x}" y="4" width="40" height="32" rx="3"/><path class="sc-dim" d="M${x + 6} 11h26M${x + 6} 17h22M${x + 6} 23h28M${x + 6} 29h16"/>`;
411
- return page(8) + page(56)
412
- + '<g class="sc-lens"><circle class="sc-gold" cx="24" cy="17" r="7"/><path class="sc-gold" d="M29.2 22.2l5 5"/></g>';
576
+ return base(box, page(8) + page(56))
577
+ + layerOf(box, 'sc-lens', '<circle class="sc-gold" cx="24" cy="17" r="7"/><path class="sc-gold" d="M29.2 22.2l5 5"/>');
413
578
  }
414
579
 
415
580
  const POINTER = 'M0 0v10.5l2.8-2.6 2 4.4 2-.9-2-4.3h3.9z';
416
581
 
417
- function browserFull() {
418
- return '<rect class="sc-dim" x="1" y="1.5" width="118" height="37" rx="5"/><path class="sc-dim" d="M1 9.5h118"/>'
582
+ /** A click's ring (a layer that starts invisible: .sc-ring) and the pointer that clicks there (drawn at 0,0, placed by its layer). */
583
+ function pointerLayers(box, kind, [cx, cy], r) {
584
+ return layerOf(box, `sc-ring sc-ripple-${kind}`, `<circle class="sc-gold" cx="${cx}" cy="${cy}" r="${r}"/>`, { origin: [cx, cy] })
585
+ + layerOf(box, `sc-point-${kind}`, `<path class="sc-gold sc-fill" d="${POINTER}"/>`, { still: [cx, cy] });
586
+ }
587
+
588
+ function browserFull(box) {
589
+ return base(box, '<rect class="sc-dim" x="1" y="1.5" width="118" height="37" rx="5"/><path class="sc-dim" d="M1 9.5h118"/>'
419
590
  + '<circle class="sc-mid sc-fill" cx="6" cy="5.5" r="1"/><circle class="sc-mid sc-fill" cx="10" cy="5.5" r="1"/><circle class="sc-mid sc-fill" cx="14" cy="5.5" r="1"/>'
420
591
  + '<rect class="sc-dim" x="22" y="3.5" width="56" height="4" rx="2"/>'
421
- + '<path class="sc-mid" d="M8 16h36"/><path class="sc-dim" d="M8 22h54M8 27h44M8 32h30"/><rect class="sc-mid" x="78" y="25" width="28" height="8" rx="2"/>'
422
- + '<circle class="sc-gold sc-ring sc-ripple-browser sc-box" cx="92" cy="29" r="5"/>'
423
- + `<g class="sc-point-browser" style="transform:translate(92px,29px)"><path class="sc-gold sc-fill" d="${POINTER}"/></g>`;
592
+ + '<path class="sc-mid" d="M8 16h36"/><path class="sc-dim" d="M8 22h54M8 27h44M8 32h30"/><rect class="sc-mid" x="78" y="25" width="28" height="8" rx="2"/>')
593
+ + pointerLayers(box, 'browser', [92, 29], 5);
424
594
  }
425
595
 
426
- function computerFull() {
427
- return '<rect class="sc-dim" x="10" y="1.5" width="100" height="30" rx="3"/><path class="sc-dim" d="M60 31.5v4M48 37.5h24"/>'
596
+ function computerFull(box) {
597
+ return base(box, '<rect class="sc-dim" x="10" y="1.5" width="100" height="30" rx="3"/><path class="sc-dim" d="M60 31.5v4M48 37.5h24"/>'
428
598
  + '<rect class="sc-mid sc-shade" x="16" y="6" width="44" height="20" rx="2"/><path class="sc-dim" d="M16 10h44M21 15h20M21 20h28"/>'
429
- + '<rect class="sc-mid sc-shade" x="52" y="11" width="50" height="17" rx="2"/><path class="sc-dim" d="M52 15h50"/><rect class="sc-mid" x="84" y="20" width="13" height="5" rx="1.5"/>'
430
- + '<circle class="sc-gold sc-ring sc-ripple-computer sc-box" cx="90" cy="22.5" r="4.5"/>'
431
- + `<g class="sc-point-computer" style="transform:translate(90px,22.5px)"><path class="sc-gold sc-fill" d="${POINTER}"/></g>`;
599
+ + '<rect class="sc-mid sc-shade" x="52" y="11" width="50" height="17" rx="2"/><path class="sc-dim" d="M52 15h50"/><rect class="sc-mid" x="84" y="20" width="13" height="5" rx="1.5"/>')
600
+ + pointerLayers(box, 'computer', [90, 22.5], 4.5);
432
601
  }
433
602
 
434
- function automationFull() {
435
- return '<circle class="sc-mid" cx="18" cy="20" r="13"/><path class="sc-dim" d="M18 9v2M18 29v2M7 20h2M27 20h2"/>'
436
- + '<path class="sc-mid" d="M18 20l5-4"/>'
437
- + '<g class="sc-hand sc-vb" style="transform-origin:18px 20px"><path class="sc-gold" d="M18 20v-9"/></g><circle class="sc-gold sc-fill" cx="18" cy="20" r="1.6"/>'
603
+ function automationFull(box) {
604
+ // The hub dot sits in the still SVG: hand and dot are the same gold, so which is on top shows nowhere.
605
+ return base(box, '<circle class="sc-mid" cx="18" cy="20" r="13"/><path class="sc-dim" d="M18 9v2M18 29v2M7 20h2M27 20h2"/>'
606
+ + '<path class="sc-mid" d="M18 20l5-4"/><circle class="sc-gold sc-fill" cx="18" cy="20" r="1.6"/>'
438
607
  + '<path class="sc-dim" d="M52 24h14M76 24h14"/><rect class="sc-mid" x="44" y="20" width="8" height="8" rx="2"/><rect class="sc-mid" x="66" y="20" width="10" height="8" rx="2"/><rect class="sc-mid" x="90" y="20" width="8" height="8" rx="2"/>'
439
- + '<path class="sc-dim" d="M94 17c0-9-46-9-46 0M48 17l-2.5-3M48 17l3-2"/>'
440
- + '<g class="sc-run-dot"><circle class="sc-gold sc-fill" cx="48" cy="24" r="2.2"/></g>';
608
+ + '<path class="sc-dim" d="M94 17c0-9-46-9-46 0M48 17l-2.5-3M48 17l3-2"/>')
609
+ + layerOf(box, 'sc-hand', '<path class="sc-gold" d="M18 20v-9"/>', { origin: [18, 20] })
610
+ + layerOf(box, 'sc-run-dot', '<circle class="sc-gold sc-fill" cx="48" cy="24" r="2.2"/>');
441
611
  }
442
612
 
443
- function designFull() {
444
- return '<rect class="sc-gold sc-fill sc-swatch" x="4" y="5" width="9" height="9" rx="2"/><rect class="sc-mid sc-fill sc-swatch-b" x="4" y="16" width="9" height="9" rx="2"/><rect class="sc-dim sc-fill sc-swatch-c" x="4" y="27" width="9" height="9" rx="2"/>'
445
- + '<rect class="sc-dim" x="20" y="2.5" width="96" height="35" rx="4"/>'
446
- + '<circle class="sc-mid sc-shape sc-box" style="--i:0" cx="40" cy="20" r="8"/>'
447
- + '<rect class="sc-mid sc-shape sc-box" style="--i:1" x="58" y="12" width="16" height="16" rx="3"/>'
448
- + '<path class="sc-mid sc-shape sc-box" style="--i:2" d="M86 28l9-16 9 16z"/>'
449
- + '<g class="sc-pen" style="transform:translate(40px,20px)"><path class="sc-gold" d="M0 0l6-6M6-6l2.5 2.5M0 0l-1.2 3.7L2.5 2.5z"/></g>';
613
+ const TRIANGLE = 'M86 28l9-16 9 16z';
614
+
615
+ function designFull(box) {
616
+ return base(box, '<rect class="sc-gold sc-fill sc-swatch" x="4" y="5" width="9" height="9" rx="2"/><rect class="sc-mid sc-fill sc-swatch-b" x="4" y="16" width="9" height="9" rx="2"/><rect class="sc-dim sc-fill sc-swatch-c" x="4" y="27" width="9" height="9" rx="2"/>'
617
+ + '<rect class="sc-dim" x="20" y="2.5" width="96" height="35" rx="4"/>')
618
+ + layerOf(box, 'sc-shape', '<circle class="sc-mid" cx="40" cy="20" r="8"/>', { origin: [40, 20], i: 0 })
619
+ + layerOf(box, 'sc-shape', '<rect class="sc-mid" x="58" y="12" width="16" height="16" rx="3"/>', { origin: [66, 20], i: 1 })
620
+ + layerOf(box, 'sc-shape', `<path class="sc-mid" d="${TRIANGLE}"/>`, { origin: pathCentre(TRIANGLE), i: 2 })
621
+ + layerOf(box, 'sc-pen', '<path class="sc-gold" d="M0 0l6-6M6-6l2.5 2.5M0 0l-1.2 3.7L2.5 2.5z"/>', { still: [40, 20] });
450
622
  }
451
623
 
452
- function imageFull() {
453
- let tiles = '';
624
+ const SPARKLE = 'M104 6l1.6 4.4L110 12l-4.4 1.6L104 18l-1.6-4.4L98 12l4.4-1.6z';
625
+
626
+ function imageFull(box) {
627
+ const tiles = [];
454
628
  for (let row = 0; row < 3; row += 1) {
455
629
  for (let col = 0; col < 4; col += 1) {
456
630
  const gold = (row === 1 && col === 2) || (row === 2 && col === 0);
457
- tiles += `<rect class="${gold ? 'sc-gold' : 'sc-mid'} sc-fill sc-tile" style="--i:${row + col}" x="${34 + col * 13.5}" y="${6 + row * 10}" width="11.5" height="8" rx="1.5"/>`;
631
+ tiles.push({ i: row + col, body: `<rect class="${gold ? 'sc-gold' : 'sc-mid'} sc-fill" x="${34 + col * 13.5}" y="${6 + row * 10}" width="11.5" height="8" rx="1.5"/>` });
458
632
  }
459
633
  }
460
- return `<rect class="sc-dim" x="30" y="2.5" width="61" height="35" rx="3"/>${tiles}`
461
- + '<g class="sc-sparkle sc-box"><path class="sc-gold sc-fill" d="M104 6l1.6 4.4L110 12l-4.4 1.6L104 18l-1.6-4.4L98 12l4.4-1.6z"/></g>'
462
- + '<path class="sc-dim" d="M100 26h12M100 31h8"/>';
634
+ return base(box, '<rect class="sc-dim" x="30" y="2.5" width="61" height="35" rx="3"/><path class="sc-dim" d="M100 26h12M100 31h8"/>')
635
+ + beatLayers(box, 'sc-tile', tiles)
636
+ + layerOf(box, 'sc-sparkle', `<path class="sc-gold sc-fill" d="${SPARKLE}"/>`, { origin: pathCentre(SPARKLE) });
463
637
  }
464
638
 
465
639
  function filmFrames(width, y, h, frameW, count) {
@@ -469,47 +643,71 @@ function filmFrames(width, y, h, frameW, count) {
469
643
  return out;
470
644
  }
471
645
 
472
- function videoFull() {
473
- return `<svg x="4" y="4" width="112" height="32" overflow="hidden"><g class="sc-film">${filmFrames(160, 2, 28, 24, 7)}</g></svg>`
474
- + '<path class="sc-gold" d="M58 2v36M55 2h6l-3 3z"/>';
646
+ function videoFull(box) {
647
+ const [, , w, h] = FILM_WINDOW;
648
+ return base(box, '')
649
+ + clipOf(box, FILM_WINDOW, layerOf({ w, h }, 'sc-film', filmFrames(160, 2, 28, 24, 7)))
650
+ + topOf(box, '<path class="sc-gold" d="M58 2v36M55 2h6l-3 3z"/>');
475
651
  }
476
652
 
477
653
  /** An open-end wrench, horizontal, its jaw round (0, 0): place it with translate(bolt) rotate(a) translate(3.5 0). */
478
654
  const WRENCH = 'M-4.6 -3.86L-1 -2V2L-4.6 3.86A6 6 0 0 0 5.5 2.4H24A2.4 2.4 0 0 0 24 -2.4H5.5A6 6 0 0 0 -4.6 -3.86Z';
479
655
  const hexagon = (cx, cy, r) => `M${[0, 1, 2, 3, 4, 5].map(i => `${r1(cx + r * Math.cos(i * Math.PI / 3))} ${r1(cy + r * Math.sin(i * Math.PI / 3))}`).join('L')}Z`;
656
+ const ZAP = 'M92 5l-8 15h7l-3 14 11-18h-7.5z';
657
+
658
+ /** Sparks off the bolt: one layer each (they flash one after another). */
659
+ const sparkLayers = (box, ds) => ds.map((d, i) => layerOf(box, 'sc-spark', `<path class="sc-gold" d="${d}"/>`, { i })).join('');
480
660
 
481
- function quickFull() {
482
- return `<path class="sc-mid" d="${hexagon(38, 24, 3.4)}"/>`
483
- + `<g class="sc-wrench sc-vb" style="transform-origin:38px 24px"><path class="sc-gold" transform="translate(38 24) rotate(-32) translate(3.5 0)" d="${WRENCH}"/></g>`
484
- + '<path class="sc-gold sc-spark" style="--i:0" d="M30.5 19.5l-3-2"/><path class="sc-gold sc-spark" style="--i:1" d="M29.5 24.5h-3.5"/><path class="sc-gold sc-spark" style="--i:2" d="M30.5 29.5l-3 2"/>'
485
- + '<g class="sc-zap sc-box"><path class="sc-gold" d="M92 5l-8 15h7l-3 14 11-18h-7.5z"/></g>';
661
+ function quickFull(box) {
662
+ return base(box, `<path class="sc-mid" d="${hexagon(38, 24, 3.4)}"/>`)
663
+ + layerOf(box, 'sc-wrench', `<path class="sc-gold" transform="translate(38 24) rotate(-32) translate(3.5 0)" d="${WRENCH}"/>`, { origin: [38, 24] })
664
+ + sparkLayers(box, ['M30.5 19.5l-3-2', 'M29.5 24.5h-3.5', 'M30.5 29.5l-3 2'])
665
+ + layerOf(box, 'sc-zap', `<path class="sc-gold" d="${ZAP}"/>`, { origin: pathCentre(ZAP) });
486
666
  }
487
667
 
488
- function genericFull() {
489
- return '<path class="sc-dim" d="M14 20h92"/><circle class="sc-mid" cx="14" cy="20" r="3"/><circle class="sc-mid" cx="60" cy="20" r="3"/><circle class="sc-mid" cx="106" cy="20" r="3"/>'
490
- + '<g class="sc-slide"><rect class="sc-gold sc-fill" x="14" y="18.5" width="24" height="3" rx="1.5"/></g>';
668
+ function genericFull(box) {
669
+ return base(box, '<path class="sc-dim" d="M14 20h92"/><circle class="sc-mid" cx="14" cy="20" r="3"/><circle class="sc-mid" cx="60" cy="20" r="3"/><circle class="sc-mid" cx="106" cy="20" r="3"/>')
670
+ + layerOf(box, 'sc-slide', '<rect class="sc-gold sc-fill" x="14" y="18.5" width="24" height="3" rx="1.5"/>');
491
671
  }
492
672
 
673
+ const MINI_TRIANGLE = 'M29 15l4.5-8 4.5 8z';
674
+
493
675
  // Minis (40×20, the tray at 32×16): one gesture each.
494
676
  const MINI = {
495
- code: () => '<path class="sc-mid" d="M5 5h20M9 10h24M5 15h14"/><rect class="sc-gold sc-fill sc-caret" x="21.5" y="12.5" width="1.8" height="5" rx=".9"/>',
496
- complex: () => `<g class="sc-gear-big sc-box"><path class="sc-mid" d="${gearPath(14, 11, 4.5, 6.6, 6)}"/></g><g class="sc-gear-small sc-box"><path class="sc-gold" d="${gearPath(26.5, 7.5, 3, 4.6, 6)}"/></g>`,
497
- review: () => '<path class="sc-dim" d="M4 5h20M4 10h24M4 15h18"/><path class="sc-gold sc-tick sc-box" style="--i:0" d="M30 5l1.6 1.6 3.2-3.4"/><path class="sc-gold sc-tick sc-box" style="--i:1" d="M32 10l1.6 1.6 3.2-3.4"/>',
498
- research: () => '<rect class="sc-dim" x="3" y="2.5" width="26" height="15" rx="2"/><path class="sc-dim" d="M7 7h16M7 11h12M7 15h14"/><g class="sc-lens-mini"><circle class="sc-gold" cx="12" cy="9" r="3.8"/><path class="sc-gold" d="M14.8 11.8l2.8 2.8"/></g>',
499
- browser: () => `<rect class="sc-dim" x="2" y="2" width="36" height="16" rx="2.5"/><path class="sc-dim" d="M2 6h36"/><rect class="sc-mid" x="24" y="11" width="10" height="4" rx="1.2"/><g class="sc-point-mini" style="transform:translate(29px,13px) scale(.6)"><path class="sc-gold sc-fill" d="${POINTER}"/></g>`,
500
- computer: () => `<rect class="sc-dim" x="5" y="1.5" width="30" height="14" rx="2"/><path class="sc-dim" d="M20 15.5v2M15 18.5h10"/><rect class="sc-mid" x="8" y="4.5" width="13" height="8" rx="1"/><g class="sc-point-mini" style="transform:translate(29px,13px) scale(.6)"><path class="sc-gold sc-fill" d="${POINTER}"/></g>`,
501
- automation: () => '<circle class="sc-mid" cx="11" cy="10" r="7.5"/><path class="sc-dim" d="M11 10l3-2.5"/><g class="sc-hand sc-vb" style="transform-origin:11px 10px"><path class="sc-gold" d="M11 10V4.5"/></g>'
502
- + '<path class="sc-mid" d="M33.5 10a5 5 0 1 1-1.5-3.6M32 3.6v2.8h-2.8"/>',
503
- design: () => '<rect class="sc-mid sc-fill" x="3" y="3" width="6" height="6" rx="1.5"/><rect class="sc-dim sc-fill" x="3" y="11" width="6" height="6" rx="1.5"/><circle class="sc-gold sc-shape sc-box" style="--i:0" cx="21" cy="10" r="5"/><path class="sc-mid sc-shape sc-box" style="--i:1" d="M29 15l4.5-8 4.5 8z"/>',
504
- image_gen: () => {
505
- let tiles = '';
506
- for (let row = 0; row < 2; row += 1) for (let col = 0; col < 3; col += 1) tiles += `<rect class="${row === 1 && col === 2 ? 'sc-gold' : 'sc-mid'} sc-fill sc-tile" style="--i:${row + col}" x="${11 + col * 6.4}" y="${5 + row * 5.6}" width="5" height="4.2" rx="1"/>`;
507
- return `<rect class="sc-dim" x="9" y="2.5" width="22" height="15" rx="2"/>${tiles}`;
677
+ code: box => base(box, '<path class="sc-mid" d="M5 5h20M9 10h24M5 15h14"/>')
678
+ + layerOf(box, 'sc-caret', '<rect class="sc-gold sc-fill" x="21.5" y="12.5" width="1.8" height="5" rx=".9"/>'),
679
+ complex: box => base(box, '')
680
+ + layerOf(box, 'sc-gear-big', `<path class="sc-mid" d="${gearPath(14, 11, 4.5, 6.6, 6)}"/>`, { origin: [14, 11] })
681
+ + layerOf(box, 'sc-gear-small', `<path class="sc-gold" d="${gearPath(26.5, 7.5, 3, 4.6, 6)}"/>`, { origin: [26.5, 7.5] }),
682
+ review: box => base(box, '<path class="sc-dim" d="M4 5h20M4 10h24M4 15h18"/>')
683
+ + tickLayer(box, 'M30 5l1.6 1.6 3.2-3.4', 0) + tickLayer(box, 'M32 10l1.6 1.6 3.2-3.4', 1),
684
+ research: box => base(box, '<rect class="sc-dim" x="3" y="2.5" width="26" height="15" rx="2"/><path class="sc-dim" d="M7 7h16M7 11h12M7 15h14"/>')
685
+ + layerOf(box, 'sc-lens-mini', '<circle class="sc-gold" cx="12" cy="9" r="3.8"/><path class="sc-gold" d="M14.8 11.8l2.8 2.8"/>'),
686
+ browser: box => base(box, '<rect class="sc-dim" x="2" y="2" width="36" height="16" rx="2.5"/><path class="sc-dim" d="M2 6h36"/><rect class="sc-mid" x="24" y="11" width="10" height="4" rx="1.2"/>')
687
+ + layerOf(box, 'sc-point-mini', `<path class="sc-gold sc-fill" d="${POINTER}"/>`, { still: [29, 13, 'scale(.6)'] }),
688
+ computer: box => base(box, '<rect class="sc-dim" x="5" y="1.5" width="30" height="14" rx="2"/><path class="sc-dim" d="M20 15.5v2M15 18.5h10"/><rect class="sc-mid" x="8" y="4.5" width="13" height="8" rx="1"/>')
689
+ + layerOf(box, 'sc-point-mini', `<path class="sc-gold sc-fill" d="${POINTER}"/>`, { still: [29, 13, 'scale(.6)'] }),
690
+ automation: box => base(box, '<circle class="sc-mid" cx="11" cy="10" r="7.5"/><path class="sc-dim" d="M11 10l3-2.5"/><path class="sc-mid" d="M33.5 10a5 5 0 1 1-1.5-3.6M32 3.6v2.8h-2.8"/>')
691
+ + layerOf(box, 'sc-hand', '<path class="sc-gold" d="M11 10V4.5"/>', { origin: [11, 10] }),
692
+ design: box => base(box, '<rect class="sc-mid sc-fill" x="3" y="3" width="6" height="6" rx="1.5"/><rect class="sc-dim sc-fill" x="3" y="11" width="6" height="6" rx="1.5"/>')
693
+ + layerOf(box, 'sc-shape', '<circle class="sc-gold" cx="21" cy="10" r="5"/>', { origin: [21, 10], i: 0 })
694
+ + layerOf(box, 'sc-shape', `<path class="sc-mid" d="${MINI_TRIANGLE}"/>`, { origin: pathCentre(MINI_TRIANGLE), i: 1 }),
695
+ image_gen: (box) => {
696
+ const tiles = [];
697
+ for (let row = 0; row < 2; row += 1) for (let col = 0; col < 3; col += 1) tiles.push({ i: row + col, body: `<rect class="${row === 1 && col === 2 ? 'sc-gold' : 'sc-mid'} sc-fill" x="${11 + col * 6.4}" y="${5 + row * 5.6}" width="5" height="4.2" rx="1"/>` });
698
+ return base(box, '<rect class="sc-dim" x="9" y="2.5" width="22" height="15" rx="2"/>') + beatLayers(box, 'sc-tile', tiles);
699
+ },
700
+ video_gen: (box) => {
701
+ const [, , w, h] = FILM_MINI_WINDOW;
702
+ return base(box, '')
703
+ + clipOf(box, FILM_MINI_WINDOW, layerOf({ w, h }, 'sc-film-mini', filmFrames(60, 1, 14, 12, 5)))
704
+ + topOf(box, '<path class="sc-gold" d="M20 1v18"/>');
508
705
  },
509
- video_gen: () => `<svg x="2" y="2" width="36" height="16" overflow="hidden"><g class="sc-film-mini">${filmFrames(60, 1, 14, 12, 5)}</g></svg><path class="sc-gold" d="M20 1v18"/>`,
510
- quick: () => `<path class="sc-mid" d="${hexagon(11, 11, 2.6)}"/><g class="sc-wrench sc-vb" style="transform-origin:11px 11px"><path class="sc-gold" stroke-width="2.4" transform="translate(11 11) rotate(-32) scale(.62) translate(3.5 0)" d="${WRENCH}"/></g>`
511
- + '<path class="sc-gold sc-spark" style="--i:0" d="M5.5 7.5l-2-1.3"/><path class="sc-gold sc-spark" style="--i:1" d="M5 11.5H2.6"/>',
512
- generic: () => '<circle class="sc-gold sc-fill sc-dot" style="--i:0" cx="11" cy="10" r="2.4"/><circle class="sc-gold sc-fill sc-dot" style="--i:1" cx="20" cy="10" r="2.4"/><circle class="sc-gold sc-fill sc-dot" style="--i:2" cx="29" cy="10" r="2.4"/>',
706
+ quick: box => base(box, `<path class="sc-mid" d="${hexagon(11, 11, 2.6)}"/>`)
707
+ + layerOf(box, 'sc-wrench', `<path class="sc-gold" stroke-width="2.4" transform="translate(11 11) rotate(-32) scale(.62) translate(3.5 0)" d="${WRENCH}"/>`, { origin: [11, 11] })
708
+ + sparkLayers(box, ['M5.5 7.5l-2-1.3', 'M5 11.5H2.6']),
709
+ generic: box => base(box, '')
710
+ + [11, 20, 29].map((cx, i) => layerOf(box, 'sc-dot', `<circle class="sc-gold sc-fill" cx="${cx}" cy="10" r="2.4"/>`, { i })).join(''),
513
711
  };
514
712
 
515
713
  const FULL = {
@@ -518,13 +716,14 @@ const FULL = {
518
716
  };
519
717
 
520
718
  /**
521
- * A scene's SVG (decorative: aria-hidden). `mini` draws the tray's 40×20
719
+ * A scene's markup (decorative: aria-hidden): an HTML box with its still SVG
720
+ * and one layer per moving part (see above). `mini` draws the tray's 40×20
522
721
  * version. `live` starts it moving (the stage and tray set data-live
523
722
  * themselves later; this is only the first state).
524
723
  */
525
724
  export function sceneSvg(scene, { mini = false, live = false, className = '' } = {}) {
526
725
  const id = Object.hasOwn(FULL, scene) ? scene : 'generic';
527
- const [w, h] = mini ? [40, 20] : [120, 40];
528
- const body = (mini ? MINI[id] : FULL[id])();
529
- return `<svg class="asst-scene${mini ? ' is-mini' : ''}${className ? ` ${className}` : ''}" data-scene="${id}"${live ? ' data-live=""' : ''} viewBox="0 0 ${w} ${h}" width="${w}" height="${h}" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">${body}</svg>`;
726
+ const box = mini ? SCENE_BOX.mini : SCENE_BOX.full;
727
+ const body = (mini ? MINI[id] : FULL[id])(box);
728
+ return `<span class="asst-scene${mini ? ' is-mini' : ''}${className ? ` ${className}` : ''}" data-scene="${id}"${live ? ' data-live=""' : ''} aria-hidden="true">${body}</span>`;
530
729
  }
@@ -459,15 +459,15 @@ export function injectAssistantSidepanelStyles() {
459
459
 
460
460
  body.ui-interacting .asp-placeholder .asp-mark,
461
461
  body.ui-interacting .asp-placeholder-track::after,
462
- body.ui-interacting .asp-status .syna-cameo-eye,
463
- body.ui-interacting .asp-session-pill .syna-cameo-eye { animation-play-state: paused !important; }
462
+ body.ui-interacting .asp-status .syna-cameo-eyes,
463
+ body.ui-interacting .asp-session-pill .syna-cameo-eyes { animation-play-state: paused !important; }
464
464
 
465
465
  @media (prefers-reduced-motion: reduce) {
466
466
  .assistant-panel { transition: opacity 0.15s ease; }
467
467
  .asp-placeholder .asp-mark,
468
468
  .asp-placeholder-track::after,
469
- .asp-status .syna-cameo-eye,
470
- .asp-session-pill .syna-cameo-eye,
469
+ .asp-status .syna-cameo-eyes,
470
+ .asp-session-pill .syna-cameo-eyes,
471
471
  .assistant-panel .asst-send::before { animation: none !important; }
472
472
  .asp-placeholder-track::after { left: 31%; }
473
473
  }