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
@@ -3,6 +3,7 @@
3
3
  // ─────────────────────────────────────────────────────────────────────────────
4
4
 
5
5
  import { isBindingToken } from './ocp-v2-binding.js';
6
+ import { knownDescendant, requestOwner } from './ocp-v2-rehydrate.js';
6
7
 
7
8
  /**
8
9
  * The compose box shows the outgoing prompt at once as a local message. The
@@ -115,3 +116,403 @@ export function settleFailedSend(turn, parked, { item, error = '' } = {}) {
115
116
  const kept = !!(turn.sessionId && item && parked?.park(turn.sessionId, { item, error }));
116
117
  return { here: false, parked: kept };
117
118
  }
119
+
120
+ // ── How long a turn may take ────────────────────────────────────────────────
121
+ // A turn can wait on the user for as long as they take (a permission, a
122
+ // question): the clock that gives up on a turn nobody hears from again counts
123
+ // only the time it works.
124
+
125
+ /** The working time a turn's send waits for its answer (message:send, command:run, an async turn's idle). */
126
+ export const TURN_LIMIT_MS = 30 * 60 * 1000;
127
+
128
+ /**
129
+ * Runs `onExpire` once `ms` of unpaused time went by. `paused()` says whether
130
+ * the turn waits on the user now; `subscribe(fn)` calls `fn` whenever that may
131
+ * have changed and returns an unsubscribe. `cancel()` stops it for good.
132
+ */
133
+ export function createTurnClock({
134
+ ms, paused = () => false, subscribe = () => () => {}, onExpire = () => {},
135
+ now = Date.now, setTimer = setTimeout, clearTimer = clearTimeout,
136
+ } = {}) {
137
+ let left = Math.max(0, Number(ms) || 0);
138
+ let since = 0;
139
+ let timer = null;
140
+ let done = false;
141
+ let unsubscribe = () => {};
142
+ const finish = () => {
143
+ done = true;
144
+ timer = null;
145
+ try { unsubscribe(); } catch { /* gone */ }
146
+ };
147
+ const run = () => {
148
+ if (done || timer) return;
149
+ since = now();
150
+ timer = setTimer(() => { finish(); onExpire(); }, left);
151
+ };
152
+ const hold = () => {
153
+ if (!timer) return;
154
+ clearTimer(timer);
155
+ timer = null;
156
+ left = Math.max(0, left - (now() - since));
157
+ };
158
+ const sync = () => {
159
+ if (done) return;
160
+ if (paused()) hold(); else run();
161
+ };
162
+ unsubscribe = subscribe(sync) || (() => {});
163
+ sync();
164
+ return {
165
+ cancel() {
166
+ if (done) return;
167
+ if (timer) clearTimer(timer);
168
+ finish();
169
+ },
170
+ /** The working time left (ms). */
171
+ left: () => (timer ? Math.max(0, left - (now() - since)) : left),
172
+ };
173
+ }
174
+
175
+ const ASKED = new Set(['permission.asked', 'question.asked']);
176
+ const ANSWERED = new Set(['permission.replied', 'question.replied', 'question.rejected']);
177
+ const askIdOf = (ev) => String(ev?.requestID || ev?.id || ev?.permissionID || '');
178
+ const askKindOf = (eventType) => (String(eventType).startsWith('permission.') ? 'permission' : 'question');
179
+
180
+ /** The two lists a session's open requests are read from (permission:list, question:list). */
181
+ export const ASK_KINDS = Object.freeze(['permission', 'question']);
182
+ /** How often a list is read before the panel gives up on it, the first read included. */
183
+ export const ASK_READ_ATTEMPTS = 3;
184
+ /** The waits before the second and the third read of a list. */
185
+ export const ASK_RETRY_MS = Object.freeze([1000, 4000]);
186
+ const LIST_STATES = new Set(['ok', 'failed', 'unsupported', 'unresolved']);
187
+
188
+ // One event applied to the open requests (request id → { owner, kind, stale }); true when what waits changed.
189
+ function applyAskEvent(open, eventType, ev) {
190
+ if (ASKED.has(eventType)) {
191
+ const id = askIdOf(ev);
192
+ const owner = requestOwner(ev);
193
+ if (!id || !owner) return false;
194
+ const known = open.get(id);
195
+ open.set(id, { owner, kind: askKindOf(eventType), stale: false });
196
+ return known?.owner !== owner;
197
+ }
198
+ if (ANSWERED.has(eventType)) return open.delete(askIdOf(ev));
199
+ if (eventType === 'session.idle' || eventType === 'session.error') {
200
+ const sid = String(ev?.sessionID || ev?.sessionId || '');
201
+ let gone = false;
202
+ for (const [id, entry] of open) if (entry.owner === sid) { open.delete(id); gone = true; }
203
+ return gone;
204
+ }
205
+ return false;
206
+ }
207
+
208
+ /**
209
+ * The requests that wait on the user, by the session that raised them, from
210
+ * the panel's event stream (every session's events reach it): asked by
211
+ * permission.asked / question.asked, gone with their answer, and gone with the
212
+ * turn (session.idle, session.error). `waits(sessionId)` is true while that
213
+ * session, or a sub-agent below it (`parentOf`: child → parent), has one.
214
+ *
215
+ * What the stream cannot tell (what was asked before the page loaded, or while
216
+ * the socket was down) is read from the server, list by list: each session's
217
+ * permissions and its questions (readOpenAsks). `read(want, { attempt, partial })`
218
+ * resolves `{ lists }`, each `{ sessionId, kind, state, requests }`; `want` is
219
+ * null for every session a panel is bound to, else `[{ sessionId, kinds }]`.
220
+ * • A list that was read (state ok, or unresolved: read, but a request in it
221
+ * is of a session whose place could not be established) replaces what was
222
+ * known of its kind for its session and the sub-agents known below it, also
223
+ * when it came back empty. Events that arrived while it was read are applied
224
+ * again on top.
225
+ * • A session whose list failed or is unresolved keeps waiting (no clock of it
226
+ * counts) and has that list read again, ASK_READ_ATTEMPTS times in all. Then,
227
+ * or at once for a list the server cannot give (unsupported), the panel gives
228
+ * up on it: what was known of it from before the outage goes, its clocks
229
+ * count again, and the rebuild resolves `{ gaveUp: [{ sessionId, kinds }] }`
230
+ * so that the panel says so. Nothing could be read at all: `{ unread: true }`.
231
+ * `hold()` (the socket closed): every session counts as waiting until the first
232
+ * read of the `rebuild(read)` that follows, and what was known turns into
233
+ * unconfirmed, to be confirmed or dropped by the lists. A newer `hold()` makes
234
+ * an older rebuild void (it resolves null).
235
+ * `expect(sessionIds)` + `rebuild(read, { sessions })` read only those sessions
236
+ * (a page load, a panel bound to another session): they wait from `expect` until
237
+ * their lists are in, and no other session is held.
238
+ */
239
+ export function createAskTracker({ parentOf = new Map(), attempts = ASK_READ_ATTEMPTS, retryMs = ASK_RETRY_MS, setTimer = setTimeout } = {}) {
240
+ let open = new Map(); // request id → { owner, kind, stale }
241
+ let held = false; // the socket is down, or the first read after it is out: everything waits
242
+ const pending = new Map(); // session → the kinds whose list is still to be read (it waits meanwhile)
243
+ let generation = 0;
244
+ let replay = null; // the events noted while a read is out
245
+ const listeners = new Set();
246
+ const changed = () => {
247
+ for (const fn of [...listeners]) {
248
+ try { fn(); } catch (e) { console.warn('[ocp-v2-send] ask listener failed', e); }
249
+ }
250
+ };
251
+ const under = (owner, root) => owner === root || knownDescendant(owner, root, parentOf);
252
+ const expect = (sessionId, kinds) => {
253
+ let set = pending.get(sessionId);
254
+ if (!set) pending.set(sessionId, (set = new Set()));
255
+ for (const kind of kinds) set.add(kind);
256
+ };
257
+ const settle = (sessionId, kind) => {
258
+ const set = pending.get(sessionId);
259
+ if (!set) return;
260
+ set.delete(kind);
261
+ if (!set.size) pending.delete(sessionId);
262
+ };
263
+ // An entry still to be confirmed by a list that will be read again.
264
+ const awaited = (entry) => {
265
+ for (const [root, kinds] of pending) if (kinds.has(entry.kind) && under(entry.owner, root)) return true;
266
+ return false;
267
+ };
268
+ const sleep = (ms) => new Promise((done) => { setTimer(done, Math.max(0, Number(ms) || 0)); });
269
+ const delayAfter = (attempt) => (Array.isArray(retryMs) ? retryMs[Math.min(attempt, retryMs.length) - 1] : retryMs) || 0;
270
+ const wantedOf = (sessions) => (Array.isArray(sessions)
271
+ ? [...new Set(sessions.map((id) => String(id || '')).filter(Boolean))].map((sessionId) => ({ sessionId, kinds: [...ASK_KINDS] }))
272
+ : null);
273
+
274
+ return {
275
+ note(eventType, ev) {
276
+ replay?.push([eventType, ev]);
277
+ if (applyAskEvent(open, eventType, ev) && !held) changed();
278
+ },
279
+ waits(sessionId) {
280
+ const sid = String(sessionId || '');
281
+ if (!sid) return false;
282
+ if (held) return true;
283
+ for (const [root, kinds] of pending) if (kinds.size && under(sid, root)) return true;
284
+ for (const { owner } of open.values()) if (owner === sid || knownDescendant(owner, sid, parentOf)) return true;
285
+ return false;
286
+ },
287
+ hold() {
288
+ generation += 1;
289
+ replay = null;
290
+ pending.clear();
291
+ for (const entry of open.values()) entry.stale = true;
292
+ if (held) return;
293
+ held = true;
294
+ changed();
295
+ },
296
+ /** These sessions wait from now until their lists are read (rebuild with `sessions`). */
297
+ expect(sessionIds) {
298
+ const wanted = wantedOf(sessionIds) || [];
299
+ for (const { sessionId, kinds } of wanted) expect(sessionId, kinds);
300
+ if (wanted.length && !held) changed();
301
+ },
302
+ /** These sessions wait for no read of their own (their parent's lists hold their requests). */
303
+ release(sessionIds) {
304
+ let gone = false;
305
+ for (const { sessionId } of wantedOf(sessionIds) || []) gone = pending.delete(sessionId) || gone;
306
+ if (gone && !held) changed();
307
+ },
308
+ async rebuild(read, { sessions = null } = {}) {
309
+ const mine = generation;
310
+ const partial = Array.isArray(sessions);
311
+ let want = wantedOf(sessions);
312
+ if (partial) {
313
+ if (!want.length) return { gaveUp: [] };
314
+ for (const { sessionId, kinds } of want) expect(sessionId, kinds);
315
+ }
316
+ const gaveUp = new Map(); // session → kinds given up on
317
+ for (let attempt = 1; ; attempt += 1) {
318
+ replay = [];
319
+ let snapshot = null;
320
+ try { snapshot = await read(want, { attempt, partial }); } catch { snapshot = null; }
321
+ if (mine !== generation) return null;
322
+ const events = replay || [];
323
+ replay = null;
324
+ const last = attempt >= attempts;
325
+ const lists = Array.isArray(snapshot?.lists) ? snapshot.lists : null;
326
+ if (!lists && !want) {
327
+ // Nothing came back, and nothing says which sessions were read.
328
+ if (!last) {
329
+ await sleep(delayAfter(attempt));
330
+ if (mine !== generation) return null;
331
+ continue;
332
+ }
333
+ for (const [id, entry] of open) if (entry.stale) open.delete(id);
334
+ held = false;
335
+ changed();
336
+ return { gaveUp: [], unread: true };
337
+ }
338
+ const results = [];
339
+ for (const list of lists || []) {
340
+ const sessionId = String(list?.sessionId || '');
341
+ if (!sessionId || !ASK_KINDS.includes(list?.kind)) continue;
342
+ results.push({
343
+ sessionId,
344
+ kind: list.kind,
345
+ state: LIST_STATES.has(list.state) ? list.state : 'failed',
346
+ requests: Array.isArray(list.requests) ? list.requests : [],
347
+ });
348
+ }
349
+ for (const { sessionId, kinds } of want || []) {
350
+ for (const kind of kinds) {
351
+ if (results.some((list) => list.sessionId === sessionId && list.kind === kind)) continue;
352
+ // Not in the answer: nothing came back (failed), or no panel is bound to it any more (not asked).
353
+ if (lists) settle(sessionId, kind);
354
+ else results.push({ sessionId, kind, state: 'failed', requests: [] });
355
+ }
356
+ }
357
+ const next = new Map(open);
358
+ for (const list of results) {
359
+ if (list.state !== 'ok' && list.state !== 'unresolved') continue;
360
+ const listed = new Map();
361
+ for (const req of list.requests) {
362
+ const id = askIdOf(req);
363
+ const owner = requestOwner(req);
364
+ if (id && owner) listed.set(id, owner);
365
+ }
366
+ // What the list does not hold is no longer open, for its session and the sub-agents known below it.
367
+ for (const [id, entry] of next) {
368
+ if (entry.kind === list.kind && under(entry.owner, list.sessionId) && !listed.has(id)) next.delete(id);
369
+ }
370
+ for (const [id, owner] of listed) next.set(id, { owner, kind: list.kind, stale: false });
371
+ }
372
+ const again = new Map(); // session → kinds to read again
373
+ for (const list of results) {
374
+ if (list.state === 'ok') { settle(list.sessionId, list.kind); continue; }
375
+ if (list.state === 'unsupported' || last) {
376
+ settle(list.sessionId, list.kind);
377
+ if (!gaveUp.has(list.sessionId)) gaveUp.set(list.sessionId, new Set());
378
+ gaveUp.get(list.sessionId).add(list.kind);
379
+ continue;
380
+ }
381
+ expect(list.sessionId, [list.kind]);
382
+ if (!again.has(list.sessionId)) again.set(list.sessionId, new Set());
383
+ again.get(list.sessionId).add(list.kind);
384
+ }
385
+ for (const [eventType, ev] of events) applyAskEvent(next, eventType, ev);
386
+ // Known from before the outage and confirmed by no list that is still to come: it goes.
387
+ for (const [id, entry] of next) if (entry.stale && !awaited(entry)) next.delete(id);
388
+ open = next;
389
+ if (!partial) held = false;
390
+ changed();
391
+ if (!again.size) {
392
+ return { gaveUp: [...gaveUp].map(([sessionId, kinds]) => ({ sessionId, kinds: ASK_KINDS.filter((kind) => kinds.has(kind)) })) };
393
+ }
394
+ await sleep(delayAfter(attempt));
395
+ if (mine !== generation) return null;
396
+ want = [...again].map(([sessionId, kinds]) => ({ sessionId, kinds: ASK_KINDS.filter((kind) => kinds.has(kind)) }));
397
+ }
398
+ },
399
+ clear() {
400
+ if (!open.size) return;
401
+ open.clear();
402
+ changed();
403
+ },
404
+ subscribe(fn) {
405
+ listeners.add(fn);
406
+ return () => listeners.delete(fn);
407
+ },
408
+ };
409
+ }
410
+
411
+ /**
412
+ * The sentence a panel shows when the open requests of its session could not
413
+ * be read (the tracker gave up on `kinds`): its turn's clock counts again.
414
+ */
415
+ export function unreadAsksNotice(kinds = ASK_KINDS) {
416
+ const set = new Set(Array.isArray(kinds) && kinds.length ? kinds : ASK_KINDS);
417
+ const what = set.has('permission') && set.has('question') ? 'permissions and questions'
418
+ : set.has('permission') ? 'permissions' : 'questions';
419
+ return `Could not read this session's open ${what} from OpenCode: its 30-minute turn limit runs as if none were waiting.`;
420
+ }
421
+
422
+ /**
423
+ * What waits on the user in the sessions panels are bound to, read from the
424
+ * server: for each `{ sessionId, cwd, kinds }` (both kinds unless it says), the
425
+ * open permissions (`api.permissionList`) and questions (`api.questionList`) of
426
+ * the serve that runs that session, with its sub-agents' (they run on the same
427
+ * serve). Each list comes back with its `state`: ok; failed; unsupported (the
428
+ * server has no such request type); or unresolved: read, but it holds a request
429
+ * of a session whose place under this one could not be established.
430
+ * A request of a session that is neither one of these nor known below one has
431
+ * its place read (`ancestry(owner, sessionId)`: true, false, or null when that
432
+ * could not be read; it remembers what it learns), so that a sub-agent spawned
433
+ * while nobody watched holds its parent's clock too: at most `maxLookups`
434
+ * lookups within `lookupMs`, each given only the time that is left (a lookup
435
+ * still waiting on the server then counts as not read). `isDescendant`, a
436
+ * yes / no answer, is accepted in its place.
437
+ * Resolves `{ lists, requests, complete }`: `complete` when every list is ok.
438
+ */
439
+ export async function readOpenAsks(api, sessions, {
440
+ ancestry = null, isDescendant = null, known = () => false,
441
+ maxLookups = 20, lookupMs = 5000, now = Date.now, setTimer = setTimeout, clearTimer = clearTimeout,
442
+ } = {}) {
443
+ const listOf = (res) => {
444
+ const data = res?.data;
445
+ if (Array.isArray(data)) return data;
446
+ if (Array.isArray(data?.questions)) return data.questions;
447
+ if (Array.isArray(data?.data)) return data.data;
448
+ return null;
449
+ };
450
+ const failed = (res) => !res || res.ok === false || res.error != null || (typeof res.status === 'number' && res.status >= 400);
451
+ const readList = async (call) => {
452
+ let res;
453
+ try { res = await call(); } catch { res = null; }
454
+ if (res?.unsupported) return { state: 'unsupported', requests: [] };
455
+ const list = failed(res) ? null : listOf(res);
456
+ if (!list) return { state: 'failed', requests: [] };
457
+ return { state: 'ok', requests: list.filter((req) => askIdOf(req) && requestOwner(req)) };
458
+ };
459
+ const lists = [];
460
+ for (const { sessionId, cwd, kinds } of Array.isArray(sessions) ? sessions : []) {
461
+ if (!sessionId) continue;
462
+ const root = String(sessionId);
463
+ const wanted = ASK_KINDS.filter((kind) => !Array.isArray(kinds) || kinds.includes(kind));
464
+ const read = await Promise.all(wanted.map((kind) => readList(() => (kind === 'permission'
465
+ ? api.permissionList({ sessionId, cwd })
466
+ : api.questionList({ sessionId, cwd })))));
467
+ wanted.forEach((kind, i) => lists.push({ sessionId: root, kind, ...read[i] }));
468
+ }
469
+
470
+ // Sub-agents spawned while nobody watched: their place under a session that was read, a few at most and for
471
+ // a few seconds at most (the clocks stay held meanwhile).
472
+ const lookup = typeof ancestry === 'function' ? ancestry
473
+ : typeof isDescendant === 'function' ? async (owner, root) => (await isDescendant(owner, root)) === true
474
+ : null;
475
+ const roots = [...new Set(lists.map((list) => list.sessionId))];
476
+ const until = now() + lookupMs;
477
+ let lookups = 0;
478
+ const place = async (owner, root) => {
479
+ if (!lookup) return false;
480
+ const left = until - now();
481
+ if (lookups >= maxLookups || left <= 0) return null;
482
+ lookups += 1;
483
+ let timer = null;
484
+ const late = new Promise((done) => { timer = setTimer(() => done(null), left); });
485
+ try {
486
+ const answer = await Promise.race([Promise.resolve().then(() => lookup(owner, root)).catch(() => null), late]);
487
+ return answer === true ? true : answer === false ? false : null;
488
+ } finally {
489
+ clearTimer(timer);
490
+ }
491
+ };
492
+ const unplaced = new Map(); // owner → the sessions whose lists hold a request of it
493
+ for (const list of lists) {
494
+ if (list.state !== 'ok') continue;
495
+ for (const req of list.requests) {
496
+ const owner = requestOwner(req);
497
+ if (roots.includes(owner) || roots.some((root) => known(owner, root))) continue;
498
+ if (!unplaced.has(owner)) unplaced.set(owner, new Set());
499
+ unplaced.get(owner).add(list.sessionId);
500
+ }
501
+ }
502
+ for (const [owner, under] of unplaced) {
503
+ const unknown = [];
504
+ let placed = false;
505
+ for (const root of under) {
506
+ const answer = await place(owner, root);
507
+ if (answer === true) { placed = true; break; }
508
+ if (answer === null) unknown.push(root);
509
+ }
510
+ if (placed) continue;
511
+ for (const list of lists) {
512
+ if (list.state === 'ok' && unknown.includes(list.sessionId) && list.requests.some((req) => requestOwner(req) === owner)) list.state = 'unresolved';
513
+ }
514
+ }
515
+ const requests = new Map();
516
+ for (const list of lists) for (const req of list.requests) requests.set(askIdOf(req), req);
517
+ return { lists, requests: [...requests.values()], complete: lists.every((list) => list.state === 'ok') };
518
+ }
@@ -6,7 +6,7 @@
6
6
  // instance for back-compat with shared bindings.
