synabun 2.0.7 → 2.0.10

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 (565) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/README.md +1 -1
  3. package/THIRD-PARTY-LICENSES.md +46 -4
  4. package/hooks/claude-code/post-plan.mjs +6 -30
  5. package/hooks/claude-code/session-start.mjs +1 -4
  6. package/hooks/claude-code/shared.mjs +106 -72
  7. package/launcher.mjs +9 -3
  8. package/lib/package-processes.js +670 -0
  9. package/lib/runtime-dependencies.js +225 -0
  10. package/lib/start-launcher.js +6 -1
  11. package/mcp-server/dist/services/browser-bench.d.ts +1 -1
  12. package/mcp-server/dist/services/browser-bench.d.ts.map +1 -1
  13. package/mcp-server/dist/services/browser-bench.js +1 -1
  14. package/mcp-server/dist/services/browser-bench.js.map +1 -1
  15. package/mcp-server/dist/services/categories.d.ts +35 -2
  16. package/mcp-server/dist/services/categories.d.ts.map +1 -1
  17. package/mcp-server/dist/services/categories.js +77 -33
  18. package/mcp-server/dist/services/categories.js.map +1 -1
  19. package/mcp-server/dist/services/desktop-bench.d.ts +7 -7
  20. package/mcp-server/dist/services/desktop-bench.d.ts.map +1 -1
  21. package/mcp-server/dist/services/desktop-bench.js +1 -1
  22. package/mcp-server/dist/services/desktop-bench.js.map +1 -1
  23. package/mcp-server/dist/tools/agents.d.ts +1 -1
  24. package/mcp-server/dist/tools/agents.d.ts.map +1 -1
  25. package/mcp-server/dist/tools/agents.js +1 -1
  26. package/mcp-server/dist/tools/agents.js.map +1 -1
  27. package/mcp-server/dist/tools/bluesky.js +1 -1
  28. package/mcp-server/dist/tools/bluesky.js.map +1 -1
  29. package/mcp-server/dist/tools/browser-advanced.d.ts +1 -1
  30. package/mcp-server/dist/tools/browser-advanced.d.ts.map +1 -1
  31. package/mcp-server/dist/tools/browser-advanced.js +1 -1
  32. package/mcp-server/dist/tools/browser-advanced.js.map +1 -1
  33. package/mcp-server/dist/tools/browser-batch.d.ts +1 -1
  34. package/mcp-server/dist/tools/browser-batch.d.ts.map +1 -1
  35. package/mcp-server/dist/tools/browser-batch.js +1 -1
  36. package/mcp-server/dist/tools/browser-batch.js.map +1 -1
  37. package/mcp-server/dist/tools/browser-cheatsheet.d.ts +1 -1
  38. package/mcp-server/dist/tools/browser-cheatsheet.d.ts.map +1 -1
  39. package/mcp-server/dist/tools/browser-cheatsheet.js +1 -1
  40. package/mcp-server/dist/tools/browser-cheatsheet.js.map +1 -1
  41. package/mcp-server/dist/tools/browser-interact.d.ts +1 -1
  42. package/mcp-server/dist/tools/browser-interact.d.ts.map +1 -1
  43. package/mcp-server/dist/tools/browser-interact.js +1 -1
  44. package/mcp-server/dist/tools/browser-interact.js.map +1 -1
  45. package/mcp-server/dist/tools/browser-navigate.d.ts +1 -1
  46. package/mcp-server/dist/tools/browser-navigate.d.ts.map +1 -1
  47. package/mcp-server/dist/tools/browser-navigate.js +1 -1
  48. package/mcp-server/dist/tools/browser-navigate.js.map +1 -1
  49. package/mcp-server/dist/tools/browser-observe.d.ts +1 -1
  50. package/mcp-server/dist/tools/browser-observe.d.ts.map +1 -1
  51. package/mcp-server/dist/tools/browser-observe.js +1 -1
  52. package/mcp-server/dist/tools/browser-observe.js.map +1 -1
  53. package/mcp-server/dist/tools/card-tools.d.ts +1 -1
  54. package/mcp-server/dist/tools/card-tools.d.ts.map +1 -1
  55. package/mcp-server/dist/tools/card-tools.js +1 -1
  56. package/mcp-server/dist/tools/card-tools.js.map +1 -1
  57. package/mcp-server/dist/tools/category.d.ts +1 -1
  58. package/mcp-server/dist/tools/category.d.ts.map +1 -1
  59. package/mcp-server/dist/tools/category.js +5 -1
  60. package/mcp-server/dist/tools/category.js.map +1 -1
  61. package/mcp-server/dist/tools/choice.d.ts +1 -1
  62. package/mcp-server/dist/tools/choice.d.ts.map +1 -1
  63. package/mcp-server/dist/tools/choice.js +1 -1
  64. package/mcp-server/dist/tools/choice.js.map +1 -1
  65. package/mcp-server/dist/tools/computer.d.ts +1 -1
  66. package/mcp-server/dist/tools/computer.d.ts.map +1 -1
  67. package/mcp-server/dist/tools/computer.js +1 -1
  68. package/mcp-server/dist/tools/computer.js.map +1 -1
  69. package/mcp-server/dist/tools/discord-channel.d.ts +1 -1
  70. package/mcp-server/dist/tools/discord-channel.d.ts.map +1 -1
  71. package/mcp-server/dist/tools/discord-channel.js +1 -1
  72. package/mcp-server/dist/tools/discord-channel.js.map +1 -1
  73. package/mcp-server/dist/tools/discord-guild.d.ts +1 -1
  74. package/mcp-server/dist/tools/discord-guild.d.ts.map +1 -1
  75. package/mcp-server/dist/tools/discord-guild.js +1 -1
  76. package/mcp-server/dist/tools/discord-guild.js.map +1 -1
  77. package/mcp-server/dist/tools/discord-member.d.ts +1 -1
  78. package/mcp-server/dist/tools/discord-member.d.ts.map +1 -1
  79. package/mcp-server/dist/tools/discord-member.js +1 -1
  80. package/mcp-server/dist/tools/discord-member.js.map +1 -1
  81. package/mcp-server/dist/tools/discord-message.d.ts +1 -1
  82. package/mcp-server/dist/tools/discord-message.d.ts.map +1 -1
  83. package/mcp-server/dist/tools/discord-message.js +1 -1
  84. package/mcp-server/dist/tools/discord-message.js.map +1 -1
  85. package/mcp-server/dist/tools/discord-onboarding.d.ts +1 -1
  86. package/mcp-server/dist/tools/discord-onboarding.d.ts.map +1 -1
  87. package/mcp-server/dist/tools/discord-onboarding.js +1 -1
  88. package/mcp-server/dist/tools/discord-onboarding.js.map +1 -1
  89. package/mcp-server/dist/tools/discord-role.d.ts +1 -1
  90. package/mcp-server/dist/tools/discord-role.d.ts.map +1 -1
  91. package/mcp-server/dist/tools/discord-role.js +1 -1
  92. package/mcp-server/dist/tools/discord-role.js.map +1 -1
  93. package/mcp-server/dist/tools/discord-thread.d.ts +1 -1
  94. package/mcp-server/dist/tools/discord-thread.d.ts.map +1 -1
  95. package/mcp-server/dist/tools/discord-thread.js +1 -1
  96. package/mcp-server/dist/tools/discord-thread.js.map +1 -1
  97. package/mcp-server/dist/tools/discord-webhook.d.ts +1 -1
  98. package/mcp-server/dist/tools/discord-webhook.d.ts.map +1 -1
  99. package/mcp-server/dist/tools/discord-webhook.js +1 -1
  100. package/mcp-server/dist/tools/discord-webhook.js.map +1 -1
  101. package/mcp-server/dist/tools/fb-groups.d.ts +1 -1
  102. package/mcp-server/dist/tools/fb-groups.d.ts.map +1 -1
  103. package/mcp-server/dist/tools/fb-groups.js +1 -1
  104. package/mcp-server/dist/tools/fb-groups.js.map +1 -1
  105. package/mcp-server/dist/tools/forget.d.ts +1 -1
  106. package/mcp-server/dist/tools/forget.d.ts.map +1 -1
  107. package/mcp-server/dist/tools/forget.js +1 -1
  108. package/mcp-server/dist/tools/forget.js.map +1 -1
  109. package/mcp-server/dist/tools/git-tools.d.ts +1 -1
  110. package/mcp-server/dist/tools/git-tools.d.ts.map +1 -1
  111. package/mcp-server/dist/tools/git-tools.js +1 -1
  112. package/mcp-server/dist/tools/git-tools.js.map +1 -1
  113. package/mcp-server/dist/tools/gsc/experience.d.ts +1 -1
  114. package/mcp-server/dist/tools/gsc/experience.d.ts.map +1 -1
  115. package/mcp-server/dist/tools/gsc/experience.js +1 -1
  116. package/mcp-server/dist/tools/gsc/experience.js.map +1 -1
  117. package/mcp-server/dist/tools/gsc/indexing.d.ts +1 -1
  118. package/mcp-server/dist/tools/gsc/indexing.d.ts.map +1 -1
  119. package/mcp-server/dist/tools/gsc/indexing.js +1 -1
  120. package/mcp-server/dist/tools/gsc/indexing.js.map +1 -1
  121. package/mcp-server/dist/tools/gsc/inspect.d.ts +1 -1
  122. package/mcp-server/dist/tools/gsc/inspect.d.ts.map +1 -1
  123. package/mcp-server/dist/tools/gsc/inspect.js +1 -1
  124. package/mcp-server/dist/tools/gsc/inspect.js.map +1 -1
  125. package/mcp-server/dist/tools/gsc/navigate.d.ts +1 -1
  126. package/mcp-server/dist/tools/gsc/navigate.d.ts.map +1 -1
  127. package/mcp-server/dist/tools/gsc/navigate.js +1 -1
  128. package/mcp-server/dist/tools/gsc/navigate.js.map +1 -1
  129. package/mcp-server/dist/tools/gsc/performance.d.ts +1 -1
  130. package/mcp-server/dist/tools/gsc/performance.d.ts.map +1 -1
  131. package/mcp-server/dist/tools/gsc/performance.js +1 -1
  132. package/mcp-server/dist/tools/gsc/performance.js.map +1 -1
  133. package/mcp-server/dist/tools/gsc/settings.d.ts +1 -1
  134. package/mcp-server/dist/tools/gsc/settings.d.ts.map +1 -1
  135. package/mcp-server/dist/tools/gsc/settings.js +1 -1
  136. package/mcp-server/dist/tools/gsc/settings.js.map +1 -1
  137. package/mcp-server/dist/tools/image-tools.d.ts +1 -1
  138. package/mcp-server/dist/tools/image-tools.d.ts.map +1 -1
  139. package/mcp-server/dist/tools/image-tools.js +1 -1
  140. package/mcp-server/dist/tools/image-tools.js.map +1 -1
  141. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts +1 -1
  142. package/mcp-server/dist/tools/leonardo-browser-tools.d.ts.map +1 -1
  143. package/mcp-server/dist/tools/leonardo-browser-tools.js +1 -1
  144. package/mcp-server/dist/tools/leonardo-browser-tools.js.map +1 -1
  145. package/mcp-server/dist/tools/loop.d.ts +1 -1
  146. package/mcp-server/dist/tools/loop.d.ts.map +1 -1
  147. package/mcp-server/dist/tools/loop.js +1 -1
  148. package/mcp-server/dist/tools/loop.js.map +1 -1
  149. package/mcp-server/dist/tools/memories.d.ts +1 -1
  150. package/mcp-server/dist/tools/memories.d.ts.map +1 -1
  151. package/mcp-server/dist/tools/memories.js +1 -1
  152. package/mcp-server/dist/tools/memories.js.map +1 -1
  153. package/mcp-server/dist/tools/morelogin.d.ts +1 -1
  154. package/mcp-server/dist/tools/morelogin.d.ts.map +1 -1
  155. package/mcp-server/dist/tools/morelogin.js +1 -1
  156. package/mcp-server/dist/tools/morelogin.js.map +1 -1
  157. package/mcp-server/dist/tools/profile.d.ts +1 -1
  158. package/mcp-server/dist/tools/profile.d.ts.map +1 -1
  159. package/mcp-server/dist/tools/profile.js +1 -1
  160. package/mcp-server/dist/tools/profile.js.map +1 -1
  161. package/mcp-server/dist/tools/recall.d.ts +1 -1
  162. package/mcp-server/dist/tools/recall.d.ts.map +1 -1
  163. package/mcp-server/dist/tools/recall.js +1 -1
  164. package/mcp-server/dist/tools/recall.js.map +1 -1
  165. package/mcp-server/dist/tools/reflect.d.ts +1 -1
  166. package/mcp-server/dist/tools/reflect.d.ts.map +1 -1
  167. package/mcp-server/dist/tools/reflect.js +1 -1
  168. package/mcp-server/dist/tools/reflect.js.map +1 -1
  169. package/mcp-server/dist/tools/remember.d.ts +1 -1
  170. package/mcp-server/dist/tools/remember.d.ts.map +1 -1
  171. package/mcp-server/dist/tools/remember.js +13 -11
  172. package/mcp-server/dist/tools/remember.js.map +1 -1
  173. package/mcp-server/dist/tools/restore.d.ts +1 -1
  174. package/mcp-server/dist/tools/restore.d.ts.map +1 -1
  175. package/mcp-server/dist/tools/restore.js +1 -1
  176. package/mcp-server/dist/tools/restore.js.map +1 -1
  177. package/mcp-server/dist/tools/style-guide-tools.d.ts +1 -1
  178. package/mcp-server/dist/tools/style-guide-tools.d.ts.map +1 -1
  179. package/mcp-server/dist/tools/style-guide-tools.js +1 -1
  180. package/mcp-server/dist/tools/style-guide-tools.js.map +1 -1
  181. package/mcp-server/dist/tools/sync.d.ts +1 -1
  182. package/mcp-server/dist/tools/sync.d.ts.map +1 -1
  183. package/mcp-server/dist/tools/sync.js +1 -1
  184. package/mcp-server/dist/tools/sync.js.map +1 -1
  185. package/mcp-server/dist/tools/tictactoe-tools.d.ts +1 -1
  186. package/mcp-server/dist/tools/tictactoe-tools.d.ts.map +1 -1
  187. package/mcp-server/dist/tools/tictactoe-tools.js +1 -1
  188. package/mcp-server/dist/tools/tictactoe-tools.js.map +1 -1
  189. package/mcp-server/dist/tools/utils.d.ts +1 -1
  190. package/mcp-server/dist/tools/utils.d.ts.map +1 -1
  191. package/mcp-server/dist/tools/utils.js +1 -1
  192. package/mcp-server/dist/tools/utils.js.map +1 -1
  193. package/mcp-server/dist/tools/whatsapp-send-file.d.ts +1 -1
  194. package/mcp-server/dist/tools/whatsapp-send-file.d.ts.map +1 -1
  195. package/mcp-server/dist/tools/whatsapp-send-file.js +1 -1
  196. package/mcp-server/dist/tools/whatsapp-send-file.js.map +1 -1
  197. package/mcp-server/dist/tools/whiteboard-tools.d.ts +3 -3
  198. package/mcp-server/dist/tools/whiteboard-tools.d.ts.map +1 -1
  199. package/mcp-server/dist/tools/whiteboard-tools.js +1 -1
  200. package/mcp-server/dist/tools/whiteboard-tools.js.map +1 -1
  201. package/mcp-server/dist/tools/youtube/analytics.d.ts +1 -1
  202. package/mcp-server/dist/tools/youtube/analytics.d.ts.map +1 -1
  203. package/mcp-server/dist/tools/youtube/analytics.js +1 -1
  204. package/mcp-server/dist/tools/youtube/analytics.js.map +1 -1
  205. package/mcp-server/dist/tools/youtube/download.d.ts +1 -1
  206. package/mcp-server/dist/tools/youtube/download.d.ts.map +1 -1
  207. package/mcp-server/dist/tools/youtube/download.js +1 -1
  208. package/mcp-server/dist/tools/youtube/download.js.map +1 -1
  209. package/mcp-server/dist/tools/youtube/media.d.ts +1 -1
  210. package/mcp-server/dist/tools/youtube/media.d.ts.map +1 -1
  211. package/mcp-server/dist/tools/youtube/media.js +1 -1
  212. package/mcp-server/dist/tools/youtube/media.js.map +1 -1
  213. package/mcp-server/dist/tools/youtube/metadata.d.ts +1 -1
  214. package/mcp-server/dist/tools/youtube/metadata.d.ts.map +1 -1
  215. package/mcp-server/dist/tools/youtube/metadata.js +1 -1
  216. package/mcp-server/dist/tools/youtube/metadata.js.map +1 -1
  217. package/mcp-server/dist/tools/youtube/navigate.d.ts +1 -1
  218. package/mcp-server/dist/tools/youtube/navigate.d.ts.map +1 -1
  219. package/mcp-server/dist/tools/youtube/navigate.js +1 -1
  220. package/mcp-server/dist/tools/youtube/navigate.js.map +1 -1
  221. package/mcp-server/dist/tools/youtube/playlist.d.ts +1 -1
  222. package/mcp-server/dist/tools/youtube/playlist.d.ts.map +1 -1
  223. package/mcp-server/dist/tools/youtube/playlist.js +1 -1
  224. package/mcp-server/dist/tools/youtube/playlist.js.map +1 -1
  225. package/mcp-server/dist/tools/youtube/schedule.d.ts +1 -1
  226. package/mcp-server/dist/tools/youtube/schedule.d.ts.map +1 -1
  227. package/mcp-server/dist/tools/youtube/schedule.js +1 -1
  228. package/mcp-server/dist/tools/youtube/schedule.js.map +1 -1
  229. package/mcp-server/dist/tools/youtube/source.d.ts +1 -1
  230. package/mcp-server/dist/tools/youtube/source.d.ts.map +1 -1
  231. package/mcp-server/dist/tools/youtube/source.js +1 -1
  232. package/mcp-server/dist/tools/youtube/source.js.map +1 -1
  233. package/mcp-server/dist/tools/youtube/upload.d.ts +1 -1
  234. package/mcp-server/dist/tools/youtube/upload.d.ts.map +1 -1
  235. package/mcp-server/dist/tools/youtube/upload.js +4 -9
  236. package/mcp-server/dist/tools/youtube/upload.js.map +1 -1
  237. package/mcp-server/dist/tui.js +16 -4
  238. package/mcp-server/dist/tui.js.map +1 -1
  239. package/mcp-server/package-lock.json +3 -3
  240. package/mcp-server/package.json +3 -3
  241. package/mcp-server/src/services/browser-bench.ts +1 -1
  242. package/mcp-server/src/services/categories.ts +77 -32
  243. package/mcp-server/src/services/desktop-bench.ts +1 -1
  244. package/mcp-server/src/tools/agents.ts +1 -1
  245. package/mcp-server/src/tools/bluesky.ts +1 -1
  246. package/mcp-server/src/tools/browser-advanced.ts +1 -1
  247. package/mcp-server/src/tools/browser-batch.ts +1 -1
  248. package/mcp-server/src/tools/browser-cheatsheet.ts +1 -1
  249. package/mcp-server/src/tools/browser-interact.ts +1 -1
  250. package/mcp-server/src/tools/browser-navigate.ts +1 -1
  251. package/mcp-server/src/tools/browser-observe.ts +1 -1
  252. package/mcp-server/src/tools/card-tools.ts +1 -1
  253. package/mcp-server/src/tools/category.ts +6 -1
  254. package/mcp-server/src/tools/choice.ts +1 -1
  255. package/mcp-server/src/tools/computer.ts +1 -1
  256. package/mcp-server/src/tools/discord-channel.ts +1 -1
  257. package/mcp-server/src/tools/discord-guild.ts +1 -1
  258. package/mcp-server/src/tools/discord-member.ts +1 -1
  259. package/mcp-server/src/tools/discord-message.ts +1 -1
  260. package/mcp-server/src/tools/discord-onboarding.ts +1 -1
  261. package/mcp-server/src/tools/discord-role.ts +1 -1
  262. package/mcp-server/src/tools/discord-thread.ts +1 -1
  263. package/mcp-server/src/tools/discord-webhook.ts +1 -1
  264. package/mcp-server/src/tools/fb-groups.ts +1 -1
  265. package/mcp-server/src/tools/forget.ts +1 -1
  266. package/mcp-server/src/tools/git-tools.ts +1 -1
  267. package/mcp-server/src/tools/gsc/experience.ts +1 -1
  268. package/mcp-server/src/tools/gsc/indexing.ts +1 -1
  269. package/mcp-server/src/tools/gsc/inspect.ts +1 -1
  270. package/mcp-server/src/tools/gsc/navigate.ts +1 -1
  271. package/mcp-server/src/tools/gsc/performance.ts +1 -1
  272. package/mcp-server/src/tools/gsc/settings.ts +1 -1
  273. package/mcp-server/src/tools/image-tools.ts +1 -1
  274. package/mcp-server/src/tools/leonardo-browser-tools.ts +1 -1
  275. package/mcp-server/src/tools/loop.ts +1 -1
  276. package/mcp-server/src/tools/memories.ts +1 -1
  277. package/mcp-server/src/tools/morelogin.ts +1 -1
  278. package/mcp-server/src/tools/profile.ts +1 -1
  279. package/mcp-server/src/tools/recall.ts +1 -1
  280. package/mcp-server/src/tools/reflect.ts +1 -1
  281. package/mcp-server/src/tools/remember.ts +13 -12
  282. package/mcp-server/src/tools/restore.ts +1 -1
  283. package/mcp-server/src/tools/style-guide-tools.ts +1 -1
  284. package/mcp-server/src/tools/sync.ts +1 -1
  285. package/mcp-server/src/tools/tictactoe-tools.ts +1 -1
  286. package/mcp-server/src/tools/utils.ts +1 -1
  287. package/mcp-server/src/tools/whatsapp-send-file.ts +1 -1
  288. package/mcp-server/src/tools/whiteboard-tools.ts +1 -1
  289. package/mcp-server/src/tools/youtube/analytics.ts +1 -1
  290. package/mcp-server/src/tools/youtube/download.ts +1 -1
  291. package/mcp-server/src/tools/youtube/media.ts +1 -1
  292. package/mcp-server/src/tools/youtube/metadata.ts +1 -1
  293. package/mcp-server/src/tools/youtube/navigate.ts +1 -1
  294. package/mcp-server/src/tools/youtube/playlist.ts +1 -1
  295. package/mcp-server/src/tools/youtube/schedule.ts +1 -1
  296. package/mcp-server/src/tools/youtube/source.ts +1 -1
  297. package/mcp-server/src/tools/youtube/upload.ts +4 -12
  298. package/mcp-server/src/tui.ts +22 -9
  299. package/neural-interface/i18n/en.json +236 -7
  300. package/neural-interface/i18n/pt-BR.json +238 -9
  301. package/neural-interface/lib/account-usage.js +5 -3
  302. package/neural-interface/lib/agent-sandbox-elevation.js +102 -0
  303. package/neural-interface/lib/agent-sandbox-setting.js +57 -0
  304. package/neural-interface/lib/app-controls-api.js +161 -0
  305. package/neural-interface/lib/assistant-api.js +40 -7
  306. package/neural-interface/lib/assistant-brains/opencode.js +13 -1
  307. package/neural-interface/lib/assistant-brains/opencode2-browser-policy/index.js +44 -0
  308. package/neural-interface/lib/assistant-brains/opencode2-route-gate/index.js +57 -0
  309. package/neural-interface/lib/assistant-catalog.js +17 -2
  310. package/neural-interface/lib/assistant-dispatch.js +3 -0
  311. package/neural-interface/lib/assistant-envelope.js +19 -1
  312. package/neural-interface/lib/assistant-route-gate-codex.js +3 -1
  313. package/neural-interface/lib/assistant-runtime.js +131 -8
  314. package/neural-interface/lib/claude-model-catalog.js +64 -14
  315. package/neural-interface/lib/codex-account-auth.js +4 -2
  316. package/neural-interface/lib/codex-accounts.js +14 -1
  317. package/neural-interface/lib/codex-settings-schema.js +111 -47
  318. package/neural-interface/lib/editor-completion-opencode.js +132 -35
  319. package/neural-interface/lib/exec-loop-command.js +11 -2
  320. package/neural-interface/lib/install-details.js +23 -5
  321. package/neural-interface/lib/launch-cache.js +293 -0
  322. package/neural-interface/lib/login-start.js +524 -0
  323. package/neural-interface/lib/native-loop-providers.js +24 -4
  324. package/neural-interface/lib/native-loop-runtime.js +19 -0
  325. package/neural-interface/lib/opencode-db-schema.js +75 -0
  326. package/neural-interface/lib/opencode-history.js +16 -1
  327. package/neural-interface/lib/opencode-protocol.js +173 -0
  328. package/neural-interface/lib/opencode-provider-view.js +81 -0
  329. package/neural-interface/lib/opencode-runtime-config.js +10 -3
  330. package/neural-interface/lib/opencode-serve-records.js +606 -0
  331. package/neural-interface/lib/opencode-v2-client.js +33 -6
  332. package/neural-interface/lib/opencode-v2-ws-requests.js +19 -5
  333. package/neural-interface/lib/opencode-worker-activity.js +229 -0
  334. package/neural-interface/lib/opencode2-client.js +760 -0
  335. package/neural-interface/lib/opencode2-proxy.js +116 -0
  336. package/neural-interface/lib/opencode2-translate.js +1008 -0
  337. package/neural-interface/lib/process-identity.js +361 -0
  338. package/neural-interface/lib/provider-panel-terminal-auth.js +3 -2
  339. package/neural-interface/lib/session-cache-builder.js +26 -5
  340. package/neural-interface/lib/session-indexer.js +3 -1
  341. package/neural-interface/lib/session-title-generator.js +20 -0
  342. package/neural-interface/lib/style-guide/api.js +4 -3
  343. package/neural-interface/lib/untrusted-file-headers.js +27 -0
  344. package/neural-interface/package-lock.json +1342 -44
  345. package/neural-interface/package.json +5 -1
  346. package/neural-interface/public/index.html +2 -2
  347. package/neural-interface/public/shared/account-menu.js +4 -1
  348. package/neural-interface/public/shared/account-usage.js +62 -2
  349. package/neural-interface/public/shared/account-view.js +2 -1
  350. package/neural-interface/public/shared/agent-runtime-options.js +55 -11
  351. package/neural-interface/public/shared/assistant/asst-account-menu.js +298 -0
  352. package/neural-interface/public/shared/assistant/asst-agents-dock.js +172 -17
  353. package/neural-interface/public/shared/assistant/asst-api.js +18 -3
  354. package/neural-interface/public/shared/assistant/asst-brain-picker.js +424 -152
  355. package/neural-interface/public/shared/assistant/asst-composer.js +1 -1
  356. package/neural-interface/public/shared/assistant/asst-hosts.js +49 -2
  357. package/neural-interface/public/shared/assistant/asst-menu.js +275 -77
  358. package/neural-interface/public/shared/assistant/asst-model-chip.js +135 -0
  359. package/neural-interface/public/shared/assistant/asst-panel.js +236 -35
  360. package/neural-interface/public/shared/assistant/asst-rack-styles.js +28 -10
  361. package/neural-interface/public/shared/assistant/asst-redact.js +186 -0
  362. package/neural-interface/public/shared/assistant/asst-render.js +382 -36
  363. package/neural-interface/public/shared/assistant/asst-run-stage.js +231 -0
  364. package/neural-interface/public/shared/assistant/asst-sanitize.js +193 -3
  365. package/neural-interface/public/shared/assistant/asst-scene-styles.js +273 -0
  366. package/neural-interface/public/shared/assistant/asst-scenes.js +528 -0
  367. package/neural-interface/public/shared/assistant/asst-sidepanel-styles.js +3 -15
  368. package/neural-interface/public/shared/assistant/asst-state.js +14 -0
  369. package/neural-interface/public/shared/assistant/asst-styles.js +109 -17
  370. package/neural-interface/public/shared/assistant/asst-tool-kinds.js +13 -1
  371. package/neural-interface/public/shared/cc-dropdown.js +480 -0
  372. package/neural-interface/public/shared/cdx/cdx-panel.js +14 -2
  373. package/neural-interface/public/shared/cdx/cdx-render.js +15 -3
  374. package/neural-interface/public/shared/cdx/cdx-styles.js +49 -5
  375. package/neural-interface/public/shared/cdx/cdx-tabs.js +152 -35
  376. package/neural-interface/public/shared/cp/cp-markdown.js +4 -57
  377. package/neural-interface/public/shared/data-cache.js +223 -0
  378. package/neural-interface/public/shared/desktop-bridge.js +11 -0
  379. package/neural-interface/public/shared/desktop-titlebar-view.js +78 -1
  380. package/neural-interface/public/shared/desktop-titlebar.js +214 -28
  381. package/neural-interface/public/shared/desktop-update-view.js +15 -5
  382. package/neural-interface/public/shared/file-links.js +73 -8
  383. package/neural-interface/public/shared/html-shell.js +74 -80
  384. package/neural-interface/public/shared/launch-prefetch.js +59 -0
  385. package/neural-interface/public/shared/ocp-v2/ocp-v2-caps.js +3 -2
  386. package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +11 -3
  387. package/neural-interface/public/shared/ocp-v2/ocp-v2-modelpicker.js +54 -17
  388. package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +97 -3
  389. package/neural-interface/public/shared/ocp-v2/ocp-v2-projectbar.js +3 -2
  390. package/neural-interface/public/shared/ocp-v2/ocp-v2-providers.js +11 -9
  391. package/neural-interface/public/shared/ocp-v2/ocp-v2-rehydrate.js +15 -4
  392. package/neural-interface/public/shared/ocp-v2/ocp-v2-render.js +1 -1
  393. package/neural-interface/public/shared/ocp-v2/ocp-v2-send-logic.js +401 -0
  394. package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +16 -9
  395. package/neural-interface/public/shared/ocp-v2/ocp-v2-sessions-logic.js +60 -0
  396. package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +83 -5
  397. package/neural-interface/public/shared/ocp-v2/ocp-v2-ws.js +195 -19
  398. package/neural-interface/public/shared/opencode-providers.js +39 -0
  399. package/neural-interface/public/shared/schedules-view.js +318 -0
  400. package/neural-interface/public/shared/settings/settings-app-pane.js +335 -0
  401. package/neural-interface/public/shared/settings/settings-app.js +243 -0
  402. package/neural-interface/public/shared/settings/settings-data.js +88 -0
  403. package/neural-interface/public/shared/settings/settings-ia.js +17 -0
  404. package/neural-interface/public/shared/showcase-privacy.js +2 -1
  405. package/neural-interface/public/shared/sidepanel-session-status.js +49 -0
  406. package/neural-interface/public/shared/styles.css +543 -372
  407. package/neural-interface/public/shared/ui-assistant.js +27 -5
  408. package/neural-interface/public/shared/ui-automation-studio.js +67 -27
  409. package/neural-interface/public/shared/ui-bookmarks.js +2 -1
  410. package/neural-interface/public/shared/ui-claude-panel.js +126 -12
  411. package/neural-interface/public/shared/ui-codex-panel.js +1 -0
  412. package/neural-interface/public/shared/ui-detail.js +6 -6
  413. package/neural-interface/public/shared/ui-explorer.js +2 -0
  414. package/neural-interface/public/shared/ui-file-links.js +1 -0
  415. package/neural-interface/public/shared/ui-image-gallery.js +6 -5
  416. package/neural-interface/public/shared/ui-invite.js +18 -2
  417. package/neural-interface/public/shared/ui-link.js +9 -9
  418. package/neural-interface/public/shared/ui-menubar.js +232 -33
  419. package/neural-interface/public/shared/ui-native-loop-router.js +2 -0
  420. package/neural-interface/public/shared/ui-opencode-panel-v2.js +1 -0
  421. package/neural-interface/public/shared/ui-schedules-studio.js +2099 -869
  422. package/neural-interface/public/shared/ui-sessions.js +15 -4
  423. package/neural-interface/public/shared/ui-settings.js +87 -36
  424. package/neural-interface/public/shared/ui-sidebar.js +4 -4
  425. package/neural-interface/public/shared/ui-sidepanel-session-entry.js +13 -0
  426. package/neural-interface/public/shared/ui-sidepanel-sessions.js +55 -4
  427. package/neural-interface/public/shared/ui-sidepanel-tray.js +84 -8
  428. package/neural-interface/public/shared/ui-skills.js +70 -12
  429. package/neural-interface/public/shared/ui-sync.js +9 -0
  430. package/neural-interface/public/shared/ui-terminal.js +36 -20
  431. package/neural-interface/public/shared/ui-trash.js +8 -1
  432. package/neural-interface/public/shared/ui-tutorial-steps.js +7 -3
  433. package/neural-interface/public/shared/ui-tutorial.js +15 -5
  434. package/neural-interface/public/shared/ui-update.js +87 -16
  435. package/neural-interface/public/shared/ui-whiteboard.js +2 -1
  436. package/neural-interface/public/variant/2d/main.js +4 -1
  437. package/neural-interface/public/variant/3d/main.js +3 -0
  438. package/neural-interface/public/vendor/highlight/LICENSE +29 -0
  439. package/neural-interface/public/vendor/highlight/github-dark-dimmed-11.12.0.min.css +9 -0
  440. package/neural-interface/public/vendor/highlight/highlight-11.12.0.min.js +1262 -0
  441. package/neural-interface/public/vendor/highlight/manifest.json +5 -0
  442. package/neural-interface/public/vendor/html2canvas/LICENSE +22 -0
  443. package/neural-interface/public/vendor/html2canvas/html2canvas-1.4.1.min.js +20 -0
  444. package/neural-interface/public/vendor/html2canvas/manifest.json +4 -0
  445. package/neural-interface/public/vendor/marked/LICENSE.md +44 -0
  446. package/neural-interface/public/vendor/marked/manifest.json +4 -0
  447. package/neural-interface/public/vendor/marked/marked-14.1.4.esm.js +2502 -0
  448. package/neural-interface/public/vendor/mermaid/LICENSE +21 -0
  449. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/abnfDiagram-PAR5IXJI.mjs +1 -0
  450. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/architecture-7GRP2DOG-M7G3SWCO.mjs +1 -0
  451. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/architectureDiagram-2PNWDENW.mjs +36 -0
  452. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/blockDiagram-PUWGUBOA.mjs +129 -0
  453. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/c4Diagram-3NLNHZP5.mjs +38 -0
  454. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-2NMSUPJH.mjs +1 -0
  455. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-32MCUW2P.mjs +206 -0
  456. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-3NPNU5GP.mjs +1 -0
  457. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-3SMGFRGC.mjs +1 -0
  458. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-4CAJECRU.mjs +14 -0
  459. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-4OADUZ5Q.mjs +10 -0
  460. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5IMINLNL.mjs +1 -0
  461. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5IQCK5RY.mjs +3 -0
  462. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5MVFYWFU.mjs +1 -0
  463. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-AQ6EADP3.mjs +1 -0
  464. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-AZZRMDJM.mjs +15 -0
  465. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-CLS4B6BI.mjs +168 -0
  466. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-DZP67EKU.mjs +70 -0
  467. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-EICP7K5X.mjs +1 -0
  468. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-GDY2UAB4.mjs +1 -0
  469. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-H7VHZCWX.mjs +1 -0
  470. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-IJBDOHL6.mjs +1 -0
  471. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JFFVMJIA.mjs +1 -0
  472. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JQRUD6KW.mjs +1 -0
  473. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JZGDI5JK.mjs +1 -0
  474. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-KD6SPIPN.mjs +2 -0
  475. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-NF366YI6.mjs +231 -0
  476. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-NUDPKBEF.mjs +32 -0
  477. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-OJINMHTS.mjs +1 -0
  478. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-Q6NGPIAH.mjs +2 -0
  479. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-QJSWEUOL.mjs +132 -0
  480. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-R7JDMUKV.mjs +1 -0
  481. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-RCXAM2GK.mjs +1 -0
  482. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-RT4MAWR3.mjs +1 -0
  483. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-SFMINX4W.mjs +1 -0
  484. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-SLDQ463B.mjs +88 -0
  485. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-STOV2HOB.mjs +1 -0
  486. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-T5OCTHI4.mjs +1 -0
  487. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-TCEHX7R3.mjs +1 -0
  488. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VQC2EELJ.mjs +1 -0
  489. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VRZKL3EH.mjs +1 -0
  490. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VTHDQ7BV.mjs +1 -0
  491. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VY2OSTJR.mjs +2 -0
  492. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-WUBWJARI.mjs +1 -0
  493. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-YBMQ5JGJ.mjs +2 -0
  494. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-YDMLL4PJ.mjs +1 -0
  495. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-Z6V44ARX.mjs +62 -0
  496. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZJJ7VQJP.mjs +339 -0
  497. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZNLK7HRR.mjs +1 -0
  498. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZQN7UHIL.mjs +1 -0
  499. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZS6VBONO.mjs +174 -0
  500. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZUNWM646.mjs +1 -0
  501. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/classDiagram-FGAMPOII.mjs +1 -0
  502. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/classDiagram-v2-AI5RJEK4.mjs +1 -0
  503. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cose-bilkent-Q72C2OJ3.mjs +1 -0
  504. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cynefin-OW5HDTMX-6OCTWOGG.mjs +1 -0
  505. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cynefinDiagram-2OOWUY4M.mjs +62 -0
  506. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/dagre-MPVFI544.mjs +4 -0
  507. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-AE4NWXFW.mjs +24 -0
  508. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-BUJID5UG.mjs +41 -0
  509. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-C44CZ5NI.mjs +24 -0
  510. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-EYOLEXXS.mjs +30 -0
  511. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-P7B6PWOJ.mjs +3 -0
  512. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ebnfDiagram-FTPZ3PV6.mjs +1 -0
  513. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/erDiagram-H3ERR26V.mjs +99 -0
  514. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/eventmodeling-NTZA5JFV-WKSWQHFS.mjs +1 -0
  515. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/flowDiagram-YHGXBVSY.mjs +1 -0
  516. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ganttDiagram-RWFTB7ED.mjs +292 -0
  517. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/gitGraph-4MIJSDKK-JH2HKYUO.mjs +1 -0
  518. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/gitGraphDiagram-MAR6GKOP.mjs +106 -0
  519. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/info-A6RAGUB7-3TX3OFWW.mjs +1 -0
  520. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/infoDiagram-LV547AFH.mjs +2 -0
  521. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ishikawaDiagram-PUJQGNDS.mjs +70 -0
  522. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/journeyDiagram-EW5QJT4W.mjs +139 -0
  523. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/kanban-definition-JSQERAZB.mjs +89 -0
  524. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/katex-CZ4GXH2S.mjs +257 -0
  525. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/mindmap-definition-VBJCLQLM.mjs +96 -0
  526. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/packet-AYTQ26CC-MKII6P3Y.mjs +1 -0
  527. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pegDiagram-7WILOQTJ.mjs +1 -0
  528. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pie-WAS4IAKB-6B4OPMJ5.mjs +1 -0
  529. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pieDiagram-EFA7CBSB.mjs +39 -0
  530. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/quadrantDiagram-WARVYA7P.mjs +7 -0
  531. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/radar-RG4KPBEZ-UPTR3XUL.mjs +1 -0
  532. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-74A4TZTK-MEFUPFMS.mjs +1 -0
  533. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-abnf-HS5TGJTU-R5YG2S5D.mjs +1 -0
  534. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-ebnf-LZEXJU2U-G5QEX2L6.mjs +1 -0
  535. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-peg-WCYAUIDC-H5I2ZRY2.mjs +1 -0
  536. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroadDiagram-5NIQVNLQ.mjs +1 -0
  537. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/requirementDiagram-SXREGOKZ.mjs +84 -0
  538. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sankeyDiagram-VV74M2VP.mjs +40 -0
  539. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sequenceDiagram-52ZFIFDL.mjs +162 -0
  540. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sizeCapture-FGA5AGYP.mjs +1 -0
  541. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/stateDiagram-3QAKPIVI.mjs +1 -0
  542. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/stateDiagram-v2-HN2P4RDZ.mjs +1 -0
  543. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/swimlanes-QLVP42QD.mjs +1 -0
  544. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/swimlanesDiagram-JKPDBFCN.mjs +8 -0
  545. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/timeline-definition-GS45XAXW.mjs +120 -0
  546. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/treeView-Q6P3EWNA-ZRJGANNQ.mjs +1 -0
  547. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/treemap-WGGIJYW6-K64VN5AS.mjs +1 -0
  548. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/vennDiagram-QIQU2ZRJ.mjs +34 -0
  549. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/wardley-WFR3VGLG-D67OWCCH.mjs +1 -0
  550. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/wardleyDiagram-U6YNM66N.mjs +78 -0
  551. package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/xychartDiagram-XJAZEDNM.mjs +7 -0
  552. package/neural-interface/public/vendor/mermaid/manifest.json +4 -0
  553. package/neural-interface/public/vendor/mermaid/mermaid-11.17.2.esm.min.mjs +14 -0
  554. package/neural-interface/scripts/build-vendor.mjs +84 -3
  555. package/neural-interface/scripts/rebuild-pty.js +14 -2
  556. package/neural-interface/server.js +1279 -372
  557. package/npm-shrinkwrap.json +4424 -0
  558. package/package.json +54 -2
  559. package/postinstall.js +61 -47
  560. package/preuninstall.js +8 -35
  561. package/setup.js +76 -44
  562. package/skills/synabun/modules/idea.md +1 -1
  563. package/skills/synabun/modules/schedule.md +2 -2
  564. package/updater.cmd +2 -2
  565. package/updater.mjs +97 -3
