synabun 2.0.10 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (656) hide show
  1. package/CHANGELOG.md +207 -0
  2. package/README.md +25 -2
  3. package/THIRD-PARTY-LICENSES.md +22 -0
  4. package/bin/synabun.js +71 -24
  5. package/docs/whatsapp.md +13 -13
  6. package/hooks/claude-code/pre-websearch.mjs +12 -1
  7. package/hooks/claude-code/shared.mjs +5 -0
  8. package/hooks/claude-code/stop.mjs +1 -1
  9. package/lib/claude-hooks.js +172 -18
  10. package/lib/client-config-repair.js +30 -17
  11. package/lib/desktop-app.js +7 -1
  12. package/lib/external-tools.js +7 -6
  13. package/lib/first-launch-protection.js +57 -12
  14. package/lib/mcp-dist.js +176 -0
  15. package/lib/release-npm-ci.mjs +138 -0
  16. package/lib/release-publish.mjs +91 -0
  17. package/lib/release-scan.mjs +50 -0
  18. package/lib/server-crash-record.js +123 -0
  19. package/lib/server-exit.js +318 -0
  20. package/lib/server-supervisor.js +508 -0
  21. package/lib/start-launcher.js +37 -4
  22. package/lib/tools-cli.js +45 -0
  23. package/lib/update-snapshot.js +302 -0
  24. package/lib/virustotal.mjs +203 -0
  25. package/lib/windows-crash-event.js +269 -0
  26. package/mcp-server/dist/http.d.ts +20 -1
  27. package/mcp-server/dist/http.d.ts.map +1 -1
  28. package/mcp-server/dist/http.js +59 -12
  29. package/mcp-server/dist/http.js.map +1 -1
  30. package/mcp-server/dist/index.d.ts +33 -27
  31. package/mcp-server/dist/index.d.ts.map +1 -1
  32. package/mcp-server/dist/index.js +128 -143
  33. package/mcp-server/dist/index.js.map +1 -1
  34. package/mcp-server/dist/preload.js +1 -1
  35. package/mcp-server/dist/preload.js.map +1 -1
  36. package/mcp-server/dist/services/budget-judgments.d.ts +1 -1
  37. package/mcp-server/dist/services/budget-judgments.d.ts.map +1 -1
  38. package/mcp-server/dist/services/budget-judgments.js +5 -3
  39. package/mcp-server/dist/services/budget-judgments.js.map +1 -1
  40. package/mcp-server/dist/services/codex-config-heal.d.ts +6 -2
  41. package/mcp-server/dist/services/codex-config-heal.d.ts.map +1 -1
  42. package/mcp-server/dist/services/codex-config-heal.js +81 -28
  43. package/mcp-server/dist/services/codex-config-heal.js.map +1 -1
  44. package/mcp-server/dist/services/identity.d.ts +2 -2
  45. package/mcp-server/dist/services/identity.js +2 -2
  46. package/mcp-server/dist/services/memory-judge-backfill.d.ts +6 -0
  47. package/mcp-server/dist/services/memory-judge-backfill.d.ts.map +1 -1
  48. package/mcp-server/dist/services/memory-judge-backfill.js +7 -1
  49. package/mcp-server/dist/services/memory-judge-backfill.js.map +1 -1
  50. package/mcp-server/dist/services/memory-sessions.d.ts +1 -1
  51. package/mcp-server/dist/services/memory-sessions.d.ts.map +1 -1
  52. package/mcp-server/dist/services/memory-sessions.js +28 -2
  53. package/mcp-server/dist/services/memory-sessions.js.map +1 -1
  54. package/mcp-server/dist/services/neural-interface.d.ts +18 -11
  55. package/mcp-server/dist/services/neural-interface.d.ts.map +1 -1
  56. package/mcp-server/dist/services/neural-interface.js +67 -11
  57. package/mcp-server/dist/services/neural-interface.js.map +1 -1
  58. package/mcp-server/dist/services/server-instructions.d.ts +7 -2
  59. package/mcp-server/dist/services/server-instructions.d.ts.map +1 -1
  60. package/mcp-server/dist/services/server-instructions.js +22 -63
  61. package/mcp-server/dist/services/server-instructions.js.map +1 -1
  62. package/mcp-server/dist/services/tool-catalog.d.ts +120 -0
  63. package/mcp-server/dist/services/tool-catalog.d.ts.map +1 -0
  64. package/mcp-server/dist/services/tool-catalog.js +339 -0
  65. package/mcp-server/dist/services/tool-catalog.js.map +1 -0
  66. package/mcp-server/dist/services/tool-list-refresh-barrier.d.ts +12 -0
  67. package/mcp-server/dist/services/tool-list-refresh-barrier.d.ts.map +1 -0
  68. package/mcp-server/dist/services/tool-list-refresh-barrier.js +40 -0
  69. package/mcp-server/dist/services/tool-list-refresh-barrier.js.map +1 -0
  70. package/mcp-server/dist/services/tool-list.d.ts +108 -0
  71. package/mcp-server/dist/services/tool-list.d.ts.map +1 -0
  72. package/mcp-server/dist/services/tool-list.js +334 -0
  73. package/mcp-server/dist/services/tool-list.js.map +1 -0
  74. package/mcp-server/dist/services/tool-runtime.d.ts +161 -0
  75. package/mcp-server/dist/services/tool-runtime.d.ts.map +1 -0
  76. package/mcp-server/dist/services/tool-runtime.js +400 -0
  77. package/mcp-server/dist/services/tool-runtime.js.map +1 -0
  78. package/mcp-server/dist/services/typesafe-config.js +1 -1
  79. package/mcp-server/dist/services/typesafe-config.js.map +1 -1
  80. package/mcp-server/dist/services/whiteboard-geometry.d.ts +26 -2
  81. package/mcp-server/dist/services/whiteboard-geometry.d.ts.map +1 -1
  82. package/mcp-server/dist/services/whiteboard-geometry.js +91 -8
  83. package/mcp-server/dist/services/whiteboard-geometry.js.map +1 -1
  84. package/mcp-server/dist/tools/agents.d.ts +14 -14
  85. package/mcp-server/dist/tools/agents.d.ts.map +1 -1
  86. package/mcp-server/dist/tools/agents.js +29 -19
  87. package/mcp-server/dist/tools/agents.js.map +1 -1
  88. package/mcp-server/dist/tools/browser-batch.d.ts +3 -3
  89. package/mcp-server/dist/tools/choice.d.ts +6 -0
  90. package/mcp-server/dist/tools/choice.d.ts.map +1 -1
  91. package/mcp-server/dist/tools/choice.js +18 -13
  92. package/mcp-server/dist/tools/choice.js.map +1 -1
  93. package/mcp-server/dist/tools/git-tools.js +2 -2
  94. package/mcp-server/dist/tools/git-tools.js.map +1 -1
  95. package/mcp-server/dist/tools/image-tools.d.ts +1 -1
  96. package/mcp-server/dist/tools/image-tools.js +1 -1
  97. package/mcp-server/dist/tools/morelogin.d.ts.map +1 -1
  98. package/mcp-server/dist/tools/morelogin.js +9 -6
  99. package/mcp-server/dist/tools/morelogin.js.map +1 -1
  100. package/mcp-server/dist/tools/skill-tools.d.ts +505 -0
  101. package/mcp-server/dist/tools/skill-tools.d.ts.map +1 -0
  102. package/mcp-server/dist/tools/skill-tools.js +642 -0
  103. package/mcp-server/dist/tools/skill-tools.js.map +1 -0
  104. package/mcp-server/dist/tools/skill.d.ts +7 -0
  105. package/mcp-server/dist/tools/skill.d.ts.map +1 -0
  106. package/mcp-server/dist/tools/skill.js +11 -0
  107. package/mcp-server/dist/tools/skill.js.map +1 -0
  108. package/mcp-server/dist/tools/tool-groups.d.ts +68 -0
  109. package/mcp-server/dist/tools/tool-groups.d.ts.map +1 -0
  110. package/mcp-server/dist/tools/tool-groups.js +147 -0
  111. package/mcp-server/dist/tools/tool-groups.js.map +1 -0
  112. package/mcp-server/dist/tools/whiteboard-format.d.ts.map +1 -1
  113. package/mcp-server/dist/tools/whiteboard-format.js +7 -4
  114. package/mcp-server/dist/tools/whiteboard-format.js.map +1 -1
  115. package/mcp-server/dist/tools/whiteboard-tools.d.ts +64 -13
  116. package/mcp-server/dist/tools/whiteboard-tools.d.ts.map +1 -1
  117. package/mcp-server/dist/tools/whiteboard-tools.js +30 -5
  118. package/mcp-server/dist/tools/whiteboard-tools.js.map +1 -1
  119. package/mcp-server/package-lock.json +2 -2
  120. package/mcp-server/package.json +1 -1
  121. package/mcp-server/src/http.ts +75 -12
  122. package/mcp-server/src/index.ts +147 -154
  123. package/mcp-server/src/preload.ts +12 -12
  124. package/mcp-server/src/services/budget-judgments.ts +5 -3
  125. package/mcp-server/src/services/codex-config-heal.ts +80 -29
  126. package/mcp-server/src/services/identity.ts +2 -2
  127. package/mcp-server/src/services/memory-judge-backfill.ts +7 -1
  128. package/mcp-server/src/services/memory-sessions.ts +24 -3
  129. package/mcp-server/src/services/neural-interface.ts +81 -21
  130. package/mcp-server/src/services/server-instructions.ts +29 -64
  131. package/mcp-server/src/services/tool-catalog.ts +403 -0
  132. package/mcp-server/src/services/tool-list-refresh-barrier.ts +33 -0
  133. package/mcp-server/src/services/tool-list.ts +410 -0
  134. package/mcp-server/src/services/tool-runtime.ts +457 -0
  135. package/mcp-server/src/services/typesafe-config.ts +1 -1
  136. package/mcp-server/src/services/whiteboard-geometry.ts +94 -9
  137. package/mcp-server/src/tools/agents.ts +29 -20
  138. package/mcp-server/src/tools/choice.ts +17 -12
  139. package/mcp-server/src/tools/git-tools.ts +2 -2
  140. package/mcp-server/src/tools/image-tools.ts +1 -1
  141. package/mcp-server/src/tools/morelogin.ts +6 -4
  142. package/mcp-server/src/tools/skill-tools.ts +592 -0
  143. package/mcp-server/src/tools/skill.ts +13 -0
  144. package/mcp-server/src/tools/tool-groups.ts +164 -0
  145. package/mcp-server/src/tools/whiteboard-format.ts +9 -3
  146. package/mcp-server/src/tools/whiteboard-tools.ts +39 -5
  147. package/neural-interface/i18n/en.json +3953 -228
  148. package/neural-interface/i18n/pt-BR.json +3901 -179
  149. package/neural-interface/lib/agent-sandbox-elevation.js +6 -0
  150. package/neural-interface/lib/antigravity/acp-client-host.js +554 -0
  151. package/neural-interface/lib/antigravity/acp-connection.js +299 -0
  152. package/neural-interface/lib/antigravity/bypass.js +100 -0
  153. package/neural-interface/lib/antigravity/catalog.js +273 -0
  154. package/neural-interface/lib/antigravity/home.js +260 -0
  155. package/neural-interface/lib/antigravity/migrate-gemini.js +139 -0
  156. package/neural-interface/lib/antigravity/panel-bridge.js +1058 -0
  157. package/neural-interface/lib/antigravity/policy-hook.mjs +78 -0
  158. package/neural-interface/lib/antigravity/policy.js +74 -0
  159. package/neural-interface/lib/antigravity/tool-call.js +178 -0
  160. package/neural-interface/lib/antigravity/transcripts.js +252 -0
  161. package/neural-interface/lib/antigravity/usage.js +43 -0
  162. package/neural-interface/lib/assistant-api.js +128 -28
  163. package/neural-interface/lib/assistant-brains/antigravity.js +423 -0
  164. package/neural-interface/lib/assistant-brains/claude.js +4 -3
  165. package/neural-interface/lib/assistant-brains/codex-browser-policy-hook.mjs +12 -2
  166. package/neural-interface/lib/assistant-brains/codex-route-gate-hook.mjs +32 -9
  167. package/neural-interface/lib/assistant-brains/codex.js +9 -5
  168. package/neural-interface/lib/assistant-brains/opencode.js +120 -54
  169. package/neural-interface/lib/assistant-brains/opencode2-browser-policy/index.js +28 -13
  170. package/neural-interface/lib/assistant-brains/opencode2-route-gate/index.js +59 -19
  171. package/neural-interface/lib/assistant-budget-planner.js +7 -3
  172. package/neural-interface/lib/assistant-budget-split.js +42 -15
  173. package/neural-interface/lib/assistant-catalog.js +81 -15
  174. package/neural-interface/lib/assistant-config.js +6 -3
  175. package/neural-interface/lib/assistant-dispatch.js +1073 -200
  176. package/neural-interface/lib/assistant-envelope.js +156 -2
  177. package/neural-interface/lib/assistant-evidence.js +80 -0
  178. package/neural-interface/lib/assistant-hidden-models.js +7 -5
  179. package/neural-interface/lib/assistant-persona.js +93 -19
  180. package/neural-interface/lib/assistant-plan-permissions.js +25 -9
  181. package/neural-interface/lib/assistant-route-gate-codex.js +3 -0
  182. package/neural-interface/lib/assistant-route-gate.js +6 -4
  183. package/neural-interface/lib/assistant-router.js +245 -38
  184. package/neural-interface/lib/assistant-runtime.js +214 -30
  185. package/neural-interface/lib/assistant-task-prompt.js +87 -21
  186. package/neural-interface/lib/assistant-tools.js +51 -0
  187. package/neural-interface/lib/assistant-usage.js +29 -0
  188. package/neural-interface/lib/backup-service.js +626 -4
  189. package/neural-interface/lib/backup-zip-reader.js +10 -5
  190. package/neural-interface/lib/backup-zip-writer.js +257 -0
  191. package/neural-interface/lib/browser-execution.js +10 -2
  192. package/neural-interface/lib/browser-guard-cdp.js +84 -0
  193. package/neural-interface/lib/browser-network-guard.js +476 -0
  194. package/neural-interface/lib/browser-policy-roots.js +64 -0
  195. package/neural-interface/lib/browser-tool-policy.js +198 -38
  196. package/neural-interface/lib/claude-agent-bridge.js +11 -2
  197. package/neural-interface/lib/claude-history-cache.js +210 -0
  198. package/neural-interface/lib/claude-hooks-status.js +103 -0
  199. package/neural-interface/lib/claude-model-catalog.js +5 -1
  200. package/neural-interface/lib/claude-temporary.js +5 -11
  201. package/neural-interface/lib/cli-install-api.js +1 -1
  202. package/neural-interface/lib/cli-install.js +163 -154
  203. package/neural-interface/lib/cli-resolver.js +13 -3
  204. package/neural-interface/lib/cli-update-planner.js +52 -41
  205. package/neural-interface/lib/cloudflared/tunnel.js +42 -2
  206. package/neural-interface/lib/codex-mcp-approvals.js +11 -0
  207. package/neural-interface/lib/codex-rollout-reader.js +52 -0
  208. package/neural-interface/lib/codex-worker-app-server.js +191 -0
  209. package/neural-interface/lib/confined-fs.js +30 -3
  210. package/neural-interface/lib/crash-notice-api.js +98 -0
  211. package/neural-interface/lib/editor-completion-opencode.js +68 -68
  212. package/neural-interface/lib/editor-git-api.js +3 -20
  213. package/neural-interface/lib/exec-loop-command.js +13 -10
  214. package/neural-interface/lib/file-explorer-api.js +74 -40
  215. package/neural-interface/lib/file-explorer-watch.js +9 -3
  216. package/neural-interface/lib/git-bash/install.js +52 -6
  217. package/neural-interface/lib/git-bash/manager.js +59 -17
  218. package/neural-interface/lib/git-bash/pins.js +12 -0
  219. package/neural-interface/lib/git-read.js +2 -2
  220. package/neural-interface/lib/git-status-runner.js +390 -0
  221. package/neural-interface/lib/git-status-watchdog.js +40 -0
  222. package/neural-interface/lib/greeting/budgets.js +1 -0
  223. package/neural-interface/lib/greeting/engine.js +2 -2
  224. package/neural-interface/lib/greeting/sources.js +10 -12
  225. package/neural-interface/lib/greeting/writer.js +1 -1
  226. package/neural-interface/lib/http-guards.js +8 -2
  227. package/neural-interface/lib/install-details.js +4 -1
  228. package/neural-interface/lib/mcp-agent-servers.js +67 -0
  229. package/neural-interface/lib/mcp-client-config.js +35 -33
  230. package/neural-interface/lib/mcp-external-servers.js +332 -0
  231. package/neural-interface/lib/mcp-installer.js +2 -1
  232. package/neural-interface/lib/{mcp-profile-refresh-coordinator.js → mcp-tools-refresh-coordinator.js} +4 -4
  233. package/neural-interface/lib/memory-session-capture.js +17 -3
  234. package/neural-interface/lib/morelogin.js +177 -25
  235. package/neural-interface/lib/native-loop-providers.js +965 -66
  236. package/neural-interface/lib/native-loop-runtime.js +290 -42
  237. package/neural-interface/lib/opencode-config.js +557 -0
  238. package/neural-interface/lib/opencode-db-schema.js +17 -34
  239. package/neural-interface/lib/opencode-history.js +48 -218
  240. package/neural-interface/lib/opencode-mcp-ready.js +108 -0
  241. package/neural-interface/lib/opencode-native-boundary.js +53 -0
  242. package/neural-interface/lib/opencode-protocol.js +249 -112
  243. package/neural-interface/lib/opencode-runtime-config.js +32 -22
  244. package/neural-interface/lib/opencode-serve-records.js +39 -21
  245. package/neural-interface/lib/opencode-v2-client.js +48 -153
  246. package/neural-interface/lib/opencode-v2-ws-requests.js +36 -210
  247. package/neural-interface/lib/opencode-worker-data.js +27 -0
  248. package/neural-interface/lib/opencode2-client.js +73 -37
  249. package/neural-interface/lib/opencode2-proxy.js +23 -63
  250. package/neural-interface/lib/opencode2-translate.js +51 -2
  251. package/neural-interface/lib/owner-authority.js +249 -0
  252. package/neural-interface/lib/page-session.js +275 -0
  253. package/neural-interface/lib/path-confine.js +12 -9
  254. package/neural-interface/lib/peer-identity.js +793 -0
  255. package/neural-interface/lib/pty-host/core.js +28 -1
  256. package/neural-interface/lib/pty-host/lifetime.js +12 -0
  257. package/neural-interface/lib/pty-host/manager.js +12 -1
  258. package/neural-interface/lib/remote-policy.js +1 -1
  259. package/neural-interface/lib/request-gate.js +20 -2
  260. package/neural-interface/lib/rulesets/api.js +7 -6
  261. package/neural-interface/lib/rulesets/fs-safe.js +1 -1
  262. package/neural-interface/lib/rulesets/installer.js +180 -36
  263. package/neural-interface/lib/rulesets/json-edit.js +1 -1
  264. package/neural-interface/lib/rulesets/render.js +1 -1
  265. package/neural-interface/lib/session-cache-builder.js +81 -31
  266. package/neural-interface/lib/session-title-generator.js +58 -36
  267. package/neural-interface/lib/skills/api-v2.js +495 -0
  268. package/neural-interface/lib/skills/bundle.js +418 -0
  269. package/neural-interface/lib/skills/catalog.js +298 -0
  270. package/neural-interface/lib/skills/creation-api.js +191 -0
  271. package/neural-interface/lib/skills/creation-brief.js +247 -0
  272. package/neural-interface/lib/skills/creation-sources.js +285 -0
  273. package/neural-interface/lib/skills/creation.js +843 -0
  274. package/neural-interface/lib/skills/deploy.js +569 -0
  275. package/neural-interface/lib/skills/digest.js +119 -0
  276. package/neural-interface/lib/skills/discover.js +111 -0
  277. package/neural-interface/lib/skills/draft-confinement.js +216 -0
  278. package/neural-interface/lib/skills/eval-confinement.js +399 -0
  279. package/neural-interface/lib/skills/eval-sandbox.js +280 -0
  280. package/neural-interface/lib/skills/eval-trace.js +135 -0
  281. package/neural-interface/lib/skills/evals-api.js +212 -0
  282. package/neural-interface/lib/skills/evals.js +1573 -0
  283. package/neural-interface/lib/skills/export.js +203 -0
  284. package/neural-interface/lib/skills/frontmatter.js +64 -0
  285. package/neural-interface/lib/skills/health.js +75 -0
  286. package/neural-interface/lib/skills/json-edit.js +165 -0
  287. package/neural-interface/lib/skills/known-bridge-digests.json +441 -0
  288. package/neural-interface/lib/skills/known-bridges.js +96 -0
  289. package/neural-interface/lib/skills/library.js +823 -0
  290. package/neural-interface/lib/skills/local-store.js +21 -0
  291. package/neural-interface/lib/skills/migration.js +433 -0
  292. package/neural-interface/lib/skills/operations.js +45 -0
  293. package/neural-interface/lib/skills/ownership.js +427 -0
  294. package/neural-interface/lib/skills/packages.js +88 -0
  295. package/neural-interface/lib/skills/reviews.js +212 -0
  296. package/neural-interface/lib/skills/revision.js +80 -0
  297. package/neural-interface/lib/skills/roots.js +269 -0
  298. package/neural-interface/lib/skills/runtime-checks.js +358 -0
  299. package/neural-interface/lib/skills/scan-assets.js +252 -0
  300. package/neural-interface/lib/skills/scan-context.js +26 -0
  301. package/neural-interface/lib/skills/scan-shell.js +324 -0
  302. package/neural-interface/lib/skills/scan.js +364 -0
  303. package/neural-interface/lib/skills/scanners.js +54 -0
  304. package/neural-interface/lib/skills/service.js +530 -0
  305. package/neural-interface/lib/skills/telemetry.js +119 -0
  306. package/neural-interface/lib/sqlite-integrity-worker.js +22 -0
  307. package/neural-interface/lib/synabun-version.js +1 -1
  308. package/neural-interface/lib/system-activity.js +1 -1
  309. package/neural-interface/lib/tool-lists.js +124 -0
  310. package/neural-interface/lib/whatsapp/brain.js +7 -3
  311. package/neural-interface/lib/whatsapp/bridge.js +6 -3
  312. package/neural-interface/lib/whatsapp/cards.js +22 -9
  313. package/neural-interface/lib/whatsapp/config.js +1 -1
  314. package/neural-interface/lib/worker-confinement.js +1268 -0
  315. package/neural-interface/lib/worker-guard-setting.js +56 -0
  316. package/neural-interface/lib/worker-mcp-channel.js +175 -0
  317. package/neural-interface/lib/worker-question.js +74 -0
  318. package/neural-interface/lib/worker-relay-ports.js +227 -0
  319. package/neural-interface/lib/worker-resume.js +238 -0
  320. package/neural-interface/lib/worker-sandbox.js +329 -0
  321. package/neural-interface/package-lock.json +34 -12
  322. package/neural-interface/package.json +3 -2
  323. package/neural-interface/public/index.html +3 -1
  324. package/neural-interface/public/index2d.html +19 -11
  325. package/neural-interface/public/onboarding.html +3 -3
  326. package/neural-interface/public/shared/account-menu.js +8 -5
  327. package/neural-interface/public/shared/agent-runtime-options.js +125 -31
  328. package/neural-interface/public/shared/agy/agy-bypass.js +47 -0
  329. package/neural-interface/public/shared/agy/agy-client.js +266 -0
  330. package/neural-interface/public/shared/agy/agy-commands.js +120 -0
  331. package/neural-interface/public/shared/agy/agy-copy.js +326 -0
  332. package/neural-interface/public/shared/agy/agy-diff.js +161 -0
  333. package/neural-interface/public/shared/agy/agy-events.js +469 -0
  334. package/neural-interface/public/shared/agy/agy-greeting.js +26 -0
  335. package/neural-interface/public/shared/agy/agy-options.js +232 -0
  336. package/neural-interface/public/shared/agy/agy-panel.js +2543 -0
  337. package/neural-interface/public/shared/agy/agy-render.js +392 -0
  338. package/neural-interface/public/shared/agy/agy-setup.js +149 -0
  339. package/neural-interface/public/shared/agy/agy-styles.js +604 -0
  340. package/neural-interface/public/shared/agy/agy-tabs-logic.js +181 -0
  341. package/neural-interface/public/shared/api.js +1527 -1336
  342. package/neural-interface/public/shared/app-frame.js +192 -0
  343. package/neural-interface/public/shared/assistant/asst-agents-dock.js +36 -6
  344. package/neural-interface/public/shared/assistant/asst-api.js +1 -1
  345. package/neural-interface/public/shared/assistant/asst-ask-styles.js +270 -0
  346. package/neural-interface/public/shared/assistant/asst-ask-tail.js +118 -0
  347. package/neural-interface/public/shared/assistant/asst-ask.js +397 -0
  348. package/neural-interface/public/shared/assistant/asst-brain-picker.js +105 -44
  349. package/neural-interface/public/shared/assistant/asst-budget.js +5 -4
  350. package/neural-interface/public/shared/assistant/asst-control.js +205 -26
  351. package/neural-interface/public/shared/assistant/asst-followups-card.js +383 -0
  352. package/neural-interface/public/shared/assistant/asst-followups.js +417 -0
  353. package/neural-interface/public/shared/assistant/asst-hosts.js +16 -7
  354. package/neural-interface/public/shared/assistant/asst-limit-dock.js +45 -0
  355. package/neural-interface/public/shared/assistant/asst-limit-wait.js +327 -0
  356. package/neural-interface/public/shared/assistant/asst-limit.js +168 -0
  357. package/neural-interface/public/shared/assistant/asst-mascot.js +49 -12
  358. package/neural-interface/public/shared/assistant/asst-menu.js +7 -6
  359. package/neural-interface/public/shared/assistant/asst-panel.js +151 -19
  360. package/neural-interface/public/shared/assistant/asst-rack-styles.js +66 -49
  361. package/neural-interface/public/shared/assistant/asst-render.js +445 -82
  362. package/neural-interface/public/shared/assistant/asst-route.js +304 -53
  363. package/neural-interface/public/shared/assistant/asst-routes-editor.js +9 -8
  364. package/neural-interface/public/shared/assistant/asst-scenes.js +56 -1
  365. package/neural-interface/public/shared/assistant/asst-sidepanel.js +117 -10
  366. package/neural-interface/public/shared/assistant/asst-slash.js +17 -9
  367. package/neural-interface/public/shared/assistant/asst-state.js +87 -24
  368. package/neural-interface/public/shared/assistant/asst-stop.js +127 -0
  369. package/neural-interface/public/shared/assistant/asst-styles.js +93 -21
  370. package/neural-interface/public/shared/assistant/asst-tool-kinds.js +190 -23
  371. package/neural-interface/public/shared/assistant/asst-usage.js +2 -1
  372. package/neural-interface/public/shared/automation-context.js +5 -2
  373. package/neural-interface/public/shared/cc-dropdown.js +89 -19
  374. package/neural-interface/public/shared/cdx/cdx-context-menu.js +10 -9
  375. package/neural-interface/public/shared/cdx/cdx-copy.js +16 -0
  376. package/neural-interface/public/shared/cdx/cdx-output-model.js +22 -1
  377. package/neural-interface/public/shared/cdx/cdx-output.js +34 -10
  378. package/neural-interface/public/shared/cdx/cdx-panel.js +59 -151
  379. package/neural-interface/public/shared/cdx/cdx-preview.js +12 -0
  380. package/neural-interface/public/shared/cdx/cdx-protocol.js +39 -11
  381. package/neural-interface/public/shared/cdx/cdx-render.js +57 -38
  382. package/neural-interface/public/shared/cdx/cdx-requests.js +14 -4
  383. package/neural-interface/public/shared/cdx/cdx-skill-hints.js +54 -0
  384. package/neural-interface/public/shared/cdx/cdx-styles.js +15 -3
  385. package/neural-interface/public/shared/cdx/cdx-tabs.js +127 -44
  386. package/neural-interface/public/shared/cdx/cdx-ws.js +0 -1
  387. package/neural-interface/public/shared/cli-install-controller.js +218 -0
  388. package/neural-interface/public/shared/cli-install-view.js +11 -12
  389. package/neural-interface/public/shared/cli-status.js +11 -10
  390. package/neural-interface/public/shared/constants.js +5 -4
  391. package/neural-interface/public/shared/context-menu-areas.js +34 -0
  392. package/neural-interface/public/shared/context-menu-logic.js +243 -0
  393. package/neural-interface/public/shared/context-menu-model.js +367 -0
  394. package/neural-interface/public/shared/context-menu.js +372 -0
  395. package/neural-interface/public/shared/cp/cp-context-menu.js +10 -9
  396. package/neural-interface/public/shared/cp/cp-restore.js +162 -0
  397. package/neural-interface/public/shared/cp/cp-tool-cards.js +10 -3
  398. package/neural-interface/public/shared/crash-notice-view.js +168 -0
  399. package/neural-interface/public/shared/desktop-bridge.js +17 -0
  400. package/neural-interface/public/shared/desktop-titlebar-view.js +12 -0
  401. package/neural-interface/public/shared/desktop-titlebar.js +13 -4
  402. package/neural-interface/public/shared/desktop-update-view.js +21 -0
  403. package/neural-interface/public/shared/editor/editor-panel-logic.js +2 -2
  404. package/neural-interface/public/shared/explorer/fx-api.js +4 -4
  405. package/neural-interface/public/shared/explorer/fx-links.js +3 -3
  406. package/neural-interface/public/shared/explorer/fx-logic.js +1 -1
  407. package/neural-interface/public/shared/explorer/fx-main.js +48 -16
  408. package/neural-interface/public/shared/explorer/fx-tree.js +1 -0
  409. package/neural-interface/public/shared/greeting/greeting-card.js +2 -2
  410. package/neural-interface/public/shared/greeting/greeting-view.js +1 -0
  411. package/neural-interface/public/shared/html-shell.js +30 -15
  412. package/neural-interface/public/shared/i18n.js +2 -0
  413. package/neural-interface/public/shared/ocp-v2/ocp-v2-approvals.js +7 -7
  414. package/neural-interface/public/shared/ocp-v2/ocp-v2-binding.js +4 -4
  415. package/neural-interface/public/shared/ocp-v2/ocp-v2-changes-logic.js +3 -101
  416. package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +2 -0
  417. package/neural-interface/public/shared/ocp-v2/ocp-v2-compact-button.js +1 -3
  418. package/neural-interface/public/shared/ocp-v2/ocp-v2-composer-logic.js +2 -6
  419. package/neural-interface/public/shared/ocp-v2/ocp-v2-context-menu.js +11 -11
  420. package/neural-interface/public/shared/ocp-v2/ocp-v2-context-model.js +0 -3
  421. package/neural-interface/public/shared/ocp-v2/ocp-v2-events.js +8 -4
  422. package/neural-interface/public/shared/ocp-v2/ocp-v2-manager.js +7 -7
  423. package/neural-interface/public/shared/ocp-v2/ocp-v2-outcome-notifications.js +16 -0
  424. package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +74 -259
  425. package/neural-interface/public/shared/ocp-v2/ocp-v2-plan.js +1 -2
  426. package/neural-interface/public/shared/ocp-v2/ocp-v2-projectbar.js +95 -202
  427. package/neural-interface/public/shared/ocp-v2/ocp-v2-rehydrate.js +13 -4
  428. package/neural-interface/public/shared/ocp-v2/ocp-v2-render.js +13 -22
  429. package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +4 -4
  430. package/neural-interface/public/shared/ocp-v2/ocp-v2-session-actions.js +8 -61
  431. package/neural-interface/public/shared/ocp-v2/ocp-v2-sessions-logic.js +2 -91
  432. package/neural-interface/public/shared/ocp-v2/ocp-v2-slash-hints.js +16 -15
  433. package/neural-interface/public/shared/ocp-v2/ocp-v2-state.js +8 -21
  434. package/neural-interface/public/shared/ocp-v2/ocp-v2-status-logic.js +1 -99
  435. package/neural-interface/public/shared/ocp-v2/ocp-v2-status.js +5 -35
  436. package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +17 -21
  437. package/neural-interface/public/shared/ocp-v2/{ocp-v2-profile-inheritance.js → ocp-v2-tools-inheritance.js} +16 -16
  438. package/neural-interface/public/shared/ocp-v2/ocp-v2-ws.js +60 -50
  439. package/neural-interface/public/shared/page-session.js +96 -0
  440. package/neural-interface/public/shared/provider-icons.js +4 -2
  441. package/neural-interface/public/shared/registry.js +5 -3
  442. package/neural-interface/public/shared/retired-2d.js +3 -0
  443. package/neural-interface/public/shared/schedules-view.js +195 -61
  444. package/neural-interface/public/shared/settings/settings-claude-hooks.js +135 -0
  445. package/neural-interface/public/shared/settings/settings-data.js +3 -1
  446. package/neural-interface/public/shared/settings/settings-ia.js +6 -6
  447. package/neural-interface/public/shared/settings/settings-opencode.js +89 -0
  448. package/neural-interface/public/shared/settings/settings-rules.js +2 -2
  449. package/neural-interface/public/shared/settings/settings-skill-folders-pane.js +265 -0
  450. package/neural-interface/public/shared/settings/settings-skill-folders.js +130 -0
  451. package/neural-interface/public/shared/settings/settings-worker-guard.js +72 -0
  452. package/neural-interface/public/shared/showcase-privacy.js +6 -1
  453. package/neural-interface/public/shared/sidepanel-session-status.js +3 -3
  454. package/neural-interface/public/shared/skills/ss-args.js +96 -0
  455. package/neural-interface/public/shared/skills/ss-creation.js +222 -0
  456. package/neural-interface/public/shared/skills/ss-dialog.js +133 -0
  457. package/neural-interface/public/shared/skills/ss-doc.js +173 -0
  458. package/neural-interface/public/shared/skills/ss-eval-adapters.js +269 -0
  459. package/neural-interface/public/shared/skills/ss-eval-grade.js +359 -0
  460. package/neural-interface/public/shared/skills/ss-eval-optimise.js +153 -0
  461. package/neural-interface/public/shared/skills/ss-eval-plan.js +315 -0
  462. package/neural-interface/public/shared/skills/ss-evals.js +417 -0
  463. package/neural-interface/public/shared/skills/ss-form.js +159 -0
  464. package/neural-interface/public/shared/skills/ss-frontmatter.js +376 -0
  465. package/neural-interface/public/shared/skills/ss-ids.js +32 -0
  466. package/neural-interface/public/shared/skills/ss-lint.js +149 -0
  467. package/neural-interface/public/shared/skills/ss-presets.js +117 -0
  468. package/neural-interface/public/shared/skills/ss-profiles.js +513 -0
  469. package/neural-interface/public/shared/skills/ss-resources.js +165 -0
  470. package/neural-interface/public/shared/skills/ss-review-view.js +190 -0
  471. package/neural-interface/public/shared/skills/ss-tabs.js +79 -0
  472. package/neural-interface/public/shared/skills/ss-unicode.js +135 -0
  473. package/neural-interface/public/shared/skills/studio/sx-actions.js +222 -0
  474. package/neural-interface/public/shared/skills/studio/sx-cm.js +101 -0
  475. package/neural-interface/public/shared/skills/studio/sx-create-ai-view.js +749 -0
  476. package/neural-interface/public/shared/skills/studio/sx-create-ai.js +237 -0
  477. package/neural-interface/public/shared/skills/studio/sx-create-view.js +254 -0
  478. package/neural-interface/public/shared/skills/studio/sx-create.js +126 -0
  479. package/neural-interface/public/shared/skills/studio/sx-diff-view.js +43 -0
  480. package/neural-interface/public/shared/skills/studio/sx-diff.js +133 -0
  481. package/neural-interface/public/shared/skills/studio/sx-docs.js +480 -0
  482. package/neural-interface/public/shared/skills/studio/sx-dom.js +230 -0
  483. package/neural-interface/public/shared/skills/studio/sx-edit-view.js +848 -0
  484. package/neural-interface/public/shared/skills/studio/sx-editor-model.js +193 -0
  485. package/neural-interface/public/shared/skills/studio/sx-errors.js +22 -0
  486. package/neural-interface/public/shared/skills/studio/sx-fixes-view.js +359 -0
  487. package/neural-interface/public/shared/skills/studio/sx-fixes.js +327 -0
  488. package/neural-interface/public/shared/skills/studio/sx-geometry.js +82 -0
  489. package/neural-interface/public/shared/skills/studio/sx-import.js +262 -0
  490. package/neural-interface/public/shared/skills/studio/sx-inspector.js +308 -0
  491. package/neural-interface/public/shared/skills/studio/sx-install-flow.js +282 -0
  492. package/neural-interface/public/shared/skills/studio/sx-install.js +313 -0
  493. package/neural-interface/public/shared/skills/studio/sx-library-view.js +748 -0
  494. package/neural-interface/public/shared/skills/studio/sx-library.js +479 -0
  495. package/neural-interface/public/shared/skills/studio/sx-main.js +690 -0
  496. package/neural-interface/public/shared/skills/studio/sx-operations-view.js +98 -0
  497. package/neural-interface/public/shared/skills/studio/sx-operations.js +11 -0
  498. package/neural-interface/public/shared/skills/studio/sx-plan.js +158 -0
  499. package/neural-interface/public/shared/skills/studio/sx-publish-view.js +621 -0
  500. package/neural-interface/public/shared/skills/studio/sx-review-view.js +369 -0
  501. package/neural-interface/public/shared/skills/studio/sx-review.js +148 -0
  502. package/neural-interface/public/shared/skills/studio/sx-scan.js +35 -0
  503. package/neural-interface/public/shared/skills/studio/sx-snippets.js +96 -0
  504. package/neural-interface/public/shared/skills/studio/sx-subject.js +249 -0
  505. package/neural-interface/public/shared/skills/studio/sx-test-view.js +994 -0
  506. package/neural-interface/public/shared/skills/studio/sx-test.js +328 -0
  507. package/neural-interface/public/shared/skills/studio/sx-versions-view.js +241 -0
  508. package/neural-interface/public/shared/skills/studio/sx-workspace-view.js +426 -0
  509. package/neural-interface/public/shared/state.js +1 -1
  510. package/neural-interface/public/shared/streaming-markdown.js +58 -0
  511. package/neural-interface/public/shared/styleguide/sg-panel.js +4 -2
  512. package/neural-interface/public/shared/styles.css +1822 -1756
  513. package/neural-interface/public/shared/synabun-mascot.js +1115 -9
  514. package/neural-interface/public/shared/text-cache.js +29 -0
  515. package/neural-interface/public/shared/tool-list-picker.js +55 -0
  516. package/neural-interface/public/shared/tool-list-storage.js +24 -0
  517. package/neural-interface/public/shared/tool-list-view.js +112 -0
  518. package/neural-interface/public/shared/topright-overflow-logic.js +54 -0
  519. package/neural-interface/public/shared/tour/tour-actor.js +268 -0
  520. package/neural-interface/public/shared/tour/tour-beats.js +336 -0
  521. package/neural-interface/public/shared/tour/tour-engine.js +884 -0
  522. package/neural-interface/public/shared/tour/tour-ink.js +390 -0
  523. package/neural-interface/public/shared/tour/tour-stage.js +440 -0
  524. package/neural-interface/public/shared/tour/tour-state.js +40 -0
  525. package/neural-interface/public/shared/tour/tour-tips.js +99 -0
  526. package/neural-interface/public/shared/tour/tour.css +144 -0
  527. package/neural-interface/public/shared/ui-antigravity-panel.js +19 -0
  528. package/neural-interface/public/shared/ui-assistant.js +2 -0
  529. package/neural-interface/public/shared/ui-automation-studio.js +111 -140
  530. package/neural-interface/public/shared/ui-claude-panel.js +376 -82
  531. package/neural-interface/public/shared/ui-cli-banner.js +23 -167
  532. package/neural-interface/public/shared/ui-command-runner.js +6 -3
  533. package/neural-interface/public/shared/ui-context-menu.js +295 -0
  534. package/neural-interface/public/shared/ui-cost-widget.js +57 -59
  535. package/neural-interface/public/shared/ui-crash-notice.js +187 -0
  536. package/neural-interface/public/shared/ui-detail.js +15 -3
  537. package/neural-interface/public/shared/ui-file-explorer.js +48 -6
  538. package/neural-interface/public/shared/ui-file-links.js +2 -2
  539. package/neural-interface/public/shared/ui-games.js +2 -2
  540. package/neural-interface/public/shared/ui-image-gallery.js +50 -47
  541. package/neural-interface/public/shared/ui-judgments.js +1 -1
  542. package/neural-interface/public/shared/ui-keybinds.js +33 -2
  543. package/neural-interface/public/shared/ui-link.js +3 -3
  544. package/neural-interface/public/shared/ui-menubar.js +10 -20
  545. package/neural-interface/public/shared/ui-native-loop-router-state.js +5 -0
  546. package/neural-interface/public/shared/ui-native-loop-router.js +11 -1
  547. package/neural-interface/public/shared/ui-navbar.js +49 -24
  548. package/neural-interface/public/shared/ui-notifications.js +1 -0
  549. package/neural-interface/public/shared/ui-panels.js +96 -65
  550. package/neural-interface/public/shared/ui-resume.js +9 -7
  551. package/neural-interface/public/shared/ui-schedules-studio.js +546 -431
  552. package/neural-interface/public/shared/ui-scroll-follow.js +16 -5
  553. package/neural-interface/public/shared/ui-sessions.js +27 -15
  554. package/neural-interface/public/shared/ui-settings.js +683 -526
  555. package/neural-interface/public/shared/ui-sidepanel-session-entry.js +9 -2
  556. package/neural-interface/public/shared/ui-sidepanel-sessions.js +4 -4
  557. package/neural-interface/public/shared/ui-sidepanel-state.js +23 -12
  558. package/neural-interface/public/shared/ui-sidepanel-tray.js +48 -7
  559. package/neural-interface/public/shared/ui-sidepanel-windows.js +18 -13
  560. package/neural-interface/public/shared/ui-skills.js +33 -2830
  561. package/neural-interface/public/shared/ui-styleguide.js +5 -2
  562. package/neural-interface/public/shared/ui-sync.js +15 -5
  563. package/neural-interface/public/shared/ui-terminal.js +270 -190
  564. package/neural-interface/public/shared/ui-tool-updates.js +6 -4
  565. package/neural-interface/public/shared/ui-tooltip.js +81 -51
  566. package/neural-interface/public/shared/ui-topright-overflow.js +233 -0
  567. package/neural-interface/public/shared/ui-trash.js +6 -4
  568. package/neural-interface/public/shared/ui-tutorial-layout.js +3 -117
  569. package/neural-interface/public/shared/ui-tutorial-preview.js +103 -0
  570. package/neural-interface/public/shared/ui-tutorial-steps.js +3 -65
  571. package/neural-interface/public/shared/ui-tutorial.css +47 -100
  572. package/neural-interface/public/shared/ui-tutorial.js +285 -509
  573. package/neural-interface/public/shared/ui-update.js +38 -2
  574. package/neural-interface/public/shared/ui-whiteboard.js +312 -59
  575. package/neural-interface/public/shared/ui-worker-end.js +5 -1
  576. package/neural-interface/public/shared/ui-workspaces.js +3 -2
  577. package/neural-interface/public/shared/view-variant.js +66 -0
  578. package/neural-interface/public/shared/whatsapp/wa-view.js +3 -3
  579. package/neural-interface/public/shared/whiteboard-list.js +172 -0
  580. package/neural-interface/public/shared/worker-end.js +10 -3
  581. package/neural-interface/public/shared/worker-questions.js +34 -0
  582. package/neural-interface/public/shared/worker-restart.js +12 -0
  583. package/neural-interface/public/sidepanel-session.html +2 -2
  584. package/neural-interface/public/variant/2d/background.js +2 -1
  585. package/neural-interface/public/variant/2d/context-menu.js +8 -2
  586. package/neural-interface/public/variant/2d/graph.js +42 -20
  587. package/neural-interface/public/variant/2d/hulls.js +14 -9
  588. package/neural-interface/public/variant/2d/lasso.js +11 -7
  589. package/neural-interface/public/variant/2d/main.js +32 -1
  590. package/neural-interface/public/variant/2d/minimap.js +11 -13
  591. package/neural-interface/public/variant/3d/main.js +69 -6
  592. package/neural-interface/public/variant/3d/map-controls.js +24 -9
  593. package/neural-interface/public/vendor/caveat/OFL.txt +93 -0
  594. package/neural-interface/public/vendor/caveat/caveat-latin-400-normal.woff2 +0 -0
  595. package/neural-interface/public/vendor/caveat/caveat-latin-700-normal.woff2 +0 -0
  596. package/neural-interface/public/vendor/caveat/caveat.css +17 -0
  597. package/neural-interface/public/vendor/caveat/manifest.json +12 -0
  598. package/neural-interface/public/vendor/yaml/LICENSE +13 -0
  599. package/neural-interface/public/vendor/yaml/manifest.json +4 -0
  600. package/neural-interface/public/vendor/yaml/yaml-2.9.1.min.js +137 -0
  601. package/neural-interface/scripts/build-vendor.mjs +32 -0
  602. package/neural-interface/server.js +4553 -2855
  603. package/neural-interface/templates/rulesets/README.md +1 -1
  604. package/neural-interface/templates/rulesets/core.md +1 -1
  605. package/neural-interface/templates/rulesets/legacy-hashes.json +23 -5
  606. package/neural-interface/templates/rulesets/manifest.json +8 -8
  607. package/npm-shrinkwrap.json +34 -12
  608. package/package.json +17 -3
  609. package/postinstall.js +9 -4
  610. package/preuninstall.js +1 -1
  611. package/setup.js +97 -322
  612. package/skills/skill-forge/SKILL.md +177 -0
  613. package/skills/skill-forge/evals/evals.json +54 -0
  614. package/skills/skill-forge/references/package.md +105 -0
  615. package/skills/skill-forge/references/review-and-recovery.md +63 -0
  616. package/skills/skill-forge/references/runtime-profiles.md +20 -0
  617. package/skills/skill-forge/references/sources-and-capabilities.md +51 -0
  618. package/skills/synabun/SKILL.md +10 -7
  619. package/skills/synabun/modules/audit.md +1 -5
  620. package/skills/synabun/modules/changelog.md +1 -5
  621. package/skills/synabun/modules/idea.md +1 -1
  622. package/skills/synabun/modules/memorize.md +6 -9
  623. package/skills/synabun/modules/schedule.md +6 -6
  624. package/mcp-server/dist/services/profiles.d.ts +0 -120
  625. package/mcp-server/dist/services/profiles.d.ts.map +0 -1
  626. package/mcp-server/dist/services/profiles.js +0 -387
  627. package/mcp-server/dist/services/profiles.js.map +0 -1
  628. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts +0 -97
  629. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts.map +0 -1
  630. package/mcp-server/dist/tools/leonardo-browser-tools.js +0 -228
  631. package/mcp-server/dist/tools/leonardo-browser-tools.js.map +0 -1
  632. package/mcp-server/dist/tools/leonardo.d.ts +0 -13
  633. package/mcp-server/dist/tools/leonardo.d.ts.map +0 -1
  634. package/mcp-server/dist/tools/leonardo.js +0 -21
  635. package/mcp-server/dist/tools/leonardo.js.map +0 -1
  636. package/mcp-server/dist/tools/profile.d.ts +0 -17
  637. package/mcp-server/dist/tools/profile.d.ts.map +0 -1
  638. package/mcp-server/dist/tools/profile.js +0 -114
  639. package/mcp-server/dist/tools/profile.js.map +0 -1
  640. package/mcp-server/src/services/profiles.ts +0 -428
  641. package/mcp-server/src/tools/leonardo-browser-tools.ts +0 -291
  642. package/mcp-server/src/tools/leonardo.ts +0 -30
  643. package/mcp-server/src/tools/profile.ts +0 -122
  644. package/neural-interface/lib/assistant-brains/opencode-browser-policy.js +0 -47
  645. package/neural-interface/lib/assistant-brains/opencode-route-gate.js +0 -62
  646. package/neural-interface/lib/mcp-profile-servers.js +0 -120
  647. package/neural-interface/public/shared/ui-tutorial-draw.js +0 -311
  648. package/skills/leonardo/SKILL.md +0 -168
  649. package/skills/leonardo/icon.svg +0 -1
  650. package/skills/leonardo/modules/browser-guide.md +0 -378
  651. package/skills/leonardo/modules/image-prompter.md +0 -283
  652. package/skills/leonardo/modules/model-advisor.md +0 -100
  653. package/skills/leonardo/modules/prompt-library.md +0 -110
  654. package/skills/leonardo/modules/style-guide.md +0 -186
  655. package/skills/leonardo/modules/video-prompter.md +0 -317
  656. /package/neural-interface/templates/rulesets/{gemini.md → antigravity.md} +0 -0
