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
@@ -50,13 +50,16 @@ import { closeMenu, isMenuOpen } from './asst-menu.js';
50
50
  import { computerToolName, describeComputerAction, frameUrls, markerPercent, openFrameLightbox, parseComputerResult, swapImage } from './asst-computer.js';
51
51
  import * as mascotLib from '../synabun-mascot.js';
52
52
  import { isReducedMotion, subscribe } from '../synabun-ticker.js';
53
- import { KIND_SPECS, callOutcome, commandOf, editDiff, editPaths, fmtDuration, groupSubject, headEllipsis, kindOf, maskEcho, mcpServerOf, middleEllipsis, planState, plural, prettyServer, receiptSentence, redactInput, resultDetail, sayCall, shouldFoldNarration, stationAggregate, stationKey, targetKey, toolWords, verbText, wrapRuns } from './asst-tool-kinds.js';
53
+ import { KIND_SPECS, callOutcome, canonicalToolInput, commandOf, editDiff, editPaths, fmtDuration, groupSubject, headEllipsis, kindOf, maskEcho, mcpServerOf, middleEllipsis, planState, plural, prettyServer, receiptSentence, redactInput, resultDetail, sayCall, shouldFoldNarration, stationAggregate, stationKey, targetKey, toolWords, verbText, wrapRuns } from './asst-tool-kinds.js';
54
54
  import { injectRackStyles } from './asst-rack-styles.js';
55
55
  import { injectSceneStyles } from './asst-scene-styles.js';
56
56
  import { activityScene, compactActivity, isLivePhase, runChip, sceneOfClass, sceneSvg, stagePhase } from './asst-scenes.js';
57
57
  import { STAGE_TIMING, createWorkerStage } from './asst-run-stage.js';
58
+ import { createMotionGate } from './asst-motion-gate.js';
59
+ import { createStyleCache } from './asst-style-cache.js';
58
60
  import { formatRunTokens } from './asst-usage.js';
59
61
  import { sanitizeHtmlString, sanitizeInto } from './asst-sanitize.js';
62
+ import { renderStreamingMarkdown } from '../streaming-markdown.js';
60
63
  import { automationView } from './asst-automation.js';
61
64
  import { guessFollowups, splitFollowups } from './asst-followups.js';
62
65
  import { createFollowupsCard } from './asst-followups-card.js';
