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
@@ -2,7 +2,7 @@
2
2
  // SynaBun — Browser tool policy: every page through the SynaBun browser
3
3
  // ═══════════════════════════════════════════
4
4
  //
5
- // The Assistant's brain (Claude, Codex, OpenCode) and the workers it
5
+ // The Assistant's brain (Claude, Codex, OpenCode, Antigravity) and the workers it
6
6
  // dispatches look at pages — public or localhost — only through SynaBun's
7
7
  // browser tools (browser_*), which open the browser configured in SynaBun
8
8
  // (MoreLogin). They never start a browser of their own, and when the SynaBun
@@ -15,14 +15,18 @@
15
15
  // reactive fallback); Assistant task runs' workers in
16
16
  // native-loop-providers.js (Claude),
17
17
  // assistant-brains/codex-browser-policy-hook.mjs and
18
- // assistant-brains/opencode-browser-policy.js
18
+ // assistant-brains/opencode2-browser-policy/
19
19
  //
20
20
  // Lexical, like remote-policy.js: a speed bump, not a sandbox. A shell that
21
21
  // builds a program name at run time, or a script loading a browser library
22
22
  // from a file SynaBun cannot read, gets past it. Mentions (rg playwright,
23
- // cat pw.cjs, sed -i … pw.cjs, git, code that only names a library) and a
24
- // project's own automated tests (npm test, node --test, vitest, jest, npx
25
- // playwright test run inside the project on files inside it) always pass.
23
+ // cat pw.cjs, sed -i … pw.cjs, git, code that only names a library), a
24
+ // syntax check (node --check <file>: Node parses it and runs nothing) and
25
+ // automated tests (npm test, node --test, vitest, jest, npx playwright test)
26
+ // run from inside one allowed project on files inside that same project
27
+ // always pass. The allowed projects are the session's own and the `roots` its
28
+ // caller passes: the registered SynaBun projects that are code projects
29
+ // (lib/browser-policy-roots.js, read by the caller as a run starts).
26
30
  // Computer use on a browser window is refused by the desktop guards
27
31
  // (lib/desktop/guards.js), which know the app a click or a key lands in.
28
32
  // Pure ESM with no imports of SynaBun's own, loaded by Node and by OpenCode's
@@ -44,13 +48,14 @@ const MAX_DEPTH = 4;
44
48
 
45
49
  // ── the rule text ───────────────────────────────────────────────────────────
46
50
 
47
- const HOSTS = { claude: 'claude', 'claude-code': 'claude', codex: 'codex', opencode: 'opencode' };
51
+ const HOSTS = { claude: 'claude', 'claude-code': 'claude', codex: 'codex', opencode: 'opencode', antigravity: 'antigravity' };
48
52
  const hostKey = (host) => HOSTS[String(host || '').toLowerCase()] || null;
49
53
  // Each host's own web search / fetch (the rule names the host's; unknown: all of them).
50
54
  const WEB_TOOL_WORDS = {
51
55
  claude: 'WebSearch / WebFetch',
52
56
  codex: 'Codex\'s web_search',
53
57
  opencode: 'webfetch / websearch',
58
+ antigravity: 'Antigravity\'s own web search, URL reading or browser',
54
59
  };
55
60
 
56
61
  /**
@@ -68,17 +73,21 @@ function browserToolNames(tools) {
68
73
  };
69
74
  }
70
75
 
76
+ // Where automated tests run, and the syntax check: one sentence for the rule text and every refusal.
77
+ const TEST_RUN_RULE = 'Automated tests run through their test runner (npm test, node --test, vitest, jest, npx playwright test, not its UI or debug mode) from inside the project they belong to: cd into that project first and name only its own files. That project may be this session\'s or any registered SynaBun project that is a code project (git, package.json or deno.json at its top; never the Downloads folder). A syntax check (node --check <file>) always runs.';
78
+
71
79
  /**
72
80
  * The browser rule, as bullet lines: the brain's persona (its host's tool
73
81
  * names in `tools`), the worker prompts of browser runs. `host`: claude /
74
- * codex / opencode (names that host's own web tools), else all of them.
82
+ * codex / opencode / antigravity (names that host's own web tools), else all of them.
75
83
  */
