@vantran-se/openchamber-web 1.24.3 → 2.0.1

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 (367) hide show
  1. package/README.md +2 -8
  2. package/bin/lib/commands-connect-url.js +3 -8
  3. package/bin/lib/commands-tunnel.js +3 -0
  4. package/dist/assets/{CodeMirrorCommentWidgets-BjJHrzmU.js → CodeMirrorCommentWidgets-ntXIbhV2.js} +1 -1
  5. package/dist/assets/DiffView-CjxUovbM.js +4 -0
  6. package/dist/assets/FilesView-DFWD0RQR.js +17 -0
  7. package/dist/assets/{GitView-CDOJy5Ay.js → GitView-BWa7e5vw.js} +4 -4
  8. package/dist/assets/{GuestAttachDialog-D3S0Rjic.js → GuestAttachDialog-DdOuyZzp.js} +1 -1
  9. package/dist/assets/GuestSurfacePane-DDfzid3U.js +1 -0
  10. package/dist/assets/{JsonTreeView-D0C9nU7K.js → JsonTreeView-3sGwqexh.js} +1 -1
  11. package/dist/assets/LinearIssuesView-C6dpIdjw.js +1 -0
  12. package/dist/assets/MarkdownImageGallery-Q7YR_tl4.js +1 -0
  13. package/dist/assets/MarkdownRendererImpl-DxDV56bL.js +12 -0
  14. package/dist/assets/OnboardingScreen-rK4Stg__.js +1 -0
  15. package/dist/assets/{PatchDiff-DnEhjXcC.js → PatchDiff-DS-IMU1j.js} +1 -1
  16. package/dist/assets/{PierreDiffViewer-DyxZVVVR.js → PierreDiffViewer-DW23KWKZ.js} +1 -1
  17. package/dist/assets/PlanView-BCk_VobP.js +5 -0
  18. package/dist/assets/PluginPane-BPP1dbck.js +3 -0
  19. package/dist/assets/SettingsView-kMmrpn43.js +29 -0
  20. package/dist/assets/SettingsWindow-BpvD6IYQ.js +1 -0
  21. package/dist/assets/SubmoduleDiffSummary-BLttSS1X.js +1 -0
  22. package/dist/assets/ToolOutputDialog-CtqDqbyr.js +15 -0
  23. package/dist/assets/ToolPartDiffPreview-5FcKdyRy.js +8 -0
  24. package/dist/assets/{VirtualizedFileDiff-0pyr_mHY.js → VirtualizedFileDiff-C763hNCR.js} +4 -4
  25. package/dist/assets/{WalkthroughView-yNj4nOP5.js → WalkthroughView-lap5btCF.js} +2 -2
  26. package/dist/assets/appThemeRegistry-u4zw1l0B.js +1 -0
  27. package/dist/assets/{commitAndPush-DvJKa3Ks.js → commitAndPush-CwGJfJG-.js} +1 -1
  28. package/dist/assets/{computeVirtualFileMetrics-DxTBMuu-.js → computeVirtualFileMetrics-DW5jjX4n.js} +1 -1
  29. package/dist/assets/de-CndEg67T.js +10 -0
  30. package/dist/assets/es-DglvPlaC.js +16 -0
  31. package/dist/assets/fr-DejPCpbS.js +14 -0
  32. package/dist/assets/index-C2r64QfD.js +1 -0
  33. package/dist/assets/index-CLcM8HKx.css +1 -0
  34. package/dist/assets/index-CvLgnuNI.js +41 -0
  35. package/dist/assets/{isDiffPlainText-D7FkBMP6.js → isDiffPlainText-D47a6hMP.js} +1 -1
  36. package/dist/assets/{isFilePlainText-CL2vsrIZ.js → isFilePlainText-B-mGgeKl.js} +1 -1
  37. package/dist/assets/ja-CVpQawCd.js +16 -0
  38. package/dist/assets/ko-Bw446h9j.js +16 -0
  39. package/dist/assets/main-Bz4WWXbr.js +2 -0
  40. package/dist/assets/main-oreqDsOV.js +896 -0
  41. package/dist/assets/{markdownCore-Dh7WEsdM.js → markdownCore-D2e5sp9y.js} +4 -4
  42. package/dist/assets/miniChat-D1v2gsBI.js +2 -0
  43. package/dist/assets/mobile-DBj3lCf2.js +2 -0
  44. package/dist/assets/{patchFileDiff-Bsba8KFp.js → patchFileDiff-BpeUOV91.js} +3 -3
  45. package/dist/assets/pl-BYNlPdhm.js +16 -0
  46. package/dist/assets/pt-BR-CL-Yfv9H.js +16 -0
  47. package/dist/assets/renderElectronMiniChatApp-DVtfEB2z.js +2 -0
  48. package/dist/assets/renderMobileApp-DFp9-xbG.js +25 -0
  49. package/dist/assets/runtimeEndpointReset-CsIpUep1.js +27 -0
  50. package/dist/assets/scheduledTasksApi-B5OHVpPM.js +1 -0
  51. package/dist/assets/{shikiHighlight-8_3csmr6.js → shikiHighlight-DNm2Z_Jc.js} +1 -1
  52. package/dist/assets/{textMateThemeFromAppTheme-CHo2fCgW.js → textMateThemeFromAppTheme-DGF2kG7g.js} +1 -1
  53. package/dist/assets/tr-DzmbxLy-.js +7 -0
  54. package/dist/assets/uk-C7vQnwro.js +16 -0
  55. package/dist/assets/useAppFontEffects-Ci3FEaPf.js +7337 -0
  56. package/dist/assets/{useInlineCommentController-DkQ_gqpn.js → useInlineCommentController-CuUuakrt.js} +2 -2
  57. package/dist/assets/useRootScrollLock-CQIsyERq.js +2 -0
  58. package/dist/assets/{vendor-codemirror-language-data-CdzUmUyZ.js → vendor-codemirror-language-data-CQa7_1cr.js} +2 -2
  59. package/dist/assets/vendor-cron-parser-CjvYVigk.js +2 -0
  60. package/dist/assets/vendor-opencode-client-_BAHQo4R.js +12 -0
  61. package/dist/assets/{vendor-remixicon-react-BDmGmFCA.js → vendor-remixicon-react-D6dZ0UwF.js} +1 -1
  62. package/dist/assets/{vendor-zod-CgAdXWZO.js → vendor-zod-Gea9uBlY.js} +1 -1
  63. package/dist/assets/{web-components-B8IcVQAA.js → web-components-B6tKQyJN.js} +2 -2
  64. package/dist/assets/zh-CN-Cl0srS-z.js +16 -0
  65. package/dist/assets/zh-TW-DtII5bDb.js +16 -0
  66. package/dist/index.html +13 -7
  67. package/dist/mini-chat.html +5 -5
  68. package/dist/mobile.html +5 -5
  69. package/package.json +6 -5
  70. package/server/index.d.ts +1 -0
  71. package/server/index.js +246 -91
  72. package/server/lib/agent-tool/DOCUMENTATION.md +32 -15
  73. package/server/lib/agent-tool/runtime.js +135 -54
  74. package/server/lib/agent-tool/runtime.test.js +155 -87
  75. package/server/lib/browser-control/DOCUMENTATION.md +37 -2
  76. package/server/lib/browser-control/provider.js +217 -0
  77. package/server/lib/browser-control/provider.test.js +251 -0
  78. package/server/lib/context-obligatory/runtime.js +61 -50
  79. package/server/lib/context-obligatory/runtime.test.js +62 -162
  80. package/server/lib/event-stream/DOCUMENTATION.md +12 -1
  81. package/server/lib/event-stream/delta-coalescer.js +0 -0
  82. package/server/lib/event-stream/delta-coalescer.test.js +68 -57
  83. package/server/lib/event-stream/directory-ws-bridge.js +1 -1
  84. package/server/lib/event-stream/global-hub.js +10 -1
  85. package/server/lib/event-stream/global-hub.test.js +27 -26
  86. package/server/lib/event-stream/index.js +6 -0
  87. package/server/lib/event-stream/protocol.js +26 -19
  88. package/server/lib/event-stream/protocol.test.js +18 -7
  89. package/server/lib/event-stream/rebind.test.js +5 -5
  90. package/server/lib/event-stream/runtime.test.js +17 -15
  91. package/server/lib/event-stream/translate-v2.js +313 -0
  92. package/server/lib/event-stream/translate-v2.test.js +209 -0
  93. package/server/lib/event-stream/upstream-reader.test.js +16 -16
  94. package/server/lib/fs/DOCUMENTATION.md +4 -2
  95. package/server/lib/fs/byte-range.js +35 -0
  96. package/server/lib/fs/byte-range.test.js +31 -0
  97. package/server/lib/fs/routes.js +47 -42
  98. package/server/lib/fs/routes.test.js +123 -18
  99. package/server/lib/git/service.js +12 -0
  100. package/server/lib/github/DOCUMENTATION.md +1 -1
  101. package/server/lib/github/pr-status.js +22 -2
  102. package/server/lib/github/pr-status.test.js +27 -14
  103. package/server/lib/guests/DOCUMENTATION.md +13 -0
  104. package/server/lib/guests/catalog.js +12 -0
  105. package/server/lib/guests/catalog.test.js +33 -0
  106. package/server/lib/guests/routes.js +10 -1
  107. package/server/lib/guests/service.js +192 -14
  108. package/server/lib/guests/service.test.js +201 -1
  109. package/server/lib/guests/surface.js +630 -0
  110. package/server/lib/guests/surface.test.js +486 -0
  111. package/server/lib/markdown-image-grants/routes.js +18 -5
  112. package/server/lib/markdown-image-grants/routes.test.js +9 -6
  113. package/server/lib/message-queue/DOCUMENTATION.md +33 -22
  114. package/server/lib/message-queue/runtime.js +155 -100
  115. package/server/lib/message-queue/runtime.test.js +168 -82
  116. package/server/lib/notifications/DOCUMENTATION.md +28 -0
  117. package/server/lib/notifications/control-stream.http.test.js +68 -0
  118. package/server/lib/notifications/emitter-runtime.js +15 -0
  119. package/server/lib/notifications/emitter-runtime.test.js +32 -0
  120. package/server/lib/notifications/push-runtime.js +5 -1
  121. package/server/lib/notifications/push-runtime.test.js +2 -2
  122. package/server/lib/notifications/routes.js +1 -1
  123. package/server/lib/notifications/runtime.js +115 -26
  124. package/server/lib/notifications/template-runtime.js +13 -15
  125. package/server/lib/notifications/template-runtime.test.js +16 -9
  126. package/server/lib/notifications/trigger-runtime.test.js +187 -0
  127. package/server/lib/openchamber-control/DOCUMENTATION.md +10 -0
  128. package/server/lib/openchamber-control/actions.js +3 -2
  129. package/server/lib/openchamber-control/error.js +1 -1
  130. package/server/lib/openchamber-control/file-open.js +59 -0
  131. package/server/lib/openchamber-control/file-open.test.js +57 -0
  132. package/server/lib/openchamber-control/routes.test.js +12 -0
  133. package/server/lib/openchamber-control/service.js +102 -49
  134. package/server/lib/openchamber-control/service.test.js +84 -44
  135. package/server/lib/openchamber-sessions/archive-store.js +224 -0
  136. package/server/lib/openchamber-sessions/archive-store.test.js +187 -0
  137. package/server/lib/openchamber-sessions/opencode-client.js +22 -0
  138. package/server/lib/openchamber-sessions/routes.js +398 -328
  139. package/server/lib/openchamber-sessions/routes.test.js +777 -740
  140. package/server/lib/openchamber-sessions/session-metadata-store.js +285 -0
  141. package/server/lib/openchamber-sessions/session-metadata-store.test.js +259 -0
  142. package/server/lib/opencode/DOCUMENTATION.md +449 -29
  143. package/server/lib/opencode/agents.js +233 -327
  144. package/server/lib/opencode/auth.js +41 -44
  145. package/server/lib/opencode/auth.test.js +92 -0
  146. package/server/lib/opencode/cli-upgrade.d.ts +4 -0
  147. package/server/lib/opencode/cli-upgrade.js +18 -0
  148. package/server/lib/opencode/cli-upgrade.test.js +36 -0
  149. package/server/lib/opencode/commands.js +164 -145
  150. package/server/lib/opencode/compatibility.d.ts +16 -0
  151. package/server/lib/opencode/compatibility.js +88 -0
  152. package/server/lib/opencode/compatibility.test.js +62 -0
  153. package/server/lib/opencode/config-entity-routes.js +58 -29
  154. package/server/lib/opencode/config-entity-v2.test.js +290 -0
  155. package/server/lib/opencode/config-mutation-response.js +17 -7
  156. package/server/lib/opencode/config-mutation-response.test.js +4 -7
  157. package/server/lib/opencode/config-paths.test.js +2 -2
  158. package/server/lib/opencode/config-v2.d.ts +183 -0
  159. package/server/lib/opencode/config-v2.js +801 -0
  160. package/server/lib/opencode/config-v2.test.js +466 -0
  161. package/server/lib/opencode/credential-db.js +144 -0
  162. package/server/lib/opencode/credential-db.test.js +104 -0
  163. package/server/lib/opencode/env-runtime.js +48 -9
  164. package/server/lib/opencode/env-runtime.test.js +45 -0
  165. package/server/lib/opencode/feature-routes-runtime.js +15 -5
  166. package/server/lib/opencode/lifecycle-process.test.js +7 -4
  167. package/server/lib/opencode/lifecycle.js +85 -30
  168. package/server/lib/opencode/lifecycle.test.js +80 -8
  169. package/server/lib/opencode/login-shell-env.js +27 -0
  170. package/server/lib/opencode/managed-config-file.js +119 -0
  171. package/server/lib/opencode/managed-config-file.test.js +152 -0
  172. package/server/lib/opencode/managed-plugin-config.js +33 -13
  173. package/server/lib/opencode/mcp.js +43 -149
  174. package/server/lib/opencode/network-runtime.js +6 -7
  175. package/server/lib/opencode/openchamber-routes.test.js +2 -5
  176. package/server/lib/opencode/plugin-routes.js +3 -3
  177. package/server/lib/opencode/plugin-routes.test.js +6 -24
  178. package/server/lib/opencode/plugins.js +91 -40
  179. package/server/lib/opencode/plugins.test.js +28 -15
  180. package/server/lib/opencode/providers.js +63 -83
  181. package/server/lib/opencode/providers.test.js +128 -59
  182. package/server/lib/opencode/proxy-agent-wiring.test.js +4 -2
  183. package/server/lib/opencode/proxy.js +179 -129
  184. package/server/lib/opencode/pwa-manifest-routes.js +4 -2
  185. package/server/lib/opencode/pwa-manifest-routes.test.js +3 -2
  186. package/server/lib/opencode/response-envelope.js +14 -0
  187. package/server/lib/opencode/response-envelope.test.js +23 -0
  188. package/server/lib/opencode/routes-upgrade.test.js +73 -116
  189. package/server/lib/opencode/routes.js +121 -428
  190. package/server/lib/opencode/server-utils-runtime.js +10 -4
  191. package/server/lib/opencode/session-activity.js +78 -0
  192. package/server/lib/opencode/session-runtime.js +21 -10
  193. package/server/lib/opencode/session-runtime.test.js +9 -9
  194. package/server/lib/opencode/settings-helpers.js +9 -9
  195. package/server/lib/opencode/settings-helpers.test.js +7 -12
  196. package/server/lib/opencode/settings-registry.json +6 -8
  197. package/server/lib/opencode/settings-runtime.js +18 -1
  198. package/server/lib/opencode/settings-runtime.test.js +31 -2
  199. package/server/lib/opencode/shared.js +54 -22
  200. package/server/lib/opencode/shared.test.js +8 -4
  201. package/server/lib/opencode/shutdown-runtime.js +54 -7
  202. package/server/lib/opencode/shutdown-runtime.test.js +224 -30
  203. package/server/lib/opencode/skill-routes.js +23 -24
  204. package/server/lib/opencode/skills.js +7 -5
  205. package/server/lib/opencode/tunnel-wiring-runtime.js +2 -1
  206. package/server/lib/opencode/upgrade-capability.test.js +1 -1
  207. package/server/lib/opencode/v1-migration-topup.js +288 -0
  208. package/server/lib/opencode/v1-migration-topup.test.js +266 -0
  209. package/server/lib/opencode/v2-install.d.ts +8 -0
  210. package/server/lib/opencode/v2-install.js +158 -0
  211. package/server/lib/opencode/v2-install.test.js +124 -0
  212. package/server/lib/opencode/watcher.js +10 -3
  213. package/server/lib/opencode/watcher.test.js +17 -21
  214. package/server/lib/opencode/websearch-config.js +66 -0
  215. package/server/lib/package-manager.js +55 -68
  216. package/server/lib/package-manager.test.js +241 -75
  217. package/server/lib/permission-auto-accept/runtime.js +38 -22
  218. package/server/lib/permission-auto-accept/runtime.test.js +39 -17
  219. package/server/lib/quota/DOCUMENTATION.md +4 -0
  220. package/server/lib/quota/providers/xai.js +4 -4
  221. package/server/lib/relay/tunnel-host.js +4 -1
  222. package/server/lib/relay/tunnel-host.test.js +7 -0
  223. package/server/lib/routing/DOCUMENTATION.md +52 -21
  224. package/server/lib/routing/defaults.js +23 -6
  225. package/server/lib/routing/jev.js +17 -7
  226. package/server/lib/routing/routes.http.test.js +68 -33
  227. package/server/lib/routing/routes.js +65 -22
  228. package/server/lib/routing/runtime.js +145 -48
  229. package/server/lib/routing/runtime.test.js +79 -55
  230. package/server/lib/scheduled-tasks/DOCUMENTATION.md +4 -0
  231. package/server/lib/scheduled-tasks/issue-2710-double-execution.test.js +51 -46
  232. package/server/lib/scheduled-tasks/runtime.js +81 -74
  233. package/server/lib/scheduled-tasks/runtime.test.js +53 -1
  234. package/server/lib/session-assist/DOCUMENTATION.md +8 -3
  235. package/server/lib/session-assist/context.js +122 -46
  236. package/server/lib/session-assist/context.test.js +117 -49
  237. package/server/lib/session-assist/runtime.js +52 -22
  238. package/server/lib/session-assist/runtime.test.js +145 -173
  239. package/server/lib/session-goal/DOCUMENTATION.md +23 -15
  240. package/server/lib/session-goal/create.js +9 -12
  241. package/server/lib/session-goal/create.test.js +27 -28
  242. package/server/lib/session-goal/runtime.js +164 -77
  243. package/server/lib/session-goal/runtime.test.js +271 -519
  244. package/server/lib/session-knowledge/DOCUMENTATION.md +5 -0
  245. package/server/lib/session-knowledge/runtime.js +59 -41
  246. package/server/lib/session-knowledge/runtime.test.js +90 -20
  247. package/server/lib/small-model/DOCUMENTATION.md +154 -208
  248. package/server/lib/small-model/client.js +113 -0
  249. package/server/lib/small-model/index.js +296 -158
  250. package/server/lib/small-model/index.test.js +423 -256
  251. package/server/lib/small-model/routes.js +1 -1
  252. package/server/lib/spaces/DOCUMENTATION.md +807 -0
  253. package/server/lib/spaces/code-in-bait.js +185 -0
  254. package/server/lib/spaces/code-in.js +641 -0
  255. package/server/lib/spaces/code-in.test.js +1048 -0
  256. package/server/lib/spaces/errors.js +8 -0
  257. package/server/lib/spaces/exec-http.js +94 -0
  258. package/server/lib/spaces/gatekeeper-channel.js +202 -0
  259. package/server/lib/spaces/gatekeeper-channel.test.js +215 -0
  260. package/server/lib/spaces/gatekeeper-program.cjs +914 -0
  261. package/server/lib/spaces/gatekeeper-program.test.js +1391 -0
  262. package/server/lib/spaces/hardening.js +457 -0
  263. package/server/lib/spaces/hardening.test.js +368 -0
  264. package/server/lib/spaces/host-git.js +127 -0
  265. package/server/lib/spaces/host-git.test.js +137 -0
  266. package/server/lib/spaces/labels.js +234 -0
  267. package/server/lib/spaces/labels.test.js +219 -0
  268. package/server/lib/spaces/layout.js +184 -0
  269. package/server/lib/spaces/layout.test.js +30 -0
  270. package/server/lib/spaces/manager.js +82 -0
  271. package/server/lib/spaces/manager.test.js +114 -0
  272. package/server/lib/spaces/places/code-in.docker.live.test.js +216 -0
  273. package/server/lib/spaces/places/contract-suite.js +156 -0
  274. package/server/lib/spaces/places/contract.docker.live.test.js +7 -0
  275. package/server/lib/spaces/places/contract.test.js +6 -0
  276. package/server/lib/spaces/places/docker-engine.js +126 -0
  277. package/server/lib/spaces/places/docker-live-support.js +202 -0
  278. package/server/lib/spaces/places/docker-tools.js +186 -0
  279. package/server/lib/spaces/places/docker.js +587 -0
  280. package/server/lib/spaces/places/docker.test.js +1610 -0
  281. package/server/lib/spaces/places/escape-suite.js +1018 -0
  282. package/server/lib/spaces/places/escape.docker.live.test.js +7 -0
  283. package/server/lib/spaces/places/fake-docker.js +375 -0
  284. package/server/lib/spaces/places/memory-place.js +103 -0
  285. package/server/lib/spaces/places/packed.docker.live.test.js +77 -0
  286. package/server/lib/spaces/places/registry.js +43 -0
  287. package/server/lib/spaces/places/registry.test.js +50 -0
  288. package/server/lib/spaces/places/server.docker.live.test.js +225 -0
  289. package/server/lib/spaces/run-command.js +261 -0
  290. package/server/lib/spaces/run-command.test.js +396 -0
  291. package/server/lib/spaces/space-server.js +190 -0
  292. package/server/lib/spaces/space-server.test.js +335 -0
  293. package/server/lib/spaces/tools-filler.js +82 -0
  294. package/server/lib/spaces/tools-filler.test.js +148 -0
  295. package/server/lib/spaces/tools-pack.js +49 -0
  296. package/server/lib/spaces/tools-pack.test.js +57 -0
  297. package/server/lib/spaces/tools.js +138 -0
  298. package/server/lib/spaces/tools.test.js +153 -0
  299. package/server/lib/tts/openai-sdk.js +11 -0
  300. package/server/lib/tts/service.js +7 -5
  301. package/server/lib/tts/stt.js +3 -2
  302. package/server/lib/tunnels/DOCUMENTATION.md +2 -0
  303. package/server/lib/tunnels/routes.js +7 -0
  304. package/server/lib/tunnels/routes.test.js +55 -0
  305. package/server/lib/ui-auth/ui-auth.js +38 -2
  306. package/server/lib/ui-auth/ui-auth.test.js +42 -0
  307. package/server/lib/ui-auth/ui-passkeys.js +12 -10
  308. package/server/lib/walkthrough/DOCUMENTATION.md +10 -1
  309. package/server/lib/walkthrough/pull-request.js +61 -8
  310. package/server/lib/walkthrough/pull-request.test.js +54 -1
  311. package/server/lib/walkthrough/routes.js +20 -0
  312. package/server/lib/walkthrough/routes.test.js +19 -0
  313. package/server/opencode-proxy.test.js +190 -166
  314. package/server/opencode-worktree-readiness.test.js +5 -4
  315. package/dist/assets/DiffView-COVQhWGd.js +0 -4
  316. package/dist/assets/FilesView-B1V5JxFX.js +0 -13
  317. package/dist/assets/LinearIssuesView-D7FKg1XJ.js +0 -1
  318. package/dist/assets/MarkdownImageGallery-BrFjAVEf.js +0 -1
  319. package/dist/assets/MarkdownRendererImpl-DWepTafh.js +0 -12
  320. package/dist/assets/OnboardingScreen-Dyxxiqdt.js +0 -1
  321. package/dist/assets/PlanView-LW2z_EAP.js +0 -5
  322. package/dist/assets/PluginPane-B4tKno2h.js +0 -3
  323. package/dist/assets/SettingsView-DEaMulN9.js +0 -29
  324. package/dist/assets/SettingsWindow-FLDJXOgQ.js +0 -1
  325. package/dist/assets/SubmoduleDiffSummary-CvVwD-Vi.js +0 -1
  326. package/dist/assets/ToolOutputDialog-BiP0x2Rw.js +0 -15
  327. package/dist/assets/ToolPartDiffPreview-CkR4msKP.js +0 -8
  328. package/dist/assets/appThemeRegistry-BuUKhbYQ.js +0 -1
  329. package/dist/assets/de-DgxgFyGG.js +0 -10
  330. package/dist/assets/es-BFsZj5F_.js +0 -16
  331. package/dist/assets/fr-jdZ5KKQi.js +0 -14
  332. package/dist/assets/index-CKHjPKbq.js +0 -1
  333. package/dist/assets/index-Cbci4i1W.js +0 -40
  334. package/dist/assets/index-DqaMWNrC.css +0 -1
  335. package/dist/assets/ja-C5kKrhO4.js +0 -16
  336. package/dist/assets/ko-DXDTT_0O.js +0 -16
  337. package/dist/assets/main-CZALtVek.js +0 -896
  338. package/dist/assets/main-CgXMBNvG.js +0 -2
  339. package/dist/assets/miniChat-CwTmDixi.js +0 -2
  340. package/dist/assets/mobile-CLf2vCtO.js +0 -2
  341. package/dist/assets/pl-D-7x4Y8Q.js +0 -16
  342. package/dist/assets/pt-BR-CSBZrHa8.js +0 -16
  343. package/dist/assets/renderElectronMiniChatApp-C5gAFBk0.js +0 -2
  344. package/dist/assets/renderMobileApp-V4hYd32H.js +0 -25
  345. package/dist/assets/runtimeEndpointReset-DhlHCn-2.js +0 -25
  346. package/dist/assets/scheduledTasksApi-DzjbLd8P.js +0 -1
  347. package/dist/assets/tr-Dr-oJ22L.js +0 -7
  348. package/dist/assets/uk-9Nx83UcI.js +0 -16
  349. package/dist/assets/useAppFontEffects-khZXpFL_.js +0 -7333
  350. package/dist/assets/useRootScrollLock-DdvHf9Pt.js +0 -2
  351. package/dist/assets/vendor-cron-parser-CUcP7OfX.js +0 -2
  352. package/dist/assets/vendor-opencode-sdk-BJ73u-bH.js +0 -7
  353. package/dist/assets/zh-CN-Bxy_Hj3r.js +0 -16
  354. package/dist/assets/zh-TW-0BB4gpHM.js +0 -16
  355. package/server/lib/opencode/mcp-oauth-callback.test.js +0 -111
  356. package/server/lib/routing/feature-flag.js +0 -11
  357. package/server/lib/small-model/call.js +0 -851
  358. package/server/lib/small-model/call.test.js +0 -1292
  359. package/server/lib/small-model/catalog.js +0 -13
  360. package/server/lib/small-model/resolve.js +0 -131
  361. package/server/lib/small-model/resolve.test.js +0 -197
  362. package/server/lib/small-model/runtime-providers.js +0 -164
  363. package/server/lib/small-model/runtime-providers.test.js +0 -118
  364. package/server/lib/system-prompt/DOCUMENTATION.md +0 -36
  365. package/server/lib/system-prompt/runtime.js +0 -49
  366. package/server/lib/system-prompt/runtime.test.js +0 -76
  367. package/server/lib/walkthrough/reproduce-2607.test.js +0 -148
