synabun 2.0.5 → 2.0.9

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 (527) hide show
  1. package/CHANGELOG.md +78 -0
  2. package/README.md +2 -1
  3. package/THIRD-PARTY-LICENSES.md +13 -0
  4. package/docs/whatsapp.md +151 -16
  5. package/hooks/claude-code/post-plan.mjs +6 -30
  6. package/hooks/claude-code/session-start.mjs +1 -4
  7. package/hooks/claude-code/shared.mjs +112 -75
  8. package/lib/child-path.js +303 -0
  9. package/lib/claude-hooks.js +2 -1
  10. package/lib/data-home-migration.js +2 -0
  11. package/lib/desktop-app.js +265 -0
  12. package/lib/external-tools.js +7 -3
  13. package/lib/log-redact.js +102 -0
  14. package/lib/package-processes.js +670 -0
  15. package/lib/packaged-runtime.js +138 -11
  16. package/lib/runtime-dependencies.js +225 -0
  17. package/mcp-server/dist/http.d.ts +3 -1
  18. package/mcp-server/dist/http.d.ts.map +1 -1
  19. package/mcp-server/dist/http.js +15 -4
  20. package/mcp-server/dist/http.js.map +1 -1
  21. package/mcp-server/dist/index.d.ts.map +1 -1
  22. package/mcp-server/dist/index.js +9 -6
  23. package/mcp-server/dist/index.js.map +1 -1
  24. package/mcp-server/dist/services/browser-bench.d.ts +1 -1
  25. package/mcp-server/dist/services/browser-bench.d.ts.map +1 -1
  26. package/mcp-server/dist/services/browser-bench.js +1 -1
  27. package/mcp-server/dist/services/browser-bench.js.map +1 -1
  28. package/mcp-server/dist/services/budget-judgments.d.ts +108 -0
  29. package/mcp-server/dist/services/budget-judgments.d.ts.map +1 -0
  30. package/mcp-server/dist/services/budget-judgments.js +153 -0
  31. package/mcp-server/dist/services/budget-judgments.js.map +1 -0
  32. package/mcp-server/dist/services/categories.d.ts +35 -2
  33. package/mcp-server/dist/services/categories.d.ts.map +1 -1
  34. package/mcp-server/dist/services/categories.js +77 -33
  35. package/mcp-server/dist/services/categories.js.map +1 -1
  36. package/mcp-server/dist/services/codex-config-heal.d.ts +5 -1
  37. package/mcp-server/dist/services/codex-config-heal.d.ts.map +1 -1
  38. package/mcp-server/dist/services/codex-config-heal.js +41 -4
  39. package/mcp-server/dist/services/codex-config-heal.js.map +1 -1
  40. package/mcp-server/dist/services/desktop-bench.d.ts +7 -7
  41. package/mcp-server/dist/services/desktop-bench.d.ts.map +1 -1
  42. package/mcp-server/dist/services/desktop-bench.js +1 -1
  43. package/mcp-server/dist/services/desktop-bench.js.map +1 -1
  44. package/mcp-server/dist/services/identity.d.ts +11 -0
  45. package/mcp-server/dist/services/identity.d.ts.map +1 -1
  46. package/mcp-server/dist/services/identity.js +24 -0
  47. package/mcp-server/dist/services/identity.js.map +1 -1
  48. package/mcp-server/dist/services/neural-interface.d.ts +13 -0
  49. package/mcp-server/dist/services/neural-interface.d.ts.map +1 -1
  50. package/mcp-server/dist/services/neural-interface.js +34 -2
  51. package/mcp-server/dist/services/neural-interface.js.map +1 -1
  52. package/mcp-server/dist/services/typesafe-config.d.ts +1 -1
  53. package/mcp-server/dist/services/typesafe-config.d.ts.map +1 -1
  54. package/mcp-server/dist/services/typesafe-config.js +4 -1
  55. package/mcp-server/dist/services/typesafe-config.js.map +1 -1
  56. package/mcp-server/dist/tools/agents.d.ts +11 -8
  57. package/mcp-server/dist/tools/agents.d.ts.map +1 -1
  58. package/mcp-server/dist/tools/agents.js +35 -14
  59. package/mcp-server/dist/tools/agents.js.map +1 -1
  60. package/mcp-server/dist/tools/bluesky.js +1 -1
  61. package/mcp-server/dist/tools/bluesky.js.map +1 -1
  62. package/mcp-server/dist/tools/browser-advanced.d.ts +1 -1
  63. package/mcp-server/dist/tools/browser-advanced.d.ts.map +1 -1
  64. package/mcp-server/dist/tools/browser-advanced.js +1 -1
  65. package/mcp-server/dist/tools/browser-advanced.js.map +1 -1
  66. package/mcp-server/dist/tools/browser-batch.d.ts +1 -1
  67. package/mcp-server/dist/tools/browser-batch.d.ts.map +1 -1
  68. package/mcp-server/dist/tools/browser-batch.js +1 -1
  69. package/mcp-server/dist/tools/browser-batch.js.map +1 -1
  70. package/mcp-server/dist/tools/browser-cheatsheet.d.ts +1 -1
  71. package/mcp-server/dist/tools/browser-cheatsheet.d.ts.map +1 -1
  72. package/mcp-server/dist/tools/browser-cheatsheet.js +1 -1
  73. package/mcp-server/dist/tools/browser-cheatsheet.js.map +1 -1
  74. package/mcp-server/dist/tools/browser-interact.d.ts +1 -1
  75. package/mcp-server/dist/tools/browser-interact.d.ts.map +1 -1
  76. package/mcp-server/dist/tools/browser-interact.js +1 -1
  77. package/mcp-server/dist/tools/browser-interact.js.map +1 -1
  78. package/mcp-server/dist/tools/browser-navigate.d.ts +1 -1
  79. package/mcp-server/dist/tools/browser-navigate.d.ts.map +1 -1
  80. package/mcp-server/dist/tools/browser-navigate.js +1 -1
  81. package/mcp-server/dist/tools/browser-navigate.js.map +1 -1
  82. package/mcp-server/dist/tools/browser-observe.d.ts +1 -1
  83. package/mcp-server/dist/tools/browser-observe.d.ts.map +1 -1
  84. package/mcp-server/dist/tools/browser-observe.js +1 -1
  85. package/mcp-server/dist/tools/browser-observe.js.map +1 -1
  86. package/mcp-server/dist/tools/card-tools.d.ts +1 -1
  87. package/mcp-server/dist/tools/card-tools.d.ts.map +1 -1
  88. package/mcp-server/dist/tools/card-tools.js +1 -1
  89. package/mcp-server/dist/tools/card-tools.js.map +1 -1
  90. package/mcp-server/dist/tools/category.d.ts +1 -1
  91. package/mcp-server/dist/tools/category.d.ts.map +1 -1
  92. package/mcp-server/dist/tools/category.js +5 -1
  93. package/mcp-server/dist/tools/category.js.map +1 -1
  94. package/mcp-server/dist/tools/choice.d.ts +1 -1
  95. package/mcp-server/dist/tools/choice.d.ts.map +1 -1
  96. package/mcp-server/dist/tools/choice.js +1 -1
  97. package/mcp-server/dist/tools/choice.js.map +1 -1
  98. package/mcp-server/dist/tools/computer.d.ts +1 -1
  99. package/mcp-server/dist/tools/computer.d.ts.map +1 -1
  100. package/mcp-server/dist/tools/computer.js +1 -1
  101. package/mcp-server/dist/tools/computer.js.map +1 -1
  102. package/mcp-server/dist/tools/discord-channel.d.ts +1 -1
  103. package/mcp-server/dist/tools/discord-channel.d.ts.map +1 -1
  104. package/mcp-server/dist/tools/discord-channel.js +1 -1
  105. package/mcp-server/dist/tools/discord-channel.js.map +1 -1
  106. package/mcp-server/dist/tools/discord-guild.d.ts +1 -1
  107. package/mcp-server/dist/tools/discord-guild.d.ts.map +1 -1
  108. package/mcp-server/dist/tools/discord-guild.js +1 -1
  109. package/mcp-server/dist/tools/discord-guild.js.map +1 -1
  110. package/mcp-server/dist/tools/discord-member.d.ts +1 -1
  111. package/mcp-server/dist/tools/discord-member.d.ts.map +1 -1
  112. package/mcp-server/dist/tools/discord-member.js +1 -1
  113. package/mcp-server/dist/tools/discord-member.js.map +1 -1
  114. package/mcp-server/dist/tools/discord-message.d.ts +1 -1
  115. package/mcp-server/dist/tools/discord-message.d.ts.map +1 -1
  116. package/mcp-server/dist/tools/discord-message.js +1 -1
  117. package/mcp-server/dist/tools/discord-message.js.map +1 -1
  118. package/mcp-server/dist/tools/discord-onboarding.d.ts +1 -1
  119. package/mcp-server/dist/tools/discord-onboarding.d.ts.map +1 -1
  120. package/mcp-server/dist/tools/discord-onboarding.js +1 -1
  121. package/mcp-server/dist/tools/discord-onboarding.js.map +1 -1
  122. package/mcp-server/dist/tools/discord-role.d.ts +1 -1
  123. package/mcp-server/dist/tools/discord-role.d.ts.map +1 -1
  124. package/mcp-server/dist/tools/discord-role.js +1 -1
  125. package/mcp-server/dist/tools/discord-role.js.map +1 -1
  126. package/mcp-server/dist/tools/discord-thread.d.ts +1 -1
  127. package/mcp-server/dist/tools/discord-thread.d.ts.map +1 -1
  128. package/mcp-server/dist/tools/discord-thread.js +1 -1
  129. package/mcp-server/dist/tools/discord-thread.js.map +1 -1
  130. package/mcp-server/dist/tools/discord-webhook.d.ts +1 -1
  131. package/mcp-server/dist/tools/discord-webhook.d.ts.map +1 -1
  132. package/mcp-server/dist/tools/discord-webhook.js +1 -1
  133. package/mcp-server/dist/tools/discord-webhook.js.map +1 -1
  134. package/mcp-server/dist/tools/fb-groups.d.ts +1 -1
  135. package/mcp-server/dist/tools/fb-groups.d.ts.map +1 -1
  136. package/mcp-server/dist/tools/fb-groups.js +1 -1
  137. package/mcp-server/dist/tools/fb-groups.js.map +1 -1
  138. package/mcp-server/dist/tools/forget.d.ts +1 -1
  139. package/mcp-server/dist/tools/forget.d.ts.map +1 -1
  140. package/mcp-server/dist/tools/forget.js +1 -1
  141. package/mcp-server/dist/tools/forget.js.map +1 -1
  142. package/mcp-server/dist/tools/git-tools.d.ts +1 -1
  143. package/mcp-server/dist/tools/git-tools.d.ts.map +1 -1
  144. package/mcp-server/dist/tools/git-tools.js +1 -1
  145. package/mcp-server/dist/tools/git-tools.js.map +1 -1
  146. package/mcp-server/dist/tools/gsc/experience.d.ts +1 -1
  147. package/mcp-server/dist/tools/gsc/experience.d.ts.map +1 -1
  148. package/mcp-server/dist/tools/gsc/experience.js +1 -1
  149. package/mcp-server/dist/tools/gsc/experience.js.map +1 -1
  150. package/mcp-server/dist/tools/gsc/indexing.d.ts +1 -1
  151. package/mcp-server/dist/tools/gsc/indexing.d.ts.map +1 -1
  152. package/mcp-server/dist/tools/gsc/indexing.js +1 -1
  153. package/mcp-server/dist/tools/gsc/indexing.js.map +1 -1
  154. package/mcp-server/dist/tools/gsc/inspect.d.ts +1 -1
  155. package/mcp-server/dist/tools/gsc/inspect.d.ts.map +1 -1
  156. package/mcp-server/dist/tools/gsc/inspect.js +1 -1
  157. package/mcp-server/dist/tools/gsc/inspect.js.map +1 -1
  158. package/mcp-server/dist/tools/gsc/navigate.d.ts +1 -1
  159. package/mcp-server/dist/tools/gsc/navigate.d.ts.map +1 -1
  160. package/mcp-server/dist/tools/gsc/navigate.js +1 -1
  161. package/mcp-server/dist/tools/gsc/navigate.js.map +1 -1
  162. package/mcp-server/dist/tools/gsc/performance.d.ts +1 -1
  163. package/mcp-server/dist/tools/gsc/performance.d.ts.map +1 -1
  164. package/mcp-server/dist/tools/gsc/performance.js +1 -1
  165. package/mcp-server/dist/tools/gsc/performance.js.map +1 -1
  166. package/mcp-server/dist/tools/gsc/settings.d.ts +1 -1
  167. package/mcp-server/dist/tools/gsc/settings.d.ts.map +1 -1
  168. package/mcp-server/dist/tools/gsc/settings.js +1 -1
  169. package/mcp-server/dist/tools/gsc/settings.js.map +1 -1
  170. package/mcp-server/dist/tools/image-tools.d.ts +1 -1
  171. package/mcp-server/dist/tools/image-tools.d.ts.map +1 -1
  172. package/mcp-server/dist/tools/image-tools.js +1 -1
  173. package/mcp-server/dist/tools/image-tools.js.map +1 -1
  174. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts +1 -1
  175. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts.map +1 -1
  176. package/mcp-server/dist/tools/leonardo-browser-tools.js +1 -1
  177. package/mcp-server/dist/tools/leonardo-browser-tools.js.map +1 -1
  178. package/mcp-server/dist/tools/loop.d.ts +1 -1
  179. package/mcp-server/dist/tools/loop.d.ts.map +1 -1
  180. package/mcp-server/dist/tools/loop.js +1 -1
  181. package/mcp-server/dist/tools/loop.js.map +1 -1
  182. package/mcp-server/dist/tools/memories.d.ts +1 -1
  183. package/mcp-server/dist/tools/memories.d.ts.map +1 -1
  184. package/mcp-server/dist/tools/memories.js +1 -1
  185. package/mcp-server/dist/tools/memories.js.map +1 -1
  186. package/mcp-server/dist/tools/morelogin.d.ts +1 -1
  187. package/mcp-server/dist/tools/morelogin.d.ts.map +1 -1
  188. package/mcp-server/dist/tools/morelogin.js +1 -1
  189. package/mcp-server/dist/tools/morelogin.js.map +1 -1
  190. package/mcp-server/dist/tools/profile.d.ts +1 -1
  191. package/mcp-server/dist/tools/profile.d.ts.map +1 -1
  192. package/mcp-server/dist/tools/profile.js +1 -1
  193. package/mcp-server/dist/tools/profile.js.map +1 -1
  194. package/mcp-server/dist/tools/recall.d.ts +1 -1
  195. package/mcp-server/dist/tools/recall.d.ts.map +1 -1
  196. package/mcp-server/dist/tools/recall.js +1 -1
  197. package/mcp-server/dist/tools/recall.js.map +1 -1
  198. package/mcp-server/dist/tools/reflect.d.ts +1 -1
  199. package/mcp-server/dist/tools/reflect.d.ts.map +1 -1
  200. package/mcp-server/dist/tools/reflect.js +1 -1
  201. package/mcp-server/dist/tools/reflect.js.map +1 -1
  202. package/mcp-server/dist/tools/remember.d.ts +1 -1
  203. package/mcp-server/dist/tools/remember.d.ts.map +1 -1
  204. package/mcp-server/dist/tools/remember.js +13 -11
  205. package/mcp-server/dist/tools/remember.js.map +1 -1
  206. package/mcp-server/dist/tools/restore.d.ts +1 -1
  207. package/mcp-server/dist/tools/restore.d.ts.map +1 -1
  208. package/mcp-server/dist/tools/restore.js +1 -1
  209. package/mcp-server/dist/tools/restore.js.map +1 -1
  210. package/mcp-server/dist/tools/style-guide-tools.d.ts +1 -1
  211. package/mcp-server/dist/tools/style-guide-tools.d.ts.map +1 -1
  212. package/mcp-server/dist/tools/style-guide-tools.js +1 -1
  213. package/mcp-server/dist/tools/style-guide-tools.js.map +1 -1
  214. package/mcp-server/dist/tools/sync.d.ts +1 -1
  215. package/mcp-server/dist/tools/sync.d.ts.map +1 -1
  216. package/mcp-server/dist/tools/sync.js +1 -1
  217. package/mcp-server/dist/tools/sync.js.map +1 -1
  218. package/mcp-server/dist/tools/tictactoe-tools.d.ts +1 -1
  219. package/mcp-server/dist/tools/tictactoe-tools.d.ts.map +1 -1
  220. package/mcp-server/dist/tools/tictactoe-tools.js +1 -1
  221. package/mcp-server/dist/tools/tictactoe-tools.js.map +1 -1
  222. package/mcp-server/dist/tools/utils.d.ts +1 -1
  223. package/mcp-server/dist/tools/utils.d.ts.map +1 -1
  224. package/mcp-server/dist/tools/utils.js +1 -1
  225. package/mcp-server/dist/tools/utils.js.map +1 -1
  226. package/mcp-server/dist/tools/whatsapp-send-file.d.ts +17 -0
  227. package/mcp-server/dist/tools/whatsapp-send-file.d.ts.map +1 -0
  228. package/mcp-server/dist/tools/whatsapp-send-file.js +44 -0
  229. package/mcp-server/dist/tools/whatsapp-send-file.js.map +1 -0
  230. package/mcp-server/dist/tools/whiteboard-tools.d.ts +3 -3
  231. package/mcp-server/dist/tools/whiteboard-tools.d.ts.map +1 -1
  232. package/mcp-server/dist/tools/whiteboard-tools.js +1 -1
  233. package/mcp-server/dist/tools/whiteboard-tools.js.map +1 -1
  234. package/mcp-server/dist/tools/youtube/analytics.d.ts +1 -1
  235. package/mcp-server/dist/tools/youtube/analytics.d.ts.map +1 -1
  236. package/mcp-server/dist/tools/youtube/analytics.js +1 -1
  237. package/mcp-server/dist/tools/youtube/analytics.js.map +1 -1
  238. package/mcp-server/dist/tools/youtube/download.d.ts +1 -1
  239. package/mcp-server/dist/tools/youtube/download.d.ts.map +1 -1
  240. package/mcp-server/dist/tools/youtube/download.js +1 -1
  241. package/mcp-server/dist/tools/youtube/download.js.map +1 -1
  242. package/mcp-server/dist/tools/youtube/media.d.ts +1 -1
  243. package/mcp-server/dist/tools/youtube/media.d.ts.map +1 -1
  244. package/mcp-server/dist/tools/youtube/media.js +1 -1
  245. package/mcp-server/dist/tools/youtube/media.js.map +1 -1
  246. package/mcp-server/dist/tools/youtube/metadata.d.ts +1 -1
  247. package/mcp-server/dist/tools/youtube/metadata.d.ts.map +1 -1
  248. package/mcp-server/dist/tools/youtube/metadata.js +1 -1
  249. package/mcp-server/dist/tools/youtube/metadata.js.map +1 -1
  250. package/mcp-server/dist/tools/youtube/navigate.d.ts +1 -1
  251. package/mcp-server/dist/tools/youtube/navigate.d.ts.map +1 -1
  252. package/mcp-server/dist/tools/youtube/navigate.js +1 -1
  253. package/mcp-server/dist/tools/youtube/navigate.js.map +1 -1
  254. package/mcp-server/dist/tools/youtube/playlist.d.ts +1 -1
  255. package/mcp-server/dist/tools/youtube/playlist.d.ts.map +1 -1
  256. package/mcp-server/dist/tools/youtube/playlist.js +1 -1
  257. package/mcp-server/dist/tools/youtube/playlist.js.map +1 -1
  258. package/mcp-server/dist/tools/youtube/schedule.d.ts +1 -1
  259. package/mcp-server/dist/tools/youtube/schedule.d.ts.map +1 -1
  260. package/mcp-server/dist/tools/youtube/schedule.js +1 -1
  261. package/mcp-server/dist/tools/youtube/schedule.js.map +1 -1
  262. package/mcp-server/dist/tools/youtube/source.d.ts +1 -1
  263. package/mcp-server/dist/tools/youtube/source.d.ts.map +1 -1
  264. package/mcp-server/dist/tools/youtube/source.js +1 -1
  265. package/mcp-server/dist/tools/youtube/source.js.map +1 -1
  266. package/mcp-server/dist/tools/youtube/upload.d.ts +1 -1
  267. package/mcp-server/dist/tools/youtube/upload.d.ts.map +1 -1
  268. package/mcp-server/dist/tools/youtube/upload.js +4 -9
  269. package/mcp-server/dist/tools/youtube/upload.js.map +1 -1
  270. package/mcp-server/dist/tui.js +18 -5
  271. package/mcp-server/dist/tui.js.map +1 -1
  272. package/mcp-server/dist/version.d.ts +5 -0
  273. package/mcp-server/dist/version.d.ts.map +1 -0
  274. package/mcp-server/dist/version.js +21 -0
  275. package/mcp-server/dist/version.js.map +1 -0
  276. package/mcp-server/package-lock.json +3 -3
  277. package/mcp-server/package.json +3 -3
  278. package/mcp-server/run.mjs +15 -9
  279. package/mcp-server/src/http.ts +18 -3
  280. package/mcp-server/src/index.ts +9 -6
  281. package/mcp-server/src/services/browser-bench.ts +1 -1
  282. package/mcp-server/src/services/budget-judgments.ts +183 -0
  283. package/mcp-server/src/services/categories.ts +77 -32
  284. package/mcp-server/src/services/codex-config-heal.ts +35 -4
  285. package/mcp-server/src/services/desktop-bench.ts +1 -1
  286. package/mcp-server/src/services/identity.ts +27 -0
  287. package/mcp-server/src/services/neural-interface.ts +34 -2
  288. package/mcp-server/src/services/typesafe-config.ts +4 -1
  289. package/mcp-server/src/tools/agents.ts +34 -15
  290. package/mcp-server/src/tools/bluesky.ts +1 -1
  291. package/mcp-server/src/tools/browser-advanced.ts +1 -1
  292. package/mcp-server/src/tools/browser-batch.ts +1 -1
  293. package/mcp-server/src/tools/browser-cheatsheet.ts +1 -1
  294. package/mcp-server/src/tools/browser-interact.ts +1 -1
  295. package/mcp-server/src/tools/browser-navigate.ts +1 -1
  296. package/mcp-server/src/tools/browser-observe.ts +1 -1
  297. package/mcp-server/src/tools/card-tools.ts +1 -1
  298. package/mcp-server/src/tools/category.ts +6 -1
  299. package/mcp-server/src/tools/choice.ts +1 -1
  300. package/mcp-server/src/tools/computer.ts +1 -1
  301. package/mcp-server/src/tools/discord-channel.ts +1 -1
  302. package/mcp-server/src/tools/discord-guild.ts +1 -1
  303. package/mcp-server/src/tools/discord-member.ts +1 -1
  304. package/mcp-server/src/tools/discord-message.ts +1 -1
  305. package/mcp-server/src/tools/discord-onboarding.ts +1 -1
  306. package/mcp-server/src/tools/discord-role.ts +1 -1
  307. package/mcp-server/src/tools/discord-thread.ts +1 -1
  308. package/mcp-server/src/tools/discord-webhook.ts +1 -1
  309. package/mcp-server/src/tools/fb-groups.ts +1 -1
  310. package/mcp-server/src/tools/forget.ts +1 -1
  311. package/mcp-server/src/tools/git-tools.ts +1 -1
  312. package/mcp-server/src/tools/gsc/experience.ts +1 -1
  313. package/mcp-server/src/tools/gsc/indexing.ts +1 -1
  314. package/mcp-server/src/tools/gsc/inspect.ts +1 -1
  315. package/mcp-server/src/tools/gsc/navigate.ts +1 -1
  316. package/mcp-server/src/tools/gsc/performance.ts +1 -1
  317. package/mcp-server/src/tools/gsc/settings.ts +1 -1
  318. package/mcp-server/src/tools/image-tools.ts +1 -1
  319. package/mcp-server/src/tools/leonardo-browser-tools.ts +1 -1
  320. package/mcp-server/src/tools/loop.ts +1 -1
  321. package/mcp-server/src/tools/memories.ts +1 -1
  322. package/mcp-server/src/tools/morelogin.ts +1 -1
  323. package/mcp-server/src/tools/profile.ts +1 -1
  324. package/mcp-server/src/tools/recall.ts +1 -1
  325. package/mcp-server/src/tools/reflect.ts +1 -1
  326. package/mcp-server/src/tools/remember.ts +13 -12
  327. package/mcp-server/src/tools/restore.ts +1 -1
  328. package/mcp-server/src/tools/style-guide-tools.ts +1 -1
  329. package/mcp-server/src/tools/sync.ts +1 -1
  330. package/mcp-server/src/tools/tictactoe-tools.ts +1 -1
  331. package/mcp-server/src/tools/utils.ts +1 -1
  332. package/mcp-server/src/tools/whatsapp-send-file.ts +51 -0
  333. package/mcp-server/src/tools/whiteboard-tools.ts +1 -1
  334. package/mcp-server/src/tools/youtube/analytics.ts +1 -1
  335. package/mcp-server/src/tools/youtube/download.ts +1 -1
  336. package/mcp-server/src/tools/youtube/media.ts +1 -1
  337. package/mcp-server/src/tools/youtube/metadata.ts +1 -1
  338. package/mcp-server/src/tools/youtube/navigate.ts +1 -1
  339. package/mcp-server/src/tools/youtube/playlist.ts +1 -1
  340. package/mcp-server/src/tools/youtube/schedule.ts +1 -1
  341. package/mcp-server/src/tools/youtube/source.ts +1 -1
  342. package/mcp-server/src/tools/youtube/upload.ts +4 -12
  343. package/mcp-server/src/tui.ts +24 -10
  344. package/mcp-server/src/version.ts +22 -0
  345. package/neural-interface/i18n/en.json +645 -57
  346. package/neural-interface/i18n/pt-BR.json +644 -56
  347. package/neural-interface/lib/account-usage.js +163 -0
  348. package/neural-interface/lib/agent-sandbox-elevation.js +102 -0
  349. package/neural-interface/lib/agent-sandbox-setting.js +57 -0
  350. package/neural-interface/lib/assistant-api.js +274 -52
  351. package/neural-interface/lib/assistant-brains/claude.js +15 -2
  352. package/neural-interface/lib/assistant-brains/codex.js +3 -0
  353. package/neural-interface/lib/assistant-brains/opencode.js +17 -4
  354. package/neural-interface/lib/assistant-budget-planner.js +390 -0
  355. package/neural-interface/lib/assistant-budget-split.js +408 -0
  356. package/neural-interface/lib/assistant-budget.js +94 -95
  357. package/neural-interface/lib/assistant-config.js +62 -14
  358. package/neural-interface/lib/assistant-dispatch.js +432 -125
  359. package/neural-interface/lib/assistant-jev.js +26 -3
  360. package/neural-interface/lib/assistant-persona.js +68 -11
  361. package/neural-interface/lib/assistant-plan-permissions.js +8 -1
  362. package/neural-interface/lib/assistant-route-accounts.js +14 -0
  363. package/neural-interface/lib/assistant-route-gate-codex.js +3 -1
  364. package/neural-interface/lib/assistant-route-gate.js +19 -3
  365. package/neural-interface/lib/assistant-router.js +373 -42
  366. package/neural-interface/lib/assistant-runtime.js +312 -48
  367. package/neural-interface/lib/assistant-user-writer.js +4 -2
  368. package/neural-interface/lib/augmented-path.js +317 -53
  369. package/neural-interface/lib/claude-accounts.js +342 -31
  370. package/neural-interface/lib/claude-agent-bridge.js +90 -3
  371. package/neural-interface/lib/claude-executable.js +6 -1
  372. package/neural-interface/lib/claude-model-catalog.js +3 -3
  373. package/neural-interface/lib/claude-panel-auth.js +221 -0
  374. package/neural-interface/lib/claude-profile-api-key.js +62 -0
  375. package/neural-interface/lib/cli-install-api.js +137 -0
  376. package/neural-interface/lib/cli-install.js +797 -0
  377. package/neural-interface/lib/cli-path.js +130 -0
  378. package/neural-interface/lib/cli-resolver.js +744 -0
  379. package/neural-interface/lib/cli-update-planner.js +143 -7
  380. package/neural-interface/lib/codex-account-auth.js +180 -0
  381. package/neural-interface/lib/codex-accounts.js +502 -0
  382. package/neural-interface/lib/codex-capabilities.js +2 -1
  383. package/neural-interface/lib/codex-compat-rpc.js +8 -2
  384. package/neural-interface/lib/codex-mcp-approvals.js +5 -1
  385. package/neural-interface/lib/codex-panel-auth.js +62 -0
  386. package/neural-interface/lib/codex-session-settings.js +1 -1
  387. package/neural-interface/lib/codex-settings-schema.js +122 -0
  388. package/neural-interface/lib/desktop/config.js +3 -0
  389. package/neural-interface/lib/exec-loop-command.js +3 -1
  390. package/neural-interface/lib/git-bash/bzip2.js +339 -0
  391. package/neural-interface/lib/git-bash/claude-settings.js +73 -0
  392. package/neural-interface/lib/git-bash/extract-worker.js +34 -0
  393. package/neural-interface/lib/git-bash/install.js +529 -0
  394. package/neural-interface/lib/git-bash/licenses/COPYING +360 -0
  395. package/neural-interface/lib/git-bash/licenses/LGPL-2.1 +511 -0
  396. package/neural-interface/lib/git-bash/manager.js +268 -0
  397. package/neural-interface/lib/git-bash/pins.js +206 -0
  398. package/neural-interface/lib/git-bash/pins.json +34 -0
  399. package/neural-interface/lib/git-bash/resolver.js +194 -0
  400. package/neural-interface/lib/git-read.js +34 -2
  401. package/neural-interface/lib/install-details.js +163 -0
  402. package/neural-interface/lib/mcp-installer.js +14 -2
  403. package/neural-interface/lib/native-loop-providers.js +22 -4
  404. package/neural-interface/lib/native-loop-runtime.js +9 -4
  405. package/neural-interface/lib/os-path.js +319 -0
  406. package/neural-interface/lib/provider-panel-api-key-auth.js +92 -0
  407. package/neural-interface/lib/provider-panel-terminal-auth.js +96 -0
  408. package/neural-interface/lib/pty-host/core.js +2 -1
  409. package/neural-interface/lib/pty-host/manager.js +27 -2
  410. package/neural-interface/lib/remote-policy.js +20 -11
  411. package/neural-interface/lib/session-indexer.js +3 -1
  412. package/neural-interface/lib/session-title-generator.js +6 -3
  413. package/neural-interface/lib/system-about.js +340 -0
  414. package/neural-interface/lib/system-activity.js +66 -0
  415. package/neural-interface/lib/terminal-env.js +11 -3
  416. package/neural-interface/lib/terminal-path.js +55 -0
  417. package/neural-interface/lib/virtual-socket.js +12 -1
  418. package/neural-interface/lib/whatsapp/baileys-adapter.js +165 -45
  419. package/neural-interface/lib/whatsapp/bridge.js +78 -34
  420. package/neural-interface/lib/whatsapp/commands.js +13 -14
  421. package/neural-interface/lib/whatsapp/config.js +134 -20
  422. package/neural-interface/lib/whatsapp/fake-baileys.js +99 -14
  423. package/neural-interface/lib/whatsapp/host-core.js +168 -35
  424. package/neural-interface/lib/whatsapp/inbound.js +5 -3
  425. package/neural-interface/lib/whatsapp/local-file.js +524 -0
  426. package/neural-interface/lib/whatsapp/manager.js +92 -32
  427. package/neural-interface/lib/whatsapp/paths.js +11 -1
  428. package/neural-interface/lib/whatsapp/protocol.js +65 -5
  429. package/neural-interface/lib/whatsapp/redact.js +63 -0
  430. package/neural-interface/lib/whatsapp/service.js +343 -91
  431. package/neural-interface/lib/whatsapp/transcription.js +463 -0
  432. package/neural-interface/package-lock.json +2 -2
  433. package/neural-interface/package.json +1 -1
  434. package/neural-interface/public/index.html +2 -0
  435. package/neural-interface/public/index2d.html +2 -0
  436. package/neural-interface/public/offline.html +16 -1
  437. package/neural-interface/public/onboarding.html +96 -2
  438. package/neural-interface/public/shared/account-i18n.js +7 -0
  439. package/neural-interface/public/shared/account-menu.js +542 -0
  440. package/neural-interface/public/shared/account-usage.js +79 -0
  441. package/neural-interface/public/shared/account-view.js +336 -0
  442. package/neural-interface/public/shared/agent-runtime-options.js +28 -8
  443. package/neural-interface/public/shared/assistant/asst-account-menu.js +298 -0
  444. package/neural-interface/public/shared/assistant/asst-accounts.js +182 -184
  445. package/neural-interface/public/shared/assistant/asst-api.js +39 -2
  446. package/neural-interface/public/shared/assistant/asst-brain-picker.js +288 -32
  447. package/neural-interface/public/shared/assistant/asst-budget.js +259 -303
  448. package/neural-interface/public/shared/assistant/asst-mascot.js +126 -7
  449. package/neural-interface/public/shared/assistant/asst-menu.js +219 -80
  450. package/neural-interface/public/shared/assistant/asst-model-chip.js +135 -0
  451. package/neural-interface/public/shared/assistant/asst-panel.js +87 -16
  452. package/neural-interface/public/shared/assistant/asst-render.js +38 -7
  453. package/neural-interface/public/shared/assistant/asst-route.js +72 -14
  454. package/neural-interface/public/shared/assistant/asst-routes-editor.js +45 -6
  455. package/neural-interface/public/shared/assistant/asst-slash.js +1 -1
  456. package/neural-interface/public/shared/assistant/asst-state.js +1 -1
  457. package/neural-interface/public/shared/assistant/asst-styles.js +160 -29
  458. package/neural-interface/public/shared/cdx/cdx-commands.js +4 -1
  459. package/neural-interface/public/shared/cdx/cdx-features.js +22 -14
  460. package/neural-interface/public/shared/cdx/cdx-icons.js +2 -0
  461. package/neural-interface/public/shared/cdx/cdx-panel.js +49 -108
  462. package/neural-interface/public/shared/cdx/cdx-settings.js +231 -0
  463. package/neural-interface/public/shared/cdx/cdx-styles.js +172 -111
  464. package/neural-interface/public/shared/cdx/cdx-tabs.js +264 -664
  465. package/neural-interface/public/shared/cdx/cdx-ws.js +2 -0
  466. package/neural-interface/public/shared/claude-account-view.js +3 -0
  467. package/neural-interface/public/shared/cli-install-view.js +392 -0
  468. package/neural-interface/public/shared/cli-status.js +282 -22
  469. package/neural-interface/public/shared/cp/cp-events.js +2 -1
  470. package/neural-interface/public/shared/cp/cp-styles.js +46 -0
  471. package/neural-interface/public/shared/desktop-bridge.js +39 -0
  472. package/neural-interface/public/shared/desktop-titlebar-page.js +59 -0
  473. package/neural-interface/public/shared/desktop-titlebar-view.js +122 -0
  474. package/neural-interface/public/shared/desktop-titlebar.js +153 -0
  475. package/neural-interface/public/shared/desktop-update-view.js +462 -0
  476. package/neural-interface/public/shared/editor/editor-panel.js +1 -1
  477. package/neural-interface/public/shared/explorer/fx-main.js +1 -1
  478. package/neural-interface/public/shared/git-bash-view.js +145 -0
  479. package/neural-interface/public/shared/html-shell.js +1 -0
  480. package/neural-interface/public/shared/i18n.js +19 -1
  481. package/neural-interface/public/shared/install-details-view.js +86 -0
  482. package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +4 -1
  483. package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +36 -1
  484. package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +17 -0
  485. package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +169 -2
  486. package/neural-interface/public/shared/pwa-install-page.js +3 -1
  487. package/neural-interface/public/shared/settings/settings-about-pane.js +271 -0
  488. package/neural-interface/public/shared/settings/settings-about.js +254 -0
  489. package/neural-interface/public/shared/settings/settings-ia.js +15 -0
  490. package/neural-interface/public/shared/showcase-privacy.js +490 -0
  491. package/neural-interface/public/shared/storage.js +30 -3
  492. package/neural-interface/public/shared/styles.css +281 -32
  493. package/neural-interface/public/shared/synabun-mascot.js +48 -2
  494. package/neural-interface/public/shared/ui-claude-panel.js +262 -217
  495. package/neural-interface/public/shared/ui-cli-banner.js +355 -0
  496. package/neural-interface/public/shared/ui-explorer.js +2 -0
  497. package/neural-interface/public/shared/ui-git-bash.js +124 -0
  498. package/neural-interface/public/shared/ui-judgments.js +10 -1
  499. package/neural-interface/public/shared/ui-loading.js +30 -6
  500. package/neural-interface/public/shared/ui-menubar.js +13 -3
  501. package/neural-interface/public/shared/ui-navbar.js +3 -1
  502. package/neural-interface/public/shared/ui-provider-auth.js +104 -0
  503. package/neural-interface/public/shared/ui-provider-terminal-auth.js +223 -0
  504. package/neural-interface/public/shared/ui-sessions.js +9 -3
  505. package/neural-interface/public/shared/ui-settings.js +55 -3
  506. package/neural-interface/public/shared/ui-sidepanel-sessions.js +3 -1
  507. package/neural-interface/public/shared/ui-sync.js +8 -0
  508. package/neural-interface/public/shared/ui-terminal.js +17 -0
  509. package/neural-interface/public/shared/ui-tool-updates.js +5 -0
  510. package/neural-interface/public/shared/ui-update.js +598 -7
  511. package/neural-interface/public/shared/ui-whatsapp.js +21 -6
  512. package/neural-interface/public/shared/whatsapp/wa-view.js +51 -8
  513. package/neural-interface/public/shared/worker-end.js +2 -0
  514. package/neural-interface/public/sw.js +1 -1
  515. package/neural-interface/public/variant/2d/main.js +10 -1
  516. package/neural-interface/public/variant/3d/main.js +10 -1
  517. package/neural-interface/scripts/rebuild-pty.js +14 -2
  518. package/neural-interface/server.js +1384 -679
  519. package/npm-shrinkwrap.json +4424 -0
  520. package/package.json +57 -2
  521. package/postinstall.js +61 -47
  522. package/preuninstall.js +8 -35
  523. package/setup.js +80 -47
  524. package/skills/synabun/modules/idea.md +1 -1
  525. package/skills/synabun/modules/schedule.md +1 -1
  526. package/updater.cmd +2 -2
  527. package/updater.mjs +97 -3
