@aiworker/web 1.22.0 → 1.22.2

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 (354) hide show
  1. package/README.md +4 -4
  2. package/bin/cli.js +7 -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-CSICpWQD.js} +1 -1
  28. package/dist/assets/{DiffView-DluiRSla.js → DiffView-hDBKesA_.js} +3 -3
  29. package/dist/assets/DirtyBranchSwitchDialog-C22HdWj4.js +1 -0
  30. package/dist/assets/FilesView-CdWzeOp9.js +17 -0
  31. package/dist/assets/GitView-VQQkYuUw.js +6 -0
  32. package/dist/assets/{JsonTreeView-B0BdZEHG.js → JsonTreeView-6lrhwD3q.js} +1 -1
  33. package/dist/assets/LinearIssuesView-Ba6Q9569.js +1 -0
  34. package/dist/assets/{MarkdownImageGallery-ClOvuZxC.js → MarkdownImageGallery-Czv_mhvS.js} +1 -1
  35. package/dist/assets/MarkdownRendererImpl-BrMcswiy.js +12 -0
  36. package/dist/assets/{OnboardingScreen-D2DG7K6b.js → OnboardingScreen-ChxQoAkx.js} +1 -1
  37. package/dist/assets/{PatchDiff-DvfqDql7.js → PatchDiff-BzcZPlOq.js} +1 -1
  38. package/dist/assets/{PierreDiffViewer-B7m3f0d7.js → PierreDiffViewer-BchBtZlp.js} +2 -2
  39. package/dist/assets/PlanView-DyDt_nZ_.js +5 -0
  40. package/dist/assets/SettingsView-BKf5xBsP.js +28 -0
  41. package/dist/assets/{SettingsWindow-i45U1Cy1.js → SettingsWindow-DDQYaKWQ.js} +1 -1
  42. package/dist/assets/{ToolOutputDialog-BTwyh5OF.js → ToolOutputDialog-iYF8Y2bz.js} +6 -6
  43. package/dist/assets/ToolPartDiffPreview-CdjbOVMM.js +8 -0
  44. package/dist/assets/{VirtualizedFileDiff-DD8lDVej.js → VirtualizedFileDiff-fFFm2QgH.js} +1 -1
  45. package/dist/assets/{WalkthroughView-egQgxel3.js → WalkthroughView-DOeCsMju.js} +2 -2
  46. package/dist/assets/{computeVirtualFileMetrics-BMIRgMHv.js → computeVirtualFileMetrics-CzgLum_K.js} +2 -2
  47. package/dist/assets/{contextPanelEmbeddedChat-C3fjDbdg.js → contextPanelEmbeddedChat-C0ZLAepL.js} +1 -1
  48. package/dist/assets/{de-C1P6X5Rs.js → de-B5JaA3SA.js} +6 -5
  49. package/dist/assets/{es-CDgaF1_t.js → es-EPIH88ii.js} +6 -5
  50. package/dist/assets/{fr-Bgxqvvz_.js → fr-CAMfxUdZ.js} +6 -5
  51. package/dist/assets/{index-CODwDsU_.js → index-Bl3LSbjn.js} +1 -1
  52. package/dist/assets/index-DF5kMP-i.js +39 -0
  53. package/dist/assets/index-Dl3xbAB_.css +1 -0
  54. package/dist/assets/{isDiffPlainText-BqayB8d3.js → isDiffPlainText-Dx-dB_8l.js} +1 -1
  55. package/dist/assets/{isFilePlainText-QfoiKJNY.js → isFilePlainText-CWFPwmnU.js} +1 -1
  56. package/dist/assets/{ja-BDRrEcNP.js → ja-CifOE1VN.js} +7 -6
  57. package/dist/assets/{ko-Ba8sQV79.js → ko-BBDyAyYQ.js} +7 -6
  58. package/dist/assets/{main-C5DVOxc6.js → main-DnBAoktx.js} +2 -2
  59. package/dist/assets/main-MhSaOZoB.js +930 -0
  60. package/dist/assets/{markdownCore-CZwzz5gw.js → markdownCore-BrBwOOMn.js} +2 -2
  61. package/dist/assets/{miniChat-DUJ4irZc.js → miniChat-BKyvLseN.js} +2 -2
  62. package/dist/assets/{mobile-CcaxB0n4.js → mobile-DKjeFgMN.js} +2 -2
  63. package/dist/assets/{patchFileDiff-yNfWXN4E.js → patchFileDiff-o8ms1me8.js} +1 -1
  64. package/dist/assets/pl-DgEHYfFM.js +16 -0
  65. package/dist/assets/{pt-BR-DIs6ElwV.js → pt-BR-DuWHojUw.js} +6 -5
  66. package/dist/assets/{renderElectronMiniChatApp-BcKLHXKe.js → renderElectronMiniChatApp-CDgBwwCS.js} +2 -2
  67. package/dist/assets/renderMobileApp-DJIKIK1r.js +25 -0
  68. package/dist/assets/runtimeEndpointReset-CYJ9O_xX.js +17 -0
  69. package/dist/assets/{scheduledTasksApi-DLW0mkQK.js → scheduledTasksApi-D8yamh1b.js} +1 -1
  70. package/dist/assets/{shikiHighlight-DYOWuY65.js → shikiHighlight-TEQCmzW8.js} +1 -1
  71. package/dist/assets/tr-D5m2yIWL.js +7 -0
  72. package/dist/assets/{uk-ZrCNjM7Y.js → uk-D_q60oog.js} +6 -5
  73. package/dist/assets/{useAppFontEffects-CjrntdL0.js → useAppFontEffects-D7sNpuL2.js} +161 -190
  74. package/dist/assets/useInlineCommentController-Brz_cLcQ.js +2 -0
  75. package/dist/assets/{useRootScrollLock-BHYPkrLv.js → useRootScrollLock-lXEnWlaU.js} +1 -1
  76. package/dist/assets/{vendor-codemirror-language-data-DFZik9R2.js → vendor-codemirror-language-data-Dp3KMRQG.js} +2 -2
  77. package/dist/assets/vendor-zod-CK21ihK-.js +39 -0
  78. package/dist/assets/{web-components-Bhg83tjf.js → web-components-_mNEMjFY.js} +1 -1
  79. package/dist/assets/{zh-CN-iv_AV4EC.js → zh-CN-D8QvsVeg.js} +6 -5
  80. package/dist/assets/{zh-TW-CzEUk38j.js → zh-TW-B9t7rQQO.js} +6 -5
  81. package/dist/index.html +22 -22
  82. package/dist/mini-chat.html +7 -7
  83. package/dist/mobile.html +5 -5
  84. package/package.json +3 -3
  85. package/server/index.js +118 -85
  86. package/server/lib/agent-memory/actions.js +2 -2
  87. package/server/lib/agent-memory/feature-flag.js +1 -1
  88. package/server/lib/agent-memory/feature-flag.test.js +8 -8
  89. package/server/lib/agent-memory/routes.js +2 -2
  90. package/server/lib/agent-tool/runtime.js +37 -54
  91. package/server/lib/agent-tool/runtime.test.js +59 -59
  92. package/server/lib/browser-control/broker.js +3 -3
  93. package/server/lib/browser-control/broker.test.js +1 -1
  94. package/server/lib/changelog/update-notes.js +82 -0
  95. package/server/lib/changelog/update-notes.test.js +59 -0
  96. package/server/lib/client-auth/remote-clients.test.js +5 -5
  97. package/server/lib/context-obligatory/runtime.js +7 -7
  98. package/server/lib/context-obligatory/runtime.test.js +5 -5
  99. package/server/lib/dev-servers/parse.js +2 -2
  100. package/server/lib/dev-servers/parse.test.js +2 -2
  101. package/server/lib/dev-servers/routes.js +1 -1
  102. package/server/lib/dev-tunnel/DOCUMENTATION.md +13 -4
  103. package/server/lib/dev-tunnel/client.js +1 -1
  104. package/server/lib/dev-tunnel/runtime.js +5 -5
  105. package/server/lib/dev-tunnel/tunnel.test.js +21 -1
  106. package/server/lib/dictation/local/model-catalog.js +1 -1
  107. package/server/lib/dictation/local/worker-process.js +2 -2
  108. package/server/lib/event-stream/directory-ws-bridge.js +1 -1
  109. package/server/lib/event-stream/global-ws-bridge.js +1 -1
  110. package/server/lib/event-stream/protocol.test.js +4 -4
  111. package/server/lib/event-stream/runtime.test.js +6 -6
  112. package/server/lib/fs/DOCUMENTATION.md +2 -0
  113. package/server/lib/fs/routes.js +37 -26
  114. package/server/lib/fs/routes.test.js +98 -21
  115. package/server/lib/git/DOCUMENTATION.md +3 -1
  116. package/server/lib/git/identity-storage.js +1 -1
  117. package/server/lib/git/issue-2746-longpaths.test.js +4 -4
  118. package/server/lib/git/routes.js +17 -1
  119. package/server/lib/git/service.js +116 -26
  120. package/server/lib/git/service.test.js +174 -3
  121. package/server/lib/github/auth.js +8 -8
  122. package/server/lib/github/pr-status.js +1 -1
  123. package/server/lib/github/routes.js +2 -2
  124. package/server/lib/inherited-env.js +1 -1
  125. package/server/lib/inherited-env.test.js +2 -2
  126. package/server/lib/linear/auth.js +8 -8
  127. package/server/lib/linear/auth.test.js +24 -24
  128. package/server/lib/linear/issues.test.js +6 -6
  129. package/server/lib/linear/mapping.test.js +4 -4
  130. package/server/lib/linear/oauth.js +2 -2
  131. package/server/lib/linear/oauth.test.js +14 -14
  132. package/server/lib/linear/routes.js +5 -5
  133. package/server/lib/linear/routes.test.js +16 -16
  134. package/server/lib/linear/status-runtime.test.js +9 -9
  135. package/server/lib/linear/status.js +1 -1
  136. package/server/lib/linear/status.test.js +15 -15
  137. package/server/lib/linear/teams.test.js +4 -4
  138. package/server/lib/magic-prompts/routes.js +2 -2
  139. package/server/lib/mcp-reconnect/DOCUMENTATION.md +55 -0
  140. package/server/lib/mcp-reconnect/runtime.js +122 -0
  141. package/server/lib/mcp-reconnect/runtime.test.js +140 -0
  142. package/server/lib/message-queue/DOCUMENTATION.md +158 -0
  143. package/server/lib/message-queue/runtime.js +870 -0
  144. package/server/lib/message-queue/runtime.test.js +482 -0
  145. package/server/lib/notifications/apns-runtime.js +17 -17
  146. package/server/lib/notifications/apns-runtime.test.js +11 -11
  147. package/server/lib/notifications/emitter-runtime.js +1 -1
  148. package/server/lib/notifications/emitter-runtime.test.js +1 -1
  149. package/server/lib/notifications/push-runtime.js +7 -7
  150. package/server/lib/notifications/routes.js +1 -1
  151. package/server/lib/notifications/runtime.js +1 -1
  152. package/server/lib/openchamber-control/action-resolution.test.js +10 -10
  153. package/server/lib/openchamber-control/actions.js +24 -24
  154. package/server/lib/openchamber-control/error.js +4 -4
  155. package/server/lib/openchamber-control/routes.js +2 -2
  156. package/server/lib/openchamber-control/routes.test.js +5 -5
  157. package/server/lib/openchamber-control/screenshots.js +1 -1
  158. package/server/lib/openchamber-control/screenshots.test.js +1 -1
  159. package/server/lib/openchamber-control/service.js +50 -50
  160. package/server/lib/openchamber-control/service.test.js +5 -5
  161. package/server/lib/openchamber-sessions/routes.js +124 -22
  162. package/server/lib/openchamber-sessions/routes.test.js +99 -11
  163. package/server/lib/opencode/DOCUMENTATION.md +13 -5
  164. package/server/lib/opencode/auth.js +1 -1
  165. package/server/lib/opencode/bootstrap-runtime.js +6 -6
  166. package/server/lib/opencode/cli-options.js +8 -8
  167. package/server/lib/opencode/config-paths.test.js +116 -0
  168. package/server/lib/opencode/core-routes.js +8 -7
  169. package/server/lib/opencode/core-routes.test.js +11 -11
  170. package/server/lib/opencode/env-config.js +5 -5
  171. package/server/lib/opencode/env-config.test.js +7 -7
  172. package/server/lib/opencode/env-runtime.js +10 -10
  173. package/server/lib/opencode/env-runtime.test.js +18 -18
  174. package/server/lib/opencode/feature-routes-runtime.js +17 -12
  175. package/server/lib/opencode/hmr-state-runtime.js +2 -2
  176. package/server/lib/opencode/hmr-state-runtime.test.js +1 -1
  177. package/server/lib/opencode/input-history-scope.js +14 -0
  178. package/server/lib/opencode/lifecycle.js +8 -8
  179. package/server/lib/opencode/lifecycle.test.js +4 -4
  180. package/server/lib/opencode/managed-plugin-config.js +35 -0
  181. package/server/lib/opencode/managed-process-registry.js +3 -3
  182. package/server/lib/opencode/mcp-oauth-callback.test.js +2 -2
  183. package/server/lib/opencode/openchamber-routes.js +15 -15
  184. package/server/lib/opencode/openchamber-routes.test.js +11 -11
  185. package/server/lib/opencode/plugins.js +2 -2
  186. package/server/lib/opencode/plugins.test.js +1 -1
  187. package/server/lib/opencode/project-icon-routes.js +2 -2
  188. package/server/lib/opencode/project-icon-routes.test.js +1 -1
  189. package/server/lib/opencode/providers.js +44 -2
  190. package/server/lib/opencode/providers.test.js +131 -4
  191. package/server/lib/opencode/proxy.js +2 -2
  192. package/server/lib/opencode/pwa-manifest-routes.js +1 -1
  193. package/server/lib/opencode/restart-session-recovery.test.js +1 -1
  194. package/server/lib/opencode/routes-upgrade.test.js +4 -4
  195. package/server/lib/opencode/routes.js +14 -14
  196. package/server/lib/opencode/server-startup-runtime.js +6 -6
  197. package/server/lib/opencode/session-runtime.js +3 -3
  198. package/server/lib/opencode/session-runtime.test.js +6 -6
  199. package/server/lib/opencode/settings-helpers.js +31 -3
  200. package/server/lib/opencode/settings-helpers.test.js +189 -12
  201. package/server/lib/opencode/settings-runtime.js +2 -2
  202. package/server/lib/opencode/settings-runtime.test.js +29 -0
  203. package/server/lib/opencode/shared.js +5 -2
  204. package/server/lib/opencode/shared.test.js +7 -7
  205. package/server/lib/opencode/shutdown-runtime.js +2 -0
  206. package/server/lib/opencode/skill-routes.js +2 -1
  207. package/server/lib/opencode/snippets.js +1 -2
  208. package/server/lib/opencode/startup-performance.js +1 -1
  209. package/server/lib/opencode/startup-performance.test.js +6 -6
  210. package/server/lib/opencode/static-routes-runtime.js +8 -8
  211. package/server/lib/opencode/static-routes-runtime.test.js +7 -7
  212. package/server/lib/opencode/upgrade-capability.js +2 -2
  213. package/server/lib/opencode/upgrade-capability.test.js +3 -3
  214. package/server/lib/package-manager.js +17 -42
  215. package/server/lib/package-manager.test.js +19 -19
  216. package/server/lib/permission-auto-accept/runtime.js +1 -1
  217. package/server/lib/project-context/routes.js +1 -1
  218. package/server/lib/projects/project-config.js +2 -2
  219. package/server/lib/quota/DOCUMENTATION.md +9 -1
  220. package/server/lib/quota/credentials/providers.js +4 -0
  221. package/server/lib/quota/credentials/store.js +4 -4
  222. package/server/lib/quota/credentials/store.test.js +8 -8
  223. package/server/lib/quota/index.js +1 -0
  224. package/server/lib/quota/providers/exe-dev.js +75 -0
  225. package/server/lib/quota/providers/exe-dev.test.js +47 -0
  226. package/server/lib/quota/providers/hyper.js +118 -0
  227. package/server/lib/quota/providers/hyper.test.js +126 -0
  228. package/server/lib/quota/providers/index.js +15 -0
  229. package/server/lib/quota/providers/ollama-cloud.js +1 -1
  230. package/server/lib/quota/providers/opencode-go.js +2 -1
  231. package/server/lib/quota/providers/opencode-go.test.js +9 -5
  232. package/server/lib/quota/providers/xai.js +1 -1
  233. package/server/lib/quota/routes.js +2 -0
  234. package/server/lib/quota/utils/auth.js +1 -1
  235. package/server/lib/relay/DOCUMENTATION.md +1 -1
  236. package/server/lib/relay/host-client.js +1 -1
  237. package/server/lib/relay/host-client.test.js +9 -1
  238. package/server/lib/relay/host-lock.js +1 -1
  239. package/server/lib/relay/service.js +5 -5
  240. package/server/lib/relay/tunnel-host.js +3 -1
  241. package/server/lib/relay/tunnel-host.test.js +9 -1
  242. package/server/lib/scheduled-tasks/issue-2710-double-execution.test.js +2 -2
  243. package/server/lib/scheduled-tasks/routes.js +5 -5
  244. package/server/lib/scheduled-tasks/service.js +25 -25
  245. package/server/lib/scheduled-tasks/service.test.js +1 -1
  246. package/server/lib/security/bind-host.js +4 -4
  247. package/server/lib/security/bind-host.test.js +1 -1
  248. package/server/lib/security/request-security.js +11 -5
  249. package/server/lib/security/request-security.test.js +14 -14
  250. package/server/lib/session-assist/runtime.js +10 -9
  251. package/server/lib/session-folders/routes.js +2 -2
  252. package/server/lib/session-folders/routes.test.js +8 -8
  253. package/server/lib/session-goal/DOCUMENTATION.md +20 -7
  254. package/server/lib/session-goal/create.js +4 -2
  255. package/server/lib/session-goal/create.test.js +1 -1
  256. package/server/lib/session-goal/objectives.js +4 -4
  257. package/server/lib/session-goal/routes.js +1 -1
  258. package/server/lib/session-goal/runtime.js +88 -22
  259. package/server/lib/session-goal/runtime.test.js +428 -2
  260. package/server/lib/session-knowledge/runtime.js +11 -11
  261. package/server/lib/session-knowledge/runtime.test.js +5 -5
  262. package/server/lib/skills-catalog/DOCUMENTATION.md +1 -1
  263. package/server/lib/skills-catalog/cache.test.js +2 -2
  264. package/server/lib/skills-catalog/disk-cache.js +5 -5
  265. package/server/lib/skills-catalog/github-meta.test.js +2 -2
  266. package/server/lib/skills-catalog/install.js +3 -2
  267. package/server/lib/small-model/DOCUMENTATION.md +4 -0
  268. package/server/lib/small-model/call.js +9 -3
  269. package/server/lib/small-model/call.test.js +29 -6
  270. package/server/lib/small-model/index.js +8 -7
  271. package/server/lib/small-model/index.test.js +1 -1
  272. package/server/lib/small-model/resolve.js +1 -1
  273. package/server/lib/small-model/resolve.test.js +1 -1
  274. package/server/lib/small-model/routes.js +2 -1
  275. package/server/lib/system-prompt/runtime.js +3 -22
  276. package/server/lib/system-prompt/runtime.test.js +3 -3
  277. package/server/lib/terminal/DOCUMENTATION.md +11 -7
  278. package/server/lib/terminal/runtime.js +180 -26
  279. package/server/lib/terminal/runtime.test.js +554 -27
  280. package/server/lib/terminal/shells.js +20 -3
  281. package/server/lib/terminal/shells.test.js +33 -2
  282. package/server/lib/tts/base-url.js +3 -3
  283. package/server/lib/tts/routes.test.js +20 -20
  284. package/server/lib/ui-auth/ui-auth.js +12 -9
  285. package/server/lib/ui-auth/ui-auth.test.js +19 -3
  286. package/server/lib/ui-auth/ui-passkeys.js +7 -7
  287. package/server/lib/walkthrough/index.js +1 -0
  288. package/server/lib/walkthrough/jobs.test.js +1 -1
  289. package/server/lib/walkthrough/language.test.js +1 -1
  290. package/server/lib/walkthrough/model-settings.js +3 -3
  291. package/server/lib/walkthrough/model-settings.test.js +1 -1
  292. package/server/lib/walkthrough/pull-request.test.js +5 -5
  293. package/server/lib/walkthrough/reproduce-2607.test.js +2 -2
  294. package/server/lib/walkthrough/routes.test.js +26 -5
  295. package/server/lib/walkthrough/store.js +3 -3
  296. package/server/lib/walkthrough/store.test.js +1 -1
  297. package/server/opencode-proxy.test.js +2 -2
  298. package/server/proxy-headers.js +1 -1
  299. package/server/sse-routes.test.js +4 -4
  300. package/README.md.bak +0 -250
  301. package/bin/lib/DOCUMENTATION.md.bak +0 -163
  302. package/dist/assets/CommitSection-SGBCAW0w.js +0 -1
  303. package/dist/assets/FilesView-Bdq8ppva.js +0 -17
  304. package/dist/assets/GitView-Znn7VJcP.js +0 -6
  305. package/dist/assets/LinearIssuesView-jP-hXyac.js +0 -1
  306. package/dist/assets/MarkdownRendererImpl-Dt9mjTRN.js +0 -12
  307. package/dist/assets/PlanView-B0F3BtPZ.js +0 -5
  308. package/dist/assets/SettingsView-BBW-S-gh.js +0 -28
  309. package/dist/assets/ToolPartDiffPreview-CUNe28U1.js +0 -8
  310. package/dist/assets/index-C57jT0Sa.css +0 -1
  311. package/dist/assets/index-DW_E3rnL.js +0 -7
  312. package/dist/assets/main-Bv5Pkngh.js +0 -928
  313. package/dist/assets/pl-Dioz29BI.js +0 -15
  314. package/dist/assets/renderMobileApp-D9yQJy0L.js +0 -25
  315. package/dist/assets/runtimeEndpointReset-CjhvxLH0.js +0 -16
  316. package/dist/assets/tr-DFnMlPxY.js +0 -6
  317. package/dist/assets/useInlineCommentController-CDEuSlPH.js +0 -2
  318. package/dist/assets/vendor-zod-BLfBSgBh.js +0 -39
  319. package/server/index.d.ts.bak +0 -39
  320. package/server/lib/agent-tool/DOCUMENTATION.md.bak +0 -119
  321. package/server/lib/browser-control/DOCUMENTATION.md.bak +0 -50
  322. package/server/lib/context-obligatory/DOCUMENTATION.md.bak +0 -19
  323. package/server/lib/dev-tunnel/DOCUMENTATION.md.bak +0 -57
  324. package/server/lib/dictation/DOCUMENTATION.md.bak +0 -100
  325. package/server/lib/event-stream/DOCUMENTATION.md.bak +0 -62
  326. package/server/lib/fs/DOCUMENTATION.md.bak +0 -47
  327. package/server/lib/git/DOCUMENTATION.md.bak +0 -193
  328. package/server/lib/github/DOCUMENTATION.md.bak +0 -183
  329. package/server/lib/linear/DOCUMENTATION.md.bak +0 -97
  330. package/server/lib/linear/OAUTH-BROKER-HANDOFF.md.bak +0 -91
  331. package/server/lib/markdown-image-grants/DOCUMENTATION.md.bak +0 -40
  332. package/server/lib/notifications/APNS.md.bak +0 -135
  333. package/server/lib/notifications/DOCUMENTATION.md.bak +0 -138
  334. package/server/lib/openchamber-control/DOCUMENTATION.md.bak +0 -64
  335. package/server/lib/opencode/DOCUMENTATION.md.bak +0 -431
  336. package/server/lib/opencode/managed-process-registry.d.ts.bak +0 -13
  337. package/server/lib/opencode/provider-env-aliases.d.ts.bak +0 -3
  338. package/server/lib/permission-auto-accept/DOCUMENTATION.md.bak +0 -34
  339. package/server/lib/project-context/DOCUMENTATION.md.bak +0 -160
  340. package/server/lib/quota/DOCUMENTATION.md.bak +0 -123
  341. package/server/lib/relay/DOCUMENTATION.md.bak +0 -100
  342. package/server/lib/scheduled-tasks/DOCUMENTATION.md.bak +0 -182
  343. package/server/lib/session-assist/DOCUMENTATION.md.bak +0 -66
  344. package/server/lib/session-goal/DOCUMENTATION.md.bak +0 -213
  345. package/server/lib/session-knowledge/DOCUMENTATION.md.bak +0 -89
  346. package/server/lib/skills-catalog/DOCUMENTATION.md.bak +0 -151
  347. package/server/lib/small-model/DOCUMENTATION.md.bak +0 -212
  348. package/server/lib/system-prompt/DOCUMENTATION.md.bak +0 -36
  349. package/server/lib/terminal/DOCUMENTATION.md.bak +0 -50
  350. package/server/lib/text/DOCUMENTATION.md.bak +0 -35
  351. package/server/lib/tts/DOCUMENTATION.md.bak +0 -147
  352. package/server/lib/tunnels/DOCUMENTATION.md.bak +0 -21
  353. package/server/lib/ui-auth/DOCUMENTATION.md.bak +0 -44
  354. package/server/lib/walkthrough/DOCUMENTATION.md.bak +0 -411
