synabun 2.0.10 → 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 (517) hide show
  1. package/CHANGELOG.md +86 -0
  2. package/README.md +25 -2
  3. package/THIRD-PARTY-LICENSES.md +22 -0
  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/lib/claude-hooks.js +172 -18
  10. package/lib/client-config-repair.js +17 -8
  11. package/lib/desktop-app.js +7 -1
  12. package/lib/external-tools.js +1 -1
  13. package/lib/first-launch-protection.js +57 -12
  14. package/lib/mcp-dist.js +176 -0
  15. package/lib/release-npm-ci.mjs +138 -0
  16. package/lib/release-publish.mjs +91 -0
  17. package/lib/release-scan.mjs +50 -0
  18. package/lib/server-crash-record.js +123 -0
  19. package/lib/server-exit.js +318 -0
  20. package/lib/server-supervisor.js +508 -0
  21. package/lib/start-launcher.js +37 -4
  22. package/lib/tools-cli.js +45 -0
  23. package/lib/update-snapshot.js +228 -0
  24. package/lib/virustotal.mjs +192 -0
  25. package/lib/windows-crash-event.js +269 -0
  26. package/mcp-server/dist/http.d.ts +20 -1
  27. package/mcp-server/dist/http.d.ts.map +1 -1
  28. package/mcp-server/dist/http.js +59 -12
  29. package/mcp-server/dist/http.js.map +1 -1
  30. package/mcp-server/dist/index.d.ts +33 -27
  31. package/mcp-server/dist/index.d.ts.map +1 -1
  32. package/mcp-server/dist/index.js +128 -143
  33. package/mcp-server/dist/index.js.map +1 -1
  34. package/mcp-server/dist/preload.js +1 -1
  35. package/mcp-server/dist/preload.js.map +1 -1
  36. package/mcp-server/dist/services/codex-config-heal.d.ts +6 -2
  37. package/mcp-server/dist/services/codex-config-heal.d.ts.map +1 -1
  38. package/mcp-server/dist/services/codex-config-heal.js +81 -28
  39. package/mcp-server/dist/services/codex-config-heal.js.map +1 -1
  40. package/mcp-server/dist/services/memory-judge-backfill.d.ts +6 -0
  41. package/mcp-server/dist/services/memory-judge-backfill.d.ts.map +1 -1
  42. package/mcp-server/dist/services/memory-judge-backfill.js +7 -1
  43. package/mcp-server/dist/services/memory-judge-backfill.js.map +1 -1
  44. package/mcp-server/dist/services/neural-interface.d.ts +16 -10
  45. package/mcp-server/dist/services/neural-interface.d.ts.map +1 -1
  46. package/mcp-server/dist/services/neural-interface.js +67 -11
  47. package/mcp-server/dist/services/neural-interface.js.map +1 -1
  48. package/mcp-server/dist/services/server-instructions.d.ts +7 -2
  49. package/mcp-server/dist/services/server-instructions.d.ts.map +1 -1
  50. package/mcp-server/dist/services/server-instructions.js +20 -62
  51. package/mcp-server/dist/services/server-instructions.js.map +1 -1
  52. package/mcp-server/dist/services/tool-catalog.d.ts +120 -0
  53. package/mcp-server/dist/services/tool-catalog.d.ts.map +1 -0
  54. package/mcp-server/dist/services/tool-catalog.js +339 -0
  55. package/mcp-server/dist/services/tool-catalog.js.map +1 -0
  56. package/mcp-server/dist/services/tool-list-refresh-barrier.d.ts +12 -0
  57. package/mcp-server/dist/services/tool-list-refresh-barrier.d.ts.map +1 -0
  58. package/mcp-server/dist/services/tool-list-refresh-barrier.js +40 -0
  59. package/mcp-server/dist/services/tool-list-refresh-barrier.js.map +1 -0
  60. package/mcp-server/dist/services/tool-list.d.ts +108 -0
  61. package/mcp-server/dist/services/tool-list.d.ts.map +1 -0
  62. package/mcp-server/dist/services/tool-list.js +334 -0
  63. package/mcp-server/dist/services/tool-list.js.map +1 -0
  64. package/mcp-server/dist/services/tool-runtime.d.ts +161 -0
  65. package/mcp-server/dist/services/tool-runtime.d.ts.map +1 -0
  66. package/mcp-server/dist/services/tool-runtime.js +400 -0
  67. package/mcp-server/dist/services/tool-runtime.js.map +1 -0
  68. package/mcp-server/dist/services/whiteboard-geometry.d.ts +26 -2
  69. package/mcp-server/dist/services/whiteboard-geometry.d.ts.map +1 -1
  70. package/mcp-server/dist/services/whiteboard-geometry.js +91 -8
  71. package/mcp-server/dist/services/whiteboard-geometry.js.map +1 -1
  72. package/mcp-server/dist/tools/agents.d.ts +10 -10
  73. package/mcp-server/dist/tools/agents.d.ts.map +1 -1
  74. package/mcp-server/dist/tools/agents.js +22 -13
  75. package/mcp-server/dist/tools/agents.js.map +1 -1
  76. package/mcp-server/dist/tools/browser-batch.d.ts +3 -3
  77. package/mcp-server/dist/tools/image-tools.d.ts +1 -1
  78. package/mcp-server/dist/tools/image-tools.js +1 -1
  79. package/mcp-server/dist/tools/skill-tools.d.ts +505 -0
  80. package/mcp-server/dist/tools/skill-tools.d.ts.map +1 -0
  81. package/mcp-server/dist/tools/skill-tools.js +639 -0
  82. package/mcp-server/dist/tools/skill-tools.js.map +1 -0
  83. package/mcp-server/dist/tools/skill.d.ts +7 -0
  84. package/mcp-server/dist/tools/skill.d.ts.map +1 -0
  85. package/mcp-server/dist/tools/skill.js +11 -0
  86. package/mcp-server/dist/tools/skill.js.map +1 -0
  87. package/mcp-server/dist/tools/tool-groups.d.ts +68 -0
  88. package/mcp-server/dist/tools/tool-groups.d.ts.map +1 -0
  89. package/mcp-server/dist/tools/tool-groups.js +147 -0
  90. package/mcp-server/dist/tools/tool-groups.js.map +1 -0
  91. package/mcp-server/dist/tools/whiteboard-format.d.ts.map +1 -1
  92. package/mcp-server/dist/tools/whiteboard-format.js +7 -4
  93. package/mcp-server/dist/tools/whiteboard-format.js.map +1 -1
  94. package/mcp-server/dist/tools/whiteboard-tools.d.ts +64 -13
  95. package/mcp-server/dist/tools/whiteboard-tools.d.ts.map +1 -1
  96. package/mcp-server/dist/tools/whiteboard-tools.js +30 -5
  97. package/mcp-server/dist/tools/whiteboard-tools.js.map +1 -1
  98. package/mcp-server/package-lock.json +2 -2
  99. package/mcp-server/package.json +1 -1
  100. package/mcp-server/src/http.ts +75 -12
  101. package/mcp-server/src/index.ts +147 -154
  102. package/mcp-server/src/preload.ts +12 -12
  103. package/mcp-server/src/services/codex-config-heal.ts +80 -29
  104. package/mcp-server/src/services/memory-judge-backfill.ts +7 -1
  105. package/mcp-server/src/services/neural-interface.ts +79 -20
  106. package/mcp-server/src/services/server-instructions.ts +27 -63
  107. package/mcp-server/src/services/tool-catalog.ts +403 -0
  108. package/mcp-server/src/services/tool-list-refresh-barrier.ts +33 -0
  109. package/mcp-server/src/services/tool-list.ts +410 -0
  110. package/mcp-server/src/services/tool-runtime.ts +457 -0
  111. package/mcp-server/src/services/whiteboard-geometry.ts +94 -9
  112. package/mcp-server/src/tools/agents.ts +22 -14
  113. package/mcp-server/src/tools/image-tools.ts +1 -1
  114. package/mcp-server/src/tools/skill-tools.ts +589 -0
  115. package/mcp-server/src/tools/skill.ts +13 -0
  116. package/mcp-server/src/tools/tool-groups.ts +164 -0
  117. package/mcp-server/src/tools/whiteboard-format.ts +9 -3
  118. package/mcp-server/src/tools/whiteboard-tools.ts +39 -5
  119. package/neural-interface/i18n/en.json +3463 -200
  120. package/neural-interface/i18n/pt-BR.json +3411 -151
  121. package/neural-interface/lib/assistant-api.js +127 -28
  122. package/neural-interface/lib/assistant-brains/claude.js +4 -3
  123. package/neural-interface/lib/assistant-brains/codex-browser-policy-hook.mjs +12 -2
  124. package/neural-interface/lib/assistant-brains/codex-route-gate-hook.mjs +32 -9
  125. package/neural-interface/lib/assistant-brains/codex.js +9 -5
  126. package/neural-interface/lib/assistant-brains/opencode.js +120 -54
  127. package/neural-interface/lib/assistant-brains/opencode2-browser-policy/index.js +28 -13
  128. package/neural-interface/lib/assistant-brains/opencode2-route-gate/index.js +59 -19
  129. package/neural-interface/lib/assistant-catalog.js +6 -7
  130. package/neural-interface/lib/assistant-dispatch.js +871 -156
  131. package/neural-interface/lib/assistant-envelope.js +3 -1
  132. package/neural-interface/lib/assistant-persona.js +80 -11
  133. package/neural-interface/lib/assistant-plan-permissions.js +10 -9
  134. package/neural-interface/lib/assistant-route-gate-codex.js +3 -0
  135. package/neural-interface/lib/assistant-route-gate.js +6 -4
  136. package/neural-interface/lib/assistant-router.js +13 -8
  137. package/neural-interface/lib/assistant-runtime.js +56 -18
  138. package/neural-interface/lib/assistant-task-prompt.js +78 -14
  139. package/neural-interface/lib/assistant-tools.js +51 -0
  140. package/neural-interface/lib/backup-service.js +620 -3
  141. package/neural-interface/lib/backup-zip-reader.js +10 -5
  142. package/neural-interface/lib/backup-zip-writer.js +257 -0
  143. package/neural-interface/lib/browser-execution.js +10 -2
  144. package/neural-interface/lib/browser-guard-cdp.js +83 -0
  145. package/neural-interface/lib/browser-network-guard.js +284 -0
  146. package/neural-interface/lib/browser-policy-roots.js +64 -0
  147. package/neural-interface/lib/browser-tool-policy.js +186 -31
  148. package/neural-interface/lib/claude-agent-bridge.js +4 -2
  149. package/neural-interface/lib/claude-hooks-status.js +103 -0
  150. package/neural-interface/lib/claude-temporary.js +5 -11
  151. package/neural-interface/lib/cli-install.js +18 -138
  152. package/neural-interface/lib/cli-resolver.js +4 -1
  153. package/neural-interface/lib/cli-update-planner.js +32 -31
  154. package/neural-interface/lib/cloudflared/tunnel.js +42 -2
  155. package/neural-interface/lib/codex-mcp-approvals.js +11 -0
  156. package/neural-interface/lib/codex-worker-app-server.js +172 -0
  157. package/neural-interface/lib/confined-fs.js +30 -3
  158. package/neural-interface/lib/crash-notice-api.js +98 -0
  159. package/neural-interface/lib/editor-completion-opencode.js +68 -68
  160. package/neural-interface/lib/exec-loop-command.js +4 -8
  161. package/neural-interface/lib/http-guards.js +8 -2
  162. package/neural-interface/lib/install-details.js +4 -1
  163. package/neural-interface/lib/mcp-agent-servers.js +67 -0
  164. package/neural-interface/lib/mcp-client-config.js +0 -29
  165. package/neural-interface/lib/mcp-external-servers.js +323 -0
  166. package/neural-interface/lib/{mcp-profile-refresh-coordinator.js → mcp-tools-refresh-coordinator.js} +4 -4
  167. package/neural-interface/lib/morelogin.js +30 -0
  168. package/neural-interface/lib/native-loop-providers.js +547 -47
  169. package/neural-interface/lib/native-loop-runtime.js +268 -41
  170. package/neural-interface/lib/opencode-config.js +557 -0
  171. package/neural-interface/lib/opencode-db-schema.js +17 -34
  172. package/neural-interface/lib/opencode-history.js +48 -218
  173. package/neural-interface/lib/opencode-mcp-ready.js +108 -0
  174. package/neural-interface/lib/opencode-native-boundary.js +44 -0
  175. package/neural-interface/lib/opencode-protocol.js +249 -112
  176. package/neural-interface/lib/opencode-runtime-config.js +32 -22
  177. package/neural-interface/lib/opencode-serve-records.js +39 -21
  178. package/neural-interface/lib/opencode-v2-client.js +48 -153
  179. package/neural-interface/lib/opencode-v2-ws-requests.js +36 -210
  180. package/neural-interface/lib/opencode-worker-data.js +27 -0
  181. package/neural-interface/lib/opencode2-client.js +73 -37
  182. package/neural-interface/lib/opencode2-proxy.js +23 -63
  183. package/neural-interface/lib/opencode2-translate.js +51 -2
  184. package/neural-interface/lib/owner-authority.js +249 -0
  185. package/neural-interface/lib/page-session.js +275 -0
  186. package/neural-interface/lib/peer-identity.js +763 -0
  187. package/neural-interface/lib/request-gate.js +17 -2
  188. package/neural-interface/lib/rulesets/api.js +1 -1
  189. package/neural-interface/lib/rulesets/fs-safe.js +1 -1
  190. package/neural-interface/lib/rulesets/installer.js +92 -27
  191. package/neural-interface/lib/rulesets/json-edit.js +1 -1
  192. package/neural-interface/lib/session-cache-builder.js +17 -30
  193. package/neural-interface/lib/session-title-generator.js +58 -36
  194. package/neural-interface/lib/skills/api-v2.js +495 -0
  195. package/neural-interface/lib/skills/bundle.js +418 -0
  196. package/neural-interface/lib/skills/catalog.js +294 -0
  197. package/neural-interface/lib/skills/creation-api.js +191 -0
  198. package/neural-interface/lib/skills/creation-brief.js +247 -0
  199. package/neural-interface/lib/skills/creation-sources.js +267 -0
  200. package/neural-interface/lib/skills/creation.js +843 -0
  201. package/neural-interface/lib/skills/deploy.js +564 -0
  202. package/neural-interface/lib/skills/digest.js +119 -0
  203. package/neural-interface/lib/skills/discover.js +111 -0
  204. package/neural-interface/lib/skills/draft-confinement.js +214 -0
  205. package/neural-interface/lib/skills/eval-confinement.js +397 -0
  206. package/neural-interface/lib/skills/eval-sandbox.js +280 -0
  207. package/neural-interface/lib/skills/eval-trace.js +119 -0
  208. package/neural-interface/lib/skills/evals-api.js +212 -0
  209. package/neural-interface/lib/skills/evals.js +1573 -0
  210. package/neural-interface/lib/skills/export.js +200 -0
  211. package/neural-interface/lib/skills/frontmatter.js +64 -0
  212. package/neural-interface/lib/skills/health.js +75 -0
  213. package/neural-interface/lib/skills/json-edit.js +165 -0
  214. package/neural-interface/lib/skills/known-bridge-digests.json +387 -0
  215. package/neural-interface/lib/skills/known-bridges.js +96 -0
  216. package/neural-interface/lib/skills/library.js +823 -0
  217. package/neural-interface/lib/skills/local-store.js +21 -0
  218. package/neural-interface/lib/skills/migration.js +433 -0
  219. package/neural-interface/lib/skills/operations.js +45 -0
  220. package/neural-interface/lib/skills/ownership.js +427 -0
  221. package/neural-interface/lib/skills/packages.js +88 -0
  222. package/neural-interface/lib/skills/reviews.js +212 -0
  223. package/neural-interface/lib/skills/revision.js +80 -0
  224. package/neural-interface/lib/skills/roots.js +262 -0
  225. package/neural-interface/lib/skills/runtime-checks.js +355 -0
  226. package/neural-interface/lib/skills/scan-assets.js +252 -0
  227. package/neural-interface/lib/skills/scan-context.js +26 -0
  228. package/neural-interface/lib/skills/scan-shell.js +324 -0
  229. package/neural-interface/lib/skills/scan.js +364 -0
  230. package/neural-interface/lib/skills/scanners.js +54 -0
  231. package/neural-interface/lib/skills/service.js +522 -0
  232. package/neural-interface/lib/skills/telemetry.js +113 -0
  233. package/neural-interface/lib/sqlite-integrity-worker.js +22 -0
  234. package/neural-interface/lib/tool-lists.js +124 -0
  235. package/neural-interface/lib/whatsapp/bridge.js +6 -3
  236. package/neural-interface/lib/worker-confinement.js +1192 -0
  237. package/neural-interface/lib/worker-guard-setting.js +56 -0
  238. package/neural-interface/lib/worker-mcp-channel.js +175 -0
  239. package/neural-interface/lib/worker-relay-ports.js +227 -0
  240. package/neural-interface/lib/worker-resume.js +229 -0
  241. package/neural-interface/lib/worker-sandbox.js +299 -0
  242. package/neural-interface/package-lock.json +18 -12
  243. package/neural-interface/package.json +2 -2
  244. package/neural-interface/public/index.html +3 -1
  245. package/neural-interface/public/index2d.html +19 -11
  246. package/neural-interface/public/onboarding.html +2 -2
  247. package/neural-interface/public/shared/account-menu.js +8 -5
  248. package/neural-interface/public/shared/agent-runtime-options.js +35 -19
  249. package/neural-interface/public/shared/api.js +1527 -1336
  250. package/neural-interface/public/shared/app-frame.js +192 -0
  251. package/neural-interface/public/shared/assistant/asst-agents-dock.js +33 -2
  252. package/neural-interface/public/shared/assistant/asst-ask-styles.js +270 -0
  253. package/neural-interface/public/shared/assistant/asst-ask-tail.js +118 -0
  254. package/neural-interface/public/shared/assistant/asst-ask.js +397 -0
  255. package/neural-interface/public/shared/assistant/asst-brain-picker.js +49 -35
  256. package/neural-interface/public/shared/assistant/asst-control.js +157 -26
  257. package/neural-interface/public/shared/assistant/asst-followups-card.js +383 -0
  258. package/neural-interface/public/shared/assistant/asst-followups.js +417 -0
  259. package/neural-interface/public/shared/assistant/asst-limit-dock.js +40 -0
  260. package/neural-interface/public/shared/assistant/asst-limit-wait.js +294 -0
  261. package/neural-interface/public/shared/assistant/asst-limit.js +168 -0
  262. package/neural-interface/public/shared/assistant/asst-mascot.js +49 -12
  263. package/neural-interface/public/shared/assistant/asst-menu.js +7 -6
  264. package/neural-interface/public/shared/assistant/asst-panel.js +106 -11
  265. package/neural-interface/public/shared/assistant/asst-rack-styles.js +66 -49
  266. package/neural-interface/public/shared/assistant/asst-render.js +401 -77
  267. package/neural-interface/public/shared/assistant/asst-route.js +83 -12
  268. package/neural-interface/public/shared/assistant/asst-scenes.js +2 -0
  269. package/neural-interface/public/shared/assistant/asst-sidepanel.js +67 -4
  270. package/neural-interface/public/shared/assistant/asst-slash.js +9 -7
  271. package/neural-interface/public/shared/assistant/asst-state.js +11 -15
  272. package/neural-interface/public/shared/assistant/asst-stop.js +127 -0
  273. package/neural-interface/public/shared/assistant/asst-styles.js +59 -21
  274. package/neural-interface/public/shared/assistant/asst-tool-kinds.js +156 -16
  275. package/neural-interface/public/shared/automation-context.js +5 -2
  276. package/neural-interface/public/shared/cc-dropdown.js +89 -19
  277. package/neural-interface/public/shared/cdx/cdx-context-menu.js +10 -9
  278. package/neural-interface/public/shared/cdx/cdx-copy.js +16 -0
  279. package/neural-interface/public/shared/cdx/cdx-output-model.js +22 -1
  280. package/neural-interface/public/shared/cdx/cdx-output.js +8 -7
  281. package/neural-interface/public/shared/cdx/cdx-panel.js +45 -149
  282. package/neural-interface/public/shared/cdx/cdx-protocol.js +28 -1
  283. package/neural-interface/public/shared/cdx/cdx-render.js +47 -29
  284. package/neural-interface/public/shared/cdx/cdx-requests.js +3 -3
  285. package/neural-interface/public/shared/cdx/cdx-skill-hints.js +54 -0
  286. package/neural-interface/public/shared/cdx/cdx-styles.js +11 -3
  287. package/neural-interface/public/shared/cdx/cdx-tabs.js +52 -39
  288. package/neural-interface/public/shared/cdx/cdx-ws.js +0 -1
  289. package/neural-interface/public/shared/cli-install-view.js +4 -8
  290. package/neural-interface/public/shared/cli-status.js +2 -2
  291. package/neural-interface/public/shared/constants.js +2 -2
  292. package/neural-interface/public/shared/context-menu-areas.js +34 -0
  293. package/neural-interface/public/shared/context-menu-logic.js +243 -0
  294. package/neural-interface/public/shared/context-menu-model.js +366 -0
  295. package/neural-interface/public/shared/context-menu.js +372 -0
  296. package/neural-interface/public/shared/cp/cp-context-menu.js +10 -9
  297. package/neural-interface/public/shared/crash-notice-view.js +168 -0
  298. package/neural-interface/public/shared/desktop-update-view.js +20 -0
  299. package/neural-interface/public/shared/editor/editor-panel-logic.js +2 -2
  300. package/neural-interface/public/shared/html-shell.js +9 -11
  301. package/neural-interface/public/shared/i18n.js +2 -0
  302. package/neural-interface/public/shared/ocp-v2/ocp-v2-approvals.js +7 -7
  303. package/neural-interface/public/shared/ocp-v2/ocp-v2-binding.js +4 -4
  304. package/neural-interface/public/shared/ocp-v2/ocp-v2-changes-logic.js +3 -101
  305. package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +2 -0
  306. package/neural-interface/public/shared/ocp-v2/ocp-v2-compact-button.js +1 -3
  307. package/neural-interface/public/shared/ocp-v2/ocp-v2-composer-logic.js +2 -6
  308. package/neural-interface/public/shared/ocp-v2/ocp-v2-context-menu.js +11 -11
  309. package/neural-interface/public/shared/ocp-v2/ocp-v2-context-model.js +0 -3
  310. package/neural-interface/public/shared/ocp-v2/ocp-v2-events.js +8 -4
  311. package/neural-interface/public/shared/ocp-v2/ocp-v2-manager.js +7 -7
  312. package/neural-interface/public/shared/ocp-v2/ocp-v2-outcome-notifications.js +16 -0
  313. package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +47 -252
  314. package/neural-interface/public/shared/ocp-v2/ocp-v2-plan.js +1 -2
  315. package/neural-interface/public/shared/ocp-v2/ocp-v2-projectbar.js +95 -202
  316. package/neural-interface/public/shared/ocp-v2/ocp-v2-render.js +6 -21
  317. package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +4 -4
  318. package/neural-interface/public/shared/ocp-v2/ocp-v2-session-actions.js +8 -61
  319. package/neural-interface/public/shared/ocp-v2/ocp-v2-sessions-logic.js +2 -91
  320. package/neural-interface/public/shared/ocp-v2/ocp-v2-slash-hints.js +16 -15
  321. package/neural-interface/public/shared/ocp-v2/ocp-v2-state.js +8 -21
  322. package/neural-interface/public/shared/ocp-v2/ocp-v2-status-logic.js +1 -99
  323. package/neural-interface/public/shared/ocp-v2/ocp-v2-status.js +5 -35
  324. package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +0 -21
  325. package/neural-interface/public/shared/ocp-v2/{ocp-v2-profile-inheritance.js → ocp-v2-tools-inheritance.js} +16 -16
  326. package/neural-interface/public/shared/ocp-v2/ocp-v2-ws.js +14 -47
  327. package/neural-interface/public/shared/page-session.js +96 -0
  328. package/neural-interface/public/shared/registry.js +5 -3
  329. package/neural-interface/public/shared/retired-2d.js +3 -0
  330. package/neural-interface/public/shared/schedules-view.js +195 -61
  331. package/neural-interface/public/shared/settings/settings-claude-hooks.js +135 -0
  332. package/neural-interface/public/shared/settings/settings-data.js +3 -1
  333. package/neural-interface/public/shared/settings/settings-ia.js +6 -6
  334. package/neural-interface/public/shared/settings/settings-opencode.js +89 -0
  335. package/neural-interface/public/shared/settings/settings-skill-folders-pane.js +265 -0
  336. package/neural-interface/public/shared/settings/settings-skill-folders.js +130 -0
  337. package/neural-interface/public/shared/settings/settings-worker-guard.js +72 -0
  338. package/neural-interface/public/shared/skills/ss-args.js +96 -0
  339. package/neural-interface/public/shared/skills/ss-creation.js +219 -0
  340. package/neural-interface/public/shared/skills/ss-dialog.js +130 -0
  341. package/neural-interface/public/shared/skills/ss-doc.js +173 -0
  342. package/neural-interface/public/shared/skills/ss-eval-adapters.js +269 -0
  343. package/neural-interface/public/shared/skills/ss-eval-grade.js +359 -0
  344. package/neural-interface/public/shared/skills/ss-eval-optimise.js +153 -0
  345. package/neural-interface/public/shared/skills/ss-eval-plan.js +315 -0
  346. package/neural-interface/public/shared/skills/ss-evals.js +417 -0
  347. package/neural-interface/public/shared/skills/ss-form.js +159 -0
  348. package/neural-interface/public/shared/skills/ss-frontmatter.js +376 -0
  349. package/neural-interface/public/shared/skills/ss-ids.js +32 -0
  350. package/neural-interface/public/shared/skills/ss-lint.js +141 -0
  351. package/neural-interface/public/shared/skills/ss-presets.js +117 -0
  352. package/neural-interface/public/shared/skills/ss-profiles.js +475 -0
  353. package/neural-interface/public/shared/skills/ss-resources.js +165 -0
  354. package/neural-interface/public/shared/skills/ss-review-view.js +190 -0
  355. package/neural-interface/public/shared/skills/ss-tabs.js +79 -0
  356. package/neural-interface/public/shared/skills/ss-unicode.js +135 -0
  357. package/neural-interface/public/shared/skills/studio/sx-actions.js +222 -0
  358. package/neural-interface/public/shared/skills/studio/sx-cm.js +101 -0
  359. package/neural-interface/public/shared/skills/studio/sx-create-ai-view.js +749 -0
  360. package/neural-interface/public/shared/skills/studio/sx-create-ai.js +236 -0
  361. package/neural-interface/public/shared/skills/studio/sx-create-view.js +254 -0
  362. package/neural-interface/public/shared/skills/studio/sx-create.js +126 -0
  363. package/neural-interface/public/shared/skills/studio/sx-diff-view.js +43 -0
  364. package/neural-interface/public/shared/skills/studio/sx-diff.js +133 -0
  365. package/neural-interface/public/shared/skills/studio/sx-docs.js +480 -0
  366. package/neural-interface/public/shared/skills/studio/sx-dom.js +229 -0
  367. package/neural-interface/public/shared/skills/studio/sx-edit-view.js +848 -0
  368. package/neural-interface/public/shared/skills/studio/sx-editor-model.js +193 -0
  369. package/neural-interface/public/shared/skills/studio/sx-errors.js +22 -0
  370. package/neural-interface/public/shared/skills/studio/sx-geometry.js +82 -0
  371. package/neural-interface/public/shared/skills/studio/sx-import.js +262 -0
  372. package/neural-interface/public/shared/skills/studio/sx-inspector.js +308 -0
  373. package/neural-interface/public/shared/skills/studio/sx-install-flow.js +279 -0
  374. package/neural-interface/public/shared/skills/studio/sx-install.js +296 -0
  375. package/neural-interface/public/shared/skills/studio/sx-library-view.js +639 -0
  376. package/neural-interface/public/shared/skills/studio/sx-library.js +475 -0
  377. package/neural-interface/public/shared/skills/studio/sx-main.js +681 -0
  378. package/neural-interface/public/shared/skills/studio/sx-operations-view.js +98 -0
  379. package/neural-interface/public/shared/skills/studio/sx-operations.js +11 -0
  380. package/neural-interface/public/shared/skills/studio/sx-plan.js +158 -0
  381. package/neural-interface/public/shared/skills/studio/sx-publish-view.js +621 -0
  382. package/neural-interface/public/shared/skills/studio/sx-review-view.js +369 -0
  383. package/neural-interface/public/shared/skills/studio/sx-review.js +148 -0
  384. package/neural-interface/public/shared/skills/studio/sx-scan.js +35 -0
  385. package/neural-interface/public/shared/skills/studio/sx-snippets.js +96 -0
  386. package/neural-interface/public/shared/skills/studio/sx-subject.js +248 -0
  387. package/neural-interface/public/shared/skills/studio/sx-test-view.js +994 -0
  388. package/neural-interface/public/shared/skills/studio/sx-test.js +328 -0
  389. package/neural-interface/public/shared/skills/studio/sx-versions-view.js +241 -0
  390. package/neural-interface/public/shared/skills/studio/sx-workspace-view.js +425 -0
  391. package/neural-interface/public/shared/styleguide/sg-panel.js +4 -2
  392. package/neural-interface/public/shared/styles.css +1525 -1779
  393. package/neural-interface/public/shared/synabun-mascot.js +1115 -9
  394. package/neural-interface/public/shared/tool-list-picker.js +55 -0
  395. package/neural-interface/public/shared/tool-list-storage.js +24 -0
  396. package/neural-interface/public/shared/tool-list-view.js +112 -0
  397. package/neural-interface/public/shared/tour/tour-actor.js +268 -0
  398. package/neural-interface/public/shared/tour/tour-beats.js +336 -0
  399. package/neural-interface/public/shared/tour/tour-engine.js +884 -0
  400. package/neural-interface/public/shared/tour/tour-ink.js +390 -0
  401. package/neural-interface/public/shared/tour/tour-stage.js +440 -0
  402. package/neural-interface/public/shared/tour/tour-state.js +40 -0
  403. package/neural-interface/public/shared/tour/tour-tips.js +99 -0
  404. package/neural-interface/public/shared/tour/tour.css +144 -0
  405. package/neural-interface/public/shared/ui-automation-studio.js +91 -128
  406. package/neural-interface/public/shared/ui-claude-panel.js +77 -5
  407. package/neural-interface/public/shared/ui-command-runner.js +6 -3
  408. package/neural-interface/public/shared/ui-context-menu.js +295 -0
  409. package/neural-interface/public/shared/ui-cost-widget.js +57 -59
  410. package/neural-interface/public/shared/ui-crash-notice.js +187 -0
  411. package/neural-interface/public/shared/ui-detail.js +15 -3
  412. package/neural-interface/public/shared/ui-image-gallery.js +50 -47
  413. package/neural-interface/public/shared/ui-keybinds.js +26 -1
  414. package/neural-interface/public/shared/ui-menubar.js +8 -18
  415. package/neural-interface/public/shared/ui-native-loop-router-state.js +5 -0
  416. package/neural-interface/public/shared/ui-native-loop-router.js +7 -1
  417. package/neural-interface/public/shared/ui-navbar.js +4 -24
  418. package/neural-interface/public/shared/ui-panels.js +96 -65
  419. package/neural-interface/public/shared/ui-schedules-studio.js +507 -423
  420. package/neural-interface/public/shared/ui-sessions.js +5 -3
  421. package/neural-interface/public/shared/ui-settings.js +594 -462
  422. package/neural-interface/public/shared/ui-sidepanel-sessions.js +1 -1
  423. package/neural-interface/public/shared/ui-sidepanel-state.js +23 -12
  424. package/neural-interface/public/shared/ui-sidepanel-windows.js +16 -11
  425. package/neural-interface/public/shared/ui-skills.js +33 -2830
  426. package/neural-interface/public/shared/ui-styleguide.js +5 -2
  427. package/neural-interface/public/shared/ui-sync.js +15 -5
  428. package/neural-interface/public/shared/ui-terminal.js +124 -180
  429. package/neural-interface/public/shared/ui-tool-updates.js +3 -1
  430. package/neural-interface/public/shared/ui-tooltip.js +10 -5
  431. package/neural-interface/public/shared/ui-trash.js +6 -4
  432. package/neural-interface/public/shared/ui-tutorial-layout.js +3 -117
  433. package/neural-interface/public/shared/ui-tutorial-preview.js +103 -0
  434. package/neural-interface/public/shared/ui-tutorial-steps.js +3 -65
  435. package/neural-interface/public/shared/ui-tutorial.css +47 -100
  436. package/neural-interface/public/shared/ui-tutorial.js +285 -509
  437. package/neural-interface/public/shared/ui-update.js +38 -2
  438. package/neural-interface/public/shared/ui-whiteboard.js +311 -58
  439. package/neural-interface/public/shared/ui-worker-end.js +4 -0
  440. package/neural-interface/public/shared/ui-workspaces.js +3 -2
  441. package/neural-interface/public/shared/view-variant.js +66 -0
  442. package/neural-interface/public/shared/whatsapp/wa-view.js +1 -1
  443. package/neural-interface/public/shared/whiteboard-list.js +172 -0
  444. package/neural-interface/public/shared/worker-end.js +10 -3
  445. package/neural-interface/public/shared/worker-restart.js +12 -0
  446. package/neural-interface/public/sidepanel-session.html +1 -1
  447. package/neural-interface/public/variant/2d/background.js +2 -1
  448. package/neural-interface/public/variant/2d/context-menu.js +8 -2
  449. package/neural-interface/public/variant/2d/graph.js +42 -20
  450. package/neural-interface/public/variant/2d/hulls.js +14 -9
  451. package/neural-interface/public/variant/2d/lasso.js +11 -7
  452. package/neural-interface/public/variant/2d/main.js +32 -1
  453. package/neural-interface/public/variant/2d/minimap.js +11 -13
  454. package/neural-interface/public/variant/3d/main.js +69 -6
  455. package/neural-interface/public/variant/3d/map-controls.js +24 -9
  456. package/neural-interface/public/vendor/caveat/OFL.txt +93 -0
  457. package/neural-interface/public/vendor/caveat/caveat-latin-400-normal.woff2 +0 -0
  458. package/neural-interface/public/vendor/caveat/caveat-latin-700-normal.woff2 +0 -0
  459. package/neural-interface/public/vendor/caveat/caveat.css +17 -0
  460. package/neural-interface/public/vendor/caveat/manifest.json +12 -0
  461. package/neural-interface/public/vendor/yaml/LICENSE +13 -0
  462. package/neural-interface/public/vendor/yaml/manifest.json +4 -0
  463. package/neural-interface/public/vendor/yaml/yaml-2.9.1.min.js +137 -0
  464. package/neural-interface/scripts/build-vendor.mjs +32 -0
  465. package/neural-interface/server.js +3934 -2454
  466. package/neural-interface/templates/rulesets/core.md +1 -1
  467. package/neural-interface/templates/rulesets/legacy-hashes.json +18 -0
  468. package/neural-interface/templates/rulesets/manifest.json +8 -8
  469. package/npm-shrinkwrap.json +18 -12
  470. package/package.json +16 -3
  471. package/postinstall.js +9 -4
  472. package/preuninstall.js +1 -1
  473. package/setup.js +97 -322
  474. package/skills/skill-forge/SKILL.md +177 -0
  475. package/skills/skill-forge/evals/evals.json +54 -0
  476. package/skills/skill-forge/references/package.md +105 -0
  477. package/skills/skill-forge/references/review-and-recovery.md +63 -0
  478. package/skills/skill-forge/references/runtime-profiles.md +20 -0
  479. package/skills/skill-forge/references/sources-and-capabilities.md +51 -0
  480. package/skills/synabun/SKILL.md +10 -7
  481. package/skills/synabun/modules/audit.md +1 -5
  482. package/skills/synabun/modules/changelog.md +1 -5
  483. package/skills/synabun/modules/idea.md +1 -1
  484. package/skills/synabun/modules/memorize.md +6 -9
  485. package/skills/synabun/modules/schedule.md +4 -4
  486. package/mcp-server/dist/services/profiles.d.ts +0 -120
  487. package/mcp-server/dist/services/profiles.d.ts.map +0 -1
  488. package/mcp-server/dist/services/profiles.js +0 -387
  489. package/mcp-server/dist/services/profiles.js.map +0 -1
  490. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts +0 -97
  491. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts.map +0 -1
  492. package/mcp-server/dist/tools/leonardo-browser-tools.js +0 -228
  493. package/mcp-server/dist/tools/leonardo-browser-tools.js.map +0 -1
  494. package/mcp-server/dist/tools/leonardo.d.ts +0 -13
  495. package/mcp-server/dist/tools/leonardo.d.ts.map +0 -1
  496. package/mcp-server/dist/tools/leonardo.js +0 -21
  497. package/mcp-server/dist/tools/leonardo.js.map +0 -1
  498. package/mcp-server/dist/tools/profile.d.ts +0 -17
  499. package/mcp-server/dist/tools/profile.d.ts.map +0 -1
  500. package/mcp-server/dist/tools/profile.js +0 -114
  501. package/mcp-server/dist/tools/profile.js.map +0 -1
  502. package/mcp-server/src/services/profiles.ts +0 -428
  503. package/mcp-server/src/tools/leonardo-browser-tools.ts +0 -291
  504. package/mcp-server/src/tools/leonardo.ts +0 -30
  505. package/mcp-server/src/tools/profile.ts +0 -122
  506. package/neural-interface/lib/assistant-brains/opencode-browser-policy.js +0 -47
  507. package/neural-interface/lib/assistant-brains/opencode-route-gate.js +0 -62
  508. package/neural-interface/lib/mcp-profile-servers.js +0 -120
  509. package/neural-interface/public/shared/ui-tutorial-draw.js +0 -311
  510. package/skills/leonardo/SKILL.md +0 -168
  511. package/skills/leonardo/icon.svg +0 -1
  512. package/skills/leonardo/modules/browser-guide.md +0 -378
  513. package/skills/leonardo/modules/image-prompter.md +0 -283
  514. package/skills/leonardo/modules/model-advisor.md +0 -100
  515. package/skills/leonardo/modules/prompt-library.md +0 -110
  516. package/skills/leonardo/modules/style-guide.md +0 -186
  517. package/skills/leonardo/modules/video-prompter.md +0 -317
