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
@@ -15,14 +15,18 @@
15
15
  // reactive fallback); Assistant task runs' workers in
16
16
  // native-loop-providers.js (Claude),
17
17
  // assistant-brains/codex-browser-policy-hook.mjs and
18
- // assistant-brains/opencode-browser-policy.js
18
+ // assistant-brains/opencode2-browser-policy/
19
19
  //
20
20
  // Lexical, like remote-policy.js: a speed bump, not a sandbox. A shell that
21
21
  // builds a program name at run time, or a script loading a browser library
22
22
  // from a file SynaBun cannot read, gets past it. Mentions (rg playwright,
23
- // cat pw.cjs, sed -i … pw.cjs, git, code that only names a library) and a
24
- // project's own automated tests (npm test, node --test, vitest, jest, npx
25
- // playwright test run inside the project on files inside it) always pass.
23
+ // cat pw.cjs, sed -i … pw.cjs, git, code that only names a library), a
24
+ // syntax check (node --check <file>: Node parses it and runs nothing) and
25
+ // automated tests (npm test, node --test, vitest, jest, npx playwright test)
26
+ // run from inside one allowed project on files inside that same project
27
+ // always pass. The allowed projects are the session's own and the `roots` its
28
+ // caller passes: the registered SynaBun projects that are code projects
29
+ // (lib/browser-policy-roots.js, read by the caller as a run starts).
26
30
  // Computer use on a browser window is refused by the desktop guards
27
31
  // (lib/desktop/guards.js), which know the app a click or a key lands in.
28
32
  // Pure ESM with no imports of SynaBun's own, loaded by Node and by OpenCode's
@@ -68,6 +72,9 @@ function browserToolNames(tools) {
68
72
  };
69
73
  }
70
74
 
75
+ // Where automated tests run, and the syntax check: one sentence for the rule text and every refusal.
76
+ const TEST_RUN_RULE = 'Automated tests run through their test runner (npm test, node --test, vitest, jest, npx playwright test, not its UI or debug mode) from inside the project they belong to: cd into that project first and name only its own files. That project may be this session\'s or any registered SynaBun project that is a code project (git, package.json or deno.json at its top; never the Downloads folder). A syntax check (node --check <file>) always runs.';
77
+
71
78
  /**
72
79
  * The browser rule, as bullet lines: the brain's persona (its host's tool
73
80
  * names in `tools`), the worker prompts of browser runs. `host`: claude /
@@ -78,7 +85,8 @@ export function browserPolicyText({ tools = '', host = null } = {}) {
78
85
  const web = WEB_TOOL_WORDS[hostKey(host)] || 'WebSearch / WebFetch (OpenCode webfetch / websearch, Codex web_search)';
79
86
  return [
80
87
  `- Every page, public or localhost, goes through SynaBun's browser tools (${t.navigate}, ${t.snapshot}, ${t.screenshot}, ${t.console} and the other browser_* tools); they open the browser configured in SynaBun (MoreLogin). Nothing else opens a page.`,
81
- '- Never run Playwright, Puppeteer or Selenium code of your own to look at a page (a script, node -e, python -c, a heredoc), and never `npx playwright` except to run the project\'s automated tests (npx playwright test).',
88
+ '- Never run Playwright, Puppeteer or Selenium code of your own to look at a page (a script, node -e, python -c, a heredoc), and never `npx playwright` except to run automated tests (npx playwright test).',
89
+ `- ${TEST_RUN_RULE}`,
82
90
  '- Never launch Chrome, Chromium, Edge, chrome-headless-shell or any other browser binary, and never take headless screenshots (--headless, --screenshot).',
83
91
  '- Never `open` a URL or a browser app, and never use computer use on a browser app.',
84
92
  `- Never use the Playwright, Chrome DevTools, Claude-in-Chrome or any other browser MCP tools, nor ${web}.`,
@@ -230,6 +238,27 @@ function insideDir(path, dir) {
230
238
  const rel = relative(resolve(dir), resolve(path));
231
239
  return rel === '' || (!rel.startsWith('..') && !isAbsolute(rel));
232
240
  }
241
+ // macOS and Windows name a folder in any letter case: an exclusion below compares that way.
242
+ const caseless = (path) => (process.platform === 'darwin' || process.platform === 'win32' ? path.toLowerCase() : path);
243
+
244
+ /**
245
+ * Where a test runner may run: the session's project, then each of `roots`
246
+ * (the caller's registered code projects) that is an absolute path, never
247
+ * the home folder or a folder above it, never the Downloads folder or
248
+ * anything in it (the caller's rule, held here too by name alone).
249
+ */
250
+ function testRoots(project, roots) {
251
+ const out = [project];
252
+ const home = caseless(resolve(homedir()));
253
+ const downloads = caseless(resolve(homedir(), 'Downloads'));
254
+ for (const root of Array.isArray(roots) ? roots : []) {
255
+ if (typeof root !== 'string' || !isAbsolute(root)) continue;
256
+ const path = resolve(root);
257
+ if (insideDir(home, caseless(path)) || insideDir(caseless(path), downloads)) continue;
258
+ if (!out.includes(path)) out.push(path);
259
+ }
260
+ return out;
261
+ }
233
262
  /** A regular file up to MAX_SCRIPT_BYTES, else null. */
