@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
@@ -0,0 +1,193 @@
1
+ /**
2
+ * HTTP surface for OpenChamber-owned session metadata and Host archive.
3
+ *
4
+ * OpenCode 2.x has no session-metadata update route. Clients (and Host
5
+ * features such as session goal) merge-patch state here; the proxy folds the
6
+ * store back onto session list/detail responses.
7
+ *
8
+ * Archive is a separate Host operation:
9
+ * `PUT /api/openchamber/sessions/:sessionId/archive` body `{ archivedAt: number }`.
10
+ *
11
+ * This module exports the store factory, archive service helpers, and the route
12
+ * registrar. Wire them from `server/index.js` / `feature-routes-runtime.js`.
13
+ */
14
+
15
+ import express from 'express';
16
+
17
+ import { withGoalExecutionGeneration } from '../session-goal/runtime.js';
18
+ import { createSessionMetadataStore } from './session-metadata-store.js';
19
+ import { SessionArchiveError } from './session-archive.js';
20
+
21
+ const asNonEmptyString = (value) => {
22
+ if (typeof value !== 'string') return null;
23
+ const trimmed = value.trim();
24
+ return trimmed.length > 0 ? trimmed : null;
25
+ };
26
+
27
+ const isPlainObject = (value) => value !== null && typeof value === 'object' && !Array.isArray(value);
28
+
29
+ /**
30
+ * @param {import('express').Express} app
31
+ * @param {object} deps
32
+ * @param {{ get: Function, setSessionMetadata: Function }} deps.sessionMetadataStore
33
+ * @param {{ setArchive: Function } | null} [deps.sessionArchiveService]
34
+ * @param {(event: { type: string, properties: object }) => void} [deps.broadcastGlobalUiEvent]
35
+ * @param {(event: { sessionID: string, directory: string, metadata: object }) => void} [deps.onMetadataWritten]
36
+ */
37
+ export const registerSessionMetadataRoutes = (app, deps = {}) => {
38
+ const {
39
+ sessionMetadataStore = null,
40
+ sessionArchiveService = null,
41
+ broadcastGlobalUiEvent = null,
42
+ onMetadataWritten = null,
43
+ } = deps;
44
+
45
+ if (!sessionMetadataStore || typeof sessionMetadataStore.setSessionMetadata !== 'function') {
46
+ throw new Error('registerSessionMetadataRoutes requires a sessionMetadataStore');
47
+ }
48
+
49
+ const putMetadata = async (req, res) => {
50
+ const sessionId = asNonEmptyString(req.params?.sessionId);
51
+ if (!sessionId) {
52
+ return res.status(400).json({ error: 'a session id is required' });
53
+ }
54
+
55
+ const body = req.body && typeof req.body === 'object' && !Array.isArray(req.body) ? req.body : {};
56
+ const patch = body.patch;
57
+ if (!isPlainObject(patch)) {
58
+ return res.status(400).json({ error: 'patch must be an object' });
59
+ }
60
+
61
+ try {
62
+ // Goal pause/resume/condition writes must advance executionGeneration so
63
+ // in-flight audits lose commit rights. Normalize inside the exclusive
64
+ // mutate boundary (same lock as persist) for UI merge-patches.
65
+ let metadata;
66
+ if (
67
+ typeof sessionMetadataStore.mutateSessionMetadata === 'function'
68
+ && isPlainObject(patch.openchamber)
69
+ && Object.prototype.hasOwnProperty.call(patch.openchamber, 'goal')
70
+ && isPlainObject(patch.openchamber.goal)
71
+ ) {
72
+ const result = await sessionMetadataStore.mutateSessionMetadata(sessionId, (current) => {
73
+ const previousGoal = isPlainObject(current?.openchamber?.goal)
74
+ ? current.openchamber.goal
75
+ : null;
76
+ return {
77
+ ok: true,
78
+ patch: {
79
+ ...patch,
80
+ openchamber: {
81
+ ...patch.openchamber,
82
+ goal: withGoalExecutionGeneration(previousGoal, patch.openchamber.goal),
83
+ },
84
+ },
85
+ };
86
+ });
87
+ if (!result?.committed) {
88
+ throw new Error(result?.reason || 'session metadata mutate was rejected');
89
+ }
90
+ metadata = result.metadata;
91
+ } else {
92
+ metadata = await sessionMetadataStore.setSessionMetadata(sessionId, patch);
93
+ }
94
+ const directory = asNonEmptyString(body.directory) || '';
95
+ if (typeof onMetadataWritten === 'function') {
96
+ try {
97
+ onMetadataWritten({ sessionID: sessionId, directory, metadata });
98
+ } catch (error) {
99
+ console.warn('[session-metadata] metadata listener failed:', error?.message ?? error);
100
+ }
101
+ }
102
+ if (typeof broadcastGlobalUiEvent === 'function') {
103
+ try {
104
+ broadcastGlobalUiEvent({
105
+ type: 'openchamber:session-metadata',
106
+ properties: { sessionID: sessionId, metadata },
107
+ });
108
+ } catch (error) {
109
+ console.warn('[session-metadata] broadcast failed:', error?.message ?? error);
110
+ }
111
+ }
112
+ return res.json({ metadata });
113
+ } catch (error) {
114
+ const message = error instanceof Error ? error.message : 'Failed to store session metadata';
115
+ // Load/read failure must not be answered as empty success — clients must
116
+ // not treat a refused write as cleared metadata.
117
+ const status = /could not be read|unavailable/i.test(message) ? 503 : 500;
118
+ console.error('[session-metadata] failed to store session metadata:', message);
119
+ return res.status(status).json({ error: message });
120
+ }
121
+ };
122
+
123
+ const putArchive = async (req, res) => {
124
+ if (!sessionArchiveService || typeof sessionArchiveService.setArchive !== 'function') {
125
+ return res.status(503).json({ error: 'session archive is not configured' });
126
+ }
127
+
128
+ const sessionId = asNonEmptyString(req.params?.sessionId);
129
+ if (!sessionId) {
130
+ return res.status(400).json({ error: 'a session id is required' });
131
+ }
132
+
133
+ const body = req.body && typeof req.body === 'object' && !Array.isArray(req.body) ? req.body : {};
134
+ if (typeof body.archivedAt !== 'number' || !Number.isFinite(body.archivedAt)) {
135
+ return res.status(400).json({ error: 'archivedAt must be a finite number' });
136
+ }
137
+
138
+ try {
139
+ const result = await sessionArchiveService.setArchive({
140
+ sessionID: sessionId,
141
+ archivedAt: body.archivedAt,
142
+ directory: asNonEmptyString(body.directory) || undefined,
143
+ });
144
+ // Metadata is committed; index may report retryable failure separately.
145
+ return res.json({
146
+ session: result.session,
147
+ ...(result.index ? { index: result.index } : {}),
148
+ });
149
+ } catch (error) {
150
+ if (error instanceof SessionArchiveError) {
151
+ return res.status(error.status || 400).json({
152
+ error: error.message,
153
+ code: error.code,
154
+ });
155
+ }
156
+ const message = error instanceof Error ? error.message : 'Failed to archive session';
157
+ const status = /could not be read|unavailable/i.test(message) ? 503 : 500;
158
+ console.error('[session-archive] failed:', message);
159
+ return res.status(status).json({ error: message });
160
+ }
161
+ };
162
+
163
+ app.put(
164
+ '/api/openchamber/sessions/:sessionId/metadata',
165
+ express.json({ limit: '1mb' }),
166
+ putMetadata,
167
+ );
168
+
169
+ app.put(
170
+ '/api/openchamber/sessions/:sessionId/archive',
171
+ express.json({ limit: '32kb' }),
172
+ putArchive,
173
+ );
174
+ };
175
+
176
+ export { createSessionMetadataStore, mergeMetadataPatch } from './session-metadata-store.js';
177
+ export {
178
+ createSessionArchiveService,
179
+ createUpstreamSessionFetcher,
180
+ SessionArchiveError,
181
+ } from './session-archive.js';
182
+ export {
183
+ projectSessionWithHostMetadata,
184
+ projectSessionWithStoredMap,
185
+ projectSessionLifecyclePayload,
186
+ resolveProjectedArchivedAt,
187
+ readHostArchivedAt,
188
+ isSessionArchived,
189
+ normalizeSessionEventType,
190
+ extractSessionInfoFromPayload,
191
+ resolveSessionDirectory,
192
+ isSessionLifecycleEventType,
193
+ } from './session-projection.js';
@@ -0,0 +1,156 @@
1
+ import fs from 'node:fs';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+ import express from 'express';
5
+ import request from 'supertest';
6
+ import { afterEach, describe, expect, it, vi } from 'vitest';
7
+
8
+ import { createSessionMetadataStore, registerSessionMetadataRoutes } from './routes.js';
9
+
10
+ const tempDirs = [];
11
+
12
+ const makeDataDir = () => {
13
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'openchamber-metadata-routes-'));
14
+ tempDirs.push(dir);
15
+ return dir;
16
+ };
17
+
18
+ afterEach(() => {
19
+ while (tempDirs.length > 0) {
20
+ fs.rmSync(tempDirs.pop(), { recursive: true, force: true });
21
+ }
22
+ vi.restoreAllMocks();
23
+ });
24
+
25
+ const mount = (overrides = {}) => {
26
+ const store = overrides.sessionMetadataStore
27
+ ?? createSessionMetadataStore({ dataDir: makeDataDir() });
28
+ const broadcastGlobalUiEvent = overrides.broadcastGlobalUiEvent ?? vi.fn();
29
+ const app = express();
30
+ registerSessionMetadataRoutes(app, {
31
+ sessionMetadataStore: store,
32
+ sessionArchiveService: overrides.sessionArchiveService ?? null,
33
+ broadcastGlobalUiEvent,
34
+ onMetadataWritten: overrides.onMetadataWritten,
35
+ });
36
+ return { app, store, broadcastGlobalUiEvent };
37
+ };
38
+
39
+ describe('registerSessionMetadataRoutes', () => {
40
+ it('merge-patches metadata and broadcasts the full merged object', async () => {
41
+ const { app, store, broadcastGlobalUiEvent } = mount();
42
+
43
+ const first = await request(app)
44
+ .put('/api/openchamber/sessions/ses_1/metadata')
45
+ .send({ patch: { openchamber: { assist: { recap: 'a' } } } })
46
+ .expect(200);
47
+ expect(first.body.metadata).toEqual({ openchamber: { assist: { recap: 'a' } } });
48
+
49
+ const second = await request(app)
50
+ .put('/api/openchamber/sessions/ses_1/metadata')
51
+ .send({ patch: { openchamber: { goal: { status: 'active' } } }, directory: '/repo' })
52
+ .expect(200);
53
+ expect(second.body.metadata).toEqual({
54
+ openchamber: { assist: { recap: 'a' }, goal: { status: 'active', executionGeneration: 0 } },
55
+ });
56
+ await expect(store.get('ses_1')).resolves.toEqual(second.body.metadata);
57
+ expect(broadcastGlobalUiEvent).toHaveBeenLastCalledWith({
58
+ type: 'openchamber:session-metadata',
59
+ properties: { sessionID: 'ses_1', metadata: second.body.metadata },
60
+ });
61
+ });
62
+
63
+ it('notifies the metadata listener with the session directory', async () => {
64
+ const onMetadataWritten = vi.fn();
65
+ const { app } = mount({ onMetadataWritten });
66
+
67
+ await request(app)
68
+ .put('/api/openchamber/sessions/ses_2/metadata')
69
+ .send({ patch: { openchamber: { goal: { id: 'g1', status: 'active', objective: 'ship' } } }, directory: '/repo' })
70
+ .expect(200);
71
+
72
+ expect(onMetadataWritten).toHaveBeenCalledWith({
73
+ sessionID: 'ses_2',
74
+ directory: '/repo',
75
+ metadata: {
76
+ openchamber: {
77
+ goal: { id: 'g1', status: 'active', objective: 'ship', executionGeneration: 0 },
78
+ },
79
+ },
80
+ });
81
+ });
82
+
83
+ it('rejects a blank session id and a non-object patch with 400', async () => {
84
+ const { app } = mount();
85
+ await request(app)
86
+ .put('/api/openchamber/sessions/%20%20/metadata')
87
+ .send({ patch: { a: 1 } })
88
+ .expect(400);
89
+ await request(app)
90
+ .put('/api/openchamber/sessions/ses_1/metadata')
91
+ .send({})
92
+ .expect(400);
93
+ await request(app)
94
+ .put('/api/openchamber/sessions/ses_1/metadata')
95
+ .send({ patch: 'nope' })
96
+ .expect(400);
97
+ await request(app)
98
+ .put('/api/openchamber/sessions/ses_1/metadata')
99
+ .send({ patch: ['a'] })
100
+ .expect(400);
101
+ });
102
+
103
+ it('does not answer a failed store load as empty success', async () => {
104
+ const store = {
105
+ setSessionMetadata: async () => {
106
+ throw new Error('session metadata is unavailable: its file could not be read');
107
+ },
108
+ };
109
+ const { app } = mount({ sessionMetadataStore: store });
110
+ const res = await request(app)
111
+ .put('/api/openchamber/sessions/ses_1/metadata')
112
+ .send({ patch: { a: 1 } })
113
+ .expect(503);
114
+ expect(res.body).toMatchObject({ error: expect.stringMatching(/could not be read/) });
115
+ });
116
+
117
+ it('archives via PUT /archive and returns the projected session', async () => {
118
+ const setArchive = vi.fn(async ({ sessionID, archivedAt }) => ({
119
+ session: {
120
+ id: sessionID,
121
+ title: 'Alpha',
122
+ directory: '/repo',
123
+ time: { created: 1, updated: 2, archived: archivedAt },
124
+ metadata: { openchamber: { archive: { archivedAt } } },
125
+ },
126
+ }));
127
+ const { app } = mount({
128
+ sessionArchiveService: { setArchive },
129
+ });
130
+
131
+ const res = await request(app)
132
+ .put('/api/openchamber/sessions/ses_1/archive')
133
+ .send({ archivedAt: 99, directory: '/repo' })
134
+ .expect(200);
135
+
136
+ expect(setArchive).toHaveBeenCalledWith({
137
+ sessionID: 'ses_1',
138
+ archivedAt: 99,
139
+ directory: '/repo',
140
+ });
141
+ expect(res.body.session).toMatchObject({
142
+ id: 'ses_1',
143
+ time: { archived: 99 },
144
+ });
145
+ });
146
+
147
+ it('rejects archive without a finite archivedAt', async () => {
148
+ const { app } = mount({
149
+ sessionArchiveService: { setArchive: vi.fn() },
150
+ });
151
+ await request(app)
152
+ .put('/api/openchamber/sessions/ses_1/archive')
153
+ .send({})
154
+ .expect(400);
155
+ });
156
+ });
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Type surface for session-archive.js (consumed by VS Code Extension Host facades).
3
+ * Runtime implementation stays in the .js module.
4
+ */
5
+
6
+ export class SessionArchiveError extends Error {
7
+ code: string;
8
+ status: number;
9
+ constructor(code: string, message: string, status?: number);
10
+ }
11
+
12
+ export type SessionArchiveIndexResult =
13
+ | { ok: true; skipped?: boolean }
14
+ | { ok: false; error?: string; retryable?: boolean };
15
+
16
+ export type SessionForgetResult =
17
+ | { ok: true; removed: boolean }
18
+ | { ok: false; removed: false; retryable?: boolean; error?: string };
19
+
20
+ export type SessionArchiveService = {
21
+ setArchive: (input: {
22
+ sessionID: string;
23
+ archivedAt: number;
24
+ directory?: string;
25
+ }) => Promise<{
26
+ session: Record<string, unknown>;
27
+ metadata: Record<string, unknown>;
28
+ archivedAt: number;
29
+ index?: SessionArchiveIndexResult;
30
+ }>;
31
+ forgetSession: (sessionID: string) => Promise<SessionForgetResult | boolean>;
32
+ stop?: () => void;
33
+ };
34
+
35
+ export function createSessionArchiveService(deps?: {
36
+ sessionMetadataStore: {
37
+ setSessionMetadata: (
38
+ sessionID: string,
39
+ patch: object,
40
+ options?: { allowArchive?: boolean },
41
+ ) => Promise<Record<string, unknown>>;
42
+ get: (sessionID: string) => Promise<Record<string, unknown>>;
43
+ removeSession?: (sessionID: string) => Promise<boolean>;
44
+ getSnapshotSync?: () => Record<string, Record<string, unknown>> | null;
45
+ };
46
+ fetchUpstreamSession: (input: {
47
+ sessionID: string;
48
+ directory?: string | null;
49
+ }) => Promise<object | null>;
50
+ sessionIndexService?: {
51
+ upsert?: (...args: unknown[]) => unknown;
52
+ upsertAndReportChange?: (...args: unknown[]) => unknown;
53
+ remove?: (...args: unknown[]) => unknown;
54
+ } | null;
55
+ broadcastSessionEvent?: (
56
+ event: { type: string; properties: object },
57
+ options?: object,
58
+ ) => void;
59
+ onIndexChanged?: (sessionID: string) => void;
60
+ now?: () => number;
61
+ setTimer?: typeof setTimeout;
62
+ clearTimer?: typeof clearTimeout;
63
+ }): SessionArchiveService;
64
+
65
+ export function createUpstreamSessionFetcher(deps: {
66
+ buildOpenCodeUrl: (path: string) => string;
67
+ getOpenCodeAuthHeaders?: () => Record<string, string>;
68
+ fetchImpl?: typeof fetch;
69
+ timeoutMs?: number;
70
+ }): (input: {
71
+ sessionID: string;
72
+ directory?: string | null;
73
+ }) => Promise<object | null>;