synabun 2.0.9 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (679) hide show
  1. package/CHANGELOG.md +115 -0
  2. package/README.md +25 -2
  3. package/THIRD-PARTY-LICENSES.md +68 -4
  4. package/bin/synabun.js +71 -24
  5. package/docs/whatsapp.md +2 -2
  6. package/hooks/claude-code/pre-websearch.mjs +12 -1
  7. package/hooks/claude-code/shared.mjs +5 -0
  8. package/hooks/claude-code/stop.mjs +1 -1
  9. package/launcher.mjs +9 -3
  10. package/lib/claude-hooks.js +172 -18
  11. package/lib/client-config-repair.js +17 -8
  12. package/lib/desktop-app.js +7 -1
  13. package/lib/external-tools.js +1 -1
  14. package/lib/first-launch-protection.js +57 -12
  15. package/lib/mcp-dist.js +176 -0
  16. package/lib/release-npm-ci.mjs +138 -0
  17. package/lib/release-publish.mjs +91 -0
  18. package/lib/release-scan.mjs +50 -0
  19. package/lib/server-crash-record.js +123 -0
  20. package/lib/server-exit.js +318 -0
  21. package/lib/server-supervisor.js +508 -0
  22. package/lib/start-launcher.js +43 -5
  23. package/lib/tools-cli.js +45 -0
  24. package/lib/update-snapshot.js +228 -0
  25. package/lib/virustotal.mjs +192 -0
  26. package/lib/windows-crash-event.js +269 -0
  27. package/mcp-server/dist/http.d.ts +20 -1
  28. package/mcp-server/dist/http.d.ts.map +1 -1
  29. package/mcp-server/dist/http.js +59 -12
  30. package/mcp-server/dist/http.js.map +1 -1
  31. package/mcp-server/dist/index.d.ts +33 -27
  32. package/mcp-server/dist/index.d.ts.map +1 -1
  33. package/mcp-server/dist/index.js +128 -143
  34. package/mcp-server/dist/index.js.map +1 -1
  35. package/mcp-server/dist/preload.js +1 -1
  36. package/mcp-server/dist/preload.js.map +1 -1
  37. package/mcp-server/dist/services/codex-config-heal.d.ts +6 -2
  38. package/mcp-server/dist/services/codex-config-heal.d.ts.map +1 -1
  39. package/mcp-server/dist/services/codex-config-heal.js +81 -28
  40. package/mcp-server/dist/services/codex-config-heal.js.map +1 -1
  41. package/mcp-server/dist/services/memory-judge-backfill.d.ts +6 -0
  42. package/mcp-server/dist/services/memory-judge-backfill.d.ts.map +1 -1
  43. package/mcp-server/dist/services/memory-judge-backfill.js +7 -1
  44. package/mcp-server/dist/services/memory-judge-backfill.js.map +1 -1
  45. package/mcp-server/dist/services/neural-interface.d.ts +16 -10
  46. package/mcp-server/dist/services/neural-interface.d.ts.map +1 -1
  47. package/mcp-server/dist/services/neural-interface.js +67 -11
  48. package/mcp-server/dist/services/neural-interface.js.map +1 -1
  49. package/mcp-server/dist/services/server-instructions.d.ts +7 -2
  50. package/mcp-server/dist/services/server-instructions.d.ts.map +1 -1
  51. package/mcp-server/dist/services/server-instructions.js +20 -62
  52. package/mcp-server/dist/services/server-instructions.js.map +1 -1
  53. package/mcp-server/dist/services/tool-catalog.d.ts +120 -0
  54. package/mcp-server/dist/services/tool-catalog.d.ts.map +1 -0
  55. package/mcp-server/dist/services/tool-catalog.js +339 -0
  56. package/mcp-server/dist/services/tool-catalog.js.map +1 -0
  57. package/mcp-server/dist/services/tool-list-refresh-barrier.d.ts +12 -0
  58. package/mcp-server/dist/services/tool-list-refresh-barrier.d.ts.map +1 -0
  59. package/mcp-server/dist/services/tool-list-refresh-barrier.js +40 -0
  60. package/mcp-server/dist/services/tool-list-refresh-barrier.js.map +1 -0
  61. package/mcp-server/dist/services/tool-list.d.ts +108 -0
  62. package/mcp-server/dist/services/tool-list.d.ts.map +1 -0
  63. package/mcp-server/dist/services/tool-list.js +334 -0
  64. package/mcp-server/dist/services/tool-list.js.map +1 -0
  65. package/mcp-server/dist/services/tool-runtime.d.ts +161 -0
  66. package/mcp-server/dist/services/tool-runtime.d.ts.map +1 -0
  67. package/mcp-server/dist/services/tool-runtime.js +400 -0
  68. package/mcp-server/dist/services/tool-runtime.js.map +1 -0
  69. package/mcp-server/dist/services/whiteboard-geometry.d.ts +26 -2
  70. package/mcp-server/dist/services/whiteboard-geometry.d.ts.map +1 -1
  71. package/mcp-server/dist/services/whiteboard-geometry.js +91 -8
  72. package/mcp-server/dist/services/whiteboard-geometry.js.map +1 -1
  73. package/mcp-server/dist/tools/agents.d.ts +10 -10
  74. package/mcp-server/dist/tools/agents.d.ts.map +1 -1
  75. package/mcp-server/dist/tools/agents.js +22 -13
  76. package/mcp-server/dist/tools/agents.js.map +1 -1
  77. package/mcp-server/dist/tools/browser-batch.d.ts +3 -3
  78. package/mcp-server/dist/tools/image-tools.d.ts +1 -1
  79. package/mcp-server/dist/tools/image-tools.js +1 -1
  80. package/mcp-server/dist/tools/skill-tools.d.ts +505 -0
  81. package/mcp-server/dist/tools/skill-tools.d.ts.map +1 -0
  82. package/mcp-server/dist/tools/skill-tools.js +639 -0
  83. package/mcp-server/dist/tools/skill-tools.js.map +1 -0
  84. package/mcp-server/dist/tools/skill.d.ts +7 -0
  85. package/mcp-server/dist/tools/skill.d.ts.map +1 -0
  86. package/mcp-server/dist/tools/skill.js +11 -0
  87. package/mcp-server/dist/tools/skill.js.map +1 -0
  88. package/mcp-server/dist/tools/tool-groups.d.ts +68 -0
  89. package/mcp-server/dist/tools/tool-groups.d.ts.map +1 -0
  90. package/mcp-server/dist/tools/tool-groups.js +147 -0
  91. package/mcp-server/dist/tools/tool-groups.js.map +1 -0
  92. package/mcp-server/dist/tools/whiteboard-format.d.ts.map +1 -1
  93. package/mcp-server/dist/tools/whiteboard-format.js +7 -4
  94. package/mcp-server/dist/tools/whiteboard-format.js.map +1 -1
  95. package/mcp-server/dist/tools/whiteboard-tools.d.ts +64 -13
  96. package/mcp-server/dist/tools/whiteboard-tools.d.ts.map +1 -1
  97. package/mcp-server/dist/tools/whiteboard-tools.js +30 -5
  98. package/mcp-server/dist/tools/whiteboard-tools.js.map +1 -1
  99. package/mcp-server/package-lock.json +2 -2
  100. package/mcp-server/package.json +1 -1
  101. package/mcp-server/src/http.ts +75 -12
  102. package/mcp-server/src/index.ts +147 -154
  103. package/mcp-server/src/preload.ts +12 -12
  104. package/mcp-server/src/services/codex-config-heal.ts +80 -29
  105. package/mcp-server/src/services/memory-judge-backfill.ts +7 -1
  106. package/mcp-server/src/services/neural-interface.ts +79 -20
  107. package/mcp-server/src/services/server-instructions.ts +27 -63
  108. package/mcp-server/src/services/tool-catalog.ts +403 -0
  109. package/mcp-server/src/services/tool-list-refresh-barrier.ts +33 -0
  110. package/mcp-server/src/services/tool-list.ts +410 -0
  111. package/mcp-server/src/services/tool-runtime.ts +457 -0
  112. package/mcp-server/src/services/whiteboard-geometry.ts +94 -9
  113. package/mcp-server/src/tools/agents.ts +22 -14
  114. package/mcp-server/src/tools/image-tools.ts +1 -1
  115. package/mcp-server/src/tools/skill-tools.ts +589 -0
  116. package/mcp-server/src/tools/skill.ts +13 -0
  117. package/mcp-server/src/tools/tool-groups.ts +164 -0
  118. package/mcp-server/src/tools/whiteboard-format.ts +9 -3
  119. package/mcp-server/src/tools/whiteboard-tools.ts +39 -5
  120. package/neural-interface/i18n/en.json +3680 -206
  121. package/neural-interface/i18n/pt-BR.json +3628 -157
  122. package/neural-interface/lib/account-usage.js +5 -3
  123. package/neural-interface/lib/app-controls-api.js +161 -0
  124. package/neural-interface/lib/assistant-api.js +148 -35
  125. package/neural-interface/lib/assistant-brains/claude.js +4 -3
  126. package/neural-interface/lib/assistant-brains/codex-browser-policy-hook.mjs +12 -2
  127. package/neural-interface/lib/assistant-brains/codex-route-gate-hook.mjs +32 -9
  128. package/neural-interface/lib/assistant-brains/codex.js +9 -5
  129. package/neural-interface/lib/assistant-brains/opencode.js +122 -44
  130. package/neural-interface/lib/assistant-brains/opencode2-browser-policy/index.js +59 -0
  131. package/neural-interface/lib/assistant-brains/opencode2-route-gate/index.js +97 -0
  132. package/neural-interface/lib/assistant-catalog.js +23 -9
  133. package/neural-interface/lib/assistant-dispatch.js +874 -156
  134. package/neural-interface/lib/assistant-envelope.js +22 -2
  135. package/neural-interface/lib/assistant-persona.js +80 -11
  136. package/neural-interface/lib/assistant-plan-permissions.js +10 -9
  137. package/neural-interface/lib/assistant-route-gate-codex.js +3 -0
  138. package/neural-interface/lib/assistant-route-gate.js +6 -4
  139. package/neural-interface/lib/assistant-router.js +13 -8
  140. package/neural-interface/lib/assistant-runtime.js +183 -26
  141. package/neural-interface/lib/assistant-task-prompt.js +78 -14
  142. package/neural-interface/lib/assistant-tools.js +51 -0
  143. package/neural-interface/lib/backup-service.js +620 -3
  144. package/neural-interface/lib/backup-zip-reader.js +10 -5
  145. package/neural-interface/lib/backup-zip-writer.js +257 -0
  146. package/neural-interface/lib/browser-execution.js +10 -2
  147. package/neural-interface/lib/browser-guard-cdp.js +83 -0
  148. package/neural-interface/lib/browser-network-guard.js +284 -0
  149. package/neural-interface/lib/browser-policy-roots.js +64 -0
  150. package/neural-interface/lib/browser-tool-policy.js +186 -31
  151. package/neural-interface/lib/claude-agent-bridge.js +4 -2
  152. package/neural-interface/lib/claude-hooks-status.js +103 -0
  153. package/neural-interface/lib/claude-model-catalog.js +64 -14
  154. package/neural-interface/lib/claude-temporary.js +5 -11
  155. package/neural-interface/lib/cli-install.js +18 -138
  156. package/neural-interface/lib/cli-resolver.js +4 -1
  157. package/neural-interface/lib/cli-update-planner.js +32 -31
  158. package/neural-interface/lib/cloudflared/tunnel.js +42 -2
  159. package/neural-interface/lib/codex-mcp-approvals.js +11 -0
  160. package/neural-interface/lib/codex-settings-schema.js +109 -47
  161. package/neural-interface/lib/codex-worker-app-server.js +172 -0
  162. package/neural-interface/lib/confined-fs.js +30 -3
  163. package/neural-interface/lib/crash-notice-api.js +98 -0
  164. package/neural-interface/lib/editor-completion-opencode.js +164 -67
  165. package/neural-interface/lib/exec-loop-command.js +4 -1
  166. package/neural-interface/lib/http-guards.js +8 -2
  167. package/neural-interface/lib/install-details.js +4 -1
  168. package/neural-interface/lib/launch-cache.js +293 -0
  169. package/neural-interface/lib/login-start.js +524 -0
  170. package/neural-interface/lib/mcp-agent-servers.js +67 -0
  171. package/neural-interface/lib/mcp-client-config.js +0 -29
  172. package/neural-interface/lib/mcp-external-servers.js +323 -0
  173. package/neural-interface/lib/{mcp-profile-refresh-coordinator.js → mcp-tools-refresh-coordinator.js} +4 -4
  174. package/neural-interface/lib/morelogin.js +30 -0
  175. package/neural-interface/lib/native-loop-providers.js +565 -50
  176. package/neural-interface/lib/native-loop-runtime.js +287 -41
  177. package/neural-interface/lib/opencode-config.js +557 -0
  178. package/neural-interface/lib/opencode-db-schema.js +58 -0
  179. package/neural-interface/lib/opencode-history.js +49 -204
  180. package/neural-interface/lib/opencode-mcp-ready.js +108 -0
  181. package/neural-interface/lib/opencode-native-boundary.js +44 -0
  182. package/neural-interface/lib/opencode-protocol.js +310 -0
  183. package/neural-interface/lib/opencode-provider-view.js +81 -0
  184. package/neural-interface/lib/opencode-runtime-config.js +32 -15
  185. package/neural-interface/lib/opencode-serve-records.js +624 -0
  186. package/neural-interface/lib/opencode-v2-client.js +53 -131
  187. package/neural-interface/lib/opencode-v2-ws-requests.js +35 -195
  188. package/neural-interface/lib/opencode-worker-activity.js +229 -0
  189. package/neural-interface/lib/opencode-worker-data.js +27 -0
  190. package/neural-interface/lib/opencode2-client.js +796 -0
  191. package/neural-interface/lib/opencode2-proxy.js +76 -0
  192. package/neural-interface/lib/opencode2-translate.js +1057 -0
  193. package/neural-interface/lib/owner-authority.js +249 -0
  194. package/neural-interface/lib/page-session.js +275 -0
  195. package/neural-interface/lib/peer-identity.js +763 -0
  196. package/neural-interface/lib/process-identity.js +361 -0
  197. package/neural-interface/lib/request-gate.js +17 -2
  198. package/neural-interface/lib/rulesets/api.js +1 -1
  199. package/neural-interface/lib/rulesets/fs-safe.js +1 -1
  200. package/neural-interface/lib/rulesets/installer.js +92 -27
  201. package/neural-interface/lib/rulesets/json-edit.js +1 -1
  202. package/neural-interface/lib/session-cache-builder.js +18 -10
  203. package/neural-interface/lib/session-title-generator.js +58 -18
  204. package/neural-interface/lib/skills/api-v2.js +495 -0
  205. package/neural-interface/lib/skills/bundle.js +418 -0
  206. package/neural-interface/lib/skills/catalog.js +294 -0
  207. package/neural-interface/lib/skills/creation-api.js +191 -0
  208. package/neural-interface/lib/skills/creation-brief.js +247 -0
  209. package/neural-interface/lib/skills/creation-sources.js +267 -0
  210. package/neural-interface/lib/skills/creation.js +843 -0
  211. package/neural-interface/lib/skills/deploy.js +564 -0
  212. package/neural-interface/lib/skills/digest.js +119 -0
  213. package/neural-interface/lib/skills/discover.js +111 -0
  214. package/neural-interface/lib/skills/draft-confinement.js +214 -0
  215. package/neural-interface/lib/skills/eval-confinement.js +397 -0
  216. package/neural-interface/lib/skills/eval-sandbox.js +280 -0
  217. package/neural-interface/lib/skills/eval-trace.js +119 -0
  218. package/neural-interface/lib/skills/evals-api.js +212 -0
  219. package/neural-interface/lib/skills/evals.js +1573 -0
  220. package/neural-interface/lib/skills/export.js +200 -0
  221. package/neural-interface/lib/skills/frontmatter.js +64 -0
  222. package/neural-interface/lib/skills/health.js +75 -0
  223. package/neural-interface/lib/skills/json-edit.js +165 -0
  224. package/neural-interface/lib/skills/known-bridge-digests.json +387 -0
  225. package/neural-interface/lib/skills/known-bridges.js +96 -0
  226. package/neural-interface/lib/skills/library.js +823 -0
  227. package/neural-interface/lib/skills/local-store.js +21 -0
  228. package/neural-interface/lib/skills/migration.js +433 -0
  229. package/neural-interface/lib/skills/operations.js +45 -0
  230. package/neural-interface/lib/skills/ownership.js +427 -0
  231. package/neural-interface/lib/skills/packages.js +88 -0
  232. package/neural-interface/lib/skills/reviews.js +212 -0
  233. package/neural-interface/lib/skills/revision.js +80 -0
  234. package/neural-interface/lib/skills/roots.js +262 -0
  235. package/neural-interface/lib/skills/runtime-checks.js +355 -0
  236. package/neural-interface/lib/skills/scan-assets.js +252 -0
  237. package/neural-interface/lib/skills/scan-context.js +26 -0
  238. package/neural-interface/lib/skills/scan-shell.js +324 -0
  239. package/neural-interface/lib/skills/scan.js +364 -0
  240. package/neural-interface/lib/skills/scanners.js +54 -0
  241. package/neural-interface/lib/skills/service.js +522 -0
  242. package/neural-interface/lib/skills/telemetry.js +113 -0
  243. package/neural-interface/lib/sqlite-integrity-worker.js +22 -0
  244. package/neural-interface/lib/style-guide/api.js +4 -3
  245. package/neural-interface/lib/tool-lists.js +124 -0
  246. package/neural-interface/lib/untrusted-file-headers.js +27 -0
  247. package/neural-interface/lib/whatsapp/bridge.js +6 -3
  248. package/neural-interface/lib/worker-confinement.js +1192 -0
  249. package/neural-interface/lib/worker-guard-setting.js +56 -0
  250. package/neural-interface/lib/worker-mcp-channel.js +175 -0
  251. package/neural-interface/lib/worker-relay-ports.js +227 -0
  252. package/neural-interface/lib/worker-resume.js +229 -0
  253. package/neural-interface/lib/worker-sandbox.js +299 -0
  254. package/neural-interface/package-lock.json +1354 -50
  255. package/neural-interface/package.json +6 -2
  256. package/neural-interface/public/index.html +5 -3
  257. package/neural-interface/public/index2d.html +19 -11
  258. package/neural-interface/public/onboarding.html +2 -2
  259. package/neural-interface/public/shared/account-menu.js +8 -5
  260. package/neural-interface/public/shared/agent-runtime-options.js +76 -16
  261. package/neural-interface/public/shared/api.js +1527 -1336
  262. package/neural-interface/public/shared/app-frame.js +192 -0
  263. package/neural-interface/public/shared/assistant/asst-agents-dock.js +205 -19
  264. package/neural-interface/public/shared/assistant/asst-api.js +11 -3
  265. package/neural-interface/public/shared/assistant/asst-ask-styles.js +270 -0
  266. package/neural-interface/public/shared/assistant/asst-ask-tail.js +118 -0
  267. package/neural-interface/public/shared/assistant/asst-ask.js +397 -0
  268. package/neural-interface/public/shared/assistant/asst-brain-picker.js +241 -112
  269. package/neural-interface/public/shared/assistant/asst-composer.js +1 -1
  270. package/neural-interface/public/shared/assistant/asst-control.js +157 -26
  271. package/neural-interface/public/shared/assistant/asst-followups-card.js +383 -0
  272. package/neural-interface/public/shared/assistant/asst-followups.js +417 -0
  273. package/neural-interface/public/shared/assistant/asst-hosts.js +49 -2
  274. package/neural-interface/public/shared/assistant/asst-limit-dock.js +40 -0
  275. package/neural-interface/public/shared/assistant/asst-limit-wait.js +294 -0
  276. package/neural-interface/public/shared/assistant/asst-limit.js +168 -0
  277. package/neural-interface/public/shared/assistant/asst-mascot.js +49 -12
  278. package/neural-interface/public/shared/assistant/asst-menu.js +84 -12
  279. package/neural-interface/public/shared/assistant/asst-panel.js +303 -44
  280. package/neural-interface/public/shared/assistant/asst-rack-styles.js +93 -58
  281. package/neural-interface/public/shared/assistant/asst-redact.js +186 -0
  282. package/neural-interface/public/shared/assistant/asst-render.js +770 -100
  283. package/neural-interface/public/shared/assistant/asst-route.js +83 -12
  284. package/neural-interface/public/shared/assistant/asst-run-stage.js +231 -0
  285. package/neural-interface/public/shared/assistant/asst-sanitize.js +193 -3
  286. package/neural-interface/public/shared/assistant/asst-scene-styles.js +273 -0
  287. package/neural-interface/public/shared/assistant/asst-scenes.js +530 -0
  288. package/neural-interface/public/shared/assistant/asst-sidepanel-styles.js +3 -15
  289. package/neural-interface/public/shared/assistant/asst-sidepanel.js +67 -4
  290. package/neural-interface/public/shared/assistant/asst-slash.js +9 -7
  291. package/neural-interface/public/shared/assistant/asst-state.js +25 -15
  292. package/neural-interface/public/shared/assistant/asst-stop.js +127 -0
  293. package/neural-interface/public/shared/assistant/asst-styles.js +102 -21
  294. package/neural-interface/public/shared/assistant/asst-tool-kinds.js +165 -13
  295. package/neural-interface/public/shared/automation-context.js +5 -2
  296. package/neural-interface/public/shared/cc-dropdown.js +550 -0
  297. package/neural-interface/public/shared/cdx/cdx-context-menu.js +10 -9
  298. package/neural-interface/public/shared/cdx/cdx-copy.js +16 -0
  299. package/neural-interface/public/shared/cdx/cdx-output-model.js +22 -1
  300. package/neural-interface/public/shared/cdx/cdx-output.js +8 -7
  301. package/neural-interface/public/shared/cdx/cdx-panel.js +58 -150
  302. package/neural-interface/public/shared/cdx/cdx-protocol.js +28 -1
  303. package/neural-interface/public/shared/cdx/cdx-render.js +62 -32
  304. package/neural-interface/public/shared/cdx/cdx-requests.js +3 -3
  305. package/neural-interface/public/shared/cdx/cdx-skill-hints.js +54 -0
  306. package/neural-interface/public/shared/cdx/cdx-styles.js +15 -3
  307. package/neural-interface/public/shared/cdx/cdx-tabs.js +201 -74
  308. package/neural-interface/public/shared/cdx/cdx-ws.js +0 -1
  309. package/neural-interface/public/shared/cli-install-view.js +4 -8
  310. package/neural-interface/public/shared/cli-status.js +2 -2
  311. package/neural-interface/public/shared/constants.js +2 -2
  312. package/neural-interface/public/shared/context-menu-areas.js +34 -0
  313. package/neural-interface/public/shared/context-menu-logic.js +243 -0
  314. package/neural-interface/public/shared/context-menu-model.js +366 -0
  315. package/neural-interface/public/shared/context-menu.js +372 -0
  316. package/neural-interface/public/shared/cp/cp-context-menu.js +10 -9
  317. package/neural-interface/public/shared/cp/cp-markdown.js +4 -57
  318. package/neural-interface/public/shared/crash-notice-view.js +168 -0
  319. package/neural-interface/public/shared/data-cache.js +223 -0
  320. package/neural-interface/public/shared/desktop-bridge.js +11 -0
  321. package/neural-interface/public/shared/desktop-titlebar-view.js +78 -1
  322. package/neural-interface/public/shared/desktop-titlebar.js +214 -28
  323. package/neural-interface/public/shared/desktop-update-view.js +35 -5
  324. package/neural-interface/public/shared/editor/editor-panel-logic.js +2 -2
  325. package/neural-interface/public/shared/file-links.js +73 -8
  326. package/neural-interface/public/shared/html-shell.js +78 -86
  327. package/neural-interface/public/shared/i18n.js +2 -0
  328. package/neural-interface/public/shared/launch-prefetch.js +59 -0
  329. package/neural-interface/public/shared/ocp-v2/ocp-v2-approvals.js +7 -7
  330. package/neural-interface/public/shared/ocp-v2/ocp-v2-binding.js +4 -4
  331. package/neural-interface/public/shared/ocp-v2/ocp-v2-caps.js +3 -2
  332. package/neural-interface/public/shared/ocp-v2/ocp-v2-changes-logic.js +3 -101
  333. package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +9 -2
  334. package/neural-interface/public/shared/ocp-v2/ocp-v2-compact-button.js +1 -3
  335. package/neural-interface/public/shared/ocp-v2/ocp-v2-composer-logic.js +2 -6
  336. package/neural-interface/public/shared/ocp-v2/ocp-v2-context-menu.js +11 -11
  337. package/neural-interface/public/shared/ocp-v2/ocp-v2-context-model.js +0 -3
  338. package/neural-interface/public/shared/ocp-v2/ocp-v2-events.js +8 -4
  339. package/neural-interface/public/shared/ocp-v2/ocp-v2-manager.js +7 -7
  340. package/neural-interface/public/shared/ocp-v2/ocp-v2-modelpicker.js +54 -17
  341. package/neural-interface/public/shared/ocp-v2/ocp-v2-outcome-notifications.js +16 -0
  342. package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +140 -254
  343. package/neural-interface/public/shared/ocp-v2/ocp-v2-plan.js +1 -2
  344. package/neural-interface/public/shared/ocp-v2/ocp-v2-projectbar.js +97 -203
  345. package/neural-interface/public/shared/ocp-v2/ocp-v2-providers.js +11 -9
  346. package/neural-interface/public/shared/ocp-v2/ocp-v2-rehydrate.js +15 -4
  347. package/neural-interface/public/shared/ocp-v2/ocp-v2-render.js +7 -22
  348. package/neural-interface/public/shared/ocp-v2/ocp-v2-send-logic.js +401 -0
  349. package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +20 -13
  350. package/neural-interface/public/shared/ocp-v2/ocp-v2-session-actions.js +8 -61
  351. package/neural-interface/public/shared/ocp-v2/ocp-v2-sessions-logic.js +53 -82
  352. package/neural-interface/public/shared/ocp-v2/ocp-v2-slash-hints.js +16 -15
  353. package/neural-interface/public/shared/ocp-v2/ocp-v2-state.js +8 -21
  354. package/neural-interface/public/shared/ocp-v2/ocp-v2-status-logic.js +1 -99
  355. package/neural-interface/public/shared/ocp-v2/ocp-v2-status.js +5 -35
  356. package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +48 -40
  357. package/neural-interface/public/shared/ocp-v2/{ocp-v2-profile-inheritance.js → ocp-v2-tools-inheritance.js} +16 -16
  358. package/neural-interface/public/shared/ocp-v2/ocp-v2-ws.js +205 -62
  359. package/neural-interface/public/shared/opencode-providers.js +39 -0
  360. package/neural-interface/public/shared/page-session.js +96 -0
  361. package/neural-interface/public/shared/registry.js +5 -3
  362. package/neural-interface/public/shared/retired-2d.js +3 -0
  363. package/neural-interface/public/shared/schedules-view.js +452 -0
  364. package/neural-interface/public/shared/settings/settings-app-pane.js +335 -0
  365. package/neural-interface/public/shared/settings/settings-app.js +243 -0
  366. package/neural-interface/public/shared/settings/settings-claude-hooks.js +135 -0
  367. package/neural-interface/public/shared/settings/settings-data.js +90 -0
  368. package/neural-interface/public/shared/settings/settings-ia.js +23 -6
  369. package/neural-interface/public/shared/settings/settings-opencode.js +89 -0
  370. package/neural-interface/public/shared/settings/settings-skill-folders-pane.js +265 -0
  371. package/neural-interface/public/shared/settings/settings-skill-folders.js +130 -0
  372. package/neural-interface/public/shared/settings/settings-worker-guard.js +72 -0
  373. package/neural-interface/public/shared/sidepanel-session-status.js +49 -0
  374. package/neural-interface/public/shared/skills/ss-args.js +96 -0
  375. package/neural-interface/public/shared/skills/ss-creation.js +219 -0
  376. package/neural-interface/public/shared/skills/ss-dialog.js +130 -0
  377. package/neural-interface/public/shared/skills/ss-doc.js +173 -0
  378. package/neural-interface/public/shared/skills/ss-eval-adapters.js +269 -0
  379. package/neural-interface/public/shared/skills/ss-eval-grade.js +359 -0
  380. package/neural-interface/public/shared/skills/ss-eval-optimise.js +153 -0
  381. package/neural-interface/public/shared/skills/ss-eval-plan.js +315 -0
  382. package/neural-interface/public/shared/skills/ss-evals.js +417 -0
  383. package/neural-interface/public/shared/skills/ss-form.js +159 -0
  384. package/neural-interface/public/shared/skills/ss-frontmatter.js +376 -0
  385. package/neural-interface/public/shared/skills/ss-ids.js +32 -0
  386. package/neural-interface/public/shared/skills/ss-lint.js +141 -0
  387. package/neural-interface/public/shared/skills/ss-presets.js +117 -0
  388. package/neural-interface/public/shared/skills/ss-profiles.js +475 -0
  389. package/neural-interface/public/shared/skills/ss-resources.js +165 -0
  390. package/neural-interface/public/shared/skills/ss-review-view.js +190 -0
  391. package/neural-interface/public/shared/skills/ss-tabs.js +79 -0
  392. package/neural-interface/public/shared/skills/ss-unicode.js +135 -0
  393. package/neural-interface/public/shared/skills/studio/sx-actions.js +222 -0
  394. package/neural-interface/public/shared/skills/studio/sx-cm.js +101 -0
  395. package/neural-interface/public/shared/skills/studio/sx-create-ai-view.js +749 -0
  396. package/neural-interface/public/shared/skills/studio/sx-create-ai.js +236 -0
  397. package/neural-interface/public/shared/skills/studio/sx-create-view.js +254 -0
  398. package/neural-interface/public/shared/skills/studio/sx-create.js +126 -0
  399. package/neural-interface/public/shared/skills/studio/sx-diff-view.js +43 -0
  400. package/neural-interface/public/shared/skills/studio/sx-diff.js +133 -0
  401. package/neural-interface/public/shared/skills/studio/sx-docs.js +480 -0
  402. package/neural-interface/public/shared/skills/studio/sx-dom.js +229 -0
  403. package/neural-interface/public/shared/skills/studio/sx-edit-view.js +848 -0
  404. package/neural-interface/public/shared/skills/studio/sx-editor-model.js +193 -0
  405. package/neural-interface/public/shared/skills/studio/sx-errors.js +22 -0
  406. package/neural-interface/public/shared/skills/studio/sx-geometry.js +82 -0
  407. package/neural-interface/public/shared/skills/studio/sx-import.js +262 -0
  408. package/neural-interface/public/shared/skills/studio/sx-inspector.js +308 -0
  409. package/neural-interface/public/shared/skills/studio/sx-install-flow.js +279 -0
  410. package/neural-interface/public/shared/skills/studio/sx-install.js +296 -0
  411. package/neural-interface/public/shared/skills/studio/sx-library-view.js +639 -0
  412. package/neural-interface/public/shared/skills/studio/sx-library.js +475 -0
  413. package/neural-interface/public/shared/skills/studio/sx-main.js +681 -0
  414. package/neural-interface/public/shared/skills/studio/sx-operations-view.js +98 -0
  415. package/neural-interface/public/shared/skills/studio/sx-operations.js +11 -0
  416. package/neural-interface/public/shared/skills/studio/sx-plan.js +158 -0
  417. package/neural-interface/public/shared/skills/studio/sx-publish-view.js +621 -0
  418. package/neural-interface/public/shared/skills/studio/sx-review-view.js +369 -0
  419. package/neural-interface/public/shared/skills/studio/sx-review.js +148 -0
  420. package/neural-interface/public/shared/skills/studio/sx-scan.js +35 -0
  421. package/neural-interface/public/shared/skills/studio/sx-snippets.js +96 -0
  422. package/neural-interface/public/shared/skills/studio/sx-subject.js +248 -0
  423. package/neural-interface/public/shared/skills/studio/sx-test-view.js +994 -0
  424. package/neural-interface/public/shared/skills/studio/sx-test.js +328 -0
  425. package/neural-interface/public/shared/skills/studio/sx-versions-view.js +241 -0
  426. package/neural-interface/public/shared/skills/studio/sx-workspace-view.js +425 -0
  427. package/neural-interface/public/shared/styleguide/sg-panel.js +4 -2
  428. package/neural-interface/public/shared/styles.css +2065 -2150
  429. package/neural-interface/public/shared/synabun-mascot.js +1115 -9
  430. package/neural-interface/public/shared/tool-list-picker.js +55 -0
  431. package/neural-interface/public/shared/tool-list-storage.js +24 -0
  432. package/neural-interface/public/shared/tool-list-view.js +112 -0
  433. package/neural-interface/public/shared/tour/tour-actor.js +268 -0
  434. package/neural-interface/public/shared/tour/tour-beats.js +336 -0
  435. package/neural-interface/public/shared/tour/tour-engine.js +884 -0
  436. package/neural-interface/public/shared/tour/tour-ink.js +390 -0
  437. package/neural-interface/public/shared/tour/tour-stage.js +440 -0
  438. package/neural-interface/public/shared/tour/tour-state.js +40 -0
  439. package/neural-interface/public/shared/tour/tour-tips.js +99 -0
  440. package/neural-interface/public/shared/tour/tour.css +144 -0
  441. package/neural-interface/public/shared/ui-assistant.js +27 -5
  442. package/neural-interface/public/shared/ui-automation-studio.js +155 -152
  443. package/neural-interface/public/shared/ui-bookmarks.js +2 -1
  444. package/neural-interface/public/shared/ui-claude-panel.js +153 -13
  445. package/neural-interface/public/shared/ui-codex-panel.js +1 -0
  446. package/neural-interface/public/shared/ui-command-runner.js +6 -3
  447. package/neural-interface/public/shared/ui-context-menu.js +295 -0
  448. package/neural-interface/public/shared/ui-cost-widget.js +57 -59
  449. package/neural-interface/public/shared/ui-crash-notice.js +187 -0
  450. package/neural-interface/public/shared/ui-detail.js +21 -9
  451. package/neural-interface/public/shared/ui-file-links.js +1 -0
  452. package/neural-interface/public/shared/ui-image-gallery.js +56 -52
  453. package/neural-interface/public/shared/ui-invite.js +18 -2
  454. package/neural-interface/public/shared/ui-keybinds.js +26 -1
  455. package/neural-interface/public/shared/ui-link.js +9 -9
  456. package/neural-interface/public/shared/ui-menubar.js +229 -40
  457. package/neural-interface/public/shared/ui-native-loop-router-state.js +5 -0
  458. package/neural-interface/public/shared/ui-native-loop-router.js +9 -1
  459. package/neural-interface/public/shared/ui-navbar.js +4 -24
  460. package/neural-interface/public/shared/ui-opencode-panel-v2.js +1 -0
  461. package/neural-interface/public/shared/ui-panels.js +96 -65
  462. package/neural-interface/public/shared/ui-schedules-studio.js +2267 -953
  463. package/neural-interface/public/shared/ui-sessions.js +20 -7
  464. package/neural-interface/public/shared/ui-settings.js +679 -496
  465. package/neural-interface/public/shared/ui-sidebar.js +4 -4
  466. package/neural-interface/public/shared/ui-sidepanel-session-entry.js +13 -0
  467. package/neural-interface/public/shared/ui-sidepanel-sessions.js +56 -5
  468. package/neural-interface/public/shared/ui-sidepanel-state.js +23 -12
  469. package/neural-interface/public/shared/ui-sidepanel-tray.js +84 -8
  470. package/neural-interface/public/shared/ui-sidepanel-windows.js +16 -11
  471. package/neural-interface/public/shared/ui-skills.js +42 -2781
  472. package/neural-interface/public/shared/ui-styleguide.js +5 -2
  473. package/neural-interface/public/shared/ui-sync.js +22 -5
  474. package/neural-interface/public/shared/ui-terminal.js +159 -199
  475. package/neural-interface/public/shared/ui-tool-updates.js +3 -1
  476. package/neural-interface/public/shared/ui-tooltip.js +10 -5
  477. package/neural-interface/public/shared/ui-trash.js +14 -5
  478. package/neural-interface/public/shared/ui-tutorial-layout.js +3 -117
  479. package/neural-interface/public/shared/ui-tutorial-preview.js +103 -0
  480. package/neural-interface/public/shared/ui-tutorial-steps.js +3 -61
  481. package/neural-interface/public/shared/ui-tutorial.css +47 -100
  482. package/neural-interface/public/shared/ui-tutorial.js +285 -499
  483. package/neural-interface/public/shared/ui-update.js +121 -16
  484. package/neural-interface/public/shared/ui-whiteboard.js +313 -59
  485. package/neural-interface/public/shared/ui-worker-end.js +4 -0
  486. package/neural-interface/public/shared/ui-workspaces.js +3 -2
  487. package/neural-interface/public/shared/view-variant.js +66 -0
  488. package/neural-interface/public/shared/whatsapp/wa-view.js +1 -1
  489. package/neural-interface/public/shared/whiteboard-list.js +172 -0
  490. package/neural-interface/public/shared/worker-end.js +10 -3
  491. package/neural-interface/public/shared/worker-restart.js +12 -0
  492. package/neural-interface/public/sidepanel-session.html +1 -1
  493. package/neural-interface/public/variant/2d/background.js +2 -1
  494. package/neural-interface/public/variant/2d/context-menu.js +8 -2
  495. package/neural-interface/public/variant/2d/graph.js +42 -20
  496. package/neural-interface/public/variant/2d/hulls.js +14 -9
  497. package/neural-interface/public/variant/2d/lasso.js +11 -7
  498. package/neural-interface/public/variant/2d/main.js +36 -2
  499. package/neural-interface/public/variant/2d/minimap.js +11 -13
  500. package/neural-interface/public/variant/3d/main.js +72 -6
  501. package/neural-interface/public/variant/3d/map-controls.js +24 -9
  502. package/neural-interface/public/vendor/caveat/OFL.txt +93 -0
  503. package/neural-interface/public/vendor/caveat/caveat-latin-400-normal.woff2 +0 -0
  504. package/neural-interface/public/vendor/caveat/caveat-latin-700-normal.woff2 +0 -0
  505. package/neural-interface/public/vendor/caveat/caveat.css +17 -0
  506. package/neural-interface/public/vendor/caveat/manifest.json +12 -0
  507. package/neural-interface/public/vendor/highlight/LICENSE +29 -0
  508. package/neural-interface/public/vendor/highlight/github-dark-dimmed-11.12.0.min.css +9 -0
  509. package/neural-interface/public/vendor/highlight/highlight-11.12.0.min.js +1262 -0
  510. package/neural-interface/public/vendor/highlight/manifest.json +5 -0
  511. package/neural-interface/public/vendor/html2canvas/LICENSE +22 -0
  512. package/neural-interface/public/vendor/html2canvas/html2canvas-1.4.1.min.js +20 -0
  513. package/neural-interface/public/vendor/html2canvas/manifest.json +4 -0
  514. package/neural-interface/public/vendor/marked/LICENSE.md +44 -0
  515. package/neural-interface/public/vendor/marked/manifest.json +4 -0
  516. package/neural-interface/public/vendor/marked/marked-14.1.4.esm.js +2502 -0
  517. package/neural-interface/public/vendor/mermaid/LICENSE +21 -0
  518. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/abnfDiagram-PAR5IXJI.mjs +1 -0
  519. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/architecture-7GRP2DOG-M7G3SWCO.mjs +1 -0
  520. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/architectureDiagram-2PNWDENW.mjs +36 -0
  521. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/blockDiagram-PUWGUBOA.mjs +129 -0
  522. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/c4Diagram-3NLNHZP5.mjs +38 -0
  523. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-2NMSUPJH.mjs +1 -0
  524. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-32MCUW2P.mjs +206 -0
  525. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-3NPNU5GP.mjs +1 -0
  526. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-3SMGFRGC.mjs +1 -0
  527. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-4CAJECRU.mjs +14 -0
  528. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-4OADUZ5Q.mjs +10 -0
  529. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5IMINLNL.mjs +1 -0
  530. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5IQCK5RY.mjs +3 -0
  531. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5MVFYWFU.mjs +1 -0
  532. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-AQ6EADP3.mjs +1 -0
  533. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-AZZRMDJM.mjs +15 -0
  534. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-CLS4B6BI.mjs +168 -0
  535. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-DZP67EKU.mjs +70 -0
  536. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-EICP7K5X.mjs +1 -0
  537. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-GDY2UAB4.mjs +1 -0
  538. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-H7VHZCWX.mjs +1 -0
  539. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-IJBDOHL6.mjs +1 -0
  540. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JFFVMJIA.mjs +1 -0
  541. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JQRUD6KW.mjs +1 -0
  542. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JZGDI5JK.mjs +1 -0
  543. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-KD6SPIPN.mjs +2 -0
  544. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-NF366YI6.mjs +231 -0
  545. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-NUDPKBEF.mjs +32 -0
  546. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-OJINMHTS.mjs +1 -0
  547. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-Q6NGPIAH.mjs +2 -0
  548. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-QJSWEUOL.mjs +132 -0
  549. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-R7JDMUKV.mjs +1 -0
  550. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-RCXAM2GK.mjs +1 -0
  551. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-RT4MAWR3.mjs +1 -0
  552. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-SFMINX4W.mjs +1 -0
  553. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-SLDQ463B.mjs +88 -0
  554. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-STOV2HOB.mjs +1 -0
  555. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-T5OCTHI4.mjs +1 -0
  556. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-TCEHX7R3.mjs +1 -0
  557. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VQC2EELJ.mjs +1 -0
  558. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VRZKL3EH.mjs +1 -0
  559. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VTHDQ7BV.mjs +1 -0
  560. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VY2OSTJR.mjs +2 -0
  561. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-WUBWJARI.mjs +1 -0
  562. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-YBMQ5JGJ.mjs +2 -0
  563. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-YDMLL4PJ.mjs +1 -0
  564. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-Z6V44ARX.mjs +62 -0
  565. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZJJ7VQJP.mjs +339 -0
  566. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZNLK7HRR.mjs +1 -0
  567. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZQN7UHIL.mjs +1 -0
  568. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZS6VBONO.mjs +174 -0
  569. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZUNWM646.mjs +1 -0
  570. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/classDiagram-FGAMPOII.mjs +1 -0
  571. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/classDiagram-v2-AI5RJEK4.mjs +1 -0
  572. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cose-bilkent-Q72C2OJ3.mjs +1 -0
  573. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cynefin-OW5HDTMX-6OCTWOGG.mjs +1 -0
  574. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cynefinDiagram-2OOWUY4M.mjs +62 -0
  575. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/dagre-MPVFI544.mjs +4 -0
  576. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-AE4NWXFW.mjs +24 -0
  577. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-BUJID5UG.mjs +41 -0
  578. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-C44CZ5NI.mjs +24 -0
  579. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-EYOLEXXS.mjs +30 -0
  580. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-P7B6PWOJ.mjs +3 -0
  581. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ebnfDiagram-FTPZ3PV6.mjs +1 -0
  582. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/erDiagram-H3ERR26V.mjs +99 -0
  583. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/eventmodeling-NTZA5JFV-WKSWQHFS.mjs +1 -0
  584. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/flowDiagram-YHGXBVSY.mjs +1 -0
  585. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ganttDiagram-RWFTB7ED.mjs +292 -0
  586. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/gitGraph-4MIJSDKK-JH2HKYUO.mjs +1 -0
  587. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/gitGraphDiagram-MAR6GKOP.mjs +106 -0
  588. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/info-A6RAGUB7-3TX3OFWW.mjs +1 -0
  589. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/infoDiagram-LV547AFH.mjs +2 -0
  590. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ishikawaDiagram-PUJQGNDS.mjs +70 -0
  591. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/journeyDiagram-EW5QJT4W.mjs +139 -0
  592. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/kanban-definition-JSQERAZB.mjs +89 -0
  593. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/katex-CZ4GXH2S.mjs +257 -0
  594. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/mindmap-definition-VBJCLQLM.mjs +96 -0
  595. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/packet-AYTQ26CC-MKII6P3Y.mjs +1 -0
  596. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pegDiagram-7WILOQTJ.mjs +1 -0
  597. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pie-WAS4IAKB-6B4OPMJ5.mjs +1 -0
  598. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pieDiagram-EFA7CBSB.mjs +39 -0
  599. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/quadrantDiagram-WARVYA7P.mjs +7 -0
  600. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/radar-RG4KPBEZ-UPTR3XUL.mjs +1 -0
  601. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-74A4TZTK-MEFUPFMS.mjs +1 -0
  602. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-abnf-HS5TGJTU-R5YG2S5D.mjs +1 -0
  603. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-ebnf-LZEXJU2U-G5QEX2L6.mjs +1 -0
  604. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-peg-WCYAUIDC-H5I2ZRY2.mjs +1 -0
  605. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroadDiagram-5NIQVNLQ.mjs +1 -0
  606. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/requirementDiagram-SXREGOKZ.mjs +84 -0
  607. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sankeyDiagram-VV74M2VP.mjs +40 -0
  608. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sequenceDiagram-52ZFIFDL.mjs +162 -0
  609. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sizeCapture-FGA5AGYP.mjs +1 -0
  610. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/stateDiagram-3QAKPIVI.mjs +1 -0
  611. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/stateDiagram-v2-HN2P4RDZ.mjs +1 -0
  612. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/swimlanes-QLVP42QD.mjs +1 -0
  613. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/swimlanesDiagram-JKPDBFCN.mjs +8 -0
  614. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/timeline-definition-GS45XAXW.mjs +120 -0
  615. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/treeView-Q6P3EWNA-ZRJGANNQ.mjs +1 -0
  616. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/treemap-WGGIJYW6-K64VN5AS.mjs +1 -0
  617. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/vennDiagram-QIQU2ZRJ.mjs +34 -0
  618. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/wardley-WFR3VGLG-D67OWCCH.mjs +1 -0
  619. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/wardleyDiagram-U6YNM66N.mjs +78 -0
  620. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/xychartDiagram-XJAZEDNM.mjs +7 -0
  621. package/neural-interface/public/vendor/mermaid/manifest.json +4 -0
  622. package/neural-interface/public/vendor/mermaid/mermaid-11.17.2.esm.min.mjs +14 -0
  623. package/neural-interface/public/vendor/yaml/LICENSE +13 -0
  624. package/neural-interface/public/vendor/yaml/manifest.json +4 -0
  625. package/neural-interface/public/vendor/yaml/yaml-2.9.1.min.js +137 -0
  626. package/neural-interface/scripts/build-vendor.mjs +116 -3
  627. package/neural-interface/server.js +4834 -2541
  628. package/neural-interface/templates/rulesets/core.md +1 -1
  629. package/neural-interface/templates/rulesets/legacy-hashes.json +18 -0
  630. package/neural-interface/templates/rulesets/manifest.json +8 -8
  631. package/npm-shrinkwrap.json +18 -12
  632. package/package.json +16 -3
  633. package/postinstall.js +9 -4
  634. package/preuninstall.js +1 -1
  635. package/setup.js +97 -322
  636. package/skills/skill-forge/SKILL.md +177 -0
  637. package/skills/skill-forge/evals/evals.json +54 -0
  638. package/skills/skill-forge/references/package.md +105 -0
  639. package/skills/skill-forge/references/review-and-recovery.md +63 -0
  640. package/skills/skill-forge/references/runtime-profiles.md +20 -0
  641. package/skills/skill-forge/references/sources-and-capabilities.md +51 -0
  642. package/skills/synabun/SKILL.md +10 -7
  643. package/skills/synabun/modules/audit.md +1 -5
  644. package/skills/synabun/modules/changelog.md +1 -5
  645. package/skills/synabun/modules/idea.md +1 -1
  646. package/skills/synabun/modules/memorize.md +6 -9
  647. package/skills/synabun/modules/schedule.md +5 -5
  648. package/mcp-server/dist/services/profiles.d.ts +0 -120
  649. package/mcp-server/dist/services/profiles.d.ts.map +0 -1
  650. package/mcp-server/dist/services/profiles.js +0 -387
  651. package/mcp-server/dist/services/profiles.js.map +0 -1
  652. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts +0 -97
  653. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts.map +0 -1
  654. package/mcp-server/dist/tools/leonardo-browser-tools.js +0 -228
  655. package/mcp-server/dist/tools/leonardo-browser-tools.js.map +0 -1
  656. package/mcp-server/dist/tools/leonardo.d.ts +0 -13
  657. package/mcp-server/dist/tools/leonardo.d.ts.map +0 -1
  658. package/mcp-server/dist/tools/leonardo.js +0 -21
  659. package/mcp-server/dist/tools/leonardo.js.map +0 -1
  660. package/mcp-server/dist/tools/profile.d.ts +0 -17
  661. package/mcp-server/dist/tools/profile.d.ts.map +0 -1
  662. package/mcp-server/dist/tools/profile.js +0 -114
  663. package/mcp-server/dist/tools/profile.js.map +0 -1
  664. package/mcp-server/src/services/profiles.ts +0 -428
  665. package/mcp-server/src/tools/leonardo-browser-tools.ts +0 -291
  666. package/mcp-server/src/tools/leonardo.ts +0 -30
  667. package/mcp-server/src/tools/profile.ts +0 -122
  668. package/neural-interface/lib/assistant-brains/opencode-browser-policy.js +0 -47
  669. package/neural-interface/lib/assistant-brains/opencode-route-gate.js +0 -62
  670. package/neural-interface/lib/mcp-profile-servers.js +0 -120
  671. package/neural-interface/public/shared/ui-tutorial-draw.js +0 -311
  672. package/skills/leonardo/SKILL.md +0 -168
  673. package/skills/leonardo/icon.svg +0 -1
  674. package/skills/leonardo/modules/browser-guide.md +0 -378
  675. package/skills/leonardo/modules/image-prompter.md +0 -283
  676. package/skills/leonardo/modules/model-advisor.md +0 -100
  677. package/skills/leonardo/modules/prompt-library.md +0 -110
  678. package/skills/leonardo/modules/style-guide.md +0 -186
  679. package/skills/leonardo/modules/video-prompter.md +0 -317
