synabun 2.0.10 → 2.1.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 (517) hide show
  1. package/CHANGELOG.md +86 -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 +2 -2
  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 +17 -8
  11. package/lib/desktop-app.js +7 -1
  12. package/lib/external-tools.js +1 -1
  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 +228 -0
  24. package/lib/virustotal.mjs +192 -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/codex-config-heal.d.ts +6 -2
  37. package/mcp-server/dist/services/codex-config-heal.d.ts.map +1 -1
  38. package/mcp-server/dist/services/codex-config-heal.js +81 -28
  39. package/mcp-server/dist/services/codex-config-heal.js.map +1 -1
  40. package/mcp-server/dist/services/memory-judge-backfill.d.ts +6 -0
  41. package/mcp-server/dist/services/memory-judge-backfill.d.ts.map +1 -1
  42. package/mcp-server/dist/services/memory-judge-backfill.js +7 -1
  43. package/mcp-server/dist/services/memory-judge-backfill.js.map +1 -1
  44. package/mcp-server/dist/services/neural-interface.d.ts +16 -10
  45. package/mcp-server/dist/services/neural-interface.d.ts.map +1 -1
  46. package/mcp-server/dist/services/neural-interface.js +67 -11
  47. package/mcp-server/dist/services/neural-interface.js.map +1 -1
  48. package/mcp-server/dist/services/server-instructions.d.ts +7 -2
  49. package/mcp-server/dist/services/server-instructions.d.ts.map +1 -1
  50. package/mcp-server/dist/services/server-instructions.js +20 -62
  51. package/mcp-server/dist/services/server-instructions.js.map +1 -1
  52. package/mcp-server/dist/services/tool-catalog.d.ts +120 -0
  53. package/mcp-server/dist/services/tool-catalog.d.ts.map +1 -0
  54. package/mcp-server/dist/services/tool-catalog.js +339 -0
  55. package/mcp-server/dist/services/tool-catalog.js.map +1 -0
  56. package/mcp-server/dist/services/tool-list-refresh-barrier.d.ts +12 -0
  57. package/mcp-server/dist/services/tool-list-refresh-barrier.d.ts.map +1 -0
  58. package/mcp-server/dist/services/tool-list-refresh-barrier.js +40 -0
  59. package/mcp-server/dist/services/tool-list-refresh-barrier.js.map +1 -0
  60. package/mcp-server/dist/services/tool-list.d.ts +108 -0
  61. package/mcp-server/dist/services/tool-list.d.ts.map +1 -0
  62. package/mcp-server/dist/services/tool-list.js +334 -0
  63. package/mcp-server/dist/services/tool-list.js.map +1 -0
  64. package/mcp-server/dist/services/tool-runtime.d.ts +161 -0
  65. package/mcp-server/dist/services/tool-runtime.d.ts.map +1 -0
  66. package/mcp-server/dist/services/tool-runtime.js +400 -0
  67. package/mcp-server/dist/services/tool-runtime.js.map +1 -0
  68. package/mcp-server/dist/services/whiteboard-geometry.d.ts +26 -2
  69. package/mcp-server/dist/services/whiteboard-geometry.d.ts.map +1 -1
  70. package/mcp-server/dist/services/whiteboard-geometry.js +91 -8
  71. package/mcp-server/dist/services/whiteboard-geometry.js.map +1 -1
  72. package/mcp-server/dist/tools/agents.d.ts +10 -10
  73. package/mcp-server/dist/tools/agents.d.ts.map +1 -1
  74. package/mcp-server/dist/tools/agents.js +22 -13
  75. package/mcp-server/dist/tools/agents.js.map +1 -1
  76. package/mcp-server/dist/tools/browser-batch.d.ts +3 -3
  77. package/mcp-server/dist/tools/image-tools.d.ts +1 -1
  78. package/mcp-server/dist/tools/image-tools.js +1 -1
  79. package/mcp-server/dist/tools/skill-tools.d.ts +505 -0
  80. package/mcp-server/dist/tools/skill-tools.d.ts.map +1 -0
  81. package/mcp-server/dist/tools/skill-tools.js +639 -0
  82. package/mcp-server/dist/tools/skill-tools.js.map +1 -0
  83. package/mcp-server/dist/tools/skill.d.ts +7 -0
  84. package/mcp-server/dist/tools/skill.d.ts.map +1 -0
  85. package/mcp-server/dist/tools/skill.js +11 -0
  86. package/mcp-server/dist/tools/skill.js.map +1 -0
  87. package/mcp-server/dist/tools/tool-groups.d.ts +68 -0
  88. package/mcp-server/dist/tools/tool-groups.d.ts.map +1 -0
  89. package/mcp-server/dist/tools/tool-groups.js +147 -0
  90. package/mcp-server/dist/tools/tool-groups.js.map +1 -0
  91. package/mcp-server/dist/tools/whiteboard-format.d.ts.map +1 -1
  92. package/mcp-server/dist/tools/whiteboard-format.js +7 -4
  93. package/mcp-server/dist/tools/whiteboard-format.js.map +1 -1
  94. package/mcp-server/dist/tools/whiteboard-tools.d.ts +64 -13
  95. package/mcp-server/dist/tools/whiteboard-tools.d.ts.map +1 -1
  96. package/mcp-server/dist/tools/whiteboard-tools.js +30 -5
  97. package/mcp-server/dist/tools/whiteboard-tools.js.map +1 -1
  98. package/mcp-server/package-lock.json +2 -2
  99. package/mcp-server/package.json +1 -1
  100. package/mcp-server/src/http.ts +75 -12
  101. package/mcp-server/src/index.ts +147 -154
  102. package/mcp-server/src/preload.ts +12 -12
  103. package/mcp-server/src/services/codex-config-heal.ts +80 -29
  104. package/mcp-server/src/services/memory-judge-backfill.ts +7 -1
  105. package/mcp-server/src/services/neural-interface.ts +79 -20
  106. package/mcp-server/src/services/server-instructions.ts +27 -63
  107. package/mcp-server/src/services/tool-catalog.ts +403 -0
  108. package/mcp-server/src/services/tool-list-refresh-barrier.ts +33 -0
  109. package/mcp-server/src/services/tool-list.ts +410 -0
  110. package/mcp-server/src/services/tool-runtime.ts +457 -0
  111. package/mcp-server/src/services/whiteboard-geometry.ts +94 -9
  112. package/mcp-server/src/tools/agents.ts +22 -14
  113. package/mcp-server/src/tools/image-tools.ts +1 -1
  114. package/mcp-server/src/tools/skill-tools.ts +589 -0
  115. package/mcp-server/src/tools/skill.ts +13 -0
  116. package/mcp-server/src/tools/tool-groups.ts +164 -0
  117. package/mcp-server/src/tools/whiteboard-format.ts +9 -3
  118. package/mcp-server/src/tools/whiteboard-tools.ts +39 -5
  119. package/neural-interface/i18n/en.json +3463 -200
  120. package/neural-interface/i18n/pt-BR.json +3411 -151
  121. package/neural-interface/lib/assistant-api.js +127 -28
  122. package/neural-interface/lib/assistant-brains/claude.js +4 -3
  123. package/neural-interface/lib/assistant-brains/codex-browser-policy-hook.mjs +12 -2
  124. package/neural-interface/lib/assistant-brains/codex-route-gate-hook.mjs +32 -9
  125. package/neural-interface/lib/assistant-brains/codex.js +9 -5
  126. package/neural-interface/lib/assistant-brains/opencode.js +120 -54
  127. package/neural-interface/lib/assistant-brains/opencode2-browser-policy/index.js +28 -13
  128. package/neural-interface/lib/assistant-brains/opencode2-route-gate/index.js +59 -19
  129. package/neural-interface/lib/assistant-catalog.js +6 -7
  130. package/neural-interface/lib/assistant-dispatch.js +871 -156
  131. package/neural-interface/lib/assistant-envelope.js +3 -1
  132. package/neural-interface/lib/assistant-persona.js +80 -11
  133. package/neural-interface/lib/assistant-plan-permissions.js +10 -9
  134. package/neural-interface/lib/assistant-route-gate-codex.js +3 -0
  135. package/neural-interface/lib/assistant-route-gate.js +6 -4
  136. package/neural-interface/lib/assistant-router.js +13 -8
  137. package/neural-interface/lib/assistant-runtime.js +56 -18
  138. package/neural-interface/lib/assistant-task-prompt.js +78 -14
  139. package/neural-interface/lib/assistant-tools.js +51 -0
  140. package/neural-interface/lib/backup-service.js +620 -3
  141. package/neural-interface/lib/backup-zip-reader.js +10 -5
  142. package/neural-interface/lib/backup-zip-writer.js +257 -0
  143. package/neural-interface/lib/browser-execution.js +10 -2
  144. package/neural-interface/lib/browser-guard-cdp.js +83 -0
  145. package/neural-interface/lib/browser-network-guard.js +284 -0
  146. package/neural-interface/lib/browser-policy-roots.js +64 -0
  147. package/neural-interface/lib/browser-tool-policy.js +186 -31
  148. package/neural-interface/lib/claude-agent-bridge.js +4 -2
  149. package/neural-interface/lib/claude-hooks-status.js +103 -0
  150. package/neural-interface/lib/claude-temporary.js +5 -11
  151. package/neural-interface/lib/cli-install.js +18 -138
  152. package/neural-interface/lib/cli-resolver.js +4 -1
  153. package/neural-interface/lib/cli-update-planner.js +32 -31
  154. package/neural-interface/lib/cloudflared/tunnel.js +42 -2
  155. package/neural-interface/lib/codex-mcp-approvals.js +11 -0
  156. package/neural-interface/lib/codex-worker-app-server.js +172 -0
  157. package/neural-interface/lib/confined-fs.js +30 -3
  158. package/neural-interface/lib/crash-notice-api.js +98 -0
  159. package/neural-interface/lib/editor-completion-opencode.js +68 -68
  160. package/neural-interface/lib/exec-loop-command.js +4 -8
  161. package/neural-interface/lib/http-guards.js +8 -2
  162. package/neural-interface/lib/install-details.js +4 -1
  163. package/neural-interface/lib/mcp-agent-servers.js +67 -0
  164. package/neural-interface/lib/mcp-client-config.js +0 -29
  165. package/neural-interface/lib/mcp-external-servers.js +323 -0
  166. package/neural-interface/lib/{mcp-profile-refresh-coordinator.js → mcp-tools-refresh-coordinator.js} +4 -4
  167. package/neural-interface/lib/morelogin.js +30 -0
  168. package/neural-interface/lib/native-loop-providers.js +547 -47
  169. package/neural-interface/lib/native-loop-runtime.js +268 -41
  170. package/neural-interface/lib/opencode-config.js +557 -0
  171. package/neural-interface/lib/opencode-db-schema.js +17 -34
  172. package/neural-interface/lib/opencode-history.js +48 -218
  173. package/neural-interface/lib/opencode-mcp-ready.js +108 -0
  174. package/neural-interface/lib/opencode-native-boundary.js +44 -0
  175. package/neural-interface/lib/opencode-protocol.js +249 -112
  176. package/neural-interface/lib/opencode-runtime-config.js +32 -22
  177. package/neural-interface/lib/opencode-serve-records.js +39 -21
  178. package/neural-interface/lib/opencode-v2-client.js +48 -153
  179. package/neural-interface/lib/opencode-v2-ws-requests.js +36 -210
  180. package/neural-interface/lib/opencode-worker-data.js +27 -0
  181. package/neural-interface/lib/opencode2-client.js +73 -37
  182. package/neural-interface/lib/opencode2-proxy.js +23 -63
  183. package/neural-interface/lib/opencode2-translate.js +51 -2
  184. package/neural-interface/lib/owner-authority.js +249 -0
  185. package/neural-interface/lib/page-session.js +275 -0
  186. package/neural-interface/lib/peer-identity.js +763 -0
  187. package/neural-interface/lib/request-gate.js +17 -2
  188. package/neural-interface/lib/rulesets/api.js +1 -1
  189. package/neural-interface/lib/rulesets/fs-safe.js +1 -1
  190. package/neural-interface/lib/rulesets/installer.js +92 -27
  191. package/neural-interface/lib/rulesets/json-edit.js +1 -1
  192. package/neural-interface/lib/session-cache-builder.js +17 -30
  193. package/neural-interface/lib/session-title-generator.js +58 -36
  194. package/neural-interface/lib/skills/api-v2.js +495 -0
  195. package/neural-interface/lib/skills/bundle.js +418 -0
  196. package/neural-interface/lib/skills/catalog.js +294 -0
  197. package/neural-interface/lib/skills/creation-api.js +191 -0
  198. package/neural-interface/lib/skills/creation-brief.js +247 -0
  199. package/neural-interface/lib/skills/creation-sources.js +267 -0
  200. package/neural-interface/lib/skills/creation.js +843 -0
  201. package/neural-interface/lib/skills/deploy.js +564 -0
  202. package/neural-interface/lib/skills/digest.js +119 -0
  203. package/neural-interface/lib/skills/discover.js +111 -0
  204. package/neural-interface/lib/skills/draft-confinement.js +214 -0
  205. package/neural-interface/lib/skills/eval-confinement.js +397 -0
  206. package/neural-interface/lib/skills/eval-sandbox.js +280 -0
  207. package/neural-interface/lib/skills/eval-trace.js +119 -0
  208. package/neural-interface/lib/skills/evals-api.js +212 -0
  209. package/neural-interface/lib/skills/evals.js +1573 -0
  210. package/neural-interface/lib/skills/export.js +200 -0
  211. package/neural-interface/lib/skills/frontmatter.js +64 -0
  212. package/neural-interface/lib/skills/health.js +75 -0
  213. package/neural-interface/lib/skills/json-edit.js +165 -0
  214. package/neural-interface/lib/skills/known-bridge-digests.json +387 -0
  215. package/neural-interface/lib/skills/known-bridges.js +96 -0
  216. package/neural-interface/lib/skills/library.js +823 -0
  217. package/neural-interface/lib/skills/local-store.js +21 -0
  218. package/neural-interface/lib/skills/migration.js +433 -0
  219. package/neural-interface/lib/skills/operations.js +45 -0
  220. package/neural-interface/lib/skills/ownership.js +427 -0
  221. package/neural-interface/lib/skills/packages.js +88 -0
  222. package/neural-interface/lib/skills/reviews.js +212 -0
  223. package/neural-interface/lib/skills/revision.js +80 -0
  224. package/neural-interface/lib/skills/roots.js +262 -0
  225. package/neural-interface/lib/skills/runtime-checks.js +355 -0
  226. package/neural-interface/lib/skills/scan-assets.js +252 -0
  227. package/neural-interface/lib/skills/scan-context.js +26 -0
  228. package/neural-interface/lib/skills/scan-shell.js +324 -0
  229. package/neural-interface/lib/skills/scan.js +364 -0
  230. package/neural-interface/lib/skills/scanners.js +54 -0
  231. package/neural-interface/lib/skills/service.js +522 -0
  232. package/neural-interface/lib/skills/telemetry.js +113 -0
  233. package/neural-interface/lib/sqlite-integrity-worker.js +22 -0
  234. package/neural-interface/lib/tool-lists.js +124 -0
  235. package/neural-interface/lib/whatsapp/bridge.js +6 -3
  236. package/neural-interface/lib/worker-confinement.js +1192 -0
  237. package/neural-interface/lib/worker-guard-setting.js +56 -0
  238. package/neural-interface/lib/worker-mcp-channel.js +175 -0
  239. package/neural-interface/lib/worker-relay-ports.js +227 -0
  240. package/neural-interface/lib/worker-resume.js +229 -0
  241. package/neural-interface/lib/worker-sandbox.js +299 -0
  242. package/neural-interface/package-lock.json +18 -12
  243. package/neural-interface/package.json +2 -2
  244. package/neural-interface/public/index.html +3 -1
  245. package/neural-interface/public/index2d.html +19 -11
  246. package/neural-interface/public/onboarding.html +2 -2
  247. package/neural-interface/public/shared/account-menu.js +8 -5
  248. package/neural-interface/public/shared/agent-runtime-options.js +35 -19
  249. package/neural-interface/public/shared/api.js +1527 -1336
  250. package/neural-interface/public/shared/app-frame.js +192 -0
  251. package/neural-interface/public/shared/assistant/asst-agents-dock.js +33 -2
  252. package/neural-interface/public/shared/assistant/asst-ask-styles.js +270 -0
  253. package/neural-interface/public/shared/assistant/asst-ask-tail.js +118 -0
  254. package/neural-interface/public/shared/assistant/asst-ask.js +397 -0
  255. package/neural-interface/public/shared/assistant/asst-brain-picker.js +49 -35
  256. package/neural-interface/public/shared/assistant/asst-control.js +157 -26
  257. package/neural-interface/public/shared/assistant/asst-followups-card.js +383 -0
  258. package/neural-interface/public/shared/assistant/asst-followups.js +417 -0
  259. package/neural-interface/public/shared/assistant/asst-limit-dock.js +40 -0
  260. package/neural-interface/public/shared/assistant/asst-limit-wait.js +294 -0
  261. package/neural-interface/public/shared/assistant/asst-limit.js +168 -0
  262. package/neural-interface/public/shared/assistant/asst-mascot.js +49 -12
  263. package/neural-interface/public/shared/assistant/asst-menu.js +7 -6
  264. package/neural-interface/public/shared/assistant/asst-panel.js +106 -11
  265. package/neural-interface/public/shared/assistant/asst-rack-styles.js +66 -49
  266. package/neural-interface/public/shared/assistant/asst-render.js +401 -77
  267. package/neural-interface/public/shared/assistant/asst-route.js +83 -12
  268. package/neural-interface/public/shared/assistant/asst-scenes.js +2 -0
  269. package/neural-interface/public/shared/assistant/asst-sidepanel.js +67 -4
  270. package/neural-interface/public/shared/assistant/asst-slash.js +9 -7
  271. package/neural-interface/public/shared/assistant/asst-state.js +11 -15
  272. package/neural-interface/public/shared/assistant/asst-stop.js +127 -0
  273. package/neural-interface/public/shared/assistant/asst-styles.js +59 -21
  274. package/neural-interface/public/shared/assistant/asst-tool-kinds.js +156 -16
  275. package/neural-interface/public/shared/automation-context.js +5 -2
  276. package/neural-interface/public/shared/cc-dropdown.js +89 -19
  277. package/neural-interface/public/shared/cdx/cdx-context-menu.js +10 -9
  278. package/neural-interface/public/shared/cdx/cdx-copy.js +16 -0
  279. package/neural-interface/public/shared/cdx/cdx-output-model.js +22 -1
  280. package/neural-interface/public/shared/cdx/cdx-output.js +8 -7
  281. package/neural-interface/public/shared/cdx/cdx-panel.js +45 -149
  282. package/neural-interface/public/shared/cdx/cdx-protocol.js +28 -1
  283. package/neural-interface/public/shared/cdx/cdx-render.js +47 -29
  284. package/neural-interface/public/shared/cdx/cdx-requests.js +3 -3
  285. package/neural-interface/public/shared/cdx/cdx-skill-hints.js +54 -0
  286. package/neural-interface/public/shared/cdx/cdx-styles.js +11 -3
  287. package/neural-interface/public/shared/cdx/cdx-tabs.js +52 -39
  288. package/neural-interface/public/shared/cdx/cdx-ws.js +0 -1
  289. package/neural-interface/public/shared/cli-install-view.js +4 -8
  290. package/neural-interface/public/shared/cli-status.js +2 -2
  291. package/neural-interface/public/shared/constants.js +2 -2
  292. package/neural-interface/public/shared/context-menu-areas.js +34 -0
  293. package/neural-interface/public/shared/context-menu-logic.js +243 -0
  294. package/neural-interface/public/shared/context-menu-model.js +366 -0
  295. package/neural-interface/public/shared/context-menu.js +372 -0
  296. package/neural-interface/public/shared/cp/cp-context-menu.js +10 -9
  297. package/neural-interface/public/shared/crash-notice-view.js +168 -0
  298. package/neural-interface/public/shared/desktop-update-view.js +20 -0
  299. package/neural-interface/public/shared/editor/editor-panel-logic.js +2 -2
  300. package/neural-interface/public/shared/html-shell.js +9 -11
  301. package/neural-interface/public/shared/i18n.js +2 -0
  302. package/neural-interface/public/shared/ocp-v2/ocp-v2-approvals.js +7 -7
  303. package/neural-interface/public/shared/ocp-v2/ocp-v2-binding.js +4 -4
  304. package/neural-interface/public/shared/ocp-v2/ocp-v2-changes-logic.js +3 -101
  305. package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +2 -0
  306. package/neural-interface/public/shared/ocp-v2/ocp-v2-compact-button.js +1 -3
  307. package/neural-interface/public/shared/ocp-v2/ocp-v2-composer-logic.js +2 -6
  308. package/neural-interface/public/shared/ocp-v2/ocp-v2-context-menu.js +11 -11
  309. package/neural-interface/public/shared/ocp-v2/ocp-v2-context-model.js +0 -3
  310. package/neural-interface/public/shared/ocp-v2/ocp-v2-events.js +8 -4
  311. package/neural-interface/public/shared/ocp-v2/ocp-v2-manager.js +7 -7
  312. package/neural-interface/public/shared/ocp-v2/ocp-v2-outcome-notifications.js +16 -0
  313. package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +47 -252
  314. package/neural-interface/public/shared/ocp-v2/ocp-v2-plan.js +1 -2
  315. package/neural-interface/public/shared/ocp-v2/ocp-v2-projectbar.js +95 -202
  316. package/neural-interface/public/shared/ocp-v2/ocp-v2-render.js +6 -21
  317. package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +4 -4
  318. package/neural-interface/public/shared/ocp-v2/ocp-v2-session-actions.js +8 -61
  319. package/neural-interface/public/shared/ocp-v2/ocp-v2-sessions-logic.js +2 -91
  320. package/neural-interface/public/shared/ocp-v2/ocp-v2-slash-hints.js +16 -15
  321. package/neural-interface/public/shared/ocp-v2/ocp-v2-state.js +8 -21
  322. package/neural-interface/public/shared/ocp-v2/ocp-v2-status-logic.js +1 -99
  323. package/neural-interface/public/shared/ocp-v2/ocp-v2-status.js +5 -35
  324. package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +0 -21
  325. package/neural-interface/public/shared/ocp-v2/{ocp-v2-profile-inheritance.js → ocp-v2-tools-inheritance.js} +16 -16
  326. package/neural-interface/public/shared/ocp-v2/ocp-v2-ws.js +14 -47
  327. package/neural-interface/public/shared/page-session.js +96 -0
  328. package/neural-interface/public/shared/registry.js +5 -3
  329. package/neural-interface/public/shared/retired-2d.js +3 -0
  330. package/neural-interface/public/shared/schedules-view.js +195 -61
  331. package/neural-interface/public/shared/settings/settings-claude-hooks.js +135 -0
  332. package/neural-interface/public/shared/settings/settings-data.js +3 -1
  333. package/neural-interface/public/shared/settings/settings-ia.js +6 -6
  334. package/neural-interface/public/shared/settings/settings-opencode.js +89 -0
  335. package/neural-interface/public/shared/settings/settings-skill-folders-pane.js +265 -0
  336. package/neural-interface/public/shared/settings/settings-skill-folders.js +130 -0
  337. package/neural-interface/public/shared/settings/settings-worker-guard.js +72 -0
  338. package/neural-interface/public/shared/skills/ss-args.js +96 -0
  339. package/neural-interface/public/shared/skills/ss-creation.js +219 -0
  340. package/neural-interface/public/shared/skills/ss-dialog.js +130 -0
  341. package/neural-interface/public/shared/skills/ss-doc.js +173 -0
  342. package/neural-interface/public/shared/skills/ss-eval-adapters.js +269 -0
  343. package/neural-interface/public/shared/skills/ss-eval-grade.js +359 -0
  344. package/neural-interface/public/shared/skills/ss-eval-optimise.js +153 -0
  345. package/neural-interface/public/shared/skills/ss-eval-plan.js +315 -0
  346. package/neural-interface/public/shared/skills/ss-evals.js +417 -0
  347. package/neural-interface/public/shared/skills/ss-form.js +159 -0
  348. package/neural-interface/public/shared/skills/ss-frontmatter.js +376 -0
  349. package/neural-interface/public/shared/skills/ss-ids.js +32 -0
  350. package/neural-interface/public/shared/skills/ss-lint.js +141 -0
  351. package/neural-interface/public/shared/skills/ss-presets.js +117 -0
  352. package/neural-interface/public/shared/skills/ss-profiles.js +475 -0
  353. package/neural-interface/public/shared/skills/ss-resources.js +165 -0
  354. package/neural-interface/public/shared/skills/ss-review-view.js +190 -0
  355. package/neural-interface/public/shared/skills/ss-tabs.js +79 -0
  356. package/neural-interface/public/shared/skills/ss-unicode.js +135 -0
  357. package/neural-interface/public/shared/skills/studio/sx-actions.js +222 -0
  358. package/neural-interface/public/shared/skills/studio/sx-cm.js +101 -0
  359. package/neural-interface/public/shared/skills/studio/sx-create-ai-view.js +749 -0
  360. package/neural-interface/public/shared/skills/studio/sx-create-ai.js +236 -0
  361. package/neural-interface/public/shared/skills/studio/sx-create-view.js +254 -0
  362. package/neural-interface/public/shared/skills/studio/sx-create.js +126 -0
  363. package/neural-interface/public/shared/skills/studio/sx-diff-view.js +43 -0
  364. package/neural-interface/public/shared/skills/studio/sx-diff.js +133 -0
  365. package/neural-interface/public/shared/skills/studio/sx-docs.js +480 -0
  366. package/neural-interface/public/shared/skills/studio/sx-dom.js +229 -0
  367. package/neural-interface/public/shared/skills/studio/sx-edit-view.js +848 -0
  368. package/neural-interface/public/shared/skills/studio/sx-editor-model.js +193 -0
  369. package/neural-interface/public/shared/skills/studio/sx-errors.js +22 -0
  370. package/neural-interface/public/shared/skills/studio/sx-geometry.js +82 -0
  371. package/neural-interface/public/shared/skills/studio/sx-import.js +262 -0
  372. package/neural-interface/public/shared/skills/studio/sx-inspector.js +308 -0
  373. package/neural-interface/public/shared/skills/studio/sx-install-flow.js +279 -0
  374. package/neural-interface/public/shared/skills/studio/sx-install.js +296 -0
  375. package/neural-interface/public/shared/skills/studio/sx-library-view.js +639 -0
  376. package/neural-interface/public/shared/skills/studio/sx-library.js +475 -0
  377. package/neural-interface/public/shared/skills/studio/sx-main.js +681 -0
  378. package/neural-interface/public/shared/skills/studio/sx-operations-view.js +98 -0
  379. package/neural-interface/public/shared/skills/studio/sx-operations.js +11 -0
  380. package/neural-interface/public/shared/skills/studio/sx-plan.js +158 -0
  381. package/neural-interface/public/shared/skills/studio/sx-publish-view.js +621 -0
  382. package/neural-interface/public/shared/skills/studio/sx-review-view.js +369 -0
  383. package/neural-interface/public/shared/skills/studio/sx-review.js +148 -0
  384. package/neural-interface/public/shared/skills/studio/sx-scan.js +35 -0
  385. package/neural-interface/public/shared/skills/studio/sx-snippets.js +96 -0
  386. package/neural-interface/public/shared/skills/studio/sx-subject.js +248 -0
  387. package/neural-interface/public/shared/skills/studio/sx-test-view.js +994 -0
  388. package/neural-interface/public/shared/skills/studio/sx-test.js +328 -0
  389. package/neural-interface/public/shared/skills/studio/sx-versions-view.js +241 -0
  390. package/neural-interface/public/shared/skills/studio/sx-workspace-view.js +425 -0
  391. package/neural-interface/public/shared/styleguide/sg-panel.js +4 -2
  392. package/neural-interface/public/shared/styles.css +1525 -1779
  393. package/neural-interface/public/shared/synabun-mascot.js +1115 -9
  394. package/neural-interface/public/shared/tool-list-picker.js +55 -0
  395. package/neural-interface/public/shared/tool-list-storage.js +24 -0
  396. package/neural-interface/public/shared/tool-list-view.js +112 -0
  397. package/neural-interface/public/shared/tour/tour-actor.js +268 -0
  398. package/neural-interface/public/shared/tour/tour-beats.js +336 -0
  399. package/neural-interface/public/shared/tour/tour-engine.js +884 -0
  400. package/neural-interface/public/shared/tour/tour-ink.js +390 -0
  401. package/neural-interface/public/shared/tour/tour-stage.js +440 -0
  402. package/neural-interface/public/shared/tour/tour-state.js +40 -0
  403. package/neural-interface/public/shared/tour/tour-tips.js +99 -0
  404. package/neural-interface/public/shared/tour/tour.css +144 -0
  405. package/neural-interface/public/shared/ui-automation-studio.js +91 -128
  406. package/neural-interface/public/shared/ui-claude-panel.js +77 -5
  407. package/neural-interface/public/shared/ui-command-runner.js +6 -3
  408. package/neural-interface/public/shared/ui-context-menu.js +295 -0
  409. package/neural-interface/public/shared/ui-cost-widget.js +57 -59
  410. package/neural-interface/public/shared/ui-crash-notice.js +187 -0
  411. package/neural-interface/public/shared/ui-detail.js +15 -3
  412. package/neural-interface/public/shared/ui-image-gallery.js +50 -47
  413. package/neural-interface/public/shared/ui-keybinds.js +26 -1
  414. package/neural-interface/public/shared/ui-menubar.js +8 -18
  415. package/neural-interface/public/shared/ui-native-loop-router-state.js +5 -0
  416. package/neural-interface/public/shared/ui-native-loop-router.js +7 -1
  417. package/neural-interface/public/shared/ui-navbar.js +4 -24
  418. package/neural-interface/public/shared/ui-panels.js +96 -65
  419. package/neural-interface/public/shared/ui-schedules-studio.js +507 -423
  420. package/neural-interface/public/shared/ui-sessions.js +5 -3
  421. package/neural-interface/public/shared/ui-settings.js +594 -462
  422. package/neural-interface/public/shared/ui-sidepanel-sessions.js +1 -1
  423. package/neural-interface/public/shared/ui-sidepanel-state.js +23 -12
  424. package/neural-interface/public/shared/ui-sidepanel-windows.js +16 -11
  425. package/neural-interface/public/shared/ui-skills.js +33 -2830
  426. package/neural-interface/public/shared/ui-styleguide.js +5 -2
  427. package/neural-interface/public/shared/ui-sync.js +15 -5
  428. package/neural-interface/public/shared/ui-terminal.js +124 -180
  429. package/neural-interface/public/shared/ui-tool-updates.js +3 -1
  430. package/neural-interface/public/shared/ui-tooltip.js +10 -5
  431. package/neural-interface/public/shared/ui-trash.js +6 -4
  432. package/neural-interface/public/shared/ui-tutorial-layout.js +3 -117
  433. package/neural-interface/public/shared/ui-tutorial-preview.js +103 -0
  434. package/neural-interface/public/shared/ui-tutorial-steps.js +3 -65
  435. package/neural-interface/public/shared/ui-tutorial.css +47 -100
  436. package/neural-interface/public/shared/ui-tutorial.js +285 -509
  437. package/neural-interface/public/shared/ui-update.js +38 -2
  438. package/neural-interface/public/shared/ui-whiteboard.js +311 -58
  439. package/neural-interface/public/shared/ui-worker-end.js +4 -0
  440. package/neural-interface/public/shared/ui-workspaces.js +3 -2
  441. package/neural-interface/public/shared/view-variant.js +66 -0
  442. package/neural-interface/public/shared/whatsapp/wa-view.js +1 -1
  443. package/neural-interface/public/shared/whiteboard-list.js +172 -0
  444. package/neural-interface/public/shared/worker-end.js +10 -3
  445. package/neural-interface/public/shared/worker-restart.js +12 -0
  446. package/neural-interface/public/sidepanel-session.html +1 -1
  447. package/neural-interface/public/variant/2d/background.js +2 -1
  448. package/neural-interface/public/variant/2d/context-menu.js +8 -2
  449. package/neural-interface/public/variant/2d/graph.js +42 -20
  450. package/neural-interface/public/variant/2d/hulls.js +14 -9
  451. package/neural-interface/public/variant/2d/lasso.js +11 -7
  452. package/neural-interface/public/variant/2d/main.js +32 -1
  453. package/neural-interface/public/variant/2d/minimap.js +11 -13
  454. package/neural-interface/public/variant/3d/main.js +69 -6
  455. package/neural-interface/public/variant/3d/map-controls.js +24 -9
  456. package/neural-interface/public/vendor/caveat/OFL.txt +93 -0
  457. package/neural-interface/public/vendor/caveat/caveat-latin-400-normal.woff2 +0 -0
  458. package/neural-interface/public/vendor/caveat/caveat-latin-700-normal.woff2 +0 -0
  459. package/neural-interface/public/vendor/caveat/caveat.css +17 -0
  460. package/neural-interface/public/vendor/caveat/manifest.json +12 -0
  461. package/neural-interface/public/vendor/yaml/LICENSE +13 -0
  462. package/neural-interface/public/vendor/yaml/manifest.json +4 -0
  463. package/neural-interface/public/vendor/yaml/yaml-2.9.1.min.js +137 -0
  464. package/neural-interface/scripts/build-vendor.mjs +32 -0
  465. package/neural-interface/server.js +3934 -2454
  466. package/neural-interface/templates/rulesets/core.md +1 -1
  467. package/neural-interface/templates/rulesets/legacy-hashes.json +18 -0
  468. package/neural-interface/templates/rulesets/manifest.json +8 -8
  469. package/npm-shrinkwrap.json +18 -12
  470. package/package.json +16 -3
  471. package/postinstall.js +9 -4
  472. package/preuninstall.js +1 -1
  473. package/setup.js +97 -322
  474. package/skills/skill-forge/SKILL.md +177 -0
  475. package/skills/skill-forge/evals/evals.json +54 -0
  476. package/skills/skill-forge/references/package.md +105 -0
  477. package/skills/skill-forge/references/review-and-recovery.md +63 -0
  478. package/skills/skill-forge/references/runtime-profiles.md +20 -0
  479. package/skills/skill-forge/references/sources-and-capabilities.md +51 -0
  480. package/skills/synabun/SKILL.md +10 -7
  481. package/skills/synabun/modules/audit.md +1 -5
  482. package/skills/synabun/modules/changelog.md +1 -5
  483. package/skills/synabun/modules/idea.md +1 -1
  484. package/skills/synabun/modules/memorize.md +6 -9
  485. package/skills/synabun/modules/schedule.md +4 -4
  486. package/mcp-server/dist/services/profiles.d.ts +0 -120
  487. package/mcp-server/dist/services/profiles.d.ts.map +0 -1
  488. package/mcp-server/dist/services/profiles.js +0 -387
  489. package/mcp-server/dist/services/profiles.js.map +0 -1
  490. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts +0 -97
  491. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts.map +0 -1
  492. package/mcp-server/dist/tools/leonardo-browser-tools.js +0 -228
  493. package/mcp-server/dist/tools/leonardo-browser-tools.js.map +0 -1
  494. package/mcp-server/dist/tools/leonardo.d.ts +0 -13
  495. package/mcp-server/dist/tools/leonardo.d.ts.map +0 -1
  496. package/mcp-server/dist/tools/leonardo.js +0 -21
  497. package/mcp-server/dist/tools/leonardo.js.map +0 -1
  498. package/mcp-server/dist/tools/profile.d.ts +0 -17
  499. package/mcp-server/dist/tools/profile.d.ts.map +0 -1
  500. package/mcp-server/dist/tools/profile.js +0 -114
  501. package/mcp-server/dist/tools/profile.js.map +0 -1
  502. package/mcp-server/src/services/profiles.ts +0 -428
  503. package/mcp-server/src/tools/leonardo-browser-tools.ts +0 -291
  504. package/mcp-server/src/tools/leonardo.ts +0 -30
  505. package/mcp-server/src/tools/profile.ts +0 -122
  506. package/neural-interface/lib/assistant-brains/opencode-browser-policy.js +0 -47
  507. package/neural-interface/lib/assistant-brains/opencode-route-gate.js +0 -62
  508. package/neural-interface/lib/mcp-profile-servers.js +0 -120
  509. package/neural-interface/public/shared/ui-tutorial-draw.js +0 -311
  510. package/skills/leonardo/SKILL.md +0 -168
  511. package/skills/leonardo/icon.svg +0 -1
  512. package/skills/leonardo/modules/browser-guide.md +0 -378
  513. package/skills/leonardo/modules/image-prompter.md +0 -283
  514. package/skills/leonardo/modules/model-advisor.md +0 -100
  515. package/skills/leonardo/modules/prompt-library.md +0 -110
  516. package/skills/leonardo/modules/style-guide.md +0 -186
  517. package/skills/leonardo/modules/video-prompter.md +0 -317
