synabun 2.0.9 → 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 (679) hide show
  1. package/CHANGELOG.md +115 -0
  2. package/README.md +25 -2
  3. package/THIRD-PARTY-LICENSES.md +68 -4
  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/launcher.mjs +9 -3
  10. package/lib/claude-hooks.js +172 -18
  11. package/lib/client-config-repair.js +17 -8
  12. package/lib/desktop-app.js +7 -1
  13. package/lib/external-tools.js +1 -1
  14. package/lib/first-launch-protection.js +57 -12
  15. package/lib/mcp-dist.js +176 -0
  16. package/lib/release-npm-ci.mjs +138 -0
  17. package/lib/release-publish.mjs +91 -0
  18. package/lib/release-scan.mjs +50 -0
  19. package/lib/server-crash-record.js +123 -0
  20. package/lib/server-exit.js +318 -0
  21. package/lib/server-supervisor.js +508 -0
  22. package/lib/start-launcher.js +43 -5
  23. package/lib/tools-cli.js +45 -0
  24. package/lib/update-snapshot.js +228 -0
  25. package/lib/virustotal.mjs +192 -0
  26. package/lib/windows-crash-event.js +269 -0
  27. package/mcp-server/dist/http.d.ts +20 -1
  28. package/mcp-server/dist/http.d.ts.map +1 -1
  29. package/mcp-server/dist/http.js +59 -12
  30. package/mcp-server/dist/http.js.map +1 -1
  31. package/mcp-server/dist/index.d.ts +33 -27
  32. package/mcp-server/dist/index.d.ts.map +1 -1
  33. package/mcp-server/dist/index.js +128 -143
  34. package/mcp-server/dist/index.js.map +1 -1
  35. package/mcp-server/dist/preload.js +1 -1
  36. package/mcp-server/dist/preload.js.map +1 -1
  37. package/mcp-server/dist/services/codex-config-heal.d.ts +6 -2
  38. package/mcp-server/dist/services/codex-config-heal.d.ts.map +1 -1
  39. package/mcp-server/dist/services/codex-config-heal.js +81 -28
  40. package/mcp-server/dist/services/codex-config-heal.js.map +1 -1
  41. package/mcp-server/dist/services/memory-judge-backfill.d.ts +6 -0
  42. package/mcp-server/dist/services/memory-judge-backfill.d.ts.map +1 -1
  43. package/mcp-server/dist/services/memory-judge-backfill.js +7 -1
  44. package/mcp-server/dist/services/memory-judge-backfill.js.map +1 -1
  45. package/mcp-server/dist/services/neural-interface.d.ts +16 -10
  46. package/mcp-server/dist/services/neural-interface.d.ts.map +1 -1
  47. package/mcp-server/dist/services/neural-interface.js +67 -11
  48. package/mcp-server/dist/services/neural-interface.js.map +1 -1
  49. package/mcp-server/dist/services/server-instructions.d.ts +7 -2
  50. package/mcp-server/dist/services/server-instructions.d.ts.map +1 -1
  51. package/mcp-server/dist/services/server-instructions.js +20 -62
  52. package/mcp-server/dist/services/server-instructions.js.map +1 -1
  53. package/mcp-server/dist/services/tool-catalog.d.ts +120 -0
  54. package/mcp-server/dist/services/tool-catalog.d.ts.map +1 -0
  55. package/mcp-server/dist/services/tool-catalog.js +339 -0
  56. package/mcp-server/dist/services/tool-catalog.js.map +1 -0
  57. package/mcp-server/dist/services/tool-list-refresh-barrier.d.ts +12 -0
  58. package/mcp-server/dist/services/tool-list-refresh-barrier.d.ts.map +1 -0
  59. package/mcp-server/dist/services/tool-list-refresh-barrier.js +40 -0
  60. package/mcp-server/dist/services/tool-list-refresh-barrier.js.map +1 -0
  61. package/mcp-server/dist/services/tool-list.d.ts +108 -0
  62. package/mcp-server/dist/services/tool-list.d.ts.map +1 -0
  63. package/mcp-server/dist/services/tool-list.js +334 -0
  64. package/mcp-server/dist/services/tool-list.js.map +1 -0
  65. package/mcp-server/dist/services/tool-runtime.d.ts +161 -0
  66. package/mcp-server/dist/services/tool-runtime.d.ts.map +1 -0
  67. package/mcp-server/dist/services/tool-runtime.js +400 -0
  68. package/mcp-server/dist/services/tool-runtime.js.map +1 -0
  69. package/mcp-server/dist/services/whiteboard-geometry.d.ts +26 -2
  70. package/mcp-server/dist/services/whiteboard-geometry.d.ts.map +1 -1
  71. package/mcp-server/dist/services/whiteboard-geometry.js +91 -8
  72. package/mcp-server/dist/services/whiteboard-geometry.js.map +1 -1
  73. package/mcp-server/dist/tools/agents.d.ts +10 -10
  74. package/mcp-server/dist/tools/agents.d.ts.map +1 -1
  75. package/mcp-server/dist/tools/agents.js +22 -13
  76. package/mcp-server/dist/tools/agents.js.map +1 -1
  77. package/mcp-server/dist/tools/browser-batch.d.ts +3 -3
  78. package/mcp-server/dist/tools/image-tools.d.ts +1 -1
  79. package/mcp-server/dist/tools/image-tools.js +1 -1
  80. package/mcp-server/dist/tools/skill-tools.d.ts +505 -0
  81. package/mcp-server/dist/tools/skill-tools.d.ts.map +1 -0
  82. package/mcp-server/dist/tools/skill-tools.js +639 -0
  83. package/mcp-server/dist/tools/skill-tools.js.map +1 -0
  84. package/mcp-server/dist/tools/skill.d.ts +7 -0
  85. package/mcp-server/dist/tools/skill.d.ts.map +1 -0
  86. package/mcp-server/dist/tools/skill.js +11 -0
  87. package/mcp-server/dist/tools/skill.js.map +1 -0
  88. package/mcp-server/dist/tools/tool-groups.d.ts +68 -0
  89. package/mcp-server/dist/tools/tool-groups.d.ts.map +1 -0
  90. package/mcp-server/dist/tools/tool-groups.js +147 -0
  91. package/mcp-server/dist/tools/tool-groups.js.map +1 -0
  92. package/mcp-server/dist/tools/whiteboard-format.d.ts.map +1 -1
  93. package/mcp-server/dist/tools/whiteboard-format.js +7 -4
  94. package/mcp-server/dist/tools/whiteboard-format.js.map +1 -1
  95. package/mcp-server/dist/tools/whiteboard-tools.d.ts +64 -13
  96. package/mcp-server/dist/tools/whiteboard-tools.d.ts.map +1 -1
  97. package/mcp-server/dist/tools/whiteboard-tools.js +30 -5
  98. package/mcp-server/dist/tools/whiteboard-tools.js.map +1 -1
  99. package/mcp-server/package-lock.json +2 -2
  100. package/mcp-server/package.json +1 -1
  101. package/mcp-server/src/http.ts +75 -12
  102. package/mcp-server/src/index.ts +147 -154
  103. package/mcp-server/src/preload.ts +12 -12
  104. package/mcp-server/src/services/codex-config-heal.ts +80 -29
  105. package/mcp-server/src/services/memory-judge-backfill.ts +7 -1
  106. package/mcp-server/src/services/neural-interface.ts +79 -20
  107. package/mcp-server/src/services/server-instructions.ts +27 -63
  108. package/mcp-server/src/services/tool-catalog.ts +403 -0
  109. package/mcp-server/src/services/tool-list-refresh-barrier.ts +33 -0
  110. package/mcp-server/src/services/tool-list.ts +410 -0
  111. package/mcp-server/src/services/tool-runtime.ts +457 -0
  112. package/mcp-server/src/services/whiteboard-geometry.ts +94 -9
  113. package/mcp-server/src/tools/agents.ts +22 -14
  114. package/mcp-server/src/tools/image-tools.ts +1 -1
  115. package/mcp-server/src/tools/skill-tools.ts +589 -0
  116. package/mcp-server/src/tools/skill.ts +13 -0
  117. package/mcp-server/src/tools/tool-groups.ts +164 -0
  118. package/mcp-server/src/tools/whiteboard-format.ts +9 -3
  119. package/mcp-server/src/tools/whiteboard-tools.ts +39 -5
  120. package/neural-interface/i18n/en.json +3680 -206
  121. package/neural-interface/i18n/pt-BR.json +3628 -157
  122. package/neural-interface/lib/account-usage.js +5 -3
  123. package/neural-interface/lib/app-controls-api.js +161 -0
  124. package/neural-interface/lib/assistant-api.js +148 -35
  125. package/neural-interface/lib/assistant-brains/claude.js +4 -3
  126. package/neural-interface/lib/assistant-brains/codex-browser-policy-hook.mjs +12 -2
  127. package/neural-interface/lib/assistant-brains/codex-route-gate-hook.mjs +32 -9
  128. package/neural-interface/lib/assistant-brains/codex.js +9 -5
  129. package/neural-interface/lib/assistant-brains/opencode.js +122 -44
  130. package/neural-interface/lib/assistant-brains/opencode2-browser-policy/index.js +59 -0
  131. package/neural-interface/lib/assistant-brains/opencode2-route-gate/index.js +97 -0
  132. package/neural-interface/lib/assistant-catalog.js +23 -9
  133. package/neural-interface/lib/assistant-dispatch.js +874 -156
  134. package/neural-interface/lib/assistant-envelope.js +22 -2
  135. package/neural-interface/lib/assistant-persona.js +80 -11
  136. package/neural-interface/lib/assistant-plan-permissions.js +10 -9
  137. package/neural-interface/lib/assistant-route-gate-codex.js +3 -0
  138. package/neural-interface/lib/assistant-route-gate.js +6 -4
  139. package/neural-interface/lib/assistant-router.js +13 -8
  140. package/neural-interface/lib/assistant-runtime.js +183 -26
  141. package/neural-interface/lib/assistant-task-prompt.js +78 -14
  142. package/neural-interface/lib/assistant-tools.js +51 -0
  143. package/neural-interface/lib/backup-service.js +620 -3
  144. package/neural-interface/lib/backup-zip-reader.js +10 -5
  145. package/neural-interface/lib/backup-zip-writer.js +257 -0
  146. package/neural-interface/lib/browser-execution.js +10 -2
  147. package/neural-interface/lib/browser-guard-cdp.js +83 -0
  148. package/neural-interface/lib/browser-network-guard.js +284 -0
  149. package/neural-interface/lib/browser-policy-roots.js +64 -0
  150. package/neural-interface/lib/browser-tool-policy.js +186 -31
  151. package/neural-interface/lib/claude-agent-bridge.js +4 -2
  152. package/neural-interface/lib/claude-hooks-status.js +103 -0
  153. package/neural-interface/lib/claude-model-catalog.js +64 -14
  154. package/neural-interface/lib/claude-temporary.js +5 -11
  155. package/neural-interface/lib/cli-install.js +18 -138
  156. package/neural-interface/lib/cli-resolver.js +4 -1
  157. package/neural-interface/lib/cli-update-planner.js +32 -31
  158. package/neural-interface/lib/cloudflared/tunnel.js +42 -2
  159. package/neural-interface/lib/codex-mcp-approvals.js +11 -0
  160. package/neural-interface/lib/codex-settings-schema.js +109 -47
  161. package/neural-interface/lib/codex-worker-app-server.js +172 -0
  162. package/neural-interface/lib/confined-fs.js +30 -3
  163. package/neural-interface/lib/crash-notice-api.js +98 -0
  164. package/neural-interface/lib/editor-completion-opencode.js +164 -67
  165. package/neural-interface/lib/exec-loop-command.js +4 -1
  166. package/neural-interface/lib/http-guards.js +8 -2
  167. package/neural-interface/lib/install-details.js +4 -1
  168. package/neural-interface/lib/launch-cache.js +293 -0
  169. package/neural-interface/lib/login-start.js +524 -0
  170. package/neural-interface/lib/mcp-agent-servers.js +67 -0
  171. package/neural-interface/lib/mcp-client-config.js +0 -29
  172. package/neural-interface/lib/mcp-external-servers.js +323 -0
  173. package/neural-interface/lib/{mcp-profile-refresh-coordinator.js → mcp-tools-refresh-coordinator.js} +4 -4
  174. package/neural-interface/lib/morelogin.js +30 -0
  175. package/neural-interface/lib/native-loop-providers.js +565 -50
  176. package/neural-interface/lib/native-loop-runtime.js +287 -41
  177. package/neural-interface/lib/opencode-config.js +557 -0
  178. package/neural-interface/lib/opencode-db-schema.js +58 -0
  179. package/neural-interface/lib/opencode-history.js +49 -204
  180. package/neural-interface/lib/opencode-mcp-ready.js +108 -0
  181. package/neural-interface/lib/opencode-native-boundary.js +44 -0
  182. package/neural-interface/lib/opencode-protocol.js +310 -0
  183. package/neural-interface/lib/opencode-provider-view.js +81 -0
  184. package/neural-interface/lib/opencode-runtime-config.js +32 -15
  185. package/neural-interface/lib/opencode-serve-records.js +624 -0
  186. package/neural-interface/lib/opencode-v2-client.js +53 -131
  187. package/neural-interface/lib/opencode-v2-ws-requests.js +35 -195
  188. package/neural-interface/lib/opencode-worker-activity.js +229 -0
  189. package/neural-interface/lib/opencode-worker-data.js +27 -0
  190. package/neural-interface/lib/opencode2-client.js +796 -0
  191. package/neural-interface/lib/opencode2-proxy.js +76 -0
  192. package/neural-interface/lib/opencode2-translate.js +1057 -0
  193. package/neural-interface/lib/owner-authority.js +249 -0
  194. package/neural-interface/lib/page-session.js +275 -0
  195. package/neural-interface/lib/peer-identity.js +763 -0
  196. package/neural-interface/lib/process-identity.js +361 -0
  197. package/neural-interface/lib/request-gate.js +17 -2
  198. package/neural-interface/lib/rulesets/api.js +1 -1
  199. package/neural-interface/lib/rulesets/fs-safe.js +1 -1
  200. package/neural-interface/lib/rulesets/installer.js +92 -27
  201. package/neural-interface/lib/rulesets/json-edit.js +1 -1
  202. package/neural-interface/lib/session-cache-builder.js +18 -10
  203. package/neural-interface/lib/session-title-generator.js +58 -18
  204. package/neural-interface/lib/skills/api-v2.js +495 -0
  205. package/neural-interface/lib/skills/bundle.js +418 -0
  206. package/neural-interface/lib/skills/catalog.js +294 -0
  207. package/neural-interface/lib/skills/creation-api.js +191 -0
  208. package/neural-interface/lib/skills/creation-brief.js +247 -0
  209. package/neural-interface/lib/skills/creation-sources.js +267 -0
  210. package/neural-interface/lib/skills/creation.js +843 -0
  211. package/neural-interface/lib/skills/deploy.js +564 -0
  212. package/neural-interface/lib/skills/digest.js +119 -0
  213. package/neural-interface/lib/skills/discover.js +111 -0
  214. package/neural-interface/lib/skills/draft-confinement.js +214 -0
  215. package/neural-interface/lib/skills/eval-confinement.js +397 -0
  216. package/neural-interface/lib/skills/eval-sandbox.js +280 -0
  217. package/neural-interface/lib/skills/eval-trace.js +119 -0
  218. package/neural-interface/lib/skills/evals-api.js +212 -0
  219. package/neural-interface/lib/skills/evals.js +1573 -0
  220. package/neural-interface/lib/skills/export.js +200 -0
  221. package/neural-interface/lib/skills/frontmatter.js +64 -0
  222. package/neural-interface/lib/skills/health.js +75 -0
  223. package/neural-interface/lib/skills/json-edit.js +165 -0
  224. package/neural-interface/lib/skills/known-bridge-digests.json +387 -0
  225. package/neural-interface/lib/skills/known-bridges.js +96 -0
  226. package/neural-interface/lib/skills/library.js +823 -0
  227. package/neural-interface/lib/skills/local-store.js +21 -0
  228. package/neural-interface/lib/skills/migration.js +433 -0
  229. package/neural-interface/lib/skills/operations.js +45 -0
  230. package/neural-interface/lib/skills/ownership.js +427 -0
  231. package/neural-interface/lib/skills/packages.js +88 -0
  232. package/neural-interface/lib/skills/reviews.js +212 -0
  233. package/neural-interface/lib/skills/revision.js +80 -0
  234. package/neural-interface/lib/skills/roots.js +262 -0
  235. package/neural-interface/lib/skills/runtime-checks.js +355 -0
  236. package/neural-interface/lib/skills/scan-assets.js +252 -0
  237. package/neural-interface/lib/skills/scan-context.js +26 -0
  238. package/neural-interface/lib/skills/scan-shell.js +324 -0
  239. package/neural-interface/lib/skills/scan.js +364 -0
  240. package/neural-interface/lib/skills/scanners.js +54 -0
  241. package/neural-interface/lib/skills/service.js +522 -0
  242. package/neural-interface/lib/skills/telemetry.js +113 -0
  243. package/neural-interface/lib/sqlite-integrity-worker.js +22 -0
  244. package/neural-interface/lib/style-guide/api.js +4 -3
  245. package/neural-interface/lib/tool-lists.js +124 -0
  246. package/neural-interface/lib/untrusted-file-headers.js +27 -0
  247. package/neural-interface/lib/whatsapp/bridge.js +6 -3
  248. package/neural-interface/lib/worker-confinement.js +1192 -0
  249. package/neural-interface/lib/worker-guard-setting.js +56 -0
  250. package/neural-interface/lib/worker-mcp-channel.js +175 -0
  251. package/neural-interface/lib/worker-relay-ports.js +227 -0
  252. package/neural-interface/lib/worker-resume.js +229 -0
  253. package/neural-interface/lib/worker-sandbox.js +299 -0
  254. package/neural-interface/package-lock.json +1354 -50
  255. package/neural-interface/package.json +6 -2
  256. package/neural-interface/public/index.html +5 -3
  257. package/neural-interface/public/index2d.html +19 -11
  258. package/neural-interface/public/onboarding.html +2 -2
  259. package/neural-interface/public/shared/account-menu.js +8 -5
  260. package/neural-interface/public/shared/agent-runtime-options.js +76 -16
  261. package/neural-interface/public/shared/api.js +1527 -1336
  262. package/neural-interface/public/shared/app-frame.js +192 -0
  263. package/neural-interface/public/shared/assistant/asst-agents-dock.js +205 -19
  264. package/neural-interface/public/shared/assistant/asst-api.js +11 -3
  265. package/neural-interface/public/shared/assistant/asst-ask-styles.js +270 -0
  266. package/neural-interface/public/shared/assistant/asst-ask-tail.js +118 -0
  267. package/neural-interface/public/shared/assistant/asst-ask.js +397 -0
  268. package/neural-interface/public/shared/assistant/asst-brain-picker.js +241 -112
  269. package/neural-interface/public/shared/assistant/asst-composer.js +1 -1
  270. package/neural-interface/public/shared/assistant/asst-control.js +157 -26
  271. package/neural-interface/public/shared/assistant/asst-followups-card.js +383 -0
  272. package/neural-interface/public/shared/assistant/asst-followups.js +417 -0
  273. package/neural-interface/public/shared/assistant/asst-hosts.js +49 -2
  274. package/neural-interface/public/shared/assistant/asst-limit-dock.js +40 -0
  275. package/neural-interface/public/shared/assistant/asst-limit-wait.js +294 -0
  276. package/neural-interface/public/shared/assistant/asst-limit.js +168 -0
  277. package/neural-interface/public/shared/assistant/asst-mascot.js +49 -12
  278. package/neural-interface/public/shared/assistant/asst-menu.js +84 -12
  279. package/neural-interface/public/shared/assistant/asst-panel.js +303 -44
  280. package/neural-interface/public/shared/assistant/asst-rack-styles.js +93 -58
  281. package/neural-interface/public/shared/assistant/asst-redact.js +186 -0
  282. package/neural-interface/public/shared/assistant/asst-render.js +770 -100
  283. package/neural-interface/public/shared/assistant/asst-route.js +83 -12
  284. package/neural-interface/public/shared/assistant/asst-run-stage.js +231 -0
  285. package/neural-interface/public/shared/assistant/asst-sanitize.js +193 -3
  286. package/neural-interface/public/shared/assistant/asst-scene-styles.js +273 -0
  287. package/neural-interface/public/shared/assistant/asst-scenes.js +530 -0
  288. package/neural-interface/public/shared/assistant/asst-sidepanel-styles.js +3 -15
  289. package/neural-interface/public/shared/assistant/asst-sidepanel.js +67 -4
  290. package/neural-interface/public/shared/assistant/asst-slash.js +9 -7
  291. package/neural-interface/public/shared/assistant/asst-state.js +25 -15
  292. package/neural-interface/public/shared/assistant/asst-stop.js +127 -0
  293. package/neural-interface/public/shared/assistant/asst-styles.js +102 -21
  294. package/neural-interface/public/shared/assistant/asst-tool-kinds.js +165 -13
  295. package/neural-interface/public/shared/automation-context.js +5 -2
  296. package/neural-interface/public/shared/cc-dropdown.js +550 -0
  297. package/neural-interface/public/shared/cdx/cdx-context-menu.js +10 -9
  298. package/neural-interface/public/shared/cdx/cdx-copy.js +16 -0
  299. package/neural-interface/public/shared/cdx/cdx-output-model.js +22 -1
  300. package/neural-interface/public/shared/cdx/cdx-output.js +8 -7
  301. package/neural-interface/public/shared/cdx/cdx-panel.js +58 -150
  302. package/neural-interface/public/shared/cdx/cdx-protocol.js +28 -1
  303. package/neural-interface/public/shared/cdx/cdx-render.js +62 -32
  304. package/neural-interface/public/shared/cdx/cdx-requests.js +3 -3
  305. package/neural-interface/public/shared/cdx/cdx-skill-hints.js +54 -0
  306. package/neural-interface/public/shared/cdx/cdx-styles.js +15 -3
  307. package/neural-interface/public/shared/cdx/cdx-tabs.js +201 -74
  308. package/neural-interface/public/shared/cdx/cdx-ws.js +0 -1
  309. package/neural-interface/public/shared/cli-install-view.js +4 -8
  310. package/neural-interface/public/shared/cli-status.js +2 -2
  311. package/neural-interface/public/shared/constants.js +2 -2
  312. package/neural-interface/public/shared/context-menu-areas.js +34 -0
  313. package/neural-interface/public/shared/context-menu-logic.js +243 -0
  314. package/neural-interface/public/shared/context-menu-model.js +366 -0
  315. package/neural-interface/public/shared/context-menu.js +372 -0
  316. package/neural-interface/public/shared/cp/cp-context-menu.js +10 -9
  317. package/neural-interface/public/shared/cp/cp-markdown.js +4 -57
  318. package/neural-interface/public/shared/crash-notice-view.js +168 -0
  319. package/neural-interface/public/shared/data-cache.js +223 -0
  320. package/neural-interface/public/shared/desktop-bridge.js +11 -0
  321. package/neural-interface/public/shared/desktop-titlebar-view.js +78 -1
  322. package/neural-interface/public/shared/desktop-titlebar.js +214 -28
  323. package/neural-interface/public/shared/desktop-update-view.js +35 -5
  324. package/neural-interface/public/shared/editor/editor-panel-logic.js +2 -2
  325. package/neural-interface/public/shared/file-links.js +73 -8
  326. package/neural-interface/public/shared/html-shell.js +78 -86
  327. package/neural-interface/public/shared/i18n.js +2 -0
  328. package/neural-interface/public/shared/launch-prefetch.js +59 -0
  329. package/neural-interface/public/shared/ocp-v2/ocp-v2-approvals.js +7 -7
  330. package/neural-interface/public/shared/ocp-v2/ocp-v2-binding.js +4 -4
  331. package/neural-interface/public/shared/ocp-v2/ocp-v2-caps.js +3 -2
  332. package/neural-interface/public/shared/ocp-v2/ocp-v2-changes-logic.js +3 -101
  333. package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +9 -2
  334. package/neural-interface/public/shared/ocp-v2/ocp-v2-compact-button.js +1 -3
  335. package/neural-interface/public/shared/ocp-v2/ocp-v2-composer-logic.js +2 -6
  336. package/neural-interface/public/shared/ocp-v2/ocp-v2-context-menu.js +11 -11
  337. package/neural-interface/public/shared/ocp-v2/ocp-v2-context-model.js +0 -3
  338. package/neural-interface/public/shared/ocp-v2/ocp-v2-events.js +8 -4
  339. package/neural-interface/public/shared/ocp-v2/ocp-v2-manager.js +7 -7
  340. package/neural-interface/public/shared/ocp-v2/ocp-v2-modelpicker.js +54 -17
  341. package/neural-interface/public/shared/ocp-v2/ocp-v2-outcome-notifications.js +16 -0
  342. package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +140 -254
  343. package/neural-interface/public/shared/ocp-v2/ocp-v2-plan.js +1 -2
  344. package/neural-interface/public/shared/ocp-v2/ocp-v2-projectbar.js +97 -203
  345. package/neural-interface/public/shared/ocp-v2/ocp-v2-providers.js +11 -9
  346. package/neural-interface/public/shared/ocp-v2/ocp-v2-rehydrate.js +15 -4
  347. package/neural-interface/public/shared/ocp-v2/ocp-v2-render.js +7 -22
  348. package/neural-interface/public/shared/ocp-v2/ocp-v2-send-logic.js +401 -0
  349. package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +20 -13
  350. package/neural-interface/public/shared/ocp-v2/ocp-v2-session-actions.js +8 -61
  351. package/neural-interface/public/shared/ocp-v2/ocp-v2-sessions-logic.js +53 -82
  352. package/neural-interface/public/shared/ocp-v2/ocp-v2-slash-hints.js +16 -15
  353. package/neural-interface/public/shared/ocp-v2/ocp-v2-state.js +8 -21
  354. package/neural-interface/public/shared/ocp-v2/ocp-v2-status-logic.js +1 -99
  355. package/neural-interface/public/shared/ocp-v2/ocp-v2-status.js +5 -35
  356. package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +48 -40
  357. package/neural-interface/public/shared/ocp-v2/{ocp-v2-profile-inheritance.js → ocp-v2-tools-inheritance.js} +16 -16
  358. package/neural-interface/public/shared/ocp-v2/ocp-v2-ws.js +205 -62
  359. package/neural-interface/public/shared/opencode-providers.js +39 -0
  360. package/neural-interface/public/shared/page-session.js +96 -0
  361. package/neural-interface/public/shared/registry.js +5 -3
  362. package/neural-interface/public/shared/retired-2d.js +3 -0
  363. package/neural-interface/public/shared/schedules-view.js +452 -0
  364. package/neural-interface/public/shared/settings/settings-app-pane.js +335 -0
  365. package/neural-interface/public/shared/settings/settings-app.js +243 -0
  366. package/neural-interface/public/shared/settings/settings-claude-hooks.js +135 -0
  367. package/neural-interface/public/shared/settings/settings-data.js +90 -0
  368. package/neural-interface/public/shared/settings/settings-ia.js +23 -6
  369. package/neural-interface/public/shared/settings/settings-opencode.js +89 -0
  370. package/neural-interface/public/shared/settings/settings-skill-folders-pane.js +265 -0
  371. package/neural-interface/public/shared/settings/settings-skill-folders.js +130 -0
  372. package/neural-interface/public/shared/settings/settings-worker-guard.js +72 -0
  373. package/neural-interface/public/shared/sidepanel-session-status.js +49 -0
  374. package/neural-interface/public/shared/skills/ss-args.js +96 -0
  375. package/neural-interface/public/shared/skills/ss-creation.js +219 -0
  376. package/neural-interface/public/shared/skills/ss-dialog.js +130 -0
  377. package/neural-interface/public/shared/skills/ss-doc.js +173 -0
  378. package/neural-interface/public/shared/skills/ss-eval-adapters.js +269 -0
  379. package/neural-interface/public/shared/skills/ss-eval-grade.js +359 -0
  380. package/neural-interface/public/shared/skills/ss-eval-optimise.js +153 -0
  381. package/neural-interface/public/shared/skills/ss-eval-plan.js +315 -0
  382. package/neural-interface/public/shared/skills/ss-evals.js +417 -0
  383. package/neural-interface/public/shared/skills/ss-form.js +159 -0
  384. package/neural-interface/public/shared/skills/ss-frontmatter.js +376 -0
  385. package/neural-interface/public/shared/skills/ss-ids.js +32 -0
  386. package/neural-interface/public/shared/skills/ss-lint.js +141 -0
  387. package/neural-interface/public/shared/skills/ss-presets.js +117 -0
  388. package/neural-interface/public/shared/skills/ss-profiles.js +475 -0
  389. package/neural-interface/public/shared/skills/ss-resources.js +165 -0
  390. package/neural-interface/public/shared/skills/ss-review-view.js +190 -0
  391. package/neural-interface/public/shared/skills/ss-tabs.js +79 -0
  392. package/neural-interface/public/shared/skills/ss-unicode.js +135 -0
  393. package/neural-interface/public/shared/skills/studio/sx-actions.js +222 -0
  394. package/neural-interface/public/shared/skills/studio/sx-cm.js +101 -0
  395. package/neural-interface/public/shared/skills/studio/sx-create-ai-view.js +749 -0
  396. package/neural-interface/public/shared/skills/studio/sx-create-ai.js +236 -0
  397. package/neural-interface/public/shared/skills/studio/sx-create-view.js +254 -0
  398. package/neural-interface/public/shared/skills/studio/sx-create.js +126 -0
  399. package/neural-interface/public/shared/skills/studio/sx-diff-view.js +43 -0
  400. package/neural-interface/public/shared/skills/studio/sx-diff.js +133 -0
  401. package/neural-interface/public/shared/skills/studio/sx-docs.js +480 -0
  402. package/neural-interface/public/shared/skills/studio/sx-dom.js +229 -0
  403. package/neural-interface/public/shared/skills/studio/sx-edit-view.js +848 -0
  404. package/neural-interface/public/shared/skills/studio/sx-editor-model.js +193 -0
  405. package/neural-interface/public/shared/skills/studio/sx-errors.js +22 -0
  406. package/neural-interface/public/shared/skills/studio/sx-geometry.js +82 -0
  407. package/neural-interface/public/shared/skills/studio/sx-import.js +262 -0
  408. package/neural-interface/public/shared/skills/studio/sx-inspector.js +308 -0
  409. package/neural-interface/public/shared/skills/studio/sx-install-flow.js +279 -0
  410. package/neural-interface/public/shared/skills/studio/sx-install.js +296 -0
  411. package/neural-interface/public/shared/skills/studio/sx-library-view.js +639 -0
  412. package/neural-interface/public/shared/skills/studio/sx-library.js +475 -0
  413. package/neural-interface/public/shared/skills/studio/sx-main.js +681 -0
  414. package/neural-interface/public/shared/skills/studio/sx-operations-view.js +98 -0
  415. package/neural-interface/public/shared/skills/studio/sx-operations.js +11 -0
  416. package/neural-interface/public/shared/skills/studio/sx-plan.js +158 -0
  417. package/neural-interface/public/shared/skills/studio/sx-publish-view.js +621 -0
  418. package/neural-interface/public/shared/skills/studio/sx-review-view.js +369 -0
  419. package/neural-interface/public/shared/skills/studio/sx-review.js +148 -0
  420. package/neural-interface/public/shared/skills/studio/sx-scan.js +35 -0
  421. package/neural-interface/public/shared/skills/studio/sx-snippets.js +96 -0
  422. package/neural-interface/public/shared/skills/studio/sx-subject.js +248 -0
  423. package/neural-interface/public/shared/skills/studio/sx-test-view.js +994 -0
  424. package/neural-interface/public/shared/skills/studio/sx-test.js +328 -0
  425. package/neural-interface/public/shared/skills/studio/sx-versions-view.js +241 -0
  426. package/neural-interface/public/shared/skills/studio/sx-workspace-view.js +425 -0
  427. package/neural-interface/public/shared/styleguide/sg-panel.js +4 -2
  428. package/neural-interface/public/shared/styles.css +2065 -2150
  429. package/neural-interface/public/shared/synabun-mascot.js +1115 -9
  430. package/neural-interface/public/shared/tool-list-picker.js +55 -0
  431. package/neural-interface/public/shared/tool-list-storage.js +24 -0
  432. package/neural-interface/public/shared/tool-list-view.js +112 -0
  433. package/neural-interface/public/shared/tour/tour-actor.js +268 -0
  434. package/neural-interface/public/shared/tour/tour-beats.js +336 -0
  435. package/neural-interface/public/shared/tour/tour-engine.js +884 -0
  436. package/neural-interface/public/shared/tour/tour-ink.js +390 -0
  437. package/neural-interface/public/shared/tour/tour-stage.js +440 -0
  438. package/neural-interface/public/shared/tour/tour-state.js +40 -0
  439. package/neural-interface/public/shared/tour/tour-tips.js +99 -0
  440. package/neural-interface/public/shared/tour/tour.css +144 -0
  441. package/neural-interface/public/shared/ui-assistant.js +27 -5
  442. package/neural-interface/public/shared/ui-automation-studio.js +155 -152
  443. package/neural-interface/public/shared/ui-bookmarks.js +2 -1
  444. package/neural-interface/public/shared/ui-claude-panel.js +153 -13
  445. package/neural-interface/public/shared/ui-codex-panel.js +1 -0
  446. package/neural-interface/public/shared/ui-command-runner.js +6 -3
  447. package/neural-interface/public/shared/ui-context-menu.js +295 -0
  448. package/neural-interface/public/shared/ui-cost-widget.js +57 -59
  449. package/neural-interface/public/shared/ui-crash-notice.js +187 -0
  450. package/neural-interface/public/shared/ui-detail.js +21 -9
  451. package/neural-interface/public/shared/ui-file-links.js +1 -0
  452. package/neural-interface/public/shared/ui-image-gallery.js +56 -52
  453. package/neural-interface/public/shared/ui-invite.js +18 -2
  454. package/neural-interface/public/shared/ui-keybinds.js +26 -1
  455. package/neural-interface/public/shared/ui-link.js +9 -9
  456. package/neural-interface/public/shared/ui-menubar.js +229 -40
  457. package/neural-interface/public/shared/ui-native-loop-router-state.js +5 -0
  458. package/neural-interface/public/shared/ui-native-loop-router.js +9 -1
  459. package/neural-interface/public/shared/ui-navbar.js +4 -24
  460. package/neural-interface/public/shared/ui-opencode-panel-v2.js +1 -0
  461. package/neural-interface/public/shared/ui-panels.js +96 -65
  462. package/neural-interface/public/shared/ui-schedules-studio.js +2267 -953
  463. package/neural-interface/public/shared/ui-sessions.js +20 -7
  464. package/neural-interface/public/shared/ui-settings.js +679 -496
  465. package/neural-interface/public/shared/ui-sidebar.js +4 -4
  466. package/neural-interface/public/shared/ui-sidepanel-session-entry.js +13 -0
  467. package/neural-interface/public/shared/ui-sidepanel-sessions.js +56 -5
  468. package/neural-interface/public/shared/ui-sidepanel-state.js +23 -12
  469. package/neural-interface/public/shared/ui-sidepanel-tray.js +84 -8
  470. package/neural-interface/public/shared/ui-sidepanel-windows.js +16 -11
  471. package/neural-interface/public/shared/ui-skills.js +42 -2781
  472. package/neural-interface/public/shared/ui-styleguide.js +5 -2
  473. package/neural-interface/public/shared/ui-sync.js +22 -5
  474. package/neural-interface/public/shared/ui-terminal.js +159 -199
  475. package/neural-interface/public/shared/ui-tool-updates.js +3 -1
  476. package/neural-interface/public/shared/ui-tooltip.js +10 -5
  477. package/neural-interface/public/shared/ui-trash.js +14 -5
  478. package/neural-interface/public/shared/ui-tutorial-layout.js +3 -117
  479. package/neural-interface/public/shared/ui-tutorial-preview.js +103 -0
  480. package/neural-interface/public/shared/ui-tutorial-steps.js +3 -61
  481. package/neural-interface/public/shared/ui-tutorial.css +47 -100
  482. package/neural-interface/public/shared/ui-tutorial.js +285 -499
  483. package/neural-interface/public/shared/ui-update.js +121 -16
  484. package/neural-interface/public/shared/ui-whiteboard.js +313 -59
  485. package/neural-interface/public/shared/ui-worker-end.js +4 -0
  486. package/neural-interface/public/shared/ui-workspaces.js +3 -2
  487. package/neural-interface/public/shared/view-variant.js +66 -0
  488. package/neural-interface/public/shared/whatsapp/wa-view.js +1 -1
  489. package/neural-interface/public/shared/whiteboard-list.js +172 -0
  490. package/neural-interface/public/shared/worker-end.js +10 -3
  491. package/neural-interface/public/shared/worker-restart.js +12 -0
  492. package/neural-interface/public/sidepanel-session.html +1 -1
  493. package/neural-interface/public/variant/2d/background.js +2 -1
  494. package/neural-interface/public/variant/2d/context-menu.js +8 -2
  495. package/neural-interface/public/variant/2d/graph.js +42 -20
  496. package/neural-interface/public/variant/2d/hulls.js +14 -9
  497. package/neural-interface/public/variant/2d/lasso.js +11 -7
  498. package/neural-interface/public/variant/2d/main.js +36 -2
  499. package/neural-interface/public/variant/2d/minimap.js +11 -13
  500. package/neural-interface/public/variant/3d/main.js +72 -6
  501. package/neural-interface/public/variant/3d/map-controls.js +24 -9
  502. package/neural-interface/public/vendor/caveat/OFL.txt +93 -0
  503. package/neural-interface/public/vendor/caveat/caveat-latin-400-normal.woff2 +0 -0
  504. package/neural-interface/public/vendor/caveat/caveat-latin-700-normal.woff2 +0 -0
  505. package/neural-interface/public/vendor/caveat/caveat.css +17 -0
  506. package/neural-interface/public/vendor/caveat/manifest.json +12 -0
  507. package/neural-interface/public/vendor/highlight/LICENSE +29 -0
  508. package/neural-interface/public/vendor/highlight/github-dark-dimmed-11.12.0.min.css +9 -0
  509. package/neural-interface/public/vendor/highlight/highlight-11.12.0.min.js +1262 -0
  510. package/neural-interface/public/vendor/highlight/manifest.json +5 -0
  511. package/neural-interface/public/vendor/html2canvas/LICENSE +22 -0
  512. package/neural-interface/public/vendor/html2canvas/html2canvas-1.4.1.min.js +20 -0
  513. package/neural-interface/public/vendor/html2canvas/manifest.json +4 -0
  514. package/neural-interface/public/vendor/marked/LICENSE.md +44 -0
  515. package/neural-interface/public/vendor/marked/manifest.json +4 -0
  516. package/neural-interface/public/vendor/marked/marked-14.1.4.esm.js +2502 -0
  517. package/neural-interface/public/vendor/mermaid/LICENSE +21 -0
  518. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/abnfDiagram-PAR5IXJI.mjs +1 -0
  519. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/architecture-7GRP2DOG-M7G3SWCO.mjs +1 -0
  520. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/architectureDiagram-2PNWDENW.mjs +36 -0
  521. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/blockDiagram-PUWGUBOA.mjs +129 -0
  522. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/c4Diagram-3NLNHZP5.mjs +38 -0
  523. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-2NMSUPJH.mjs +1 -0
  524. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-32MCUW2P.mjs +206 -0
  525. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-3NPNU5GP.mjs +1 -0
  526. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-3SMGFRGC.mjs +1 -0
  527. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-4CAJECRU.mjs +14 -0
  528. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-4OADUZ5Q.mjs +10 -0
  529. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5IMINLNL.mjs +1 -0
  530. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5IQCK5RY.mjs +3 -0
  531. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5MVFYWFU.mjs +1 -0
  532. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-AQ6EADP3.mjs +1 -0
  533. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-AZZRMDJM.mjs +15 -0
  534. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-CLS4B6BI.mjs +168 -0
  535. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-DZP67EKU.mjs +70 -0
  536. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-EICP7K5X.mjs +1 -0
  537. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-GDY2UAB4.mjs +1 -0
  538. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-H7VHZCWX.mjs +1 -0
  539. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-IJBDOHL6.mjs +1 -0
  540. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JFFVMJIA.mjs +1 -0
  541. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JQRUD6KW.mjs +1 -0
  542. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JZGDI5JK.mjs +1 -0
  543. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-KD6SPIPN.mjs +2 -0
  544. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-NF366YI6.mjs +231 -0
  545. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-NUDPKBEF.mjs +32 -0
  546. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-OJINMHTS.mjs +1 -0
  547. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-Q6NGPIAH.mjs +2 -0
  548. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-QJSWEUOL.mjs +132 -0
  549. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-R7JDMUKV.mjs +1 -0
  550. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-RCXAM2GK.mjs +1 -0
  551. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-RT4MAWR3.mjs +1 -0
  552. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-SFMINX4W.mjs +1 -0
  553. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-SLDQ463B.mjs +88 -0
  554. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-STOV2HOB.mjs +1 -0
  555. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-T5OCTHI4.mjs +1 -0
  556. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-TCEHX7R3.mjs +1 -0
  557. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VQC2EELJ.mjs +1 -0
  558. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VRZKL3EH.mjs +1 -0
  559. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VTHDQ7BV.mjs +1 -0
  560. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VY2OSTJR.mjs +2 -0
  561. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-WUBWJARI.mjs +1 -0
  562. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-YBMQ5JGJ.mjs +2 -0
  563. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-YDMLL4PJ.mjs +1 -0
  564. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-Z6V44ARX.mjs +62 -0
  565. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZJJ7VQJP.mjs +339 -0
  566. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZNLK7HRR.mjs +1 -0
  567. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZQN7UHIL.mjs +1 -0
  568. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZS6VBONO.mjs +174 -0
  569. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZUNWM646.mjs +1 -0
  570. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/classDiagram-FGAMPOII.mjs +1 -0
  571. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/classDiagram-v2-AI5RJEK4.mjs +1 -0
  572. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cose-bilkent-Q72C2OJ3.mjs +1 -0
  573. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cynefin-OW5HDTMX-6OCTWOGG.mjs +1 -0
  574. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cynefinDiagram-2OOWUY4M.mjs +62 -0
  575. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/dagre-MPVFI544.mjs +4 -0
  576. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-AE4NWXFW.mjs +24 -0
  577. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-BUJID5UG.mjs +41 -0
  578. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-C44CZ5NI.mjs +24 -0
  579. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-EYOLEXXS.mjs +30 -0
  580. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-P7B6PWOJ.mjs +3 -0
  581. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ebnfDiagram-FTPZ3PV6.mjs +1 -0
  582. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/erDiagram-H3ERR26V.mjs +99 -0
  583. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/eventmodeling-NTZA5JFV-WKSWQHFS.mjs +1 -0
  584. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/flowDiagram-YHGXBVSY.mjs +1 -0
  585. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ganttDiagram-RWFTB7ED.mjs +292 -0
  586. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/gitGraph-4MIJSDKK-JH2HKYUO.mjs +1 -0
  587. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/gitGraphDiagram-MAR6GKOP.mjs +106 -0
  588. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/info-A6RAGUB7-3TX3OFWW.mjs +1 -0
  589. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/infoDiagram-LV547AFH.mjs +2 -0
  590. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ishikawaDiagram-PUJQGNDS.mjs +70 -0
  591. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/journeyDiagram-EW5QJT4W.mjs +139 -0
  592. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/kanban-definition-JSQERAZB.mjs +89 -0
  593. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/katex-CZ4GXH2S.mjs +257 -0
  594. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/mindmap-definition-VBJCLQLM.mjs +96 -0
  595. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/packet-AYTQ26CC-MKII6P3Y.mjs +1 -0
  596. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pegDiagram-7WILOQTJ.mjs +1 -0
  597. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pie-WAS4IAKB-6B4OPMJ5.mjs +1 -0
  598. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pieDiagram-EFA7CBSB.mjs +39 -0
  599. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/quadrantDiagram-WARVYA7P.mjs +7 -0
  600. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/radar-RG4KPBEZ-UPTR3XUL.mjs +1 -0
  601. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-74A4TZTK-MEFUPFMS.mjs +1 -0
  602. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-abnf-HS5TGJTU-R5YG2S5D.mjs +1 -0
  603. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-ebnf-LZEXJU2U-G5QEX2L6.mjs +1 -0
  604. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-peg-WCYAUIDC-H5I2ZRY2.mjs +1 -0
  605. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroadDiagram-5NIQVNLQ.mjs +1 -0
  606. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/requirementDiagram-SXREGOKZ.mjs +84 -0
  607. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sankeyDiagram-VV74M2VP.mjs +40 -0
  608. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sequenceDiagram-52ZFIFDL.mjs +162 -0
  609. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sizeCapture-FGA5AGYP.mjs +1 -0
  610. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/stateDiagram-3QAKPIVI.mjs +1 -0
  611. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/stateDiagram-v2-HN2P4RDZ.mjs +1 -0
  612. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/swimlanes-QLVP42QD.mjs +1 -0
  613. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/swimlanesDiagram-JKPDBFCN.mjs +8 -0
  614. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/timeline-definition-GS45XAXW.mjs +120 -0
  615. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/treeView-Q6P3EWNA-ZRJGANNQ.mjs +1 -0
  616. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/treemap-WGGIJYW6-K64VN5AS.mjs +1 -0
  617. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/vennDiagram-QIQU2ZRJ.mjs +34 -0
  618. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/wardley-WFR3VGLG-D67OWCCH.mjs +1 -0
  619. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/wardleyDiagram-U6YNM66N.mjs +78 -0
  620. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/xychartDiagram-XJAZEDNM.mjs +7 -0
  621. package/neural-interface/public/vendor/mermaid/manifest.json +4 -0
  622. package/neural-interface/public/vendor/mermaid/mermaid-11.17.2.esm.min.mjs +14 -0
  623. package/neural-interface/public/vendor/yaml/LICENSE +13 -0
  624. package/neural-interface/public/vendor/yaml/manifest.json +4 -0
  625. package/neural-interface/public/vendor/yaml/yaml-2.9.1.min.js +137 -0
  626. package/neural-interface/scripts/build-vendor.mjs +116 -3
  627. package/neural-interface/server.js +4834 -2541
  628. package/neural-interface/templates/rulesets/core.md +1 -1
  629. package/neural-interface/templates/rulesets/legacy-hashes.json +18 -0
  630. package/neural-interface/templates/rulesets/manifest.json +8 -8
  631. package/npm-shrinkwrap.json +18 -12
  632. package/package.json +16 -3
  633. package/postinstall.js +9 -4
  634. package/preuninstall.js +1 -1
  635. package/setup.js +97 -322
  636. package/skills/skill-forge/SKILL.md +177 -0
  637. package/skills/skill-forge/evals/evals.json +54 -0
  638. package/skills/skill-forge/references/package.md +105 -0
  639. package/skills/skill-forge/references/review-and-recovery.md +63 -0
  640. package/skills/skill-forge/references/runtime-profiles.md +20 -0
  641. package/skills/skill-forge/references/sources-and-capabilities.md +51 -0
  642. package/skills/synabun/SKILL.md +10 -7
  643. package/skills/synabun/modules/audit.md +1 -5
  644. package/skills/synabun/modules/changelog.md +1 -5
  645. package/skills/synabun/modules/idea.md +1 -1
  646. package/skills/synabun/modules/memorize.md +6 -9
  647. package/skills/synabun/modules/schedule.md +5 -5
  648. package/mcp-server/dist/services/profiles.d.ts +0 -120
  649. package/mcp-server/dist/services/profiles.d.ts.map +0 -1
  650. package/mcp-server/dist/services/profiles.js +0 -387
  651. package/mcp-server/dist/services/profiles.js.map +0 -1
  652. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts +0 -97
  653. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts.map +0 -1
  654. package/mcp-server/dist/tools/leonardo-browser-tools.js +0 -228
  655. package/mcp-server/dist/tools/leonardo-browser-tools.js.map +0 -1
  656. package/mcp-server/dist/tools/leonardo.d.ts +0 -13
  657. package/mcp-server/dist/tools/leonardo.d.ts.map +0 -1
  658. package/mcp-server/dist/tools/leonardo.js +0 -21
  659. package/mcp-server/dist/tools/leonardo.js.map +0 -1
  660. package/mcp-server/dist/tools/profile.d.ts +0 -17
  661. package/mcp-server/dist/tools/profile.d.ts.map +0 -1
  662. package/mcp-server/dist/tools/profile.js +0 -114
  663. package/mcp-server/dist/tools/profile.js.map +0 -1
  664. package/mcp-server/src/services/profiles.ts +0 -428
  665. package/mcp-server/src/tools/leonardo-browser-tools.ts +0 -291
  666. package/mcp-server/src/tools/leonardo.ts +0 -30
  667. package/mcp-server/src/tools/profile.ts +0 -122
  668. package/neural-interface/lib/assistant-brains/opencode-browser-policy.js +0 -47
  669. package/neural-interface/lib/assistant-brains/opencode-route-gate.js +0 -62
  670. package/neural-interface/lib/mcp-profile-servers.js +0 -120
  671. package/neural-interface/public/shared/ui-tutorial-draw.js +0 -311
  672. package/skills/leonardo/SKILL.md +0 -168
  673. package/skills/leonardo/icon.svg +0 -1
  674. package/skills/leonardo/modules/browser-guide.md +0 -378
  675. package/skills/leonardo/modules/image-prompter.md +0 -283
  676. package/skills/leonardo/modules/model-advisor.md +0 -100
  677. package/skills/leonardo/modules/prompt-library.md +0 -110
  678. package/skills/leonardo/modules/style-guide.md +0 -186
  679. package/skills/leonardo/modules/video-prompter.md +0 -317