@@ -3,10 +3,12 @@
3
3
  // ═══════════════════════════════════════════
4
4
  //
5
5
  // What the side panels' Install button runs (POST /api/cli/install/:tool,
6
- // lib/cli-install-api.js) when Claude Code, Codex or OpenCode is not installed.
7
- // Each tool is installed the way its vendor documents for the system, from the
8
- // vendor's own source, with nothing else needed (no Node, npm, Homebrew or
9
- // Scoop). The sources are fixed here; a request only names the tool.
6
+ // lib/cli-install-api.js) when Claude Code, Codex, OpenCode or the Antigravity
7
+ // CLI is not installed. Each tool is installed the way its vendor documents for
8
+ // the system, from the vendor's own source, with nothing else needed (no Node,
9
+ // npm or Scoop; Homebrew only where it is installed already, for the
10
+ // Antigravity CLI's cask on macOS). The sources are fixed here; a request only
11
+ // names the tool.
10
12
  //
11
13
  // Claude Code Anthropic's native installer: https://claude.ai/install.sh
12
14
  // (bash) on macOS and Linux, https://claude.ai/install.ps1
@@ -19,34 +21,40 @@
19
21
  // checked against the SHA-256 GitHub publishes for it, or, when
20
22
  // GitHub's API does not answer, from https://chatgpt.com/codex/
