@openchambery/web 2.0.0-beta.3 → 2.0.0-beta.30

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 (292) hide show
  1. package/README.md +14 -0
  2. package/dist/assets/{AgentAvatar-B_JQoreg.js → AgentAvatar-O2x_1cFU.js} +1 -1
  3. package/dist/assets/AssistantView-pBywAsqy.js +3 -0
  4. package/dist/assets/{DiagramView-BNnda8qO.js → DiagramView-B984aE-R.js} +1 -1
  5. package/dist/assets/{FadeInOnReveal-VYQTSAkr.js → FadeInOnReveal-CMBd5BTd.js} +1 -1
  6. package/dist/assets/Icon-BN87CyS4.js +1 -0
  7. package/dist/assets/MarkdownRenderer-DHiNU8n3.js +2 -0
  8. package/dist/assets/{MarkdownRendererImpl-DwrHFGUp.js → MarkdownRendererImpl-xJHMGHju.js} +3 -3
  9. package/dist/assets/MarkstreamRendererImpl-BZflns6x.js +3 -0
  10. package/dist/assets/{MobileDetailNavigation-BXr6AGLT.js → MobileDetailNavigation-DUvxsvrB.js} +1 -1
  11. package/dist/assets/{MobileShareBridge-D7OE9OP_.js → MobileShareBridge-DWo-J3Vc.js} +3 -3
  12. package/dist/assets/MobileSurface-B-Y6U5xm.js +2 -0
  13. package/dist/assets/{MultiRunWindow-DF3iIFCd.js → MultiRunWindow-rYiVSNKK.js} +1 -1
  14. package/dist/assets/{OnboardingScreen-BjHmlwlw.js → OnboardingScreen-BLjZIBOs.js} +1 -1
  15. package/dist/assets/{OverlayScrollbar-DLtWO_Gp.js → OverlayScrollbar-CoZ4wtau.js} +1 -1
  16. package/dist/assets/SettingsView-pjD0LrHE.js +25 -0
  17. package/dist/assets/{SettingsWindow-BI5swspb.js → SettingsWindow-CFOQRwjA.js} +1 -1
  18. package/dist/assets/TerminalView-Dw5jaYkc.js +8 -0
  19. package/dist/assets/{ToolOutputDialog-BEWhBcRd.js → ToolOutputDialog-B4v-ona2.js} +1 -1
  20. package/dist/assets/appThemeRegistry-BqDCGocy.js +1 -0
  21. package/dist/assets/{assistant-attachment-cache-C0aRnFkj.js → assistant-attachment-cache-sG8YQsVs.js} +1 -1
  22. package/dist/assets/{button-DKuz3L8l.js → button-Ck8ipzBm.js} +1 -1
  23. package/dist/assets/collapsible-nU99prkD.js +1 -0
  24. package/dist/assets/context-menu-DMzZN1oi.js +1 -0
  25. package/dist/assets/{desktopHosts-CoDkOnyS.js → desktopHosts-DuftEj8B.js} +1 -1
  26. package/dist/assets/desktopRelayRestore-g378BdZf.js +1 -0
  27. package/dist/assets/{diagram-D7T8HQgj.js → diagram-CvO4P8ds.js} +1 -1
  28. package/dist/assets/dialog-ByGUkS3c.js +1 -0
  29. package/dist/assets/dropdown-menu.styles-ayLWk2gf.js +1 -0
  30. package/dist/assets/es-DCjl24dV.js +15 -0
  31. package/dist/assets/fileMentionTouchSelection-Cgkxwzqb.js +2 -0
  32. package/dist/assets/{fileQueries-JrpcsOCs.js → fileQueries-DuF89nFO.js} +1 -1
  33. package/dist/assets/fr-DfJ5j0t5.js +13 -0
  34. package/dist/assets/{gitApi-CM42qUed.js → gitApi-Dwqkc2nZ.js} +3 -3
  35. package/dist/assets/{imageSource-CIl0FL10.js → imageSource-BpUsiwFd.js} +1 -1
  36. package/dist/assets/{input-CzQy8UhV.js → input-CXhFmHcq.js} +1 -1
  37. package/dist/assets/insertionBoundaries-BhWfAOPY.js +1 -0
  38. package/dist/assets/ja-B_9_w2Xf.js +15 -0
  39. package/dist/assets/ko-DlGbo3kV.js +15 -0
  40. package/dist/assets/main-CGMinhgQ.js +169 -0
  41. package/dist/assets/main-pMpcLJha.js +2 -0
  42. package/dist/assets/{markdownHeightCache-Cj1I5NDw.js → markdownHeightCache-g_UsWzbA.js} +1 -1
  43. package/dist/assets/markdownTheme-DM5h1i18.js +1 -0
  44. package/dist/assets/{mcpQueries-D5mQymgM.js → mcpQueries-DfrW3VHF.js} +1 -1
  45. package/dist/assets/miniChat-YOt30ECc.js +2 -0
  46. package/dist/assets/mobile-BK1bBCYD.js +2 -0
  47. package/dist/assets/multirun-Dua24A69.js +3 -0
  48. package/dist/assets/persistence-Dnj1QOdX.js +3 -0
  49. package/dist/assets/pl-DjUsS8Ei.js +15 -0
  50. package/dist/assets/platform-X3Y3GyM5.js +6 -0
  51. package/dist/assets/projectMeta-DXdoPmbz.js +1 -0
  52. package/dist/assets/pt-BR-B8sV7qo1.js +15 -0
  53. package/dist/assets/{relay-image-stream-DM7atqJs.js → relay-image-stream-D2XooXKZ.js} +1 -1
  54. package/dist/assets/renderElectronMiniChatApp-BOuEz_oT.js +2 -0
  55. package/dist/assets/renderMobileApp-C8Alpv-B.js +28 -0
  56. package/dist/assets/runtime-fetch-CiqQd__Y.js +1 -0
  57. package/dist/assets/runtime-switch-BJM2k_uH.js +1 -0
  58. package/dist/assets/runtimeConfig-DX_NP2Zm.js +2 -0
  59. package/dist/assets/runtimeEndpointReset-BSQU3e5U.js +148 -0
  60. package/dist/assets/runtimeEndpointReset-DsuP5FPT.css +1 -0
  61. package/dist/assets/sessionChangeSummary-8AIBkExf.js +2 -0
  62. package/dist/assets/{sessionLookup-myHe5ltu.js → sessionLookup-Bdwd1Fit.js} +1 -1
  63. package/dist/assets/{sortable-tabs-strip-BQtmHx9r.js → sortable-tabs-strip-T-dk_L69.js} +1 -1
  64. package/dist/assets/src-OzbnJsph.css +2 -0
  65. package/dist/assets/store-Cuktref-.js +15 -0
  66. package/dist/assets/{terminalApi-BxcdiduX.js → terminalApi-C_4joKUG.js} +1 -1
  67. package/dist/assets/textarea-biAqiqnJ.js +1 -0
  68. package/dist/assets/{tooltip-Cx5gTbdY.js → tooltip-BKL7J5hx.js} +1 -1
  69. package/dist/assets/uk-Bh7HXyLp.js +15 -0
  70. package/dist/assets/{url-CDHnjlsm.js → url-DNRMq_0R.js} +1 -1
  71. package/dist/assets/{useAppFontEffects-CNeo0aZs.js → useAppFontEffects-bafOEpgK.js} +57 -52
  72. package/dist/assets/{useAssistantUIStore-asNG6K7n.js → useAssistantUIStore-DBwfg9nX.js} +1 -1
  73. package/dist/assets/useDesktopWindowControlsLayout-CkCVOkxa.js +1 -0
  74. package/dist/assets/{useEffectiveDirectory-B4LvR8Gt.js → useEffectiveDirectory-B7htpJfU.js} +1 -1
  75. package/dist/assets/{useFontPreferences-CUnQ4TVm.js → useFontPreferences-CMrbTA0r.js} +1 -1
  76. package/dist/assets/useMobileNavigationStore-D2tnhKYV.js +415 -0
  77. package/dist/assets/{useRuntimeAPIs-DwLtO0c_.js → useRuntimeAPIs-DSLXJybW.js} +1 -1
  78. package/dist/assets/useSessionAutoCleanup-BC5OOH3M.js +2 -0
  79. package/dist/assets/{useThemeSystem-BlNUWH47.js → useThemeSystem-DMzWVJaW.js} +1 -1
  80. package/dist/assets/useUIStore-Dfx6TKvi.js +1 -0
  81. package/dist/assets/{useWorkerHighlightedLines-CJZbJDW3.js → useWorkerHighlightedLines-BNQUAMEB.js} +1 -1
  82. package/dist/assets/{vendor-base-ui-CDjyofeD.js → vendor-base-ui-CnHfUmDN.js} +1 -1
  83. package/dist/assets/{vendor-cmdk-BFH0UpXX.js → vendor-cmdk-CeAGfrLo.js} +1 -1
  84. package/dist/assets/{vendor-dnd-kit-accessibility-BrR3AKvM.js → vendor-dnd-kit-accessibility-BY5LhhUB.js} +1 -1
  85. package/dist/assets/{vendor-dnd-kit-core-CNfdvk6H.js → vendor-dnd-kit-core-CvWxUPdb.js} +1 -1
  86. package/dist/assets/{vendor-dnd-kit-sortable-DQUaTeGj.js → vendor-dnd-kit-sortable-hHdP9lLb.js} +1 -1
  87. package/dist/assets/{vendor-framer-motion-4dogsUk3.js → vendor-framer-motion-DFy_BSVd.js} +1 -1
  88. package/dist/assets/{vendor-legendapp-list-BU7MdPZR.js → vendor-legendapp-list-WE32lwNk.js} +1 -1
  89. package/dist/assets/{vendor-markstream-react-qHC2FykU.js → vendor-markstream-react-DX55XLGO.js} +3 -3
  90. package/dist/assets/vendor-opencode-client-MF2GBrFx.js +12 -0
  91. package/dist/assets/{vendor-pierre-diffs-CUfqC003.js → vendor-pierre-diffs-DX7XTPG3.js} +1 -1
  92. package/dist/assets/{vendor-react-C94A0AHl.js → vendor-react-DLPElpoQ.js} +1 -1
  93. package/dist/assets/{vendor-react-drawio-FVlWqKVE.js → vendor-react-drawio-ECtEwvbc.js} +1 -1
  94. package/dist/assets/{vendor-reactuses-core-C2A3EjUi.js → vendor-reactuses-core-Dq5ocTF8.js} +1 -1
  95. package/dist/assets/{vendor-sonner-DNqHmUQs.js → vendor-sonner-DVzioF3d.js} +1 -1
  96. package/dist/assets/{vendor-stream-diffs-CwbKsmlv.js → vendor-stream-diffs-DWy3xSmp.js} +2 -2
  97. package/dist/assets/{vendor-tanstack-react-query-D0iFK57C.js → vendor-tanstack-react-query-D7pys_c9.js} +1 -1
  98. package/dist/assets/{vendor-tanstack-react-virtual-B2kV6cnT.js → vendor-tanstack-react-virtual-tlDgH6PG.js} +1 -1
  99. package/dist/assets/{vendor-zustand-BqLKf6ZY.js → vendor-zustand-DzRqcymP.js} +2 -2
  100. package/dist/assets/zh-CN-Uzia0gk4.js +15 -0
  101. package/dist/assets/zh-TW-CiI7DLdB.js +15 -0
  102. package/dist/index.html +15 -15
  103. package/dist/mini-chat.html +15 -15
  104. package/dist/mobile.html +15 -15
  105. package/package.json +3 -2
  106. package/server/index.js +46 -27
  107. package/server/lib/browser-provider/DOCUMENTATION.md +141 -0
  108. package/server/lib/browser-provider/contract.js +312 -0
  109. package/server/lib/browser-provider/host.js +421 -0
  110. package/server/lib/browser-provider/host.test.js +304 -0
  111. package/server/lib/browser-provider/routes.js +122 -0
  112. package/server/lib/browser-provider/routes.test.js +120 -0
  113. package/server/lib/browser-provider/selection-store.js +43 -0
  114. package/server/lib/browser-provider/selection-store.test.js +35 -0
  115. package/server/lib/event-stream/DOCUMENTATION.md +3 -1
  116. package/server/lib/event-stream/reasoning-projection.js +16 -1
  117. package/server/lib/event-stream/reasoning-projection.test.js +15 -0
  118. package/server/lib/git/DOCUMENTATION.md +1 -0
  119. package/server/lib/git/routes.js +7 -4
  120. package/server/lib/git/routes.test.js +34 -0
  121. package/server/lib/git/service.js +3 -1
  122. package/server/lib/llm/DOCUMENTATION.md +6 -4
  123. package/server/lib/llm/generate.js +8 -9
  124. package/server/lib/llm/generate.test.js +33 -6
  125. package/server/lib/message-queue/service.js +1 -1
  126. package/server/lib/notifications/DOCUMENTATION.md +3 -1
  127. package/server/lib/notifications/runtime.js +128 -31
  128. package/server/lib/notifications/runtime.test.js +103 -0
  129. package/server/lib/notifications/template-runtime.js +130 -38
  130. package/server/lib/notifications/template-runtime.test.js +96 -0
  131. package/server/lib/opencode/DOCUMENTATION.md +36 -19
  132. package/server/lib/opencode/agents.js +13 -22
  133. package/server/lib/opencode/auth-state-runtime.js +3 -3
  134. package/server/lib/opencode/auth-state-runtime.test.js +59 -0
  135. package/server/lib/opencode/auth.d.ts +13 -0
  136. package/server/lib/opencode/auth.js +74 -64
  137. package/server/lib/opencode/auth.test.js +57 -0
  138. package/server/lib/opencode/commands.js +1 -1
  139. package/server/lib/opencode/config-entities-layering.test.js +72 -0
  140. package/server/lib/opencode/config-entity-routes.js +16 -124
  141. package/server/lib/opencode/config-entity-routes.test.js +48 -11
  142. package/server/lib/opencode/config-files.d.ts +17 -0
  143. package/server/lib/opencode/config-files.js +187 -0
  144. package/server/lib/opencode/config-files.test.js +201 -0
  145. package/server/lib/opencode/core-routes.js +0 -1
  146. package/server/lib/opencode/core-routes.test.js +0 -15
  147. package/server/lib/opencode/credential-boundary.d.ts +1 -0
  148. package/server/lib/opencode/credential-boundary.js +11 -0
  149. package/server/lib/opencode/ensure-cli.d.ts +8 -0
  150. package/server/lib/opencode/ensure-cli.js +4 -1
  151. package/server/lib/opencode/env-config.js +4 -1
  152. package/server/lib/opencode/env-config.test.js +28 -0
  153. package/server/lib/opencode/env-runtime.test.js +18 -1
  154. package/server/lib/opencode/feature-routes-runtime.js +19 -7
  155. package/server/lib/opencode/feature-routes-runtime.test.js +7 -0
  156. package/server/lib/opencode/hmr-state-runtime.js +4 -4
  157. package/server/lib/opencode/lifecycle.js +1 -49
  158. package/server/lib/opencode/lifecycle.test.js +30 -4
  159. package/server/lib/opencode/location-release.d.ts +8 -0
  160. package/server/lib/opencode/location-release.js +32 -0
  161. package/server/lib/opencode/location-release.test.js +43 -0
  162. package/server/lib/opencode/mcp.js +1 -1
  163. package/server/lib/opencode/opencode2-pin.js +2 -1
  164. package/server/lib/opencode/owned-runtime-upgrade.test.js +5 -5
  165. package/server/lib/opencode/plugin-routes.test.js +4 -2
  166. package/server/lib/opencode/plugins.js +12 -60
  167. package/server/lib/opencode/plugins.test.js +5 -3
  168. package/server/lib/opencode/providers.js +6 -3
  169. package/server/lib/opencode/proxy.js +13 -1
  170. package/server/lib/opencode/proxy.test.js +31 -3
  171. package/server/lib/opencode/remote-upgrade.integration.test.js +66 -0
  172. package/server/lib/opencode/routes.js +40 -8
  173. package/server/lib/opencode/routes.test.js +51 -10
  174. package/server/lib/opencode/runtime-contract.js +3 -2
  175. package/server/lib/opencode/runtime-contract.test.js +12 -12
  176. package/server/lib/opencode/shared.js +6 -175
  177. package/server/lib/opencode/update-discovery.js +39 -0
  178. package/server/lib/opencode/update-discovery.test.js +39 -0
  179. package/server/lib/opencode/upgrade-screen.d.ts +30 -0
  180. package/server/lib/opencode/upgrade-screen.js +292 -0
  181. package/server/lib/opencode/upgrade-screen.test.js +196 -0
  182. package/server/lib/opencode/version-alignment.test.js +40 -0
  183. package/server/lib/question-auto-delegate/DOCUMENTATION.md +21 -6
  184. package/server/lib/question-auto-delegate/core.d.ts +5 -1
  185. package/server/lib/question-auto-delegate/core.js +21 -13
  186. package/server/lib/question-auto-delegate/form-io.d.ts +6 -0
  187. package/server/lib/question-auto-delegate/form-io.js +39 -0
  188. package/server/lib/question-auto-delegate/runtime.js +4 -24
  189. package/server/lib/question-auto-delegate/runtime.test.js +138 -0
  190. package/server/lib/quota/DOCUMENTATION.md +9 -0
  191. package/server/lib/quota/provider-credentials.test.js +29 -0
  192. package/server/lib/quota/providers/claude.js +4 -4
  193. package/server/lib/quota/providers/codex.js +4 -4
  194. package/server/lib/quota/providers/codex.test.js +1 -1
  195. package/server/lib/quota/providers/copilot.js +5 -5
  196. package/server/lib/quota/providers/google/auth.js +3 -3
  197. package/server/lib/quota/providers/google/index.js +2 -2
  198. package/server/lib/quota/providers/index.js +3 -7
  199. package/server/lib/quota/providers/index.test.js +2 -2
  200. package/server/lib/quota/providers/kimi.js +4 -4
  201. package/server/lib/quota/providers/minimax-shared.js +4 -4
  202. package/server/lib/quota/providers/nanogpt.js +4 -4
  203. package/server/lib/quota/providers/openai.js +4 -4
  204. package/server/lib/quota/providers/openrouter.js +4 -4
  205. package/server/lib/quota/providers/wafer.js +4 -4
  206. package/server/lib/quota/providers/zai.js +4 -4
  207. package/server/lib/quota/providers/zhipuai-coding-plan.js +6 -20
  208. package/server/lib/quota/routes.js +1 -1
  209. package/server/lib/relay/DOCUMENTATION.md +3 -1
  210. package/server/lib/relay/service.js +1 -0
  211. package/server/lib/relay/service.test.js +13 -0
  212. package/server/lib/scheduled-tasks/DOCUMENTATION.md +8 -1
  213. package/server/lib/scheduled-tasks/runtime.js +12 -4
  214. package/server/lib/scheduled-tasks/runtime.test.js +81 -6
  215. package/server/lib/session-goal/DOCUMENTATION.md +11 -0
  216. package/server/lib/session-goal/runtime.js +4 -4
  217. package/server/lib/session-goal/runtime.test.js +32 -3
  218. package/server/lib/session-index/DOCUMENTATION.md +7 -0
  219. package/server/lib/session-index/event-ingest.js +13 -0
  220. package/server/lib/session-index/event-ingest.test.js +7 -0
  221. package/server/lib/session-index/service.js +45 -0
  222. package/server/lib/session-index/service.test.js +47 -0
  223. package/server/lib/session-metadata/DOCUMENTATION.md +33 -17
  224. package/server/lib/session-metadata/opencode-session-record.d.ts +57 -0
  225. package/server/lib/session-metadata/opencode-session-record.js +316 -0
  226. package/server/lib/session-metadata/opencode-session-record.test.js +242 -0
  227. package/server/lib/session-metadata/routes.js +5 -1
  228. package/server/lib/session-metadata/session-archive.js +1 -1
  229. package/server/lib/session-metadata/session-metadata-store.d.ts +2 -0
  230. package/server/lib/session-metadata/session-metadata-store.js +63 -16
  231. package/server/lib/session-metadata/session-metadata-store.test.js +23 -0
  232. package/server/lib/session-metadata/session-projection.d.ts +1 -0
  233. package/server/lib/session-metadata/session-projection.js +49 -2
  234. package/server/lib/session-metadata/session-projection.test.js +35 -0
  235. package/server/lib/session-title/DOCUMENTATION.md +52 -14
  236. package/server/lib/session-title/native-runtime.test.js +59 -5
  237. package/server/lib/session-title/runtime.js +65 -19
  238. package/server/lib/session-title/session-access.js +108 -3
  239. package/server/lib/session-title/session-access.test.js +125 -7
  240. package/server/lib/tts/DOCUMENTATION.md +7 -5
  241. package/server/lib/tts/credential-source.test.js +23 -0
  242. package/server/lib/tts/routes.js +2 -2
  243. package/server/lib/tts/service.js +16 -37
  244. package/dist/assets/AssistantView-ClQAfGOT.js +0 -3
  245. package/dist/assets/Icon-BiEQEcih.js +0 -1
  246. package/dist/assets/MarkdownRenderer-CJHSsWin.js +0 -2
  247. package/dist/assets/MarkstreamRendererImpl-CSnbQMu3.js +0 -3
  248. package/dist/assets/MobileSurface-D2jUkX9l.js +0 -2
  249. package/dist/assets/SettingsView-BRxELjow.js +0 -25
  250. package/dist/assets/TerminalView-BU3x8-fr.js +0 -8
  251. package/dist/assets/appThemeRegistry-4MR0F7Jz.js +0 -1
  252. package/dist/assets/collapsible-DXbDynN4.js +0 -3
  253. package/dist/assets/context-menu-CqolsLCm.js +0 -1
  254. package/dist/assets/desktopRelayRestore-DDlVKyOE.js +0 -1
  255. package/dist/assets/dialog-DQYl3W_o.js +0 -1
  256. package/dist/assets/dropdown-menu.styles-Bzo6L3FH.js +0 -1
  257. package/dist/assets/es-CN3E_zXj.js +0 -15
  258. package/dist/assets/fileMentionTouchSelection-BZ6ovBYH.js +0 -4
  259. package/dist/assets/fr-9zZvQZD2.js +0 -13
  260. package/dist/assets/insertionBoundaries-CtkZ9720.js +0 -1
  261. package/dist/assets/ja-Dnjk_82N.js +0 -15
  262. package/dist/assets/ko-BxCEE99C.js +0 -15
  263. package/dist/assets/main-BILgBI3B.js +0 -169
  264. package/dist/assets/main-BeveiW6F.js +0 -2
  265. package/dist/assets/markdownTheme-CKac3wKC.js +0 -1
  266. package/dist/assets/miniChat-BgrzM3u7.js +0 -2
  267. package/dist/assets/mobile-DtYoQE8C.js +0 -2
  268. package/dist/assets/multirun-jy8dEI96.js +0 -4
  269. package/dist/assets/persistence-C9LQpiOS.js +0 -3
  270. package/dist/assets/pl-CNNsWnPM.js +0 -15
  271. package/dist/assets/platform-BQghHRfp.js +0 -6
  272. package/dist/assets/pt-BR-BZB2DJMp.js +0 -15
  273. package/dist/assets/renderElectronMiniChatApp-BGrrmeME.js +0 -2
  274. package/dist/assets/renderMobileApp-u3c4GtFC.js +0 -28
  275. package/dist/assets/runtime-fetch-zIalUnbb.js +0 -1
  276. package/dist/assets/runtime-switch-LvWDU-SL.js +0 -1
  277. package/dist/assets/runtimeConfig-BIGBRGQI.js +0 -2
  278. package/dist/assets/runtimeEndpointReset-D2savkuw.js +0 -147
  279. package/dist/assets/sessionChangeSummary-eIbpSfrO.js +0 -2
  280. package/dist/assets/src-CLN7Z-zx.css +0 -2
  281. package/dist/assets/store-DLCiZaA6.js +0 -15
  282. package/dist/assets/textarea-CakKvqFw.js +0 -1
  283. package/dist/assets/uk-rwQrxeYM.js +0 -15
  284. package/dist/assets/useDesktopWindowControlsLayout-DBJ56qIo.js +0 -1
  285. package/dist/assets/useMobileNavigationStore-ZHJPxlHt.js +0 -414
  286. package/dist/assets/useSessionAutoCleanup-BIVmrnYU.js +0 -2
  287. package/dist/assets/useUIStore-CQYKJnrg.js +0 -1
  288. package/dist/assets/vendor-opencode-client-BOe2qpQb.js +0 -12
  289. package/dist/assets/zh-CN-BvmBDnkD.js +0 -15
  290. package/dist/assets/zh-TW-9wcHTX0y.js +0 -15
  291. package/server/lib/opencode/snippets.js +0 -242
  292. package/server/lib/opencode/snippets.test.js +0 -97
