@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
@@ -87,7 +87,7 @@ const resolveOutsideFileGrant = async ({ token, targetPath, scope, fsPromises })
87
87
  };
88
88
 
89
89
  const createCommandTimeoutMs = () => {
90
- const raw = Number(process.env.OPENCHAMBER_FS_EXEC_TIMEOUT_MS);
90
+ const raw = Number(process.env.AIWORKER_FS_EXEC_TIMEOUT_MS);
91
91
  if (Number.isFinite(raw) && raw > 0) return raw;
92
92
  return 5 * 60 * 1000;
93
93
  };
@@ -97,19 +97,19 @@ const createCommandTimeoutMs = () => {
97
97
  // absorbs the burst of identical lookups a fresh client (e.g. right after a
98
98
  // page reload) fires for every project. Set to 0 to disable caching.
99
99
  const createGitReadCacheTtlMs = () => {
100
- const raw = Number(process.env.OPENCHAMBER_GIT_READ_CACHE_TTL_MS);
100
+ const raw = Number(process.env.AIWORKER_GIT_READ_CACHE_TTL_MS);
101
101
  if (Number.isFinite(raw) && raw >= 0) return raw;
102
102
  return 30 * 1000;
103
103
  };
104
104
 
105
105
  const createGitCheckIgnoreTimeoutMs = () => {
106
- const raw = Number(process.env.OPENCHAMBER_GIT_CHECK_IGNORE_TIMEOUT_MS);
106
+ const raw = Number(process.env.AIWORKER_GIT_CHECK_IGNORE_TIMEOUT_MS);
107
107
  if (Number.isFinite(raw) && raw >= 0) return raw;
108
108
  return 2500;
109
109
  };
110
110
 
111
111
  const createUploadMaxBytes = () => {
112
- const raw = Number(process.env.OPENCHAMBER_FS_UPLOAD_MAX_BYTES);
112
+ const raw = Number(process.env.AIWORKER_FS_UPLOAD_MAX_BYTES);
113
113
  if (Number.isFinite(raw) && raw > 0) return Math.floor(raw);
114
114
  return 100 * 1024 * 1024;
115
115
  };
@@ -196,7 +196,7 @@ const isPathWithinRoot = (resolvedPath, rootPath, path, os) => {
196
196
  return true;
197
197
  };
198
198
 
199
- const resolveWorkspacePath = ({ targetPath, baseDirectory, path, os, normalizeDirectoryPath, openchamberUserConfigRoot }) => {
199
+ const resolveWorkspacePath = ({ targetPath, baseDirectory, path, os, normalizeDirectoryPath, managedRoots }) => {
200
200
  const normalized = normalizeDirectoryPath(targetPath);
201
201
  if (!normalized || typeof normalized !== 'string') {
202
202
  return { ok: false, error: 'Path is required' };
@@ -209,8 +209,12 @@ const resolveWorkspacePath = ({ targetPath, baseDirectory, path, os, normalizeDi
209
209
  return { ok: true, base: resolvedBase, resolved };
210
210
  }
211
211
 
212
- if (isPathWithinRoot(resolved, openchamberUserConfigRoot, path, os)) {
213
- return { ok: true, base: path.resolve(openchamberUserConfigRoot), resolved };
212
+ // Managed roots (config root, relocated chats root) stay valid targets
213
+ // even outside the active workspace.
214
+ for (const root of managedRoots) {
215
+ if (isPathWithinRoot(resolved, root, path, os)) {
216
+ return { ok: true, base: path.resolve(root), resolved };
217
+ }
214
218
  }
215
219
 
216
220
  return { ok: false, error: 'Path is outside of active workspace' };
@@ -249,7 +253,7 @@ const resolveWorkspacePathFromWorktrees = async ({ targetPath, baseDirectory, pa
249
253
  return { ok: false, error: 'Path is outside of active workspace' };
250
254
  };
251
255
 
252
- const resolveWorkspacePathFromContext = async ({ req, targetPath, resolveProjectDirectory, path, os, normalizeDirectoryPath, openchamberUserConfigRoot }) => {
256
+ const resolveWorkspacePathFromContext = async ({ req, targetPath, resolveProjectDirectory, path, os, normalizeDirectoryPath, managedRoots }) => {
253
257
  const resolvedProject = await resolveProjectDirectory(req);
254
258
  if (!resolvedProject.directory) {
255
259
  return { ok: false, error: resolvedProject.error || 'Active workspace is required' };
@@ -261,7 +265,7 @@ const resolveWorkspacePathFromContext = async ({ req, targetPath, resolveProject
261
265
  path,
262
266
  os,
263
267
  normalizeDirectoryPath,
264
- openchamberUserConfigRoot,
268
+ managedRoots,
265
269
  });
266
270
  if (resolved.ok || resolved.error !== 'Path is outside of active workspace') {
267
271
  return resolved;
@@ -281,7 +285,7 @@ const resolveWorkspacePathFromContext = async ({ req, targetPath, resolveProject
281
285
  path,
282
286
  os,
283
287
  normalizeDirectoryPath,
284
- openchamberUserConfigRoot,
288
+ managedRoots,
285
289
  });
286
290
  if (lexical.ok) {
287
291
  return lexical;
@@ -412,7 +416,7 @@ const escapeCloneSshKeyPath = (sshKeyPath) => {
412
416
  return `'${normalized.replace(/'/g, "'\\''")}'`;
413
417
  };
414
418
 
415
- const resolveReadPathFromContext = async ({ req, targetPath, scope, resolveProjectDirectory, path, os, fsPromises, normalizeDirectoryPath, openchamberUserConfigRoot }) => {
419
+ const resolveReadPathFromContext = async ({ req, targetPath, scope, resolveProjectDirectory, path, os, fsPromises, normalizeDirectoryPath, managedRoots }) => {
416
420
  if (req.query?.allowOutsideWorkspace === 'true') {
417
421
  const normalized = normalizeDirectoryPath(targetPath);
418
422
  if (!normalized || typeof normalized !== 'string') {
@@ -434,7 +438,7 @@ const resolveReadPathFromContext = async ({ req, targetPath, scope, resolveProje
434
438
  path,
435
439
  os,
436
440
  normalizeDirectoryPath,
437
- openchamberUserConfigRoot,
441
+ managedRoots,
438
442
  });
439
443
  };
440
444
 
@@ -519,8 +523,15 @@ export const registerFsRoutes = (app, dependencies) => {
519
523
  resolveProjectDirectory,
520
524
  buildAugmentedPath,
521
525
  resolveGitBinaryForSpawn,
522
- openchamberUserConfigRoot,
526
+ aiworkerUserConfigRoot,
527
+ managedChatsRoot,
523
528
  } = dependencies;
529
+ // Chat worktrees may live outside every project workspace; both managed
530
+ // roots stay valid filesystem targets.
531
+ const chatsRoot = typeof managedChatsRoot === 'string' && managedChatsRoot.trim()
532
+ ? path.resolve(managedChatsRoot.trim())
533
+ : path.join(aiworkerUserConfigRoot, 'chats');
534
+ const managedRoots = [path.resolve(aiworkerUserConfigRoot), chatsRoot];
524
535
  const realpathCache = createRealpathCache({
525
536
  realpath: fsPromises.realpath.bind(fsPromises),
526
537
  });
@@ -699,7 +710,7 @@ export const registerFsRoutes = (app, dependencies) => {
699
710
  if (!home || typeof home !== 'string' || home.length === 0) {
700
711
  return res.status(500).json({ error: 'Failed to resolve home directory' });
701
712
  }
702
- return res.json({ home });
713
+ return res.json({ home, chatsRoot });
703
714
  } catch (error) {
704
715
  console.error('Failed to resolve home directory:', error);
705
716
  return res.status(500).json({ error: (error && error.message) || 'Failed to resolve home directory' });
@@ -725,7 +736,7 @@ export const registerFsRoutes = (app, dependencies) => {
725
736
  path,
726
737
  os,
727
738
  normalizeDirectoryPath,
728
- openchamberUserConfigRoot,
739
+ managedRoots,
729
740
  });
730
741
  if (!resolved.ok) {
731
742
  return res.status(400).json({ error: resolved.error });
@@ -870,7 +881,7 @@ export const registerFsRoutes = (app, dependencies) => {
870
881
  os,
871
882
  fsPromises,
872
883
  normalizeDirectoryPath,
873
- openchamberUserConfigRoot,
884
+ managedRoots,
874
885
  });
875
886
  if (!resolved.ok) {
876
887
  if (req.query?.allowOutsideWorkspace === 'true') {
@@ -920,7 +931,7 @@ export const registerFsRoutes = (app, dependencies) => {
920
931
  os,
921
932
  fsPromises,
922
933
  normalizeDirectoryPath,
923
- openchamberUserConfigRoot,
934
+ managedRoots,
924
935
  });
925
936
  if (!resolved.ok) {
926
937
  if (req.query?.allowOutsideWorkspace === 'true') {
@@ -984,7 +995,7 @@ export const registerFsRoutes = (app, dependencies) => {
984
995
  os,
985
996
  fsPromises,
986
997
  normalizeDirectoryPath,
987
- openchamberUserConfigRoot,
998
+ managedRoots,
988
999
  });
989
1000
  if (!resolved.ok) {
990
1001
  if (req.query?.allowOutsideWorkspace === 'true') {
@@ -1065,7 +1076,7 @@ export const registerFsRoutes = (app, dependencies) => {
1065
1076
  path,
1066
1077
  os,
1067
1078
  normalizeDirectoryPath,
1068
- openchamberUserConfigRoot,
1079
+ managedRoots,
1069
1080
  });
1070
1081
  if (!resolved.ok) {
1071
1082
  return res.status(400).json({ error: resolved.error });
@@ -1117,7 +1128,7 @@ export const registerFsRoutes = (app, dependencies) => {
1117
1128
  path,
1118
1129
  os,
1119
1130
  normalizeDirectoryPath,
1120
- openchamberUserConfigRoot,
1131
+ managedRoots,
1121
1132
  });
1122
1133
  if (!resolved.ok) {
1123
1134
  return res.status(400).json({ error: resolved.error });
@@ -1187,7 +1198,7 @@ export const registerFsRoutes = (app, dependencies) => {
1187
1198
  path,
1188
1199
  os,
1189
1200
  normalizeDirectoryPath,
1190
- openchamberUserConfigRoot,
1201
+ managedRoots,
1191
1202
  });
1192
1203
  if (!resolved.ok) {
1193
1204
  return res.status(400).json({ error: resolved.error });
@@ -1294,7 +1305,7 @@ export const registerFsRoutes = (app, dependencies) => {
1294
1305
  path,
1295
1306
  os,
1296
1307
  normalizeDirectoryPath,
1297
- openchamberUserConfigRoot,
1308
+ managedRoots,
1298
1309
  });
1299
1310
  if (!resolved.ok) {
1300
1311
  return res.status(400).json({ error: resolved.error });
@@ -1332,7 +1343,7 @@ export const registerFsRoutes = (app, dependencies) => {
1332
1343
  path,
1333
1344
  os,
1334
1345
  normalizeDirectoryPath,
1335
- openchamberUserConfigRoot,
1346
+ managedRoots,
1336
1347
  });
1337
1348
  if (!resolvedOld.ok) {
1338
1349
  return res.status(400).json({ error: resolvedOld.error });
@@ -1345,7 +1356,7 @@ export const registerFsRoutes = (app, dependencies) => {
1345
1356
  path,
1346
1357
  os,
1347
1358
  normalizeDirectoryPath,
1348
- openchamberUserConfigRoot,
1359
+ managedRoots,
1349
1360
  });
1350
1361
  if (!resolvedNew.ok) {
1351
1362
  return res.status(400).json({ error: resolvedNew.error });
@@ -1451,7 +1462,7 @@ export const registerFsRoutes = (app, dependencies) => {
1451
1462
  path,
1452
1463
  os,
1453
1464
  normalizeDirectoryPath,
1454
- openchamberUserConfigRoot,
1465
+ managedRoots,
1455
1466
  });
1456
1467
  if (!resolvedForWorkspace.ok) {
1457
1468
  console.warn(`Rejected /api/fs/exec outside workspace: ${resolvedForWorkspace.error}`);
@@ -1689,7 +1700,7 @@ export const registerFsRoutes = (app, dependencies) => {
1689
1700
  path,
1690
1701
  os,
1691
1702
  normalizeDirectoryPath,
1692
- openchamberUserConfigRoot,
1703
+ managedRoots,
1693
1704
  });
1694
1705
  if (!resolved.ok) {
1695
1706
  return res.status(400).json({ error: resolved.error });
@@ -116,7 +116,7 @@ const registerExec = ({ spawn }) => {
116
116
  resolveProjectDirectory: async () => ({ directory: '/repo' }),
117
117
  buildAugmentedPath: () => '/usr/bin',
118
118
  resolveGitBinaryForSpawn: () => 'git',
119
- openchamberUserConfigRoot: '/home/user/.config',
119
+ aiworkerUserConfigRoot: '/home/user/.config',
120
120
  });
121
121
  return getRoute('POST', '/api/fs/exec');
122
122
  };
@@ -136,7 +136,7 @@ const registerWrite = (fsPromises) => {
136
136
  resolveProjectDirectory: async () => ({ directory: '/repo' }),
137
137
  buildAugmentedPath: () => '/usr/bin',
138
138
  resolveGitBinaryForSpawn: () => 'git',
139
- openchamberUserConfigRoot: '/home/user/.config',
139
+ aiworkerUserConfigRoot: '/home/user/.config',
140
140
  });
141
141
  return getRoute('POST', '/api/fs/write');
142
142
  };
@@ -160,7 +160,7 @@ const registerUpload = (fsPromises) => {
160
160
  resolveProjectDirectory: async () => ({ directory: '/repo' }),
161
161
  buildAugmentedPath: () => '/usr/bin',
162
162
  resolveGitBinaryForSpawn: () => 'git',
163
- openchamberUserConfigRoot: '/home/user/.config',
163
+ aiworkerUserConfigRoot: '/home/user/.config',
164
164
  });
165
165
  return getRoute('POST', '/api/fs/upload');
166
166
  };
@@ -180,7 +180,7 @@ const registerRead = (fsPromises, resolveProjectDirectory = async () => ({ direc
180
180
  resolveProjectDirectory,
181
181
  buildAugmentedPath: () => '/usr/bin',
182
182
  resolveGitBinaryForSpawn: () => 'git',
183
- openchamberUserConfigRoot: '/home/user/.config',
183
+ aiworkerUserConfigRoot: '/home/user/.config',
184
184
  });
185
185
  return getRoute('GET', '/api/fs/read');
186
186
  };
@@ -200,7 +200,7 @@ const registerRaw = (fsPromises) => {
200
200
  resolveProjectDirectory: async () => ({ directory: '/repo' }),
201
201
  buildAugmentedPath: () => '/usr/bin',
202
202
  resolveGitBinaryForSpawn: () => 'git',
203
- openchamberUserConfigRoot: '/home/user/.config',
203
+ aiworkerUserConfigRoot: '/home/user/.config',
204
204
  });
205
205
  return getRoute('GET', '/api/fs/raw');
206
206
  };
@@ -220,7 +220,7 @@ const registerMkdir = (fsPromises) => {
220
220
  resolveProjectDirectory: async () => ({ directory: '/repo' }),
221
221
  buildAugmentedPath: () => '/usr/bin',
222
222
  resolveGitBinaryForSpawn: () => 'git',
223
- openchamberUserConfigRoot: '/home/user/.config',
223
+ aiworkerUserConfigRoot: '/home/user/.config',
224
224
  });
225
225
  return getRoute('POST', '/api/fs/mkdir');
226
226
  };
@@ -241,7 +241,7 @@ const registerReveal = ({ fsPromises, spawn, platform = 'linux' }) => {
241
241
  resolveProjectDirectory: async () => ({ directory: '/repo' }),
242
242
  buildAugmentedPath: () => '/usr/bin',
243
243
  resolveGitBinaryForSpawn: () => 'git',
244
- openchamberUserConfigRoot: '/home/user/.config',
244
+ aiworkerUserConfigRoot: '/home/user/.config',
245
245
  });
246
246
  return getRoute('POST', '/api/fs/reveal');
247
247
  };
@@ -482,8 +482,8 @@ describe('fs upload', () => {
482
482
  });
483
483
 
484
484
  it('cleans up a partial temp file when the configured streaming limit is exceeded', async () => {
485
- const previous = process.env.OPENCHAMBER_FS_UPLOAD_MAX_BYTES;
486
- process.env.OPENCHAMBER_FS_UPLOAD_MAX_BYTES = '5';
485
+ const previous = process.env.AIWORKER_FS_UPLOAD_MAX_BYTES;
486
+ process.env.AIWORKER_FS_UPLOAD_MAX_BYTES = '5';
487
487
  const write = vi.fn(async (_buffer, _offset, length) => ({ bytesWritten: length }));
488
488
  const fsPromises = {
489
489
  open: vi.fn(async () => ({ write, close: vi.fn(async () => undefined) })),
@@ -504,14 +504,14 @@ describe('fs upload', () => {
504
504
  expect(fsPromises.link).not.toHaveBeenCalled();
505
505
  expect(fsPromises.unlink).toHaveBeenCalledWith(expect.stringMatching(/^\/repo\/file\.bin\.upload-/));
506
506
  } finally {
507
- if (previous === undefined) delete process.env.OPENCHAMBER_FS_UPLOAD_MAX_BYTES;
508
- else process.env.OPENCHAMBER_FS_UPLOAD_MAX_BYTES = previous;
507
+ if (previous === undefined) delete process.env.AIWORKER_FS_UPLOAD_MAX_BYTES;
508
+ else process.env.AIWORKER_FS_UPLOAD_MAX_BYTES = previous;
509
509
  }
510
510
  });
511
511
 
512
512
  it('rejects a declared oversized upload before opening a temp file', async () => {
513
- const previous = process.env.OPENCHAMBER_FS_UPLOAD_MAX_BYTES;
514
- process.env.OPENCHAMBER_FS_UPLOAD_MAX_BYTES = '5';
513
+ const previous = process.env.AIWORKER_FS_UPLOAD_MAX_BYTES;
514
+ process.env.AIWORKER_FS_UPLOAD_MAX_BYTES = '5';
515
515
  const fsPromises = {
516
516
  open: vi.fn(async () => ({ write: vi.fn(), close: vi.fn() })),
517
517
  };
@@ -523,8 +523,8 @@ describe('fs upload', () => {
523
523
  expect(res.body).toEqual({ error: 'File exceeds maximum size of 5 bytes' });
524
524
  expect(fsPromises.open).not.toHaveBeenCalled();
525
525
  } finally {
526
- if (previous === undefined) delete process.env.OPENCHAMBER_FS_UPLOAD_MAX_BYTES;
527
- else process.env.OPENCHAMBER_FS_UPLOAD_MAX_BYTES = previous;
526
+ if (previous === undefined) delete process.env.AIWORKER_FS_UPLOAD_MAX_BYTES;
527
+ else process.env.AIWORKER_FS_UPLOAD_MAX_BYTES = previous;
528
528
  }
529
529
  });
530
530
 
@@ -843,11 +843,11 @@ describe('fs reveal', () => {
843
843
 
844
844
  describe('fs exec git-read cache', () => {
845
845
  beforeEach(() => {
846
- delete process.env.OPENCHAMBER_GIT_READ_CACHE_TTL_MS;
846
+ delete process.env.AIWORKER_GIT_READ_CACHE_TTL_MS;
847
847
  });
848
848
 
849
849
  afterEach(() => {
850
- delete process.env.OPENCHAMBER_GIT_READ_CACHE_TTL_MS;
850
+ delete process.env.AIWORKER_GIT_READ_CACHE_TTL_MS;
851
851
  });
852
852
 
853
853
  it('rejects background command execution', async () => {
@@ -956,7 +956,7 @@ describe('fs exec git-read cache', () => {
956
956
  });
957
957
 
958
958
  it('disables caching when TTL is 0', async () => {
959
- process.env.OPENCHAMBER_GIT_READ_CACHE_TTL_MS = '0';
959
+ process.env.AIWORKER_GIT_READ_CACHE_TTL_MS = '0';
960
960
  const command = 'git rev-parse --absolute-git-dir';
961
961
  const { spawn, calls } = createSpawn({ stdoutByCommand: { [command]: '/repo/.git\n' } });
962
962
  const handler = registerExec({ spawn });
@@ -1062,7 +1062,7 @@ describe('fs list symlink path space (issue 2627)', () => {
1062
1062
  resolveProjectDirectory: async () => ({ directory: '/workspace' }),
1063
1063
  buildAugmentedPath: () => '/usr/bin',
1064
1064
  resolveGitBinaryForSpawn: () => 'git',
1065
- openchamberUserConfigRoot: '/home/user/.config',
1065
+ aiworkerUserConfigRoot: '/home/user/.config',
1066
1066
  });
1067
1067
  return getRoute('GET', '/api/fs/list');
1068
1068
  };
@@ -1162,7 +1162,7 @@ describe('fs git-dirs', () => {
1162
1162
  resolveProjectDirectory: async () => ({ directory: '/workspace' }),
1163
1163
  buildAugmentedPath: () => '/usr/bin',
1164
1164
  resolveGitBinaryForSpawn: () => 'git',
1165
- openchamberUserConfigRoot: '/home/user/.config',
1165
+ aiworkerUserConfigRoot: '/home/user/.config',
1166
1166
  });
1167
1167
  return { handler: getRoute('GET', '/api/fs/git-dirs'), readdir };
1168
1168
  };
@@ -1393,7 +1393,7 @@ describe('fs stat directory scope (issue 3019)', () => {
1393
1393
  resolveProjectDirectory: projectDirectoryRuntime.resolveProjectDirectory,
1394
1394
  buildAugmentedPath: () => '/usr/bin',
1395
1395
  resolveGitBinaryForSpawn: () => 'git',
1396
- openchamberUserConfigRoot: '/home/user/.config',
1396
+ aiworkerUserConfigRoot: '/home/user/.config',
1397
1397
  });
1398
1398
  return getRoute('GET', '/api/fs/stat');
1399
1399
  };
@@ -1429,3 +1429,80 @@ describe('fs stat directory scope (issue 3019)', () => {
1429
1429
  expect(res.body.isFile).toBe(true);
1430
1430
  });
1431
1431
  });
1432
+
1433
+ describe('fs managed chats root', () => {
1434
+ const registerWithChatsRoot = ({ managedChatsRoot, fsPromises = {} } = {}) => {
1435
+ const { app, getRoute } = createRouteRegistry();
1436
+ registerFsRoutes(app, {
1437
+ os: { homedir: () => '/home/user' },
1438
+ path: path.posix,
1439
+ fsPromises: {
1440
+ realpath: async (targetPath) => targetPath,
1441
+ mkdir: async () => undefined,
1442
+ ...fsPromises,
1443
+ },
1444
+ spawn: vi.fn(),
1445
+ crypto: { randomUUID: () => 'job-0' },
1446
+ normalizeDirectoryPath: (p) => p,
1447
+ resolveProjectDirectory: async () => ({ directory: '/repo' }),
1448
+ buildAugmentedPath: () => '/usr/bin',
1449
+ resolveGitBinaryForSpawn: () => 'git',
1450
+ aiworkerUserConfigRoot: '/home/user/.config/openchamber',
1451
+ managedChatsRoot,
1452
+ });
1453
+ return {
1454
+ home: getRoute('GET', '/api/fs/home'),
1455
+ mkdir: getRoute('POST', '/api/fs/mkdir'),
1456
+ };
1457
+ };
1458
+
1459
+ it('exposes the default chats root next to the home directory', async () => {
1460
+ const { home } = registerWithChatsRoot();
1461
+
1462
+ const res = createMockResponse();
1463
+ await home(undefined, res);
1464
+
1465
+ expect(res.statusCode).toBe(200);
1466
+ expect(res.body.home).toBe('/home/user');
1467
+ expect(res.body.chatsRoot).toBe('/home/user/.config/openchamber/chats');
1468
+ });
1469
+
1470
+ it('exposes a relocated chats root when AIWORKER_CHATS_DIR is configured upstream', async () => {
1471
+ const { home } = registerWithChatsRoot({ managedChatsRoot: '/srv/openchamber-chats' });
1472
+
1473
+ const res = createMockResponse();
1474
+ await home(undefined, res);
1475
+
1476
+ expect(res.statusCode).toBe(200);
1477
+ expect(res.body.chatsRoot).toBe('/srv/openchamber-chats');
1478
+ });
1479
+
1480
+ it('allows mkdir inside the relocated chats root outside the active workspace', async () => {
1481
+ const mkdirCalls = [];
1482
+ const { mkdir } = registerWithChatsRoot({
1483
+ managedChatsRoot: '/srv/openchamber-chats',
1484
+ fsPromises: {
1485
+ mkdir: async (targetPath) => {
1486
+ mkdirCalls.push(targetPath);
1487
+ },
1488
+ },
1489
+ });
1490
+
1491
+ const res = createMockResponse();
1492
+ await mkdir({ body: { path: '/srv/openchamber-chats/2026-08-25/session-a' } }, res);
1493
+
1494
+ expect(res.statusCode).toBe(200);
1495
+ expect(res.body.success).toBe(true);
1496
+ expect(mkdirCalls).toEqual(['/srv/openchamber-chats/2026-08-25/session-a']);
1497
+ });
1498
+
1499
+ it('still rejects mkdir outside the workspace and all managed roots', async () => {
1500
+ const { mkdir } = registerWithChatsRoot({ managedChatsRoot: '/srv/openchamber-chats' });
1501
+
1502
+ const res = createMockResponse();
1503
+ await mkdir({ body: { path: '/etc/passwd-holder' } }, res);
1504
+
1505
+ expect(res.statusCode).toBe(400);
1506
+ expect(res.body).toEqual({ error: 'Path is outside of active workspace' });
1507
+ });
1508
+ });
@@ -39,6 +39,7 @@ The following functions are exported and used by the web server:
39
39
 
40
40
  ### Branch Operations
41
41
  - `getBranches(directory)`: Get list of local and remote branches (filtered to active remote branches).
42
+ - `getUnpushedBranchCounts(directory, branchNames)`: Count commits ahead of each locally known upstream for up to five supplied local branches. This reads local refs only and omits branches without an upstream.
42
43
  - `createBranch(directory, branchName, options)`: Create and checkout a new branch.
43
44
  - `checkoutBranch(directory, branchName)`: Checkout an existing branch. A remote-tracking name (`origin/main`, or the `remotes/`-prefixed form) resolves to the local branch of that name, created with `--track` when it does not exist yet, because the branch selector offers remote branches as places to work rather than commits to inspect — a literal checkout of the remote ref would detach HEAD. A local branch whose own name looks like a remote ref wins over that resolution, and anything unresolvable is checked out as requested. The returned `branch` is the branch that was actually checked out, which callers should report instead of the requested name.
44
45
  - `deleteBranch(directory, branch, options)`: Delete a branch (supports force flag).
@@ -48,7 +49,7 @@ The following functions are exported and used by the web server:
48
49
  ### Worktree Operations
49
50
  - `getWorktrees(directory)`: List all git worktrees for a repository.
50
51
  - `validateWorktreeCreate(directory, input)`: Validate worktree creation parameters (mode, branchName, startRef, upstream config).
51
- - `createWorktree(directory, input)`: Create a new worktree (supports 'new' and 'existing' modes, upstream setup). After populating the worktree, the repository's `post-checkout` hook runs once with git's standard arguments (null ref as previous HEAD, the checked-out HEAD, and flag `1`) from the worktree directory, mirroring `git worktree add` without `--no-checkout`; a missing or non-executable hook is skipped and a failing hook is logged as a warning, never failing worktree creation or the session bootstrap.
52
+ - `createWorktree(directory, input)`: Create a new worktree (supports 'new' and 'existing' modes, upstream setup). When the current tracked branch has no unpublished commits, the UI supplies its remote-tracking ref and this operation fetches that branch once before creating the worktree. A failed fetch falls back to the local branch and reports `sourceFetchFailed`; other remote start refs still require an existing local ref when their fetch fails. After populating the worktree, the repository's `post-checkout` hook runs once with git's standard arguments (null ref as previous HEAD, the checked-out HEAD, and flag `1`) from the worktree directory, mirroring `git worktree add` without `--no-checkout`; a missing or non-executable hook is skipped and a failing hook is logged as a warning, never failing worktree creation or the session bootstrap.
52
53
  - `removeWorktree(directory, input)`: Remove a worktree (optionally delete local branch).
53
54
  - `isLinkedWorktree(directory)`: Check if directory is a linked worktree (not primary).
54
55
 
@@ -142,6 +143,7 @@ The following functions are internal helpers used by exported functions:
142
143
  - `path`: Absolute path to worktree directory.
143
144
  - `directoryCreated`: Present when create returned after the target directory exists while background Git/bootstrap work continues.
144
145
  - `bootstrapStatus`: Background setup state. The legacy `status` remains `pending`, `ready`, or `failed`, while `phase` reports `directory-created`, `git-ready`, or `setup-ready`. Fast create starts at `pending`/`directory-created`; population and upstream Git completion advances to `pending`/`git-ready` before setup/start scripts; completed setup is `ready`/`setup-ready`. A missing in-memory state falls back to `ready`/`setup-ready`; clients continue to accept legacy status responses that omit `phase`.
146
+ - `sourceFetchFailed`: Present when the automatic source-branch fetch failed and creation fell back to the tracked local branch.
145
147
  - Fast-create background failures remove OpenCode sandbox metadata for directories that never became Git worktrees, and remove the pre-created directory only if it is still empty. User-created files are never recursively deleted by this cleanup.
146
148
  - Worktree removal waits for any active create/bootstrap task for that directory before deleting it, preventing a background Git or setup task from restoring removed state or racing filesystem cleanup.
147
149
  - Worktree bootstrap retries transient `index.lock` conflicts. If the lock remains byte-for-byte and metadata-identical across the retry window, it is treated as stale, removed, and population continues automatically; changing locks are left untouched and reported as failures.
@@ -2,7 +2,7 @@ import fs from 'fs';
2
2
  import path from 'path';
3
3
  import os from 'os';
4
4
 
5
- const STORAGE_DIR = path.join(os.homedir(), '.config', 'openchamber');
5
+ const STORAGE_DIR = path.join(os.homedir(), '.config', 'aiworker');
6
6
  const STORAGE_FILE = path.join(STORAGE_DIR, 'git-identities.json');
7
7
 
8
8
  function ensureStorageDir() {
@@ -12,11 +12,11 @@ import {
12
12
  } from './service.js';
13
13
 
14
14
  // ---------------------------------------------------------------------------
15
- // Regression for https://github.com/openchamber/openchamber/issues/2746
15
+ // Regression for https://roweb.cn/roweb/openchamber/issues/2746
16
16
  //
17
17
  // "[Bug] new worktree, Filename too long"
18
18
  //
19
- // OpenChamber places worktrees under:
19
+ // AiWorker places worktrees under:
20
20
  // <XDG_DATA_HOME>/opencode/worktree/<40-char root commit hash>/<worktree name>
21
21
  // and populates them with `git reset --hard`. On Windows, that deep prefix plus
22
22
  // a deeply nested repo file (e.g. yudao ~173 chars) exceeds MAX_PATH (260) and
@@ -95,7 +95,7 @@ describe('issue #2746 - worktree long path support', () => {
95
95
  const created = await createWorktree(repo, {
96
96
  mode: 'new',
97
97
  worktreeName: 'issue-2746',
98
- branchName: 'openchamber/issue-2746',
98
+ branchName: 'aiworker/issue-2746',
99
99
  });
100
100
  expect(created.directoryCreated).toBe(true);
101
101
 
@@ -162,7 +162,7 @@ describe('issue #2746 - worktree long path support', () => {
162
162
  const created = await createWorktree(repo, {
163
163
  mode: 'new',
164
164
  worktreeName: 'issue-2746-namemax',
165
- branchName: 'openchamber/issue-2746-namemax',
165
+ branchName: 'aiworker/issue-2746-namemax',
166
166
  });
167
167
  expect(created.directoryCreated).toBe(true);
168
168
 
@@ -873,6 +873,22 @@ export function registerGitRoutes(app) {
873
873
  }
874
874
  });
875
875
 
876
+ app.post('/api/git/branch-push-status', async (req, res) => {
877
+ const { getUnpushedBranchCounts } = await getGitLibraries();
878
+ try {
879
+ const directory = req.query.directory;
880
+ const branches = req.body?.branches;
881
+ if (!directory) return res.status(400).json({ error: 'directory parameter is required' });
882
+ if (!Array.isArray(branches) || branches.some((branch) => typeof branch !== 'string')) {
883
+ return res.status(400).json({ error: 'branches must be an array of branch names' });
884
+ }
885
+ res.json(await getUnpushedBranchCounts(directory, branches));
886
+ } catch (error) {
887
+ console.error('Failed to get branch push status:', error);
888
+ res.status(500).json({ error: error.message || 'Failed to get branch push status' });
889
+ }
890
+ });
891
+
876
892
  app.post('/api/git/branches', async (req, res) => {
877
893
  const { createBranch } = await getGitLibraries();
878
894
  try {
@@ -1074,7 +1090,7 @@ export function registerGitRoutes(app) {
1074
1090
  // Worktrees are an optional feature. Avoid repeated 500s (and repeated client retries)
1075
1091
  // when the directory isn't a git repo or uses shell shorthand like "~/".
1076
1092
  console.warn('Failed to get worktrees, returning empty list:', error?.message || error);
1077
- res.setHeader('X-OpenChamber-Warning', 'git worktrees unavailable');
1093
+ res.setHeader('X-AiWorker-Warning', 'git worktrees unavailable');
1078
1094
  res.json([]);
1079
1095
  }
1080
1096
  });