@openchambery/web 1.19.22-beta.1 → 2.0.0-beta.3

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 (311) hide show
  1. package/README.md +13 -7
  2. package/bin/cli-opencode.test.js +208 -0
  3. package/bin/cli.js +62 -9
  4. package/bin/lib/cli-startup.js +105 -2
  5. package/bin/lib/cli-startup.test.js +179 -0
  6. package/dist/assets/{AgentAvatar-CRaBJXKs.js → AgentAvatar-B_JQoreg.js} +1 -1
  7. package/dist/assets/AssistantView-ClQAfGOT.js +3 -0
  8. package/dist/assets/{DiagramView-D1LGK_s2.js → DiagramView-BNnda8qO.js} +1 -1
  9. package/dist/assets/{FadeInOnReveal-B0kJo9Ii.js → FadeInOnReveal-VYQTSAkr.js} +1 -1
  10. package/dist/assets/{Icon-BgdfPhNs.js → Icon-BiEQEcih.js} +1 -1
  11. package/dist/assets/MarkdownRenderer-CJHSsWin.js +2 -0
  12. package/dist/assets/{MarkdownRendererImpl-DfoCJ1Mq.js → MarkdownRendererImpl-DwrHFGUp.js} +3 -3
  13. package/dist/assets/{MarkstreamRendererImpl-D2dsW5Lg.js → MarkstreamRendererImpl-CSnbQMu3.js} +1 -1
  14. package/dist/assets/MobileDetailNavigation-BXr6AGLT.js +1 -0
  15. package/dist/assets/{MobileShareBridge-2Yjn6wXg.js → MobileShareBridge-D7OE9OP_.js} +2 -2
  16. package/dist/assets/MobileSurface-D2jUkX9l.js +2 -0
  17. package/dist/assets/{MultiRunWindow-tTbMFowS.js → MultiRunWindow-DF3iIFCd.js} +1 -1
  18. package/dist/assets/{OnboardingScreen-CD2KtlF3.js → OnboardingScreen-BjHmlwlw.js} +1 -1
  19. package/dist/assets/OverlayScrollbar-DLtWO_Gp.js +2 -0
  20. package/dist/assets/SettingsView-BRxELjow.js +25 -0
  21. package/dist/assets/{SettingsWindow-zIa76s4t.js → SettingsWindow-BI5swspb.js} +1 -1
  22. package/dist/assets/{TerminalView-CDdzF4yi.js → TerminalView-BU3x8-fr.js} +1 -1
  23. package/dist/assets/{ToolOutputDialog-DNqA4uBl.js → ToolOutputDialog-BEWhBcRd.js} +2 -2
  24. package/dist/assets/appThemeRegistry-4MR0F7Jz.js +1 -0
  25. package/dist/assets/{button-CI7Q-Zw_.js → button-DKuz3L8l.js} +1 -1
  26. package/dist/assets/collapsible-DXbDynN4.js +3 -0
  27. package/dist/assets/context-menu-CqolsLCm.js +1 -0
  28. package/dist/assets/{desktopHosts-B1ixEylr.js → desktopHosts-CoDkOnyS.js} +1 -1
  29. package/dist/assets/{desktopRelayRestore-4JmFUw8r.js → desktopRelayRestore-DDlVKyOE.js} +1 -1
  30. package/dist/assets/{diagram-DdLO8HZ9.js → diagram-D7T8HQgj.js} +1 -1
  31. package/dist/assets/{dialog-B6pnIYmp.js → dialog-DQYl3W_o.js} +1 -1
  32. package/dist/assets/es-CN3E_zXj.js +15 -0
  33. package/dist/assets/{fileMentionTouchSelection-DNeiqns-.js → fileMentionTouchSelection-BZ6ovBYH.js} +1 -1
  34. package/dist/assets/{fileQueries-DQc8EJUf.js → fileQueries-JrpcsOCs.js} +1 -1
  35. package/dist/assets/fr-9zZvQZD2.js +13 -0
  36. package/dist/assets/gitApi-CM42qUed.js +10 -0
  37. package/dist/assets/{imageSource-BlAJJUEI.js → imageSource-CIl0FL10.js} +1 -1
  38. package/dist/assets/{input-D-__fwRi.js → input-CzQy8UhV.js} +1 -1
  39. package/dist/assets/insertionBoundaries-CtkZ9720.js +1 -0
  40. package/dist/assets/ja-Dnjk_82N.js +15 -0
  41. package/dist/assets/ko-BxCEE99C.js +15 -0
  42. package/dist/assets/main-BILgBI3B.js +169 -0
  43. package/dist/assets/main-BeveiW6F.js +2 -0
  44. package/dist/assets/markdown-worker-bS5OgGO3.js +2 -0
  45. package/dist/assets/{markdownHeightCache-BhxqJOvf.js → markdownHeightCache-Cj1I5NDw.js} +1 -1
  46. package/dist/assets/{markdownTheme-DOfGg-A7.js → markdownTheme-CKac3wKC.js} +1 -1
  47. package/dist/assets/mcpQueries-D5mQymgM.js +1 -0
  48. package/dist/assets/miniChat-BgrzM3u7.js +2 -0
  49. package/dist/assets/mobile-DtYoQE8C.js +2 -0
  50. package/dist/assets/multirun-jy8dEI96.js +4 -0
  51. package/dist/assets/{persistence-Ce3AnpEr.js → persistence-C9LQpiOS.js} +2 -2
  52. package/dist/assets/pl-CNNsWnPM.js +15 -0
  53. package/dist/assets/platform-BQghHRfp.js +6 -0
  54. package/dist/assets/pt-BR-BZB2DJMp.js +15 -0
  55. package/dist/assets/renderElectronMiniChatApp-BGrrmeME.js +2 -0
  56. package/dist/assets/renderMobileApp-u3c4GtFC.js +28 -0
  57. package/dist/assets/{runtimeConfig-CMkwoQ_X.js → runtimeConfig-BIGBRGQI.js} +1 -1
  58. package/dist/assets/{runtimeEndpointReset-ChOxt-J7.js → runtimeEndpointReset-D2savkuw.js} +12 -12
  59. package/dist/assets/{sessionChangeSummary-NnxcqCTI.js → sessionChangeSummary-eIbpSfrO.js} +1 -1
  60. package/dist/assets/{sessionLookup-BrU3rFHJ.js → sessionLookup-myHe5ltu.js} +1 -1
  61. package/dist/assets/{sortable-tabs-strip-Fnfhf3K9.js → sortable-tabs-strip-BQtmHx9r.js} +1 -1
  62. package/dist/assets/src-CLN7Z-zx.css +2 -0
  63. package/dist/assets/store-DLCiZaA6.js +15 -0
  64. package/dist/assets/{terminalApi-xjqssKke.js → terminalApi-BxcdiduX.js} +1 -1
  65. package/dist/assets/{textarea-bHYxZtfH.js → textarea-CakKvqFw.js} +1 -1
  66. package/dist/assets/{tooltip-0T5jv0cu.js → tooltip-Cx5gTbdY.js} +1 -1
  67. package/dist/assets/uk-rwQrxeYM.js +15 -0
  68. package/dist/assets/{url-_z7evzdK.js → url-CDHnjlsm.js} +1 -1
  69. package/dist/assets/{useAppFontEffects-C02YFyAv.js → useAppFontEffects-CNeo0aZs.js} +59 -45
  70. package/dist/assets/{useAssistantUIStore-CMutVh9B.js → useAssistantUIStore-asNG6K7n.js} +1 -1
  71. package/dist/assets/useDesktopWindowControlsLayout-DBJ56qIo.js +1 -0
  72. package/dist/assets/useEffectiveDirectory-B4LvR8Gt.js +1 -0
  73. package/dist/assets/{useFontPreferences-B1JYyzpK.js → useFontPreferences-CUnQ4TVm.js} +1 -1
  74. package/dist/assets/useMobileNavigationStore-ZHJPxlHt.js +414 -0
  75. package/dist/assets/{useRuntimeAPIs-DSLXJybW.js → useRuntimeAPIs-DwLtO0c_.js} +1 -1
  76. package/dist/assets/useSessionAutoCleanup-BIVmrnYU.js +2 -0
  77. package/dist/assets/{useThemeSystem-DMzWVJaW.js → useThemeSystem-BlNUWH47.js} +1 -1
  78. package/dist/assets/useUIStore-CQYKJnrg.js +1 -0
  79. package/dist/assets/{useWorkerHighlightedLines-C9z0ML1z.js → useWorkerHighlightedLines-CJZbJDW3.js} +2 -2
  80. package/dist/assets/{vendor-base-ui-CnHfUmDN.js → vendor-base-ui-CDjyofeD.js} +1 -1
  81. package/dist/assets/{vendor-cmdk-CeAGfrLo.js → vendor-cmdk-BFH0UpXX.js} +1 -1
  82. package/dist/assets/{vendor-dnd-kit-accessibility-BY5LhhUB.js → vendor-dnd-kit-accessibility-BrR3AKvM.js} +1 -1
  83. package/dist/assets/{vendor-dnd-kit-core-CvWxUPdb.js → vendor-dnd-kit-core-CNfdvk6H.js} +1 -1
  84. package/dist/assets/{vendor-dnd-kit-sortable-hHdP9lLb.js → vendor-dnd-kit-sortable-DQUaTeGj.js} +1 -1
  85. package/dist/assets/{vendor-framer-motion-DFy_BSVd.js → vendor-framer-motion-4dogsUk3.js} +1 -1
  86. package/dist/assets/{vendor-legendapp-list-WE32lwNk.js → vendor-legendapp-list-BU7MdPZR.js} +1 -1
  87. package/dist/assets/{vendor-markstream-react-DX55XLGO.js → vendor-markstream-react-qHC2FykU.js} +3 -3
  88. package/dist/assets/vendor-opencode-client-BOe2qpQb.js +12 -0
  89. package/dist/assets/{vendor-pierre-diffs-DX7XTPG3.js → vendor-pierre-diffs-CUfqC003.js} +1 -1
  90. package/dist/assets/{vendor-react-DLPElpoQ.js → vendor-react-C94A0AHl.js} +1 -1
  91. package/dist/assets/{vendor-react-drawio-ECtEwvbc.js → vendor-react-drawio-FVlWqKVE.js} +1 -1
  92. package/dist/assets/{vendor-reactuses-core-BnW6GxJt.js → vendor-reactuses-core-C2A3EjUi.js} +1 -1
  93. package/dist/assets/{vendor-sonner-DVzioF3d.js → vendor-sonner-DNqHmUQs.js} +1 -1
  94. package/dist/assets/{vendor-stream-diffs-DWy3xSmp.js → vendor-stream-diffs-CwbKsmlv.js} +2 -2
  95. package/dist/assets/{vendor-tanstack-react-query-D7pys_c9.js → vendor-tanstack-react-query-D0iFK57C.js} +1 -1
  96. package/dist/assets/{vendor-tanstack-react-virtual-tlDgH6PG.js → vendor-tanstack-react-virtual-B2kV6cnT.js} +1 -1
  97. package/dist/assets/{vendor-yaml-DIcAK3EC.js → vendor-yaml-C9KlJAlj.js} +37 -37
  98. package/dist/assets/{vendor-zustand-B4dlGEM2.js → vendor-zustand-BqLKf6ZY.js} +1 -1
  99. package/dist/assets/zh-CN-BvmBDnkD.js +15 -0
  100. package/dist/assets/zh-TW-9wcHTX0y.js +15 -0
  101. package/dist/index.html +13 -13
  102. package/dist/mini-chat.html +13 -13
  103. package/dist/mobile.html +13 -13
  104. package/package.json +2 -2
  105. package/server/index.js +392 -20
  106. package/server/lib/assistants/DOCUMENTATION.md +26 -21
  107. package/server/lib/assistants/assign.js +2 -1
  108. package/server/lib/assistants/contact-store.js +37 -19
  109. package/server/lib/assistants/contracts.js +11 -1
  110. package/server/lib/assistants/projection-history.test.js +454 -0
  111. package/server/lib/assistants/routes.js +11 -5
  112. package/server/lib/assistants/service.js +850 -294
  113. package/server/lib/assistants/service.test.js +588 -274
  114. package/server/lib/conversations/DOCUMENTATION.md +5 -5
  115. package/server/lib/conversations/service.js +87 -57
  116. package/server/lib/conversations/service.test.js +132 -100
  117. package/server/lib/conversations/validation.js +11 -1
  118. package/server/lib/event-stream/directory-ws-bridge.js +13 -2
  119. package/server/lib/event-stream/global-hub.js +51 -5
  120. package/server/lib/event-stream/runtime.js +57 -20
  121. package/server/lib/event-stream/runtime.test.js +112 -0
  122. package/server/lib/llm/DOCUMENTATION.md +95 -84
  123. package/server/lib/llm/catalog.js +111 -45
  124. package/server/lib/llm/catalog.test.js +121 -59
  125. package/server/lib/llm/completions.js +41 -12
  126. package/server/lib/llm/completions.test.js +45 -4
  127. package/server/lib/llm/generate.js +516 -453
  128. package/server/lib/llm/generate.test.js +705 -484
  129. package/server/lib/llm/routes.js +8 -4
  130. package/server/lib/message-queue/DOCUMENTATION.md +5 -5
  131. package/server/lib/message-queue/opencode-adapter.js +191 -104
  132. package/server/lib/message-queue/opencode-adapter.test.js +328 -58
  133. package/server/lib/message-queue/runtime.js +15 -2
  134. package/server/lib/message-queue/runtime.test.js +6 -6
  135. package/server/lib/message-queue/worker.js +7 -1
  136. package/server/lib/notifications/runtime.js +5 -0
  137. package/server/lib/opencode/DOCUMENTATION.md +103 -16
  138. package/server/lib/opencode/agent-document.d.ts +28 -0
  139. package/server/lib/opencode/agent-document.js +280 -0
  140. package/server/lib/opencode/agent-document.test.js +137 -0
  141. package/server/lib/opencode/agents.js +96 -0
  142. package/server/lib/opencode/auth-state-runtime.js +5 -0
  143. package/server/lib/opencode/bootstrap-runtime.js +2 -0
  144. package/server/lib/opencode/config-entity-routes.js +111 -102
  145. package/server/lib/opencode/config-entity-routes.test.js +123 -10
  146. package/server/lib/opencode/config-hot-reload.integration.test.js +105 -0
  147. package/server/lib/opencode/ensure-cli.js +238 -0
  148. package/server/lib/opencode/ensure-cli.test.js +119 -0
  149. package/server/lib/opencode/env-runtime.js +208 -111
  150. package/server/lib/opencode/env-runtime.test.js +211 -14
  151. package/server/lib/opencode/feature-routes-runtime.js +80 -5
  152. package/server/lib/opencode/feature-routes-runtime.test.js +18 -0
  153. package/server/lib/opencode/http-server-connections.js +98 -0
  154. package/server/lib/opencode/http-server-connections.test.js +321 -0
  155. package/server/lib/opencode/lifecycle.js +539 -95
  156. package/server/lib/opencode/lifecycle.test.js +698 -6
  157. package/server/lib/opencode/managed-capabilities-runtime.js +15 -2
  158. package/server/lib/opencode/managed-capabilities-runtime.test.js +1 -0
  159. package/server/lib/opencode/network-runtime.js +28 -16
  160. package/server/lib/opencode/network-runtime.test.js +68 -4
  161. package/server/lib/opencode/openchamber-routes.js +7 -1
  162. package/server/lib/opencode/opencode2-pin.js +139 -0
  163. package/server/lib/opencode/opencode2-pin.test.js +88 -0
  164. package/server/lib/opencode/opencode2-sidecar.e2e.test.js +326 -0
  165. package/server/lib/opencode/owned-runtime-upgrade.js +431 -0
  166. package/server/lib/opencode/owned-runtime-upgrade.test.js +160 -0
  167. package/server/lib/opencode/plugin-compatibility.js +15 -0
  168. package/server/lib/opencode/plugin-compatibility.test.js +21 -0
  169. package/server/lib/opencode/plugin-routes.js +3 -18
  170. package/server/lib/opencode/plugin-routes.test.js +9 -9
  171. package/server/lib/opencode/plugins.js +4 -3
  172. package/server/lib/opencode/plugins.test.js +12 -0
  173. package/server/lib/opencode/provider-catalog.js +58 -12
  174. package/server/lib/opencode/provider-catalog.test.js +48 -0
  175. package/server/lib/opencode/proxy.js +368 -28
  176. package/server/lib/opencode/proxy.test.js +338 -0
  177. package/server/lib/opencode/routes.js +303 -76
  178. package/server/lib/opencode/routes.test.js +315 -50
  179. package/server/lib/opencode/runtime-contract.js +401 -0
  180. package/server/lib/opencode/runtime-contract.test.js +214 -0
  181. package/server/lib/opencode/server-opencode-fetch.js +242 -0
  182. package/server/lib/opencode/server-opencode-fetch.test.js +130 -0
  183. package/server/lib/opencode/server-utils-runtime.js +35 -0
  184. package/server/lib/opencode/shared-service.integration.test.js +66 -0
  185. package/server/lib/opencode/shared-service.js +147 -0
  186. package/server/lib/opencode/shared-service.test.js +93 -0
  187. package/server/lib/opencode/shared.js +3 -3
  188. package/server/lib/opencode/shutdown-runtime.js +15 -6
  189. package/server/lib/opencode/shutdown-runtime.test.js +49 -1
  190. package/server/lib/opencode/skill-routes.js +26 -40
  191. package/server/lib/opencode/skill-routes.test.js +71 -7
  192. package/server/lib/opencode/skills.test.js +15 -0
  193. package/server/lib/opencode/startup-pipeline-runtime.js +4 -0
  194. package/server/lib/opencode/static-routes-runtime.js +3 -1
  195. package/server/lib/opencode/static-routes-runtime.test.js +33 -0
  196. package/server/lib/opencode/v1-migration-gate.js +157 -0
  197. package/server/lib/opencode/v1-migration-gate.test.js +111 -0
  198. package/server/lib/opencode/v2-client.js +60 -0
  199. package/server/lib/opencode/v2-plugin-host-shim/index.mjs +155 -0
  200. package/server/lib/opencode/v2-plugin-host-shim/package.json +4 -0
  201. package/server/lib/opencode/watcher.js +2 -1
  202. package/server/lib/opencode/watcher.test.js +1 -1
  203. package/server/lib/permission-auto-accept/DOCUMENTATION.md +5 -5
  204. package/server/lib/permission-auto-accept/runtime.js +14 -7
  205. package/server/lib/permission-auto-accept/runtime.test.js +27 -12
  206. package/server/lib/relay/reasoning-projection.e2e.test.ts +22 -7
  207. package/server/lib/scheduled-tasks/DOCUMENTATION.md +79 -39
  208. package/server/lib/scheduled-tasks/managed-tool-route.js +31 -1
  209. package/server/lib/scheduled-tasks/managed-tool-route.test.js +23 -0
  210. package/server/lib/scheduled-tasks/routes.js +27 -0
  211. package/server/lib/scheduled-tasks/routes.test.js +94 -0
  212. package/server/lib/scheduled-tasks/runtime.js +381 -310
  213. package/server/lib/scheduled-tasks/runtime.test.js +600 -309
  214. package/server/lib/session-goal/DOCUMENTATION.md +173 -22
  215. package/server/lib/session-goal/capability.js +57 -0
  216. package/server/lib/session-goal/capability.test.js +33 -0
  217. package/server/lib/session-goal/routes.js +240 -2
  218. package/server/lib/session-goal/routes.test.js +211 -0
  219. package/server/lib/session-goal/runtime.js +1617 -113
  220. package/server/lib/session-goal/runtime.test.js +1500 -70
  221. package/server/lib/session-index/DOCUMENTATION.md +18 -15
  222. package/server/lib/session-index/event-ingest.js +89 -16
  223. package/server/lib/session-index/event-ingest.test.js +73 -0
  224. package/server/lib/session-index/host-authority-snapshot.js +92 -0
  225. package/server/lib/session-index/routes.host-archive.test.js +201 -0
  226. package/server/lib/session-index/routes.js +63 -10
  227. package/server/lib/session-index/routes.test.js +8 -8
  228. package/server/lib/session-index/service.js +7 -1
  229. package/server/lib/session-index/sync-runtime.js +171 -41
  230. package/server/lib/session-index/sync-runtime.test.js +164 -9
  231. package/server/lib/session-metadata/DOCUMENTATION.md +86 -0
  232. package/server/lib/session-metadata/routes.js +193 -0
  233. package/server/lib/session-metadata/routes.test.js +156 -0
  234. package/server/lib/session-metadata/session-archive.d.ts +73 -0
  235. package/server/lib/session-metadata/session-archive.js +654 -0
  236. package/server/lib/session-metadata/session-archive.test.js +359 -0
  237. package/server/lib/session-metadata/session-metadata-store.d.ts +36 -0
  238. package/server/lib/session-metadata/session-metadata-store.js +375 -0
  239. package/server/lib/session-metadata/session-metadata-store.test.js +379 -0
  240. package/server/lib/session-metadata/session-projection.d.ts +41 -0
  241. package/server/lib/session-metadata/session-projection.js +255 -0
  242. package/server/lib/session-metadata/session-projection.test.js +64 -0
  243. package/server/lib/session-metadata/system-session.js +55 -0
  244. package/server/lib/session-metadata/system-session.test.js +55 -0
  245. package/server/lib/session-title/DOCUMENTATION.md +40 -7
  246. package/server/lib/session-title/native-runtime.test.js +167 -0
  247. package/server/lib/session-title/runtime.js +67 -42
  248. package/server/lib/session-title/session-access.js +46 -0
  249. package/server/lib/session-title/session-access.test.js +91 -0
  250. package/server/lib/session-turn-pages/DOCUMENTATION.md +12 -11
  251. package/server/lib/session-turn-pages/reconcile.service.js +1 -1
  252. package/server/lib/session-turn-pages/reconcile.service.test.js +16 -0
  253. package/server/lib/session-turn-pages/routes.js +123 -75
  254. package/server/lib/session-turn-pages/routes.test.js +566 -0
  255. package/server/lib/session-turn-pages/service.js +6 -2
  256. package/server/lib/session-turn-pages/service.test.js +34 -0
  257. package/server/lib/session-turn-pages/session-message-projection.d.ts +13 -0
  258. package/server/lib/session-turn-pages/session-message-projection.js +281 -0
  259. package/server/lib/small-model/DOCUMENTATION.md +101 -146
  260. package/server/lib/small-model/catalog.js +84 -54
  261. package/server/lib/small-model/catalog.test.js +111 -9
  262. package/server/lib/small-model/custom-api.js +68 -0
  263. package/server/lib/small-model/custom-api.test.js +64 -0
  264. package/server/lib/small-model/index.js +125 -241
  265. package/server/lib/small-model/resolve.js +35 -120
  266. package/server/lib/small-model/resolve.test.js +20 -110
  267. package/server/lib/small-model/routes.js +1 -3
  268. package/server/lib/small-model/summary-settings.test.js +157 -253
  269. package/server/opencode-proxy.test.js +63 -12
  270. package/dist/assets/AssistantView-BUveAgc4.js +0 -3
  271. package/dist/assets/MarkdownRenderer-BbrbDH6-.js +0 -2
  272. package/dist/assets/MobileDetailNavigation-B0aqKXd7.js +0 -1
  273. package/dist/assets/MobileSurface-DW7WfPsy.js +0 -2
  274. package/dist/assets/OverlayScrollbar-DrA0Vsg5.js +0 -2
  275. package/dist/assets/SettingsView-PkXIavr7.js +0 -25
  276. package/dist/assets/appThemeRegistry-D5Yxg4YF.js +0 -1
  277. package/dist/assets/collapsible-D5Phaykh.js +0 -1
  278. package/dist/assets/context-menu-CubSDW2g.js +0 -1
  279. package/dist/assets/es-DA3MqOo0.js +0 -15
  280. package/dist/assets/fr-Dbz0CdIA.js +0 -13
  281. package/dist/assets/gitApi-DXyC4MiV.js +0 -7
  282. package/dist/assets/insertionBoundaries-KlOVrHHt.js +0 -1
  283. package/dist/assets/ja-DumanVQA.js +0 -15
  284. package/dist/assets/ko-C0IkiUjQ.js +0 -15
  285. package/dist/assets/main-BPS5ylib.js +0 -2
  286. package/dist/assets/main-Cpd9VWYs.js +0 -169
  287. package/dist/assets/markdown-worker-CptoICmq.js +0 -2
  288. package/dist/assets/miniChat-B8_KLWiY.js +0 -2
  289. package/dist/assets/mobile-CtktKrXn.js +0 -2
  290. package/dist/assets/multirun-CYfP9Cfm.js +0 -4
  291. package/dist/assets/pl-B9No6MQp.js +0 -15
  292. package/dist/assets/platform-0w_Q9_ji.js +0 -2
  293. package/dist/assets/projectMeta-S1hJ7oBp.js +0 -3
  294. package/dist/assets/pt-BR-DyQ0WTDh.js +0 -15
  295. package/dist/assets/renderElectronMiniChatApp-iK14LWm8.js +0 -2
  296. package/dist/assets/renderMobileApp-DORLPWnb.js +0 -28
  297. package/dist/assets/src-rS3zCcsC.css +0 -2
  298. package/dist/assets/store-5B_LDnLM.js +0 -15
  299. package/dist/assets/uk-C_1KkqyP.js +0 -15
  300. package/dist/assets/useDesktopWindowControlsLayout-Dnr-jX0C.js +0 -1
  301. package/dist/assets/useEffectiveDirectory-CZLLyarc.js +0 -1
  302. package/dist/assets/useMobileNavigationStore-CoCiqNgm.js +0 -413
  303. package/dist/assets/useSessionAutoCleanup-xQyETQkG.js +0 -2
  304. package/dist/assets/useUIStore-Bxv3f23A.js +0 -1
  305. package/dist/assets/vendor-opencode-sdk-C07HQypa.js +0 -7
  306. package/dist/assets/zh-CN-uWILgBdt.js +0 -15
  307. package/dist/assets/zh-TW-MYfdvhbD.js +0 -15
  308. package/server/lib/small-model/call.js +0 -427
  309. package/server/lib/small-model/call.test.js +0 -382
  310. package/server/lib/small-model/opencode-session.js +0 -339
  311. package/server/lib/small-model/opencode-session.test.js +0 -177