package/dist/index.html CHANGED
@@ -552,28 +552,28 @@
552
552
  opacity: 0.72;
553
553
  }
554
554
  </style>
555
- <script type="module" crossorigin src="/assets/main-BeveiW6F.js"></script>
555
+ <script type="module" crossorigin src="/assets/main-pMpcLJha.js"></script>
556
556
  <link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-C0FnF6B9.js">
557
557
  <link rel="modulepreload" crossorigin href="/assets/runtime-auth-D66yq6ie.js">
558
- <link rel="modulepreload" crossorigin href="/assets/runtime-switch-LvWDU-SL.js">
559
- <link rel="modulepreload" crossorigin href="/assets/runtime-fetch-zIalUnbb.js">
560
- <link rel="modulepreload" crossorigin href="/assets/vendor-base-ui-CDjyofeD.js">
561
- <link rel="modulepreload" crossorigin href="/assets/vendor-zustand-BqLKf6ZY.js">
562
- <link rel="modulepreload" crossorigin href="/assets/useUIStore-CQYKJnrg.js">
563
- <link rel="modulepreload" crossorigin href="/assets/vendor-react-C94A0AHl.js">
558
+ <link rel="modulepreload" crossorigin href="/assets/runtime-switch-BJM2k_uH.js">
559
+ <link rel="modulepreload" crossorigin href="/assets/runtime-fetch-CiqQd__Y.js">
560
+ <link rel="modulepreload" crossorigin href="/assets/vendor-base-ui-CnHfUmDN.js">
561
+ <link rel="modulepreload" crossorigin href="/assets/vendor-zustand-DzRqcymP.js">
562
+ <link rel="modulepreload" crossorigin href="/assets/useUIStore-Dfx6TKvi.js">
563
+ <link rel="modulepreload" crossorigin href="/assets/vendor-react-DLPElpoQ.js">
564
564
  <link rel="modulepreload" crossorigin href="/assets/vendor-pathe-vBmvQE8f.js">
