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
@@ -6,7 +6,7 @@
6
6
  // keeps an untouched copy current:
7
7
  //
8
8
  // claude owned file ~/.claude/rules/synabun.md (and each Claude account's config dir)
9
- // opencode owned file <opencode config dir>/synabun.md + one `instructions` entry in config.json
9
+ // opencode owned file <opencode config dir>/synabun.md + one `instructions` entry in opencode.json
10
10
  // codex block ~/.codex/AGENTS.md (account homes link to it, or get their own block)
11
11
  // gemini block ~/.gemini/GEMINI.md
12
12
  // cursor none User Rules live inside the app: copy and paste ("manual")
@@ -29,7 +29,7 @@
29
29
  // (the user opted out) or null (never asked). `created` lists the files and
30
30
  // directories install made, `links` the symlinks it made and where each
31
31
  // pointed. OpenCode's row also holds `instructionsEntry`, the exact string
32
- // SynaBun added to config.json. `removal` on a row is a removal that is not
32
+ // SynaBun added to opencode.json. `removal` on a row is a removal that is not
33
33
  // over: it is saved, with the paths it is about to take, before the first
34
34
  // copy goes, and it stays when a copy was refused (damaged markers, an
35
35
  // unreadable file). The next boot finishes it (reconcile), and the record is
@@ -74,6 +74,7 @@ import { loadLegacyHashes, normalise, renderRuleset, RULESET_HOSTS } from './ren
74
74
  import { findBlocks, findLegacy, isPristine, removeBlock, removeRange, replaceRange, upsertBlock, wrap } from './managed-text.js';
75
75
  import { backupFile, findBrokenLink, readBytes, readJsonStrict, unlinkIfUnchanged, writeTextAtomic } from './fs-safe.js';
76
76
  import { addToJsonList, countJsonKey, removeFromJsonList } from './json-edit.js';
77
+ import { mcpServersOf, mergedOpencodeConfig, opencodeConfigDir, opencodeConfigFilePath, readOpencodeConfigDocuments } from '../opencode-config.js';
77
78
  import { createWriterLock, DEFAULT_LOCK_TIMEOUT_MS, LOCK_FILE_NAME } from './lock.js';
78
79
 
79
80
  export const RULESET_STATES = Object.freeze(['not-installed', 'installed', 'newer', 'outdated', 'modified', 'conflict', 'shadowed', 'error', 'manual']);
