synabun 2.0.0-beta → 2.0.5

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 (374) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/NOTICE +5 -0
  3. package/README.md +1 -1
  4. package/THIRD-PARTY-LICENSES.md +51 -0
  5. package/benchmarks/fixtures/browser/README.md +1 -1
  6. package/benchmarks/fixtures/desktop/README.md +1 -1
  7. package/docs/whatsapp.md +2 -2
  8. package/hooks/claude-code/pre-compact.mjs +11 -0
  9. package/hooks/claude-code/prompt-submit.mjs +60 -184
  10. package/hooks/claude-code/session-start.mjs +73 -16
  11. package/hooks/claude-code/shared.mjs +20 -0
  12. package/hooks/claude-code/stop.mjs +5 -5
  13. package/launcher.mjs +40 -0
  14. package/lib/claude-hooks.js +61 -8
  15. package/lib/client-config-repair.js +4 -3
  16. package/lib/data-home-migration.js +4 -0
  17. package/lib/desktop-pwa.js +206 -0
  18. package/lib/external-tools.js +221 -0
  19. package/lib/first-launch-protection.js +5 -0
  20. package/lib/packaged-runtime.js +110 -0
  21. package/lib/start-launcher.js +1396 -0
  22. package/mcp-server/package-lock.json +2 -2
  23. package/mcp-server/package.json +1 -3
  24. package/neural-interface/i18n/en.json +1540 -154
  25. package/neural-interface/i18n/pt-BR.json +1538 -153
  26. package/neural-interface/lib/assistant-api.js +62 -6
  27. package/neural-interface/lib/assistant-brains/claude.js +4 -0
  28. package/neural-interface/lib/assistant-catalog.js +179 -27
  29. package/neural-interface/lib/assistant-config.js +31 -2
  30. package/neural-interface/lib/assistant-dispatch.js +62 -13
  31. package/neural-interface/lib/assistant-envelope.js +9 -6
  32. package/neural-interface/lib/assistant-hidden-models.js +393 -66
  33. package/neural-interface/lib/assistant-memory.js +24 -10
  34. package/neural-interface/lib/assistant-persona.js +6 -2
  35. package/neural-interface/lib/assistant-pricing.js +21 -6
  36. package/neural-interface/lib/assistant-runtime.js +181 -12
  37. package/neural-interface/lib/assistant-task-prompt.js +13 -3
  38. package/neural-interface/lib/assistant-test-density.js +142 -0
  39. package/neural-interface/lib/assistant-user-context-budgets.js +123 -0
  40. package/neural-interface/lib/assistant-user-context.js +908 -0
  41. package/neural-interface/lib/assistant-user-knowledge.js +328 -0
  42. package/neural-interface/lib/assistant-user-learn.js +404 -0
  43. package/neural-interface/lib/assistant-user-threads.js +226 -0
  44. package/neural-interface/lib/assistant-user-writer.js +181 -0
  45. package/neural-interface/lib/augmented-path.js +23 -3
  46. package/neural-interface/lib/browser-background-tab.js +134 -0
  47. package/neural-interface/lib/browser-language.js +83 -0
  48. package/neural-interface/lib/browser-screenshot.js +678 -61
  49. package/neural-interface/lib/claude-agent-bridge.js +87 -153
  50. package/neural-interface/lib/claude-executable.js +241 -0
  51. package/neural-interface/lib/claude-model-catalog.js +82 -93
  52. package/neural-interface/lib/claude-temporary.js +46 -7
  53. package/neural-interface/lib/cloudflared/install.js +533 -0
  54. package/neural-interface/lib/cloudflared/manager.js +545 -0
  55. package/neural-interface/lib/cloudflared/pins.js +115 -0
  56. package/neural-interface/lib/cloudflared/pins.json +63 -0
  57. package/neural-interface/lib/cloudflared/tunnel.js +265 -0
  58. package/neural-interface/lib/editor-completion-endpoint.js +264 -0
  59. package/neural-interface/lib/editor-completion-opencode.js +436 -0
  60. package/neural-interface/lib/editor-completion.js +714 -0
  61. package/neural-interface/lib/editor-config.js +149 -0
  62. package/neural-interface/lib/editor-files-api.js +268 -0
  63. package/neural-interface/lib/editor-git-api.js +134 -0
  64. package/neural-interface/lib/file-explorer-api.js +1039 -0
  65. package/neural-interface/lib/file-explorer-system.js +355 -0
  66. package/neural-interface/lib/file-explorer-trash.ps1 +85 -0
  67. package/neural-interface/lib/file-explorer-watch.js +239 -0
  68. package/neural-interface/lib/git-diff-api.js +103 -0
  69. package/neural-interface/lib/git-read.js +202 -0
  70. package/neural-interface/lib/greeting/api.js +89 -0
  71. package/neural-interface/lib/greeting/budgets.js +90 -0
  72. package/neural-interface/lib/greeting/engine.js +461 -0
  73. package/neural-interface/lib/greeting/facts.js +320 -0
  74. package/neural-interface/lib/greeting/sources.js +252 -0
  75. package/neural-interface/lib/greeting/writer.js +139 -0
  76. package/neural-interface/lib/http-guards.js +189 -13
  77. package/neural-interface/lib/machine-names.js +88 -0
  78. package/neural-interface/lib/memory-api.js +31 -7
  79. package/neural-interface/lib/native-binary-runtime.js +69 -337
  80. package/neural-interface/lib/native-loop-providers.js +40 -49
  81. package/neural-interface/lib/offline-page.js +54 -0
  82. package/neural-interface/lib/plugin-installer.js +4 -2
  83. package/neural-interface/lib/project-storage.js +5 -7
  84. package/neural-interface/lib/request-gate.js +589 -0
  85. package/neural-interface/lib/session-title-generator.js +5 -0
  86. package/neural-interface/lib/synabun-update-plan.js +19 -0
  87. package/neural-interface/lib/ui-blob-api.js +108 -0
  88. package/neural-interface/lib/ui-blob-store.js +68 -0
  89. package/neural-interface/package-lock.json +701 -253
  90. package/neural-interface/package.json +13 -2
  91. package/neural-interface/public/install-app.html +34 -0
  92. package/neural-interface/public/manifest.json +2 -0
  93. package/neural-interface/public/offline.html +402 -66
  94. package/neural-interface/public/onboarding.html +264 -147
  95. package/neural-interface/public/shared/agent-runtime-options.js +22 -6
  96. package/neural-interface/public/shared/assistant/asst-automation.js +286 -0
  97. package/neural-interface/public/shared/assistant/asst-brain-picker.js +312 -62
  98. package/neural-interface/public/shared/assistant/asst-composer.js +11 -1
  99. package/neural-interface/public/shared/assistant/asst-mascot.js +26 -64
  100. package/neural-interface/public/shared/assistant/asst-menu.js +12 -8
  101. package/neural-interface/public/shared/assistant/asst-panel.js +150 -28
  102. package/neural-interface/public/shared/assistant/asst-rack-styles.js +0 -3
  103. package/neural-interface/public/shared/assistant/asst-render.js +219 -67
  104. package/neural-interface/public/shared/assistant/asst-route-models.js +108 -0
  105. package/neural-interface/public/shared/assistant/asst-route.js +23 -329
  106. package/neural-interface/public/shared/assistant/asst-routes-editor.js +495 -0
  107. package/neural-interface/public/shared/assistant/asst-sanitize.js +8 -1
  108. package/neural-interface/public/shared/assistant/asst-sidepanel.js +31 -9
  109. package/neural-interface/public/shared/assistant/asst-state.js +185 -1
  110. package/neural-interface/public/shared/assistant/asst-styles.js +162 -6
  111. package/neural-interface/public/shared/blob-store.js +111 -22
  112. package/neural-interface/public/shared/cdx/cdx-panel.js +32 -11
  113. package/neural-interface/public/shared/cdx/cdx-render.js +25 -89
  114. package/neural-interface/public/shared/cdx/cdx-styles.js +36 -0
  115. package/neural-interface/public/shared/cdx/cdx-tabs.js +87 -4
  116. package/neural-interface/public/shared/command-runner-model.js +30 -0
  117. package/neural-interface/public/shared/constants.js +6 -1
  118. package/neural-interface/public/shared/cp/cp-rehydrate.js +2 -1
  119. package/neural-interface/public/shared/cp/cp-styles.js +15 -0
  120. package/neural-interface/public/shared/editor/editor-ai-logic.js +409 -0
  121. package/neural-interface/public/shared/editor/editor-ai.js +619 -0
  122. package/neural-interface/public/shared/editor/editor-commands.js +212 -0
  123. package/neural-interface/public/shared/editor/editor-compare.js +103 -0
  124. package/neural-interface/public/shared/editor/editor-completion-list.js +172 -0
  125. package/neural-interface/public/shared/editor/editor-doc.js +257 -0
  126. package/neural-interface/public/shared/editor/editor-git-logic.js +131 -0
  127. package/neural-interface/public/shared/editor/editor-git.js +95 -0
  128. package/neural-interface/public/shared/editor/editor-languages.js +156 -0
  129. package/neural-interface/public/shared/editor/editor-lint.js +229 -0
  130. package/neural-interface/public/shared/editor/editor-loader.js +51 -0
  131. package/neural-interface/public/shared/editor/editor-markdown.js +90 -0
  132. package/neural-interface/public/shared/editor/editor-menu.js +233 -0
  133. package/neural-interface/public/shared/editor/editor-minimap.js +371 -0
  134. package/neural-interface/public/shared/editor/editor-palette-logic.js +192 -0
  135. package/neural-interface/public/shared/editor/editor-palette.js +125 -0
  136. package/neural-interface/public/shared/editor/editor-panel-logic.js +288 -0
  137. package/neural-interface/public/shared/editor/editor-panel.js +2099 -0
  138. package/neural-interface/public/shared/editor/editor-prefs.js +224 -0
  139. package/neural-interface/public/shared/editor/editor-safety.js +500 -0
  140. package/neural-interface/public/shared/editor/editor-search.js +352 -0
  141. package/neural-interface/public/shared/editor/editor-statusbar.js +144 -0
  142. package/neural-interface/public/shared/editor/editor-tabs-logic.js +331 -0
  143. package/neural-interface/public/shared/editor/editor-tabs.js +233 -0
  144. package/neural-interface/public/shared/editor/editor-theme.js +244 -0
  145. package/neural-interface/public/shared/editor/editor-view.js +332 -0
  146. package/neural-interface/public/shared/explorer/fx-api.js +216 -0
  147. package/neural-interface/public/shared/explorer/fx-links.js +204 -0
  148. package/neural-interface/public/shared/explorer/fx-logic.js +537 -0
  149. package/neural-interface/public/shared/explorer/fx-main.js +865 -0
  150. package/neural-interface/public/shared/explorer/fx-names.js +87 -0
  151. package/neural-interface/public/shared/explorer/fx-ops.js +370 -0
  152. package/neural-interface/public/shared/explorer/fx-popups.js +490 -0
  153. package/neural-interface/public/shared/explorer/fx-tree.js +790 -0
  154. package/neural-interface/public/shared/file-links.js +339 -0
  155. package/neural-interface/public/shared/greeting/greeting-card.js +178 -0
  156. package/neural-interface/public/shared/greeting/greeting-view.js +148 -0
  157. package/neural-interface/public/shared/html-shell.js +169 -170
  158. package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +4 -0
  159. package/neural-interface/public/shared/ocp-v2/ocp-v2-greeting.js +47 -0
  160. package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +99 -17
  161. package/neural-interface/public/shared/ocp-v2/ocp-v2-render.js +7 -1
  162. package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +5 -0
  163. package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +40 -0
  164. package/neural-interface/public/shared/ocp-v2/ocp-v2-ws.js +3 -2
  165. package/neural-interface/public/shared/pwa-install-page.js +62 -0
  166. package/neural-interface/public/shared/pwa-install.css +12 -0
  167. package/neural-interface/public/shared/pwa-install.js +127 -0
  168. package/neural-interface/public/shared/settings/settings-code-editor-pane.js +412 -0
  169. package/neural-interface/public/shared/settings/settings-code-editor.js +328 -0
  170. package/neural-interface/public/shared/settings/settings-greeting.js +133 -0
  171. package/neural-interface/public/shared/settings/settings-ia.js +18 -4
  172. package/neural-interface/public/shared/settings/settings-rules.js +160 -0
  173. package/neural-interface/public/shared/settings/settings-user-context.js +154 -0
  174. package/neural-interface/public/shared/start-bridge.js +802 -0
  175. package/neural-interface/public/shared/styleguide/sg-colors.js +5 -2
  176. package/neural-interface/public/shared/styleguide/sg-import-export.js +4 -3
  177. package/neural-interface/public/shared/styleguide/sg-kit.js +4 -1
  178. package/neural-interface/public/shared/styleguide/sg-panel.js +9 -1
  179. package/neural-interface/public/shared/styleguide/sg-typography.js +1 -0
  180. package/neural-interface/public/shared/styles.css +2219 -1117
  181. package/neural-interface/public/shared/synabun-mascot.js +20 -56
  182. package/neural-interface/public/shared/term-ready.js +307 -0
  183. package/neural-interface/public/shared/tunnel-view.js +167 -0
  184. package/neural-interface/public/shared/ui-claude-panel.js +160 -19
  185. package/neural-interface/public/shared/ui-command-runner.js +251 -468
  186. package/neural-interface/public/shared/ui-detail.js +15 -0
  187. package/neural-interface/public/shared/ui-explorer.js +22 -0
  188. package/neural-interface/public/shared/ui-file-explorer.js +481 -2496
  189. package/neural-interface/public/shared/ui-file-links.js +103 -0
  190. package/neural-interface/public/shared/ui-help.js +26 -0
  191. package/neural-interface/public/shared/ui-invite.js +126 -116
  192. package/neural-interface/public/shared/ui-judgments.js +1 -1
  193. package/neural-interface/public/shared/ui-keybinds.js +4 -0
  194. package/neural-interface/public/shared/ui-loading.js +367 -12
  195. package/neural-interface/public/shared/ui-menubar.js +21 -55
  196. package/neural-interface/public/shared/ui-native-loop-router-state.js +11 -0
  197. package/neural-interface/public/shared/ui-native-loop-router.js +15 -2
  198. package/neural-interface/public/shared/ui-navbar.js +45 -21
  199. package/neural-interface/public/shared/ui-settings.js +491 -547
  200. package/neural-interface/public/shared/ui-sidepanel-runtime.js +2 -1
  201. package/neural-interface/public/shared/ui-sync.js +16 -0
  202. package/neural-interface/public/shared/ui-terminal.js +153 -149
  203. package/neural-interface/public/shared/ui-tunnel.js +130 -0
  204. package/neural-interface/public/shared/ui-tutorial-steps.js +6 -2
  205. package/neural-interface/public/shared/ui-whiteboard.js +12 -0
  206. package/neural-interface/public/shared/ui-worker-end.js +245 -0
  207. package/neural-interface/public/shared/ui-workspaces.js +41 -27
  208. package/neural-interface/public/shared/worker-end.js +251 -0
  209. package/neural-interface/public/sw.js +3 -1
  210. package/neural-interface/public/variant/2d/main.js +2 -1
  211. package/neural-interface/public/variant/3d/main.js +2 -1
  212. package/neural-interface/public/vendor/codemirror/chunks/apl-CSDKT72Z.js +1 -0
  213. package/neural-interface/public/vendor/codemirror/chunks/asciiarmor-JYYPU5BM.js +1 -0
  214. package/neural-interface/public/vendor/codemirror/chunks/asn1-NRWCZDA6.js +1 -0
  215. package/neural-interface/public/vendor/codemirror/chunks/asterisk-5OU6D4ZQ.js +1 -0
  216. package/neural-interface/public/vendor/codemirror/chunks/brainfuck-ID4N4SYC.js +1 -0
  217. package/neural-interface/public/vendor/codemirror/chunks/chunk-4RZWGCS2.js +1 -0
  218. package/neural-interface/public/vendor/codemirror/chunks/chunk-ACTJM3JR.js +11 -0
  219. package/neural-interface/public/vendor/codemirror/chunks/chunk-S6BMAXLK.js +1 -0
  220. package/neural-interface/public/vendor/codemirror/chunks/chunk-TO2RDOHQ.js +3 -0
  221. package/neural-interface/public/vendor/codemirror/chunks/chunk-US2GMZZQ.js +13 -0
  222. package/neural-interface/public/vendor/codemirror/chunks/chunk-WYYO5ZAJ.js +1 -0
  223. package/neural-interface/public/vendor/codemirror/chunks/chunk-XALZTDJC.js +1 -0
  224. package/neural-interface/public/vendor/codemirror/chunks/chunk-YRNUTRDV.js +1 -0
  225. package/neural-interface/public/vendor/codemirror/chunks/chunk-Z3QOKH62.js +1 -0
  226. package/neural-interface/public/vendor/codemirror/chunks/clike-OWQBSOGL.js +1 -0
  227. package/neural-interface/public/vendor/codemirror/chunks/clojure-KV75UQWC.js +1 -0
  228. package/neural-interface/public/vendor/codemirror/chunks/cmake-GTEP5Y3C.js +1 -0
  229. package/neural-interface/public/vendor/codemirror/chunks/cobol-WCZ7QEGJ.js +1 -0
  230. package/neural-interface/public/vendor/codemirror/chunks/coffeescript-TGLBOT6B.js +1 -0
  231. package/neural-interface/public/vendor/codemirror/chunks/commonlisp-WVVI432V.js +1 -0
  232. package/neural-interface/public/vendor/codemirror/chunks/crystal-S6R6HLKQ.js +1 -0
  233. package/neural-interface/public/vendor/codemirror/chunks/css-PDA2RINP.js +1 -0
  234. package/neural-interface/public/vendor/codemirror/chunks/cypher-HL5QPL4C.js +1 -0
  235. package/neural-interface/public/vendor/codemirror/chunks/d-HHJH2HAJ.js +1 -0
  236. package/neural-interface/public/vendor/codemirror/chunks/diff-MN3A35BY.js +1 -0
  237. package/neural-interface/public/vendor/codemirror/chunks/dist-25SQLBVS.js +3 -0
  238. package/neural-interface/public/vendor/codemirror/chunks/dist-27ZGGJJS.js +1 -0
  239. package/neural-interface/public/vendor/codemirror/chunks/dist-4E52OJIF.js +1 -0
  240. package/neural-interface/public/vendor/codemirror/chunks/dist-6FT73XDC.js +2 -0
  241. package/neural-interface/public/vendor/codemirror/chunks/dist-BE6YGRMW.js +1 -0
  242. package/neural-interface/public/vendor/codemirror/chunks/dist-CJSGKW2O.js +1 -0
  243. package/neural-interface/public/vendor/codemirror/chunks/dist-CRPH2WLI.js +1 -0
  244. package/neural-interface/public/vendor/codemirror/chunks/dist-CTG7JEQN.js +1 -0
  245. package/neural-interface/public/vendor/codemirror/chunks/dist-I3FEVELX.js +1 -0
  246. package/neural-interface/public/vendor/codemirror/chunks/dist-IM5BBSWZ.js +1 -0
  247. package/neural-interface/public/vendor/codemirror/chunks/dist-KERUKTIF.js +1 -0
  248. package/neural-interface/public/vendor/codemirror/chunks/dist-LXTMWZAM.js +1 -0
  249. package/neural-interface/public/vendor/codemirror/chunks/dist-MABASSET.js +1 -0
  250. package/neural-interface/public/vendor/codemirror/chunks/dist-MJVBUZLL.js +3 -0
  251. package/neural-interface/public/vendor/codemirror/chunks/dist-MNB3WZVU.js +1 -0
  252. package/neural-interface/public/vendor/codemirror/chunks/dist-QYWXOE3U.js +7 -0
  253. package/neural-interface/public/vendor/codemirror/chunks/dist-TEBOFWLZ.js +1 -0
  254. package/neural-interface/public/vendor/codemirror/chunks/dist-UNXFROM3.js +1 -0
  255. package/neural-interface/public/vendor/codemirror/chunks/dist-XL2SLQO6.js +1 -0
  256. package/neural-interface/public/vendor/codemirror/chunks/dist-XO42Y3AP.js +6 -0
  257. package/neural-interface/public/vendor/codemirror/chunks/dist-Y2WWDWJK.js +1 -0
  258. package/neural-interface/public/vendor/codemirror/chunks/dist-YFEZKWMU.js +1 -0
  259. package/neural-interface/public/vendor/codemirror/chunks/dist-ZY7SWQO6.js +1 -0
  260. package/neural-interface/public/vendor/codemirror/chunks/dockerfile-3Y4R4NCH.js +1 -0
  261. package/neural-interface/public/vendor/codemirror/chunks/dtd-5343GJ4P.js +1 -0
  262. package/neural-interface/public/vendor/codemirror/chunks/dylan-FI2CXSW2.js +1 -0
  263. package/neural-interface/public/vendor/codemirror/chunks/ebnf-GNQ77YWA.js +1 -0
  264. package/neural-interface/public/vendor/codemirror/chunks/ecl-MRPUAE2L.js +1 -0
  265. package/neural-interface/public/vendor/codemirror/chunks/eiffel-DZROES27.js +1 -0
  266. package/neural-interface/public/vendor/codemirror/chunks/elm-4KICRFKQ.js +1 -0
  267. package/neural-interface/public/vendor/codemirror/chunks/erlang-3IHYC263.js +1 -0
  268. package/neural-interface/public/vendor/codemirror/chunks/factor-C6D3E5UK.js +1 -0
  269. package/neural-interface/public/vendor/codemirror/chunks/fcl-VYTWUJMI.js +1 -0
  270. package/neural-interface/public/vendor/codemirror/chunks/forth-ZBO2EH5M.js +1 -0
  271. package/neural-interface/public/vendor/codemirror/chunks/fortran-5NDCRWIK.js +1 -0
  272. package/neural-interface/public/vendor/codemirror/chunks/gas-SKRMOXFP.js +1 -0
  273. package/neural-interface/public/vendor/codemirror/chunks/gherkin-L45YXZLW.js +1 -0
  274. package/neural-interface/public/vendor/codemirror/chunks/groovy-GLPTLN44.js +1 -0
  275. package/neural-interface/public/vendor/codemirror/chunks/haskell-E7NF7P4Y.js +1 -0
  276. package/neural-interface/public/vendor/codemirror/chunks/haxe-K2NVDOB6.js +1 -0
  277. package/neural-interface/public/vendor/codemirror/chunks/http-Q6DRQIJB.js +1 -0
  278. package/neural-interface/public/vendor/codemirror/chunks/idl-MZYNJVLN.js +1 -0
  279. package/neural-interface/public/vendor/codemirror/chunks/javascript-6YRYK2HR.js +1 -0
  280. package/neural-interface/public/vendor/codemirror/chunks/julia-HXEL2T5G.js +1 -0
  281. package/neural-interface/public/vendor/codemirror/chunks/livescript-MV7CI2JZ.js +1 -0
  282. package/neural-interface/public/vendor/codemirror/chunks/lua-E36NHOOD.js +1 -0
  283. package/neural-interface/public/vendor/codemirror/chunks/mathematica-3XOZZCMC.js +1 -0
  284. package/neural-interface/public/vendor/codemirror/chunks/mbox-ODYGFKS7.js +1 -0
  285. package/neural-interface/public/vendor/codemirror/chunks/mirc-WB43AWF5.js +1 -0
  286. package/neural-interface/public/vendor/codemirror/chunks/mllike-ZT6ET7ZH.js +1 -0
  287. package/neural-interface/public/vendor/codemirror/chunks/modelica-LLMZPFGA.js +1 -0
  288. package/neural-interface/public/vendor/codemirror/chunks/mscgen-2OPNNYFH.js +1 -0
  289. package/neural-interface/public/vendor/codemirror/chunks/mumps-6P3HWJH6.js +1 -0
  290. package/neural-interface/public/vendor/codemirror/chunks/nginx-TCGKQTRW.js +1 -0
  291. package/neural-interface/public/vendor/codemirror/chunks/nsis-ATIGIXTJ.js +1 -0
  292. package/neural-interface/public/vendor/codemirror/chunks/ntriples-5PLBI5OV.js +1 -0
  293. package/neural-interface/public/vendor/codemirror/chunks/octave-QF2S3NL6.js +1 -0
  294. package/neural-interface/public/vendor/codemirror/chunks/oz-JFIVFFH2.js +1 -0
  295. package/neural-interface/public/vendor/codemirror/chunks/pascal-JG6SW76V.js +1 -0
  296. package/neural-interface/public/vendor/codemirror/chunks/perl-4B3IWVVO.js +1 -0
  297. package/neural-interface/public/vendor/codemirror/chunks/pig-ABEBH4MI.js +1 -0
  298. package/neural-interface/public/vendor/codemirror/chunks/powershell-H32XE7TL.js +1 -0
  299. package/neural-interface/public/vendor/codemirror/chunks/properties-NN644MMA.js +1 -0
  300. package/neural-interface/public/vendor/codemirror/chunks/protobuf-YKWQK2J3.js +1 -0
  301. package/neural-interface/public/vendor/codemirror/chunks/pug-RIYXEKFW.js +1 -0
  302. package/neural-interface/public/vendor/codemirror/chunks/puppet-JZQ5WPEV.js +1 -0
  303. package/neural-interface/public/vendor/codemirror/chunks/python-EBCGGHAC.js +1 -0
  304. package/neural-interface/public/vendor/codemirror/chunks/q-5UMH2YQY.js +1 -0
  305. package/neural-interface/public/vendor/codemirror/chunks/r-7XMGG453.js +1 -0
  306. package/neural-interface/public/vendor/codemirror/chunks/rpm-IEV7TSLR.js +1 -0
  307. package/neural-interface/public/vendor/codemirror/chunks/ruby-T4SPFPNM.js +1 -0
  308. package/neural-interface/public/vendor/codemirror/chunks/sas-GEDX67ET.js +1 -0
  309. package/neural-interface/public/vendor/codemirror/chunks/scheme-FTLOWKPC.js +1 -0
  310. package/neural-interface/public/vendor/codemirror/chunks/shell-HUFRKFSJ.js +1 -0
  311. package/neural-interface/public/vendor/codemirror/chunks/sieve-P5QUDVYO.js +1 -0
  312. package/neural-interface/public/vendor/codemirror/chunks/smalltalk-2SORJNQI.js +1 -0
  313. package/neural-interface/public/vendor/codemirror/chunks/solr-M22TGAR5.js +1 -0
  314. package/neural-interface/public/vendor/codemirror/chunks/sparql-4M3KL752.js +1 -0
  315. package/neural-interface/public/vendor/codemirror/chunks/spreadsheet-3K23LA4N.js +1 -0
  316. package/neural-interface/public/vendor/codemirror/chunks/sql-VHRFMUBI.js +1 -0
  317. package/neural-interface/public/vendor/codemirror/chunks/stex-QZDAQUY2.js +1 -0
  318. package/neural-interface/public/vendor/codemirror/chunks/stylus-7ZDKAKBD.js +1 -0
  319. package/neural-interface/public/vendor/codemirror/chunks/swift-WCLCLGMR.js +1 -0
  320. package/neural-interface/public/vendor/codemirror/chunks/tcl-JLMU6WOK.js +1 -0
  321. package/neural-interface/public/vendor/codemirror/chunks/textile-4CHDKZ4T.js +1 -0
  322. package/neural-interface/public/vendor/codemirror/chunks/tiddlywiki-DKMCZZQ4.js +1 -0
  323. package/neural-interface/public/vendor/codemirror/chunks/tiki-F4JIG36Q.js +1 -0
  324. package/neural-interface/public/vendor/codemirror/chunks/toml-BHMHTIM2.js +1 -0
  325. package/neural-interface/public/vendor/codemirror/chunks/troff-YQ2KV5NT.js +1 -0
  326. package/neural-interface/public/vendor/codemirror/chunks/ttcn-ZHRCVFJY.js +1 -0
  327. package/neural-interface/public/vendor/codemirror/chunks/ttcn-cfg-KJOVTY4X.js +1 -0
  328. package/neural-interface/public/vendor/codemirror/chunks/turtle-535P5N6I.js +1 -0
  329. package/neural-interface/public/vendor/codemirror/chunks/vb-76UMQHOT.js +1 -0
  330. package/neural-interface/public/vendor/codemirror/chunks/vbscript-CGNDTK6Z.js +1 -0
  331. package/neural-interface/public/vendor/codemirror/chunks/velocity-VSJDO5T5.js +1 -0
  332. package/neural-interface/public/vendor/codemirror/chunks/verilog-4T6ETXIP.js +1 -0
  333. package/neural-interface/public/vendor/codemirror/chunks/vhdl-T7FNAXUN.js +1 -0
  334. package/neural-interface/public/vendor/codemirror/chunks/webidl-P6MJSJ6J.js +1 -0
  335. package/neural-interface/public/vendor/codemirror/chunks/xquery-UOVILRGN.js +1 -0
  336. package/neural-interface/public/vendor/codemirror/chunks/yacas-CV2APROL.js +1 -0
  337. package/neural-interface/public/vendor/codemirror/chunks/z80-3KFNVM4M.js +1 -0
  338. package/neural-interface/public/vendor/codemirror/codemirror-6.43.14-75f05e67.min.js +2 -0
  339. package/neural-interface/public/vendor/codemirror/manifest.json +60 -0
  340. package/neural-interface/scripts/build-vendor.mjs +78 -2
  341. package/neural-interface/scripts/rebuild-pty.js +15 -12
  342. package/neural-interface/scripts/vendor-codemirror-entry.js +121 -0
  343. package/neural-interface/server.js +1092 -1212
  344. package/neural-interface/templates/rulesets/README.md +1 -1
  345. package/package.json +13 -7
  346. package/postinstall.js +11 -81
  347. package/setup.js +111 -6
  348. package/benchmarks/browser-live-results.json +0 -79
  349. package/benchmarks/browser-v2-results.json +0 -258
  350. package/docs/browser-v2.md +0 -109
  351. package/docs/hook-integrity.md +0 -89
  352. package/docs/judgments.md +0 -182
  353. package/docs/style-guide.md +0 -246
  354. package/neural-interface/lib/codex-capabilities.d.ts +0 -41
  355. package/neural-interface/public/category-logos/claude.svg +0 -1
  356. package/neural-interface/public/category-logos/gemini-color.svg +0 -1
  357. package/neural-interface/public/category-logos/openai.svg +0 -1
  358. package/neural-interface/public/category-logos/synabun.png +0 -0
  359. package/neural-interface/public/claude.svg +0 -1
  360. package/neural-interface/public/gallery.svg +0 -6
  361. package/neural-interface/public/leonardoai.svg +0 -1
  362. package/neural-interface/public/mcp.svg +0 -4
  363. package/neural-interface/public/opencode-logo-dark-square.svg +0 -1
  364. package/neural-interface/public/pin-svgrepo-com.svg +0 -25
  365. package/neural-interface/public/sessionicon.svg +0 -8
  366. package/neural-interface/public/toolbar-album.svg +0 -8
  367. package/neural-interface/public/toolbar-question.svg +0 -6
  368. package/neural-interface/public/toolbar-sessions.svg +0 -6
  369. package/neural-interface/scripts/codex-protocol-fixture.mjs +0 -83
  370. package/scripts/audit-claude-hook-usage.mjs +0 -12
  371. package/scripts/audit-memory-duplicates.mjs +0 -44
  372. package/scripts/measure-claude-hook-overhead.mjs +0 -77
  373. package/scripts/recover-user-config.mjs +0 -254
  374. package/skills/synabun/synabunicon.png +0 -0