@@ -20,6 +20,8 @@ import path from 'path';
20
20
 
21
21
  import { GOAL_OBJECTIVE_CHAR_LIMIT, readObjective } from './objectives.js';
22
22
  import { readMergedSettingsSync } from '../opencode/settings-files.js';
23
+ import { createSessionActivityProbe } from '../opencode/session-activity.js';
24
+ import { unwrapOpenCodeResponse } from '../opencode/response-envelope.js';
23
25
 
24
26
  const OPENCHAMBER_SETTINGS_FILE = path.join(
25
27
  process.env.OPENCHAMBER_DATA_DIR
@@ -158,24 +160,29 @@ const extractSessionStatus = (payload) => {
158
160
  return { sessionId, type, directory };
159
161
  };
160
162
 
161
- // A user abort lands as an assistant message carrying MessageAbortedError.
163
+ /**
164
+ * A user abort no longer lands as an assistant message carrying
165
+ * `MessageAbortedError`: v2 reports `session.execution.interrupted`, which the
166
+ * translator turns into `session.idle` with `aborted: true`.
167
+ */
162
168
  const extractAbortedAssistant = (payload) => {
163
- if (!payload || payload.type !== 'message.updated') return null;
164
- const info = payload.properties?.info;
165
- if (!info || typeof info !== 'object' || info.role !== 'assistant') return null;
166
- if (info.error?.name !== 'MessageAbortedError') return null;
167
- if (typeof info.sessionID !== 'string' || !info.sessionID) return null;
168
- return { sessionId: info.sessionID };
169
+ if (!payload || payload.type !== 'session.idle') return null;
170
+ const properties = payload.properties;
171
+ if (!properties || typeof properties !== 'object' || properties.aborted !== true) return null;
172
+ if (typeof properties.sessionID !== 'string' || !properties.sessionID) return null;
173
+ return { sessionId: properties.sessionID };
169
174
  };
170
175
 
171
176
  const extractSessionUpdate = (payload) => {
172
177
  if (!payload || payload.type !== 'session.updated') return null;
173
178
  const info = payload.properties?.info;
174
179
  if (!info || typeof info !== 'object' || typeof info.id !== 'string' || !info.id) return null;
180
+ // No goal here any more: the record OpenCode publishes carries only what
181
+ // OpenCode owns, and the goal lives in OpenChamber's own metadata store. A
182
+ // new or resumed goal reaches this runtime through `notifyGoalChanged`.
175
183
  return {
176
184
  sessionId: info.id,
177
185
  directory: typeof info.directory === 'string' ? info.directory : '',
178
- goal: parseGoalMetadata(info),
179
186
  parentID: typeof info.parentID === 'string' ? info.parentID : '',
180
187
  };
181
188
  };
@@ -216,6 +223,67 @@ const parseGoalMetadata = (session) => {
216
223
  };
217
224
  };
