@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
@@ -200,7 +200,7 @@ const resolveGitBinary = () => {
200
200
  return resolvedGitBinary;
201
201
  }
202
202
 
203
- const explicit = [process.env.GIT_BINARY, process.env.OPENCHAMBER_GIT_BINARY]
203
+ const explicit = [process.env.GIT_BINARY, process.env.AIWORKER_GIT_BINARY]
204
204
  .map((value) => (typeof value === 'string' ? value.trim() : ''))
205
205
  .filter(Boolean);
206
206
  for (const candidate of explicit) {
@@ -364,7 +364,7 @@ const createGit = async (directory, { allowUnsafeSshCommand = false } = {}) => {
364
364
  }
365
365
  : undefined;
366
366
  // Always pin simple-git to an explicit working directory. Omitting baseDir
367
- // makes simple-git use process.cwd(), which breaks when the OpenChamber
367
+ // makes simple-git use process.cwd(), which breaks when the AiWorker
368
368
  // server was launched from a neutral directory (e.g. $HOME) and the opened
369
369
  // project lives elsewhere — session/project discovery then sees spurious
370
370
  // "not a git repository" errors and can abort enumeration.
@@ -684,6 +684,15 @@ const parseWorktreePorcelain = (raw) => {
684
684
  const branchRef = line.substring('branch '.length).trim();
685
685
  current.branchRef = branchRef;
686
686
  current.branch = cleanBranchName(branchRef);
687
+ continue;
688
+ }
689
+
690
+ // git marks a worktree whose directory is gone (deleted outside git) as
691
+ // prunable; it stays registered until `git worktree prune`. The sidebar
692
+ // needs that distinction: the directory is missing, but the sessions that
693
+ // lived there are not.
694
+ if (line === 'prunable' || line.startsWith('prunable ')) {
695
+ current.prunable = true;
687
696
  }
688
697
  }
689
698
 
@@ -991,7 +1000,7 @@ const getFileIdentity = async (filePath) => {
991
1000
  }
992
1001
  };
993
1002
 
994
- // OpenChamber places managed worktrees under a deep data-dir path
1003
+ // AiWorker places managed worktrees under a deep data-dir path
995
1004
  // (`<XDG_DATA_HOME>/opencode/worktree/<40-char project id>/<name>/`). On
996
1005
  // Windows that prefix plus a deeply nested repo file routinely exceeds
997
1006
  // MAX_PATH (260). Git can check those paths out when core.longpaths is
@@ -1009,7 +1018,7 @@ const formatWorktreePopulateError = (message) => {
1009
1018
  return [
1010
1019
  text,
1011
1020
  'The worktree checkout path exceeds this system\'s path-length limit.',
1012
- 'OpenChamber enables Git `core.longpaths` for worktree population; if this still fails on Windows, enable OS long paths (LongPathsEnabled) or open the repository from a shorter absolute path.',
1021
+ 'AiWorker enables Git `core.longpaths` for worktree population; if this still fails on Windows, enable OS long paths (LongPathsEnabled) or open the repository from a shorter absolute path.',
1013
1022
  ].join('\n');
1014
1023
  };
1015
1024
 
@@ -1019,7 +1028,7 @@ export const ensureWorktreeLongpaths = async (directory) => {
1019
1028
  return;
1020
1029
  }
1021
1030
  // Local config is shared across linked worktrees via the common git dir, so
1022
- // subsequent OpenChamber and CLI git operations in this repo also get long
1031
+ // subsequent AiWorker and CLI git operations in this repo also get long
1023
1032
  // path support. Failures here are non-fatal: populate still passes
1024
1033
  // `-c core.longpaths=true` on reset.
1025
1034
  await runGitCommand(directory, ['config', 'core.longpaths', 'true']);
@@ -1309,7 +1318,7 @@ export async function computeIntegratePlan(input = {}) {
1309
1318
  }
1310
1319
 