234
263
  function defaultReadFile(path) {
235
264
  const stat = statSync(path);
@@ -549,13 +578,12 @@ function pathArgs(args) {
549
578
  }
550
579
 
551
580
  /**
552
- * A project's own automated tests: npm|pnpm|yarn|bun test (and run test*),
553
- * node --test, deno test, vitest, jest, playwright test — through a package
554
- * runner too — run from inside the project (`cwd`, where the command runs, `cd`
555
- * included) on file arguments, if any, that lie inside it too.
581
+ * A test runner's command, wherever it runs: { rest (its arguments, the files
582
+ * among them), playwright } for npm|pnpm|yarn|bun test (and run test*), node
583
+ * --test, deno test, vitest, jest, playwright test — through a package runner
584
+ * too — else null.
556
585
  */
557
- function isTestRun(words, { cwd, project }) {
558
- if (!insideDir(cwd, project)) return false;
586
+ function testRunner(words) {
559
587
  const [head, ...args] = words;
560
588
  const name = programName(head);
561
589
  let rest = null;
@@ -575,14 +603,58 @@ function isTestRun(words, { cwd, project }) {
575
603
  if (run?.pkg === 'vitest' || run?.pkg === 'jest') rest = run.args;
576
604
  else if (PLAYWRIGHT_TEST.has(run?.pkg) && run.args[0] === 'test') { rest = run.args.slice(1); playwright = true; }
577
605
  }
578
- if (rest === null) return false;
579
- if (playwright && rest.some((arg) => PLAYWRIGHT_INTERACTIVE.test(arg))) return false;
580
- return pathArgs(rest).every((path) => insideDir(resolvePath(cwd, path), project));
606
+ return rest === null ? null : { rest, playwright };
607
+ }
608
+ /** The allowed projects (ctx.roots) the command runs from (`cwd`, where it runs, `cd` included). */
609
+ const rootsHolding = (cwd, roots) => roots.filter((root) => insideDir(cwd, root));
610
+
611
+ /**
612
+ * Automated tests: a test runner (testRunner) run from inside one of the
613
+ * allowed projects (the session's own, or a registered code project the
614
+ * caller passed) on file arguments, if any, that lie inside that same one.
615
+ */
616
+ function isTestRun(words, { cwd, roots }) {
617
+ const run = testRunner(words);
618
+ if (!run) return false;
619
+ if (run.playwright && run.rest.some((arg) => PLAYWRIGHT_INTERACTIVE.test(arg))) return false;
620
+ const files = pathArgs(run.rest).map((path) => resolvePath(cwd, path));
621
+ return rootsHolding(cwd, roots).some((root) => files.every((file) => insideDir(file, root)));
622
+ }
623
+ /** Where a test run that is not exempt ran from, for its refusal. */
624
+ function testRunWhere({ cwd, roots }) {
625
+ return rootsHolding(cwd, roots).length
626
+ ? 'on files outside the project it runs in'
627
+ : `run from ${cwd}, outside this session's project and every registered code project`;
581
628
  }
582
629
  /** Why a `playwright test` that is not an automated test run is refused. */
583
- function playwrightTestWhy(runner, args, { cwd, project }) {
630
+ function playwrightTestWhy(runner, args, ctx) {
584
631
  if (args.some((arg) => PLAYWRIGHT_INTERACTIVE.test(arg))) return `${runner} test in its UI or debug mode (a browser window)`;
585
- return insideDir(cwd, project) ? `${runner} test on files outside the project` : `${runner} test run from ${cwd}, outside the project`;
632
+ return `${runner} test ${testRunWhere(ctx)}`;
633
+ }
634
+
635
+ /**
636
+ * `node --check <file>` / `node -c <file>` (or its program on stdin): Node
637
+ * parses the program and runs none of it. Checked on Node 24: the forms
638
+ * below run code and are not exempt, so the usual check applies to them:
639
+ * any other option before the file (-r / --require and --import run the
640
+ * module they name, --env-file and --experimental-config-file can add a
641
+ * --require, --run runs a package.json script; -e / -p, --test and --watch
642
+ * Node refuses to combine with --check), NODE_OPTIONS set anywhere on the
643
+ * line (it can hold a --require), `inspect` as the file (node inspect
644
+ * starts the next file under the debugger) and arguments xargs supplies.
645
+ * Only node / nodejs started directly: a package runner's (npx node) is not.
646
+ */
647
+ function syntaxCheckOnly(args, seg, ctx) {
648
+ if (ctx.nodeOptions || seg.words.some((word) => word.includes('NODE_OPTIONS') || programName(word) === 'xargs')) return false;
649
+ let check = false;
650
+ for (let i = 0; i < args.length; i += 1) {
651
+ const arg = args[i];
652
+ if (arg === '--check' || arg === '-c') { check = true; continue; }
653
+ if (arg === '--') return check && args[i + 1] !== 'inspect';
654
+ if (arg.startsWith('-') && arg !== '-') return false;
655
+ return check && arg !== 'inspect';
656
+ }
657
+ return check;
586
658
  }
587
659
 
588
660
  /** What `open` / xdg-open is asked to show when it is a browser, a URL or a web page, else null. */
@@ -660,14 +732,28 @@ const RUNTIME_VALUE_OPTIONS = {
660
732
  ts: new Set(['--tsconfig', '-P', '--project', '-O', '--compiler-options', '-r', '--require', '--import', '--loader', '-C', '--conditions', '--env-file', '--config', '--root', '--mode', '-I', '--ignore']),
661
733
  };
662
734
  const EVAL_FLAG = /^(?:--eval|--print|-[A-Za-z]*[ep])$/;
735
+ // Options whose value is a module the runtime loads and runs before the program (node -r, --import, a loader; bun --preload).
736
+ const PRELOAD_OPTIONS = new Set(['-r', '--require', '--import', '--loader', '--experimental-loader', '--preload']);
737
+ const PRELOAD_INLINE = /^(--require|--import|--loader|--experimental-loader|--preload)=(.*)$/;
738
+
739
+ /** The modules a list of runtime options preloads (`-r x`, `--import=x` …), in order. */
740
+ function preloadsIn(words) {
741
+ const out = [];
742
+ for (let i = 0; i < words.length; i += 1) {
743
+ if (PRELOAD_OPTIONS.has(words[i])) { if (words[i + 1] !== undefined) out.push(words[i + 1]); i += 1; continue; }
744
+ const inline = PRELOAD_INLINE.exec(words[i]);
745
+ if (inline) out.push(inline[2]);
746
+ }
747
+ return out;
748
+ }
663
749
 
664
750
  /**
665
- * A JS runtime's arguments → { code: [inline code], script, stdin }: node,
751
+ * A JS runtime's arguments → { code: [inline code], script, preload }: node,
666
752
  * bun, deno, tsx, ts-node and friends. `script` "-" or none (and no code):
667
- * the program comes from stdin.
753
+ * the program comes from stdin. `preload`: the modules its options load first.
668
754
  */
669
755
  function jsProgram(name, args) {
670
- const out = { code: [], script: null };
756
+ const out = { code: [], script: null, preload: [] };
671
757
  let list = args;
672
758
  let valued = NODE_VALUE_OPTIONS;
673
759
  if (name === 'bun') {
@@ -683,14 +769,25 @@ function jsProgram(name, args) {
683
769
  valued = RUNTIME_VALUE_OPTIONS.ts;
684
770
  if (list[0] === 'watch') list = list.slice(1); // tsx watch <file>
685
771
  }
772
+ const node = name === 'node' || name === 'nodejs';
686
773
  for (let i = 0; i < list.length; i += 1) {
687
774
  const arg = list[i];
688
775
  if (arg === '-') { out.script = '-'; return out; }
689
- if (arg === '--') { out.script = list[i + 1] ?? null; return out; }
776
+ if (arg === '--') {
777
+ // `node -- inspect <file>` is node inspect too.
778
+ const inspect = node && !out.inspect && list[i + 1] === 'inspect';
779
+ out.script = list[i + (inspect ? 2 : 1)] ?? null;
780
+ return out;
781
+ }
690
782
  if (/^--(?:eval|print)=/.test(arg)) { out.code.push(arg.slice(arg.indexOf('=') + 1)); return out; }
691
783
  if (EVAL_FLAG.test(arg)) { if (list[i + 1] !== undefined) out.code.push(list[i + 1]); return out; }
784
+ if (PRELOAD_OPTIONS.has(arg) && valued.has(arg)) { if (list[i + 1] !== undefined) out.preload.push(list[i + 1]); i += 1; continue; }
785
+ const inline = PRELOAD_INLINE.exec(arg);
786
+ if (inline) { out.preload.push(inline[2]); continue; }
692
787
  if (valued.has(arg)) { i += 1; continue; }
693
788
  if (arg.startsWith('-')) continue;
789
+ // `node inspect <file>` runs <file> under the debugger.
790
+ if (arg === 'inspect' && node && !out.inspect) { out.inspect = true; continue; }
694
791
  out.script = arg;
695
792
  return out;
696
793
  }
@@ -723,6 +820,17 @@ const FILE_READERS = new Set(['cat', 'type', 'head', 'tail', 'bat', 'more', 'les
723
820
  function interpreterDenial(name, args, seg, ctx) {
724
821
  const python = PYTHON.test(name);
725
822
  const program = python ? pythonProgram(args) : jsProgram(name, args);
823
+ // A preloaded file runs before the program (with --check too): its options', and NODE_OPTIONS set on the command itself.
824
+ if (!python) {
825
+ const inherited = seg.words.filter((word) => word.startsWith('NODE_OPTIONS=')).flatMap((word) => preloadsIn(word.slice(13).trim().split(/\s+/)));
826
+ for (const module of [...inherited, ...program.preload]) {
827
+ if (!PATH_LIKE.test(module)) continue; // a package name: not read
828
+ let file = module;
829
+ if (/^file:/i.test(module)) { try { file = decodeURIComponent(new URL(module).pathname); } catch { continue; } }
830
+ const what = codeMarker(readScript(ctx, resolvePath(ctx.cwd, file)));
831
+ if (what) return `preloading ${module}, a script that ${what}, into ${name}`;
832
+ }
833
+ }
726
834
  for (const code of program.code) {
727
835
  const what = codeMarker(code);
728
836
  if (what) return `inline code that ${what} (${name} ${python ? '-c' : '-e'})`;
@@ -818,7 +926,12 @@ function segmentDenial(words, seg, ctx) {
818
926
  }
819
927
  if (name === 'playwright' && args[0] === 'test') return playwrightTestWhy(name, args.slice(1), ctx);
820
928
  if (BROWSER_CLIS.has(name)) return `${name}${args[0] ? ` ${args[0]}` : ''} (a browser CLI)`;
821
- if (JS_RUNTIMES.has(name) || PYTHON.test(name)) return interpreterDenial(name, args, seg, ctx);
929
+ if ((name === 'node' || name === 'nodejs') && syntaxCheckOnly(args, seg, ctx)) return null;
930
+ if (JS_RUNTIMES.has(name) || PYTHON.test(name)) {
931
+ const why = interpreterDenial(name, args, seg, ctx);
932
+ // node --test / deno test of a browser test from outside the project it belongs to: say where it may run.
933
+ return why && testRunner(words) ? `${why} (${name === 'deno' ? 'deno test' : `${name} --test`} ${testRunWhere(ctx)})` : why;
934
+ }
822
935
  // A script run as a program (./shot.sh, ./pw.cjs, /tmp/x): by its shebang, else its extension.
823
936
  if (/[/\\]/.test(head)) {
824
937
  const text = readScript(ctx, resolvePath(ctx.cwd, head));
@@ -838,7 +951,10 @@ function segmentDenial(words, seg, ctx) {
838
951
  function commandDenial(text, ctx) {
839
952
  if (ctx.depth > MAX_DEPTH) return null;
840
953
  let cwd = ctx.cwd;
954
+ // NODE_OPTIONS set or exported earlier on the line reaches every later node (syntaxCheckOnly).
955
+ let nodeOptions = ctx.nodeOptions === true;
841
956
  for (const seg of simpleCommands(text)) {
957
+ if (seg.words.some((word) => word.includes('NODE_OPTIONS'))) nodeOptions = true;
842
958
  const words = commandWords(seg.words);
843
959
  // `cd dir && node pw.cjs`: the rest of the line runs there (a bare cd: the home folder).
844
960
  if (words[0] === 'cd' || words[0] === 'pushd') {
@@ -847,7 +963,7 @@ function commandDenial(text, ctx) {
847
963
  else if (words[0] === 'cd' && words.length === 1) cwd = homedir();
848
964
  continue;
849
965
  }
850
- const why = segmentDenial(words, seg, { ...ctx, cwd });
966
+ const why = segmentDenial(words, seg, { ...ctx, cwd, nodeOptions });
851
967
  if (why) return why;
852
968
  }
853
969
  return null;
@@ -855,13 +971,15 @@ function commandDenial(text, ctx) {
855
971
 
856
972
  /** A shell tool's command: a string (a command line) or an argv array (Codex). */
857
973
  function argvDenial(argv, ctx) {
858
- const words = commandWords(argv.map((arg) => String(arg ?? '')));
974
+ const raw = argv.map((arg) => String(arg ?? ''));
975
+ const words = commandWords(raw);
859
976
  if (!words.length) return null;
860
977
  if (SHELLS.has(programName(words[0]))) {
861
978
  const script = shellScript(words.slice(1));
862
979
  if (script !== null) return commandDenial(script, ctx);
863
980
  }
864
- return segmentDenial(words, { words, heredocs: [], inputs: [], pipedFrom: null }, ctx);
981
+ // The segment keeps its wrappers and assignments (env NODE_OPTIONS=… node --check …).
982
+ return segmentDenial(words, { words: raw, heredocs: [], inputs: [], pipedFrom: null }, ctx);
865
983
  }
866
984
 
867
985
  // Where each host puts a shell tool's command and its working directory.
@@ -889,18 +1007,22 @@ function shellDenial(input, ctx) {
889
1007
  // ── the refusal ─────────────────────────────────────────────────────────────
890
1008
 
891
1009
  function refusal(tool, what) {
892
- return `SynaBun browser policy: ${tool} was refused — ${what}. Every page, public or localhost, goes through SynaBun's browser tools (browser_navigate, browser_snapshot, browser_screenshot, browser_console and the other browser_* tools), which open the browser configured in SynaBun. If the SynaBun browser fails or cannot do this, stop and report it; do not switch to another browser or tool. The project's own automated tests still run through its test runner (npm test, node --test, npx playwright test).`;
1010
+ return `SynaBun browser policy: ${tool} was refused — ${what}. Every page, public or localhost, goes through SynaBun's browser tools (browser_navigate, browser_snapshot, browser_screenshot, browser_console and the other browser_* tools), which open the browser configured in SynaBun. If the SynaBun browser fails or cannot do this, stop and report it; do not switch to another browser or tool. ${TEST_RUN_RULE}`;
893
1011
  }
894
1012
 
895
1013
  /**
896
1014
  * Why this tool call may not run under the browser policy (the refusal text),
897
1015
  * else null. `host`: claude / codex / opencode (null: any). `cwd`: the
898
- * project directory: relative script paths resolve against it, and a test
899
- * runner's files must lie inside it. `readFile(path)` returns an executed
900
- * script's text or null (tests); by default a regular file up to
901
- * MAX_SCRIPT_BYTES is read, and anything unreadable is allowed.
1016
+ * session's project directory: relative script paths resolve against it, and
1017
+ * a test runner may run inside it. `roots`: the other projects a test runner
1018
+ * may run inside (absolute paths: the registered code projects,
1019
+ * lib/browser-policy-roots.js; the home folder, a folder above it and the
1020
+ * Downloads folder are dropped). A test run's directory and its files lie in
1021
+ * one of them. `readFile(path)` returns an executed script's text or null
1022
+ * (tests); by default a regular file up to MAX_SCRIPT_BYTES is read, and
1023
+ * anything unreadable is allowed.
902
1024
  */
903
- export function browserToolDenial(tool, input = {}, { host = null, cwd = null, readFile = defaultReadFile } = {}) {
1025
+ export function browserToolDenial(tool, input = {}, { host = null, cwd = null, roots = [], readFile = defaultReadFile } = {}) {
904
1026
  const name = String(tool ?? '').trim();
905
1027
  if (!name) return null;
906
1028
  const kind = hostKey(host);
@@ -919,8 +1041,41 @@ export function browserToolDenial(tool, input = {}, { host = null, cwd = null, r
919
1041
  }
920
1042
  if (isSynabunTool(name) || /^mcp__/i.test(name)) return null;
921
1043
  if (WEB_TOOLS.has(lower)) return refusal(name, 'web search / fetch outside the SynaBun browser');
1044
+ // OpenCode's own browser tool drives a browser that is not SynaBun's.
1045
+ if (kind === 'opencode' && lower === 'browser') return refusal(name, 'OpenCode\'s own browser');
922
1046
  if (!SHELL_TOOLS.has(lower)) return null;
923
1047
  const project = cwd ? resolve(String(cwd)) : process.cwd();
924
- const why = shellDenial(args, { project, cwd: project, readFile: typeof readFile === 'function' ? readFile : defaultReadFile, depth: 0 });
1048
+ const why = shellDenial(args, { roots: testRoots(project, roots), cwd: project, readFile: typeof readFile === 'function' ? readFile : defaultReadFile, depth: 0 });
925
1049
  return why ? refusal(name, why) : null;
926
1050
  }
1051
+
1052
+ // ── SynaBun's own OpenCode serves ───────────────────────────────────────────
1053
+
1054
+ /**
1055
+ * The port a web address (http, https, ws, wss) opens: its own, else the scheme's (80 / 443); null for any other
1056
+ * address (about:blank, data:, file:, chrome:) or one that cannot be read.
1057
+ */
1058
+ export function addressPort(url) {
1059
+ let parsed;
1060
+ try { parsed = new URL(String(url ?? '')); } catch { return null; }
1061
+ if (!/^(?:https?|wss?):$/.test(parsed.protocol)) return null;
1062
+ const port = Number(parsed.port || (parsed.protocol === 'https:' || parsed.protocol === 'wss:' ? 443 : 80));
1063
+ return Number.isInteger(port) && port > 0 ? port : null;
1064
+ }
1065
+
1066
+ /**
1067
+ * Why the SynaBun browser may not open this address (the refusal text), else null: it is on the port of one of
1068
+ * SynaBun's own OpenCode serves running now (`ports`, a Set or a list: server.js liveOpencodeServePorts). Such a
1069
+ * serve's API changes a session's rules or moves it; nothing a page does needs it. Any host counts, not only
1070
+ * localhost: a name that resolves to this computer reaches the serve too. server.js refuses a navigation to it and
1071
+ * aborts every request and WebSocket of the browser to it (installServePortGuard), whatever opened the page.
1072
+ */
1073
+ export function browserServePortDenial(url, ports) {
1074
+ const port = addressPort(url);
1075
+ if (!port) return null;
1076
+ const live = ports instanceof Set ? ports : new Set(Array.isArray(ports) ? ports.map(Number) : []);
1077
+ if (!live.has(port)) return null;
1078
+ let host = '';
1079
+ try { host = new URL(String(url)).hostname; } catch { /* addressPort read it */ }
1080
+ return `SynaBun browser policy: ${host}:${port} is one of SynaBun's own OpenCode servers, which the SynaBun browser never opens (their API changes what a session may do). Use your tools instead; whatever they cannot do is yours to report.`;
1081
+ }
@@ -2895,10 +2895,12 @@ export class ClaudeSession {
2895
2895
  catch { this._greetingNote = ''; }
2896
2896
  }
2897
2897
 
2898
- // SynaBun skill injection runs FIRST; unrecognized /commands pass through to the CLI
2898
+ // SynaBun skill injection runs FIRST; unrecognized /commands pass through to the CLI. A skill Claude Code
2899
+ // loads by itself in this session (the account's or the project's) is left to it (server.js
2900
+ // resolveSkillPrompt), so its own settings apply; only a SynaBun skill it cannot see is handed over as text.
2899
2901
  if (prompt && prompt.startsWith('/')) {
2900
2902
  try {
2901
- const injected = deps.maybeInjectSkillPrompt(prompt);
2903
+ const injected = deps.maybeInjectSkillPrompt(prompt, { cwd: cwd || this.cwd || null, runtime: 'claude', accountId: (queryAccount?.account ?? this.accountId) || 'default' });
2902
2904
  if (injected.command === 'clear' && !injected.skill) return; // client-only
2903
2905
  if (injected.skill) {
2904
2906
  log('skill injection: /' + injected.command);
@@ -0,0 +1,103 @@
1
+ // ═══════════════════════════════════════════
2
+ // SynaBun — the real state of SynaBun's Claude Code hooks (Settings → Automations)
3
+ // ═══════════════════════════════════════════
4
+ //
5
+ // What GET /api/claude-code/integrations reports as `claudeHooks`, read from the files Claude Code itself reads:
6
+ // the user's ~/.claude/settings.json (SynaBun's handlers live there), the managed settings an organization may
7
+ // install, and the registered projects' .claude/settings.json and settings.local.json. It answers "would a Claude
8
+ // Code session the owner starts by themselves run SynaBun's hooks?", which a count of entries alone does not:
9
+ // • Claude Code's own switches: disableAllHooks (any scope) runs no hook at all; allowManagedHooksOnly (managed
10
+ // settings) runs none of the user's or a project's;
11
+ // • a project whose SynaBun handlers differ from the user's: Claude Code runs one copy of identical handlers from
12
+ // both files and both copies of different ones (every hook twice: the 2026-09-15 bug);
13
+ // • macOS / Linux: a Claude Code started from the Dock, Finder, a desktop app or launchd has no login PATH. The
14
+ // handlers then look for Node in the usual folders and SYNABUN_NODE (lib/claude-hooks.js); `node: null` says
15
+ // such a launch would find none.
16
+ // Pure apart from the file reads, which are injected (tests drive it with an in-memory tree).
17
+
18
+ import { existsSync, readFileSync } from 'node:fs';
19
+ import { homedir } from 'node:os';
20
+ import { join } from 'node:path';
21
+ import { hookInstallBlocker, hookInstallState, hookNodeWithoutPath, hooksSwitchedOff, managedClaudeSettingsPath, projectHooksAgree } from '../../lib/claude-hooks.js';
22
+ import { packagedRuntime } from '../../lib/packaged-runtime.js';
23
+
24
+ /** Bumped when the shape changes; the page shows the hooks' state only from a server that sends one. */
25
+ export const CLAUDE_HOOKS_STATUS_VERSION = 1;
26
+
27
+ /** A settings file: { settings } (parsed), { missing: true }, or { error } (it exists and cannot be read or parsed: why). */
28
+ export function readSettingsFile(path, { read = (p) => readFileSync(p, 'utf8'), exists = existsSync } = {}) {
29
+ try {
30
+ if (!path || !exists(path)) return { missing: true };
31
+ } catch { return { missing: true }; }
32
+ let raw;
33
+ try { raw = read(path); } catch (error) { return { error: String(error?.code || error?.message || error) }; }
34
+ try {
35
+ const settings = JSON.parse(raw);
36
+ return settings && typeof settings === 'object' && !Array.isArray(settings) ? { settings } : { error: 'not a JSON object' };
37
+ } catch (error) { return { error: `not valid JSON: ${error?.message || error}` }; }
38
+ }
39
+
40
+ /**
41
+ * @param {object} o
42
+ * @param {string} o.userPath the user's ~/.claude/settings.json
43
+ * @param {Array<{path:string,label?:string}>} [o.projects] the registered projects
44
+ * @param {string} [o.managedPath] managed settings (managedClaudeSettingsPath)
45
+ * @param {string} [o.platform]
46
+ * @param {object|null} [o.runtime] lib/packaged-runtime.js packagedRuntime()
47
+ * @param {(path:string) => string} [o.read] @param {(path:string) => boolean} [o.exists]
48
+ * @param {(path:string) => boolean} [o.runnable] a file Node could be started from (tests)
49
+ * @param {string} [o.home]
50
+ */
51
+ export function claudeHooksStatus({ userPath, projects = [], managedPath = managedClaudeSettingsPath(), platform = process.platform, runtime = packagedRuntime(), read, exists, runnable, home = homedir() } = {}) {
52
+ const io = { ...(read ? { read } : {}), ...(exists ? { exists } : {}) };
53
+ const base = { version: CLAUDE_HOOKS_STATUS_VERSION, settingsPath: userPath || null, installBlocker: hookInstallBlocker(runtime) };
54
+ const user = readSettingsFile(userPath, io);
55
+ if (user.error) return { ...base, state: 'error', error: user.error, installed: 0, current: 0, duplicates: 0, total: 0, events: {}, blockedBy: null, projects: [], node: null, nodeMissing: false, needsRepair: false };
56
+ const settings = user.settings || {};
57
+ const install = hookInstallState(settings, { runtime, platform });
58
+ const state = install.installed === 0 ? 'off' : install.installed === install.total ? 'on' : 'partial';
59
+
60
+ // Claude Code's own switches. Managed settings first: nothing below them can turn hooks back on.
61
+ let blockedBy = null;
62
+ const managed = readSettingsFile(managedPath, io);
63
+ const managedSwitch = hooksSwitchedOff(managed.settings, { managed: true });
64
+ if (managedSwitch) blockedBy = { setting: managedSwitch, scope: 'managed', path: managedPath };
65
+ else {
66
+ const userSwitch = hooksSwitchedOff(settings);
67
+ if (userSwitch) blockedBy = { setting: userSwitch, scope: 'user', path: userPath };
68
+ }
69
+
70
+ // The registered projects: hooks switched off there, or SynaBun handlers that would run next to the user's.
71
+ const projectIssues = [];
72
+ for (const project of Array.isArray(projects) ? projects : []) {
73
+ if (!project?.path) continue;
74
+ for (const name of ['settings.json', 'settings.local.json']) {
75
+ const file = join(project.path, '.claude', name);
76
+ const found = readSettingsFile(file, io);
77
+ if (!found.settings) continue;
78
+ let issue = hooksSwitchedOff(found.settings) ? 'disableAllHooks' : projectHooksAgree(settings, found.settings) === 'different' ? 'different' : null;
79
+ // Off for the user, still on there: that project's sessions keep running them.
80
+ if (!issue && install.installed === 0 && hookInstallState(found.settings, { targetProjectPath: project.path, runtime, platform }).installed > 0) issue = 'project-only';
81
+ if (issue) projectIssues.push({ path: project.path, label: project.label || null, file, issue });
82
+ }
83
+ }
84
+
85
+ // Asked of the packaged application too: its entry finds its own Node, so the answer is only shown for the others.
86
+ const node = platform === 'win32' || runtime ? null : hookNodeWithoutPath({ env: settings.env || {}, home, platform, ...(runnable ? { runnable } : {}) });
87
+ const nodeMissing = install.installed > 0 && platform !== 'win32' && !runtime && !node;
88
+ return {
89
+ ...base,
90
+ state,
91
+ installed: install.installed,
92
+ current: install.current,
93
+ duplicates: install.duplicates,
94
+ total: install.total,
95
+ events: install.events,
96
+ blockedBy,
97
+ projects: projectIssues,
98
+ node,
99
+ nodeMissing,
100
+ // What turning the hooks on again would put right: an old command form, an extra copy, a project out of step.
101
+ needsRepair: install.installed > 0 && (install.current < install.installed || install.duplicates > 0 || projectIssues.some((p) => p.issue === 'different') || nodeMissing),
102
+ };
103
+ }
@@ -43,7 +43,39 @@ const DISCOVERY_TIMEOUT_MS = 15000;
43
43
  const CACHE_TTL_MS = 10 * 60 * 1000;
44
44
 
45
45
  let _cache = { at: 0, key: '', models: [] };
46
- let _inflight = null;
46
+ const _inflight = new Map(); // cache key → the discovery running for it
47
+ // Where the last verified list is kept across restarts ({ read(), write(entry) },
48
+ // lib/launch-cache.js createSnapshotStore): a start answers with it at once and
49
+ // asks the CLI again in the background.
50
+ let _store = null;
51
+ let _storeRead = false;
52
+
53
+ export function setClaudeModelStore(store) {
54
+ _store = store && typeof store.read === 'function' && typeof store.write === 'function' ? store : null;
55
+ _storeRead = false;
56
+ }
57
+
58
+ // The list the last run verified, for this very binary and account: given at once
59
+ // after a restart (as an old answer, so the first read asks the CLI again).
60
+ function adoptStoredModels(key) {
61
+ if (_storeRead || !_store) return;
62
+ _storeRead = true;
63
+ if (_cache.models.length) return;
64
+ try {
65
+ const saved = _store.read();
66
+ const models = saved?.key === key && Array.isArray(saved.models)
67
+ ? saved.models.filter(m => m && typeof m === 'object' && typeof m.id === 'string' && m.id)
68
+ : [];
69
+ if (models.length) _cache = { at: 0, key, models };
70
+ } catch { /* nothing kept: the first read asks the CLI */ }
71
+ }
72
+
73
+ // What the list depends on: the binary (an update changes it, binaryIdentity) and
74
+ // the account it was read under (another account can be entitled to other models).
75
+ function cacheKeyOf(bin, account) {
76
+ const who = String(account || '');
77
+ return who ? `${binaryIdentity(bin)}#${who}` : binaryIdentity(bin);
78
+ }
47
79
 
48
80
  // Who else keeps a copy of this list (the Assistant's model catalog). Told when a
49
81
  // discovery returns a list that differs from the one before it, so a copy is
@@ -286,37 +318,55 @@ export function queryClaudeCliModels(claudeBin, { cwd, timeoutMs = DISCOVERY_TIM
286
318
  }
287
319
 
288
320
  // Cached discovery. `source` lets the UI distinguish a verified list from the
289
- // baked-in fallback. Cache is keyed on the binary's identity, so switching the
290
- // configured CLI (Settings > Terminal) or updating it re-discovers.
291
- export async function discoverClaudeModels(claudeBin, { force = false, cwd, query = queryClaudeCliModels } = {}) {
321
+ // baked-in fallback. Cache is keyed on the binary's identity (and the account
322
+ // the list was read under, `account`), so switching the configured CLI
323
+ // (Settings > Terminal), updating it or signing in to another account
324
+ // re-discovers. A list that is merely old is still given at once, and the CLI is
325
+ // asked again in the background (one discovery at a time): only a first read, a
326
+ // changed key or `force` waits for the CLI.
327
+ export async function discoverClaudeModels(claudeBin, { force = false, cwd, query = queryClaudeCliModels, account = '' } = {}) {
292
328
  const bin = String(claudeBin || '');
293
- const key = binaryIdentity(bin);
294
- const fresh = _cache.models.length
295
- && _cache.key === key
296
- && Date.now() - _cache.at < CACHE_TTL_MS;
297
- if (!force && fresh) return { source: 'cache', models: _cache.models };
298
- if (_inflight) return _inflight;
299
-
300
- _inflight = (async () => {
329
+ const key = cacheKeyOf(bin, account);
330
+ adoptStoredModels(key);
331
+ const known = _cache.models.length && _cache.key === key;
332
+ if (!force && known) {
333
+ if (Date.now() - _cache.at >= CACHE_TTL_MS) discover(bin, key, cwd, query).catch(() => {});
334
+ return { source: 'cache', models: _cache.models };
335
+ }
336
+ return discover(bin, key, cwd, query);
337
+ }
338
+
339
+ function discover(bin, key, cwd, query) {
340
+ if (_inflight.has(key)) return _inflight.get(key);
341
+ const job = (async () => {
301
342
  try {
302
343
  const raw = await query(bin, { cwd });
303
344
  const models = normalizeClaudeModels(raw);
304
345
  if (models.length) {
305
346
  const changed = claudeModelsSignature(models) !== claudeModelsSignature(_cache.models);
306
347
  _cache = { at: Date.now(), key, models };
348
+ try { _store?.write({ key, at: _cache.at, models }); } catch { /* kept in memory still */ }
307
349
  if (changed) notifyModelsChanged(models);
308
350
  return { source: 'cli', models };
309
351
  }
310
352
  return { source: 'fallback', models: [...CLAUDE_FALLBACK_MODELS] };
311
353
  } finally {
312
- _inflight = null;
354
+ if (_inflight.get(key) === job) _inflight.delete(key);
313
355
  }
314
356
  })();
315
- return _inflight;
357
+ _inflight.set(key, job);
358
+ return job;
359
+ }
360
+
361
+ /** The kept list is due again: the next read still answers with it and asks the CLI in the background. */
362
+ export function markClaudeModelsStale() {
363
+ _cache = { ..._cache, at: 0 };
316
364
  }
317
365
 
318
366
  export function clearClaudeModelCache() {
319
367
  _cache = { at: 0, key: '', models: [] };
368
+ _inflight.clear();
369
+ _storeRead = !!_store;
320
370
  _skewCache = { key: null, result: undefined };
321
371
  _skewInflight.clear();
322
372
  }
@@ -49,7 +49,7 @@ const READ_TOOLS = new Set([
49
49
  ]);
50
50
  // One tool, both: the actions that only read. Any other action is refused, an
51
51
  // action nobody listed included. `''` is the tool's own default action.
52
- // (`profile`: `set` writes the runtime's profile, to a file and to the server.)
52
+ // (`tool_groups`: `add` / `set` write the runtime list, to a file and to the server.)
53
53
  const READ_ACTIONS = Object.freeze({
54
54
  memories: new Set(['recent', 'stats', 'by-category', 'by-project', 'get', 'get-batch', 'history', 'context']),
55
55
  category: new Set(['list']),
@@ -57,7 +57,7 @@ const READ_ACTIONS = Object.freeze({
57
57
  fb_groups: new Set(['worklist', 'list', 'stats']),
58
58
  image_staged: new Set(['list']),
59
59
  morelogin: new Set(['status', 'list']),
60
- profile: new Set(['get']),
60
+ tool_groups: new Set(['get']),
61
61
  });
62
62
  // Acting on the outside world through the browser, an API or the desktop: what
63
63
  // Bash and Edit do too. They leave what they do where they do it (a post, a
@@ -84,19 +84,13 @@ const ACT_TOOLS = new Set([
84
84
  'gsc_removals_cancel', 'gsc_screenshot', 'gsc_security_issues', 'gsc_settings', 'gsc_shopping', 'gsc_sitemap', 'gsc_users', 'gsc_videos_report',
85
85
  'youtube_analytics', 'youtube_channel', 'youtube_download', 'youtube_endscreen', 'youtube_metadata', 'youtube_navigate',
86
86
  'youtube_playlist', 'youtube_schedule', 'youtube_source', 'youtube_thumbnail',
87
- 'leonardo_browser_download', 'leonardo_browser_generate', 'leonardo_browser_library', 'leonardo_browser_navigate',
88
87
  'computer', 'computer_apps', 'computer_ax', 'computer_status',
89
88
  'git',
90
89
  ]);
91
90
  // An acting tool that also changes one of SynaBun's stores unless it is told
92
- // not to: allowed with that input only. (`leonardo_browser_reference` deletes
93
- // the staged images it uploaded from SynaBun's image store by default.)
94
- const ACT_WHEN = Object.freeze({
95
- leonardo_browser_reference: {
96
- ok: (input) => input?.autoClear === false,
97
- why: 'it removes the staged images from SynaBun\'s store unless it is called with autoClear: false',
98
- },
99
- });
91
+ // not to: allowed with that input only, as `{ ok: (input) => boolean, why }`.
92
+ // No tool of the server needs one today.
93
+ const ACT_WHEN = Object.freeze({});
100
94
  // Why a storing tool that looks like an acting one is off.
101
95
  const STORE_REASONS = Object.freeze({
102
96
  youtube_upload: 'it records every upload as a memory',