@@ -502,7 +505,9 @@ const SUGGESTION_KINDS = { computer: 'computer', web: 'web', fix: 'edit', skill:
502
505
  * onFollowup(text, { set, indices }) (a follow-up was clicked: send `text` as the user's message),
503
506
  * onFollowupOther() ("Something else…": the composer), limitInfo() → the session's limit notice
504
507
  * ({ status, resetsAt } | null), brainProvider() → the brain's provider id, onLimitRetry(text)
505
- * (Retry now on the Assistant's own limit card: send `text`) }
508
+ * (Retry now on the Assistant's own limit card: send `text`), onSwitchProvider(anchorEl, { excludeProvider, retryText })
509
+ * (Continue with another provider on the Assistant's own limit card: the host opens its own
510
+ * provider picker anchored on anchorEl and decides what a pick does) }
506
511
  */
507
512
  export function createRenderer(transcriptEl, hooks = {}) {
508
513
  loadMarked();
@@ -522,6 +527,7 @@ export function createRenderer(transcriptEl, hooks = {}) {
522
527
  // there, above the "Working…" row, until it is answered; rows appended meanwhile go above it.
523
528
  const askTail = createAskTail($msgs, { anchor: () => (working?.parentNode === $msgs ? working : null) });
524
529
  let followTail = true;
530
+ let scrollFrame = 0;
525
531
  let emptyEl = null;
526
532
  let hero = null; // the empty state's character: { rig, el, box, parked, leaving, held, dock, egg, target }
527
533
  const mcpWarned = new Set();
@@ -570,6 +576,16 @@ export function createRenderer(transcriptEl, hooks = {}) {
570
576
  const stageWidths = new WeakMap(); // stage element → { rack, width }
571
577
  const toRecut = new Set();
572
578
  let recutTimer = 0;
579
+ // What the stylesheet decides about a bubble (--rk-cut, the line's white-space) changes only with a container
580
+ // query, so only with the stage's width: read once, forgotten when the width changes (here) or the fonts load.
581
+ const styleCache = createStyleCache();
582
+ // A web font that arrives changes every measured width: the next paint of each bubble measures again.
583
+ const onFontsLoaded = () => { styleCache.invalidate(); for (const rack of racks) rack.budgetMemo = null; };
584
+ const fontSet = typeof document !== 'undefined' ? document.fonts : null;
585
+ try { fontSet?.addEventListener?.('loadingdone', onFontsLoaded); } catch { /* no FontFaceSet events */ }
586
+ const stopFontWatch = () => { try { fontSet?.removeEventListener?.('loadingdone', onFontsLoaded); } catch { /* gone */ } };
587
+ // The transcript's loops run only while their holder is on screen (run cards, racks, route lines).
588
+ const motion = createMotionGate();
573
589
  const stageResizes = typeof ResizeObserver === 'function' ? new ResizeObserver((entries) => {
574
590
  for (const entry of entries) {
575
591
  const seen = stageWidths.get(entry.target);
@@ -578,6 +594,7 @@ export function createRenderer(transcriptEl, hooks = {}) {
578
594
  if (seen.width === null) { seen.width = width; continue; } // the first report: the width it was cut at
579
595
  if (width === seen.width) continue;
580
596
  seen.width = width;
597
+ forgetBubbleStyle(seen.rack);
581
598
  toRecut.add(seen.rack);
582
599
  }
583
600
  if (!toRecut.size) return;
@@ -637,7 +654,8 @@ export function createRenderer(transcriptEl, hooks = {}) {
637
654
 
638
655
  function scrollEnd(force = false) {
639
656
  if (!force && !followTail) return;
640
- requestAnimationFrame(() => { $msgs.scrollTop = $msgs.scrollHeight; });
657
+ if (scrollFrame) return;
658
+ scrollFrame = requestAnimationFrame(() => { scrollFrame = 0; $msgs.scrollTop = $msgs.scrollHeight; });
641
659
  }
642
660
 
643
661
  function root() { return { container: $msgs, stream: null, key: null, msgId: null, lastAt: 0 }; }
@@ -948,7 +966,7 @@ export function createRenderer(transcriptEl, hooks = {}) {
948
966
  */
949
967
  function paintMessage(row, body, text, { streaming = false, scope = rootScope } = {}) {
950
968
  const split = splitFollowups(text, { streaming });
951
- renderMarkdownInto(body, split.body);
969
+ renderStreamingMarkdown(body, split.body, renderMarkdownInto, { streaming });
952
970
  if (!streaming && split.block && scope === rootScope) attachFollowups(row, split.block);
953
971
  return split;
954
972
  }
@@ -963,6 +981,10 @@ export function createRenderer(transcriptEl, hooks = {}) {
963
981
  function attachFollowups(row, set) {
964
982
  if (!row || !set?.items?.length) return null;
965
983
  if (row._followups?.el.isConnected) return row._followups;
984
+ // One turn, one card: a set offered earlier in this turn (another text segment between tool calls, a
985
+ // streamed row the final message replaced) is superseded by this one. `offers` holds only this turn's:
986
+ // the user's prompt and a new turn settle and drop the earlier ones (settleOffers), which stay as history.
987
+ supersedeFollowups(row);
966
988
  const card = createFollowupsCard(set, {
967
989
  t,
968
990
  // A card drawn from the journal comes in quietly; a live one with a nod.
@@ -972,6 +994,7 @@ export function createRenderer(transcriptEl, hooks = {}) {
972
994
  onFocusComposer: () => hooks.onFollowupOther?.(),
973
995
  });
974
996
  row._followups = card;
997
+ card._row = row;
975
998
  (row.querySelector('.asst-msg-content') || row).appendChild(card.el);
976
999
  offers.add(card);
977
1000
  registerAsk(card);
@@ -980,6 +1003,19 @@ export function createRenderer(transcriptEl, hooks = {}) {
980
1003
  return card;
981
1004
  }
982
1005
 
1006
+ /** Take out this turn's open follow-ups cards that belong to a row other than `row`. */
1007
+ function supersedeFollowups(row) {
1008
+ for (const offer of [...offers]) {
1009
+ if (!offer._row || offer._row === row) continue;
1010
+ offers.delete(offer);
1011
+ askCards.delete(offer);
1012
+ try { offer.presenter?.destroy?.(); } catch { /* gone */ }
1013
+ if (offer._row._followups === offer) offer._row._followups = null;
1014
+ offer.el?.remove();
1015
+ }
1016
+ askTail.sync();
1017
+ }
1018
+
983
1019
  /**
984
1020
  * A finished turn whose last message still ends in a list of options or an "I can X, or Y" offer,
985
1021
  * with no block: best-effort items read from the prose. Once per message.
@@ -987,6 +1023,8 @@ export function createRenderer(transcriptEl, hooks = {}) {
987
1023
  function guessOffer() {
988
1024
  const row = lastTextRow;
989
1025
  if (!row?.isConnected || row._followups || row._guessed || row.classList.contains('asst-msg-error')) return;
1026
+ // The turn already offered a set from its block: a guess from the prose would be a second card.
1027
+ for (const offer of offers) if (offer._row && offer.el?.isConnected) return;
990
1028
  row._guessed = true;
991
1029
  const set = guessFollowups(row._text || '');
992
1030
  if (set) attachFollowups(row, set);
@@ -1023,9 +1061,17 @@ export function createRenderer(transcriptEl, hooks = {}) {
1023
1061
  if (!read && !(brainError && reported)) return null;
1024
1062
  const resetsAt = reported ? info.resetsAt : read?.resetsAt;
1025
1063
  const retryText = t('assistant.limitWait.continue', 'The usage limit has reset. Retry what was blocked and continue where you left off.');
1026
- let provider = '';
1027
- try { provider = providerShortLabel(hooks.brainProvider?.() || ''); } catch { /* unknown */ }
1028
- return limitDock.set('brain', { resetsAt, since: nowMs(), provider, onRetry: () => { limitDock.set('brain', null); hooks.onLimitRetry?.(retryText); } });
1064
+ let providerId = '';
1065
+ try { providerId = hooks.brainProvider?.() || ''; } catch { /* unknown */ }
1066
+ const provider = providerId ? providerShortLabel(providerId) : '';
1067
+ return limitDock.set('brain', {
1068
+ resetsAt, since: nowMs(), provider,
1069
+ onRetry: () => { limitDock.set('brain', null); hooks.onLimitRetry?.(retryText); },
1070
+ onSwitchProvider: typeof hooks.onSwitchProvider === 'function'
1071
+ ? (anchor) => hooks.onSwitchProvider(anchor, { excludeProvider: providerId, retryText })
1072
+ : null,
1073
+ onClose: () => limitDock.set('brain', null),
1074
+ });
1029
1075
  }
1030
1076
 
1031
1077
  /** The session's limit report changed (assistant:limit): this turn's waiting card counts to its reset time. */
@@ -1368,7 +1414,7 @@ export function createRenderer(transcriptEl, hooks = {}) {
1368
1414
  const kind = kindOf(block.name, block.input);
1369
1415
  const step = {
1370
1416
  type: 'call', id: block.id || `call-${++stepSeq}`, seq: ++stepSeq, name: block.name || 'tool', kind, key: stationKey(kind, block.name),
1371
- input: block.input || {}, state: 'running', result: '', detail: '', code: null, startedAt: nowMs(), endedAt: 0, progress: 0,
1417
+ input: canonicalToolInput(block.input), state: 'running', result: '', detail: '', code: null, startedAt: nowMs(), endedAt: 0, progress: 0,
1372
1418
  timed: isTimed(), ghost, stale: false, rack, station: null, card: null, parent: parentOf(rack.scope), bodyBuilt: false,
1373
1419
  ...(extra || {}),
1374
1420
  };
@@ -1383,7 +1429,7 @@ export function createRenderer(transcriptEl, hooks = {}) {
1383
1429
  /** The final block of a streamed call, or the same block replayed: the step learns its input, nothing is added. */
1384
1430
  function updateCall(step, block) {
1385
1431
  if (block.name) step.name = block.name;
1386
- if (block.input && typeof block.input === 'object' && Object.keys(block.input).length) step.input = block.input;
1432
+ if (block.input && typeof block.input === 'object' && Object.keys(block.input).length) step.input = canonicalToolInput(block.input);
1387
1433
  step.ghost = false;
1388
1434
  if (step.card?._computer) { step.card._computer.input = step.input; step.card._computer.description = describeComputerAction(step.input, step.name); }
1389
1435
  refreshStep(step);
@@ -1568,6 +1614,7 @@ export function createRenderer(transcriptEl, hooks = {}) {
1568
1614
  sr: { last: 0, timer: 0, pending: '' },
1569
1615
  };
1570
1616
  row._rack = rack;
1617
+ motion.watch(row); // its sweep, ticks and scene loop only while it is on screen
1571
1618
  rack.receipt.btn.addEventListener('click', () => setRackOpen(rack, !rack.open));
1572
1619
  row.querySelector('.asst-rack-view').addEventListener('click', (e) => {
1573
1620
  const btn = e.target.closest('button[data-view]');
@@ -2046,6 +2093,22 @@ export function createRenderer(transcriptEl, hooks = {}) {
2046
2093
  * head (subjectCut).
2047
2094
  */
2048
2095
  function subjectBudget(rack, verb, cut = 'middle') {
2096
+ const s = rack.stage;
2097
+ // The same inputs give the same budget: the 1 Hz clock tick reuses it instead of measuring the stage again
2098
+ // (a measure on the frame's path forces style and layout of whatever the frame dirtied). The key holds every
2099
+ // input the measure reads: the stage's width (its ResizeObserver's), the scene beside the mascot, whether the
2100
+ // bubble shows, the verb, the clock's length (tabular digits: same length, same width), the running reserve, the cut.
2101
+ const seen = stageResizes ? stageWidths.get(s.el) : null;
2102
+ const key = seen && seen.width != null
2103
+ ? `${seen.width}|${rack.sceneId}|${s.bubble.hidden ? 0 : 1}|${verb}|${s.meta.textContent.length}|${rack.bubble.step?.state === 'running' ? 1 : 0}|${cut}`
2104
+ : '';
2105
+ if (key && rack.budgetMemo?.key === key) return rack.budgetMemo.value;
2106
+ const value = measureSubjectBudget(rack, verb, cut);
2107
+ rack.budgetMemo = key ? { key, value } : null;
2108
+ return value;
2109
+ }
2110
+
2111
+ function measureSubjectBudget(rack, verb, cut) {
2049
2112
  const s = rack.stage;
2050
2113
  const width = s.el.clientWidth;
2051
2114
  if (!width) return 96;
@@ -2062,14 +2125,30 @@ export function createRenderer(transcriptEl, hooks = {}) {
2062
2125
  // Two lines, less what wrapping at token boundaries wastes (a head cut is one tail: close to two full
2063
2126
  // lines, a path's pieces wrapping at its separators); a guess on the generous side, since fitSubject
2064
2127
  // cuts what the clamp would hide or a piece would push past the edge.
2065
- const lines = getComputedStyle(s.line).whiteSpace === 'nowrap' ? 1 : cut === 'head' ? 2 : 1.85;
2128
+ const lines = bubbleStyle(rack, s.line, 'white-space') === 'nowrap' ? 1 : cut === 'head' ? 2 : 1.85;
2066
2129
  const taken = Math.ceil((verbPx + 7 + (numbersPx ? numbersPx + 7 : 0)) / 7);
2067
2130
  return Math.max(24, Math.min(240, Math.floor(perLine * lines) - taken - 1));
2068
2131
  }
2069
2132
 
2070
- /** 'head' where the stylesheet says so (≤320 px: keep the tail), else 'middle'. */
2133
+ /**
2134
+ * A computed style of the bubble, read once while the stage keeps its width (styleCache; the stage's
2135
+ * ResizeObserver forgets it). Without a ResizeObserver nothing would say when to forget: read it each time.
2136
+ */
2137
+ function bubbleStyle(rack, node, prop) {
2138
+ if (stageResizes && stageWidths.has(rack.stage.el)) return styleCache.get(node, prop);
2139
+ try { return getComputedStyle(node).getPropertyValue(prop).trim(); } catch { return ''; }
2140
+ }
2141
+
2142
+ /** The stage's width changed (or the fonts did): its cut, its line's wrap and its budget are read again. */
2143
+ function forgetBubbleStyle(rack) {
2144
+ styleCache.invalidate(rack.stage.subject);
2145
+ styleCache.invalidate(rack.stage.line);
2146
+ rack.budgetMemo = null;
2147
+ }
2148
+
2149
+ /** 'head' where the stylesheet says so (≤320 px: keep the tail), else 'middle'. Never read per frame: see bubbleStyle. */
2071
2150
  function subjectCut(rack) {
2072
- try { return getComputedStyle(rack.stage.subject).getPropertyValue('--rk-cut').trim() === 'head' ? 'head' : 'middle'; } catch { return 'middle'; }
2151
+ return bubbleStyle(rack, rack.stage.subject, '--rk-cut') === 'head' ? 'head' : 'middle';
2073
2152
  }
2074
2153
 
2075
2154
  /**
@@ -2828,9 +2907,11 @@ export function createRenderer(transcriptEl, hooks = {}) {
2828
2907
  }
2829
2908
 
2830
2909
  // ── Rack upkeep ──
2910
+ // The 1 Hz beats run only while the transcript is on screen (a hidden tab, a closed panel): they paint clocks
2911
+ // and bubbles nobody would see. Back on screen, the ticker runs them at once.
2831
2912
  function needTicker() {
2832
2913
  if (unsubTick) return;
2833
- try { unsubTick = subscribe(tickRacks, { fps: 1 }); } catch { unsubTick = null; }
2914
+ try { unsubTick = subscribe(tickRacks, { fps: 1, target: $msgs }); } catch { unsubTick = null; }
2834
2915
  }
2835
2916
 
2836
2917
  function stopTicker() {
@@ -2855,6 +2936,7 @@ export function createRenderer(transcriptEl, hooks = {}) {
2855
2936
  const stage = rack.stage.el;
2856
2937
  if (on && !stageWidths.has(stage)) {
2857
2938
  stageWidths.set(stage, { rack, width: null });
2939
+ forgetBubbleStyle(rack); // read again from here on, while the observer watches the width
2858
2940
  stageResizes.observe(stage);
2859
2941
  } else if (!on && stageWidths.has(stage)) {
2860
2942
  stageWidths.delete(stage);
@@ -2881,6 +2963,7 @@ export function createRenderer(transcriptEl, hooks = {}) {
2881
2963
 
2882
2964
  function dropRack(rack) {
2883
2965
  watchStageWidth(rack, false);
2966
+ motion.unwatch(rack.row);
2884
2967
  clearTimeout(rack.stageTimer);
2885
2968
  clearTimeout(rack.clearTimer);
2886
2969
  clearTimeout(rack.sr.timer);
@@ -3145,6 +3228,7 @@ export function createRenderer(transcriptEl, hooks = {}) {
3145
3228
  runCards.set(run.runId, card);
3146
3229
  const { wrap } = assistantRow(rootScope);
3147
3230
  wrap.appendChild(card);
3231
+ motion.watch(card); // its cameo, stage, scene and sweep loop only while it is on screen
3148
3232
  syncStage(run.runId, card, run);
3149
3233
  return card;
3150
3234
  }
@@ -3187,7 +3271,7 @@ export function createRenderer(transcriptEl, hooks = {}) {
3187
3271
 
3188
3272
  function needStageTicker() {
3189
3273
  if (unsubStageTick) return;
3190
- try { unsubStageTick = subscribe(tickStages, { fps: 1 }); } catch { unsubStageTick = null; }
3274
+ try { unsubStageTick = subscribe(tickStages, { fps: 1, target: $msgs }); } catch { unsubStageTick = null; }
3191
3275
  }
3192
3276
 
3193
3277
  function stopStageTicker() {
@@ -3366,6 +3450,7 @@ export function createRenderer(transcriptEl, hooks = {}) {
3366
3450
  const line = createRouteLine(route, routeLineOpts(phase));
3367
3451
  routeLines.set(routeId, line);
3368
3452
  append(line.el);
3453
+ motion.watch(line.el); // its sweep and icon loop only while it is on screen
3369
3454
  syncRouteLive(routeId);
3370
3455
  enterRow(line.el);
3371
3456
  return line;
@@ -3376,6 +3461,7 @@ export function createRenderer(transcriptEl, hooks = {}) {
3376
3461
  if (!routeId || !line) return;
3377
3462
  const fresh = routeLines.get(routeId) !== line;
3378
3463
  routeLines.set(routeId, line);
3464
+ if (line.el) motion.watch(line.el);
3379
3465
  syncRouteLive(routeId);
3380
3466
  if (fresh && line.el?.isConnected) enterRow(line.el);
3381
3467
  }
@@ -3397,7 +3483,7 @@ export function createRenderer(transcriptEl, hooks = {}) {
3397
3483
 
3398
3484
  function removeRouteLine(routeId) {
3399
3485
  const line = routeLines.get(routeId);
3400
- if (line) { line.el.remove(); routeLines.delete(routeId); }
3486
+ if (line) { motion.unwatch(line.el); line.el.remove(); routeLines.delete(routeId); }
3401
3487
  }
3402
3488
 
3403
3489
  // ── The automation trace ──
@@ -3833,8 +3919,8 @@ export function createRenderer(transcriptEl, hooks = {}) {
3833
3919
  }
3834
3920
  case 'result': {
3835
3921
  flushStream(scope);
3836
- // Codex/OpenCode also send an `error` packet; the SDK reports only here.
3837
- const errorText = !parentId && ev.brain !== 'codex' && ev.brain !== 'opencode' ? resultErrorText(ev, t) : '';
3922
+ // Codex/OpenCode/Antigravity also send an `error` packet; the SDK reports only here.
3923
+ const errorText = !parentId && ev.brain !== 'codex' && ev.brain !== 'opencode' && ev.brain !== 'antigravity' ? resultErrorText(ev, t) : '';
3838
3924
  if (errorText && !muted) turn.errored = true;
3839
3925
  // The stage on screen waits for the turn's verdict (onResult → finishTurn) before it folds.
3840
3926
  if (!parentId && !muted) grace = newestStage();
@@ -4043,6 +4129,10 @@ export function createRenderer(transcriptEl, hooks = {}) {
4043
4129
  }
4044
4130
 
4045
4131
  function clear() {
4132
+ if (scrollFrame) { cancelAnimationFrame(scrollFrame); scrollFrame = 0; }
4133
+ clearTimeout(recutTimer);
4134
+ recutTimer = 0;
4135
+ toRecut.clear();
4046
4136
  for (const scope of scopes.values()) { if (scope.stream?.mdTimer) clearTimeout(scope.stream.mdTimer); if (scope.stream?.thinkTimer) clearTimeout(scope.stream.thinkTimer); }
4047
4137
  if (rootScope.stream?.mdTimer) clearTimeout(rootScope.stream.mdTimer);
4048
4138
  if (rootScope.stream?.thinkTimer) clearTimeout(rootScope.stream.thinkTimer);
@@ -4057,6 +4147,8 @@ export function createRenderer(transcriptEl, hooks = {}) {
4057
4147
  runActivity.clear();
4058
4148
  runCards.clear();
4059
4149
  routeLines.clear();
4150
+ motion.disconnect(); // every holder it watched goes with the transcript
4151
+ styleCache.invalidate();
4060
4152
  autoRows.clear();
4061
4153
  turnFrames = [];
4062
4154
  rootScope.stream = null;
@@ -4085,7 +4177,7 @@ export function createRenderer(transcriptEl, hooks = {}) {
4085
4177
  return {
4086
4178
  el: $msgs,
4087
4179
  clear,
4088
- destroy: () => { clear(); limitDock.destroy(); },
4180
+ destroy: () => { clear(); stageResizes?.disconnect(); limitDock.destroy(); stopFontWatch(); },
4089
4181
  appendUser,
4090
4182
  appendAssistantMarkdown,
4091
4183
  appendStatus,
@@ -4126,6 +4218,8 @@ export function createRenderer(transcriptEl, hooks = {}) {
4126
4218
  setWaiting,
4127
4219
  /** The session's usage-limit report changed: this turn's waiting card counts to its reset time. */
4128
4220
  noteLimit,
4221
+ /** Dismiss the Assistant's own limit-wait card (a provider switch already decided what follows). */
4222
+ clearLimitWait: () => limitDock.set('brain', null),
4129
4223
  finishTurn,
4130
4224
  renderTranscript,
4131
4225
  showWorking,