1311
1320
  const createIntegrateTempWorktree = async (repoRoot, targetBranch) => {
1312
- const tmpParent = path.join(os.homedir(), '.config', 'openchamber', 'tmp');
1321
+ const tmpParent = path.join(os.homedir(), '.config', 'aiworker', 'tmp');
1313
1322
  await fsp.mkdir(tmpParent, { recursive: true });
1314
1323
  const tmpDir = await fsp.mkdtemp(path.join(tmpParent, 'oc-integrate-'));
1315
1324
  try {
@@ -1622,7 +1631,7 @@ const resolveCandidateDirectory = async (worktreeRoot, preferredName, explicitBr
1622
1631
  return { name, directory, branch: explicitBranchName };
1623
1632
  }
1624
1633
 
1625
- const branch = `openchamber/${name}`;
1634
+ const branch = `aiworker/${name}`;
1626
1635
  const branchRef = `refs/heads/${branch}`;
1627
1636
  const branchExists = await runGitCommand(primaryWorktree, ['show-ref', '--verify', '--quiet', branchRef]);
1628
1637
  if (branchExists.success) {
@@ -1742,7 +1751,7 @@ const loadProjectStartCommand = async (projectID) => {
1742
1751
 
1743
1752
  // OpenCode owns its own project/sandbox registry. It records a worktree as a
1744
1753
  // sandbox itself when an instance boots for that directory, and filters entries
1745
- // whose directory no longer exists when reading them back. OpenChamber used to
1754
+ // whose directory no longer exists when reading them back. AiWorker used to
1746
1755
  // write that state directly into OpenCode's storage JSON and SQLite database,
1747
1756
  // behind the back of the running process: the row changed but the server was
1748
1757
  // never told, so a worktree created while OpenCode was running stayed unknown
@@ -3248,7 +3257,7 @@ export async function stashPush(directory, options = {}) {
3248
3257
  const { git } = await createRepositoryGitContext(directory);
3249
3258
  const message = typeof options.message === 'string' && options.message.trim()
3250
3259
  ? options.message.trim()
3251
- : `OpenChamber stash ${new Date().toISOString()}`;
3260
+ : `AiWorker stash ${new Date().toISOString()}`;
3252
3261
  const output = await git.raw(['stash', 'push', '--include-untracked', '-m', message]);
3253
3262
  return {
3254
3263
  success: true,
@@ -3687,6 +3696,35 @@ export async function getBranches(directory) {
3687
3696
  }
3688
3697
  }
3689
3698
 
3699
+ /**
3700
+ * Counts locally unpushed commits for a small caller-supplied set of local
3701
+ * branches. This deliberately reads only local refs: the branch picker calls
3702
+ * it when opened, never polls, and never fetches a remote behind the user's
3703
+ * back. Unknown, remote, and upstream-less branches are omitted.
3704
+ */
3705
+ export async function getUnpushedBranchCounts(directory, branchNames) {
3706
+ const { git } = await createRepositoryGitContext(directory);
3707
+ const requested = [...new Set(Array.isArray(branchNames) ? branchNames : [])]
3708
+ .filter((name) => typeof name === 'string' && name.length > 0)
3709
+ .slice(0, 5);
3710
+ if (requested.length === 0) return { counts: {} };
3711
+
3712
+ const local = new Set((await git.branchLocal()).all);
3713
+ const counts = {};
3714
+ await Promise.all(requested.map(async (branch) => {
3715
+ if (!local.has(branch)) return;
3716
+ const upstream = await git.raw(['rev-parse', '--abbrev-ref', '--symbolic-full-name', `${branch}@{upstream}`])
3717
+ .then((value) => value.trim())
3718
+ .catch(() => '');
3719
+ if (!upstream) return;
3720
+ const count = await git.raw(['rev-list', '--count', `${upstream}..${branch}`])
3721
+ .then((value) => Number.parseInt(value.trim(), 10))
3722
+ .catch(() => 0);
3723
+ if (Number.isFinite(count) && count > 0) counts[branch] = count;
3724
+ }));
3725
+ return { counts };
3726
+ }
3727
+
3690
3728
  async function getRemoteDefaultBranches(git) {
3691
3729
  let defaults = {};
3692
3730
 
@@ -4007,6 +4045,7 @@ export async function getWorktrees(directory) {
4007
4045
  name: path.basename(entry.worktree || ''),
4008
4046
  branch: entry.branch || '',
4009
4047
  path: entry.worktree,
4048
+ prunable: entry.prunable === true,
4010
4049
  }));
4011
4050
  } catch (error) {
4012
4051
  // Worktrees are an optional feature. When the caller passes a directory
@@ -4266,6 +4305,7 @@ async function attachGitWorktreeToCandidate(context, candidate, input = {}) {
4266
4305
 
4267
4306
  const parsedRemoteStartRef = await resolveRemoteBranchRef(context.primaryWorktree, startRef);
4268
4307
  if (parsedRemoteStartRef) {
4308
+ worktreeAddArgs.splice(2, 0, '--no-track');
4269
4309
  inferredUpstream = {
4270
4310
  remote: parsedRemoteStartRef.remote,
4271
4311
  branch: parsedRemoteStartRef.branch,
@@ -4273,24 +4313,17 @@ async function attachGitWorktreeToCandidate(context, candidate, input = {}) {
4273
4313
  }
4274
4314
  }
4275
4315
 
4276
- if (ensureRemoteName && ensureRemoteUrl) {
4316
+ if (mode === 'existing' && ensureRemoteName && ensureRemoteUrl) {
4277
4317
  await ensureRemoteWithUrl(context.primaryWorktree, ensureRemoteName, ensureRemoteUrl);
4278
4318
  }
4279
4319
 
4280
- if (mode === 'new') {
4281
- const parsedRemoteStartRef = await resolveRemoteBranchRef(context.primaryWorktree, startRef);
4282
- if (parsedRemoteStartRef) {
4283
- await fetchRemoteBranchRef(context.primaryWorktree, parsedRemoteStartRef.remote, parsedRemoteStartRef.branch);
4284
- }
4285
- }
4286
-
4287
4320
  await runGitCommandOrThrow(context.primaryWorktree, worktreeAddArgs, 'Failed to create git worktree');
4288
4321
 
4289
4322
  const upstreamRemote = shouldSetUpstream
4290
- ? String(inferredUpstream?.remote || input?.upstreamRemote || '').trim()
4323
+ ? String(input?.upstreamRemote || inferredUpstream?.remote || '').trim()
4291
4324
  : '';
4292
4325
  const upstreamBranch = shouldSetUpstream
4293
- ? String(inferredUpstream?.branch || input?.upstreamBranch || '').trim()
4326
+ ? String(input?.upstreamBranch || inferredUpstream?.branch || '').trim()
4294
4327
  : '';
4295
4328
 
4296
4329
  const bootstrapStatus = setWorktreeBootstrapState(
@@ -4325,6 +4358,50 @@ async function attachGitWorktreeToCandidate(context, candidate, input = {}) {
4325
4358
  };
4326
4359
  }
4327
4360
 
4361
+ const prepareWorktreeCreateSource = async (context, input = {}) => {
4362
+ if (input?.mode === 'existing') {
4363
+ return { input, sourceFetchFailed: false };
4364
+ }
4365
+
4366
+ const startRef = normalizeStartRef(input?.startRef);
4367
+ const remoteStartRef = await resolveRemoteBranchRef(context.primaryWorktree, startRef);
4368
+ if (!remoteStartRef) {
4369
+ return { input, sourceFetchFailed: false };
4370
+ }
4371
+
4372
+ const status = await getStatus(context.primaryWorktree, { mode: 'light' }).catch(() => null);
4373
+ const trackingRef = status?.tracking
4374
+ ? await resolveRemoteBranchRef(context.primaryWorktree, status.tracking)
4375
+ : null;
4376
+ const canFallbackToLocal = Boolean(
4377
+ status?.current
4378
+ && status.ahead === 0
4379
+ && trackingRef?.fullRef === remoteStartRef.fullRef
4380
+ );
4381
+
4382
+ try {
4383
+ await fetchRemoteBranchRef(context.primaryWorktree, remoteStartRef.remote, remoteStartRef.branch);
4384
+ return { input, sourceFetchFailed: false };
4385
+ } catch (error) {
4386
+ if (canFallbackToLocal) {
4387
+ return {
4388
+ input: { ...input, startRef: status.current },
4389
+ sourceFetchFailed: true,
4390
+ };
4391
+ }
4392
+
4393
+ const refExists = await runGitCommand(
4394
+ context.primaryWorktree,
4395
+ ['show-ref', '--verify', '--quiet', remoteStartRef.fullRef]
4396
+ );
4397
+ if (!refExists.success) {
4398
+ throw error;
4399
+ }
4400
+ console.warn(`Worktree create: failed to refresh ${remoteStartRef.remote}/${remoteStartRef.branch}, proceeding with the existing remote-tracking ref`);
4401
+ return { input, sourceFetchFailed: false };
4402
+ }
4403
+ };
4404
+
4328
4405
  export async function createWorktree(directory, input = {}) {
4329
4406
  const mode = input?.mode === 'existing' ? 'existing' : 'new';
4330
4407
  const context = await resolveWorktreeProjectContext(directory);
@@ -4333,10 +4410,18 @@ export async function createWorktree(directory, input = {}) {
4333
4410
  await assertWorktreeCreatePreflight(directory, input);
4334
4411
  }
4335
4412
 
4413
+ const ensureRemoteName = String(input?.ensureRemoteName || '').trim();
4414
+ const ensureRemoteUrl = String(input?.ensureRemoteUrl || '').trim();
4415
+ if (ensureRemoteName && ensureRemoteUrl) {
4416
+ await ensureRemoteWithUrl(context.primaryWorktree, ensureRemoteName, ensureRemoteUrl);
4417
+ }
4418
+ const prepared = await prepareWorktreeCreateSource(context, input);
4419
+ const preparedInput = prepared.input;
4420
+
4336
4421
  await fsp.mkdir(context.worktreeRoot, { recursive: true });
4337
4422
 
4338
- const preferredName = String(input?.worktreeName || input?.name || '').trim();
4339
- const preferredBranchName = cleanBranchName(String(input?.branchName || '').trim());
4423
+ const preferredName = String(preparedInput?.worktreeName || preparedInput?.name || '').trim();
4424
+ const preferredBranchName = cleanBranchName(String(preparedInput?.branchName || '').trim());
4340
4425
 
4341
4426
  const candidate = await resolveCandidateDirectory(
4342
4427
  context.worktreeRoot,
@@ -4345,7 +4430,7 @@ export async function createWorktree(directory, input = {}) {
4345
4430
  context.primaryWorktree
4346
4431
  );
4347
4432
 
4348
- if (input?.returnAfterDirectoryCreated === true) {
4433
+ if (preparedInput?.returnAfterDirectoryCreated === true) {
4349
4434
  await fsp.mkdir(candidate.directory, { recursive: false });
4350
4435
 
4351
4436
  const bootstrapStatus = setWorktreeBootstrapState(
@@ -4354,10 +4439,10 @@ export async function createWorktree(directory, input = {}) {
4354
4439
  WORKTREE_BOOTSTRAP_PHASE_DIRECTORY_CREATED
4355
4440
  );
4356
4441
  const localBranch = mode === 'existing'
4357
- ? cleanBranchName(String(input?.branchName || input?.existingBranch || candidate.branch || '').trim())
4442
+ ? cleanBranchName(String(preparedInput?.branchName || preparedInput?.existingBranch || candidate.branch || '').trim())
4358
4443
  : candidate.branch;
4359
4444
 
4360
- const task = attachGitWorktreeToCandidate(context, candidate, input).catch(async (error) => {
4445
+ const task = attachGitWorktreeToCandidate(context, candidate, preparedInput).catch(async (error) => {
4361
4446
  setWorktreeBootstrapState(
4362
4447
  candidate.directory,
4363
4448
  WORKTREE_BOOTSTRAP_FAILED,
@@ -4369,7 +4454,7 @@ export async function createWorktree(directory, input = {}) {
4369
4454
  });
4370
4455
  trackWorktreeBootstrapTask(candidate.directory, task);
4371
4456
 
4372
- return {
4457
+ const result = {
4373
4458
  head: '',
4374
4459
  name: candidate.name,
4375
4460
  branch: localBranch,
@@ -4377,9 +4462,14 @@ export async function createWorktree(directory, input = {}) {
4377
4462
  directoryCreated: true,
4378
4463
  bootstrapStatus,
4379
4464
  };
4465
+ if (prepared.sourceFetchFailed) {
4466
+ result.sourceFetchFailed = true;
4467
+ }
4468
+ return result;
4380
4469
  }
4381
4470
 
4382
- return attachGitWorktreeToCandidate(context, candidate, input);
4471
+ const result = await attachGitWorktreeToCandidate(context, candidate, preparedInput);
4472
+ return prepared.sourceFetchFailed ? { ...result, sourceFetchFailed: true } : result;
4383
4473
  }
4384
4474
 
4385
4475
  export async function getWorktreeBootstrapStatus(directory) {
@@ -12,6 +12,7 @@ import {
12
12
  createWorktree,
13
13
  getWorktreeBootstrapStatus,
14
14
  getBranches,
15
+ getUnpushedBranchCounts,
15
16
  getRangeDiff,
16
17
  getStatus,
17
18
  getWorktrees,
@@ -54,6 +55,14 @@ const runGit = (cwd, args) =>
54
55
  stdio: ['ignore', 'pipe', 'pipe'],
55
56
  });
56
57
 
58
+ const readBranchConfig = (cwd, branch, key) => {
59
+ try {
60
+ return runGit(cwd, ['config', '--get', `branch.${branch}.${key}`]).trim();
61
+ } catch {
62
+ return '';
63
+ }
64
+ };
65
+
57
66
  /**
58
67
  * A repository on `next` whose only remote publishes `defaultBranch` and has it
59
68
  * recorded as that remote's HEAD — the shape of every repository whose default
@@ -508,6 +517,24 @@ describe('getWorktrees', () => {
508
517
  expect(Array.isArray(result)).toBe(true);
509
518
  expect(warnSpy).not.toHaveBeenCalled();
510
519
  });
520
+ it('flags a worktree whose directory was deleted outside git as prunable', async () => {
521
+ const repo = createTempDir();
522
+ runGit(repo, ['init', '-b', 'main']);
523
+ runGit(repo, ['config', 'user.email', 'test@example.com']);
524
+ runGit(repo, ['config', 'user.name', 'Test User']);
525
+ runGit(repo, ['commit', '--allow-empty', '-m', 'init']);
526
+ const worktreePath = path.join(createTempDir(), 'feature');
527
+ runGit(repo, ['worktree', 'add', worktreePath, '-b', 'feature']);
528
+
529
+ const before = await getWorktrees(repo);
530
+ expect(before.find((entry) => entry.branch === 'feature')).toMatchObject({ prunable: false });
531
+
532
+ fs.rmSync(worktreePath, { recursive: true, force: true });
533
+
534
+ const after = await getWorktrees(repo);
535
+ expect(after.find((entry) => entry.branch === 'feature')).toMatchObject({ path: expect.any(String), prunable: true });
536
+ expect(after.find((entry) => entry.branch === 'main')).toMatchObject({ prunable: false });
537
+ });
511
538
  });
512
539
 
513
540
  // ---------------------------------------------------------------------------
@@ -622,7 +649,7 @@ describe('createWorktree', () => {
622
649
  const created = await createWorktree(repo, {
623
650
  mode: 'new',
624
651
  worktreeName: 'hook-test',
625
- branchName: 'openchamber/hook-test',
652
+ branchName: 'aiworker/hook-test',
626
653
  returnAfterDirectoryCreated: true,
627
654
  });
628
655
 
@@ -674,7 +701,7 @@ describe('createWorktree', () => {
674
701
  const created = await createWorktree(repo, {
675
702
  mode: 'new',
676
703
  worktreeName: 'hook-skip-test',
677
- branchName: 'openchamber/hook-skip-test',
704
+ branchName: 'aiworker/hook-skip-test',
678
705
  returnAfterDirectoryCreated: true,
679
706
  });
680
707
 
@@ -717,7 +744,7 @@ describe('createWorktree', () => {
717
744
  const created = await createWorktree(repo, {
718
745
  mode: 'new',
719
746
  worktreeName: 'hook-fail-test',
720
- branchName: 'openchamber/hook-fail-test',
747
+ branchName: 'aiworker/hook-fail-test',
721
748
  returnAfterDirectoryCreated: true,
722
749
  });
723
750
 
@@ -854,6 +881,135 @@ describe('createWorktree', () => {
854
881
  }
855
882
  }
856
883
  });
884
+
885
+ it('does not auto-track the remote start ref when creating a new branch from it', async () => {
886
+ if (!canRunGit()) return;
887
+
888
+ const previousXdgDataHome = process.env.XDG_DATA_HOME;
889
+ const dataHome = createTempDir();
890
+ process.env.XDG_DATA_HOME = dataHome;
891
+
892
+ try {
893
+ const { repository } = createRepositoryWithRemote({ defaultBranch: 'main' });
894
+
895
+ const created = await createWorktree(repository, {
896
+ mode: 'new',
897
+ branchName: 'aiworker/feature',
898
+ worktreeName: 'feature-wt',
899
+ startRef: 'remotes/origin/main',
900
+ setUpstream: true,
901
+ upstreamRemote: 'origin',
902
+ upstreamBranch: 'aiworker/feature',
903
+ });
904
+
905
+ expect(created.branch).toBe('aiworker/feature');
906
+
907
+ await expect.poll(
908
+ () => getWorktreeBootstrapStatus(created.path).then((status) => status.status === 'ready' || status.status === 'failed'),
909
+ { timeout: 5_000 }
910
+ ).toBe(true);
911
+
912
+ expect(readBranchConfig(created.path, 'aiworker/feature', 'remote')).toBe('');
913
+ expect(readBranchConfig(created.path, 'aiworker/feature', 'merge')).toBe('');
914
+ } finally {
915
+ if (previousXdgDataHome === undefined) {
916
+ delete process.env.XDG_DATA_HOME;
917
+ } else {
918
+ process.env.XDG_DATA_HOME = previousXdgDataHome;
919
+ }
920
+ }
921
+ }, 30_000);
922
+
923
+ it('falls back to the remote start ref for upstream tracking when no explicit keys are given', async () => {
924
+ if (!canRunGit()) return;
925
+
926
+ const previousXdgDataHome = process.env.XDG_DATA_HOME;
927
+ const dataHome = createTempDir();
928
+ process.env.XDG_DATA_HOME = dataHome;
929
+
930
+ try {
931
+ const { repository } = createRepositoryWithRemote({ defaultBranch: 'main' });
932
+
933
+ const created = await createWorktree(repository, {
934
+ mode: 'new',
935
+ branchName: 'aiworker/fallback-wt',
936
+ worktreeName: 'fallback-wt',
937
+ startRef: 'remotes/origin/main',
938
+ setUpstream: true,
939
+ });
940
+
941
+ await expect.poll(
942
+ () => readBranchConfig(created.path, 'aiworker/fallback-wt', 'merge'),
943
+ { timeout: 5_000 }
944
+ ).toBe('refs/heads/main');
945
+ expect(readBranchConfig(created.path, 'aiworker/fallback-wt', 'remote')).toBe('origin');
946
+ } finally {
947
+ if (previousXdgDataHome === undefined) {
948
+ delete process.env.XDG_DATA_HOME;
949
+ } else {
950
+ process.env.XDG_DATA_HOME = previousXdgDataHome;
951
+ }
952
+ }
953
+ }, 30_000);
954
+
955
+ it('falls back to the tracked local branch when the source fetch fails', async () => {
956
+ if (!canRunGit()) return;
957
+
958
+ const previousXdgDataHome = process.env.XDG_DATA_HOME;
959
+ const dataHome = createTempDir();
960
+ process.env.XDG_DATA_HOME = dataHome;
961
+
962
+ try {
963
+ const { repository } = createRepositoryWithRemote({ defaultBranch: 'main' });
964
+ runGit(repository, ['branch', '--set-upstream-to=origin/main', 'next']);
965
+ runGit(repository, ['remote', 'set-url', 'origin', '/nonexistent/openchamber-unreachable.git']);
966
+
967
+ const created = await createWorktree(repository, {
968
+ mode: 'new',
969
+ branchName: 'aiworker/stale-ref-wt',
970
+ worktreeName: 'stale-ref-wt',
971
+ startRef: 'remotes/origin/main',
972
+ });
973
+
974
+ expect(created.branch).toBe('aiworker/stale-ref-wt');
975
+ expect(created.sourceFetchFailed).toBe(true);
976
+ const expectedHead = runGit(repository, ['rev-parse', 'next']).trim();
977
+ expect(runGit(created.path, ['rev-parse', 'HEAD']).trim()).toBe(expectedHead);
978
+ } finally {
979
+ if (previousXdgDataHome === undefined) {
980
+ delete process.env.XDG_DATA_HOME;
981
+ } else {
982
+ process.env.XDG_DATA_HOME = previousXdgDataHome;
983
+ }
984
+ }
985
+ }, 30_000);
986
+
987
+ it('rejects creation from a remote start ref that was never fetched and cannot be fetched', async () => {
988
+ if (!canRunGit()) return;
989
+
990
+ const previousXdgDataHome = process.env.XDG_DATA_HOME;
991
+ const dataHome = createTempDir();
992
+ process.env.XDG_DATA_HOME = dataHome;
993
+
994
+ try {
995
+ const { repository } = createRepositoryWithRemote({ defaultBranch: 'main' });
996
+ runGit(repository, ['update-ref', '-d', 'refs/remotes/origin/main']);
997
+ runGit(repository, ['remote', 'set-url', 'origin', '/nonexistent/openchamber-unreachable.git']);
998
+
999
+ await expect(createWorktree(repository, {
1000
+ mode: 'new',
1001
+ branchName: 'aiworker/never-fetched-wt',
1002
+ worktreeName: 'never-fetched-wt',
1003
+ startRef: 'remotes/origin/main',
1004
+ })).rejects.toThrow(/does not appear to be a git repository|Could not read from remote repository/i);
1005
+ } finally {
1006
+ if (previousXdgDataHome === undefined) {
1007
+ delete process.env.XDG_DATA_HOME;
1008
+ } else {
1009
+ process.env.XDG_DATA_HOME = previousXdgDataHome;
1010
+ }
1011
+ }
1012
+ }, 30_000);
857
1013
  });
858
1014
 
859
1015
  // ---------------------------------------------------------------------------
@@ -1498,6 +1654,21 @@ describe.runIf(canRunGit())('getBranches', () => {
1498
1654
  });
1499
1655
  });
1500
1656
 
1657
+ describe.runIf(canRunGit())('getUnpushedBranchCounts', () => {
1658
+ it('counts only commits ahead of a locally known upstream', async () => {
1659
+ const { repository } = createRepositoryWithRemote();
1660
+ runGit(repository, ['branch', '--set-upstream-to=origin/react', 'next']);
1661
+ fs.writeFileSync(path.join(repository, 'ahead.txt'), 'ahead\n');
1662
+ runGit(repository, ['add', 'ahead.txt']);
1663
+ runGit(repository, ['commit', '-m', 'ahead']);
1664
+ runGit(repository, ['checkout', '-b', 'no-upstream']);
1665
+
1666
+ await expect(getUnpushedBranchCounts(repository, ['next', 'no-upstream', 'remotes/origin/react'])).resolves.toEqual({
1667
+ counts: { next: 1 },
1668
+ });
1669
+ });
1670
+ });
1671
+
1501
1672
  describe.runIf(canRunGit())('getRangeDiff', () => {
1502
1673
  it('resolves a base that exists only on a remote other than origin', async () => {
1503
1674
  const { repository } = createRepositoryWithRemote({ remoteName: 'upstream', defaultBranch: 'react' });
@@ -2,13 +2,13 @@ import fs from 'fs';
2
2
  import path from 'path';
3
3
  import os from 'os';
4
4
 
5
- const OPENCHAMBER_DATA_DIR = process.env.OPENCHAMBER_DATA_DIR
6
- ? path.resolve(process.env.OPENCHAMBER_DATA_DIR)
7
- : path.join(os.homedir(), '.config', 'openchamber');
5
+ const AIWORKER_DATA_DIR = process.env.AIWORKER_DATA_DIR
6
+ ? path.resolve(process.env.AIWORKER_DATA_DIR)
7
+ : path.join(os.homedir(), '.config', 'aiworker');
8
8
 
9
- const STORAGE_DIR = OPENCHAMBER_DATA_DIR;
9
+ const STORAGE_DIR = AIWORKER_DATA_DIR;
10
10
  const STORAGE_FILE = path.join(STORAGE_DIR, 'github-auth.json');
11
- const SETTINGS_FILE = path.join(OPENCHAMBER_DATA_DIR, 'settings.json');
11
+ const SETTINGS_FILE = path.join(AIWORKER_DATA_DIR, 'settings.json');
12
12
 
13
13
  const DEFAULT_GITHUB_CLIENT_ID = 'Ov23lizomPOC3eFYo56r';
14
14
  const DEFAULT_GITHUB_SCOPES = 'repo read:org workflow read:user user:email';
@@ -45,7 +45,7 @@ function readJsonFile() {
45
45
  function writeJsonFile(payload) {
46
46
  ensureStorageDir();
47
47
 
48
- // Atomic write so multiple OpenChamber instances can safely share the same file.
48
+ // Atomic write so multiple AiWorker instances can safely share the same file.
49
49
  const tmpFile = `${STORAGE_FILE}.${process.pid}.${Date.now()}.tmp`;
50
50
  fs.writeFileSync(tmpFile, JSON.stringify(payload, null, 2), 'utf8');
51
51
  try {
@@ -299,7 +299,7 @@ export function clearGitHubAuth() {
299
299
  }
300
300
 
301
301
  export function getGitHubClientId() {
302
- const raw = process.env.OPENCHAMBER_GITHUB_CLIENT_ID;
302
+ const raw = process.env.AIWORKER_GITHUB_CLIENT_ID;
303
303
  const clientId = typeof raw === 'string' ? raw.trim() : '';
304
304
  if (clientId) return clientId;
305
305
 
@@ -317,7 +317,7 @@ export function getGitHubClientId() {
317
317
  }
318
318
 
319
319
  export function getGitHubScopes() {
320
- const raw = process.env.OPENCHAMBER_GITHUB_SCOPES;
320
+ const raw = process.env.AIWORKER_GITHUB_SCOPES;
321
321
  const fromEnv = typeof raw === 'string' ? raw.trim() : '';
322
322
  if (fromEnv) return fromEnv;
323
323
 
@@ -339,7 +339,7 @@ const repoPullsCache = new Map();
339
339
  // head, and while that one is open the open-PR path wins and never reads this
340
340
  // cache at all. "No history yet" is the volatile answer, since closing or
341
341
  // merging a PR elsewhere flips it, so it expires far sooner. Either way, doing
342
- // it from OpenChamber invalidates the entry immediately.
342
+ // it from AiWorker invalidates the entry immediately.
343
343
  const HISTORICAL_PR_FOUND_TTL_MS = 6 * 60 * 60 * 1000;
344
344
  const HISTORICAL_PR_ABSENT_TTL_MS = 10 * 60 * 1000;
345
345
  const HISTORICAL_PR_CACHE_MAX_ENTRIES = 500;
@@ -281,7 +281,7 @@ export function registerGitHubRoutes(app) {
281
281
  const clientId = getGitHubClientId();
282
282
  if (!clientId) {
283
283
  return res.status(400).json({
284
- error: 'GitHub OAuth client not configured. Set OPENCHAMBER_GITHUB_CLIENT_ID.',
284
+ error: 'GitHub OAuth client not configured. Set AIWORKER_GITHUB_CLIENT_ID.',
285
285
  });
286
286
  }
287
287
 
@@ -313,7 +313,7 @@ export function registerGitHubRoutes(app) {
313
313
  const clientId = getGitHubClientId();
314
314
  if (!clientId) {
315
315
  return res.status(400).json({
316
- error: 'GitHub OAuth client not configured. Set OPENCHAMBER_GITHUB_CLIENT_ID.',
316
+ error: 'GitHub OAuth client not configured. Set AIWORKER_GITHUB_CLIENT_ID.',
317
317
  });
318
318
  }
319
319
 
@@ -6,7 +6,7 @@
6
6
  * external command it spawns, which corrupts Python venv detection and any
7
7
  * other program that reads argv[0]/$0 while leaving `/proc/self/exe` correct.
8
8
  *
9
- * See openchamber/openchamber#2588 and pingdotgg/t3code#2509.
9
+ * See aiworker/openchamber#2588 and pingdotgg/t3code#2509.
10
10
  */
11
11
 
12
12
  import { createRequire } from 'node:module';
@@ -9,7 +9,7 @@ describe('stripAppImageArgv0Leak', () => {
9
9
  it('removes ARGV0 from a child env object', () => {
10
10
  const env = {
11
11
  PATH: '/usr/bin',
12
- ARGV0: '/path/to/OpenChamber-1.17.2-linux-x86_64.AppImage',
12
+ ARGV0: '/path/to/AiWorker-1.17.2-linux-x86_64.AppImage',
13
13
  SHELL: '/bin/zsh',
14
14
  };
15
15
 
@@ -35,7 +35,7 @@ describe('stripAppImageArgv0Leak', () => {
35
35
  describe('clearAppImageArgv0FromProcessEnv', () => {
36
36
  it('removes ARGV0 from process.env', () => {
37
37
  const previous = process.env.ARGV0;
38
- process.env.ARGV0 = '/path/to/OpenChamber.AppImage';
38
+ process.env.ARGV0 = '/path/to/AiWorker.AppImage';
39
39
  try {
40
40
  clearAppImageArgv0FromProcessEnv();
41
41
  expect(process.env.ARGV0).toBeUndefined();