@@ -1,60 +1,31 @@
1
- // ── Cross-platform native binary runtime (resolve → verify → repair → diagnose) ──
1
+ // ── Executables SynaBun starts: verify → repair → diagnose ──
2
2
  //
3
- // The Claude Agent SDK resolves its bundled native CLI with `require.resolve` +
4
- // `existsSync` and nothing else — no stat, no X_OK probe, no spawn test. When the
5
- // binary is present but not executable, `spawn` fails EACCES and the SDK reports:
3
+ // Two kinds of executable pass through here.
6
4
  //
7
- // "Claude Code native binary at <p> exists but failed to launch. This usually
8
- // means the binary does not match this system's libc — e.g. spawning a
9
- // musl-linked binary on a glibc Linux host…"
5
+ // The user's Claude Code. SynaBun ships none (lib/external-tools.js at the
6
+ // package root): every Agent SDK call is given the user's own installation as
7
+ // `pathToClaudeCodeExecutable` (lib/claude-executable.js). The SDK uses that
8
+ // value verbatim, with no stat, no X_OK probe and no spawn test, and when the
9
+ // launch fails it buckets ENOENT/EACCES/EPERM/ENOTDIR/ELOOP/ENAMETOOLONG/EROFS
10
+ // together and reports a musl/glibc mismatch, which is only ever right on
11
+ // Linux. It also throws a ReferenceError, not an Error. So this module:
12
+ // - validates a path before the SDK gets it (a bare command name and a
13
+ // Windows command file cannot be spawned with shell:false)
14
+ // - recognises a launch failure, whatever shape the SDK gave it
15
+ // - explains it for the platform it happened on
10
16
  //