package/setup.js CHANGED
@@ -5,6 +5,10 @@
5
5
  *
6
6
  * Usage: node setup.js (or: npm start)
7
7
  *
8
+ * The commands (mcp, doctor, profile, migrate-data, restore-backup, version)
9
+ * are listed by `synabun help`; `synabun mcp` never gets here (bin/synabun.js
10
+ * starts the MCP server itself).
11
+ *
8
12
  * 1. Checks Node.js version (>=22)
9
13
  * 2. Ensures data directory exists (~/.synabun or %APPDATA%/synabun)
10
14
  * 3. Migrates data from old scaffolded installs if detected
@@ -17,8 +21,8 @@
17
21
  * 8. Auto-opens browser to onboarding wizard (or main page if setup complete)
18
22
  */
19
23
 
20
- import { execFileSync, spawn, exec } from 'node:child_process';
21
- import { existsSync, readFileSync, writeFileSync, cpSync, readdirSync, mkdirSync, unlinkSync, createWriteStream, statSync, renameSync } from 'node:fs';
24
+ import { execFileSync, exec } from 'node:child_process';
25
+ import { existsSync, readFileSync, writeFileSync, cpSync, readdirSync, mkdirSync } from 'node:fs';
22
26
  import { resolve, dirname, join } from 'node:path';