@@ -0,0 +1,557 @@
1
+ // ─────────────────────────────────────────────────────────────────────────────
2
+ // OpenCode 2's configuration, as SynaBun reads and writes it.
3
+ //
4
+ // OpenCode 2 reads its global configuration from `opencode.json` and
5
+ // `opencode.jsonc` in its configuration folder (OPENCODE_CONFIG_DIR when set,
6
+ // else $XDG_CONFIG_HOME/opencode, else ~/.config/opencode), the .jsonc after
7
+ // the .json, and never reads `config.json` (OpenCode 1's legacy file, which
8
+ // older SynaBun releases wrote). It still accepts OpenCode 1's field shapes in
9
+ // those files and converts them as it reads them; SynaBun writes OpenCode 2's
10
+ // shapes only:
11
+ // mcp.servers.<name> { type: 'local', command: [...], environment, disabled }
12
+ // or { type: 'remote', url, headers, disabled }
13
+ // permissions [{ action, resource, effect: 'allow'|'ask'|'deny' }],
14
+ // the last matching rule deciding; OpenCode 1's
15
+ // `permission` object (read first) is converted here the
16
+ // way OpenCode converts it (bash → shell, task → subagent)
17
+ // agents.<name> { system, description, mode, hidden, model, steps, permissions }
18
+ // plugins [package | { package, options }]
19
+ // providers.<id> { name, package, settings: { baseURL }, models }
20
+ // compaction { auto, buffer, keep: { tokens } }
21
+ // snapshots boolean
22
+ // SynaBun writes `opencode.json` and never the .jsonc (its comments are the
23
+ // user's): OpenCode merges both, so an entry of SynaBun's in opencode.json is
24
+ // in effect unless the user's .jsonc overrides it.
25
+ //
26
+ // Pure, apart from the read and write helpers at the end that take a path.
27
+ // ─────────────────────────────────────────────────────────────────────────────
28
+
29
+ import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
30
+ import os from 'node:os';
31
+ import { dirname, join, resolve } from 'node:path';
32
+
33
+ export const OPENCODE_CONFIG_SCHEMA = 'https://opencode.ai/config.json';
34
+ /** The global documents OpenCode 2 reads, lowest precedence first. */
35
+ export const OPENCODE_CONFIG_FILES = Object.freeze(['opencode.json', 'opencode.jsonc']);
36
+ /** The one SynaBun writes. */
37
+ export const OPENCODE_CONFIG_FILE = 'opencode.json';
38
+
39
+ /**
40
+ * Permission actions of OpenCode 2's own tools (its edit, write and patch tools all ask `edit`), in the order
41
+ * Settings → OpenCode lists them. MCP tools are actions too, named `<server>_<tool>`.
42
+ */
43
+ export const OPENCODE_TOOL_ACTIONS = Object.freeze([
44
+ 'read', 'edit', 'shell', 'glob', 'grep', 'list', 'lsp', 'webfetch', 'websearch',
45
+ 'subagent', 'skill', 'question', 'external_directory', 'browser', 'doom_loop',
46
+ ]);
47
+ /** What OpenCode 2 decides for an action no rule names (its default agent: everything allowed, its browser denied). */
48
+ export const OPENCODE_DEFAULT_EFFECTS = Object.freeze({ browser: 'deny' });
49
+ export const PERMISSION_EFFECTS = Object.freeze(['allow', 'ask', 'deny']);
50
+
51
+ /** OpenCode 1 names of permission actions OpenCode 2 renamed. */
52
+ const RENAMED_ACTIONS = Object.freeze({ bash: 'shell', task: 'subagent' });
53
+
54
+ const isObject = (value) => !!value && typeof value === 'object' && !Array.isArray(value);
55
+ const asObject = (value) => (isObject(value) ? value : {});
56
+
57
+ /** OpenCode's configuration folder: OPENCODE_CONFIG_DIR, else $XDG_CONFIG_HOME/opencode, else ~/.config/opencode. */
58
+ export function opencodeConfigDir({ env = process.env, home = os.homedir() } = {}) {
59
+ if (env.OPENCODE_CONFIG_DIR) return resolve(String(env.OPENCODE_CONFIG_DIR));
60
+ if (env.XDG_CONFIG_HOME) return join(String(env.XDG_CONFIG_HOME), 'opencode');
61
+ return join(home, '.config', 'opencode');
62
+ }
63
+
64
+ /** The file SynaBun writes in a configuration folder. */
65
+ export function opencodeConfigFilePath(dir) {
66
+ return join(dir, OPENCODE_CONFIG_FILE);
67
+ }
68
+
69
+ // ── JSONC ────────────────────────────────────────────────────────────────────
70
+
71
+ /**
72
+ * The value of a JSON-with-comments text (`//` and block comments, trailing commas), as OpenCode reads its
73
+ * .jsonc. Throws a SyntaxError on text that is not JSON once comments and trailing commas are gone.
74
+ */
75
+ export function parseJsonc(text) {
76
+ const s = String(text ?? '').replace(/^/, '');
77
+ let out = '';
78
+ let i = 0;
79
+ while (i < s.length) {
80
+ const ch = s[i];
81
+ if (ch === '"') {
82
+ let j = i + 1;
83
+ while (j < s.length && s[j] !== '"') j += s[j] === '\\' ? 2 : 1;
84
+ out += s.slice(i, j + 1);
85
+ i = j + 1;
86
+ continue;
87
+ }
88
+ if (ch === '/' && s[i + 1] === '/') {
89
+ while (i < s.length && s[i] !== '\n') i++;
90
+ continue;
91
+ }
92
+ if (ch === '/' && s[i + 1] === '*') {
93
+ const end = s.indexOf('*/', i + 2);
94
+ if (end < 0) throw new SyntaxError('Unterminated comment');
95
+ i = end + 2;
96
+ continue;
97
+ }
98
+ if (ch === ',') {
99
+ // A comma followed (after blanks and comments) by a closing bracket is a trailing comma.
100
+ let j = i + 1;
101
+ for (;;) {
102
+ while (j < s.length && /\s/.test(s[j])) j++;
103
+ if (s[j] === '/' && s[j + 1] === '/') { while (j < s.length && s[j] !== '\n') j++; continue; }
104
+ if (s[j] === '/' && s[j + 1] === '*') { const end = s.indexOf('*/', j + 2); if (end < 0) break; j = end + 2; continue; }
105
+ break;
106
+ }
107
+ if (s[j] === '}' || s[j] === ']') { i++; continue; }
108
+ }
109
+ out += ch;
110
+ i++;
111
+ }
112
+ return out.trim() ? JSON.parse(out) : {};
113
+ }
114
+
115
+ // ── MCP servers ──────────────────────────────────────────────────────────────
116
+
117
+ // A remote server's OAuth client as OpenCode 2 names it (seen on 2.1.4: it keeps these and drops any other name,
118
+ // `clientId` and `callbackPort` included), from the names SynaBun's MCP registry and Claude Code use.
119
+ const OAUTH_NAMES = { clientId: 'client_id', clientSecret: 'client_secret', scope: 'scope', callbackPort: 'callback_port', redirectUri: 'redirect_uri' };
120
+ const OAUTH_KEPT = new Set(Object.values(OAUTH_NAMES));
121
+
122
+ /** `false` (no OAuth), the OAuth client in OpenCode 2's names, or undefined (nothing to say: OpenCode's own default). */
123
+ function opencodeOauth(oauth) {
124
+ if (oauth === false) return false;
125
+ if (!isObject(oauth)) return undefined;
126
+ const out = {};
127
+ for (const [key, value] of Object.entries(oauth)) {
128
+ const name = OAUTH_NAMES[key] || (OAUTH_KEPT.has(key) ? key : null);
129
+ if (name && value !== undefined && value !== null && value !== '') out[name] = value;
130
+ }
131
+ return Object.keys(out).length ? out : undefined;
132
+ }
133
+
134
+ /**
135
+ * An MCP server as OpenCode 2 takes it (`mcp.servers.<name>`), from what SynaBun describes as
136
+ * `{ command, args, env }` / `{ url, headers, oauth }`, or from an entry of either major (`enabled: false` →
137
+ * `disabled`). Every word of a command goes through as it is: an argument may be empty or carry spaces on purpose.
138
+ */
139
+ export function opencodeMcpServerEntry(input = {}) {
140
+ const source = asObject(input);
141
+ const disabled = source.disabled === true || source.enabled === false;
142
+ const timeout = isObject(source.timeout)
143
+ ? { ...source.timeout }
144
+ : (Number(source.timeout) > 0 ? { startup: Number(source.timeout), catalog: Number(source.timeout), execution: Number(source.timeout) } : null);
145
+ // Options OpenCode 2 takes on either kind of server, as they are.
146
+ const shared = {
147
+ ...(typeof source.codemode === 'boolean' ? { codemode: source.codemode } : {}),
148
+ ...(source.protocol !== undefined && source.protocol !== null ? { protocol: source.protocol } : {}),
149
+ ...(timeout ? { timeout } : {}),
150
+ ...(disabled ? { disabled: true } : {}),
151
+ };
152
+ if (source.type === 'remote' || (typeof source.url === 'string' && source.url && source.type !== 'local')) {
153
+ const oauth = opencodeOauth(source.oauth);
154
+ return {
155
+ type: 'remote',
156
+ url: String(source.url || ''),
157
+ ...(isObject(source.headers) && Object.keys(source.headers).length ? { headers: { ...source.headers } } : {}),
158
+ ...(oauth !== undefined ? { oauth } : {}),
159
+ ...shared,
160
+ };
161
+ }
162
+ const head = Array.isArray(source.command) ? source.command : (source.command != null ? [source.command] : []);
163
+ const command = [...head, ...(Array.isArray(source.args) ? source.args : [])].filter((part) => typeof part === 'string');
164
+ const environment = isObject(source.environment) ? source.environment : (isObject(source.env) ? source.env : null);
165
+ return {
166
+ type: 'local',
167
+ command,
168
+ ...(environment && Object.keys(environment).length ? { environment: { ...environment } } : {}),
169
+ ...(typeof source.cwd === 'string' && source.cwd ? { cwd: source.cwd } : {}),
170
+ ...shared,
171
+ };
172
+ }
173
+
174
+ /** The MCP servers a config names, OpenCode 1 entries (`mcp.<name>`) as OpenCode 2 reads them: `{ name: entry }`. */
175
+ export function mcpServersOf(config) {
176
+ const mcp = asObject(asObject(config).mcp);
177
+ const out = {};
178
+ for (const [name, entry] of Object.entries(mcp)) {
179
+ if (name === 'servers' || name === 'timeout' || !isObject(entry)) continue;
180
+ Object.defineProperty(out, name, { value: opencodeMcpServerEntry(entry), enumerable: true, configurable: true, writable: true });
181
+ }
182
+ for (const [name, entry] of Object.entries(asObject(mcp.servers))) if (isObject(entry)) Object.defineProperty(out, name, { value: { ...entry }, enumerable: true, configurable: true, writable: true });
183
+ return out;
184
+ }
185
+
186
+ /** `config` with MCP server `name` set to `entry` (an OpenCode 1 entry of that name taken out). Mutates and returns it. */
187
+ export function setMcpServer(config, name, entry) {
188
+ const mcp = asObject(config.mcp);
189
+ delete mcp[name];
190
+ mcp.servers = { ...asObject(mcp.servers), [name]: opencodeMcpServerEntry(entry) };
191
+ config.mcp = mcp;
192
+ return config;
193
+ }
194
+
195
+ /** `config` without MCP server `name`, in either shape; empty containers go. Mutates and returns it. */
196
+ export function removeMcpServer(config, name) {
197
+ if (!isObject(config.mcp)) return config;
198
+ delete config.mcp[name];
199
+ if (isObject(config.mcp.servers)) {
200
+ delete config.mcp.servers[name];
201
+ if (!Object.keys(config.mcp.servers).length) delete config.mcp.servers;
202
+ }
203
+ if (!Object.keys(config.mcp).length) delete config.mcp;
204
+ return config;
205
+ }
206
+
207
+ /**
208
+ * Every MCP server of `config` moved into `mcp.servers` (OpenCode 1 entries converted), so SynaBun's own entries
209
+ * and the user's live in one shape before SynaBun changes any. Mutates and returns it.
210
+ */
211
+ export function normalizeMcpServers(config) {
212
+ if (!isObject(config.mcp)) return config;
213
+ const servers = mcpServersOf(config);
214
+ const timeout = config.mcp.timeout;
215
+ config.mcp = { ...(isObject(timeout) ? { timeout } : {}), ...(Object.keys(servers).length ? { servers } : {}) };
216
+ if (!Object.keys(config.mcp).length) delete config.mcp;
217
+ return config;
218
+ }
219
+
220
+ // ── Permission rules ─────────────────────────────────────────────────────────
221
+
222
+ /** The OpenCode 2 name of a permission action (OpenCode 1's bash → shell, task → subagent). */
223
+ export function opencodeAction(name) {
224
+ const key = String(name ?? '');
225
+ return RENAMED_ACTIONS[key] || key;
226
+ }
227
+
228
+ /** One permission rule. */
229
+ export function permissionRule(action, effect, resource = '*') {
230
+ return { action: opencodeAction(action), resource: String(resource), effect };
231
+ }
232
+
233
+ /** OpenCode 1's `permission` object as OpenCode 2's rules, the way OpenCode converts it. */
234
+ export function rulesFromPermissionObject(permission) {
235
+ if (typeof permission === 'string') return PERMISSION_EFFECTS.includes(permission) ? [permissionRule('*', permission)] : [];
236
+ const rules = [];
237
+ for (const [action, value] of Object.entries(asObject(permission))) {
238
+ if (typeof value === 'string') {
239
+ if (PERMISSION_EFFECTS.includes(value)) rules.push(permissionRule(action, value));
240
+ } else if (isObject(value)) {
241
+ for (const [resource, effect] of Object.entries(value)) {
242
+ if (PERMISSION_EFFECTS.includes(effect)) rules.push(permissionRule(action, effect, resource));
243
+ }
244
+ }
245
+ }
246
+ return rules;
247
+ }
248
+
249
+ /** Every rule of a config, in the order OpenCode applies them: OpenCode 1's object first, then `permissions`. */
250
+ export function permissionRulesOf(config) {
251
+ const source = asObject(config);
252
+ const v2 = Array.isArray(source.permissions)
253
+ ? source.permissions.filter((rule) => isObject(rule) && typeof rule.action === 'string' && PERMISSION_EFFECTS.includes(rule.effect))
254
+ .map((rule) => ({ action: rule.action, resource: typeof rule.resource === 'string' ? rule.resource : '*', effect: rule.effect }))
255
+ : [];
256
+ return [...rulesFromPermissionObject(source.permission), ...v2];
257
+ }
258
+
259
+ function wildcardMatch(pattern, value) {
260
+ const text = String(pattern ?? '');
261
+ if (text === '*') return true;
262
+ const re = new RegExp(`^${text.split('*').map((part) => part.replace(/[.+?^${}()|[\]\\]/g, '\\$&')).join('.*')}$`);
263
+ return re.test(String(value ?? ''));
264
+ }
265
+
266
+ /**
267
+ * The effect the last rule matching `action` on `resource` gives ('allow' | 'ask' | 'deny'), or null when no rule
268
+ * names it. `exact` counts only rules naming the action itself (not a wildcard).
269
+ */
270
+ export function effectFor(rules, action, { resource = '*', exact = false } = {}) {
271
+ const wanted = opencodeAction(action);
272
+ let effect = null;
273
+ for (const rule of Array.isArray(rules) ? rules : []) {
274
+ const named = exact ? rule.action === wanted : wildcardMatch(rule.action, wanted);
275
+ if (named && (rule.resource === '*' || wildcardMatch(rule.resource, resource))) effect = rule.effect;
276
+ }
277
+ return effect;
278
+ }
279
+
280
+ /** What a config decides for each of OpenCode's own tool actions, for resource `*` (its defaults where no rule says). */
281
+ export function toolEffectsOf(config) {
282
+ const rules = permissionRulesOf(config);
283
+ const out = {};
284
+ for (const action of OPENCODE_TOOL_ACTIONS) out[action] = effectFor(rules, action) || OPENCODE_DEFAULT_EFFECTS[action] || 'allow';
285
+ return out;
286
+ }
287
+
288
+ /**
289
+ * `config` with an `allow` rule for each of `actions` that has no rule of its own (an explicit deny or ask of the
290
+ * user's stays the user's). Mutates and returns it.
291
+ */
292
+ export function allowActions(config, actions) {
293
+ const rules = permissionRulesOf(config);
294
+ const list = Array.isArray(config.permissions) ? config.permissions : [];
295
+ for (const action of actions || []) {
296
+ if (effectFor(rules, action, { exact: true }) == null) list.push(permissionRule(action, 'allow'));
297
+ }
298
+ if (list.length) config.permissions = list;
299
+ return config;
300
+ }
301
+
302
+ /**
303
+ * `config` with exactly one rule deciding `action` for every resource: `effect`. Earlier `*` rules of that action
304
+ * go (OpenCode 1's string value too); rules for particular resources stay. Mutates and returns it.
305
+ */
306
+ export function setActionEffect(config, action, effect) {
307
+ if (!PERMISSION_EFFECTS.includes(effect)) throw new Error(`Unknown permission effect: ${effect}`);
308
+ const wanted = opencodeAction(action);
309
+ if (isObject(config.permission)) {
310
+ for (const [key, value] of Object.entries(config.permission)) {
311
+ if (opencodeAction(key) === wanted && typeof value === 'string') delete config.permission[key];
312
+ }
313
+ if (!Object.keys(config.permission).length) delete config.permission;
314
+ }
315
+ const list = (Array.isArray(config.permissions) ? config.permissions : []).filter((rule) => !(isObject(rule) && rule.action === wanted && (rule.resource ?? '*') === '*'));
316
+ list.push(permissionRule(wanted, effect));
317
+ config.permissions = list;
318
+ return config;
319
+ }
320
+
321
+ /** `config` with `rules` appended to its `permissions` (each converted to OpenCode 2's action names). Mutates and returns it. */
322
+ export function appendRules(config, rules) {
323
+ const list = Array.isArray(config.permissions) ? config.permissions : [];
324
+ for (const rule of rules || []) if (isObject(rule) && PERMISSION_EFFECTS.includes(rule.effect)) list.push(permissionRule(rule.action, rule.effect, rule.resource ?? '*'));
325
+ if (list.length) config.permissions = list;
326
+ return config;
327
+ }
328
+
329
+ // ── Agents ───────────────────────────────────────────────────────────────────
330
+
331
+ /** An agent as OpenCode 2 takes it, from an entry of either major (`prompt` → `system`, `permission` → rules). */
332
+ export function opencodeAgentEntry(input = {}) {
333
+ const source = asObject(input);
334
+ const { prompt, permission, permissions, tools: _tools, ...rest } = source;
335
+ const out = { ...rest };
336
+ if (typeof prompt === 'string' && out.system === undefined) out.system = prompt;
337
+ const rules = [...rulesFromPermissionObject(permission), ...(Array.isArray(permissions) ? permissions.filter(isObject) : [])];
338
+ if (rules.length) out.permissions = rules;
339
+ return out;
340
+ }
341
+
342
+ /** Agent `name` of a config in OpenCode 2's shape (an OpenCode 1 `agent.<name>` converted), or `{}`. */
343
+ export function agentOf(config, name) {
344
+ const v1 = asObject(asObject(config).agent)[name];
345
+ const v2 = asObject(asObject(config).agents)[name];
346
+ if (!isObject(v1) && !isObject(v2)) return {};
347
+ const converted = opencodeAgentEntry(v1 || {});
348
+ const own = opencodeAgentEntry(v2 || {});
349
+ const permissions = [...(converted.permissions || []), ...(own.permissions || [])];
350
+ return { ...converted, ...own, ...(permissions.length ? { permissions } : {}) };
351
+ }
352
+
353
+ /** `config` with agent `name` set to `agent` (an OpenCode 1 `agent.<name>` taken out). Mutates and returns it. */
354
+ export function setAgent(config, name, agent) {
355
+ if (isObject(config.agent)) {
356
+ delete config.agent[name];
357
+ if (!Object.keys(config.agent).length) delete config.agent;
358
+ }
359
+ config.agents = { ...asObject(config.agents), [name]: opencodeAgentEntry(agent) };
360
+ return config;
361
+ }
362
+
363
+ // ── Plugins ──────────────────────────────────────────────────────────────────
364
+
365
+ const pluginPackage = (entry) => (isObject(entry) ? entry.package : Array.isArray(entry) ? entry[0] : entry);
366
+
367
+ /** `config` with plugin `pkg` (a file URL or package name) listed once, with `options`. Mutates and returns it. */
368
+ export function withPlugin(config, pkg, options = {}) {
369
+ const list = (Array.isArray(config.plugins) ? config.plugins : []).filter((entry) => pluginPackage(entry) !== pkg);
370
+ list.push({ package: pkg, options: { ...asObject(options) } });
371
+ config.plugins = list;
372
+ return config;
373
+ }
374
+
375
+ /** `config` without plugin `pkg`, in either list. Mutates and returns it. */
376
+ export function withoutPlugin(config, pkg) {
377
+ for (const key of ['plugins', 'plugin']) {
378
+ if (!Array.isArray(config[key])) continue;
379
+ config[key] = config[key].filter((entry) => pluginPackage(entry) !== pkg);
380
+ if (!config[key].length) delete config[key];
381
+ }
382
+ return config;
383
+ }
384
+
385
+ // ── Providers, compaction, snapshots ─────────────────────────────────────────
386
+
387
+ /** Provider `id` of a config, either shape (`provider.<id>` or `providers.<id>`), or null. */
388
+ export function providerOf(config, id) {
389
+ const source = asObject(config);
390
+ const v2 = asObject(source.providers)[id];
391
+ if (isObject(v2)) return v2;
392
+ const v1 = asObject(source.provider)[id];
393
+ return isObject(v1) ? v1 : null;
394
+ }
395
+
396
+ /**
397
+ * Whether a document keeps providers other than `id` in OpenCode 1's `provider` section. OpenCode 2 reads one
398
+ * provider section per document: its own `providers` replaces OpenCode 1's whole when both are there, so an entry
399
+ * of SynaBun's in `providers` would hide every one of those.
400
+ */
401
+ export function hasOpencode1Providers(config, id = null) {
402
+ return Object.keys(asObject(asObject(config).provider)).some((key) => key !== id);
403
+ }
404
+
405
+ /**
406
+ * `config` with provider `id` set to `entry` (OpenCode 2's shape; an OpenCode 1 entry of that id taken out).
407
+ * Throws (code OPENCODE1_PROVIDERS) when the document keeps other providers in OpenCode 1's section: they are
408
+ * moved to `providers` first (as OpenCode converted them: GET /api/config), never dropped.
409
+ */
410
+ export function setProvider(config, id, entry) {
411
+ if (hasOpencode1Providers(config, id)) {
412
+ throw Object.assign(new Error('This OpenCode configuration keeps its providers in OpenCode 1\'s "provider" section, which a "providers" section would hide.'), { code: 'OPENCODE1_PROVIDERS' });
413
+ }
414
+ removeProvider(config, id);
415
+ config.providers = { ...asObject(config.providers), [id]: { ...asObject(entry) } };
416
+ return config;
417
+ }
418
+
419
+ /** `config` without provider `id`, in either shape. Mutates and returns it. */
420
+ export function removeProvider(config, id) {
421
+ for (const key of ['provider', 'providers']) {
422
+ if (!isObject(config[key])) continue;
423
+ delete config[key][id];
424
+ if (!Object.keys(config[key]).length) delete config[key];
425
+ }
426
+ return config;
427
+ }
428
+
429
+ /**
430
+ * A request timeout (ms) for provider `id` of a config written for one of SynaBun's serves, unless the provider
431
+ * sets one: `providers.<id>.settings.timeout`. A document that keeps its providers in OpenCode 1's section is left
432
+ * as it is (a `providers` section would hide them: hasOpencode1Providers). Mutates and returns it.
433
+ */
434
+ export function withProviderTimeout(config, id, timeoutMs) {
435
+ if (!id || isObject(config.provider)) return config;
436
+ const existing = asObject(asObject(config.providers)[id]);
437
+ const settings = { ...asObject(existing.settings) };
438
+ if (settings.timeout == null) settings.timeout = timeoutMs;
439
+ config.providers = { ...asObject(config.providers), [id]: { ...existing, settings } };
440
+ return config;
441
+ }
442
+
443
+ /** `{ auto, buffer }` of a config's compaction (OpenCode 1's `reserved` read as `buffer`); null where unset. */
444
+ export function compactionOf(config) {
445
+ const compaction = asObject(asObject(config).compaction);
446
+ return {
447
+ auto: typeof compaction.auto === 'boolean' ? compaction.auto : null,
448
+ buffer: Number.isFinite(compaction.buffer) ? compaction.buffer : (Number.isFinite(compaction.reserved) ? compaction.reserved : null),
449
+ };
450
+ }
451
+
452
+ /**
453
+ * `config` with its compaction set (`auto`, `buffer`) in OpenCode 2's shape (OpenCode 1's `prune`, `reserved`
454
+ * gone). A `buffer` of null takes it out: OpenCode's own default applies again.
455
+ */
456
+ export function setCompaction(config, { auto, buffer } = {}) {
457
+ const current = asObject(config.compaction);
458
+ const { prune: _prune, reserved, ...rest } = current;
459
+ const next = { ...rest };
460
+ if (rest.buffer === undefined && Number.isFinite(reserved)) next.buffer = reserved;
461
+ if (typeof auto === 'boolean') next.auto = auto;
462
+ if (buffer === null) delete next.buffer;
463
+ else if (buffer !== undefined) {
464
+ const value = Math.round(Number(buffer));
465
+ if (!Number.isFinite(value) || value < 0) throw new Error('The compaction buffer must be a whole number of tokens, 0 or more.');
466
+ next.buffer = value;
467
+ }
468
+ config.compaction = next;
469
+ return config;
470
+ }
471
+
472
+ /** Whether a config keeps snapshots (OpenCode 1's `snapshot` read too); null where unset. */
473
+ export function snapshotsOf(config) {
474
+ const source = asObject(config);
475
+ if (typeof source.snapshots === 'boolean') return source.snapshots;
476
+ if (typeof source.snapshot === 'boolean') return source.snapshot;
477
+ return null;
478
+ }
479
+
480
+ /** `config` with `snapshots` set (OpenCode 1's `snapshot` gone). Mutates and returns it. */
481
+ export function setSnapshots(config, enabled) {
482
+ delete config.snapshot;
483
+ config.snapshots = enabled === true;
484
+ return config;
485
+ }
486
+
487
+ // ── Files ────────────────────────────────────────────────────────────────────
488
+
489
+ /**
490
+ * One configuration document: `{ path, exists, config, error }`. A .jsonc is read with its comments; a file that is
491
+ * not JSON is `{ config: null, error }`, never thrown.
492
+ */
493
+ export function readOpencodeConfigDocument(path) {
494
+ if (!existsSync(path)) return { path, exists: false, config: {}, error: null };
495
+ try {
496
+ const text = readFileSync(path, 'utf8');
497
+ const value = path.endsWith('.jsonc') ? parseJsonc(text) : (text.trim() ? JSON.parse(text.replace(/^/, '')) : {});
498
+ if (!isObject(value)) return { path, exists: true, config: null, error: 'it does not hold a JSON object' };
499
+ return { path, exists: true, config: value, error: null };
500
+ } catch (error) {
501
+ return { path, exists: true, config: null, error: error?.message || String(error) };
502
+ }
503
+ }
504
+
505
+ /** The global documents of a configuration folder, lowest precedence first. */
506
+ export function readOpencodeConfigDocuments(dir) {
507
+ return OPENCODE_CONFIG_FILES.map((name) => readOpencodeConfigDocument(join(dir, name)));
508
+ }
509
+
510
+ /**
511
+ * Read `opencode.json` of `dir`, change it with `mutate(config)` and write it back (a new file when there is none),
512
+ * whole, through a temporary file and a rename. A file that is not JSON is never overwritten: throws instead.
513
+ * Resolves the path written.
514
+ */
515
+ export function updateOpencodeConfigFile(dir, mutate) {
516
+ const path = opencodeConfigFilePath(dir);
517
+ const doc = readOpencodeConfigDocument(path);
518
+ if (doc.error) throw new Error(`${path} could not be read (${doc.error}); SynaBun did not change it.`);
519
+ const config = doc.exists ? doc.config : { $schema: OPENCODE_CONFIG_SCHEMA };
520
+ const next = mutate(config) || config;
521
+ mkdirSync(dirname(path), { recursive: true });
522
+ const temp = `${path}.synabun-${process.pid}-${Date.now()}.tmp`;
523
+ writeFileSync(temp, `${JSON.stringify(next, null, 2)}\n`, 'utf8');
524
+ renameSync(temp, path);
525
+ return path;
526
+ }
527
+
528
+ /**
529
+ * The user's global configuration as one object, for a serve of SynaBun's own whose configuration folder is
530
+ * another (XDG_CONFIG_HOME set to it): opencode.json, then opencode.jsonc over it (top-level keys replaced; `mcp`
531
+ * servers, agents, providers and permission rules merged the way OpenCode merges them). A document that cannot be
532
+ * read is left out.
533
+ */
534
+ export function mergedOpencodeConfig(documents) {
535
+ const merged = {};
536
+ for (const doc of documents || []) {
537
+ const config = doc?.config;
538
+ if (!isObject(config)) continue;
539
+ for (const [key, value] of Object.entries(config)) {
540
+ if (key === 'permission' || key === 'permissions') continue;
541
+ if (key === 'mcp' && isObject(value)) {
542
+ const servers = { ...mcpServersOf(merged), ...mcpServersOf(config) };
543
+ merged.mcp = { ...(isObject(value.timeout) ? { timeout: value.timeout } : (isObject(merged.mcp?.timeout) ? { timeout: merged.mcp.timeout } : {})), ...(Object.keys(servers).length ? { servers } : {}) };
544
+ } else if ((key === 'agents' || key === 'agent' || key === 'providers' || key === 'provider') && isObject(value)) {
545
+ merged[key] = { ...asObject(merged[key]), ...value };
546
+ } else if ((key === 'plugins' || key === 'plugin' || key === 'instructions') && Array.isArray(value)) {
547
+ merged[key] = [...(Array.isArray(merged[key]) ? merged[key] : []), ...value];
548
+ } else {
549
+ merged[key] = value;
550
+ }
551
+ }
552
+ // A document's rules in OpenCode's order (its OpenCode 1 object first), after the earlier document's.
553
+ const rules = permissionRulesOf(config);
554
+ if (rules.length) merged.permissions = [...(Array.isArray(merged.permissions) ? merged.permissions : []), ...rules];
555
+ }
556
+ return merged;
557
+ }
@@ -0,0 +1,58 @@
1
+ // ─────────────────────────────────────────────────────────────────────────────
2
+ // The tables of OpenCode's database SynaBun reads.
3
+ //
4
+ // SynaBun reads OpenCode's own SQLite database ($XDG_DATA_HOME/opencode/
5
+ // opencode.db) for the session lists of every registered project and for the
6
+ // Resume cache. OpenCode 2 keeps its sessions in `session_v2` and their
7
+ // messages in `session_message`. A file OpenCode 2 migrated from OpenCode 1
8
+ // also holds OpenCode 1's `session` / `message` / `part` tables, frozen: they
9
+ // are never read (they would show yesterday's sessions and none of today's).
10
+ // ─────────────────────────────────────────────────────────────────────────────
11
+
12
+ /** The table names of an open node:sqlite database, or an empty set. */
13
+ export function tableNamesOf(db) {
14
+ try {
15
+ return new Set(db.prepare("SELECT name FROM sqlite_master WHERE type = 'table'").all().map((row) => String(row?.name || '')));
16
+ } catch {
17
+ return new Set();
18
+ }
19
+ }
20
+
21
+ /** Whether a database holds OpenCode 2's session tables (false for none, or for OpenCode 1's alone). */
22
+ export function hasOpencodeSessionTables(db) {
23
+ if (!db) return false;
24
+ const tables = tableNamesOf(db);
25
+ return tables.has('session_v2') && tables.has('session_message');
26
+ }
27
+
28
+ /** The session table and the message-count expression (`s` is the session row). */
29
+ export const OPENCODE_SESSION_TABLES = Object.freeze({
30
+ session: 'session_v2',
31
+ messageCount: "(SELECT COUNT(*) FROM session_message m WHERE m.session_id = s.id AND m.type IN ('user', 'assistant'))",
32
+ });
33
+
34
+ /**
35
+ * The visible text of one `session_message` row (its `type` and JSON `data`)
36
+ * as `{ role, text }`, or null for a row without any (a switch, an idle
37
+ * marker, a tool-only step).
38
+ */
39
+ export function v2MessageText(type, data) {
40
+ let body = data;
41
+ if (typeof data === 'string') {
42
+ try { body = JSON.parse(data); } catch { return null; }
43
+ }
44
+ if (!body || typeof body !== 'object') return null;
45
+ if (type === 'user') {
46
+ const text = typeof body.text === 'string' ? body.text : '';
47
+ return text ? { role: 'user', text } : null;
48
+ }
49
+ if (type === 'assistant') {
50
+ const text = (Array.isArray(body.content) ? body.content : [])
51
+ .filter((item) => item?.type === 'text' && typeof item.text === 'string')
52
+ .map((item) => item.text)
53
+ .join('\n')
54
+ .trim();
55
+ return text ? { role: 'assistant', text } : null;
56
+ }
57
+ return null;
58
+ }