7
7
  // ─────────────────────────────────────────────────────────────────────────────
8
8
 
9
- import { api, supports, capabilities, onEvent } from './ocp-v2-ws.js';
9
+ import { api, supports, capabilities, onEvent, sessionWaitsOnUser, onAsksChanged } from './ocp-v2-ws.js';
10
10
  import { getDefaultStore, agentForMode } from './ocp-v2-state.js';
11
11
  import { mountModelPicker } from './ocp-v2-modelpicker.js';
12
12
  import { mountVariantPicker } from './ocp-v2-variantpicker.js';
@@ -30,6 +30,7 @@ import {
30
30
  } from './ocp-v2-plan.js';
31
31
  import {
32
32
  trackOptimisticMessage, beginTurn, currentTurn, endTurn, settleFailedSend, TRANSCRIPT_SAFETY_POLL_MS,
33
+ createTurnClock, TURN_LIMIT_MS,
33
34
  } from './ocp-v2-send-logic.js';
34
35
  import { hydrateTranscript } from './ocp-v2-rehydrate.js';
35
36
  import { captureBinding, trackBinding, isBindingToken, searchOnBinding } from './ocp-v2-binding.js';
@@ -1512,7 +1513,7 @@ export function mountCompose(rootEl, store = getDefaultStore(), opts = {}) {
1512
1513
  async function waitForAsyncTurn({ stopPolling, drainOnce, isPlanTurn, planTurn, turn, run }) {
1513
1514
  let done = false;
1514
1515
  let cleanup = null;
1515
- let timer = null;
1516
+ let clock = null;
1516
1517
 
1517
1518
  await new Promise((resolve) => {
1518
1519
  // The composer was unmounted: nobody waits for the end of this turn any
@@ -1521,7 +1522,7 @@ export function mountCompose(rootEl, store = getDefaultStore(), opts = {}) {
1521
1522
  if (done) return;
1522
1523
  done = true;
1523
1524
  _turnWatches.delete(abandon);
1524
- if (timer) clearTimeout(timer);
1525
+ clock?.cancel();
1525
1526
  stopPolling();
1526
1527
  if (unsubInner) unsubInner();
1527
1528
  resolve();
@@ -1530,7 +1531,7 @@ export function mountCompose(rootEl, store = getDefaultStore(), opts = {}) {
1530
1531
  if (done) return;
1531
1532
  done = true;
1532
1533
  _turnWatches.delete(abandon);
1533
- if (timer) clearTimeout(timer);
1534
+ clock?.cancel();
1534
1535
  stopPolling();
1535
1536
  if (unsubInner) unsubInner();
1536
1537
  await drainOnce(true);
@@ -1544,11 +1545,17 @@ export function mountCompose(rootEl, store = getDefaultStore(), opts = {}) {
1544
1545
  const unsubInner = store.subscribe((event, state) => {
1545
1546
  if ((event?.type === 'running:set' && !state.running) || !turn.isCurrent()) cleanup();
1546
1547
  });
1547
- timer = setTimeout(() => {
1548
- if (run.isCurrent()) store.pushError({ message: 'OpenCode turn timed out waiting for session.idle.' });
1549
- endTurn(store, run);
1550
- cleanup();
1551
- }, 30 * 60 * 1000);
1548
+ // Working time only: the clock stops while the session waits on the user (a permission, a question).
1549
+ clock = createTurnClock({
1550
+ ms: TURN_LIMIT_MS,
1551
+ paused: () => sessionWaitsOnUser(turn.sessionId),
1552
+ subscribe: onAsksChanged,
1553
+ onExpire: () => {
1554
+ if (run.isCurrent()) store.pushError({ message: 'OpenCode turn timed out waiting for session.idle.' });
1555
+ endTurn(store, run);
1556
+ cleanup();
1557
+ },
1558
+ });
1552
1559
  _turnWatches.add(abandon);
1553
1560
  if (!store.getState().running) cleanup();
1554
1561
  });
@@ -287,6 +287,66 @@ export function createStoppedShares({ load = () => null, save = () => {}, max =
287
287
  };
288
288
  }
289
289
 
290
+ // ── Tabs that are not on screen ─────────────────────────────────────────────
291
+ // The panel shows one session; its other tabs go on running their turns in
292
+ // OpenCode. What each of them does comes from OpenCode's own run events (every
293
+ // session's reach every window) and from asking it (session:status) after a
294
+ // reload or a reconnect. Their tray pills read it; the session on screen reads
295
+ // its store.
296
+
297
+ /** `{ sessionId, busy }` for an event about a session's run, else null. */
298
+ export function sessionBusyFromEvent(eventType, ev) {
299
+ const sessionId = String(ev?.sessionID || ev?.sessionId || '');
300
+ if (!sessionId) return null;
301
+ if (eventType === 'session.status') {
302
+ const type = ev?.status?.type;
303
+ return { sessionId, busy: type === 'busy' || type === 'retry' };
304
+ }
305
+ if (eventType === 'session.idle' || eventType === 'session.error') return { sessionId, busy: false };
306
+ return null;
307
+ }
308
+
309
+ /** busy (true) / idle (false) from a session:status reply; null when it did not say. */
310
+ export function sessionBusyFromStatus(res) {
311
+ const type = res?.data?.status?.type;
312
+ return typeof type === 'string' && type ? (type === 'busy' || type === 'retry') : null;
313
+ }
314
+
315
+ /**
316
+ * What an automation run's tab shows of its turn: 'working' while a turn runs,
317
+ * 'waiting' while the run waits on the user (a permission, a question: the
318
+ * dispatcher's awaiting_permission; or a turn that ended asking: an idle warm
319
+ * worker whose outcome, the result its turn reported, is needs_input), 'idle'
320
+ * between turns (a warm worker done with its task waits for a follow-up) and
321
+ * null once the run ended (its tab reads the session like any other). A run
322
+ * that reports no turn phase (a classic loop) works for as long as it runs:
323
+ * each iteration starts the next.
324
+ */
325
+ export function automationTurnPhase(run) {
326
+ if (run?.status !== 'starting' && run?.status !== 'running') return null;
327
+ switch (run.turnState) {
328
+ case 'awaiting_permission': case 'needs_input': return 'waiting';
329
+ case 'idle': return (run.outcome || run.lastResult?.status) === 'needs_input' ? 'waiting' : 'idle';
330
+ case 'terminal': return 'idle';
331
+ default: return 'working';
332
+ }
333
+ }
334
+
335
+ /**
336
+ * A tab's tray pill: 'waiting' while its session waits on the user, 'working'
337
+ * while a turn of it runs, else 'idle'. A live automation run's own phase
338
+ * (`automation`, automationTurnPhase) decides: an idle warm worker rests,
339
+ * whatever its run (and the store of the session on screen, which follows the
340
+ * run) says; nobody else can start a turn in it meanwhile (canSend). Otherwise
341
+ * the session on screen reads its store (`running`) and another tab what
342
+ * OpenCode said of it (`busy`).
343
+ */
344
+ export function tabPillState({ sessionId, activeSessionId, running = false, busy = false, automation = null } = {}) {
345
+ if (automation === 'working' || automation === 'waiting' || automation === 'idle') return automation;
346
+ const turn = sessionId && sessionId === activeSessionId ? !!running : !!busy;
347
+ return turn ? 'working' : 'idle';
348
+ }
349
+
290
350
  // ── Deleting a message ──────────────────────────────────────────────────────
291
351
 
292
352
  /** The question before a message is deleted: which one, and that it is final. */