76
84
  export function browserPolicyText({ tools = '', host = null } = {}) {
77
85
  const t = browserToolNames(tools);
78
86
  const web = WEB_TOOL_WORDS[hostKey(host)] || 'WebSearch / WebFetch (OpenCode webfetch / websearch, Codex web_search)';
79
87
  return [
80
88
  `- Every page, public or localhost, goes through SynaBun's browser tools (${t.navigate}, ${t.snapshot}, ${t.screenshot}, ${t.console} and the other browser_* tools); they open the browser configured in SynaBun (MoreLogin). Nothing else opens a page.`,
81
- '- Never run Playwright, Puppeteer or Selenium code of your own to look at a page (a script, node -e, python -c, a heredoc), and never `npx playwright` except to run the project\'s automated tests (npx playwright test).',
89
+ '- Never run Playwright, Puppeteer or Selenium code of your own to look at a page (a script, node -e, python -c, a heredoc), and never `npx playwright` except to run automated tests (npx playwright test).',
90
+ `- ${TEST_RUN_RULE}`,
82
91
  '- Never launch Chrome, Chromium, Edge, chrome-headless-shell or any other browser binary, and never take headless screenshots (--headless, --screenshot).',
83
92
  '- Never `open` a URL or a browser app, and never use computer use on a browser app.',
84
93
  `- Never use the Playwright, Chrome DevTools, Claude-in-Chrome or any other browser MCP tools, nor ${web}.`,
@@ -106,9 +115,11 @@ const OPENCODE_BROWSER_TOOL = new RegExp(`^([a-z0-9-]*?(?:${BROWSER_SERVER_WORD}
106
115
  const PAGE_TOOL = /^(?:browser_.+|navigate(?:_(?:page|to|to_url|url|back|forward))?|go_?to(?:_(?:url|page))?|go_(?:back|forward)|open_(?:url|page|link|website|webpage|browser|in_browser)|new_page|launch_browser|(?:take|capture)_(?:page_|full_page_|web_?page_|website_)?screenshot|(?:page|full_page|web_?page|website)_screenshot|screenshot(?:_(?:page|url|website|webpage))?)$/;
107
116
  const snakeName = (text) => String(text || '').replace(/([a-z0-9])([A-Z])/g, '$1_$2').replace(/[-.\s]+/g, '_').toLowerCase();
108
117
  // Web search / fetch outside the SynaBun browser: Claude's, OpenCode's, Codex's.
109
- const WEB_TOOLS = new Set(['websearch', 'webfetch', 'web_search', 'web_fetch', 'web_search_preview']);
118
+ const WEB_TOOLS = new Set(['websearch', 'webfetch', 'web_search', 'web_fetch', 'web_search_preview', 'search_web', 'read_url_content', 'execute_url']);
119
+ // Antigravity's own browser and browser subagent (its tools' own names, lib/antigravity/tool-call.js).
120
+ const ANTIGRAVITY_BROWSER_TOOLS = new Set(['open_browser_url', 'read_browser_page', 'browser_subagent', 'list_browser_pages', 'capture_browser_screenshot', 'capture_browser_console_logs', 'execute_browser_javascript', 'click_browser_pixel']);
110
121
  // Shell tools: Claude's Bash / PowerShell, Codex's shell family, OpenCode's bash.
111
- const SHELL_TOOLS = new Set(['bash', 'powershell', 'shell', 'shell_command', 'exec_command', 'local_shell', 'container.exec', 'unified_exec']);
122
+ const SHELL_TOOLS = new Set(['bash', 'powershell', 'shell', 'shell_command', 'exec_command', 'local_shell', 'container.exec', 'unified_exec', 'run_command']);
112
123
 
113
124
  /**
114
125
  * What another MCP server's tool does to a browser (for the refusal), else null:
@@ -230,6 +241,27 @@ function insideDir(path, dir) {
230
241
  const rel = relative(resolve(dir), resolve(path));
231
242
  return rel === '' || (!rel.startsWith('..') && !isAbsolute(rel));
232
243
  }
244
+ // macOS and Windows name a folder in any letter case: an exclusion below compares that way.
245
+ const caseless = (path) => (process.platform === 'darwin' || process.platform === 'win32' ? path.toLowerCase() : path);
246
+
247
+ /**
248
+ * Where a test runner may run: the session's project, then each of `roots`
249
+ * (the caller's registered code projects) that is an absolute path, never
250
+ * the home folder or a folder above it, never the Downloads folder or
251
+ * anything in it (the caller's rule, held here too by name alone).
252
+ */
253
+ function testRoots(project, roots) {
254
+ const out = [project];
255
+ const home = caseless(resolve(homedir()));
256
+ const downloads = caseless(resolve(homedir(), 'Downloads'));
257
+ for (const root of Array.isArray(roots) ? roots : []) {
258
+ if (typeof root !== 'string' || !isAbsolute(root)) continue;
259
+ const path = resolve(root);
260
+ if (insideDir(home, caseless(path)) || insideDir(caseless(path), downloads)) continue;
261
+ if (!out.includes(path)) out.push(path);
262
+ }
263
+ return out;
264
+ }
233
265
  /** A regular file up to MAX_SCRIPT_BYTES, else null. */
234
266
  function defaultReadFile(path) {
235
267
  const stat = statSync(path);
@@ -549,13 +581,12 @@ function pathArgs(args) {
549
581
  }
550
582
 
551
583
  /**
552
- * A project's own automated tests: npm|pnpm|yarn|bun test (and run test*),
553
- * node --test, deno test, vitest, jest, playwright test — through a package
554
- * runner too — run from inside the project (`cwd`, where the command runs, `cd`
555
- * included) on file arguments, if any, that lie inside it too.
584
+ * A test runner's command, wherever it runs: { rest (its arguments, the files
585
+ * among them), playwright } for npm|pnpm|yarn|bun test (and run test*), node
586
+ * --test, deno test, vitest, jest, playwright test — through a package runner
587
+ * too — else null.
556
588
  */
557
- function isTestRun(words, { cwd, project }) {
558
- if (!insideDir(cwd, project)) return false;
589
+ function testRunner(words) {
559
590
  const [head, ...args] = words;
560
591
  const name = programName(head);
561
592
  let rest = null;
@@ -575,14 +606,58 @@ function isTestRun(words, { cwd, project }) {
575
606
  if (run?.pkg === 'vitest' || run?.pkg === 'jest') rest = run.args;
576
607
  else if (PLAYWRIGHT_TEST.has(run?.pkg) && run.args[0] === 'test') { rest = run.args.slice(1); playwright = true; }
577
608
  }
578
- if (rest === null) return false;
579
- if (playwright && rest.some((arg) => PLAYWRIGHT_INTERACTIVE.test(arg))) return false;
580
- return pathArgs(rest).every((path) => insideDir(resolvePath(cwd, path), project));
609
+ return rest === null ? null : { rest, playwright };
610
+ }
611
+ /** The allowed projects (ctx.roots) the command runs from (`cwd`, where it runs, `cd` included). */
612
+ const rootsHolding = (cwd, roots) => roots.filter((root) => insideDir(cwd, root));
613
+
614
+ /**
615
+ * Automated tests: a test runner (testRunner) run from inside one of the
616
+ * allowed projects (the session's own, or a registered code project the
617
+ * caller passed) on file arguments, if any, that lie inside that same one.
618
+ */
619
+ function isTestRun(words, { cwd, roots }) {
620
+ const run = testRunner(words);
621
+ if (!run) return false;
622
+ if (run.playwright && run.rest.some((arg) => PLAYWRIGHT_INTERACTIVE.test(arg))) return false;
623
+ const files = pathArgs(run.rest).map((path) => resolvePath(cwd, path));
624
+ return rootsHolding(cwd, roots).some((root) => files.every((file) => insideDir(file, root)));
625
+ }
626
+ /** Where a test run that is not exempt ran from, for its refusal. */
627
+ function testRunWhere({ cwd, roots }) {
628
+ return rootsHolding(cwd, roots).length
629
+ ? 'on files outside the project it runs in'
630
+ : `run from ${cwd}, outside this session's project and every registered code project`;
581
631
  }
582
632
  /** Why a `playwright test` that is not an automated test run is refused. */
583
- function playwrightTestWhy(runner, args, { cwd, project }) {
633
+ function playwrightTestWhy(runner, args, ctx) {
584
634
  if (args.some((arg) => PLAYWRIGHT_INTERACTIVE.test(arg))) return `${runner} test in its UI or debug mode (a browser window)`;
585
- return insideDir(cwd, project) ? `${runner} test on files outside the project` : `${runner} test run from ${cwd}, outside the project`;
635
+ return `${runner} test ${testRunWhere(ctx)}`;
636
+ }
637
+
638
+ /**
639
+ * `node --check <file>` / `node -c <file>` (or its program on stdin): Node
640
+ * parses the program and runs none of it. Checked on Node 24: the forms
641
+ * below run code and are not exempt, so the usual check applies to them:
642
+ * any other option before the file (-r / --require and --import run the
643
+ * module they name, --env-file and --experimental-config-file can add a
644
+ * --require, --run runs a package.json script; -e / -p, --test and --watch
645
+ * Node refuses to combine with --check), NODE_OPTIONS set anywhere on the
646
+ * line (it can hold a --require), `inspect` as the file (node inspect
647
+ * starts the next file under the debugger) and arguments xargs supplies.
648
+ * Only node / nodejs started directly: a package runner's (npx node) is not.
649
+ */
650
+ function syntaxCheckOnly(args, seg, ctx) {
651
+ if (ctx.nodeOptions || seg.words.some((word) => word.includes('NODE_OPTIONS') || programName(word) === 'xargs')) return false;
652
+ let check = false;
653
+ for (let i = 0; i < args.length; i += 1) {
654
+ const arg = args[i];
655
+ if (arg === '--check' || arg === '-c') { check = true; continue; }
656
+ if (arg === '--') return check && args[i + 1] !== 'inspect';
657
+ if (arg.startsWith('-') && arg !== '-') return false;
658
+ return check && arg !== 'inspect';
659
+ }
660
+ return check;
586
661
  }
587
662
 
588
663
  /** What `open` / xdg-open is asked to show when it is a browser, a URL or a web page, else null. */
@@ -660,14 +735,28 @@ const RUNTIME_VALUE_OPTIONS = {
660
735
  ts: new Set(['--tsconfig', '-P', '--project', '-O', '--compiler-options', '-r', '--require', '--import', '--loader', '-C', '--conditions', '--env-file', '--config', '--root', '--mode', '-I', '--ignore']),
661
736
  };
662
737
  const EVAL_FLAG = /^(?:--eval|--print|-[A-Za-z]*[ep])$/;
738
+ // Options whose value is a module the runtime loads and runs before the program (node -r, --import, a loader; bun --preload).
739
+ const PRELOAD_OPTIONS = new Set(['-r', '--require', '--import', '--loader', '--experimental-loader', '--preload']);
740
+ const PRELOAD_INLINE = /^(--require|--import|--loader|--experimental-loader|--preload)=(.*)$/;
741
+
742
+ /** The modules a list of runtime options preloads (`-r x`, `--import=x` …), in order. */
743
+ function preloadsIn(words) {
744
+ const out = [];
745
+ for (let i = 0; i < words.length; i += 1) {
746
+ if (PRELOAD_OPTIONS.has(words[i])) { if (words[i + 1] !== undefined) out.push(words[i + 1]); i += 1; continue; }
747
+ const inline = PRELOAD_INLINE.exec(words[i]);
748
+ if (inline) out.push(inline[2]);
749
+ }
750
+ return out;
751
+ }
663
752
 
664
753
  /**
665
- * A JS runtime's arguments → { code: [inline code], script, stdin }: node,
754
+ * A JS runtime's arguments → { code: [inline code], script, preload }: node,
666
755
  * bun, deno, tsx, ts-node and friends. `script` "-" or none (and no code):
667
- * the program comes from stdin.
756
+ * the program comes from stdin. `preload`: the modules its options load first.
668
757
  */
669
758
  function jsProgram(name, args) {
670
- const out = { code: [], script: null };
759
+ const out = { code: [], script: null, preload: [] };
671
760
  let list = args;
672
761
  let valued = NODE_VALUE_OPTIONS;
673
762
  if (name === 'bun') {
@@ -683,14 +772,25 @@ function jsProgram(name, args) {
683
772
  valued = RUNTIME_VALUE_OPTIONS.ts;
684
773
  if (list[0] === 'watch') list = list.slice(1); // tsx watch <file>
685
774
  }
775
+ const node = name === 'node' || name === 'nodejs';
686
776
  for (let i = 0; i < list.length; i += 1) {
687
777
  const arg = list[i];
688
778
  if (arg === '-') { out.script = '-'; return out; }
689
- if (arg === '--') { out.script = list[i + 1] ?? null; return out; }
779
+ if (arg === '--') {
780
+ // `node -- inspect <file>` is node inspect too.
781
+ const inspect = node && !out.inspect && list[i + 1] === 'inspect';
782
+ out.script = list[i + (inspect ? 2 : 1)] ?? null;
783
+ return out;
784
+ }
690
785
  if (/^--(?:eval|print)=/.test(arg)) { out.code.push(arg.slice(arg.indexOf('=') + 1)); return out; }
691
786
  if (EVAL_FLAG.test(arg)) { if (list[i + 1] !== undefined) out.code.push(list[i + 1]); return out; }
787
+ if (PRELOAD_OPTIONS.has(arg) && valued.has(arg)) { if (list[i + 1] !== undefined) out.preload.push(list[i + 1]); i += 1; continue; }
788
+ const inline = PRELOAD_INLINE.exec(arg);
789
+ if (inline) { out.preload.push(inline[2]); continue; }
692
790
  if (valued.has(arg)) { i += 1; continue; }
693
791
  if (arg.startsWith('-')) continue;
792
+ // `node inspect <file>` runs <file> under the debugger.
793
+ if (arg === 'inspect' && node && !out.inspect) { out.inspect = true; continue; }
694
794
  out.script = arg;
695
795
  return out;
696
796
  }
@@ -723,6 +823,17 @@ const FILE_READERS = new Set(['cat', 'type', 'head', 'tail', 'bat', 'more', 'les
723
823
  function interpreterDenial(name, args, seg, ctx) {
724
824
  const python = PYTHON.test(name);
725
825
  const program = python ? pythonProgram(args) : jsProgram(name, args);
826
+ // A preloaded file runs before the program (with --check too): its options', and NODE_OPTIONS set on the command itself.
827
+ if (!python) {
828
+ const inherited = seg.words.filter((word) => word.startsWith('NODE_OPTIONS=')).flatMap((word) => preloadsIn(word.slice(13).trim().split(/\s+/)));
829
+ for (const module of [...inherited, ...program.preload]) {
830
+ if (!PATH_LIKE.test(module)) continue; // a package name: not read
831
+ let file = module;
832
+ if (/^file:/i.test(module)) { try { file = decodeURIComponent(new URL(module).pathname); } catch { continue; } }
833
+ const what = codeMarker(readScript(ctx, resolvePath(ctx.cwd, file)));
834
+ if (what) return `preloading ${module}, a script that ${what}, into ${name}`;
835
+ }
836
+ }
726
837
  for (const code of program.code) {
727
838
  const what = codeMarker(code);
728
839
  if (what) return `inline code that ${what} (${name} ${python ? '-c' : '-e'})`;
@@ -818,7 +929,12 @@ function segmentDenial(words, seg, ctx) {
818
929
  }
819
930
  if (name === 'playwright' && args[0] === 'test') return playwrightTestWhy(name, args.slice(1), ctx);
820
931
  if (BROWSER_CLIS.has(name)) return `${name}${args[0] ? ` ${args[0]}` : ''} (a browser CLI)`;
821
- if (JS_RUNTIMES.has(name) || PYTHON.test(name)) return interpreterDenial(name, args, seg, ctx);
932
+ if ((name === 'node' || name === 'nodejs') && syntaxCheckOnly(args, seg, ctx)) return null;
933
+ if (JS_RUNTIMES.has(name) || PYTHON.test(name)) {
934
+ const why = interpreterDenial(name, args, seg, ctx);
935
+ // node --test / deno test of a browser test from outside the project it belongs to: say where it may run.
936
+ return why && testRunner(words) ? `${why} (${name === 'deno' ? 'deno test' : `${name} --test`} ${testRunWhere(ctx)})` : why;
937
+ }
822
938
  // A script run as a program (./shot.sh, ./pw.cjs, /tmp/x): by its shebang, else its extension.
823
939
  if (/[/\\]/.test(head)) {
824
940
  const text = readScript(ctx, resolvePath(ctx.cwd, head));
@@ -838,7 +954,10 @@ function segmentDenial(words, seg, ctx) {
838
954
  function commandDenial(text, ctx) {
839
955
  if (ctx.depth > MAX_DEPTH) return null;
840
956
  let cwd = ctx.cwd;
957
+ // NODE_OPTIONS set or exported earlier on the line reaches every later node (syntaxCheckOnly).
958
+ let nodeOptions = ctx.nodeOptions === true;
841
959
  for (const seg of simpleCommands(text)) {
960
+ if (seg.words.some((word) => word.includes('NODE_OPTIONS'))) nodeOptions = true;
842
961
  const words = commandWords(seg.words);
843
962
  // `cd dir && node pw.cjs`: the rest of the line runs there (a bare cd: the home folder).
844
963
  if (words[0] === 'cd' || words[0] === 'pushd') {
@@ -847,7 +966,7 @@ function commandDenial(text, ctx) {
847
966
  else if (words[0] === 'cd' && words.length === 1) cwd = homedir();
848
967
  continue;
849
968
  }
850
- const why = segmentDenial(words, seg, { ...ctx, cwd });
969
+ const why = segmentDenial(words, seg, { ...ctx, cwd, nodeOptions });
851
970
  if (why) return why;
852
971
  }
853
972
  return null;
@@ -855,18 +974,20 @@ function commandDenial(text, ctx) {
855
974
 
856
975
  /** A shell tool's command: a string (a command line) or an argv array (Codex). */
857
976
  function argvDenial(argv, ctx) {
858
- const words = commandWords(argv.map((arg) => String(arg ?? '')));
977
+ const raw = argv.map((arg) => String(arg ?? ''));
978
+ const words = commandWords(raw);
859
979
  if (!words.length) return null;
860
980
  if (SHELLS.has(programName(words[0]))) {
861
981
  const script = shellScript(words.slice(1));
862
982
  if (script !== null) return commandDenial(script, ctx);
863
983
  }
864
- return segmentDenial(words, { words, heredocs: [], inputs: [], pipedFrom: null }, ctx);
984
+ // The segment keeps its wrappers and assignments (env NODE_OPTIONS=… node --check …).
985
+ return segmentDenial(words, { words: raw, heredocs: [], inputs: [], pipedFrom: null }, ctx);
865
986
  }
866
987
 
867
988
  // Where each host puts a shell tool's command and its working directory.
868
- const COMMAND_KEYS = ['command', 'cmd', 'commands', 'script'];
869
- const WORKDIR_KEYS = ['workdir', 'cwd', 'working_directory', 'workingDirectory', 'dir'];
989
+ const COMMAND_KEYS = ['command', 'cmd', 'commands', 'script', 'CommandLine'];
990
+ const WORKDIR_KEYS = ['workdir', 'cwd', 'working_directory', 'workingDirectory', 'dir', 'Cwd'];
870
991
 
871
992
  function shellDenial(input, ctx) {
872
993
  const args = input && typeof input === 'object' ? input : {};
@@ -889,18 +1010,22 @@ function shellDenial(input, ctx) {
889
1010
  // ── the refusal ─────────────────────────────────────────────────────────────
890
1011
 
891
1012
  function refusal(tool, what) {
892
- return `SynaBun browser policy: ${tool} was refused — ${what}. Every page, public or localhost, goes through SynaBun's browser tools (browser_navigate, browser_snapshot, browser_screenshot, browser_console and the other browser_* tools), which open the browser configured in SynaBun. If the SynaBun browser fails or cannot do this, stop and report it; do not switch to another browser or tool. The project's own automated tests still run through its test runner (npm test, node --test, npx playwright test).`;
1013
+ return `SynaBun browser policy: ${tool} was refused — ${what}. Every page, public or localhost, goes through SynaBun's browser tools (browser_navigate, browser_snapshot, browser_screenshot, browser_console and the other browser_* tools), which open the browser configured in SynaBun. If the SynaBun browser fails or cannot do this, stop and report it; do not switch to another browser or tool. ${TEST_RUN_RULE}`;
893
1014
  }
894
1015
 
895
1016
  /**
896
1017
  * Why this tool call may not run under the browser policy (the refusal text),
897
1018
  * else null. `host`: claude / codex / opencode (null: any). `cwd`: the
898
- * project directory: relative script paths resolve against it, and a test
899
- * runner's files must lie inside it. `readFile(path)` returns an executed
900
- * script's text or null (tests); by default a regular file up to
901
- * MAX_SCRIPT_BYTES is read, and anything unreadable is allowed.
1019
+ * session's project directory: relative script paths resolve against it, and
1020
+ * a test runner may run inside it. `roots`: the other projects a test runner
1021
+ * may run inside (absolute paths: the registered code projects,
1022
+ * lib/browser-policy-roots.js; the home folder, a folder above it and the
1023
+ * Downloads folder are dropped). A test run's directory and its files lie in
1024
+ * one of them. `readFile(path)` returns an executed script's text or null
1025
+ * (tests); by default a regular file up to MAX_SCRIPT_BYTES is read, and
1026
+ * anything unreadable is allowed.
902
1027
  */
903
- export function browserToolDenial(tool, input = {}, { host = null, cwd = null, readFile = defaultReadFile } = {}) {
1028
+ export function browserToolDenial(tool, input = {}, { host = null, cwd = null, roots = [], readFile = defaultReadFile } = {}) {
904
1029
  const name = String(tool ?? '').trim();
905
1030
  if (!name) return null;
906
1031
  const kind = hostKey(host);
@@ -919,8 +1044,43 @@ export function browserToolDenial(tool, input = {}, { host = null, cwd = null, r
919
1044
  }
920
1045
  if (isSynabunTool(name) || /^mcp__/i.test(name)) return null;
921
1046
  if (WEB_TOOLS.has(lower)) return refusal(name, 'web search / fetch outside the SynaBun browser');
1047
+ // OpenCode's own browser tool drives a browser that is not SynaBun's.
1048
+ if (kind === 'opencode' && lower === 'browser') return refusal(name, 'OpenCode\'s own browser');
1049
+ // Antigravity's own browser and browser subagent (its built-in tools carry no server: never SynaBun's browser_*).
1050
+ if (kind === 'antigravity' && (ANTIGRAVITY_BROWSER_TOOLS.has(lower) || /^browser_/.test(lower))) return refusal(name, 'Antigravity\'s own browser');
922
1051
  if (!SHELL_TOOLS.has(lower)) return null;
923
1052
  const project = cwd ? resolve(String(cwd)) : process.cwd();
924
- const why = shellDenial(args, { project, cwd: project, readFile: typeof readFile === 'function' ? readFile : defaultReadFile, depth: 0 });
1053
+ const why = shellDenial(args, { roots: testRoots(project, roots), cwd: project, readFile: typeof readFile === 'function' ? readFile : defaultReadFile, depth: 0 });
925
1054
  return why ? refusal(name, why) : null;
926
1055
  }
1056
+
1057
+ // ── SynaBun's own OpenCode serves ───────────────────────────────────────────
1058
+
1059
+ /**
1060
+ * The port a web address (http, https, ws, wss) opens: its own, else the scheme's (80 / 443); null for any other
1061
+ * address (about:blank, data:, file:, chrome:) or one that cannot be read.
1062
+ */
1063
+ export function addressPort(url) {
1064
+ let parsed;
1065
+ try { parsed = new URL(String(url ?? '')); } catch { return null; }
1066
+ if (!/^(?:https?|wss?):$/.test(parsed.protocol)) return null;
1067
+ const port = Number(parsed.port || (parsed.protocol === 'https:' || parsed.protocol === 'wss:' ? 443 : 80));
1068
+ return Number.isInteger(port) && port > 0 ? port : null;
1069
+ }
1070
+
1071
+ /**
1072
+ * Why the SynaBun browser may not open this address (the refusal text), else null: it is on the port of one of
1073
+ * SynaBun's own OpenCode serves running now (`ports`, a Set or a list: server.js liveOpencodeServePorts). Such a
1074
+ * serve's API changes a session's rules or moves it; nothing a page does needs it. Any host counts, not only
1075
+ * localhost: a name that resolves to this computer reaches the serve too. server.js refuses a navigation to it and
1076
+ * aborts every request and WebSocket of the browser to it (installServePortGuard), whatever opened the page.
1077
+ */
1078
+ export function browserServePortDenial(url, ports) {
1079
+ const port = addressPort(url);
1080
+ if (!port) return null;
1081
+ const live = ports instanceof Set ? ports : new Set(Array.isArray(ports) ? ports.map(Number) : []);
1082
+ if (!live.has(port)) return null;
1083
+ let host = '';
1084
+ try { host = new URL(String(url)).hostname; } catch { /* addressPort read it */ }
1085
+ return `SynaBun browser policy: ${host}:${port} is one of SynaBun's own OpenCode servers, which the SynaBun browser never opens (their API changes what a session may do). Use your tools instead; whatever they cannot do is yours to report.`;
1086
+ }
@@ -104,6 +104,7 @@ export const PANEL_CAPABILITIES = Object.freeze([
104
104
  'ask_annotations', // AskUserQuestion answers keep their `annotations`
105
105
  'tool_policy', // query `toolPolicy`: 'full' | 'read-only' | 'no-web'
106
106
  'elicitation', // MCP elicitation as control_request subtype `elicitation` (for clients that declare the feature)
107
+ 'effort_off', // query `effort: 'off'`: thinking disabled, over any effortLevel in the user's settings
107
108
  'session_settings', // query `session`: fallback model, limits, directories, plugins, strict MCP, instructions, sandbox, thinking, fast mode, output style, agent
108
109
  'reload_plugins', // inbound `reload_plugins` → `reload_result` + fresh commands_list / mcp_status / plugins_list
109
110
  'message_flags', // session.hookEvents / promptSuggestions / subagentText / agentSummaries → the matching SDK options
@@ -754,6 +755,9 @@ export class ClaudeSession {
754
755
  if (this.sessionId && this._resumeAt) { options.resumeSessionAt = this._resumeAt; this._resumeAt = null; }
755
756
  }
756
757
  if (this.model) options.model = this.model;
758
+ // Off is the user's pick, not the model's default: without it an
759
+ // effortLevel in the user's settings would still apply.
760
+ if (this.panel && this.effort === 'off') options.thinking = { type: 'disabled' };
757
761
  if (this.effort && CLAUDE_EFFORT_LEVELS.includes(this.effort)) {
758
762
  // Panel sessions use the typed option; every other caller keeps the flag it had.
759
763
  if (this.panel) options.effort = this.effort;
@@ -2895,10 +2899,12 @@ export class ClaudeSession {
2895
2899
  catch { this._greetingNote = ''; }
2896
2900
  }
2897
2901
 
2898
- // SynaBun skill injection runs FIRST; unrecognized /commands pass through to the CLI
2902
+ // SynaBun skill injection runs FIRST; unrecognized /commands pass through to the CLI. A skill Claude Code
2903
+ // loads by itself in this session (the account's or the project's) is left to it (server.js
2904
+ // resolveSkillPrompt), so its own settings apply; only a SynaBun skill it cannot see is handed over as text.
2899
2905
  if (prompt && prompt.startsWith('/')) {
2900
2906
  try {
2901
- const injected = deps.maybeInjectSkillPrompt(prompt);
2907
+ const injected = deps.maybeInjectSkillPrompt(prompt, { cwd: cwd || this.cwd || null, runtime: 'claude', accountId: (queryAccount?.account ?? this.accountId) || 'default' });
2902
2908
  if (injected.command === 'clear' && !injected.skill) return; // client-only
2903
2909
  if (injected.skill) {
2904
2910
  log('skill injection: /' + injected.command);
@@ -2964,6 +2970,7 @@ export class ClaudeSession {
2964
2970
  if (cwd) this.cwd = cwd;
2965
2971
  // A panel tab that sends no effort means "the model's default": a level that
2966
2972
  // was set goes back to it, live when a session exists.
2973
+ const prevEffort = this.effort;
2967
2974
  const effortCleared = this.panel && !effort && !!this.effort;
2968
2975
  if (effort) this.effort = effort;
2969
2976
  else if (effortCleared) this.effort = null;
@@ -3004,7 +3011,9 @@ export class ClaudeSession {
3004
3011
 
3005
3012
  // Effort alone switches on the live CLI. A restart would cold-start the
3006
3013
  // session and kill any background agents it is running.
3014
+ // (Off disables thinking, a start-up option: to or from it the session restarts.)
3007
3015
  if (this.q && effortChanged && !cwdChanged && !sessionChanged && !newChat
3016
+ && prevEffort !== 'off' && effort !== 'off'
3008
3017
  && typeof this.q.applyFlagSettings === 'function') {
3009
3018
  const effortLevel = CLAUDE_EFFORT_LEVELS.includes(effort) ? effort : null;
3010
3019
  this.q.applyFlagSettings({ effortLevel }).catch(err => log('applyFlagSettings(effort) failed:', err.message));