@@ -0,0 +1,524 @@
1
+ // ═══════════════════════════════════════════
2
+ // SynaBun — start at login, for an npm or Git install (Settings > App)
3
+ // ═══════════════════════════════════════════
4
+ //
5
+ // The server starts in the background when the user logs in, with no window
6
+ // and no terminal, through the same launcher the Start Server button uses
7
+ // (launcher.mjs → lib/start-launcher.js runLauncher, in its background mode:
8
+ // nothing happens when a server already answers or a start is under way, and
9
+ // the server gets the login shell's environment, so an nvm or Homebrew Node
10
+ // and the user's CLIs are found as in a terminal). Every path in the entry is
11
+ // absolute: the PATH a login starts programs with is not the user's.
12
+ //
13
+ // macOS ~/Library/LaunchAgents/ai.synabun.server.plist (RunAtLoad; the
14
+ // launcher's process group is left alone when it exits)
15
+ // Windows HKCU\...\Run "SynaBun Server": wscript.exe runs a small script of
16
+ // SynaBun's (DATA_HOME/runtime/login/synabun-hidden.vbs) that starts
17
+ // node with no window. A console program started from Run would
18
+ // show a console. A packaged entry (a GUI program) runs directly
19
+ // Linux ~/.config/autostart/synabun-server.desktop (XDG autostart)
20
+ //
21
+ // The entry itself is the setting: on while it is there, off when it is gone.
22
+ // It is read back from the system for every answer (inspect), and put back in
23
+ // place on every start of the server while it is on (heal: another Node, a
24
+ // moved install). One the user turned off in the system (disabled in Startup
25
+ // apps, in Login Items, or in the desktop's autostart settings) stays off and
26
+ // is reported as off.
27
+ //
28
+ // The SynaBun desktop app on the same data folder opens at login on its own
29
+ // (packaging/desktop/src/login-item.mjs, which names both apps' entries the
30
+ // same way: NPM_LOGIN, DESKTOP_LOGIN; a test keeps the two equal). Two starts
31
+ // at login would start two servers on one data folder: while the app's entry is
32
+ // there and on for this data folder (read from the system, desktopLoginOwner),
33
+ // this one is refused ('desktop-app'); turning the app's on removes this one.
34
+ //
35
+ // Pure: the file calls and the programs it runs are handed in (tests/login-start.test.mjs).
36
+
37
+ import { execFileSync } from 'node:child_process';
38
+ import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs';
39
+ import { homedir, tmpdir } from 'node:os';
40
+ import { dirname, join as nativeJoin, posix, win32 } from 'node:path';
41
+ import { desktopExecArg, launcherOverrides, winQuote } from '../../lib/start-launcher.js';
42
+
43
+ /** The names of the entries (packaging/desktop/src/login-item.mjs NPM_LOGIN must be equal). */
44
+ export const NPM_LOGIN = Object.freeze({
45
+ macLabel: 'ai.synabun.server',
46
+ winName: 'SynaBun Server',
47
+ linuxFile: 'synabun-server.desktop',
48
+ });
49
+ /** What the launcher is started with at login (lib/start-launcher.js parseLauncherArgs reads them). */
50
+ export const LOGIN_ARGS = Object.freeze(['--via=login', '--background']);
51
+ /**
52
+ * The desktop app's own login entries (packaging/desktop/src/login-item.mjs DESKTOP_LOGIN must be equal): read from
53
+ * the system to know whether the app opens at login on this data folder, never from the app's settings file.
54
+ */
55
+ export const DESKTOP_LOGIN = Object.freeze({
56
+ macLabel: 'ai.synabun.app.login',
57
+ winName: 'ai.synabun.app',
58
+ linuxFile: 'synabun-app.desktop',
59
+ env: 'SYNABUN_DESKTOP_LOGIN',
60
+ flag: '--synabun-login',
61
+ dataFlag: '--synabun-data-home=',
62
+ portFlag: '--synabun-port=',
63
+ });
64
+ export const HIDDEN_SCRIPT = 'synabun-hidden.vbs';
65
+ export const LINUX_MARKER = 'X-SynaBun-Login=server';
66
+
67
+ const RUN_KEY = 'HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run';
68
+ const APPROVED_KEY = 'HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartupApproved\\Run';
69
+
70
+ /**
71
+ * Runs its arguments as one command line with no window. ASCII only, no path
72
+ * in it: what it starts comes in as its arguments, which the registry holds as
73
+ * Unicode (Windows Script Host reads the file itself in the ANSI code page).
74
+ */
75
+ export const HIDDEN_SCRIPT_SOURCE = [
76
+ "' SynaBun: runs its arguments as one command, with no window (start at login).",
77
+ "' Generated by SynaBun. Do not edit.",
78
+ 'Option Explicit',
79
+ 'Dim shell, command, i, a, n',
80
+ 'command = ""',
81
+ 'For i = 0 To WScript.Arguments.Count - 1',
82
+ ' a = WScript.Arguments(i)',
83
+ " ' Backslashes before the closing quote are doubled, or the last one would escape it.",
84
+ ' n = 0',
85
+ ' Do While n < Len(a)',
86
+ ' If Mid(a, Len(a) - n, 1) <> "\\" Then Exit Do',
87
+ ' n = n + 1',
88
+ ' Loop',
89
+ ' command = command & " """ & a & String(n, "\\") & """"',
90
+ 'Next',
91
+ 'Set shell = CreateObject("WScript.Shell")',
92
+ 'shell.Run Trim(command), 0, False',
93
+ '',
94
+ ].join('\r\n');
95
+
96
+ function defaultRun(file, args, { timeout = 5000 } = {}) {
97
+ return execFileSync(file, args, { encoding: 'utf8', timeout, stdio: ['ignore', 'pipe', 'pipe'], windowsHide: true });
98
+ }
99
+
100
+ const DEFAULT_FS = { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync };
101
+
102
+ const failure = (code, message) => Object.assign(new Error(message || code), { code });
103
+
104
+ function xmlEscape(value) {
105
+ return String(value).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
106
+ }
107
+
108
+ function systemTool(env, name) {
109
+ const root = env.SystemRoot || env.SYSTEMROOT || env.windir;
110
+ return root ? win32.join(root, 'System32', name) : name;
111
+ }
112
+
113
+ /**
114
+ * One REG_SZ value of a `reg export` file, or null. `reg query` prints in the console's code page, which turns a
115
+ * non-ASCII folder name (C:\Users\João) into other characters; the export (UTF-16) keeps it.
116
+ */
117
+ export function parseRegExport(text, name) {
118
+ const quoted = `"${String(name).replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"=`;
119
+ for (const line of String(text || '').replace(/^\uFEFF/, '').split(/\r?\n/)) {
120
+ if (!line.toLowerCase().startsWith(quoted.toLowerCase())) continue;
121
+ const rest = line.slice(quoted.length);
122
+ if (!rest.startsWith('"') || !rest.endsWith('"')) return null;
123
+ return rest.slice(1, -1).replace(/\\(["\\])/g, '$1');
124
+ }
125
+ return null;
126
+ }
127
+
128
+ function decodeRegFile(buffer) {
129
+ const bytes = Buffer.isBuffer(buffer) ? buffer : Buffer.from(String(buffer ?? ''), 'utf8');
130
+ return bytes[0] === 0xff && bytes[1] === 0xfe ? bytes.subarray(2).toString('utf16le') : bytes.toString('utf8');
131
+ }
132
+
133
+ /** One value of a registry key, read through `reg export` (Unicode-safe), or null. */
134
+ export function readRegValue(key, name, { run = defaultRun, fs = DEFAULT_FS, env = process.env, tmp = tmpdir() } = {}) {
135
+ const file = nativeJoin(tmp, `synabun-login-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.reg`);
136
+ try {
137
+ run(systemTool(env, 'reg.exe'), ['export', key, file, '/y']);
138
+ return parseRegExport(decodeRegFile(fs.readFileSync(file)), name);
139
+ } catch {
140
+ return null;
141
+ } finally {
142
+ try { fs.rmSync(file, { force: true }); } catch {}
143
+ }
144
+ }
145
+
146
+ /** The data of one value in `reg query` output, or null. */
147
+ export function parseRegQuery(output, name) {
148
+ for (const line of String(output || '').split(/\r?\n/)) {
149
+ const match = /^\s{2,}(.+?)\s{2,}(REG_[A-Z_]+)\s{2,}(.*)$/.exec(line) || /^\s{2,}(.+?)\s{2,}(REG_[A-Z_]+)\s*$/.exec(line);
150
+ if (match && match[1].toLowerCase() === String(name).toLowerCase()) return (match[3] ?? '').trim();
151
+ }
152
+ return null;
153
+ }
154
+
155
+ /** Windows' Startup apps switch, from its REG_BINARY: an odd first byte is "disabled". null when unknown. */
156
+ export function startupApproved(hex) {
157
+ const first = /^[0-9a-f]{2}/i.exec(String(hex || '').trim());
158
+ if (!first) return null;
159
+ return (parseInt(first[0], 16) & 1) === 0;
160
+ }
161
+
162
+ /** The [Desktop Entry] keys of a .desktop file (the first value of a key counts). */
163
+ function desktopEntryKeys(text) {
164
+ const out = {};
165
+ let inGroup = false;
166
+ for (const raw of String(text || '').split(/\r?\n/)) {
167
+ const line = raw.trim();
168
+ if (!line || line.startsWith('#')) continue;
169
+ if (line.startsWith('[')) { inGroup = line === '[Desktop Entry]'; continue; }
170
+ const at = line.indexOf('=');
171
+ if (inGroup && at > 0 && !(line.slice(0, at).trim() in out)) out[line.slice(0, at).trim()] = line.slice(at + 1).trim();
172
+ }
173
+ return out;
174
+ }
175
+
176
+ /**
177
+ * The entry this install would write now, as data: no side effects.
178
+ * { kind: 'launch-agent' | 'run-value' | 'autostart', path?, content?, key?, name?, value?, helper? }
179
+ * `entry` is a packaged build's entry executable (it brings its own Node): `<entry> launcher …`.
180
+ */
181
+ export function buildLoginPlan({
182
+ platform = process.platform, nodePath = process.execPath, packageRoot, home = homedir(), env = process.env, dataHome, entry = null,
183
+ } = {}) {
184
+ if (!packageRoot) throw new Error('packageRoot is required');
185
+ const overrides = launcherOverrides({ env, home, platform });
186
+ const args = [...LOGIN_ARGS, ...(overrides.dataHome ? ['--data-home', overrides.dataHome] : []), ...(overrides.port ? ['--port', String(overrides.port)] : [])];
187
+
188
+ if (platform === 'win32') {
189
+ const launcher = entry || win32.join(packageRoot, 'launcher.mjs');
190
+ const program = entry ? [entry, 'launcher', ...args] : [nodePath, launcher, ...args];
191
+ const mark = winQuote(launcher);
192
+ if (entry) return { kind: 'run-value', key: RUN_KEY, name: NPM_LOGIN.winName, value: program.map(winQuote).join(' '), helper: null, mark, refuse: null };
193
+ const helperPath = win32.join(dataHome, 'runtime', 'login', HIDDEN_SCRIPT);
194
+ // wscript's own options stay bare (//B: no message boxes); everything else is one quoted argument each.
195
+ const value = [winQuote(systemTool(env, 'wscript.exe')), '//B', '//NoLogo', ...[helperPath, ...program].map(winQuote)].join(' ');
196
+ // WshShell.Run expands %NAME% in what it runs, and nothing escapes it: such a path cannot be started this way.
197
+ const refuse = [helperPath, ...program].some(word => word.includes('%')) ? 'bad-path' : null;
198
+ return { kind: 'run-value', key: RUN_KEY, name: NPM_LOGIN.winName, value, helper: { path: helperPath, content: HIDDEN_SCRIPT_SOURCE }, mark, refuse };
199
+ }
200
+
201
+ const launcher = entry || posix.join(packageRoot, 'launcher.mjs');
202
+ const program = entry ? [entry, 'launcher', ...args] : [nodePath, launcher, ...args];
203
+ if (platform === 'darwin') {
204
+ const shell = /^\/[\w./-]+$/.test(String(env.SHELL || '')) ? env.SHELL : null;
205
+ const content = [
206
+ '<?xml version="1.0" encoding="UTF-8"?>',
207
+ '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">',
208
+ '<plist version="1.0">',
209
+ '<dict>',
210
+ ` <key>Label</key><string>${NPM_LOGIN.macLabel}</string>`,
211
+ ' <key>ProgramArguments</key>',
212
+ ' <array>',
213
+ ...program.map(word => ` <string>${xmlEscape(word)}</string>`),
214
+ ' </array>',
215
+ ` <key>WorkingDirectory</key><string>${xmlEscape(packageRoot)}</string>`,
216
+ // The launcher reads the login shell's environment (PATH, nvm): it is told which shell that is.
217
+ ...(shell ? [' <key>EnvironmentVariables</key>', ' <dict>', ` <key>SHELL</key><string>${xmlEscape(shell)}</string>`, ' </dict>'] : []),
218
+ ' <key>RunAtLoad</key><true/>',
219
+ // The server outlives the launcher: launchd must not end it with the launcher's process group.
220
+ ' <key>AbandonProcessGroup</key><true/>',
221
+ ' <key>ProcessType</key><string>Interactive</string>',
222
+ ' <key>StandardOutPath</key><string>/dev/null</string>',
223
+ ' <key>StandardErrorPath</key><string>/dev/null</string>',
224
+ '</dict>',
225
+ '</plist>',
226
+ '',
227
+ ].join('\n');
228
+ return { kind: 'launch-agent', path: posix.join(home, 'Library', 'LaunchAgents', `${NPM_LOGIN.macLabel}.plist`), content, mark: `<string>${xmlEscape(launcher)}</string>` };
229
+ }
230
+
231
+ const config = String(env.XDG_CONFIG_HOME || '');
232
+ const dir = posix.join(config.startsWith('/') ? config : posix.join(home, '.config'), 'autostart');
233
+ const content = [
234
+ '[Desktop Entry]',
235
+ 'Type=Application',
236
+ 'Name=SynaBun server',
237
+ 'Comment=Starts the SynaBun server in the background when you log in',
238
+ `Exec=${program.map(desktopExecArg).join(' ')}`,
239
+ 'Terminal=false',
240
+ 'NoDisplay=true',
241
+ 'X-GNOME-Autostart-enabled=true',
242
+ LINUX_MARKER,
243
+ '',
244
+ ].join('\n');
245
+ return { kind: 'autostart', path: posix.join(dir, NPM_LOGIN.linuxFile), content, mark: desktopExecArg(launcher) };
246
+ }
247
+
248
+ /**
249
+ * The entry as the system has it: 'on' (in place), 'stale' (there, but it
250
+ * starts something else: another Node, a moved install), 'disabled' (turned
251
+ * off in the system) or 'off' (not there).
252
+ */
253
+ export function inspectLoginEntry(plan, { env = process.env, fs = DEFAULT_FS, run = defaultRun, uid = typeof process.getuid === 'function' ? process.getuid() : null } = {}) {
254
+ if (plan.kind === 'run-value') {
255
+ const reg = systemTool(env, 'reg.exe');
256
+ const value = readRegValue(plan.key, plan.name, { run, fs, env });
257
+ if (value == null) return 'off';
258
+ let approved = null;
259
+ try { approved = startupApproved(parseRegQuery(run(reg, ['query', APPROVED_KEY, '/v', plan.name]), plan.name)); } catch {}
260
+ if (approved === false) return 'disabled';
261
+ const helperOk = !plan.helper || (() => { try { return fs.readFileSync(plan.helper.path, 'utf8') === plan.helper.content; } catch { return false; } })();
262
+ return value === plan.value && helperOk ? 'on' : 'stale';
263
+ }
264
+ let text = null;
265
+ try { text = fs.readFileSync(plan.path, 'utf8'); } catch { return 'off'; }
266
+ if (plan.kind === 'autostart') {
267
+ const keys = desktopEntryKeys(text);
268
+ if (/^true$/i.test(keys.Hidden || '') || /^false$/i.test(keys['X-GNOME-Autostart-enabled'] || 'true')) return 'disabled';
269
+ }
270
+ if (plan.kind === 'launch-agent' && uid != null) {
271
+ // Login Items > Allow in the Background, switched off, disables the job.
272
+ try {
273
+ const out = run('/bin/launchctl', ['print-disabled', `gui/${uid}`]);
274
+ if (new RegExp(`"${NPM_LOGIN.macLabel.replace(/\./g, '\\.')}"\\s*=>\\s*(?:true|disabled)`).test(String(out))) return 'disabled';
275
+ } catch {}
276
+ }
277
+ return text === plan.content ? 'on' : 'stale';
278
+ }
279
+
280
+ function writeAtomic(fs, path, content, mode) {
281
+ fs.mkdirSync(dirname(path), { recursive: true });
282
+ const temp = `${path}.${process.pid}.tmp`;
283
+ fs.writeFileSync(temp, content, mode ? { mode } : undefined);
284
+ fs.renameSync(temp, path);
285
+ }
286
+
287
+ /**
288
+ * Put the entry in place. Throws { code: 'write-failed' | 'no-wscript' }. With `enable` (the user turned it on
289
+ * in Settings) a switch the system holds for it is turned on too: Windows' Startup apps, launchd's disabled list.
290
+ */
291
+ export function applyLoginEntry(plan, { env = process.env, fs = DEFAULT_FS, run = defaultRun, uid = typeof process.getuid === 'function' ? process.getuid() : null, enable = false } = {}) {
292
+ if (plan.refuse) throw failure(plan.refuse, 'a path with % in it cannot be started at login on Windows');
293
+ try {
294
+ if (plan.kind === 'run-value') {
295
+ const wscript = systemTool(env, 'wscript.exe');
296
+ if (plan.helper && win32.isAbsolute(wscript) && !fs.existsSync(wscript)) throw failure('no-wscript', `${wscript} is missing`);
297
+ if (plan.helper) writeAtomic(fs, plan.helper.path, plan.helper.content);
298
+ run(systemTool(env, 'reg.exe'), ['add', plan.key, '/v', plan.name, '/t', 'REG_SZ', '/d', plan.value, '/f']);
299
+ // No Startup apps record: enabled.
300
+ if (enable) { try { run(systemTool(env, 'reg.exe'), ['delete', APPROVED_KEY, '/v', plan.name, '/f']); } catch {} }
301
+ return;
302
+ }
303
+ writeAtomic(fs, plan.path, plan.content, 0o644);
304
+ if (enable && plan.kind === 'launch-agent' && uid != null) { try { run('/bin/launchctl', ['enable', `gui/${uid}/${NPM_LOGIN.macLabel}`]); } catch {} }
305
+ } catch (error) {
306
+ if (error.code === 'no-wscript') throw error;
307
+ throw failure('write-failed', error.message);
308
+ }
309
+ }
310
+
311
+ /** The entry as it is written now (the file, or the Run value), or null. */
312
+ export function readLoginEntry(plan, { env = process.env, fs = DEFAULT_FS, run = defaultRun } = {}) {
313
+ if (plan.kind === 'run-value') return readRegValue(plan.key, plan.name, { run, fs, env });
314
+ try { return fs.readFileSync(plan.path, 'utf8'); } catch { return null; }
315
+ }
316
+
317
+ /** Take the entry away. Throws { code: 'write-failed' } when it stays. */
318
+ export function removeLoginEntry(plan, { env = process.env, fs = DEFAULT_FS, run = defaultRun, uid = typeof process.getuid === 'function' ? process.getuid() : null } = {}) {
319
+ try {
320
+ if (plan.kind === 'run-value') {
321
+ try { run(systemTool(env, 'reg.exe'), ['delete', plan.key, '/v', plan.name, '/f']); } catch (error) {
322
+ if (inspectLoginEntry(plan, { env, fs, run }) !== 'off') throw error;
323
+ }
324
+ if (plan.helper) fs.rmSync(plan.helper.path, { force: true });
325
+ return;
326
+ }
327
+ if (plan.kind === 'launch-agent' && uid != null) {
328
+ // Loaded since the last login (it ran once then): unload it too.
329
+ try { run('/bin/launchctl', ['bootout', `gui/${uid}/${NPM_LOGIN.macLabel}`]); } catch {}
330
+ }
331
+ fs.rmSync(plan.path, { force: true });
332
+ } catch (error) {
333
+ throw failure('write-failed', error.message);
334
+ }
335
+ }
336
+
337
+ // ── The desktop app's entry, as the system has it ──
338
+
339
+ /** The strings of a plist's ProgramArguments array. */
340
+ function plistArguments(text) {
341
+ const block = /<key>\s*ProgramArguments\s*<\/key>\s*<array>([\s\S]*?)<\/array>/.exec(String(text || ''));
342
+ const unxml = (v) => v.replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&quot;/g, '"').replace(/&apos;/g, "'").replace(/&amp;/g, '&');
343
+ return block ? [...block[1].matchAll(/<string>([\s\S]*?)<\/string>/g)].map(m => unxml(m[1])) : [];
344
+ }
345
+
346
+ /** The words of a .desktop Exec value (its quoting and escapes undone). */
347
+ function desktopExecWords(value) {
348
+ const text = String(value || '').replace(/\\\\/g, '\\').replace(/%%/g, '%');
349
+ const words = [];
350
+ let word = '';
351
+ let quoted = false;
352
+ let any = false;
353
+ for (let i = 0; i < text.length; i++) {
354
+ const ch = text[i];
355
+ if (quoted) {
356
+ if (ch === '\\' && i + 1 < text.length) { word += text[++i]; continue; }
357
+ if (ch === '"') { quoted = false; continue; }
358
+ word += ch;
359
+ } else if (ch === '"') { quoted = true; any = true; } else if (/\s/.test(ch)) {
360
+ if (word || any) words.push(word);
361
+ word = ''; any = false;
362
+ } else word += ch;
363
+ }
364
+ if (word || any) words.push(word);
365
+ return words;
366
+ }
367
+
368
+ /** The words of a Windows command line (CommandLineToArgvW's quoting). */
369
+ function windowsWords(line) {
370
+ const text = String(line || '');
371
+ const words = [];
372
+ let word = '';
373
+ let quoted = false;
374
+ let any = false;
375
+ let i = 0;
376
+ while (i < text.length) {
377
+ const ch = text[i];
378
+ if (ch === '\\') {
379
+ let slashes = 0;
380
+ while (text[i] === '\\') { slashes++; i++; }
381
+ if (text[i] === '"') {
382
+ word += '\\'.repeat(Math.floor(slashes / 2));
383
+ if (slashes % 2) { word += '"'; any = true; i++; }
384
+ } else word += '\\'.repeat(slashes);
385
+ continue;
386
+ }
387
+ i++;
388
+ if (ch === '"') { quoted = !quoted; any = true; continue; }
389
+ if (!quoted && /\s/.test(ch)) { if (word || any) words.push(word); word = ''; any = false; continue; }
390
+ word += ch;
391
+ }
392
+ if (word || any) words.push(word);
393
+ return words;
394
+ }
395
+
396
+ const samePath = (a, b, platform) => {
397
+ if (!a || !b) return false;
398
+ const norm = (value) => (platform === 'win32' ? win32.resolve(value) : posix.resolve(value)).replace(/[\\/]+$/, '');
399
+ return platform === 'linux' ? norm(a) === norm(b) : norm(a).toLowerCase() === norm(b).toLowerCase();
400
+ };
401
+
402
+ /**
403
+ * The desktop app's program when its login entry, as the system has it now (there, not switched off, its program
404
+ * still there), opens it on `dataHome`; otherwise null. The app's own settings file is not asked: an entry the user
405
+ * removed or switched off while the app was closed never blocks this install.
406
+ */
407
+ export function desktopLoginOwner(dataHome, {
408
+ platform = process.platform, home = homedir(), env = process.env, fs = DEFAULT_FS, run = defaultRun,
409
+ uid = typeof process.getuid === 'function' ? process.getuid() : null,
410
+ } = {}) {
411
+ const usual = platform === 'win32' ? (env.APPDATA ? win32.resolve(env.APPDATA, 'synabun') : null) : posix.join(home, '.synabun');
412
+ const owns = (program, folder) => (program && fs.existsSync(program) && samePath(folder || usual, dataHome, platform) ? program : null);
413
+ try {
414
+ if (platform === 'darwin') {
415
+ const text = fs.readFileSync(posix.join(home, 'Library', 'LaunchAgents', `${DESKTOP_LOGIN.macLabel}.plist`), 'utf8');
416
+ if (uid != null) {
417
+ try {
418
+ const out = run('/bin/launchctl', ['print-disabled', `gui/${uid}`]);
419
+ if (new RegExp(`"${DESKTOP_LOGIN.macLabel.replace(/\./g, '\\.')}"\\s*=>\\s*(?:true|disabled)`).test(String(out))) return null;
420
+ } catch {}
421
+ }
422
+ // `open -a <app> --env …`, or (a Mac whose `open` has no --env) the app's own program with its environment.
423
+ const words = plistArguments(text);
424
+ const unxml = (v) => v.replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&');
425
+ const direct = /^(.+\.app)\/Contents\/MacOS\/[^/]+$/.exec(words[0] || '');
426
+ const bundle = words.indexOf('-a') >= 0 ? words[words.indexOf('-a') + 1] : direct ? direct[1] : null;
427
+ const folder = words.find(w => w.startsWith('SYNABUN_DATA_HOME='))?.slice('SYNABUN_DATA_HOME='.length)
428
+ ?? (/<key>SYNABUN_DATA_HOME<\/key>\s*<string>([\s\S]*?)<\/string>/.exec(text)?.[1] ? unxml(/<key>SYNABUN_DATA_HOME<\/key>\s*<string>([\s\S]*?)<\/string>/.exec(text)[1]) : undefined);
429
+ return owns(bundle, folder);
430
+ }
431
+ if (platform === 'win32') {
432
+ const value = readRegValue(RUN_KEY, DESKTOP_LOGIN.winName, { run, fs, env });
433
+ if (value == null) return null;
434
+ let approved = null;
435
+ try { approved = startupApproved(parseRegQuery(run(systemTool(env, 'reg.exe'), ['query', APPROVED_KEY, '/v', DESKTOP_LOGIN.winName]), DESKTOP_LOGIN.winName)); } catch {}
436
+ if (approved === false) return null;
437
+ const words = windowsWords(value);
438
+ const data = words.find(w => w.startsWith(DESKTOP_LOGIN.dataFlag));
439
+ let folder = null;
440
+ if (data) { try { folder = Buffer.from(data.slice(DESKTOP_LOGIN.dataFlag.length), 'base64url').toString('utf8') || null; } catch {} }
441
+ return words.includes(DESKTOP_LOGIN.flag) ? owns(words[0], folder) : null;
442
+ }
443
+ const config = String(env.XDG_CONFIG_HOME || '');
444
+ const file = posix.join(config.startsWith('/') ? config : posix.join(home, '.config'), 'autostart', DESKTOP_LOGIN.linuxFile);
445
+ const keys = desktopEntryKeys(fs.readFileSync(file, 'utf8'));
446
+ if (/^true$/i.test(keys.Hidden || '') || /^false$/i.test(keys['X-GNOME-Autostart-enabled'] || 'true')) return null;
447
+ const words = desktopExecWords(keys.Exec);
448
+ const vars = words[0] === 'env' ? words.slice(1).filter(w => /^[A-Za-z_][A-Za-z0-9_]*=/.test(w)) : [];
449
+ const program = words[0] === 'env' ? words.slice(1).find(w => !/^[A-Za-z_][A-Za-z0-9_]*=/.test(w)) : words[0];
450
+ const folder = vars.find(w => w.startsWith('SYNABUN_DATA_HOME='))?.slice('SYNABUN_DATA_HOME='.length);
451
+ return owns(program, folder);
452
+ } catch {
453
+ return null;
454
+ }
455
+ }
456
+
457
+ /**
458
+ * The start at login of this install.
459
+ *
460
+ * status() { supported, reason, enabled, state, owner }: reason 'desktop' (the desktop
461
+ * app has its own: Settings reads it from the app), 'not-here' (a test run or a
462
+ * throwaway data folder) or 'unsupported'; owner is the desktop app's program
463
+ * when it opens at login on this data folder
464
+ * set(enabled) turn it on or off; resolves to status(). Throws { code }: 'desktop-app', 'not-here',
465
+ * 'write-failed', 'no-wscript', 'refused'
466
+ * heal() on a server start: this install's own entry, when stale, is put back in place; an entry that
467
+ * starts another install, or one the user turned off, is left as it is
468
+ */
469
+ export function createLoginStart({
470
+ platform = process.platform, nodePath = process.execPath, packageRoot, home = homedir(), env = process.env, dataHome,
471
+ entry = null, desktopShell = false, allowed = () => true, fs = DEFAULT_FS, run = defaultRun, uid,
472
+ log = () => {},
473
+ } = {}) {
474
+ const ops = { env, fs, run, ...(uid !== undefined ? { uid } : {}) };
475
+ const plan = () => buildLoginPlan({ platform, nodePath, packageRoot, home, env, dataHome, entry });
476
+ const support = () => {
477
+ if (desktopShell) return { supported: false, reason: 'desktop' };
478
+ if (!['darwin', 'win32', 'linux'].includes(platform)) return { supported: false, reason: 'unsupported' };
479
+ if (!allowed()) return { supported: false, reason: 'not-here' };
480
+ return { supported: true, reason: null };
481
+ };
482
+
483
+ function status() {
484
+ const { supported, reason } = support();
485
+ const owner = desktopLoginOwner(dataHome, { platform, home, env, ...ops });
486
+ if (!supported) return { supported, reason, enabled: false, state: 'off', owner };
487
+ let state = 'off';
488
+ try { state = inspectLoginEntry(plan(), ops); } catch {}
489
+ return { supported, reason, enabled: state === 'on' || state === 'stale', state, owner };
490
+ }
491
+
492
+ async function set(enabled) {
493
+ const { supported, reason } = support();
494
+ if (!supported) throw failure(reason, `start at login is not available here (${reason})`);
495
+ const target = plan();
496
+ if (enabled) {
497
+ const owner = desktopLoginOwner(dataHome, { platform, home, env, ...ops });
498
+ if (owner) throw failure('desktop-app', `the SynaBun app opens at login on this data folder (${owner})`);
499
+ applyLoginEntry(target, { ...ops, enable: true });
500
+ } else {
501
+ removeLoginEntry(target, ops);
502
+ }
503
+ const after = status();
504
+ log(`start at login ${enabled ? 'on' : 'off'}: ${after.state}`);
505
+ if (enabled ? after.state !== 'on' : after.enabled) throw failure('refused', after.state);
506
+ return after;
507
+ }
508
+
509
+ function heal() {
510
+ const { supported } = support();
511
+ if (!supported) return { changed: false, state: 'off' };
512
+ const target = plan();
513
+ const state = inspectLoginEntry(target, ops);
514
+ if (state !== 'stale') return { changed: false, state };
515
+ // Only this install's own entry (another Node, other pins): one that starts another install on this data folder
516
+ // (an npm install, a Git checkout run by hand) is that install's, and stays as it is.
517
+ if (!String(readLoginEntry(target, ops) || '').includes(target.mark)) return { changed: false, state };
518
+ applyLoginEntry(target, ops);
519
+ log('start at login: the entry now starts this install');
520
+ return { changed: true, state: inspectLoginEntry(target, ops) };
521
+ }
522
+
523
+ return { status, set, heal, plan };
524
+ }
@@ -10,6 +10,7 @@ import { codexReasoningEffort } from './effort-levels.js';
10
10
  import { codexStreamMedia, collectCodexMedia, openCodeMediaPart, ownCodexImages } from './assistant-media.js';
11
11
  import { browserToolDenial } from './browser-tool-policy.js';
12
12
  import { CODEX_BROWSER_POLICY_UNTRUSTED_NOTE, codexBrowserPolicyHook } from './assistant-route-gate-codex.js';
13
+ import { codexWindowsSandbox, codexWindowsSandboxConfig } from './agent-sandbox-elevation.js';
13
14
 
14
15
  function stringEnv(source) {
15
16
  const out = {};
@@ -251,6 +252,9 @@ export async function createCodexNativeLoopAdapter(options = {}) {
251
252
  // Inherited variables to remove before extraEnv applies (the Codex account's launch:
252
253
  // lib/codex-accounts.js launchFor() — inherited OpenAI/Codex credentials never reach the run).
253
254
  unsetEnv = [],
255
+ // The Admin sandbox setting when the run started (lib/agent-sandbox-elevation.js): the Windows
256
+ // sandbox every `codex exec` of the thread may use. The run keeps it while it lives.
257
+ adminSandbox = false,
254
258
  } = options;
255
259
  const permissionPolicy = normalizePermissionPolicy(rawPolicy);
256
260
  const capability = normalizeCapability(rawCapability);
@@ -287,7 +291,7 @@ export async function createCodexNativeLoopAdapter(options = {}) {
287
291
  const inherited = { ...process.env };
288
292
  for (const key of Array.isArray(unsetEnv) ? unsetEnv : []) delete inherited[key];
289
293
  const env = stringEnv({ ...inherited, ...pins, CODEX_HOME: codexHome, ...(browserPolicy ? { SYNABUN_BROWSER_POLICY_CWD: cwd || process.cwd() } : {}), ...stringEnv(extraEnv) });
290
- const config = {};
294
+ const config = { ...codexWindowsSandboxConfig(adminSandbox) };
291
295
  if (Object.keys(pins).length) config.mcp_servers = { SynaBun: { env: pins } };
292
296
  if (extended) config.model_context_window = Math.floor(Number(modelContextWindow));
293
297
  if (browserPolicy) Object.assign(config, browserPolicy.config);
@@ -334,6 +338,7 @@ export async function createCodexNativeLoopAdapter(options = {}) {
334
338
  isAlive: () => alive,
335
339
  describe: () => ({
336
340
  provider: 'codex', permissionPolicy, capability, sandboxMode: codexSandboxModeFor({ permissionPolicy, capability }),
341
+ windowsSandbox: codexWindowsSandbox(adminSandbox),
337
342
  ...(task ? { browserPolicy: browserPolicy ? 'hook' : 'instructions' } : {}),
338
343
  }),
339
344
  async runTurn(prompt, meta = {}) {
@@ -751,10 +756,12 @@ export async function createOpenCodeNativeLoopAdapter(options = {}) {
751
756
  const eventSource = client.onEvent ? client : client.event;
752
757
  let sessionId = null;
753
758
  // Assistant text assembled from the SSE stream (message.updated gives roles,
754
- // message.part.updated gives text parts keyed by message id).
759
+ // message.part.updated gives text parts keyed by message id, message.part.delta
760
+ // the text a part grows by between them).
755
761
  const messageRoles = new Map();
756
762
  const messageOrder = [];
757
763
  const textParts = new Map(); // messageID → Map(partID → text)
764
+ const textPartMessages = new Map(); // partID of a text part → its messageID (where a delta goes)
758
765
  const rememberMessage = (info) => {
759
766
  if (!info?.id) return;
760
767
  if (!messageRoles.has(info.id)) messageOrder.push(info.id);
@@ -775,8 +782,16 @@ export async function createOpenCodeNativeLoopAdapter(options = {}) {
775
782
  if (!messageRoles.has(part.messageID)) rememberMessage({ id: part.messageID, role: null });
776
783
  let parts = textParts.get(part.messageID);
777
784
  if (!parts) { parts = new Map(); textParts.set(part.messageID, parts); }
785
+ if (part.id) textPartMessages.set(part.id, part.messageID);
778
786
  parts.set(part.id || `${parts.size}`, part.text);
779
787
  };
788
+ // A delta of an announced text part extends it (OpenCode 2 streams text only this way until the part ends).
789
+ const rememberDelta = (event) => {
790
+ if (!event?.partID || (event.field && event.field !== 'text') || typeof event.delta !== 'string' || !event.delta) return;
791
+ const messageID = textPartMessages.get(event.partID);
792
+ if (!messageID || (event.messageID && event.messageID !== messageID)) return;
793
+ rememberPart({ id: event.partID, messageID, type: 'text', text: `${textParts.get(messageID)?.get(event.partID) || ''}${event.delta}` });
794
+ };
780
795
  /** { media } with the generated files not returned yet (none: {}). */
781
796
  const turnMedia = (extraParts = []) => {
782
797
  for (const part of extraParts) rememberPart(part);
@@ -853,6 +868,7 @@ export async function createOpenCodeNativeLoopAdapter(options = {}) {
853
868
  }
854
869
  if (/^message[.:]updated$/i.test(eventType)) rememberMessage(event.info || event.message?.info || null);
855
870
  if (/^message[.:]part[.:]updated$/i.test(eventType)) rememberPart(event.part || null);
871
+ if (/^message[.:]part[.:]delta$/i.test(eventType)) rememberDelta(event);
856
872
  if (/question\.asked/i.test(eventType)) {
857
873
  const requestID = event.id || event.requestID;
858
874
  if (requestID && askMode && client.question?.reply) {
@@ -911,9 +927,13 @@ export async function createOpenCodeNativeLoopAdapter(options = {}) {
911
927
  // What the serve stored, for the usage meter's reconcile at a turn's end (assistant-usage.js).
912
928
  // A call that fails, times out or is missing on an older serve throws: the caller then knows
913
929
  // the turn was not reconciled.
930
+ // The clients SynaBun builds (lib/opencode-v2-client.js, either major) keep `session` as it was and carry
931
+ // `children` under `extra.session`.
914
932
  const storedRows = async (method, id) => {
915
- if (typeof client.session?.[method] !== 'function') throw new Error(`OpenCode session.${method} is not available`);
916
- const response = await settleWithin(client.session[method]({ sessionID: id, directory: cwd || undefined }), 5000);
933
+ const group = typeof client.session?.[method] === 'function' ? client.session
934
+ : typeof client.extra?.session?.[method] === 'function' ? client.extra.session : null;
935
+ if (!group) throw new Error(`OpenCode session.${method} is not available`);
936
+ const response = await settleWithin(group[method]({ sessionID: id, directory: cwd || undefined }), 5000);
917
937
  if (!response || response.error) throw new Error(providerErrorMessage(response?.error, `OpenCode session.${method} did not answer`));
918
938
  const rows = Array.isArray(response.data) ? response.data : Array.isArray(response) ? response : null;
919
939
  if (!rows) throw new Error(`OpenCode session.${method} returned no list`);
@@ -49,6 +49,9 @@ function cleanDescriptor(record) {
49
49
  // existing consumers (router, sidepanels, schedules) are unaffected.
50
50
  runMode: record.runMode || 'loop',
51
51
  turnState: record.turnState || null,
52
+ // What the last turn's result said (task mode: done, blocked or needs_input; the dispatcher's
53
+ // lastResult.status): an idle warm worker whose turn ended asking waits on the user.
54
+ outcome: record.outcome || null,
52
55
  assistantSessionId: record.assistantSessionId || null,
53
56
  };
54
57
  }
@@ -161,6 +164,21 @@ export class NativeLoopRuntime {
161
164
  return this._emit('sidepanel:run-updated', record, { reason: 'turn-state' });
162
165
  }
163
166
 
167
+ /**
168
+ * Task-mode helper: records what the wrapper's last turn reported ('done' |
169
+ * 'blocked' | 'needs_input', the dispatcher's lastResult.status) and
170
+ * broadcasts it, so a panel can tell a warm worker that rests from one whose
171
+ * turn ended asking the user. No-op for unknown runs.
172
+ */
173
+ setOutcome(runId, outcome) {
174
+ const record = this.records.get(runId);
175
+ if (!record) return null;
176
+ const next = outcome ? String(outcome) : null;
177
+ if ((record.outcome || null) === next) return cleanDescriptor(record);
178
+ record.outcome = next;
179
+ return this._emit('sidepanel:run-updated', record, { reason: 'outcome' });
180
+ }
181
+
164
182
  _loadLedger() {
165
183
  const rows = readJson(this.ledgerPath, []);
166
184
  if (!Array.isArray(rows)) return;
@@ -461,6 +479,7 @@ export class NativeLoopRuntime {
461
479
  runId,
462
480
  emit: (event) => this._emitProviderEvent(record, event),
463
481
  setTurnState: (turnState) => this.setTurnState(runId, turnState),
482
+ setOutcome: (outcome) => this.setOutcome(runId, outcome),
464
483
  readState: () => this._readState(runId),
465
484
  })
466
485
  : adapter;