@aiworker/web 1.22.0 → 1.23.0

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 (415) hide show
  1. package/README.md +4 -4
  2. package/bin/cli.js +14 -4
  3. package/bin/cli.test.js +165 -73
  4. package/bin/lib/cli-api-target.js +2 -2
  5. package/bin/lib/cli-args.js +119 -119
  6. package/bin/lib/cli-lifecycle.js +9 -9
  7. package/bin/lib/cli-network.js +3 -3
  8. package/bin/lib/cli-paths.js +3 -3
  9. package/bin/lib/cli-ports.js +2 -2
  10. package/bin/lib/cli-process.js +4 -4
  11. package/bin/lib/cli-startup.js +64 -15
  12. package/bin/lib/cli-tunnel-profiles.js +1 -1
  13. package/bin/lib/cli-tunnel-utils.js +2 -2
  14. package/bin/lib/commands-connect-url.js +19 -19
  15. package/bin/lib/commands-lifecycle.js +27 -27
  16. package/bin/lib/commands-logs.js +5 -5
  17. package/bin/lib/commands-models.js +1 -1
  18. package/bin/lib/commands-projects.js +1 -1
  19. package/bin/lib/commands-schedule.js +1 -1
  20. package/bin/lib/commands-serve.js +29 -29
  21. package/bin/lib/commands-session.js +1 -1
  22. package/bin/lib/commands-startup.js +45 -10
  23. package/bin/lib/commands-status.js +1 -1
  24. package/bin/lib/commands-tunnel.js +40 -40
  25. package/bin/lib/commands-update.js +1 -1
  26. package/bin/lib/commands-update.test.js +6 -6
  27. package/dist/assets/{CodeMirrorCommentWidgets-B3u7UIcE.js → CodeMirrorCommentWidgets-B1Gizi3a.js} +1 -1
  28. package/dist/assets/DiffView-DXjVsEOw.js +4 -0
  29. package/dist/assets/DirtyBranchSwitchDialog-aig6zJjg.js +1 -0
  30. package/dist/assets/FilesView-CJdG0-wk.js +17 -0
  31. package/dist/assets/GitView-BXsS3jG6.js +6 -0
  32. package/dist/assets/{JsonTreeView-B0BdZEHG.js → JsonTreeView-D_hpXBnF.js} +1 -1
  33. package/dist/assets/LinearIssuesView-BoUiLQG1.js +1 -0
  34. package/dist/assets/MarkdownImageGallery-B_B_a9KS.js +1 -0
  35. package/dist/assets/MarkdownRendererImpl-xgyyLiBM.js +12 -0
  36. package/dist/assets/OnboardingScreen-DIp84OWt.js +1 -0
  37. package/dist/assets/{PatchDiff-DvfqDql7.js → PatchDiff-8p6nLJaU.js} +1 -1
  38. package/dist/assets/PierreDiffViewer-DjC8nTk9.js +161 -0
  39. package/dist/assets/PlanView-CJTmOF6I.js +5 -0
  40. package/dist/assets/SettingsView-DD-JqIJx.js +28 -0
  41. package/dist/assets/{SettingsWindow-i45U1Cy1.js → SettingsWindow-Cpb4hM6q.js} +1 -1
  42. package/dist/assets/SymbolsNerdFontMono-Regular-aK5vsLov.woff2 +0 -0
  43. package/dist/assets/{ToolOutputDialog-BTwyh5OF.js → ToolOutputDialog-DfaKZXNU.js} +6 -6
  44. package/dist/assets/ToolPartDiffPreview-DtZLzrSK.js +8 -0
  45. package/dist/assets/{VirtualizedFileDiff-DD8lDVej.js → VirtualizedFileDiff-C8i9HpTB.js} +1 -1
  46. package/dist/assets/WalkthroughView-DeKMvZlL.js +4 -0
  47. package/dist/assets/{computeVirtualFileMetrics-BMIRgMHv.js → computeVirtualFileMetrics-BBI7ZwrC.js} +2 -2
  48. package/dist/assets/contextPanelEmbeddedChat-BdA6bdky.js +1 -0
  49. package/dist/assets/de-DCrsQ5zS.js +10 -0
  50. package/dist/assets/es-Dwv4YfH6.js +16 -0
  51. package/dist/assets/fr-BCWg4Cnx.js +14 -0
  52. package/dist/assets/ghostty-vt-DdA0Zryv.wasm +0 -0
  53. package/dist/assets/index-B68h5S5B.css +1 -0
  54. package/dist/assets/index-DVwMarHI.js +39 -0
  55. package/dist/assets/{index-CODwDsU_.js → index-jXSK5RrB.js} +1 -1
  56. package/dist/assets/{isDiffPlainText-BqayB8d3.js → isDiffPlainText-B_x_rVon.js} +1 -1
  57. package/dist/assets/{isFilePlainText-QfoiKJNY.js → isFilePlainText-DW_xMer1.js} +1 -1
  58. package/dist/assets/ja-Bruw3RYC.js +16 -0
  59. package/dist/assets/ko-idhXGF8j.js +16 -0
  60. package/dist/assets/main-BkyaQhJX.js +930 -0
  61. package/dist/assets/{main-C5DVOxc6.js → main-CzdPuL0s.js} +2 -2
  62. package/dist/assets/markdownCore-Cn4Tyejo.js +5 -0
  63. package/dist/assets/{miniChat-DUJ4irZc.js → miniChat-CCkqKOLp.js} +2 -2
  64. package/dist/assets/{mobile-CcaxB0n4.js → mobile-mvxTo055.js} +2 -2
  65. package/dist/assets/patchFileDiff-Csk4iNUi.js +13 -0
  66. package/dist/assets/pl-CGZWUqZJ.js +16 -0
  67. package/dist/assets/pt-BR-B8V7u7tA.js +16 -0
  68. package/dist/assets/renderElectronMiniChatApp-BxoyujA5.js +2 -0
  69. package/dist/assets/renderMobileApp-B48CsP4r.js +25 -0
  70. package/dist/assets/runtimeEndpointReset-Bg5gx18H.js +17 -0
  71. package/dist/assets/scheduledTasksApi-BW0Etzwz.js +1 -0
  72. package/dist/assets/{shikiHighlight-DYOWuY65.js → shikiHighlight-CRl0SUC9.js} +1 -1
  73. package/dist/assets/surface-oMvhsog3.js +1 -0
  74. package/dist/assets/tr-BK_KiO2V.js +7 -0
  75. package/dist/assets/uk-CG74xV8N.js +16 -0
  76. package/dist/assets/useAppFontEffects-CPKeOpUo.js +7284 -0
  77. package/dist/assets/useGitComparison-DH220WmO.js +1 -0
  78. package/dist/assets/useInlineCommentController-BiWz4AVb.js +2 -0
  79. package/dist/assets/useRootScrollLock-BS4-kr7P.js +1 -0
  80. package/dist/assets/{vendor-base-ui-BeMD8X_w.js → vendor-base-ui-DdV8vhHn.js} +1 -1
  81. package/dist/assets/{vendor-codemirror-language-data-DFZik9R2.js → vendor-codemirror-language-data-Bg4AEeCr.js} +2 -2
  82. package/dist/assets/vendor-zod-BPAANqvH.js +39 -0
  83. package/dist/assets/{web-components-Bhg83tjf.js → web-components-z7hfnS8n.js} +1 -1
  84. package/dist/assets/zh-CN-T4AXofZI.js +16 -0
  85. package/dist/assets/zh-TW-Dte40sxp.js +16 -0
  86. package/dist/index.html +21 -59
  87. package/dist/mini-chat.html +7 -7
  88. package/dist/mobile.html +5 -5
  89. package/package.json +3 -4
  90. package/server/index.d.ts +15 -0
  91. package/server/index.js +158 -89
  92. package/server/lib/agent-memory/actions.js +2 -2
  93. package/server/lib/agent-memory/feature-flag.js +1 -1
  94. package/server/lib/agent-memory/feature-flag.test.js +8 -8
  95. package/server/lib/agent-memory/routes.js +2 -2
  96. package/server/lib/agent-tool/runtime.js +37 -54
  97. package/server/lib/agent-tool/runtime.test.js +59 -59
  98. package/server/lib/browser-control/broker.js +3 -3
  99. package/server/lib/browser-control/broker.test.js +1 -1
  100. package/server/lib/changelog/update-notes.js +82 -0
  101. package/server/lib/changelog/update-notes.test.js +59 -0
  102. package/server/lib/client-auth/remote-clients.test.js +5 -5
  103. package/server/lib/context-obligatory/runtime.js +7 -7
  104. package/server/lib/context-obligatory/runtime.test.js +5 -5
  105. package/server/lib/data-dir-migration.js +40 -0
  106. package/server/lib/data-dir-migration.test.js +59 -0
  107. package/server/lib/dev-servers/parse.js +2 -2
  108. package/server/lib/dev-servers/parse.test.js +2 -2
  109. package/server/lib/dev-servers/routes.js +1 -1
  110. package/server/lib/dev-tunnel/DOCUMENTATION.md +13 -4
  111. package/server/lib/dev-tunnel/client.js +1 -1
  112. package/server/lib/dev-tunnel/runtime.js +5 -5
  113. package/server/lib/dev-tunnel/tunnel.test.js +21 -1
  114. package/server/lib/dictation/local/model-catalog.js +1 -1
  115. package/server/lib/dictation/local/worker-process.js +2 -2
  116. package/server/lib/event-stream/directory-ws-bridge.js +1 -1
  117. package/server/lib/event-stream/global-ws-bridge.js +1 -1
  118. package/server/lib/event-stream/protocol.test.js +4 -4
  119. package/server/lib/event-stream/runtime.test.js +18 -18
  120. package/server/lib/fs/DOCUMENTATION.md +5 -0
  121. package/server/lib/fs/routes.js +68 -26
  122. package/server/lib/fs/routes.test.js +208 -22
  123. package/server/lib/git/DOCUMENTATION.md +32 -6
  124. package/server/lib/git/identity-storage.js +1 -1
  125. package/server/lib/git/issue-2746-longpaths.test.js +4 -4
  126. package/server/lib/git/routes.js +41 -5
  127. package/server/lib/git/service.js +300 -224
  128. package/server/lib/git/service.test.js +596 -28
  129. package/server/lib/github/auth.js +8 -8
  130. package/server/lib/github/pr-status.js +1 -1
  131. package/server/lib/github/routes.js +2 -2
  132. package/server/lib/inherited-env.js +17 -10
  133. package/server/lib/inherited-env.test.js +10 -11
  134. package/server/lib/linear/auth.js +8 -8
  135. package/server/lib/linear/auth.test.js +24 -24
  136. package/server/lib/linear/issues.test.js +6 -6
  137. package/server/lib/linear/mapping.test.js +4 -4
  138. package/server/lib/linear/oauth.js +2 -2
  139. package/server/lib/linear/oauth.test.js +14 -14
  140. package/server/lib/linear/routes.js +5 -5
  141. package/server/lib/linear/routes.test.js +16 -16
  142. package/server/lib/linear/status-runtime.test.js +9 -9
  143. package/server/lib/linear/status.js +1 -1
  144. package/server/lib/linear/status.test.js +15 -15
  145. package/server/lib/linear/teams.test.js +4 -4
  146. package/server/lib/magic-prompts/routes.js +2 -2
  147. package/server/lib/mcp-reconnect/DOCUMENTATION.md +55 -0
  148. package/server/lib/mcp-reconnect/runtime.js +122 -0
  149. package/server/lib/mcp-reconnect/runtime.test.js +140 -0
  150. package/server/lib/message-queue/DOCUMENTATION.md +161 -0
  151. package/server/lib/message-queue/runtime.js +870 -0
  152. package/server/lib/message-queue/runtime.test.js +482 -0
  153. package/server/lib/network-defaults.js +23 -0
  154. package/server/lib/network-defaults.test.js +52 -0
  155. package/server/lib/notifications/apns-runtime.js +17 -17
  156. package/server/lib/notifications/apns-runtime.test.js +11 -11
  157. package/server/lib/notifications/emitter-runtime.js +1 -1
  158. package/server/lib/notifications/emitter-runtime.test.js +1 -1
  159. package/server/lib/notifications/push-runtime.js +7 -7
  160. package/server/lib/notifications/routes.js +1 -1
  161. package/server/lib/notifications/runtime.js +1 -1
  162. package/server/lib/openchamber-control/action-resolution.test.js +10 -10
  163. package/server/lib/openchamber-control/actions.js +24 -24
  164. package/server/lib/openchamber-control/error.js +4 -4
  165. package/server/lib/openchamber-control/routes.js +2 -2
  166. package/server/lib/openchamber-control/routes.test.js +5 -5
  167. package/server/lib/openchamber-control/screenshots.js +1 -1
  168. package/server/lib/openchamber-control/screenshots.test.js +1 -1
  169. package/server/lib/openchamber-control/service.js +50 -50
  170. package/server/lib/openchamber-control/service.test.js +5 -5
  171. package/server/lib/openchamber-sessions/routes.js +124 -22
  172. package/server/lib/openchamber-sessions/routes.test.js +99 -11
  173. package/server/lib/opencode/DOCUMENTATION.md +30 -6
  174. package/server/lib/opencode/auth.js +1 -1
  175. package/server/lib/opencode/bootstrap-runtime.js +8 -6
  176. package/server/lib/opencode/cli-options.js +8 -8
  177. package/server/lib/opencode/config-paths.test.js +116 -0
  178. package/server/lib/opencode/core-routes.js +8 -7
  179. package/server/lib/opencode/core-routes.test.js +11 -11
  180. package/server/lib/opencode/env-config.js +5 -5
  181. package/server/lib/opencode/env-config.test.js +7 -7
  182. package/server/lib/opencode/env-runtime.js +10 -10
  183. package/server/lib/opencode/env-runtime.test.js +18 -18
  184. package/server/lib/opencode/feature-routes-runtime.js +19 -12
  185. package/server/lib/opencode/hmr-state-runtime.js +2 -2
  186. package/server/lib/opencode/hmr-state-runtime.test.js +1 -1
  187. package/server/lib/opencode/input-history-scope.js +14 -0
  188. package/server/lib/opencode/lifecycle.js +8 -8
  189. package/server/lib/opencode/lifecycle.test.js +4 -4
  190. package/server/lib/opencode/managed-plugin-config.js +35 -0
  191. package/server/lib/opencode/managed-process-registry.js +3 -3
  192. package/server/lib/opencode/mcp-oauth-callback.test.js +2 -2
  193. package/server/lib/opencode/openchamber-routes.js +79 -19
  194. package/server/lib/opencode/openchamber-routes.test.js +139 -12
  195. package/server/lib/opencode/plugins.js +2 -2
  196. package/server/lib/opencode/plugins.test.js +1 -1
  197. package/server/lib/opencode/project-icon-routes.js +2 -2
  198. package/server/lib/opencode/project-icon-routes.test.js +1 -1
  199. package/server/lib/opencode/providers.js +44 -2
  200. package/server/lib/opencode/providers.test.js +131 -4
  201. package/server/lib/opencode/proxy.js +2 -2
  202. package/server/lib/opencode/pwa-manifest-routes.js +1 -1
  203. package/server/lib/opencode/restart-session-recovery.test.js +1 -1
  204. package/server/lib/opencode/routes-upgrade.test.js +4 -4
  205. package/server/lib/opencode/routes.js +19 -17
  206. package/server/lib/opencode/server-startup-runtime.js +6 -6
  207. package/server/lib/opencode/session-runtime.js +3 -3
  208. package/server/lib/opencode/session-runtime.test.js +6 -6
  209. package/server/lib/opencode/settings-files.js +214 -0
  210. package/server/lib/opencode/settings-helpers.js +116 -44
  211. package/server/lib/opencode/settings-helpers.test.js +354 -12
  212. package/server/lib/opencode/settings-registry.json +747 -0
  213. package/server/lib/opencode/settings-runtime.js +141 -20
  214. package/server/lib/opencode/settings-runtime.test.js +191 -4
  215. package/server/lib/opencode/shared.js +5 -2
  216. package/server/lib/opencode/shared.test.js +7 -7
  217. package/server/lib/opencode/shutdown-runtime.js +2 -0
  218. package/server/lib/opencode/skill-routes.js +2 -1
  219. package/server/lib/opencode/snippets.js +1 -2
  220. package/server/lib/opencode/startup-performance.js +1 -1
  221. package/server/lib/opencode/startup-performance.test.js +6 -6
  222. package/server/lib/opencode/static-routes-runtime.js +8 -8
  223. package/server/lib/opencode/static-routes-runtime.test.js +7 -7
  224. package/server/lib/opencode/upgrade-capability.js +2 -2
  225. package/server/lib/opencode/upgrade-capability.test.js +3 -3
  226. package/server/lib/package-manager.js +17 -42
  227. package/server/lib/package-manager.test.js +19 -19
  228. package/server/lib/permission-auto-accept/runtime.js +1 -1
  229. package/server/lib/project-context/DOCUMENTATION.md +25 -1
  230. package/server/lib/project-context/routes.http.test.js +18 -0
  231. package/server/lib/project-context/routes.js +16 -1
  232. package/server/lib/project-context/runtime.js +248 -23
  233. package/server/lib/project-context/runtime.test.js +106 -3
  234. package/server/lib/projects/DOCUMENTATION.md +76 -0
  235. package/server/lib/projects/project-config.js +144 -11
  236. package/server/lib/projects/project-id.js +17 -0
  237. package/server/lib/projects/project-setup.js +409 -0
  238. package/server/lib/projects/project-setup.test.js +557 -0
  239. package/server/lib/projects/routes.js +59 -0
  240. package/server/lib/quota/DOCUMENTATION.md +40 -2
  241. package/server/lib/quota/credentials/providers.js +4 -0
  242. package/server/lib/quota/credentials/store.js +4 -4
  243. package/server/lib/quota/credentials/store.test.js +8 -8
  244. package/server/lib/quota/index.js +1 -0
  245. package/server/lib/quota/providers/cline-pass.js +125 -0
  246. package/server/lib/quota/providers/cline-pass.test.js +103 -0
  247. package/server/lib/quota/providers/exe-dev.js +75 -0
  248. package/server/lib/quota/providers/exe-dev.test.js +47 -0
  249. package/server/lib/quota/providers/hyper.js +118 -0
  250. package/server/lib/quota/providers/hyper.test.js +126 -0
  251. package/server/lib/quota/providers/index.js +22 -0
  252. package/server/lib/quota/providers/neuralwatt.js +3 -6
  253. package/server/lib/quota/providers/neuralwatt.test.js +7 -7
  254. package/server/lib/quota/providers/ollama-cloud.js +32 -1
  255. package/server/lib/quota/providers/ollama-cloud.test.js +33 -1
  256. package/server/lib/quota/providers/opencode-go.js +3 -2
  257. package/server/lib/quota/providers/opencode-go.test.js +35 -6
  258. package/server/lib/quota/providers/openrouter.js +119 -24
  259. package/server/lib/quota/providers/openrouter.test.js +330 -0
  260. package/server/lib/quota/providers/xai.js +1 -1
  261. package/server/lib/quota/routes.js +2 -0
  262. package/server/lib/quota/utils/auth.js +1 -1
  263. package/server/lib/relay/DOCUMENTATION.md +56 -1
  264. package/server/lib/relay/cross-compat.test.js +26 -0
  265. package/server/lib/relay/downstream-scheduler.js +154 -0
  266. package/server/lib/relay/downstream-scheduler.test.js +162 -0
  267. package/server/lib/relay/e2ee.js +10 -8
  268. package/server/lib/relay/flow-control.test.js +177 -0
  269. package/server/lib/relay/host-client.js +38 -9
  270. package/server/lib/relay/host-client.test.js +9 -1
  271. package/server/lib/relay/host-lock.js +1 -1
  272. package/server/lib/relay/service.js +5 -5
  273. package/server/lib/relay/tunnel-codec.js +9 -0
  274. package/server/lib/relay/tunnel-host.js +69 -18
  275. package/server/lib/relay/tunnel-host.test.js +9 -1
  276. package/server/lib/scheduled-tasks/issue-2710-double-execution.test.js +2 -2
  277. package/server/lib/scheduled-tasks/routes.js +5 -5
  278. package/server/lib/scheduled-tasks/service.js +25 -25
  279. package/server/lib/scheduled-tasks/service.test.js +1 -1
  280. package/server/lib/security/bind-host.js +4 -4
  281. package/server/lib/security/bind-host.test.js +1 -1
  282. package/server/lib/security/request-security.js +11 -5
  283. package/server/lib/security/request-security.test.js +14 -14
  284. package/server/lib/session-assist/runtime.js +15 -18
  285. package/server/lib/session-folders/routes.js +2 -2
  286. package/server/lib/session-folders/routes.test.js +8 -8
  287. package/server/lib/session-goal/DOCUMENTATION.md +20 -7
  288. package/server/lib/session-goal/create.js +4 -2
  289. package/server/lib/session-goal/create.test.js +1 -1
  290. package/server/lib/session-goal/objectives.js +4 -4
  291. package/server/lib/session-goal/routes.js +1 -1
  292. package/server/lib/session-goal/runtime.js +91 -30
  293. package/server/lib/session-goal/runtime.test.js +428 -2
  294. package/server/lib/session-knowledge/runtime.js +11 -11
  295. package/server/lib/session-knowledge/runtime.test.js +5 -5
  296. package/server/lib/skills-catalog/DOCUMENTATION.md +1 -1
  297. package/server/lib/skills-catalog/cache.test.js +2 -2
  298. package/server/lib/skills-catalog/disk-cache.js +5 -5
  299. package/server/lib/skills-catalog/github-meta.test.js +2 -2
  300. package/server/lib/skills-catalog/install.js +3 -2
  301. package/server/lib/small-model/DOCUMENTATION.md +7 -2
  302. package/server/lib/small-model/call.js +18 -7
  303. package/server/lib/small-model/call.test.js +58 -6
  304. package/server/lib/small-model/index.js +12 -16
  305. package/server/lib/small-model/index.test.js +1 -1
  306. package/server/lib/small-model/resolve.js +1 -1
  307. package/server/lib/small-model/resolve.test.js +1 -1
  308. package/server/lib/small-model/routes.js +2 -1
  309. package/server/lib/small-model/runtime-providers.js +15 -7
  310. package/server/lib/small-model/runtime-providers.test.js +7 -1
  311. package/server/lib/system-prompt/runtime.js +3 -22
  312. package/server/lib/system-prompt/runtime.test.js +3 -3
  313. package/server/lib/terminal/DOCUMENTATION.md +14 -10
  314. package/server/lib/terminal/runtime.js +190 -31
  315. package/server/lib/terminal/runtime.test.js +572 -38
  316. package/server/lib/terminal/shells.js +20 -3
  317. package/server/lib/terminal/shells.test.js +33 -2
  318. package/server/lib/tts/base-url.js +3 -3
  319. package/server/lib/tts/routes.test.js +20 -20
  320. package/server/lib/ui-auth/ui-auth.js +12 -9
  321. package/server/lib/ui-auth/ui-auth.test.js +19 -3
  322. package/server/lib/ui-auth/ui-passkeys.js +7 -7
  323. package/server/lib/walkthrough/DOCUMENTATION.md +33 -14
  324. package/server/lib/walkthrough/index.js +1 -0
  325. package/server/lib/walkthrough/jobs.test.js +1 -1
  326. package/server/lib/walkthrough/language.test.js +1 -1
  327. package/server/lib/walkthrough/model-settings.js +11 -15
  328. package/server/lib/walkthrough/model-settings.test.js +1 -1
  329. package/server/lib/walkthrough/prompt.js +3 -1
  330. package/server/lib/walkthrough/pull-request.test.js +5 -5
  331. package/server/lib/walkthrough/reproduce-2607.test.js +2 -2
  332. package/server/lib/walkthrough/routes.test.js +26 -5
  333. package/server/lib/walkthrough/sources.js +23 -2
  334. package/server/lib/walkthrough/store.js +3 -3
  335. package/server/lib/walkthrough/store.test.js +1 -1
  336. package/server/opencode-proxy.test.js +2 -2
  337. package/server/proxy-headers.js +1 -1
  338. package/server/sse-routes.test.js +4 -4
  339. package/README.md.bak +0 -250
  340. package/bin/lib/DOCUMENTATION.md.bak +0 -163
  341. package/dist/assets/CommitSection-SGBCAW0w.js +0 -1
  342. package/dist/assets/DiffView-DluiRSla.js +0 -4
  343. package/dist/assets/FilesView-Bdq8ppva.js +0 -17
  344. package/dist/assets/GitView-Znn7VJcP.js +0 -6
  345. package/dist/assets/LinearIssuesView-jP-hXyac.js +0 -1
  346. package/dist/assets/MarkdownImageGallery-ClOvuZxC.js +0 -1
  347. package/dist/assets/MarkdownRendererImpl-Dt9mjTRN.js +0 -12
  348. package/dist/assets/OnboardingScreen-D2DG7K6b.js +0 -1
  349. package/dist/assets/PierreDiffViewer-B7m3f0d7.js +0 -157
  350. package/dist/assets/PlanView-B0F3BtPZ.js +0 -5
  351. package/dist/assets/SettingsView-BBW-S-gh.js +0 -28
  352. package/dist/assets/ToolPartDiffPreview-CUNe28U1.js +0 -8
  353. package/dist/assets/WalkthroughView-egQgxel3.js +0 -4
  354. package/dist/assets/contextPanelEmbeddedChat-C3fjDbdg.js +0 -1
  355. package/dist/assets/de-C1P6X5Rs.js +0 -9
  356. package/dist/assets/es-CDgaF1_t.js +0 -15
  357. package/dist/assets/fr-Bgxqvvz_.js +0 -13
  358. package/dist/assets/index-C57jT0Sa.css +0 -1
  359. package/dist/assets/index-DW_E3rnL.js +0 -7
  360. package/dist/assets/ja-BDRrEcNP.js +0 -15
  361. package/dist/assets/ko-Ba8sQV79.js +0 -15
  362. package/dist/assets/main-Bv5Pkngh.js +0 -928
  363. package/dist/assets/markdownCore-CZwzz5gw.js +0 -3
  364. package/dist/assets/patchFileDiff-yNfWXN4E.js +0 -10
  365. package/dist/assets/pl-Dioz29BI.js +0 -15
  366. package/dist/assets/pt-BR-DIs6ElwV.js +0 -15
  367. package/dist/assets/renderElectronMiniChatApp-BcKLHXKe.js +0 -2
  368. package/dist/assets/renderMobileApp-D9yQJy0L.js +0 -25
  369. package/dist/assets/runtimeEndpointReset-CjhvxLH0.js +0 -16
  370. package/dist/assets/scheduledTasksApi-DLW0mkQK.js +0 -1
  371. package/dist/assets/tr-DFnMlPxY.js +0 -6
  372. package/dist/assets/uk-ZrCNjM7Y.js +0 -15
  373. package/dist/assets/useAppFontEffects-CjrntdL0.js +0 -7310
  374. package/dist/assets/useInlineCommentController-CDEuSlPH.js +0 -2
  375. package/dist/assets/useRootScrollLock-BHYPkrLv.js +0 -1
  376. package/dist/assets/vendor-ghostty-web-CrxinGGH.js +0 -13
  377. package/dist/assets/vendor-zod-BLfBSgBh.js +0 -39
  378. package/dist/assets/zh-CN-iv_AV4EC.js +0 -15
  379. package/dist/assets/zh-TW-CzEUk38j.js +0 -15
  380. package/server/index.d.ts.bak +0 -39
  381. package/server/lib/agent-tool/DOCUMENTATION.md.bak +0 -119
  382. package/server/lib/browser-control/DOCUMENTATION.md.bak +0 -50
  383. package/server/lib/context-obligatory/DOCUMENTATION.md.bak +0 -19
  384. package/server/lib/dev-tunnel/DOCUMENTATION.md.bak +0 -57
  385. package/server/lib/dictation/DOCUMENTATION.md.bak +0 -100
  386. package/server/lib/event-stream/DOCUMENTATION.md.bak +0 -62
  387. package/server/lib/fs/DOCUMENTATION.md.bak +0 -47
  388. package/server/lib/git/DOCUMENTATION.md.bak +0 -193
  389. package/server/lib/github/DOCUMENTATION.md.bak +0 -183
  390. package/server/lib/linear/DOCUMENTATION.md.bak +0 -97
  391. package/server/lib/linear/OAUTH-BROKER-HANDOFF.md.bak +0 -91
  392. package/server/lib/markdown-image-grants/DOCUMENTATION.md.bak +0 -40
  393. package/server/lib/notifications/APNS.md.bak +0 -135
  394. package/server/lib/notifications/DOCUMENTATION.md.bak +0 -138
  395. package/server/lib/openchamber-control/DOCUMENTATION.md.bak +0 -64
  396. package/server/lib/opencode/DOCUMENTATION.md.bak +0 -431
  397. package/server/lib/opencode/managed-process-registry.d.ts.bak +0 -13
  398. package/server/lib/opencode/provider-env-aliases.d.ts.bak +0 -3
  399. package/server/lib/permission-auto-accept/DOCUMENTATION.md.bak +0 -34
  400. package/server/lib/project-context/DOCUMENTATION.md.bak +0 -160
  401. package/server/lib/quota/DOCUMENTATION.md.bak +0 -123
  402. package/server/lib/relay/DOCUMENTATION.md.bak +0 -100
  403. package/server/lib/scheduled-tasks/DOCUMENTATION.md.bak +0 -182
  404. package/server/lib/session-assist/DOCUMENTATION.md.bak +0 -66
  405. package/server/lib/session-goal/DOCUMENTATION.md.bak +0 -213
  406. package/server/lib/session-knowledge/DOCUMENTATION.md.bak +0 -89
  407. package/server/lib/skills-catalog/DOCUMENTATION.md.bak +0 -151
  408. package/server/lib/small-model/DOCUMENTATION.md.bak +0 -212
  409. package/server/lib/system-prompt/DOCUMENTATION.md.bak +0 -36
  410. package/server/lib/terminal/DOCUMENTATION.md.bak +0 -50
  411. package/server/lib/text/DOCUMENTATION.md.bak +0 -35
  412. package/server/lib/tts/DOCUMENTATION.md.bak +0 -147
  413. package/server/lib/tunnels/DOCUMENTATION.md.bak +0 -21
  414. package/server/lib/ui-auth/DOCUMENTATION.md.bak +0 -44
  415. package/server/lib/walkthrough/DOCUMENTATION.md.bak +0 -411
