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
@@ -50,24 +50,44 @@ export function buildClaudeMcpEntry(config) {
50
50
  }
51
51
 
52
52
  /**
53
- * Registry config → a `~/.gemini/settings.json` mcpServers entry.
54
- * Gemini CLI addresses streamable HTTP as `httpUrl` and SSE as `url`.
53
+ * Registry config → an entry of Antigravity's `~/.gemini/config/mcp_config.json` mcpServers
54
+ * (the file `agy mcp add` writes, shared by the CLI and the Antigravity app): a local server is
55
+ * `{ command, args, env, disabled }`, a remote one `{ serverUrl, headers, disabled }` whatever
56
+ * its transport (Antigravity tells streamable HTTP and SSE apart by itself).
55
57
  */
56
- export function buildGeminiMcpEntry(config) {
58
+ export function buildAntigravityMcpEntry(config) {
57
59
  const source = asObject(config);
58
60
  if (!isRemoteMcp(source)) {
59
61
  const entry = { command: source.command || '' };
60
62
  if (source.args?.length) entry.args = [...source.args];
61
63
  const env = hasKeys(source.env);
62
64
  if (env) entry.env = { ...env };
65
+ entry.disabled = false;
63
66
  return entry;
64
67
  }
65
- const entry = source.type === 'sse' ? { url: source.url } : { httpUrl: source.url };
68
+ const entry = { serverUrl: source.url };
66
69
  const headers = hasKeys(source.headers);
67
70
  if (headers) entry.headers = { ...headers };
71
+ entry.disabled = false;
68
72
  return entry;
69
73
  }
70
74
 
75
+ /** The transport and address of an Antigravity mcp_config.json entry ({ transport, url? , command? }), for the installed list. */
76
+ export function describeAntigravityMcpEntry(entry) {
77
+ const source = asObject(entry);
78
+ if (typeof source.serverUrl === 'string' && source.serverUrl) return { transport: 'http', url: source.serverUrl, disabled: source.disabled === true };
79
+ return { transport: 'stdio', command: typeof source.command === 'string' ? source.command : '', args: Array.isArray(source.args) ? source.args : [], disabled: source.disabled === true };
80
+ }
81
+
82
+ /** An Antigravity mcp_config.json's text as an object: an empty file (as Antigravity creates it) is `{}`. Throws on JSON that is not an object. */
83
+ export function parseAntigravityMcpConfig(text) {
84
+ const raw = String(text ?? '').replace(/^\uFEFF/, '');
85
+ if (!raw.trim()) return {};
86
+ const value = JSON.parse(raw);
87
+ if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error('mcp_config.json does not hold a JSON object');
88
+ return value;
89
+ }
90
+
71
91
  /**
72
92
  * Registry config → the key/value pairs for a `[mcp_servers.<name>]` TOML section.
73
93
  * Remote servers get `url` and never a `command`, which Codex would treat as stdio.
@@ -87,7 +107,8 @@ export function buildCodexMcpKv(config) {
87
107
  return kv;
88
108
  }
89
109
 
90
- export function mergeGeminiMcpConfig(existing, definition) {
110
+ /** SynaBun's own entry in Antigravity's mcp_config.json; every other server and key is kept as it was. */
111
+ export function mergeAntigravityMcpConfig(existing, definition) {
91
112
  const config = asObject(existing);
92
113
  return {
93
114
  ...config,
@@ -97,37 +118,18 @@ export function mergeGeminiMcpConfig(existing, definition) {
97
118
  command: definition.command,
98
119
  args: [...(definition.args || [])],
99
120
  env: { ...asObject(definition.env) },
100
- trust: true,
121
+ disabled: false,
101
122
  },
102
123
  },
103
124
  };
104
125
  }
105
126
 