@@ -5,6 +5,7 @@
5
5
 
6
6
  import { getVariant } from './registry.js';
7
7
  import { t } from './i18n.js';
8
+ import { FRAMED_CLASS } from './app-frame.js';
8
9
 
9
10
  /**
10
11
  * The File Explorer's editor panel (slides from the file explorer's right edge).
@@ -86,6 +87,10 @@ export function getSharedHTML() {
86
87
  const is3D = variant === '3d';
87
88
 
88
89
  return `
90
+ <!-- App frame (styles.css APP FRAME): the card's interior under the graph, its border and gutter over the windows -->
91
+ <div id="app-frame-surface" aria-hidden="true"></div>
92
+ <div id="app-frame" aria-hidden="true"></div>
93
+
89
94
  <!-- Loading Overlay -->
90
95
  <div id="loading-overlay">
91
96
  <div id="loading-mascot" data-state="asleep">
@@ -148,12 +153,6 @@ export function getSharedHTML() {
148
153
  <div class="bar-left">
149
154
  <img src="synabun.png?v=2" alt="SynaBun" id="titlebar-logo" style="height:24px;width:auto;cursor:pointer;" data-tooltip="${t('tooltip.toggleExplorer')}">
150
155
  <div class="bar-sep"></div>
151
- <div class="view-toggle">
152
- <a class="view-toggle-btn${is3D ? '' : ' active'}" href="${is3D ? '/index2d.html' : '#'}" id="nav-2d-link">${t('nav.toggle2d')}</a>
153
- <a class="view-toggle-btn${is3D ? ' active' : ''}" href="${is3D ? '#' : '/'}" id="nav-3d-link">${t('nav.toggle3d')}</a>
154
- <span class="view-toggle-sep"></span>
155
- </div>
156
- <div class="bar-sep"></div>
157
156
 
158
157
  <!-- OS-style menubar -->
159
158
  <div class="menubar">
@@ -227,10 +226,6 @@ export function getSharedHTML() {
227
226
  <span class="menu-check"></span>
228
227
  <span class="menu-text"><span class="menu-icon"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z"/></svg></span> WhatsApp</span>
229
228
  </div>
230
- <div class="menu-item" id="menu-app-leonardo" hidden>
231
- <span class="menu-check"></span>
232
- <span class="menu-text"><span class="menu-icon"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M9.5 2l1.5 3.5L14.5 7l-3.5 1.5L9.5 12l-1.5-3.5L4.5 7l3.5-1.5L9.5 2zM19 10l1 2 2 1-2 1-1 2-1-2-2-1 2-1 1-2zM5 17l1 2 2 1-2 1-1 2-1-2-2-1 2-1 1-2z"/></svg></span> Leonardo.AI</span>
233
- </div>
234
229
  </div>
235
230
  <div class="menu-sep"></div>
236
231
  <div class="menu-item" id="menu-command-runner">
@@ -248,7 +243,7 @@ export function getSharedHTML() {
248
243
  </div>
249
244
  <div class="menu-sep"></div>
250
245
  ${is3D ? ` <!-- Map (3D memory map) -->
251
- <div class="menu-item menu-submenu-parent" id="menu-map-label" data-submenu="map" aria-haspopup="menu" aria-expanded="false">
246
+ <div class="menu-item menu-submenu-parent" id="menu-map-label" data-menu="graph" data-submenu="map" aria-haspopup="menu" aria-expanded="false">
252
247
  <span class="menu-check"></span>
253
248
  <span class="menu-text"><span class="menu-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="1 6 1 22 8 18 16 22 23 18 23 2 16 6 8 2 1 6"/><line x1="8" y1="2" x2="8" y2="18"/><line x1="16" y1="6" x2="16" y2="22"/></svg></span> ${t('nav.map')}</span>
254
249
  <span class="menu-submenu-arrow" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg></span>
@@ -862,5 +857,8 @@ ${getEditorPanelHTML()}
862
857
  * Call this once at the start of variant main.js, BEFORE any DOM queries.
863
858
  */
