@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
@@ -2,12 +2,14 @@ import crypto from 'crypto';
2
2
  import fs from 'fs';
3
3
  import os from 'os';
4
4
  import path from 'path';
5
- import {
6
- generateAuthenticationOptions,
7
- generateRegistrationOptions,
8
- verifyAuthenticationResponse,
9
- verifyRegistrationResponse,
10
- } from '@simplewebauthn/server';
5
+
6
+ // @simplewebauthn/server and its ASN.1 dependencies are ~130 modules; only
7
+ // passkey registration and authentication need them, so they load on first use.
8
+ let webauthnPending;
9
+ const loadWebAuthn = () => {
10
+ webauthnPending ??= import('@simplewebauthn/server');
11
+ return webauthnPending;
12
+ };
11
13
 
12
14
  const DEFAULT_STORE_VERSION = 1;
13
15
  const DEFAULT_CHALLENGE_TTL_MS = 5 * 60 * 1000;
@@ -326,7 +328,7 @@ export const createUiPasskeys = ({
326
328
  throw error;
327
329
  }
328
330
 
329
- const options = await generateRegistrationOptions({
331
+ const options = await (await loadWebAuthn()).generateRegistrationOptions({
330
332
  rpName,
331
333
  rpID,
332
334
  userID,
@@ -377,7 +379,7 @@ export const createUiPasskeys = ({
377
379
 
378
380
  registrationChallenges.delete(requestId);
379
381
 
380
- const verification = await verifyRegistrationResponse({
382
+ const verification = await (await loadWebAuthn()).verifyRegistrationResponse({
381
383
  response,
382
384
  expectedChallenge: matchingRecord.challenge,
383
385
  expectedOrigin: matchingRecord.expectedOrigins,
@@ -437,7 +439,7 @@ export const createUiPasskeys = ({
437
439
  throw error;
438
440
  }
439
441
 
440
- const options = await generateAuthenticationOptions({
442
+ const options = await (await loadWebAuthn()).generateAuthenticationOptions({
441
443
  rpID,
442
444
  userVerification: 'required',
443
445
  allowCredentials: passkeys.map((passkey) => ({
@@ -485,7 +487,7 @@ export const createUiPasskeys = ({
485
487
 
486
488
  authenticationChallenges.delete(requestId);
487
489
 
488
- const verification = await verifyAuthenticationResponse({
490
+ const verification = await (await loadWebAuthn()).verifyAuthenticationResponse({
489
491
  response,
490
492
  expectedChallenge: matchingRecord.challenge,
491
493
  expectedOrigin: matchingRecord.expectedOrigins,
@@ -20,7 +20,8 @@ has to ask for it.
20
20
  `PROMPT_VERSION`.
21
21
  - `schema.js` — response schema, response normalization, tolerant JSON parsing.
22
22
  - `store.js` — content-addressed cache entries plus mutable pointers.
23
- - `pull-request.js` — PR diffs via the shared GitHub octokit helper.
23
+ - `pull-request.js` — PR diffs and per-file contents via the shared GitHub
24
+ octokit helper.
24
25
  - `model-settings.js` — the feature's own model override.
25
26
  - `languages.js` — the languages the prose may be written in.
26
27
  - `index.js` — orchestration.
@@ -102,6 +103,14 @@ GitHub and malformed-response failures remain errors. Walkthrough generation
102
103
  keeps its existing empty-diff refusal. UI comparison behavior is documented in
103
104
  `packages/ui/src/components/views/DOCUMENTATION.md`.
104
105
 
106
+ `GET /api/walkthrough/pr-file` takes the same `directory` and PR `source` plus
107
+ `path`, optional `previousPath`, and `status`, and returns `{ original, modified }`
108
+ for that one file as GitHub has it: the base side at the PR's merge base, the
109
+ head side at the PR head. This is how the comparison view expands collapsed
110
+ context for a PR: its patch arrives at fixed context and its commits may not be
111
+ on disk, so the working tree is never read. Files above 5 MB answer `413`
112
+ (`code: 'file-too-large'`).
113
+
105
114
  ## No truncation
106
115
 
107
116
  Within what it covers, the digest is complete. When it does not fit the resolved
@@ -2,14 +2,7 @@ import { getOctokitOrNull } from '../github/octokit.js';
2
2
  import assert from 'node:assert/strict';
3
3
  import { resolveGitHubRepoFromDirectory } from '../github/repo/index.js';
4
4
 
5
- /**
6
- * Raw unified diff for a pull request.
7
- *
8
- * GitHub already returns the merge-base diff for a PR, so this matches the
9
- * three-dot semantics used for local branch reviews: work merged in from the
10
- * base branch is not part of it.
11
- */
12
- export async function getPullRequestDiff(directory, number, sourceRepo, { allowEmpty = false } = {}) {
5
+ async function resolvePullRequestRepo(directory, sourceRepo) {
13
6
  const octokit = getOctokitOrNull();
14
7
  if (!octokit) {
15
8
  throw Object.assign(new Error('Connect a GitHub account to review pull requests'), {
@@ -28,6 +21,18 @@ export async function getPullRequestDiff(directory, number, sourceRepo, { allowE
28
21
  code: 'no-github-remote',
29
22
  });
30
23
  }
24
+ return { octokit, repo };
25
+ }
26
+
27
+ /**
28
+ * Raw unified diff for a pull request.
29
+ *
30
+ * GitHub already returns the merge-base diff for a PR, so this matches the
31
+ * three-dot semantics used for local branch reviews: work merged in from the
32
+ * base branch is not part of it.
33
+ */
34
+ export async function getPullRequestDiff(directory, number, sourceRepo, { allowEmpty = false } = {}) {
35
+ const { octokit, repo } = await resolvePullRequestRepo(directory, sourceRepo);
31
36
 
32
37
  const response = await octokit.request('GET /repos/{owner}/{repo}/pulls/{pull_number}', {
33
38
  owner: repo.owner,
@@ -47,3 +52,51 @@ export async function getPullRequestDiff(directory, number, sourceRepo, { allowE
47
52
 
48
53
  return { patch, meta: { owner: repo.owner, repo: repo.repo, number } };
49
54
  }
55
+
56
+ /** Above this the full-context view is no longer a readable diff, and the round trip is wasted. */
57
+ const MAX_FULL_FILE_BYTES = 5 * 1024 * 1024;
58
+
59
+ /**
60
+ * Both sides of one file as GitHub has them, so the comparison view can expand
61
+ * collapsed context for a PR whose commits are not on disk (a fork, a branch
62
+ * that was never fetched) without ever reading the working tree.
63
+ *
64
+ * The base side is the merge base, not the base branch tip: the PR diff is
65
+ * three-dot, and reading the tip would leak unrelated base-branch work into
66
+ * the expanded context. Head commits of a fork PR are reachable through the
67
+ * base repository (`refs/pull/<n>/head`), so every read goes to one repo.
68
+ */
69
+ export async function getPullRequestFileContents(directory, number, sourceRepo, { path, previousPath, status }) {
70
+ const { octokit, repo } = await resolvePullRequestRepo(directory, sourceRepo);
71
+ const pull = await octokit.request('GET /repos/{owner}/{repo}/pulls/{pull_number}', {
72
+ owner: repo.owner, repo: repo.repo, pull_number: number,
73
+ });
74
+ const headSha = pull.data?.head?.sha;
75
+ const baseSha = pull.data?.base?.sha;
76
+ assert.match(String(headSha), /^[0-9a-f]{40}$/, 'GitHub returned an invalid pull request head');
77
+ assert.match(String(baseSha), /^[0-9a-f]{40}$/, 'GitHub returned an invalid pull request base');
78
+ const compare = await octokit.request('GET /repos/{owner}/{repo}/compare/{basehead}', {
79
+ owner: repo.owner, repo: repo.repo, basehead: `${baseSha}...${headSha}`,
80
+ });
81
+ const mergeBaseSha = compare.data?.merge_base_commit?.sha;
82
+ assert.match(String(mergeBaseSha), /^[0-9a-f]{40}$/, 'GitHub returned an invalid merge base');
83
+
84
+ const readFile = async (filePath, ref) => {
85
+ const response = await octokit.request('GET /repos/{owner}/{repo}/contents/{path}', {
86
+ owner: repo.owner, repo: repo.repo, path: filePath, ref,
87
+ headers: { accept: 'application/vnd.github.raw+json' },
88
+ });
89
+ const content = response.data;
90
+ assert.equal(typeof content, 'string', 'GitHub returned invalid file contents');
91
+ if (Buffer.byteLength(content) > MAX_FULL_FILE_BYTES) {
92
+ throw Object.assign(new Error('This file is too large to show in full'), { statusCode: 413, code: 'file-too-large' });
93
+ }
94
+ return content;
95
+ };
96
+
97
+ const [original, modified] = await Promise.all([
98
+ status === 'A' ? '' : readFile(previousPath || path, mergeBaseSha),
99
+ status === 'D' ? '' : readFile(path, headSha),
100
+ ]);
101
+ return { original, modified };
102
+ }
@@ -3,7 +3,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
3
3
  vi.mock('../github/octokit.js', () => ({ getOctokitOrNull: vi.fn() }));
4
4
  vi.mock('../github/repo/index.js', () => ({ resolveGitHubRepoFromDirectory: vi.fn() }));
5
5
 
6
- const { getPullRequestDiff } = await import('./pull-request.js');
6
+ const { getPullRequestDiff, getPullRequestFileContents } = await import('./pull-request.js');
7
7
  const { getOctokitOrNull } = await import('../github/octokit.js');
8
8
  const { resolveGitHubRepoFromDirectory } = await import('../github/repo/index.js');
9
9
 
@@ -91,3 +91,56 @@ describe('getPullRequestDiff', () => {
91
91
  });
92
92
  });
93
93
  });
94
+
95
+ describe('getPullRequestFileContents', () => {
96
+ const HEAD = 'a'.repeat(40);
97
+ const BASE_TIP = 'b'.repeat(40);
98
+ const MERGE_BASE = 'c'.repeat(40);
99
+ let request;
100
+
101
+ beforeEach(() => {
102
+ request = vi.fn(async (route, params) => {
103
+ if (route === 'GET /repos/{owner}/{repo}/pulls/{pull_number}') return { data: { head: { sha: HEAD }, base: { sha: BASE_TIP } } };
104
+ if (route === 'GET /repos/{owner}/{repo}/compare/{basehead}') return { data: { merge_base_commit: { sha: MERGE_BASE } } };
105
+ if (route === 'GET /repos/{owner}/{repo}/contents/{path}') return { data: `${params.path}@${params.ref}` };
106
+ throw new Error(`unexpected ${route}`);
107
+ });
108
+ getOctokitOrNull.mockReturnValue({ request });
109
+ });
110
+
111
+ afterEach(() => {
112
+ vi.clearAllMocks();
113
+ });
114
+
115
+ it('reads the base side at the merge base and the head side at the PR head', async () => {
116
+ const result = await getPullRequestFileContents('/repo', 7, { owner: 'upstream', repo: 'project' }, { path: 'src/a.ts', status: 'M' });
117
+ expect(result).toEqual({ original: `src/a.ts@${MERGE_BASE}`, modified: `src/a.ts@${HEAD}` });
118
+ expect(request).toHaveBeenCalledWith('GET /repos/{owner}/{repo}/compare/{basehead}', {
119
+ owner: 'upstream', repo: 'project', basehead: `${BASE_TIP}...${HEAD}`,
120
+ });
121
+ expect(request).toHaveBeenCalledWith('GET /repos/{owner}/{repo}/contents/{path}', expect.objectContaining({
122
+ owner: 'upstream', repo: 'project', headers: { accept: 'application/vnd.github.raw+json' },
123
+ }));
124
+ });
125
+
126
+ it('skips the missing side of added and deleted files and follows renames', async () => {
127
+ expect(await getPullRequestFileContents('/repo', 7, { owner: 'o', repo: 'r' }, { path: 'new.ts', status: 'A' }))
128
+ .toEqual({ original: '', modified: `new.ts@${HEAD}` });
129
+ expect(await getPullRequestFileContents('/repo', 7, { owner: 'o', repo: 'r' }, { path: 'gone.ts', status: 'D' }))
130
+ .toEqual({ original: `gone.ts@${MERGE_BASE}`, modified: '' });
131
+ expect(await getPullRequestFileContents('/repo', 7, { owner: 'o', repo: 'r' }, { path: 'new.ts', previousPath: 'old.ts', status: 'R' }))
132
+ .toEqual({ original: `old.ts@${MERGE_BASE}`, modified: `new.ts@${HEAD}` });
133
+ });
134
+
135
+ it('rejects oversized files and malformed GitHub metadata', async () => {
136
+ request.mockImplementationOnce(async () => ({ data: { head: { sha: 'nope' }, base: { sha: BASE_TIP } } }));
137
+ await expect(getPullRequestFileContents('/repo', 7, { owner: 'o', repo: 'r' }, { path: 'a.ts', status: 'M' })).rejects.toThrow(/invalid pull request head/);
138
+
139
+ request.mockImplementation(async (route) => {
140
+ if (route === 'GET /repos/{owner}/{repo}/pulls/{pull_number}') return { data: { head: { sha: HEAD }, base: { sha: BASE_TIP } } };
141
+ if (route === 'GET /repos/{owner}/{repo}/compare/{basehead}') return { data: { merge_base_commit: { sha: MERGE_BASE } } };
142
+ return { data: 'x'.repeat(5 * 1024 * 1024 + 1) };
143
+ });
144
+ await expect(getPullRequestFileContents('/repo', 7, { owner: 'o', repo: 'r' }, { path: 'a.ts', status: 'M' })).rejects.toMatchObject({ code: 'file-too-large', statusCode: 413 });
145
+ });
146
+ });
@@ -70,6 +70,26 @@ export function registerWalkthroughRoutes(app, { getWalkthroughService }) {
70
70
  }
71
71
  });
72
72
 
73
+ // One file, both sides, straight from GitHub: the comparison view expands
74
+ // collapsed context on demand without touching the working tree.
75
+ app.get('/api/walkthrough/pr-file', async (req, res) => {
76
+ try {
77
+ const query = new URL(req.originalUrl, 'http://localhost').searchParams;
78
+ const directory = query.get('directory')?.trim() ?? '';
79
+ if (!directory) return res.status(400).json({ error: 'directory parameter is required' });
80
+ const source = parseSource(readSource(query.get('source')));
81
+ if (source.kind !== 'pr') return res.status(400).json({ error: 'A pull request source is required' });
82
+ const path = query.get('path')?.trim() ?? '';
83
+ if (!path) return res.status(400).json({ error: 'path parameter is required' });
84
+ const previousPath = query.get('previousPath')?.trim() || undefined;
85
+ const status = query.get('status') ?? 'M';
86
+ const { getPullRequestFileContents } = await getWalkthroughService();
87
+ res.json(await getPullRequestFileContents(directory, source.number, source.sourceRepo, { path, previousPath, status }));
88
+ } catch (error) {
89
+ respondWithError(res, error, 'Failed to load pull request file');
90
+ }
91
+ });
92
+
73
93
  // Deliberately not aborted when the client disconnects: generation runs for
74
94
  // minutes and a refresh must not throw the work away. Leaving detaches the
75
95
  // client; the job finishes and caches its result. Stopping is an explicit
@@ -23,6 +23,11 @@ describe('walkthrough routes', () => {
23
23
  if (number === 99) throw Object.assign(new Error('GitHub unavailable'), { statusCode: 503 });
24
24
  return { patch: number === 1 ? '' : 'diff --git a/a.ts b/a.ts\n' };
25
25
  },
26
+ async getPullRequestFileContents(directory, number, sourceRepo, file) {
27
+ lastArgs = { directory, number, sourceRepo, file };
28
+ if (file.path === 'huge.bin') throw Object.assign(new Error('too large'), { statusCode: 413, code: 'file-too-large' });
29
+ return { original: 'before', modified: 'after' };
30
+ },
26
31
  async getWalkthrough(args) {
27
32
  lastArgs = args;
28
33
  return { walkthrough: null, hunks: [], hunkCount: 0, generating: Boolean(job) };
@@ -110,6 +115,20 @@ describe('walkthrough routes', () => {
110
115
  }
111
116
  });
112
117
 
118
+ it('serves both sides of one PR file and passes GitHub failures through', async () => {
119
+ const source = { kind: 'pr', number: 42, sourceRepo: { owner: 'upstream', repo: 'project' } };
120
+ const request = (params) => fetch(`${base}/api/walkthrough/pr-file?${new URLSearchParams({ directory: '/repo', source: JSON.stringify(source), ...params })}`);
121
+ const ok = await request({ path: 'new.ts', previousPath: 'old.ts', status: 'R' });
122
+ expect(ok.status).toBe(200);
123
+ expect(await ok.json()).toEqual({ original: 'before', modified: 'after' });
124
+ expect(lastArgs).toEqual({ directory: '/repo', number: 42, sourceRepo: source.sourceRepo, file: { path: 'new.ts', previousPath: 'old.ts', status: 'R' } });
125
+ expect((await request({ path: 'a.ts', status: 'M', source: JSON.stringify({ kind: 'branch', baseRef: 'main', headRef: 'x' }) })).status).toBe(400);
126
+ expect((await request({ status: 'M' })).status).toBe(400);
127
+ const huge = await request({ path: 'huge.bin', status: 'M' });
128
+ expect(huge.status).toBe(413);
129
+ expect(await huge.json()).toMatchObject({ code: 'file-too-large' });
130
+ });
131
+
113
132
  it('delivers the result to a client that reconnected after a refresh', async () => {
114
133
  const controller = new AbortController();
115
134
  const seen = generateCalls;