@@ -190,7 +191,7 @@ export function createRulesetInstaller({
190
191
  // `hooks` are seams for tests, each a point where another program could act
191
192
  // (or where a test holds an operation still, inside the lock):
192
193
  // afterInspect(host, path, status) once a carrier was read and is about to be
193
- // written, beforeCommit(path) right before a file (a carrier, config.json,
194
+ // written, beforeCommit(path) right before a file (a carrier, opencode.json,
194
195
  // the state file) is checked against what was read and replaced or deleted,
195
196
  // afterCheck(path) between that check and a delete, afterSave(revision) once
196
197
  // the state file was saved.
@@ -351,12 +352,14 @@ export function createRulesetInstaller({
351
352
 
352
353
  // ── Where things live ──────────────────────────────────────────────────────
353
354
  // Resolved the way the MCP toggle routes resolve them: Claude, Codex and
354
- // Gemini under the home directory, OpenCode under XDG_CONFIG_HOME when set.
355
+ // Gemini under the home directory, OpenCode in its configuration folder
356
+ // (OPENCODE_CONFIG_DIR, else XDG_CONFIG_HOME/opencode, else ~/.config/opencode),
357
+ // whose opencode.json OpenCode 2 reads (lib/opencode-config.js).
355
358
  function layout() {
356
359
  // The server passes the resolver its /api/opencode/mcp toggle uses, so both always edit the same file.
357
360
  const opencodeConfig = opencodeConfigPath
358
361
  ? resolve(opencodeConfigPath())
359
- : join(env?.XDG_CONFIG_HOME ? join(env.XDG_CONFIG_HOME, 'opencode') : join(home, '.config', 'opencode'), 'config.json');
362
+ : opencodeConfigFilePath(opencodeConfigDir({ env: env || {}, home }));
360
363
  return {
361
364
  claudeDir: join(home, '.claude'),
362
365
  codexHome: join(home, '.codex'),
@@ -427,7 +430,7 @@ export function createRulesetInstaller({
427
430
  if (host === 'claude') return !!JSON.parse(readFileSync(join(home, '.claude.json'), 'utf8'))?.mcpServers?.SynaBun;
428
431
  if (host === 'gemini') return !!JSON.parse(readFileSync(join(where.geminiDir, 'settings.json'), 'utf8'))?.mcpServers?.SynaBun;
429
432
  if (host === 'codex') return /^\[mcp_servers\.SynaBun\]/m.test(readFileSync(join(where.codexHome, 'config.toml'), 'utf8'));
430
- if (host === 'opencode') return !!JSON.parse(readFileSync(where.opencodeConfig, 'utf8'))?.mcp?.SynaBun;
433
+ if (host === 'opencode') return !!mcpServersOf(mergedOpencodeConfig(readOpencodeConfigDocuments(where.opencodeDir))).SynaBun;
431
434
  } catch { /* no config, no registration */ }
432
435
  return false;
433
436
  }
@@ -511,7 +514,7 @@ export function createRulesetInstaller({
511
514
  /**
512
515
  * The file an `instructions` entry of `configPath` names, or null when the entry is not one plain path: a URL, or
513
516
  * a pattern with glob characters. A leading `~` is the installer's home, and a relative path starts at the
514
- * directory of config.json (never at this process's working directory).
517
+ * directory of opencode.json (never at this process's working directory).
515
518
  */
516
519
  function entryFile(value, configPath) {
517
520
  if (typeof value !== 'string' || !value) return null;
@@ -530,8 +533,7 @@ export function createRulesetInstaller({
530
533
  if (path === resolve(owned)) return true;
531
534
  try { return realpathSync(path) === realpathSync(owned); } catch { return false; }
532
535
  }
533
- function readOpencodeConfig() {
534
- const path = layout().opencodeConfig;
536
+ function readOpencodeConfig(path = layout().opencodeConfig) {
535
537
  const entry = opencodeEntry();
536
538
  const refuse = (why) => ({ path, exists: true, hasEntry: false, cfg: null, text: null, bytes: null, error: `${path} ${why}. SynaBun will not rewrite it: fix the file, or add "${entry}" to its "instructions" list by hand.` });
537
539
  let bytes;
@@ -558,7 +560,7 @@ export function createRulesetInstaller({
558
560
  return { path, exists: true, hasEntry: (cfg.instructions || []).some((value) => entryIsOwnedFile(value, path)), cfg, text, bytes, error: null };
559
561
  }
560
562
  /**
561
- * The text of config.json after `edit()`, accepted only when it parses to
563
+ * The text of opencode.json after `edit()`, accepted only when it parses to
562
564
  * exactly `cfg`. There is no other way to write this file: when the edit
563
565
  * cannot be made on the text, SynaBun refuses rather than write the whole
564
566
  * object out again and lose what the user's file spells its own way.
@@ -570,7 +572,7 @@ export function createRulesetInstaller({
570
572
  } catch { /* text the editor could not follow */ }
571
573
  throw new Error(`${path} could not be edited safely, so SynaBun did not write it. Change its "instructions" list by hand: the entry is "${opencodeEntry()}".`);
572
574
  }
573
- /** What install writes when there is no config.json yet: remove deletes the file only while it still holds exactly this. */
575
+ /** What install writes when there is no opencode.json yet: remove deletes the file only while it still holds exactly this. */
574
576
  function newConfigText(value) {
575
577
  return addToJsonList('{}\n', 'instructions', value);
576
578
  }
@@ -582,7 +584,7 @@ export function createRulesetInstaller({
582
584
  }
583
585
  /**
584
586
  * The `instructions` entries that resolve to SynaBun's owned file and that SynaBun has no record of adding: the
585
- * user's own lines, however they are spelled (`~/...`, relative to config.json, a symlink to the file). One listing
587
+ * user's own lines, however they are spelled (`~/...`, relative to opencode.json, a symlink to the file). One listing
586
588
  * of the recorded string is SynaBun's; every other is theirs. A URL or a glob pattern is never one of them.
587
589
  */
588
590
  function userEntries(row, config) {
@@ -592,13 +594,13 @@ export function createRulesetInstaller({
592
594
  return list.filter((value, index) => index !== mine && entryIsOwnedFile(value, config.path));
593
595
  }
594
596
  /**
595
- * One change to config.json. `plan(config)` answers null (nothing to do) or
597
+ * One change to opencode.json. `plan(config)` answers null (nothing to do) or
596
598
  * {text, done?}; `text: null` deletes the file. The file is replaced only
597
599
  * while it still holds the bytes that were read: a change by another program
598
- * in between is CHANGED_UNDERNEATH, and config.json is left to it.
600
+ * in between is CHANGED_UNDERNEATH, and opencode.json is left to it.
599
601
  */
600
- function editOpencodeConfig(tally, plan) {
601
- const config = readOpencodeConfig();
602
+ function editOpencodeConfig(tally, plan, path = layout().opencodeConfig) {
603
+ const config = readOpencodeConfig(path);
602
604
  if (config.error) throw new Error(config.error);
603
605
  const step = plan(config);
604
606
  if (!step) return;
@@ -611,7 +613,7 @@ export function createRulesetInstaller({
611
613
  tally.changed = true;
612
614
  if (step.done) step.done();
613
615
  }
614
- /** Lists synabun.md in config.json unless it is listed already, and records the string SynaBun added. */
616
+ /** Lists synabun.md in opencode.json unless it is listed already, and records the string SynaBun added. */
615
617
  function addOpencodeEntry(row, tally) {
616
618
  const value = opencodeEntry();
617
619
  let listed = null;
@@ -645,7 +647,7 @@ export function createRulesetInstaller({
645
647
  const mine = ownedEntry(row, config);
646
648
  const others = theirs ? userEntries(row, config) : [];
647
649
  if (mine === null && !others.length) return null;
648
- // A config.json install created goes only while its bytes are still what install wrote. Anything the user
650
+ // An opencode.json install created goes only while its bytes are still what install wrote. Anything the user
649
651
  // added since makes it their file: the entries are edited out and the file stays.
650
652
  if (mine !== null && row.created.includes(config.path) && config.text === newConfigText(mine)) return { text: null };
651
653
  const dropKey = row.created.includes(`${config.path}#instructions`);
@@ -661,6 +663,60 @@ export function createRulesetInstaller({
661
663
  });
662
664
  }
663
665
 
666
+ // ── OpenCode 1's config.json ───────────────────────────────────────────────
667
+ // An older SynaBun listed synabun.md in config.json, which OpenCode 2 never reads. A copy SynaBun manages whose
668
+ // recorded entry is there is moved, at the next boot (reconcile) or install: listed in opencode.json, then the one
669
+ // string SynaBun added is taken out of config.json (the file goes when SynaBun made it and it still holds only that
670
+ // string). A remove takes that string out too. A line the user wrote in config.json is never touched. At a boot, a
671
+ // copy config.json no longer lists (the user took the line out, or the file) is an opt-out, as it was with
672
+ // OpenCode 1: never put back in opencode.json. An install, which the user asked for, lists it whatever config.json says.
673
+ function opencode1ConfigPath() {
674
+ return join(layout().opencodeDir, 'config.json');
675
+ }
676
+ /** The entry an older SynaBun recorded adding to config.json, or null. */
677
+ function opencode1Record(row) {
678
+ const owned = row.instructionsEntry;
679
+ return owned && typeof owned.value === 'string' && samePath(owned.config, opencode1ConfigPath()) ? { config: owned.config, value: owned.value } : null;
680
+ }
681
+ /**
682
+ * Whether config.json still lists the copy (`legacy`: opencode1Record), by any spelling: the line SynaBun added or
683
+ * one of the user's. A config.json SynaBun cannot read as plain JSON cannot say it does not, so it counts as listing.
684
+ */
685
+ function opencode1Listed(legacy) {
686
+ const config = readOpencodeConfig(legacy.config);
687
+ return !!config.error || config.hasEntry;
688
+ }
689
+ /** Takes the string of `legacy` (opencode1Record) out of config.json, and SynaBun's record of what it made there. */
690
+ function removeOpencode1Entry(row, tally, legacy) {
691
+ editOpencodeConfig(tally, (config) => {
692
+ if (!config.exists || !config.cfg) return null;
693
+ const list = [...(config.cfg.instructions || [])];
694
+ const at = list.lastIndexOf(legacy.value);
695
+ if (at < 0) return null;
696
+ if (row.created.includes(config.path) && config.text === newConfigText(legacy.value)) return { text: null };
697
+ const dropKey = row.created.includes(`${config.path}#instructions`);
698
+ list.splice(at, 1);
699
+ const cfg = { ...config.cfg, instructions: list };
700
+ if (!list.length && dropKey) delete cfg.instructions;
701
+ return { text: configText(config.path, cfg, () => removeFromJsonList(config.text, 'instructions', legacy.value, { dropEmptyKey: dropKey })) };
702
+ }, legacy.config);
703
+ row.created = row.created.filter((path) => !samePath(path, legacy.config) && path !== `${legacy.config}#instructions`);
704
+ }
705
+ /**
706
+ * A managed copy listed in config.json only: listed in opencode.json, and SynaBun's string taken out of
707
+ * config.json (a failure there leaves it with a warning: OpenCode 2 does not read that file). False when the row
708
+ * has no such record.
709
+ */
710
+ function moveOpencode1Entry(row, tally) {
711
+ const legacy = opencode1Record(row);
712
+ if (!legacy) return false;
713
+ addOpencodeEntry(row, tally);
714
+ try { removeOpencode1Entry(row, tally, legacy); } catch (error) {
715
+ tally.warnings.push(`${legacy.config} still lists ${legacy.value} under "instructions" (OpenCode 2 does not read that file): ${error?.message || error}`);
716
+ }
717
+ return true;
718
+ }
719
+
664
720
  // ── Writing ────────────────────────────────────────────────────────────────
665
721
  /**
666
722
  * The pasted copies in `text`, sorted by what install may do with them:
@@ -847,8 +903,7 @@ export function createRulesetInstaller({
847
903
  if (first.block) out.installedVersion = first.block.version;
848
904
  if (host === 'opencode') {
849
905
  const config = readOpencodeConfig();
850
- const sideFiles = ['opencode.json', 'opencode.jsonc'].filter((name) => existsSync(join(primary.dir, name)));
851
- if (sideFiles.length) out.notes = [`OpenCode also reads ${sideFiles.join(' and ')} in ${primary.dir}; SynaBun writes config.json, the same file its MCP toggle uses.`];
906
+ if (existsSync(join(primary.dir, 'opencode.jsonc'))) out.notes = [`OpenCode also reads opencode.jsonc in ${primary.dir}; SynaBun writes opencode.json, the same file its MCP toggle uses.`];
852
907
  if (config.error) return { ...out, state: 'error', error: config.error, detail: config.error };
853
908
  if (first.status !== 'missing' && !config.hasEntry) {
854
909
  unlisted = `${config.path} does not list it under "instructions", so OpenCode does not load it.`;
@@ -858,7 +913,7 @@ export function createRulesetInstaller({
858
913
  return { ...out, state: 'not-installed', installedVersion: null, detail: `${primary.path} exists, but ${unlisted}` };
859
914
  }
860
915
  }
861
- // A line in config.json that SynaBun did not add points at the file: a remove keeps both unless it is forced.
916
+ // A line in opencode.json that SynaBun did not add points at the file: a remove keeps both unless it is forced.
862
917
  if (first.status !== 'missing' && userEntries(row, config).length) out.entry = 'user';
863
918
  }
864
919
  if (first.status === 'missing' && RANK[worst.status] < RANK.error) return { ...out, installedVersion: null };
@@ -991,7 +1046,7 @@ export function createRulesetInstaller({
991
1046
  stripLegacy(host, target.legacyFile, tally);
992
1047
  }
993
1048
  }
994
- if (host === 'opencode') addOpencodeEntry(row, tally);
1049
+ if (host === 'opencode' && !moveOpencode1Entry(row, tally)) addOpencodeEntry(row, tally);
995
1050
 
996
1051
  Object.assign(row, {
997
1052
  managed: true,
@@ -1055,10 +1110,10 @@ export function createRulesetInstaller({
1055
1110
  * first; damaged markers, a block stamped for another tool, a symlinked owned
1056
1111
  * file and a file that cannot be read are refused either way.
1057
1112
  *
1058
- * OpenCode: a line in config.json that points at the owned file and that
1113
+ * OpenCode: a line in opencode.json that points at the owned file and that
1059
1114
  * SynaBun did not add keeps the file too (`kept`, reason `listed-in-config`):
1060
1115
  * nothing is ever left pointing at a file SynaBun deleted. With `force` that
1061
- * line goes as well, after a backup of config.json, and then the file.
1116
+ * line goes as well, after a backup of opencode.json, and then the file.
1062
1117
  *
1063
1118
  * Symlinks at a block carrier (AGENTS.md, GEMINI.md): the block is taken out
1064
1119
  * of the file the link points at and the link stays, exactly as install wrote
@@ -1076,7 +1131,7 @@ export function createRulesetInstaller({
1076
1131
  * True while a copy that keeps a removal open is still on disk: one SynaBun
1077
1132
  * should have taken and could not. That is damaged markers, a file that
1078
1133
  * cannot be read, an untouched copy of this host's rules (behind a symlink,
1079
- * or held back by another refusal), and for OpenCode a config.json that
1134
+ * or held back by another refusal), and for OpenCode an opencode.json that
1080
1135
  * cannot be edited while SynaBun's entry is on record. A copy the user
1081
1136
  * edited, a file without markers and a block stamped for another tool are
1082
1137
  * not: the keep rule leaves the first two to the user, and the third was
@@ -1169,6 +1224,11 @@ export function createRulesetInstaller({
1169
1224
  if (go && doomed.length) recordIntent(doomed.map((entry) => entry.path));
1170
1225
  if (go && together) {
1171
1226
  try { removeOpencodeEntry(row, tally, { theirs: force && doomed.length > 0 }); } catch (error) { refuse(layout().opencodeConfig, 'error', error?.message || String(error)); }
1227
+ // The string an older SynaBun added to OpenCode 1's config.json goes too (OpenCode 2 never read it).
1228
+ const legacy = opencode1Record(row);
1229
+ if (legacy) {
1230
+ try { removeOpencode1Entry(row, tally, legacy); } catch (error) { tally.warnings.push(`${legacy.config} still lists ${legacy.value} under "instructions": ${error?.message || error}`); }
1231
+ }
1172
1232
  }
1173
1233
  if (!(together && refused.length)) {
1174
1234
  for (const { path, text } of go ? doomed : []) {
@@ -1253,7 +1313,7 @@ export function createRulesetInstaller({
1253
1313
  // (`created`, OpenCode's entry) stays on record, so a forced remove or a Replace can still clean up. The same
1254
1314
  // row for a refusal that leaves nothing to wait for (a block stamped for another tool, a copy that turned out
1255
1315
  // edited): the host is opted out, and no removal is kept open over a file that was never SynaBun's to take.
1256
- // `paths` are places a copy of the rules is: config.json, which a refusal can name, is not one of them.
1316
+ // `paths` are places a copy of the rules is: opencode.json, which a refusal can name, is not one of them.
1257
1317
  const config = host === 'opencode' ? layout().opencodeConfig : null;
1258
1318
  Object.assign(row, {
1259
1319
  managed: false, installedVersion: null, installedSha: null, path: primary.path,
@@ -1349,7 +1409,11 @@ export function createRulesetInstaller({
1349
1409
  const config = host === 'opencode' ? readOpencodeConfig() : null;
1350
1410
  if (config?.error) { states[host] = 'error'; continue; }
1351
1411
  const first = isDir(primary.dir) ? inspect(host, primary, expected) : { status: 'missing' };
1352
- if (first.status === 'missing' || (config && !config.hasEntry)) {
1412
+ // Listed by an older SynaBun in OpenCode 1's config.json only: moved to opencode.json, never an opt-out. A copy
1413
+ // config.json does not list any more is not moved: the user took it out, which is the opt-out below.
1414
+ const older = config && first.status !== 'missing' && !config.hasEntry ? opencode1Record(row) : null;
1415
+ const moving = older !== null && opencode1Listed(older);
1416
+ if (first.status === 'missing' || (config && !config.hasEntry && !moving)) {
1353
1417
  // The user deleted it: an opt-out, never a reason to put it back. (A copy SynaBun's own removal took is
1354
1418
  // not this case: that removal is on record and was dealt with above.)
1355
1419
  Object.assign(row, { managed: false, optedOutAt: stamp() });
@@ -1358,6 +1422,7 @@ export function createRulesetInstaller({
1358
1422
  continue;
1359
1423
  }
1360
1424
  const tally = call.tally(host);
1425
+ if (moving) moveOpencode1Entry(row, tally);
1361
1426
  const known = new Set(row.paths.map((path) => realKey(path)));
1362
1427
  let primaryCurrent = first.status === 'current';
1363
1428
  for (const target of list) {
@@ -2,7 +2,7 @@
2
2
  // SynaBun — one entry of a JSON list, edited as text (pure, no fs)
3
3
  // ═══════════════════════════════════════════
4
4
  //
5
- // OpenCode's config.json belongs to the user. Parsing it and writing it back
5
+ // OpenCode's opencode.json belongs to the user. Parsing it and writing it back
6
6
  // would re-indent it, re-space it and drop whatever JSON.stringify spells
7
7
  // differently, all to add one string to one list. These two functions change
8
8
  // only the characters of that entry (and of the key, when SynaBun adds or takes
@@ -24,6 +24,7 @@ import {
24
24
  } from './db.js';
25
25
  import { parseLine } from './session-chunker.js';
26
26
  import { listCodexSessionsFromAccounts } from './codex-session-catalog.js';
27
+ import { OPENCODE_SESSION_TABLES, hasOpencodeSessionTables, v2MessageText } from './opencode-db-schema.js';
27
28
 
28
29
  const MAX_BODY = 256 * 1024;
29
30
  const MAX_MSG_CHARS = 8 * 1024;
@@ -380,20 +381,23 @@ export function rebuildCodexCache({ project, projects, accounts, onProgress } =
380
381
 
381
382
  // --- OpenCode ---
382
383
 
384
+ // OpenCode 2 keeps its sessions in session_v2 and their text in session_message rows
385
+ // (lib/opencode-db-schema.js); a file without those tables has nothing to index.
383
386
  export function rebuildOpencodeCache({ getOpencodeDb, onProgress } = {}) {
384
387
  const emit = onProgress || (() => {});
385
388
  if (typeof getOpencodeDb !== 'function') return { sessions: 0, updated: 0 };
386
389
 
387
390
  const ocdb = getOpencodeDb();
388
- if (!ocdb) return { sessions: 0, updated: 0 };
391
+ if (!ocdb || !hasOpencodeSessionTables(ocdb)) return { sessions: 0, updated: 0 };
392
+ const tables = OPENCODE_SESSION_TABLES;
389
393
 
390
394
  let sessions;
391
395
  try {
392
396
  sessions = ocdb.prepare(`
393
397
  SELECT s.id, s.title, s.directory, s.time_created, s.time_updated,
394
398
  p.worktree AS project_worktree,
395
- (SELECT COUNT(*) FROM message m WHERE m.session_id = s.id) AS message_count
396
- FROM session s
399
+ ${tables.messageCount} AS message_count
400
+ FROM ${tables.session} s
397
401
  LEFT JOIN project p ON s.project_id = p.id
398
402
  WHERE s.time_archived IS NULL
399
403
  `).all();
@@ -402,15 +406,19 @@ export function rebuildOpencodeCache({ getOpencodeDb, onProgress } = {}) {
402
406
  let total = sessions.length;
403
407
  let updated = 0;
404
408
 
405
- // OpenCode schema: message.data (JSON w/ role+metadata) + part.data (JSON w/ type+text).
406
- // Pull parts per message, decode JSON, grab text where type === 'text'.
409
+ // One session_message row per message, its text in `data` (v2MessageText); read as
410
+ // { part_id, part_created, pdata, mdata } rows.
407
411
  let partStmt;
408
412
  try {
409
- partStmt = ocdb.prepare(`SELECT p.id AS part_id, p.time_created AS part_created, p.data AS pdata, m.data AS mdata
410
- FROM part p
411
- LEFT JOIN message m ON m.id = p.message_id
412
- WHERE p.session_id = ?
413
- ORDER BY p.time_created ASC`);
413
+ const rows = ocdb.prepare(`SELECT id, type, time_created, data FROM session_message
414
+ WHERE session_id = ? AND type IN ('user', 'assistant')
415
+ ORDER BY seq ASC`);
416
+ partStmt = {
417
+ all: (sessionId) => rows.all(sessionId).map((row) => {
418
+ const said = v2MessageText(row.type, row.data);
419
+ return said ? { part_id: row.id, part_created: row.time_created, pdata: JSON.stringify({ type: 'text', text: said.text }), mdata: JSON.stringify({ role: said.role }) } : null;
420
+ }).filter(Boolean),
421
+ };
414
422
  } catch { partStmt = null; }
415
423
 
416
424
  for (const row of sessions) {
@@ -111,10 +111,32 @@ async function generateClaudeTitle(input, deps) {
111
111
  }
112
112
  }
113
113
 
114
+ /**
115
+ * Why a `codex exec` title run failed, in one short line: never its command
116
+ * line (the arguments name the project folder) and never its whole stderr.
117
+ */
118
+ export function codexTitleFailure(error) {
119
+ const lines = String(error?.stderr || '').split(/\r?\n/).map(line => line.trim())
120
+ .filter(line => line && !/^Reading (?:prompt|additional input) from stdin/i.test(line));
121
+ const said = lines.length ? `: ${lines.at(-1).slice(0, 200)}` : '';
122
+ if (error?.code === 'ERR_CHILD_PROCESS_STDIO_MAXBUFFER') return new Error('codex exec wrote more than its title run may');
123
+ if (error?.killed || error?.signal === 'SIGTERM') return new Error(`codex exec did not answer within ${SESSION_TITLE_TIMEOUT_MS / 1000} s${said}`);
124
+ if (error?.code === 'ENOENT') return new Error('codex was not found');
125
+ const status = Number.isInteger(error?.code) ? `exit code ${error.code}` : error?.code || error?.signal || 'an error';
126
+ return new Error(`codex exec failed (${status})${said}`);
127
+ }
128
+
114
129
  async function generateCodexTitle(input, deps) {
115
130
  if (typeof deps.execFile !== 'function' || typeof deps.getCodexBin !== 'function') {
116
131
  throw new Error('Codex title runner is unavailable');
117
132
  }
133
+ // The prompt goes in on stdin, which is then ended, as the Codex SDK does,
134
+ // never as an argument. `codex exec` reads stdin whenever it is not a
135
+ // terminal: given a prompt argument it waits for stdin to end to add it to
136
+ // the prompt ("Reading additional input from stdin..."), so an open pipe held
137
+ // every title request until its timeout, whose error message then carried
138
+ // the whole command line (the person's prompt) into the server log. Windows
139
+ // also limits a command line to 32,767 characters.
118
140
  const args = [
119
141
  'exec', '--ephemeral', '--skip-git-repo-check', '--ignore-rules',
120
142
  '--sandbox', 'read-only', '--color', 'never', '--json',
@@ -125,20 +147,39 @@ async function generateCodexTitle(input, deps) {
125
147
  if (input.model) args.push('-m', input.model);
126
148
  const effort = codexReasoningEffort(input.effort);
127
149
  if (effort) args.push('-c', `model_reasoning_effort="${effort}"`);
128
- args.push(titlePrompt(input));
129
150
  let env = {
130
151
  ...(deps.env || process.env),
131
152
  CODEX_HOME: deps.getCodexAccountHome?.(input.accountId || 'default'),
132
153
  };
133
154
  if (typeof deps.getAugmentedPath === 'function') env = withPathEnv(env, deps.getAugmentedPath());
134
- const { stdout } = await deps.execFile(deps.getCodexBin(), args, {
155
+ // util.promisify(execFile) hands the child over as `.child`.
156
+ const running = deps.execFile(deps.getCodexBin(), args, {
135
157
  cwd: input.cwd || process.cwd(),
136
158
  env,
137
159
  timeout: SESSION_TITLE_TIMEOUT_MS,
138
160
  maxBuffer: 2 * 1024 * 1024,
139
161
  windowsHide: true,
140
162
  });
141
- return extractCodexText(stdout);
163
+ // Handled before anything else is done with the child: the run rejects when codex fails, is stopped or times out,
164
+ // and a rejection nobody handles ends the server (server.js handleProcessFailure).
165
+ const settled = Promise.resolve(running).then(result => ({ result }), error => ({ error }));
166
+ try {
167
+ const stdin = running?.child?.stdin;
168
+ if (stdin) {
169
+ // A Codex that ended before reading it: its exit says why, not this pipe.
170
+ stdin.on?.('error', () => {});
171
+ stdin.end(titlePrompt(input));
172
+ }
173
+ } catch (error) {
174
+ // The prompt could not be handed over: the run is stopped (it would wait for its stdin until the timeout) and
175
+ // its end awaited, never left behind.
176
+ try { running?.child?.kill?.(); } catch {}
177
+ await settled;
178
+ throw new Error(`codex exec could not be given the prompt (${error?.code || 'stdin'})`);
179
+ }
180
+ const { result, error } = await settled;
181
+ if (error) throw codexTitleFailure(error);
182
+ return extractCodexText(result?.stdout);
142
183
  }
143
184
 
144
185
  async function generateOpenCodeTitle(input, deps) {
@@ -152,24 +193,24 @@ async function generateOpenCodeTitle(input, deps) {
152
193
  const timer = setTimeout(() => controller.abort(new Error('Session title request timed out')), SESSION_TITLE_TIMEOUT_MS);
153
194
  timer.unref?.();
154
195
  let sessionId = null;
196
+ // The client's one-shot generator when the model allows it (OpenCode's free
197
+ // tier answers it 503), else a temporary session whose rules deny every tool:
198
+ // OpenCode has no tool switch per prompt.
199
+ try {
200
+ const generated = await deps.openCodeClient.getClient?.()?.generate?.({
201
+ prompt: `${TITLE_SYSTEM_PROMPT}\n\n${titlePrompt(input)}`,
202
+ model: input.model || undefined,
203
+ directory: input.cwd || undefined,
204
+ signal: controller.signal,
205
+ });
206
+ const text = String(generated?.data?.text || '').trim();
207
+ if (!generated?.error && text) { clearTimeout(timer); return text; }
208
+ } catch { /* the session below */ }
155
209
  try {
156
- const toolIds = new Set([
157
- 'bash', 'edit', 'write', 'patch', 'apply_patch', 'multiedit', 'read',
158
- 'glob', 'grep', 'list', 'task', 'webfetch', 'question', 'skill',
159
- 'todowrite', 'todoread',
160
- ]);
161
- try {
162
- const toolResult = await deps.openCodeClient.getClient?.()?.tool?.ids(
163
- { directory: input.cwd || undefined },
164
- { signal: controller.signal },
165
- );
166
- for (const id of (toolResult?.data || [])) if (id) toolIds.add(String(id));
167
- } catch {}
168
- const disabledTools = Object.fromEntries([...toolIds].map((id) => [id, false]));
169
-
170
210
  const created = await deps.openCodeClient.session.create({
171
211
  directory: input.cwd || undefined,
172
212
  title: 'SessionTitleDraft',
213
+ permission: [{ action: '*', resource: '*', effect: 'deny' }],
173
214
  });
174
215
  sessionId = created?.data?.id || created?.data?.sessionID || created?.id || created?.sessionID;
175
216
  if (!sessionId) throw new Error('OpenCode did not create a temporary title session');
@@ -181,7 +222,6 @@ async function generateOpenCodeTitle(input, deps) {
181
222
  variant: input.variant || undefined,
182
223
  system: TITLE_SYSTEM_PROMPT,
183
224
  directory: input.cwd || undefined,
184
- tools: disabledTools,
185
225
  signal: controller.signal,
186
226
  });
187
227
  return extractOpenCodeText(response);