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
@@ -0,0 +1,271 @@
1
+ // ═══════════════════════════════════════════
2
+ // SETTINGS — About (the pane)
3
+ // ═══════════════════════════════════════════
4
+ //
5
+ // The last page of Settings: who SynaBun is and what it runs on. A header that is always shown (the app's icon,
6
+ // name, version and channel, how it was installed, the package's one-line description, "Check for updates" and
7
+ // "Copy info"), then three sections: Links, System, Dependencies, and the license line at the foot.
8
+ //
9
+ // It asks GET /api/system/about once, when the page is first shown. A server from before that route (404, or not
10
+ // JSON) gets the header and the version from /api/health and /api/system/version, and a note that the rest comes
11
+ // with a restart. settings-about.js decides what is said; this draws it.
12
+ //
13
+ // "Check for updates" is the Apps menu's own item (#menu-check-cli-updates, ui-menubar.js): the same check, the
14
+ // same toast. Links open in a new window, which the desktop app hands to the default browser.
15
+
16
+ import * as kit from './settings-kit.js';
17
+ import { revealSettingsTarget } from './settings-shell.js';
18
+ import { desktopBridge } from '../desktop-bridge.js';
19
+ import {
20
+ ABOUT_URL, ABOUT_FILTER_MIN, buildLabel, diagnosticsText, filterDependencies, installLine, isExternalUrl, linkHost, linkLabel,
21
+ npmUrl, osLine, packageLabel, readAboutAnswer, readClientRuntime, versionLine,
22
+ } from './settings-about.js';
23
+
24
+ const UPDATE_MENU_ITEM = 'menu-check-cli-updates';
25
+ const EXTERNAL = 'target="_blank" rel="noopener noreferrer"';
26
+ const ARROW = '<svg class="stg-about-arrow" viewBox="0 0 16 16" aria-hidden="true"><path d="M5.5 4.5h6v6M11.5 4.5l-7 7"/></svg>';
27
+
28
+ export function buildAboutTab() {
29
+ return `
30
+ <div class="stg-pane stg-about" data-stg-pane="about">
31
+ <div class="stg-about-hero" id="stg-about-hero">
32
+ <img class="stg-about-logo" src="/icon-192.png" alt="" width="64" height="64" decoding="async">
33
+ <h3 class="stg-about-name">SynaBun</h3>
34
+ <p class="stg-about-version" id="stg-about-version" aria-live="polite">${kit.te('settings.redesign.about.loading')}</p>
35
+ <p class="stg-about-line" id="stg-about-install" hidden></p>
36
+ <p class="stg-about-line stg-about-desc" id="stg-about-desc" hidden></p>
37
+ <div class="stg-action-row stg-about-actions">
38
+ <button type="button" class="stg-action-btn" id="stg-about-update" ${kit.inv('ABT001')} title="${kit.H('ABT001')}">${kit.L('ABT001')}</button>
39
+ <button type="button" class="stg-action-btn" id="stg-about-copy" ${kit.inv('ABT002')} title="${kit.H('ABT002')}">${kit.L('ABT002')}</button>
40
+ </div>
41
+ <p class="stg-help stg-about-note" id="stg-about-note" role="status" hidden></p>
42
+ </div>
43
+ ${kit.card({
44
+ id: 'stg-sec-about-links', section: 'about.links',
45
+ body: `<ul class="stg-about-links" id="stg-about-links" data-stg-search="off"></ul>`,
46
+ })}
47
+ ${kit.card({
48
+ id: 'stg-sec-about-system', section: 'about.system',
49
+ body: `<dl class="stg-about-facts" id="stg-about-facts" data-stg-search="off"></dl>`,
50
+ })}
51
+ ${kit.card({
52
+ id: 'stg-sec-about-dependencies', section: 'about.dependencies',
53
+ // how many dependencies the lists hold; empty until the server has answered
54
+ status: '<span class="stg-about-count" id="stg-about-deps-count"></span>',
55
+ body: `
56
+ <div class="stg-about-filter" ${kit.inv('ABT003')} hidden>
57
+ <input type="search" class="stg-input stg-about-filter-input" id="stg-about-filter" placeholder="${kit.te('settings.redesign.about.deps.filterPlaceholder')}" aria-label="${kit.L('ABT003')}" aria-describedby="stg-about-filter-help" autocomplete="off" autocapitalize="off" spellcheck="false" enterkeyhint="search">
58
+ <span class="stg-sr" id="stg-about-filter-help">${kit.H('ABT003')}</span>
59
+ </div>
60
+ <div class="stg-about-deps" id="stg-about-deps" data-stg-search="off"></div>`,
61
+ })}
62
+ <footer class="stg-about-footer" id="stg-about-footer" hidden></footer>
63
+ </div>`;
64
+ }
65
+
66
+ // ── Drawing ──
67
+
68
+ function linkRow(link) {
69
+ return `<li><a class="stg-about-link" href="${kit.esc(link.url)}" ${EXTERNAL}>
70
+ <span class="stg-about-link-label">${kit.esc(linkLabel(link, kit.tx))}</span>
71
+ <span class="stg-about-link-url">${kit.esc(linkHost(link.url))}</span>${ARROW}</a></li>`;
72
+ }
73
+
74
+ function fact(label, value, { mono = false } = {}) {
75
+ if (value == null || value === '') return '';
76
+ return `<div class="stg-about-fact"><dt>${label}</dt><dd${mono ? ' class="stg-about-mono"' : ''}>${kit.esc(String(value))}</dd></div>`;
77
+ }
78
+
79
+ function depRow(dep) {
80
+ const url = npmUrl(dep.name);
81
+ const name = url ? `<a class="stg-about-dep-name" href="${kit.esc(url)}" ${EXTERNAL}>${kit.esc(dep.name)}</a>` : `<span class="stg-about-dep-name">${kit.esc(dep.name)}</span>`;
82
+ const version = dep.installed
83
+ ? `<span class="stg-about-dep-version">${kit.esc(dep.version)}</span>`
84
+ : `<span class="stg-about-dep-version" data-state="missing">${kit.esc(dep.declared)} · ${kit.te('settings.redesign.about.deps.notInstalled')}</span>`;
85
+ const meta = [
86
+ dep.installed && dep.declared && dep.declared !== dep.version ? kit.te('settings.redesign.about.deps.declared', { range: dep.declared }) : '',
87
+ dep.optional ? kit.te('settings.redesign.about.deps.optional') : '',
88
+ dep.license ? kit.esc(dep.license) : '',
89
+ ].filter(Boolean).join(' · ');
90
+ return `<li class="stg-about-dep">${name}${version}${meta ? `<span class="stg-about-dep-meta">${meta}</span>` : ''}</li>`;
91
+ }
92
+
93
+ function depGroup(title, sub, deps, { note = '' } = {}) {
94
+ if (!deps.length) return '';
95
+ return `<div class="stg-about-group">
96
+ <h4 class="stg-subhead stg-about-group-head"><span>${title}</span>${sub ? `<span class="stg-about-group-sub">${sub}</span>` : ''}<span class="stg-about-count">${deps.length}</span></h4>
97
+ ${note ? `<p class="stg-help stg-about-group-note">${note}</p>` : ''}
98
+ <ul class="stg-about-dep-list">${deps.map(depRow).join('')}</ul>
99
+ </div>`;
100
+ }
101
+
102
+ function drawDependencies(host, shown) {
103
+ const { packages, vendored, counts } = shown;
104
+ const runtime = packages.map((p) => depGroup(kit.esc(packageLabel(p, kit.tx)), kit.esc(p.name), p.runtime, { note: p.onDemand ? kit.te('settings.redesign.about.deps.onDemand') : '' })).join('');
105
+ const singles = vendored.filter((b) => b.packages.length === 1).flatMap((b) => b.packages);
106
+ const bundles = vendored.filter((b) => b.packages.length > 1)
107
+ .map((b) => depGroup(kit.esc(b.label), kit.esc(b.version || ''), b.packages)).join('');
108
+ const bundled = singles.length || bundles
109
+ ? `<div class="stg-about-bundled">${depGroup(kit.te('settings.redesign.about.deps.vendored'), '', singles)}${bundles}</div>`
110
+ : '';
111
+ // A filter opens the group to show its matches; one the user opened stays open while they type.
112
+ const devOpen = !!shown.query || !!host.querySelector('.stg-about-dev')?.open;
113
+ const dev = counts.dev
114
+ ? `<details class="stg-advanced stg-about-dev"${devOpen ? ' open' : ''}>
115
+ <summary>${kit.CHEVRON}<span>${kit.te('settings.redesign.about.deps.dev', { count: counts.dev })}</span></summary>
116
+ <div class="stg-advanced-body">${packages.map((p) => depGroup(kit.esc(packageLabel(p, kit.tx)), kit.esc(p.name), p.dev)).join('')}</div>
117
+ </details>`
118
+ : '';
119
+ const empty = counts.total ? '' : `<p class="stg-help">${shown.query ? kit.te('settings.redesign.about.deps.noMatch', { query: shown.query }) : kit.te('settings.redesign.about.deps.none')}</p>`;
120
+ host.innerHTML = `${runtime}${bundled}${dev}${empty}`;
121
+ }
122
+
123
+ /**
124
+ * Load and draw the page the first time it is shown, and wire its buttons.
125
+ * @param {HTMLElement} overlay the Settings panel
126
+ * @param {Object} [o]
127
+ * @param {Function} [o.fetchImpl] fetch (tests)
128
+ * @param {(msg: string) => void} [o.toast] the panel's toast
129
+ * @param {Window} [o.win] where the user agent and the desktop app's bridge are read
130
+ */
131
+ export function wireAboutTab(overlay, { fetchImpl = (...args) => fetch(...args), toast = () => {}, win = window } = {}) {
132
+ const pane = kit.paneOf(overlay, 'about');
133
+ if (!pane) return;
134
+ const $ = (id) => pane.querySelector(`#${id}`);
135
+ const client = readClientRuntime({ userAgent: win.navigator?.userAgent, desktop: desktopBridge(win) });
136
+ let model = null;
137
+ let loading = null;
138
+
139
+ const getJson = async (url) => {
140
+ try {
141
+ const res = await fetchImpl(url, { headers: { Accept: 'application/json' } });
142
+ if (!res.ok) return null;
143
+ return await res.json().catch(() => null);
144
+ } catch {
145
+ return null;
146
+ }
147
+ };
148
+
149
+ const show = (node, text) => {
150
+ if (!node) return;
151
+ node.textContent = text || '';
152
+ node.hidden = !text;
153
+ };
154
+
155
+ function drawHeader() {
156
+ const { app } = model;
157
+ show($('stg-about-version'), versionLine(app, kit.tx));
158
+ show($('stg-about-install'), installLine(app, kit.tx));
159
+ show($('stg-about-desc'), app.description);
160
+ show($('stg-about-note'), model.full ? '' : kit.tx('settings.redesign.about.restartNote'));
161
+ }
162
+
163
+ function drawLinks() {
164
+ const host = $('stg-about-links');
165
+ if (!host) return;
166
+ host.innerHTML = model.links.length
167
+ ? model.links.filter((l) => isExternalUrl(l.url)).map(linkRow).join('')
168
+ : `<li class="stg-help stg-about-empty">${model.full ? kit.te('settings.redesign.about.links.none') : kit.te('settings.redesign.about.afterRestart')}</li>`;
169
+ }
170
+
171
+ function drawFacts() {
172
+ const host = $('stg-about-facts');
173
+ if (!host) return;
174
+ const { app, runtime } = model;
175
+ host.innerHTML = [
176
+ fact(kit.te('settings.redesign.about.row.version'), app.version ? `${app.version} (${buildLabel(app, kit.tx)})` : ''),
177
+ fact(kit.te('settings.redesign.about.row.install'), installLine(app, kit.tx)),
178
+ fact('Node.js', runtime.node),
179
+ fact('SQLite', runtime.sqlite),
180
+ fact('Electron', client.electron),
181
+ fact('Chromium', client.chromium),
182
+ fact(kit.te('settings.redesign.about.row.os'), osLine(runtime, client)),
183
+ fact(kit.te('settings.redesign.about.row.dataFolder'), runtime.dataHome, { mono: true }),
184
+ fact(kit.te('settings.redesign.about.row.port'), runtime.port),
185
+ ].join('');
186
+ }
187
+
188
+ function drawDeps() {
189
+ const host = $('stg-about-deps');
190
+ const count = $('stg-about-deps-count');
191
+ const filter = pane.querySelector('.stg-about-filter');
192
+ const deps = model.dependencies;
193
+ if (!host) return;
194
+ if (!deps) {
195
+ host.innerHTML = `<p class="stg-help stg-about-empty">${kit.te('settings.redesign.about.afterRestart')}</p>`;
196
+ if (filter) filter.hidden = true;
197
+ return;
198
+ }
199
+ if (count) count.textContent = deps.counts.total ? String(deps.counts.total) : '';
200
+ if (filter) filter.hidden = deps.counts.total <= ABOUT_FILTER_MIN;
201
+ drawDependencies(host, filterDependencies(deps, $('stg-about-filter')?.value || ''));
202
+ }
203
+
204
+ function drawFooter() {
205
+ const host = $('stg-about-footer');
206
+ if (!host) return;
207
+ const { app } = model;
208
+ const lines = [];
209
+ if (app.license) lines.push(`<p>${kit.te('settings.redesign.about.footer.license', { license: app.license })}</p>`);
210
+ if (app.copyright) lines.push(`<p>${kit.te('settings.redesign.about.footer.copyright', { years: app.copyright.years, holder: app.copyright.holder })}</p>`);
211
+ if (model.dependencies?.counts.total) lines.push(`<p><button type="button" class="stg-about-builtwith" id="stg-about-builtwith">${kit.te('settings.redesign.about.footer.builtWith')}</button></p>`);
212
+ host.innerHTML = lines.join('');
213
+ host.hidden = !lines.length;
214
+ }
215
+
216
+ function draw() {
217
+ drawHeader();
218
+ drawLinks();
219
+ drawFacts();
220
+ drawDeps();
221
+ drawFooter();
222
+ }
223
+
224
+ async function load() {
225
+ const about = await getJson(ABOUT_URL);
226
+ let answer = readAboutAnswer({ about });
227
+ if (!answer.full) {
228
+ // An older server: what it has always said.
229
+ const [health, version] = await Promise.all([getJson('/api/health'), getJson('/api/system/version')]);
230
+ answer = readAboutAnswer({ health, version });
231
+ }
232
+ if (!document.body.contains(overlay)) return;
233
+ model = answer;
234
+ draw();
235
+ }
236
+
237
+ const ensure = () => { if (!loading) loading = load(); return loading; };
238
+ if (kit.paneActive(overlay, 'about')) ensure();
239
+ overlay.addEventListener('stg-page-change', (e) => { if (e.detail?.page === 'about') ensure(); });
240
+
241
+ // ── Buttons ──
242
+
243
+ const updateBtn = $('stg-about-update');
244
+ // The Apps menu's own item: no menu (an embed, a test page), no button.
245
+ if (updateBtn && !document.getElementById(UPDATE_MENU_ITEM)) updateBtn.hidden = true;
246
+ updateBtn?.addEventListener('click', () => document.getElementById(UPDATE_MENU_ITEM)?.click());
247
+
248
+ $('stg-about-copy')?.addEventListener('click', async () => {
249
+ if (!model) await ensure();
250
+ const body = diagnosticsText(model, client, { tx: kit.tx });
251
+ try {
252
+ await win.navigator.clipboard.writeText(body);
253
+ toast(kit.tx('settings.redesign.about.copied'));
254
+ } catch {
255
+ toast(kit.tx('settings.redesign.about.copyFailed'));
256
+ }
257
+ });
258
+
259
+ $('stg-about-filter')?.addEventListener('input', () => { if (model) drawDeps(); });
260
+
261
+ pane.addEventListener('click', (e) => {
262
+ if (!e.target.closest?.('#stg-about-builtwith')) return;
263
+ const section = $('stg-sec-about-dependencies');
264
+ const content = overlay.querySelector('.settings-content');
265
+ if (!section || !content) return;
266
+ revealSettingsTarget(overlay, section);
267
+ // Only the page scrolls, never the panel around it.
268
+ const top = section.getBoundingClientRect().top - content.getBoundingClientRect().top + content.scrollTop - 8;
269
+ content.scrollTo({ top: Math.max(0, top), behavior: matchMedia('(prefers-reduced-motion: reduce)').matches ? 'auto' : 'smooth' });
270
+ });
271
+ }
@@ -0,0 +1,254 @@
1
+ // ═══════════════════════════════════════════
2
+ // SETTINGS — About (what it says)
3
+ // ═══════════════════════════════════════════
4
+ //
5
+ // The About page reads GET /api/system/about (lib/system-about.js). A server from before that route answers 404
6
+ // until it restarts (the page's files are served live): the page then shows what /api/health and
7
+ // /api/system/version already say, with a note, and nothing fails. This module turns either answer into what the
8
+ // page draws: labels, the dependency lists a filter leaves, the plain-text block "Copy info" puts on the clipboard.
9
+ //
10
+ // No DOM and no imports: node --test loads it as it is (tests/settings-about.test.mjs). Strings come through the
11
+ // translate function the caller passes (`tx`, the kit's); the keys are written out in full so the i18n audit sees them.
12
+
13
+ export const ABOUT_URL = '/api/system/about';
14
+ /** The filter field shows once there are more dependencies than this. */
15
+ export const ABOUT_FILTER_MIN = 20;
16
+
17
+ const INSTALL_KEYS = {
18
+ desktop: 'settings.redesign.about.install.desktop',
19
+ app: 'settings.redesign.about.install.app',
20
+ npm: 'settings.redesign.about.install.npm',
21
+ git: 'settings.redesign.about.install.git',
22
+ };
23
+ const BUILD_KEYS = {
24
+ stable: 'settings.redesign.about.channel.stable',
25
+ prerelease: 'settings.redesign.about.channel.prerelease',
26
+ dev: 'settings.redesign.about.channel.dev',
27
+ };
28
+ export const LINK_KEYS = {
29
+ repository: 'settings.redesign.about.link.repository',
30
+ releases: 'settings.redesign.about.link.releases',
31
+ changelog: 'settings.redesign.about.link.changelog',
32
+ issues: 'settings.redesign.about.link.issues',
33
+ website: 'settings.redesign.about.link.website',
34
+ docs: 'settings.redesign.about.link.docs',
35
+ npm: 'settings.redesign.about.link.npm',
36
+ license: 'settings.redesign.about.link.license',
37
+ discord: 'settings.redesign.about.link.discord',
38
+ x: 'settings.redesign.about.link.x',
39
+ };
40
+ const PACKAGE_KEYS = {
41
+ 'neural-interface': 'settings.redesign.about.package.neural_interface',
42
+ 'mcp-server': 'settings.redesign.about.package.mcp_server',
43
+ desktop: 'settings.redesign.about.package.desktop',
44
+ 'whatsapp-connector': 'settings.redesign.about.package.whatsapp_connector',
45
+ };
46
+
47
+ const NPM_NAME = /^(?:@[a-z0-9][a-z0-9._~-]*\/)?[a-z0-9][a-z0-9._~-]*$/i;
48
+ const SEP = ' · ';
49
+
50
+ const str = (value) => (typeof value === 'string' && value.trim() ? value.trim() : null);
51
+ const list = (value) => (Array.isArray(value) ? value : []);
52
+
53
+ /** An address the page may link to: https only. */
54
+ export const isExternalUrl = (url) => typeof url === 'string' && /^https:\/\/[^\s"'<>]+$/.test(url);
55
+
56
+ /** A link's address without the scheme, for the quiet line beside its name. */
57
+ export const linkHost = (url) => String(url || '').replace(/^https:\/\//, '').replace(/\/+$/, '');
58
+
59
+ /** A package's page on npm, or null for a name npm would not have. */
60
+ export const npmUrl = (name) => (typeof name === 'string' && NPM_NAME.test(name) ? `https://www.npmjs.com/package/${name}` : null);
61
+
62
+ function readDependency(dep) {
63
+ if (!dep || typeof dep !== 'object' || !str(dep.name)) return null;
64
+ return {
65
+ name: dep.name,
66
+ declared: str(dep.declared) || '',
67
+ version: dep.installed ? str(dep.version) : null,
68
+ installed: !!dep.installed && !!str(dep.version),
69
+ license: str(dep.license),
70
+ optional: !!dep.optional,
71
+ };
72
+ }
73
+
74
+ function readDependencies(deps) {
75
+ if (!deps || typeof deps !== 'object') return null;
76
+ const packages = list(deps.packages).filter((p) => p && str(p.id)).map((p) => ({
77
+ id: p.id,
78
+ name: str(p.name) || p.id,
79
+ onDemand: !!p.onDemand,
80
+ runtime: list(p.runtime).map(readDependency).filter(Boolean),
81
+ dev: list(p.dev).map(readDependency).filter(Boolean),
82
+ }));
83
+ const vendored = list(deps.vendored).filter((b) => b && str(b.id)).map((b) => ({
84
+ id: b.id,
85
+ label: str(b.label) || b.id,
86
+ version: str(b.version),
87
+ packages: list(b.packages).filter((p) => p && str(p.name) && str(p.version))
88
+ .map((p) => ({ name: p.name, declared: '', version: p.version, installed: true, license: str(p.license), optional: false })),
89
+ }));
90
+ return { packages, vendored, counts: countDependencies({ packages, vendored }) };
91
+ }
92
+
93
+ /** How many runtime, dev and vendored dependencies a set of lists holds. */
94
+ export function countDependencies({ packages = [], vendored = [] } = {}) {
95
+ const runtime = packages.reduce((n, p) => n + p.runtime.length, 0);
96
+ const dev = packages.reduce((n, p) => n + p.dev.length, 0);
97
+ const bundled = vendored.reduce((n, b) => n + b.packages.length, 0);
98
+ return { runtime, dev, vendored: bundled, total: runtime + dev + bundled };
99
+ }
100
+
101
+ /**
102
+ * What the page shows, from the answers it got. `about` is the body of GET /api/system/about when it answered
103
+ * (anything else: null); `health` and `version` are the bodies of /api/health and /api/system/version, or null.
104
+ * `full` is false when the About route did not answer: the page then says that a restart brings the rest.
105
+ */
106
+ export function readAboutAnswer({ about = null, health = null, version = null } = {}) {
107
+ const full = !!(about && typeof about === 'object' && about.app && typeof about.app === 'object');
108
+ if (full) {
109
+ const app = about.app;
110
+ const install = INSTALL_KEYS[app.install] ? app.install : null;
111
+ const channel = app.channel === 'prerelease' ? 'prerelease' : 'stable';
112
+ const git = app.git && typeof app.git === 'object' ? { branch: str(app.git.branch), commit: str(app.git.commit) } : null;
113
+ const rt = about.runtime && typeof about.runtime === 'object' ? about.runtime : {};
114
+ const os = rt.os && typeof rt.os === 'object' ? rt.os : null;
115
+ return {
116
+ full: true,
117
+ app: {
118
+ version: str(app.version),
119
+ channel,
120
+ build: install === 'git' ? 'dev' : channel,
121
+ install,
122
+ git: git && (git.branch || git.commit) ? git : null,
123
+ description: str(app.description),
124
+ license: str(app.license),
125
+ copyright: app.copyright && str(app.copyright.years) && str(app.copyright.holder) ? { years: app.copyright.years, holder: app.copyright.holder } : null,
126
+ },
127
+ runtime: {
128
+ node: str(rt.node),
129
+ sqlite: str(rt.sqlite),
130
+ os: os ? { name: str(os.name), version: str(os.version), arch: str(os.arch), kernel: str(os.kernel) } : null,
131
+ dataHome: str(rt.dataHome),
132
+ port: Number.isFinite(Number(rt.port)) && Number(rt.port) > 0 ? Number(rt.port) : null,
133
+ },
134
+ links: list(about.links).filter((l) => l && LINK_KEYS[l.id] && isExternalUrl(l.url)).map((l) => ({ id: l.id, url: l.url })),
135
+ dependencies: readDependencies(about.dependencies),
136
+ };
137
+ }
138
+ // An older server: what /api/health and /api/system/version say.
139
+ const h = health && typeof health === 'object' ? health : {};
140
+ const v = version && typeof version === 'object' ? version : {};
141
+ const install = v.desktopManaged ? 'desktop' : (INSTALL_KEYS[h.install] && h.install !== 'desktop' ? h.install : null);
142
+ const channel = v.installedChannel === 'prerelease' ? 'prerelease' : 'stable';
143
+ return {
144
+ full: false,
145
+ app: {
146
+ version: str(h.version) || str(v.current),
147
+ channel,
148
+ build: install === 'git' ? 'dev' : channel,
149
+ install,
150
+ git: null,
151
+ description: null,
152
+ license: null,
153
+ copyright: null,
154
+ },
155
+ runtime: { node: null, sqlite: null, os: null, dataHome: null, port: null },
156
+ links: [],
157
+ dependencies: null,
158
+ };
159
+ }
160
+
161
+ /**
162
+ * What the page itself knows about where it runs: inside the desktop app, the Electron and Chromium versions
163
+ * its window reports in the user agent (the app never changes it), and the app's own platform and processor.
164
+ */
165
+ export function readClientRuntime({ userAgent = '', desktop = null } = {}) {
166
+ const ua = String(userAgent || '');
167
+ const electron = /\bElectron\/(\d[\w.-]*)/.exec(ua)?.[1] || null;
168
+ const inApp = !!desktop || !!electron;
169
+ return {
170
+ desktop: inApp,
171
+ electron: inApp ? electron : null,
172
+ chromium: inApp ? (/\bChrome\/(\d[\w.-]*)/.exec(ua)?.[1] || null) : null,
173
+ platform: desktop && str(desktop.platform),
174
+ arch: desktop && str(desktop.arch),
175
+ };
176
+ }
177
+
178
+ /** "Stable", "Pre-release" or "Development build". */
179
+ export const buildLabel = (app, tx) => tx(BUILD_KEYS[app?.build] || BUILD_KEYS.stable);
180
+
181
+ /** "Desktop app", "npm install", "Git clone" …, or null when the server did not say. */
182
+ export const installLabel = (app, tx) => (INSTALL_KEYS[app?.install] ? tx(INSTALL_KEYS[app.install]) : null);
183
+
184
+ /** The install line under the version: "Git clone · Dev · 295547c". */
185
+ export function installLine(app, tx) {
186
+ const parts = [installLabel(app, tx)];
187
+ if (app?.git) parts.push(app.git.branch, app.git.commit);
188
+ return parts.filter(Boolean).join(SEP);
189
+ }
190
+
191
+ /** The version line: "Version 2.0.5 · Stable". */
192
+ export function versionLine(app, tx) {
193
+ if (!app?.version) return buildLabel(app, tx);
194
+ return `${tx('settings.redesign.about.version', { version: app.version })}${SEP}${buildLabel(app, tx)}`;
195
+ }
196
+
197
+ /** "macOS 26.1 · arm64" from the server's answer; the desktop app's platform and processor when there is none. */
198
+ export function osLine(runtime, client = {}) {
199
+ const os = runtime?.os;
200
+ if (os && (os.name || os.version)) return [[os.name, os.version].filter(Boolean).join(' '), os.arch].filter(Boolean).join(SEP);
201
+ return [client.platform, client.arch].filter(Boolean).join(SEP) || null;
202
+ }
203
+
204
+ /** A package of the product by its id, in the page's language; its npm name otherwise. */
205
+ export const packageLabel = (pkg, tx) => (PACKAGE_KEYS[pkg?.id] ? tx(PACKAGE_KEYS[pkg.id]) : (pkg?.name || ''));
206
+
207
+ /** A link's name in the page's language. */
208
+ export const linkLabel = (link, tx) => (LINK_KEYS[link?.id] ? tx(LINK_KEYS[link.id]) : linkHost(link?.url));
209
+
210
+ /**
211
+ * The lists a filter leaves: every dependency whose name holds the query (case-insensitive), and the counts of
212
+ * what is shown. An empty query leaves everything.
213
+ */
214
+ export function filterDependencies(deps, query = '') {
215
+ const q = String(query || '').trim().toLowerCase();
216
+ const keep = (dep) => !q || dep.name.toLowerCase().includes(q);
217
+ const packages = list(deps?.packages).map((p) => ({ ...p, runtime: p.runtime.filter(keep), dev: p.dev.filter(keep) }));
218
+ const vendored = list(deps?.vendored).map((b) => ({ ...b, packages: b.packages.filter(keep) }));
219
+ return { query: q, packages, vendored, counts: countDependencies({ packages, vendored }) };
220
+ }
221
+
222
+ /**
223
+ * The plain-text block "Copy info" copies: version and channel, install, runtime, system, and the version of every
224
+ * runtime dependency and bundled library. No path, no address, nothing from a setting.
225
+ */
226
+ export function diagnosticsText(model, client = {}, { tx }) {
227
+ const lines = [];
228
+ const app = model?.app || {};
229
+ const rt = model?.runtime || {};
230
+ lines.push(`SynaBun ${app.version || '?'} (${buildLabel(app, tx)})`);
231
+ const install = installLine(app, tx);
232
+ if (install) lines.push(`${tx('settings.redesign.about.row.install')}: ${install}`);
233
+ if (rt.node) lines.push(`Node.js: ${rt.node}`);
234
+ if (rt.sqlite) lines.push(`SQLite: ${rt.sqlite}`);
235
+ if (client.electron) lines.push(`Electron: ${client.electron}`);
236
+ if (client.chromium) lines.push(`Chromium: ${client.chromium}`);
237
+ const os = osLine(rt, client);
238
+ if (os) lines.push(`${tx('settings.redesign.about.row.os')}: ${os}`);
239
+ const deps = model?.dependencies;
240
+ if (deps) {
241
+ for (const pkg of deps.packages) {
242
+ if (!pkg.runtime.length) continue;
243
+ lines.push('', `${packageLabel(pkg, tx)} (${pkg.name})`);
244
+ for (const dep of pkg.runtime) lines.push(` ${dep.name} ${dep.installed ? dep.version : `${dep.declared} (${tx('settings.redesign.about.deps.notInstalled')})`}`);
245
+ }
246
+ if (deps.vendored.length) {
247
+ lines.push('', tx('settings.redesign.about.deps.vendored'));
248
+ for (const bundle of deps.vendored) lines.push(` ${bundle.label} ${bundle.version || '?'}`);
249
+ }
250
+ } else if (model && !model.full) {
251
+ lines.push('', tx('settings.redesign.about.restartNote'));
252
+ }
253
+ return lines.join('\n');
254
+ }
@@ -29,6 +29,7 @@ export const SETTINGS_GROUPS = [
29
29
  { id: 'tools', labelKey: k('group.tools') },
30
30
  { id: 'automations', labelKey: k('group.automations') },
31
31
  { id: 'personalize', labelKey: k('group.personalize') },
32
+ { id: 'app', labelKey: k('group.app') },
32
33
  ];
33
34
 
34
35
  /** `key` is the i18n slug under settings.redesign.{nav,page,section}; `icon` names a TAB_ICONS entry. */
@@ -183,6 +184,17 @@ export const SETTINGS_PAGES = [
183
184
  { id: 'stg-sec-2d-graph', key: 'd2_graph', state: 'advanced', variant: 'graphics' },
184
185
  ],
185
186
  },
187
+ {
188
+ // The last page: version, links, system and dependencies (settings-about-pane.js, GET /api/system/about).
189
+ // Its header (icon, version, Check for updates, Copy info) is not a section: it is always shown.
190
+ id: 'about', key: 'about', group: 'app', icon: 'about',
191
+ panes: [{ id: 'about' }],
192
+ sections: [
193
+ { id: 'stg-sec-about-links', key: 'links', state: 'open' },
194
+ { id: 'stg-sec-about-system', key: 'system', state: 'open' },
195
+ { id: 'stg-sec-about-dependencies', key: 'dependencies', state: 'open' },
196
+ ],
197
+ },
186
198
  ];