@@ -5,10 +5,10 @@ function resolveSystemdServiceUnit(environment) {
5
5
  return null;
6
6
  }
7
7
 
8
- const configuredUnit = typeof environment.OPENCHAMBER_SYSTEMD_UNIT === 'string'
9
- ? environment.OPENCHAMBER_SYSTEMD_UNIT.trim()
8
+ const configuredUnit = typeof environment.AIWORKER_SYSTEMD_UNIT === 'string'
9
+ ? environment.AIWORKER_SYSTEMD_UNIT.trim()
10
10
  : '';
11
- const unit = configuredUnit || 'openchamber.service';
11
+ const unit = configuredUnit || 'aiworker.service';
12
12
  return SYSTEMD_SERVICE_UNIT_PATTERN.test(unit) ? unit : null;
13
13
  }
14
14
 
@@ -16,24 +16,26 @@ function quotePosixShell(value) {
16
16
  return `'${String(value).replace(/'/g, "'\\''")}'`;
17
17
  }
18
18
 
19
- export const registerOpenChamberRoutes = (app, dependencies) => {
19
+ export const registerAiWorkerRoutes = (app, dependencies) => {
20
20
  const {
21
21
  fs,
22
22
  path,
23
23
  process,
24
24
  server,
25
25
  __dirname,
26
- openchamberDataDir,
26
+ aiworkerDataDir,
27
27
  modelsDevApiUrl,
28
28
  modelsMetadataCacheTtl,
29
29
  readSettingsFromDiskMigrated,
30
30
  fetchFreeZenModels,
31
31
  getCachedZenModels,
32
+ desktopUpdater,
32
33
  } = dependencies;
33
34
 
35
+ let desktopRestartError = null;
36
+
34
37
  app.get('/api/openchamber/update-check', async (req, res) => {
35
38
  try {
36
- const { checkForUpdates } = await import('../package-manager.js');
37
39
  const parseString = (value) => (typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined);
38
40
  const parseReportUsage = (value) => {
39
41
  if (typeof value !== 'string') return true;
@@ -49,8 +51,7 @@ export const registerOpenChamberRoutes = (app, dependencies) => {
49
51
  return 'desktop';
50
52
  };
51
53
  const userAgent = typeof req.headers['user-agent'] === 'string' ? req.headers['user-agent'] : '';
52
-
53
- const updateInfo = await checkForUpdates({
54
+ const updateRequest = {
54
55
  appType: parseString(req.query.appType),
55
56
  deviceClass: parseString(req.query.deviceClass) || inferDeviceClass(userAgent),
56
57
  platform: parseString(req.query.platform),
@@ -59,7 +60,31 @@ export const registerOpenChamberRoutes = (app, dependencies) => {
59
60
  currentVersion: parseString(req.query.currentVersion),
60
61
  installId: parseString(req.query.installId),
61
62
  reportUsage: parseReportUsage(parseString(req.query.reportUsage)),
62
- });
63
+ };
64
+ let updateInfo;
65
+ if (process.env.AIWORKER_RUNTIME === 'desktop' && updateRequest.appType === 'web') {
66
+ if (desktopRestartError && req.query.updateStatus === 'true') {
67
+ return res.status(503).json({
68
+ code: 'DESKTOP_UPDATE_RESTART_FAILED',
69
+ error: desktopRestartError,
70
+ });
71
+ }
72
+ if (typeof desktopUpdater?.check !== 'function') {
73
+ return res.status(503).json({
74
+ available: false,
75
+ code: 'DESKTOP_UPDATER_UNAVAILABLE',
76
+ error: 'The desktop updater is not available.',
77
+ });
78
+ }
79
+ updateInfo = {
80
+ ...await desktopUpdater.check(),
81
+ packageManager: 'electron',
82
+ updateOwner: 'electron-updater',
83
+ };
84
+ } else {
85
+ const { checkForUpdates } = await import('../package-manager.js');
86
+ updateInfo = await checkForUpdates(updateRequest);
87
+ }
63
88
  res.json(updateInfo);
64
89
  } catch (error) {
65
90
  console.error('Failed to check for updates:', error);
@@ -72,6 +97,41 @@ export const registerOpenChamberRoutes = (app, dependencies) => {
72
97
 
73
98
  app.post('/api/openchamber/update-install', async (_req, res) => {
74
99
  try {
100
+ if (process.env.AIWORKER_RUNTIME === 'desktop') {
101
+ if (typeof desktopUpdater?.install !== 'function' || typeof desktopUpdater?.restart !== 'function') {
102
+ return res.status(503).json({
103
+ code: 'DESKTOP_UPDATER_UNAVAILABLE',
104
+ error: 'The desktop updater is not available.',
105
+ });
106
+ }
107
+
108
+ desktopRestartError = null;
109
+ const updateInfo = await desktopUpdater.install();
110
+ if (!updateInfo?.available) {
111
+ return res.status(400).json({ error: 'No update available' });
112
+ }
113
+
114
+ res.json({
115
+ success: true,
116
+ message: 'Desktop update downloaded, host will restart shortly',
117
+ version: updateInfo.version,
118
+ packageManager: 'electron',
119
+ updateOwner: 'electron-updater',
120
+ autoRestart: true,
121
+ restartManager: 'electron-updater',
122
+ });
123
+
124
+ setImmediate(() => {
125
+ Promise.resolve()
126
+ .then(() => desktopUpdater.restart())
127
+ .catch((error) => {
128
+ desktopRestartError = error instanceof Error ? error.message : 'Failed to restart after desktop update';
129
+ console.error('Failed to restart after desktop update:', error);
130
+ });
131
+ });
132
+ return;
133
+ }
134
+
75
135
  const { spawn: spawnChild, spawnSync } = await import('child_process');
76
136
  const {
77
137
  checkForUpdates,
@@ -119,7 +179,7 @@ export const registerOpenChamberRoutes = (app, dependencies) => {
119
179
  }
120
180
 
121
181
  const currentPort = server.address()?.port || 3000;
122
- const instanceFilePath = path.join(openchamberDataDir, 'run', `openchamber-${currentPort}.json`);
182
+ const instanceFilePath = path.join(aiworkerDataDir, 'run', `openchamber-${currentPort}.json`);
123
183
  let storedOptions = { port: currentPort, daemon: true };
124
184
  try {
125
185
  const content = await fs.promises.readFile(instanceFilePath, 'utf8');
@@ -133,7 +193,7 @@ export const registerOpenChamberRoutes = (app, dependencies) => {
133
193
  if (isForegroundService) {
134
194
  if (!systemdServiceUnit) {
135
195
  return res.status(409).json({
136
- error: 'Foreground servers must be updated by their service manager. Set OPENCHAMBER_SYSTEMD_UNIT when running under systemd, or run openchamber update and restart the service.',
196
+ error: 'Foreground servers must be updated by their service manager. Set AIWORKER_SYSTEMD_UNIT when running under systemd, or run aiworker update and restart the service.',
137
197
  });
138
198
  }
139
199
 
@@ -168,7 +228,7 @@ export const registerOpenChamberRoutes = (app, dependencies) => {
168
228
 
169
229
  return res.json({
170
230
  success: true,
171
- message: 'Update queued; OpenChamber will restart after installation completes',
231
+ message: 'Update queued; AiWorker will restart after installation completes',
172
232
  version: updateInfo.version,
173
233
  packageManager: pm,
174
234
  autoRestart: true,
@@ -194,7 +254,7 @@ export const registerOpenChamberRoutes = (app, dependencies) => {
194
254
  String(storedOptions.port),
195
255
  ];
196
256
  let restartCmdPrimary = restartParts.join(' ');
197
- let restartCmdFallback = `openchamber serve --port ${storedOptions.port}`;
257
+ let restartCmdFallback = `aiworker serve --port ${storedOptions.port}`;
198
258
  if (storedOptions.host) {
199
259
  if (isWindows) {
200
260
  const escapedHost = storedOptions.host.replace(/"/g, '""');
@@ -222,10 +282,10 @@ export const registerOpenChamberRoutes = (app, dependencies) => {
222
282
  restartCmdFallback += ' --api-only';
223
283
  }
224
284
  const restartCmd = isForegroundService ? '' : `(${restartCmdPrimary}) || (${restartCmdFallback})`;
225
- const updateLogPath = path.join(openchamberDataDir, 'update-install.log');
285
+ const updateLogPath = path.join(aiworkerDataDir, 'update-install.log');
226
286
  const logPreamble = [
227
287
  '',
228
- `=== OpenChamber update ${new Date().toISOString()} ===`,
288
+ `=== AiWorker update ${new Date().toISOString()} ===`,
229
289
  `currentVersion=${updateInfo.currentVersion || 'unknown'}`,
230
290
  `targetVersion=${updateInfo.version || 'unknown'}`,
231
291
  `packageManager=${pm}`,
@@ -262,8 +322,8 @@ export const registerOpenChamberRoutes = (app, dependencies) => {
262
322
  timeout /t 2 /nobreak >nul
263
323
  ${updateCmd}
264
324
  if %ERRORLEVEL% EQU 0 (
265
- echo Update successful, restarting OpenChamber...
266
- ${restartCmd || 'echo Service manager will restart OpenChamber.'}
325
+ echo Update successful, restarting AiWorker...
326
+ ${restartCmd || 'echo Service manager will restart AiWorker.'}
267
327
  ) else (
268
328
  echo Update failed
269
329
  exit /b 1
@@ -274,8 +334,8 @@ export const registerOpenChamberRoutes = (app, dependencies) => {
274
334
  sleep 2
275
335
  ${updateCmd}
276
336
  if [ $? -eq 0 ]; then
277
- echo "Update successful, restarting OpenChamber..."
278
- ${restartCmd || 'echo "Service manager will restart OpenChamber."'}
337
+ echo "Update successful, restarting AiWorker..."
338
+ ${restartCmd || 'echo "Service manager will restart AiWorker."'}
279
339
  else
280
340
  echo "Update failed"
281
341
  exit 1
@@ -16,9 +16,9 @@ vi.mock('../package-manager.js', () => ({
16
16
 
17
17
  const childProcess = await import('child_process');
18
18
  const packageManager = await import('../package-manager.js');
19
- const { registerOpenChamberRoutes } = await import('./openchamber-routes.js');
19
+ const { registerAiWorkerRoutes } = await import('./openchamber-routes.js');
20
20
 
21
- const createApp = ({ environment = {}, storedOptions = {} } = {}) => {
21
+ const createApp = ({ environment = {}, storedOptions = {}, desktopUpdater } = {}) => {
22
22
  const app = express();
23
23
  const dependencies = {
24
24
  fs: {
@@ -41,15 +41,16 @@ const createApp = ({ environment = {}, storedOptions = {} } = {}) => {
41
41
  address: () => ({ port: 7897 }),
42
42
  },
43
43
  __dirname: '/opt/openchamber/server',
44
- openchamberDataDir: '/tmp/openchamber',
44
+ aiworkerDataDir: '/tmp/openchamber',
45
45
  modelsDevApiUrl: 'https://models.example.test',
46
46
  modelsMetadataCacheTtl: 0,
47
47
  readSettingsFromDiskMigrated: vi.fn(),
48
48
  fetchFreeZenModels: vi.fn(),
49
49
  getCachedZenModels: vi.fn(),
50
+ desktopUpdater,
50
51
  };
51
52
 
52
- registerOpenChamberRoutes(app, dependencies);
53
+ registerAiWorkerRoutes(app, dependencies);
53
54
  return { app, dependencies };
54
55
  };
55
56
 
@@ -61,7 +62,7 @@ beforeEach(() => {
61
62
  packageManager.detectPackageManagerDetails.mockReturnValue({
62
63
  packageManager: 'npm',
63
64
  });
64
- packageManager.getUpdateCommand.mockReturnValue('npm install -g @openchamber/web@latest');
65
+ packageManager.getUpdateCommand.mockReturnValue('npm install -g @aiworker/web@latest');
65
66
  });
66
67
 
67
68
  afterEach(() => {
@@ -69,14 +70,140 @@ afterEach(() => {
69
70
  vi.clearAllMocks();
70
71
  });
71
72
 
72
- describe('OpenChamber foreground update route', () => {
73
+ describe('AiWorker desktop host update route', () => {
74
+ it('reports a restart rejection until the user retries installation', async () => {
75
+ const desktopUpdater = {
76
+ check: vi.fn(async () => ({ available: true, currentVersion: '1.17.0', version: '1.17.1' })),
77
+ install: vi.fn(async () => ({ available: true, version: '1.17.1' })),
78
+ restart: vi.fn().mockRejectedValueOnce(new Error('Signature rejected')).mockResolvedValue(undefined),
79
+ };
80
+ const { app } = createApp({ environment: { AIWORKER_RUNTIME: 'desktop' }, desktopUpdater });
81
+ const logError = vi.spyOn(console, 'error').mockImplementation(() => {});
82
+
83
+ await request(app).post('/api/openchamber/update-install').expect(200);
84
+ await new Promise(resolve => setImmediate(resolve));
85
+ await request(app).get('/api/openchamber/update-check?appType=web&reportUsage=false&updateStatus=true').expect(503, {
86
+ code: 'DESKTOP_UPDATE_RESTART_FAILED', error: 'Signature rejected',
87
+ });
88
+ expect(desktopUpdater.check).not.toHaveBeenCalled();
89
+ expect(logError).toHaveBeenCalledOnce();
90
+ // Availability remains reachable after a browser reload, so users can retry.
91
+ await request(app).get('/api/openchamber/update-check?appType=web&reportUsage=false').expect(200);
92
+
93
+ await request(app).post('/api/openchamber/update-install').expect(200);
94
+ await new Promise(resolve => setImmediate(resolve));
95
+ const response = await request(app).get('/api/openchamber/update-check?appType=web&reportUsage=false').expect(200);
96
+ expect(response.body.currentVersion).toBe('1.17.0');
97
+ expect(response.body.updateOwner).toBe('electron-updater');
98
+ expect(packageManager.checkForUpdates).not.toHaveBeenCalled();
99
+ });
100
+
101
+ it('rejects native checks without a bridge and preserves explicit non-web checks', async () => {
102
+ const { app } = createApp({ environment: { AIWORKER_RUNTIME: 'desktop' } });
103
+ await request(app).get('/api/openchamber/update-check?appType=web').expect(503, {
104
+ available: false, code: 'DESKTOP_UPDATER_UNAVAILABLE', error: 'The desktop updater is not available.',
105
+ });
106
+ expect(packageManager.checkForUpdates).not.toHaveBeenCalled();
107
+ await request(app).get('/api/openchamber/update-check?appType=desktop-electron').expect(200);
108
+ expect(packageManager.checkForUpdates).toHaveBeenCalledOnce();
109
+ });
110
+
111
+ it('uses electron-updater to check for Web client updates', async () => {
112
+ const desktopUpdater = {
113
+ check: vi.fn(async () => ({
114
+ available: true,
115
+ currentVersion: '1.17.0',
116
+ version: '1.17.1',
117
+ })),
118
+ install: vi.fn(),
119
+ restart: vi.fn(),
120
+ };
121
+ const { app } = createApp({
122
+ environment: {
123
+ AIWORKER_RUNTIME: 'desktop',
124
+ },
125
+ desktopUpdater,
126
+ });
127
+
128
+ await request(app)
129
+ .get('/api/openchamber/update-check?appType=web&reportUsage=false')
130
+ .expect(200, {
131
+ available: true,
132
+ currentVersion: '1.17.0',
133
+ version: '1.17.1',
134
+ packageManager: 'electron',
135
+ updateOwner: 'electron-updater',
136
+ });
137
+
138
+ expect(desktopUpdater.check).toHaveBeenCalledOnce();
139
+ expect(packageManager.checkForUpdates).not.toHaveBeenCalled();
140
+ });
141
+
142
+ it('installs through electron-updater and restarts after responding', async () => {
143
+ const desktopUpdater = {
144
+ check: vi.fn(),
145
+ install: vi.fn(async () => ({
146
+ available: true,
147
+ version: '1.17.1',
148
+ })),
149
+ restart: vi.fn(),
150
+ };
151
+ const { app } = createApp({
152
+ environment: {
153
+ AIWORKER_RUNTIME: 'desktop',
154
+ },
155
+ desktopUpdater,
156
+ });
157
+
158
+ await request(app)
159
+ .post('/api/openchamber/update-install')
160
+ .expect(200, {
161
+ success: true,
162
+ message: 'Desktop update downloaded, host will restart shortly',
163
+ version: '1.17.1',
164
+ packageManager: 'electron',
165
+ updateOwner: 'electron-updater',
166
+ autoRestart: true,
167
+ restartManager: 'electron-updater',
168
+ });
169
+ await new Promise((resolve) => setImmediate(resolve));
170
+
171
+ expect(desktopUpdater.install).toHaveBeenCalledOnce();
172
+ expect(desktopUpdater.restart).toHaveBeenCalledOnce();
173
+ expect(packageManager.checkForUpdates).not.toHaveBeenCalled();
174
+ expect(packageManager.detectPackageManagerDetails).not.toHaveBeenCalled();
175
+ expect(packageManager.getUpdateCommand).not.toHaveBeenCalled();
176
+ expect(childProcess.spawn).not.toHaveBeenCalled();
177
+ expect(childProcess.spawnSync).not.toHaveBeenCalled();
178
+ });
179
+
180
+ it('fails safely when the Electron updater bridge is unavailable', async () => {
181
+ const { app } = createApp({
182
+ environment: {
183
+ AIWORKER_RUNTIME: 'desktop',
184
+ },
185
+ });
186
+
187
+ await request(app)
188
+ .post('/api/openchamber/update-install')
189
+ .expect(503, {
190
+ code: 'DESKTOP_UPDATER_UNAVAILABLE',
191
+ error: 'The desktop updater is not available.',
192
+ });
193
+
194
+ expect(packageManager.checkForUpdates).not.toHaveBeenCalled();
195
+ expect(childProcess.spawn).not.toHaveBeenCalled();
196
+ });
197
+ });
198
+
199
+ describe('AiWorker foreground update route', () => {
73
200
  it('rejects a foreground update when the server is not owned by systemd', async () => {
74
201
  const { app } = createApp();
75
202
 
76
203
  await request(app)
77
204
  .post('/api/openchamber/update-install')
78
205
  .expect(409, {
79
- error: 'Foreground servers must be updated by their service manager. Set OPENCHAMBER_SYSTEMD_UNIT when running under systemd, or run openchamber update and restart the service.',
206
+ error: 'Foreground servers must be updated by their service manager. Set AIWORKER_SYSTEMD_UNIT when running under systemd, or run aiworker update and restart the service.',
80
207
  });
81
208
 
82
209
  expect(childProcess.spawnSync).not.toHaveBeenCalled();
@@ -86,14 +213,14 @@ describe('OpenChamber foreground update route', () => {
86
213
  const { app } = createApp({
87
214
  environment: {
88
215
  INVOCATION_ID: 'systemd-invocation',
89
- OPENCHAMBER_SYSTEMD_UNIT: 'openchamber.service; rm -rf /',
216
+ AIWORKER_SYSTEMD_UNIT: 'aiworker.service; rm -rf /',
90
217
  },
91
218
  });
92
219
 
93
220
  await request(app)
94
221
  .post('/api/openchamber/update-install')
95
222
  .expect(409, {
96
- error: 'Foreground servers must be updated by their service manager. Set OPENCHAMBER_SYSTEMD_UNIT when running under systemd, or run openchamber update and restart the service.',
223
+ error: 'Foreground servers must be updated by their service manager. Set AIWORKER_SYSTEMD_UNIT when running under systemd, or run aiworker update and restart the service.',
97
224
  });
98
225
 
99
226
  expect(childProcess.spawnSync).not.toHaveBeenCalled();
@@ -105,7 +232,7 @@ describe('OpenChamber foreground update route', () => {
105
232
  const { app } = createApp({
106
233
  environment: {
107
234
  INVOCATION_ID: 'systemd-invocation',
108
- OPENCHAMBER_SYSTEMD_UNIT: 'openchamber@wsl.service',
235
+ AIWORKER_SYSTEMD_UNIT: 'aiworker@wsl.service',
109
236
  PATH: '/home/syu/.npm-global/bin:/usr/bin:/bin',
110
237
  },
111
238
  });
@@ -114,7 +241,7 @@ describe('OpenChamber foreground update route', () => {
114
241
  .post('/api/openchamber/update-install')
115
242
  .expect(200, {
116
243
  success: true,
117
- message: 'Update queued; OpenChamber will restart after installation completes',
244
+ message: 'Update queued; AiWorker will restart after installation completes',
118
245
  version: '1.17.1',
119
246
  packageManager: 'npm',
120
247
  autoRestart: true,
@@ -131,7 +258,7 @@ describe('OpenChamber foreground update route', () => {
131
258
  '--setenv=PATH=/home/syu/.npm-global/bin:/usr/bin:/bin',
132
259
  '/bin/sh',
133
260
  '-c',
134
- "set -eu\nnpm install -g @openchamber/web@latest\nsystemctl --user restart 'openchamber@wsl.service'",
261
+ "set -eu\nnpm install -g @aiworker/web@latest\nsystemctl --user restart 'aiworker@wsl.service'",
135
262
  ], {
136
263
  encoding: 'utf8',
137
264
  stdio: ['ignore', 'pipe', 'pipe'],
@@ -1,8 +1,8 @@
1
1
  import fs from 'fs';
2
- import os from 'os';
3
2
  import path from 'path';
4
3
  import {
5
4
  AGENT_SCOPE,
5
+ OPENCODE_CONFIG_DIR,
6
6
  readConfigFile,
7
7
  readConfigLayer,
8
8
  writeConfig,
@@ -71,7 +71,7 @@ function getActiveOpencodeConfigDir() {
71
71
  if (customConfigPath) {
72
72
  return path.dirname(path.resolve(customConfigPath));
73
73
  }
74
- return path.join(os.homedir(), '.config', 'opencode');
74
+ return OPENCODE_CONFIG_DIR;
75
75
  }
76
76
 
77
77
  function getActiveUserConfigPaths() {
@@ -136,7 +136,7 @@ describe('opencode plugins data layer', () => {
136
136
 
137
137
  expect(plugins.listPluginEntries(projectDir).map((entry) => entry.spec)).toEqual(['user-plugin']);
138
138
  expect(fs.readFileSync(projectFile, 'utf8')).toBe(partialProject);
139
- expect(fs.existsSync(`${projectFile}.openchamber.backup`)).toBe(false);
139
+ expect(fs.existsSync(`${projectFile}.aiworker.backup`)).toBe(false);
140
140
  });
141
141
 
142
142
  test('lists entries from user and project layers with scopes and parsed kinds', () => {
@@ -3,7 +3,7 @@ export const registerProjectIconRoutes = (app, dependencies) => {
3
3
  fsPromises,
4
4
  path,
5
5
  crypto,
6
- openchamberDataDir,
6
+ aiworkerDataDir,
7
7
  sanitizeProjects,
8
8
  readSettingsFromDiskMigrated,
9
9
  persistSettings,
@@ -12,7 +12,7 @@ export const registerProjectIconRoutes = (app, dependencies) => {
12
12
  resolveGitBinaryForSpawn,
13
13
  } = dependencies;
14
14
 
15
- const projectIconsDirPath = path.join(openchamberDataDir, 'project-icons');
15
+ const projectIconsDirPath = path.join(aiworkerDataDir, 'project-icons');
16
16
  const projectIconMimeToExtension = {
17
17
  'image/png': 'png',
18
18
  'image/jpeg': 'jpg',
@@ -79,7 +79,7 @@ describe('project icon routes', () => {
79
79
  fsPromises,
80
80
  path,
81
81
  crypto,
82
- openchamberDataDir: '/tmp/openchamber-test',
82
+ aiworkerDataDir: '/tmp/openchamber-test',
83
83
  sanitizeProjects: (projects) => projects,
84
84
  readSettingsFromDiskMigrated: async () => ({
85
85
  projects: [{
@@ -152,6 +152,37 @@ function validateCustomProviderConfig(providerId, config, options = {}) {
152
152
  return { ok: true, value: { providerId, config: normalized } };
153
153
  }
154
154
 
155
+ function mergeCustomProviderConfig(existingValue, normalizedConfig) {
156
+ const existing = isPlainObject(existingValue) ? existingValue : {};
157
+ const existingOptions = isPlainObject(existing.options) ? existing.options : {};
158
+ const normalizedOptions = isPlainObject(normalizedConfig.options) ? normalizedConfig.options : {};
159
+ const mergedOptions = { ...existingOptions, ...normalizedOptions };
160
+ if (!Object.prototype.hasOwnProperty.call(normalizedOptions, 'headers')) {
161
+ delete mergedOptions.headers;
162
+ }
163
+
164
+ const existingModels = isPlainObject(existing.models) ? existing.models : {};
165
+ const normalizedModels = isPlainObject(normalizedConfig.models) ? normalizedConfig.models : {};
166
+ const mergedModels = Object.fromEntries(
167
+ Object.entries(normalizedModels).map(([modelId, normalizedModel]) => {
168
+ const existingModel = isPlainObject(existingModels[modelId]) ? existingModels[modelId] : {};
169
+ const nextModel = isPlainObject(normalizedModel) ? normalizedModel : {};
170
+ return [modelId, { ...existingModel, ...nextModel }];
171
+ }),
172
+ );
173
+
174
+ const merged = {
175
+ ...existing,
176
+ ...normalizedConfig,
177
+ options: mergedOptions,
178
+ models: mergedModels,
179
+ };
180
+ if (!Object.prototype.hasOwnProperty.call(normalizedConfig, 'env')) {
181
+ delete merged.env;
182
+ }
183
+ return merged;
184
+ }
185
+
155
186
  /**
156
187
  * Persist (create or update) a custom provider block in OpenCode user/project/custom config.
157
188
  * Does not write secrets — API keys remain in auth.json via the OpenCode auth API.
@@ -183,8 +214,19 @@ function upsertProviderConfig(providerId, config, workingDirectory, scope = 'use
183
214
 
184
215
  const targetConfig = getConfigForPath(layers, targetPath);
185
216
  const providerConfig = isPlainObject(targetConfig.provider) ? { ...targetConfig.provider } : {};
186
- providerConfig[validated.value.providerId] = validated.value.config;
217
+ const providersAlias = isPlainObject(targetConfig.providers) ? { ...targetConfig.providers } : {};
218
+ const existingProvider = providerConfig[validated.value.providerId] ?? providersAlias[validated.value.providerId];
219
+ const mergedConfig = mergeCustomProviderConfig(existingProvider, validated.value.config);
220
+ providerConfig[validated.value.providerId] = mergedConfig;
187
221
  targetConfig.provider = providerConfig;
222
+ if (Object.prototype.hasOwnProperty.call(providersAlias, validated.value.providerId)) {
223
+ delete providersAlias[validated.value.providerId];
224
+ if (Object.keys(providersAlias).length === 0) {
225
+ delete targetConfig.providers;
226
+ } else {
227
+ targetConfig.providers = providersAlias;
228
+ }
229
+ }
188
230
 
189
231
  if (Array.isArray(targetConfig.disabled_providers)) {
190
232
  targetConfig.disabled_providers = targetConfig.disabled_providers.filter(
@@ -198,7 +240,7 @@ function upsertProviderConfig(providerId, config, workingDirectory, scope = 'use
198
240
  return {
199
241
  providerId: validated.value.providerId,
200
242
  path: writePath,
201
- config: validated.value.config,
243
+ config: mergedConfig,
202
244
  };
203
245
  }
204
246