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
@@ -16,12 +16,12 @@ export function readOpenCodeSessionLink(event = {}) {
16
16
  };
17
17
  }
18
18
 
19
- export function bindOpenCodeChildSessionProfile({
19
+ export function bindOpenCodeChildSessionTools({
20
20
  eventType,
21
21
  event,
22
22
  sourceRuntime,
23
23
  sessionToRuntime,
24
- sessionProfiles,
24
+ sessionTools,
25
25
  runtimes,
26
26
  }) {
27
27
  if (!CHILD_LINK_EVENT_TYPES.has(eventType)) return { bound: false, reason: 'event-type' };
@@ -41,10 +41,10 @@ export function bindOpenCodeChildSessionProfile({
41
41
  runtimes?.get(previousRuntimeId)?.sessions?.delete(childSessionId);
42
42
  }
43
43
 
44
- const profile = sourceRuntime.mcpProfile || sessionProfiles?.get(parentSessionId) || null;
44
+ const tools = sourceRuntime.tools || sessionTools?.get(parentSessionId) || null;
45
45
  sessionToRuntime.set(childSessionId, sourceRuntimeId);
46
- if (profile) sessionProfiles.set(childSessionId, profile);
47
- else sessionProfiles.delete(childSessionId);
46
+ if (tools) sessionTools.set(childSessionId, tools);
47
+ else sessionTools.delete(childSessionId);
48
48
  sourceRuntime.sessions?.add(childSessionId);
49
49
 
50
50
  return {
@@ -52,27 +52,27 @@ export function bindOpenCodeChildSessionProfile({
52
52
  childSessionId,
53
53
  parentSessionId,
54
54
  runtimeId: sourceRuntimeId,
55
- profile,
55
+ tools,
56
56
  };
57
57
  }
58
58
 
59
59
  /**
60
- * The MCP profile a sub-agent panel starts with: its parent's. The primary
60
+ * The MCP tools a sub-agent panel starts with: its parent's. The primary
61
61
  * panel's store speaks for the parent only while it is bound to that parent
62
- * (`parentSessionId`): after a switch its profile is another session's, and
63
- * then the parent's saved choice (`savedProfile(parentSessionId)`) or what the
62
+ * (`parentSessionId`): after a switch its tools is another session's, and
63
+ * then the parent's saved choice (`savedTools(parentSessionId)`) or what the
64
64
  * child session itself carries is used. Without `parentSessionId` the parent
65
65
  * store is trusted as before.
66
66
  */
67
- export function inheritChildPanelMcpProfile(childStore, parentStore, childInfo = null, { parentSessionId, savedProfile } = {}) {
67
+ export function inheritChildPanelTools(childStore, parentStore, childInfo = null, { parentSessionId, savedTools } = {}) {
68
68
  const parentState = parentStore?.getState?.() || null;
69
69
  const parentIsBound = !parentSessionId || parentState?.sessionId === parentSessionId;
70
- const parentProfile = parentIsBound ? (parentState?.mcpProfile || null) : null;
70
+ const parentTools = parentIsBound ? (parentState?.tools || null) : null;
71
71
  let saved = null;
72
- if (!parentProfile && parentSessionId && typeof savedProfile === 'function') {
73
- try { saved = savedProfile(parentSessionId) || null; } catch { saved = null; }
72
+ if (!parentTools && parentSessionId && typeof savedTools === 'function') {
73
+ try { saved = savedTools(parentSessionId) || null; } catch { saved = null; }
74
74
  }
75
- const profile = parentProfile || saved || childInfo?.mcpProfile || null;
76
- if (profile) childStore?.setMcpProfile?.(profile);
77
- return profile;
75
+ const tools = parentTools || saved || childInfo?.tools || null;
76
+ if (tools) childStore?.setTools?.(tools);
77
+ return tools;
78
78
  }
@@ -6,6 +6,7 @@
6
6
  // listeners (used by the panel manager to spawn child panels).
7
7
  // ─────────────────────────────────────────────────────────────────────────────
8
8
 
9
+ import { createOutcomeNotifications } from './ocp-v2-outcome-notifications.js';
9
10
  import { getDefaultStore } from './ocp-v2-state.js';
10
11
  import { notify as uiNotify, NOTIF_TYPE } from '../ui-notifications.js';
11
12
  import { nativeLoopWindowId } from '../ui-native-window-id.js';
@@ -13,30 +14,20 @@ import { registerAutomationSession } from './ocp-v2-automation-ownership.js';
13
14
  import { applyEvent, resolveEventTargets } from './ocp-v2-events.js';
14
15
  import { createCapabilities, gatedRequest } from './ocp-v2-caps.js';
15
16
  import { shouldAutoAccept, autoAcceptRequest, autoAcceptInherited } from './ocp-v2-approvals.js';
16
- import { verifyDescendant, knownDescendant, createReconnectNotifier, requestOwner } from './ocp-v2-rehydrate.js';
17
+ import { verifyDescendant, descendantState, knownDescendant, createReconnectNotifier, requestOwner } from './ocp-v2-rehydrate.js';
18
+ import { createAskTracker, createTurnClock, readOpenAsks, unreadAsksNotice, TURN_LIMIT_MS } from './ocp-v2-send-logic.js';
17
19
 
18
20
  // Request types the connected server answers. Empty against a server that
19
21
  // predates the list; cleared on every disconnect and refilled on reconnect.
20
22
  export const capabilities = createCapabilities();
21
23
  export const supports = (...types) => capabilities.hasAll(...types);
22
- // The @opencode-ai/sdk version the server answered `init` with ('' from a
23
- // server that does not say).
24
- let _sdkVersion = '';
25
- export const sdkVersion = () => _sdkVersion;
26
24
 
27
25
  const _notifiedPermissionIds = new Set();
28
- // Per-store DONE/ERROR dedup: once an outcome fires for a turn, suppress
29
- // duplicates until the next time `running` flips back to true (new turn).
30
- // ERROR locks out future DONE; DONE allows a later ERROR through.
31
- const _outcomeKey = new WeakMap(); // store → NOTIF_TYPE.DONE | NOTIF_TYPE.ERROR
32
- const _outcomeSubscribed = new WeakSet(); // stores already wired for reset
26
+ const _outcomes = createOutcomeNotifications();
33
27
 
34
28
  function _fireOutcomeNotify(store, type) {
35
- const last = _outcomeKey.get(store);
36
- if (last === type) return;
37
- if (last === NOTIF_TYPE.ERROR && type === NOTIF_TYPE.DONE) return;
38
- _outcomeKey.set(store, type);
39
29
  const s = store.getState();
30
+ if (!_outcomes.take(s, type === NOTIF_TYPE.ERROR ? 'error' : 'done')) return;
40
31
  const baseLabel = s.sessionInfo?.title || s.sessionInfo?.info?.title || 'OpenCode';
41
32
  const label = s.parentSessionId ? `↳ ${baseLabel}` : baseLabel;
42
33
  try {
@@ -44,18 +35,6 @@ function _fireOutcomeNotify(store, type) {
44
35
  } catch (err) { console.warn('[ocp-v2-ws] outcome notify failed', err); }
45
36
  }
46
37
 
47
- function _ensureOutcomeReset(store) {
48
- if (_outcomeSubscribed.has(store)) return;
49
- _outcomeSubscribed.add(store);
50
- try {
51
- store.subscribe((event, state) => {
52
- if (event?.type === 'running:set' && state.running) {
53
- _outcomeKey.delete(store);
54
- }
55
- });
56
- } catch (err) { console.warn('[ocp-v2-ws] outcome subscribe failed', err); }
57
- }
58
-
59
38
  let _ws = null;
60
39
  let _connecting = null;
61
40
  let _reqSeq = 0;
@@ -99,6 +78,7 @@ export async function connect() {
99
78
  catch (err) { console.warn('[ocp-v2-ws] identify failed', err); }
100
79
  _connecting = null;
101
80
  _reconnects.opened();
81
+ asksOpened();
102
82
  resolve(ws);
103
83
  });
104
84
 
@@ -114,7 +94,11 @@ export async function connect() {
114
94
  _connecting = null;
115
95
  capabilities.clear();
116
96
  _reconnects.closed();
117
- for (const [, p] of _pending) p.reject(new Error('websocket closed'));
97
+ for (const [, p] of _pending) { p.timeout.cancel(); p.reject(new Error('websocket closed')); }
98
+ // What waits on the user is not known again until the server's lists are read after the reconnect
99
+ // (rebuildAsks): until then no turn's clock counts. A socket that never opened lost nothing.
100
+ if (opened) _asks.hold();
101
+ asksClosed();
118
102
  _pending.clear();
119
103
  broadcastServerStatus({ status: 'reconnecting' });
120
104
  setTimeout(() => { connect().catch(() => {}); }, 1500);
@@ -139,6 +123,21 @@ function broadcastServerStatus(payload) {
139
123
  for (const store of _allStores) store.setServerStatus(payload);
140
124
  }
141
125
 
126
+ // Why OpenCode cannot be used, as the server says it (an OpenCode version
127
+ // SynaBun does not drive, a port held by an OpenCode server it did not start,
128
+ // a web page where the API should be): one line in each panel's error list,
129
+ // never a second copy of the same sentence while the panel keeps retrying.
130
+ function broadcastServerProblem(text) {
131
+ const message = typeof text === 'string' ? text.trim().slice(0, 600) : '';
132
+ if (!message) return;
133
+ const stores = _allStores.size ? [..._allStores] : [getDefaultStore()];
134
+ for (const store of stores) {
135
+ const errors = store.getState?.().errors || [];
136
+ if (errors.some((err) => err?.message === message)) continue;
137
+ store.pushError?.({ message, kind: 'server' });
138
+ }
139
+ }
140
+
142
141
  export function disconnect() {
143
142
  if (_ws) {
144
143
  try { _ws.close(); } catch {}
@@ -152,7 +151,6 @@ export function disconnect() {
152
151
  export function subscribeSession(sessionId, store) {
153
152
  if (!store) return () => {};
154
153
  _allStores.add(store);
155
- _ensureOutcomeReset(store);
156
154
  if (!sessionId) {
157
155
  // Not yet bound — caller should call again once a session exists.
158
156
  return () => { _allStores.delete(store); };
@@ -160,6 +158,7 @@ export function subscribeSession(sessionId, store) {
160
158
  let set = _storesBySession.get(sessionId);
161
159
  if (!set) { set = new Set(); _storesBySession.set(sessionId, set); }
162
160
  set.add(store);
161
+ readAsksOf(sessionId);
163
162
  return () => {
164
163
  const s = _storesBySession.get(sessionId);
165
164
  if (s) {
@@ -195,6 +194,7 @@ function handleMessage(msg) {
195
194
  // Broadcast to every registered store; also poke the default singleton
196
195
  // so legacy callers (no panel registered yet) still see status.
197
196
  broadcastServerStatus(payload);
197
+ if (msg.status === 'error' && msg.error) broadcastServerProblem(msg.error);
198
198
  return;
199
199
  }
200
200
 
@@ -206,6 +206,7 @@ function handleMessage(msg) {
206
206
  if (msg.type === 'capabilities') {
207
207
  capabilities.set(msg.capabilities);
208
208
  _reconnects.capabilities();
209
+ asksReady();
209
210
  return;
210
211
  }
211
212
 
@@ -216,6 +217,7 @@ function handleMessage(msg) {
216
217
  if (msg.nativeRunId && msg.nativeRootSessionId) {
217
218
  registerAutomationSession(msg.nativeRootSessionId, msg.nativeRunId);
218
219
  }
220
+ _asks.note(msg.eventType, msg.event || {});
219
221
  handleEvent(msg.eventType, msg.event || {});
220
222
  fanout(msg.eventType, msg.event || {});
221
223
  return;
@@ -224,10 +226,11 @@ function handleMessage(msg) {
224
226
  if (msg.id != null && _pending.has(msg.id)) {
225
227
  const p = _pending.get(msg.id);
226
228
  _pending.delete(msg.id);
227
- clearTimeout(p.timeout);
229
+ p.timeout.cancel();
228
230
  if (msg.type === 'init:result') {
229
231
  capabilities.set(msg.capabilities);
230
- if (typeof msg.sdkVersion === 'string') _sdkVersion = msg.sdkVersion;
232
+ if (msg.ready === false && msg.problem) broadcastServerProblem(msg.problem);
233
+ asksReady();
231
234
  }
232
235
  p.resolve(msg);
233
236
  return;
@@ -265,6 +268,18 @@ function handleEvent(eventType, ev) {
265
268
  // Lets a sub-agent's permission or question reach the panel of its parent
266
269
  // when no child panel is open for it.
267
270
  const _parentOf = new Map();
271
+
272
+ // Requests that wait on the user, by session (a sub-agent's count for its parent): a turn's send does not
273
+ // count the time they wait (createTurnClock). A permission left open for more than 30 minutes used to end
274
+ // the turn's send with "request timeout: message:send" while the turn went on in OpenCode. Across a lost
275
+ // socket they are held from the close and read again from the server after the reconnect (rebuildAsks); a
276
+ // session a panel is bound to after the page loaded has its own read once (readAsksOf).
277
+ const _asks = createAskTracker({ parentOf: _parentOf });
278
+ /** True while `sessionId`, or a sub-agent below it, waits on a permission or a question. */
279
+ export const sessionWaitsOnUser = (sessionId) => _asks.waits(sessionId);
280
+ /** `listener()` whenever what waits on the user may have changed; returns an unsubscribe. */
281
+ export const onAsksChanged = (listener) => _asks.subscribe(listener);
282
+
268
283
  function rememberParent(ev) {
269
284
  const info = ev?.info || ev?.session || ev || {};
270
285
  const childId = info.id || ev?.sessionID || ev?.sessionId;
@@ -316,15 +331,19 @@ const _rootSessions = new Set();
316
331
  * from the session itself. Anything that cannot be established is false.
317
332
  */
318
333
  export function isDescendantSession(sessionId, ancestorId) {
319
- return verifyDescendant(sessionId, ancestorId, {
320
- parentOf: _parentOf,
321
- roots: _rootSessions,
322
- fetchParent: async (id) => {
323
- const res = await api.sessionGet(id);
324
- if (!res || res.error || (typeof res.status === 'number' && res.status >= 400) || !res.data?.id) return null;
325
- return String(res.data.parentID || res.data.parentId || '');
326
- },
327
- });
334
+ return verifyDescendant(sessionId, ancestorId, { parentOf: _parentOf, roots: _rootSessions, fetchParent: fetchSessionParent });
335
+ }
336
+
337
+ // The same question with "could not be read" kept apart from "no" (true, false or null): what the open
338
+ // requests read from the server need, so that a sub-agent whose place is unknown keeps its parent waiting.
339
+ function sessionAncestry(sessionId, ancestorId) {
340
+ return descendantState(sessionId, ancestorId, { parentOf: _parentOf, roots: _rootSessions, fetchParent: fetchSessionParent });
341
+ }
342
+
343
+ async function fetchSessionParent(id) {
344
+ const res = await api.sessionGet(id);
345
+ if (!res || res.error || (typeof res.status === 'number' && res.status >= 400) || !res.data?.id) return null;
346
+ return String(res.data.parentID || res.data.parentId || '');
328
347
  }
329
348
 
330
349
  /**
@@ -336,11 +355,135 @@ export function isKnownDescendantSession(sessionId, ancestorId) {
336
355
  return knownDescendant(sessionId, ancestorId, _parentOf);
337
356
  }
338
357
 
358
+ // ── What waits on the user, read from the server ───────────────────────────
359
+ // The stream says what is asked and answered while the socket is up. What was asked before (the page loaded,
360
+ // a panel was bound to another session, the socket was down) is read from the server (permission:list and
361
+ // question:list), one session at a time: its clocks wait until then. After a
362
+ // reconnect every bound session is read again (rebuildAsks). A list that cannot be read is read again a few
363
+ // times; then the session's clocks count again and its panel says so (noteUnreadAsks).
364
+
365
+ // A sub-agent runs on its parent's serve, in its folder: a bound parent's lists hold its requests too.
366
+ function underSession(sessionId, isAncestor) {
367
+ let cursor = parentSessionOf(sessionId);
368
+ for (let depth = 0; cursor && depth < 12; depth++) {
369
+ if (isAncestor(cursor)) return true;
370
+ cursor = parentSessionOf(cursor);
371
+ }
372
+ return false;
373
+ }
374
+
375
+ // The sessions whose lists were read (or are out) since the socket opened.
376
+ const _asksRead = new Set();
377
+ // Bound sessions waiting for the socket to say what it serves before their lists are read.
378
+ const _asksUnread = new Set();
379
+ let _asksReady = false;
380
+ let _asksReadyTimer = null;
381
+ let _asksFlushTimer = null;
382
+ const asksKnown = (sessionId) => _asksRead.has(sessionId) || underSession(sessionId, (id) => _asksRead.has(id));
383
+
384
+ function askSession(sessionId, kinds) {
385
+ const s = [...(_storesBySession.get(sessionId) || [])][0]?.getState?.() || {};
386
+ return { sessionId, cwd: s.cwd || s.sessionInfo?.directory || undefined, ...(kinds ? { kinds } : {}) };
387
+ }
388
+
389
+ // `want`: null for every bound session (not one under another), else the sessions (and lists) to read.
390
+ // The first read of sessions bound at a page load (or later) looks up no sub-agent's place: the panel manager
391
+ // reads the session tree right then, for the pills, and the read again a second later finds the links it
392
+ // learned (a list holding a request whose place is not known yet is unresolved meanwhile: its session waits).
393
+ // After a reconnect the tree is known; only a sub-agent spawned during the outage is looked up.
394
+ function readAsks(want, { attempt = 1, partial = false } = {}) {
395
+ const bound = new Set(_storesBySession.keys());
396
+ const sessions = want
397
+ ? want.filter(({ sessionId }) => bound.has(sessionId)).map(({ sessionId, kinds }) => askSession(sessionId, kinds))
398
+ : [...bound].filter((sessionId) => !underSession(sessionId, (id) => bound.has(id))).map((sessionId) => askSession(sessionId));
399
+ for (const { sessionId } of sessions) _asksRead.add(sessionId);
400
+ return readOpenAsks(api, sessions, {
401
+ ancestry: sessionAncestry,
402
+ known: (owner, root) => knownDescendant(owner, root, _parentOf),
403
+ ...(partial && attempt === 1 ? { maxLookups: 0 } : {}),
404
+ });
405
+ }
406
+
407
+ // The tracker gave up on some lists: the panels of those sessions say that their clock counts again.
408
+ function noteUnreadAsks(result) {
409
+ if (!result) return;
410
+ const lost = result.unread
411
+ ? [..._storesBySession.keys()].map((sessionId) => ({ sessionId, kinds: undefined }))
412
+ : result.gaveUp || [];
413
+ for (const { sessionId, kinds } of lost) {
414
+ const message = unreadAsksNotice(kinds);
415
+ for (const store of _storesBySession.get(sessionId) || []) {
416
+ if ((store.getState?.().errors || []).some((err) => err?.message === message)) continue;
417
+ store.pushError?.({ message, notice: true });
418
+ }
419
+ }
420
+ }
421
+
422
+ function rebuildAsks() {
423
+ return _asks.rebuild(readAsks).then(noteUnreadAsks);
424
+ }
425
+
426
+ // A session a panel was bound to: unless its lists (or a bound parent's) were read since the socket opened,
427
+ // its clocks wait from now and its lists are read once the socket can serve them.
428
+ function readAsksOf(sessionId) {
429
+ if (!sessionId || asksKnown(sessionId) || _asksUnread.has(sessionId)) return;
430
+ _asksUnread.add(sessionId);
431
+ _asks.expect([sessionId]);
432
+ flushAsksSoon();
433
+ }
434
+
435
+ function flushAsksSoon() {
436
+ if (_asksFlushTimer || !_asksReady || !_asksUnread.size) return;
437
+ _asksFlushTimer = setTimeout(() => {
438
+ _asksFlushTimer = null;
439
+ if (!_asksReady) return;
440
+ // Those no panel is bound to any more are let go by the tracker (not in its answer); those whose lists
441
+ // were read meanwhile (their own, or a bound parent's) wait for nothing more.
442
+ // A sub-agent read in the same go as its parent is read with it.
443
+ const batch = [..._asksUnread];
444
+ const known = batch.filter((sessionId) => _storesBySession.has(sessionId)
445
+ && (asksKnown(sessionId) || underSession(sessionId, (id) => id !== sessionId && batch.includes(id) && _storesBySession.has(id))));
446
+ const sessions = batch.filter((sessionId) => !known.includes(sessionId));
447
+ _asksUnread.clear();
448
+ if (known.length) _asks.release(known);
449
+ if (!sessions.length) return;
450
+ _asks.rebuild(readAsks, { sessions }).then(noteUnreadAsks)
451
+ .catch((err) => console.warn('[ocp-v2-ws] reading the open questions failed', err));
452
+ }, 0);
453
+ }
454
+
455
+ // The lists can be asked for once the socket said what it serves (capabilities, init:result), or, from a
456
+ // server that does not say, a moment after it opened.
457
+ function asksOpened() {
458
+ clearTimeout(_asksReadyTimer);
459
+ _asksReadyTimer = setTimeout(asksReady, 1500);
460
+ }
461
+
462
+ function asksReady() {
463
+ clearTimeout(_asksReadyTimer);
464
+ _asksReadyTimer = null;
465
+ if (!isConnected()) return;
466
+ _asksReady = true;
467
+ flushAsksSoon();
468
+ }
469
+
470
+ // (A session still to be read stays so: a socket that never opened read nothing, and after a reconnect
471
+ // rebuildAsks reads every bound session anyway.)
472
+ function asksClosed() {
473
+ clearTimeout(_asksReadyTimer);
474
+ clearTimeout(_asksFlushTimer);
475
+ _asksReadyTimer = null;
476
+ _asksFlushTimer = null;
477
+ _asksReady = false;
478
+ _asksRead.clear();
479
+ }
480
+
339
481
  // The socket came back after an outage: whatever was sent meanwhile reached no
340
482
  // panel. Listeners re-read their session (the primary panel does it through its
341
483
  // auto-heal; the panel manager does it for the sub-agent panel).
342
484
  const _reconnectListeners = new Set();
343
485
  const _reconnects = createReconnectNotifier(() => {
486
+ rebuildAsks().catch((err) => console.warn('[ocp-v2-ws] reading the open questions again failed', err));
344
487
  for (const fn of _reconnectListeners) {
345
488
  try { fn(); } catch (e) { console.warn('[ocp-v2-ws] reconnect listener error', e); }
346
489
  }
@@ -462,14 +605,23 @@ function fanout(eventType, ev) {
462
605
 
463
606
  // ── Request/response (id-correlated, 30s default timeout) ──
464
607
 
465
- function request(payload, timeoutMs = 30000) {
608
+ // `turnOf`: the session whose turn the request waits for (a prompt, a command). Its clock stops while that
609
+ // session waits on the user, so only working time counts toward `timeoutMs` (createTurnClock).
610
+ function request(payload, timeoutMs = 30000, { turnOf = '' } = {}) {
466
611
  return new Promise(async (resolve, reject) => {
467
612
  try { await connect(); } catch (e) { return reject(e); }
468
613
  const id = ++_reqSeq;
469
- const timeout = setTimeout(() => {
614
+ const expire = () => {
470
615
  _pending.delete(id);
471
616
  reject(new Error(`request timeout: ${payload.type}`));
472
- }, timeoutMs);
617
+ };
618
+ let timeout;
619
+ if (turnOf) {
620
+ timeout = createTurnClock({ ms: timeoutMs, paused: () => sessionWaitsOnUser(turnOf), subscribe: onAsksChanged, onExpire: expire });
621
+ } else {
622
+ const timer = setTimeout(expire, timeoutMs);
623
+ timeout = { cancel: () => clearTimeout(timer) };
624
+ }
473
625
  _pending.set(id, { resolve, reject, timeout });
474
626
  _ws.send(JSON.stringify({ ...payload, id }));
475
627
  });
@@ -487,17 +639,17 @@ export const api = {
487
639
  sessionMessages:(sessionId) => request({ type: 'session:messages', sessionId }),
488
640
  sessionContext: ({ sessionId, cwd } = {}) => request({ type: 'session:context', sessionId, cwd }),
489
641
  // `human` / `greetingId`: lib/greeting/ (a server that does not know them ignores them).
490
- send: ({ sessionId, parts, model, agent, mode, variant, cwd, mcpProfile, noAbortPrev, human, greetingId }) =>
491
- request({ type: 'message:send', sessionId, parts, model, agent, mode, variant, cwd, mcpProfile, noAbortPrev: !!noAbortPrev, ...(human ? { human: true } : {}), ...(greetingId ? { greetingId } : {}) }, 30 * 60 * 1000),
642
+ send: ({ sessionId, parts, model, agent, mode, variant, cwd, tools, noAbortPrev, human, greetingId }) =>
643
+ request({ type: 'message:send', sessionId, parts, model, agent, mode, variant, cwd, tools, noAbortPrev: !!noAbortPrev, ...(human ? { human: true } : {}), ...(greetingId ? { greetingId } : {}) }, TURN_LIMIT_MS, { turnOf: sessionId }),
492
644
  abort: (sessionId) => request({ type: 'message:abort', sessionId }),
493
- compact: ({ sessionId, cwd, mcpProfile, model } = {}) => request({ type: 'session:compact', sessionId, cwd, mcpProfile, model }, 5 * 60 * 1000),
645
+ compact: ({ sessionId, cwd, tools } = {}) => request({ type: 'session:compact', sessionId, cwd, tools }, 5 * 60 * 1000),
494
646
  permissionReply: ({ sessionId, permissionId, response, cwd, message }) =>
495
647
  request({ type: 'permission:reply', sessionId, permissionId, response, cwd, message }),
496
648
  questionList: ({ cwd, sessionId } = {}) => request({ type: 'question:list', cwd, sessionId }),
497
649
  questionReply: ({ requestId, answers, cwd, sessionId }) => request({ type: 'question:reply', requestId, answers, cwd, sessionId }),
498
650
  questionReject: ({ requestId, sessionId }) => request({ type: 'question:reject', requestId, sessionId }),
499
- mcpProfileGet: (sessionId) => request({ type: 'mcp:profile:get', sessionId }),
500
- mcpProfileSet: (sessionId, profile) => request({ type: 'mcp:profile:set', sessionId, profile }, 45_000),
651
+ toolsGet: (sessionId) => gated({ type: 'mcp:tools:get', sessionId }),
652
+ toolsSet: (sessionId, tools) => gated({ type: 'mcp:tools:set', sessionId, tools }, 45_000),
501
653
 
502
654
  // ── Newer request types: sent only when the server lists them (see
503
655
  // ocp-v2-caps.js); otherwise they resolve { ok:false, unsupported:true }.
@@ -508,16 +660,12 @@ export const api = {
508
660
  sessionUnrevert: ({ sessionId, cwd } = {}) => gated({ type: 'session:unrevert', sessionId, cwd }),
509
661
  sessionFork: ({ sessionId, messageID, cwd } = {}) => gated({ type: 'session:fork', sessionId, messageID, cwd }),
510
662
  sessionChildren: ({ sessionId, cwd } = {}) => gated({ type: 'session:children', sessionId, cwd }),
511
- sessionShare: ({ sessionId, cwd } = {}) => gated({ type: 'session:share', sessionId, cwd }),
512
- sessionUnshare: ({ sessionId, cwd } = {}) => gated({ type: 'session:unshare', sessionId, cwd }),
513
- sessionSharePolicy: ({ cwd } = {}) => gated({ type: 'session:share:policy', cwd }),
514
- messageDelete: ({ sessionId, messageID, cwd } = {}) => gated({ type: 'message:delete', sessionId, messageID, cwd }),
515
663
  commandList: ({ cwd } = {}) => gated({ type: 'command:list', cwd }),
516
664
  // A command is a turn: it can run as long as a prompt does.
517
- commandRun: ({ sessionId, command, arguments: args, agent, model, variant, parts, cwd, mcpProfile } = {}) =>
518
- gated({ type: 'command:run', sessionId, command, arguments: args, agent, model, variant, parts, cwd, mcpProfile }, 30 * 60 * 1000),
519
- sessionShell: ({ sessionId, command, agent, model, cwd, mcpProfile } = {}) =>
520
- gated({ type: 'session:shell', sessionId, command, agent, model, cwd, mcpProfile }, 10 * 60 * 1000),
665
+ commandRun: ({ sessionId, command, arguments: args, agent, model, variant, parts, cwd, tools } = {}) =>
666
+ gated({ type: 'command:run', sessionId, command, arguments: args, agent, model, variant, parts, cwd, tools }, TURN_LIMIT_MS, { turnOf: sessionId }),
667
+ sessionShell: ({ sessionId, command, agent, model, cwd, tools } = {}) =>
668
+ gated({ type: 'session:shell', sessionId, command, agent, model, cwd, tools }, 10 * 60 * 1000),
521
669
  findFiles: ({ query, cwd, dirs } = {}) => gated({ type: 'find:files', query, cwd, dirs }, 10000),
522
670
  findSymbols: ({ sessionId, query, cwd } = {}) => gated({ type: 'find:symbols', sessionId, query, cwd }, 10000),
523
671
  resourceList: ({ sessionId, cwd } = {}) => gated({ type: 'resource:list', sessionId, cwd }, 15000),
@@ -527,20 +675,15 @@ export const api = {
527
675
  vcsGet: ({ cwd } = {}) => gated({ type: 'vcs:get', cwd }),
528
676
  vcsStatus: ({ cwd } = {}) => gated({ type: 'vcs:status', cwd }),
529
677
  vcsDiff: ({ cwd, mode } = {}) => gated({ type: 'vcs:diff', cwd, mode }, 60_000),
530
- worktreeList: ({ cwd } = {}) => gated({ type: 'worktree:list', cwd }),
531
- worktreeCreate: ({ cwd, name } = {}) => gated({ type: 'worktree:create', cwd, name }, 60_000),
532
- worktreeRemove: ({ cwd, directory } = {}) => gated({ type: 'worktree:remove', cwd, directory }, 60_000),
533
678
  mcpStatus: ({ sessionId, cwd } = {}) => gated({ type: 'mcp:status', sessionId, cwd }),
534
679
  mcpConnect: ({ sessionId, name, cwd } = {}) => gated({ type: 'mcp:connect', sessionId, name, cwd }, 60_000),
535
680
  mcpDisconnect: ({ sessionId, name, cwd } = {}) => gated({ type: 'mcp:disconnect', sessionId, name, cwd }, 60_000),
536
- // OAuth: OpenCode opens the browser and waits for the callback.
537
- mcpAuthenticate: ({ sessionId, name, cwd } = {}) => gated({ type: 'mcp:authenticate', sessionId, name, cwd }, 5 * 60 * 1000 + 5000),
538
681
  // Registers a server on the serve running this session and, with `persist`,
539
682
  // saves it to the OpenCode config in the same request (see ocp-v2-status.js).
540
683
  mcpAdd: ({ sessionId, name, config, persist, cwd } = {}) => gated({ type: 'mcp:add', sessionId, name, config, persist: persist === true, cwd }, 60_000),
541
684
  envStatus: ({ sessionId, cwd } = {}) => gated({ type: 'env:status', sessionId, cwd }),
542
685
  };
543
686
 
544
- function gated(payload, timeoutMs) {
545
- return gatedRequest(capabilities, request, payload, timeoutMs);
687
+ function gated(payload, timeoutMs, options) {
688
+ return gatedRequest(capabilities, request, payload, timeoutMs, options);
546
689
  }
@@ -0,0 +1,39 @@
1
+ // ═══════════════════════════════════════════
2
+ // SynaBun Neural Interface — OpenCode's providers, as the pickers read them
3
+ // ═══════════════════════════════════════════
4
+ // GET /api/opencode/providers/full?view=compact: the connected providers only,
5
+ // with every field their models carry (the whole models.dev catalog is
6
+ // megabytes, and only Settings → OpenCode lists it). One copy in the data
7
+ // cache (data-cache.js) for every module that reads it: the OpenCode panel's
8
+ // model and variant pickers, its context gauge and composer, the Assistant's
9
+ // and the Studios' model lists. A provider change (`ocp-providers-changed`,
10
+ // which reaches every window: the OpenCode socket where a panel is open, the
11
+ // sync socket everywhere) drops it and asks for it again at once.
12
+
13
+ import { createDataCache } from './data-cache.js';
14
+ import { registerLaunchPrefetch } from './launch-prefetch.js';
15
+
16
+ export const OPENCODE_PROVIDERS_URL = '/api/opencode/providers/full?view=compact';
17
+
18
+ export const opencodeProviders = createDataCache('opencode-providers', {
19
+ ttlMs: 5 * 60_000,
20
+ persist: true,
21
+ load: async (_key, { force }) => {
22
+ const resp = await fetch(force ? `${OPENCODE_PROVIDERS_URL}&refresh=1` : OPENCODE_PROVIDERS_URL);
23
+ // A body that is not JSON (a web page) throws: nothing is kept.
24
+ return resp.json();
25
+ },
26
+ // Only a provider list is kept: `{ ok: false }` (the serve is not running, an error) never is.
27
+ accept: (body) => !!body && body.ok !== false && !!body.data && typeof body.data === 'object' && !Array.isArray(body.data),
28
+ });
29
+
30
+ /** The parsed body `{ ok, data: { all, default, connected } }`, connected providers only. */
31
+ export function fetchOpencodeProviders({ force = false } = {}) {
32
+ return opencodeProviders.get('', { force });
33
+ }
34
+
35
+ if (typeof document !== 'undefined') {
36
+ document.addEventListener('ocp-providers-changed', () => opencodeProviders.invalidate('', { refetch: true }));
37
+ // Launch: read once the page has painted, so the first OpenCode picker opens from it.
38
+ registerLaunchPrefetch('opencode-providers', () => opencodeProviders.prefetch(''), { order: 8, owner: true });
39
+ }
@@ -0,0 +1,96 @@
1
+ // ═══════════════════════════════════════════
2
+ // SynaBun — the page secret's recovery: an open tab outlives a server restart
3
+ // ═══════════════════════════════════════════
4
+ //
5
+ // The server tells the owner's own page from a local process by a secret it mints per boot and hands the page as
6
+ // an HttpOnly cookie (lib/page-session.js). The page's code never sees or sends that cookie: the browser does. A
7
+ // restart mints a new secret, and a tab that stayed open still carries the old cookie, so its first owner write
8
+ // (a dispatch, Protect workers, a route card, a Skills Studio install…) would come back 403 UI_ONLY or
9
+ // PAGE_SECRET_REQUIRED and the owner would have to reload. The owner wants zero friction, so this module wraps the
10
+ // page's fetch once: when a same-origin write is refused with one of those two codes, it asks GET /api/page-session
11
+ // (which sets this boot's cookie), then sends the very same request once more and hands back that answer. No
12
+ // reload, no toast (the toast fires on the error jsonFetch throws, and it throws only on the final answer), no lost
13
+ // action. Anything else (a read, another 403, a refusal the refresh did not cure, a body that cannot be sent
14
+ // twice) is handed back as it came, so nothing changes for a request this is not about.
15
+ //
16
+ // No imports and nothing done at load under Node: tests load it with node --test and a fake fetch. In a browser it
17
+ // installs itself on window.fetch when the page loads it (index.html, index2d.html and sidepanel-session.html load
18
+ // it as their first module script, before any module that writes), and once only.
19
+
20
+ /** The route that hands an open tab this boot's cookie (lib/page-session.js PAGE_SECRET_REFRESH_PATH). */
21
+ export const PAGE_SECRET_REFRESH_PATH = '/api/page-session';
22
+ /** The refusals that mean "the page secret is missing or stale", and nothing else. */
23
+ export const PAGE_SECRET_CODES = Object.freeze(['UI_ONLY', 'PAGE_SECRET_REQUIRED']);
24
+ const SAFE_METHODS = new Set(['GET', 'HEAD', 'OPTIONS']);
25
+
26
+ /** Whether an answer is the server refusing a write for want of this boot's page secret. */
27
+ export function isPageSecretRefusal(status, body) {
28
+ return Number(status) === 403 && !!body && typeof body === 'object' && PAGE_SECRET_CODES.includes(body.code);
29
+ }
30
+
31
+ /**
32
+ * What a request is, for the retry: its method, whether it is same-origin, and the arguments that send it again,
33
+ * or null when it is not a write, goes elsewhere, or cannot be sent twice (a streamed body).
34
+ */
35
+ export function replayPlan(input, init, origin = null) {
36
+ const isRequest = typeof Request !== 'undefined' && input instanceof Request;
37
+ const method = String(init?.method || (isRequest ? input.method : '') || 'GET').toUpperCase();
38
+ if (SAFE_METHODS.has(method)) return null;
39
+ const url = isRequest ? input.url : (input instanceof URL ? input.href : String(input ?? ''));
40
+ if (!sameOrigin(url, origin)) return null;
41
+ const body = init?.body;
42
+ if (body && typeof body === 'object' && typeof body.getReader === 'function') return null; // a stream is read once
43
+ // fetch(request) reads the request's body: a copy taken before the first send is what the second one sends.
44
+ const again = isRequest ? input.clone() : input;
45
+ return { method, url, args: init === undefined ? [again] : [again, init] };
46
+ }
47
+
48
+ function sameOrigin(url, origin) {
49
+ if (!/^[a-z][a-z0-9+.-]*:/i.test(url) && !url.startsWith('//')) return true; // a path of this page
50
+ if (!origin) return false;
51
+ try { return new URL(url).origin === new URL(origin).origin; } catch { return false; }
52
+ }
53
+
54
+ /**
55
+ * A fetch over `fetchImpl` that recovers the page secret once: the refresh is one request at a time (writes refused
56
+ * together share it), the refused request is sent again only when the refresh answered, and the second answer is
57
+ * final whatever it says.
58
+ */
59
+ export function createPageSessionFetch(fetchImpl, { refreshPath = PAGE_SECRET_REFRESH_PATH, origin = null, onRecover = null } = {}) {
60
+ if (typeof fetchImpl !== 'function') throw new TypeError('createPageSessionFetch needs a fetch');
61
+ let refreshing = null;
62
+ function refreshCookie() {
63
+ if (!refreshing) {
64
+ refreshing = (async () => {
65
+ try {
66
+ const res = await fetchImpl(refreshPath, { method: 'GET', credentials: 'same-origin', cache: 'no-store', headers: { Accept: 'application/json' } });
67
+ return !!res && res.ok === true;
68
+ } catch { return false; } finally { refreshing = null; }
69
+ })();
70
+ }
71
+ return refreshing;
72
+ }
73
+ return async function pageSessionFetch(input, init) {
74
+ const plan = replayPlan(input, init, origin);
75
+ const res = await fetchImpl(input, init);
76
+ if (!plan || !res || res.status !== 403 || typeof res.clone !== 'function') return res;
77
+ let body = null;
78
+ try { body = await res.clone().json(); } catch { return res; }
79
+ if (!isPageSecretRefusal(res.status, body)) return res;
80
+ if (!(await refreshCookie())) return res;
81
+ try { onRecover?.({ method: plan.method, url: plan.url, code: body.code }); } catch { /* a listener's own error */ }
82
+ return fetchImpl(...plan.args);
83
+ };
84
+ }
85
+
86
+ /** Wrap `target.fetch` (the window's) once; returns true when it did, false when it already had or there is none. */
87
+ export function installPageSessionRecovery(target = globalThis) {
88
+ if (!target || typeof target.fetch !== 'function' || target.__synabunPageSession) return false;
89
+ const original = target.fetch.bind(target);
90
+ const origin = target.location && typeof target.location.origin === 'string' ? target.location.origin : null;
91
+ target.fetch = createPageSessionFetch(original, { origin });
92
+ try { Object.defineProperty(target, '__synabunPageSession', { value: true, configurable: true }); } catch { target.__synabunPageSession = true; }
93
+ return true;
94
+ }
95
+
96
+ if (typeof window !== 'undefined' && typeof document !== 'undefined') installPageSessionRecovery(window);