@@ -174,11 +174,29 @@ export function getLocaleChoice() {
174
174
  return matchLocale(saved) || SYSTEM_LOCALE;
175
175
  }
176
176
 
177
+ /**
178
+ * The locale the page address asks for with `?lang=<tag>`, matched like a stored choice
179
+ * ('pt' → 'pt-BR'), or null (no tag, or one no locale answers). It holds for this page
180
+ * load only and is never stored: showcase captures use it to get an English UI without
181
+ * touching the user's own choice.
182
+ */
183
+ export function getAddressLocale() {
184
+ const search = globalThis.window?.location?.search;
185
+ if (!search) return null;
186
+ try {
187
+ return matchLocale(new URLSearchParams(search).get('lang'));
188
+ } catch {
189
+ return null;
190
+ }
191
+ }
192
+
177
193
  /**
178
194
  * Detect the user's preferred locale.
179
- * Priority: stored explicit choice → system language → 'en'
195
+ * Priority: the page address (?lang=) → stored explicit choice → system language → 'en'
180
196
  */
181
197
  function detectLocale() {
198
+ const address = getAddressLocale();
199
+ if (address) return address;
182
200
  const choice = getLocaleChoice();
183
201
  return choice === SYSTEM_LOCALE ? getSystemLocale() : choice;
184
202
  }