565
565
  <link rel="modulepreload" crossorigin href="/assets/vendor-tanstack-query-core-BWz0ose6.js">
566
- <link rel="modulepreload" crossorigin href="/assets/persistence-C9LQpiOS.js">
567
- <link rel="modulepreload" crossorigin href="/assets/desktopHosts-CoDkOnyS.js">
568
- <link rel="modulepreload" crossorigin href="/assets/desktopRelayRestore-DDlVKyOE.js">
569
- <link rel="modulepreload" crossorigin href="/assets/vendor-opencode-client-BOe2qpQb.js">
566
+ <link rel="modulepreload" crossorigin href="/assets/persistence-Dnj1QOdX.js">
567
+ <link rel="modulepreload" crossorigin href="/assets/desktopHosts-DuftEj8B.js">
568
+ <link rel="modulepreload" crossorigin href="/assets/desktopRelayRestore-g378BdZf.js">
569
+ <link rel="modulepreload" crossorigin href="/assets/vendor-opencode-client-MF2GBrFx.js">
570
570
  <link rel="modulepreload" crossorigin href="/assets/vendor-aparajita-capacitor-secure-storage-CjQdwfjS.js">
571
- <link rel="modulepreload" crossorigin href="/assets/platform-BQghHRfp.js">
572
- <link rel="modulepreload" crossorigin href="/assets/terminalApi-BxcdiduX.js">
571
+ <link rel="modulepreload" crossorigin href="/assets/platform-X3Y3GyM5.js">
572
+ <link rel="modulepreload" crossorigin href="/assets/terminalApi-C_4joKUG.js">
573
573
  <link rel="modulepreload" crossorigin href="/assets/types-BuiqMmh_.js">
