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,361 @@
1
+ // ─────────────────────────────────────────────────────────────────────────────
2
+ // Which process a pid is.
3
+ //
4
+ // The OS gives a pid to a new process once the old one is gone: a server
5
+ // SynaBun started and recorded by its pid may have exited, and that number now
6
+ // belong to another program. A pid together with the time its process started
7
+ // and its command line, as the OS reports them, names one process and no other.
8
+ // SynaBun records all three when it starts a server (readProcessIdentity) and
9
+ // signals that pid only while the OS still reports the same three
10
+ // (sameProcess), checked again right before each signal. A process whose
11
+ // identity cannot be read is never taken for SynaBun's.
12
+ //
13
+ // A start time to the second can still be shared by two processes, and a pid,
14
+ // a start time and a command line mean something only on the machine, for the
15
+ // user and in the boot they were read in. So a serve SynaBun spawns also
16
+ // carries a random token in its environment (SERVE_TOKEN_ENV, newServeToken),
17
+ // which the OS gives back for the user's own processes (readEnvironmentHas:
18
+ // `ps -E` on macOS, /proc/<pid>/environ on Linux; Windows cannot read another
19
+ // process's environment, and its start times are to the fraction of a second),
20
+ // and every record says where it was written (readHostScope: the machine's id,
21
+ // the user, the boot). The parent chain (readProcessParentAsync) and the
22
+ // listeners of a port (listPortListenersAsync) tell whether what answers on a
23
+ // port is a process SynaBun spawned, or one that process started.
24
+ // ─────────────────────────────────────────────────────────────────────────────
25
+
26
+ import { execFile, execFileSync } from 'node:child_process';
27
+ import { randomBytes } from 'node:crypto';
28
+ import { readFileSync } from 'node:fs';
29
+
30
+ /** The environment variable that carries the token of a serve SynaBun spawned. */
31
+ export const SERVE_TOKEN_ENV = 'SYNABUN_SERVE_TOKEN';
32
+
33
+ /** A fresh token for one spawn: 128 random bits, hex. */
34
+ export function newServeToken() {
35
+ return randomBytes(16).toString('hex');
36
+ }
37
+
38
+ // `ps -o uid= -o lstart=` in the C locale and UTC: " 501 Tue Oct 21 04:12:50 2026" (the day may be padded with a
39
+ // space). The uid is optional here: a test may hand in what an older query printed.
40
+ const PS_LINE = /^(?:(\d+)\s+)?(\S+\s+\S+\s+\d{1,2}\s+\d{1,2}:\d{2}:\d{2}\s+\d{4})\s+(\S.*)$/;
41
+ const PS_PARENT = /^(\d+)\s+(\S+\s+\S+\s+\d{1,2}\s+\d{1,2}:\d{2}:\d{2}\s+\d{4})$/;
42
+ // One locale and one time zone, so a record reads the same after either changes.
43
+ const C_ENV = () => ({ ...process.env, LC_ALL: 'C', LANG: 'C', TZ: 'UTC' });
44
+
45
+ const pidOf = (pid) => {
46
+ const n = Number(pid);
47
+ return Number.isInteger(n) && n > 0 ? n : null;
48
+ };
49
+
50
+ const firstLine = (out) => String(out ?? '').split('\n').map((l) => l.trim()).find(Boolean) || '';
51
+
52
+ function powershell(script, timeout = 8000) {
53
+ return { file: 'powershell.exe', args: ['-NoProfile', '-NonInteractive', '-Command', script], options: { encoding: 'utf8', timeout, windowsHide: true } };
54
+ }
55
+
56
+ // What asks the OS about one pid: `ps -ww -o uid= -o lstart= -o command=` (the user, the start time to the second,
57
+ // the whole command line) on macOS and Linux; the process's CreationDate and CommandLine (CIM, through PowerShell)
58
+ // on Windows.
59
+ function identityQuery(n, platform) {
60
+ if (platform === 'win32') {
61
+ return powershell(`$p = Get-CimInstance Win32_Process -Filter "ProcessId=${n}"; if ($p) { $p.CreationDate.ToUniversalTime().ToString('o'); $p.CommandLine }`);
62
+ }
63
+ return {
64
+ file: 'ps',
65
+ args: ['-ww', '-o', 'uid=', '-o', 'lstart=', '-o', 'command=', '-p', String(n)],
66
+ options: { encoding: 'utf8', timeout: 5000, env: C_ENV() },
67
+ };
68
+ }
69
+
70
+ function parseIdentity(n, platform, out) {
71
+ const text = String(out ?? '');
72
+ if (platform === 'win32') {
73
+ const [first = '', ...rest] = text.split(/\r?\n/);
74
+ const startedAt = first.trim();
75
+ const command = rest.join('\n').trim();
76
+ return startedAt && command ? { pid: n, startedAt, command } : null;
77
+ }
78
+ const match = PS_LINE.exec(firstLine(text));
79
+ if (!match) return null;
80
+ const identity = { pid: n, startedAt: match[2].replace(/\s+/g, ' '), command: match[3].trim() };
81
+ if (match[1] != null) identity.uid = match[1];
82
+ return identity;
83
+ }
84
+
85
+ /**
86
+ * `{ pid, startedAt, command }` of a running process (`uid` too on macOS and Linux), or null: gone, or the OS could
87
+ * not be asked. macOS and Linux: `ps -ww -o uid= -o lstart= -o command=` (the start time to the second, the whole
88
+ * command line); Windows: the process's CreationDate (to the fraction of a second) and CommandLine (CIM, through
89
+ * PowerShell).
90
+ * @param {number} pid
91
+ * @param {{ platform?: string, run?: typeof execFileSync }} [o] `run`: tests hand in what the OS would answer
92
+ */
93
+ export function readProcessIdentity(pid, { platform = process.platform, run = execFileSync } = {}) {
94
+ const n = pidOf(pid);
95
+ if (!n) return null;
96
+ const query = identityQuery(n, platform);
97
+ try {
98
+ return parseIdentity(n, platform, run(query.file, query.args, { ...query.options, stdio: ['ignore', 'pipe', 'ignore'] }));
99
+ } catch {
100
+ // ps exits 1 for a pid nothing runs under; a missing ps or PowerShell is "could not be asked".
101
+ return null;
102
+ }
103
+ }
104
+
105
+ /**
106
+ * readProcessIdentity without holding the event loop while the OS answers (PowerShell takes about a second):
107
+ * for a look that may read several pids, such as the sweep of SynaBun's leftover serves.
108
+ * @param {number} pid
109
+ * @param {{ platform?: string, run?: (file: string, args: string[], options: object) => Promise<string> }} [o]
110
+ */
111
+ export async function readProcessIdentityAsync(pid, { platform = process.platform, run = runFile } = {}) {
112
+ const n = pidOf(pid);
113
+ if (!n) return null;
114
+ const query = identityQuery(n, platform);
115
+ try {
116
+ return parseIdentity(n, platform, await run(query.file, query.args, query.options));
117
+ } catch {
118
+ return null;
119
+ }
120
+ }
121
+
122
+ function runFile(file, args, options) {
123
+ return new Promise((resolve, reject) => {
124
+ execFile(file, args, options, (error, stdout, stderr) => (error ? reject(Object.assign(error, { stdout, stderr })) : resolve(stdout)));
125
+ });
126
+ }
127
+
128
+ /** Is `current` (readProcessIdentity now) the process `recorded` was: the same pid, start time and command line? */
129
+ export function sameProcess(recorded, current) {
130
+ if (!recorded || !current || !recorded.startedAt || !recorded.command) return false;
131
+ return Number(recorded.pid) === Number(current.pid)
132
+ && String(recorded.startedAt) === String(current.startedAt)
133
+ && String(recorded.command) === String(current.command);
134
+ }
135
+
136
+ /**
137
+ * Does any process run under `pid`? true, false (none: the OS said so), or null (it could not be told). Signal 0
138
+ * sends nothing: the OS only checks the pid. A process of another user answers EPERM, which is a process too.
139
+ * @param {number} pid
140
+ * @param {{ kill?: (pid: number, signal: number | string) => void }} [o]
141
+ */
142
+ export function pidExists(pid, { kill = (p, s) => process.kill(p, s) } = {}) {
143
+ const n = pidOf(pid);
144
+ if (!n) return false;
145
+ try {
146
+ kill(n, 0);
147
+ return true;
148
+ } catch (error) {
149
+ if (error?.code === 'ESRCH') return false;
150
+ if (error?.code === 'EPERM') return true;
151
+ return null;
152
+ }
153
+ }
154
+
155
+ // ── The environment a process started with ──────────────────────────────────
156
+
157
+ const ENV_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;
158
+ const ENV_VALUE = /^[A-Za-z0-9_.:-]+$/;
159
+
160
+ // macOS prints the environment after the command line (`ps -E`) only for a process it lets the user read: the
161
+ // user's own, and not a binary of the system's. The line must start with the command line read for the identity
162
+ // (else the pid is another process's by now), and hold more than that (else the environment was not shown).
163
+ function parseEnvironmentHas(out, command, name, value) {
164
+ const text = firstLine(out);
165
+ const plain = String(command ?? '').trim();
166
+ if (!plain || !text.startsWith(plain)) return null;
167
+ const environment = text.slice(plain.length);
168
+ if (!environment.trim()) return null;
169
+ return new RegExp(`(?:^|\\s)${name}=${value}(?=\\s|$)`).test(environment);
170
+ }
171
+
172
+ function linuxEnvironmentHas(n, name, value, readFile) {
173
+ let text;
174
+ try { text = readFile(`/proc/${n}/environ`, 'utf8'); } catch { return null; } // gone, or another user's
175
+ const vars = String(text).split('\0').filter(Boolean);
176
+ if (!vars.length) return null; // a process that has ended shows none
177
+ return vars.includes(`${name}=${value}`);
178
+ }
179
+
180
+ function environmentQuery(n) {
181
+ return { file: 'ps', args: ['-E', '-ww', '-o', 'command=', '-p', String(n)], options: { encoding: 'utf8', timeout: 5000, env: C_ENV() } };
182
+ }
183
+
184
+ /**
185
+ * Does the environment `pid` started with hold `name=value`? true, false (it was read, and does not), or null (it
186
+ * could not be read: gone, another user's, or the OS does not say). macOS: `ps -E`, given the command line just
187
+ * read for the process's identity; Linux: /proc/<pid>/environ; Windows and anything else: null.
188
+ * @param {number} pid
189
+ * @param {string} name
190
+ * @param {string} value
191
+ * @param {{ command?: string, platform?: string, run?: typeof execFileSync, readFile?: typeof readFileSync }} [o]
192
+ */
193
+ export function readEnvironmentHas(pid, name, value, { command = '', platform = process.platform, run = execFileSync, readFile = readFileSync } = {}) {
194
+ const n = pidOf(pid);
195
+ if (!n || !ENV_NAME.test(String(name)) || !ENV_VALUE.test(String(value))) return null;
196
+ if (platform === 'linux') return linuxEnvironmentHas(n, name, value, readFile);
197
+ if (platform !== 'darwin') return null;
198
+ const query = environmentQuery(n);
199
+ try {
200
+ return parseEnvironmentHas(run(query.file, query.args, { ...query.options, stdio: ['ignore', 'pipe', 'ignore'] }), command, name, value);
201
+ } catch {
202
+ return null;
203
+ }
204
+ }
205
+
206
+ /** readEnvironmentHas without holding the event loop while the OS answers. */
207
+ export async function readEnvironmentHasAsync(pid, name, value, { command = '', platform = process.platform, run = runFile, readFile = readFileSync } = {}) {
208
+ const n = pidOf(pid);
209
+ if (!n || !ENV_NAME.test(String(name)) || !ENV_VALUE.test(String(value))) return null;
210
+ if (platform === 'linux') return linuxEnvironmentHas(n, name, value, readFile);
211
+ if (platform !== 'darwin') return null;
212
+ const query = environmentQuery(n);
213
+ try {
214
+ return parseEnvironmentHas(await run(query.file, query.args, query.options), command, name, value);
215
+ } catch {
216
+ return null;
217
+ }
218
+ }
219
+
220
+ // ── Where: the machine, the user, the boot ──────────────────────────────────
221
+
222
+ const WINDOWS_SCOPE = "(Get-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Cryptography').MachineGuid; "
223
+ + "(Get-CimInstance Win32_OperatingSystem).LastBootUpTime.ToUniversalTime().ToString('o'); "
224
+ + '[System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value';
225
+
226
+ const clean = (v) => {
227
+ const text = String(v ?? '').trim();
228
+ return text || null;
229
+ };
230
+
231
+ function uidOf(getuid) {
232
+ try { const uid = getuid?.(); return Number.isInteger(uid) && uid >= 0 ? String(uid) : null; } catch { return null; }
233
+ }
234
+
235
+ function readFirst(readFile, paths) {
236
+ for (const path of paths) {
237
+ try { const text = clean(readFile(path, 'utf8')); if (text) return text; } catch { /* the next one */ }
238
+ }
239
+ return null;
240
+ }
241
+
242
+ const machineFromIoreg = (out) => clean(/"IOPlatformUUID"\s*=\s*"([^"]+)"/.exec(String(out ?? ''))?.[1]);
243
+ const bootFromBoottime = (out) => {
244
+ const sec = /sec\s*=\s*(\d+)/.exec(String(out ?? ''))?.[1];
245
+ return sec ? `boottime:${sec}` : null;
246
+ };
247
+ function scopeFromPowershell(out) {
248
+ const [machine, boot, uid] = String(out ?? '').split(/\r?\n/).map(clean);
249
+ return { machine: machine || null, uid: uid || null, boot: boot || null };
250
+ }
251
+
252
+ /**
253
+ * Where a record is written, and for whom: `{ machine, uid, boot }`, each a string, or null where the OS could not
254
+ * tell. macOS: the platform UUID (ioreg), the user's uid, the boot session's UUID (kern.bootsessionuuid; the boot
255
+ * time when that is missing); Linux: /etc/machine-id, the uid, /proc/sys/kernel/random/boot_id; Windows: the
256
+ * MachineGuid, the user's SID and the last boot time (one PowerShell).
257
+ * @param {{ platform?: string, run?: typeof execFileSync, readFile?: typeof readFileSync, getuid?: () => number }} [o]
258
+ */
259
+ export function readHostScope({ platform = process.platform, run = execFileSync, readFile = readFileSync, getuid = process.getuid } = {}) {
260
+ const ask = (file, args, timeout = 5000) => {
261
+ try { return run(file, args, { encoding: 'utf8', timeout, env: C_ENV(), windowsHide: true, stdio: ['ignore', 'pipe', 'ignore'] }); } catch { return null; }
262
+ };
263
+ if (platform === 'darwin') {
264
+ return {
265
+ machine: machineFromIoreg(ask('ioreg', ['-rd1', '-c', 'IOPlatformExpertDevice'])),
266
+ uid: uidOf(getuid),
267
+ boot: clean(ask('sysctl', ['-n', 'kern.bootsessionuuid'])) || bootFromBoottime(ask('sysctl', ['-n', 'kern.boottime'])),
268
+ };
269
+ }
270
+ if (platform === 'linux') {
271
+ return {
272
+ machine: readFirst(readFile, ['/etc/machine-id', '/var/lib/dbus/machine-id']),
273
+ uid: uidOf(getuid),
274
+ boot: readFirst(readFile, ['/proc/sys/kernel/random/boot_id']),
275
+ };
276
+ }
277
+ if (platform === 'win32') {
278
+ const query = powershell(WINDOWS_SCOPE, 15000);
279
+ return scopeFromPowershell(ask(query.file, query.args, 15000));
280
+ }
281
+ return { machine: null, uid: uidOf(getuid), boot: null };
282
+ }
283
+
284
+ /** readHostScope without holding the event loop while the OS answers (PowerShell takes about a second). */
285
+ export async function readHostScopeAsync({ platform = process.platform, run = runFile, readFile = readFileSync, getuid = process.getuid } = {}) {
286
+ const ask = async (file, args, timeout = 5000) => {
287
+ try { return await run(file, args, { encoding: 'utf8', timeout, env: C_ENV(), windowsHide: true }); } catch { return null; }
288
+ };
289
+ if (platform === 'darwin') {
290
+ const [ioreg, session] = await Promise.all([ask('ioreg', ['-rd1', '-c', 'IOPlatformExpertDevice']), ask('sysctl', ['-n', 'kern.bootsessionuuid'])]);
291
+ return {
292
+ machine: machineFromIoreg(ioreg),
293
+ uid: uidOf(getuid),
294
+ boot: clean(session) || bootFromBoottime(await ask('sysctl', ['-n', 'kern.boottime'])),
295
+ };
296
+ }
297
+ if (platform === 'win32') {
298
+ const query = powershell(WINDOWS_SCOPE, 15000);
299
+ return scopeFromPowershell(await ask(query.file, query.args, 15000));
300
+ }
301
+ return readHostScope({ platform, readFile, getuid });
302
+ }
303
+
304
+ // ── The parent chain, and who listens on a port ─────────────────────────────
305
+
306
+ /**
307
+ * The parent of a running process and when the process started: `{ pid, ppid, startedAt }`, or null (gone, or the
308
+ * OS could not be asked). macOS and Linux: `ps -o ppid= -o lstart=`; Windows: CIM's ParentProcessId and CreationDate
309
+ * (a parent pid Windows keeps after that parent ended: the caller compares start times).
310
+ * @param {number} pid
311
+ * @param {{ platform?: string, run?: (file: string, args: string[], options: object) => Promise<string> }} [o]
312
+ */
313
+ export async function readProcessParentAsync(pid, { platform = process.platform, run = runFile } = {}) {
314
+ const n = pidOf(pid);
315
+ if (!n) return null;
316
+ try {
317
+ if (platform === 'win32') {
318
+ const query = powershell(`$p = Get-CimInstance Win32_Process -Filter "ProcessId=${n}"; if ($p) { $p.ParentProcessId; $p.CreationDate.ToUniversalTime().ToString('o') }`);
319
+ const [ppid = '', startedAt = ''] = String(await run(query.file, query.args, query.options)).split(/\r?\n/).map((l) => l.trim());
320
+ return /^\d+$/.test(ppid) && startedAt ? { pid: n, ppid: Number(ppid), startedAt } : null;
321
+ }
322
+ const out = await run('ps', ['-o', 'ppid=', '-o', 'lstart=', '-p', String(n)], { encoding: 'utf8', timeout: 5000, env: C_ENV() });
323
+ const match = PS_PARENT.exec(firstLine(out));
324
+ return match ? { pid: n, ppid: Number(match[1]), startedAt: match[2].replace(/\s+/g, ' ') } : null;
325
+ } catch {
326
+ return null;
327
+ }
328
+ }
329
+
330
+ /**
331
+ * The pids that listen on a local TCP port: a list (empty: nothing listens that the user may see), or null when the
332
+ * OS could not be asked. macOS and Linux: lsof (exit 1 with nothing printed is "none"; no lsof is null); Windows:
333
+ * Get-NetTCPConnection, where an empty answer is null too (it lists every user's listeners: something answered on
334
+ * the port a moment ago).
335
+ * @param {number} port
336
+ * @param {{ platform?: string, run?: (file: string, args: string[], options: object) => Promise<string> }} [o]
337
+ */
338
+ export async function listPortListenersAsync(port, { platform = process.platform, run = runFile, selfPid = process.pid } = {}) {
339
+ const p = Number(port);
340
+ if (!Number.isInteger(p) || p <= 0 || p > 65535) return null;
341
+ const pidsIn = (out) => [...new Set(String(out ?? '').split(/\r?\n/).map((l) => l.trim()).filter((l) => /^\d+$/.test(l)).map(Number))]
342
+ .filter((n) => n > 0 && n !== selfPid);
343
+ if (platform === 'win32') {
344
+ const query = powershell(`Get-NetTCPConnection -LocalPort ${p} -State Listen -ErrorAction SilentlyContinue | ForEach-Object { $_.OwningProcess }`);
345
+ try {
346
+ const pids = pidsIn(await run(query.file, query.args, query.options));
347
+ return pids.length ? pids : null;
348
+ } catch {
349
+ return null;
350
+ }
351
+ }
352
+ try {
353
+ return pidsIn(await run('lsof', ['-nP', `-tiTCP:${p}`, '-sTCP:LISTEN'], { encoding: 'utf8', timeout: 5000, env: C_ENV() }));
354
+ } catch (error) {
355
+ // lsof exits 1 when nothing matched, and for some errors too: nothing printed but a warning is "cannot be told".
356
+ if (error?.code !== 1) return null;
357
+ const pids = pidsIn(error.stdout);
358
+ if (pids.length) return pids;
359
+ return String(error.stderr ?? '').trim() ? null : [];
360
+ }
361
+ }
@@ -4,7 +4,8 @@ import { claudeAuthEnv } from './claude-panel-auth.js';
4
4
  import { applyCodexLaunchEnv } from './codex-accounts.js';