@@ -1,5 +1,6 @@
1
1
  const TERMINAL_SHELL_IDS = ['bash', 'zsh', 'sh', 'fish', 'pwsh', 'powershell', 'cmd', 'dash', 'ksh', 'nu'];
2
2
  const TERMINAL_SHELL_ID_SET = new Set(TERMINAL_SHELL_IDS);
3
+ const isString = (value) => String(value) === value;
3
4
 
4
5
  export const normalizeTerminalShell = (value) => {
5
6
  if (typeof value !== 'string') return null;
@@ -24,6 +25,22 @@ export const getTerminalShellLoginArgs = (executable, platform = process.platfor
24
25
  return null;
25
26
  };
26
27
 
28
+ export const buildTerminalShellLaunch = (executable, { mode = 'interactive', command = null, loginShell = false, platform = process.platform } = {}) => {
29
+ const loginArgs = loginShell ? getTerminalShellLoginArgs(executable, platform) : [];
30
+ if (!loginArgs) throw new Error(`Terminal shell "${shellIdFromPath(executable) ?? executable}" does not support login mode`);
31
+
32
+ if (mode === 'interactive') return { executable, args: loginArgs };
33
+
34
+ const trimmedCommand = isString(command) ? command.trim() : '';
35
+ if (!trimmedCommand) throw new Error('Terminal command is required');
36
+
37
+ const id = shellIdFromPath(executable);
38
+ if (id === 'nu') return { executable, args: [...loginArgs, '-c', trimmedCommand] };
39
+ if (id === 'pwsh' || id === 'powershell') return { executable, args: [...loginArgs, '-Command', trimmedCommand] };
40
+ if (id === 'cmd') return { executable, args: ['/d', '/s', '/c', trimmedCommand] };
41
+ return { executable, args: [...loginArgs, '-i', '-c', trimmedCommand] };
42
+ };
43
+
27
44
  export const createTerminalShellResolver = ({ fs, path, searchPathFor, isExecutable, buildAugmentedPath = () => env.PATH || '', platform = process.platform, env = process.env }) => {
28
45
  const resolveExecutable = (candidate) => {
29
46
  if (!candidate) return null;
@@ -35,7 +52,7 @@ export const createTerminalShellResolver = ({ fs, path, searchPathFor, isExecuta
35
52
 
36
53
  const defaultCandidates = () => platform === 'win32'
37
54
  ? [
38
- env.OPENCHAMBER_TERMINAL_SHELL,
55
+ env.AIWORKER_TERMINAL_SHELL,
39
56
  env.SHELL,
40
57
  env.ComSpec,
41
58
  path.join(env.SystemRoot || 'C:\\Windows', 'System32', 'WindowsPowerShell', 'v1.0', 'powershell.exe'),
@@ -43,7 +60,7 @@ export const createTerminalShellResolver = ({ fs, path, searchPathFor, isExecuta
43
60
  'powershell.exe',
44
61
  'cmd.exe',
45
62
  ]
46
- : [env.OPENCHAMBER_TERMINAL_SHELL, env.SHELL, '/bin/zsh', '/bin/bash', '/bin/sh', 'zsh', 'bash', 'sh'];
63
+ : [env.AIWORKER_TERMINAL_SHELL, env.SHELL, '/bin/zsh', '/bin/bash', '/bin/sh', 'zsh', 'bash', 'sh'];
47
64
 
48
65
  const resolveCandidates = (candidates) => {
49
66
  const seen = new Set();
@@ -68,7 +85,7 @@ export const createTerminalShellResolver = ({ fs, path, searchPathFor, isExecuta
68
85
 
69
86
  const candidates = platform === 'win32'
70
87
  ? [...defaultCandidates(), ...TERMINAL_SHELL_IDS]
71
- : [env.OPENCHAMBER_TERMINAL_SHELL, env.SHELL, ...configuredShells, ...TERMINAL_SHELL_IDS, '/bin/zsh', '/bin/bash', '/bin/sh'];
88
+ : [env.AIWORKER_TERMINAL_SHELL, env.SHELL, ...configuredShells, ...TERMINAL_SHELL_IDS, '/bin/zsh', '/bin/bash', '/bin/sh'];
72
89
  const autoExecutable = resolveCandidates(defaultCandidates())[0] ?? null;
73
90
  const byId = new Map([
74
91
  ['auto', {
@@ -1,6 +1,8 @@
1
1
  import { describe, expect, it } from 'vitest';
2
2
 
3
- import { createTerminalShellResolver, getTerminalShellLoginArgs } from './shells.js';
3
+ import * as shells from './shells.js';
4
+
5
+ const { createTerminalShellResolver, getTerminalShellLoginArgs } = shells;
4
6
 
5
7
  const createResolver = ({ platform = 'linux', env = {}, augmentedPath = '/augmented/bin', executables = [] } = {}) => {
6
8
  const available = new Set(executables);
@@ -55,7 +57,7 @@ describe('terminal shell resolver', () => {
55
57
 
56
58
  it('uses environment overrides before platform defaults for auto', async () => {
57
59
  const { resolver } = createResolver({
58
- env: { OPENCHAMBER_TERMINAL_SHELL: '/custom/zsh', SHELL: '/bin/bash' },
60
+ env: { AIWORKER_TERMINAL_SHELL: '/custom/zsh', SHELL: '/bin/bash' },
59
61
  executables: ['/custom/zsh', '/bin/bash'],
60
62
  });
61
63
 
@@ -70,4 +72,33 @@ describe('terminal shell resolver', () => {
70
72
  expect(getTerminalShellLoginArgs('C:\\Program Files\\PowerShell\\7\\pwsh.exe', 'win32')).toBeNull();
71
73
  expect(getTerminalShellLoginArgs('/bin/dash', 'linux')).toBeNull();
72
74
  });
75
+
76
+ it('builds interactive shell launches by shell family', () => {
77
+ const buildLaunch = shells.buildTerminalShellLaunch;
78
+
79
+ expect(buildLaunch('/bin/bash', { mode: 'interactive', loginShell: true, platform: 'linux' })).toEqual({ executable: '/bin/bash', args: ['-l'] });
80
+ expect(buildLaunch('/opt/homebrew/bin/fish', { mode: 'interactive', loginShell: true, platform: 'darwin' })).toEqual({ executable: '/opt/homebrew/bin/fish', args: ['--login'] });
81
+ expect(buildLaunch('/usr/bin/nu', { mode: 'interactive', loginShell: true, platform: 'linux' })).toEqual({ executable: '/usr/bin/nu', args: ['--login'] });
82
+ expect(buildLaunch('/usr/bin/pwsh', { mode: 'interactive', loginShell: true, platform: 'linux' })).toEqual({ executable: '/usr/bin/pwsh', args: ['-Login'] });
83
+ expect(buildLaunch('C:\\Windows\\System32\\cmd.exe', { mode: 'interactive', loginShell: false, platform: 'win32' })).toEqual({ executable: 'C:\\Windows\\System32\\cmd.exe', args: [] });
84
+ });
85
+
86
+ it('builds command launches by shell family', () => {
87
+ const buildLaunch = shells.buildTerminalShellLaunch;
88
+
89
+ expect(buildLaunch('/bin/zsh', { mode: 'command', command: 'printf ready', loginShell: true, platform: 'linux' })).toEqual({ executable: '/bin/zsh', args: ['-l', '-i', '-c', 'printf ready'] });
90
+ expect(buildLaunch('/opt/homebrew/bin/fish', { mode: 'command', command: 'echo ready', loginShell: true, platform: 'darwin' })).toEqual({ executable: '/opt/homebrew/bin/fish', args: ['--login', '-i', '-c', 'echo ready'] });
91
+ expect(buildLaunch('/usr/bin/nu', { mode: 'command', command: 'ls', loginShell: true, platform: 'linux' })).toEqual({ executable: '/usr/bin/nu', args: ['--login', '-c', 'ls'] });
92
+ expect(buildLaunch('/usr/bin/pwsh', { mode: 'command', command: 'Get-ChildItem', loginShell: true, platform: 'linux' })).toEqual({ executable: '/usr/bin/pwsh', args: ['-Login', '-Command', 'Get-ChildItem'] });
93
+ expect(buildLaunch('C:\\Program Files\\PowerShell\\7\\pwsh.exe', { mode: 'command', command: 'Get-Date', loginShell: false, platform: 'win32' })).toEqual({ executable: 'C:\\Program Files\\PowerShell\\7\\pwsh.exe', args: ['-Command', 'Get-Date'] });
94
+ expect(buildLaunch('C:\\Windows\\System32\\cmd.exe', { mode: 'command', command: 'dir', loginShell: false, platform: 'win32' })).toEqual({ executable: 'C:\\Windows\\System32\\cmd.exe', args: ['/d', '/s', '/c', 'dir'] });
95
+ });
96
+
97
+ it('rejects unsupported login and command combinations', () => {
98
+ const buildLaunch = shells.buildTerminalShellLaunch;
99
+
100
+ expect(() => buildLaunch('/bin/sh', { mode: 'interactive', loginShell: true, platform: 'linux' })).toThrow('does not support login mode');
101
+ expect(() => buildLaunch('/bin/dash', { mode: 'command', command: 'pwd', loginShell: true, platform: 'linux' })).toThrow('does not support login mode');
102
+ expect(() => buildLaunch('/bin/bash', { mode: 'command', command: '', loginShell: false, platform: 'linux' })).toThrow('Terminal command is required');
103
+ });
73
104
  });
@@ -47,13 +47,13 @@ export const normalizeCustomOpenAIBaseURL = (value) => {
47
47
  return { error: 'Custom server URL must not include credentials' };
48
48
  }
49
49
 
50
- const isDesktop = (process.env.OPENCHAMBER_RUNTIME || '').trim().toLowerCase() === 'desktop';
51
- const envFlagRaw = process.env.OPENCHAMBER_ALLOW_REMOTE_OPENAI_COMPAT_URLS;
50
+ const isDesktop = (process.env.AIWORKER_RUNTIME || '').trim().toLowerCase() === 'desktop';
51
+ const envFlagRaw = process.env.AIWORKER_ALLOW_REMOTE_OPENAI_COMPAT_URLS;
52
52
  const hasExplicitFlag = typeof envFlagRaw === 'string' && envFlagRaw.trim().length > 0;
53
53
  const allowRemote = hasExplicitFlag ? isEnvFlagEnabled(envFlagRaw) : isDesktop;
54
54
  if (!allowRemote && !isAllowedLocalHost(parsed.hostname)) {
55
55
  return {
56
- error: 'Remote custom server URLs are disabled. Set OPENCHAMBER_ALLOW_REMOTE_OPENAI_COMPAT_URLS=true to allow this host.',
56
+ error: 'Remote custom server URLs are disabled. Set AIWORKER_ALLOW_REMOTE_OPENAI_COMPAT_URLS=true to allow this host.',
57
57
  };
58
58
  }
59
59
 
@@ -97,44 +97,44 @@ describe('tts routes', () => {
97
97
  });
98
98
 
99
99
  describe('normalizeCustomOpenAIBaseURL', () => {
100
- const originalRuntime = process.env.OPENCHAMBER_RUNTIME;
101
- const originalAllowRemote = process.env.OPENCHAMBER_ALLOW_REMOTE_OPENAI_COMPAT_URLS;
100
+ const originalRuntime = process.env.AIWORKER_RUNTIME;
101
+ const originalAllowRemote = process.env.AIWORKER_ALLOW_REMOTE_OPENAI_COMPAT_URLS;
102
102
 
103
103
  afterEach(() => {
104
104
  // Restore env vars after each test
105
105
  if (originalRuntime === undefined) {
106
- delete process.env.OPENCHAMBER_RUNTIME;
106
+ delete process.env.AIWORKER_RUNTIME;
107
107
  } else {
108
- process.env.OPENCHAMBER_RUNTIME = originalRuntime;
108
+ process.env.AIWORKER_RUNTIME = originalRuntime;
109
109
  }
110
110
  if (originalAllowRemote === undefined) {
111
- delete process.env.OPENCHAMBER_ALLOW_REMOTE_OPENAI_COMPAT_URLS;
111
+ delete process.env.AIWORKER_ALLOW_REMOTE_OPENAI_COMPAT_URLS;
112
112
  } else {
113
- process.env.OPENCHAMBER_ALLOW_REMOTE_OPENAI_COMPAT_URLS = originalAllowRemote;
113
+ process.env.AIWORKER_ALLOW_REMOTE_OPENAI_COMPAT_URLS = originalAllowRemote;
114
114
  }
115
115
  });
116
116
 
117
- it('rejects remote URLs when OPENCHAMBER_RUNTIME is not set (web)', () => {
118
- delete process.env.OPENCHAMBER_RUNTIME;
119
- delete process.env.OPENCHAMBER_ALLOW_REMOTE_OPENAI_COMPAT_URLS;
117
+ it('rejects remote URLs when AIWORKER_RUNTIME is not set (web)', () => {
118
+ delete process.env.AIWORKER_RUNTIME;
119
+ delete process.env.AIWORKER_ALLOW_REMOTE_OPENAI_COMPAT_URLS;
120
120
 
121
121
  const result = normalizeCustomOpenAIBaseURL('https://my-tts-server.example.com/v1');
122
122
  expect(result.error).toMatch(/Remote custom server URLs are disabled/);
123
123
  expect(result.value).toBeUndefined();
124
124
  });
125
125
 
126
- it('allows remote URLs when OPENCHAMBER_RUNTIME is desktop', () => {
127
- process.env.OPENCHAMBER_RUNTIME = 'desktop';
128
- delete process.env.OPENCHAMBER_ALLOW_REMOTE_OPENAI_COMPAT_URLS;
126
+ it('allows remote URLs when AIWORKER_RUNTIME is desktop', () => {
127
+ process.env.AIWORKER_RUNTIME = 'desktop';
128
+ delete process.env.AIWORKER_ALLOW_REMOTE_OPENAI_COMPAT_URLS;
129
129
 
130
130
  const result = normalizeCustomOpenAIBaseURL('https://my-tts-server.example.com/v1');
131
131
  expect(result.error).toBeUndefined();
132
132
  expect(result.value).toBe('https://my-tts-server.example.com/v1');
133
133
  });
134
134
 
135
- it('allows remote URLs when OPENCHAMBER_ALLOW_REMOTE_OPENAI_COMPAT_URLS is true', () => {
136
- delete process.env.OPENCHAMBER_RUNTIME;
137
- process.env.OPENCHAMBER_ALLOW_REMOTE_OPENAI_COMPAT_URLS = 'true';
135
+ it('allows remote URLs when AIWORKER_ALLOW_REMOTE_OPENAI_COMPAT_URLS is true', () => {
136
+ delete process.env.AIWORKER_RUNTIME;
137
+ process.env.AIWORKER_ALLOW_REMOTE_OPENAI_COMPAT_URLS = 'true';
138
138
 
139
139
  const result = normalizeCustomOpenAIBaseURL('https://my-tts-server.example.com/v1');
140
140
  expect(result.error).toBeUndefined();
@@ -142,8 +142,8 @@ describe('normalizeCustomOpenAIBaseURL', () => {
142
142
  });
143
143
 
144
144
  it('allows localhost URLs regardless of runtime', () => {
145
- delete process.env.OPENCHAMBER_RUNTIME;
146
- delete process.env.OPENCHAMBER_ALLOW_REMOTE_OPENAI_COMPAT_URLS;
145
+ delete process.env.AIWORKER_RUNTIME;
146
+ delete process.env.AIWORKER_ALLOW_REMOTE_OPENAI_COMPAT_URLS;
147
147
 
148
148
  const result = normalizeCustomOpenAIBaseURL('http://localhost:8880/v1');
149
149
  expect(result.error).toBeUndefined();
@@ -151,15 +151,15 @@ describe('normalizeCustomOpenAIBaseURL', () => {
151
151
  });
152
152
 
153
153
  it('strips query strings and trailing slashes', () => {
154
- process.env.OPENCHAMBER_RUNTIME = 'desktop';
154
+ process.env.AIWORKER_RUNTIME = 'desktop';
155
155
 
156
156
  const result = normalizeCustomOpenAIBaseURL('https://my-server.com/v1/?key=123');
157
157
  expect(result.value).toBe('https://my-server.com/v1');
158
158
  });
159
159
 
160
160
  it('denies remote URLs on desktop when env var is explicitly false', () => {
161
- process.env.OPENCHAMBER_RUNTIME = 'desktop';
162
- process.env.OPENCHAMBER_ALLOW_REMOTE_OPENAI_COMPAT_URLS = 'false';
161
+ process.env.AIWORKER_RUNTIME = 'desktop';
162
+ process.env.AIWORKER_ALLOW_REMOTE_OPENAI_COMPAT_URLS = 'false';
163
163
 
164
164
  const result = normalizeCustomOpenAIBaseURL('https://my-tts-server.example.com/v1');
165
165
  expect(result.error).toMatch(/Remote custom server URLs are disabled/);
@@ -12,10 +12,10 @@ const URL_AUTH_TOKEN_TTL_MS = 60 * 1000;
12
12
  const URL_AUTH_TOKEN_PREFIX = 'oc_url_';
13
13
 
14
14
  const RATE_LIMIT_WINDOW_MS = 5 * 60 * 1000;
15
- const RATE_LIMIT_MAX_ATTEMPTS = Number(process.env.OPENCHAMBER_RATE_LIMIT_MAX_ATTEMPTS) || 10;
15
+ const RATE_LIMIT_MAX_ATTEMPTS = Number(process.env.AIWORKER_RATE_LIMIT_MAX_ATTEMPTS) || 10;
16
16
  const RATE_LIMIT_LOCKOUT_MS = 15 * 60 * 1000;
17
17
  const RATE_LIMIT_CLEANUP_MS = 60 * 60 * 1000;
18
- const RATE_LIMIT_NO_IP_MAX_ATTEMPTS = Number(process.env.OPENCHAMBER_RATE_LIMIT_NO_IP_MAX_ATTEMPTS) || 3;
18
+ const RATE_LIMIT_NO_IP_MAX_ATTEMPTS = Number(process.env.AIWORKER_RATE_LIMIT_NO_IP_MAX_ATTEMPTS) || 3;
19
19
 
20
20
  const loginRateLimiter = new Map();
21
21
  let rateLimitCleanupTimer = null;
@@ -310,6 +310,7 @@ const isUrlAuthWebSocketPath = (pathname) => {
310
310
  || pathname === '/api/openchamber/realtime-proxy/ws'
311
311
  || pathname === '/api/terminal/ws'
312
312
  || pathname === '/api/dictation/ws'
313
+ || pathname === '/api/dev-tunnel'
313
314
  || pathname.startsWith('/api/preview/proxy/');
314
315
  };
315
316
 
@@ -361,10 +362,10 @@ const normalizePassword = (candidate) => {
361
362
 
362
363
  const isTrustedDeviceRequest = (value) => value === true;
363
364
 
364
- const OPENCHAMBER_DATA_DIR = process.env.OPENCHAMBER_DATA_DIR
365
- ? path.resolve(process.env.OPENCHAMBER_DATA_DIR)
366
- : path.join(os.homedir(), '.config', 'openchamber');
367
- const JWT_SECRET_FILE = path.join(OPENCHAMBER_DATA_DIR, 'jwt-secret');
365
+ const AIWORKER_DATA_DIR = process.env.AIWORKER_DATA_DIR
366
+ ? path.resolve(process.env.AIWORKER_DATA_DIR)
367
+ : path.join(os.homedir(), '.config', 'aiworker');
368
+ const JWT_SECRET_FILE = path.join(AIWORKER_DATA_DIR, 'jwt-secret');
368
369
 
369
370
  function getOrCreateJwtSecret() {
370
371
  const envSecret = process.env.OPENCODE_JWT_SECRET;
@@ -382,7 +383,7 @@ function getOrCreateJwtSecret() {
382
383
 
383
384
  const secret = crypto.randomBytes(32).toString('hex');
384
385
  try {
385
- fs.mkdirSync(OPENCHAMBER_DATA_DIR, { recursive: true });
386
+ fs.mkdirSync(AIWORKER_DATA_DIR, { recursive: true });
386
387
  fs.writeFileSync(JWT_SECRET_FILE, secret, { mode: 0o600 });
387
388
  console.log('[JWT] Generated and persisted new secret to', JWT_SECRET_FILE);
388
389
  } catch (e) {
@@ -399,7 +400,7 @@ function persistJwtSecret(secret) {
399
400
  throw error;
400
401
  }
401
402
 
402
- fs.mkdirSync(OPENCHAMBER_DATA_DIR, { recursive: true });
403
+ fs.mkdirSync(AIWORKER_DATA_DIR, { recursive: true });
403
404
  fs.writeFileSync(JWT_SECRET_FILE, secret, { mode: 0o600 });
404
405
  return new TextEncoder().encode(secret);
405
406
  }
@@ -984,7 +985,9 @@ export const createUiAuth = ({
984
985
  handlePasskeyList,
985
986
  handlePasskeyRevoke,
986
987
  handleResetAuth,
987
- ensureSessionToken: async (req, _res) => {
988
+ ensureSessionToken: (req, _res) => {
989
+ const urlAuth = authenticateUrlAuthToken(req);
990
+ if (urlAuth) return clientSessionToken(urlAuth);
988
991
  return resolveAuthenticatedSessionToken(req);
989
992
  },
990
993
  dispose,
@@ -4,7 +4,7 @@ import os from 'node:os';
4
4
  import path from 'node:path';
5
5
 
6
6
  const dataDir = fs.mkdtempSync(path.join(os.tmpdir(), 'openchamber-ui-auth-test-'));
7
- process.env.OPENCHAMBER_DATA_DIR = dataDir;
7
+ process.env.AIWORKER_DATA_DIR = dataDir;
8
8
 
9
9
  afterAll(() => {
10
10
  fs.rmSync(dataDir, { recursive: true, force: true });
@@ -221,6 +221,22 @@ describe('ui auth client credential seam', () => {
221
221
  };
222
222
  expect(await auth.ensureSessionToken(dictationWsReq, null)).toBe('client:device-1');
223
223
 
224
+ const devTunnelWsReq = {
225
+ method: 'GET',
226
+ path: '/api/dev-tunnel',
227
+ url: `/api/dev-tunnel?port=4322&oc_url_token=${encodeURIComponent(urlToken)}`,
228
+ headers: { upgrade: 'websocket' },
229
+ };
230
+ expect(await auth.ensureSessionToken(devTunnelWsReq, null)).toBe('client:device-1');
231
+
232
+ const devTunnelSubpathWsReq = {
233
+ method: 'GET',
234
+ path: '/api/dev-tunnel/private',
235
+ url: `/api/dev-tunnel/private?port=4322&oc_url_token=${encodeURIComponent(urlToken)}`,
236
+ headers: { upgrade: 'websocket' },
237
+ };
238
+ expect(await auth.ensureSessionToken(devTunnelSubpathWsReq, null)).toBe(null);
239
+
224
240
  const dictationHttpReq = {
225
241
  method: 'GET',
226
242
  path: '/api/dictation/ws',
@@ -287,7 +303,7 @@ describe('ui auth client credential seam', () => {
287
303
  body: {
288
304
  password: 'secret',
289
305
  issueClientToken: true,
290
- clientLabel: 'OpenChamber Desktop',
306
+ clientLabel: 'AiWorker Desktop',
291
307
  },
292
308
  };
293
309
  const res = createResponse();
@@ -295,7 +311,7 @@ describe('ui auth client credential seam', () => {
295
311
  await auth.handleSessionCreate(req, res);
296
312
 
297
313
  expect(res.body.clientToken).toBe('client-token');
298
- expect(createClientInput.fallbackLabel).toBe('OpenChamber Desktop');
314
+ expect(createClientInput.fallbackLabel).toBe('AiWorker Desktop');
299
315
  const expiresAt = Date.parse(createClientInput.expiresAt);
300
316
  expect(expiresAt).toBeGreaterThanOrEqual(before + 122_000);
301
317
  expect(expiresAt).toBeLessThanOrEqual(Date.now() + 124_000);
@@ -11,13 +11,13 @@ import {
11
11
 
12
12
  const DEFAULT_STORE_VERSION = 1;
13
13
  const DEFAULT_CHALLENGE_TTL_MS = 5 * 60 * 1000;
14
- const DEFAULT_RP_NAME = 'OpenChamber';
14
+ const DEFAULT_RP_NAME = 'AiWorker';
15
15
 
16
- const OPENCHAMBER_DATA_DIR = process.env.OPENCHAMBER_DATA_DIR
17
- ? path.resolve(process.env.OPENCHAMBER_DATA_DIR)
18
- : path.join(os.homedir(), '.config', 'openchamber');
16
+ const AIWORKER_DATA_DIR = process.env.AIWORKER_DATA_DIR
17
+ ? path.resolve(process.env.AIWORKER_DATA_DIR)
18
+ : path.join(os.homedir(), '.config', 'aiworker');
19
19
 
20
- const PASSKEY_STORE_FILE = path.join(OPENCHAMBER_DATA_DIR, 'ui-passkeys.json');
20
+ const PASSKEY_STORE_FILE = path.join(AIWORKER_DATA_DIR, 'ui-passkeys.json');
21
21
 
22
22
  const createUserId = () => crypto.randomBytes(32).toString('base64url');
23
23
 
@@ -331,7 +331,7 @@ export const createUiPasskeys = ({
331
331
  rpID,
332
332
  userID,
333
333
  userName: 'openchamber-ui',
334
- userDisplayName: 'OpenChamber UI',
334
+ userDisplayName: 'AiWorker UI',
335
335
  attestationType: 'none',
336
336
  excludeCredentials: getPasskeysForRpId(store, rpID).map((passkey) => ({
337
337
  id: passkey.id,
@@ -471,7 +471,7 @@ export const createUiPasskeys = ({
471
471
  const passkey = store.passkeys.find((item) => item.id === response?.id);
472
472
 
473
473
  if (!passkey) {
474
- const error = new Error('That passkey is not registered for this OpenChamber instance');
474
+ const error = new Error('That passkey is not registered for this AiWorker instance');
475
475
  error.statusCode = 404;
476
476
  throw error;
477
477
  }
@@ -474,6 +474,7 @@ async function runGeneration({ directory, source, repoRoot, key, force, explicit
474
474
  prompt: options.prompt,
475
475
  system: options.system,
476
476
  directory,
477
+ sessionID: `openchamber-walkthrough-${cacheKey}`,
477
478
  model: `${model.providerID}/${model.modelID}`,
478
479
  responseSchema: options.responseSchema,
479
480
  onOverflow: 'error',
@@ -4,7 +4,7 @@ import path from 'path';
4
4
  import { afterAll, afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
5
5
 
6
6
  const TEMP_DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'walkthrough-jobs-'));
7
- process.env.OPENCHAMBER_DATA_DIR = TEMP_DATA_DIR;
7
+ process.env.AIWORKER_DATA_DIR = TEMP_DATA_DIR;
8
8
 
9
9
  // Mocking git rather than this module's own source loading: fewer of our own
10
10
  // seams faked means the test exercises the real digest and prompt path.
@@ -4,7 +4,7 @@ import path from 'path';
4
4
  import { afterAll, beforeEach, describe, expect, it, vi } from 'vitest';
5
5
 
6
6
  const TEMP_DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'walkthrough-language-'));
7
- process.env.OPENCHAMBER_DATA_DIR = TEMP_DATA_DIR;
7
+ process.env.AIWORKER_DATA_DIR = TEMP_DATA_DIR;
8
8
 
9
9
  vi.mock('../git/service.js', () => ({
10
10
  getRepositoryRoot: vi.fn(async () => '/repo'),
@@ -8,9 +8,9 @@ import path from 'path';
8
8
  // means the user has to degrade one feature to fix the other.
9
9
 
10
10
  const SETTINGS_FILE = path.join(
11
- process.env.OPENCHAMBER_DATA_DIR
12
- ? path.resolve(process.env.OPENCHAMBER_DATA_DIR)
13
- : path.join(os.homedir(), '.config', 'openchamber'),
11
+ process.env.AIWORKER_DATA_DIR
12
+ ? path.resolve(process.env.AIWORKER_DATA_DIR)
13
+ : path.join(os.homedir(), '.config', 'aiworker'),
14
14
  'settings.json',
15
15
  );
16
16
 
@@ -4,7 +4,7 @@ import path from 'path';
4
4
  import { afterAll, beforeEach, describe, expect, it } from 'vitest';
5
5
 
6
6
  const TEMP_DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'walkthrough-model-settings-'));
7
- process.env.OPENCHAMBER_DATA_DIR = TEMP_DATA_DIR;
7
+ process.env.AIWORKER_DATA_DIR = TEMP_DATA_DIR;
8
8
 
9
9
  const { readWalkthroughModelOverride } = await import('./model-settings.js');
10
10
 
@@ -24,8 +24,8 @@ describe('getPullRequestDiff', () => {
24
24
  // wrapper made every repository look remote-less, which is what this suite
25
25
  // exists to prevent.
26
26
  resolveGitHubRepoFromDirectory.mockResolvedValue({
27
- repo: { owner: 'openchamber', repo: 'openchamber' },
28
- remoteUrl: 'git@github.com:openchamber/openchamber.git',
27
+ repo: { owner: 'aiworker', repo: 'aiworker' },
28
+ remoteUrl: 'git@github.com:aiworker/openchamber.git',
29
29
  });
30
30
  });
31
31
 
@@ -37,10 +37,10 @@ describe('getPullRequestDiff', () => {
37
37
  const result = await getPullRequestDiff('/repo', 2122);
38
38
 
39
39
  expect(result.patch).toBe(PATCH);
40
- expect(result.meta).toEqual({ owner: 'openchamber', repo: 'openchamber', number: 2122 });
40
+ expect(result.meta).toEqual({ owner: 'aiworker', repo: 'aiworker', number: 2122 });
41
41
  expect(request).toHaveBeenCalledWith('GET /repos/{owner}/{repo}/pulls/{pull_number}', {
42
- owner: 'openchamber',
43
- repo: 'openchamber',
42
+ owner: 'aiworker',
43
+ repo: 'aiworker',
44
44
  pull_number: 2122,
45
45
  headers: { accept: 'application/vnd.github.v3.diff' },
46
46
  });
@@ -6,7 +6,7 @@ import express from 'express';
6
6
  import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest';
7
7
 
8
8
  // ---------------------------------------------------------------------------
9
- // Regression for https://github.com/openchamber/openchamber/issues/2607
9
+ // Regression for https://roweb.cn/roweb/openchamber/issues/2607
10
10
  // "[Bug] Why say so?" (walkthrough panel)
11
11
  //
12
12
  // Before the fix, a walkthrough small model whose provider had no usable login
@@ -20,7 +20,7 @@ import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest';
20
20
 
21
21
  const TEMP_HOME = fs.mkdtempSync(path.join(os.tmpdir(), 'oc-home-2607-'));
22
22
  process.env.HOME = TEMP_HOME;
23
- process.env.OPENCHAMBER_DATA_DIR = path.join(TEMP_HOME, '.config', 'openchamber');
23
+ process.env.AIWORKER_DATA_DIR = path.join(TEMP_HOME, '.config', 'aiworker');
24
24
 
25
25
  const CATALOG = {
26
26
  deepseek: {
@@ -15,6 +15,7 @@ describe('walkthrough routes', () => {
15
15
  let job;
16
16
 
17
17
  let lastArgs;
18
+ let generateCalls = 0;
18
19
 
19
20
  const service = {
20
21
  async getWalkthrough(args) {
@@ -23,6 +24,7 @@ describe('walkthrough routes', () => {
23
24
  },
24
25
  async generateWalkthrough(args) {
25
26
  lastArgs = args;
27
+ generateCalls += 1;
26
28
  if (job) return job;
27
29
  job = new Promise((resolve) => {
28
30
  releaseJob = () => resolve({ walkthrough: { title: 'DONE' }, hunks: [], hunkCount: 1 });
@@ -54,12 +56,27 @@ describe('walkthrough routes', () => {
54
56
  });
55
57
 
56
58
  afterEach(async () => {
59
+ // A response a failed test never received keeps its keep-alive socket
60
+ // open, and server.close() would wait on it until the hook timeout.
61
+ server.closeAllConnections();
57
62
  await new Promise((resolve) => server.close(resolve));
58
63
  });
59
64
 
65
+ // Resolves once the route has asked the service to generate one more time
66
+ // than `seen`. A fixed sleep assumed the request had arrived by then; on a
67
+ // loaded runner it had not, and the step that followed acted on a request
68
+ // the server had not seen yet.
69
+ const untilGenerateCalled = async (seen) => {
70
+ for (let attempt = 0; attempt < 300 && generateCalls <= seen; attempt += 1) {
71
+ await new Promise((resolve) => setTimeout(resolve, 10));
72
+ }
73
+ if (generateCalls <= seen) throw new Error('the route never asked the service to generate');
74
+ };
75
+
60
76
  it('answers a generation request that nobody interrupted', async () => {
77
+ const seen = generateCalls;
61
78
  const pending = generate();
62
- await new Promise((resolve) => setTimeout(resolve, 20));
79
+ await untilGenerateCalled(seen);
63
80
  releaseJob();
64
81
 
65
82
  const body = await (await pending).json();
@@ -69,8 +86,9 @@ describe('walkthrough routes', () => {
69
86
 
70
87
  it('delivers the result to a client that reconnected after a refresh', async () => {
71
88
  const controller = new AbortController();
89
+ const seen = generateCalls;
72
90
  generate(controller.signal).catch(() => {});
73
- await new Promise((resolve) => setTimeout(resolve, 20));
91
+ await untilGenerateCalled(seen);
74
92
  controller.abort();
75
93
  await new Promise((resolve) => setTimeout(resolve, 20));
76
94
 
@@ -80,8 +98,9 @@ describe('walkthrough routes', () => {
80
98
  )).json();
81
99
  expect(read.generating).toBe(true);
82
100
 
101
+ const seenBeforeReattach = generateCalls;
83
102
  const reattached = generate();
84
- await new Promise((resolve) => setTimeout(resolve, 20));
103
+ await untilGenerateCalled(seenBeforeReattach);
85
104
  releaseJob();
86
105
 
87
106
  const body = await (await reattached).json();
@@ -108,12 +127,13 @@ describe('walkthrough routes', () => {
108
127
  );
109
128
  expect(lastArgs.language).toBe('uk');
110
129
 
130
+ const seen = generateCalls;
111
131
  const pending = fetch(`${base}/api/walkthrough/generate`, {
112
132
  method: 'POST',
113
133
  headers: { 'Content-Type': 'application/json' },
114
134
  body: JSON.stringify({ directory: '/repo', source: SOURCE, language: 'ja' }),
115
135
  });
116
- await new Promise((resolve) => setTimeout(resolve, 20));
136
+ await untilGenerateCalled(seen);
117
137
  releaseJob();
118
138
  await pending;
119
139
 
@@ -129,8 +149,9 @@ describe('walkthrough routes', () => {
129
149
  });
130
150
 
131
151
  it('cancels through its own endpoint rather than a dropped connection', async () => {
152
+ const seen = generateCalls;
132
153
  generate().catch(() => {});
133
- await new Promise((resolve) => setTimeout(resolve, 20));
154
+ await untilGenerateCalled(seen);
134
155
 
135
156
  const response = await fetch(`${base}/api/walkthrough/cancel`, {
136
157
  method: 'POST',
@@ -17,9 +17,9 @@ import { PROMPT_VERSION, WALKTHROUGH_VERSION } from './schema.js';
17
17
  // it written about, and has the code moved since. It is also what feeds the
18
18
  // previous walkthrough into a regeneration.
19
19
 
20
- const DATA_DIR = process.env.OPENCHAMBER_DATA_DIR
21
- ? path.resolve(process.env.OPENCHAMBER_DATA_DIR)
22
- : path.join(os.homedir(), '.config', 'openchamber');
20
+ const DATA_DIR = process.env.AIWORKER_DATA_DIR
21
+ ? path.resolve(process.env.AIWORKER_DATA_DIR)
22
+ : path.join(os.homedir(), '.config', 'aiworker');
23
23
 
24
24
  const WALKTHROUGH_DIR = path.join(DATA_DIR, 'walkthroughs');
25
25
  const ENTRIES_DIR = path.join(WALKTHROUGH_DIR, 'entries');
@@ -6,7 +6,7 @@ import { afterAll, beforeEach, describe, expect, it } from 'vitest';
6
6
  // The store resolves its directory at import time from the environment, so the
7
7
  // temp dir has to be in place before the module is loaded.
8
8
  const TEMP_ROOT = fs.mkdtempSync(path.join(os.tmpdir(), 'walkthrough-store-'));
9
- process.env.OPENCHAMBER_DATA_DIR = TEMP_ROOT;
9
+ process.env.AIWORKER_DATA_DIR = TEMP_ROOT;
10
10
 
11
11
  const store = await import('./store.js');
12
12
  const {
@@ -381,7 +381,7 @@ describe('OpenCode proxy SSE forwarding', () => {
381
381
  files: 2,
382
382
  diffs: [{ patch: '@@ -1 +1 @@', additions: 5, deletions: 3 }],
383
383
  },
384
- metadata: { openchamber: { kind: 'review', originalSessionID: 'ses_original' } },
384
+ metadata: { aiworker: { kind: 'review', originalSessionID: 'ses_original' } },
385
385
  permission: [{ permission: 'todowrite', action: 'deny', pattern: '*' }],
386
386
  revert: { messageID: 'msg_1', partID: 'part_1', snapshot: 'abc123', diff: 'diff --git a/x b/x' },
387
387
  },
@@ -445,7 +445,7 @@ describe('OpenCode proxy SSE forwarding', () => {
445
445
  cost: 7,
446
446
  tokens: { input: 10, output: 20 },
447
447
  share: { url: 'https://share.example/ses_1' },
448
- metadata: { openchamber: { kind: 'review', originalSessionID: 'ses_original' } },
448
+ metadata: { aiworker: { kind: 'review', originalSessionID: 'ses_original' } },
449
449
  project: { id: 'proj_1', worktree: '/repo/app' },
450
450
  summary: { additions: 5, deletions: 3, files: 2 },
451
451
  revert: { messageID: 'msg_1', partID: 'part_1' },
@@ -1,5 +1,5 @@
1
1
  const filteredRequestHeaders = new Set([
2
- // Client credentials for the OpenChamber server (UI client tokens) must
2
+ // Client credentials for the AiWorker server (UI client tokens) must
3
3
  // never reach the managed OpenCode upstream — it only accepts its own auth,
4
4
  // so a forwarded client bearer turns every upstream response into a 401.
5
5
  'authorization',
@@ -136,7 +136,7 @@ describe('local SSE routes', () => {
136
136
  expect(res.getHeader('connection')).toBe('keep-alive');
137
137
  expect(res.getHeader('x-accel-buffering')).toBe('no');
138
138
  expect(res.flushed).toBe(true);
139
- expect(res.body).toContain('openchamber:notification-stream-ready');
139
+ expect(res.body).toContain('aiworker:notification-stream-ready');
140
140
  expect(clients.has(res)).toBe(true);
141
141
  expect(vi.getTimerCount()).toBe(1);
142
142
  expect(res.bodyFlushCount).toBe(1);
@@ -157,12 +157,12 @@ describe('local SSE routes', () => {
157
157
  }
158
158
  });
159
159
 
160
- it('serves OpenChamber SSE with nginx-safe headers', () => {
160
+ it('serves AiWorker SSE with nginx-safe headers', () => {
161
161
  const { app, getRoute } = createRouteRegistry();
162
162
  const clients = new Set();
163
163
 
164
164
  registerScheduledTaskRoutes(app, {
165
- getOpenChamberEventClients: () => clients,
165
+ getAiWorkerEventClients: () => clients,
166
166
  writeSseEvent(res, payload) {
167
167
  res.write(`data: ${JSON.stringify(payload)}\n\n`);
168
168
  },
@@ -180,7 +180,7 @@ describe('local SSE routes', () => {
180
180
  expect(res.getHeader('connection')).toBe('keep-alive');
181
181
  expect(res.getHeader('x-accel-buffering')).toBe('no');
182
182
  expect(res.flushed).toBe(true);
183
- expect(res.body).toContain('openchamber:event-stream-ready');
183
+ expect(res.body).toContain('aiworker:event-stream-ready');
184
184
  expect(clients.has(res)).toBe(true);
185
185
 
186
186
  req.emit('close');