@@ -0,0 +1,372 @@
1
+ // ═══════════════════════════════════════════
2
+ // SynaBun Neural Interface — Context menu component
3
+ // One menu at a time, at the pointer or by the focused element, in the box of
4
+ // the menubar's dropdown and with its rows (.menu-item, .menu-shortcut,
5
+ // .menu-submenu-arrow, .menu-sep). Items are data (context-menu-logic.js);
6
+ // this module draws them, places the menu and its submenus inside the window,
7
+ // takes the keys while it is open and closes on a press outside, Escape,
8
+ // Tab, scroll, resize, window blur and after an action. Any area can open
9
+ // one; the app's global right-click menu is ui-context-menu.js.
10
+ // ═══════════════════════════════════════════
11
+
12
+ import {
13
+ anchorPoint, firstIndex, lastIndex, normalizeItems, placeMenu, placeSubmenu, stepIndex, typeaheadIndex,
14
+ } from './context-menu-logic.js';
15
+ import { boundsForPoint, frameRect } from './app-frame.js';
16
+
17
+ const SUBMENU_OPEN_DELAY = 120; // hover intent before a submenu opens
18
+ const SUBMENU_GRACE = 300; // the pointer may cross other rows on its way into an open submenu
19
+ const TYPEAHEAD_RESET = 600;
20
+ const ARROW_SVG = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg>';
21
+
22
+ let _open = null; // the open menu's handle
23
+
24
+ /** Whether a menu is open. */
25
+ export const isContextMenuOpen = () => !!_open;
26
+
27
+ /** Close the open menu, if there is one. `refocus: false` leaves the keyboard where it is. */
28
+ export function closeContextMenu(o) { _open?.close(o); }
29
+
30
+ /** The root element of the open menu, or null. */
31
+ export const openContextMenuElement = () => _open?.element || null;
32
+
33
+ /**
34
+ * Open a menu.
35
+ * @param {object} o
36
+ * @param {import('./context-menu-logic.js').MenuItem[]} o.items
37
+ * @param {number} [o.x] @param {number} [o.y] where the press was (client px)
38
+ * @param {DOMRect | null} [o.anchorRect] opened from the keyboard: the focused element's box, used when x/y are missing
39
+ * @param {string} [o.label] the menu's accessible name
40
+ * @param {boolean} [o.keyboard] opened from the keyboard: the first row has the focus from the start
41
+ * @param {Element | null} [o.returnFocus] where the keyboard goes back to when the menu closes
42
+ * @param {() => void} [o.onClose]
43
+ * @returns {{ close: Function, element: HTMLElement } | null} null when no item is left to show
44
+ */
45
+ export function openContextMenu({ items, x, y, anchorRect = null, label = '', keyboard = false,
46
+ returnFocus = document.activeElement, onClose } = {}) {
47
+ // A menu opened over another one hands the keyboard back to where the first one would have.
48
+ if (_open && (!returnFocus || _open.contains(returnFocus))) returnFocus = _open.returnFocus;
49
+ closeContextMenu({ refocus: false });
50
+ const list = normalizeItems(items);
51
+ if (!list.length) return null;
52
+
53
+ const levels = []; // [{ el, items, rows, active, parentRow }]
54
+ let bounds = null; // the app frame for a menu opened inside it (it and its submenus stay in it), else the window
55
+ let closed = false;
56
+ let subTimer = 0;
57
+ let subPending = null;
58
+ let typed = '';
59
+ let typedAt = 0;
60
+
61
+ // ── Drawing ──
62
+ function drawRow(item) {
63
+ if (item.separator) {
64
+ const sep = document.createElement('div');
65
+ sep.className = 'menu-sep';
66
+ sep.setAttribute('role', 'separator');
67
+ return sep;
68
+ }
69
+ const row = document.createElement('div');
70
+ row.className = 'menu-item';
71
+ row.tabIndex = -1;
72
+ const checkable = typeof item.checked === 'boolean';
73
+ row.setAttribute('role', checkable ? 'menuitemcheckbox' : 'menuitem');
74
+ if (checkable) {
75
+ row.setAttribute('aria-checked', String(item.checked));
76
+ row.classList.toggle('active', item.checked);
77
+ }
78
+ if (item.id) row.dataset.ctxId = item.id;
79
+ if (item.disabled) {
80
+ row.classList.add('disabled');
81
+ row.setAttribute('aria-disabled', 'true');
82
+ }
83
+ const check = document.createElement('span');
84
+ check.className = 'menu-check';
85
+ check.setAttribute('aria-hidden', 'true');
86
+ check.textContent = checkable ? '✓' : '';
87
+ const text = document.createElement('span');
88
+ text.className = 'menu-text';
89
+ if (item.icon) {
90
+ const icon = document.createElement('span');
91
+ icon.className = 'menu-icon';
92
+ icon.setAttribute('aria-hidden', 'true');
93
+ icon.innerHTML = item.icon; // the app's own markup, never text from the page
94
+ text.append(icon);
95
+ }
96
+ const name = document.createElement('span');
97
+ name.className = 'app-ctx-label';
98
+ name.textContent = item.label;
99
+ text.append(name);
100
+ row.append(check, text);
101
+ if (item.submenu) {
102
+ row.setAttribute('aria-haspopup', 'menu');
103
+ row.setAttribute('aria-expanded', 'false');
104
+ const arrow = document.createElement('span');
105
+ arrow.className = 'menu-submenu-arrow';
106
+ arrow.setAttribute('aria-hidden', 'true');
107
+ arrow.innerHTML = ARROW_SVG;
108
+ row.append(arrow);
109
+ } else if (item.shortcut) {
110
+ const key = document.createElement('span');
111
+ key.className = 'menu-shortcut';
112
+ key.textContent = item.shortcut;
113
+ row.append(key);
114
+ }
115
+ return row;
116
+ }
117
+
118
+ function drawLevel(levelItems, name) {
119
+ const el = document.createElement('div');
120
+ el.className = 'app-ctx-menu';
121
+ el.setAttribute('role', 'menu');
122
+ if (name) el.setAttribute('aria-label', name);
123
+ el.tabIndex = -1;
124
+ el.style.visibility = 'hidden';
125
+ const rows = levelItems.map(drawRow);
126
+ el.append(...rows);
127
+ const level = { el, items: levelItems, rows, active: -1, parentRow: null };
128
+ el.addEventListener('pointermove', (event) => onHover(level, event));
129
+ el.addEventListener('click', (event) => {
130
+ const index = rowIndex(level, event.target);
131
+ if (index >= 0) activate(level, index);
132
+ });
133
+ // The press stays off the page: nothing selected there is cleared, nothing behind the menu is focused.
134
+ el.addEventListener('pointerdown', (event) => event.preventDefault());
135
+ el.addEventListener('mousedown', (event) => event.preventDefault());
136
+ el.addEventListener('contextmenu', (event) => event.preventDefault());
137
+ document.body.appendChild(el);
138
+ return level;
139
+ }
140
+
141
+ const rowIndex = (level, node) => {
142
+ const row = node?.closest?.('.menu-item');
143
+ return row ? level.rows.indexOf(row) : -1;
144
+ };
145
+ const levelOf = (index) => levels[index];
146
+ const levelIndex = (level) => levels.indexOf(level);
147
+
148
+ // ── The row the keyboard and the pointer are on ──
149
+ function setActive(level, index, { focus = true } = {}) {
150
+ if (level.active >= 0) level.rows[level.active]?.classList.remove('focused');
151
+ level.active = index;
152
+ const row = index >= 0 ? level.rows[index] : null;
153
+ if (!row) { if (focus) level.el.focus({ preventScroll: true }); return; }
154
+ row.classList.add('focused');
155
+ if (focus) row.focus({ preventScroll: true });
156
+ row.scrollIntoView?.({ block: 'nearest' });
157
+ }
158
+
159
+ // The level the keyboard is in: the deepest one with a row on, else the deepest one open.
160
+ function keyLevel() {
161
+ for (let i = levels.length - 1; i >= 0; i--) if (levels[i].active >= 0) return levels[i];
162
+ return levels[levels.length - 1];
163
+ }
164
+
165
+ // ── Submenus ──
166
+ function openSubmenu(level, index, { focusFirst = false } = {}) {
167
+ cancelTimer();
168
+ const item = level.items[index];
169
+ const row = level.rows[index];
170
+ if (!item?.submenu || item.disabled) return;
171
+ const depth = levelIndex(level);
172
+ const next = levelOf(depth + 1);
173
+ if (next?.parentRow !== row) {
174
+ closeFrom(depth + 1);
175
+ const sub = drawLevel(item.submenu, item.label);
176
+ sub.parentRow = row;
177
+ levels.push(sub);
178
+ row.classList.add('submenu-open');
179
+ row.setAttribute('aria-expanded', 'true');
180
+ const menuRect = level.el.getBoundingClientRect();
181
+ const rowRect = row.getBoundingClientRect();
182
+ const box = sub.el.getBoundingClientRect();
183
+ const at = placeSubmenu({ menuRect, rowRect, width: box.width, height: box.height,
184
+ viewportWidth: window.innerWidth, viewportHeight: window.innerHeight, bounds });
185
+ sub.el.style.left = `${at.left}px`;
186
+ sub.el.style.top = `${at.top}px`;
187
+ sub.el.dataset.side = at.side;
188
+ sub.el.style.visibility = '';
189
+ }
190
+ if (focusFirst) setActive(levelOf(depth + 1), firstIndex(item.submenu));
191
+ }
192
+
193
+ // Close every level from `depth` down; the row that opened the first of them is no longer open.
194
+ function closeFrom(depth) {
195
+ while (levels.length > Math.max(depth, 1)) {
196
+ const level = levels.pop();
197
+ level.parentRow?.classList.remove('submenu-open');
198
+ level.parentRow?.setAttribute('aria-expanded', 'false');
199
+ level.el.remove();
200
+ }
201
+ }
202
+
203
+ function scheduleTimer(row, fn, ms) {
204
+ clearTimeout(subTimer);
205
+ subPending = row;
206
+ subTimer = setTimeout(() => { subTimer = 0; subPending = null; if (!closed) fn(); }, ms);
207
+ }
208
+ function cancelTimer() {
209
+ clearTimeout(subTimer);
210
+ subTimer = 0;
211
+ subPending = null;
212
+ }
213
+
214
+ function onHover(level, event) {
215
+ const index = rowIndex(level, event.target);
216
+ if (index < 0) return;
217
+ const item = level.items[index];
218
+ const row = level.rows[index];
219
+ if (item.disabled) return;
220
+ if (level.active !== index) setActive(level, index);
221
+ // Back in a parent level: the deeper ones lose their highlight, not their place.
222
+ const depth = levelIndex(level);
223
+ for (let i = depth + 1; i < levels.length; i++) setActive(levels[i], -1, { focus: false });
224
+ if (row === subPending) return;
225
+ const next = levelOf(depth + 1);
226
+ if (next) {
227
+ if (next.parentRow === row) { cancelTimer(); return; }
228
+ scheduleTimer(row, () => (item.submenu ? openSubmenu(level, index) : closeFrom(depth + 1)), SUBMENU_GRACE);
229
+ } else if (item.submenu) {
230
+ scheduleTimer(row, () => openSubmenu(level, index), SUBMENU_OPEN_DELAY);
231
+ } else {
232
+ cancelTimer();
233
+ }
234
+ }
235
+
236
+ // ── Choosing ──
237
+ function activate(level, index) {
238
+ const item = level.items[index];
239
+ if (!item || item.separator || item.disabled) return;
240
+ if (item.submenu) { openSubmenu(level, index, { focusFirst: true }); return; }
241
+ close({ refocus: true });
242
+ try {
243
+ const result = item.run?.();
244
+ if (result && typeof result.catch === 'function') result.catch((err) => console.warn('[context-menu] action failed:', err));
245
+ } catch (err) {
246
+ console.warn('[context-menu] action failed:', err);
247
+ }
248
+ }
249
+
250
+ // ── Keys (at the window, before anything in the page; the app's single-key shortcuts must not fire) ──
251
+ function onKey(event) {
252
+ if (event.ctrlKey || event.metaKey || event.altKey) {
253
+ if (event.key === 'Escape') { event.preventDefault(); close({ refocus: true }); }
254
+ return; // the browser's and the system's keys stay theirs
255
+ }
256
+ const level = keyLevel();
257
+ const depth = levelIndex(level);
258
+ const deepest = levels.length - 1; // a submenu the pointer opened may be open without the keyboard in it
259
+ const { key } = event;
260
+ const handled = () => { event.preventDefault(); event.stopPropagation(); };
261
+ // Moving to another row closes a submenu that belongs to the row left.
262
+ const move = (index) => {
263
+ setActive(level, index);
264
+ if (levelOf(depth + 1) && levelOf(depth + 1).parentRow !== level.rows[level.active]) closeFrom(depth + 1);
265
+ };
266
+ switch (key) {
267
+ case 'ArrowDown': handled(); move(stepIndex(level.items, level.active, 1)); return;
268
+ case 'ArrowUp': handled(); move(stepIndex(level.items, level.active, -1)); return;
269
+ case 'Home': handled(); move(firstIndex(level.items)); return;
270
+ case 'End': handled(); move(lastIndex(level.items)); return;
271
+ case 'ArrowRight':
272
+ handled();
273
+ if (level.items[level.active]?.submenu) openSubmenu(level, level.active, { focusFirst: true });
274
+ return;
275
+ case 'ArrowLeft':
276
+ handled();
277
+ if (deepest > 0) backTo(deepest);
278
+ return;
279
+ case 'Escape':
280
+ handled();
281
+ if (deepest > 0) backTo(deepest); else close({ refocus: true });
282
+ return;
283
+ case 'Tab': handled(); close({ refocus: true }); return;
284
+ case 'Enter':
285
+ case ' ':
286
+ handled();
287
+ if (level.active >= 0) activate(level, level.active);
288
+ return;
289
+ default:
290
+ if (key.length !== 1) return;
291
+ handled();
292
+ {
293
+ const now = Date.now();
294
+ typed = now - typedAt > TYPEAHEAD_RESET ? key : typed + key;
295
+ typedAt = now;
296
+ const index = typeaheadIndex(level.items, level.active, typed);
297
+ if (index >= 0) move(index);
298
+ }
299
+ }
300
+ }
301
+ // A Space released on a row must not reach it as a click either.
302
+ function onKeyUp(event) {
303
+ if (!event.ctrlKey && !event.metaKey && !event.altKey && (event.key === ' ' || event.key === 'Enter')) {
304
+ event.preventDefault();
305
+ event.stopPropagation();
306
+ }
307
+ }
308
+
309
+ // Leave a submenu for the row that opened it.
310
+ function backTo(depth) {
311
+ const parent = levelOf(depth - 1);
312
+ const row = levelOf(depth).parentRow;
313
+ closeFrom(depth);
314
+ setActive(parent, parent.rows.indexOf(row));
315
+ }
316
+
317
+ // ── Closing ──
318
+ const inside = (node) => levels.some((level) => level.el.contains(node));
319
+ const onOutsidePress = (event) => { if (!inside(event.target)) close({ refocus: false }); };
320
+ const onScroll = (event) => { if (!inside(event.target)) close({ refocus: false }); };
321
+ const onGone = () => close({ refocus: false });
322
+
323
+ function close({ refocus = true } = {}) {
324
+ if (closed) return;
325
+ closed = true;
326
+ if (_open === handle) _open = null;
327
+ cancelTimer();
328
+ window.removeEventListener('keydown', onKey, true);
329
+ window.removeEventListener('keyup', onKeyUp, true);
330
+ document.removeEventListener('pointerdown', onOutsidePress, true);
331
+ document.removeEventListener('scroll', onScroll, true);
332
+ document.removeEventListener('wheel', onScroll, true);
333
+ window.removeEventListener('resize', onGone);
334
+ window.removeEventListener('blur', onGone);
335
+ // The keyboard goes back where it was, unless the press outside already took it somewhere.
336
+ const active = document.activeElement;
337
+ const held = !active || active === document.body || inside(active);
338
+ for (const level of levels.splice(0)) level.el.remove();
339
+ if (refocus && held && returnFocus?.isConnected && typeof returnFocus.focus === 'function') {
340
+ try { returnFocus.focus({ preventScroll: true }); } catch { /* not focusable any more */ }
341
+ }
342
+ try { onClose?.(); } catch (err) { console.warn('[context-menu] onClose failed:', err); }
343
+ }
344
+
345
+ // ── Open ──
346
+ const root = drawLevel(list, label);
347
+ levels.push(root);
348
+ const box = root.el.getBoundingClientRect();
349
+ let px = x;
350
+ let py = y;
351
+ if (!Number.isFinite(px) || !Number.isFinite(py)) ({ x: px, y: py } = anchorPoint(anchorRect, window.innerWidth, window.innerHeight));
352
+ bounds = boundsForPoint(frameRect(), px, py);
353
+ const at = placeMenu({ x: px, y: py, width: box.width, height: box.height,
354
+ viewportWidth: window.innerWidth, viewportHeight: window.innerHeight, bounds });
355
+ root.el.style.left = `${at.left}px`;
356
+ root.el.style.top = `${at.top}px`;
357
+ root.el.style.visibility = '';
358
+ root.el.classList.add('app-ctx-menu--root');
359
+
360
+ const handle = { close, element: root.el, returnFocus, contains: inside };
361
+ _open = handle;
362
+ window.addEventListener('keydown', onKey, true);
363
+ window.addEventListener('keyup', onKeyUp, true);
364
+ document.addEventListener('pointerdown', onOutsidePress, true);
365
+ document.addEventListener('scroll', onScroll, true);
366
+ document.addEventListener('wheel', onScroll, { capture: true, passive: true });
367
+ window.addEventListener('resize', onGone);
368
+ window.addEventListener('blur', onGone);
369
+ if (keyboard) setActive(root, firstIndex(list));
370
+ else root.el.focus({ preventScroll: true });
371
+ return handle;
372
+ }
@@ -12,6 +12,7 @@
12
12
 
