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
@@ -9,6 +9,7 @@
9
9
  import { on, emit } from './state.js';
10
10
  import { KEYS } from './constants.js';
11
11
  import { storage } from './storage.js';
12
+ import { clampToFrame } from './app-frame.js';
12
13
 
13
14
  // ── State ──
14
15
 
@@ -39,10 +40,10 @@ export function initCostWidget() {
39
40
  if (!_docked) {
40
41
  const savedPos = _loadPos();
41
42
  if (savedPos) {
42
- const maxLeft = window.innerWidth - 270;
43
- const maxTop = window.innerHeight - 60;
44
- _widget.style.left = Math.max(0, Math.min(savedPos.left, maxLeft)) + 'px';
45
- _widget.style.top = Math.max(0, Math.min(savedPos.top, maxTop)) + 'px';
43
+ // Inside the app frame (about 270 × 60 of it on screen)
44
+ const at = clampToFrame(savedPos.left, savedPos.top, 270, 60);
45
+ _widget.style.left = at.x + 'px';
46
+ _widget.style.top = at.y + 'px';
46
47
  } else {
47
48
  _widget.style.right = '24px';
48
49
  _widget.style.bottom = '24px';
@@ -531,47 +532,47 @@ function _toggleCollapse() {
531
532
 
532
533
  // ── Drag ──
533
534
 
534
- function _makeDraggable(header) {
535
- header.style.cursor = 'grab';
536
-
537
- header.addEventListener('mousedown', (e) => {
535
+ function _makeDraggable(header) {
536
+ header.style.cursor = 'move';
537
+
538
+ header.addEventListener('mousedown', (e) => {
538
539
  if (e.target.closest('.cw-collapse') || e.target.closest('.cw-scan')) return;
539
540
  e.preventDefault();
540
541
 
541
542
  // If docked, undock on drag
542
543
  if (_docked) _undock();
543
-
544
- const rect = _widget.getBoundingClientRect();
545
- _drag = {
546
- startX: e.clientX,
547
- startY: e.clientY,
548
- origLeft: rect.left,
549
- origTop: rect.top,
550
- width: rect.width,
551
- height: rect.height,
552
- };
553
- let dragRaf = 0;
554
- let pendingPos = null;
555
- const applyDrag = () => {
556
- dragRaf = 0;
557
- if (!_widget || !pendingPos) return;
558
- _widget.style.left = pendingPos.left + 'px';
559
- _widget.style.top = pendingPos.top + 'px';
560
- };
561
- const scheduleDrag = (left, top) => {
562
- pendingPos = { left, top };
563
- if (!dragRaf) dragRaf = requestAnimationFrame(applyDrag);
564
- };
565
- const flushDrag = () => {
566
- if (dragRaf) {
567
- cancelAnimationFrame(dragRaf);
568
- dragRaf = 0;
569
- }
570
- applyDrag();
571
- };
572
- header.style.cursor = 'grabbing';
573
-
574
- // Reset right/bottom positioning and switch to left/top
544
+
545
+ const rect = _widget.getBoundingClientRect();
546
+ _drag = {
547
+ startX: e.clientX,
548
+ startY: e.clientY,
549
+ origLeft: rect.left,
550
+ origTop: rect.top,
551
+ width: rect.width,
552
+ height: rect.height,
553
+ };
554
+ let dragRaf = 0;
555
+ let pendingPos = null;
556
+ const applyDrag = () => {
557
+ dragRaf = 0;
558
+ if (!_widget || !pendingPos) return;
559
+ _widget.style.left = pendingPos.left + 'px';
560
+ _widget.style.top = pendingPos.top + 'px';
561
+ };
562
+ const scheduleDrag = (left, top) => {
563
+ pendingPos = { left, top };
564
+ if (!dragRaf) dragRaf = requestAnimationFrame(applyDrag);
565
+ };
566
+ const flushDrag = () => {
567
+ if (dragRaf) {
568
+ cancelAnimationFrame(dragRaf);
569
+ dragRaf = 0;
570
+ }
571
+ applyDrag();
572
+ };
573
+ header.style.cursor = 'move';
574
+
575
+ // Reset right/bottom positioning and switch to left/top
575
576
  _widget.style.right = 'auto';
576
577
  _widget.style.bottom = 'auto';
577
578
  _widget.style.left = _drag.origLeft + 'px';
@@ -581,25 +582,22 @@ function _makeDraggable(header) {
581
582
  if (!_drag) return;
582
583
  const dx = ev.clientX - _drag.startX;
583
584
  const dy = ev.clientY - _drag.startY;
584
- let newLeft = _drag.origLeft + dx;
585
- let newTop = _drag.origTop + dy;
586
- // Constrain to viewport
587
- const ww = _drag.width;
588
- const wh = _drag.height;
589
- newLeft = Math.max(0, Math.min(window.innerWidth - ww, newLeft));
590
- newTop = Math.max(0, Math.min(window.innerHeight - wh, newTop));
591
- scheduleDrag(newLeft, newTop);
592
- };
593
-
594
- const onUp = () => {
595
- document.removeEventListener('mousemove', onMove);
596
- document.removeEventListener('mouseup', onUp);
597
- header.style.cursor = 'grab';
598
- if (_drag) {
599
- flushDrag();
600
- _savePos(parseInt(_widget.style.left), parseInt(_widget.style.top));
601
- _drag = null;
602
- }
585
+ let newLeft = _drag.origLeft + dx;
586
+ let newTop = _drag.origTop + dy;
587
+ // Constrain to the app frame
588
+ ({ x: newLeft, y: newTop } = clampToFrame(newLeft, newTop, _drag.width, _drag.height));
589
+ scheduleDrag(newLeft, newTop);
590
+ };
591
+
592
+ const onUp = () => {
593
+ document.removeEventListener('mousemove', onMove);
594
+ document.removeEventListener('mouseup', onUp);
595
+ header.style.cursor = 'move';
596
+ if (_drag) {
597
+ flushDrag();
598
+ _savePos(parseInt(_widget.style.left), parseInt(_widget.style.top));
599
+ _drag = null;
600
+ }
603
601
  };
604
602
 
605
603
  document.addEventListener('mousemove', onMove);
@@ -0,0 +1,187 @@
1
+ // ═══════════════════════════════════════════
2
+ // SynaBun Neural Interface — the notice after an automatic restart: the page side
3
+ // ═══════════════════════════════════════════
4
+ //
5
+ // Asks GET /api/system/crash-notice when the page starts and every time its sync
6
+ // socket connects: a page that was open through the crash is not reloaded, its
7
+ // sockets reconnect (ui-sync.js `session:info`). What crash-notice-view.js says is
8
+ // drawn in the update toast's shape (bottom right, styles.css .update-check-toast,
9
+ // .crash-notice) once the loading screen is gone, and stays until it is dismissed.
10
+ // Dismiss asks the server to drop it (POST /api/system/crash-notice/dismiss), which
11
+ // tells every other window (`sync:crash-notice:changed`); this browser also keeps
12
+ // the id it dismissed, for a server that could not remove its record. Open logs
13
+ // is Settings > App's own: the desktop app's bridge, or POST
14
+ // /api/system/app/open-folder, which only a page on this computer may ask. Never
15
+ // asked by an invite guest, and never drawn for one, whatever reaches its sync
16
+ // socket: /api/system is the owner's (the server sends `crash-notice:` to the
17
+ // owner's pages only).
18
+
19
+ import { on } from './state.js';
20
+ import { getLocale, t } from './i18n.js';
21
+ import { desktopApp } from './desktop-bridge.js';
22
+ import { isGuest } from './ui-sync.js';
23
+ import { crashNoticeView, isLoopbackHost, readCrashNotice } from './crash-notice-view.js';
24
+
25
+ const NOTICE_URL = '/api/system/crash-notice';
26
+ const OPEN_FOLDER_URL = '/api/system/app/open-folder';
27
+ const WRITE = Object.freeze({ 'Content-Type': 'application/json', 'X-SynaBun-UI': '1', Accept: 'application/json' });
28
+ const DISMISSED_KEY = 'synabun-crash-notice-dismissed';
29
+ const NOTICE_ID = 'crash-notice';
30
+
31
+ const translate = (key, params) => t(`crashNotice.${key}`, params);
32
+
33
+ let _wired = false;
34
+ let _asking = null;
35
+ let _current = null; // { id, el }
36
+ let _waiting = null; // the notice that waits for the loading screen to go
37
+ let _guest = false; // what the last `session:info` said (ui-sync.js isGuest() is the socket's own word)
38
+
39
+ const guestPage = () => _guest || isGuest();
40
+
41
+ function esc(value) {
42
+ return String(value ?? '').replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
43
+ }
44
+
45
+ function dismissedHere(id) {
46
+ try { return localStorage.getItem(DISMISSED_KEY) === id; } catch { return false; }
47
+ }
48
+
49
+ function rememberDismissed(id) {
50
+ try { localStorage.setItem(DISMISSED_KEY, id); } catch { /* storage refused: the server's word is enough */ }
51
+ }
52
+
53
+ function canOpenLogs() {
54
+ if (typeof desktopApp()?.openFolder === 'function') return true;
55
+ return isLoopbackHost(location.hostname);
56
+ }
57
+
58
+ function hide() {
59
+ const current = _current;
60
+ _current = null;
61
+ if (!current) return;
62
+ current.el.classList.remove('show');
63
+ setTimeout(() => current.el.remove(), 250);
64
+ }
65
+
66
+ /** The loading screen covers the page while it starts: the notice waits for it to go. */
67
+ function whenPageShown(run) {
68
+ const overlay = document.getElementById('loading-overlay');
69
+ if (!overlay || overlay.classList.contains('hidden')) { run(); return; }
70
+ const watch = new MutationObserver(() => {
71
+ if (!overlay.classList.contains('hidden')) return;
72
+ watch.disconnect();
73
+ run();
74
+ });
75
+ watch.observe(overlay, { attributes: true, attributeFilter: ['class'] });
76
+ }
77
+
78
+ function show(view) {
79
+ hide();
80
+ document.querySelectorAll(`#${NOTICE_ID}`).forEach((el) => el.remove());
81
+ const el = document.createElement('div');
82
+ el.className = 'update-check-toast crash-notice';
83
+ el.id = NOTICE_ID;
84
+ el.setAttribute('role', 'status');
85
+ el.setAttribute('aria-label', view.label);
86
+ el.dataset.noticeId = view.id;
87
+ const buttons = view.actions.map((item) => `<button class="action-btn action-btn--ghost crash-notice-btn" type="button" data-crash-action="${esc(item.id)}" id="crash-notice-${esc(item.id)}">${esc(item.label)}</button>`).join('');
88
+ el.innerHTML = `
89
+ <div class="utc-icon utc-icon--err" aria-hidden="true">!</div>
90
+ <div class="utc-body">
91
+ <div class="utc-title" id="crash-notice-title">${esc(view.title)}</div>
92
+ <div class="utc-sub" id="crash-notice-when">${esc(view.when)}</div>
93
+ ${view.how ? `<div class="utc-sub" id="crash-notice-how">${esc(view.how)}</div>` : ''}
94
+ <div class="crash-notice-lost-title" id="crash-notice-lost-title">${esc(view.lostTitle)}</div>
95
+ <ul class="utc-list crash-notice-lost" aria-labelledby="crash-notice-lost-title">${view.lost.map((line) => `<li>${esc(line)}</li>`).join('')}</ul>
96
+ <div class="utc-sub crash-notice-note" id="crash-notice-note" role="status" hidden></div>
97
+ <div class="update-notice-actions">${buttons}</div>
98
+ </div>`;
99
+ el.querySelectorAll('[data-crash-action]').forEach((btn) => {
100
+ btn.addEventListener('click', (event) => {
101
+ event.stopPropagation();
102
+ if (btn.dataset.crashAction === 'dismiss') dismiss(view.id);
103
+ else if (btn.dataset.crashAction === 'logs') openLogs(el);
104
+ });
105
+ });
106
+ document.body.appendChild(el);
107
+ requestAnimationFrame(() => el.classList.add('show'));
108
+ _current = { id: view.id, el };
109
+ }
110
+
111
+ /** Show this notice (or none): once per crash, never one this browser dismissed, never on a guest's page. */
112
+ function present(notice) {
113
+ if (!notice || guestPage()) {
114
+ _waiting = null;
115
+ hide();
116
+ return;
117
+ }
118
+ // A notice something else took off the page is drawn again: it stays until it is dismissed.
119
+ if (_current && !_current.el.isConnected) _current = null;
120
+ if (dismissedHere(notice.id) || _current?.id === notice.id || _waiting?.id === notice.id) return;
121
+ _waiting = notice;
122
+ whenPageShown(() => {
123
+ if (_waiting !== notice) return;
124
+ _waiting = null;
125
+ if (dismissedHere(notice.id) || guestPage()) return;
126
+ show(crashNoticeView(notice, { t: translate, locale: getLocale(), canOpenLogs: canOpenLogs() }));
127
+ });
128
+ }
129
+
130
+ /** Ask the server; an older server (404) or a guest (403) has nothing to say. */
131
+ export function checkCrashNotice() {
132
+ if (guestPage()) return Promise.resolve(null);
133
+ if (_asking) return _asking;
134
+ _asking = (async () => {
135
+ try {
136
+ const res = await fetch(NOTICE_URL, { headers: { Accept: 'application/json' }, cache: 'no-store' });
137
+ if (!res.ok) return null;
138
+ const notice = readCrashNotice(await res.json());
139
+ present(notice);
140
+ return notice;
141
+ } catch {
142
+ return null;
143
+ }
144
+ })().finally(() => { _asking = null; });
145
+ return _asking;
146
+ }
147
+
148
+ async function dismiss(id) {
149
+ rememberDismissed(id);
150
+ hide();
151
+ try {
152
+ const res = await fetch(`${NOTICE_URL}/dismiss`, { method: 'POST', headers: WRITE, body: JSON.stringify({ id }) });
153
+ const next = res.ok ? readCrashNotice(await res.json()) : null;
154
+ // A newer crash came while this one was shown: that one is news.
155
+ if (next && next.id !== id) present(next);
156
+ } catch { /* the server is away: this browser keeps it dismissed */ }
157
+ }
158
+
159
+ async function openLogs(el) {
160
+ const note = el.querySelector('#crash-notice-note');
161
+ const bridge = desktopApp();
162
+ let ok = false;
163
+ if (typeof bridge?.openFolder === 'function') {
164
+ try { ok = !!(await bridge.openFolder('logs'))?.ok; } catch { ok = false; }
165
+ } else {
166
+ try {
167
+ const res = await fetch(OPEN_FOLDER_URL, { method: 'POST', headers: WRITE, body: JSON.stringify({ which: 'logs' }) });
168
+ ok = res.ok;
169
+ } catch { ok = false; }
170
+ }
171
+ if (!note) return;
172
+ note.hidden = ok;
173
+ note.textContent = ok ? '' : translate('openLogsFailed');
174
+ }
175
+
176
+ /** Wire the notice once: ask now, and again every time the sync socket connects. */
177
+ export function initCrashNotice() {
178
+ if (_wired) return;
179
+ _wired = true;
180
+ on('session:info', (info) => {
181
+ _guest = !!info?.isGuest;
182
+ if (_guest) present(null);
183
+ else checkCrashNotice();
184
+ });
185
+ on('sync:crash-notice:changed', (message) => present(readCrashNotice(message)));
186
+ checkCrashNotice();
187
+ }
@@ -14,7 +14,8 @@ import { storage } from './storage.js';
14
14
  import { catColor } from './colors.js';
15
15
  import { truncate, formatMemoryContent, exportMemoryAsMarkdown, rafThrottle, escapeHtml } from './utils.js';
16
16
  import { t, getLocale } from './i18n.js';
17
- import { savePanelLayout, restorePanelLayout } from './ui-panels.js';
17
+ import { savePanelLayout, restorePanelLayout, clampPanelToFrame } from './ui-panels.js';
18
+ import { frameRect } from './app-frame.js';
18
19
  import { sendSync as _sendSync, hasPermission, isGuest } from './ui-sync.js';
19
20
 
20
21
  // Wrap sendSync — skip card events when guest lacks cards permission
@@ -546,9 +547,11 @@ function bringToFront(cardEl) {
546
547
  function getNextCardPosition() {
547
548
  const count = _openCards.size;
548
549
  const offset = count * 30;
550
+ // Cascading from 200 / 80 px of the window (192 / 24 px into the app frame), inside the frame.
551
+ const f = frameRect();
549
552
  return {
550
- left: Math.min(window.innerWidth - 540, 200 + (offset % 300)) + 'px',
551
- top: Math.min(window.innerHeight - 300, 80 + (offset % 200)) + 'px',
553
+ left: Math.max(f.left, Math.min(f.right - 540, f.left + 192 + (offset % 300))) + 'px',
554
+ top: Math.max(f.top, Math.min(f.bottom - 300, f.top + 24 + (offset % 200))) + 'px',
552
555
  };
553
556
  }
554
557
 
@@ -587,6 +590,13 @@ export function getOpenCardCount() {
587
590
  return _openCards.size;
588
591
  }
589
592
 
593
+ /** Press an open card's Linked button from outside it (the context menu), unless it is on already. */
594
+ export function focusLinkedMemories(memoryId) {
595
+ const card = _openCards.get(memoryId);
596
+ if (!card || state.focusedNodeId === memoryId) return;
597
+ q(card.el, 'focus-btn')?.click();
598
+ }
599
+
590
600
  export function restoreOpenCards() {
591
601
  const raw = storage.getItem(KEYS.OPEN_CARDS);
592
602
  if (!raw) return;
@@ -1062,6 +1072,8 @@ export function openMemoryCard(node, savedPosition) {
1062
1072
  // ── Add to DOM and state ──
1063
1073
  _openCards.set(node.id, cardState);
1064
1074
  document.body.appendChild(card);
1075
+ // A position saved in another window size, or with the explorers closed, comes back inside the app frame.
1076
+ if (savedPosition) clampPanelToFrame(card);
1065
1077
  bringToFront(card);
1066
1078
 
1067
1079
  // Trigger entrance animation on next frame
@@ -18,6 +18,7 @@ import { registerAction } from './ui-keybinds.js';
18
18
  import { storage } from './storage.js';
19
19
  import { sendToPanel as sendToClaudePanel } from './ui-claude-panel.js';
20
20
  import { attachPathToOpencode } from './ui-opencode-panel-v2.js';
21
+ import { attachPathToAntigravity, isAntigravityPanelOpen, toggleAntigravityPanel } from './ui-antigravity-panel.js';
21
22
  import { isCodexPanelOpen, toggleCodexPanel } from './cdx/cdx-panel.js';
22
23
  import { addPathChip as addCodexPathChip } from './cdx/cdx-tabs.js';
23
24
  import { on, emit, state } from './state.js';
@@ -35,6 +36,7 @@ const SEND = {
35
36
  claude: (path) => sendToClaudePanel(path, { asFile: true }),
36
37
  codex: async (path) => { if (!isCodexPanelOpen()) await toggleCodexPanel(); addCodexPathChip(path); },
37
38
  opencode: (path) => attachPathToOpencode(path),
39
+ antigravity: async (path) => { if (!isAntigravityPanelOpen()) await toggleAntigravityPanel(); return attachPathToAntigravity(path); },
38
40
  assistant: (path) => attachToAssistant('assistant', path),
39
41
  };
40
42
  function attachToAssistant(target, filePath) {
@@ -289,6 +291,13 @@ async function showTree() {
289
291
  }
290
292
  }
291
293
 
294
+ // What each scan state says, in words. The header never shows them while a branch is on screen (that would
295
+ // move the row): there they are a dot on the branch button, its tooltip and label, and a line of the git popover.
296
+ const SCAN_STATE_TEXT = { scanning: 'fileExplorer.branch.scanning', 'timed-out': 'fileExplorer.branch.timedOut', failed: 'fileExplorer.branch.scanFailed' };
297
+ function scanStateText(git) {
298
+ return git && SCAN_STATE_TEXT[git.scanState] ? tr(SCAN_STATE_TEXT[git.scanState]) : '';
299
+ }
300
+
292
301
  function updateBranchLabel(git) {
293
302
  _git = git;
294
303
  const btn = $('fe-branch-btn');
@@ -296,15 +305,33 @@ function updateBranchLabel(git) {
296
305
  const badge = $('fe-branch-btn-badge');
297
306
  if (!btn) return;
298
307
 
299
- if (git.isGit && git.branch) {
308
+ const state = SCAN_STATE_TEXT[git.scanState] ? git.scanState : '';
309
+ const message = scanStateText(git);
310
+ const hasBranch = !!(git.isGit && git.branch);
311
+ // Nothing on screen yet (the project's first scan): the state, in one truncated line, where the branch will be.
312
+ const placeholder = !hasBranch && !git.shown && !!message;
313
+ let dot = btn.querySelector('.fe-branch-btn-state');
314
+ if (!dot) { dot = document.createElement('span'); dot.className = 'fe-branch-btn-state'; dot.setAttribute('aria-hidden', 'true'); btn.appendChild(dot); }
315
+ if (state) btn.dataset.scanState = state; else delete btn.dataset.scanState;
316
+ btn.setAttribute('aria-busy', String(state === 'scanning'));
317
+ // Read out, never drawn: only what the owner is waiting for (a first scan, a Refresh), or how one ended.
318
+ const live = $('fe-git-scan-live');
319
+ // A background scan clears it (that is not read out) rather than leave an old sentence there.
320
+ if (live) { const said = git.loud ? message : ''; if (live.textContent !== said) live.textContent = said; }
321
+
322
+ if (hasBranch || placeholder) {
300
323
  btn.style.display = '';
301
- if (nameEl) nameEl.textContent = git.branch;
302
- if (badge) badge.textContent = git.count > 0 ? git.count : '';
303
- btn.setAttribute('aria-label', tr('fileExplorer.branch.label', { branch: git.branch, count: git.count }));
304
- btn.dataset.tooltip = tr('fileExplorer.branch.label', { branch: git.branch, count: git.count });
324
+ btn.classList.toggle('fe-branch-btn--placeholder', placeholder);
325
+ if (nameEl) nameEl.textContent = hasBranch ? git.branch : message;
326
+ if (badge) badge.textContent = hasBranch && git.count > 0 ? git.count : '';
327
+ const label = hasBranch ? tr('fileExplorer.branch.label', { branch: git.branch, count: git.count }) : '';
328
+ const full = label && message ? tr('fileExplorer.branch.withState', { label, state: message }) : label || message;
329
+ btn.setAttribute('aria-label', full);
330
+ btn.dataset.tooltip = full;
305
331
  if (_gitPopoverOpen) renderGitSummary();
306
332
  } else {
307
333
  btn.style.display = 'none';
334
+ btn.classList.remove('fe-branch-btn--placeholder');
308
335
  closeGitPopover();
309
336
  }
310
337
  }
@@ -358,7 +385,8 @@ function openGitPopover() {
358
385
  requestAnimationFrame(() => pop.classList.add('visible'));
359
386
  loadGitBranches();
360
387
  renderGitSummary();
361
- _fx?.refresh();
388
+ // Fresh counts for the popover, without a word in the header: nobody pressed Refresh.
389
+ _fx?.refresh({ quiet: true });
362
390
  }
363
391
 
364
392
  function closeGitPopover() {
@@ -379,6 +407,7 @@ function toggleGitPopover() {
379
407
 
380
408
  // What changed, in words and counts: from the git state the tree already holds.
381
409
  function renderGitSummary() {
410
+ renderGitScanState();
382
411
  const summary = $('fe-git-summary');
383
412
  if (!summary) return;
384
413
  const changes = _fx?.state.git.changed() || [];
@@ -405,6 +434,18 @@ function renderGitSummary() {
405
434
  }
406
435
  }
407
436
 
437
+ // How the last scan went, in the popover (the header has no room for words): a timeout or a failure always,
438
+ // a scan under way only when the owner is waiting for it (the first one, a Refresh).
439
+ function renderGitScanState() {
440
+ const line = $('fe-git-scan-state');
441
+ if (!line) return;
442
+ const state = _git?.scanState;
443
+ const message = state === 'scanning' && !_git.loud ? '' : scanStateText(_git);
444
+ line.textContent = message;
445
+ line.hidden = !message;
446
+ if (message) line.dataset.tone = state; else delete line.dataset.tone;
447
+ }
448
+
408
449
  async function loadGitBranches() {
409
450
  if (!_selectedProject) return;
410
451
  const sel = $('fe-git-branch-select');
@@ -561,6 +602,7 @@ function createGitPopover() {
561
602
  </div>
562
603
  <div class="fe-git-pop-sep"></div>
563
604
  <div class="fe-git-pop-section">
605
+ <div class="fe-git-scan-state" id="fe-git-scan-state" hidden></div>
564
606
  <div class="fe-git-summary" id="fe-git-summary"></div>
565
607
  </div>
566
608
  </div>
@@ -2,8 +2,8 @@
2
2
  // SynaBun Neural Interface — File links in agent messages: the page side
3
3
  // ═══════════════════════════════════════════
4
4
  //
5
- // One click handler for the links in the messages of the four side panels
6
- // (Assistant, Claude, Codex, OpenCode). A link that points at a file the code
5
+ // One click handler for the links in the messages of the five side panels
6
+ // (Assistant, Claude, Codex, OpenCode, Antigravity). A link that points at a file the code
7
7
  // editor can open opens it there (`open-file-editor`), at its line and column;
8
8
  // every other link keeps what its panel did with it. What a target means and
9
9
  // what a click does are decided in file-links.js; this module gives it the
@@ -197,12 +197,12 @@ function detectActiveGame() {
197
197
  // ── SVG icons for opponent picker ──
198
198
  const ICON_CLAUDE = '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M4.709 15.955l4.72-2.647.08-.23-.08-.128H9.2l-.79-.048-2.698-.073-2.339-.097-2.266-.122-.571-.121L0 11.784l.055-.352.48-.321.686.06 1.52.103 2.278.158 1.652.097 2.449.255h.389l.055-.157-.134-.098-.103-.097-2.358-1.596-2.552-1.688-1.336-.972-.724-.491-.364-.462-.158-1.008.656-.722.881.06.225.061.893.686 1.908 1.476 2.491 1.833.365.304.145-.103.019-.073-.164-.274-1.355-2.446-1.446-2.49-.644-1.032-.17-.619a2.97 2.97 0 01-.104-.729L6.283.134 6.696 0l.996.134.42.364.62 1.414 1.002 2.229 1.555 3.03.456.898.243.832.091.255h.158V9.01l.128-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.584.28.48.685-.067.444-.286 1.851-.559 2.903-.364 1.942h.212l.243-.242.985-1.306 1.652-2.064.73-.82.85-.904.547-.431h1.033l.76 1.129-.34 1.166-1.064 1.347-.881 1.142-1.264 1.7-.79 1.36.073.11.188-.02 2.856-.606 1.543-.28 1.841-.315.833.388.091.395-.328.807-1.969.486-2.309.462-3.439.813-.042.03.049.061 1.549.146.662.036h1.622l3.02.225.79.522.474.638-.079.485-1.215.62-1.64-.389-3.829-.91-1.312-.329h-.182v.11l1.093 1.068 2.006 1.81 2.509 2.33.127.578-.322.455-.34-.049-2.205-1.657-.851-.747-1.926-1.62h-.128v.17l.444.649 2.345 3.521.122 1.08-.17.353-.608.213-.668-.122-1.374-1.925-1.415-2.167-1.143-1.943-.14.08-.674 7.254-.316.37-.729.28-.607-.461-.322-.747.322-1.476.389-1.924.315-1.53.286-1.9.17-.632-.012-.042-.14.018-1.434 1.967-2.18 2.945-1.726 1.845-.414.164-.717-.37.067-.662.401-.589 2.388-3.036 1.44-1.882.93-1.086-.006-.158h-.055L4.132 18.56l-1.13.146-.487-.456.061-.746.231-.243 1.908-1.312-.006.006z"/></svg>';
199
199
  const ICON_OPENAI = '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M9.205 8.658v-2.26c0-.19.072-.333.238-.428l4.543-2.616c.619-.357 1.356-.523 2.117-.523 2.854 0 4.662 2.212 4.662 4.566 0 .167 0 .357-.024.547l-4.71-2.759a.797.797 0 00-.856 0l-5.97 3.473zm10.609 8.8V12.06c0-.333-.143-.57-.429-.737l-5.97-3.473 1.95-1.118a.433.433 0 01.476 0l4.543 2.617c1.309.76 2.189 2.378 2.189 3.948 0 1.808-1.07 3.473-2.76 4.163zM7.802 12.703l-1.95-1.142c-.167-.095-.239-.238-.239-.428V5.899c0-2.545 1.95-4.472 4.591-4.472 1 0 1.927.333 2.712.928L8.23 5.067c-.285.166-.428.404-.428.737v6.898zM12 15.128l-2.795-1.57v-3.33L12 8.658l2.795 1.57v3.33L12 15.128zm1.796 7.23c-1 0-1.927-.332-2.712-.927l4.686-2.712c.285-.166.428-.404.428-.737v-6.898l1.974 1.142c.167.095.238.238.238.428v5.233c0 2.545-1.974 4.472-4.614 4.472zm-5.637-5.303l-4.544-2.617c-1.308-.761-2.188-2.378-2.188-3.948A4.482 4.482 0 014.21 6.327v5.423c0 .333.143.571.428.738l5.947 3.449-1.95 1.118a.432.432 0 01-.476 0zm-.262 3.9c-2.688 0-4.662-2.021-4.662-4.519 0-.19.024-.38.047-.57l4.686 2.71c.286.167.571.167.856 0l5.97-3.448v2.26c0 .19-.07.333-.237.428l-4.543 2.616c-.619.357-1.356.523-2.117.523zm5.899 2.83a5.947 5.947 0 005.827-4.756C22.287 18.339 24 15.84 24 13.296c0-1.665-.713-3.282-1.998-4.448.119-.5.19-.999.19-1.498 0-3.401-2.759-5.947-5.946-5.947-.642 0-1.26.095-1.88.31A5.962 5.962 0 0010.205 0a5.947 5.947 0 00-5.827 4.757C1.713 5.447 0 7.945 0 10.49c0 1.666.713 3.283 1.998 4.448-.119.5-.19 1-.19 1.499 0 3.401 2.759 5.946 5.946 5.946.642 0 1.26-.095 1.88-.309a5.96 5.96 0 004.162 1.713z"/></svg>';
200
- const ICON_GEMINI = '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z"/></svg>';
200
+ const ICON_ANTIGRAVITY = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4.5 20 12 4l7.5 16"/><path d="M8.2 20a3.8 3.8 0 0 1 7.6 0"/></svg>';
201
201
 
202
202
  const OPPONENTS = [
203
203
  { id: 'claude-code', icon: ICON_CLAUDE, label: 'Claude' },
204
204
  { id: 'codex', icon: ICON_OPENAI, label: 'OpenAI' },
205
- { id: 'gemini', icon: ICON_GEMINI, label: 'Gemini' },
205
+ { id: 'antigravity', icon: ICON_ANTIGRAVITY, label: 'Antigravity' },
206
206
  ];
207
207
 
208
208
  // ── Opponent picker overlay ──
@@ -8,6 +8,7 @@ import { emit, on } from './state.js';
8
8
  import { fetchImages, toggleImageFavorite, deleteImage } from './api.js';
9
9
  import { addImageToWhiteboard } from './ui-whiteboard.js';
10
10
  import { escapeHtml } from './utils.js';
11
+ import { centeredInFrame } from './app-frame.js';
11
12
 
12
13
  const $ = (id) => document.getElementById(id);
13
14
 
@@ -23,33 +24,33 @@ let _lightboxImg = null; // filename currently in lightbox
23
24
  let isVisible = false;
24
25
 
25
26
  // ── Drag state ──
26
- let _dragging = false;
27
- let _dragOff = { x: 0, y: 0 };
28
- let _dragRaf = 0;
29
- let _pendingDrag = null;
30
-
31
- function applyDragPosition() {
32
- _dragRaf = 0;
33
- if (!_panel || !_pendingDrag) return;
34
- _panel.style.left = _pendingDrag.left + 'px';
35
- _panel.style.top = _pendingDrag.top + 'px';
36
- }
37
-
38
- function scheduleDragPosition(left, top) {
39
- _pendingDrag = { left, top };
40
- if (!_dragRaf) _dragRaf = requestAnimationFrame(applyDragPosition);
41
- }
42
-
43
- function flushDragPosition() {
44
- if (_dragRaf) {
45
- cancelAnimationFrame(_dragRaf);
46
- _dragRaf = 0;
47
- }
48
- applyDragPosition();
49
- }
50
-
51
- // ── Icons ──
52
- const ICON_CLOSE = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M4 4l8 8M12 4l-8 8"/></svg>';
27
+ let _dragging = false;
28
+ let _dragOff = { x: 0, y: 0 };
29
+ let _dragRaf = 0;
30
+ let _pendingDrag = null;
31
+
32
+ function applyDragPosition() {
33
+ _dragRaf = 0;
34
+ if (!_panel || !_pendingDrag) return;
35
+ _panel.style.left = _pendingDrag.left + 'px';
36
+ _panel.style.top = _pendingDrag.top + 'px';
37
+ }
38
+
39
+ function scheduleDragPosition(left, top) {
40
+ _pendingDrag = { left, top };
41
+ if (!_dragRaf) _dragRaf = requestAnimationFrame(applyDragPosition);
42
+ }
43
+
44
+ function flushDragPosition() {
45
+ if (_dragRaf) {
46
+ cancelAnimationFrame(_dragRaf);
47
+ _dragRaf = 0;
48
+ }
49
+ applyDragPosition();
50
+ }
51
+
52
+ // ── Icons ──
53
+ const ICON_CLOSE = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M4 4l8 8M12 4l-8 8"/></svg>';
53
54
  const ICON_REFRESH = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M2.5 8a5.5 5.5 0 019.2-4M13.5 8a5.5 5.5 0 01-9.2 4"/><path d="M11.5 2v2.5H14M4.5 14v-2.5H2"/></svg>';
54
55
  const ICON_HEART = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M8 13.7C4.3 11 2 8.7 2 6.3A3.3 3.3 0 018 4.6a3.3 3.3 0 016 1.7c0 2.4-2.3 4.7-6 7.4z"/></svg>';
55
56
  const ICON_HEART_FILL = '<svg viewBox="0 0 16 16" fill="currentColor" stroke="none"><path d="M8 13.7C4.3 11 2 8.7 2 6.3A3.3 3.3 0 018 4.6a3.3 3.3 0 016 1.7c0 2.4-2.3 4.7-6 7.4z"/></svg>';
@@ -388,13 +389,13 @@ function wirePanel() {
388
389
  header.addEventListener('mousedown', (e) => {
389
390
  if (e.target.closest('button')) return;
390
391
  _dragging = true;
391
- _panel.classList.add('dragging');
392
- const rect = _panel.getBoundingClientRect();
393
- _dragOff = { x: e.clientX - rect.left, y: e.clientY - rect.top };
394
- _pendingDrag = null;
395
- e.preventDefault();
396
- });
397
- }
392
+ _panel.classList.add('dragging');
393
+ const rect = _panel.getBoundingClientRect();
394
+ _dragOff = { x: e.clientX - rect.left, y: e.clientY - rect.top };
395
+ _pendingDrag = null;
396
+ e.preventDefault();
397
+ });
398
+ }
398
399
 
399
400
  // Keyboard in lightbox
400
401
  document.addEventListener('keydown', handleKey);
@@ -425,24 +426,26 @@ function openPanel() {
425
426
  _panel.innerHTML = buildPanelHTML();
426
427
  document.body.appendChild(_panel);
427
428
 
428
- _panel.style.left = Math.max(20, (window.innerWidth - 780) / 2) + 'px';
429
- _panel.style.top = Math.max(48, (window.innerHeight - 560) / 2) + 'px';
429
+ // Centred in the app frame
430
+ const at = centeredInFrame(780, 560);
431
+ _panel.style.left = at.left + 'px';
432
+ _panel.style.top = at.top + 'px';
430
433
 
431
434
  wirePanel();
432
435
  isVisible = true;
433
436
  refreshImages();
434
437
 
435
- // Global mouse handlers for drag
436
- const onMouseMove = (e) => {
437
- if (!_dragging) return;
438
- scheduleDragPosition(e.clientX - _dragOff.x, e.clientY - _dragOff.y);
439
- };
440
- const onMouseUp = () => {
441
- if (!_dragging) return;
442
- _dragging = false;
443
- flushDragPosition();
444
- if (_panel) _panel.classList.remove('dragging');
445
- };
438
+ // Global mouse handlers for drag
439
+ const onMouseMove = (e) => {
440
+ if (!_dragging) return;
441
+ scheduleDragPosition(e.clientX - _dragOff.x, e.clientY - _dragOff.y);
442
+ };
443
+ const onMouseUp = () => {
444
+ if (!_dragging) return;
445
+ _dragging = false;
446
+ flushDragPosition();
447
+ if (_panel) _panel.classList.remove('dragging');
448
+ };
446
449
  document.addEventListener('mousemove', onMouseMove);
447
450
  document.addEventListener('mouseup', onMouseUp);
448
451