23
27
  import { fileURLToPath } from 'node:url';
24
28
  import { platform } from 'node:os';
@@ -52,9 +56,17 @@ import { packagedRuntime } from './lib/packaged-runtime.js';
52
56
  import {
53
57
  OPTIONAL_AT_ROOT, checkRuntimeDependencies, findInstalled, installAtPackageRoot, installKind, mcpCompiler,
54
58
  } from './lib/runtime-dependencies.js';
59
+ import { mcpDistBuilt } from './lib/mcp-dist.js';
60
+ import { superviseServer } from './lib/server-supervisor.js';
61
+ import { MCP_COMMAND, nodeArgs, runNode } from './bin/synabun.js';
55
62
 
56
63
  const __dirname = dirname(fileURLToPath(import.meta.url));
57
64
 
65
+ // The environment as this process got it, before the data home below is
66
+ // settled into it: `node setup.js mcp` hands the MCP server exactly what
67
+ // `node mcp-server/run.mjs` would get.
68
+ const LAUNCH_ENV = { ...process.env };
69
+
58
70
  // ── ANSI color helpers ──
59
71
 
60
72
  const c = {
@@ -388,9 +400,10 @@ function installPlaywrightChromium() {
388
400
 
389
401
  // ── Phase 4: MCP server build ──
390
402
 
403
+ // Built means dist/index.js and every module it imports (lib/mcp-dist.js): a checkout can hold a tracked
404
+ // dist/index.js whose newer imports git ignores.
391
405
  function needsBuild() {
392
- const distIndex = resolve(PACKAGE_ROOT, 'mcp-server', 'dist', 'index.js');
393
- return !existsSync(distIndex);
406
+ return !mcpDistBuilt(PACKAGE_ROOT);
394
407
  }
395
408
 
396
409
  function buildMcpServer() {
@@ -456,333 +469,81 @@ function openBrowser(url) {
456
469
  }
457
470
  }
458
471
 
459
- // Sentinel exit code for supervised restart. Server exits with this code via
460
- // /api/server/restart; the supervisor below respawns instead of giving up.
461
- // 75 = sysexits EX_TEMPFAIL — conventional "transient, retry" signal.
462
- const RESTART_EXIT_CODE = 75;
463
-
464
- // Marker file written by /api/server/restart before tearing down. If the
465
- // server crashes during shutdown (e.g. native module mutex error in sqlite/
466
- // playwright/node-pty), the exit code will not be 75 — but the marker tells
467
- // the supervisor the user asked for a restart, so we respawn anyway.
468
- const RESTART_MARKER = resolve(DATA_HOME, 'restart-requested');
469
-
472
+ // The server runs under lib/server-supervisor.js: started again when it asks
473
+ // for a restart (exit code 75, or the restart marker) and when it crashes after
474
+ // it was up (within the crash-loop guard, 5 starts in 60 s); after a crash the
475
+ // server it starts finds a record of it, and tells the user's pages once. A
476
+ // stop that was asked for (the stop marker, or the stop line on its stdout), a
477
+ // clean end and a start that failed end this process too. The server's stdout
478
+ // and stderr also go to DATA_HOME/data/server-stdout.log and server-stderr.log.
470
479
  function startServer() {
471
480
  const serverPath = resolve(PACKAGE_ROOT, 'neural-interface', 'server.js');
472
481
  const niDir = resolve(PACKAGE_ROOT, 'neural-interface');
473
482
  const setupComplete = isSetupComplete();
474
483
 
475
- // Clear any stale marker from a previous run so we do not respawn on a
476
- // clean exit from this child.
477
- try { if (existsSync(RESTART_MARKER)) unlinkSync(RESTART_MARKER); } catch {}
478
-
479
484
  info('Starting Neural Interface server...');
480
485
  console.log('');
481
486
 
482
- // Capture the server's stdout/stderr to log files so diagnostics survive
483
- // regardless of how the supervisor itself was launched (Apps dropdown, manual
484
- // `node setup.js`, or launchd). Previously logs only reached the launching
485
- // terminal — when started outside a terminal they were lost, leaving
486
- // data/server-*.log frozen at the last launchd run. Rotate at 50MB so capture
487
- // never grows unbounded.
488
- const LOG_DIR = resolve(DATA_HOME, 'data');
489
- const STDOUT_LOG = resolve(LOG_DIR, 'server-stdout.log');
490
- const STDERR_LOG = resolve(LOG_DIR, 'server-stderr.log');
491
- try { mkdirSync(LOG_DIR, { recursive: true }); } catch {}
492
- const rotateIfLarge = (p) => {
493
- try { if (existsSync(p) && statSync(p).size > 50 * 1024 * 1024) renameSync(p, p + '.1'); } catch {}
494
- };
495
- rotateIfLarge(STDOUT_LOG);
496
- rotateIfLarge(STDERR_LOG);
497
- let outLog = null, errLog = null;
498
- try { outLog = createWriteStream(STDOUT_LOG, { flags: 'a' }); } catch (e) { warn(`Could not open stdout log: ${e.message}`); }
499
- try { errLog = createWriteStream(STDERR_LOG, { flags: 'a' }); } catch (e) { warn(`Could not open stderr log: ${e.message}`); }
500
- // A full disk reports asynchronously from WriteStream.write(). Without an
501
- // error listener that event terminates the supervisor itself, even though
502
- // the child server's persistence paths already handle ENOSPC. Disable only
503
- // the affected capture stream and keep the server console/supervision alive.
504
- const disableLogStream = (kind, stream, error) => {
505
- if (kind === 'stdout' && outLog === stream) outLog = null;
506
- if (kind === 'stderr' && errLog === stream) errLog = null;
507
- warn(`Could not persist ${kind} server log: ${error.message} — continuing without file capture.`);
508
- try { stream.destroy(); } catch {}
509
- };
510
- const stdoutLog = outLog;
511
- const stderrLog = errLog;
512
- stdoutLog?.on('error', (error) => disableLogStream('stdout', stdoutLog, error));
513
- stderrLog?.on('error', (error) => disableLogStream('stderr', stderrLog, error));
514
- const stamp = `\n===== supervisor start ${new Date().toISOString()} (pid ${process.pid}) =====\n`;
515
- try { outLog?.write(stamp); errLog?.write(stamp); } catch {}
516
-
517
- let firstLaunch = true;
518
- let currentChild = null;
519
- let shuttingDown = false;
520
- // The port the server last said it listens on: where a restart's report is read.
521
- let listenPort = null;
522
- const restartLog = [];
523
- const CRASH_WINDOW_MS = 60_000;
524
- const CRASH_LIMIT = 5;
525
-
526
- // A restart that ends without a server keeps saying why until the page that
527
- // waits for it has read it (a moment; 20 s at the most when nobody reads).
528
- const exitAfterReport = (code, error) => {
529
- const report = restartReport;
530
- if (!report?.open) { process.exit(code); return; }
531
- report.failed(error).finally(() => process.exit(code));
532
- };
533
-
534
- function spawnOnce() {
535
- const child = spawn(process.execPath, ['--disable-warning=ExperimentalWarning', '--max-old-space-size=6144', serverPath], {
536
- cwd: niDir,
537
- stdio: ['ignore', 'pipe', 'pipe'],
538
- windowsHide: !!packagedRuntime(),
539
- env: {
540
- ...process.env,
541
- SYNABUN_DATA_HOME: DATA_HOME,
542
- MEMORY_DATA_DIR: resolve(DATA_HOME, 'mcp-data'),
543
- SYNABUN_SUPERVISED: '1',
544
- },
545
- });
546
- currentChild = child;
547
- startPhase('server', { pid: child.pid });
548
- child.on('error', (error) => {
549
- fail(`Could not start the server: ${error.message}`);
550
- startFailed('SERVER_SPAWN_FAILED', `the server could not be started: ${error.message}`);
551
- exitAfterReport(1, { code: 'SERVER_SPAWN_FAILED', message: `the server could not be started: ${error.message}` });
552
- });
553
-
554
- let opened = !firstLaunch;
555
- let announced = false;
556
- child.stdout.on('data', (data) => {
557
- const s = data.toString();
558
- process.stdout.write(s);
559
- try { outLog?.write(s); } catch {}
560
- // The server prints its address from its listen callback: it is up.
561
- if (!announced && s.includes('Server:')) {
562
- announced = true;
563
- const port = Number(s.match(/Server:\s+http:\/\/localhost:(\d+)/)?.[1]) || undefined;
564
- if (port) listenPort = port;
565
- startPhase('listening', { port });
566
- }
567
- if (!opened && s.includes('Server:')) {
568
- opened = true;
569
- const port = s.match(/Server:\s+http:\/\/localhost:(\d+)/)?.[1] || '3344';
570
- const url = `http://localhost:${port}${setupComplete ? '/' : '/onboarding.html'}`;
571
- // The Start Server button already has a tab waiting for the server.
572
- if (process.env.SYNABUN_OPEN_BROWSER !== '0') setTimeout(() => openBrowser(url), 1500);
573
- }
574
- });
575
- child.stderr.on('data', (data) => {
576
- const s = data.toString();
577
- process.stderr.write(s);
578
- try { errLog?.write(s); } catch {}
579
- });
580
-
581
- child.on('exit', (code) => {
582
- currentChild = null;
583
- if (shuttingDown) return;
584
-
585
- // Treat a present marker file the same as exit code 75. Native module
586
- // crashes during shutdown can clobber the exit code; the marker keeps
587
- // restart reliable in that case.
588
- let restartRequested = code === RESTART_EXIT_CODE;
589
- if (!restartRequested && existsSync(RESTART_MARKER)) {
590
- restartRequested = true;
591
- info(`Server exited with code ${code} but restart marker present — respawning.`);
592
- }
593
- try { if (existsSync(RESTART_MARKER)) unlinkSync(RESTART_MARKER); } catch {}
594
-
595
- if (restartRequested) {
596
- if (code === RESTART_EXIT_CODE) info('Server requested restart — respawning...');
597
- const now = Date.now();
598
- restartLog.push(now);
599
- while (restartLog.length && now - restartLog[0] > CRASH_WINDOW_MS) restartLog.shift();
600
- // The page that asked for this has no server to ask now: from here
601
- // until the new one is listening, this supervisor says what happens.
487
+ const supervision = superviseServer({
488
+ serverPath,
489
+ cwd: niDir,
490
+ dataHome: DATA_HOME,
491
+ windowsHide: !!packagedRuntime(),
492
+ print: { info, warn, fail },
493
+ onPhase: startPhase,
494
+ onFailed: startFailed,
495
+ onListening: ({ port, first }) => {
496
+ // Only the first start opens a page: a server started again finds its pages open, and they reconnect.
497
+ if (!first) return;
498
+ const url = `http://localhost:${port || 3344}${setupComplete ? '/' : '/onboarding.html'}`;
499
+ // The Start Server button already has a tab waiting for the server.
500
+ if (process.env.SYNABUN_OPEN_BROWSER !== '0') setTimeout(() => openBrowser(url), 1500);
501
+ },
502
+ // A page that waits for the server while it is away has no server to ask: from the moment it exited to be
503
+ // started again until the new one is listening, this supervisor says what happens on the start beacon
504
+ // (lib/start-launcher.js openRestartReport). A supervisor that ends without a server says why there first.
505
+ reports: {
506
+ reopen(port) {
602
507
  try { restartReport?.close(); } catch {}
603
- restartReport = openRestartReport({ port: listenPort || resolvePort({ dataHome: DATA_HOME }), dataHome: DATA_HOME, exited: true });
604
- if (restartLog.length > CRASH_LIMIT) {
605
- const message = `the server restarted ${restartLog.length} times in ${Math.round(CRASH_WINDOW_MS / 1000)} s`;
606
- fail(`Server restarted ${restartLog.length} times in ${Math.round(CRASH_WINDOW_MS / 1000)}s — aborting supervisor.`);
607
- startFailed('RESTART_LOOP', message);
608
- exitAfterReport(1, { code: 'RESTART_LOOP', message });
609
- return;
610
- }
611
- firstLaunch = false;
612
- setTimeout(spawnOnce, 250);
613
- return;
614
- }
615
-
616
- if (code !== 0 && code !== null) {
617
- fail(`Server exited with code ${code}`);
618
- startFailed('SERVER_EXITED', `the server exited with code ${code}`, { exitCode: code });
619
- exitAfterReport(code, { code: 'SERVER_EXITED', message: `the server exited with code ${code}`, exitCode: code });
620
- return;
621
- }
622
- process.exit(0);
623
- });
624
- }
625
-
626
- spawnOnce();
627
-
628
- const stop = (sig) => {
629
- shuttingDown = true;
630
- if (currentChild) {
631
- try { currentChild.kill(sig); } catch {}
632
- }
633
- process.exit(0);
634
- };
635
- process.on('SIGINT', () => stop('SIGINT'));
636
- process.on('SIGTERM', () => stop('SIGTERM'));
637
- }
638
-
639
- // ── CLI: profile subcommand ──
640
-
641
- const TOOL_GROUPS = {
642
- memory: { label: 'Memory', tools: 6, alwaysOn: true },
643
- category: { label: 'Categories', tools: 1, alwaysOn: true },
644
- sync: { label: 'Sync', tools: 1, alwaysOn: true },
645
- loop: { label: 'Loop', tools: 1, alwaysOn: true },
646
- profile: { label: 'Profile', tools: 1, alwaysOn: true },
647
- git: { label: 'Git', tools: 1 },
648
- image: { label: 'Images', tools: 1 },
649
- whiteboard: { label: 'Whiteboard', tools: 5 },
650
- card: { label: 'Cards', tools: 5 },
651
- tictactoe: { label: 'TicTacToe', tools: 1 },
652
- browser: { label: 'Browser', tools: 18 },
653
- browser_twitter: { label: 'Twitter/X', tools: 1 },
654
- browser_facebook: { label: 'Facebook', tools: 1 },
655
- browser_tiktok: { label: 'TikTok', tools: 4 },
656
- browser_whatsapp: { label: 'WhatsApp', tools: 2 },
657
- browser_instagram: { label: 'Instagram', tools: 5 },
658
- browser_linkedin: { label: 'LinkedIn', tools: 8 },
659
- leonardo: { label: 'Leonardo', tools: 5 },
660
- discord: { label: 'Discord', tools: 8 },
661
- gsc: { label: 'Google Search Console', tools: 30 },
662
- };
663
-
664
- function readRegistry(dataHome) {
665
- const registryPath = resolve(dataHome, 'data', 'mcp-registry.json');
666
- try {
667
- if (existsSync(registryPath)) return JSON.parse(readFileSync(registryPath, 'utf-8'));
668
- } catch {}
669
- return null;
670
- }
671
-
672
- function getProfiles(dataHome) {
673
- const registry = readRegistry(dataHome);
674
- if (registry?.profiles) return registry.profiles;
675
- // Fallback defaults
676
- return {
677
- core: { label: 'Core', groups: ['git', 'image'] },
678
- standard: { label: 'Standard', groups: ['git', 'image', 'whiteboard', 'card', 'tictactoe'] },
679
- twitter: { label: 'Twitter/X', groups: ['git', 'image', 'browser', 'browser_twitter'] },
680
- facebook: { label: 'Facebook', groups: ['git', 'image', 'browser', 'browser_facebook'] },
681
- tiktok: { label: 'TikTok', groups: ['git', 'image', 'browser', 'browser_tiktok'] },
682
- whatsapp: { label: 'WhatsApp', groups: ['git', 'image', 'browser', 'browser_whatsapp'] },
683
- instagram: { label: 'Instagram', groups: ['git', 'image', 'browser', 'browser_instagram'] },
684
- linkedin: { label: 'LinkedIn', groups: ['git', 'image', 'browser', 'browser_linkedin'] },
685
- discord: { label: 'Discord', groups: ['git', 'image', 'discord'] },
686
- browser: { label: 'Browser', groups: ['git', 'image', 'whiteboard', 'card', 'tictactoe', 'browser', 'browser_twitter', 'browser_facebook', 'browser_tiktok', 'browser_whatsapp', 'browser_instagram', 'browser_linkedin', 'leonardo', 'gsc'] },
687
- full: { label: 'Full', groups: ['git', 'image', 'whiteboard', 'card', 'tictactoe', 'browser', 'browser_twitter', 'browser_facebook', 'browser_tiktok', 'browser_whatsapp', 'browser_instagram', 'browser_linkedin', 'leonardo', 'discord', 'gsc'] },
688
- leonardoai: { label: 'LeonardoAI', groups: ['leonardo'] },
689
- gsc: { label: 'GSC', groups: ['git', 'image', 'browser', 'gsc'] },
690
- };
691
- }
692
-
693
- function countProfileTools(groups) {
694
- const alwaysOn = Object.values(TOOL_GROUPS).filter(g => g.alwaysOn).reduce((s, g) => s + g.tools, 0);
695
- const groupTools = (groups || []).reduce((s, g) => s + (TOOL_GROUPS[g]?.tools || 0), 0);
696
- return alwaysOn + groupTools;
697
- }
698
-
699
- function getCurrentProfile(dataHome) {
700
- const profilePath = resolve(dataHome, 'data', 'active-profile.json');
701
- try {
702
- if (existsSync(profilePath)) {
703
- const data = JSON.parse(readFileSync(profilePath, 'utf-8'));
704
- if (data.profile) return data.profile;
705
- }
706
- } catch {}
707
- return 'full';
708
- }
709
-
710
- function writeProfile(dataHome, profileName) {
711
- const payload = JSON.stringify({ profile: profileName }, null, 2) + '\n';
712
-
713
- // Write to data/active-profile.json (Neural Interface reads this)
714
- const niPath = resolve(dataHome, 'data', 'active-profile.json');
715
- const niDir = resolve(niPath, '..');
716
- if (!existsSync(niDir)) mkdirSync(niDir, { recursive: true });
717
- writeFileSync(niPath, payload, 'utf-8');
718
-
719
- // Write to mcp-data/active-profile.json (MCP server watches this)
720
- const mcpPath = resolve(dataHome, 'mcp-data', 'active-profile.json');
721
- const mcpDir = resolve(mcpPath, '..');
722
- if (!existsSync(mcpDir)) mkdirSync(mcpDir, { recursive: true });
723
- writeFileSync(mcpPath, payload, 'utf-8');
508
+ restartReport = openRestartReport({ port, dataHome: DATA_HOME, exited: true });
509
+ },
510
+ async failed(error) {
511
+ const report = restartReport;
512
+ if (report?.open) await report.failed(error);
513
+ },
514
+ },
515
+ resolvePort: () => resolvePort({ dataHome: DATA_HOME }),
516
+ });
517
+ process.on('SIGINT', () => supervision.stop('SIGINT'));
518
+ process.on('SIGTERM', () => supervision.stop('SIGTERM'));
724
519
  }
725
520
 
726
- function handleProfileCommand(dataHome) {
727
- const sub = process.argv[3];
728
- const profiles = getProfiles(dataHome);
729
- const current = getCurrentProfile(dataHome);
730
-
731
- // synabun profile OR synabun profile list
732
- if (!sub || sub === 'list') {
733
- console.log('');
734
- console.log(` ${c.bold}Available MCP Profiles${c.reset}`);
735
- console.log('');
736
- for (const [name, prof] of Object.entries(profiles)) {
737
- const label = prof.label || name;
738
- const tools = countProfileTools(prof.groups);
739
- const active = name === current ? ` ${c.green}← active${c.reset}` : '';
740
- const groups = (prof.groups || []).join(', ');
741
- console.log(` ${c.cyan}${name.padEnd(14)}${c.reset} ${c.dim}${label.padEnd(12)}${c.reset} ~${String(tools).padStart(2)} tools ${c.dim}[${groups}]${c.reset}${active}`);
742
- }
743
- console.log('');
744
- console.log(` ${c.dim}Usage: synabun profile set <name>${c.reset}`);
745
- console.log('');
746
- return;
747
- }
748
-
749
- // synabun profile get
750
- if (sub === 'get') {
751
- const prof = profiles[current];
752
- const tools = prof ? countProfileTools(prof.groups) : '?';
753
- console.log('');
754
- console.log(` ${c.bold}Current Profile:${c.reset} ${c.cyan}${current}${c.reset} (~${tools} tools)`);
755
- if (prof?.groups) console.log(` ${c.dim}Groups: ${prof.groups.join(', ')}${c.reset}`);
756
- console.log('');
757
- return;
758
- }
759
-
760
- // synabun profile set <name>
761
- if (sub === 'set') {
762
- const name = process.argv[4]?.toLowerCase().trim();
763
- if (!name) {
764
- fail('Missing profile name. Usage: synabun profile set <name>');
765
- console.log(` ${c.dim}Run "synabun profile list" to see available profiles.${c.reset}`);
766
- process.exit(1);
767
- }
768
- if (!profiles[name]) {
769
- fail(`Unknown profile "${name}"`);
770
- console.log('');
771
- console.log(` ${c.dim}Available profiles:${c.reset} ${Object.keys(profiles).join(', ')}`);
772
- process.exit(1);
773
- }
774
- writeProfile(dataHome, name);
775
- const prof = profiles[name];
776
- const tools = countProfileTools(prof.groups);
777
- ok(`Profile set to ${c.cyan}${name}${c.reset} (${prof.label}, ~${tools} tools)`);
778
- console.log(` ${c.dim}Groups: ${prof.groups.join(', ')}${c.reset}`);
779
- console.log('');
780
- console.log(` ${c.dim}Running MCP servers will pick up the change automatically.${c.reset}`);
781
- return;
782
- }
783
-
784
- fail(`Unknown subcommand "${sub}". Usage: synabun profile [list|get|set <name>]`);
785
- process.exit(1);
521
+ // ── synabun help ──
522
+
523
+ function usage(version) {
524
+ return [
525
+ '',
526
+ ` ${c.bold}SynaBun v${version}${c.reset}: persistent memory for AI coding tools`,
527
+ '',
528
+ ' synabun start SynaBun: the Neural Interface on port 3344 (or NEURAL_PORT),',
529
+ ' with the setup wizard on the first start',
530
+ ' synabun mcp the MCP server on stdio, for an AI tool\'s MCP config:',
531
+ ' "command": "synabun", "args": ["mcp"]',
532
+ ' stdout carries the protocol only; logs go to stderr',
533
+ ' synabun doctor [--json] the state of your data and your tool connections',
534
+ ' synabun tools [list | get | set <ids>]',
535
+ ' SynaBun groups and default tools for future runtimes',
536
+ ' synabun migrate-data [--apply | --choose external|legacy]',
537
+ ' copy an older install\'s data into the data folder (a dry run without --apply)',
538
+ ' synabun restore-backup --from <backup.zip> [--apply]',
539
+ ' check a backup; --apply restores it',
540
+ ' synabun version the installed version',
541
+ ' synabun help this list',
542
+ '',
543
+ ` Data folder: ${DATA_HOME} (SYNABUN_DATA_HOME sets another)`,
544
+ ' Docs: https://synabun.ai/docs',
545
+ '',
546
+ ].join('\n');
786
547
  }
787
548
 
788
549
  // ── Main ──
@@ -792,10 +553,24 @@ async function main() {
792
553
 
793
554
  // ── Subcommand routing (before setup flow) ──
794
555
  const cmd = process.argv[2];
795
- if (cmd === 'profile') {
796
- handleProfileCommand(DATA_HOME);
556
+ if (cmd === MCP_COMMAND) {
557
+ // `synabun mcp` is started by bin/synabun.js without this file; this is
558
+ // `node setup.js mcp`, which must not print the banner on stdout either.
559
+ runNode(nodeArgs(process.argv.slice(2)), { env: LAUNCH_ENV, forwardSignals: true });
560
+ return;
561
+ }
562
+ if (cmd === 'help' || cmd === '--help' || cmd === '-h') {
563
+ console.log(usage(version));
797
564
  process.exit(0);
798
565
  }
566
+ if (cmd === 'profile') {
567
+ console.error('synabun profile was removed; use synabun tools [list | get | set <ids>].');
568
+ process.exit(1);
569
+ }
570
+ if (cmd === 'tools') {
571
+ const { runToolsCommand } = await import('./lib/tools-cli.js');
572
+ process.exit(runToolsCommand(process.argv.slice(3), { dataHome: DATA_HOME }));
573
+ }
799
574
  if (cmd === 'migrate-data') {
800
575
  handleMigrateDataCommand();
801
576
  process.exit(0);