218
225
 
226
+ /**
227
+ * The loop reads the v1 view of a message — `{ info, parts }` with
228
+ * `info.role`, `info.summary`, `info.time`, `info.tokens`, `info.error`,
229
+ * `info.finish`, `info.providerID` / `modelID` / `agent` / `variant` — and v2
230
+ * records are flat: `type` instead of `role`, `content[]` instead of `parts`,
231
+ * `model.{providerID,id}`, and a compaction turn is its own `compaction` type
232
+ * rather than an assistant message flagged `summary`. This is the only place
233
+ * that knows both shapes. Roles the loop does not reason about (system,
234
+ * skill, shell, switches, idle) are dropped; a `synthetic` message folds into
235
+ * the user role so a trailing context item still reads as "user just sent".
236
+ */
237
+ const toLoopMessage = (message) => {
238
+ const id = String(message?.id ?? '');
239
+ if (!id) return null;
240
+ const time = message.time && !Array.isArray(message.time) ? { ...message.time } : {};
241
+ const base = { id, sessionID: message.sessionID, time };
242
+ switch (message.type) {
243
+ case 'user':
244
+ case 'synthetic':
245
+ return {
246
+ info: { ...base, role: 'user' },
247
+ parts: message.text ? [{ type: 'text', text: String(message.text) }] : [],
248
+ };
249
+ case 'assistant': {
250
+ const model = message.model ?? {};
251
+ // v1 errors carried `name`; v2's structured error calls it `type`.
252
+ const error = message.error ? { name: message.error.type, ...message.error } : undefined;
253
+ return {
254
+ info: {
255
+ ...base,
256
+ role: 'assistant',
257
+ summary: false,
258
+ agent: message.agent,
259
+ providerID: model.providerID,
260
+ modelID: model.id,
261
+ variant: model.variant,
262
+ finish: message.finish,
263
+ tokens: message.tokens,
264
+ error,
265
+ },
266
+ parts: (Array.isArray(message.content) ? message.content : [])
267
+ .filter((part) => part?.type === 'text' && part.text)
268
+ .map((part) => ({ type: 'text', text: String(part.text) })),
269
+ };
270
+ }
271
+ case 'compaction': {
272
+ // A finished compaction plays the part of v1's `summary: true` assistant
273
+ // turn: it closes a token segment and is never audited or continued
274
+ // from. Its model must not be inherited either (v1: "the compaction
275
+ // summary carries the summarize model").
276
+ if (message.status !== 'completed') return null;
277
+ return {
278
+ info: { ...base, role: 'assistant', summary: true, tokens: message.tokens, finish: 'stop' },
279
+ parts: message.summary ? [{ type: 'text', text: String(message.summary) }] : [],
280
+ };
281
+ }
282
+ default:
283
+ return null;
284
+ }
285
+ };
286
+
219
287
  const messagePartsToText = (message) => {
220
288
  const parts = Array.isArray(message?.parts) ? message.parts : [];
221
289
  return parts
@@ -299,6 +367,8 @@ export const createSessionGoalRuntime = ({
299
367
  idleQuietMs = IDLE_QUIET_MS,
300
368
  kickoffQuietMs = KICKOFF_QUIET_MS,
301
369
  maxAutoTurns = MAX_AUTO_TURNS,
370
+ persistSessionGoal = null,
371
+ readSessionMetadata = null,
302
372
  }) => {
303
373
  const timers = new Map();
304
374
  const inflight = new Set();
@@ -331,53 +401,45 @@ export const createSessionGoalRuntime = ({
331
401
  if (!response.ok) {
332
402
  throw new Error(`OpenCode ${method} ${fetchPath} failed with ${response.status}`);
333
403
  }
334
- return response.json().catch(() => null);
404
+ return unwrapOpenCodeResponse(await response.json().catch(() => null));
335
405
  };
336
406
 
337
407
  const fetchRecentMessages = async (sessionId, directory) => {
338
- const messages = await openCodeFetch(`/session/${encodeURIComponent(sessionId)}/message`, {
408
+ // v2 pages messages as `{ data, cursor }`, newest first.
409
+ const page = await openCodeFetch(`/api/session/${encodeURIComponent(sessionId)}/message`, {
339
410
  directory,
340
411
  query: { limit: String(MESSAGE_FETCH_LIMIT) },
341
412
  }).catch(() => null);
342
- return Array.isArray(messages) ? messages : null;
343
- };
344
-
345
- const fetchSessionStatuses = async (directory) => {
346
- const statuses = await openCodeFetch('/session/status', { directory }).catch(() => null);
347
- return statuses && typeof statuses === 'object' && !Array.isArray(statuses) ? statuses : null;
413
+ const messages = page && typeof page === 'object' ? page.data : null;
414
+ if (!Array.isArray(messages)) return null;
415
+ return messages.map(toLoopMessage).filter(Boolean).reverse();
348
416
  };
349
417
 
350
- const fetchSessionChildren = async (sessionId, directory) => {
351
- const children = await openCodeFetch(`/session/${encodeURIComponent(sessionId)}/children`, { directory })
352
- .catch(() => null);
353
- return Array.isArray(children) ? children : null;
354
- };
418
+ const activityProbe = createSessionActivityProbe({
419
+ buildOpenCodeUrl,
420
+ getOpenCodeAuthHeaders,
421
+ timeoutMs: FETCH_TIMEOUT_MS,
422
+ });
355
423
 
356
- const isWorkingStatus = (status) => status?.type === 'busy' || status?.type === 'retry';
424
+ // v2 reports only that a session is running.
425
+ const isWorkingStatus = (status) => Boolean(status);
357
426
 
358
427
  // Merge-write the goal payload from a FRESH session read so concurrent
359
428
  // metadata writes (assist payloads, dismissals, UI goal edits) survive.
360
429
  // Returns the written goal, or null when the stored goal no longer matches
361
430
  // the expected id (user replaced/cleared it while we worked).
431
+ /**
432
+ * The goal lives in OpenChamber's own metadata store: OpenCode 2.x accepts
433
+ * session metadata only at create time. Re-read before every write so a
434
+ * concurrent edit (the user pausing from the UI) is not overwritten.
435
+ */
436
+ const readGoal = async (sessionId) => parseGoalMetadata({ metadata: await readSessionMetadata(sessionId) });
437
+
362
438
  const writeGoal = async (sessionId, directory, expectedGoalId, mutate) => {
363
- const session = await openCodeFetch(`/session/${encodeURIComponent(sessionId)}`, { directory });
364
- const currentGoal = parseGoalMetadata(session);
439
+ const currentGoal = await readGoal(sessionId);
365
440
  if (!currentGoal || currentGoal.id !== expectedGoalId) return null;
366
441
  const nextGoal = { ...currentGoal, ...mutate(currentGoal), updatedAt: Date.now() };
367
- const currentMetadata = session?.metadata && typeof session.metadata === 'object' ? session.metadata : {};
368
- const currentNamespace = currentMetadata.openchamber && typeof currentMetadata.openchamber === 'object'
369
- ? currentMetadata.openchamber
370
- : {};
371
- await openCodeFetch(`/session/${encodeURIComponent(sessionId)}`, {
372
- directory,
373
- method: 'PATCH',
374
- body: {
375
- metadata: {
376
- ...currentMetadata,
377
- openchamber: { ...currentNamespace, goal: nextGoal },
378
- },
379
- },
380
- });
442
+ await persistSessionGoal(sessionId, directory, nextGoal);
381
443
  return nextGoal;
382
444
  };
383
445
 
@@ -469,32 +531,21 @@ export const createSessionGoalRuntime = ({
469
531
  }
470
532
  };
471
533
 
472
- const sendContinuation = async ({ sessionId, directory, goal, lastAssistantInfo }) => {
473
- const providerID = typeof lastAssistantInfo?.providerID === 'string' ? lastAssistantInfo.providerID : '';
474
- const modelID = typeof lastAssistantInfo?.modelID === 'string' ? lastAssistantInfo.modelID : '';
475
- if (!providerID || !modelID) {
476
- throw new Error('cannot continue goal: last assistant message has no provider/model');
477
- }
478
- const agent = typeof lastAssistantInfo?.agent === 'string' && lastAssistantInfo.agent
479
- ? lastAssistantInfo.agent
480
- : (typeof lastAssistantInfo?.mode === 'string' ? lastAssistantInfo.mode : '');
481
- const variant = typeof lastAssistantInfo?.variant === 'string' ? lastAssistantInfo.variant : '';
482
- await openCodeFetch(`/session/${encodeURIComponent(sessionId)}/prompt_async`, {
534
+ // v2 keeps the model and agent on the session itself, so a plain prompt
535
+ // runs on whatever the session was already using. v1 had to repeat the
536
+ // selection on every request; there is nothing to repeat here.
537
+ const sendContinuation = async ({ sessionId, directory, goal }) => {
538
+ await openCodeFetch(`/api/session/${encodeURIComponent(sessionId)}/prompt`, {
483
539
  directory,
484
540
  method: 'POST',
485
- body: {
486
- model: { providerID, modelID },
487
- ...(agent ? { agent } : {}),
488
- ...(variant ? { variant } : {}),
489
- parts: [{ type: 'text', text: buildContinuationPrompt(goal) }],
490
- },
541
+ body: { text: buildContinuationPrompt(goal) },
491
542
  });
492
543
  };
493
544
 
494
545
  const tick = async (sessionId, directory) => {
495
546
  if (!isEnabled()) return;
496
547
 
497
- const session = await openCodeFetch(`/session/${encodeURIComponent(sessionId)}`, { directory })
548
+ const session = await openCodeFetch(`/api/session/${encodeURIComponent(sessionId)}`, { directory })
498
549
  .catch((error) => {
499
550
  console.warn(`[session-goal] session fetch failed: ${error?.message || error}`);
500
551
  return null;
@@ -503,7 +554,7 @@ export const createSessionGoalRuntime = ({
503
554
  // Sub-agent/task sessions never carry user goals — skip them.
504
555
  if (typeof session.parentID === 'string' && session.parentID) return;
505
556
 
506
- const goal = parseGoalMetadata(session);
557
+ const goal = await readGoal(sessionId);
507
558
  if (!goal || goal.status !== 'active') return;
508
559
 
509
560
  // File-backed objectives: the metadata carries only a flag; the objective
@@ -530,19 +581,19 @@ export const createSessionGoalRuntime = ({
530
581
  // its next idle event will arm a fresh tick. If a child is still working,
531
582
  // OpenCode will inject its result into the parent and produce the same
532
583
  // busy→idle cycle, so do not poll or audit the interim parent reply.
533
- const statuses = await fetchSessionStatuses(directory);
584
+ const statuses = await activityProbe.fetchActiveSessionStatuses();
534
585
  if (!statuses) {
535
586
  armTimer(sessionId, directory, idleQuietMs);
536
587
  return;
537
588
  }
538
589
  if (isWorkingStatus(statuses[sessionId])) return;
539
590
 
540
- const children = await fetchSessionChildren(sessionId, directory);
541
- if (!children) {
591
+ const childrenWorking = await activityProbe.hasWorkingChildren(sessionId, statuses);
592
+ if (childrenWorking === null) {
542
593
  armTimer(sessionId, directory, idleQuietMs);
543
594
  return;
544
595
  }
545
- if (children.some((child) => typeof child?.id === 'string' && isWorkingStatus(statuses[child.id]))) return;
596
+ if (childrenWorking) return;
546
597
 
547
598
  const messages = await fetchRecentMessages(sessionId, directory);
548
599
  if (!messages) return;
@@ -797,7 +848,7 @@ export const createSessionGoalRuntime = ({
797
848
  }
798
849
 
799
850
  console.log(`[session-goal] continuing ${sessionId} (turn ${written.turnsUsed}/${maxAutoTurns}, tokens ${written.tokensUsed}${written.tokenBudget ? `/${written.tokenBudget}` : ''})`);
800
- await sendContinuation({ sessionId, directory, goal: { ...written, objective: effectiveObjective }, lastAssistantInfo: executionInfo ?? lastAssistantInfo });
851
+ await sendContinuation({ sessionId, directory, goal: { ...written, objective: effectiveObjective } });
801
852
  };
802
853
 
803
854
  const armTimer = (sessionId, directory, quietMs) => {
@@ -823,9 +874,7 @@ export const createSessionGoalRuntime = ({
823
874
  // "stop". Messages the user sends afterwards leave the paused goal alone;
824
875
  // Resume re-arms the loop (and kicks off immediately on an idle session).
825
876
  const pauseAfterAbort = async (sessionId, directory) => {
826
- const session = await openCodeFetch(`/session/${encodeURIComponent(sessionId)}`, { directory })
827
- .catch(() => null);
828
- const goal = parseGoalMetadata(session);
877
+ const goal = await readGoal(sessionId);
829
878
  if (!goal || goal.status !== 'active') return;
830
879
  await writeGoal(sessionId, directory, goal.id, () => ({
831
880
  status: 'paused',
@@ -834,8 +883,44 @@ export const createSessionGoalRuntime = ({
834
883
  console.log(`[session-goal] ${sessionId} paused after user abort`);
835
884
  };
836
885
 
886
+ const isWired = () => typeof persistSessionGoal === 'function' && typeof readSessionMetadata === 'function';
887
+
888
+ /**
889
+ * A goal is created, edited or resumed through OpenChamber's own metadata
890
+ * route, not through an OpenCode event, so the write tells this runtime
891
+ * directly. That is also the authoritative moment: the store already holds it.
892
+ */
893
+ const notifyGoalChanged = async (sessionId, directory, metadata) => {
894
+ if (stopped || !isWired()) return;
895
+ const goal = parseGoalMetadata({ metadata });
896
+ if (!goal || goal.status !== 'active') {
897
+ clearTimer(sessionId);
898
+ return;
899
+ }
900
+ if (goal.turnsUsed !== 0 && goal.statusReason !== 'resumed') return;
901
+ if (timers.has(sessionId) || inflight.has(sessionId)) return;
902
+
903
+ // A patch from the UI names no directory, and the loop needs one to scope
904
+ // its own OpenCode calls. The session record is authoritative for it.
905
+ let resolved = directory;
906
+ if (!resolved) {
907
+ const session = await openCodeFetch(`/api/session/${encodeURIComponent(sessionId)}`).catch(() => null);
908
+ resolved = typeof session?.location?.directory === 'string' ? session.location.directory : '';
909
+ }
910
+ if (stopped || timers.has(sessionId) || inflight.has(sessionId)) return;
911
+ armTimer(sessionId, resolved, goal.statusReason === 'resumed' ? RESUME_KICKOFF_MS : kickoffQuietMs);
912
+ };
913
+
914
+ let parkedNoticeLogged = false;
837
915
  const processPayload = (payload, directoryHint = '') => {
838
916
  if (stopped) return;
917
+ if (!isWired()) {
918
+ if (!parkedNoticeLogged) {
919
+ parkedNoticeLogged = true;
920
+ console.log('[session-goal] parked: no session metadata store is wired, so goal progress cannot be saved');
921
+ }
922
+ return;
923
+ }
839
924
 
840
925
  const aborted = extractAbortedAssistant(payload);
841
926
  if (aborted) {
@@ -868,17 +953,19 @@ export const createSessionGoalRuntime = ({
868
953
  // transition, only session.updated. Arm a short timer; the tick's
869
954
  // quiescence check keeps this safe if the session is actually busy.
870
955
  const update = extractSessionUpdate(payload);
871
- if (
872
- update
873
- && !update.parentID
874
- && update.goal
875
- && update.goal.status === 'active'
876
- && (update.goal.turnsUsed === 0 || update.goal.statusReason === 'resumed')
877
- && !timers.has(update.sessionId)
878
- && !inflight.has(update.sessionId)
879
- ) {
880
- const quiet = update.goal.statusReason === 'resumed' ? RESUME_KICKOFF_MS : kickoffQuietMs;
881
- armTimer(update.sessionId, update.directory || directoryHint, quiet);
956
+ if (update && !update.parentID && !timers.has(update.sessionId) && !inflight.has(update.sessionId)) {
957
+ void readGoal(update.sessionId)
958
+ .then((goal) => {
959
+ if (stopped || !goal || goal.status !== 'active') return;
960
+ if (goal.turnsUsed !== 0 && goal.statusReason !== 'resumed') return;
961
+ if (timers.has(update.sessionId) || inflight.has(update.sessionId)) return;
962
+ armTimer(
963
+ update.sessionId,
964
+ update.directory || directoryHint,
965
+ goal.statusReason === 'resumed' ? RESUME_KICKOFF_MS : kickoffQuietMs,
966
+ );
967
+ })
968
+ .catch(() => undefined);
882
969
  }
883
970
  };
884
971
 
@@ -890,5 +977,5 @@ export const createSessionGoalRuntime = ({
890
977
  timers.clear();
891
978
  };
892
979
 
893
- return { processPayload, stop };
980
+ return { processPayload, notifyGoalChanged, stop };
894
981
  };