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
@@ -13,6 +13,9 @@ import { storage } from './storage.js';
13
13
  import { isGuest, hasPermission } from './ui-sync.js';
14
14
  import { openSettingsModal } from './ui-settings.js';
15
15
  import { fetchRulesStatus } from './api.js';
16
+ import { registerContextMenuArea } from './context-menu-areas.js';
17
+ import { frameRect } from './app-frame.js';
18
+ import { readListItems, writeListItems, fitListLevels, indentListItem, outdentListItem, listMarkers } from './whiteboard-list.js';
16
19
 
17
20
  // ── Helpers ──
18
21
 
@@ -412,11 +415,31 @@ function flushListEdits() {
412
415
  const elId = dom.dataset.wbId;
413
416
  const el = _elements.find(e => e.id === elId);
414
417
  if (el && ul) {
415
- el.items = [...ul.querySelectorAll('li')].map(li => li.innerText.trimEnd());
416
- if (!el.items.length) el.items = [''];
418
+ const { items, levels } = _readListDom(ul);
419
+ if (items.length) writeListItems(el, items, levels);
420
+ else writeListItems(el, [''], [0]);
417
421
  }
418
422
  }
419
423
 
424
+ /** Text and level of every <li> of a list, an edit in progress included (levels: whiteboard-list.js). */
425
+ function _readListDom(ul) {
426
+ const lis = [...ul.querySelectorAll('li')];
427
+ return {
428
+ items: lis.map(li => li.innerText.trimEnd()),
429
+ levels: lis.map(li => Number(li.dataset.level) || 0),
430
+ };
431
+ }
432
+
433
+ // The list being edited as it was when editing began (the "before" of its undo entry).
434
+ let _listEditBefore = null;
435
+
436
+ /** A copy of a list element for an undo entry: its own items and levels arrays. */
437
+ function _listSnapshot(el) {
438
+ const copy = { ...el, items: [...(el.items || [])] };
439
+ if (Array.isArray(el.levels)) copy.levels = [...el.levels];
440
+ return copy;
441
+ }
442
+
420
443
  /** Flush in-progress text edits from contenteditable DOM back into _elements (without exiting edit mode). */