574
574
  <link rel="modulepreload" crossorigin href="/assets/capgoAdapter-DCowZ2ab.js">
575
- <link rel="modulepreload" crossorigin href="/assets/runtimeConfig-BIGBRGQI.js">
576
- <link rel="stylesheet" crossorigin href="/assets/src-CLN7Z-zx.css">
575
+ <link rel="modulepreload" crossorigin href="/assets/runtimeConfig-DX_NP2Zm.js">
576
+ <link rel="stylesheet" crossorigin href="/assets/src-OzbnJsph.css">
577
577
  </head>
578
578
  <body class="h-full bg-background text-foreground">
579
579
  <!-- Keep the startup layer outside #root. React replaces every child of
@@ -74,28 +74,28 @@
74
74
  }
75
75
  </style>
76
76
 
77
- <script type="module" crossorigin src="/assets/miniChat-BgrzM3u7.js"></script>
77
+ <script type="module" crossorigin src="/assets/miniChat-YOt30ECc.js"></script>
78
78
  <link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-C0FnF6B9.js">
79
79
  <link rel="modulepreload" crossorigin href="/assets/runtime-auth-D66yq6ie.js">
80
- <link rel="modulepreload" crossorigin href="/assets/runtime-switch-LvWDU-SL.js">
81
- <link rel="modulepreload" crossorigin href="/assets/runtime-fetch-zIalUnbb.js">
82
- <link rel="modulepreload" crossorigin href="/assets/vendor-base-ui-CDjyofeD.js">
83
- <link rel="modulepreload" crossorigin href="/assets/vendor-zustand-BqLKf6ZY.js">
84
- <link rel="modulepreload" crossorigin href="/assets/useUIStore-CQYKJnrg.js">
85
- <link rel="modulepreload" crossorigin href="/assets/vendor-react-C94A0AHl.js">
80
+ <link rel="modulepreload" crossorigin href="/assets/runtime-switch-BJM2k_uH.js">
81
+ <link rel="modulepreload" crossorigin href="/assets/runtime-fetch-CiqQd__Y.js">
82
+ <link rel="modulepreload" crossorigin href="/assets/vendor-base-ui-CnHfUmDN.js">
83
+ <link rel="modulepreload" crossorigin href="/assets/vendor-zustand-DzRqcymP.js">
84
+ <link rel="modulepreload" crossorigin href="/assets/useUIStore-Dfx6TKvi.js">
85
+ <link rel="modulepreload" crossorigin href="/assets/vendor-react-DLPElpoQ.js">
86
86
  <link rel="modulepreload" crossorigin href="/assets/vendor-pathe-vBmvQE8f.js">