11
- // That wording is hardcoded and wrong everywhere except Linux: the SDK buckets
12
- // ENOENT/EACCES/EPERM/ENOTDIR/ELOOP/ENAMETOOLONG/EROFS together and picks the
13
- // message using only `existsSync`. It also throws a ReferenceError, not an Error.
17
+ // SynaBun's own native helpers. node-pty's spawn-helper has to be executable
18
+ // and npm does not preserve the bit, so a sweep restores it, built by
19
+ // enumeration rather than a hardcoded list.
14
20
  //
15
- // SynaBun hits this constantly because `node_modules` is committed with
16
- // core.filemode=false, so every vendored binary checks out mode 0644.
17
- //
18
- // This module supplies what the SDK lacks:
19
- // - a faithful reimplementation of the SDK's candidate resolution, so we know
20
- // WHICH file it will pick and can stat/chmod exactly that one
21
- // - exec-bit verification and repair (POSIX), plus an X_OK probe that catches
22
- // modes the `& 0o111` mask misses (e.g. root-owned 0711)
23
- // - a sweep over every vendored binary (Claude SDK, Codex, node-pty), built by
24
- // enumeration rather than a hardcoded list
25
- // - platform-accurate diagnosis + a recovery plan (repair-and-retry, then fall
26
- // back to the user's global CLI)
27
- //
28
- // Resolution logic below mirrors @anthropic-ai/claude-agent-sdk@0.3.220. We never
29
- // hand the resolved path back to the SDK on the happy path — it re-resolves for
30
- // itself, and our copy exists only to know what to repair and how to explain a
31
- // failure. A drift between the two therefore degrades to "we chmod'd a file
32
- // nobody uses", never to launching the wrong binary.
33
- //
34
- // Every dependency is injectable (platform, arch, exists, stat, chmod, access,
35
- // readdir, report) so all eight platform targets are testable from one host.
36
- // Nothing here throws.
21
+ // Every dependency is injectable (platform, exists, stat, chmod, access,
22
+ // readdir), so every platform is testable from one host. Nothing here throws.
37
23
 