@@ -0,0 +1,86 @@
1
+ // ═══════════════════════════════════════════
2
+ // SynaBun Neural Interface — the setup wizard's Details: what they say
3
+ // ═══════════════════════════════════════════
4
+ //
5
+ // Inside the SynaBun desktop app, the setup wizard (onboarding.html) shows
6
+ // what it checked and what this copy has, step by step, in a Details area
7
+ // under Environment Check and under Install & Build: the commands SynaBun ran
8
+ // and what they answered, where `npm i -g` puts packages, and every part's
9
+ // dependencies with the version installed. The facts are
10
+ // GET /api/setup/install-details (lib/install-details.js); this turns them into
11
+ // the lines shown. English, like the rest of the wizard.
12
+ //
13
+ // No imports and no DOM: `node --test` loads this file as it is
14
+ // (tests/install-details-view.test.mjs).
15
+
16
+ const said = (tool) => (tool.ok ? tool.output || '(no answer)' : `did not run: ${tool.output || 'no output'}`);
17
+
18
+ /** Environment Check: the Node.js SynaBun runs on, its npm and npx (the command and the answer), and the user's own npm. */
19
+ export function environmentLines(details) {
20
+ if (!details || typeof details !== 'object') return [];
21
+ const lines = [];
22
+ const node = details.node;
23
+ if (node) {
24
+ lines.push('$ node --version');
25
+ lines.push(`${node.version} ${node.path}${node.bundled ? ' (the Node.js that came with SynaBun)' : ''}`);
26
+ }
27
+ for (const name of ['npm', 'npx']) {
28
+ const tool = details[name];
29
+ if (!tool) { lines.push(`${name}: not found`); continue; }
30
+ lines.push(`$ ${tool.command}`);
31
+ lines.push(`${said(tool)}${tool.ok && tool.bundled ? ' (came with SynaBun)' : ''}`);
32
+ }
33
+ const prefix = details.globalPrefix;
34
+ if (prefix?.path) {
35
+ const setIn = prefix.from === 'npm_config_prefix' ? ', from npm_config_prefix' : prefix.from ? `, set in ${prefix.from}` : '';
36
+ const why = prefix.source === 'user' ? `your own npm prefix${setIn}` : 'a folder of SynaBun\'s, outside the app';
37
+ lines.push(`npm i -g installs into ${prefix.path} (${why})${prefix.bin ? `, commands in ${prefix.bin}` : ''}`);
38
+ }
39
+ if (details.kind === 'app') {
40
+ const user = details.userNpm;
41
+ lines.push(user
42
+ ? `Your own npm: ${user.path} ${user.ok ? user.output : '(did not answer)'}. SynaBun's terminals find it first.`
43
+ : 'No npm of your own: SynaBun\'s terminals use the one that came with SynaBun.');
44
+ }
45
+ return lines;
46
+ }
47
+
48
+ /** One part's packages: how many, then each dependency with the version installed. */
49
+ function partLines(part, bundled) {
50
+ const lines = [`${part.name}: ${part.packages} package${part.packages === 1 ? '' : 's'} installed${bundled ? ' (came with SynaBun)' : ''}`];
51
+ for (const dep of part.dependencies || []) {
52
+ lines.push(` ${dep.name} ${dep.installed || `not installed (wants ${dep.wanted})`}`);
53
+ }
54
+ return lines;
55
+ }
56
+
57
+ /** Install & Build: what this copy has, from the runtime to every dependency, and what is still to come. */
58
+ export function installLines(details) {
59
+ if (!details || typeof details !== 'object') return [];
60
+ const app = details.kind === 'app';
61
+ const lines = [];
62
+ if (app) {
63
+ const where = details.app?.target ? ` for ${details.app.target}` : '';
64
+ lines.push(`SynaBun ${details.app?.version || ''}${where}: nothing to install, this copy came with its dependencies.`.replace(/\s+:/, ':'));
65
+ }
66
+ if (details.node) {
67
+ const npm = details.npm?.ok ? `, npm ${details.npm.output}` : '';
68
+ const npx = details.npx?.ok ? `, npx ${details.npx.output}` : '';
69
+ lines.push(`Node.js ${String(details.node.version).replace(/^v/, '')}${npm}${npx}${details.node.bundled ? ' (the runtime that came with SynaBun)' : ''}`);
70
+ }
71
+ for (const part of details.parts || []) lines.push(...partLines(part, app));
72
+ lines.push(details.mcp?.built ? `MCP server: built (${details.mcp.file})` : 'MCP server: not built yet');
73
+ const bundled = details.bundled;
74
+ if (bundled) {
75
+ lines.push(bundled.embeddingModel ? `Local embedding model: ${bundled.embeddingModel} (came with SynaBun)` : 'Local embedding model: not included (keyword recall only)');
76
+ if (bundled.cloudflared) lines.push(`cloudflared ${bundled.cloudflared}, for invite links and remote MCP (came with SynaBun)`);
77
+ if (bundled.gitBash) lines.push(`Git for Windows ${bundled.gitBash}, the Git Bash Claude Code needs (came with SynaBun)`);
78
+ if (details.app?.electron) lines.push(`The window: Electron ${details.app.electron}`);
79
+ }
80
+ if (details.browser) {
81
+ lines.push(details.browser.installed
82
+ ? `Automation browser (Chromium for Playwright): installed, ${details.browser.path}`
83
+ : 'Automation browser (Chromium for Playwright): not downloaded yet; SynaBun downloads it at its next start.');
84
+ }
85
+ return lines;
86
+ }
@@ -419,9 +419,12 @@ export function createChildPanel({
419
419
  _statusEl.removeAttribute('data-tooltip');
420
420
  }
421
421
  }