21
23
  // (the same file). The installer checks the package it fetches.
22
- // OpenCode the install script https://opencode.ai/install (bash) on
23
- // macOS and Linux. On Windows, where that script does not run:
24
- // the newest OpenCode 1 release archive for the processor
25
- // (opencode-windows-x64-baseline.zip, which runs on every x64
26
- // CPU, or opencode-windows-arm64.zip) from the anomalyco/opencode
27
- // GitHub releases, checked against its published SHA-256, its
28
- // opencode.exe read out without an unzip program (the backups'
29
- // streaming reader) and put in %USERPROFILE%\.opencode\bin, the
30
- // folder the official installer uses (and the resolver looks in).
24
+ // OpenCode OpenCode 2's install script https://opencode.ai/v2/install
25
+ // (bash) on macOS and Linux, the one `opencode upgrade` itself
26
+ // runs (it puts opencode in ~/.opencode/bin). Windows has no
27
+ // one-click install: OpenCode 2 comes from WinGet there
28
+ // (Anomaly.OpenCode), and the banner shows that command.
29
+ // Antigravity Google's Antigravity CLI (agy). On a Mac with Homebrew, the
30
+ // cask antigravity-cli (Google's signed binary, linked as agy):
31
+ // `brew install --cask antigravity-cli`. Otherwise Google's
32
+ // installer https://antigravity.google/cli/install.sh (bash) on
33
+ // macOS and Linux, https://antigravity.google/cli/install.ps1
34
+ // (powershell.exe -NoProfile -ExecutionPolicy Bypass -File) on
35
+ // Windows, from antigravity.google only. The script checks the
36
+ // binary against the SHA-512 of Google's release manifest and
37
+ // puts agy in ~/.local/bin (%LOCALAPPDATA%\agy\bin on Windows).
31
38
  //