38
24
  import { existsSync, statSync, chmodSync, accessSync, readdirSync, constants } from 'node:fs';
39
- import { createRequire } from 'node:module';
40
25
  import path from 'node:path';
41
26
 
42
27
  export const SDK_PKG = '@anthropic-ai/claude-agent-sdk';
43
28
 
44
- // Platform packages the SDK declares as optionalDependencies. Kept here so a
45
- // test can assert we still match the installed SDK's own list (see the drift
46
- // guard in tests/native-binary-runtime.test.mjs).
47
- export const SDK_PLATFORM_PACKAGES = [
48
- `${SDK_PKG}-darwin-arm64`,
49
- `${SDK_PKG}-darwin-x64`,
50
- `${SDK_PKG}-linux-arm64`,
51
- `${SDK_PKG}-linux-arm64-musl`,
52
- `${SDK_PKG}-linux-x64`,
53
- `${SDK_PKG}-linux-x64-musl`,
54
- `${SDK_PKG}-win32-arm64`,
55
- `${SDK_PKG}-win32-x64`,
56
- ];
57
-
58
29
  // The SDK's isNativeBinary(): a path NOT ending in one of these is spawned
59
30
  // directly and needs +x. Note `.cjs` is absent — it IS spawned directly.
60
31
  const SCRIPT_EXTENSIONS = ['.js', '.mjs', '.tsx', '.ts', '.jsx'];