13
13
  import { cpCtx } from './cp-ctx.js';
14
14
  import { contextReading, contextMenuModel, isUnset } from './cp-context-model.js';
15
+ import { frameRect } from '../app-frame.js';
15
16
 
16
17
  const POP_ID = 'cp-context-popover';
17
18
  const LABEL = 'Context settings';
@@ -149,24 +150,24 @@ function tipClipped() {
149
150
  }
150
151
 
151
152
  // Below the cog, its right edge on the cog's; above it when there is more room
152
- // there; always inside the viewport, scrolling inside when it is taller.
153
+ // there; always inside the app frame, scrolling inside when it is taller.
153
154
  function place() {
154
155
  const $cog = cog();
155
156
  if (!_open || !_pop || !$cog) return;
156
157
  const r = $cog.getBoundingClientRect();
157
- const vw = window.innerWidth;
158
- const vh = window.innerHeight;
159
- const width = Math.max(0, Math.min(WIDTH, vw - MARGIN * 2));
158
+ // Inside the app frame (app-frame.js; the whole window on a page without it)
159
+ const f = frameRect();
160
+ const width = Math.max(0, Math.min(WIDTH, f.width - MARGIN * 2));
160
161
  _pop.style.width = `${width}px`;
161
- const below = vh - r.bottom - GAP - MARGIN;
162
- const above = r.top - GAP - MARGIN;
162
+ const below = f.bottom - r.bottom - GAP - MARGIN;
163
+ const above = r.top - f.top - GAP - MARGIN;
163
164
  const up = below < 220 && above > below;
164
165
  _pop.style.maxHeight = `${Math.max(120, up ? above : below)}px`;
165
166
  const height = _pop.offsetHeight;
166
- const left = Math.max(MARGIN, Math.min(r.right - width, vw - width - MARGIN));
167
+ const left = Math.max(f.left + MARGIN, Math.min(r.right - width, f.right - width - MARGIN));
167
168
  const top = up
168
- ? Math.max(MARGIN, r.top - GAP - height)
169
- : Math.max(MARGIN, Math.min(r.bottom + GAP, vh - MARGIN - height));
169
+ ? Math.max(f.top + MARGIN, r.top - GAP - height)
170
+ : Math.max(f.top + MARGIN, Math.min(r.bottom + GAP, f.bottom - MARGIN - height));
170
171
  _pop.style.left = `${Math.round(left)}px`;
171
172
  _pop.style.top = `${Math.round(top)}px`;
172
173
  // Once it has its width: only now is a cut value known.
@@ -1,5 +1,4 @@
1
- // Markdown → HTML for every Markdown sink of the Claude panel, and the scrub a
2
- // stored transcript snapshot goes through before it is put back on the page.
1
+ // Markdown → HTML for every Markdown sink of the Claude panel, and the panel's one escaper.
3
2
  //
4
3
  // What a model writes, what a command prints and what a transcript replays is
5
4
  // not ours: marked passes raw HTML through, so `<img onerror>` or a
@@ -47,58 +46,6 @@ export function renderMarkdown(text, { parse = null, sanitize = sanitizeHtmlStri
47
46
  }
48
47
  }
49
48
 
50
- // ── Stored snapshots ──
51
- // A snapshot is the transcript's own innerHTML, saved to be shown again on a
52
- // reopen. It is the panel's markup (cards, icons, buttons, data attributes),
53
- // so the Markdown allowlist would destroy it; but it may have been written by
54
- // a build that did not sanitise, and it comes back from storage. It is parsed
55
- // into an inert <template> and stripped of everything that can run or load
56
- // code before it reaches the page.
57
-
58
- const STORED_DROPPED = new Set(['script', 'iframe', 'frame', 'frameset', 'object', 'embed', 'applet', 'base', 'meta', 'link', 'style', 'template', 'noscript', 'foreignobject', 'animate', 'set', 'animatetransform', 'animatemotion']);
59
- const URL_ATTRS = new Set(['href', 'src', 'xlink:href', 'action', 'formaction', 'poster', 'data', 'background', 'ping']);
60
- const REMOVED_ATTRS = new Set(['srcdoc', 'srcset']);
61
- const SAFE_URL_SCHEMES = new Set(['http', 'https', 'mailto']);
62
-
63
- /** The scheme of a URL attribute as a browser reads it (whitespace and control characters ignored), or ''. */
64
- function schemeOf(value) {
65
- const m = /^([a-z][a-z0-9+.-]*):/i.exec(String(value ?? '').replace(/[\u0000- ]/g, ''));
66
- return m ? m[1].toLowerCase() : '';
67
- }
68
-
69
- function storedImageAllowed(src) {
70
- const compact = String(src ?? '').replace(/[\u0000- ]/g, '');
71
- if (!compact) return false;
72
- if (/^data:image\//i.test(compact) || /^blob:/i.test(compact)) return true;
73
- // A path on this server; a remote image is not loaded again from storage.
74
- return !schemeOf(compact) && !compact.startsWith('//');
75
- }
76
-
77
- function scrubNode(parent) {
78
- for (const node of [...parent.childNodes]) {
79
- if (node.nodeType === 3) continue;
80
- if (node.nodeType !== 1) { parent.removeChild(node); continue; }
81
- const tag = String(node.localName || '').toLowerCase();
82
- if (STORED_DROPPED.has(tag) || (tag === 'img' && !storedImageAllowed(node.getAttribute('src')))) { parent.removeChild(node); continue; }
83
- for (const name of node.getAttributeNames()) {
84
- const lower = name.toLowerCase();
85
- if (lower.startsWith('on') || REMOVED_ATTRS.has(lower)) { node.removeAttribute(name); continue; }
86
- if (!URL_ATTRS.has(lower)) continue;
87
- const scheme = schemeOf(node.getAttribute(name));
88
- if (!scheme || SAFE_URL_SCHEMES.has(scheme)) continue;
89
- if (tag === 'img' && lower === 'src') continue; // data:image / blob, checked above
90
- node.removeAttribute(name);
91
- }
92
- scrubNode(node);
93
- }
94
- }
95
-
96
- /** A stored snapshot's markup → a DocumentFragment with nothing executable left in it. */
97
- export function scrubStoredHtml(html, doc = globalThis.document) {
98
- const tpl = doc.createElement('template');
99
- tpl.innerHTML = String(html ?? '');
100
- scrubNode(tpl.content);
101
- const out = doc.createDocumentFragment();
102
- for (const node of [...tpl.content.childNodes]) out.appendChild(node);
103
- return out;
104
- }
49
+ // A stored transcript snapshot is not scrubbed here: the panel puts it back through
50
+ // sanitizeStoredHtml() of assistant/asst-sanitize.js, the stored-transcript allowlist
51
+ // every panel uses.
@@ -0,0 +1,168 @@
1
+ // ═══════════════════════════════════════════
2
+ // SynaBun Neural Interface — the notice after an automatic restart: what it says
3
+ // ═══════════════════════════════════════════
4
+ //
5
+ // When SynaBun's server crashes after it was up, its supervisor starts it again
6
+ // and leaves the new server a record of the crash (lib/server-crash-record.js,
7
+ // GET /api/system/crash-notice). The owner's pages say so until it is dismissed:
8
+ // that the server stopped unexpectedly and was restarted, when and how it ended,
9
+ // and what the restart ended. This module decides the words; ui-crash-notice.js
10
+ // asks the server and draws them.
11
+ //
12
+ // What the restart ends is what the code does when the server process dies and
13
+ // a new one starts, nothing more:
14
+ // - terminals: the pty host ends with the server and kills its shells
15
+ // (lib/pty-host/host.js on 'disconnect'); a new host has none of them
16
+ // - runs: dispatched worker runs and native loops that were running are marked
17
+ // interrupted at boot (lib/assistant-dispatch.js, lib/native-loop-runtime.js);
18
+ // Quick Timers, schedule timers set for later and the schedule queue live in
19
+ // memory; saved schedules keep firing. The program a run had started is not
20
+ // always ended with the server: on macOS and Linux a CLI whose input is not
21
+ // the server's (`claude -p`, `codex exec`) ends at its next write to the
22
+ // server, and on Windows one started through a shell is not in the server's
23
+ // job: hence "a step already under way may still finish"
24
+ // - replies: a Claude Code, Codex or Assistant turn in progress is gone, the
25
+ // conversation stays and the next message resumes it (an OpenCode serve that
26
+ // outlived the server may be adopted and go on: hence "may have been")
27
+ // - browser: the sessions SynaBun drove live in memory; their profiles stay
28
+ // - public address: cloudflared is not started again, a new start gets a new
29
+ // one. Windows ends it with the server (its job); on macOS and Linux it
30
+ // outlives a crash, and the new server ends it by its record at start
31
+ // (server.js sweepLeftoverTunnels). One it could not end is `tunnel:
32
+ // 'unknown'` in the notice, and the notice says the address may still be open
33
+ //
34
+ // No imports and no DOM: `node --test` loads this file as it is
35
+ // (tests/crash-notice-view.test.mjs). CRASH_NOTICE_COPY is the English of every
36
+ // sentence; `crashNotice.*` in i18n/en.json must equal it and i18n/pt-BR.json
37
+ // must have the same keys.
38
+
39
+ export const CRASH_NOTICE_COPY = Object.freeze({
40
+ title: 'SynaBun\'s server stopped unexpectedly and was restarted automatically.',
41
+ whenToday: 'It happened at {time}.',
42
+ whenEarlier: 'It happened on {date} at {time}.',
43
+ whenManyToday: 'It happened {count} times, the last at {time}.',
44
+ whenManyEarlier: 'It happened {count} times, the last on {date} at {time}.',
45
+ how: 'How it ended: {exit}.',
46
+ lostTitle: 'What the restart ended',
47
+ lostTerminals: 'Open terminals were closed.',
48
+ lostRuns: 'Agent runs and loops that were running were interrupted, though a step already under way may still finish on its own. Timers and queued runs were cleared. Saved schedules keep running.',
49
+ lostReplies: 'Replies being written in the side panels or the Assistant may have been cut off. The conversations are kept: send again what did not finish.',
50
+ lostBrowser: 'Browser sessions SynaBun was driving ended. Their saved sign-ins are kept.',
51
+ lostTunnel: 'The public address, if it was on, is off. Turning it on again gives a new address.',
52
+ lostTunnelUnknown: 'The public address, if it was on, may still be open: SynaBun could not end the cloudflared that served it. Ending that process, or restarting the computer, closes it.',
53
+ openLogs: 'Open logs',
54
+ openLogsFailed: 'The logs folder could not be opened.',
55
+ dismiss: 'Dismiss',
56
+ label: 'Server restarted after a crash',
57
+ exitCode: 'exit code {code}',
58
+ exitText: '{status}, {kind}',
59
+ kindNativeCrash: 'native crash',
60
+ kindOutOfMemory: 'out of memory',
61
+ kindNodeFatal: 'Node.js fatal error',
62
+ kindError: 'stopped by an error',
63
+ kindKilled: 'ended by force',
64
+ kindInterrupted: 'interrupted',
65
+ });
66
+
67
+ /** The order the notice lists what the restart ended (the last: lostTunnelUnknown for a notice whose `tunnel` is 'unknown'). */
68
+ export const CRASH_NOTICE_LOST = Object.freeze(['lostTerminals', 'lostRuns', 'lostReplies', 'lostBrowser', 'lostTunnel']);
69
+
70
+ /** The word for each kind lib/server-exit.js names; a kind without one shows the status alone. */
71
+ export const CRASH_KIND_KEYS = Object.freeze({
72
+ 'native-crash': 'kindNativeCrash',
73
+ 'out-of-memory': 'kindOutOfMemory',
74
+ 'node-fatal': 'kindNodeFatal',
75
+ error: 'kindError',
76
+ killed: 'kindKilled',
77
+ interrupted: 'kindInterrupted',
78
+ });
79
+
80
+ /** A sentence of CRASH_NOTICE_COPY in English with its {values} filled; an unknown key is itself. */
81
+ export function fillCrashNoticeCopy(key, params = {}) {
82
+ const text = Object.prototype.hasOwnProperty.call(CRASH_NOTICE_COPY, key) ? CRASH_NOTICE_COPY[key] : key;
83
+ return text.replace(/\{(\w+)\}/g, (whole, name) => (params[name] != null ? String(params[name]) : whole));
84
+ }
85
+
86
+ const ID = /^[0-9a-f]{16}$/;
87
+
88
+ /**
89
+ * The notice in an answer of GET /api/system/crash-notice (or a `crash-notice:changed`
90
+ * message: both carry `notice`), checked field by field; null when there is none.
91
+ * `tunnel: 'unknown'` is there only when the server could not end the crashed
92
+ * server's cloudflared.
93
+ */
94
+ export function readCrashNotice(answer) {
95
+ const notice = answer && typeof answer === 'object' ? answer.notice : null;
96
+ if (!notice || typeof notice !== 'object' || Array.isArray(notice)) return null;
97
+ if (typeof notice.id !== 'string' || !ID.test(notice.id)) return null;
98
+ const at = Number(notice.at);
99
+ if (!Number.isFinite(at) || at <= 0) return null;
100
+ const exit = notice.exit && typeof notice.exit === 'object' && !Array.isArray(notice.exit) ? notice.exit : {};
101
+ return {
102
+ id: notice.id,
103
+ at,
104
+ count: Number.isInteger(notice.count) && notice.count > 0 ? Math.min(notice.count, 999) : 1,
105
+ exit: {
106
+ hex: typeof exit.hex === 'string' && /^0x[0-9a-f]{8}$/i.test(exit.hex) ? `0x${exit.hex.slice(2).toUpperCase()}` : '',
107
+ signal: typeof exit.signal === 'string' && /^SIG[A-Z0-9]{1,10}$/.test(exit.signal) ? exit.signal : '',
108
+ code: Number.isInteger(exit.code) ? exit.code : null,
109
+ kind: typeof exit.kind === 'string' && /^[a-z][a-z-]{0,23}$/.test(exit.kind) ? exit.kind : '',
110
+ },
111
+ ...(notice.tunnel === 'unknown' ? { tunnel: 'unknown' } : {}),
112
+ };
113
+ }
114
+
115
+ /** How it ended in the reader's words ("0xC0000409, native crash"), or '' when the record names nothing. */
116
+ export function crashExitWords(exit, t = fillCrashNoticeCopy) {
117
+ if (!exit || typeof exit !== 'object') return '';
118
+ const status = exit.hex || exit.signal || (Number.isInteger(exit.code) ? t('exitCode', { code: exit.code }) : '');
119
+ if (!status) return '';
120
+ const key = CRASH_KIND_KEYS[exit.kind];
121
+ return key ? t('exitText', { status, kind: t(key) }) : status;
122
+ }
123
+
124
+ /** When it happened, in the reader's locale: { today, date, time } (the date is for another day). */
125
+ export function crashTimeParts(at, { now = Date.now(), locale = undefined } = {}) {
126
+ const when = new Date(at);
127
+ if (!Number.isFinite(when.getTime())) return null;
128
+ const day = new Date(now);
129
+ const today = when.getFullYear() === day.getFullYear() && when.getMonth() === day.getMonth() && when.getDate() === day.getDate();
130
+ const format = (fn, options, fallback) => { try { return fn.call(when, locale, options); } catch { return fallback; } };
131
+ return {
132
+ today,
133
+ date: format(Date.prototype.toLocaleDateString, { dateStyle: 'medium' }, when.toISOString().slice(0, 10)),
134
+ time: format(Date.prototype.toLocaleTimeString, { hour: '2-digit', minute: '2-digit' }, when.toISOString().slice(11, 16)),
135
+ };
136
+ }
137
+
138
+ /**
139
+ * What the notice shows, or null: { id, label, title, when, how, lostTitle, lost[], actions[] }.
140
+ * `t(key, params)` is a sentence of CRASH_NOTICE_COPY in the page's language; `canOpenLogs`
141
+ * says whether this page can open the logs folder (the desktop app, or a page on this computer).
142
+ */
143
+ export function crashNoticeView(notice, { t = fillCrashNoticeCopy, now = Date.now(), locale = undefined, canOpenLogs = false } = {}) {
144
+ if (!notice || typeof notice !== 'object' || !notice.id) return null;
145
+ const parts = crashTimeParts(notice.at, { now, locale }) || { today: true, date: '', time: '' };
146
+ const many = notice.count > 1;
147
+ const whenKey = `${many ? 'whenMany' : 'when'}${parts.today ? 'Today' : 'Earlier'}`;
148
+ const exit = crashExitWords(notice.exit, t);
149
+ return {
150
+ id: notice.id,
151
+ label: t('label'),
152
+ title: t('title'),
153
+ when: t(whenKey, { count: notice.count, date: parts.date, time: parts.time }),
154
+ how: exit ? t('how', { exit }) : '',
155
+ lostTitle: t('lostTitle'),
156
+ lost: CRASH_NOTICE_LOST.map((key) => t(key === 'lostTunnel' && notice.tunnel === 'unknown' ? 'lostTunnelUnknown' : key)),
157
+ actions: [
158
+ ...(canOpenLogs ? [{ id: 'logs', label: t('openLogs') }] : []),
159
+ { id: 'dismiss', label: t('dismiss') },
160
+ ],
161
+ };
162
+ }
163
+
164
+ /** True for a page served from this computer's loopback address: the only one the logs folder opens for. */
165
+ export function isLoopbackHost(hostname) {
166
+ const host = String(hostname || '').toLowerCase().replace(/^\[|\]$/g, '');
167
+ return host === 'localhost' || host === '::1' || /^127(?:\.\d{1,3}){3}$/.test(host);
168
+ }