@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.
- package/README.md +4 -4
- package/bin/cli.js +7 -4
- package/bin/cli.test.js +165 -73
- package/bin/lib/cli-api-target.js +2 -2
- package/bin/lib/cli-args.js +119 -119
- package/bin/lib/cli-lifecycle.js +9 -9
- package/bin/lib/cli-network.js +3 -3
- package/bin/lib/cli-paths.js +3 -3
- package/bin/lib/cli-ports.js +2 -2
- package/bin/lib/cli-process.js +4 -4
- package/bin/lib/cli-startup.js +64 -15
- package/bin/lib/cli-tunnel-profiles.js +1 -1
- package/bin/lib/cli-tunnel-utils.js +2 -2
- package/bin/lib/commands-connect-url.js +19 -19
- package/bin/lib/commands-lifecycle.js +27 -27
- package/bin/lib/commands-logs.js +5 -5
- package/bin/lib/commands-models.js +1 -1
- package/bin/lib/commands-projects.js +1 -1
- package/bin/lib/commands-schedule.js +1 -1
- package/bin/lib/commands-serve.js +29 -29
- package/bin/lib/commands-session.js +1 -1
- package/bin/lib/commands-startup.js +45 -10
- package/bin/lib/commands-status.js +1 -1
- package/bin/lib/commands-tunnel.js +40 -40
- package/bin/lib/commands-update.js +1 -1
- package/bin/lib/commands-update.test.js +6 -6
- package/dist/assets/{CodeMirrorCommentWidgets-B3u7UIcE.js → CodeMirrorCommentWidgets-CSICpWQD.js} +1 -1
- package/dist/assets/{DiffView-DluiRSla.js → DiffView-hDBKesA_.js} +3 -3
- package/dist/assets/DirtyBranchSwitchDialog-C22HdWj4.js +1 -0
- package/dist/assets/FilesView-CdWzeOp9.js +17 -0
- package/dist/assets/GitView-VQQkYuUw.js +6 -0
- package/dist/assets/{JsonTreeView-B0BdZEHG.js → JsonTreeView-6lrhwD3q.js} +1 -1
- package/dist/assets/LinearIssuesView-Ba6Q9569.js +1 -0
- package/dist/assets/{MarkdownImageGallery-ClOvuZxC.js → MarkdownImageGallery-Czv_mhvS.js} +1 -1
- package/dist/assets/MarkdownRendererImpl-BrMcswiy.js +12 -0
- package/dist/assets/{OnboardingScreen-D2DG7K6b.js → OnboardingScreen-ChxQoAkx.js} +1 -1
- package/dist/assets/{PatchDiff-DvfqDql7.js → PatchDiff-BzcZPlOq.js} +1 -1
- package/dist/assets/{PierreDiffViewer-B7m3f0d7.js → PierreDiffViewer-BchBtZlp.js} +2 -2
- package/dist/assets/PlanView-DyDt_nZ_.js +5 -0
- package/dist/assets/SettingsView-BKf5xBsP.js +28 -0
- package/dist/assets/{SettingsWindow-i45U1Cy1.js → SettingsWindow-DDQYaKWQ.js} +1 -1
- package/dist/assets/{ToolOutputDialog-BTwyh5OF.js → ToolOutputDialog-iYF8Y2bz.js} +6 -6
- package/dist/assets/ToolPartDiffPreview-CdjbOVMM.js +8 -0
- package/dist/assets/{VirtualizedFileDiff-DD8lDVej.js → VirtualizedFileDiff-fFFm2QgH.js} +1 -1
- package/dist/assets/{WalkthroughView-egQgxel3.js → WalkthroughView-DOeCsMju.js} +2 -2
- package/dist/assets/{computeVirtualFileMetrics-BMIRgMHv.js → computeVirtualFileMetrics-CzgLum_K.js} +2 -2
- package/dist/assets/{contextPanelEmbeddedChat-C3fjDbdg.js → contextPanelEmbeddedChat-C0ZLAepL.js} +1 -1
- package/dist/assets/{de-C1P6X5Rs.js → de-B5JaA3SA.js} +6 -5
- package/dist/assets/{es-CDgaF1_t.js → es-EPIH88ii.js} +6 -5
- package/dist/assets/{fr-Bgxqvvz_.js → fr-CAMfxUdZ.js} +6 -5
- package/dist/assets/{index-CODwDsU_.js → index-Bl3LSbjn.js} +1 -1
- package/dist/assets/index-DF5kMP-i.js +39 -0
- package/dist/assets/index-Dl3xbAB_.css +1 -0
- package/dist/assets/{isDiffPlainText-BqayB8d3.js → isDiffPlainText-Dx-dB_8l.js} +1 -1
- package/dist/assets/{isFilePlainText-QfoiKJNY.js → isFilePlainText-CWFPwmnU.js} +1 -1
- package/dist/assets/{ja-BDRrEcNP.js → ja-CifOE1VN.js} +7 -6
- package/dist/assets/{ko-Ba8sQV79.js → ko-BBDyAyYQ.js} +7 -6
- package/dist/assets/{main-C5DVOxc6.js → main-DnBAoktx.js} +2 -2
- package/dist/assets/main-MhSaOZoB.js +930 -0
- package/dist/assets/{markdownCore-CZwzz5gw.js → markdownCore-BrBwOOMn.js} +2 -2
- package/dist/assets/{miniChat-DUJ4irZc.js → miniChat-BKyvLseN.js} +2 -2
- package/dist/assets/{mobile-CcaxB0n4.js → mobile-DKjeFgMN.js} +2 -2
- package/dist/assets/{patchFileDiff-yNfWXN4E.js → patchFileDiff-o8ms1me8.js} +1 -1
- package/dist/assets/pl-DgEHYfFM.js +16 -0
- package/dist/assets/{pt-BR-DIs6ElwV.js → pt-BR-DuWHojUw.js} +6 -5
- package/dist/assets/{renderElectronMiniChatApp-BcKLHXKe.js → renderElectronMiniChatApp-CDgBwwCS.js} +2 -2
- package/dist/assets/renderMobileApp-DJIKIK1r.js +25 -0
- package/dist/assets/runtimeEndpointReset-CYJ9O_xX.js +17 -0
- package/dist/assets/{scheduledTasksApi-DLW0mkQK.js → scheduledTasksApi-D8yamh1b.js} +1 -1
- package/dist/assets/{shikiHighlight-DYOWuY65.js → shikiHighlight-TEQCmzW8.js} +1 -1
- package/dist/assets/tr-D5m2yIWL.js +7 -0
- package/dist/assets/{uk-ZrCNjM7Y.js → uk-D_q60oog.js} +6 -5
- package/dist/assets/{useAppFontEffects-CjrntdL0.js → useAppFontEffects-D7sNpuL2.js} +161 -190
- package/dist/assets/useInlineCommentController-Brz_cLcQ.js +2 -0
- package/dist/assets/{useRootScrollLock-BHYPkrLv.js → useRootScrollLock-lXEnWlaU.js} +1 -1
- package/dist/assets/{vendor-codemirror-language-data-DFZik9R2.js → vendor-codemirror-language-data-Dp3KMRQG.js} +2 -2
- package/dist/assets/vendor-zod-CK21ihK-.js +39 -0
- package/dist/assets/{web-components-Bhg83tjf.js → web-components-_mNEMjFY.js} +1 -1
- package/dist/assets/{zh-CN-iv_AV4EC.js → zh-CN-D8QvsVeg.js} +6 -5
- package/dist/assets/{zh-TW-CzEUk38j.js → zh-TW-B9t7rQQO.js} +6 -5
- package/dist/index.html +22 -22
- package/dist/mini-chat.html +7 -7
- package/dist/mobile.html +5 -5
- package/package.json +3 -3
- package/server/index.js +118 -85
- package/server/lib/agent-memory/actions.js +2 -2
- package/server/lib/agent-memory/feature-flag.js +1 -1
- package/server/lib/agent-memory/feature-flag.test.js +8 -8
- package/server/lib/agent-memory/routes.js +2 -2
- package/server/lib/agent-tool/runtime.js +37 -54
- package/server/lib/agent-tool/runtime.test.js +59 -59
- package/server/lib/browser-control/broker.js +3 -3
- package/server/lib/browser-control/broker.test.js +1 -1
- package/server/lib/changelog/update-notes.js +82 -0
- package/server/lib/changelog/update-notes.test.js +59 -0
- package/server/lib/client-auth/remote-clients.test.js +5 -5
- package/server/lib/context-obligatory/runtime.js +7 -7
- package/server/lib/context-obligatory/runtime.test.js +5 -5
- package/server/lib/dev-servers/parse.js +2 -2
- package/server/lib/dev-servers/parse.test.js +2 -2
- package/server/lib/dev-servers/routes.js +1 -1
- package/server/lib/dev-tunnel/DOCUMENTATION.md +13 -4
- package/server/lib/dev-tunnel/client.js +1 -1
- package/server/lib/dev-tunnel/runtime.js +5 -5
- package/server/lib/dev-tunnel/tunnel.test.js +21 -1
- package/server/lib/dictation/local/model-catalog.js +1 -1
- package/server/lib/dictation/local/worker-process.js +2 -2
- package/server/lib/event-stream/directory-ws-bridge.js +1 -1
- package/server/lib/event-stream/global-ws-bridge.js +1 -1
- package/server/lib/event-stream/protocol.test.js +4 -4
- package/server/lib/event-stream/runtime.test.js +6 -6
- package/server/lib/fs/DOCUMENTATION.md +2 -0
- package/server/lib/fs/routes.js +37 -26
- package/server/lib/fs/routes.test.js +98 -21
- package/server/lib/git/DOCUMENTATION.md +3 -1
- package/server/lib/git/identity-storage.js +1 -1
- package/server/lib/git/issue-2746-longpaths.test.js +4 -4
- package/server/lib/git/routes.js +17 -1
- package/server/lib/git/service.js +116 -26
- package/server/lib/git/service.test.js +174 -3
- package/server/lib/github/auth.js +8 -8
- package/server/lib/github/pr-status.js +1 -1
- package/server/lib/github/routes.js +2 -2
- package/server/lib/inherited-env.js +1 -1
- package/server/lib/inherited-env.test.js +2 -2
- package/server/lib/linear/auth.js +8 -8
- package/server/lib/linear/auth.test.js +24 -24
- package/server/lib/linear/issues.test.js +6 -6
- package/server/lib/linear/mapping.test.js +4 -4
- package/server/lib/linear/oauth.js +2 -2
- package/server/lib/linear/oauth.test.js +14 -14
- package/server/lib/linear/routes.js +5 -5
- package/server/lib/linear/routes.test.js +16 -16
- package/server/lib/linear/status-runtime.test.js +9 -9
- package/server/lib/linear/status.js +1 -1
- package/server/lib/linear/status.test.js +15 -15
- package/server/lib/linear/teams.test.js +4 -4
- package/server/lib/magic-prompts/routes.js +2 -2
- package/server/lib/mcp-reconnect/DOCUMENTATION.md +55 -0
- package/server/lib/mcp-reconnect/runtime.js +122 -0
- package/server/lib/mcp-reconnect/runtime.test.js +140 -0
- package/server/lib/message-queue/DOCUMENTATION.md +158 -0
- package/server/lib/message-queue/runtime.js +870 -0
- package/server/lib/message-queue/runtime.test.js +482 -0
- package/server/lib/notifications/apns-runtime.js +17 -17
- package/server/lib/notifications/apns-runtime.test.js +11 -11
- package/server/lib/notifications/emitter-runtime.js +1 -1
- package/server/lib/notifications/emitter-runtime.test.js +1 -1
- package/server/lib/notifications/push-runtime.js +7 -7
- package/server/lib/notifications/routes.js +1 -1
- package/server/lib/notifications/runtime.js +1 -1
- package/server/lib/openchamber-control/action-resolution.test.js +10 -10
- package/server/lib/openchamber-control/actions.js +24 -24
- package/server/lib/openchamber-control/error.js +4 -4
- package/server/lib/openchamber-control/routes.js +2 -2
- package/server/lib/openchamber-control/routes.test.js +5 -5
- package/server/lib/openchamber-control/screenshots.js +1 -1
- package/server/lib/openchamber-control/screenshots.test.js +1 -1
- package/server/lib/openchamber-control/service.js +50 -50
- package/server/lib/openchamber-control/service.test.js +5 -5
- package/server/lib/openchamber-sessions/routes.js +124 -22
- package/server/lib/openchamber-sessions/routes.test.js +99 -11
- package/server/lib/opencode/DOCUMENTATION.md +13 -5
- package/server/lib/opencode/auth.js +1 -1
- package/server/lib/opencode/bootstrap-runtime.js +6 -6
- package/server/lib/opencode/cli-options.js +8 -8
- package/server/lib/opencode/config-paths.test.js +116 -0
- package/server/lib/opencode/core-routes.js +8 -7
- package/server/lib/opencode/core-routes.test.js +11 -11
- package/server/lib/opencode/env-config.js +5 -5
- package/server/lib/opencode/env-config.test.js +7 -7
- package/server/lib/opencode/env-runtime.js +10 -10
- package/server/lib/opencode/env-runtime.test.js +18 -18
- package/server/lib/opencode/feature-routes-runtime.js +17 -12
- package/server/lib/opencode/hmr-state-runtime.js +2 -2
- package/server/lib/opencode/hmr-state-runtime.test.js +1 -1
- package/server/lib/opencode/input-history-scope.js +14 -0
- package/server/lib/opencode/lifecycle.js +8 -8
- package/server/lib/opencode/lifecycle.test.js +4 -4
- package/server/lib/opencode/managed-plugin-config.js +35 -0
- package/server/lib/opencode/managed-process-registry.js +3 -3
- package/server/lib/opencode/mcp-oauth-callback.test.js +2 -2
- package/server/lib/opencode/openchamber-routes.js +15 -15
- package/server/lib/opencode/openchamber-routes.test.js +11 -11
- package/server/lib/opencode/plugins.js +2 -2
- package/server/lib/opencode/plugins.test.js +1 -1
- package/server/lib/opencode/project-icon-routes.js +2 -2
- package/server/lib/opencode/project-icon-routes.test.js +1 -1
- package/server/lib/opencode/providers.js +44 -2
- package/server/lib/opencode/providers.test.js +131 -4
- package/server/lib/opencode/proxy.js +2 -2
- package/server/lib/opencode/pwa-manifest-routes.js +1 -1
- package/server/lib/opencode/restart-session-recovery.test.js +1 -1
- package/server/lib/opencode/routes-upgrade.test.js +4 -4
- package/server/lib/opencode/routes.js +14 -14
- package/server/lib/opencode/server-startup-runtime.js +6 -6
- package/server/lib/opencode/session-runtime.js +3 -3
- package/server/lib/opencode/session-runtime.test.js +6 -6
- package/server/lib/opencode/settings-helpers.js +31 -3
- package/server/lib/opencode/settings-helpers.test.js +189 -12
- package/server/lib/opencode/settings-runtime.js +2 -2
- package/server/lib/opencode/settings-runtime.test.js +29 -0
- package/server/lib/opencode/shared.js +5 -2
- package/server/lib/opencode/shared.test.js +7 -7
- package/server/lib/opencode/shutdown-runtime.js +2 -0
- package/server/lib/opencode/skill-routes.js +2 -1
- package/server/lib/opencode/snippets.js +1 -2
- package/server/lib/opencode/startup-performance.js +1 -1
- package/server/lib/opencode/startup-performance.test.js +6 -6
- package/server/lib/opencode/static-routes-runtime.js +8 -8
- package/server/lib/opencode/static-routes-runtime.test.js +7 -7
- package/server/lib/opencode/upgrade-capability.js +2 -2
- package/server/lib/opencode/upgrade-capability.test.js +3 -3
- package/server/lib/package-manager.js +17 -42
- package/server/lib/package-manager.test.js +19 -19
- package/server/lib/permission-auto-accept/runtime.js +1 -1
- package/server/lib/project-context/routes.js +1 -1
- package/server/lib/projects/project-config.js +2 -2
- package/server/lib/quota/DOCUMENTATION.md +9 -1
- package/server/lib/quota/credentials/providers.js +4 -0
- package/server/lib/quota/credentials/store.js +4 -4
- package/server/lib/quota/credentials/store.test.js +8 -8
- package/server/lib/quota/index.js +1 -0
- package/server/lib/quota/providers/exe-dev.js +75 -0
- package/server/lib/quota/providers/exe-dev.test.js +47 -0
- package/server/lib/quota/providers/hyper.js +118 -0
- package/server/lib/quota/providers/hyper.test.js +126 -0
- package/server/lib/quota/providers/index.js +15 -0
- package/server/lib/quota/providers/ollama-cloud.js +1 -1
- package/server/lib/quota/providers/opencode-go.js +2 -1
- package/server/lib/quota/providers/opencode-go.test.js +9 -5
- package/server/lib/quota/providers/xai.js +1 -1
- package/server/lib/quota/routes.js +2 -0
- package/server/lib/quota/utils/auth.js +1 -1
- package/server/lib/relay/DOCUMENTATION.md +1 -1
- package/server/lib/relay/host-client.js +1 -1
- package/server/lib/relay/host-client.test.js +9 -1
- package/server/lib/relay/host-lock.js +1 -1
- package/server/lib/relay/service.js +5 -5
- package/server/lib/relay/tunnel-host.js +3 -1
- package/server/lib/relay/tunnel-host.test.js +9 -1
- package/server/lib/scheduled-tasks/issue-2710-double-execution.test.js +2 -2
- package/server/lib/scheduled-tasks/routes.js +5 -5
- package/server/lib/scheduled-tasks/service.js +25 -25
- package/server/lib/scheduled-tasks/service.test.js +1 -1
- package/server/lib/security/bind-host.js +4 -4
- package/server/lib/security/bind-host.test.js +1 -1
- package/server/lib/security/request-security.js +11 -5
- package/server/lib/security/request-security.test.js +14 -14
- package/server/lib/session-assist/runtime.js +10 -9
- package/server/lib/session-folders/routes.js +2 -2
- package/server/lib/session-folders/routes.test.js +8 -8
- package/server/lib/session-goal/DOCUMENTATION.md +20 -7
- package/server/lib/session-goal/create.js +4 -2
- package/server/lib/session-goal/create.test.js +1 -1
- package/server/lib/session-goal/objectives.js +4 -4
- package/server/lib/session-goal/routes.js +1 -1
- package/server/lib/session-goal/runtime.js +88 -22
- package/server/lib/session-goal/runtime.test.js +428 -2
- package/server/lib/session-knowledge/runtime.js +11 -11
- package/server/lib/session-knowledge/runtime.test.js +5 -5
- package/server/lib/skills-catalog/DOCUMENTATION.md +1 -1
- package/server/lib/skills-catalog/cache.test.js +2 -2
- package/server/lib/skills-catalog/disk-cache.js +5 -5
- package/server/lib/skills-catalog/github-meta.test.js +2 -2
- package/server/lib/skills-catalog/install.js +3 -2
- package/server/lib/small-model/DOCUMENTATION.md +4 -0
- package/server/lib/small-model/call.js +9 -3
- package/server/lib/small-model/call.test.js +29 -6
- package/server/lib/small-model/index.js +8 -7
- package/server/lib/small-model/index.test.js +1 -1
- package/server/lib/small-model/resolve.js +1 -1
- package/server/lib/small-model/resolve.test.js +1 -1
- package/server/lib/small-model/routes.js +2 -1
- package/server/lib/system-prompt/runtime.js +3 -22
- package/server/lib/system-prompt/runtime.test.js +3 -3
- package/server/lib/terminal/DOCUMENTATION.md +11 -7
- package/server/lib/terminal/runtime.js +180 -26
- package/server/lib/terminal/runtime.test.js +554 -27
- package/server/lib/terminal/shells.js +20 -3
- package/server/lib/terminal/shells.test.js +33 -2
- package/server/lib/tts/base-url.js +3 -3
- package/server/lib/tts/routes.test.js +20 -20
- package/server/lib/ui-auth/ui-auth.js +12 -9
- package/server/lib/ui-auth/ui-auth.test.js +19 -3
- package/server/lib/ui-auth/ui-passkeys.js +7 -7
- package/server/lib/walkthrough/index.js +1 -0
- package/server/lib/walkthrough/jobs.test.js +1 -1
- package/server/lib/walkthrough/language.test.js +1 -1
- package/server/lib/walkthrough/model-settings.js +3 -3
- package/server/lib/walkthrough/model-settings.test.js +1 -1
- package/server/lib/walkthrough/pull-request.test.js +5 -5
- package/server/lib/walkthrough/reproduce-2607.test.js +2 -2
- package/server/lib/walkthrough/routes.test.js +26 -5
- package/server/lib/walkthrough/store.js +3 -3
- package/server/lib/walkthrough/store.test.js +1 -1
- package/server/opencode-proxy.test.js +2 -2
- package/server/proxy-headers.js +1 -1
- package/server/sse-routes.test.js +4 -4
- package/README.md.bak +0 -250
- package/bin/lib/DOCUMENTATION.md.bak +0 -163
- package/dist/assets/CommitSection-SGBCAW0w.js +0 -1
- package/dist/assets/FilesView-Bdq8ppva.js +0 -17
- package/dist/assets/GitView-Znn7VJcP.js +0 -6
- package/dist/assets/LinearIssuesView-jP-hXyac.js +0 -1
- package/dist/assets/MarkdownRendererImpl-Dt9mjTRN.js +0 -12
- package/dist/assets/PlanView-B0F3BtPZ.js +0 -5
- package/dist/assets/SettingsView-BBW-S-gh.js +0 -28
- package/dist/assets/ToolPartDiffPreview-CUNe28U1.js +0 -8
- package/dist/assets/index-C57jT0Sa.css +0 -1
- package/dist/assets/index-DW_E3rnL.js +0 -7
- package/dist/assets/main-Bv5Pkngh.js +0 -928
- package/dist/assets/pl-Dioz29BI.js +0 -15
- package/dist/assets/renderMobileApp-D9yQJy0L.js +0 -25
- package/dist/assets/runtimeEndpointReset-CjhvxLH0.js +0 -16
- package/dist/assets/tr-DFnMlPxY.js +0 -6
- package/dist/assets/useInlineCommentController-CDEuSlPH.js +0 -2
- package/dist/assets/vendor-zod-BLfBSgBh.js +0 -39
- package/server/index.d.ts.bak +0 -39
- package/server/lib/agent-tool/DOCUMENTATION.md.bak +0 -119
- package/server/lib/browser-control/DOCUMENTATION.md.bak +0 -50
- package/server/lib/context-obligatory/DOCUMENTATION.md.bak +0 -19
- package/server/lib/dev-tunnel/DOCUMENTATION.md.bak +0 -57
- package/server/lib/dictation/DOCUMENTATION.md.bak +0 -100
- package/server/lib/event-stream/DOCUMENTATION.md.bak +0 -62
- package/server/lib/fs/DOCUMENTATION.md.bak +0 -47
- package/server/lib/git/DOCUMENTATION.md.bak +0 -193
- package/server/lib/github/DOCUMENTATION.md.bak +0 -183
- package/server/lib/linear/DOCUMENTATION.md.bak +0 -97
- package/server/lib/linear/OAUTH-BROKER-HANDOFF.md.bak +0 -91
- package/server/lib/markdown-image-grants/DOCUMENTATION.md.bak +0 -40
- package/server/lib/notifications/APNS.md.bak +0 -135
- package/server/lib/notifications/DOCUMENTATION.md.bak +0 -138
- package/server/lib/openchamber-control/DOCUMENTATION.md.bak +0 -64
- package/server/lib/opencode/DOCUMENTATION.md.bak +0 -431
- package/server/lib/opencode/managed-process-registry.d.ts.bak +0 -13
- package/server/lib/opencode/provider-env-aliases.d.ts.bak +0 -3
- package/server/lib/permission-auto-accept/DOCUMENTATION.md.bak +0 -34
- package/server/lib/project-context/DOCUMENTATION.md.bak +0 -160
- package/server/lib/quota/DOCUMENTATION.md.bak +0 -123
- package/server/lib/relay/DOCUMENTATION.md.bak +0 -100
- package/server/lib/scheduled-tasks/DOCUMENTATION.md.bak +0 -182
- package/server/lib/session-assist/DOCUMENTATION.md.bak +0 -66
- package/server/lib/session-goal/DOCUMENTATION.md.bak +0 -213
- package/server/lib/session-knowledge/DOCUMENTATION.md.bak +0 -89
- package/server/lib/skills-catalog/DOCUMENTATION.md.bak +0 -151
- package/server/lib/small-model/DOCUMENTATION.md.bak +0 -212
- package/server/lib/system-prompt/DOCUMENTATION.md.bak +0 -36
- package/server/lib/terminal/DOCUMENTATION.md.bak +0 -50
- package/server/lib/text/DOCUMENTATION.md.bak +0 -35
- package/server/lib/tts/DOCUMENTATION.md.bak +0 -147
- package/server/lib/tunnels/DOCUMENTATION.md.bak +0 -21
- package/server/lib/ui-auth/DOCUMENTATION.md.bak +0 -44
- package/server/lib/walkthrough/DOCUMENTATION.md.bak +0 -411
|
@@ -55,19 +55,19 @@ describe('resolveOpenCodeEnvConfig hostname', () => {
|
|
|
55
55
|
expect(resolveOpenCodeEnvConfig({ env: {} }).configuredOpenCodeHostname).toBe('127.0.0.1');
|
|
56
56
|
});
|
|
57
57
|
|
|
58
|
-
it('reads
|
|
59
|
-
const result = resolveOpenCodeEnvConfig({ env: {
|
|
58
|
+
it('reads AIWORKER_OPENCODE_HOSTNAME', () => {
|
|
59
|
+
const result = resolveOpenCodeEnvConfig({ env: { AIWORKER_OPENCODE_HOSTNAME: '0.0.0.0' } });
|
|
60
60
|
expect(result.configuredOpenCodeHostname).toBe('0.0.0.0');
|
|
61
61
|
});
|
|
62
62
|
|
|
63
63
|
it('trims surrounding whitespace', () => {
|
|
64
|
-
const result = resolveOpenCodeEnvConfig({ env: {
|
|
64
|
+
const result = resolveOpenCodeEnvConfig({ env: { AIWORKER_OPENCODE_HOSTNAME: ' tailscale-host ' } });
|
|
65
65
|
expect(result.configuredOpenCodeHostname).toBe('tailscale-host');
|
|
66
66
|
});
|
|
67
67
|
|
|
68
68
|
it('warns and falls back for an empty value', () => {
|
|
69
69
|
const logger = { warn: vi.fn(), error: vi.fn() };
|
|
70
|
-
const result = resolveOpenCodeEnvConfig({ env: {
|
|
70
|
+
const result = resolveOpenCodeEnvConfig({ env: { AIWORKER_OPENCODE_HOSTNAME: ' ' }, logger });
|
|
71
71
|
expect(result.configuredOpenCodeHostname).toBe('127.0.0.1');
|
|
72
72
|
expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining('empty after trimming'));
|
|
73
73
|
expect(logger.error).not.toHaveBeenCalled();
|
|
@@ -76,19 +76,19 @@ describe('resolveOpenCodeEnvConfig hostname', () => {
|
|
|
76
76
|
it('rejects invalid values with a clear error and falls back to loopback', () => {
|
|
77
77
|
const logger = { warn: vi.fn(), error: vi.fn() };
|
|
78
78
|
const result = resolveOpenCodeEnvConfig({
|
|
79
|
-
env: {
|
|
79
|
+
env: { AIWORKER_OPENCODE_HOSTNAME: 'http://nope:4096' },
|
|
80
80
|
logger,
|
|
81
81
|
});
|
|
82
82
|
expect(result.configuredOpenCodeHostname).toBe('127.0.0.1');
|
|
83
83
|
expect(logger.error).toHaveBeenCalledWith(
|
|
84
|
-
expect.stringContaining('Rejecting
|
|
84
|
+
expect.stringContaining('Rejecting AIWORKER_OPENCODE_HOSTNAME'),
|
|
85
85
|
);
|
|
86
86
|
expect(logger.error).toHaveBeenCalledWith(expect.stringContaining('127.0.0.1'));
|
|
87
87
|
});
|
|
88
88
|
|
|
89
89
|
it('keeps other env config intact when the hostname is validated', () => {
|
|
90
90
|
const result = resolveOpenCodeEnvConfig({
|
|
91
|
-
env: {
|
|
91
|
+
env: { AIWORKER_OPENCODE_HOSTNAME: '0.0.0.0', OPENCODE_PORT: '4096' },
|
|
92
92
|
});
|
|
93
93
|
expect(result.configuredOpenCodeHostname).toBe('0.0.0.0');
|
|
94
94
|
expect(result.configuredOpenCodePort).toBe(4096);
|
|
@@ -289,7 +289,7 @@ export const createOpenCodeEnvRuntime = (deps) => {
|
|
|
289
289
|
const bundledOpenCodeCliCandidates = () => {
|
|
290
290
|
const names = process.platform === 'win32' ? ['opencode.exe'] : ['opencode'];
|
|
291
291
|
const roots = [
|
|
292
|
-
process.env.
|
|
292
|
+
process.env.AIWORKER_BUNDLED_OPENCODE_CLI_DIR,
|
|
293
293
|
typeof process.resourcesPath === 'string' ? path.join(process.resourcesPath, 'opencode-cli') : null,
|
|
294
294
|
]
|
|
295
295
|
.map((value) => (typeof value === 'string' ? value.trim() : ''))
|
|
@@ -362,8 +362,8 @@ export const createOpenCodeEnvRuntime = (deps) => {
|
|
|
362
362
|
const explicit = [
|
|
363
363
|
process.env.OPENCODE_BINARY,
|
|
364
364
|
process.env.OPENCODE_PATH,
|
|
365
|
-
process.env.
|
|
366
|
-
process.env.
|
|
365
|
+
process.env.AIWORKER_OPENCODE_PATH,
|
|
366
|
+
process.env.AIWORKER_OPENCODE_BIN,
|
|
367
367
|
]
|
|
368
368
|
.map(stripWrappingQuotes)
|
|
369
369
|
.filter(Boolean);
|
|
@@ -485,7 +485,7 @@ export const createOpenCodeEnvRuntime = (deps) => {
|
|
|
485
485
|
};
|
|
486
486
|
|
|
487
487
|
const resolveNodeCliPath = () => {
|
|
488
|
-
const explicit = [process.env.NODE_BINARY, process.env.
|
|
488
|
+
const explicit = [process.env.NODE_BINARY, process.env.AIWORKER_NODE_BINARY]
|
|
489
489
|
.map((v) => (typeof v === 'string' ? v.trim() : ''))
|
|
490
490
|
.filter(Boolean);
|
|
491
491
|
|
|
@@ -551,7 +551,7 @@ export const createOpenCodeEnvRuntime = (deps) => {
|
|
|
551
551
|
};
|
|
552
552
|
|
|
553
553
|
const resolveBunCliPath = () => {
|
|
554
|
-
const explicit = [process.env.BUN_BINARY, process.env.
|
|
554
|
+
const explicit = [process.env.BUN_BINARY, process.env.AIWORKER_BUN_BINARY]
|
|
555
555
|
.map((v) => (typeof v === 'string' ? v.trim() : ''))
|
|
556
556
|
.filter(Boolean);
|
|
557
557
|
|
|
@@ -950,7 +950,7 @@ export const createOpenCodeEnvRuntime = (deps) => {
|
|
|
950
950
|
const createConfiguredOpencodeBinaryError = (raw, normalized) => {
|
|
951
951
|
const configured = typeof raw === 'string' ? raw.trim() : '';
|
|
952
952
|
const candidate = typeof normalized === 'string' && normalized.trim().length > 0 ? normalized.trim() : configured;
|
|
953
|
-
const messageSuffix = '
|
|
953
|
+
const messageSuffix = 'AiWorker needs the standalone opencode CLI. Install it and set settings.opencodeBinary to the CLI path, for example ~/.opencode/bin/opencode, or leave the setting empty to use PATH lookup.';
|
|
954
954
|
const error = (() => {
|
|
955
955
|
if (isKnownOpenCodeDesktopAppPath(candidate) || isKnownOpenCodeDesktopAppPath(configured)) {
|
|
956
956
|
const platformName = process.platform === 'win32' ? 'Windows desktop app install' : 'macOS desktop app bundle';
|
|
@@ -983,7 +983,7 @@ export const createOpenCodeEnvRuntime = (deps) => {
|
|
|
983
983
|
};
|
|
984
984
|
|
|
985
985
|
const createConfiguredWslOpencodeError = (raw) => new Error(
|
|
986
|
-
`Configured settings.opencodeBinary uses WSL but
|
|
986
|
+
`Configured settings.opencodeBinary uses WSL but AiWorker could not resolve a WSL OpenCode command: ${raw}. Ensure WSL is available and opencode is installed in the configured distro.`
|
|
987
987
|
);
|
|
988
988
|
|
|
989
989
|
const normalizeOpencodeBinarySetting = (raw) => {
|
|
@@ -1044,7 +1044,7 @@ export const createOpenCodeEnvRuntime = (deps) => {
|
|
|
1044
1044
|
if (strict) {
|
|
1045
1045
|
throw createConfiguredWslOpencodeError(raw);
|
|
1046
1046
|
}
|
|
1047
|
-
console.warn(`Configured settings.opencodeBinary uses WSL, which is no longer supported by
|
|
1047
|
+
console.warn(`Configured settings.opencodeBinary uses WSL, which is no longer supported by AiWorker desktop: ${raw}`);
|
|
1048
1048
|
return null;
|
|
1049
1049
|
}
|
|
1050
1050
|
|
|
@@ -1053,7 +1053,7 @@ export const createOpenCodeEnvRuntime = (deps) => {
|
|
|
1053
1053
|
if (strict) {
|
|
1054
1054
|
throw createConfiguredWslOpencodeError(raw);
|
|
1055
1055
|
}
|
|
1056
|
-
console.warn(`Configured settings.opencodeBinary points to WSL, which is no longer supported by
|
|
1056
|
+
console.warn(`Configured settings.opencodeBinary points to WSL, which is no longer supported by AiWorker desktop: ${raw}`);
|
|
1057
1057
|
return null;
|
|
1058
1058
|
}
|
|
1059
1059
|
|
|
@@ -1132,7 +1132,7 @@ export const createOpenCodeEnvRuntime = (deps) => {
|
|
|
1132
1132
|
return state.resolvedGitBinary;
|
|
1133
1133
|
}
|
|
1134
1134
|
|
|
1135
|
-
const explicit = [process.env.GIT_BINARY, process.env.
|
|
1135
|
+
const explicit = [process.env.GIT_BINARY, process.env.AIWORKER_GIT_BINARY]
|
|
1136
1136
|
.map((value) => (typeof value === 'string' ? value.trim() : ''))
|
|
1137
1137
|
.filter(Boolean);
|
|
1138
1138
|
for (const candidate of explicit) {
|
|
@@ -9,10 +9,10 @@ const originalComSpec = process.env.ComSpec;
|
|
|
9
9
|
const originalPath = process.env.PATH;
|
|
10
10
|
const originalLocalAppData = process.env.LOCALAPPDATA;
|
|
11
11
|
const originalSystemRoot = process.env.SystemRoot;
|
|
12
|
-
const originalBundledOpencodeCliDir = process.env.
|
|
12
|
+
const originalBundledOpencodeCliDir = process.env.AIWORKER_BUNDLED_OPENCODE_CLI_DIR;
|
|
13
13
|
const originalResourcesPath = process.resourcesPath;
|
|
14
14
|
const originalWslBinary = process.env.WSL_BINARY;
|
|
15
|
-
const
|
|
15
|
+
const originalAiWorkerWslBinary = process.env.AIWORKER_WSL_BINARY;
|
|
16
16
|
const originalPlatform = process.platform;
|
|
17
17
|
const tempDirs = [];
|
|
18
18
|
const itIf = (condition) => condition ? it : it.skip;
|
|
@@ -69,9 +69,9 @@ afterEach(() => {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
if (typeof originalBundledOpencodeCliDir === 'string') {
|
|
72
|
-
process.env.
|
|
72
|
+
process.env.AIWORKER_BUNDLED_OPENCODE_CLI_DIR = originalBundledOpencodeCliDir;
|
|
73
73
|
} else {
|
|
74
|
-
delete process.env.
|
|
74
|
+
delete process.env.AIWORKER_BUNDLED_OPENCODE_CLI_DIR;
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
Object.defineProperty(process, 'resourcesPath', {
|
|
@@ -85,10 +85,10 @@ afterEach(() => {
|
|
|
85
85
|
delete process.env.WSL_BINARY;
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
if (typeof
|
|
89
|
-
process.env.
|
|
88
|
+
if (typeof originalAiWorkerWslBinary === 'string') {
|
|
89
|
+
process.env.AIWORKER_WSL_BINARY = originalAiWorkerWslBinary;
|
|
90
90
|
} else {
|
|
91
|
-
delete process.env.
|
|
91
|
+
delete process.env.AIWORKER_WSL_BINARY;
|
|
92
92
|
}
|
|
93
93
|
});
|
|
94
94
|
|
|
@@ -133,21 +133,21 @@ describe('OpenCode env runtime', () => {
|
|
|
133
133
|
|
|
134
134
|
it('clears AppImage ARGV0 when applying a login-shell env snapshot', () => {
|
|
135
135
|
const previousArgv0 = process.env.ARGV0;
|
|
136
|
-
process.env.ARGV0 = '/path/to/
|
|
137
|
-
delete process.env.
|
|
136
|
+
process.env.ARGV0 = '/path/to/AiWorker.AppImage';
|
|
137
|
+
delete process.env.AIWORKER_ARGV0_TEST_MARKER;
|
|
138
138
|
const { runtime, state } = createRuntime({});
|
|
139
139
|
state.cachedLoginShellEnvSnapshot = {
|
|
140
140
|
PATH: '/usr/bin',
|
|
141
141
|
ARGV0: '/leaked/from/shell.AppImage',
|
|
142
|
-
|
|
142
|
+
AIWORKER_ARGV0_TEST_MARKER: '1',
|
|
143
143
|
};
|
|
144
144
|
|
|
145
145
|
try {
|
|
146
146
|
runtime.applyLoginShellEnvSnapshot();
|
|
147
147
|
expect(process.env.ARGV0).toBeUndefined();
|
|
148
|
-
expect(process.env.
|
|
148
|
+
expect(process.env.AIWORKER_ARGV0_TEST_MARKER).toBe('1');
|
|
149
149
|
} finally {
|
|
150
|
-
delete process.env.
|
|
150
|
+
delete process.env.AIWORKER_ARGV0_TEST_MARKER;
|
|
151
151
|
if (previousArgv0 === undefined) delete process.env.ARGV0;
|
|
152
152
|
else process.env.ARGV0 = previousArgv0;
|
|
153
153
|
}
|
|
@@ -155,7 +155,7 @@ describe('OpenCode env runtime', () => {
|
|
|
155
155
|
|
|
156
156
|
it('clears AppImage ARGV0 even when no login-shell snapshot is available', () => {
|
|
157
157
|
const previousArgv0 = process.env.ARGV0;
|
|
158
|
-
process.env.ARGV0 = '/path/to/
|
|
158
|
+
process.env.ARGV0 = '/path/to/AiWorker.AppImage';
|
|
159
159
|
const { runtime, state } = createRuntime({});
|
|
160
160
|
state.cachedLoginShellEnvSnapshot = null;
|
|
161
161
|
|
|
@@ -244,7 +244,7 @@ describe('OpenCode env runtime', () => {
|
|
|
244
244
|
fs.chmodSync(bundledBinary, 0o755);
|
|
245
245
|
fs.chmodSync(pathBinary, 0o755);
|
|
246
246
|
}
|
|
247
|
-
process.env.
|
|
247
|
+
process.env.AIWORKER_BUNDLED_OPENCODE_CLI_DIR = bundledDir;
|
|
248
248
|
process.env.PATH = pathDir;
|
|
249
249
|
delete process.env.OPENCODE_BINARY;
|
|
250
250
|
const { runtime, state } = createRuntime({});
|
|
@@ -258,7 +258,7 @@ describe('OpenCode env runtime', () => {
|
|
|
258
258
|
const bundledBinary = path.join(bundledDir, process.platform === 'win32' ? 'opencode.exe' : 'opencode');
|
|
259
259
|
fs.writeFileSync(bundledBinary, '#!/bin/sh\nexit 0\n');
|
|
260
260
|
if (process.platform !== 'win32') fs.chmodSync(bundledBinary, 0o755);
|
|
261
|
-
process.env.
|
|
261
|
+
process.env.AIWORKER_BUNDLED_OPENCODE_CLI_DIR = bundledDir;
|
|
262
262
|
const { runtime } = createRuntime({});
|
|
263
263
|
|
|
264
264
|
expect(runtime.isBundledOpenCodeCliPath(bundledBinary)).toBe(true);
|
|
@@ -276,7 +276,7 @@ describe('OpenCode env runtime', () => {
|
|
|
276
276
|
fs.chmodSync(bundledBinary, 0o755);
|
|
277
277
|
fs.chmodSync(explicitBinary, 0o755);
|
|
278
278
|
}
|
|
279
|
-
process.env.
|
|
279
|
+
process.env.AIWORKER_BUNDLED_OPENCODE_CLI_DIR = bundledDir;
|
|
280
280
|
process.env.OPENCODE_BINARY = explicitBinary;
|
|
281
281
|
const { runtime, state } = createRuntime({});
|
|
282
282
|
|
|
@@ -298,7 +298,7 @@ describe('OpenCode env runtime', () => {
|
|
|
298
298
|
value: resourcesPath,
|
|
299
299
|
});
|
|
300
300
|
process.env.PATH = createTempDir('openchamber-empty-path-');
|
|
301
|
-
delete process.env.
|
|
301
|
+
delete process.env.AIWORKER_BUNDLED_OPENCODE_CLI_DIR;
|
|
302
302
|
delete process.env.OPENCODE_BINARY;
|
|
303
303
|
const emptyHome = createTempDir('openchamber-empty-home-');
|
|
304
304
|
const { runtime, state } = createRuntime({}, {
|
|
@@ -400,7 +400,7 @@ describe('OpenCode env runtime', () => {
|
|
|
400
400
|
process.env.PATH = dir;
|
|
401
401
|
process.env.SystemRoot = dir;
|
|
402
402
|
process.env.WSL_BINARY = path.join(dir, 'missing-wsl.exe');
|
|
403
|
-
process.env.
|
|
403
|
+
process.env.AIWORKER_WSL_BINARY = path.join(dir, 'missing-openchamber-wsl.exe');
|
|
404
404
|
const { runtime } = createRuntime({ opencodeBinary: 'wsl:/usr/local/bin/opencode' });
|
|
405
405
|
|
|
406
406
|
await expect(runtime.applyOpencodeBinaryFromSettings({ strict: true })).rejects.toMatchObject({
|
|
@@ -13,12 +13,13 @@ import { registerProjectContextRoutes } from '../project-context/routes.js';
|
|
|
13
13
|
import { registerAgentMemoryRoutes } from '../agent-memory/routes.js';
|
|
14
14
|
import { registerSessionKnowledgeRoutes } from '../session-knowledge/routes.js';
|
|
15
15
|
import { registerPermissionAutoAcceptRoutes } from '../permission-auto-accept/runtime.js';
|
|
16
|
+
import { registerMessageQueueRoutes } from '../message-queue/runtime.js';
|
|
16
17
|
import { registerConfigEntityRoutes } from './config-entity-routes.js';
|
|
17
18
|
import { registerSettingsUtilityRoutes } from './core-routes.js';
|
|
18
19
|
import { registerProjectIconRoutes } from './project-icon-routes.js';
|
|
19
20
|
import { registerScheduledTaskRoutes } from '../scheduled-tasks/routes.js';
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
21
|
+
import { registerAiWorkerSessionRoutes } from '../openchamber-sessions/routes.js';
|
|
22
|
+
import { registerAiWorkerControlRoutes } from '../openchamber-control/routes.js';
|
|
22
23
|
import { registerMarkdownImageGrantRoutes } from '../markdown-image-grants/routes.js';
|
|
23
24
|
import { registerSkillRoutes } from './skill-routes.js';
|
|
24
25
|
import { registerPluginRoutes } from './plugin-routes.js';
|
|
@@ -95,8 +96,9 @@ export const createFeatureRoutesRuntime = (dependencies) => {
|
|
|
95
96
|
spawn,
|
|
96
97
|
resolveGitBinaryForSpawn,
|
|
97
98
|
createFsSearchRuntime,
|
|
98
|
-
|
|
99
|
-
|
|
99
|
+
aiworkerDataDir,
|
|
100
|
+
aiworkerUserConfigRoot,
|
|
101
|
+
managedChatsRoot,
|
|
100
102
|
normalizeDirectoryPath,
|
|
101
103
|
resolveProjectDirectory,
|
|
102
104
|
resolveOptionalProjectDirectory,
|
|
@@ -128,10 +130,11 @@ export const createFeatureRoutesRuntime = (dependencies) => {
|
|
|
128
130
|
openChamberSessionService,
|
|
129
131
|
openChamberControlService,
|
|
130
132
|
waitForOpenCodeReady,
|
|
131
|
-
|
|
133
|
+
getAiWorkerEventClients,
|
|
132
134
|
writeSseEvent,
|
|
133
135
|
emitSessionCreatedEvent,
|
|
134
136
|
permissionAutoAcceptRuntime,
|
|
137
|
+
messageQueueRuntime,
|
|
135
138
|
} = routeDependencies;
|
|
136
139
|
|
|
137
140
|
registerSettingsUtilityRoutes(app, {
|
|
@@ -141,6 +144,7 @@ export const createFeatureRoutesRuntime = (dependencies) => {
|
|
|
141
144
|
});
|
|
142
145
|
|
|
143
146
|
registerPermissionAutoAcceptRoutes(app, permissionAutoAcceptRuntime);
|
|
147
|
+
registerMessageQueueRoutes(app, messageQueueRuntime);
|
|
144
148
|
|
|
145
149
|
registerOpenCodeRoutes(app, {
|
|
146
150
|
crypto,
|
|
@@ -166,7 +170,7 @@ export const createFeatureRoutesRuntime = (dependencies) => {
|
|
|
166
170
|
fsPromises,
|
|
167
171
|
path,
|
|
168
172
|
crypto,
|
|
169
|
-
|
|
173
|
+
aiworkerDataDir,
|
|
170
174
|
sanitizeProjects,
|
|
171
175
|
readSettingsFromDiskMigrated,
|
|
172
176
|
persistSettings,
|
|
@@ -181,11 +185,11 @@ export const createFeatureRoutesRuntime = (dependencies) => {
|
|
|
181
185
|
projectConfigRuntime,
|
|
182
186
|
scheduledTasksRuntime,
|
|
183
187
|
scheduledTaskService,
|
|
184
|
-
|
|
188
|
+
getAiWorkerEventClients,
|
|
185
189
|
writeSseEvent,
|
|
186
190
|
});
|
|
187
191
|
|
|
188
|
-
|
|
192
|
+
registerAiWorkerSessionRoutes(app, {
|
|
189
193
|
readSettingsFromDiskMigrated,
|
|
190
194
|
sanitizeProjects,
|
|
191
195
|
validateDirectoryPath,
|
|
@@ -196,7 +200,7 @@ export const createFeatureRoutesRuntime = (dependencies) => {
|
|
|
196
200
|
sessionService: openChamberSessionService,
|
|
197
201
|
});
|
|
198
202
|
|
|
199
|
-
|
|
203
|
+
registerAiWorkerControlRoutes(app, { controlService: openChamberControlService });
|
|
200
204
|
|
|
201
205
|
registerMarkdownImageGrantRoutes(app, {
|
|
202
206
|
fsPromises,
|
|
@@ -307,7 +311,7 @@ export const createFeatureRoutesRuntime = (dependencies) => {
|
|
|
307
311
|
registerMagicPromptRoutes(app, {
|
|
308
312
|
fsPromises,
|
|
309
313
|
path,
|
|
310
|
-
|
|
314
|
+
aiworkerDataDir,
|
|
311
315
|
});
|
|
312
316
|
registerProjectContextRoutes(app, { projectContextRuntime });
|
|
313
317
|
registerAgentMemoryRoutes(app, { agentMemoryRuntime, isAgentMemoryEnabled });
|
|
@@ -316,7 +320,7 @@ export const createFeatureRoutesRuntime = (dependencies) => {
|
|
|
316
320
|
registerSessionFoldersRoutes(app, {
|
|
317
321
|
fsPromises,
|
|
318
322
|
path,
|
|
319
|
-
|
|
323
|
+
aiworkerDataDir,
|
|
320
324
|
});
|
|
321
325
|
registerFsRoutes(app, {
|
|
322
326
|
os,
|
|
@@ -328,7 +332,8 @@ export const createFeatureRoutesRuntime = (dependencies) => {
|
|
|
328
332
|
resolveProjectDirectory,
|
|
329
333
|
buildAugmentedPath,
|
|
330
334
|
resolveGitBinaryForSpawn,
|
|
331
|
-
|
|
335
|
+
aiworkerUserConfigRoot,
|
|
336
|
+
managedChatsRoot,
|
|
332
337
|
});
|
|
333
338
|
};
|
|
334
339
|
|
|
@@ -7,8 +7,8 @@ export const createHmrStateRuntime = (dependencies) => {
|
|
|
7
7
|
} = dependencies;
|
|
8
8
|
|
|
9
9
|
const getInitialOpenCodeWorkingDirectory = () => {
|
|
10
|
-
const configured = typeof processLike.env.
|
|
11
|
-
? processLike.env.
|
|
10
|
+
const configured = typeof processLike.env.AIWORKER_OPENCODE_CWD === 'string'
|
|
11
|
+
? processLike.env.AIWORKER_OPENCODE_CWD.trim()
|
|
12
12
|
: '';
|
|
13
13
|
return configured || os.homedir();
|
|
14
14
|
};
|
|
@@ -11,7 +11,7 @@ const createRuntime = (env = {}) => createHmrStateRuntime({
|
|
|
11
11
|
|
|
12
12
|
describe('hmr state runtime', () => {
|
|
13
13
|
it('uses configured OpenCode cwd when provided', () => {
|
|
14
|
-
const runtime = createRuntime({
|
|
14
|
+
const runtime = createRuntime({ AIWORKER_OPENCODE_CWD: '/tmp/openchamber-data' });
|
|
15
15
|
|
|
16
16
|
expect(runtime.getOrCreateHmrState().openCodeWorkingDirectory).toBe('/tmp/openchamber-data');
|
|
17
17
|
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const DEFAULT_INPUT_HISTORY_SCOPE = 'session';
|
|
2
|
+
export const DEFAULT_INPUT_HISTORY_LIMIT = 40;
|
|
3
|
+
const MIN_INPUT_HISTORY_LIMIT = 1;
|
|
4
|
+
const MAX_INPUT_HISTORY_LIMIT = 100;
|
|
5
|
+
|
|
6
|
+
export const isInputHistoryScope = (value) => (
|
|
7
|
+
value === 'global' || value === 'session'
|
|
8
|
+
);
|
|
9
|
+
|
|
10
|
+
export const isInputHistoryLimit = (value) => (
|
|
11
|
+
Number.isInteger(value)
|
|
12
|
+
&& value >= MIN_INPUT_HISTORY_LIMIT
|
|
13
|
+
&& value <= MAX_INPUT_HISTORY_LIMIT
|
|
14
|
+
);
|
|
@@ -10,13 +10,13 @@ const parsePositiveInt = (value, fallback) => {
|
|
|
10
10
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
-
const HEALTH_CHECK_TIMEOUT_MS = parsePositiveInt(process.env.
|
|
13
|
+
const HEALTH_CHECK_TIMEOUT_MS = parsePositiveInt(process.env.AIWORKER_OPENCODE_HEALTH_TIMEOUT_MS, 5000);
|
|
14
14
|
const HEALTH_CHECK_MAX_CONSECUTIVE_FAILURES = parsePositiveInt(
|
|
15
|
-
process.env.
|
|
15
|
+
process.env.AIWORKER_OPENCODE_HEALTH_CONSECUTIVE_FAILURES,
|
|
16
16
|
20
|
|
17
17
|
);
|
|
18
|
-
const HEALTH_CHECK_INTERVAL_OVERRIDE_MS = parsePositiveInt(process.env.
|
|
19
|
-
const HEALTH_CHECK_RESULT_CACHE_MS = parsePositiveInt(process.env.
|
|
18
|
+
const HEALTH_CHECK_INTERVAL_OVERRIDE_MS = parsePositiveInt(process.env.AIWORKER_OPENCODE_HEALTH_INTERVAL_MS, 0);
|
|
19
|
+
const HEALTH_CHECK_RESULT_CACHE_MS = parsePositiveInt(process.env.AIWORKER_OPENCODE_HEALTH_CACHE_MS, 750);
|
|
20
20
|
const OPENCODE_HEALTH_PATH = '/global/health';
|
|
21
21
|
// Last-used directory plus the three most recently opened projects — deeper
|
|
22
22
|
// tails are unlikely to be the user's first click and just add background work.
|
|
@@ -490,7 +490,7 @@ export const createOpenCodeLifecycleRuntime = (deps) => {
|
|
|
490
490
|
const onExit = (code, signal) => {
|
|
491
491
|
const reason = signal ? `signal ${signal}` : `code ${code}`;
|
|
492
492
|
const appBundleHint = process.platform === 'darwin' && /\/OpenCode\.app\/Contents\/MacOS\/(?:OpenCode|opencode-cli)$/i.test(binary)
|
|
493
|
-
? ' The configured binary appears to point at the macOS desktop app bundle;
|
|
493
|
+
? ' The configured binary appears to point at the macOS desktop app bundle; AiWorker needs the standalone opencode CLI.'
|
|
494
494
|
: '';
|
|
495
495
|
finish(reject, new Error(`OpenCode process exited before serving with ${reason}. Binary used: ${binary}.${appBundleHint} ${formatCapturedOutput({ stdout, stderr })}`));
|
|
496
496
|
};
|
|
@@ -511,7 +511,7 @@ export const createOpenCodeLifecycleRuntime = (deps) => {
|
|
|
511
511
|
|
|
512
512
|
// Record this child so a future run can reap it if we crash before teardown.
|
|
513
513
|
// The web-server lifecycle runs in-process inside multiple hosts, so tag the
|
|
514
|
-
// actual host (Electron sets
|
|
514
|
+
// actual host (Electron sets AIWORKER_RUNTIME='desktop'; the standalone
|
|
515
515
|
// web CLI leaves it unset → 'web'; SSH remote → 'ssh-remote') rather than a
|
|
516
516
|
// hardcoded label, matching the server's existing runtimeName convention.
|
|
517
517
|
await registerManagedProcess({
|
|
@@ -519,7 +519,7 @@ export const createOpenCodeLifecycleRuntime = (deps) => {
|
|
|
519
519
|
ownerPid: process.pid,
|
|
520
520
|
port,
|
|
521
521
|
binary,
|
|
522
|
-
runtime: process.env.
|
|
522
|
+
runtime: process.env.AIWORKER_RUNTIME || 'web',
|
|
523
523
|
});
|
|
524
524
|
|
|
525
525
|
return {
|
|
@@ -1024,7 +1024,7 @@ export const createOpenCodeLifecycleRuntime = (deps) => {
|
|
|
1024
1024
|
|
|
1025
1025
|
// A managed OpenCode process is restarted (and thus re-reads config from
|
|
1026
1026
|
// disk) by restartOpenCode(). An external OpenCode server is NOT owned by
|
|
1027
|
-
//
|
|
1027
|
+
// AiWorker: restartOpenCode() only re-probes its health, so the freshly
|
|
1028
1028
|
// written config is on disk but the running server keeps serving its old,
|
|
1029
1029
|
// startup-cached config until the user restarts it themselves. Report this
|
|
1030
1030
|
// honestly so callers don't claim the change is live.
|
|
@@ -636,7 +636,7 @@ describe('OpenCode lifecycle', () => {
|
|
|
636
636
|
it('strips AppImage ARGV0 from managed OpenCode launch env', async () => {
|
|
637
637
|
delete process.env.OPENCODE_BINARY;
|
|
638
638
|
const previousArgv0 = process.env.ARGV0;
|
|
639
|
-
process.env.ARGV0 = '/path/to/
|
|
639
|
+
process.env.ARGV0 = '/path/to/AiWorker/AiWorker-1.17.2-linux-x86_64.AppImage';
|
|
640
640
|
const child = createMockChild();
|
|
641
641
|
spawnMock.mockImplementationOnce(() => {
|
|
642
642
|
queueMicrotask(() => {
|
|
@@ -667,7 +667,7 @@ describe('OpenCode lifecycle', () => {
|
|
|
667
667
|
}
|
|
668
668
|
});
|
|
669
669
|
|
|
670
|
-
it('adds managed
|
|
670
|
+
it('adds managed AiWorker tool environment without allowing it to replace launch invariants', async () => {
|
|
671
671
|
const child = createMockChild();
|
|
672
672
|
spawnMock.mockImplementationOnce(() => {
|
|
673
673
|
queueMicrotask(() => {
|
|
@@ -677,7 +677,7 @@ describe('OpenCode lifecycle', () => {
|
|
|
677
677
|
});
|
|
678
678
|
const getManagedOpenCodeEnv = vi.fn(async () => ({
|
|
679
679
|
OPENCODE_CONFIG_CONTENT: '{"plugin":["file:///tool.js"]}',
|
|
680
|
-
|
|
680
|
+
AIWORKER_AGENT_TOOL_TOKEN: 'ephemeral',
|
|
681
681
|
PATH: '/untrusted/path',
|
|
682
682
|
OPENCODE_SERVER_PASSWORD: 'untrusted-password',
|
|
683
683
|
}));
|
|
@@ -688,7 +688,7 @@ describe('OpenCode lifecycle', () => {
|
|
|
688
688
|
|
|
689
689
|
expect(getManagedOpenCodeEnv).toHaveBeenCalledOnce();
|
|
690
690
|
expect(options.env.OPENCODE_CONFIG_CONTENT).toBe('{"plugin":["file:///tool.js"]}');
|
|
691
|
-
expect(options.env.
|
|
691
|
+
expect(options.env.AIWORKER_AGENT_TOOL_TOKEN).toBe('ephemeral');
|
|
692
692
|
expect(options.env.PATH).toBe('/home/user/.bun/bin:/usr/local/bin:/usr/bin');
|
|
693
693
|
expect(options.env.OPENCODE_SERVER_PASSWORD).toBe('password');
|
|
694
694
|
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { parse as parseJsonc } from 'jsonc-parser';
|
|
2
|
+
|
|
3
|
+
const isJsonObject = (value) => value !== null && value !== undefined && Object.getPrototypeOf(value) === Object.prototype;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Append a managed AiWorker plugin to the `plugin` list of an
|
|
7
|
+
* `OPENCODE_CONFIG_CONTENT` value.
|
|
8
|
+
*
|
|
9
|
+
* Existing entries are preserved; an earlier entry for the same URL is dropped
|
|
10
|
+
* so a restart never registers the same plugin twice. Every managed plugin
|
|
11
|
+
* (agent tools, system prompt optimizer, MCP reconnect) goes through this one
|
|
12
|
+
* merge so they compose in any order.
|
|
13
|
+
*
|
|
14
|
+
* @param {string | undefined} rawConfig the current `OPENCODE_CONFIG_CONTENT`, JSONC or unset
|
|
15
|
+
* @param {string} pluginUrl `file://` URL of the materialized plugin
|
|
16
|
+
* @param {string} purpose short noun phrase for the error message, e.g. "managed tool"
|
|
17
|
+
* @returns {string} the merged config as JSON
|
|
18
|
+
*/
|
|
19
|
+
export const appendManagedPlugin = (rawConfig, pluginUrl, purpose) => {
|
|
20
|
+
const errors = [];
|
|
21
|
+
const text = (rawConfig ?? '').trim();
|
|
22
|
+
const parsed = text ? parseJsonc(text, errors, { allowTrailingComma: true }) : {};
|
|
23
|
+
if (errors.length > 0 || !isJsonObject(parsed)) {
|
|
24
|
+
throw new Error(`OPENCODE_CONFIG_CONTENT must contain a valid JSON object before AiWorker can inject its ${purpose}`);
|
|
25
|
+
}
|
|
26
|
+
if (parsed.plugin !== undefined && !Array.isArray(parsed.plugin)) {
|
|
27
|
+
throw new Error(`OPENCODE_CONFIG_CONTENT plugin must be an array before AiWorker can inject its ${purpose}`);
|
|
28
|
+
}
|
|
29
|
+
const configured = Array.isArray(parsed.plugin) ? parsed.plugin : [];
|
|
30
|
+
parsed.plugin = [
|
|
31
|
+
...configured.filter((value) => value !== pluginUrl && (!Array.isArray(value) || value[0] !== pluginUrl)),
|
|
32
|
+
pluginUrl,
|
|
33
|
+
];
|
|
34
|
+
return JSON.stringify(parsed);
|
|
35
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Managed OpenCode process registry + orphan reaper.
|
|
2
2
|
//
|
|
3
|
-
//
|
|
3
|
+
// AiWorker spawns the OpenCode server as an EXTERNAL child binary (on Unix
|
|
4
4
|
// with `detached: true`, so it leads its own process group). That binary can
|
|
5
5
|
// therefore outlive its parent if the parent is hard-killed/crashes/`Ctrl+C`ed
|
|
6
6
|
// before graceful teardown runs — leaving an orphaned `opencode serve` that
|
|
@@ -54,9 +54,9 @@ import { promisify } from 'node:util';
|
|
|
54
54
|
const defaultExecFileAsync = promisify(execFile);
|
|
55
55
|
|
|
56
56
|
const resolveRegistryDir = () => {
|
|
57
|
-
const override = process.env.
|
|
57
|
+
const override = process.env.AIWORKER_MANAGED_PROCESS_REGISTRY;
|
|
58
58
|
if (override && override.trim()) return override.trim();
|
|
59
|
-
return path.join(os.homedir(), '.config', '
|
|
59
|
+
return path.join(os.homedir(), '.config', 'aiworker', 'managed-opencode');
|
|
60
60
|
};
|
|
61
61
|
|
|
62
62
|
const entryFilePath = (pid) => path.join(resolveRegistryDir(), `${pid}.json`);
|
|
@@ -47,7 +47,7 @@ describe('MCP OAuth browser callback route', () => {
|
|
|
47
47
|
|
|
48
48
|
expect(response.text).toContain('Authorization Complete');
|
|
49
49
|
// Started from the desktop shell: the page hands control back via deep link.
|
|
50
|
-
expect(response.text).toContain('
|
|
50
|
+
expect(response.text).toContain('aiworker://focus/mcp-auth');
|
|
51
51
|
|
|
52
52
|
await request(app).get('/api/mcp/auth/pending').query({ state: 'state-1' }).expect(404);
|
|
53
53
|
});
|
|
@@ -76,7 +76,7 @@ describe('MCP OAuth browser callback route', () => {
|
|
|
76
76
|
.query({ state: 'state-web', code: 'auth-code' })
|
|
77
77
|
.expect(200);
|
|
78
78
|
|
|
79
|
-
expect(response.text).not.toContain('
|
|
79
|
+
expect(response.text).not.toContain('aiworker://');
|
|
80
80
|
});
|
|
81
81
|
|
|
82
82
|
it('reports a provider error without contacting OpenCode', async () => {
|