5
5
 
6
6
  // Only server-owned account records and resolved executables enter the PTY.
7
- export function providerLoginSpec({ provider, accountId, claudeAccounts, codexAccount, claudeExecutable, codexExecutable, env }) {
7
+ // `codexConfigArgs`: the `-c` words every Codex SynaBun starts gets (the Admin sandbox setting's Windows sandbox).
8
+ export function providerLoginSpec({ provider, accountId, claudeAccounts, codexAccount, claudeExecutable, codexExecutable, env, codexConfigArgs = [] }) {
8
9
  if (!['claude', 'codex'].includes(provider) || typeof accountId !== 'string' || !/^[a-z0-9-]{1,64}$/.test(accountId)) {
9
10
  throw Object.assign(new Error('Unknown provider account'), { status: 404 });
10
11
  }
@@ -24,7 +25,7 @@ export function providerLoginSpec({ provider, accountId, claudeAccounts, codexAc
24
25
  if (!account.home) throw new Error('This Claude account has no isolated home.');
25
26
  baseEnv = claudeAuthEnv(baseEnv, { CLAUDE_CONFIG_DIR: account.home });
26
27
  }
27
- const args = provider === 'claude' ? ['auth', 'login', '--claudeai'] : ['login'];
28
+ const args = provider === 'claude' ? ['auth', 'login', '--claudeai'] : ['login', ...codexConfigArgs];
28
29
  return { launch: /\.[cm]?js$/i.test(file) ? { shell: process.execPath, args: [file, ...args] } : { shell: file, args }, baseEnv };
29
30
  }
30
31
 
@@ -24,6 +24,7 @@ import {
24
24
  } from './db.js';
25
25
  import { parseLine } from './session-chunker.js';
26
26
  import { listCodexSessionsFromAccounts } from './codex-session-catalog.js';
27
+ import { opencodeDbFlavor, sessionTablesFor, v2MessageText } from './opencode-db-schema.js';
27
28
 
28
29
  const MAX_BODY = 256 * 1024;
29
30
  const MAX_MSG_CHARS = 8 * 1024;
@@ -380,20 +381,26 @@ export function rebuildCodexCache({ project, projects, accounts, onProgress } =
380
381
 
381
382
  // --- OpenCode ---
382
383
 
383
- export function rebuildOpencodeCache({ getOpencodeDb, onProgress } = {}) {
384
+ // `protocol`: the OpenCode major SynaBun talks to (lib/opencode-db-schema.js
385
+ // opencodeDbFlavor): OpenCode 2 keeps its sessions in session_v2 and their text
386
+ // in session_message rows, in the same database file as OpenCode 1's tables.
387
+ export function rebuildOpencodeCache({ getOpencodeDb, onProgress, protocol = null } = {}) {
384
388
  const emit = onProgress || (() => {});
385
389
  if (typeof getOpencodeDb !== 'function') return { sessions: 0, updated: 0 };
386
390
 
387
391
  const ocdb = getOpencodeDb();
388
392
  if (!ocdb) return { sessions: 0, updated: 0 };
393
+ const flavor = opencodeDbFlavor(ocdb, protocol);
394
+ if (!flavor) return { sessions: 0, updated: 0 };
395
+ const tables = sessionTablesFor(flavor);
389
396
 
390
397
  let sessions;
391
398
  try {
392
399
  sessions = ocdb.prepare(`
393
400
  SELECT s.id, s.title, s.directory, s.time_created, s.time_updated,
394
401
  p.worktree AS project_worktree,
395
- (SELECT COUNT(*) FROM message m WHERE m.session_id = s.id) AS message_count
396
- FROM session s
402
+ ${tables.messageCount} AS message_count
403
+ FROM ${tables.session} s
397
404
  LEFT JOIN project p ON s.project_id = p.id
398
405
  WHERE s.time_archived IS NULL
399
406
  `).all();
@@ -402,11 +409,25 @@ export function rebuildOpencodeCache({ getOpencodeDb, onProgress } = {}) {
402
409
  let total = sessions.length;
403
410
  let updated = 0;
404
411
 
405
- // OpenCode schema: message.data (JSON w/ role+metadata) + part.data (JSON w/ type+text).
412
+ // OpenCode 1 schema: message.data (JSON w/ role+metadata) + part.data (JSON w/ type+text).
406
413
  // Pull parts per message, decode JSON, grab text where type === 'text'.
414
+ // OpenCode 2: one session_message row per message, its text in `data`
415
+ // (v2MessageText); read as the same { part_id, part_created, pdata, mdata } rows.
407
416
  let partStmt;
408
417
  try {
409
- partStmt = ocdb.prepare(`SELECT p.id AS part_id, p.time_created AS part_created, p.data AS pdata, m.data AS mdata
418
+ partStmt = flavor === 'v2'
419
+ ? (() => {
420
+ const rows = ocdb.prepare(`SELECT id, type, time_created, data FROM session_message
421
+ WHERE session_id = ? AND type IN ('user', 'assistant')
422
+ ORDER BY seq ASC`);
423
+ return {
424
+ all: (sessionId) => rows.all(sessionId).map((row) => {
425
+ const said = v2MessageText(row.type, row.data);
426
+ return said ? { part_id: row.id, part_created: row.time_created, pdata: JSON.stringify({ type: 'text', text: said.text }), mdata: JSON.stringify({ role: said.role }) } : null;
427
+ }).filter(Boolean),
428
+ };
429
+ })()
430
+ : ocdb.prepare(`SELECT p.id AS part_id, p.time_created AS part_created, p.data AS pdata, m.data AS mdata
410
431
  FROM part p
411
432
  LEFT JOIN message m ON m.id = p.message_id
412
433
  WHERE p.session_id = ?
@@ -227,9 +227,10 @@ export async function startIndexing(options = {}) {
227
227
  * Uses vectors already stored in SQLite — no re-embedding needed.
228
228
  * Skips chunks that already exist in memories (same UUID) or have dedup_memory_id.
229
229
  * @param {function} [onProgress] - Progress callback
230
+ * @param {{ ensureCategory?: () => void }} [options] - ensureCategory creates "conversations" before the first write (a fresh install has none)
230
231
  * @returns {Promise<{ mirrored: number, skipped: number, errors: number }>}
231
232
  */
232
- export async function mirrorExistingChunks(onProgress) {
233
+ export async function mirrorExistingChunks(onProgress, { ensureCategory = null } = {}) {
233
234
  const emit = onProgress || (() => {});
234
235
  const d = getDb();
235
236
 
@@ -296,6 +297,7 @@ export async function mirrorExistingChunks(onProgress) {
296
297
  // Batch upsert to memories
297
298
  if (mirrorPoints.length > 0) {
298
299
  try {
300
+ if (typeof ensureCategory === 'function') ensureCategory();
299
301
  for (let i = 0; i < mirrorPoints.length; i += UPSERT_BATCH_SIZE) {
300
302
  const batch = mirrorPoints.slice(i, i + UPSERT_BATCH_SIZE);
301
303
  upsertMemories(batch);
@@ -118,6 +118,8 @@ async function generateCodexTitle(input, deps) {
118
118
  const args = [
119
119
  'exec', '--ephemeral', '--skip-git-repo-check', '--ignore-rules',
120
120
  '--sandbox', 'read-only', '--color', 'never', '--json',
121
+ // The Windows sandbox the Admin sandbox setting allows (lib/agent-sandbox-elevation.js).
122
+ ...(typeof deps.codexConfigArgs === 'function' ? deps.codexConfigArgs() : []),
121
123
  ];
122
124
  if (input.cwd) args.push('-C', input.cwd);
123
125
  if (input.model) args.push('-m', input.model);
@@ -150,6 +152,23 @@ async function generateOpenCodeTitle(input, deps) {
150
152
  const timer = setTimeout(() => controller.abort(new Error('Session title request timed out')), SESSION_TITLE_TIMEOUT_MS);
151
153
  timer.unref?.();
152
154
  let sessionId = null;
155
+ // OpenCode 2 (lib/opencode2-client.js): its one-shot generator when the model
156
+ // allows it (OpenCode's free tier answers it 503), else a temporary session
157
+ // whose permissions deny every tool: OpenCode 2 has no tool switch per prompt.
158
+ const opencode2 = deps.openCodeClient.getProtocol?.() === 2;
159
+ if (opencode2) {
160
+ const raw = deps.openCodeClient.getClient?.();
161
+ try {
162
+ const generated = await raw?.generate?.({
163
+ prompt: `${TITLE_SYSTEM_PROMPT}\n\n${titlePrompt(input)}`,
164
+ model: input.model || undefined,
165
+ directory: input.cwd || undefined,
166
+ signal: controller.signal,
167
+ });
168
+ const text = String(generated?.data?.text || '').trim();
169
+ if (!generated?.error && text) { clearTimeout(timer); return text; }
170
+ } catch { /* the session below */ }
171
+ }
153
172
  try {
154
173
  const toolIds = new Set([
155
174
  'bash', 'edit', 'write', 'patch', 'apply_patch', 'multiedit', 'read',
@@ -168,6 +187,7 @@ async function generateOpenCodeTitle(input, deps) {
168
187
  const created = await deps.openCodeClient.session.create({
169
188
  directory: input.cwd || undefined,
170
189
  title: 'SessionTitleDraft',
190
+ ...(opencode2 ? { permission: [{ permission: '*', pattern: '*', action: 'deny' }] } : {}),
171
191
  });
172
192
  sessionId = created?.data?.id || created?.data?.sessionID || created?.id || created?.sessionID;
173
193
  if (!sessionId) throw new Error('OpenCode did not create a temporary title session');
@@ -47,6 +47,7 @@ import { EXPORT_FORMATS, StyleGuideError, renderFormat } from './store.js';
47
47
  import { estimateTokens, styleGuideSummaryForClass } from './summary.js';
48
48
  import { resolvedTokens } from './tokens.js';
49
49
  import { safeLogoFile } from './security.js';
50
+ import { setUntrustedFileHeaders } from '../untrusted-file-headers.js';
50
51
 
51
52
  const LOGO_TYPES = Object.freeze({ 'image/png': '.png', 'image/svg+xml': '.svg', 'image/jpeg': '.jpg', 'image/webp': '.webp' });
52
53
  const SAVE_SOURCE_RE = /^(ui|import:[a-z-]{1,24}|preset:[a-z0-9-]{1,40})$/;
@@ -367,9 +368,9 @@ export function registerStyleGuideRoutes(app, { store, fetchImpl = null, log = (
367
368
  if (!full.startsWith(store.assetsDir + sep)) return res.status(403).json({ ok: false, error: 'Forbidden' });
368
369
  if (!existsSync(full)) return res.status(404).json({ ok: false, error: 'Not found' });
369
370
  store.assertPath(store.assetsDir, full);
370
- // An uploaded SVG is served as a file to look at, never as a page that can run script on this origin.
371
- res.set('Content-Security-Policy', "default-src 'none'; style-src 'unsafe-inline'; sandbox");
372
- res.set('X-Content-Type-Options', 'nosniff');
371
+ // An uploaded SVG is served as a file to look at, never as a page that can run script on this origin
372
+ // (and opened by its address, a download).
373
+ setUntrustedFileHeaders(res, file);
373
374
  res.sendFile(full);
374
375
  }));
375
376
  }
@@ -0,0 +1,27 @@
1
+ // The headers of a file a user uploaded or an agent made, served back to the page: a pasted or generated image, a
2
+ // category logo, a custom file icon, a Skills Studio icon, a Style Guide logo, an Assistant run's media. An <img> or
3
+ // <video> in the app shows it as before (it ignores all three); opened by its address it runs nothing. An SVG is a
4
+ // document that can carry script, so it also comes as a download there. tests/untrusted-file-headers.test.mjs.
5
+ import { basename } from 'node:path';
6
+
7
+ /** No script, no request, no plugin, no form; a unique origin (sandbox). Inline styles stay, so an SVG still draws. */
8
+ export const UNTRUSTED_FILE_CSP = "default-src 'none'; style-src 'unsafe-inline'; sandbox";
9
+
10
+ /** Is this file an SVG, by its name or by the type it is sent as? */
11
+ export function isSvgFile(name, type = '') {
12
+ return /\.svg$/i.test(String(name || '')) || /^image\/svg\+xml\b/i.test(String(type || ''));
13
+ }
14
+
15
+ /**
16
+ * Set the three headers on `res` (an Express response) for the file `name` (a path or a file name) sent as `type`.
17
+ * Call it before the body goes out; it does not touch Content-Type.
18
+ */
19
+ export function setUntrustedFileHeaders(res, name, type = '') {
20
+ res.setHeader('Content-Security-Policy', UNTRUSTED_FILE_CSP);
21
+ res.setHeader('X-Content-Type-Options', 'nosniff');
22
+ if (isSvgFile(name, type)) {
23
+ const file = basename(String(name || '')) || 'image.svg';
24
+ const ascii = file.replace(/[^\x20-\x7e]|["\\]/g, '_');
25
+ res.setHeader('Content-Disposition', ascii === file ? `attachment; filename="${file}"` : `attachment; filename="${ascii}"; filename*=UTF-8''${encodeURIComponent(file)}`);
26
+ }
27
+ }