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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neural-memory-interface",
3
- "version": "2.0.7",
3
+ "version": "2.0.10",
4
4
  "private": true,
5
5
  "description": "Private local SynaBun interface for memory visualization and multi-agent workflows",
6
6
  "license": "Apache-2.0",
@@ -61,9 +61,13 @@
61
61
  "@codemirror/search": "6.7.2",
62
62
  "@codemirror/state": "6.7.6",
63
63
  "@codemirror/view": "6.43.14",
64
+ "@highlightjs/cdn-assets": "11.12.0",
64
65
  "@lezer/highlight": "1.2.5",
65
66
  "@replit/codemirror-indentation-markers": "6.5.3",
66
67
  "esbuild": "^0.28.1",
68
+ "html2canvas": "1.4.1",
69
+ "marked": "14.1.4",
70
+ "mermaid": "11.17.2",
67
71
  "three": "0.169.0"
68
72
  }
69
73
  }
@@ -56,8 +56,8 @@
56
56
  </head>
57
57
  <body>
58
58
 
59
- <!-- html2canvas for card screenshot MCP tool -->
60
- <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js" defer></script>
59
+ <!-- html2canvas for card screenshot MCP tool (vendored: public/vendor/html2canvas/) -->
60
+ <script src="/vendor/html2canvas/html2canvas-1.4.1.min.js" defer></script>
61
61
 
62
62
  <script type="module" src="/variant/3d/main.js"></script>
63
63
  </body>