87
87
  <link rel="modulepreload" crossorigin href="/assets/vendor-tanstack-query-core-BWz0ose6.js">
88
- <link rel="modulepreload" crossorigin href="/assets/persistence-C9LQpiOS.js">
89
- <link rel="modulepreload" crossorigin href="/assets/desktopHosts-CoDkOnyS.js">
90
- <link rel="modulepreload" crossorigin href="/assets/desktopRelayRestore-DDlVKyOE.js">
91
- <link rel="modulepreload" crossorigin href="/assets/vendor-opencode-client-BOe2qpQb.js">
88
+ <link rel="modulepreload" crossorigin href="/assets/persistence-Dnj1QOdX.js">
89
+ <link rel="modulepreload" crossorigin href="/assets/desktopHosts-DuftEj8B.js">
90
+ <link rel="modulepreload" crossorigin href="/assets/desktopRelayRestore-g378BdZf.js">
91
+ <link rel="modulepreload" crossorigin href="/assets/vendor-opencode-client-MF2GBrFx.js">
92
92
  <link rel="modulepreload" crossorigin href="/assets/vendor-aparajita-capacitor-secure-storage-CjQdwfjS.js">
93
- <link rel="modulepreload" crossorigin href="/assets/platform-BQghHRfp.js">
94
- <link rel="modulepreload" crossorigin href="/assets/terminalApi-BxcdiduX.js">
93
+ <link rel="modulepreload" crossorigin href="/assets/platform-X3Y3GyM5.js">
94
+ <link rel="modulepreload" crossorigin href="/assets/terminalApi-C_4joKUG.js">
95
95
  <link rel="modulepreload" crossorigin href="/assets/types-BuiqMmh_.js">
96
96
  <link rel="modulepreload" crossorigin href="/assets/capgoAdapter-DCowZ2ab.js">
97
- <link rel="modulepreload" crossorigin href="/assets/runtimeConfig-BIGBRGQI.js">
98
- <link rel="stylesheet" crossorigin href="/assets/src-CLN7Z-zx.css">
97
+ <link rel="modulepreload" crossorigin href="/assets/runtimeConfig-DX_NP2Zm.js">
98
+ <link rel="stylesheet" crossorigin href="/assets/src-OzbnJsph.css">
99
99
  </head>
100
100
  <body class="h-full bg-background text-foreground">
101
101
  <div id="root" class="h-full">
package/dist/mobile.html CHANGED
@@ -63,28 +63,28 @@
63
63
  })();
64
64
  </script>
65
65
 
66
- <script type="module" crossorigin src="/assets/mobile-DtYoQE8C.js"></script>
66
+ <script type="module" crossorigin src="/assets/mobile-BK1bBCYD.js"></script>
67
67
  <link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-C0FnF6B9.js">
68
68
  <link rel="modulepreload" crossorigin href="/assets/runtime-auth-D66yq6ie.js">
69
- <link rel="modulepreload" crossorigin href="/assets/runtime-switch-LvWDU-SL.js">
70
- <link rel="modulepreload" crossorigin href="/assets/runtime-fetch-zIalUnbb.js">
71
- <link rel="modulepreload" crossorigin href="/assets/vendor-base-ui-CDjyofeD.js">
72
- <link rel="modulepreload" crossorigin href="/assets/vendor-zustand-BqLKf6ZY.js">
73
- <link rel="modulepreload" crossorigin href="/assets/useUIStore-CQYKJnrg.js">
74
- <link rel="modulepreload" crossorigin href="/assets/vendor-react-C94A0AHl.js">
69
+ <link rel="modulepreload" crossorigin href="/assets/runtime-switch-BJM2k_uH.js">
70
+ <link rel="modulepreload" crossorigin href="/assets/runtime-fetch-CiqQd__Y.js">
71
+ <link rel="modulepreload" crossorigin href="/assets/vendor-base-ui-CnHfUmDN.js">
72
+ <link rel="modulepreload" crossorigin href="/assets/vendor-zustand-DzRqcymP.js">
73
+ <link rel="modulepreload" crossorigin href="/assets/useUIStore-Dfx6TKvi.js">
74
+ <link rel="modulepreload" crossorigin href="/assets/vendor-react-DLPElpoQ.js">
75
75
  <link rel="modulepreload" crossorigin href="/assets/vendor-pathe-vBmvQE8f.js">