32
39
  // Every download is HTTPS, every redirect too, and only to the vendor's own
33
- // hosts. Nothing runs as administrator; everything lands in the user's own
40
+ // hosts (Homebrew downloads a cask itself and checks it against the cask's
41
+ // SHA-256). Nothing runs as administrator; everything lands in the user's own
34
42
  // folders. Install consents to adding the resolved CLI's folder to persistent
35
43
  // PATH when the vendor did not do so. That is a visible final step, using the
36
44
  // same writer as Add to PATH; a failed PATH write leaves the CLI installed and
37
45
  // reports a warning. Installers run without a terminal and without questions
38
- // (CODEX_NON_INTERACTIVE=1, PowerShell -NonInteractive).
46
+ // (CODEX_NON_INTERACTIVE=1, PowerShell -NonInteractive; NONINTERACTIVE=1 and
47
+ // no auto-update for Homebrew).
39
48
  //
40
49
  // One install per tool at a time. Every failure is a CliInstallError with a
41
50
  // `code` the page has words for. Nothing here throws to a caller of start().
42
51
 
43
52
  import { spawn } from 'node:child_process';
44
- import { createHash, randomBytes } from 'node:crypto';
45
- import { createWriteStream, existsSync, mkdirSync, rmSync, renameSync, unlinkSync } from 'node:fs';
53
+ import { createHash } from 'node:crypto';
54
+ import { accessSync, constants as fsConstants, existsSync, rmSync, statSync } from 'node:fs';
46
55
  import { mkdtemp, open } from 'node:fs/promises';