421
444
  function flushTextEdits() {
422
445
  const editingText = _root?.querySelector('.wb-text.editing .wb-text-content');
@@ -874,7 +897,8 @@ function updateElementDOM(dom, el) {
874
897
  } else if (el.type === 'list') {
875
898
  let list = dom.querySelector('ul, ol');
876
899
  if (list && !dom.classList.contains('editing')) {
877
- const items = el.items && el.items.length ? el.items : [''];
900
+ // Plain strings without `levels` (every older board) read as level 0.
901
+ const { items, levels } = readListItems(el.items && el.items.length ? el.items : [''], el.levels);
878
902
  const wantTag = el.ordered ? 'OL' : 'UL';
879
903
  if (list.tagName !== wantTag) {
880
904
  // ordered flag changed — swap the container (never while editing)
@@ -883,10 +907,10 @@ function updateElementDOM(dom, el) {
883
907
  list = swapped;
884
908
  dom._wbListKey = null;
885
909
  }
886
- const key = wantTag + '|' + JSON.stringify(items);
910
+ const key = wantTag + '|' + JSON.stringify(items) + '|' + levels.join(',');
887
911
  if (dom._wbListKey !== key) {
888
- list.innerHTML = items.map(item =>
889
- `<li>${item.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')}</li>`
912
+ list.innerHTML = items.map((item, i) =>
913
+ `<li${levels[i] ? ` data-level="${levels[i]}"` : ''}>${item.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')}</li>`
890
914
  ).join('');
891
915
  dom._wbListKey = key;
892
916
  }
@@ -903,7 +927,8 @@ function updateElementDOM(dom, el) {
903
927
  svg.setAttribute('viewBox', `0 0 ${w} ${h}`);
904
928
  svg.setAttribute('width', w);
905
929
  svg.setAttribute('height', h);
906
- const sc = el.color || 'rgba(255,255,255,0.8)';
930
+ // The colour is whatever whiteboard_add / whiteboard_update was given: an attribute value, never markup.
931
+ const sc = String(el.color || 'rgba(255,255,255,0.8)').replace(/[&"<>]/g, (c) => ({ '&': '&amp;', '"': '&quot;', '<': '&lt;', '>': '&gt;' })[c]);
907
932
  if (shape === 'drawn-circle') {
908
933
  svg.innerHTML = `<path d="${generateDrawnCirclePath(w, h, el.id)}" fill="none" stroke="${sc}" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>`;
909
934
  } else {
@@ -2059,25 +2084,28 @@ function exitEditMode() {
2059
2084
  if (editing) editing.blur();
2060
2085
  }
2061
2086
 
2062
- function enterListEditMode(dom, elId) {
2087
+ /**
2088
+ * Edit a list. `point` ({ x, y }, viewport px) is where the double-click that opened it landed: the caret goes
2089
+ * exactly there (that item, that line, that character). The items were not editable when the press came, so the
2090
+ * browser placed no caret of its own. Without a point (a list the list tool just made) the caret goes to the end
2091
+ * of the last item.
2092
+ */
2093
+ function enterListEditMode(dom, elId, point = null) {
2063
2094
  const ul = dom.querySelector('ul, ol');
2064
2095
  if (!ul) return;
2065
2096
  dom.classList.add('editing');
2097
+ // The undo entry of this edit starts from here: the saves made while editing (Tab, Enter, Backspace call
2098
+ // persistDebounced, which flushes the items into the element) must not become its "before".
2099
+ const el = _elements.find(e => e.id === elId);
2100
+ _listEditBefore = el ? _listSnapshot(el) : null;
2066
2101
 
2067
2102
  // Make all existing items editable
2068
2103
  [...ul.querySelectorAll('li')].forEach(li => li.setAttribute('contenteditable', 'true'));
2069
2104
 
2070
- // Focus last item, cursor at end
2105
+ if (point && _placeListCaretAt(dom, point.x, point.y)) return;
2071
2106
  const lis = [...ul.querySelectorAll('li')];
2072
2107
  const target = lis[lis.length - 1] || null;
2073
- if (target) {
2074
- target.focus();
2075
- const range = document.createRange();
2076
- range.selectNodeContents(target);
2077
- range.collapse(false);
2078
- window.getSelection().removeAllRanges();
2079
- window.getSelection().addRange(range);
2080
- }
2108
+ if (target) _placeCaret(target, 'end');
2081
2109
  }
2082
2110
 
2083
2111
  function exitListEditMode() {
@@ -2092,18 +2120,156 @@ function exitListEditMode() {
2092
2120
  if (document.activeElement?.closest('.wb-list')) document.activeElement.blur();
2093
2121
 
2094
2122
  const el = _elements.find(e => e.id === elId);
2123
+ const editBefore = _listEditBefore;
2124
+ _listEditBefore = null;
2095
2125
  if (el) {
2096
- const before = { ...el, items: [...(el.items || [])] };
2097
- const rawItems = [...ul.querySelectorAll('li')].map(li => li.innerText.trimEnd());
2098
- el.items = rawItems.filter((t, i, arr) => t !== '' || arr.length === 1);
2099
- if (!el.items.length) el.items = [''];
2100
- pushUndo('edit', before, { ...el, items: [...el.items] });
2126
+ const before = editBefore?.id === el.id ? editBefore : _listSnapshot(el);
2127
+ const { items, levels } = _readListDom(ul);
2128
+ // Empty items are dropped (the only item stays); the levels of what is left are fitted again.
2129
+ const kept = items.map((text, i) => ({ text, level: levels[i] })).filter((it, i, arr) => it.text !== '' || arr.length === 1);
2130
+ if (kept.length) writeListItems(el, kept.map(it => it.text), kept.map(it => it.level));
2131
+ else writeListItems(el, [''], [0]);
2132
+ pushUndo('edit', before, _listSnapshot(el));
2101
2133
  dom._wbListKey = null; // editing mutated the <li>s directly — force a clean rewrite
2102
2134
  renderElements();
2103
2135
  persistDebounced();
2104
2136
  }
2105
2137
  }
2106
2138
 
2139
+ /** A collapsed range at a viewport point (the standard call, then the WebKit/Blink one), or null. */
2140
+ function _caretRangeAtPoint(x, y) {
2141
+ if (typeof document.caretPositionFromPoint === 'function') {
2142
+ const pos = document.caretPositionFromPoint(x, y);
2143
+ if (pos?.offsetNode) {
2144
+ const range = document.createRange();
2145
+ range.setStart(pos.offsetNode, pos.offset);
2146
+ range.collapse(true);
2147
+ return range;
2148
+ }
2149
+ }
2150
+ if (typeof document.caretRangeFromPoint === 'function') return document.caretRangeFromPoint(x, y);
2151
+ return null;
2152
+ }
2153
+
2154
+ /** Focus an item being edited with the caret at its start or end. */
2155
+ function _placeCaret(li, where) {
2156
+ li.focus({ preventScroll: true });
2157
+ const range = document.createRange();
2158
+ range.selectNodeContents(li);
2159
+ range.collapse(where === 'start');
2160
+ const sel = window.getSelection();
2161
+ sel.removeAllRanges();
2162
+ sel.addRange(range);
2163
+ }
2164
+
2165
+ /**
2166
+ * Put the caret of a list being edited under a viewport point: in the item on that row, at the character under
2167
+ * the point. A point beside the text (the padding, a bullet, past the end of a line) lands on the nearest spot
2168
+ * of the nearest item. Returns false when the list has no item.
2169
+ */
2170
+ function _placeListCaretAt(listDom, x, y) {
2171
+ const lis = [...listDom.querySelectorAll('li')];
2172
+ if (!lis.length) return false;
2173
+ let li = lis[0], best = Infinity;
2174
+ for (const item of lis) {
2175
+ const r = item.getBoundingClientRect();
2176
+ const d = y < r.top ? r.top - y : y > r.bottom ? y - r.bottom : 0;
2177
+ if (d < best) { best = d; li = item; }
2178
+ }
2179
+ const r = li.getBoundingClientRect();
2180
+ const cx = Math.min(Math.max(x, r.left + 1), r.right - 1);
2181
+ const cy = Math.min(Math.max(y, r.top + 1), r.bottom - 1);
2182
+ let range = _caretRangeAtPoint(cx, cy);
2183
+ if (!range || !li.contains(range.startContainer)) {
2184
+ range = document.createRange();
2185
+ range.selectNodeContents(li);
2186
+ range.collapse(x < r.left + r.width / 2);
2187
+ }
2188
+ li.focus({ preventScroll: true });
2189
+ const sel = window.getSelection();
2190
+ sel.removeAllRanges();
2191
+ sel.addRange(range);
2192
+ return true;
2193
+ }
2194
+
2195
+ /** Write levels onto <li>s (level 0 is no attribute, as the render writes it). */
2196
+ function _applyListLevels(lis, levels) {
2197
+ lis.forEach((li, i) => {
2198
+ const level = levels[i] || 0;
2199
+ if (level) li.dataset.level = String(level);
2200
+ else delete li.dataset.level;
2201
+ });
2202
+ }
2203
+
2204
+ /** Fit the levels of a list being edited after an item was removed or merged (whiteboard-list.js rules). */
2205
+ function _refitListDom(ul) {
2206
+ const lis = [...ul.querySelectorAll('li')];
2207
+ _applyListLevels(lis, fitListLevels(lis.map(li => Number(li.dataset.level) || 0), lis.length));
2208
+ }
2209
+
2210
+ /** Tab / Shift+Tab on an item being edited: one level deeper (+1) or shallower (-1). False when it cannot move. */
2211
+ function _shiftListItemLevel(li, dir) {
2212
+ const lis = [...li.parentElement.querySelectorAll('li')];
2213
+ const levels = lis.map(n => Number(n.dataset.level) || 0);
2214
+ const index = lis.indexOf(li);
2215
+ const next = dir > 0 ? indentListItem(levels, index) : outdentListItem(levels, index);
2216
+ if (!next) return false;
2217
+ _applyListLevels(lis, next);
2218
+ return true;
2219
+ }
2220
+
2221
+ /** An item left with no text holds nothing (no stray <br>), so the empty placeholder shows. */
2222
+ function _tidyEmptyItem(li) {
2223
+ if (li.textContent === '' && !li.querySelector('img')) li.replaceChildren();
2224
+ }
2225
+
2226
+ /** Whether the caret (collapsed) sits at the very start of an item being edited. */
2227
+ function _caretAtItemStart(li) {
2228
+ const sel = window.getSelection();
2229
+ if (!sel.rangeCount || !sel.isCollapsed) return false;
2230
+ const caret = sel.getRangeAt(0);
2231
+ if (!li.contains(caret.startContainer)) return false;
2232
+ const before = document.createRange();
2233
+ before.setStart(li, 0);
2234
+ before.setEnd(caret.startContainer, caret.startOffset);
2235
+ return before.toString() === '' && !before.cloneContents().querySelector('br, img');
2236
+ }
2237
+
2238
+ /** Enter: what follows the caret (the selection removed first) leaves the item, for the new one. */
2239
+ function _cutAfterCaret(li) {
2240
+ const sel = window.getSelection();
2241
+ if (!sel.rangeCount) return null;
2242
+ const range = sel.getRangeAt(0);
2243
+ if (!li.contains(range.startContainer)) return null;
2244
+ if (!li.contains(range.endContainer)) range.collapse(true);
2245
+ else if (!range.collapsed) range.deleteContents();
2246
+ const tail = document.createRange();
2247
+ tail.setStart(range.startContainer, range.startOffset);
2248
+ tail.setEnd(li, li.childNodes.length);
2249
+ return tail.extractContents();
2250
+ }
2251
+
2252
+ /** Backspace at the start of an item that has text: it joins the end of the item above, the caret at the seam. */
2253
+ function _mergeIntoPrevious(li) {
2254
+ const prev = li.previousElementSibling;
2255
+ if (!prev) return false;
2256
+ _tidyEmptyItem(prev);
2257
+ const seam = prev.childNodes.length;
2258
+ _tidyEmptyItem(li);
2259
+ while (li.firstChild) prev.appendChild(li.firstChild);
2260
+ const ul = li.parentElement;
2261
+ li.remove();
2262
+ _refitListDom(ul);
2263
+ prev.focus({ preventScroll: true });
2264
+ const range = document.createRange();
2265
+ range.setStart(prev, seam);
2266
+ range.collapse(true);
2267
+ const sel = window.getSelection();
2268
+ sel.removeAllRanges();
2269
+ sel.addRange(range);
2270
+ return true;
2271
+ }
2272
+
2107
2273
 
2108
2274
  // ═══════════════════════════════════════════
2109
2275
  // MULTI-SELECT HELPERS
@@ -2171,6 +2337,19 @@ function onMouseDown(e) {
2171
2337
  // Block drawing for guests without whiteboard permission (select/view still allowed)
2172
2338
  if (isGuest() && !hasPermission('whiteboard') && _activeTool !== 'select') return;
2173
2339
 
2340
+ // A press inside the list being edited belongs to its text, as in a text editor: the browser puts the caret
2341
+ // under the pointer (any item, any line, any character) and a drag selects. Leaving edit mode here, starting
2342
+ // a move and preventDefault() (below, for any press on an element) is what threw the caret onto the end of
2343
+ // the last item. A press beside the items (padding, bullets) is placed on the nearest item by hand.
2344
+ const editingList = e.target.closest?.('.wb-list.editing');
2345
+ if (editingList) {
2346
+ if (!e.target.closest('li')) {
2347
+ e.preventDefault();
2348
+ _placeListCaretAt(editingList, e.clientX, e.clientY);
2349
+ }
2350
+ return;
2351
+ }
2352
+
2174
2353
  // Steal focus from terminal/other elements so Ctrl+V paste works on whiteboard
2175
2354
  _root.focus({ preventScroll: true });
2176
2355
 
@@ -2798,12 +2977,14 @@ function onDblClick(e) {
2798
2977
  return;
2799
2978
  }
2800
2979
 
2801
- // Double-click list → edit
2980
+ // Double-click list → edit, the caret where the double-click landed
2802
2981
  const listEl = e.target.closest('.wb-list[data-wb-id]');
2803
2982
  if (listEl && _activeTool === 'select') {
2983
+ // Already editing: the double-click is the text's (the browser selects the word under it).
2984
+ if (listEl.classList.contains('editing')) return;
2804
2985
  const id = listEl.dataset.wbId;
2805
2986
  selectElement(id);
2806
- enterListEditMode(listEl, id);
2987
+ enterListEditMode(listEl, id, { x: e.clientX, y: e.clientY });
2807
2988
  e.preventDefault();
2808
2989
  return;
2809
2990
  }
@@ -2914,35 +3095,63 @@ function onKeyDown(e) {
2914
3095
  const editingListLi = document.activeElement?.closest('.wb-list.editing li') || null;
2915
3096
  const isEditing = isEditingText || !!editingListLi;
2916
3097
 
2917
- // List Enter → insert new item
2918
- if (editingListLi && e.key === 'Enter') {
3098
+ // Keys of a list item being edited (an IME composition keeps its own Enter / Tab / Backspace).
3099
+ // Tab / Shift+Tab → one level deeper / shallower (whiteboard-list.js rules). Always taken here: Tab never
3100
+ // leaves the list or types a tab, even when the item cannot move.
3101
+ if (editingListLi && e.key === 'Tab' && !e.isComposing && !e.ctrlKey && !e.metaKey && !e.altKey) {
3102
+ e.preventDefault();
3103
+ e.stopImmediatePropagation();
3104
+ if (_shiftListItemLevel(editingListLi, e.shiftKey ? -1 : 1)) persistDebounced();
3105
+ return;
3106
+ }
3107
+
3108
+ // List Enter → a new item at the same level; what follows the caret moves into it
3109
+ if (editingListLi && e.key === 'Enter' && !e.isComposing) {
2919
3110
  e.preventDefault();
2920
3111
  e.stopImmediatePropagation();
2921
3112
  const newLi = document.createElement('li');
2922
3113
  newLi.setAttribute('contenteditable', 'true');
3114
+ if (editingListLi.dataset.level) newLi.dataset.level = editingListLi.dataset.level;
3115
+ const tail = _cutAfterCaret(editingListLi);
3116
+ if (tail) newLi.appendChild(tail);
3117
+ _tidyEmptyItem(editingListLi);
3118
+ _tidyEmptyItem(newLi);
2923
3119
  editingListLi.after(newLi);
2924
- newLi.focus();
3120
+ _placeCaret(newLi, 'start');
3121
+ persistDebounced();
2925
3122
  return;
2926
3123
  }
2927
3124
 
2928
- // List Backspace on empty item → remove item (keep at least 1)
2929
- if (editingListLi && e.key === 'Backspace' && editingListLi.textContent === '') {
3125
+ // List Backspace at the start of an item: an indented item goes one level up first; then an empty item is
3126
+ // removed (keep at least 1) and one with text joins the item above.
3127
+ if (editingListLi && e.key === 'Backspace' && !e.isComposing
3128
+ && (editingListLi.textContent === '' || _caretAtItemStart(editingListLi))) {
2930
3129
  const ul = editingListLi.parentElement;
2931
- if (ul && ul.children.length > 1) {
3130
+ const plain = !e.ctrlKey && !e.metaKey && !e.altKey;
3131
+ if (plain && (Number(editingListLi.dataset.level) || 0) > 0) {
2932
3132
  e.preventDefault();
2933
3133
  e.stopImmediatePropagation();
2934
- const prev = editingListLi.previousElementSibling;
2935
- const next = editingListLi.nextElementSibling;
2936
- editingListLi.remove();
2937
- const focusTarget = prev || next;
2938
- if (focusTarget) {
2939
- focusTarget.focus();
2940
- const range = document.createRange();
2941
- range.selectNodeContents(focusTarget);
2942
- range.collapse(false);
2943
- window.getSelection().removeAllRanges();
2944
- window.getSelection().addRange(range);
3134
+ if (_shiftListItemLevel(editingListLi, -1)) persistDebounced();
3135
+ return;
3136
+ }
3137
+ if (editingListLi.textContent === '') {
3138
+ if (ul && ul.children.length > 1) {
3139
+ e.preventDefault();
3140
+ e.stopImmediatePropagation();
3141
+ const prev = editingListLi.previousElementSibling;
3142
+ const next = editingListLi.nextElementSibling;
3143
+ editingListLi.remove();
3144
+ _refitListDom(ul);
3145
+ const focusTarget = prev || next;
3146
+ if (focusTarget) _placeCaret(focusTarget, 'end');
3147
+ persistDebounced();
2945
3148
  }
3149
+ return;
3150
+ }
3151
+ if (plain && editingListLi.previousElementSibling) {
3152
+ e.preventDefault();
3153
+ e.stopImmediatePropagation();
3154
+ if (_mergeIntoPrevious(editingListLi)) persistDebounced();
2946
3155
  }
2947
3156
  return;
2948
3157
  }
@@ -3399,6 +3608,41 @@ export function addImageToWhiteboard(url) {
3399
3608
  img.src = url;
3400
3609
  }
3401
3610
 
3611
+ // ═══════════════════════════════════════════
3612
+ // THE APP'S RIGHT-CLICK MENU (context-menu-model.js focusItems)
3613
+ // ═══════════════════════════════════════════
3614
+
3615
+ // Each row goes through what the board already does: its toolbar's own buttons (onToolbarClick, with
3616
+ // its guest check and the multi-select mode a tool leaves) and Ctrl+A's selectMultiple.
3617
+ const pressToolbar = (selector) => _toolbar?.querySelector(selector)?.click();
3618
+
3619
+ // The whole focus-mode screen (#static-bg while it is shown): the board, its toolbar, the logo.
3620
+ const focusMenuArea = {
3621
+ id: 'focus-whiteboard',
3622
+ match(el) {
3623
+ if (!el?.closest?.('#static-bg.visible')) return null;
3624
+ return {
3625
+ kind: 'focus',
3626
+ focus: {
3627
+ tool: _activeTool,
3628
+ multi: _multiSelectMode,
3629
+ canUndo: _undoStack.length > 0,
3630
+ canRedo: _redoStack.length > 0,
3631
+ hasElements: _elements.length > 0,
3632
+ canEdit: !(isGuest() && !hasPermission('whiteboard')),
3633
+ },
3634
+ act: {
3635
+ setTool: (name) => pressToolbar(`.wb-tool[data-tool="${name}"]`),
3636
+ toggleMulti: () => pressToolbar('#wb-multiselect'),
3637
+ undo: () => pressToolbar('#wb-undo'),
3638
+ redo: () => pressToolbar('#wb-redo'),
3639
+ selectAll: () => { const ids = _elements.map(e => e.id); if (ids.length) selectMultiple(ids); },
3640
+ exitFocus: () => $('titlebar-viz-toggle')?.click(), // the navbar's button, as the V key presses it
3641
+ },
3642
+ };
3643
+ },
3644
+ };
3645
+
3402
3646
  // ═══════════════════════════════════════════
3403
3647
  // INIT
3404
3648
  // ═══════════════════════════════════════════
@@ -3486,8 +3730,10 @@ export function initWhiteboard() {
3486
3730
  // Logo-adjacent ruleset reminder
3487
3731
  initRulesetAlert();
3488
3732
 
3489
- // Prevent context menu on whiteboard
3490
- _root.addEventListener('contextmenu', e => e.preventDefault());
3733
+ // Right-click: the board has no menu of its own, so it leaves the event to the app's menu
3734
+ // (ui-context-menu.js), which adds the board's section from focusMenuArea. A card being
3735
+ // edited keeps the browser's menu (spelling, paste), as every field does.
3736
+ registerContextMenuArea(focusMenuArea);
3491
3737
 
3492
3738
  // Listen for workspace events
3493
3739
  on('whiteboard:restore', restoreWhiteboardSnapshot);
@@ -3617,27 +3863,31 @@ function _cssPx(name) {
3617
3863
  }
3618
3864
 
3619
3865
  /** Usable whiteboard viewport in CSS px relative to #wb-root's top-left: the
3620
- * root minus the left tool rail, the navbar and the docked right-side agent
3621
- * panel (its reserved width is published as --right-panel-width by
3622
- * ui-sidepanel-layout.js; 0 when hidden or floating). #wb-root already ends
3623
- * above a docked terminal (--terminal-height). Sent to the server so MCP
3624
- * coordinate math and screenshots describe what the user can actually see. */
3866
+ * part of the root inside the app frame (below the navbar, right of the
3867
+ * explorers, the gutter around it: app-frame.js), minus the left tool rail
3868
+ * and the docked right-side agent panel (its reserved width is published as
3869
+ * --right-panel-width by ui-sidepanel-layout.js; 0 when hidden or floating).
3870
+ * #wb-root already ends above a docked terminal (--terminal-height). Sent to
3871
+ * the server so MCP coordinate math and screenshots describe what the user
3872
+ * can actually see. */
3625
3873
  function _computeViewport() {
3626
3874
  const rect = _root.getBoundingClientRect();
3627
- const titleBar = document.getElementById('title-bar');
3628
3875
  const toolbar = document.getElementById('wb-toolbar');
3629
- const navH = titleBar ? titleBar.getBoundingClientRect().height : _cssPx('--navbar-height');
3630
- const tbW = toolbar ? Math.max(0, toolbar.getBoundingClientRect().right - rect.left + 12) : 60;
3631
3876
  const rightW = Math.max(0, _cssPx('--right-panel-width') || _cssPx('--claude-panel-width'));
3877
+ const f = frameRect();
3878
+ const top = Math.max(rect.top, f.top);
3879
+ const left = Math.max(rect.left, f.left, toolbar ? toolbar.getBoundingClientRect().right + 12 : rect.left + 60);
3880
+ const right = Math.min(rect.right, f.right, window.innerWidth - rightW);
3881
+ const bottom = Math.min(rect.bottom, f.bottom);
3632
3882
  return {
3633
3883
  type: 'viewport',
3634
3884
  clientId: _clientId,
3635
3885
  focusActive: isWhiteboardActive(),
3636
3886
  visible: document.visibilityState === 'visible',
3637
- width: Math.max(0, Math.round(rect.width - tbW - rightW)),
3638
- height: Math.max(0, Math.round(rect.height - navH)),
3639
- xOffset: Math.round(tbW),
3640
- yOffset: Math.round(navH),
3887
+ width: Math.max(0, Math.round(right - left)),
3888
+ height: Math.max(0, Math.round(bottom - top)),
3889
+ xOffset: Math.round(left - rect.left),
3890
+ yOffset: Math.round(top - rect.top),
3641
3891
  rootWidth: Math.round(rect.width),
3642
3892
  rootHeight: Math.round(rect.height),
3643
3893
  rightPanelWidth: Math.round(rightW),
@@ -3694,6 +3944,7 @@ function _handleExternalCommand(msg) {
3694
3944
  const before = { ...el, points: el.points ? el.points.map(p => [...p]) : undefined };
3695
3945
  for (const [key, value] of Object.entries(msg.updates || {})) {
3696
3946
  if (key === 'id' || key === 'type') continue;
3947
+ if (key === 'levels' && value == null) { delete el.levels; continue; } // the list went flat
3697
3948
  el[key] = value;
3698
3949
  }
3699
3950
  pushUndo('edit', before, { ...el, points: el.points ? el.points.map(p => [...p]) : undefined });
@@ -3755,6 +4006,7 @@ function _handleExternalCommand(msg) {
3755
4006
  befores.push(copyEl(el));
3756
4007
  for (const [key, value] of Object.entries(op.updates || {})) {
3757
4008
  if (key === 'id' || key === 'type') continue;
4009
+ if (key === 'levels' && value == null) { delete el.levels; continue; } // the list went flat
3758
4010
  el[key] = value;
3759
4011
  }
3760
4012
  afters.push(copyEl(el));
@@ -3979,20 +4231,22 @@ async function _captureScreenshot(requestId, { crop } = {}) {
3979
4231
  lineTop += lineH;
3980
4232
  }
3981
4233
  } else if (el.type === 'list') {
3982
- // .wb-list: same box, line-height 1.5, <ul>/<ol> padding-left 1.4em
4234
+ // .wb-list: same box, line-height 1.5, <ul>/<ol> padding-left 1.4em, plus 1.4em per nesting level;
4235
+ // each level's bullet / numbering as styles.css draws it (whiteboard-list.js listMarkers)
3983
4236
  const fs = el.fontSize || 18;
3984
4237
  ctx.font = `400 ${fs}px ${mono}`;
3985
4238
  ctx.fillStyle = el.color || 'rgba(255,255,255,0.85)';
3986
4239
  ctx.textBaseline = 'alphabetic';
3987
4240
  const lineH = fs * 1.5;
3988
4241
  const baseOff = _lineBaseline(ctx, fs, lineH);
3989
- const items = el.items && el.items.length ? el.items : [''];
3990
- const contentLeft = el.x + 15 + 1.4 * fs;
4242
+ const { items, levels } = readListItems(el.items && el.items.length ? el.items : [''], el.levels);
4243
+ const markers = listMarkers(levels, !!el.ordered);
3991
4244
  let lineTop = el.y + 11;
3992
4245
  items.forEach((item, i) => {
3993
4246
  const baseline = lineTop + baseOff;
4247
+ const contentLeft = el.x + 15 + 1.4 * fs * (1 + levels[i]);
3994
4248
  ctx.textAlign = 'right';
3995
- ctx.fillText(el.ordered ? `${i + 1}.` : '•', contentLeft - 0.6 * fs, baseline);
4249
+ ctx.fillText(markers[i], contentLeft - 0.6 * fs, baseline);
3996
4250
  ctx.textAlign = 'left';
3997
4251
  if (item) ctx.fillText(item, contentLeft, baseline);
3998
4252
  lineTop += lineH;
@@ -34,6 +34,10 @@ let _wired = false;
34
34
 
35
35
  function newer(next, current) {
36
36
  if (!current) return true;
37
+ // A run resumed after a server restart (`resumes` only grows) is newer whatever its version: a crash can lose the
38
+ // last saved versions of a run a page already saw.
39
+ const resumed = (Number(next?.resumes) || 0) - (Number(current?.resumes) || 0);
40
+ if (resumed) return resumed > 0;
37
41
  const a = Number(next?.version) || 0;
38
42
  const b = Number(current?.version) || 0;
39
43
  if (a !== b) return a > b;
@@ -24,6 +24,7 @@ import { storage } from './storage.js';
24
24
  import { t } from './i18n.js';
25
25
  import { posStore } from './node-positions-store.js';
26
26
  import { getVariant } from './registry.js';
27
+ import { normalizeWorkspaceVariant } from './view-variant.js';
27
28
  import {
28
29
  getOpenCardsSnapshot,
29
30
  closeAllCards,
@@ -51,14 +52,14 @@ let _isOpen = false;
51
52
 
52
53
  function getWorkspaces() {
53
54
  try {
54
- return JSON.parse(storage.getItem(KEYS.WORKSPACES) || '[]');
55
+ return JSON.parse(storage.getItem(KEYS.WORKSPACES) || '[]').map(normalizeWorkspaceVariant);
55
56
  } catch {
56
57
  return [];
57
58
  }
58
59
  }
59
60
 
60
61
  function saveWorkspacesToStorage(list) {
61
- storage.setItem(KEYS.WORKSPACES, JSON.stringify(list));
62
+ storage.setItem(KEYS.WORKSPACES, JSON.stringify(list.map(normalizeWorkspaceVariant)));
62
63
  }
63
64
 
64
65
  function _readStoredPositions(key) {
@@ -0,0 +1,66 @@
1
+ // The Neural Interface offers only the 3D memory map. The 2D implementation is deprecated, kept on disk.
2
+ import { KEYS } from './constants.js';
3
+
4
+ export function resolveViewVariant(_requested) { return '3d'; }
5
+
6
+ /** Preserve other URL state, including memory anchors, when retiring a 2D address. Shared with the server. */
7
+ export function normalizeViewUrl(input) {
8
+ const url = new URL(input, 'http://localhost');
9
+ if (url.pathname.toLowerCase() === '/index2d.html') url.pathname = '/';
10
+ if (url.searchParams.has('variant')) url.searchParams.set('variant', resolveViewVariant(url.searchParams.get('variant')));
11
+ const hash = url.hash.slice(1);
12
+ if (hash === '2d') url.hash = '3d';
13
+ else {
14
+ const start = hash.includes('?') ? hash.indexOf('?') + 1 : 0;
15
+ const params = new URLSearchParams(hash.slice(start));
16
+ if (params.has('variant')) {
17
+ params.set('variant', resolveViewVariant(params.get('variant')));
18
+ url.hash = hash.slice(0, start) + params.toString();
19
+ }
20
+ }
21
+ return url.pathname + url.search + url.hash;
22
+ }
23
+
24
+ /** Optional legacy config fields are normalized without changing Focus Mode, glass or accent settings. */
25
+ export function normalizeViewConfig(config) {
26
+ if (!config || typeof config !== 'object' || Array.isArray(config)) return config;
27
+ const next = { ...config };
28
+ for (const key of ['variant', 'viewVariant']) {
29
+ if (Object.hasOwn(next, key)) next[key] = resolveViewVariant(next[key]);
30
+ }
31
+ return next;
32
+ }
33
+
34
+ /** Retain archived 2D coordinates, but never reinterpret their x/y positions as 3D positions. */
35
+ export function normalizeWorkspaceVariant(workspace) {
36
+ if (workspace?.variant !== '2d') return workspace;
37
+ return {
38
+ ...workspace,
39
+ variant: '3d',
40
+ nodePositions2d: workspace.nodePositions2d || workspace.nodePositions || {},
41
+ nodePositions3d: workspace.nodePositions3d || {},
42
+ };
43
+ }
44
+
45
+ /** Rewrite persisted preferences at boot, in both the hydrated server store and any browser-local copy. */
46
+ export function migrateViewPreferences(...stores) {
47
+ for (const store of new Set(stores.filter(Boolean))) {
48
+ // A refused read/write or malformed old value must not stop the supported view from booting.
49
+ try {
50
+ if (store.getItem(KEYS.VIEW_VARIANT) !== '3d') store.setItem(KEYS.VIEW_VARIANT, '3d');
51
+ } catch {}
52
+ for (const [key, normalize] of [
53
+ [KEYS.INTERFACE_CONFIG, normalizeViewConfig],
54
+ [KEYS.WORKSPACES, (list) => Array.isArray(list) ? list.map(normalizeWorkspaceVariant) : list],
55
+ ]) {
56
+ try {
57
+ const raw = store.getItem(key);
58
+ if (!raw) continue;
59
+ const value = JSON.parse(raw);
60
+ const next = normalize(value);
61
+ if (JSON.stringify(next) !== JSON.stringify(value)) store.setItem(key, JSON.stringify(next));
62
+ } catch {}
63
+ }
64
+ }
65
+ return resolveViewVariant();
66
+ }
@@ -242,7 +242,7 @@ export const HELP = Object.freeze({
242
242
  'Stuck on "Reconnecting"? Check this computer\'s internet connection, then press Reconnect now.',
243
243
  'Voice notes not transcribed? This computer needs whisper.cpp, its speech model and FFmpeg, which you install yourself; the line under "Transcribe voice notes" says what is missing.',
244
244
  ],
245
- browserTools: 'Not the same as the WhatsApp browser tools. The whatsapp MCP profile lets agents read WhatsApp Web in SynaBun\'s browser; this tab is you chatting with SynaBun from your phone. They do not share a session.',
245
+ browserTools: 'Not the same as the WhatsApp browser tools. The browser_whatsapp tool group lets agents read WhatsApp Web in SynaBun\'s browser; this tab is you chatting with SynaBun from your phone. They do not share a session.',
246
246
  uninstall: 'Uninstalling SynaBun does not unlink WhatsApp. Use Unlink or Remove here first, or log SynaBun out under WhatsApp → Settings → Linked devices.',
247
247
  });
248
248