@@ -67,91 +38,6 @@ const LAUNCH_ERROR_CODES = new Set([
67
38
 
68
39
  export const SDK_LIBC_MESSAGE_RE = /native binary at .+ exists but failed to launch/i;
69
40
 
70
- // ─────────────────────────────────────────────────────────────────────────────
71
- // Resolution (faithful to the SDK)
72
- // ─────────────────────────────────────────────────────────────────────────────
73
-
74
- /**
75
- * musl detection, exactly as the SDK does it: linux-only, and an ABSENT
76
- * `glibcVersionRuntime` in the diagnostic report means musl. Anything we cannot
77
- * read falls back to the glibc ordering, matching the SDK.
78
- */
79
- export function detectMusl({ platform = process.platform, report = process.report } = {}) {
80
- if (platform !== 'linux') return false;
81
- try {
82
- if (typeof report?.getReport !== 'function') return false;
83
- const r = report.getReport();
84
- return r != null && r.header?.glibcVersionRuntime === undefined;
85
- } catch {
86
- return false;
87
- }
88
- }
89
-
90
- /**
91
- * The request specifiers the SDK tries, in order. Each is `<pkg>/claude`, or
92
- * `<pkg>/claude.exe` on Windows. darwin and win32 get a SINGLE candidate with no
93
- * fallback; only linux has a two-entry list, ordered by libc.
94
- */
95
- export function sdkBinaryCandidates({
96
- platform = process.platform,
97
- arch = process.arch,
98
- preferMusl,
99
- } = {}) {
100
- const musl = preferMusl === undefined ? detectMusl({ platform }) : !!preferMusl;
101
- const binary = platform === 'win32' ? 'claude.exe' : 'claude';
102
-
103
- let packages;
104
- if (platform === 'android') {
105
- packages = [`${SDK_PKG}-linux-${arch}-android`];
106
- } else if (platform === 'linux') {
107
- packages = musl
108
- ? [`${SDK_PKG}-linux-${arch}-musl`, `${SDK_PKG}-linux-${arch}`]
109
- : [`${SDK_PKG}-linux-${arch}`, `${SDK_PKG}-linux-${arch}-musl`];
110
- } else {
111
- packages = [`${SDK_PKG}-${platform}-${arch}`];
112
- }
113
- return packages.map((p) => `${p}/${binary}`);
114
- }
115
-
116
- // Anchor resolution at the SDK's own entry file, NOT at this module. The SDK
117
- // calls createRequire(fileURLToPath(import.meta.url)) from inside sdk.mjs, so a
118
- // nested or pnpm-style layout resolves from that directory's ancestry — not
119
- // ours. Resolving from here would find a different (or no) platform package.
120
- const _selfRequire = createRequire(import.meta.url);
121
- function defaultSdkResolve(specifier) {
122
- const sdkRequire = createRequire(_selfRequire.resolve(SDK_PKG));
123
- return sdkRequire.resolve(specifier);
124
- }
125
-
126
- /**
127
- * Resolve the native binary the SDK would pick.
128
- * @returns {{path: string|null, specifier: string|null, candidates: string[], checked: object[]}}
129
- */
130
- export function resolveSdkBinary({
131
- platform = process.platform,
132
- arch = process.arch,
133
- preferMusl,
134
- resolve = defaultSdkResolve,
135
- exists = existsSync,
136
- } = {}) {
137
- const candidates = sdkBinaryCandidates({ platform, arch, preferMusl });
138
- const checked = [];
139
-
140
- for (const specifier of candidates) {
141
- try {
142
- const resolved = resolve(specifier);
143
- const found = exists(resolved);
144
- checked.push({ specifier, path: resolved, exists: found });
145
- if (found) return { path: resolved, specifier, candidates, checked };
146
- } catch (error) {
147
- // MODULE_NOT_FOUND on an uninstalled optional dep — the SDK swallows this
148
- // per-candidate too and moves on.
149
- checked.push({ specifier, error: error?.message || String(error) });
150
- }
151
- }
152
- return { path: null, specifier: null, candidates, checked };
153
- }
154
-
155
41
  // ─────────────────────────────────────────────────────────────────────────────
156
42
  // Exec-bit verification and repair
157
43
  // ─────────────────────────────────────────────────────────────────────────────
@@ -254,77 +140,16 @@ export function ensureExecutable(binPath, {
254
140
  };
255
141
  }
256
142
 
257
- // ─────────────────────────────────────────────────────────────────────────────
258
- // Claude runtime (resolution + repair, memoized)
259
- // ─────────────────────────────────────────────────────────────────────────────
260
-
261
- const _runtimeCache = new Map();
262
-
263
- export function clearNativeBinaryCache() {
264
- _runtimeCache.clear();
265
- }
266
-
267
- /**
268
- * Resolve and repair the SDK's bundled Claude binary.
269
- *
270
- * The returned `path` is informational: callers should NOT pass it to the SDK as
271
- * `pathToClaudeCodeExecutable` on the happy path. Calling this for its chmod
272
- * side effect and letting the SDK resolve for itself keeps us immune to future
273
- * changes in the SDK's resolution.
274
- */
275
- export function claudeRuntime({
276
- platform = process.platform,
277
- arch = process.arch,
278
- preferMusl,
279
- resolve,
280
- exists,
281
- stat,
282
- chmod,
283
- access,
284
- cache = true,
285
- } = {}) {
286
- const musl = preferMusl === undefined ? detectMusl({ platform }) : !!preferMusl;
287
- const key = `${platform}:${arch}:${musl}`;
288
- if (cache && _runtimeCache.has(key)) return _runtimeCache.get(key);
289
-
290
- const resolved = resolveSdkBinary({ platform, arch, preferMusl: musl, resolve, exists });
291
-
292
- let result;
293
- if (!resolved.path) {
294
- result = {
295
- path: null,
296
- specifier: null,
297
- ok: false,
298
- state: 'not-installed',
299
- repaired: false,
300
- repairCommand: null,
301
- candidates: resolved.candidates,
302
- checked: resolved.checked,
303
- reason: `No Claude native binary is installed for ${platform}-${arch}`,
304
- };
305
- } else {
306
- const verdict = ensureExecutable(resolved.path, { platform, stat, chmod, access });
307
- result = {
308
- ...verdict,
309
- specifier: resolved.specifier,
310
- candidates: resolved.candidates,
311
- checked: resolved.checked,
312
- };
313
- }
314
-
315
- if (cache) _runtimeCache.set(key, result);
316
- return result;
317
- }
318
-
319
143
  // ─────────────────────────────────────────────────────────────────────────────
320
144
  // Executable override contract (one contract for every SDK caller)
321
145
  // ─────────────────────────────────────────────────────────────────────────────
322
146
 
323
147
  /**
324
- * Validate a user-supplied `pathToClaudeCodeExecutable`.
148
+ * Validate a path before it becomes `pathToClaudeCodeExecutable`: the explicit
149
+ * override, or the installation lib/claude-executable.js found.
325
150
  *
326
- * The SDK uses that value verbatim with zero validation, so a bad one produces a
327
- * worse failure than the one we are fixing. In particular a BARE COMMAND NAME
151
+ * The SDK uses that value verbatim with zero validation, so a bad one fails
152
+ * late and with the wrong explanation. In particular a BARE COMMAND NAME
328
153
  * (e.g. the string 'claude', which getClaudeBin() returns as its last resort)
329
154
  * is a guaranteed ENOENT under spawn(shell:false) — it must be rejected here.
330
155
  *
@@ -379,9 +204,6 @@ export function resolveClaudeExecutableOverride(spec, {
379
204
  // Vendored binary sweep
380
205
  // ─────────────────────────────────────────────────────────────────────────────
381
206
 
382
- const CODEX_VENDOR_BIN_DIRS = ['bin', 'codex', 'path'];
383
- const CODEX_VENDOR_BIN_NAMES = ['codex', 'codex.exe', 'rg', 'rg.exe'];
384
-
385
207
  function safeReaddir(readdir, dir) {
386
208
  try {
387
209
  return readdir(dir, { withFileTypes: false }) || [];
@@ -391,12 +213,15 @@ function safeReaddir(readdir, dir) {
391
213
  }
392
214
 
393
215
  /**
394
- * Enumerate every vendored binary that must be executable, by walking the tree
395
- * rather than hardcoding names. This is what keeps the sweep correct as
396
- * platform packages and node-pty prebuild directories come and go — the old
216
+ * Enumerate every native helper of SynaBun's own that must be executable, by
217
+ * walking the tree rather than hardcoding names: node-pty's spawn-helper, for
218
+ * every prebuild directory present and for a build from source. The old
397
219
  * hardcoded list in scripts/rebuild-pty.js named linux dirs that do not exist
398
220
  * here while missing ones that do.
399
221
  *
222
+ * The agent tools are not in this list: Claude Code and Codex are the user's
223
+ * installations, outside this tree, and nothing of theirs is repaired here.
224
+ *
400
225
  * Every target is optional: a given checkout has only a subset installed.
401
226
  */
402
227
  export function vendoredBinaryTargets({
@@ -410,18 +235,6 @@ export function vendoredBinaryTargets({
410
235
  const targets = [];
411
236
  const add = (id, p, kind) => { if (exists(p)) targets.push({ id, path: p, kind }); };
412
237
 
413
- // 1. Claude Agent SDK platform packages (all of them, not just this host's —
414
- // a vendored checkout can carry several).
415
- const anthropicDir = path.join(nm, '@anthropic-ai');
416
- for (const entry of safeReaddir(readdir, anthropicDir)) {
417
- const name = String(entry);
418
- if (!name.startsWith('claude-agent-sdk-')) continue;
419
- const pkgDir = path.join(anthropicDir, name);
420
- add(`sdk:${name}`, path.join(pkgDir, 'claude'), 'sdk-claude');
421
- add(`sdk:${name}:exe`, path.join(pkgDir, 'claude.exe'), 'sdk-claude');
422
- }
423
-
424
- // 2. node-pty spawn-helper, for every prebuild directory present.
425
238
  const ptyDir = path.join(nm, 'node-pty');
426
239
  const prebuildsDir = path.join(ptyDir, 'prebuilds');
427
240
  for (const entry of safeReaddir(readdir, prebuildsDir)) {
@@ -429,26 +242,6 @@ export function vendoredBinaryTargets({
429
242
  }
430
243
  add('pty:build', path.join(ptyDir, 'build', 'Release', 'spawn-helper'), 'pty-spawn-helper');
431
244
 
432
- // 3. Codex platform packages: vendor/<triple>/{bin,codex,path}/{codex,rg}.
433
- // Hygiene only — server.js deliberately never falls back to the bundled
434
- // Codex binary (macOS quarantine); repairing the bit must not be read as
435
- // enabling that fallback.
436
- const openaiDir = path.join(nm, '@openai');
437
- for (const entry of safeReaddir(readdir, openaiDir)) {
438
- const name = String(entry);
439
- if (!name.startsWith('codex')) continue;
440
- const vendorDir = path.join(openaiDir, name, 'vendor');
441
- for (const triple of safeReaddir(readdir, vendorDir)) {
442
- for (const binDir of CODEX_VENDOR_BIN_DIRS) {
443
- for (const binName of CODEX_VENDOR_BIN_NAMES) {
444
- const p = path.join(vendorDir, String(triple), binDir, binName);
445
- add(`codex:${name}:${triple}:${binDir}:${binName}`, p, binName.startsWith('rg') ? 'ripgrep' : 'codex');
446
- }
447
- }
448
- }
449
- add(`codex:${name}:bin-rg`, path.join(openaiDir, name, 'bin', 'rg'), 'ripgrep');
450
- }
451
-
452
245
  return targets;
453
246
  }
454
247
 
@@ -514,137 +307,76 @@ export function isNativeBinaryLaunchFailure(err) {
514
307
  }
515
308
 
516
309
  /**
517
- * Turn a launch failure into a platform-accurate explanation, replacing the
518
- * SDK's hardcoded musl/glibc story (which is only correct on Linux).
310
+ * Turn a launch failure of the user's Claude Code into an explanation for the
311
+ * platform it happened on, replacing the SDK's hardcoded musl/glibc story
312
+ * (which is only correct on Linux). `executable` is the path the SDK was given.
519
313
  *
520
- * @returns {{kind: string, message: string, repairCommand: string|null, canRetryAfterRepair: boolean}}
314
+ * @returns {{kind: string, message: string, repairCommand: string|null}}
521
315
  */
522
316
  export function diagnoseLaunchFailure({
523
317
  err,
524
- runtime,
318
+ executable,
525
319
  platform = process.platform,
526
320
  arch = process.arch,
321
+ stat = statSync,
322
+ access = accessSync,
527
323
  } = {}) {
528
- const rt = runtime || {};
529
- const p = rt.path || '(unresolved)';
324
+ const p = executable || '';
530
325
  const raw = (typeof err === 'string' ? err : err?.message) || '';
531
326
 
532
- switch (rt.state) {
533
- case 'repaired':
534
- return {
535
- kind: 'exec-bit',
536
- repairCommand: rt.repairCommand,
537
- canRetryAfterRepair: true,
538
- message: [
539
- `The bundled Claude binary was not executable (mode ${(rt.mode & 0o777).toString(8).padStart(3, '0')}).`,
540
- 'This is a file permission problem, not a libc mismatch — the SDK always blames libc here.',
541
- 'Execute permission has been restored; retrying.',
542
- ].join(' '),
543
- };
327
+ // The literal "Claude CLI not found" keeps the panel's install help
328
+ // (ui-claude-panel.js) appearing without a frontend change.
329
+ const missing = {
330
+ kind: 'missing',
331
+ repairCommand: null,
332
+ message: p
333
+ ? `Claude CLI not found at ${p}. Claude Code is installed separately from SynaBun: install it again, or correct its path in Settings > Terminal.`
334
+ : 'Claude CLI not found. Claude Code is installed separately from SynaBun: install it, then send your message again.',
335
+ };
336
+ if (!p) return missing;
544
337
 
545
- case 'chmod-failed':
546
- case 'access-denied':
547
- return {
548
- kind: 'exec-bit',
549
- repairCommand: rt.repairCommand,
550
- canRetryAfterRepair: false,
551
- message: [
552
- `The bundled Claude binary at ${p} is not executable and the permission could not be repaired`,
553
- `(${rt.error || rt.state}).`,
554
- 'This is a file permission problem, not a libc mismatch.',
555
- `The install may be read-only or owned by another user. Fix it with: sudo ${rt.repairCommand || `chmod +x ${quoteForShell(p)}`}`,
556
- ].join(' '),
557
- };
338
+ let info = null;
339
+ try { info = stat(p); } catch { return missing; }
340
+ if (typeof info?.isFile === 'function' && !info.isFile()) return { ...missing, message: `Claude CLI not found: ${p} is not a file. Correct its path in Settings > Terminal.` };
558
341
 
559
- case 'windows-bad-name':
342
+ if (platform === 'win32') {
343
+ if (!/\.exe$/i.test(p) && !isScriptPath(p)) {
560
344
  return {
561
345
  kind: 'shim',
562
346
  repairCommand: null,
563
- canRetryAfterRepair: false,
564
- message: [
565
- `${p} cannot be launched: the Claude Agent SDK spawns with shell:false,`,
566
- 'so npm .cmd/.bat/.ps1 shims will not run. Point the override at the real claude.exe instead.',
567
- ].join(' '),
347
+ message: `${p} cannot be started: the Claude Agent SDK spawns without a shell, so a .cmd, .bat or .ps1 launcher will not run. Name the real claude.exe in cli-config.json ("claude-skin": { "sdkExecutable": "…" }).`,
568
348
  };
349
+ }
350
+ return { kind: 'unknown', repairCommand: null, message: raw || `Claude Code at ${p} could not be started.` };
351
+ }
569
352
 
570
- case 'not-installed':
571
- case 'missing':
572
- case 'not-a-file':
353
+ if (!isScriptPath(p)) {
354
+ try {
355
+ access(p, constants.X_OK);
356
+ } catch {
357
+ const repairCommand = `chmod +x ${quoteForShell(p)}`;
573
358
  return {
574
- kind: 'missing',
575
- repairCommand: null,
576
- canRetryAfterRepair: false,
577
- // The literal "Claude CLI not found" keeps the panel's existing
578
- // install-CTA regex (ui-claude-panel.js) firing without a frontend change.
579
- message: [
580
- `Claude CLI not found for ${platform}-${arch}.`,
581
- 'The SDK ships its native binary as a per-platform optional dependency.',
582
- 'Reinstall without --omit=optional (npm install --include=optional), or install Claude Code globally.',
583
- ].join(' '),
359
+ kind: 'exec-bit',
360
+ repairCommand,
361
+ message: `Claude Code at ${p} is not executable by this user. This is a file permission problem, not a libc mismatch. Fix it with: ${repairCommand}`,
584
362
  };
585
-
586
- default:
587
- break;
363
+ }
588
364
  }
589
365
 
590
- // Resolved, executable, and it still would not launch.
591
366
  if (platform === 'darwin') {
367
+ const repairCommand = `xattr -d com.apple.quarantine ${quoteForShell(p)}`;
592
368
  return {
593
369
  kind: 'gatekeeper',
594
- repairCommand: `xattr -d com.apple.quarantine ${quoteForShell(p)}`,
595
- canRetryAfterRepair: false,
596
- message: [
597
- `The Claude binary at ${p} is executable but macOS refused to launch it.`,
598
- `Usually Gatekeeper quarantine, or a binary built for another architecture (this host is ${arch}).`,
599
- `Try: xattr -d com.apple.quarantine ${quoteForShell(p)}`,
600
- ].join(' '),
370
+ repairCommand,
371
+ message: `Claude Code at ${p} is executable but macOS refused to start it. Usually Gatekeeper quarantine, or a build for another processor (this one is ${arch}). Try: ${repairCommand}`,
601
372
  };
602
373
  }
603
374
  if (platform === 'linux') {
604
375
  return {
605
376
  kind: 'libc',
606
377
  repairCommand: null,
607
- canRetryAfterRepair: false,
608
- message: [
609
- `The Claude binary at ${p} is executable but failed to launch.`,
610
- `This host looks like ${detectMusl({ platform }) ? 'musl' : 'glibc'}.`,
611
- 'A musl-linked binary on a glibc host (or the reverse) fails because the matching dynamic loader is missing.',
612
- 'Reinstall so the correct linux variant is selected.',
613
- ].join(' '),
614
- };
615
- }
616
- return {
617
- kind: 'unknown',
618
- repairCommand: null,
619
- canRetryAfterRepair: false,
620
- message: raw || `The Claude binary at ${p} failed to launch.`,
621
- };
622
- }
623
-
624
- /**
625
- * Decide what to do about a launch failure. Pure, so the bridge's recovery
626
- * behaviour is unit-testable without a live WebSocket.
627
- *
628
- * @returns {{action: 'retry'|'fallback'|'fail', message: string, kind: string, repairCommand: string|null}}
629
- */
630
- export function planRuntimeRecovery({
631
- err,
632
- runtime,
633
- fallbackBin = null,
634
- alreadyTried = false,
635
- platform = process.platform,
636
- arch = process.arch,
637
- } = {}) {
638
- const dx = diagnoseLaunchFailure({ err, runtime, platform, arch });
639
- const base = { message: dx.message, kind: dx.kind, repairCommand: dx.repairCommand };
640
-
641
- if (dx.canRetryAfterRepair && !alreadyTried) return { ...base, action: 'retry' };
642
- if (fallbackBin) {
643
- return {
644
- ...base,
645
- action: 'fallback',
646
- message: `${dx.message}\nFalling back to your installed Claude CLI: ${fallbackBin}`,
378
+ message: `Claude Code at ${p} is executable but could not be started. A musl-linked build on a glibc system (or the reverse) fails because its dynamic loader is missing. Reinstall Claude Code so that the build for this system is selected.`,
647
379
  };
648
380
  }
649
- return { ...base, action: 'fail' };
381
+ return { kind: 'unknown', repairCommand: null, message: raw || `Claude Code at ${p} could not be started.` };
650
382
  }
@@ -1,8 +1,8 @@
1
1
  import { detectProject as memoryProject } from '../../mcp-server/dist/config.js';
2
2
  import { Codex } from '@openai/codex-sdk';
3
3
  import { query as claudeQuery } from '@anthropic-ai/claude-agent-sdk';
4
- import { CLAUDE_EFFORT_LEVELS, markAlignedClaudeExecutableFailed } from './claude-model-catalog.js';
5
- import { claudeRuntime, isNativeBinaryLaunchFailure, resolveClaudeExecutableOverride } from './native-binary-runtime.js';
4
+ import { CLAUDE_EFFORT_LEVELS } from './claude-model-catalog.js';
5
+ import { CLAUDE_NOT_INSTALLED, resolveClaudeSdkExecutable } from './claude-executable.js';
6
6
  import { extractOpenCodeText } from './session-title-generator.js';
7
7
  import { patchCodexLineSplitting } from './jsonl-lines.js';
8
8
  import { dirname } from 'node:path';
@@ -286,6 +286,14 @@ export async function createCodexNativeLoopAdapter(options = {}) {
286
286
  if (Object.keys(pins).length) config.mcp_servers = { SynaBun: { env: pins } };
287
287
  if (extended) config.model_context_window = Math.floor(Number(modelContextWindow));
288
288
  if (browserPolicy) Object.assign(config, browserPolicy.config);
289
+ // The SDK is always told which Codex to start: the user's own installation.
290
+ // SynaBun carries none, and left to itself the SDK would look for one inside
291
+ // its own packages and report that as a broken install.
292
+ if (!codexPath && CodexClass === Codex) {
293
+ const error = new Error('Codex CLI not found. Codex is installed separately from SynaBun: install it, then run this again.');
294
+ error.code = 'CODEX_NOT_INSTALLED';
295
+ throw error;
296
+ }
289
297
  const codex = new CodexClass({
290
298
  ...(codexPath ? { codexPathOverride: codexPath } : {}),
291
299
  env,
@@ -406,12 +414,11 @@ export async function createClaudeNativeLoopAdapter(options = {}) {
406
414
  const {
407
415
  runId, cwd, model, effort, browserSessionId, browserTabId,
408
416
  mcpUrl, onIdentity = () => {}, onEvent = () => {}, queryFactory = claudeQuery,
409
- sdkExecutable, includePartialMessages = process.platform !== 'win32',
410
- // Fallback CLI + runtime probe, injectable for tests.
411
- claudeBin = null, resolveRuntime = claudeRuntime, logWarn = console.warn,
412
- // Installed CLI to run instead of the bundled one because it is newer — see
413
- // alignedClaudeExecutable() in claude-model-catalog.js. null keeps bundled.
414
- alignedClaudeBin = null,
417
+ includePartialMessages = process.platform !== 'win32',
418
+ // Which Claude Code runs the loop: the answer of resolveClaudeSdkExecutable()
419
+ // (lib/claude-executable.js), as the host worked it out. A caller without
420
+ // one names the pieces instead: the cli-config override and the installed CLI.
421
+ claudeExecutable = null, sdkExecutable = null, claudeBin = null, logWarn = console.warn,
415
422
  // Task-mode options (assistant dispatch).
416
423
  extraEnv = {}, permissionPolicy: rawPolicy = 'auto', permissionBroker = null,
417
424
  capability: rawCapability = 'full', maxBudgetUsd = null, outputSchema = null, runMode = 'loop',
@@ -522,41 +529,22 @@ export async function createClaudeNativeLoopAdapter(options = {}) {
522
529
  if (capability === 'read-only') queryOptions.disallowedTools = [...CLAUDE_READ_ONLY_DISALLOWED_TOOLS];
523
530
  if (Number(maxBudgetUsd) > 0) queryOptions.maxBudgetUsd = Number(maxBudgetUsd);
524
531
  if (outputSchema && typeof outputSchema === 'object') queryOptions.outputFormat = { type: 'json_schema', schema: outputSchema };
525
- // The SDK uses pathToClaudeCodeExecutable verbatim with no validation, so vet
526
- // the override first (a bare command name would ENOENT under shell:false).
527
- // With no override, calling resolveRuntime() also restores the execute bit on
528
- // the bundled binary — npm drops it, and this repo commits node_modules.
532
+ // The loop runs the user's own Claude Code: SynaBun carries none, and the SDK
533
+ // is never left to look for one. The SDK uses pathToClaudeCodeExecutable
534
+ // verbatim with no validation, so the path was vetted where it was resolved
535
+ // (a bare command name would ENOENT under shell:false).
529
536
  //
530
- // Pre-flight only: unattended loops have no one to prompt, and retries are
531
- // owned by native-loop-runtime.js. A bad runtime here means we pick the
532
- // fallback CLI up front rather than failing mid-loop.
533
- const override = resolveClaudeExecutableOverride(sdkExecutable);
534
- // The installed CLI, when it is newer than the bundled one: the loop's model was
535
- // picked from that CLI's list, and the bundled binary would resolve the same alias
536
- // to an older model. Vetted with the same contract as any override.
537
- const aligned = !override.path && alignedClaudeBin
538
- ? resolveClaudeExecutableOverride(alignedClaudeBin)
539
- : null;
540
- const alignedPath = aligned?.ok && aligned.path ? aligned.path : null;
541
- if (override.path) {
542
- queryOptions.pathToClaudeCodeExecutable = override.path;
543
- } else {
544
- if (sdkExecutable) logWarn(`[native-loop] ignoring sdkExecutable override — ${override.reason}`);
545
- if (alignedPath) {
546
- queryOptions.pathToClaudeCodeExecutable = alignedPath;
547
- } else {
548
- const runtime = resolveRuntime();
549
- if (!runtime.ok) {
550
- const fallback = resolveClaudeExecutableOverride(claudeBin);
551
- if (fallback.ok && fallback.path) {
552
- queryOptions.pathToClaudeCodeExecutable = fallback.path;
553
- logWarn(`[native-loop] bundled Claude binary unusable (${runtime.state}) — using ${fallback.path}`);
554
- } else {
555
- logWarn(`[native-loop] bundled Claude binary unusable (${runtime.state}) and no launchable `
556
- + `fallback CLI: ${runtime.reason || fallback.reason || 'none configured'}`);
557
- }
558
- }
559
- }
537
+ // Pre-flight only: an unattended loop has no one to prompt, and retries are
538
+ // owned by native-loop-runtime.js. Without a Claude Code to start, the run
539
+ // fails here, with the reason, instead of somewhere inside the first turn.
540
+ const executable = claudeExecutable || resolveClaudeSdkExecutable({ launcher: claudeBin, sdkExecutable });
541
+ if (executable.ignored) logWarn(`[native-loop] ignoring sdkExecutable override — ${executable.ignored}`);
542
+ if (executable.path) {
543
+ queryOptions.pathToClaudeCodeExecutable = executable.path;
544
+ } else if (queryFactory === claudeQuery) {
545
+ const error = new Error(executable.reason || CLAUDE_NOT_INSTALLED);
546
+ error.code = 'CLAUDE_NOT_INSTALLED';
547
+ throw error;
560
548
  }
561
549
 
562
550
  const q = queryFactory({ prompt: input, options: queryOptions });
@@ -648,8 +636,6 @@ export async function createClaudeNativeLoopAdapter(options = {}) {
648
636
  }
649
637
  } catch (error) {
650
638
  pumpError = error;
651
- // The aligned CLI would not start. Later runs go back to the bundled runtime.
652
- if (alignedPath && isNativeBinaryLaunchFailure(error)) markAlignedClaudeExecutableFailed(alignedPath);
653
639
  } finally {
654
640
  flushDeltas();
655
641
  if (alive) {
@@ -663,11 +649,16 @@ export async function createClaudeNativeLoopAdapter(options = {}) {
663
649
  }
664
650
  if (pumpError) throw pumpError;
665
651
  })();
666
- pump.catch((error) => onEvent({
667
- provider: 'claude-code',
668
- runId,
669
- event: { type: 'synabun.error', message: error?.message || String(error) },
670
- }));
652
+ pump.catch((error) => {
653
+ // dispose() aborts the query when the run ends, however it ended, and the
654
+ // SDK throws "Claude Code process aborted by user" for it: not a failure.
655
+ if (abortController.signal.aborted) return;
656
+ onEvent({
657
+ provider: 'claude-code',
658
+ runId,
659
+ event: { type: 'synabun.error', message: error?.message || String(error) },
660
+ });
661
+ });
671
662
 
672
663
  return {
673
664
  identity: () => ({ providerSessionId: sessionId }),