422
+ const title = sessionTitleFor(store);
422
423
  if (_titleEl && !_titleEl.querySelector('.ocpv2-rename-input')) {
423
- _titleEl.textContent = sessionTitleFor(store);
424
+ _titleEl.textContent = title;
424
425
  }
426
+ // The whole name, for when the header shows only part of it.
427
+ if (_titleEl?.parentElement) _titleEl.parentElement.title = title;
425
428
  if (_renameBtn) _renameBtn.disabled = !s.sessionId;
426
429
  renderCrumbs();
427
430
  renderPill();
@@ -50,6 +50,7 @@ import { registerSidepanel, syncSidepanelLayout, focusSidepanel, openAnotherSide
50
50
  import { nativeLoopWindowId } from '../ui-native-window-id.js';
51
51
  import { requestGeneratedSessionTitle } from '../session-title.js';
52
52
  import { wireFileLinks } from '../ui-file-links.js';
53
+ import { mountCliBanner } from '../ui-cli-banner.js';
53
54
  import { backToAssistant, buildWorkerEndCard, endWorkerRunOnClose, forgetWorkerEnd, trackWorkerEnd } from '../ui-worker-end.js';
54
55
  import { isDispatchedRun } from '../worker-end.js';
55
56
  import {
@@ -121,6 +122,8 @@ const _titleReassertTimers = new Map();
121
122
  // rename carries is not the session's: nothing shows it or pushes it again.
122
123
  const _pendingRenames = createPendingRenames();
123
124
  let _composer = null; // the primary panel's composer (mountCompose)
125
+ let _cliBanner = null; // the CLI banner and send-block (ui-cli-banner.js)
126
+ let _cliWasBlocked = false; // the banner held sends back last time it said (a change to usable heals the serve)
124
127
  // Where the panel goes. Every choice of the user (a tab, a session in the
125
128
  // menu, New session, a project, a worktree) begins an intent, and a navigation
126
129
  // binds the panel only while its intent is the latest one: a later choice wins
@@ -430,6 +433,30 @@ function buildPanel() {
430
433
  // path is a path in the session's directory.
431
434
  wireFileLinks(messagesContainer, { cwd: () => getState().cwd || '' });
432
435
 
436
+ // ── The CLI banner (ui-cli-banner.js) ───────────────────────────────────
437
+ // Above the transcript while OpenCode is not usable: not installed (with
438
+ // Install, which runs OpenCode's own installer or official release on the
439
+ // server), being installed, failed to install, or found but failed to start
440
+ // (with the error it gave). The panel gets `ocp-cli-blocked` meanwhile, and
441
+ // the composer holds sends back (sendBlocked below).
442
+ _cliBanner = mountCliBanner({
443
+ toolKey: 'opencode',
444
+ prefix: 'ocp',
445
+ panel: () => panel,
446
+ anchor: () => messagesContainer,
447
+ // OpenCode was installed (or found again) while its serve could not start: start it now rather than at the
448
+ // next retry of the auto-heal, whose wait has grown by then.
449
+ onBlockedChange: (blocked) => {
450
+ const usableAgain = _cliWasBlocked && !blocked;
451
+ _cliWasBlocked = blocked;
452
+ if (usableAgain && getState().serverStatus !== 'ready') {
453
+ clearTimeout(_healTimer);
454
+ _healTimer = null;
455
+ scheduleAutoHeal('cli-usable', 0);
456
+ }
457
+ },
458
+ });
459
+
433
460
  // ── What the session changed on disk (session.diff) ─────────────────────
434
461
  mountChangesBar(panel, getDefaultStore());
435
462
 
@@ -519,6 +546,10 @@ function buildPanel() {
519
546
  // (ocp-v2-binding.js): the session the prompt or the Stop was for, frozen
520
547
  // before the first await. It is never the live state.
521
548
  canSend: (session) => !_automationRunning.has(session?.sessionId),
549
+ // While the CLI banner shows (OpenCode missing, broken or being installed),
550
+ // a send stays in the box and the banner is pointed at instead.
551
+ sendBlocked: () => !!_cliBanner?.blocked(),
552
+ onSendBlocked: () => _cliBanner?.nudge(),
522
553
  onManualSend: (session, phase, meta) => {
523
554
  const sessionId = session?.sessionId;
524
555
  if (phase === 'started') requestOpenCodeSessionTitle(session, meta);
@@ -640,10 +671,13 @@ function syncHeader() {
640
671
  // The footer row gives the text only the room that is left: the tooltip
641
672
  // says it in full when just the dot fits.
642
673
  _statusEl.setAttribute('data-tooltip', status.text);
674
+ const title = sessionTitleFor(s);
643
675
  // Skip label update while user is mid-rename (input is mounted in the label).
644
676
  if (_sessionLabelEl && !_sessionLabelEl.querySelector('.ocpv2-rename-input')) {
645
- _sessionLabelEl.textContent = sessionTitleFor(s);
677
+ _sessionLabelEl.textContent = title;
646
678
  }
679
+ // The whole name, for when the header shows only part of it.
680
+ if (_sessionBtnEl) _sessionBtnEl.title = title;
647
681
  if (_renameBtnEl) {
648
682
  _renameBtnEl.disabled = !s.sessionId;
649
683
  }
@@ -2210,6 +2244,7 @@ function applyVisibility(nextVisible) {
2210
2244
  _panelEl.classList.toggle('ocpv2-open', _visible);
2211
2245
  if (_visible) {
2212
2246
  state.lastActivePanel = 'opencode';
2247
+ _cliBanner?.refresh();
2213
2248
  } else {
2214
2249
  // The popover is a child of <body>: it does not go with the panel by itself.
2215
2250
  _contextMenu?.close();
@@ -966,6 +966,16 @@ export function mountCompose(rootEl, store = getDefaultStore(), opts = {}) {
966
966
  syncButton();
967
967
  }
968
968
 
969
+ // The panel holds sends back while its CLI banner shows (opts.sendBlocked,
970
+ // ui-cli-banner.js): nothing is sent, nothing is cleared, the banner is
971
+ // pointed at. A composer mounted without the option (a sub-agent's) never is.
972
+ function sendHeldBack() {
973
+ let held = false;
974
+ try { held = !!opts.sendBlocked?.(); } catch { held = false; }
975
+ if (held) { try { opts.onSendBlocked?.(); } catch {} }
976
+ return held;
977
+ }
978
+
969
979
  function rememberPrompt(text) {
970
980
  if (!text) return;
971
981
  _history.push(text);
@@ -1038,6 +1048,7 @@ export function mountCompose(rootEl, store = getDefaultStore(), opts = {}) {
1038
1048
  // read this snapshot.
1039
1049
  const turn = captureBinding(store);
1040
1050
  if (!turn.sessionId) { store.pushError({ message: 'No session. Reopen the panel to retry.' }); return false; }
1051
+ if (sendHeldBack()) return false;
1041
1052
  if (opts.canSend && opts.canSend(turn) === false) {
1042
1053
  store.pushError({ message: 'Stop the running automation before sending a manual turn.' });
1043
1054
  return false;
@@ -1140,6 +1151,11 @@ export function mountCompose(rootEl, store = getDefaultStore(), opts = {}) {
1140
1151
  const hasPaths = (s.pendingPaths?.length || 0) > 0;
1141
1152
 
1142
1153
  if (_shell) {
1154
+ // The CLI is missing, broken or being installed (the panel's CLI banner
1155
+ // says so): the command stays in the box, in shell mode. (Prompts and
1156
+ // server commands are held back where they are sent, and come back into
1157
+ // the box from there; a local slash command needs no CLI.)
1158
+ if (sendHeldBack()) return false;
1143
1159
  // Only what the user typed (or pasted) into the shell-mode composer runs.
1144
1160
  // Anything that got into the box another way drops back to a prompt.
1145
1161
  const allowed = shellRunAllowed({ shell: _shell, value: _input.value, typedValue: _shellTypedValue });
@@ -1224,6 +1240,7 @@ export function mountCompose(rootEl, store = getDefaultStore(), opts = {}) {
1224
1240
  // first await; everything after it reads `turn`.
1225
1241
  const turn = captureBinding(store);
1226
1242
  const s = store.getState();
1243
+ if (sendHeldBack()) return false;
1227
1244
  if (opts.canSend && opts.canSend(turn) === false) {
1228
1245
  store.pushError({ message: 'Stop the running automation before sending a manual turn.' });
1229
1246
  return false;
@@ -98,8 +98,12 @@ const CSS = `
98
98
  padding: 5px 10px;
99
99
  border-radius: 8px 0 0 8px;
100
100
  transition: background 0.15s, color 0.15s;
101
- max-width: 100%;
102
- min-width: 0;
101
+ /* The session name gives way first: it starts from nothing and takes only
102
+ the room the pencil and the actions leave, up to its own width, so a long
103
+ name can never push them. 32px keeps the caret in view. */
104
+ flex: 1 1 0;
105
+ min-width: 32px;
106
+ max-width: max-content;
103
107
  overflow: hidden;
104
108
  }
105
109
  .ocpv2-session-btn:hover {
@@ -135,6 +139,7 @@ const CSS = `
135
139
  .ocpv2-rename-input:focus { border-color: rgba(100,160,255,0.5); }
136
140
  .ocpv2-rename-input::placeholder { color: rgba(255,255,255,0.3); }
137
141
  .ocpv2-session-btn .ocpv2-dd-arrow {
142
+ flex-shrink: 0;
138
143
  font-size: 9px;
139
144
  padding: 4px 6px;
140
145
  margin: -4px -6px -4px 0;
@@ -164,6 +169,8 @@ const CSS = `
164
169
  -webkit-tap-highlight-color: transparent;
165
170
  touch-action: manipulation;
166
171
  flex-shrink: 0;
172
+ /* The actions' own gap, kept when the name fills the row. */
173
+ margin-right: 3px;
167
174
  }
168
175
  .ocpv2-header-rename:hover:not(:disabled) {
169
176
  color: rgba(100,160,255,0.95);
@@ -359,6 +366,8 @@ const CSS = `
359
366
  margin-left: auto;
360
367
  flex-shrink: 0;
361
368
  }
369
+ /* The header buttons never shrink, whatever the session name's length. */
370
+ .ocpv2-actions > * { flex-shrink: 0; }
362
371
  .ocpv2-btn {
363
372
  display: flex;
364
373
  align-items: center;
@@ -2718,16 +2727,56 @@ const CHILD_CSS = `
2718
2727
  set inline via --right-panel-offset-{owner}. */
2719
2728
  border: 0.5px dashed rgba(180, 200, 255, 0.18);
2720
2729
  }
2730
+ /* A query container measured in controls: 1em is one header button (24px
2731
+ docked, the window's control size when detached, which follows the font
2732
+ scale), so the thresholds below hold at any scale. Nothing in this row
2733
+ inherits it: the crumbs and the title set their own sizes. */
2734
+ .ocpv2-panel-child > .ocpv2-header {
2735
+ container: ocpv2-child-header / inline-size;
2736
+ font-size: 24px;
2737
+ }
2738
+ .ocpv2-panel-child.sp-floating > .ocpv2-header { font-size: var(--fw-header-control-size); }
2739
+ /* The sub-agent's name keeps a readable 88px (or its own width if shorter):
2740
+ the chain of parents gives way first. */
2741
+ .ocpv2-panel-child .ocpv2-session-btn { flex: 1 0 88px; }
2742
+ /* The chain of parents: at most 40% of the row, and it gives way before the
2743
+ name. When it is cut, it is cut from the left, so the nearest parent (the
2744
+ last crumb, which keeps its own width, at most 140px) stays readable. */
2721
2745
  .ocpv2-panel-child .ocpv2-child-crumbs {
2722
2746
  display: inline-flex;
2723
2747
  align-items: center;
2748
+ justify-content: flex-end;
2724
2749
  gap: 3px;
2725
2750
  min-width: 0;
2751
+ max-width: 40%;
2726
2752
  flex-shrink: 1;
2727
2753
  overflow: hidden;
2728
2754
  margin-right: 6px;
2729
2755
  }
2730
2756
  .ocpv2-panel-child .ocpv2-child-crumbs:empty { display: none; }
2757
+ .ocpv2-panel-child .ocpv2-child-crumbs > .ocpv2-child-crumb:last-child { flex-shrink: 0; }
2758
+ /* Narrow headers, in order: with less than 140px for the chain, only the
2759
+ nearest parent shows, truncated; with less than 64px, the chain is hidden
2760
+ and the name goes down to its caret. Room counted in controls (em) plus px:
2761
+ docked, the pencil and six buttons are 7em with 18px of gaps; detached, the
2762
+ move handle makes 8em and the window's 6px gaps 42px. Thresholds: the
2763
+ name's 88px + the chain's 6px margin + 140px or 64px + that row. */
2764
+ @container ocpv2-child-header (width < calc(7em + 252px)) {
2765
+ .ocpv2-panel-child:not(.sp-floating) .ocpv2-child-crumbs > :not(:last-child) { display: none; }
2766
+ .ocpv2-panel-child:not(.sp-floating) .ocpv2-child-crumbs > .ocpv2-child-crumb:last-child { flex-shrink: 1; min-width: 0; }
2767
+ }
2768
+ @container ocpv2-child-header (width < calc(7em + 176px)) {
2769
+ .ocpv2-panel-child:not(.sp-floating) .ocpv2-child-crumbs { display: none; }
2770
+ .ocpv2-panel-child:not(.sp-floating) .ocpv2-session-btn { flex: 1 1 0; }
2771
+ }
2772
+ @container ocpv2-child-header (width < calc(8em + 276px)) {
2773
+ .ocpv2-panel-child.sp-floating .ocpv2-child-crumbs > :not(:last-child) { display: none; }
2774
+ .ocpv2-panel-child.sp-floating .ocpv2-child-crumbs > .ocpv2-child-crumb:last-child { flex-shrink: 1; min-width: 0; }
2775
+ }
2776
+ @container ocpv2-child-header (width < calc(8em + 200px)) {
2777
+ .ocpv2-panel-child.sp-floating .ocpv2-child-crumbs { display: none; }
2778
+ .ocpv2-panel-child.sp-floating .ocpv2-session-btn { flex: 1 1 0; }
2779
+ }
2731
2780
  .ocpv2-panel-child .ocpv2-child-crumb-sep {
2732
2781
  flex-shrink: 0;
2733
2782
  color: rgba(180, 200, 255, 0.4);
@@ -3567,6 +3616,124 @@ const PARITY_CSS = `
3567
3616
  .ocpv2-help-name { flex-shrink: 0; color: rgba(232,224,220,0.95); font-family: 'JetBrains Mono', ui-monospace, monospace; }
3568
3617
  .ocpv2-help-text { flex: 1; min-width: 0; color: rgba(255,255,255,0.62); overflow-wrap: anywhere; }
3569
3618
  .ocpv2-help-row .ocpv2-session-item-meta { flex-shrink: 0; margin-left: 0; }
3619
+
3620
+ /* ── CLI banner (ui-cli-banner.js): OpenCode not installed / installing / failed to start ── */
3621
+ /* Mono like the rest of the panel; the panel's own amber, error red and green. */
3622
+ .ocp-cli-banner {
3623
+ flex-shrink: 0;
3624
+ display: grid;
3625
+ grid-template-columns: auto minmax(0, 1fr);
3626
+ gap: 10px;
3627
+ align-items: start;
3628
+ margin: 6px 8px 0;
3629
+ padding: 10px 12px;
3630
+ border: 1px solid rgba(232,180,80,0.32);
3631
+ border-radius: 8px;
3632
+ background: rgba(232,180,80,0.04);
3633
+ color: rgba(255,255,255,0.86);
3634
+ font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, monospace;
3635
+ font-size: 11px;
3636
+ line-height: 1.45;
3637
+ position: relative;
3638
+ z-index: 5;
3639
+ }
3640
+ .ocp-cli-banner [hidden] { display: none !important; }
3641
+ .ocp-cli-banner--broken, .ocp-cli-banner--failed { border-color: rgba(220,100,100,0.32); background: rgba(220,100,100,0.05); }
3642
+ .ocp-cli-banner--done { border-color: rgba(140,210,170,0.32); background: rgba(140,210,170,0.05); }
3643
+ .ocp-cli-banner-icon {
3644
+ width: 22px; height: 22px;
3645
+ display: flex; align-items: center; justify-content: center;
3646
+ border-radius: 50%;
3647
+ background: rgba(232,180,80,0.14);
3648
+ border: 1px solid rgba(232,180,80,0.28);
3649
+ color: rgba(255,200,120,0.95);
3650
+ font-weight: 700;
3651
+ }
3652
+ .ocp-cli-banner--broken .ocp-cli-banner-icon, .ocp-cli-banner--failed .ocp-cli-banner-icon { background: rgba(220,100,100,0.12); border-color: rgba(220,100,100,0.3); color: rgba(255,166,166,0.92); }
3653
+ .ocp-cli-banner--done .ocp-cli-banner-icon { background: rgba(140,210,170,0.14); border-color: rgba(140,210,170,0.28); color: rgba(180,230,200,0.92); }
3654
+ .ocp-cli-banner--installing .ocp-cli-banner-icon { animation: ocpv2-abort-sweep 1.2s ease-in-out infinite; }
3655
+ .ocp-cli-banner--nudge { animation: ocp-cli-nudge 0.5s ease; }
3656
+ @keyframes ocp-cli-nudge { 0%, 100% { transform: none; } 25% { transform: translateX(-3px); } 75% { transform: translateX(3px); } }
3657
+ .ocp-cli-banner-text { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
3658
+ .ocp-cli-banner-title { font-size: 11.5px; font-weight: 600; color: rgba(255,200,120,0.95); }
3659
+ .ocp-cli-banner--broken .ocp-cli-banner-title, .ocp-cli-banner--failed .ocp-cli-banner-title { color: rgba(255,166,166,0.92); }
3660
+ .ocp-cli-banner--done .ocp-cli-banner-title { color: rgba(180,230,200,0.92); }
3661
+ .ocp-cli-banner-body, .ocp-cli-banner-note, .ocp-cli-banner-step { color: rgba(255,255,255,0.62); overflow-wrap: anywhere; }
3662
+ .ocp-cli-banner-command { display: flex; align-items: flex-start; gap: 6px; }
3663
+ .ocp-cli-banner-command code, .ocp-cli-banner-error code {
3664
+ flex: 1;
3665
+ min-width: 0;
3666
+ padding: 3px 6px;
3667
+ background: rgba(0,0,0,0.3);
3668
+ border: 1px solid rgba(255,255,255,0.06);
3669
+ border-radius: 4px;
3670
+ font: inherit;
3671
+ font-size: 10.5px;
3672
+ color: rgba(232,224,220,0.95);
3673
+ white-space: pre-wrap;
3674
+ word-break: break-all;
3675
+ user-select: text;
3676
+ }
3677
+ .ocp-cli-banner-error code { display: block; max-height: 96px; overflow: auto; color: rgba(255,166,166,0.92); }
3678
+ .ocp-cli-banner-copy {
3679
+ flex-shrink: 0;
3680
+ height: 22px;
3681
+ padding: 0 8px;
3682
+ border: 1px solid rgba(255,255,255,0.12);
3683
+ border-radius: 5px;
3684
+ background: transparent;
3685
+ color: rgba(255,255,255,0.62);
3686
+ font: inherit;
3687
+ font-size: 10.5px;
3688
+ cursor: pointer;
3689
+ }
3690
+ .ocp-cli-banner-copy:hover { color: rgba(252,246,240,0.98); border-color: rgba(232,224,220,0.3); }
3691
+ .ocp-cli-banner-progress { display: flex; flex-direction: column; gap: 4px; }
3692
+ .ocp-cli-banner-bar { height: 3px; border-radius: 2px; background: rgba(255,255,255,0.08); overflow: hidden; }
3693
+ .ocp-cli-banner-bar > span { display: block; height: 100%; width: 0; background: rgba(232,224,220,0.7); transition: width 0.2s ease; }
3694
+ .ocp-cli-banner-log {
3695
+ margin: 0;
3696
+ max-height: 84px;
3697
+ overflow: auto;
3698
+ padding: 4px 6px;
3699
+ background: rgba(0,0,0,0.25);
3700
+ border-radius: 4px;
3701
+ font: inherit;
3702
+ font-size: 10px;
3703
+ line-height: 1.45;
3704
+ color: rgba(255,255,255,0.5);
3705
+ white-space: pre-wrap;
3706
+ word-break: break-all;
3707
+ }
3708
+ .ocp-cli-banner-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 2px; }
3709
+ .ocp-cli-banner-install, .ocp-cli-banner-link, .ocp-cli-banner-path, .ocp-cli-banner-recheck, .ocp-cli-banner-dismiss {
3710
+ display: inline-flex; align-items: center; gap: 4px;
3711
+ height: 22px;
3712
+ padding: 0 10px;
3713
+ font: inherit;
3714
+ font-size: 11.5px;
3715
+ font-weight: 500;
3716
+ line-height: 1;
3717
+ border-radius: 5px;
3718
+ border: 1px solid rgba(255,255,255,0.14);
3719
+ background: rgba(255,255,255,0.04);
3720
+ color: rgba(255,255,255,0.86);
3721
+ text-decoration: none;
3722
+ cursor: pointer;
3723
+ user-select: none;
3724
+ }
3725
+ .ocp-cli-banner-install { background: rgba(232,224,220,0.15); border-color: rgba(232,224,220,0.3); color: rgba(245,239,232,0.95); }
3726
+ .ocp-cli-banner-install:hover:not(:disabled) { background: rgba(232,224,220,0.25); border-color: rgba(232,224,220,0.45); }
3727
+ .ocp-cli-banner-link:hover, .ocp-cli-banner-path:hover:not(:disabled), .ocp-cli-banner-recheck:hover:not(:disabled), .ocp-cli-banner-dismiss:hover { background: rgba(255,255,255,0.08); border-color: rgba(255,255,255,0.26); }
3728
+ .ocp-cli-banner-install:disabled, .ocp-cli-banner-path:disabled, .ocp-cli-banner-recheck:disabled { opacity: 0.5; cursor: default; }
3729
+ .ocp-cli-banner button:focus-visible, .ocp-cli-banner a:focus-visible { outline: 2px solid rgba(255,255,255,0.7); outline-offset: 2px; }
3730
+ @media (prefers-reduced-motion: reduce) {
3731
+ .ocp-cli-banner--installing .ocp-cli-banner-icon, .ocp-cli-banner--nudge { animation: none; }
3732
+ .ocp-cli-banner--nudge { box-shadow: 0 0 0 1px rgba(232,180,80,0.6); }
3733
+ .ocp-cli-banner-bar > span { transition: none; }
3734
+ }
3735
+ .ocpv2-panel.ocp-cli-blocked .ocpv2-compose-btn:not(.ocpv2-compose-abort) { opacity: 0.4; cursor: not-allowed; }
3736
+ .ocpv2-panel.ocp-cli-blocked .ocpv2-compose-input { opacity: 0.7; }
3570
3737
  `;
3571
3738
 
3572
3739
  export function injectStyles() {
@@ -1,5 +1,6 @@
1
1
  import { canPromptPwaInstall, initPwaInstall, installGuideMode, installGuideRequested, isStandalone,
2
2
  leavePwaInstallHandoff, requestPwaInstall } from './pwa-install.js';
3
+ import { isDesktopApp } from './desktop-bridge.js';
3
4
 
4
5
  // The wizard (first run) and the main UI (setup done) open the browser's dialog from a press the user makes
5
6
  // anyway, so a browser that has one shows this page only when Apps > Install as App asked for it. true, false,
@@ -12,7 +13,8 @@ async function setupComplete() {
12
13
  } catch { return null; }
13
14
  }
14
15
 
15
- if (isStandalone()) location.replace('/');
16
+ // Already the installed app, or the SynaBun desktop app's own window: nothing to install here.
17
+ if (isStandalone() || isDesktopApp()) location.replace('/');
16
18
  else {
17
19
  const pt = navigator.language.toLowerCase().startsWith('pt');
18
20
  const copy = pt ? {