864
859
  export function injectSharedHTML() {
860
+ // The workspace sits in the inset rounded frame (app-frame.js): set before the shell lands, so nothing is laid
861
+ // out once without it.
862
+ document.documentElement.classList.add(FRAMED_CLASS);
865
863
  document.body.insertAdjacentHTML('afterbegin', getSharedHTML());
866
864
  }
@@ -246,6 +246,8 @@ export function setLocaleChoice(choice) {
246
246
  const value = choice === SYSTEM_LOCALE ? SYSTEM_LOCALE : (SUPPORTED_LOCALES.includes(choice) ? choice : null);
247
247
  if (!value) return false;
248
248
  storage.setItem(LOCALE_STORAGE_KEY, value);
249
+ // Windows that open again after the reload (the Schedules window) note it now, while they are open.
250
+ try { globalThis.window?.dispatchEvent?.(new CustomEvent('synabun:locale-change', { detail: { choice: value } })); } catch { /* nobody listens */ }
249
251
  // The store writes to the server after a pause; the reload must read the new choice.
250
252
  // (A write still pending when the page unloads goes out as a beacon, so a slow server only delays the reload.)
251
253
  const written = Promise.resolve().then(() => storageModule.flushStorage?.()).catch(() => {});
@@ -200,14 +200,14 @@ export async function setAutoAccept(store, api, enabled, { cwd, isDescendant } =
200
200
  }
201
201
 
202
202
  /**
203
- * How long an "Always allow" lasts, for the card. On OpenCode 1.18.34 the
204
- * answer is kept by the serve process that runs the session: the patterns are
205
- * allowed for the project on that serve until it restarts. It is not written
206
- * to OpenCode's saved-permissions store (`/api/permission/saved` stays empty
207
- * after an "always"; checked against a live serve), so there is no list of
208
- * earlier answers to show or take back.
203
+ * How far an "Always allow" reaches, for the card. OpenCode 2 saves the answer
204
+ * for the session's project: after an "always" reply on 2.1.4,
205
+ * `GET /api/permission/saved` lists `{ projectID, action, resource }` with the
206
+ * card's pattern (checked against a live serve), so it holds in every session
207
+ * of that project and outlives the serve. The panel shows no list of saved
208
+ * answers; OpenCode's own saved permissions are where one is taken back.
209
209
  */
210
- export const ALWAYS_ALLOW_SCOPE = 'until this session\u2019s OpenCode runtime restarts';
210
+ export const ALWAYS_ALLOW_SCOPE = 'in every session of this project: OpenCode saves the answer';
211
211
 
212
212
  // ── Questions ───────────────────────────────────────────────────────────────
213
213
  // The answer path of a question card, whatever built the card: a request in
@@ -63,7 +63,7 @@ function frozenCopy(value, seen = new Map()) {
63
63
  * isCurrent() an extra veto, e.g. "this child panel is still the open one"
64
64
  * Returns a frozen token:
65
65
  * binding, sessionId, cwd, directory (cwd, else the session's directory),
66
- * model, variant, agent, mode, mcpProfile, sessionInfo (model and
66
+ * model, variant, agent, mode, tools, sessionInfo (model and
67
67
  * sessionInfo are frozen copies, nested objects included)
68
68
  * isCurrent() the store is still on this binding
69
69
  * isStale() the opposite
@@ -90,7 +90,7 @@ export function captureBinding(store, { sessionId, isCurrent } = {}) {
90
90
  variant: s.variant || null,
91
91
  agent: s.agent || null,
92
92
  mode: s.mode || null,
93
- mcpProfile: s.mcpProfile || null,
93
+ tools: s.tools ? frozenCopy(s.tools) : null,
94
94
  sessionInfo: s.sessionInfo ? frozenCopy(s.sessionInfo) : null,
95
95
  isCurrent: current,
96
96
  isStale: () => !current(),
@@ -218,8 +218,8 @@ export function boundReader(store) {
218
218
  // another tab after it. Both were started on the same binding.
219
219
  //
220
220
  // So where the panel goes has an identity of its own. Every choice of the user
221
- // (a tab, a session in the menu, New session, another project, a new worktree)
222
- // begins an intent, and a navigation binds the panel only while its intent is
221
+ // (a tab, a session in the menu, New session, another project) begins an
222
+ // intent, and a navigation binds the panel only while its intent is
223
223
  // the latest one: after every wait it checks `isCurrent()`, and it binds
224
224
  // through `apply()`. A later choice always wins over an older one that is
225
225
  // still in flight. A rebinding nobody announced (the active tab was closed)
@@ -59,113 +59,15 @@ export function changesTabs(supports = () => false) {
59
59
  return tabs;
60
60
  }
61
61
 
62
- // ── Worktrees ───────────────────────────────────────────────────────────────
63
-
64
- /**
65
- * Watch one worktree creation from request to ready.
66
- *
67
- * Subscribe before asking OpenCode to create the worktree (worktree.ready can
68
- * beat the reply), then call `identify(name)` with the name the reply carries.
69
- * Until then events are kept, not acted on: `worktree.ready` names its
70
- * worktree, so only the one for `name` counts, and another window's or
71
- * project's creation finishing first changes nothing.
72
- *
73
- * The outcome is decided by that ready event and nothing else. `worktree.failed`
74
- * carries a message and no name (1.18.34: `{ message }`), so a failure cannot
75
- * be told apart from the failure of another creation on the same serve
76
- * (another window, another project). It therefore never ends this creation:
77
- * the message is kept, the wait goes on, and a ready for `name` still wins. If
78
- * no ready arrives before `timeoutMs`, the last resort, the result says so and
79
- * quotes the failure that was seen, as what it is: possibly this creation's,
80
- * possibly not. What this costs: a creation that really failed is reported
81
- * after the timeout instead of at once.
82
- *
83
- * subscribe(listener) raw event subscription, returns unsubscribe
84
- * returns { result, identify(name), cancel(error?) }
85
- * result resolves { ok: true } or { ok: false, error, failureSeen? }
86
- */
87
- export function watchWorktree(subscribe, {
88
- timeoutMs = 60_000, setTimer = setTimeout, clearTimer = clearTimeout,
89
- } = {}) {
90
- let name = '';
91
- let done = false;
92
- let unsubscribe = () => {};
93
- let timer = null;
94
- let failure = ''; // the last unattributable worktree.failed message
95
- const readyNames = new Set(); // worktree.ready seen before identify()
96
- let resolveResult;
97
- const result = new Promise((resolve) => { resolveResult = resolve; });
98
-
99
- const finish = (outcome) => {
100
- if (done) return;
101
- done = true;
102
- if (timer) clearTimer(timer);
103
- try { unsubscribe(); } catch { /* already gone */ }
104
- resolveResult(outcome);
105
- };
106
-
107
- unsubscribe = subscribe((eventType, ev) => {
108
- if (done) return;
109
- if (eventType === 'worktree.ready') {
110
- const readyName = typeof ev?.name === 'string' ? ev.name : '';
111
- if (!readyName) return;
112
- if (!name) readyNames.add(readyName);
113
- else if (readyName === name) finish({ ok: true });
114
- } else if (eventType === 'worktree.failed') {
115
- failure = ev?.message || 'OpenCode could not prepare a worktree.';
116
- }
117
- });
118
- timer = setTimer(() => finish(worktreeTimeoutOutcome(failure)), timeoutMs);
119
-
120
- return {
121
- result,
122
- /** The create reply named the worktree: act on what was seen so far. */
123
- identify(worktreeName) {
124
- if (done || name) return;
125
- name = String(worktreeName || '');
126
- if (!name) { finish({ ok: false, error: 'OpenCode did not name the new worktree.' }); return; }
127
- if (readyNames.has(name)) finish({ ok: true });
128
- },
129
- cancel(error = 'Worktree creation was cancelled.') { finish({ ok: false, error }); },
130
- };
131
- }
132
-
133
- /** What the wait reports when no ready event for the worktree came in time. */
134
- export function worktreeTimeoutOutcome(failure) {
135
- if (!failure) return { ok: false, error: 'The worktree was not ready in time.' };
136
- return {
137
- ok: false,
138
- failureSeen: failure,
139
- error: `The worktree was not ready in time. OpenCode reported a worktree failure meanwhile, which may or may not be this one (the report names no worktree): ${failure}`,
140
- };
141
- }
142
-
143
- /**
144
- * Wait for the worktree called `name` (already known) to be ready.
145
- * Resolves { ok: true } on its worktree.ready, { ok: false, error } on a
146
- * failure or after `timeoutMs`.
147
- */
148
- export function waitForWorktree(subscribe, name, options = {}) {
149
- const watch = watchWorktree(subscribe, options);
150
- watch.identify(name);
151
- return watch.result;
152
- }
153
-
154
62
  // ── New-session dialog ──────────────────────────────────────────────────────
155
63
 
156
64
  /**
157
65
  * What "Save" in the new-session dialog does.
158
- * { project, branch, currentBranch, wantsWorktree, cwd }
159
- * → { worktree, checkout, projectChanged }
160
- * A session in a new worktree never touches the project's own checkout: the
161
- * worktree is created from what the project has checked out now (OpenCode's
162
- * worktree.create takes no base), so no branch is switched for it.
66
+ * { project, branch, currentBranch, cwd } → { checkout, projectChanged }
163
67
  */
164
- export function newSessionPlan({ project = '', branch = '', currentBranch = '', wantsWorktree = false, cwd = '' } = {}) {
165
- const worktree = !!wantsWorktree && !!project;
166
- const switchBranch = !worktree && !!project && !!branch && !!currentBranch && branch !== currentBranch;
68
+ export function newSessionPlan({ project = '', branch = '', currentBranch = '', cwd = '' } = {}) {
69
+ const switchBranch = !!project && !!branch && !!currentBranch && branch !== currentBranch;
167
70
  return {
168
- worktree,
169
71
  checkout: switchBranch ? { path: project, branch } : null,
170
72
  projectChanged: !!project && project !== (cwd || ''),
171
73
  };
@@ -20,6 +20,7 @@ import { state, emit } from '../state.js';
20
20
  import { injectStyles } from './ocp-v2-styles.js';
21
21
  import { getDefaultStore } from './ocp-v2-state.js';
22
22
  import { wireFileLinks } from '../ui-file-links.js';
23
+ import { frameRect } from '../app-frame.js';
23
24
  import { mountRenderer } from './ocp-v2-render.js';
24
25
  import { mountCompose } from './ocp-v2-send.js';
25
26
  import { trackContextGauge } from './ocp-v2-context-gauge.js';
@@ -205,6 +206,7 @@ export function createChildPanel({
205
206
  _contextGauge = trackContextGauge(store);
206
207
  _compactControl = createCompactControl(store);
207
208
  _contextMenu = mountContextMenu(actions, panel, store, {
209
+ bounds: frameRect, // the popover stays in the app frame
208
210
  compact: _compactControl,
209
211
  agent: () => _taskInfo?.subagentType || '',
210
212
  });
@@ -40,9 +40,7 @@ export function createCompactControl(store = getDefaultStore()) {
40
40
  const res = await api.compact({
41
41
  sessionId: at.sessionId,
42
42
  cwd: s.cwd || undefined,
43
- mcpProfile: s.mcpProfile || undefined,
44
- // OpenCode 1.18 compacts through session.summarize, which needs a model.
45
- model: s.model || undefined,
43
+ tools: s.tools || undefined,
46
44
  });
47
45
  if (at.isCurrent() && (res?.error || res?.ok === false)) {
48
46
  const msg = res?.error || res?.data?.error || 'Compact failed';
@@ -20,8 +20,6 @@ export const LOCAL_SLASH_COMMANDS = Object.freeze([
20
20
  { name: 'compact', description: 'Compact context', action: 'compact', aliases: ['summarize'] },
21
21
  { name: 'undo', description: 'Undo the last prompt', action: 'undo', needs: ['session:revert'] },
22
22
  { name: 'redo', description: 'Restore what was undone', action: 'redo', needs: ['session:unrevert'] },
23
- { name: 'share', description: 'Share this session (public link)', action: 'share', needs: ['session:share', 'session:unshare'] },
24
- { name: 'unshare', description: 'Stop sharing this session', action: 'unshare', needs: ['session:share', 'session:unshare'] },
25
23
  { name: 'export', description: 'Export the transcript as JSON', action: 'export' },
26
24
  { name: 'fork', description: 'Fork this session', action: 'fork', needs: ['session:fork'] },
27
25
  { name: 'models', description: 'Pick a model', action: 'models' },
@@ -49,9 +47,8 @@ const SERVER_SOURCES = new Set(['command', 'skill', 'mcp']);
49
47
  * legacy { skills, userCommands } from the pre-SDK REST lists, used
50
48
  * only when serverCommands is null
51
49
  * supports(type) capability check
52
- * sharePolicy OpenCode's `share` setting; 'disabled' removes /share and /unshare
53
50
  */
54
- export function buildSlashCatalog({ serverCommands = null, legacy = null, supports = () => false, sharePolicy = null } = {}) {
51
+ export function buildSlashCatalog({ serverCommands = null, legacy = null, supports = () => false } = {}) {
55
52
  const out = [];
56
53
  const seen = new Set();
57
54
  const add = (entry) => {
@@ -62,7 +59,6 @@ export function buildSlashCatalog({ serverCommands = null, legacy = null, suppor
62
59
  };
63
60
  for (const cmd of LOCAL_SLASH_COMMANDS) {
64
61
  if ((cmd.needs || []).some((type) => !supports(type))) continue;
65
- if (sharePolicy === 'disabled' && (cmd.action === 'share' || cmd.action === 'unshare')) continue;
66
62
  add({ name: cmd.name, description: cmd.description, aliases: cmd.aliases || [], source: 'builtin', kind: 'local', action: cmd.action });
67
63
  }
68
64
  const canRun = supports('command:run');
@@ -153,7 +149,7 @@ export function helpCardView({ catalog = [], supports = () => false, canAct = tr
153
149
  name: 'Enter',
154
150
  text: 'While a turn runs, Enter queues the prompt. The queue is listed above the box and sent in order when the turn ends; after a failed turn it waits for Resume.',
155
151
  }] });
156
- const mine = ['Copy', canAct && supports('session:revert') && 'Undo to here', canAct && supports('session:fork') && 'Fork from here', canAct && supports('message:delete') && 'Delete'].filter(Boolean);
152
+ const mine = ['Copy', canAct && supports('session:revert') && 'Undo to here', canAct && supports('session:fork') && 'Fork from here'].filter(Boolean);
157
153
  const replies = ['Copy', canAct && supports('session:revert') && 'Retry'].filter(Boolean);
158
154
  sections.push({ title: 'Message actions', rows: [
159
155
  { name: 'Your prompts', text: `Hover one: ${mine.join(', ')}.` },
@@ -12,7 +12,7 @@
12
12
  // every render reads the store again.
13
13
  // ─────────────────────────────────────────────────────────────────────────────
14
14
 
15
- import { api, supports, onEvent, sdkVersion } from './ocp-v2-ws.js';
15
+ import { api, supports, onEvent } from './ocp-v2-ws.js';
16
16
  import { getDefaultStore } from './ocp-v2-state.js';
17
17
  import { replyFailed, replyError } from './ocp-v2-caps.js';
18
18
  import { boundReader, onRebind } from './ocp-v2-binding.js';
@@ -199,6 +199,7 @@ function turnsOf(s) {
199
199
  * opts.onManage() opens the MCP manager; without it there is no "Manage"
200
200
  * opts.onOpen() the popover is about to open (the panel closes its other menus)
201
201
  * opts.agent() the agent this panel's session runs as, when the panel knows better than the store
202
+ * opts.bounds() the area the popover stays in ({ left, top, right, bottom }: the app frame); the window without it
202
203
  * Returns { element, open(), close({ focus }), isOpen(), sync(), destroy() }.
203
204
  */
204
205
  export function mountContextMenu(actionsEl, panelEl, store = getDefaultStore(), opts = {}) {
@@ -244,7 +245,6 @@ export function mountContextMenu(actionsEl, panelEl, store = getDefaultStore(),
244
245
  // A sub-agent's store hears the version only on a status change; the
245
246
  // main one has it from init, and there is one OpenCode behind both.
246
247
  serverVersion: s.serverVersion || getDefaultStore().getState().serverVersion || '',
247
- sdkVersion: sdkVersion(),
248
248
  updateAvailable: updateAvailableVersion(),
249
249
  sessionId: s.sessionId || '',
250
250
  folder: s.cwd || s.sessionInfo?.directory || '',
@@ -278,23 +278,23 @@ export function mountContextMenu(actionsEl, panelEl, store = getDefaultStore(),
278
278
  }
279
279
 
280
280
  // Below the cog, its right edge on the cog's; above it when there is more room
281
- // there; always inside the viewport, scrolling inside when it is taller.
281
+ // there; always inside the app frame, scrolling inside when it is taller.
282
282
  function place() {
283
283
  if (!open || !pop) return;
284
284
  const r = cog.getBoundingClientRect();
285
- const vw = window.innerWidth;
286
- const vh = window.innerHeight;
287
- const width = Math.max(0, Math.min(WIDTH, vw - MARGIN * 2));
285
+ // Inside the area the panel names (the app frame), else the window
286
+ const f = opts.bounds?.() || { left: 0, top: 0, right: window.innerWidth, bottom: window.innerHeight, width: window.innerWidth };
287
+ const width = Math.max(0, Math.min(WIDTH, f.width - MARGIN * 2));
288
288
  pop.style.width = `${width}px`;
289
- const below = vh - r.bottom - GAP - MARGIN;
290
- const above = r.top - GAP - MARGIN;
289
+ const below = f.bottom - r.bottom - GAP - MARGIN;
290
+ const above = r.top - f.top - GAP - MARGIN;
291
291
  const up = below < 220 && above > below;
292
292
  pop.style.maxHeight = `${Math.max(120, up ? above : below)}px`;
293
293
  const height = pop.offsetHeight;
294
- const left = Math.max(MARGIN, Math.min(r.right - width, vw - width - MARGIN));
294
+ const left = Math.max(f.left + MARGIN, Math.min(r.right - width, f.right - width - MARGIN));
295
295
  const top = up
296
- ? Math.max(MARGIN, r.top - GAP - height)
297
- : Math.max(MARGIN, Math.min(r.bottom + GAP, vh - MARGIN - height));
296
+ ? Math.max(f.top + MARGIN, r.top - GAP - height)
297
+ : Math.max(f.top + MARGIN, Math.min(r.bottom + GAP, f.bottom - MARGIN - height));
298
298
  pop.style.left = `${Math.round(left)}px`;
299
299
  pop.style.top = `${Math.round(top)}px`;
300
300
  // Once it has its width: only now is a cut value known.
@@ -143,9 +143,6 @@ export function contextMenuModel(d = {}) {
143
143
  const notice = updateNoticeText(d.updateAvailable, d.serverVersion);
144
144
  const versions = [['OpenCode', d.serverVersion ? String(d.serverVersion) : NOT_REPORTED]];
145
145
  if (notice) versions.push(['Update', `${String(d.updateAvailable).replace(/^v/i, '')} available`, notice]);
146
- versions.push(d.sdkVersion
147
- ? ['OpenCode SDK', String(d.sdkVersion), '@opencode-ai/sdk, the client SynaBun talks to OpenCode through']
148
- : ['OpenCode SDK', NOT_REPORTED, d.serverVersion ? 'Restart SynaBun to see the SDK version here.' : '']);
149
146
 
150
147
  const sessionId = d.sessionId ? String(d.sessionId) : '';
151
148
  const sessionRows = [
@@ -1,3 +1,4 @@
1
+ import { toolWord } from '../tool-list-picker.js';
1
2
  // ─────────────────────────────────────────────────────────────────────────────
2
3
  // OpenCode V2 — events → store (no DOM, no socket)
3
4
  // One function per concern so node:test can drive them with a real store:
@@ -188,12 +189,15 @@ export function applyEvent(store, eventType, ev = {}, hooks = {}) {
188
189
  case 'session.diff':
189
190
  store.setSessionDiff(ev.diff);
190
191
  break;
191
- case 'mcp.profile.changed':
192
- store.setMcpProfile(ev.profile || null);
192
+ case 'synabun.mcp.status':
193
+ if (ev.text) store.pushError({ message: ev.text, notice: true });
193
194
  break;
194
- case 'mcp.profile.refresh.failed':
195
+ case 'mcp.tools.changed':
196
+ store.setTools(ev.tools ?? null);
197
+ break;
198
+ case 'mcp.tools.refresh.failed':
195
199
  store.pushError({
196
- message: ev.error || `MCP profile changed to ${ev.profile || 'the requested profile'}, but OpenCode could not reload its tools.`,
200
+ message: ev.error || toolWord('reloadFailed'),
197
201
  raw: ev,
198
202
  });
199
203
  break;
@@ -28,7 +28,7 @@ import { on } from '../state.js';
28
28
  import { setSidepanelVisible } from '../ui-sidepanel-windows.js';
29
29
  import { createPanelStore } from './ocp-v2-state.js';
30
30
  import { createChildPanel } from './ocp-v2-childpanel.js';
31
- import { inheritChildPanelMcpProfile } from './ocp-v2-profile-inheritance.js';
31
+ import { inheritChildPanelTools } from './ocp-v2-tools-inheritance.js';
32
32
  import { notify as uiNotify, NOTIF_TYPE } from '../ui-notifications.js';
33
33
  import {
34
34
  isAutomationSession, onAutomationSessionRegistered, shouldMaterializeChildPanel,
@@ -513,12 +513,12 @@ function parentTitleFor(reg, parentSid) {
513
513
  } catch { return 'parent'; }
514
514
  }
515
515
 
516
- // The tool profile the user chose for a session (the project bar saves it
516
+ // The tool list the user chose for a session (the project bar saves it
517
517
  // under this key): what a sub-agent of a session that is not on screen inherits.
518
- const MCP_SESSION_PROFILE_KEY = 'synabun-opencode-session-mcp-profiles';
519
- function savedSessionProfile(sessionId) {
518
+ const MCP_SESSION_TOOLS_KEY = 'synabun-opencode-session-tools';
519
+ function savedSessionTools(sessionId) {
520
520
  try {
521
- const parsed = JSON.parse(storage.getItem(MCP_SESSION_PROFILE_KEY) || '{}');
521
+ const parsed = JSON.parse(storage.getItem(MCP_SESSION_TOOLS_KEY) || '{}');
522
522
  return (parsed && typeof parsed === 'object' && parsed[sessionId]) || null;
523
523
  } catch { return null; }
524
524
  }
@@ -529,8 +529,8 @@ function spawnChildPanel({ childSessionId, childInfo, parentPanelId, parentSessi
529
529
  store.setSession(childSessionId, childInfo || null);
530
530
  store.setParentSession(parentSessionId, parentPanelId);
531
531
  // The parent's profile: the primary store's only while it is bound to that
532
- // parent (see inheritChildPanelMcpProfile).
533
- inheritChildPanelMcpProfile(store, _primary?.store, childInfo, { parentSessionId, savedProfile: savedSessionProfile });
532
+ // parent (see inheritChildPanelTools).
533
+ inheritChildPanelTools(store, _primary?.store, childInfo, { parentSessionId, savedTools: savedSessionTools });
534
534
 
535
535
  const wsUnsub = subscribeSession(childSessionId, store);
536
536
 
@@ -0,0 +1,16 @@
1
+ // Running is a display hint: tool activity, replay and automation reattachment
2
+ // can all set it. Only a new prompt gives completion notifications a new owner.
3
+ export function createOutcomeNotifications() {
4
+ const outcomes = new Map();
5
+ return {
6
+ take(state, type) {
7
+ const prompt = [...(state.messageOrder || [])].reverse().find(id => state.messages?.get(id)?.role === 'user');
8
+ const key = `${state.sessionId || ''}:${prompt || ''}`;
9
+ const last = outcomes.get(key);
10
+ if (last === type || (last === 'error' && type === 'done')) return false;
11
+ outcomes.set(key, type);
12
+ if (outcomes.size > 200) outcomes.delete(outcomes.keys().next().value);
13
+ return true;
14
+ },
15
+ };
16
+ }