187
199
 
188
200
  export const DEFAULT_SETTINGS_PAGE = 'ai-connections';
@@ -278,11 +290,13 @@ export const SETTINGS_CONTROLS = {
278
290
  'stg-sec-visual-tuning': 'UI003 UI004 UI005 UI006 UI007 UI008 UI009 UI010',
279
291
  'stg-sec-file-icons': 'ICO001 ICO003 ICO002 ICO004 ICO005',
280
292
  'stg-sec-2d-graph': 'GFX001 GFX002 GFX003 GFX004 GFX005 GFX006 GFX007 GFX008',
293
+ 'stg-sec-about-dependencies': 'ABT003',
281
294
  };
282
295
  /** Controls of a page that sit outside its sections (a pane's save bar, the tabs of a pane). */
283
296
  export const SETTINGS_PAGE_CONTROLS = {
284
297
  browser: 'BRW081 BRW082 BRW085',
285
298
  'connected-tools': 'MCP001',
299
+ about: 'ABT001 ABT002',
286
300
  };
287
301
  /** The window's own controls (dim the background, close, the page list): not settings, so never search results. */
288
302
  export const SETTINGS_SHELL_CONTROLS = 'SH002 SH003 SH005';
@@ -306,6 +320,7 @@ export const homeOfControl = (controlId) => CONTROL_HOME.get(controlId) || null;
306
320
  // ── Deep-link aliases ──────────────────────────────────────────────────────
307
321
  // Old tab id → the page that took it over, and the section a link to that tab
308
322
  // should land on. Old callers keep working; new code uses the page ids.
323
+ // A page that never had an old tab needs no entry: `{ tab: 'about' }` names the About page itself.
309
324
 
310
325
  export const SETTINGS_TAB_ALIASES = {
311
326
  server: { page: 'memory-backups', section: 'stg-sec-database' },