106
- export function toOpenCodeMcpEntry(mcpConfig) {
107
- const source = asObject(mcpConfig);
108
- const { type: _type, command, args, env, environment, headers, oauth: _oauth, url, ...rest } = source;
109
- if (isRemoteMcp(source)) {
110
- // OpenCode names the URL-addressed transport "remote"; there is no http/sse split.
111
- const entry = { type: 'remote', url, ...rest };
112
- const hdrs = hasKeys(headers);
113
- if (hdrs) entry.headers = { ...hdrs };
114
- if (entry.enabled === undefined) entry.enabled = true;
115
- return entry;
116
- }
117
- const entry = { type: 'local', ...rest };
118
- if (command) entry.command = Array.isArray(command) ? [...command] : [command, ...(args || [])];
119
- const envObj = environment || env;
120
- if (envObj && Object.keys(envObj).length > 0) entry.environment = { ...envObj };
121
- return entry;
122
- }
123
-
124
- export function mergeOpenCodeMcpConfig(existing, name, mcpConfig) {
125
- const config = asObject(existing);
126
- return {
127
- ...config,
128
- mcp: {
129
- ...asObject(config.mcp),
130
- [name]: toOpenCodeMcpEntry(mcpConfig),
131
- },
132
- };
127
+ /** Antigravity's mcp_config.json without SynaBun's entry (and without an emptied `mcpServers`). */
128
+ export function removeAntigravityMcpServer(existing, name = 'SynaBun') {
129
+ const config = { ...asObject(existing) };
130
+ const servers = { ...asObject(config.mcpServers) };
131
+ delete servers[name];
132
+ if (Object.keys(servers).length) config.mcpServers = servers;
133
+ else delete config.mcpServers;
134
+ return config;
133
135
  }
@@ -0,0 +1,332 @@
1
+ import { buildClaudeMcpEntry } from './mcp-client-config.js';
2
+ // External definitions stay at the launch boundary. Public views contain names and availability only.
3
+ import { existsSync, realpathSync, readFileSync, mkdirSync, writeFileSync, renameSync, chmodSync } from 'node:fs';
4
+ import { homedir } from 'node:os';
5
+ import { dirname, join, resolve } from 'node:path';
6
+ import { parseJsonc, mcpServersOf, mergedOpencodeConfig, readOpencodeConfigDocuments } from './opencode-config.js';
7
+ import { agentAccessFrom } from './mcp-agent-servers.js';
8
+
9
+ const object = value => value && typeof value === 'object' && !Array.isArray(value) ? value : {};
10
+ const canonical = path => { try { return realpathSync(path); } catch { return resolve(path); } };
11
+ const claudeProject = (user, cwd) => user.projects?.[canonical(cwd)] || user.projects?.[resolve(cwd)] || {};
12
+ const external = name => name !== 'SynaBun';
13
+ export const EXTERNAL_SERVER_LIMITATIONS = Object.freeze({ codex: 'Plugin-provided MCP servers cannot be enumerated from config.toml', 'claude-code': 'claude.ai connectors are unavailable under strict MCP configuration', antigravity: 'A project\'s own .agents/mcp_config.json still loads into an Antigravity session; managed brains, workers and restricted panel sessions refuse enabled project servers before starting agy' });
14
+ /** Where Antigravity keeps its MCP servers: { mcpServers: { name: { command, args, env, disabled } | { serverUrl, headers, disabled } } }. */
15
+ export function antigravityMcpConfigPath(home = homedir()) { return join(home, '.gemini', 'config', 'mcp_config.json'); }
16
+ export const externalServerName = name => typeof name === 'string' && /^[A-Za-z0-9][A-Za-z0-9._:-]{0,63}$/.test(name) && external(name);
17
+ function read(path, fallback = null) {
18
+ try { return readFileSync(path, 'utf8'); }
19
+ catch (error) { if (error.code === 'ENOENT') return fallback; throw Object.assign(new Error('Could not read an MCP configuration source'), { code: 'MCP_DISCOVERY_FAILED' }); }
20
+ }
21
+ function document(path) {
22
+ const text = read(path);
23
+ if (text === null) return {};
24
+ try { return object(parseJsonc(text)); }
25
+ catch { throw Object.assign(new Error('Could not parse an MCP configuration source'), { code: 'MCP_DISCOVERY_FAILED' }); }
26
+ }
27
+ /** Names/kinds/enabled only: Codex keeps definitions and secrets in its own TOML. Quoted dotted names stay whole. */
28
+ export function parseCodexMcpServers(text = '') {
29
+ // Structural TOML reader: supports tables, dotted/quoted keys and inline maps without copying definitions.
30
+ const tokens = []; let at = 0;
31
+ const input = String(text);
32
+ const fail = () => Object.assign(new Error('Could not parse Codex MCP configuration'), { code: 'MCP_DISCOVERY_FAILED' });
33
+ while (at < input.length) {
34
+ const ch = input[at];
35
+ if (ch === '#') { while (at < input.length && input[at] !== '\n') at++; continue; }
36
+ if (ch === '\n') { tokens.push({ type: 'nl', value: ch }); at++; continue; }
37
+ if (/\s/.test(ch)) { at++; continue; }
38
+ if ('[]{}=.,'.includes(ch)) { tokens.push({ type: 'punct', value: ch }); at++; continue; }
39
+ if (ch === '"' || ch === "'") {
40
+ const start = at, triple = input.slice(at, at + 3) === ch.repeat(3); at += triple ? 3 : 1;
41
+ let closed = false;
42
+ while (at < input.length) {
43
+ if (ch === '"' && input[at] === '\\') { at += 2; continue; }
44
+ if (input.slice(at, at + (triple ? 3 : 1)) === ch.repeat(triple ? 3 : 1)) { at += triple ? 3 : 1; closed = true; break; }
45
+ at++;
46
+ }
47
+ if (!closed) throw fail();
48
+ const raw = input.slice(start, at); let value;
49
+ if (triple) value = raw.slice(3, -3);
50
+ else if (ch === "'") value = raw.slice(1, -1);
51
+ else {
52
+ try { value = JSON.parse(raw.replace(/\\U([0-9a-fA-F]{8})/g, (_, code) => String.fromCodePoint(parseInt(code, 16)))); }
53
+ catch { throw fail(); }
54
+ }
55
+ tokens.push({ type: 'string', value }); continue;
56
+ }
57
+ const start = at;
58
+ while (at < input.length && !/[\s\[\]{}=.,#"']/.test(input[at])) at++;
59
+ if (at === start) throw fail();
60
+ tokens.push({ type: 'word', value: input.slice(start, at) });
61
+ }
62
+ let index = 0;
63
+ const peek = () => tokens[index]?.value;
64
+ const skipLines = () => { while (tokens[index]?.type === 'nl') index++; };
65
+ function keys() {
66
+ const out = [];
67
+ while (tokens[index] && ['word', 'string'].includes(tokens[index].type)) {
68
+ const token = tokens[index++];
69
+ if (token.type === 'word' && !/^[A-Za-z0-9_-]+$/.test(token.value)) throw fail();
70
+ out.push(token.value); if (peek() !== '.') break; index++;
71
+ }
72
+ return out;
73
+ }
74
+ function put(root, path, value) {
75
+ let target = root;
76
+ for (const key of path.slice(0, -1)) { if (!target[key] || typeof target[key] !== 'object') target[key] = Object.create(null); target = target[key]; }
77
+ target[path.at(-1)] = value;
78
+ }
79
+ function value() {
80
+ if (peek() === '{') {
81
+ index++; const out = Object.create(null); skipLines();
82
+ while (peek() !== '}') {
83
+ const path = keys(); if (!path.length || peek() !== '=') throw fail(); index++;
84
+ put(out, path, value()); skipLines();
85
+ if (peek() === ',') { index++; skipLines(); } else if (peek() !== '}') throw fail();
86
+ }
87
+ index++; return out;
88
+ }
89
+ if (peek() === '[') {
90
+ index++; const out = []; skipLines();
91
+ while (peek() !== ']') {
92
+ if (!tokens[index]) throw fail(); out.push(value()); skipLines();
93
+ if (peek() === ',') { index++; skipLines(); } else if (peek() !== ']') throw fail();
94
+ }
95
+ index++; return out;
96
+ }
97
+ const first = tokens[index++]; if (!first) throw fail();
98
+ if (first.type === 'string') return first.value;
99
+ let raw = first.value;
100
+ while (tokens[index] && tokens[index].type !== 'nl' && ![',', '}', ']'].includes(peek())) raw += tokens[index++].value;
101
+ return raw === 'false' ? false : raw === 'true' ? true : raw;
102
+ }
103
+ const rows = new Map(); let table = [];
104
+ function observe(path, item) {
105
+ if (path[0] !== 'mcp_servers') return;
106
+ if (path.length === 1 && item && typeof item === 'object') { for (const [name, entry] of Object.entries(item)) observe(['mcp_servers', name], entry); return; }
107
+ const name = path[1]; if (name === undefined) return;
108
+ if (!rows.has(name)) rows.set(name, { kind: 'stdio', enabled: true });
109
+ const info = rows.get(name);
110
+ if (path.length === 2 && item && typeof item === 'object') { if (typeof item.url === 'string') info.kind = 'http'; if (item.enabled === false) info.enabled = false; }
111
+ if (path.length === 3 && path[2] === 'url') info.kind = 'http';
112
+ if (path.length === 3 && path[2] === 'enabled') info.enabled = item !== false;
113
+ }
114
+ while (index < tokens.length) {
115
+ skipLines(); if (!tokens[index]) break;
116
+ if (peek() === '[') {
117
+ index++; const arrayTable = peek() === '['; if (arrayTable) index++;
118
+ table = keys(); if (peek() !== ']') throw fail(); index++;
119
+ if (arrayTable) { if (peek() !== ']') throw fail(); index++; }
120
+ observe(table); continue;
121
+ }
122
+ const path = keys(); if (!path.length || peek() !== '=') throw fail(); index++;
123
+ observe([...table, ...path], value());
124
+ while (tokens[index] && tokens[index].type !== 'nl') index++;
125
+ }
126
+ return rows;
127
+ }
128
+ export function codexMcpServerNames(codexHome) { if (!codexHome) return []; return [...parseCodexMcpServers(read(join(codexHome, 'config.toml'), '')).keys()]; }
129
+ export function projectOpenCodeConfigs(cwd) {
130
+ const dirs = []; let dir = canonical(cwd);
131
+ while (true) { dirs.unshift(dir); const parent = dirname(dir); if (parent === dir) break; dir = parent; }
132
+ // Every direct file, then every .opencode directory, farthest ancestor first (OpenCode 2 discovery).
133
+ return [...dirs, ...dirs.map(path => join(path, '.opencode'))].flatMap(path => ['opencode.json', 'opencode.jsonc'].map(name => join(path, name)));
134
+ }
135
+ export function claudePluginDefinitions(pluginRoot, manifest = document(join(pluginRoot, '.claude-plugin', 'plugin.json'))) {
136
+ const out = {};
137
+ const expand = value => typeof value === 'string' ? value.replaceAll('${CLAUDE_PLUGIN_ROOT}', pluginRoot) : Array.isArray(value) ? value.map(expand) : value && typeof value === 'object' ? Object.fromEntries(Object.entries(value).map(([k, v]) => [k, expand(v)])) : value;
138
+ const add = data => Object.assign(out, object(data.mcpServers || data));
139
+ add(document(join(pluginRoot, '.mcp.json')));
140
+ const declared = manifest.mcpServers;
141
+ if (typeof declared === 'string') add(document(resolve(pluginRoot, declared)));
142
+ else if (Array.isArray(declared)) { for (const path of declared) if (typeof path === 'string') add(document(resolve(pluginRoot, path))); }
143
+ else Object.assign(out, object(declared));
144
+ return expand(out);
145
+ }
146
+ function claudeEntry(entry) { return structuredClone(entry); }
147
+
148
+ /** This is the only filesystem discovery boundary; definitions never escape through servers/catalogView. */
149
+ export function externalServerInventory({ provider, cwd = process.cwd(), codexHome, home = homedir(), dataHome, registry, opencodeConfig, antigravityConfigPath = antigravityMcpConfigPath(home), readProject = true, env = process.env } = {}) {
150
+ const reg = registry || (dataHome ? document(join(dataHome, 'data', 'mcp-registry.json')) : {});
151
+ const access = agentAccessFrom(reg), definitions = new Map(), rows = new Map();
152
+ function add(name, entry, source, deliverable = true, reason = null, kind = null) {
153
+ if (!external(name)) return;
154
+ const enabled = entry.enabled !== false && entry.disabled !== true;
155
+ const transport = provider === 'codex' || (entry.url ? typeof entry.url === 'string' : Array.isArray(entry.command) ? entry.command.length > 0 : typeof entry.command === 'string' && !!entry.command);
156
+ const supported = provider !== 'claude-code' || (entry.url ? ['http', 'streamable-http', 'sse', 'ws'].includes(entry.type) : entry.type === undefined || entry.type === 'stdio');
157
+ const reserved = provider === 'claude-code' && Object.hasOwn(Object.prototype, name);
158
+ const available = deliverable && enabled && transport && supported && !reserved;
159
+ rows.set(name, { name, provider, source, kind: kind || (entry.url ? entry.type === 'ws' ? 'ws' : entry.type === 'sse' ? 'sse' : 'http' : 'stdio'), deliverable: available, selectable: externalServerName(name), ...(available ? {} : { reason: reason || (!enabled ? 'disabled-in-provider' : 'unsupported-definition') }), blocked: access[name] === false });
160
+ definitions.set(name, entry);
161
+ }
162
+ if (provider === 'codex') {
163
+ for (const [path, source] of [[join(codexHome || env.CODEX_HOME || join(home, '.codex'), 'config.toml'), 'user'], [join(cwd, '.codex', 'config.toml'), 'project']]) {
164
+ for (const [name, info] of parseCodexMcpServers(read(path, ''))) add(name, info, source, true, null, info.kind);
165
+ }
166
+ } else if (provider === 'opencode') {
167
+ const configDir = env.OPENCODE_CONFIG_DIR || join(env.XDG_CONFIG_HOME || join(home, '.config'), 'opencode');
168
+ let base = opencodeConfig;
169
+ if (base == null) {
170
+ const docs = readOpencodeConfigDocuments(configDir);
171
+ if (docs.some(row => row.error)) throw Object.assign(new Error('Could not parse an MCP configuration source'), { code: 'MCP_DISCOVERY_FAILED' });
172
+ base = mergedOpencodeConfig(docs);
173
+ }
174
+ for (const [name, entry] of Object.entries(mcpServersOf(base))) add(name, entry, 'user');
175
+ if (env.OPENCODE_CONFIG) for (const [name, entry] of Object.entries(mcpServersOf(document(resolve(env.OPENCODE_CONFIG))))) add(name, entry, 'user-override');
176
+ if (readProject) for (const path of projectOpenCodeConfigs(cwd)) for (const [name, entry] of Object.entries(mcpServersOf(document(path)))) add(name, entry, 'project');
177
+ } else if (provider === 'antigravity') {
178
+ // A remote server names its address `serverUrl` there; `disabled: true` turns it off in Antigravity itself.
179
+ for (const [name, entry] of Object.entries(object(document(antigravityConfigPath).mcpServers))) {
180
+ const own = object(entry);
181
+ const url = typeof own.serverUrl === 'string' ? own.serverUrl : own.url;
182
+ add(name, url !== undefined && own.url === undefined ? { ...own, url } : own, 'user', true, null, url !== undefined ? 'http' : 'stdio');
183
+ }
184
+ } else if (provider === 'claude-code') {
185
+ const configDir = env.CLAUDE_CONFIG_DIR || join(home, '.claude');
186
+ const settings = { ...document(join(configDir, 'settings.json')), ...document(join(cwd, '.claude', 'settings.json')), ...document(join(cwd, '.claude', 'settings.local.json')) };
187
+ // Registry entries are a compatibility fallback for FleetView's pre-Phase-2 registry-only servers.
188
+ for (const [name, entry] of Object.entries(object(reg.servers))) if (!entry.builtin) {
189
+ add(name, buildClaudeMcpEntry(entry), 'registry');
190
+ }
191
+ const user = document(env.CLAUDE_CONFIG_DIR ? join(configDir, '.claude.json') : join(home, '.claude.json'));
192
+ for (const [name, entry] of Object.entries(object(user.mcpServers))) add(name, claudeEntry(entry), 'user');
193
+ const disabled = new Set([...(settings.disabledMcpjsonServers || []), ...(claudeProject(user, cwd)?.disabledMcpjsonServers || [])]);
194
+ for (const [name, entry] of Object.entries(object(document(join(cwd, '.mcp.json')).mcpServers))) {
195
+ const approved = !disabled.has(name) && (settings.enableAllProjectMcpServers === true || claudeProject(user, cwd)?.enableAllProjectMcpServers === true || settings.enabledMcpjsonServers?.includes(name) || claudeProject(user, cwd)?.enabledMcpjsonServers?.includes(name));
196
+ add(name, claudeEntry(entry), 'project', !!approved, 'project-not-approved');
197
+ }
198
+ for (const [name, entry] of Object.entries(object(claudeProject(user, cwd)?.mcpServers))) add(name, claudeEntry(entry), 'local');
199
+ const installed = document(join(configDir, 'plugins', 'installed_plugins.json'));
200
+ for (const [key, installs] of Object.entries(object(installed.plugins))) {
201
+ if (settings.enabledPlugins?.[key] === false) continue;
202
+ const install = (Array.isArray(installs) ? installs : [installs]).filter(row => row?.installPath && (!row.projectPath || canonical(row.projectPath) === canonical(cwd))).at(-1);
203
+ if (!install) continue;
204
+ const manifest = document(join(install.installPath, '.claude-plugin', 'plugin.json'));
205
+ if (!manifest.name) continue;
206
+ for (const [name, entry] of Object.entries(claudePluginDefinitions(install.installPath, manifest))) add(`plugin:${manifest.name}:${name}`, claudeEntry(entry), 'plugin');
207
+ }
208
+ }
209
+ if (provider === 'claude-code') {
210
+ const configDir = env.CLAUDE_CONFIG_DIR || join(home, '.claude');
211
+ const user = document(env.CLAUDE_CONFIG_DIR ? join(configDir, '.claude.json') : join(home, '.claude.json'));
212
+ const disabled = new Set([...(user.disabledMcpServers || []), ...(claudeProject(user, cwd)?.disabledMcpServers || [])]);
213
+ for (const name of disabled) if (rows.has(name)) Object.assign(rows.get(name), { deliverable: false, reason: 'disabled-in-provider' });
214
+ }
215
+ const servers = [...rows.values()].sort((a, b) => a.name.localeCompare(b.name));
216
+ return { provider, servers, definitionFor(name) {
217
+ const definition = definitions.get(name);
218
+ if (!definition) return undefined;
219
+ const entry = structuredClone(definition);
220
+ if (provider === 'claude-code' && dataHome && object(reg.servers)[name] && !entry.url) entry.env = { ...object(entry.env), ...document(join(dataHome, 'data', 'mcp', name, 'env.json')) };
221
+ return entry;
222
+ }, isBlocked(name) { return access[name] === false; } };
223
+ }
224
+ export function discoverExternalServers(options) { return externalServerInventory(options).servers; }
225
+
226
+ /** Codex CLI splits paths on literal dots; quoted TOML key syntax is not supported. */
227
+ export function codexMcpEnabledOverride(name) {
228
+ if (!name || /[.=\x00-\x1f\x7f]/.test(name)) throw Object.assign(new Error(`Codex cannot disable MCP server ${JSON.stringify(name)} for this run: its CLI override paths do not support dots, equals signs or control characters in server names. Rename the server in Codex configuration before retrying.`), { code: 'MCP_SCOPE_UNENFORCED', status: 400 });
229
+ return `mcp_servers.${name}.enabled`;
230
+ }
231
+
232
+ export function selectExternalServers(tools, inventory) {
233
+ const requested = [...new Set((tools || []).filter(item => item.startsWith('mcp:')))];
234
+ const selected = new Set(), problems = [];
235
+ for (const ref of requested) {
236
+ if (ref === 'mcp:*') { for (const row of inventory.servers) if (row.deliverable && !row.blocked) selected.add(row.name); continue; }
237
+ const name = ref.slice(4), row = inventory.servers.find(row => row.name === name);
238
+ // A names-only cross-provider catalog distinguishes a typo from a server
239
+ // configured on a different provider. Resolve it only for a missing name.
240
+ const known = !row ? (typeof inventory.catalog === 'function' ? inventory.catalog() : inventory.catalog || []).find(item => item.ref === ref) : null;
241
+ const provider = inventory.provider || row?.provider;
242
+ const context = provider ? ` for ${provider}` : '';
243
+ const reason = row?.blocked || known?.blocked || inventory.isBlocked?.(name) === true ? 'blocked'
244
+ : row?.selectable === false || !externalServerName(name) ? 'non-selectable'
245
+ : !row ? known ? 'absent-for-provider' : 'unknown-server' : !row.deliverable ? 'unavailable' : null;
246
+ const hint = reason === 'blocked' ? `${ref} is blocked for workers by the owner's MCP access setting${context}.`
247
+ : reason === 'non-selectable' ? `${ref} cannot be selected by name; external names must start with a letter or digit and contain only letters, digits, dots, underscores, colons or hyphens (at most 64 characters).`
248
+ : reason === 'absent-for-provider' ? `${ref} is not configured${context}. Configure it there or choose a provider where it is available.`
249
+ : reason === 'unknown-server' ? `Unknown external MCP server ${ref}${context}; use an exact, case-sensitive name from tools.servers.`
250
+ : reason === 'unavailable' ? `${ref} is configured${context} but unavailable (${row.reason || 'disabled or unsupported definition'}).` : null;
251
+ if (reason) problems.push({ item: ref, reason, provider: provider || null, hint, suggestions: inventory.servers.filter(row => row.deliverable && !row.blocked && row.selectable !== false && externalServerName(row.name) && row.name.toLowerCase().includes(name.toLowerCase())).map(row => `mcp:${row.name}`).slice(0, 3) });
252
+ else selected.add(name);
253
+ }
254
+ if (problems.length) throw Object.assign(new Error(problems.map(problem => problem.hint).join(' ')), { code: 'TOOLS_INVALID', status: 400, problems });
255
+ return { names: [...selected].sort(), disabled: inventory.servers.filter(row => !selected.has(row.name)).map(row => row.name) };
256
+ }
257
+ export function externalCatalog(options = {}) {
258
+ const rows = new Map();
259
+ for (const provider of ['codex', 'opencode', 'claude-code', 'antigravity']) for (const row of discoverExternalServers({ ...options, provider })) {
260
+ if (!rows.has(row.name)) rows.set(row.name, { ref: `mcp:${row.name}`, label: row.name, selectable: row.selectable, providers: { codex: 'absent', opencode: 'absent', 'claude-code': 'absent', antigravity: 'absent' }, blocked: row.blocked });
261
+ rows.get(row.name).providers[provider] = row.blocked ? 'blocked' : row.deliverable ? 'deliverable' : 'unavailable';
262
+ }
263
+ return [...rows.values()].sort((a, b) => a.ref.localeCompare(b.ref));
264
+ }
265
+ /** Complete validated disabled entries, proved on 2.1.4. No owner env/header/URL payload in the disabled copy. */
266
+ export function scopeOpenCodeServers(config, tools, inventory, { node = process.execPath } = {}) {
267
+ const scope = selectExternalServers(tools, inventory);
268
+ const servers = new Map(Object.entries(mcpServersOf(config)));
269
+ for (const row of inventory.servers) servers.set(row.name, scope.names.includes(row.name) ? inventory.definitionFor(row.name) : { type: 'local', command: [node, '-e', 'process.exit(0)'], disabled: true });
270
+ return { scope, config: { ...config, mcp: { ...object(config.mcp), servers: Object.fromEntries(servers) } }, overlay: { mcp: { servers: Object.fromEntries(inventory.servers.filter(row => !scope.names.includes(row.name)).map(row => [row.name, servers.get(row.name)])) } } };
271
+ }
272
+ /** Secret values go only into the CLI environment; the SDK serializes reference strings into argv. */
273
+ export function referenceClaudeMap(mcpServers, baseEnv = {}) {
274
+ const env = {}; let n = 0;
275
+ const reference = value => {
276
+ // Existing references must be expanded by the CLI, which applies its own credential/managed-policy rules.
277
+ if (String(value).includes('${')) return String(value);
278
+ const key = `SYNABUN_MCP_${++n}`;
279
+ env[key] = String(value);
280
+ return '${' + key + '}';
281
+ };
282
+ const map = {};
283
+ for (const [name, definition] of Object.entries(mcpServers)) {
284
+ const entry = structuredClone(definition);
285
+ for (const field of ['env', 'headers']) if (entry[field]) entry[field] = Object.fromEntries(Object.entries(entry[field]).map(([key, value]) => [key, reference(value)]));
286
+ if (entry.headersHelper) entry.headersHelper = reference(entry.headersHelper);
287
+ if (entry.oauth) entry.oauth = Object.fromEntries(Object.entries(entry.oauth).map(([key, value]) => [key, typeof value === 'string' ? reference(value) : value]));
288
+ if (entry.url) entry.url = reference(entry.url);
289
+ if (Array.isArray(entry.args)) entry.args = entry.args.map(reference);
290
+ Object.defineProperty(map, name, { value: entry, enumerable: true, configurable: true, writable: true });
291
+ }
292
+ return { mcpServers: map, env };
293
+ }
294
+ export function assertClaudeMcpScope(status, names) {
295
+ if (!Array.isArray(status) || status.some(row => !names.includes(row.name)) || names.some(name => !status.some(row => row.name === name))) throw Object.assign(new Error('Claude MCP scope could not be enforced before the first turn'), { code: 'MCP_SCOPE_UNENFORCED' });
296
+ }
297
+ export function writePrivateMcpConfig(path, mcpServers) {
298
+ mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
299
+ const temporary = `${path}.${process.pid}.tmp`;
300
+ writeFileSync(temporary, JSON.stringify({ mcpServers }) + '\n', { mode: 0o600 }); chmodSync(temporary, 0o600); renameSync(temporary, path); chmodSync(path, 0o600);
301
+ return path;
302
+ }
303
+
304
+ /** Keep external grants fixed when an MCP child reports only SynaBun group changes. */
305
+ export function retainExternalRefs(groups, previous) {
306
+ return [...new Set([...(groups || []).filter(item => !item.startsWith('mcp:')), ...(previous || []).filter(item => item.startsWith('mcp:'))])];
307
+ }
308
+ export async function waitForClaudeMcpScope(q, names, { timeoutMs = 30000 } = {}) {
309
+ const end = Date.now() + timeoutMs;
310
+ while (Date.now() < end) {
311
+ if (typeof q.mcpServerStatus !== 'function') break;
312
+ const remaining = end - Date.now(); let timer;
313
+ let rows;
314
+ try { rows = await Promise.race([q.mcpServerStatus(), new Promise((_, reject) => { timer = setTimeout(() => reject(new Error('MCP scope check timed out')), remaining); })]); }
315
+ finally { clearTimeout(timer); }
316
+ if (!Array.isArray(rows) || rows.some(row => !names.includes(row.name))) break;
317
+ if (names.every(name => rows.some(row => row.name === name))) return;
318
+ await new Promise(done => setTimeout(done, Math.min(100, Math.max(0, end - Date.now()))));
319
+ }
320
+ throw Object.assign(new Error('Claude MCP scope could not be enforced before the first turn'), { code: 'MCP_SCOPE_UNENFORCED' });
321
+ }
322
+ export function redactMcpValues(value, values) {
323
+ if (typeof value === 'string') { for (const secret of [...new Set(values)].filter(Boolean).sort((a, b) => b.length - a.length)) value = value.split(secret).join('[MCP value]'); return value; }
324
+ if (Array.isArray(value)) return value.map(item => redactMcpValues(item, values));
325
+ if (value && typeof value === 'object') return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, redactMcpValues(item, values)]));
326
+ return value;
327
+ }
328
+
329
+ export function mcpDefinitionValues(servers) {
330
+ const strings = value => typeof value === 'string' ? [value] : Array.isArray(value) ? value.flatMap(strings) : value && typeof value === 'object' ? Object.values(value).flatMap(strings) : [];
331
+ return [...new Set(Object.values(servers || {}).flatMap(entry => ['command', 'args', 'cwd', 'env', 'environment', 'headers', 'url', 'oauth', 'headersHelper', 'authToken'].flatMap(field => strings(entry[field]))))].filter(Boolean);
332
+ }
@@ -422,7 +422,8 @@ function scanHints(repoPath) {
422
422
  const hints = [];
423
423
  if (existsSync(join(repoPath, '.claude-plugin', 'plugin.json'))) hints.push('claude-plugin');
424
424
  if (existsSync(join(repoPath, '.codex'))) hints.push('codex');
425
- if (existsSync(join(repoPath, 'gemini-extension.json'))) hints.push('gemini');
425
+ // Antigravity's plugins: its own manifests, and the Gemini CLI extensions `agy plugin install` imports.
426
+ if (['gemini-extension.json', join('.antigravity-plugin', 'plugin.json'), join('.gemini-plugin', 'plugin.json')].some((file) => existsSync(join(repoPath, file)))) hints.push('antigravity');
426
427
  if (existsSync(join(repoPath, '.cursor'))) hints.push('cursor');
427
428
  if (existsSync(join(repoPath, '.windsurf'))) hints.push('windsurf');
428
429
  return hints;
@@ -3,9 +3,9 @@ import { randomUUID } from 'crypto';
3
3
  /**
4
4
  * Serializes and coalesces post-tool-call MCP refreshes per managed runtime.
5
5
  * Different sidepanels remain independent; repeated selections in one panel
6
- * collapse to the newest pending profile and never reconnect concurrently.
6
+ * collapse to the newest pending tools and never reconnect concurrently.
7
7
  */
8
- export class McpProfileRefreshCoordinator {
8
+ export class McpToolsRefreshCoordinator {
9
9
  constructor({
10
10
  delayMs = 250,
11
11
  setTimer = setTimeout,
@@ -21,7 +21,7 @@ export class McpProfileRefreshCoordinator {
21
21
  this.states = new Map();
22
22
  }
23
23
 
24
- schedule(runtimeId, profile, runtimeKind, refresh) {
24
+ schedule(runtimeId, tools, runtimeKind, refresh) {
25
25
  const refreshCorrelationId = this.correlationId();
26
26
  let state = this.states.get(runtimeId);
27
27
  if (!state) {
@@ -29,7 +29,7 @@ export class McpProfileRefreshCoordinator {
29
29
  this.states.set(runtimeId, state);
30
30
  }
31
31
  state.cancelled = false;
32
- state.pending = { profile, runtimeKind, correlationId: refreshCorrelationId, refresh };
32
+ state.pending = { tools, runtimeKind, correlationId: refreshCorrelationId, refresh };
33
33
  if (state.timer) this.clearTimer(state.timer);
34
34
  if (!state.running) this.#arm(runtimeId, state);
35
35
  return refreshCorrelationId;
@@ -4,10 +4,24 @@ import { detectProject } from '../../mcp-server/dist/config.js';
4
4
  import { normalizeMemoryEvents, ingestMemoryEvents } from '../../mcp-server/dist/services/memory-sessions.js';
5
5
  import { maintenancePaused } from './memory-timers.js';
6
6
 
7
- export function queueMemoryCapture({host,sessionId,filePath,project,cwd}) {
8
- if(!filePath || !sessionId || !['claude-code','codex'].includes(host))return;
7
+ /** The hosts whose transcripts are captured from a file (OpenCode's rows are taken in session-cache-builder.js). */
8
+ export const CAPTURE_HOSTS=Object.freeze(['claude-code','codex','antigravity']);
9
+
10
+ /**
11
+ * `size`: the transcript's size now, when the caller knows it. A file already read to that size is left as it is
12
+ * (a pass over every Antigravity conversation would otherwise mark each one pending again).
13
+ */
14
+ export function queueMemoryCapture({host,sessionId,filePath,project,cwd,size=null}) {
15
+ if(!filePath || !sessionId || !CAPTURE_HOSTS.includes(host))return;
16
+ if(size!=null) {
17
+ const row=getDb().prepare('SELECT file_path,byte_offset,status,cwd FROM memory_capture_files WHERE host=? AND session_id=?').get(host,sessionId);
18
+ if(row && row.status==='complete' && row.file_path===filePath && Number(row.byte_offset)===Number(size) && (row.cwd || null)===(cwd || null))return;
19
+ }
20
+ // An Antigravity conversation whose folder agy named only later is read again from its start: its events take the
21
+ // project (each step keeps its source id, so nothing is stored twice).
9
22
  getDb().prepare(`INSERT INTO memory_capture_files(host,session_id,file_path,project,cwd) VALUES(?,?,?,?,?)
10
- ON CONFLICT(host,session_id) DO UPDATE SET file_path=excluded.file_path,project=excluded.project,cwd=excluded.cwd,status='pending',error=NULL`)
23
+ ON CONFLICT(host,session_id) DO UPDATE SET file_path=excluded.file_path,project=excluded.project,cwd=excluded.cwd,status='pending',error=NULL,
24
+ byte_offset=CASE WHEN excluded.host='antigravity' AND memory_capture_files.cwd IS NOT excluded.cwd THEN 0 ELSE memory_capture_files.byte_offset END`)
11
25
  .run(host,sessionId,filePath,cwd ? detectProject(cwd) : project || 'global',cwd || null);
12
26
  }
13
27