76
76
  <link rel="modulepreload" crossorigin href="/assets/vendor-tanstack-query-core-BWz0ose6.js">
77
- <link rel="modulepreload" crossorigin href="/assets/persistence-C9LQpiOS.js">
78
- <link rel="modulepreload" crossorigin href="/assets/desktopHosts-CoDkOnyS.js">
79
- <link rel="modulepreload" crossorigin href="/assets/desktopRelayRestore-DDlVKyOE.js">
80
- <link rel="modulepreload" crossorigin href="/assets/vendor-opencode-client-BOe2qpQb.js">
77
+ <link rel="modulepreload" crossorigin href="/assets/persistence-Dnj1QOdX.js">
78
+ <link rel="modulepreload" crossorigin href="/assets/desktopHosts-DuftEj8B.js">
79
+ <link rel="modulepreload" crossorigin href="/assets/desktopRelayRestore-g378BdZf.js">
80
+ <link rel="modulepreload" crossorigin href="/assets/vendor-opencode-client-MF2GBrFx.js">
81
81
  <link rel="modulepreload" crossorigin href="/assets/vendor-aparajita-capacitor-secure-storage-CjQdwfjS.js">
82
- <link rel="modulepreload" crossorigin href="/assets/platform-BQghHRfp.js">
83
- <link rel="modulepreload" crossorigin href="/assets/terminalApi-BxcdiduX.js">
82
+ <link rel="modulepreload" crossorigin href="/assets/platform-X3Y3GyM5.js">
83
+ <link rel="modulepreload" crossorigin href="/assets/terminalApi-C_4joKUG.js">
84
84
  <link rel="modulepreload" crossorigin href="/assets/types-BuiqMmh_.js">
85
85
  <link rel="modulepreload" crossorigin href="/assets/capgoAdapter-DCowZ2ab.js">
86
- <link rel="modulepreload" crossorigin href="/assets/runtimeConfig-BIGBRGQI.js">
87
- <link rel="stylesheet" crossorigin href="/assets/src-CLN7Z-zx.css">
86
+ <link rel="modulepreload" crossorigin href="/assets/runtimeConfig-DX_NP2Zm.js">
87
+ <link rel="stylesheet" crossorigin href="/assets/src-OzbnJsph.css">
88
88
  </head>
89
89
  <body class="h-full bg-background text-foreground">
90
90
  <div id="root" class="h-full"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openchambery/web",
3
- "version": "2.0.0-beta.3",
3
+ "version": "2.0.0-beta.30",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./server/index.js",
@@ -27,7 +27,8 @@
27
27
  "@clack/prompts": "^1.1.0",
28
28
  "@earendil-works/pi-agent-core": "0.84.4",
29
29
  "@octokit/rest": "^22.0.1",
30
- "@opencode/client": "2.0.12",
30
+ "@opencode/client": "2.0.23",
31
+ "@opencode/schema": "2.0.23",
31
32
  "@simplewebauthn/server": "13.3.1",
32
33
  "adm-zip": "^0.5.16",
33
34
  "better-sqlite3": "^12.10.0",
package/server/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import 'reflect-metadata';
2
2
  import express from 'express';
3
+ import { configureOpenCodeCredentials, openCodeCredentialSource } from './lib/opencode/auth.js';
3
4
  import compression from 'compression';
4
5
  import path from 'path';
5
6
  import { spawn, spawnSync } from 'child_process';
@@ -56,6 +57,7 @@ import { createServerUtilsRuntime } from './lib/opencode/server-utils-runtime.js
56
57
  import {
57
58
  configureServerOpenCodeFetchGate,
58
59
  createServerOpenCodeFetch,
60
+ wrapFetchWithRuntimeContractGate,
59
61
  } from './lib/opencode/server-opencode-fetch.js';
60
62
  import { createStaticRoutesRuntime } from './lib/opencode/static-routes-runtime.js';
61
63
  import { createSettingsRuntime } from './lib/opencode/settings-runtime.js';
@@ -79,13 +81,17 @@ import {
79
81
  withGoalExecutionGeneration,
80
82
  } from './lib/session-goal/runtime.js';
81
83
  import { createSessionMetadataStore } from './lib/session-metadata/session-metadata-store.js';
84
+ import {
85
+ createHttpSessionRecordClient,
86
+ retainOpenCodeSessions,
87
+ startSideStoreMigration,
88
+ } from './lib/session-metadata/opencode-session-record.js';
82
89
  import {
83
90
  createSessionArchiveService,
84
91
  createUpstreamSessionFetcher,
85
92
  } from './lib/session-metadata/session-archive.js';
86
93
  import {
87
94
  projectSessionLifecyclePayload,
88
- projectSessionWithHostMetadata,
89
95
  projectSessionWithStoredMap,
90
96
  } from './lib/session-metadata/session-projection.js';
91
97
  import { createScheduledTasksRuntime } from './lib/scheduled-tasks/runtime.js';
@@ -596,6 +602,7 @@ const waitForReady = (...args) => openCodeNetworkRuntime.waitForReady(...args);
596
602
  const normalizeApiPrefix = (...args) => openCodeNetworkRuntime.normalizeApiPrefix(...args);
597
603
  const setDetectedOpenCodeApiPrefix = (...args) => openCodeNetworkRuntime.setDetectedOpenCodeApiPrefix(...args);
598
604
  const buildOpenCodeUrl = (...args) => openCodeNetworkRuntime.buildOpenCodeUrl(...args);
605
+ configureOpenCodeCredentials(openCodeCredentialSource({ buildOpenCodeUrl, getOpenCodeAuthHeaders }));
599
606
  const ensureOpenCodeApiPrefix = (...args) => openCodeNetworkRuntime.ensureOpenCodeApiPrefix(...args);
600
607
  const scheduleOpenCodeApiDetection = (...args) => openCodeNetworkRuntime.scheduleOpenCodeApiDetection(...args);
601
608
 