@@ -332,7 +332,10 @@ export function mountAccountMenu({ provider = 'claude', container, before = null
332
332
 
333
333
  function place() {
334
334
  if (!open) return;
335
- const rect = trigger.getBoundingClientRect();
335
+ let rect = trigger.getBoundingClientRect();
336
+ // A header too narrow for the trigger hides it (the panels' container queries); the menu,
337
+ // opened from the cog's Account row, then hangs from the row the trigger sits in.
338
+ if (!rect.width && !rect.height && trigger.parentElement) rect = trigger.parentElement.getBoundingClientRect();
336
339
  const owner = layer?.() || trigger.closest('[class*="panel"]');
337
340
  const ownerWidth = owner?.getBoundingClientRect?.().width;
338
341
  popup.style.width = `${Math.max(0, Math.min(320, ownerWidth > 240 ? ownerWidth - 16 : 320, window.innerWidth - 16))}px`;
@@ -1,9 +1,12 @@
1
1
  // Text only: keep the account menus in their existing component/token scope.
2
- export function accountUsageText(row, t) {
3
- const tr = (key, fallback, params = {}) => {
2
+ function translator(t) {
3
+ return (key, fallback, params = {}) => {
4
4
  const value = t?.(`assistant.accountUsage.${key}`, params);
5
5
  return value && value !== `assistant.accountUsage.${key}` ? value : fallback.replace(/\{(\w+)\}/g, (_, k) => params[k] ?? '');
6
6
  };
7
+ }
8
+ export function accountUsageText(row, t) {
9
+ const tr = translator(t);
7
10
  if (row?.mode === 'apiKey' || row?.mode === 'api') return tr('notApplicable', 'Usage n/a');
8
11
  const u = row?.usage;
9
12
  const reset = u?.resetsAt ? new Date(u.resetsAt) : null;
@@ -17,3 +20,60 @@ export function autoAccountLabel(t) {
17
20
  const value = t?.(key);
18
21
  return value && value !== key ? value : 'Auto · most usage left';
19
22
  }
23
+
24
+ function pageLocale() {
25
+ try { return globalThis.document?.documentElement?.lang || undefined; } catch { return undefined; }
26
+ }
27
+ function dateFormat(locale, options) {
28
+ try { return new Intl.DateTimeFormat(locale, options); } catch { return new Intl.DateTimeFormat(undefined, options); }
29
+ }
30
+ const dayStart = (ms) => { const day = new Date(ms); day.setHours(0, 0, 0, 0); return day.getTime(); };
31
+ const bare = (text) => String(text).replace(/\.$/, '');
32
+
33
+ /**
34
+ * When an account's usage comes back, short enough for one menu line in the page's language:
35
+ * "15:59" today, "Thu 15:59" within the week, "Oct 19 15:59" / "19 out 15:59" later; '' without a
36
+ * valid date. `long` is the full form for a tooltip ("Thursday, October 22 at 15:59").
37
+ */
38
+ export function resetTimeText(value, { now = Date.now(), locale = pageLocale(), long = false } = {}) {
39
+ const at = value ? new Date(value) : null;
40
+ if (!at || !Number.isFinite(at.getTime())) return '';
41
+ if (long) return dateFormat(locale, { weekday: 'long', day: 'numeric', month: 'long', hour: '2-digit', minute: '2-digit', hourCycle: 'h23' }).format(at);
42
+ const time = dateFormat(locale, { hour: '2-digit', minute: '2-digit', hourCycle: 'h23' }).format(at);
43
+ const days = Math.round((dayStart(at.getTime()) - dayStart(now)) / 86_400_000);
44
+ if (days === 0) return time;
45
+ if (days > 0 && days < 7) return `${bare(dateFormat(locale, { weekday: 'short' }).format(at))} ${time}`;
46
+ const date = dateFormat(locale, { day: 'numeric', month: 'short' }).formatToParts(at)
47
+ .filter((part) => part.type === 'day' || part.type === 'month').map((part) => bare(part.value)).join(' ');
48
+ return `${date} ${time}`;
49
+ }
50
+
51
+ /**
52
+ * An account's usage as one short line of a menu row: { text, tone: 'muted' | 'warn', title }
53
+ * ("50% left · resets Thu 15:59", "Limited until 23:10", "Usage unknown"), the title with the full
54
+ * reset date. null where usage does not apply: an API key, a signed-out or unchecked account.
55
+ */
56
+ export function accountUsageLine(row, t, { now = Date.now(), locale = pageLocale() } = {}) {
57
+ if (!row || row.signedIn !== true || row.mode !== 'subscription') return null;
58
+ const tr = translator(t);
59
+ const u = row.usage;
60
+ const short = resetTimeText(u?.resetsAt, { now, locale });
61
+ const full = resetTimeText(u?.resetsAt, { now, locale, long: true });
62
+ if (u?.limited) {
63
+ return {
64
+ text: short ? tr('limitedUntil', 'Limited until {time}', { time: short }) : tr('limited', 'Limited'),
65
+ tone: 'warn',
66
+ title: full ? tr('limitedUntil', 'Limited until {time}', { time: full }) : tr('limited', 'Limited'),
67
+ };
68
+ }
69
+ if (typeof u?.remainingPercent !== 'number' || !Number.isFinite(u.remainingPercent)) {
70
+ const text = tr('unknown', 'Usage unknown');
71
+ return { text, tone: 'muted', title: text };
72
+ }
73
+ const left = tr('left', '{percent}% left', { percent: Math.round(Math.max(0, Math.min(100, u.remainingPercent))) });
74
+ return {
75
+ text: [left, short ? tr('resets', 'resets {time}', { time: short }) : ''].filter(Boolean).join(' · '),
76
+ tone: 'muted',
77
+ title: [left, full ? tr('resets', 'resets {time}', { time: full }) : ''].filter(Boolean).join(' · '),
78
+ };
79
+ }
@@ -145,7 +145,8 @@ export function accountBadge(row, provider = null) {
145
145
  return { text: accountText('checking', {}, p), tone: 'muted', mode: row.mode || null };
146
146
  }
147
147
 
148
- function planName(plan) {
148
+ /** A subscription plan as its name ("max" → "Max"); '' for none. */
149
+ export function planName(plan) {
149
150
  const value = String(plan || '').trim();
150
151
  return value ? value.charAt(0).toUpperCase() + value.slice(1) : '';
151
152
  }
@@ -1,6 +1,7 @@
1
1
  // Shared launch/runtime metadata for Automation Studio, Schedules Studio,
2
2
  // and agent sidepanels.
3
3
  import { normalizeAutomationSelection } from './automation-context.js';
4
+ import { fetchOpencodeProviders, opencodeProviders } from './opencode-providers.js';
4
5
 
5
6
  export const CLI_PROFILES = [
6
7
  { id: 'claude-code', label: 'Claude Code', desc: 'Anthropic' },
@@ -145,6 +146,27 @@ let _opencodeModelsLoading = null;
145
146
  let _claudeModelsCache = null;
146
147
  let _claudeModelsLoading = null;
147
148
  let _mcpProfilePresets = null;
149
+ let _mcpProfilePresetsLoading = null;
150
+
151
+ // The verified Claude and Codex lists are also kept in sessionStorage (this tab only): after a reload the
152
+ // pickers paint from them at once (a list read back is due, so the first load still asks the server).
153
+ const LIST_STORE_PREFIX = 'synabun:runtime-models:v1:';
154
+ function keepList(key, list) {
155
+ try { if (typeof sessionStorage !== 'undefined') sessionStorage.setItem(LIST_STORE_PREFIX + key, JSON.stringify(list)); } catch { /* full or unavailable */ }
156
+ }
157
+ function keptList(key) {
158
+ try {
159
+ if (typeof sessionStorage === 'undefined') return null;
160
+ const list = JSON.parse(sessionStorage.getItem(LIST_STORE_PREFIX + key) || 'null');
161
+ return Array.isArray(list) && list.length ? list : null;
162
+ } catch { return null; }
163
+ }
164
+ (() => {
165
+ const claude = keptList('claude-code');
166
+ if (claude && !_claudeModelsCache) _claudeModelsCache = claude;
167
+ const codex = keptList('codex:default');
168
+ if (codex && !_codexModelsCache.has('default')) _codexModelsCache.set('default', codex);
169
+ })();
148
170
 
149
171
  function localJsonArray(key) {
150
172
  try {
@@ -287,6 +309,7 @@ export async function fetchCodexModels(force = false, accountId = 'default') {
287
309
  const normalized = mergeCodexModelOptions(models, { fallback: false });
288
310
  _codexModelsCache.set(account, normalized);
289
311
  _modelListAt.set(`codex:${account}`, Date.now());
312
+ if (normalized.length) keepList(`codex:${account}`, normalized);
290
313
  return normalized;
291
314
  } catch {
292
315
  const previous = _codexModelsCache.get(account) || [];
@@ -466,8 +489,8 @@ export async function fetchOpencodeModels(force = false) {
466
489
  if (_opencodeModelsLoading) return _opencodeModelsLoading;
467
490
  _opencodeModelsLoading = (async () => {
468
491
  try {
469
- const resp = await fetch('/api/opencode/providers/full');
470
- const data = await resp.json().catch(() => ({}));
492
+ // The connected providers, from the page's one kept read (opencode-providers.js).
493
+ const data = await fetchOpencodeProviders({ force }).catch(() => ({}));
471
494
  if (!data || data.ok === false) return [];
472
495
  const out = parseOpencodeProviderModels(data);
473
496
  if (out.length) _opencodeModelsCache = out;
@@ -497,6 +520,7 @@ export async function fetchClaudeModels(force = false) {
497
520
  if (models.length && data?.source !== 'fallback') {
498
521
  _claudeModelsCache = models.map(model => ({ ...model, catalogSource: data?.source || 'cli' }));
499
522
  _modelListAt.set('claude-code', Date.now());
523
+ keepList('claude-code', _claudeModelsCache);
500
524
  } else {
501
525
  _claudeModelsCache = verified() || (models.length ? models.map(model => ({ ...model, catalogSource: 'fallback' })) : [...CLAUDE_FALLBACK_MODELS]);
502
526
  }
@@ -524,9 +548,19 @@ export async function ensureModelsForProfile(profileId, force = false, accountId
524
548
  return getModelsForProfile(profileId, accountId);
525
549
  }
526
550
 
551
+ // OpenCode's list parsed from the provider list the page already holds (read at launch, kept across a reload,
552
+ // or by another module): no request, and the hidden models of this window are applied as it is parsed.
553
+ function keptOpencodeModels() {
554
+ const kept = opencodeProviders.peek('');
555
+ if (!kept || kept.ok === false) return null;
556
+ const out = parseOpencodeProviderModels(kept);
557
+ if (out.length) _opencodeModelsCache = out;
558
+ return out;
559
+ }
560
+
527
561
  export function getModelsForProfile(profileId, accountId = 'default') {
528
562
  if (profileId === 'codex') return _codexModelsCache.get(String(accountId || 'default')) || [];
529
- if (profileId === 'opencode') return _opencodeModelsCache || [];
563
+ if (profileId === 'opencode') return _opencodeModelsCache || keptOpencodeModels() || [];
530
564
  if (profileId === 'claude-code') return _claudeModelsCache || [];
531
565
  return STATIC_MODELS[profileId] || [];
532
566
  }
@@ -601,14 +635,21 @@ export function normalizeEffortForProfile(profileId, effort) {
601
635
 
602
636
  export async function fetchMcpProfilePresets(force = false) {
603
637
  if (!force && _mcpProfilePresets) return _mcpProfilePresets;
604
- try {
605
- const resp = await fetch('/api/mcp/profile');
606
- const data = await resp.json().catch(() => ({}));
607
- _mcpProfilePresets = data?.ok && data.presets ? data.presets : {};
608
- return _mcpProfilePresets;
609
- } catch {
610
- return {};
611
- }
638
+ // Callers asking at the same time share one request.
639
+ if (_mcpProfilePresetsLoading) return _mcpProfilePresetsLoading;
640
+ _mcpProfilePresetsLoading = (async () => {
641
+ try {
642
+ const resp = await fetch('/api/mcp/profile');
643
+ const data = await resp.json().catch(() => ({}));
644
+ _mcpProfilePresets = data?.ok && data.presets ? data.presets : {};
645
+ return _mcpProfilePresets;
646
+ } catch {
647
+ return {};
648
+ } finally {
649
+ _mcpProfilePresetsLoading = null;
650
+ }
651
+ })();
652
+ return _mcpProfilePresetsLoading;
612
653
  }
613
654
 
614
655
  export function getCachedMcpProfilePresets() {
@@ -619,6 +660,7 @@ export function clearRuntimeOptionCaches() {
619
660
  _codexModelsCache.clear();
620
661
  _codexModelsLoading.clear();
621
662
  _opencodeModelsCache = null;
663
+ opencodeProviders.invalidate('');
622
664
  _claudeModelsCache = null;
623
665
  _modelListAt.clear();
624
666
  _mcpProfilePresets = null;
@@ -630,3 +672,5 @@ if (typeof document !== 'undefined') {
630
672
  document.addEventListener('ocp-hidden-models-changed', () => { _opencodeModelsCache = null; });
631
673
  document.addEventListener('ocp-providers-changed', () => { _opencodeModelsCache = null; });
632
674
  }
675
+ // A background read of the provider list brought another one: the parsed copy is made again from it.
676
+ opencodeProviders.subscribe(() => { _opencodeModelsCache = null; });
@@ -0,0 +1,298 @@
1
+ // ═══════════════════════════════════════════
2
+ // SynaBun Assistant — account menu (⚙ → Account profile)
3
+ // ═══════════════════════════════════════════
4
+ // Which Claude or Codex account this conversation runs on and which one
5
+ // dispatched workers use, in one popover that stays inside the panel
6
+ // (asst-menu.js `bounds`; only the list scrolls, the footer stays). Every
7
+ // account is listed once: its name, who it is when that adds to the name, the
8
+ // plan or API key, the usage left or the limit, and when it comes back. Auto is
9
+ // one line (its sentence is the tooltip). "Workers use" opens the workers'
10
+ // choice in the same popover (Esc goes back). The words come from
11
+ // account-view.js and account-usage.js; what a choice does is the caller's
12
+ // (asst-brain-picker.js). accountMenuRow is DOM-free (node --test loads it).
13
+ // The composer's Model menu lists the same rows (accountChoiceItems,
14
+ // accountModeItem, accountManageItem), so both show an account the same way.
15
+
16
+ import { accountBadge, accountName, accountText, accountUsable, modeChoices, planName } from '../account-view.js';
17
+ import { accountUsageLine, autoAccountLabel } from '../account-usage.js';
18
+ import { openMenu } from './asst-menu.js';
19
+
20
+ const ICON_CHECK = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3.5 8.5l3 3 6-7"/></svg>';
21
+ // Auto: the usage gauge (the same drawing as the brain picker's effort icon).
22
+ const ICON_AUTO = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 16a8 8 0 1 1 16 0"/><path d="m12 16 4-5"/></svg>';
23
+ const ICON_NEXT = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 3.5 10.5 8 6 12.5"/></svg>';
24
+ const ICON_BACK = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 3.5 5.5 8l4.5 4.5"/></svg>';
25
+ // As wide as this in a wide panel; a narrow panel gets its own width less the menu's margins.
26
+ const MENU_WIDTH = 340;
27
+
28
+ function tf(t) {
29
+ return (key, fallback, params) => {
30
+ const v = typeof t === 'function' ? t(key, params) : undefined;
31
+ if (v && v !== key && typeof v === 'string') return v;
32
+ return params ? String(fallback).replace(/\{(\w+)\}/g, (_, k) => (params[k] != null ? params[k] : `{${k}}`)) : fallback;
33
+ };
34
+ }
35
+
36
+ /** Who the account is, when that adds to its name: the subscription's email or the key's hint (never the name again). */
37
+ function identityOf(row, name) {
38
+ const raw = row?.mode === 'apiKey' ? (row.apiKey?.hint || row.identity) : (row?.subscription?.email || row?.identity);
39
+ const text = String(raw || '').trim();
40
+ return text && text.toLowerCase() !== String(name || '').trim().toLowerCase() ? text : '';
41
+ }
42
+
43
+ /**
44
+ * One account as the menu shows it: { id, name, initial, badge: { text, tone }, identity,
45
+ * line: { text, tone, title } | null, usable, signedOut }. The badge is what it runs on (the
46
+ * plan, "API key"), or that it is signed out; `line` is its usage, or how to sign it in.
47
+ */
48
+ export function accountMenuRow(row, { provider = 'claude', t = null, now = Date.now(), locale } = {}) {
49
+ const p = provider === 'codex' ? 'codex' : 'claude';
50
+ const name = accountName(row, p) || String(row?.id || '');
51
+ const signedOut = row?.signedIn === false;
52
+ let badge;
53
+ if (!signedOut && row?.mode === 'apiKey') badge = { text: accountText('apiKeyBadge', {}, p), tone: 'muted' };
54
+ else if (!signedOut && row?.mode === 'subscription' && row.signedIn === true) badge = { text: planName(row.subscription?.plan) || accountText('subscriptionShort', {}, p), tone: 'muted' };
55
+ else badge = accountBadge(row, p);
56
+ let line = accountUsageLine(row, t, { now, locale });
57
+ if (signedOut) {
58
+ const text = accountText(row?.apiKey?.error ? 'keyUnreadableLong' : 'signIn', {}, p);
59
+ line = { text, tone: 'muted', title: text };
60
+ }
61
+ return {
62
+ id: row?.id,
63
+ name,
64
+ initial: Array.from(name.trim())[0]?.toLocaleUpperCase() || '?',
65
+ badge: { text: badge.text || '', tone: badge.tone === 'warn' ? 'warn' : 'muted' },
66
+ identity: signedOut ? '' : identityOf(row, name),
67
+ line,
68
+ usable: accountUsable(row),
69
+ signedOut,
70
+ };
71
+ }
72
+
73
+ /** The full words of a row, for its tooltip and its accessible name. */
74
+ function rowWords(r, extra = []) {
75
+ return [r.name, r.identity, r.badge.text, r.line?.title || r.line?.text, ...extra].filter(Boolean).join(' · ');
76
+ }
77
+
78
+ function node(tag, className, text) {
79
+ const n = document.createElement(tag);
80
+ if (className) n.className = className;
81
+ if (text != null) n.textContent = text;
82
+ return n;
83
+ }
84
+ function icon(className, svg) {
85
+ const n = node('span', className);
86
+ n.setAttribute('aria-hidden', 'true');
87
+ n.innerHTML = svg;
88
+ return n;
89
+ }
90
+
91
+ // avatar | name ✓ … badge / identity / usage
92
+ function drawAccount(btn, r, checked) {
93
+ btn.classList.add('asst-acct-item');
94
+ const avatar = node('span', 'asst-acct-avatar', r.initial);
95
+ avatar.setAttribute('aria-hidden', 'true');
96
+ const head = node('span', 'asst-acct-head');
97
+ head.append(node('span', 'asst-acct-name', r.name));
98
+ if (checked) head.append(icon('asst-acct-check', ICON_CHECK));
99
+ if (r.badge.text) { const badge = node('span', 'asst-acct-badge', r.badge.text); badge.dataset.tone = r.badge.tone; head.append(badge); }
100
+ const main = node('span', 'asst-acct-main');
101
+ main.append(head);
102
+ if (r.identity) main.append(node('span', 'asst-acct-line', r.identity));
103
+ if (r.line) { const line = node('span', 'asst-acct-line', r.line.text); line.dataset.tone = r.line.tone; main.append(line); }
104
+ btn.append(avatar, main);
105
+ }
106
+ function drawAuto(btn, label, checked) {
107
+ btn.classList.add('asst-acct-item', 'asst-acct-auto');
108
+ const head = node('span', 'asst-acct-head');
109
+ head.append(node('span', 'asst-acct-name', label));
110
+ if (checked) head.append(icon('asst-acct-check', ICON_CHECK));
111
+ const main = node('span', 'asst-acct-main');
112
+ main.append(head);
113
+ btn.append(icon('asst-acct-avatar', ICON_AUTO), main);
114
+ }
115
+ // label … value ›
116
+ function drawValue(btn, label, value, tone) {
117
+ btn.classList.add('asst-acct-value');
118
+ const text = node('span', 'asst-acct-value-text', value);
119
+ text.dataset.tone = tone;
120
+ btn.append(node('span', 'asst-acct-value-label', label), text, icon('asst-acct-next', ICON_NEXT));
121
+ }
122
+ function drawBack(btn, label) {
123
+ btn.classList.add('asst-acct-back');
124
+ btn.append(icon('asst-acct-next', ICON_BACK), node('span', 'asst-acct-value-label', label));
125
+ }
126
+ function drawChoice(btn, label, checked) {
127
+ btn.classList.add('asst-acct-choice');
128
+ if (checked) btn.append(icon('asst-acct-check', ICON_CHECK));
129
+ btn.append(node('span', '', label));
130
+ }
131
+
132
+ /**
133
+ * The account choices as menu items (this menu and the composer's Model menu): Auto, every account
134
+ * once, and the note that another account starts a new conversation. rows: accountMenuRow()s;
135
+ * onAuto(), onPick(id) (never for the current account), onSignIn(id) (a signed-out account is its sign-in).
136
+ */
137
+ export function accountChoiceItems({ t = null, rows = [], currentId = null, onAuto, onPick, onSignIn } = {}) {
138
+ const tr = tf(t);
139
+ const newConversation = tr('assistant.brain.newConversation', 'starts a new conversation');
140
+ const items = [{
141
+ kind: 'radio', id: 'auto', label: autoAccountLabel(t), selected: currentId === 'auto',
142
+ title: tr('assistant.accountUsage.composerHint', 'Pick the subscription with most usage left and start a new conversation.'),
143
+ render: (btn, { checked }) => drawAuto(btn, autoAccountLabel(t), checked),
144
+ onSelect: () => onAuto?.(),
145
+ }];
146
+ for (const r of rows) {
147
+ const current = r.id === currentId;
148
+ // A signed-out account is listed with its way back in: choosing it opens its sign-in.
149
+ const words = rowWords(r, [!current && !r.signedOut ? newConversation : '']);
150
+ items.push({
151
+ kind: current ? 'radio' : r.signedOut ? 'item' : 'radio', id: r.id, label: r.name, keywords: r.identity,
152
+ selected: current, title: words, ariaLabel: words,
153
+ render: (btn, { checked }) => drawAccount(btn, r, checked),
154
+ onSelect: () => (r.signedOut ? onSignIn?.(r.id) : current ? null : onPick?.(r.id)),
155
+ });
156
+ }
157
+ items.push({ kind: 'info', className: 'asst-acct-note', label: tr('assistant.accountMenu.switchNote', 'Another account starts a new conversation.') });
158
+ return items;
159
+ }
160
+
161
+ /**
162
+ * What an account holding both credentials uses, as one row of two choices ("Work uses Subscription |
163
+ * API key"); null for any other account. Waits while a turn runs. onSetMode(id, mode) for the other one.
164
+ */
165
+ export function accountModeItem({ provider = 'claude', t = null, account = null, running = false, onSetMode } = {}) {
166
+ const p = provider === 'codex' ? 'codex' : 'claude';
167
+ const modes = modeChoices(account, p);
168
+ if (!modes.length) return null;
169
+ const tr = tf(t);
170
+ const newConversation = tr('assistant.brain.newConversation', 'starts a new conversation');
171
+ const name = accountName(account, p);
172
+ return {
173
+ kind: 'buttons', id: 'uses', label: tr('assistant.accountMenu.uses', '{label} uses', { label: name }), ariaLabel: accountText('usesGroup', { label: name }, p),
174
+ buttons: modes.map((m) => {
175
+ const text = accountText(m.mode === 'apiKey' ? 'apiKeyBadge' : 'subscriptionShort', {}, p);
176
+ return {
177
+ kind: 'radio', id: `mode:${m.mode}`, label: text, selected: m.current, disabled: running,
178
+ title: [m.label, m.detail, !m.current ? newConversation : ''].filter(Boolean).join(' · '),
179
+ render: (btn, { checked }) => drawChoice(btn, text, checked),
180
+ onSelect: () => { if (!m.current) onSetMode?.(account.id, m.mode); },
181
+ };
182
+ }),
183
+ };
184
+ }
185
+
186
+ /** Add account… and Manage… side by side. */
187
+ export function accountManageItem({ t = null, onAdd, onManage } = {}) {
188
+ const tr = tf(t);
189
+ return {
190
+ kind: 'buttons', id: 'manage-row',
191
+ buttons: [
192
+ { id: '__add', label: tr('assistant.accounts.add', 'Add account…'), onSelect: () => onAdd?.() },
193
+ { id: '__manage', label: tr('assistant.accounts.manage', 'Manage…'), onSelect: () => onManage?.() },
194
+ ],
195
+ };
196
+ }
197
+
198
+ /**
199
+ * Open the menu from `anchor`. ctx: { provider: 'claude' | 'codex', t, placement, bounds,
200
+ * read() → { accounts, currentId, workerId, running },
201
+ * onAuto(), onPick(id), onSetWorker(id) → Promise, onSetMode(id, mode), onAdd(), onManage(id?), onError(err),
202
+ * now, locale (the clock and language of the reset times; default: now and the page's) }
203
+ * Returns the asst-menu handle (or null).
204
+ */
205
+ export function openAccountMenu(anchor, ctx = {}) {
206
+ const tr = tf(ctx.t);
207
+ const p = ctx.provider === 'codex' ? 'codex' : 'claude';
208
+ const workersTitle = p === 'codex' ? tr('assistant.accounts.codexWorkersHeader', 'Codex workers use') : tr('assistant.accounts.workersHeader', 'Claude Code workers use');
209
+ let view = 'main';
210
+ let busy = false;
211
+ let handle = null;
212
+
213
+ const state = () => {
214
+ const s = ctx.read?.() || {};
215
+ const accounts = Array.isArray(s.accounts) ? s.accounts : [];
216
+ const rows = accounts.map((a) => accountMenuRow(a, { provider: p, t: ctx.t, now: ctx.now, locale: ctx.locale }));
217
+ return { accounts, rows, currentId: s.currentId || null, workerId: s.workerId || 'default', running: s.running === true };
218
+ };
219
+
220
+ function mainItems(s) {
221
+ return accountChoiceItems({ t: ctx.t, rows: s.rows, currentId: s.currentId, onAuto: () => ctx.onAuto?.(), onPick: (id) => ctx.onPick?.(id), onSignIn: (id) => ctx.onManage?.(id) });
222
+ }
223
+
224
+ function mainFooter(s) {
225
+ const footer = [];
226
+ const uses = accountModeItem({ provider: p, t: ctx.t, account: s.accounts.find((a) => a.id === s.currentId), running: s.running, onSetMode: (id, mode) => ctx.onSetMode?.(id, mode) });
227
+ if (uses) footer.push(uses);
228
+ const worker = s.rows.find((r) => r.id === s.workerId);
229
+ const workerName = worker ? worker.name : (s.workerId === 'default' ? accountText('defaultName', {}, p) : s.workerId);
230
+ const workerState = worker?.signedOut ? worker.badge.text : worker?.line?.tone === 'warn' ? tr('assistant.accountUsage.limited', 'Limited') : '';
231
+ const value = [workerName, workerState].filter(Boolean).join(' · ');
232
+ const workersLabel = tr('assistant.accountMenu.workers', 'Workers use');
233
+ footer.push({
234
+ kind: 'item', id: 'workers', label: workersLabel, keywords: workerName, keepOpen: true,
235
+ title: [`${workersTitle}: ${value}`, tr('assistant.accountMenu.workersHint', 'Used when a dispatch names no account.')].join(' · '),
236
+ ariaLabel: `${workersTitle}: ${value}`,
237
+ render: (btn) => drawValue(btn, workersLabel, value, workerState ? 'warn' : 'muted'),
238
+ onSelect: () => showWorkers(),
239
+ });
240
+ footer.push(accountManageItem({ t: ctx.t, onAdd: () => ctx.onAdd?.(), onManage: () => ctx.onManage?.() }));
241
+ return footer;
242
+ }
243
+
244
+ function workerItems(s) {
245
+ const items = [{
246
+ kind: 'item', id: 'back', label: accountText('back', {}, p), keepOpen: true,
247
+ render: (btn) => drawBack(btn, accountText('back', {}, p)),
248
+ onSelect: () => showMain('workers'),
249
+ }];
250
+ for (const r of s.rows) {
251
+ const chosen = r.id === s.workerId;
252
+ const words = rowWords(r);
253
+ items.push({
254
+ kind: 'radio', id: `worker:${r.id}`, label: r.name, keywords: r.identity, selected: chosen,
255
+ disabled: !r.usable && !chosen, keepOpen: true, title: words, ariaLabel: words,
256
+ render: (btn, { checked }) => drawAccount(btn, r, checked),
257
+ onSelect: async () => {
258
+ if (chosen) { showMain('workers'); return; }
259
+ if (busy) return;
260
+ busy = true;
261
+ try { await ctx.onSetWorker?.(r.id); showMain('workers'); }
262
+ catch (err) { ctx.onError?.(err); }
263
+ finally { busy = false; }
264
+ },
265
+ });
266
+ }
267
+ items.push({ kind: 'info', className: 'asst-acct-note', label: tr('assistant.accountMenu.workersHint', 'Used when a dispatch names no account.') });
268
+ return items;
269
+ }
270
+
271
+ function showMain(focus = null) {
272
+ if (view === 'closed') return;
273
+ view = 'main';
274
+ const s = state();
275
+ handle?.update({ title: accountText('menuTitle', {}, p), items: mainItems(s), footer: mainFooter(s), focus });
276
+ }
277
+ function showWorkers() {
278
+ if (view === 'closed') return;
279
+ view = 'workers';
280
+ const s = state();
281
+ handle?.update({ title: workersTitle, items: workerItems(s), footer: [], focus: `worker:${s.workerId}` });
282
+ }
283
+
284
+ const s = state();
285
+ handle = openMenu(anchor, {
286
+ title: accountText('menuTitle', {}, p),
287
+ items: mainItems(s),
288
+ footer: mainFooter(s),
289
+ role: 'menu',
290
+ placement: ctx.placement || 'auto',
291
+ width: MENU_WIDTH,
292
+ bounds: ctx.bounds || null,
293
+ className: 'asst-account-menu',
294
+ onEscape: () => { if (view !== 'workers') return false; showMain('workers'); return true; },
295
+ onClose: () => { view = 'closed'; },
296
+ });
297
+ return handle;
298
+ }