@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
@@ -15,7 +15,7 @@ export const registerScheduledTaskRoutes = (app, dependencies) => {
15
15
  sanitizeProjects,
16
16
  projectConfigRuntime,
17
17
  scheduledTasksRuntime,
18
- getOpenChamberEventClients,
18
+ getAiWorkerEventClients,
19
19
  writeSseEvent,
20
20
  scheduledTaskService = createScheduledTaskService(dependencies),
21
21
  } = dependencies;
@@ -149,14 +149,14 @@ export const registerScheduledTaskRoutes = (app, dependencies) => {
149
149
  // not of this server: a desktop shell and a browser tab can be connected to
150
150
  // the same server at once. Recording it on the connection keeps the answer
151
151
  // current without any enable/disable setting to go stale.
152
- res.openchamberBrowserCapable = req.query?.browser === '1';
152
+ res.aiworkerBrowserCapable = req.query?.browser === '1';
153
153
 
154
- const clients = getOpenChamberEventClients();
154
+ const clients = getAiWorkerEventClients();
155
155
  clients.add(res);
156
156
 
157
157
  try {
158
158
  writeSseEvent(res, {
159
- type: 'openchamber:event-stream-ready',
159
+ type: 'aiworker:event-stream-ready',
160
160
  properties: {
161
161
  connectedAt: Date.now(),
162
162
  },
@@ -167,7 +167,7 @@ export const registerScheduledTaskRoutes = (app, dependencies) => {
167
167
  const heartbeat = setInterval(() => {
168
168
  try {
169
169
  writeSseEvent(res, {
170
- type: 'openchamber:heartbeat',
170
+ type: 'aiworker:heartbeat',
171
171
  properties: {
172
172
  timestamp: Date.now(),
173
173
  },
@@ -1,6 +1,6 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
- import { OpenChamberControlError } from '../openchamber-control/error.js';
3
+ import { AiWorkerControlError } from '../openchamber-control/error.js';
4
4
  import { setLoopFileEnabled } from './loops.js';
5
5
 
6
6
  const asNonEmptyString = (value) => {
@@ -24,10 +24,10 @@ export const createScheduledTaskService = (dependencies) => {
24
24
 
25
25
  const findProjectByID = async (projectID) => {
26
26
  const normalized = asNonEmptyString(projectID);
27
- if (!normalized) throw new OpenChamberControlError('projectId is required', 400);
27
+ if (!normalized) throw new AiWorkerControlError('projectId is required', 400);
28
28
  const projects = await listProjects();
29
29
  const project = projects.find((entry) => entry.id === normalized) || null;
30
- if (!project) throw new OpenChamberControlError('Project not found', 404);
30
+ if (!project) throw new AiWorkerControlError('Project not found', 404);
31
31
  return project;
32
32
  };
33
33
 
@@ -35,17 +35,17 @@ export const createScheduledTaskService = (dependencies) => {
35
35
  const requestedProjectID = asNonEmptyString(projectId);
36
36
  const requestedDirectory = asNonEmptyString(directory);
37
37
  if (requestedProjectID && requestedDirectory) {
38
- throw new OpenChamberControlError('Provide only one of projectId or directory', 400);
38
+ throw new AiWorkerControlError('Provide only one of projectId or directory', 400);
39
39
  }
40
40
  if (requestedProjectID) {
41
41
  await findProjectByID(requestedProjectID);
42
42
  return requestedProjectID;
43
43
  }
44
- if (!requestedDirectory) throw new OpenChamberControlError('projectId or directory is required', 400);
44
+ if (!requestedDirectory) throw new AiWorkerControlError('projectId or directory is required', 400);
45
45
  const resolvedDirectory = path.resolve(requestedDirectory);
46
46
  const projects = await listProjects();
47
47
  const project = projects.find((entry) => path.resolve(entry.path) === resolvedDirectory);
48
- if (!project) throw new OpenChamberControlError(`Project not found for directory: ${resolvedDirectory}`, 404);
48
+ if (!project) throw new AiWorkerControlError(`Project not found for directory: ${resolvedDirectory}`, 404);
49
49
  return project.id;
50
50
  };
51
51
 
@@ -57,28 +57,28 @@ export const createScheduledTaskService = (dependencies) => {
57
57
  const findLoopTask = async (projectID, taskID) => {
58
58
  await findProjectByID(projectID);
59
59
  const normalizedTaskID = asNonEmptyString(taskID);
60
- if (!normalizedTaskID) throw new OpenChamberControlError('taskId is required', 400);
60
+ if (!normalizedTaskID) throw new AiWorkerControlError('taskId is required', 400);
61
61
  const tasks = await scheduledTasksRuntime.syncProject(projectID);
62
62
  const task = tasks.find((entry) => entry?.id === normalizedTaskID) || null;
63
- if (!task) throw new OpenChamberControlError('Task not found', 404);
64
- if (!task.loopFile) throw new OpenChamberControlError('Task is not managed by a loop file', 400);
65
- if (!fs.existsSync(task.loopFile)) throw new OpenChamberControlError('Loop file not found', 404);
63
+ if (!task) throw new AiWorkerControlError('Task not found', 404);
64
+ if (!task.loopFile) throw new AiWorkerControlError('Task is not managed by a loop file', 400);
65
+ if (!fs.existsSync(task.loopFile)) throw new AiWorkerControlError('Loop file not found', 404);
66
66
  return task;
67
67
  };
68
68
 
69
69
  const setLoopEnabled = async (projectID, taskID, enabled) => {
70
70
  if (typeof enabled !== 'boolean') {
71
- throw new OpenChamberControlError('enabled must be a boolean', 400);
71
+ throw new AiWorkerControlError('enabled must be a boolean', 400);
72
72
  }
73
73
  const task = await findLoopTask(projectID, taskID);
74
74
  try {
75
75
  if (!setLoopFileEnabled(task.loopFile, enabled)) {
76
- throw new OpenChamberControlError('Loop file must be valid before changing its enabled state', 400);
76
+ throw new AiWorkerControlError('Loop file must be valid before changing its enabled state', 400);
77
77
  }
78
78
  } catch (error) {
79
- if (error instanceof OpenChamberControlError) throw error;
79
+ if (error instanceof AiWorkerControlError) throw error;
80
80
  const message = error instanceof Error ? error.message : 'Failed to update loop file';
81
- throw new OpenChamberControlError(message, 500);
81
+ throw new AiWorkerControlError(message, 500);
82
82
  }
83
83
  const tasks = await scheduledTasksRuntime.syncProject(projectID);
84
84
  return tasks.find((entry) => entry.id === taskID) || null;
@@ -90,7 +90,7 @@ export const createScheduledTaskService = (dependencies) => {
90
90
  fs.unlinkSync(task.loopFile);
91
91
  } catch (error) {
92
92
  const message = error instanceof Error ? error.message : 'Failed to delete loop file';
93
- throw new OpenChamberControlError(message, 500);
93
+ throw new AiWorkerControlError(message, 500);
94
94
  }
95
95
  return scheduledTasksRuntime.syncProject(projectID);
96
96
  };
@@ -98,7 +98,7 @@ export const createScheduledTaskService = (dependencies) => {
98
98
  const upsert = async (projectID, taskInput) => {
99
99
  await findProjectByID(projectID);
100
100
  if (!taskInput || typeof taskInput !== 'object') {
101
- throw new OpenChamberControlError('task payload is required', 400);
101
+ throw new AiWorkerControlError('task payload is required', 400);
102
102
  }
103
103
  let upserted;
104
104
  try {
@@ -106,7 +106,7 @@ export const createScheduledTaskService = (dependencies) => {
106
106
  } catch (error) {
107
107
  const message = error instanceof Error ? error.message : 'Failed to save scheduled task';
108
108
  const invalid = message.toLowerCase().includes('required') || message.toLowerCase().includes('invalid');
109
- throw new OpenChamberControlError(message, invalid ? 400 : 500);
109
+ throw new AiWorkerControlError(message, invalid ? 400 : 500);
110
110
  }
111
111
  await scheduledTasksRuntime.syncProject(projectID);
112
112
  const tasks = await projectConfigRuntime.listScheduledTasks(projectID);
@@ -120,7 +120,7 @@ export const createScheduledTaskService = (dependencies) => {
120
120
  const remove = async (projectID, taskID) => {
121
121
  await findProjectByID(projectID);
122
122
  const normalizedTaskID = asNonEmptyString(taskID);
123
- if (!normalizedTaskID) throw new OpenChamberControlError('taskId is required', 400);
123
+ if (!normalizedTaskID) throw new AiWorkerControlError('taskId is required', 400);
124
124
  const current = await projectConfigRuntime.listScheduledTasks(projectID);
125
125
  const existing = current.find((task) => task.id === normalizedTaskID) || null;
126
126
  if (existing?.loopFile && fs.existsSync(existing.loopFile)) {
@@ -129,13 +129,13 @@ export const createScheduledTaskService = (dependencies) => {
129
129
  // file exists. The file itself is the removal surface. Once the file is
130
130
  // gone (the task is an orphan that the next sync would remove anyway),
131
131
  // deleting the row is safe and allowed.
132
- throw new OpenChamberControlError(
132
+ throw new AiWorkerControlError(
133
133
  'Loop task is managed by its .agents/loops markdown file; delete the file to remove the task',
134
134
  400,
135
135
  );
136
136
  }
137
137
  const result = await projectConfigRuntime.deleteScheduledTask(projectID, normalizedTaskID);
138
- if (!result.deleted) throw new OpenChamberControlError('Task not found', 404);
138
+ if (!result.deleted) throw new AiWorkerControlError('Task not found', 404);
139
139
  await scheduledTasksRuntime.syncProject(projectID);
140
140
  return projectConfigRuntime.listScheduledTasks(projectID);
141
141
  };
@@ -143,14 +143,14 @@ export const createScheduledTaskService = (dependencies) => {
143
143
  const run = async (projectID, taskID) => {
144
144
  await findProjectByID(projectID);
145
145
  const normalizedTaskID = asNonEmptyString(taskID);
146
- if (!normalizedTaskID) throw new OpenChamberControlError('taskId is required', 400);
146
+ if (!normalizedTaskID) throw new AiWorkerControlError('taskId is required', 400);
147
147
  const result = await scheduledTasksRuntime.runNow(projectID, normalizedTaskID);
148
148
  if (result.running || result.queued) {
149
- throw new OpenChamberControlError(result.error || 'Task already running', 409);
149
+ throw new AiWorkerControlError(result.error || 'Task already running', 409);
150
150
  }
151
- if (result.skipped) throw new OpenChamberControlError('Task not found or disabled', 404);
151
+ if (result.skipped) throw new AiWorkerControlError('Task not found or disabled', 404);
152
152
  if (!result.ok) {
153
- throw new OpenChamberControlError(result.error || 'Task run failed', 500, { task: result.task });
153
+ throw new AiWorkerControlError(result.error || 'Task run failed', 500, { task: result.task });
154
154
  }
155
155
  return {
156
156
  task: result.task,
@@ -164,7 +164,7 @@ export const createScheduledTaskService = (dependencies) => {
164
164
  const setEnabled = async (projectID, taskID, enabled) => {
165
165
  const tasks = await list(projectID);
166
166
  const task = tasks.find((entry) => entry?.id === taskID);
167
- if (!task) throw new OpenChamberControlError('Task not found', 404);
167
+ if (!task) throw new AiWorkerControlError('Task not found', 404);
168
168
  const result = await upsert(projectID, { ...task, enabled });
169
169
  return result.task;
170
170
  };
@@ -166,7 +166,7 @@ describe('scheduled-task loop-file routes', () => {
166
166
  sanitizeProjects: vi.fn(),
167
167
  projectConfigRuntime: {},
168
168
  scheduledTasksRuntime: {},
169
- getOpenChamberEventClients: () => new Set(),
169
+ getAiWorkerEventClients: () => new Set(),
170
170
  writeSseEvent: vi.fn(),
171
171
  });
172
172
  return handlers;
@@ -32,9 +32,9 @@ export const isLoopbackBindHost = (host) => {
32
32
  export const isNetworkExposedBindHost = (host) => !isLoopbackBindHost(host);
33
33
 
34
34
  export const isUnsafeUnauthenticatedLanAllowed = (env = process.env) =>
35
- env?.OPENCHAMBER_ALLOW_UNAUTHENTICATED_LAN === 'true';
35
+ env?.AIWORKER_ALLOW_UNAUTHENTICATED_LAN === 'true';
36
36
 
37
37
  export const getUnauthenticatedLanErrorMessage = (host) =>
38
- `OpenChamber refuses to bind to ${host || 'a network-exposed host'} without UI authentication. `
39
- + 'Set --ui-password or OPENCHAMBER_UI_PASSWORD before exposing it over LAN, '
40
- + 'or set OPENCHAMBER_ALLOW_UNAUTHENTICATED_LAN=true to accept the risk.';
38
+ `AiWorker refuses to bind to ${host || 'a network-exposed host'} without UI authentication. `
39
+ + 'Set --ui-password or AIWORKER_UI_PASSWORD before exposing it over LAN, '
40
+ + 'or set AIWORKER_ALLOW_UNAUTHENTICATED_LAN=true to accept the risk.';
@@ -25,7 +25,7 @@ describe('bind host exposure classification', () => {
25
25
  '::ffff:192.168.1.10',
26
26
  'fe80::1',
27
27
  'fc00::1',
28
- 'openchamber.local',
28
+ 'aiworker.local',
29
29
  'example.com',
30
30
  '',
31
31
  ]) {
@@ -103,7 +103,7 @@ export const createRequestSecurityRuntime = (deps) => {
103
103
  return { origins, hosts };
104
104
  };
105
105
 
106
- const isRequestOriginAllowed = async (req) => {
106
+ const isRequestOriginAllowed = (req) => {
107
107
  const originHeader = typeof req.headers.origin === 'string' ? req.headers.origin.trim() : '';
108
108
  if (!originHeader) {
109
109
  return false;
@@ -120,15 +120,21 @@ export const createRequestSecurityRuntime = (deps) => {
120
120
  return false;
121
121
  }
122
122
 
123
- const candidates = await getRequestOriginCandidates(req);
124
- if (candidates.origins.has(origin.origin)) return true;
123
+ const forwardedHostHeader = req.headers['x-forwarded-host'];
124
+ const forwardedHost = (Array.isArray(forwardedHostHeader) ? forwardedHostHeader[0] : forwardedHostHeader || '')
125
+ .split(',')[0].trim().toLowerCase();
126
+ const hostHeader = req.headers.host;
127
+ const host = forwardedHost || (Array.isArray(hostHeader) ? hostHeader[0] : hostHeader || '').trim().toLowerCase();
128
+ if (host && host === origin.host.toLowerCase()) return true;
125
129
 
126
- // TLS commonly ends at a cloud edge before an HTTP hop to OpenChamber.
130
+ // TLS commonly ends at a cloud edge before an HTTP hop to AiWorker.
127
131
  // In that setup the browser's Origin is https while a generic reverse
128
132
  // proxy reports the upstream request as http. The external host remains
129
133
  // authoritative, so compare it directly instead of requiring the proxy to
130
134
  // preserve the browser-facing protocol.
131
- return candidates.hosts.has(origin.host.toLowerCase());
135
+ return getRequestOriginCandidates(req).then((candidates) => (
136
+ candidates.origins.has(origin.origin) || candidates.hosts.has(origin.host.toLowerCase())
137
+ ));
132
138
  };
133
139
 
134
140
  return {
@@ -9,55 +9,55 @@ describe('request security runtime', () => {
9
9
  test('allows packaged client origins for remote client transports', async () => {
10
10
  const runtime = createRuntime();
11
11
 
12
- await expect(runtime.isRequestOriginAllowed({
12
+ expect(await runtime.isRequestOriginAllowed({
13
13
  headers: {
14
14
  origin: 'openchamber-ui://app',
15
15
  host: '192.168.1.130:1202',
16
16
  },
17
17
  socket: {},
18
- })).resolves.toBe(true);
18
+ })).toBe(true);
19
19
 
20
- await expect(runtime.isRequestOriginAllowed({
20
+ expect(await runtime.isRequestOriginAllowed({
21
21
  headers: {
22
22
  origin: 'capacitor://localhost',
23
23
  host: '192.168.1.130:1202',
24
24
  },
25
25
  socket: {},
26
- })).resolves.toBe(true);
26
+ })).toBe(true);
27
27
 
28
28
  // Android Capacitor WebView (androidScheme 'https') reports this origin.
29
- await expect(runtime.isRequestOriginAllowed({
29
+ expect(await runtime.isRequestOriginAllowed({
30
30
  headers: {
31
31
  origin: 'https://localhost',
32
32
  host: '192.168.1.130:1202',
33
33
  },
34
34
  socket: {},
35
- })).resolves.toBe(true);
35
+ })).toBe(true);
36
36
  });
37
37
 
38
38
  test('rejects unknown origins', async () => {
39
39
  const runtime = createRuntime();
40
40
 
41
- await expect(runtime.isRequestOriginAllowed({
41
+ expect(await runtime.isRequestOriginAllowed({
42
42
  headers: {
43
43
  origin: 'https://evil.example.com',
44
44
  host: '192.168.1.130:1202',
45
45
  },
46
46
  socket: {},
47
- })).resolves.toBe(false);
47
+ })).toBe(false);
48
48
  });
49
49
 
50
50
  test('allows the external host when TLS terminates before an HTTP proxy hop', async () => {
51
51
  const runtime = createRuntime();
52
52
 
53
- await expect(runtime.isRequestOriginAllowed({
53
+ expect(await runtime.isRequestOriginAllowed({
54
54
  headers: {
55
55
  origin: 'https://devchamber.example.com',
56
56
  host: 'devchamber.example.com',
57
57
  'x-forwarded-proto': 'http',
58
58
  },
59
59
  socket: {},
60
- })).resolves.toBe(true);
60
+ })).toBe(true);
61
61
  });
62
62
 
63
63
  test('uses the forwarded external host without trusting a different origin', async () => {
@@ -71,13 +71,13 @@ describe('request security runtime', () => {
71
71
  socket: {},
72
72
  };
73
73
 
74
- await expect(runtime.isRequestOriginAllowed({
74
+ expect(await runtime.isRequestOriginAllowed({
75
75
  ...request,
76
76
  headers: { ...request.headers, origin: 'https://devchamber.example.com' },
77
- })).resolves.toBe(true);
78
- await expect(runtime.isRequestOriginAllowed({
77
+ })).toBe(true);
78
+ expect(await runtime.isRequestOriginAllowed({
79
79
  ...request,
80
80
  headers: { ...request.headers, origin: 'https://evil.example.com' },
81
- })).resolves.toBe(false);
81
+ })).toBe(false);
82
82
  });
83
83
  });
@@ -1,7 +1,7 @@
1
1
  // Session assist: after a session goes idle and stays quiet, generate a short
2
2
  // recap of the agent's last reply plus one suggested user follow-up with the
3
3
  // small model, and store both on the session's metadata
4
- // (metadata.openchamber.assist). Clients decide visibility from
4
+ // (metadata.aiworker.assist). Clients decide visibility from
5
5
  // assist.forMessageID — a new message makes the payload stale everywhere
6
6
  // without any extra writes.
7
7
  //
@@ -12,10 +12,10 @@ import fs from 'fs';
12
12
  import os from 'os';
13
13
  import path from 'path';
14
14
 
15
- const OPENCHAMBER_SETTINGS_FILE = path.join(
16
- process.env.OPENCHAMBER_DATA_DIR
17
- ? path.resolve(process.env.OPENCHAMBER_DATA_DIR)
18
- : path.join(os.homedir(), '.config', 'openchamber'),
15
+ const AIWORKER_SETTINGS_FILE = path.join(
16
+ process.env.AIWORKER_DATA_DIR
17
+ ? path.resolve(process.env.AIWORKER_DATA_DIR)
18
+ : path.join(os.homedir(), '.config', 'aiworker'),
19
19
  'settings.json',
20
20
  );
21
21
 
@@ -24,7 +24,7 @@ const OPENCHAMBER_SETTINGS_FILE = path.join(
24
24
  // payloads stay untouched — clients keep showing them and dismissal still works.
25
25
  const getSessionAssistTargets = () => {
26
26
  try {
27
- const raw = fs.readFileSync(OPENCHAMBER_SETTINGS_FILE, 'utf8');
27
+ const raw = fs.readFileSync(AIWORKER_SETTINGS_FILE, 'utf8');
28
28
  const settings = JSON.parse(raw);
29
29
  return {
30
30
  recap: settings?.sessionRecapEnabled !== false,
@@ -257,6 +257,7 @@ export const createSessionAssistRuntime = ({
257
257
  prompt: `The latest exchange in the conversation:\n\n${transcript}\n\nWrite ${requestedFields} in the SAME language as this sample from the conversation: "${languageSample}"`,
258
258
  system: buildAssistSystemPrompt(targets),
259
259
  directory,
260
+ sessionID: sessionId,
260
261
  preferredProviderID: typeof lastAssistantInfo.providerID === 'string' ? lastAssistantInfo.providerID : undefined,
261
262
  preferredModelID: typeof lastAssistantInfo.modelID === 'string' ? lastAssistantInfo.modelID : undefined,
262
263
  });
@@ -316,8 +317,8 @@ export const createSessionAssistRuntime = ({
316
317
  const currentMetadata = freshSession?.metadata && typeof freshSession.metadata === 'object'
317
318
  ? freshSession.metadata
318
319
  : (session.metadata && typeof session.metadata === 'object' ? session.metadata : {});
319
- const currentNamespace = currentMetadata.openchamber && typeof currentMetadata.openchamber === 'object'
320
- ? currentMetadata.openchamber
320
+ const currentNamespace = currentMetadata.aiworker && typeof currentMetadata.aiworker === 'object'
321
+ ? currentMetadata.aiworker
321
322
  : {};
322
323
 
323
324
  console.log(`[session-assist] generated for ${sessionId} via ${generated.providerID}/${generated.modelID}`);
@@ -327,7 +328,7 @@ export const createSessionAssistRuntime = ({
327
328
  body: {
328
329
  metadata: {
329
330
  ...currentMetadata,
330
- openchamber: {
331
+ aiworker: {
331
332
  ...currentNamespace,
332
333
  assist: {
333
334
  recap,
@@ -32,10 +32,10 @@ export const registerSessionFoldersRoutes = (app, dependencies) => {
32
32
  const {
33
33
  fsPromises,
34
34
  path,
35
- openchamberDataDir,
35
+ aiworkerDataDir,
36
36
  } = dependencies;
37
37
 
38
- const filePath = path.join(openchamberDataDir, 'sessions-directories.json');
38
+ const filePath = path.join(aiworkerDataDir, 'sessions-directories.json');
39
39
  let saveQueue = Promise.resolve();
40
40
 
41
41
  const ensureDir = async () => {
@@ -73,7 +73,7 @@ describe('session folders routes', () => {
73
73
  registerSessionFoldersRoutes(app, {
74
74
  fsPromises,
75
75
  path,
76
- openchamberDataDir: '/tmp/openchamber-test',
76
+ aiworkerDataDir: '/tmp/openchamber-test',
77
77
  });
78
78
 
79
79
  const handler = getRoute('POST', '/api/session-folders');
@@ -103,7 +103,7 @@ describe('session folders routes', () => {
103
103
  registerSessionFoldersRoutes(app, {
104
104
  fsPromises,
105
105
  path,
106
- openchamberDataDir: '/tmp/openchamber-test',
106
+ aiworkerDataDir: '/tmp/openchamber-test',
107
107
  });
108
108
 
109
109
  const handler = getRoute('POST', '/api/session-folders');
@@ -121,7 +121,7 @@ describe('session folders routes', () => {
121
121
  registerSessionFoldersRoutes(app, {
122
122
  fsPromises,
123
123
  path,
124
- openchamberDataDir: '/tmp/openchamber-test',
124
+ aiworkerDataDir: '/tmp/openchamber-test',
125
125
  });
126
126
 
127
127
  const response = createMockResponse();
@@ -137,7 +137,7 @@ describe('session folders routes', () => {
137
137
  registerSessionFoldersRoutes(app, {
138
138
  fsPromises,
139
139
  path,
140
- openchamberDataDir: '/tmp/openchamber-test',
140
+ aiworkerDataDir: '/tmp/openchamber-test',
141
141
  });
142
142
 
143
143
  const response = createMockResponse();
@@ -156,7 +156,7 @@ describe('session folders routes', () => {
156
156
  registerSessionFoldersRoutes(app, {
157
157
  fsPromises,
158
158
  path,
159
- openchamberDataDir: '/tmp/openchamber-test',
159
+ aiworkerDataDir: '/tmp/openchamber-test',
160
160
  });
161
161
 
162
162
  const response = createMockResponse();
@@ -181,7 +181,7 @@ describe('session folders routes', () => {
181
181
  registerSessionFoldersRoutes(app, {
182
182
  fsPromises,
183
183
  path,
184
- openchamberDataDir: '/tmp/openchamber-test',
184
+ aiworkerDataDir: '/tmp/openchamber-test',
185
185
  });
186
186
 
187
187
  const response = createMockResponse();
@@ -204,7 +204,7 @@ describe('session folders routes', () => {
204
204
  registerSessionFoldersRoutes(app, {
205
205
  fsPromises,
206
206
  path,
207
- openchamberDataDir: '/tmp/openchamber-test',
207
+ aiworkerDataDir: '/tmp/openchamber-test',
208
208
  });
209
209
 
210
210
  const response = createMockResponse();
@@ -227,7 +227,7 @@ describe('session folders routes', () => {
227
227
  registerSessionFoldersRoutes(app, {
228
228
  fsPromises,
229
229
  path,
230
- openchamberDataDir: '/tmp/openchamber-test',
230
+ aiworkerDataDir: '/tmp/openchamber-test',
231
231
  });
232
232
 
233
233
  const response = createMockResponse();
@@ -108,13 +108,26 @@ before touching the filesystem). Rationale: metadata rides every
108
108
  stop), with a tick-side safety net. Messages sent while paused leave
109
109
  the goal alone; Resume re-arms the loop, and resuming over an aborted
110
110
  tail skips the audit and goes straight to a continuation nudge;
111
- - terminal checks, cheapest first: assistant turn error → `blocked`;
112
- `tokensUsed >= tokenBudget` → `budgetLimited`;
113
- `turnsUsed >= MAX_AUTO_TURNS` (20) → `blocked`;
114
- - if the latest message is a compaction summary, skip the audit and
115
- continue unconditionally running into the context window mid-work is
116
- by definition "in progress, not finished" (the summary is a retelling,
117
- not evidence, and must not be judged);
111
+ - terminal checks, cheapest first: assistant turn error → `blocked`;
112
+ `tokensUsed >= tokenBudget` → `budgetLimited`;
113
+ `turnsUsed >= MAX_AUTO_TURNS` (20) → `blocked`;
114
+ - error classification is independent of `finish`: `MessageAbortedError`
115
+ keeps the pause/resume behavior; only a `finish: "length"` with no
116
+ error, or `MessageOutputLengthError`, is an in-progress truncation that
117
+ skips the audit and continues. Any other non-null error wins over a
118
+ length finish and blocks with its non-empty `error.name`, or
119
+ `assistant turn failed` when unnamed;
120
+ - length recovery is bounded separately from the token budget and
121
+ auto-continuation cap: the first truncation permits one continuation, but
122
+ a second consecutive completed, non-summary assistant turn that is also
123
+ truncated settles the goal as `blocked` (`repeated output truncation`).
124
+ The consecutive state is derived from the loaded message history, not
125
+ persisted, using `info.time.created` chronology rather than message IDs.
126
+ Summary messages are not agent turns; an ordinary completed assistant
127
+ turn naturally breaks the consecutive condition. Explicit Resume grants
128
+ one new recovery attempt over the same transcript; the continuation
129
+ consumes that permission, so another truncation blocks again. Resume
130
+ does not bypass assistant errors or the token budget;
118
131
  - otherwise, small-model audit of the objective + the last assistant turn
119
132
  only — no conversation history and no continuation prompts
120
133
  (`restrictToPreferredProvider`, session's own provider/model preferred):
@@ -14,7 +14,7 @@ export const buildGoalIntroText = (tokenBudget) => {
14
14
  + '\n</system-reminder>';
15
15
  };
16
16
 
17
- const fitObjective = async ({ objective, directory, providerID, modelID, warn }) => {
17
+ const fitObjective = async ({ objective, directory, sessionID, providerID, modelID, warn }) => {
18
18
  if (objective.length <= GOAL_OBJECTIVE_CHAR_LIMIT) return objective;
19
19
 
20
20
  let distilled = null;
@@ -32,6 +32,7 @@ const fitObjective = async ({ objective, directory, providerID, modelID, warn })
32
32
  'Write in the same language as the task text.',
33
33
  ].join('\n'),
34
34
  directory,
35
+ sessionID,
35
36
  preferredProviderID: providerID,
36
37
  preferredModelID: modelID,
37
38
  });
@@ -66,6 +67,7 @@ export const createSessionGoal = async ({
66
67
  const objectiveText = await fitObjective({
67
68
  objective: String(objective ?? '').trim(),
68
69
  directory,
70
+ sessionID,
69
71
  providerID,
70
72
  modelID,
71
73
  warn,
@@ -105,7 +107,7 @@ export const createSessionGoal = async ({
105
107
  'content-type': 'application/json',
106
108
  accept: 'application/json',
107
109
  },
108
- body: JSON.stringify({ metadata: { openchamber: { goal } } }),
110
+ body: JSON.stringify({ metadata: { aiworker: { goal } } }),
109
111
  });
110
112
  if (!response.ok) throw new Error(`goal metadata patch failed (${response.status})`);
111
113
  return goal;
@@ -64,7 +64,7 @@ describe('session goal creation', () => {
64
64
  });
65
65
 
66
66
  const payload = JSON.parse(fetchMock.mock.calls[0][1].body);
67
- expect(payload.metadata.openchamber.goal).toMatchObject({
67
+ expect(payload.metadata.aiworker.goal).toMatchObject({
68
68
  objective: 'Finish the migration',
69
69
  objectiveFile: false,
70
70
  });
@@ -1,6 +1,6 @@
1
1
  // File-backed goal objectives. Session metadata must stay light (it rides
2
2
  // every session.updated event), so the objective TEXT lives in a file under
3
- // the OpenChamber data dir, keyed by the SESSION ID: sessions are globally
3
+ // the AiWorker data dir, keyed by the SESSION ID: sessions are globally
4
4
  // unique and carry at most one goal at a time, so the mapping is fully
5
5
  // deterministic — the metadata only carries an `objectiveFile: true` flag,
6
6
  // never a path, and user-writable metadata cannot become a file-read vector.
@@ -16,9 +16,9 @@ export const GOAL_OBJECTIVE_CHAR_LIMIT = 5_000;
16
16
  const SESSION_ID_PATTERN = /^[A-Za-z0-9_-]{4,128}$/;
17
17
 
18
18
  const goalsDir = () => path.join(
19
- process.env.OPENCHAMBER_DATA_DIR
20
- ? path.resolve(process.env.OPENCHAMBER_DATA_DIR)
21
- : path.join(os.homedir(), '.config', 'openchamber'),
19
+ process.env.AIWORKER_DATA_DIR
20
+ ? path.resolve(process.env.AIWORKER_DATA_DIR)
21
+ : path.join(os.homedir(), '.config', 'aiworker'),
22
22
  'goals',
23
23
  );
24
24
 
@@ -1,6 +1,6 @@
1
1
  import { deleteObjective, readObjective, writeObjective } from './objectives.js';
2
2
 
3
- // OpenChamber-owned routes for file-backed goal objectives, keyed by session
3
+ // AiWorker-owned routes for file-backed goal objectives, keyed by session
4
4
  // id (one goal per session; a new goal overwrites the old file). The UI
5
5
  // writes the objective file before stamping the goal metadata (which only
6
6
  // carries an `objectiveFile: true` flag), reads it back for display, and