@@ -750,6 +757,8 @@ const sessionTitleRuntime = createSessionTitleRuntime({
750
757
  buildOpenCodeUrl,
751
758
  getOpenCodeAuthHeaders,
752
759
  readSessionMetadata: (sessionID) => sessionMetadataStore.get(sessionID),
760
+ mutateSessionMetadata: (sessionID, decide) => sessionMetadataStore.mutateSessionMetadata(sessionID, decide),
761
+ listSessionMetadata: () => sessionMetadataStore.getAll(),
753
762
  persistSessionMetadata: (sessionID, patch) => persistSessionMetadataToStore(sessionID, patch),
754
763
  publishSession: (session, directory) => {
755
764
  const payload = { type: 'session.updated', properties: { info: session, directory } };
@@ -766,7 +775,32 @@ let questionAutoDelegateRuntime = null;
766
775
  /** Filled inside main() once the SQLite session index is constructed. */
767
776
  let sessionIndexServiceRef = null;
768
777
 
769
- const sessionMetadataStore = createSessionMetadataStore({ dataDir: OPENCHAMBER_DATA_DIR });
778
+ const sessionRecordClient = createHttpSessionRecordClient({
779
+ buildSessionUrl: (sessionID, directory) => {
780
+ const url = new URL(buildOpenCodeUrl(`/session/${encodeURIComponent(sessionID)}`));
781
+ if (directory) url.searchParams.set('directory', directory);
782
+ return url.toString();
783
+ },
784
+ getHeaders: () => getOpenCodeAuthHeaders(),
785
+ fetchFn: wrapFetchWithRuntimeContractGate(fetch),
786
+ });
787
+ const sessionMetadataStore = createSessionMetadataStore({
788
+ dataDir: OPENCHAMBER_DATA_DIR,
789
+ recordReader: (sessionID, directory) => sessionRecordClient.read(sessionID, directory),
790
+ recordWriter: (sessionID, metadata, directory) => sessionRecordClient.write({
791
+ sessionID,
792
+ metadata,
793
+ directory,
794
+ }),
795
+ });
796
+ const stopSessionRecordMigration = startSideStoreMigration({
797
+ load: () => sessionMetadataStore.load(),
798
+ readSession: (sessionID) => sessionRecordClient.read(sessionID),
799
+ writeMetadata: async (sessionID, metadata, record) => {
800
+ const directory = record?.location?.directory || record?.directory || undefined;
801
+ await sessionRecordClient.write({ sessionID, metadata, directory });
802
+ },
803
+ });
770
804
  /**
771
805
  * load() resolves `{ ok:false }` on read/corrupt failure (does not reject).
772
806
  * Callers must check ok / isLoaded — never treat unresolved as empty success.
@@ -1013,6 +1047,9 @@ const openCodeWatcherRuntime = createOpenCodeWatcherRuntime({
1013
1047
  // envelope's directory to route their own OpenCode calls to the right instance.
1014
1048
  console.log('[session-title] listening for session events');
1015
1049
  console.log('[session-goal] listening for session events');
1050
+ globalMessageStreamHub.subscribeStatus((status) => {
1051
+ if (status.type === 'connect') sessionTitleRuntime.processPayload({ type: 'server.connected' });
1052
+ });
1016
1053
  globalMessageStreamHub.subscribeEvent((event) => {
1017
1054
  const raw = event?.payload;
1018
1055
  const payload = raw?.payload && typeof raw.payload === 'object' ? raw.payload : raw;
@@ -1263,26 +1300,6 @@ const openCodeLifecycleRuntime = createOpenCodeLifecycleRuntime({
1263
1300
  getManagedOpenCodeShellEnvSnapshot: getLoginShellEnvSnapshot,
1264
1301
  managedCapabilitiesRuntime,
1265
1302
  getActiveSessionCount,
1266
- // Most-recently-used directories first: OpenCode initializes each directory
1267
- // lazily on first request (seconds on large session stores), so the
1268
- // lifecycle warms these right after readiness — before the UI's first
1269
- // interactive request would otherwise pay that cost.
1270
- getWarmupDirectories: async () => {
1271
- const settings = await readSettingsFromDiskMigrated().catch(() => null);
1272
- if (!settings) return [];
1273
- const directories = [];
1274
- if (typeof settings.lastDirectory === 'string' && settings.lastDirectory) {
1275
- directories.push(settings.lastDirectory);
1276
- }
1277
- const projects = Array.isArray(settings.projects) ? [...settings.projects] : [];
1278
- projects.sort((a, b) => (b?.lastOpenedAt ?? 0) - (a?.lastOpenedAt ?? 0));
1279
- for (const project of projects) {
1280
- if (typeof project?.path === 'string' && project.path) {
1281
- directories.push(project.path);
1282
- }
1283
- }
1284
- return [...new Set(directories)];
1285
- },
1286
1303
  });
1287
1304
 
1288
1305
  const restartOpenCode = (...args) => openCodeLifecycleRuntime.restartOpenCode(...args);
@@ -1621,10 +1638,11 @@ async function main(options = {}) {
1621
1638
  projectSessions: (sessions) => {
1622
1639
  const snap = sessionMetadataStore.getSnapshotSync();
1623
1640
  // Not ready / unavailable — throw so sync keeps prior directory rows.
1641
+ // A missing side-store row must not drop a session OpenCode still has.
1624
1642
  if (!snap) {
1625
1643
  throw new Error('session metadata is unavailable: Host store not ready');
1626
1644
  }
1627
- return sessions.map((session) => projectSessionWithStoredMap(session, snap));
1645
+ return retainOpenCodeSessions(sessions, snap);
1628
1646
  },
1629
1647
  onRevisionTip: (tip) => {
1630
1648
  broadcastOpenChamberEvent({
@@ -1664,10 +1682,9 @@ async function main(options = {}) {
1664
1682
  isHostReady: () => sessionMetadataStore.isLoaded(),
1665
1683
  projectSession: (session) => {
1666
1684
  if (!sessionMetadataStore.isLoaded()) return null;
1667
- return projectSessionWithHostMetadata(
1668
- session,
1669
- readHostMetadataForSession(session?.id),
1670
- );
1685
+ const snap = sessionMetadataStore.getSnapshotSync();
1686
+ if (!snap) return null;
1687
+ return projectSessionWithStoredMap(session, snap);
1671
1688
  },
1672
1689
  onSessionDeleted: (sessionID) => sessionArchiveServiceRef?.forgetSession(sessionID),
1673
1690
  })) {
@@ -2158,6 +2175,7 @@ async function main(options = {}) {
2158
2175
  };
2159
2176
  },
2160
2177
  stop: async (shutdownOptions = {}) => {
2178
+ sessionTitleRuntime.stop();
2161
2179
  try {
2162
2180
  unsubscribeSessionIndexEvents();
2163
2181
  unsubscribeMessageQueueEvents();
@@ -2165,6 +2183,7 @@ async function main(options = {}) {
2165
2183
  sessionIndexSyncRuntime?.stop();
2166
2184
  sessionIndexService?.close();
2167
2185
  sessionArchiveServiceRef?.stop?.();
2186
+ stopSessionRecordMigration();
2168
2187
  } catch {
2169
2188
  // The index is a local cache; a failed close must not block shutdown.
2170
2189
  }
@@ -0,0 +1,141 @@
1
+ # Browser Provider Host
2
+
3
+ ## Purpose
4
+
5
+ An installed extension can declare that it provides `browser`. Agent `browser.*`
6
+ actions then go to that extension, and the host adopts the extension's result.
7
+ This fork has no `packages/sdk` and no guest process platform, so this module is
8
+ the minimal host: recognize the declaration, list reachable providers, send one
9
+ action to the selected provider, and refuse when none is selected.
10
+
11
+ It does not render a settings dropdown, a live rail, or takeover / handoff.
12
+ Those belong to a later surface that calls this contract.
13
+
14
+ ## What this fork does not do
15
+
16
+ - It does not spawn extension processes, approve capabilities, or proxy a guest panel.
17
+ - It does not drive the in-app browser pane. No provider means the action is
18
+ refused. The pane's existing behavior is unchanged because this module never
19
+ calls it.
20
+ - It does not persist the installed-extension catalog. Registration is
21
+ in-process. The selected id is persisted; the extension must be registered
22
+ again after a restart before that id is listed or used.
23
+ - It does not write `browser.capture` images to disk. The extension's `data` is
24
+ returned as-is.
25
+
26
+ ## Declaration
27
+
28
+ An extension declares the role with the first array among:
29
+
30
+ 1. `service.provides`
31
+ 2. `provides`
32
+ 3. `contributes.service.provides`
33
+
34
+ `"browser"` in that array is the declaration. A service array that does not
35
+ include `browser` is not a browser provider, even if another field says it is.
36
+ The host recognizes that declaration with `extensionDeclaresBrowser`.
37
+
38
+ Registration is in-process, not an open HTTP install route (an endpoint field
39
+ would otherwise be a client-controlled fetch):
40
+
41
+ ```js
42
+ getBrowserProviderHost().install({
43
+ id: 'server-chrome',
44
+ name: 'Server Chrome',
45
+ service: { provides: ['browser'] },
46
+ answer: async (request) => ({ ok: true, data: { url, title } }),
47
+ // or endpoint: 'http://127.0.0.1:9' → POST /browser-control
48
+ });
49
+ ```
50
+
51
+ `answer` wins when both are set. `endpoint` must be loopback `http:` or
52
+ `https:` with no userinfo. A bare origin is posted to `/browser-control`.
53
+ A disabled extension, a missing id, or a declaration with no way to answer is
54
+ rejected and not listed.
55
+
56
+ ## Agent action
57
+
58
+ `host.dispatchAgentBrowserAction({ action, parameters, context, providerId, signal })`
59
+ is the agent entry. `providerId` overrides the stored selection for that call
60
+ only. Otherwise the stored selection is used. The model does not supply
61
+ `context`; callers pass `{ directory, sessionId }`, each `null` when unknown.
62
+
63
+ The extension receives:
64
+
65
+ ```json
66
+ {
67
+ "requestId": "…",
68
+ "action": "browser.click",
69
+ "parameters": { "selector": "#save" },
70
+ "context": { "directory": "/repo", "sessionId": "ses_1" }
71
+ }
72
+ ```
73
+
74
+ It answers `{ "ok": true, "data": { } }` or `{ "ok": false, "error": "…" }`.
75
+ `data` is what the agent gets. `ok: false` is the agent-visible error, not an
76
+ empty success. A missing, non-JSON, or non-200 answer is unknown page state.
77
+ A call that was sent and then lost may have run; a call that never left the
78
+ host did not.
79
+
80
+ Actions: `browser.open`, `browser.snapshot`, `browser.click`, `browser.type`,
81
+ `browser.scroll`, `browser.back`, `browser.forward`, `browser.inspect`,
82
+ `browser.capture`, `browser.resize`. Parameters are validated before send.
83
+ `browser.open` waits 45s; other actions wait 20s.
84
+
85
+ ## HTTP contract
86
+
87
+ Registered on the web server before the generic OpenCode proxy. The global
88
+ `/api` auth gate already covers these routes; this module does not add a second
89
+ one. Web, Electron
90
+ (in-process server), hosted mobile, and Capacitor mobile use these routes.
91
+ VS Code returns **501** `{ ok: false, code: "UNSUPPORTED", error }` for the
92
+ same paths and does not proxy them. That is not an empty catalog.
93
+
94
+ Settings and the rail call the first two routes. Provider ids match
95
+ `^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$`. `surface` is always `false` here: this
96
+ host does not push a live picture, and reporting `true` would open a socket
97
+ that does not exist.
98
+
99
+ | Call | Success | Refusal |
100
+ |---|---|---|
101
+ | `GET /api/browser-providers` | `200 { providers: [{ id, name, surface: false }], selectedId }` | `503 { error, code: "CATALOG_UNAVAILABLE" }` — never `providers: []` |
102
+ | `PUT /api/browser-providers/selection` body `{ id }` | `200 { selectedId }` naming that same id | `404 PROVIDER_NOT_FOUND`, `400 INVALID_SELECTION`, or `503 SELECTION_UNAVAILABLE`; selection unchanged |
103
+ | `POST /api/browser-providers/actions` body `{ action, parameters?, context?, providerId? }` | `200 { ok: true, providerId, data }` | `ok: false` plus `code` — never `{ ok: true, data: {} }` |
104
+
105
+ `selectedId` is `null` unless it names a provider in `providers`. A saved id
106
+ for an extension that is not installed right now is kept on disk but not
107
+ reported as connected. The selection file is
108
+ `browser-provider-selection.json` under the OpenChamber data dir and stores
109
+ only `{ selectedId }`. A missing file is no selection. A read or write failure
110
+ is not an empty catalog and does not change the previous choice.
111
+
112
+ No endpoint, handler, or credential is returned.
113
+
114
+ Action codes:
115
+
116
+ | code | status | meaning |
117
+ |---|---|---|
118
+ | `NO_PROVIDER` | 409 | nothing selected; nothing ran |
119
+ | `PROVIDER_NOT_FOUND` | 404 | id is not a reachable provider; nothing ran |
120
+ | `CATALOG_UNAVAILABLE` | 503 | catalog read failed; nothing ran |
121
+ | `INVALID_ACTION` | 400 | action or parameters rejected; nothing sent |
122
+ | `PROVIDER_REJECTED` | 400 | extension `ok: false`; `error` is the extension text |
123
+ | `UNKNOWN_RESULT` | 502 | answer was not a browser result; page state unknown |
124
+ | `REQUEST_FAILED` | 504 | sent, no usable answer; may have run |
125
+ | `PROVIDER_UNAVAILABLE` | 503 | never sent |
126
+ | `CANCELLED` | 499 | cancelled before send |
127
+ | `UNSUPPORTED` | 501 | VS Code only |
128
+
129
+ An empty `providers` array with status 200 means the catalog was read and no
130
+ reachable browser provider is installed. That is not a connected browser.
131
+
132
+ ## Invariants
133
+
134
+ - No selected provider does not fall through to the in-app pane and does not
135
+ return success.
136
+ - A catalog read failure is not "no providers" and does not run the action.
137
+ - The extension is re-read from the catalog on every action. A stale selection
138
+ that is no longer listed fails; it is not silently retargeted.
139
+ - Choosing an unknown id does not clear a previous valid selection.
140
+ - Failure after the request was handed to the extension is not described as
141
+ "nothing changed".