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
@@ -9,7 +9,7 @@
9
9
  // obligation nudges. All server dependencies are injected.
10
10
 
11
11
  import { createHash, randomBytes, randomUUID, timingSafeEqual } from 'node:crypto';
12
- import { appendFileSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs';
12
+ import { appendFileSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from 'node:fs';
13
13
  import { dirname, resolve } from 'node:path';
14
14
  import { createClaudeBrain } from './assistant-brains/claude.js';
15
15
  import { createCodexBrain } from './assistant-brains/codex.js';
@@ -246,10 +246,14 @@ export function createAssistantRuntime({
246
246
  // (capability) → boolean, the verifier of lib/remote-policy.js createPhoneAuthority(): is this the
247
247
  // capability of the one WhatsApp bridge? Without a verifier nothing can grant computer use remotely.
248
248
  phoneAuthority = null,
249
+ // The Admin sandbox setting (lib/agent-sandbox-setting.js): global, shown in every session view.
250
+ adminSandbox = null,
249
251
  } = {}) {
250
252
  if (!dataDir) throw new Error('createAssistantRuntime requires dataDir');
251
253
  const settings = {
252
254
  idleDisposeMs: Math.max(60_000, Number(config.idleDisposeMinutes || 120) * 60_000),
255
+ // A draft (a session the panel opened, before its first prompt) with no socket attached goes after this.
256
+ draftIdleMs: Math.max(60_000, Number(config.draftIdleMinutes || 10) * 60_000),
253
257
  // A remote session on OpenCode waits this long for its gate plugin's hello before a turn (else refused).
254
258
  remoteGateHelloMs: Math.max(0, Number(config.remoteGateHelloMs ?? 5000)),
255
259
  // An OpenCode turn's end waits this long for the serve's stored messages (the usage meter's
@@ -293,11 +297,30 @@ export function createAssistantRuntime({
293
297
 
294
298
  // ── persistence ────────────────────────────────────────────────────────────
295
299
  function transcriptPath(id) { return resolve(dataDir, 'assistant', id, 'transcript.jsonl'); }
300
+ function transcriptHasEntries(id) { try { return statSync(transcriptPath(id)).size > 0; } catch { return false; } }
301
+ function transcriptHasPrompt(id) { try { return readFileSync(transcriptPath(id), 'utf8').includes('"synabun.user_prompt"'); } catch { return false; } }
302
+ /**
303
+ * A record from before `chatStartedAt`: its chat started when it ran a turn, adopted a provider
304
+ * conversation or holds a human prompt (the time is its best guess). One that never did is listed
305
+ * nowhere; with nothing in it at all (no transcript, no runs, not remote, no spend) it is dropped.
306
+ */
307
+ function settleLegacyRow(row) {
308
+ if (row.chatStartedAt) return 'started';
309
+ if (Number(row.turns) > 0 || row.providerSessionId || row.providerThreadId || transcriptHasPrompt(row.id)) {
310
+ row.chatStartedAt = row.lastActiveAt || row.updatedAt || row.createdAt || iso(now());
311
+ return 'started';
312
+ }
313
+ const holds = transcriptHasEntries(row.id) || (Array.isArray(row.dispatchRunIds) && row.dispatchRunIds.length > 0)
314
+ || !!row.remote || !!row.channel || Number(row.costUsd) > 0;
315
+ return holds ? 'unstarted' : 'empty';
316
+ }
296
317
  function loadIndex() {
297
318
  const rows = readJson(indexPath, []);
298
319
  if (!Array.isArray(rows)) return;
320
+ let dropped = 0;
299
321
  for (const row of rows) {
300
322
  if (!row?.id) continue;
323
+ if (settleLegacyRow(row) === 'empty') { dropped += 1; continue; }
301
324
  sessions.set(row.id, makeLive({ ...row, status: row.status === 'ended' ? 'ended' : 'idle', windowIds: [] }));
302
325
  // A remote session nobody registered again since the restart reads as read-only.
303
326
  if (row.remote) {
@@ -305,11 +328,14 @@ export function createAssistantRuntime({
305
328
  try { remotePolicy?.setSessionBrain?.(row.id, row.brain?.provider || null); } catch {}
306
329
  }
307
330
  }
331
+ // The index is written again without them (and with the started marks).
332
+ if (dropped) { log('assistant:index', `${dropped} session record(s) without a conversation dropped`); persist(); }
308
333
  }
309
334
  let persistTimer = null;
310
335
  function persist({ force = false } = {}) {
311
336
  const write = () => {
312
- const rows = [...sessions.values()].map((live) => publicRecord(live.record, { withLive: false, persisted: true }))
337
+ // A draft is never written: it exists on disk only once its first prompt was sent (startChat).
338
+ const rows = [...sessions.values()].filter((live) => !live.draft).map((live) => publicRecord(live.record, { withLive: false, persisted: true }))
313
339
  .sort((a, b) => String(b.updatedAt || '').localeCompare(String(a.updatedAt || '')))
314
340
  .slice(0, settings.retention);
315
341
  try { writeJsonAtomic(indexPath, rows); } catch (error) { log('assistant:index-error', error?.message || String(error)); }
@@ -339,6 +365,9 @@ export function createAssistantRuntime({
339
365
  function makeLive(record) {
340
366
  return {
341
367
  record, brain: null, brainProvider: null, brainMeter: null, brainMeterProvider: null, turnTaskId: null, turnTasks: [], sockets: new Set(), buffer: [], running: false, pendingControls: new Map(), controlTimers: new Map(),
368
+ // A draft: opened by a panel and not chatted in yet. Kept in memory only, listed nowhere, and
369
+ // gone when it is closed or left without a socket (draftTimer); its first prompt stores it (startChat).
370
+ draft: false, draftTimer: null,
342
371
  mailbox: [], mailboxTimer: null, obligations: new Set(), rememberedThisTurn: false, disposeTimer: null, personaText: '',
343
372
  // The last human prompt and where it came from ('ui', 'whatsapp', 'api'): a route continuation
344
373
  // answers there (lastPromptOrigin; the transcript's after a restart).
@@ -906,7 +935,11 @@ export function createAssistantRuntime({
906
935
  out.testDensity = testDensityOf(record);
907
936
  out.testDensityExplicit = normalizeTestDensity(record.testDensity, null);
908
937
  // `rename`: this server keeps a rename on the record (userRenamed), so a panel writes it here.
909
- out.features = { routing: !!router, computer: computerSupported(), testDensity: true, rename: true };
938
+ // `adminSandbox`: the global setting is served here (PUT /api/assistant/admin-sandbox).
939
+ // `drafts`: a session is stored and listed from its first prompt on; `remove`: DELETE stops its work and purges it.
940
+ out.features = { routing: !!router, computer: computerSupported(), testDensity: true, rename: true, adminSandbox: !!adminSandbox, drafts: true, remove: true };
941
+ out.draft = live.draft === true;
942
+ if (adminSandbox) { try { out.adminSandbox = adminSandbox.enabled() === true; } catch { out.adminSandbox = false; } }
910
943
  out.budget = sessionMoney(record.id);
911
944
  out.remoteLevel = policy ? effectiveLevel(policy, { untrusted: live.turnUntrusted === true, now: now() }) : null;
912
945
  }
@@ -2298,6 +2331,8 @@ export function createAssistantRuntime({
2298
2331
  live.lastPromptOrigin = origin ? String(origin) : null;
2299
2332
  // A prompt from elsewhere (WhatsApp, the API) is news to the panel: it goes live too.
2300
2333
  const promptPacket = { type: 'event', event: { type: 'synabun.user_prompt', text: prompt, images: images.length, ...(origin && origin !== 'ui' ? { origin: String(origin) } : {}) } };
2334
+ // The chat starts with its first human prompt: from here on the session is stored and listed.
2335
+ startChat(live);
2301
2336
  appendTranscript(live.record.id, { at: iso(now()), packet: promptPacket });
2302
2337
  if (origin && origin !== 'ui') sendToSockets(live, promptPacket);
2303
2338
  if (live.brainProvider !== 'claude-code' && memory?.recallForPrompt) {
@@ -2668,8 +2703,56 @@ export function createAssistantRuntime({
2668
2703
  }
2669
2704
 
2670
2705
  // ── public API ─────────────────────────────────────────────────────────────
2706
+ /**
2707
+ * Every session list (REST, the socket's list_sessions, the catalog view) reads this: only sessions
2708
+ * whose chat started. A draft, or a record nobody ever prompted, is in none of them. `activeRuns`:
2709
+ * the workers it dispatched that still run (a removal stops them, and its question says so).
2710
+ */
2671
2711
  function listSessions() {
2672
- return [...sessions.values()].map((live) => view(live)).sort((a, b) => String(b.updatedAt || '').localeCompare(String(a.updatedAt || '')));
2712
+ const runs = new Map();
2713
+ try {
2714
+ for (const run of dispatcher?.list?.({ activeOnly: true, limit: 500 }) || []) {
2715
+ if (run?.assistantSessionId) runs.set(run.assistantSessionId, (runs.get(run.assistantSessionId) || 0) + 1);
2716
+ }
2717
+ } catch {}
2718
+ return [...sessions.values()].filter((live) => !live.draft && !!live.record.chatStartedAt)
2719
+ .map((live) => ({ ...view(live), activeRuns: runs.get(live.record.id) || 0 }))
2720
+ .sort((a, b) => String(b.updatedAt || '').localeCompare(String(a.updatedAt || '')));
2721
+ }
2722
+ /**
2723
+ * The first human prompt (or a provider conversation adopted with `resume`) starts the chat: the
2724
+ * record is marked, and a draft becomes a stored session (written now, listed from now on).
2725
+ */
2726
+ function startChat(live) {
2727
+ if (live.record.chatStartedAt && !live.draft) return;
2728
+ live.record.chatStartedAt ||= iso(now());
2729
+ const wasDraft = live.draft;
2730
+ live.draft = false;
2731
+ if (live.draftTimer) { clearTimeout(live.draftTimer); live.draftTimer = null; }
2732
+ persist({ force: true });
2733
+ if (wasDraft) broadcast('assistant:session-created', live);
2734
+ }
2735
+ /** A draft with no socket attached is removed after settings.draftIdleMs (a page that went and never came back). */
2736
+ function armDraftExpiry(live) {
2737
+ if (live.draftTimer) { clearTimeout(live.draftTimer); live.draftTimer = null; }
2738
+ if (!live.draft || live.sockets.size || shuttingDown || sessions.get(live.record.id) !== live) return;
2739
+ live.draftTimer = setTimeout(() => {
2740
+ live.draftTimer = null;
2741
+ if (!live.draft || live.sockets.size || sessions.get(live.record.id) !== live || sessionBusy(live) || live.closing) return;
2742
+ destroySession(live.record.id).catch((error) => log('assistant:draft-expiry', error?.message || String(error)));
2743
+ }, settings.draftIdleMs);
2744
+ live.draftTimer.unref?.();
2745
+ }
2746
+ /**
2747
+ * Whether closing a session keeps its record (ended, reopenable) or removes it: a session that
2748
+ * never held a conversation (no prompt, no turn, no runs, nothing in its transcript, not remote,
2749
+ * no work under way) leaves nothing behind.
2750
+ */
2751
+ function holdsConversation(live) {
2752
+ const r = live.record;
2753
+ return !!r.chatStartedAt || Number(r.turns) > 0 || (Array.isArray(r.dispatchRunIds) && r.dispatchRunIds.length > 0)
2754
+ || !!r.providerSessionId || !!r.providerThreadId || !!r.remote || !!r.channel || Number(r.costUsd) > 0
2755
+ || sessionBusy(live) || !!workReserved(live) || transcriptHasEntries(r.id);
2673
2756
  }
2674
2757
  function getSession(id, { transcript = true, limit = 400 } = {}) {
2675
2758
  const live = sessions.get(id);
@@ -2694,7 +2777,7 @@ export function createAssistantRuntime({
2694
2777
  if (!row) throw Object.assign(new Error('Auto requires a signed-in subscription account.'), { code: 'ACCOUNT_NO_SUBSCRIPTION', status: 409 });
2695
2778
  return { ...brain, accountId: row.id };
2696
2779
  }
2697
- async function createSession({ brain = {}, label = null, cwd = null, windowId = null, fallback = false, channel = null } = {}, internal = {}) {
2780
+ async function createSession({ brain = {}, label = null, cwd = null, windowId = null, fallback = false, channel = null, draft = false } = {}, internal = {}) {
2698
2781
  const id = `assistant-${randomUUID()}`;
2699
2782
  const requested = normalizeBrain({ ...brain, cwd: brain?.cwd || cwd || settings.defaultBrain.cwd || PACKAGE_ROOT }, settings.defaultBrain, { catalog: catalog?.peek?.() || null });
2700
2783
  const enabled = await enabledBrain(requested, { fallback: fallback === true, named: !!brain?.model });
@@ -2725,8 +2808,16 @@ export function createAssistantRuntime({
2725
2808
  live.creating = false;
2726
2809
  record.brain = clampedBrain(live, record.brain);
2727
2810
  }
2728
- persist({ force: true });
2729
- broadcast('assistant:session-created', live);
2811
+ // `draft` (a panel's new session, POST /sessions): stored and announced by its first prompt
2812
+ // (startChat); until then it lives here only, and is removed when it is closed or left (armDraftExpiry).
2813
+ // A remote session is never one: its bridge sends the prompt it was made for.
2814
+ if (draft === true && !remote && !record.channel) {
2815
+ live.draft = true;
2816
+ armDraftExpiry(live);
2817
+ } else {
2818
+ persist({ force: true });
2819
+ broadcast('assistant:session-created', live);
2820
+ }
2730
2821
  return enabled.fallback ? { ...view(live), fallback: enabled.fallback } : view(live);
2731
2822
  }
2732
2823
  function applyRouteMode(live, mode) {
@@ -2826,6 +2917,12 @@ export function createAssistantRuntime({
2826
2917
  }
2827
2918
  async function closeSession(id) {
2828
2919
  const live = requireLive(id);
2920
+ // Never chatted in (a draft, a record nobody prompted): closing it leaves nothing behind.
2921
+ if (!holdsConversation(live)) {
2922
+ const gone = { ...view(live), status: 'destroyed', removed: true };
2923
+ await destroySession(id);
2924
+ return gone;
2925
+ }
2829
2926
  const closed = await endSessionWork(live);
2830
2927
  try {
2831
2928
  await disposeBrain(live, 'closed');
@@ -2843,6 +2940,9 @@ export function createAssistantRuntime({
2843
2940
  if (!live) return false;
2844
2941
  const closed = await endSessionWork(live);
2845
2942
  try {
2943
+ if (sessions.get(id) !== live) return false; // another removal got there first
2944
+ if (live.draftTimer) { clearTimeout(live.draftTimer); live.draftTimer = null; }
2945
+ if (live.disposeTimer) { clearTimeout(live.disposeTimer); live.disposeTimer = null; }
2846
2946
  await disposeBrain(live, 'closed');
2847
2947
  for (const ws of live.sockets) { try { ws.close(1000, 'session destroyed'); } catch {} }
2848
2948
  sessions.delete(id);
@@ -2859,6 +2959,24 @@ export function createAssistantRuntime({
2859
2959
  } finally { closed(); }
2860
2960
  return true;
2861
2961
  }
2962
+ /**
2963
+ * The Sessions menu's Remove (DELETE /api/assistant/sessions/:id): the session goes for good, in
2964
+ * every host and list, and its work goes with it: the workers it dispatched that still run are
2965
+ * stopped (no orphaned run is left), then the running turn and the brain (destroySession). Only
2966
+ * the record, its transcript and its usage journal are removed: memories made from it (its
2967
+ * assistant-threads record included) stay, and so do the dispatcher's records of its runs.
2968
+ */
2969
+ async function removeSession(id) {
2970
+ const live = sessions.get(String(id || ''));
2971
+ if (!live) return { removed: false, stoppedRuns: [] };
2972
+ let stoppedRuns = [];
2973
+ try {
2974
+ const result = await dispatcher?.killAll?.({ assistantSessionId: live.record.id, reason: 'session_removed' });
2975
+ stoppedRuns = Array.isArray(result?.stopped) ? result.stopped : [];
2976
+ } catch (error) { log('assistant:remove', `${live.record.id}: stopping its runs failed (${error?.message || error})`); }
2977
+ const removed = await destroySession(live.record.id);
2978
+ return { removed, stoppedRuns };
2979
+ }
2862
2980
  /**
2863
2981
  * MCP terminal pin → assistant session id. Claude brains pin the session id
2864
2982
  * itself; the OpenCode brain pins `assistant-oc-<24>` (its isolated serve).
@@ -3123,6 +3241,7 @@ export function createAssistantRuntime({
3123
3241
  ws.on('close', () => {
3124
3242
  live.sockets.delete(ws);
3125
3243
  scheduleDispose(live);
3244
+ armDraftExpiry(live);
3126
3245
  });
3127
3246
  if (held) {
3128
3247
  while (live.closing) await live.closing;
@@ -3133,6 +3252,7 @@ export function createAssistantRuntime({
3133
3252
  if (ws.readyState !== 1) return; // gone while it waited
3134
3253
  }
3135
3254
  if (live.disposeTimer) { clearTimeout(live.disposeTimer); live.disposeTimer = null; }
3255
+ if (live.draftTimer) { clearTimeout(live.draftTimer); live.draftTimer = null; }
3136
3256
  live.sockets.add(ws);
3137
3257
  live.record.status = live.record.status === 'ended' ? 'idle' : live.record.status;
3138
3258
  const engine = live.brain ? { type: 'engine', engine: live.brainProvider === 'claude-code' ? 'sdk' : live.brainProvider, brain: live.brainProvider, sdkVersion } : { type: 'engine', engine: 'assistant', brain: live.record.brain.provider, sdkVersion };
@@ -3264,6 +3384,8 @@ export function createAssistantRuntime({
3264
3384
  if (msg.providerSessionId) {
3265
3385
  const moved = msg.providerSessionId !== live.record.providerSessionId;
3266
3386
  live.record.providerSessionId = msg.providerSessionId;
3387
+ // A provider conversation adopted (/resume <id>): the session holds a chat now.
3388
+ startChat(live);
3267
3389
  // Another provider session: the meter's baseline was the old one's.
3268
3390
  if (moved) resetMeterIdentity(live, msg.providerSessionId);
3269
3391
  // …and so was the frozen user-context digest.
@@ -3724,6 +3846,7 @@ export function createAssistantRuntime({
3724
3846
  for (const live of sessions.values()) {
3725
3847
  if (live.mailboxTimer) clearTimeout(live.mailboxTimer);
3726
3848
  if (live.disposeTimer) clearTimeout(live.disposeTimer);
3849
+ if (live.draftTimer) clearTimeout(live.draftTimer);
3727
3850
  if (live.workTimer) clearTimeout(live.workTimer);
3728
3851
  await disposeBrain(live, 'shutdown').catch(() => {});
3729
3852
  live.record.status = 'idle';
@@ -3750,7 +3873,7 @@ export function createAssistantRuntime({
3750
3873
  broadcastSync = (message) => { try { originalBroadcast(message); } catch {} if (message?.type === 'assistant:permission-request' || message?.type === 'assistant:permission-resolved') onPermissionBroadcast(message); };
3751
3874
 
3752
3875
  return {
3753
- handleWebSocket, listSessions, getSession, createSession, updateSession, closeSession, destroySession,
3876
+ handleWebSocket, listSessions, getSession, createSession, updateSession, closeSession, destroySession, removeSession,
3754
3877
  resolveTerminal, accountInUse, ownsIsolatedServe, noteDispatch, subscribe, shutdown,
3755
3878
  observeBroadcast: onPermissionBroadcast,
3756
3879
  testDensityFor, routerSession, routerSend, routerEvent, routerMailbox, routerContinue, routerSinks, routerRouted, routerRouteFailed, routerComputerApproved, gateCheck, isPlanning, isPlanReadOnly,
@@ -43,7 +43,39 @@ const DISCOVERY_TIMEOUT_MS = 15000;
43
43
  const CACHE_TTL_MS = 10 * 60 * 1000;
44
44
 
45
45
  let _cache = { at: 0, key: '', models: [] };
46
- let _inflight = null;
46
+ const _inflight = new Map(); // cache key → the discovery running for it
47
+ // Where the last verified list is kept across restarts ({ read(), write(entry) },
48
+ // lib/launch-cache.js createSnapshotStore): a start answers with it at once and
49
+ // asks the CLI again in the background.
50
+ let _store = null;
51
+ let _storeRead = false;
52
+
53
+ export function setClaudeModelStore(store) {
54
+ _store = store && typeof store.read === 'function' && typeof store.write === 'function' ? store : null;
55
+ _storeRead = false;
56
+ }
57
+
58
+ // The list the last run verified, for this very binary and account: given at once
59
+ // after a restart (as an old answer, so the first read asks the CLI again).
60
+ function adoptStoredModels(key) {
61
+ if (_storeRead || !_store) return;
62
+ _storeRead = true;
63
+ if (_cache.models.length) return;
64
+ try {
65
+ const saved = _store.read();
66
+ const models = saved?.key === key && Array.isArray(saved.models)
67
+ ? saved.models.filter(m => m && typeof m === 'object' && typeof m.id === 'string' && m.id)
68
+ : [];
69
+ if (models.length) _cache = { at: 0, key, models };
70
+ } catch { /* nothing kept: the first read asks the CLI */ }
71
+ }
72
+
73
+ // What the list depends on: the binary (an update changes it, binaryIdentity) and
74
+ // the account it was read under (another account can be entitled to other models).
75
+ function cacheKeyOf(bin, account) {
76
+ const who = String(account || '');
77
+ return who ? `${binaryIdentity(bin)}#${who}` : binaryIdentity(bin);
78
+ }
47
79
 
48
80
  // Who else keeps a copy of this list (the Assistant's model catalog). Told when a
49
81
  // discovery returns a list that differs from the one before it, so a copy is
@@ -286,37 +318,55 @@ export function queryClaudeCliModels(claudeBin, { cwd, timeoutMs = DISCOVERY_TIM
286
318
  }
287
319
 
288
320
  // Cached discovery. `source` lets the UI distinguish a verified list from the
289
- // baked-in fallback. Cache is keyed on the binary's identity, so switching the
290
- // configured CLI (Settings > Terminal) or updating it re-discovers.
291
- export async function discoverClaudeModels(claudeBin, { force = false, cwd, query = queryClaudeCliModels } = {}) {
321
+ // baked-in fallback. Cache is keyed on the binary's identity (and the account
322
+ // the list was read under, `account`), so switching the configured CLI
323
+ // (Settings > Terminal), updating it or signing in to another account
324
+ // re-discovers. A list that is merely old is still given at once, and the CLI is
325
+ // asked again in the background (one discovery at a time): only a first read, a
326
+ // changed key or `force` waits for the CLI.
327
+ export async function discoverClaudeModels(claudeBin, { force = false, cwd, query = queryClaudeCliModels, account = '' } = {}) {
292
328
  const bin = String(claudeBin || '');
293
- const key = binaryIdentity(bin);
294
- const fresh = _cache.models.length
295
- && _cache.key === key
296
- && Date.now() - _cache.at < CACHE_TTL_MS;
297
- if (!force && fresh) return { source: 'cache', models: _cache.models };
298
- if (_inflight) return _inflight;
299
-
300
- _inflight = (async () => {
329
+ const key = cacheKeyOf(bin, account);
330
+ adoptStoredModels(key);
331
+ const known = _cache.models.length && _cache.key === key;
332
+ if (!force && known) {
333
+ if (Date.now() - _cache.at >= CACHE_TTL_MS) discover(bin, key, cwd, query).catch(() => {});
334
+ return { source: 'cache', models: _cache.models };
335
+ }
336
+ return discover(bin, key, cwd, query);
337
+ }
338
+
339
+ function discover(bin, key, cwd, query) {
340
+ if (_inflight.has(key)) return _inflight.get(key);
341
+ const job = (async () => {
301
342
  try {
302
343
  const raw = await query(bin, { cwd });
303
344
  const models = normalizeClaudeModels(raw);
304
345
  if (models.length) {
305
346
  const changed = claudeModelsSignature(models) !== claudeModelsSignature(_cache.models);
306
347
  _cache = { at: Date.now(), key, models };
348
+ try { _store?.write({ key, at: _cache.at, models }); } catch { /* kept in memory still */ }
307
349
  if (changed) notifyModelsChanged(models);
308
350
  return { source: 'cli', models };
309
351
  }
310
352
  return { source: 'fallback', models: [...CLAUDE_FALLBACK_MODELS] };
311
353
  } finally {
312
- _inflight = null;
354
+ if (_inflight.get(key) === job) _inflight.delete(key);
313
355
  }
314
356
  })();
315
- return _inflight;
357
+ _inflight.set(key, job);
358
+ return job;
359
+ }
360
+
361
+ /** The kept list is due again: the next read still answers with it and asks the CLI in the background. */
362
+ export function markClaudeModelsStale() {
363
+ _cache = { ..._cache, at: 0 };
316
364
  }
317
365
 
318
366
  export function clearClaudeModelCache() {
319
367
  _cache = { at: 0, key: '', models: [] };
368
+ _inflight.clear();
369
+ _storeRead = !!_store;
320
370
  _skewCache = { key: null, result: undefined };
321
371
  _skewInflight.clear();
322
372
  }
@@ -9,7 +9,7 @@
9
9
  import { spawn } from 'node:child_process';
10
10
  import { verifyOpenAiApiKey } from './claude-profile-api-key.js';
11
11
  import { validateProviderApiKey } from './provider-panel-api-key-auth.js';
12
- import { applyCodexLaunchEnv } from './codex-accounts.js';
12
+ import { applyCodexLaunchEnv, codexLaunchArgs } from './codex-accounts.js';
13
13
 
14
14
  const fail = (message, status = 409, code = null) => Object.assign(new Error(message), { status, ...(code ? { code } : {}) });
15
15
 
@@ -32,13 +32,15 @@ export function createCodexAccountAuth({
32
32
  }
33
33
  // Codex run under the account's own store: inherited credentials out, its
34
34
  // CODEX_HOME in, never the key SynaBun holds (that is not Codex's store).
35
- function launch(id, args) {
35
+ // The launch's overrides (the Windows sandbox of the Admin sandbox setting) follow the subcommand.
36
+ function launch(id, words) {
36
37
  account(id);
37
38
  const plan = accounts.launchFor(id);
38
39
  if (!plan.ok) throw fail(plan.message, 404);
39
40
  prepareConfig(plan.home);
40
41
  let file = codexBin();
41
42
  if (!file) throw fail('Codex CLI not found. Install Codex to sign in.', 503);
43
+ const args = [...words, ...codexLaunchArgs(plan)];
42
44
  const script = /\.[cm]?js$/i.test(file);
43
45
  const shell = process.platform === 'win32' && /\.(cmd|bat)$/i.test(file);
44
46
  const proc = spawnProcess(script ? process.execPath : file, script ? [file, ...args] : args, {
@@ -32,6 +32,7 @@ import { dirname, join, resolve, sep } from 'node:path';
32
32
  import { homedir } from 'node:os';
33
33
  import { readProfileApiKey, saveProfileApiKey, clearProfileApiKey } from './claude-profile-api-key.js';
34
34
  import { apiKeyHint, resolveClaudeAuth } from './claude-accounts.js';
35
+ import { normalizeAdminSandbox, sandboxElevationFor } from './agent-sandbox-elevation.js';
35
36
 
36
37
  export const CODEX_DEFAULT_ACCOUNT_ID = 'default';
37
38
  export const CODEX_AUTH_MODES = Object.freeze(['subscription', 'apiKey']);
@@ -123,9 +124,13 @@ export function applyCodexLaunchEnv(base, launch) {
123
124
  export function codexExecEnv(launch) {
124
125
  return { ...(launch?.env || {}), ...(launch?.apiKey ? { CODEX_API_KEY: launch.apiKey } : {}) };
125
126
  }
127
+ /** The `-c` overrides every Codex process of the launch starts with: the Windows sandbox the Admin sandbox setting allows. */
128
+ export function codexLaunchArgs(launch) {
129
+ return [...(launch?.configArgs || [])];
130
+ }
126
131
  /** The `-c` overrides an app-server of the account starts with (before the subcommand). */
127
132
  export function codexAppServerArgs(launch) {
128
- return launch?.apiKey ? [...CODEX_EPHEMERAL_STORE_ARGS] : [];
133
+ return [...codexLaunchArgs(launch), ...(launch?.apiKey ? CODEX_EPHEMERAL_STORE_ARGS : [])];
129
134
  }
130
135
 
131
136
  export function createCodexAccounts({
@@ -141,6 +146,8 @@ export function createCodexAccounts({
141
146
  statusTimeoutMs = 20_000,
142
147
  // Called before a new account links Default's config.toml (server.js repairs it there).
143
148
  prepareDefaultConfig = () => {},
149
+ // () => the Admin sandbox setting (lib/agent-sandbox-setting.js): which Windows sandbox every launch may use.
150
+ adminSandbox = () => false,
144
151
  } = {}) {
145
152
  if (!dataHome) throw new Error('createCodexAccounts requires dataHome');
146
153
  const registryPath = resolve(dataHome, 'data', 'codex-accounts.json');
@@ -273,11 +280,17 @@ export function createCodexAccounts({
273
280
  }
274
281
  const { row, key } = describeProfile(profile, data);
275
282
  const apiKey = row.mode === 'apiKey' && row.apiKey.source === 'synabun' && key ? key : null;
283
+ // A launch override, never written into config.toml: Default's home is the user's own ~/.codex.
284
+ let on = false;
285
+ try { on = normalizeAdminSandbox(adminSandbox()); } catch { on = false; }
286
+ const sandbox = sandboxElevationFor('codex', on);
276
287
  return {
277
288
  ok: true, accountId: wanted, label: row.label, mode: row.mode, signedIn: row.signedIn, identity: row.identity, home: row.home,
278
289
  env: { CODEX_HOME: row.home }, unset: [...CODEX_CREDENTIAL_ENV], apiKey,
279
290
  // Which credential a process started with: a change means the account's idle processes restart.
280
291
  credential: [row.mode || 'none', row.apiKey.source || '', row.apiKey.hint || '', row.subscription.email || ''].join(':'),
292
+ // The Windows sandbox it may use ('elevated' | 'unelevated'): a change restarts idle app-servers too.
293
+ windowsSandbox: sandbox.value, configArgs: sandbox.args,
281
294
  };
282
295
  }
283
296