@@ -1,5 +1,24 @@
1
1
  import { createProjectIdFromPath } from '../projects/project-id.js';
2
2
  import { projectBootstrapSettingsResponse } from './settings-helpers.js';
3
+ import {
4
+ PINNED_OPENCODE2_VERSION,
5
+ evaluateOpenCodeHealthBody,
6
+ isOpenCode1xVersion,
7
+ resolveOpenCode2UpgradeTarget,
8
+ } from './opencode2-pin.js';
9
+ import {
10
+ installPinnedOpenCode2Cli,
11
+ readOpenCode2BinaryVersion,
12
+ resolveOpenChamberDataDir,
13
+ } from './ensure-cli.js';
14
+ import { evaluateRuntimeContract } from './runtime-contract.js';
15
+ import {
16
+ buildUpgradeStatusSnapshot,
17
+ classifyRuntimeOwnership,
18
+ createUpgradeOperationState,
19
+ evaluateOwnedUpgradeResult,
20
+ resolveOwnedCacheBinaryPath,
21
+ } from './owned-runtime-upgrade.js';
3
22
  import fs from 'fs';
4
23
  import os from 'os';
5
24
  import path from 'path';
@@ -22,8 +41,23 @@ export const registerOpenCodeRoutes = (app, dependencies) => {
22
41
  buildOpenCodeUrl,
23
42
  getOpenCodeAuthHeaders,
24
43
  onSettingsPersisted,
44
+ getIsExternalOpenCode = () => false,
45
+ getIsSharedOpenCodeService = () => false,
46
+ forceResolvedOpenCodeBinary = null,
47
+ restartOpenCode = null,
48
+ waitForOpenCodeReady = null,
49
+ getRuntimeContract = () => null,
50
+ getOpenCodeServeVersion = () => null,
51
+ getOpenCodeCliVersion = () => null,
52
+ getResolvedOpenCodeBinary = () => null,
53
+ getResolvedOpenCodeBinarySource = () => null,
54
+ getActiveSessionCount = () => 0,
55
+ openchamberDataDir = null,
25
56
  } = dependencies;
