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,417 @@
1
+ // ═══════════════════════════════════════════
2
+ // SynaBun Assistant — follow-ups: what a finished turn offers, as items to click
3
+ // ═══════════════════════════════════════════
4
+ // A brain that ends a turn with next steps, decisions or offers appends one
5
+ // fenced block after all its text (lib/assistant-persona.js, "Follow-ups"):
6
+ //
7
+ // ```synabun-followups
8
+ // {"multi": false, "items": [{"label": "Ship it", "send": "Ship 1.4.0 to npm now", "description": "…"}]}
9
+ // ```
10
+ //
11
+ // An optional "style" says how the mascot presents it (asst-followups-card.js):
12
+ // "next" (quick actions, one click sends), "decisions" (independent picks sent
13
+ // together: what "multi": true has always meant), "confirm" (one proposed
14
+ // action: go ahead, or not now) and "question" (2-4 answers, the recommended
15
+ // one first, plus a typed answer; "question" holds the question). A block
16
+ // without it is "decisions" when multi, else "next", so older replies draw as
17
+ // they always did.
18
+ // The panel never shows the block: splitFollowups takes it out of the text
19
+ // (while it streams too) and the transcript draws its items as buttons
20
+ // (asst-followups-card.js); a click sends `send` as the user's next message.
21
+ // A model that leaves the tag off (a json or bare fence) still gets buttons
22
+ // when that fence is the message's last and holds exactly the block's shape.
23
+ // A turn whose last message has no block but still ends in a list of options
24
+ // or an "I can X, or Y" offer gets items read from the prose (guessFollowups),
25
+ // best effort. Whether a set was answered is read from the transcript: the
26
+ // user's next message is one of its items, or several of them one per line
27
+ // (matchFollowupReply), so a reload draws the same state as the live panel.
28
+ // No imports and no DOM: the server strips the block too (stripFollowups).
29
+
30
+ export const FOLLOWUPS_FENCE = 'synabun-followups';
31
+ export const FOLLOWUP_LIMITS = Object.freeze({ items: 8, label: 80, send: 2000, description: 200, heuristicItem: 400, question: 240, answer: 300 });
32
+ /** How a set is presented: quick actions, independent picks, one proposed action, a question. */
33
+ export const FOLLOWUP_STYLES = Object.freeze(['next', 'decisions', 'confirm', 'question']);
34
+ // What a model may write for a style; anything else falls back to the legacy reading of "multi".
35
+ const STYLE_NAMES = Object.freeze({
36
+ next: 'next', 'next-steps': 'next', steps: 'next', actions: 'next',
37
+ decisions: 'decisions', decision: 'decisions', multi: 'decisions', checklist: 'decisions',
38
+ confirm: 'confirm', confirmation: 'confirm', proceed: 'confirm', approve: 'confirm', 'go-ahead': 'confirm',
39
+ question: 'question', ask: 'question', choice: 'question',
40
+ });
41
+ /** A style name as the block wrote it ("Next steps", "next_steps", "Question") → a FOLLOWUP_STYLES entry, or ''. */
42
+ export function followupStyleName(value) {
43
+ const key = String(value ?? '').trim().toLowerCase().replace(/[\s_]+/g, '-');
44
+ return Object.hasOwn(STYLE_NAMES, key) ? STYLE_NAMES[key] : '';
45
+ }
46
+ // "Postgres (Recommended)": the label the way AskUserQuestion asks for it; the card shows a badge instead.
47
+ const RECOMMENDED_RE = /\s*[([]\s*(?:recommended|recomendad[oa])\s*[)\]]\s*$/i;
48
+
49
+ function clip(value, max) {
50
+ const text = String(value ?? '').replace(/\s+/g, ' ').trim();
51
+ return text.length > max ? `${text.slice(0, max - 1).trimEnd()}…` : text;
52
+ }
53
+ /** Inline markdown off a label or a message (bold, italics, code ticks, links). */
54
+ function plain(value) {
55
+ return String(value ?? '')
56
+ .replace(/\[([^\]]+)\]\([^)]*\)/g, '$1')
57
+ .replace(/(\*\*|__)(.+?)\1/g, '$2')
58
+ .replace(/(^|[\s(])[*_]([^*_\s][^*_]*?)[*_](?=[\s).,;:!?]|$)/g, '$1$2')
59
+ .replace(/`([^`]+)`/g, '$1')
60
+ .trim();
61
+ }
62
+ const norm = (value) => String(value ?? '').replace(/\s+/g, ' ').trim().toLowerCase();
63
+
64
+ const FENCE_OPEN_RE = /^[ \t]*(`{3,}|~{3,})[ \t]*([^\n]*?)[ \t]*$/;
65
+ const FENCE_CLOSE_RE = /^[ \t]*(`{3,}|~{3,})[ \t]*$/;
66
+ // A fence a model may put the block in when it forgets the tag: none, or JSON's.
67
+ const PLAIN_LANG_RE = /^(?:json5?|jsonc)?$/;
68
+
69
+ /**
70
+ * The text's fenced blocks, in order: { start, end, lang, inner, closed, typed }. A fence opened inside
71
+ * another is that block's content, never a block (a ```markdown example of the format is not the format).
72
+ * `typed`: the opening line has no newline yet, so its info string may still be growing.
73
+ */
74
+ function scanFences(src) {
75
+ const blocks = [];
76
+ let open = null;
77
+ let at = 0;
78
+ while (at <= src.length) {
79
+ const nl = src.indexOf('\n', at);
80
+ const lineEnd = nl < 0 ? src.length : nl;
81
+ const line = src.slice(at, lineEnd);
82
+ if (!open) {
83
+ const m = FENCE_OPEN_RE.exec(line);
84
+ if (m && !(m[1][0] === '`' && m[2].includes('`'))) {
85
+ open = { start: at, fence: m[1], lang: (m[2].split(/\s+/)[0] || '').toLowerCase(), contentStart: nl < 0 ? src.length : nl + 1, typed: nl < 0 };
86
+ }
87
+ } else {
88
+ const m = FENCE_CLOSE_RE.exec(line);
89
+ if (m && m[1][0] === open.fence[0] && m[1].length >= open.fence.length) {
90
+ blocks.push({ start: open.start, end: lineEnd, lang: open.lang, inner: src.slice(open.contentStart, at), closed: true, typed: false });
91
+ open = null;
92
+ }
93
+ }
94
+ if (nl < 0) break;
95
+ at = nl + 1;
96
+ }
97
+ if (open) blocks.push({ start: open.start, end: src.length, lang: open.lang, inner: src.slice(open.contentStart), closed: false, typed: open.typed });
98
+ return blocks;
99
+ }
100
+
101
+ /** The first characters of an untagged or json fence that may become a follow-ups object: hidden while they stream. */
102
+ function mayBecomeFollowups(inner) {
103
+ const src = inner.trim();
104
+ return !src || /^\{\s*(?:"[a-z_]*"?)?$/i.test(src) || /^\{\s*"(?:multi|multi_select|multiSelect|title|items)"/.test(src);
105
+ }
106
+
107
+ /** The text with `b` taken out: what came before it, then what came after it as its own paragraph. */
108
+ function without(src, b) {
109
+ return [src.slice(0, b.start).replace(/\s+$/, ''), src.slice(b.end).trim()].filter(Boolean).join('\n\n');
110
+ }
111
+
112
+ /**
113
+ * The text without its follow-ups block → { body, block, partial }.
114
+ * `block`: the parsed set ({ multi, items, title, source: 'block' }) or null.
115
+ * The block is the last fence tagged synabun-followups; with no such fence, the message's LAST
116
+ * fenced block when it is untagged or json and holds exactly the follow-ups shape
117
+ * ({"items": [{"label", "send"}, …]}, optional multi / title / description), so a model that
118
+ * forgot the tag still gets buttons and an ordinary code block is never taken.
119
+ * `streaming`: the text is still arriving, so a fence being typed at its very end ("```synab",
120
+ * "```json\n{\"multi\"") is hidden too (`partial`), and an open block hides what follows it.
121
+ */
122
+ export function splitFollowups(text, { streaming = false } = {}) {
123
+ const src = String(text ?? '').replace(/\r\n?/g, '\n');
124
+ const blocks = scanFences(src);
125
+ const tagged = blocks.filter((b) => b.lang === FOLLOWUPS_FENCE).pop();
126
+ if (tagged) {
127
+ const partial = !tagged.closed && streaming;
128
+ return { body: without(src, tagged), block: partial ? null : parseFollowupsBlock(tagged.inner), partial };
129
+ }
130
+ const last = blocks[blocks.length - 1];
131
+ if (last && !last.closed && streaming) {
132
+ // An opening still being typed ("```synab"), or a json / bare fence whose content may be the block.
133
+ const typing = last.typed && !!last.lang && (FOLLOWUPS_FENCE.startsWith(last.lang) || 'json'.startsWith(last.lang));
134
+ if (typing || (PLAIN_LANG_RE.test(last.lang) && mayBecomeFollowups(last.inner))) {
135
+ return { body: without(src, last), block: null, partial: true };
136
+ }
137
+ }
138
+ if (last && PLAIN_LANG_RE.test(last.lang) && (last.closed || !streaming)) {
139
+ const block = shapedFollowups(last.inner);
140
+ if (block) return { body: without(src, last), block, partial: false };
141
+ }
142
+ return { body: src, block: null, partial: false };
143
+ }
144
+
145
+ /** The text a surface that cannot click (WhatsApp, a summary) keeps: the block left out. */
146
+ export function stripFollowups(text) {
147
+ return splitFollowups(text).body;
148
+ }
149
+
150
+ /**
151
+ * A label as a card shows it: without a "(Recommended)" suffix, and whether it had one. Display only:
152
+ * a question card's answer keeps the label exactly as the brain wrote it.
153
+ */
154
+ export function splitRecommended(label) {
155
+ const text = String(label ?? '');
156
+ if (!RECOMMENDED_RE.test(text)) return { label: text, recommended: false };
157
+ return { label: text.replace(RECOMMENDED_RE, '').trim() || text, recommended: true };
158
+ }
159
+
160
+ /** `item` with `recommended: true` when it says so (the flag, or a "(Recommended)" label suffix, which goes). */
161
+ function withRecommended(item, flagged) {
162
+ const marked = RECOMMENDED_RE.test(item.label);
163
+ if (marked) item.label = item.label.replace(RECOMMENDED_RE, '').trim() || item.label;
164
+ if (flagged || marked) item.recommended = true;
165
+ return item;
166
+ }
167
+
168
+ function itemFrom(raw) {
169
+ const { label: maxLabel, send: maxSend, description: maxDesc } = FOLLOWUP_LIMITS;
170
+ if (typeof raw === 'string') {
171
+ const text = plain(raw);
172
+ if (!text) return null;
173
+ const item = withRecommended({ label: clip(shortLabel(text), maxLabel), send: clip(text, maxSend), description: '' }, false);
174
+ if (item.recommended) item.send = clip(text.replace(RECOMMENDED_RE, '').trim() || text, maxSend);
175
+ return item;
176
+ }
177
+ if (!raw || typeof raw !== 'object') return null;
178
+ const label = plain(raw.label ?? raw.title ?? raw.text ?? raw.name ?? '');
179
+ const send = plain(raw.send ?? raw.message ?? raw.prompt ?? raw.reply ?? raw.value ?? raw.text ?? label);
180
+ if (!label && !send) return null;
181
+ return withRecommended({
182
+ label: clip(label || shortLabel(send), maxLabel),
183
+ send: clip(send || label, maxSend),
184
+ description: clip(plain(raw.description ?? raw.desc ?? raw.detail ?? raw.hint ?? ''), maxDesc),
185
+ }, raw.recommended === true || raw.recommended === 'true');
186
+ }
187
+
188
+ function itemsFrom(list) {
189
+ const seen = new Set();
190
+ const out = [];
191
+ for (const raw of Array.isArray(list) ? list : []) {
192
+ const item = itemFrom(raw);
193
+ if (!item || seen.has(norm(item.send))) continue;
194
+ seen.add(norm(item.send));
195
+ out.push(item);
196
+ if (out.length >= FOLLOWUP_LIMITS.items) break;
197
+ }
198
+ return out;
199
+ }
200
+
201
+ const LIST_ITEM_RE = /^\s*(?:[-*•+]|\(?\d{1,2}[.)])\s+(.+)$/;
202
+
203
+ /** A block that is no JSON: one item per list line ("- Ship it", "1. Ship it"). */
204
+ function linesToItems(src) {
205
+ const lines = src.split('\n').map((line) => LIST_ITEM_RE.exec(line)?.[1] || '').filter(Boolean);
206
+ return lines.length ? lines : null;
207
+ }
208
+
209
+ /** JSON, a trailing comma forgiven; undefined when it is none. */
210
+ function parseJson(src) {
211
+ for (const candidate of [src, src.replace(/,\s*([}\]])/g, '$1')]) {
212
+ try { return JSON.parse(candidate); } catch { /* the next candidate */ }
213
+ }
214
+ return undefined;
215
+ }
216
+
217
+ /** The fenced block's content → { multi, items, title, source: 'block' } or null. */
218
+ export function parseFollowupsBlock(raw) {
219
+ const src = String(raw ?? '').trim();
220
+ if (!src) return null;
221
+ let data = parseJson(src);
222
+ if (data === undefined) data = linesToItems(src);
223
+ return setFrom(data);
224
+ }
225
+
226
+ const filled = (value) => typeof value === 'string' && value.trim() !== '';
227
+
228
+ /**
229
+ * An untagged or json fence's content as a set, only in the exact follow-ups shape: an object whose
230
+ * `items` are all objects with a `label` and a `send`. Anything else is an ordinary code block.
231
+ */
232
+ function shapedFollowups(raw) {
233
+ const data = parseJson(String(raw ?? '').trim());
234
+ if (!data || typeof data !== 'object' || Array.isArray(data) || !Array.isArray(data.items) || !data.items.length) return null;
235
+ if (!data.items.every((item) => item && typeof item === 'object' && filled(item.label) && filled(item.send))) return null;
236
+ return setFrom(data);
237
+ }
238
+
239
+ /**
240
+ * The style a set is drawn in: the block's own when it fits its items, else what "multi" always meant.
241
+ * decisions needs two items to pick from; confirm is one proposed action and at most one alternative.
242
+ */
243
+ function resolveStyle(named, multi, count) {
244
+ let style = named || (multi ? 'decisions' : 'next');
245
+ if (style === 'decisions' && count < 2) style = 'next';
246
+ if (style === 'confirm' && count > 2) style = 'next';
247
+ return style;
248
+ }
249
+
250
+ /** Parsed block content (an object or a list) → { style, multi, items, title, question, source: 'block' } or null. */
251
+ function setFrom(data) {
252
+ const list = Array.isArray(data) ? data
253
+ : Array.isArray(data?.items) ? data.items
254
+ : Array.isArray(data?.followups) ? data.followups
255
+ : Array.isArray(data?.options) ? data.options : null;
256
+ const items = itemsFrom(list);
257
+ if (!items.length) return null;
258
+ const obj = data && !Array.isArray(data) && typeof data === 'object' ? data : {};
259
+ const multi = obj.multi === true || obj.multi_select === true || obj.multiSelect === true || obj.multiple === true;
260
+ const style = resolveStyle(followupStyleName(obj.style), multi, items.length);
261
+ const title = clip(plain(obj.title ?? obj.prompt ?? ''), 80);
262
+ // A question's own words: "question", else the title (a question block that put it there).
263
+ const question = style === 'question' ? clip(plain(obj.question ?? obj.ask ?? obj.title ?? obj.prompt ?? ''), FOLLOWUP_LIMITS.question) : '';
264
+ return { style, multi: style === 'decisions', items, title, question, source: 'block' };
265
+ }
266
+
267
+ /** "**Ship it** — publishes 1.4.0" → "Ship it": a bold lead, else the words before " — " / ": ", else the first ~8 words. */
268
+ function shortLabel(text) {
269
+ const src = String(text ?? '').trim();
270
+ const bold = /^\s*(?:\*\*|__)(.+?)(?:\*\*|__)/.exec(src);
271
+ if (bold) return plain(bold[1]).replace(/[:.\-–—]+$/, '').trim();
272
+ const flat = plain(src);
273
+ const cut = /^(.{3,60}?)\s*(?:\s[—–-]\s|:\s)/.exec(flat);
274
+ if (cut) return cut[1].trim();
275
+ const words = flat.split(/\s+/);
276
+ return words.length <= 8 ? flat.replace(/[.;]+$/, '') : `${words.slice(0, 8).join(' ')}…`;
277
+ }
278
+ /** What follows the label, as its one-line description. */
279
+ function restOf(text, label) {
280
+ const flat = plain(text);
281
+ const lead = flat.indexOf(label.replace(/…$/, ''));
282
+ const rest = lead === 0 ? flat.slice(label.replace(/…$/, '').length) : '';
283
+ return clip(rest.replace(/^\s*[:\-–—.]+\s*/, ''), FOLLOWUP_LIMITS.description);
284
+ }
285
+
286
+ // A list or an offer is a follow-up only when the text says it asks: words of choice or a question.
287
+ const OFFER_HEADER_RE = /\b(?:next steps?|follow[- ]?ups?|options?|choices?|decisions?|decide|choose|pick|which|want me to|would you like|do you want|should i|shall i|let me know|tell me|reply with|i can|i could|we can|you can|prefer|your call|up to you|need from you|ready to|suggest(?:ed|ions?)?|recommend(?:ed|ations?)?)\b/i;
288
+ const MULTI_HEADER_RE = /\b(?:numbers|decisions|any of|all that apply|pick (?:any|several|one or more)|one or more|as many|each)\b/i;
289
+
290
+ /** A list that ends the text, under a line that asks: its items. */
291
+ function trailingList(src) {
292
+ const lines = src.split('\n');
293
+ let i = lines.length - 1;
294
+ while (i >= 0 && !lines[i].trim()) i -= 1;
295
+ const raw = [];
296
+ let current = [];
297
+ let numbered = 0;
298
+ for (; i >= 0; i -= 1) {
299
+ const line = lines[i];
300
+ if (!line.trim()) {
301
+ // A blank line inside a loose list: the list goes on when an item is above it.
302
+ let j = i - 1;
303
+ while (j >= 0 && !lines[j].trim()) j -= 1;
304
+ if (j >= 0 && (LIST_ITEM_RE.test(lines[j]) || /^\s{2,}\S/.test(lines[j])) && raw.length) { i = j + 1; continue; }
305
+ break;
306
+ }
307
+ const item = LIST_ITEM_RE.exec(line);
308
+ if (item) {
309
+ raw.unshift([item[1], ...current].join(' '));
310
+ current = [];
311
+ if (/^\s*\(?\d/.test(line)) numbered += 1;
312
+ continue;
313
+ }
314
+ if (/^\s{2,}\S/.test(line)) { current.unshift(line.trim()); continue; } // an item's continuation line
315
+ break;
316
+ }
317
+ if (current.length || raw.length < 2 || raw.length > FOLLOWUP_LIMITS.items) return null;
318
+ if (raw.some((text) => text.length > FOLLOWUP_LIMITS.heuristicItem)) return null;
319
+ let h = i;
320
+ while (h >= 0 && !lines[h].trim()) h -= 1;
321
+ const header = h >= 0 ? lines[h].trim() : '';
322
+ if (!header || header.length > 300 || !(OFFER_HEADER_RE.test(header) || /\?\s*\**\s*$/.test(header))) return null;
323
+ const items = raw.map((text) => {
324
+ const label = clip(shortLabel(text), FOLLOWUP_LIMITS.label);
325
+ return { label, send: clip(plain(text), FOLLOWUP_LIMITS.send), description: restOf(text, label) };
326
+ });
327
+ const multi = numbered === raw.length && MULTI_HEADER_RE.test(header);
328
+ return { style: multi ? 'decisions' : 'next', multi, items, title: clip(plain(header).replace(/[:]\s*$/, ''), 80), question: '', source: 'heuristic' };
329
+ }
330
+
331
+ const OFFER_RE = /^(?:(?:but |and |so |or )?(?:i can|i could|we can|i'm happy to|happy to|want me to|do you want me to|would you like me to|should i|shall i))\s+(.+?)\s*[.?!]*$/i;
332
+ const ASKS_RE = /^(?:(?:but |and |so )?(?:want me to|do you want me to|would you like me to|should i|shall i))\s/i;
333
+ const capital = (s) => (s ? s[0].toUpperCase() + s.slice(1) : s);
334
+
335
+ /** "I can re-run it after the reset, or now on Claude…" → its alternatives; "Want me to ship it?" → one yes. */
336
+ function orOffer(src) {
337
+ const paragraphs = src.split(/\n\s*\n/).map((p) => p.trim()).filter(Boolean);
338
+ const last = paragraphs[paragraphs.length - 1] || '';
339
+ if (!last || last.length > 600 || LIST_ITEM_RE.test(last.split('\n').pop())) return null;
340
+ const sentences = plain(last).replace(/\s+/g, ' ').split(/(?<=[.?!])\s+(?=[A-Z"'(])/);
341
+ const sentence = sentences[sentences.length - 1] || '';
342
+ const m = OFFER_RE.exec(sentence);
343
+ if (!m) return null;
344
+ const rest = m[1].trim();
345
+ const parts = rest.split(/\s*,?\s+\bor\b\s+/i).map((p) => p.replace(/^(?:else|instead)\s+/i, '').trim()).filter(Boolean);
346
+ if (parts.length >= 2 && parts.length <= 4 && parts.every((p) => p.split(/\s+/).length >= 2)) {
347
+ const items = parts.map((p) => { const send = clip(capital(p), FOLLOWUP_LIMITS.send); return { label: clip(shortLabel(send), FOLLOWUP_LIMITS.label), send, description: '' }; });
348
+ return { style: 'next', multi: false, items, title: '', question: '', source: 'heuristic' };
349
+ }
350
+ if (ASKS_RE.test(sentence) && rest.split(/\s+/).length >= 2) {
351
+ // "Want me to open a PR?": one proposed action, so a confirm (go ahead, or not now).
352
+ const send = clip(`Yes, ${rest.replace(/[.?!]+$/, '')}`, FOLLOWUP_LIMITS.send);
353
+ return { style: 'confirm', multi: false, items: [{ label: clip(send, FOLLOWUP_LIMITS.label), send, description: '' }], title: clip(sentence, 80), question: '', source: 'heuristic' };
354
+ }
355
+ return null;
356
+ }
357
+
358
+ /**
359
+ * Best-effort follow-ups of a finished message that has no block: a list of options that ends it,
360
+ * under a line that asks ("Decisions I need from you (reply with the numbers):"), or an offer in
361
+ * its last sentence ("I can X, or Y.", "Want me to X?"). null when the text offers nothing.
362
+ */
363
+ export function guessFollowups(text) {
364
+ const src = String(text ?? '').replace(/\r\n?/g, '\n').trim();
365
+ if (!src) return null;
366
+ const split = splitFollowups(src);
367
+ if (split.block) return null;
368
+ // A code block that ends the message is output, not options.
369
+ if (/```\s*$/.test(split.body)) return null;
370
+ return trailingList(split.body) || orOffer(split.body);
371
+ }
372
+
373
+ /** The message a choice sends: one item's `send`, or several of them, one per line. */
374
+ export function followupMessage(set, indices = []) {
375
+ const items = [...new Set(indices)].sort((a, b) => a - b).map((i) => set?.items?.[i]).filter(Boolean);
376
+ if (!items.length) return '';
377
+ if (items.length === 1) return items[0].send;
378
+ return items.map((item) => `- ${item.send}`).join('\n');
379
+ }
380
+
381
+ /**
382
+ * A confirm with one proposed action gets a way to say no: `hold` ({ label, send }, the card's own words)
383
+ * as its second item, so a "Not now" is a message too and reads back from the transcript like any pick.
384
+ */
385
+ export function confirmSet(set, hold) {
386
+ if (set?.style !== 'confirm' || !Array.isArray(set.items) || set.items.length !== 1 || !hold?.send) return set;
387
+ return { ...set, items: [...set.items, { label: String(hold.label || hold.send), send: String(hold.send), description: '', hold: true }] };
388
+ }
389
+
390
+ /**
391
+ * What the user's next message `text` did to an offered set: { state: 'answered', indices, text } or
392
+ * { state: 'stale', indices: [] }. One of its items (several, one per line, for decisions) answers any
393
+ * set; for a question, whatever the user says next is their answer (`text`, the words they typed),
394
+ * except a slash command. The same rule live and from the journal, so a reload draws the same state.
395
+ */
396
+ export function settleFollowups(set, text) {
397
+ const indices = matchFollowupReply(set, text);
398
+ if (indices) return { state: 'answered', indices, text: '' };
399
+ const typed = String(text ?? '').trim();
400
+ if (set?.style === 'question' && typed && !typed.startsWith('/')) return { state: 'answered', indices: [], text: clip(typed, FOLLOWUP_LIMITS.answer) };
401
+ return { state: 'stale', indices: [], text: '' };
402
+ }
403
+
404
+ /** Which items of `set` the user's message `text` chose (the indices), or null when it chose none of them. */
405
+ export function matchFollowupReply(set, text) {
406
+ const items = Array.isArray(set?.items) ? set.items : [];
407
+ if (!items.length) return null;
408
+ const whole = norm(text);
409
+ if (!whole) return null;
410
+ const single = items.findIndex((item) => norm(item.send) === whole);
411
+ if (single >= 0) return [single];
412
+ if (!set.multi) return null;
413
+ const lines = String(text ?? '').split('\n').map((line) => norm(line.replace(/^\s*[-*•]\s+/, ''))).filter(Boolean);
414
+ if (lines.length < 2) return null;
415
+ const picked = lines.map((line) => items.findIndex((item) => norm(item.send) === line));
416
+ return picked.every((i) => i >= 0) ? [...new Set(picked)].sort((a, b) => a - b) : null;
417
+ }
@@ -54,7 +54,7 @@ export function describeBrainFallback(fallback) {
54
54
  }
55
55
 
56
56
  /**
57
- * deps: { api: { list(), get(id), create({brain,label,fallback}) },
57
+ * deps: { api: { list(), get(id), create({brain,label,fallback,draft}), remove?(id) },
58
58
  * isBlocked() → bool, toast(text), storedBrain() → brain|null,
59
59
  * fallbackText(session.fallback) → text, defaultHost: 'terminal' }
60
60
  */
@@ -149,7 +149,9 @@ export function createAssistantHosts({
149
149
  try {
150
150
  // A model disabled since it was picked (Assistant → Models) must not
151
151
  // lock the Assistant out: the server starts on its enabled stand-in.
152
- res = await api.create({ brain: b, label: label || undefined, fallback: true });
152
+ // A draft: the server stores and lists it from its first prompt on (a prompt
153
+ // given here is that prompt); closed or left unused, nothing of it remains.
154
+ res = await api.create({ brain: b, label: label || undefined, fallback: true, draft: true });
153
155
  } catch (err) {
154
156
  say(`Assistant unavailable: ${err?.message || err}`);
155
157
  return null;
@@ -245,6 +247,48 @@ export function createAssistantHosts({
245
247
  return true;
246
248
  }
247
249
 
250
+ /**
251
+ * A session nobody chatted in that the user left (they picked another one in its Sessions menu):
252
+ * its tab closes the way the user closes one, and the server removes it (it holds no conversation).
253
+ */
254
+ function discard(sessionId) {
255
+ const owner = ownerOf(sessionId);
256
+ if (last?.sessionId === sessionId) last = null;
257
+ if (!owner) return false;
258
+ adapters.get(owner).close(sessionId, { closeServer: true });
259
+ return true;
260
+ }
261
+
262
+ /**
263
+ * The Sessions menu's Remove: the server stops the session's running turn and workers and purges it,
264
+ * then its tab closes wherever it is open (other windows: the session-ended broadcast). `fresh`: it is
265
+ * the session showing where the user asked, and the host that has it gets a new one first, as New does
266
+ * (a host is never left empty in between). → { ok: true, stoppedRuns } | { ok: false, error }
267
+ */
268
+ async function remove(sessionId, { host = null, fresh = false, brain = null } = {}) {
269
+ if (!sessionId || !api.remove) return { ok: false, error: 'unavailable' };
270
+ if (isBlocked()) return { ok: false, error: 'blocked' };
271
+ if (fresh) { try { await open({ host: host || ownerOf(sessionId), brain }); } catch { /* the removal goes on */ } }
272
+ let res = null;
273
+ try { res = await api.remove(sessionId); }
274
+ catch (err) { return { ok: false, error: err?.message || String(err) }; }
275
+ ended(sessionId);
276
+ return { ok: true, stoppedRuns: Array.isArray(res?.stoppedRuns) ? res.stoppedRuns : [] };
277
+ }
278
+
279
+ /**
280
+ * The server no longer has a session a host shows (a draft it dropped, a restart before its first
281
+ * prompt, a removal this page missed): its tab closes, and with `fresh` (it was showing and had
282
+ * no conversation) a new session takes its place in the host that had it, so the user never sees a dead tab.
283
+ */
284
+ async function gone(sessionId, { host = null, fresh = false, brain = null } = {}) {
285
+ if (!sessionId) return null;
286
+ let opened = null;
287
+ if (fresh && !isBlocked()) { try { opened = await open({ host: host || ownerOf(sessionId), brain }); } catch { opened = null; } }
288
+ ended(sessionId);
289
+ return opened;
290
+ }
291
+
248
292
  return {
249
293
  register,
250
294
  ownerOf,
@@ -253,6 +297,9 @@ export function createAssistantHosts({
253
297
  toggle,
254
298
  show,
255
299
  ended,
300
+ discard,
301
+ remove,
302
+ gone,
256
303
  noteFocus,
257
304
  fetchLive,
258
305
  isLive: isAssistantSessionLive,
@@ -0,0 +1,40 @@
1
+ // One countdown owner per mounted conversation. Transcript replay and run-card
2
+ // refreshes update keyed records; they never allocate their own waiting cards.
3
+ import { createLimitWait } from './asst-limit-wait.js';
4
+
5
+ export function createLimitDock(transcript, { t, createWait = createLimitWait, createElement = () => document.createElement('div') } = {}) {
6
+ const host = createElement();
7
+ host.className = 'asst-limit-dock';
8
+ host.hidden = true;
9
+ transcript.after(host);
10
+ const entries = new Map();
11
+ let active = null;
12
+ let wait = null;
13
+ let provider = null;
14
+ let destroyed = false;
15
+ function render() {
16
+ const next = [...entries.entries()].sort((a, b) => (b[1].since || 0) - (a[1].since || 0))[0];
17
+ const key = next?.[0] || null;
18
+ if (key !== active || next?.[1].provider !== provider) {
19
+ wait?.destroy();
20
+ host.replaceChildren();
21
+ active = key;
22
+ provider = next?.[1].provider;
23
+ wait = next ? createWait({ t, ...next[1], onRetry: next[1].onRetry ? () => entries.get(key)?.onRetry?.() : null }) : null;
24
+ if (wait) host.appendChild(wait.el);
25
+ } else if (wait) wait.update({ resetsAt: next[1].resetsAt });
26
+ host.hidden = !wait;
27
+ return wait;
28
+ }
29
+ return {
30
+ el: host,
31
+ set(key, info) {
32
+ if (destroyed) return null;
33
+ if (info) entries.set(key, { ...info, since: entries.get(key)?.since || info.since });
34
+ else entries.delete(key);
35
+ return render();
36
+ },
37
+ clear() { if (destroyed) return; entries.clear(); render(); },
38
+ destroy() { destroyed = true; entries.clear(); wait?.destroy(); wait = null; active = null; host.remove(); },
39
+ };
40
+ }