47
56
  import os from 'node:os';
48
57
  import path from 'node:path';
49
- import { openZipArchive } from './backup-zip-reader.js';
50
58
  import { buildInstallCommand } from './cli-update-planner.js';
51
59
  import { packagedPathLast, rememberedPackagedPath, withPathEnv } from './augmented-path.js';
52
60
 
@@ -60,7 +68,6 @@ export const CLI_INSTALL_ERROR_CODES = Object.freeze([
60
68
  'timeout', // nothing arrived for too long, or the installer ran too long
61
69
  'installer-failed', // the vendor's installer exited with an error
62
70
  'not-found-after-install', // it finished, but no working CLI is found
63
- 'unpack', // the archive did not hold the program
64
71
  'disk', // a file could not be written
65
72
  'cancelled', // stopped (SynaBun shutting down)
66
73
  'internal', // anything else
@@ -79,13 +86,12 @@ export class CliInstallError extends Error {
79
86
  export const CLI_INSTALL_GUIDES = Object.freeze({
80
87
  'claude-code': 'https://code.claude.com/docs/en/setup',
81
88
  codex: 'https://learn.chatgpt.com/docs/codex/cli',
82
- opencode: 'https://opencode.ai/docs/',
83
- gemini: 'https://github.com/google-gemini/gemini-cli',
89
+ opencode: 'https://opencode.ai/v2/docs',
90
+ antigravity: 'https://antigravity.google/docs/getting-started',
84
91
  });
85
92
 
86
93
  const GITHUB_DOWNLOAD_HOSTS = ['github.com', 'objects.githubusercontent.com', 'release-assets.githubusercontent.com', 'github-releases.githubusercontent.com'];
87
94
  const MAX_SCRIPT_BYTES = 2 * 1024 * 1024;
88
- const MAX_ARCHIVE_BYTES = 600 * 1024 * 1024;
89
95
  const MAX_JSON_BYTES = 8 * 1024 * 1024;
90
96
  const MAX_REDIRECTS = 6;
91
97
  const LOG_KEEP = 200;
@@ -95,12 +101,15 @@ const hostIs = (...hosts) => (url) => hosts.includes(url.hostname);
95
101
 
96
102
  /**
97
103
  * The one-click method for a tool on this system, or null when there is none
98
- * (Gemini CLI, a 32-bit or other system). Pure: tests ask it for every OS.
104
+ * (OpenCode on Windows, a 32-bit or other system). `brew` is the path of a
105
+ * Homebrew this process can run (findBrew), or null: on macOS the Antigravity
106
+ * CLI is installed through it (its cask), else with Google's installer.
107
+ * `manualCommand`, when a plan has one, is what to type for the same install.
108
+ * Pure: tests ask it for every OS.
99
109
  */
100
- export function installPlanFor(toolKey, { platform = process.platform, arch = process.arch, env = process.env, home } = {}) {
110
+ export function installPlanFor(toolKey, { platform = process.platform, arch = process.arch, env = process.env, home, brew = null } = {}) {
101
111
  if (!(SUPPORTED[platform] || []).includes(arch)) return null;
102
112
  const windows = platform === 'win32';
103
- const homeDir = home || (windows ? env.USERPROFILE : env.HOME) || os.homedir();
104
113
  switch (toolKey) {
105
114
  case 'claude-code':
106
115
  return {
@@ -126,30 +135,41 @@ export function installPlanFor(toolKey, { platform = process.platform, arch = pr
126
135
  env: { CODEX_NON_INTERACTIVE: '1' },
127
136
  };
128
137
  case 'opencode':
129
- if (windows) {
138
+ // OpenCode 2's own installer is a bash script; on Windows it comes from WinGet (no one-click install).
139
+ if (windows) return null;
140
+ return {
141
+ tool: toolKey,
142
+ kind: 'script',
143
+ interpreter: 'bash',
144
+ url: 'https://opencode.ai/v2/install',
145
+ allow: (url) => url.hostname === 'opencode.ai' || (url.hostname === 'raw.githubusercontent.com' && url.pathname.startsWith('/anomalyco/opencode/')),
146
+ source: 'https://opencode.ai/v2/install',
147
+ label: 'OpenCode 2 install script',
148
+ env: {},
149
+ };
150
+ case 'antigravity':
151
+ // Homebrew's cask on a Mac that has Homebrew: the CLI then updates with the user's other casks.
152
+ if (platform === 'darwin' && brew) {
130
153
  return {
131
154
  tool: toolKey,
132
- kind: 'archive',
133
- interpreter: null,
134
- repo: 'anomalyco/opencode',
135
- tag: /^v1\.\d+\.\d+$/,
136
- assets: arch === 'arm64' ? ['opencode-windows-arm64.zip'] : ['opencode-windows-x64-baseline.zip', 'opencode-windows-x64.zip'],
137
- member: 'opencode.exe',
138
- // The official installer's folder; $OPENCODE_INSTALL_DIR, which older installers honoured, when set.
139
- dir: env.OPENCODE_INSTALL_DIR || path.win32.join(homeDir, '.opencode', 'bin'),
140
- source: 'https://github.com/anomalyco/opencode/releases',
141
- label: 'OpenCode release archive',
142
- env: {},
155
+ kind: 'brew',
156
+ brew,
157
+ args: ['install', '--cask', 'antigravity-cli'],
158
+ source: 'https://formulae.brew.sh/cask/antigravity-cli',
159
+ label: 'Homebrew cask antigravity-cli',
160
+ manualCommand: 'brew install --cask antigravity-cli',
161
+ env: { HOMEBREW_NO_AUTO_UPDATE: '1', HOMEBREW_NO_ENV_HINTS: '1', NONINTERACTIVE: '1' },
143
162
  };
144
163
  }
145
164
  return {
146
165
  tool: toolKey,
147
166
  kind: 'script',
148
- interpreter: 'bash',
149
- url: 'https://opencode.ai/install',
150
- allow: (url) => url.hostname === 'opencode.ai' || (url.hostname === 'raw.githubusercontent.com' && url.pathname.startsWith('/anomalyco/opencode/')),
151
- source: 'https://opencode.ai/install',
152
- label: 'OpenCode install script',
167
+ interpreter: windows ? 'powershell' : 'bash',
168
+ url: windows ? 'https://antigravity.google/cli/install.ps1' : 'https://antigravity.google/cli/install.sh',
169
+ allow: hostIs('antigravity.google'),
170
+ source: windows ? 'https://antigravity.google/cli/install.ps1' : 'https://antigravity.google/cli/install.sh',
171
+ label: 'Google Antigravity CLI installer',
172
+ manualCommand: windows ? 'irm https://antigravity.google/cli/install.ps1 | iex' : 'curl -fsSL https://antigravity.google/cli/install.sh | bash',
153
173
  env: {},
154
174
  };
155
175
  default:
@@ -157,14 +177,47 @@ export function installPlanFor(toolKey, { platform = process.platform, arch = pr
157
177
  }
158
178
  }
159
179
 
160
- /** What the status of a tool says about its one-click install. */
161
- export function describeInstall(toolKey, options) {
162
- const plan = installPlanFor(toolKey, options);
180
+ /** A file this process may run (a link is followed). */
181
+ function isExecutableFile(file) {
182
+ try {
183
+ if (!statSync(file).isFile()) return false;
184
+ accessSync(file, fsConstants.X_OK);
185
+ return true;
186
+ } catch {
187
+ return false;
188
+ }
189
+ }
190
+
191
+ /**
192
+ * Homebrew's brew on macOS: /opt/homebrew/bin (Apple silicon), /usr/local/bin
193
+ * (Intel), then each folder of PATH; the first executable file. A relative
194
+ * PATH folder is never looked in. Null on any other system, and on a Mac
195
+ * without Homebrew.
196
+ */
197
+ export function findBrew({ platform = process.platform, env = process.env, isExecutable = isExecutableFile } = {}) {
198
+ if (platform !== 'darwin') return null;
199
+ const asked = new Set();
200
+ for (const folder of ['/opt/homebrew/bin', '/usr/local/bin', ...String(env.PATH || '').split(':')]) {
201
+ if (!folder || !path.posix.isAbsolute(folder)) continue;
202
+ const file = path.posix.join(folder, 'brew');
203
+ if (asked.has(file)) continue;
204
+ asked.add(file);
205
+ if (isExecutable(file)) return file;
206
+ }
207
+ return null;
208
+ }
209
+
210
+ function describePlan(plan) {
163
211
  return plan
164
- ? { available: true, method: plan.kind, source: plan.source, interpreter: plan.interpreter, label: plan.label }
212
+ ? { available: true, method: plan.kind, source: plan.source, interpreter: plan.interpreter || null, label: plan.label }
165
213
  : { available: false, method: null, source: null, interpreter: null, label: null };
166
214
  }
167
215
 
216
+ /** What the status of a tool says about its one-click install. */
217
+ export function describeInstall(toolKey, options) {
218
+ return describePlan(installPlanFor(toolKey, options));
219
+ }
220
+
168
221
  // ── Transfers ───────────────────────────────────────────────────────────────
169
222
 
170
223
  function errorCode(error) {
@@ -340,55 +393,6 @@ export function releaseAsset(release, name, repo) {
340
393
  return { name, url, size: Number(asset.size) || null, sha256: sha256OfDigest(asset.digest) };
341
394
  }
342
395
 
343
- /**
344
- * The newest OpenCode 1 release (not a draft, not a prerelease; OpenCode 2 is
345
- * a different program SynaBun's panel does not drive) that carries one of
346
- * `assets`, the first listed preferred.
347
- */
348
- export function pickOpencodeRelease(releases, { assets, repo = 'anomalyco/opencode', tag = /^v1\.\d+\.\d+$/ } = {}) {
349
- for (const release of Array.isArray(releases) ? releases : []) {
350
- if (!release || release.draft || release.prerelease || !tag.test(String(release.tag_name || ''))) continue;
351
- for (const name of assets || []) {
352
- const asset = releaseAsset(release, name, repo);
353
- if (asset) return { tag: release.tag_name, version: String(release.tag_name).replace(/^v/, ''), asset };
354
- }
355
- }
356
- return null;
357
- }
358
-
359
- // ── Zip ─────────────────────────────────────────────────────────────────────
360
-
361
- const unpack = (message) => new CliInstallError('unpack', message);
362
-
363
- /**
364
- * Read one member out of a zip archive into `destination` (a new file),
365
- * without an unzip program and without using a name of the archive as a path:
366
- * only the entry called exactly `member` is read, through the streaming
367
- * reader of backups (backup-zip-reader.js: ZIP64, stored or deflated, checked
368
- * against its size and CRC-32).
369
- */
370
- export async function extractZipMember({ archive, member, destination, maxSize = 1024 ** 3, mode = 0o755 }) {
371
- let zip;
372
- try { zip = await openZipArchive(archive); } catch (error) { throw unpack(`The download is not a readable zip archive (${error?.message || error}).`); }
373
- let opened = false;
374
- try {
375
- const entry = zip.getEntry(member);
376
- if (!entry) throw unpack(`The archive holds no ${member}.`);
377
- if (entry.uncompressedSize > maxSize) throw unpack(`The archive's ${member} is larger than expected.`);
378
- const out = createWriteStream(destination, { flags: 'wx', mode });
379
- out.on('open', () => { opened = true; });
380
- await zip.pipeEntry(entry, out);
381
- return { size: entry.uncompressedSize };
382
- } catch (error) {
383
- if (opened) rmSync(destination, { force: true });
384
- if (error instanceof CliInstallError) throw error;
385
- if (DISK_CODES.has(errorCode(error))) throw asInstallError(error, 'disk', `The program could not be written (${errorCode(error)}).`);
386
- throw unpack(`The archive's ${member} could not be read (${error?.message || error}).`);
387
- } finally {
388
- try { await zip.close(); } catch { /* closed */ }
389
- }
390
- }
391
-
392
396
  // ── Output ──────────────────────────────────────────────────────────────────
393
397
 
394
398
  const ANSI = /\x1b\[[0-9;?]*[ -\/]*[@-~]|\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)|\x1b[()][A-Za-z0-9]|\x1b[=>78DEHMNOZc]/g;
@@ -423,6 +427,19 @@ export function createLineSplitter(onLine) {
423
427
  };
424
428
  }
425
429
 
430
+ /**
431
+ * The step a line of Homebrew's output begins, or null: its download (and its
432
+ * download queue's "Fetching"), the check of what it downloaded against the
433
+ * cask's checksum, and the install itself (moving and linking the binary).
434
+ */
435
+ export function brewStepOf(line) {
436
+ const text = String(line ?? '').trim();
437
+ if (/^==> (?:Downloading|Fetching)\b/.test(text)) return 'download';
438
+ if (/^==> Verifying\b/.test(text) || /checksum|sha-?256/i.test(text)) return 'verify';
439
+ if (/^==> (?:Installing|Moving|Linking)\b/.test(text)) return 'run';
440
+ return null;
441
+ }
442
+
426
443
  function sameDir(a, b, platform) {
427
444
  const clean = (value) => {
428
445
  const text = String(value || '').replace(/[\\/]+$/, '');
@@ -442,6 +459,7 @@ export function onPathList(dir, entries, platform = process.platform) {
442
459
  * @param {object} deps
443
460
  * @param {{ resolve: Function }} deps.resolver cli-resolver.js: the final check (force)
444
461
  * @param {() => Promise<string[]>} [deps.readOsPath] the OS PATH a new terminal gets, read afresh
462
+ * @param {(o: { platform: string, env: object }) => string|null} [deps.findBrew] Homebrew's brew, or null (findBrew)
445
463
  * @param {(tool: string, ok: boolean, status: object|null) => void} [deps.onFinished]
446
464
  */
447
465
  export function createCliInstaller({
@@ -453,6 +471,7 @@ export function createCliInstaller({
453
471
  tmpRoot = os.tmpdir(),
454
472
  fetchImpl = fetch,
455
473
  spawnImpl = spawn,
474
+ findBrew: lookForBrew = findBrew,
456
475
  readOsPath = async () => [],
457
476
  addToPath = null,
458
477
  installerPath = null,
@@ -464,9 +483,12 @@ export function createCliInstaller({
464
483
  if (!resolver?.resolve) throw new Error('createCliInstaller needs the CLI resolver');
465
484
  const jobs = new Map();
466
485
  const windows = platform === 'win32';
467
- const planFor = (toolKey) => installPlanFor(toolKey, { platform, arch, env, home });
486
+ // Homebrew is looked for at every ask: one installed meanwhile counts from the next check on.
487
+ const brewOf = () => { try { return lookForBrew({ platform, env }) || null; } catch { return null; } };
488
+ const planFor = (toolKey) => installPlanFor(toolKey, { platform, arch, env, home, brew: brewOf() });
468
489
  const guideOf = (toolKey) => CLI_INSTALL_GUIDES[toolKey] || null;
469
- const manualOf = (toolKey) => buildInstallCommand(toolKey, 'unknown', { platform });
490
+ // The command for the very install the button runs here, when its plan names one; else the vendor's for this system.
491
+ const manualOf = (toolKey) => planFor(toolKey)?.manualCommand || buildInstallCommand(toolKey, 'unknown', { platform });
470
492
 
471
493
  function publicJob(job) {
472
494
  return {
@@ -580,15 +602,19 @@ export function createCliInstaller({
580
602
  return file;
581
603
  }
582
604
 
583
- function runScript(job, plan, scriptFile, workDir, osEntries, { line }) {
584
- const interpreter = interpreterFor(plan);
605
+ /**
606
+ * Run an installer to its end: no stdin, every line of its output to `onLine`, stopped with everything it
607
+ * started when it runs longer than timeoutMs or the job is stopped. Resolves on exit code 0. `name` is what
608
+ * the sentence of a failure calls it (`slowName`, the one of a timeout).
609
+ */
610
+ function runChild(job, plan, { file, args, cwd, osEntries, onLine, name, slowName = name }) {
585
611
  const childEnv = { ...withPathEnv({ ...env, ...plan.env }, installerPathValue(osEntries), platform), TERM: 'dumb', NO_COLOR: '1' };
586
612
  delete childEnv.FORCE_COLOR;
587
613
  return new Promise((resolve, reject) => {
588
614
  let child;
589
615
  try {
590
- child = spawnImpl(interpreter.file, interpreter.args(scriptFile), {
591
- cwd: workDir,
616
+ child = spawnImpl(file, args, {
617
+ cwd,
592
618
  env: childEnv,
593
619
  stdio: ['ignore', 'pipe', 'pipe'],
594
620
  windowsHide: true,
@@ -597,18 +623,18 @@ export function createCliInstaller({
597
623
  detached: !windows,
598
624
  });
599
625
  } catch (error) {
600
- reject(asInstallError(error, 'installer-failed', `${interpreter.file} could not be started.`));
626
+ reject(asInstallError(error, 'installer-failed', `${file} could not be started.`));
601
627
  return;
602
628
  }
603
629
  job.child = child;
604
- const out = createLineSplitter(line);
605
- const err = createLineSplitter(line);
630
+ const out = createLineSplitter(onLine);
631
+ const err = createLineSplitter(onLine);
606
632
  child.stdout?.on('data', chunk => out.push(chunk.toString('utf8')));
607
633
  child.stderr?.on('data', chunk => err.push(chunk.toString('utf8')));
608
634
  let settled = false;
609
635
  const timer = setTimeout(() => {
610
636
  stopChild(child, windows, spawnImpl);
611
- finish(new CliInstallError('timeout', `The installer was still running after ${Math.round(timeoutMs / 60_000)} minutes and was stopped.`));
637
+ finish(new CliInstallError('timeout', `${slowName} was still running after ${Math.round(timeoutMs / 60_000)} minutes and was stopped.`));
612
638
  }, timeoutMs);
613
639
  timer.unref?.();
614
640
  const onAbort = () => { stopChild(child, windows, spawnImpl); finish(new CliInstallError('cancelled', 'The install was stopped.')); };
@@ -622,58 +648,41 @@ export function createCliInstaller({
622
648
  err.end();
623
649
  job.child = null;
624
650
  if (error) reject(error);
625
- else if (code !== 0) reject(new CliInstallError('installer-failed', `The ${plan.label} stopped with exit code ${code}.`, { detail: code }));
651
+ else if (code !== 0) reject(new CliInstallError('installer-failed', `${name} stopped with exit code ${code}.`, { detail: code }));
626
652
  else resolve();
627
653
  }
628
- child.on('error', error => finish(asInstallError(error, 'installer-failed', `${interpreter.file} could not be started (${errorCode(error) || error?.message}).`)));
654
+ child.on('error', error => finish(asInstallError(error, 'installer-failed', `${file} could not be started (${errorCode(error) || error?.message}).`)));
629
655
  child.on('close', (code, signal) => finish(null, code ?? (signal ? 128 : 1)));
630
656
  });
631
657
  }
632
658
 
633
- async function installArchive(job, plan, workDir, { step, line, progress }) {
634
- step('download');
635
- const releases = await fetchGithubJson(`https://api.github.com/repos/${plan.repo}/releases?per_page=20`, { fetchImpl, signal: job.abort.signal });
636
- const picked = pickOpencodeRelease(releases, { assets: plan.assets, repo: plan.repo, tag: plan.tag });
637
- if (!picked) throw new CliInstallError('http', `No OpenCode 1 release of ${plan.repo} carries ${plan.assets.join(' or ')}.`);
638
- job.source = picked.asset.url;
639
- line(`OpenCode ${picked.version}: ${picked.asset.name}`);
640
- const archive = path.join(workDir, picked.asset.name);
641
- const got = await downloadFile({
642
- url: picked.asset.url,
643
- allow: (url) => GITHUB_DOWNLOAD_HOSTS.includes(url.hostname),
644
- destination: archive,
645
- maxBytes: MAX_ARCHIVE_BYTES,
646
- expectedSize: picked.asset.size,
647
- sha256: picked.asset.sha256,
648
- fetchImpl,
649
- signal: job.abort.signal,
650
- onProgress: progress,
651
- stallMs,
659
+ function runScript(job, plan, scriptFile, workDir, osEntries, { line }) {
660
+ const interpreter = interpreterFor(plan);
661
+ return runChild(job, plan, {
662
+ file: interpreter.file, args: interpreter.args(scriptFile), cwd: workDir, osEntries, onLine: line,
663
+ name: `The ${plan.label}`, slowName: 'The installer',
664
+ });
665
+ }
666
+
667
+ /**
668
+ * Homebrew installs the cask (`brew install --cask …`, never auto-updating first). It downloads and checks the
669
+ * cask itself: its own lines move the steps (brewStepOf), from 'run' on.
670
+ */
671
+ function runBrew(job, plan, workDir, osEntries, { step, line }) {
672
+ let at = 'run';
673
+ step(at);
674
+ return runChild(job, plan, {
675
+ file: plan.brew, args: plan.args, cwd: workDir, osEntries,
676
+ onLine: (text) => {
677
+ const next = brewStepOf(text);
678
+ if (next && next !== at) {
679
+ at = next;
680
+ step(next);
681
+ }
682
+ line(text);
683
+ },
684
+ name: `brew ${plan.args.join(' ')}`,
652
685
  });
653
- step('verify');
654
- line(picked.asset.sha256 ? `SHA-256 matches the published one (${got.sha256.slice(0, 12)}…).` : 'GitHub publishes no SHA-256 for this file; its size matches.');
655
- step('extract');
656
- try { mkdirSync(plan.dir, { recursive: true }); } catch (error) { throw asInstallError(error, 'disk', `${plan.dir} could not be created (${errorCode(error)}).`); }
657
- const part = path.join(plan.dir, `.${plan.member}.${randomBytes(4).toString('hex')}.part`);
658
- await extractZipMember({ archive, member: plan.member, destination: part });
659
- step('place');
660
- const head = Buffer.alloc(2);
661
- const handle = await open(part, 'r');
662
- try { await handle.read(head, 0, 2, 0); } finally { await handle.close(); }
663
- if (head[0] !== 0x4d || head[1] !== 0x5a) {
664
- rmSync(part, { force: true });
665
- throw new CliInstallError('unpack', `The archive's ${plan.member} is not a Windows program.`);
666
- }
667
- const target = path.join(plan.dir, plan.member);
668
- try {
669
- renameSync(part, target);
670
- } catch (error) {
671
- rmSync(part, { force: true });
672
- throw asInstallError(error, 'disk', `${target} could not be written (${errorCode(error)}: is an OpenCode still running from there?).`);
673
- }
674
- // Files SynaBun writes carry no Mark of the Web; a copy that does (a mirror, an antivirus) is cleared so it can start.
675
- try { unlinkSync(`${target}:Zone.Identifier`); } catch { /* none */ }
676
- line(`Placed ${target}`);
677
686
  }
678
687
 
679
688
  async function run(job) {
@@ -685,12 +694,12 @@ export function createCliInstaller({
685
694
  emit(job, { type: 'start', tool, method: plan.kind, source: plan.source, label: plan.label, platform, arch });
686
695
  try { before = await readOsPath(); } catch { before = []; }
687
696
  workDir = await mkdtemp(path.join(tmpRoot, `synabun-cli-install-${tool}-`));
688
- if (plan.kind === 'script') {
697
+ if (plan.kind === 'brew') {
698
+ await runBrew(job, plan, workDir, before, io);
699
+ } else {
689
700
  const script = await fetchScript(job, plan, workDir, io);
690
701
  io.step('run');
691
702
  await runScript(job, plan, script, workDir, before, io);
692
- } else {
693
- await installArchive(job, plan, workDir, io);
694
703
  }
695
704
  io.step('check');
696
705
  const status = await resolver.resolve(tool, { force: true });
@@ -738,7 +747,7 @@ export function createCliInstaller({
738
747
  }
739
748
 
740
749
  return {
741
- describe: (toolKey) => describeInstall(toolKey, { platform, arch, env, home }),
750
+ describe: (toolKey) => describePlan(planFor(toolKey)),
742
751
  guideUrl: guideOf,
743
752
  manualCommand: manualOf,
744
753
  jobs() {
@@ -1,5 +1,5 @@
1
1
  // ═══════════════════════════════════════════
2
- // SynaBun — where the user's Claude Code, Codex and OpenCode are
2
+ // SynaBun — where the user's Claude Code, Codex, OpenCode and Antigravity (agy) are
3
3
  // ═══════════════════════════════════════════
4
4
  //
5
5
  // One answer for every place that looks for one of these CLIs: the version
@@ -55,7 +55,7 @@ export const CLI_TOOLS = Object.freeze({
55
55
  'claude-code': Object.freeze({ key: 'claude-code', command: 'claude', label: 'Claude Code' }),
56
56
  codex: Object.freeze({ key: 'codex', command: 'codex', label: 'Codex' }),
57
57
  opencode: Object.freeze({ key: 'opencode', command: 'opencode', label: 'OpenCode' }),
58
- gemini: Object.freeze({ key: 'gemini', command: 'gemini', label: 'Gemini CLI' }),
58
+ antigravity: Object.freeze({ key: 'antigravity', command: 'agy', label: 'Antigravity CLI' }),
59
59
  });
60
60
 
61
61
  const PROBE_TIMEOUT_MS = 15_000;
@@ -134,6 +134,10 @@ function wingetPackageFiles({ localAppData, prefixes, exe, readdir, pathImpl })
134
134
  * OpenCode install script: ~/.opencode/bin/opencode (older scripts:
135
135
  * $OPENCODE_INSTALL_DIR, $XDG_BIN_DIR); on Windows the folder
136
136
  * SynaBun's own install uses, %USERPROFILE%\.opencode\bin
137
+ * Antigravity Google's installer (antigravity.google/cli/install.sh, checked
138
+ * 2026-10-30): ~/.local/bin/agy; install.ps1 on Windows:
139
+ * %LOCALAPPDATA%\agy\bin\agy.exe. Homebrew's cask links agy
140
+ * into Homebrew's bin, which the package-manager folders cover.
137
141
  */
138
142
  export function toolSpecificFiles(toolKey, {
139
143
  platform = process.platform,
@@ -168,6 +172,9 @@ export function toolSpecificFiles(toolKey, {
168
172
  if (env.XDG_BIN_DIR) add(join(env.XDG_BIN_DIR, exe('opencode')), 'standalone');
169
173
  if (windows) for (const file of wingetPackageFiles({ localAppData, prefixes: ['sst.opencode', 'anomalyco.opencode', 'opencode.'], exe: 'opencode.exe', readdir, pathImpl })) add(file, 'winget');
170
174
  break;
175
+ case 'antigravity':
176
+ add(windows ? join(localAppData, 'agy', 'bin', 'agy.exe') : join(home, '.local', 'bin', 'agy'), 'standalone');
177
+ break;
171
178
  default:
172
179
  break;
173
180
  }
@@ -198,7 +205,10 @@ export function describeConfigured(value, toolKey, {
198
205
  return { value: raw, kind: 'command', name: text };
199
206
  }
200
207
 
201
- /** OpenCode's npm package: its command file runs node_modules\opencode-ai\bin\opencode.exe, the platform build its postinstall put there. */
208
+ /**
209
+ * npm's opencode-ai (OpenCode 1): its command file runs node_modules\opencode-ai\bin\opencode.exe, the platform build
210
+ * its postinstall put there. Still found, so that SynaBun can say which version it is when it refuses it.
211
+ */
202
212
  export function windowsOpencodeTargets(launcher, arch = process.arch) {
203
213
  const pathImpl = path.win32;
204
214
  const folder = pathImpl.dirname(String(launcher || ''));