@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
@@ -52,6 +52,11 @@ Nothing here may fail a send. A message without its background costs the agent
52
52
  some context; a failed send costs the user their message. Every caller treats an
53
53
  error as "no block this time".
54
54
 
55
+ While memory is on, every session is told when to save, even with an empty
56
+ store. The tool description alone is read only when the agent already means to
57
+ call it, so agents told nothing here saved only when the user said "remember".
58
+ The session hears "nothing is stored yet" only when both scopes loaded.
59
+
55
60
  A source that will not load never blanks the rest: an unreadable memory store
56
61
  still delivers the pinned notes. A memory scope that failed to load is left out
57
62
  rather than indexed as empty, which would teach the agent to store again what it
@@ -37,6 +37,9 @@ export const buildKnowledgeSignature = ({ notes, plans, memory }) => {
37
37
  ...plans.map((plan) => `p:${plan.id}:${plan.title}`),
38
38
  ...memory.global.map((entry) => `mg:${entry.id}:${entry.updatedAt}`),
39
39
  ...memory.project.map((entry) => `mp:${entry.id}:${entry.updatedAt}`),
40
+ // Memory being on is itself worth telling a session: without it an empty
41
+ // store sends nothing, and an agent never told when to save never does.
42
+ ...(memory.enabled ? [`m:on:${memory.complete ? 'c' : 'p'}`] : []),
40
43
  ];
41
44
  return parts.length === 0 ? '' : parts.sort().join('|');
42
45
  };
@@ -47,24 +50,46 @@ const renderMemorySection = (entries) => entries
47
50
  .map((entry) => `- [${entry.type}] ${entry.title}`)
48
51
  .join('\n');
49
52
 
53
+ /**
54
+ * When to save, stated in every session where memory is on. The tool
55
+ * description alone is read only when the agent already means to call it, so
56
+ * agents told nothing here saved only when the user said "remember".
57
+ */
58
+ const MEMORY_SAVE_GUIDANCE = 'You have memory that persists across sessions, through the'
59
+ + ' openchamber_memory tool. Save to it in the moment, without asking first, when:'
60
+ + ' the user corrects how you work or states a preference; the user confirms that'
61
+ + ' a non-obvious approach worked; or you learn a project fact that took real'
62
+ + ' effort to find and is not in the code or docs. One fact per entry. The user'
63
+ + ' can review and remove what you save, so save when it fits and mention it'
64
+ + ' briefly.';
65
+
50
66
  /**
51
67
  * Titles only for memory, never bodies: an index carrying full text grows
52
68
  * without bound until it crowds out the conversation it was meant to inform.
53
69
  */