26
57
 
58
+ const upgradeOperation = createUpgradeOperationState();
59
+ const resolveDataDir = () => openchamberDataDir || resolveOpenChamberDataDir();
60
+
27
61
  let authLibrary = null;
28
62
  const pendingMcpAuthContextByState = new Map();
29
63
  const PENDING_MCP_AUTH_TTL_MS = 30 * 60 * 1000;
@@ -50,16 +84,87 @@ export const registerOpenCodeRoutes = (app, dependencies) => {
50
84
  };
51
85
 
52
86
  const readOpenCodeCurrentVersion = async () => {
53
- const healthResponse = await fetch(buildOpenCodeUrl('/global/health', ''), {
87
+ const healthResponse = await fetch(buildOpenCodeUrl('/api/info', ''), {
54
88
  method: 'GET',
55
89
  headers: { Accept: 'application/json', ...getOpenCodeAuthHeaders() },
56
90
  });
57
91
  const health = await healthResponse.json().catch(() => null);
58
92
  if (!healthResponse.ok) {
59
- return { ok: false, status: healthResponse.status, error: health?.error || healthResponse.statusText };
93
+ return {
94
+ ok: false,
95
+ status: healthResponse.status,
96
+ error: health?.error || healthResponse.statusText,
97
+ authenticated: healthResponse.status === 401 || healthResponse.status === 403 ? false : null,
98
+ };
99
+ }
100
+ const gate = evaluateOpenCodeHealthBody(health);
101
+ const currentVersion = gate.version
102
+ || (typeof health?.version === 'string' ? health.version.replace(/^v/, '') : null);
103
+ return { ok: gate.ok, currentVersion, healthOk: gate.ok, authenticated: true };
104
+ };
105
+
106
+ const resolveOwnershipContext = async () => {
107
+ const isExternal = getIsExternalOpenCode() === true;
108
+ let binarySource = typeof getResolvedOpenCodeBinarySource === 'function'
109
+ ? getResolvedOpenCodeBinarySource()
110
+ : null;
111
+ let binaryPath = typeof getResolvedOpenCodeBinary === 'function'
112
+ ? getResolvedOpenCodeBinary()
113
+ : null;
114
+ try {
115
+ const settings = await readSettingsFromDiskMigrated();
116
+ const resolution = await getOpenCodeResolutionSnapshot(settings);
117
+ binarySource = binarySource || resolution?.source || resolution?.detectedSourceNow || null;
118
+ binaryPath = binaryPath || resolution?.resolved || null;
119
+ if (resolution?.source === 'bundled' || resolution?.detectedSourceNow === 'bundled') {
120
+ binarySource = 'bundled';
121
+ }
122
+ } catch {
123
+ // Resolution failures still allow ownership classification from runtime flags.
60
124
  }
61
- const currentVersion = typeof health?.version === 'string' ? health.version.replace(/^v/, '') : null;
62
- return { ok: true, currentVersion };
125
+ return classifyRuntimeOwnership({
126
+ isExternal,
127
+ isSharedService: getIsSharedOpenCodeService() === true,
128
+ binarySource,
129
+ binaryPath,
130
+ dataDir: resolveDataDir(),
131
+ });
132
+ };
133
+
134
+ const buildLiveContract = async ({ fresh = false } = {}) => {
135
+ const cached = typeof getRuntimeContract === 'function' ? getRuntimeContract() : null;
136
+ const serveProbe = await readOpenCodeCurrentVersion().catch(() => ({ ok: false, currentVersion: null }));
137
+ const serveVersion = serveProbe.currentVersion
138
+ || (!fresh && typeof getOpenCodeServeVersion === 'function' ? getOpenCodeServeVersion() : null);
139
+ const binaryPath = typeof getResolvedOpenCodeBinary === 'function' ? getResolvedOpenCodeBinary() : null;
140
+ const cliVersion = (typeof getOpenCodeCliVersion === 'function' ? getOpenCodeCliVersion() : null)
141
+ || (binaryPath ? readOpenCode2BinaryVersion(binaryPath) : null)
142
+ || null;
143
+ return evaluateRuntimeContract({
144
+ serveVersion,
145
+ cliVersion,
146
+ reachable: fresh ? serveProbe.ok === true : serveProbe.ok === true || Boolean(serveVersion) || Boolean(cached?.reachable),
147
+ authenticated: serveProbe.authenticated ?? (fresh ? null : cached?.authenticated) ?? null,
148
+ healthOk: serveProbe.healthOk ?? serveProbe.ok ?? (fresh ? false : cached?.healthOk) ?? null,
149
+ migrationAdmitTranscript: cached?.migrationExecutable ?? null,
150
+ migrationPhase: cached?.migrationPhase ?? null,
151
+ migrationError: cached?.migrationError ?? null,
152
+ });
153
+ };
154
+
155
+ const buildUpgradeStatus = async () => {
156
+ const ownership = await resolveOwnershipContext();
157
+ const contract = await buildLiveContract();
158
+ const activeCount = typeof getActiveSessionCount === 'function' ? Number(getActiveSessionCount()) || 0 : 0;
159
+ return buildUpgradeStatusSnapshot({
160
+ ownership,
161
+ serveVersion: contract.serveVersion,
162
+ cliVersion: contract.cliVersion,
163
+ targetVersion: PINNED_OPENCODE2_VERSION,
164
+ contract,
165
+ operation: upgradeOperation.getState(),
166
+ hasActiveTasks: activeCount > 0,
167
+ });
63
168
  };
64
169
 
65
170
  const parseVersionForComparison = (value) => {
@@ -183,51 +288,157 @@ export const registerOpenCodeRoutes = (app, dependencies) => {
183
288
 
184
289
  app.post('/api/opencode/upgrade', async (req, res) => {
185
290
  try {
186
- if (await isBundledOpenCodeBinaryActive()) {
187
- return res.status(409).json({
291
+ const ownership = await resolveOwnershipContext();
292
+ if (!ownership.canUpgradeInApp) {
293
+ const status = ownership.ownership === 'external-serve' || ownership.ownership === 'bundled' ? 409 : 409;
294
+ return res.status(status).json({
188
295
  success: false,
189
- error: 'OpenCode is bundled with OpenChamber Desktop and cannot be upgraded separately.',
296
+ error: ownership.guidance
297
+ || 'OpenChamber can only upgrade its owned OpenCode cache in-app.',
298
+ errorCode: ownership.reason || 'UPGRADE_NOT_MANAGED',
299
+ ownership: ownership.ownership,
300
+ management: ownership.management,
301
+ guidance: ownership.guidance,
190
302
  });
191
303
  }
192
304
 
193
- const target = normalizeOpenCodeUpgradeTarget(req.body?.target);
194
- if (!target) {
305
+ const rawTarget = typeof req.body?.target === 'string' && req.body.target.trim().length > 0
306
+ ? req.body.target.trim()
307
+ : undefined;
308
+ if (isOpenCode1xVersion(rawTarget)) {
195
309
  return res.status(400).json({
196
310
  success: false,
197
- error: 'OpenCode upgrade requires a semantic version target',
311
+ error: 'OpenCode upgrade refuses 1.x targets. Only pinned opencode2 is allowed.',
312
+ errorCode: 'OPENCODE_UPGRADE_1X_REFUSED',
198
313
  });
199
314
  }
200
-
201
- const response = await fetch(buildOpenCodeUrl('/global/upgrade', ''), {
202
- method: 'POST',
203
- headers: {
204
- 'Content-Type': 'application/json',
205
- Accept: 'application/json',
206
- ...getOpenCodeAuthHeaders(),
207
- },
208
- body: JSON.stringify({ target }),
209
- });
210
- const payload = await response.json().catch(() => null);
211
- if (!response.ok) {
212
- return res.status(response.status).json({
315
+ const target = resolveOpenCode2UpgradeTarget(rawTarget);
316
+ const confirmActive = req.body?.confirmActiveTasks === true || req.body?.force === true;
317
+ const activeCount = typeof getActiveSessionCount === 'function' ? Number(getActiveSessionCount()) || 0 : 0;
318
+ if (activeCount > 0 && !confirmActive) {
319
+ return res.status(409).json({
213
320
  success: false,
214
- error: readOpenCodeUpgradeError(payload, response.statusText || 'Failed to upgrade OpenCode'),
321
+ error: 'OpenCode has active sessions. Confirm upgrade to interrupt them, or wait until idle.',
322
+ errorCode: 'UPGRADE_ACTIVE_TASKS',
323
+ hasActiveTasks: true,
324
+ activeSessionCount: activeCount,
215
325
  });
216
326
  }
217
327
 
328
+ const begin = upgradeOperation.begin(target);
329
+ if (!begin.ok) {
330
+ return res.status(begin.status).json(begin.body);
331
+ }
332
+
333
+ const expectedBinaryPath = resolveOwnedCacheBinaryPath(target, { dataDir: resolveDataDir() });
334
+ let installedPath = expectedBinaryPath;
335
+ const previousBinary = getResolvedOpenCodeBinary();
336
+ const previousSource = getResolvedOpenCodeBinarySource();
337
+
218
338
  try {
219
- await refreshOpenCodeAfterConfigChange('OpenCode upgrade');
220
- } catch (restartError) {
339
+ upgradeOperation.setPhase('download');
340
+ installedPath = await installPinnedOpenCode2Cli({
341
+ version: target,
342
+ dataDir: resolveDataDir(),
343
+ });
344
+ const diskVersion = readOpenCode2BinaryVersion(installedPath);
345
+ if (diskVersion !== target) {
346
+ const error = new Error(
347
+ `Owned-cache binary version mismatch after install: expected ${target}, got ${diskVersion || 'unknown'}`,
348
+ );
349
+ error.code = 'UPGRADE_BINARY_VERSION_MISMATCH';
350
+ throw error;
351
+ }
352
+
353
+ upgradeOperation.setPhase('pin-binary', { binaryPath: installedPath });
354
+ if (typeof forceResolvedOpenCodeBinary !== 'function') {
355
+ const error = new Error('Owned-cache upgrade requires forceResolvedOpenCodeBinary');
356
+ error.code = 'UPGRADE_FORCE_BINARY_UNAVAILABLE';
357
+ throw error;
358
+ }
359
+ // Keep target identity through restart — do not rediscover global CLI.
360
+ forceResolvedOpenCodeBinary(installedPath, 'installed');
361
+
362
+ upgradeOperation.setPhase('restart');
363
+ if (typeof restartOpenCode === 'function') {
364
+ await restartOpenCode(ownership.ownership === 'shared-service' ? { binaryPath: installedPath } : undefined);
365
+ } else if (typeof refreshOpenCodeAfterConfigChange === 'function') {
366
+ // Fallback: still pin binary first so restart prefers owned cache.
367
+ await refreshOpenCodeAfterConfigChange('OpenCode owned-cache upgrade');
368
+ } else {
369
+ const error = new Error('No OpenCode restart path is configured');
370
+ error.code = 'UPGRADE_RESTART_UNAVAILABLE';
371
+ throw error;
372
+ }
373
+
374
+ if (typeof waitForOpenCodeReady === 'function') {
375
+ upgradeOperation.setPhase('wait-ready');
376
+ await waitForOpenCodeReady();
377
+ }
378
+
379
+ upgradeOperation.setPhase('verify');
380
+ // Re-pin after restart helpers that may clear resolution.
381
+ forceResolvedOpenCodeBinary(installedPath, 'installed');
382
+ const contract = await buildLiveContract({ fresh: true });
383
+ const verification = evaluateOwnedUpgradeResult({
384
+ targetVersion: target,
385
+ serveVersion: contract.serveVersion,
386
+ cliVersion: contract.cliVersion,
387
+ binaryPath: typeof getResolvedOpenCodeBinary === 'function'
388
+ ? getResolvedOpenCodeBinary()
389
+ : installedPath,
390
+ expectedBinaryPath: installedPath,
391
+ contract,
392
+ });
393
+ if (!verification.ok) {
394
+ const error = new Error(verification.error);
395
+ error.code = verification.errorCode;
396
+ error.serveVersion = verification.serveVersion;
397
+ error.contract = verification.contract;
398
+ throw error;
399
+ }
400
+
401
+ upgradeOperation.succeed({
402
+ serveVersion: verification.serveVersion,
403
+ binaryPath: installedPath,
404
+ });
405
+ return res.json({
406
+ success: true,
407
+ upgraded: true,
408
+ restarted: true,
409
+ version: verification.serveVersion,
410
+ targetVersion: target,
411
+ pinned: true,
412
+ supplySource: 'owned-cache',
413
+ ownership: ownership.ownership === 'shared-service' ? 'shared-service' : 'owned-cache',
414
+ binaryPath: installedPath,
415
+ contract: verification.contract,
416
+ operation: upgradeOperation.getState(),
417
+ });
418
+ } catch (upgradeError) {
419
+ if (previousBinary && typeof forceResolvedOpenCodeBinary === 'function') {
420
+ forceResolvedOpenCodeBinary(previousBinary, previousSource);
421
+ }
422
+ const message = upgradeError instanceof Error ? upgradeError.message : 'Failed to upgrade OpenCode';
423
+ const errorCode = upgradeError?.code || 'UPGRADE_FAILED';
424
+ upgradeOperation.fail({
425
+ error: message,
426
+ errorCode,
427
+ phase: upgradeOperation.getState().phase,
428
+ serveVersion: upgradeError?.serveVersion ?? null,
429
+ binaryPath: installedPath,
430
+ });
431
+ // Preserve previous owned cache on disk; only report failure.
221
432
  return res.status(500).json({
222
433
  success: false,
223
- upgraded: true,
224
- error: restartError instanceof Error
225
- ? `OpenCode upgraded, but restart failed: ${restartError.message}`
226
- : 'OpenCode upgraded, but restart failed',
434
+ upgraded: false,
435
+ error: message,
436
+ errorCode,
437
+ targetVersion: target,
438
+ operation: upgradeOperation.getState(),
439
+ contract: upgradeError?.contract || null,
227
440
  });
228
441
  }
229
-
230
- return res.json({ ...(payload ?? { success: true }), restarted: true });
231
442
  } catch (error) {
232
443
  console.error('Failed to upgrade OpenCode:', error);
233
444
  return res.status(500).json({
@@ -239,74 +450,88 @@ export const registerOpenCodeRoutes = (app, dependencies) => {
239
450
 
240
451
  app.get('/api/opencode/upgrade-status', async (_req, res) => {
241
452
  try {
242
- if (await isBundledOpenCodeBinaryActive()) {
243
- const current = await readOpenCodeCurrentVersion().catch(() => ({ ok: false, currentVersion: null }));
244
- return res.json({
245
- available: false,
246
- currentVersion: current.ok ? current.currentVersion : null,
247
- latestVersion: null,
248
- source: 'bundled',
249
- });
250
- }
453
+ const status = await buildUpgradeStatus();
454
+ return res.json(status);
455
+ } catch (error) {
456
+ return res.status(500).json({
457
+ available: null,
458
+ error: error instanceof Error ? error.message : 'Failed to check OpenCode upgrade status',
459
+ operation: upgradeOperation.getState(),
460
+ });
461
+ }
462
+ });
251
463
 
252
- const [healthResponse, latestVersion] = await Promise.all([
253
- fetch(buildOpenCodeUrl('/global/health', ''), {
254
- method: 'GET',
255
- headers: { Accept: 'application/json', ...getOpenCodeAuthHeaders() },
256
- }),
257
- fetchLatestOpenCodeVersion(),
258
- ]);
259
- const health = await healthResponse.json().catch(() => null);
260
- if (!healthResponse.ok) {
261
- return res.status(healthResponse.status).json({
262
- available: null,
263
- error: health?.error || healthResponse.statusText || 'Failed to read OpenCode version',
264
- });
265
- }
266
- const currentVersion = typeof health?.version === 'string' ? health.version.replace(/^v/, '') : null;
267
- if (!currentVersion || !latestVersion) {
268
- return res.json({ available: null, currentVersion, latestVersion: latestVersion || null });
269
- }
270
- const available = compareVersions(latestVersion, currentVersion) > 0;
464
+ app.get('/api/opencode/contract', async (_req, res) => {
465
+ try {
466
+ const contract = await buildLiveContract();
467
+ const ownership = await resolveOwnershipContext();
271
468
  return res.json({
272
- available,
273
- currentVersion,
274
- latestVersion,
469
+ ...contract,
470
+ ownership: ownership.ownership,
471
+ supplySource: ownership.supplySource,
472
+ canManageUpgrade: ownership.canUpgradeInApp,
473
+ management: ownership.management,
474
+ guidance: ownership.guidance,
275
475
  });
276
476
  } catch (error) {
277
477
  return res.status(500).json({
278
- available: null,
279
- error: error instanceof Error ? error.message : 'Failed to check OpenCode upgrade status',
478
+ schemaVersion: 1,
479
+ phase: 'unknown',
480
+ executionAllowed: false,
481
+ error: error instanceof Error ? error.message : 'Failed to evaluate OpenCode runtime contract',
280
482
  });
281
483
  }
282
484
  });
283
485
 
284
486
  app.get('/api/opencode/health', async (_req, res) => {
285
487
  try {
286
- const healthResponse = await fetch(buildOpenCodeUrl('/global/health', ''), {
488
+ const healthResponse = await fetch(buildOpenCodeUrl('/api/info', ''), {
287
489
  method: 'GET',
288
490
  headers: { Accept: 'application/json', ...getOpenCodeAuthHeaders() },
289
491
  signal: AbortSignal.timeout(4_000),
290
492
  });
291
493
  const health = await healthResponse.json().catch(() => null);
292
494
  if (!healthResponse.ok) {
495
+ const contract = evaluateRuntimeContract({
496
+ reachable: false,
497
+ authenticated: healthResponse.status === 401 || healthResponse.status === 403 ? false : null,
498
+ healthOk: false,
499
+ });
293
500
  return res.status(healthResponse.status).json({
294
501
  healthy: false,
295
502
  error: health?.error || healthResponse.statusText || 'OpenCode health check failed',
503
+ contract,
296
504
  });
297
505
  }
298
- return res.json({ healthy: health?.healthy === true });
506
+ // Reuse lifecycle/sidecar gate: official 2.x ServerInfo omits `healthy`.
507
+ const gate = evaluateOpenCodeHealthBody(health);
508
+ const contract = await buildLiveContract().catch(() => evaluateRuntimeContract({
509
+ serveVersion: gate.version,
510
+ reachable: gate.ok,
511
+ authenticated: true,
512
+ healthOk: gate.ok,
513
+ }));
514
+ return res.json({
515
+ healthy: gate.ok,
516
+ version: gate.version,
517
+ // Healthy is reachability/version shape only — not full execution semantics.
518
+ executionAllowed: contract.executionAllowed === true,
519
+ protocolCompatible: contract.protocolCompatible === true,
520
+ contract,
521
+ });
299
522
  } catch (error) {
300
523
  return res.status(503).json({
301
524
  healthy: false,
302
525
  error: error instanceof Error ? error.message : 'OpenCode health check failed',
526
+ contract: evaluateRuntimeContract({ reachable: false, healthOk: false }),
303
527
  });
304
528
  }
305
529
  });
306
530
 
307
531
  app.get('/api/opencode/version', async (_req, res) => {
308
532
  try {
309
- const healthResponse = await fetch(buildOpenCodeUrl('/global/health', ''), {
533
+ const contract = await buildLiveContract();
534
+ const healthResponse = await fetch(buildOpenCodeUrl('/api/info', ''), {
310
535
  method: 'GET',
311
536
  headers: { Accept: 'application/json', ...getOpenCodeAuthHeaders() },
312
537
  });
@@ -314,11 +539,20 @@ export const registerOpenCodeRoutes = (app, dependencies) => {
314
539
  if (!healthResponse.ok) {
315
540
  return res.status(healthResponse.status).json({
316
541
  version: null,
542
+ serveVersion: null,
543
+ cliVersion: contract.cliVersion,
317
544
  error: health?.error || healthResponse.statusText || 'Failed to read OpenCode version',
545
+ contract,
318
546
  });
319
547
  }
320
548
  const version = typeof health?.version === 'string' ? health.version.replace(/^v/, '') : null;
321
- return res.json({ version });
549
+ return res.json({
550
+ version,
551
+ serveVersion: version,
552
+ cliVersion: contract.cliVersion,
553
+ versionMismatch: Boolean(version && contract.cliVersion && version !== contract.cliVersion),
554
+ contract,
555
+ });
322
556
  } catch (error) {
323
557
  return res.status(500).json({
324
558
  version: null,
@@ -606,13 +840,6 @@ export const registerOpenCodeRoutes = (app, dependencies) => {
606
840
 
607
841
  await fs.promises.writeFile(AGENTS_MD_PATH, content, 'utf8');
608
842
 
609
- // Refresh OpenCode so it picks up the new AGENTS.md without a full restart
610
- try {
611
- await refreshOpenCodeAfterConfigChange('global behavior (AGENTS.md) updated');
612
- } catch {
613
- // Non-fatal: file was written successfully
614
- }
615
-
616
843
  return res.json({ success: true });
617
844
  } catch (error) {
618
845
  console.error('Failed to write AGENTS.md:', error);