54
- const buildMemoryBlock = ({ global, project }) => {
70
+ const buildMemoryBlock = ({ global, project, enabled = false, complete = false }) => {
55
71
  const sections = [];
56
72
  if (global.length > 0) sections.push(`### About the user\n\n${renderMemorySection(global)}`);
57
73
  if (project.length > 0) sections.push(`### About this project\n\n${renderMemorySection(project)}`);
58
- if (sections.length === 0) return '';
74
+ if (sections.length === 0) {
75
+ if (!enabled) return '';
76
+ // "Empty" only when both scopes loaded: a failed read is not an empty store.
77
+ return complete
78
+ ? `${MEMORY_SAVE_GUIDANCE}\n\nNothing is stored yet.`
79
+ : MEMORY_SAVE_GUIDANCE;
80
+ }
59
81
 
60
82
  return [
61
- 'You have stored memory from earlier sessions. Only the titles are listed below.',
83
+ ...(enabled ? [MEMORY_SAVE_GUIDANCE] : []),
84
+ 'Stored memory from earlier sessions: only the titles are listed below.',
62
85
  'A title is an abbreviation, not the memory. Read the entry with the'
63
86
  + ' openchamber_memory tool before you act on it: titles routinely leave out'
64
87
  + ' the conditions, exceptions and reasons that decide how the memory'
65
88
  + ' applies, and a title that looks self-explanatory is the most likely to'
66
89
  + ' be hiding them. Read every title that could bear on the task at hand;'
67
- + ' you need not read the ones unrelated to what you are doing.',
90
+ + ' you need not read the ones unrelated to what you are doing. Read each'
91
+ + ' entry once per conversation: what you read stays in your context, so do'
92
+ + ' not read it again on later turns unless your context was summarized.',
68
93
  'Memory records what was true when it was written. Verify anything it says'
69
94
  + ' about files, flags or commands before relying on it.',
70
95
  ...sections,
@@ -112,9 +137,21 @@ export const createSessionKnowledgeRuntime = (dependencies) => {
112
137
  agentMemoryRuntime,
113
138
  resolveProjectId,
114
139
  isAgentMemoryEnabled,
115
- openCodeFetch = null,
140
+ // Pins and the delivered-signature cursor live in OpenChamber's own session
141
+ // metadata store: OpenCode 2.x accepts session metadata only at create time.
142
+ readSessionMetadata = null,
143
+ persistSessionMetadata = null,
116
144
  } = dependencies;
117
145
 
146
+ const requireMetadataStore = () => {
147
+ if (typeof readSessionMetadata !== 'function' || typeof persistSessionMetadata !== 'function') {
148
+ throw new Error('project knowledge needs a session metadata store');
149
+ }
150
+ };
151
+
152
+ /** The session shape the readers below expect, built from our own store. */
153
+ const readStoredSession = async (sessionId) => ({ metadata: await readSessionMetadata(sessionId) });
154
+
118
155
  /**
119
156
  * Everything the session should be carrying, read fresh. A failure in one
120
157
  * source never blanks the rest: a memory store that will not load must not
@@ -156,7 +193,7 @@ export const createSessionKnowledgeRuntime = (dependencies) => {
156
193
  }
157
194
  }
158
195
 
159
- let memory = { global: [], project: [] };
196
+ let memory = { global: [], project: [], enabled: false, complete: false };
160
197
  const memoryEnabled = typeof isAgentMemoryEnabled === 'function'
161
198
  ? await isAgentMemoryEnabled().catch(() => false)
162
199
  : true;
@@ -173,9 +210,11 @@ export const createSessionKnowledgeRuntime = (dependencies) => {
173
210
  memory = {
174
211
  global: stored.globalFailed ? [] : visible(stored.global),
175
212
  project: stored.projectFailed ? [] : visible(stored.project),
213
+ enabled: true,
214
+ complete: !stored.globalFailed && !stored.projectFailed,
176
215
  };
177
216
  } catch {
178
- memory = { global: [], project: [] };
217
+ memory = { global: [], project: [], enabled: true, complete: false };
179
218
  }
180
219
  }
181
220
 
@@ -247,44 +286,32 @@ export const createSessionKnowledgeRuntime = (dependencies) => {
247
286
  return { text: buildKnowledgeText(collected), signature };
248
287
  };
249
288
 
250
- const readSession = async (sessionId, directory) => (
251
- openCodeFetch(`/session/${encodeURIComponent(sessionId)}`, { directory })
252
- );
253
-
254
289
  /**
255
290
  * What this session still owes, read from its own stored signature.
256
291
  */
257
292
  const resolvePendingForSession = async (sessionId, directory) => {
258
- const session = await readSession(sessionId, directory).catch(() => null);
293
+ const session = await readStoredSession(sessionId).catch(() => null);
259
294
  return resolvePending(directory, readDeliveredSignature(session), readPins(session));
260
295
  };
261
296
 
262
297
  const collectSummaryForSession = async (sessionId, directory) => {
263
- const session = await readSession(sessionId, directory).catch(() => null);
298
+ const session = await readStoredSession(sessionId).catch(() => null);
264
299
  return collectSummary(directory, readPins(session));
265
300
  };
266
301
 
267
302
  const setPin = async (sessionId, directory, kind, id, pinned) => {
268
- const fresh = await readSession(sessionId, directory);
269
- const metadata = isRecord(fresh?.metadata) ? fresh.metadata : {};
270
- const openchamber = isRecord(metadata.openchamber) ? metadata.openchamber : {};
271
- const pins = readPins(fresh);
303
+ requireMetadataStore();
304
+ const pins = readPins(await readStoredSession(sessionId));
272
305
  const key = kind === 'note' ? 'notes' : 'plans';
273
306
  const next = new Set(pins[key]);
274
307
  if (pinned) next.add(id);
275
308
  else next.delete(id);
276
- await openCodeFetch(`/session/${encodeURIComponent(sessionId)}`, {
277
- directory,
278
- method: 'PATCH',
279
- body: {
280
- metadata: {
281
- ...metadata,
282
- openchamber: {
283
- ...openchamber,
284
- [PINS_METADATA_KEY]: { ...pins, [key]: [...next] },
285
- [KNOWLEDGE_METADATA_KEY]: '',
286
- },
287
- },
309
+ // Clearing the delivered signature is what makes the next send carry the
310
+ // changed pin set; the merge patch leaves neighbouring state alone.
311
+ await persistSessionMetadata(sessionId, directory, {
312
+ openchamber: {
313
+ [PINS_METADATA_KEY]: { ...pins, [key]: [...next] },
314
+ [KNOWLEDGE_METADATA_KEY]: '',
288
315
  },
289
316
  });
290
317
  return { ...pins, [key]: [...next] };
@@ -300,18 +327,9 @@ export const createSessionKnowledgeRuntime = (dependencies) => {
300
327
  * drop whatever changed in between.
301
328
  */
302
329
  const recordDelivered = async (sessionId, directory, signature) => {
303
- const fresh = await readSession(sessionId, directory);
304
- const metadata = isRecord(fresh?.metadata) ? fresh.metadata : {};
305
- const openchamber = isRecord(metadata.openchamber) ? metadata.openchamber : {};
306
- await openCodeFetch(`/session/${encodeURIComponent(sessionId)}`, {
307
- directory,
308
- method: 'PATCH',
309
- body: {
310
- metadata: {
311
- ...metadata,
312
- openchamber: { ...openchamber, [KNOWLEDGE_METADATA_KEY]: signature },
313
- },
314
- },
330
+ requireMetadataStore();
331
+ await persistSessionMetadata(sessionId, directory, {
332
+ openchamber: { [KNOWLEDGE_METADATA_KEY]: signature },
315
333
  });
316
334
  };
317
335
 
@@ -27,10 +27,26 @@ const createRuntime = (overrides = {}) => createSessionKnowledgeRuntime({
27
27
  readAll: async () => ({ global: [memory()], project: [], globalFailed: false, projectFailed: false }),
28
28
  ...overrides.agentMemoryRuntime,
29
29
  },
30
- ...('openCodeFetch' in overrides ? { openCodeFetch: overrides.openCodeFetch } : {}),
30
+ ...('readSessionMetadata' in overrides ? { readSessionMetadata: overrides.readSessionMetadata } : {}),
31
+ ...('persistSessionMetadata' in overrides ? { persistSessionMetadata: overrides.persistSessionMetadata } : {}),
31
32
  ...('isAgentMemoryEnabled' in overrides ? { isAgentMemoryEnabled: overrides.isAgentMemoryEnabled } : {}),
32
33
  });
33
34
 
35
+ /** An in-memory stand-in for `session-metadata-store.js`. */
36
+ const createMetadataStub = (initial = {}) => {
37
+ const state = { ...initial };
38
+ const patches = [];
39
+ return {
40
+ patches,
41
+ readSessionMetadata: async (sessionId) => state[sessionId] ?? {},
42
+ persistSessionMetadata: async (sessionId, directory, patch) => {
43
+ patches.push({ sessionId, directory, patch });
44
+ const openchamber = { ...(state[sessionId]?.openchamber ?? {}), ...(patch.openchamber ?? {}) };
45
+ state[sessionId] = { ...(state[sessionId] ?? {}), openchamber };
46
+ },
47
+ };
48
+ };
49
+
34
50
  describe('what the session is owed', () => {
35
51
  test('carries pinned notes, pinned plan bodies, and the memory index', async () => {
36
52
  const { text } = await createRuntime().resolvePending(DIRECTORY, '', PINS);
@@ -59,12 +75,10 @@ describe('what the session is owed', () => {
59
75
  expect(text).not.toContain('Pinned note body.');
60
76
  });
61
77
 
62
- test('nothing pinned and nothing remembered owes nothing', async () => {
78
+ test('nothing pinned with memory off owes nothing', async () => {
63
79
  const runtime = createRuntime({
64
80
  projectContextRuntime: { readContext: async () => ({ notes: [], todos: [], plans: [] }) },
65
- agentMemoryRuntime: {
66
- readAll: async () => ({ global: [], project: [], globalFailed: false, projectFailed: false }),
67
- },
81
+ isAgentMemoryEnabled: async () => false,
68
82
  });
69
83
 
70
84
  const { text, signature } = await runtime.resolvePending(DIRECTORY, '');
@@ -72,6 +86,35 @@ describe('what the session is owed', () => {
72
86
  expect(signature).toBe('');
73
87
  expect(text).toBe('');
74
88
  });
89
+
90
+ test('an empty memory store still tells the session when to save', async () => {
91
+ const runtime = createRuntime({
92
+ projectContextRuntime: { readContext: async () => ({ notes: [], todos: [], plans: [] }) },
93
+ agentMemoryRuntime: {
94
+ readAll: async () => ({ global: [], project: [], globalFailed: false, projectFailed: false }),
95
+ },
96
+ });
97
+
98
+ const first = await runtime.resolvePending(DIRECTORY, '');
99
+ expect(first.text).toContain('Save to it in the moment');
100
+ expect(first.text).toContain('Nothing is stored yet.');
101
+
102
+ const again = await runtime.resolvePending(DIRECTORY, first.signature);
103
+ expect(again.text).toBe('');
104
+ });
105
+
106
+ test('a memory store that failed to load is not called empty', async () => {
107
+ const runtime = createRuntime({
108
+ projectContextRuntime: { readContext: async () => ({ notes: [], todos: [], plans: [] }) },
109
+ agentMemoryRuntime: {
110
+ readAll: async () => ({ global: [], project: [], globalFailed: true, projectFailed: false }),
111
+ },
112
+ });
113
+
114
+ const { text } = await runtime.resolvePending(DIRECTORY, '');
115
+ expect(text).toContain('Save to it in the moment');
116
+ expect(text).not.toContain('Nothing is stored yet.');
117
+ });
75
118
  });
76
119
 
77
120
  describe('what has already been delivered', () => {
@@ -201,25 +244,52 @@ describe('reading what a session was told', () => {
201
244
  expect(runtime.readPins({})).toEqual({ notes: [], plans: [] });
202
245
  });
203
246
 
204
- test('pinning updates only the target session and invalidates its delivered signature', async () => {
205
- const requests = [];
206
- const runtime = createRuntime({
207
- openCodeFetch: async (path, options = {}) => {
208
- requests.push({ path, options });
209
- if (options.method === 'PATCH') return {};
210
- return {
211
- metadata: { openchamber: { project_context_pins: { notes: [], plans: [] }, knowledge_context_delivered: 'old' } },
212
- };
247
+ test('pins into OpenChamber\'s own store and invalidates the delivered signature', async () => {
248
+ const store = createMetadataStub({
249
+ ses_a: { openchamber: { project_context_pins: { notes: [], plans: [] }, knowledge_context_delivered: 'old' } },
250
+ });
251
+ const runtime = createRuntime(store);
252
+
253
+ await expect(runtime.setPin('ses_a', DIRECTORY, 'note', 'n1', true)).resolves.toEqual({ notes: ['n1'], plans: [] });
254
+
255
+ expect(store.patches).toEqual([{
256
+ sessionId: 'ses_a',
257
+ directory: DIRECTORY,
258
+ patch: {
259
+ openchamber: {
260
+ project_context_pins: { notes: ['n1'], plans: [] },
261
+ knowledge_context_delivered: '',
262
+ },
213
263
  },
264
+ }]);
265
+ });
266
+
267
+ test('unpins the same way', async () => {
268
+ const store = createMetadataStub({
269
+ ses_a: { openchamber: { project_context_pins: { notes: ['n1', 'n2'], plans: [] } } },
214
270
  });
271
+ const runtime = createRuntime(store);
272
+
273
+ await expect(runtime.setPin('ses_a', DIRECTORY, 'note', 'n1', false)).resolves.toEqual({ notes: ['n2'], plans: [] });
274
+ });
215
275
 
216
- await runtime.setPin('ses_a', DIRECTORY, 'note', 'n1', true);
276
+ test('records delivery as a merge patch, leaving neighbouring state alone', async () => {
277
+ const store = createMetadataStub();
278
+ const runtime = createRuntime(store);
217
279
 
218
- expect(requests.map((request) => request.path)).toEqual(['/session/ses_a', '/session/ses_a']);
219
- expect(requests[1].options.body.metadata.openchamber).toEqual({
220
- project_context_pins: { notes: ['n1'], plans: [] },
221
- knowledge_context_delivered: '',
222
- });
280
+ await runtime.recordDelivered('ses_a', DIRECTORY, 'sig-1');
281
+
282
+ expect(store.patches).toEqual([{
283
+ sessionId: 'ses_a',
284
+ directory: DIRECTORY,
285
+ patch: { openchamber: { knowledge_context_delivered: 'sig-1' } },
286
+ }]);
287
+ });
288
+
289
+ test('says so plainly when no metadata store is wired', async () => {
290
+ const runtime = createRuntime();
291
+ await expect(runtime.setPin('ses_a', DIRECTORY, 'note', 'n1', true)).rejects.toThrow(/session metadata store/);
292
+ await expect(runtime.recordDelivered('ses_a', DIRECTORY, 'sig')).rejects.toThrow(/session metadata store/);
223
293
  });
224
294
 
225
295
  test('finds the signature stored on the session', () => {