@aiworker/web 1.22.0 → 1.23.0
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 +14 -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-B1Gizi3a.js} +1 -1
- package/dist/assets/DiffView-DXjVsEOw.js +4 -0
- package/dist/assets/DirtyBranchSwitchDialog-aig6zJjg.js +1 -0
- package/dist/assets/FilesView-CJdG0-wk.js +17 -0
- package/dist/assets/GitView-BXsS3jG6.js +6 -0
- package/dist/assets/{JsonTreeView-B0BdZEHG.js → JsonTreeView-D_hpXBnF.js} +1 -1
- package/dist/assets/LinearIssuesView-BoUiLQG1.js +1 -0
- package/dist/assets/MarkdownImageGallery-B_B_a9KS.js +1 -0
- package/dist/assets/MarkdownRendererImpl-xgyyLiBM.js +12 -0
- package/dist/assets/OnboardingScreen-DIp84OWt.js +1 -0
- package/dist/assets/{PatchDiff-DvfqDql7.js → PatchDiff-8p6nLJaU.js} +1 -1
- package/dist/assets/PierreDiffViewer-DjC8nTk9.js +161 -0
- package/dist/assets/PlanView-CJTmOF6I.js +5 -0
- package/dist/assets/SettingsView-DD-JqIJx.js +28 -0
- package/dist/assets/{SettingsWindow-i45U1Cy1.js → SettingsWindow-Cpb4hM6q.js} +1 -1
- package/dist/assets/SymbolsNerdFontMono-Regular-aK5vsLov.woff2 +0 -0
- package/dist/assets/{ToolOutputDialog-BTwyh5OF.js → ToolOutputDialog-DfaKZXNU.js} +6 -6
- package/dist/assets/ToolPartDiffPreview-DtZLzrSK.js +8 -0
- package/dist/assets/{VirtualizedFileDiff-DD8lDVej.js → VirtualizedFileDiff-C8i9HpTB.js} +1 -1
- package/dist/assets/WalkthroughView-DeKMvZlL.js +4 -0
- package/dist/assets/{computeVirtualFileMetrics-BMIRgMHv.js → computeVirtualFileMetrics-BBI7ZwrC.js} +2 -2
- package/dist/assets/contextPanelEmbeddedChat-BdA6bdky.js +1 -0
- package/dist/assets/de-DCrsQ5zS.js +10 -0
- package/dist/assets/es-Dwv4YfH6.js +16 -0
- package/dist/assets/fr-BCWg4Cnx.js +14 -0
- package/dist/assets/ghostty-vt-DdA0Zryv.wasm +0 -0
- package/dist/assets/index-B68h5S5B.css +1 -0
- package/dist/assets/index-DVwMarHI.js +39 -0
- package/dist/assets/{index-CODwDsU_.js → index-jXSK5RrB.js} +1 -1
- package/dist/assets/{isDiffPlainText-BqayB8d3.js → isDiffPlainText-B_x_rVon.js} +1 -1
- package/dist/assets/{isFilePlainText-QfoiKJNY.js → isFilePlainText-DW_xMer1.js} +1 -1
- package/dist/assets/ja-Bruw3RYC.js +16 -0
- package/dist/assets/ko-idhXGF8j.js +16 -0
- package/dist/assets/main-BkyaQhJX.js +930 -0
- package/dist/assets/{main-C5DVOxc6.js → main-CzdPuL0s.js} +2 -2
- package/dist/assets/markdownCore-Cn4Tyejo.js +5 -0
- package/dist/assets/{miniChat-DUJ4irZc.js → miniChat-CCkqKOLp.js} +2 -2
- package/dist/assets/{mobile-CcaxB0n4.js → mobile-mvxTo055.js} +2 -2
- package/dist/assets/patchFileDiff-Csk4iNUi.js +13 -0
- package/dist/assets/pl-CGZWUqZJ.js +16 -0
- package/dist/assets/pt-BR-B8V7u7tA.js +16 -0
- package/dist/assets/renderElectronMiniChatApp-BxoyujA5.js +2 -0
- package/dist/assets/renderMobileApp-B48CsP4r.js +25 -0
- package/dist/assets/runtimeEndpointReset-Bg5gx18H.js +17 -0
- package/dist/assets/scheduledTasksApi-BW0Etzwz.js +1 -0
- package/dist/assets/{shikiHighlight-DYOWuY65.js → shikiHighlight-CRl0SUC9.js} +1 -1
- package/dist/assets/surface-oMvhsog3.js +1 -0
- package/dist/assets/tr-BK_KiO2V.js +7 -0
- package/dist/assets/uk-CG74xV8N.js +16 -0
- package/dist/assets/useAppFontEffects-CPKeOpUo.js +7284 -0
- package/dist/assets/useGitComparison-DH220WmO.js +1 -0
- package/dist/assets/useInlineCommentController-BiWz4AVb.js +2 -0
- package/dist/assets/useRootScrollLock-BS4-kr7P.js +1 -0
- package/dist/assets/{vendor-base-ui-BeMD8X_w.js → vendor-base-ui-DdV8vhHn.js} +1 -1
- package/dist/assets/{vendor-codemirror-language-data-DFZik9R2.js → vendor-codemirror-language-data-Bg4AEeCr.js} +2 -2
- package/dist/assets/vendor-zod-BPAANqvH.js +39 -0
- package/dist/assets/{web-components-Bhg83tjf.js → web-components-z7hfnS8n.js} +1 -1
- package/dist/assets/zh-CN-T4AXofZI.js +16 -0
- package/dist/assets/zh-TW-Dte40sxp.js +16 -0
- package/dist/index.html +21 -59
- package/dist/mini-chat.html +7 -7
- package/dist/mobile.html +5 -5
- package/package.json +3 -4
- package/server/index.d.ts +15 -0
- package/server/index.js +158 -89
- 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/data-dir-migration.js +40 -0
- package/server/lib/data-dir-migration.test.js +59 -0
- 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 +18 -18
- package/server/lib/fs/DOCUMENTATION.md +5 -0
- package/server/lib/fs/routes.js +68 -26
- package/server/lib/fs/routes.test.js +208 -22
- package/server/lib/git/DOCUMENTATION.md +32 -6
- 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 +41 -5
- package/server/lib/git/service.js +300 -224
- package/server/lib/git/service.test.js +596 -28
- 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 +17 -10
- package/server/lib/inherited-env.test.js +10 -11
- 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 +161 -0
- package/server/lib/message-queue/runtime.js +870 -0
- package/server/lib/message-queue/runtime.test.js +482 -0
- package/server/lib/network-defaults.js +23 -0
- package/server/lib/network-defaults.test.js +52 -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 +30 -6
- package/server/lib/opencode/auth.js +1 -1
- package/server/lib/opencode/bootstrap-runtime.js +8 -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 +19 -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 +79 -19
- package/server/lib/opencode/openchamber-routes.test.js +139 -12
- 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 +19 -17
- 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-files.js +214 -0
- package/server/lib/opencode/settings-helpers.js +116 -44
- package/server/lib/opencode/settings-helpers.test.js +354 -12
- package/server/lib/opencode/settings-registry.json +747 -0
- package/server/lib/opencode/settings-runtime.js +141 -20
- package/server/lib/opencode/settings-runtime.test.js +191 -4
- 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/DOCUMENTATION.md +25 -1
- package/server/lib/project-context/routes.http.test.js +18 -0
- package/server/lib/project-context/routes.js +16 -1
- package/server/lib/project-context/runtime.js +248 -23
- package/server/lib/project-context/runtime.test.js +106 -3
- package/server/lib/projects/DOCUMENTATION.md +76 -0
- package/server/lib/projects/project-config.js +144 -11
- package/server/lib/projects/project-id.js +17 -0
- package/server/lib/projects/project-setup.js +409 -0
- package/server/lib/projects/project-setup.test.js +557 -0
- package/server/lib/projects/routes.js +59 -0
- package/server/lib/quota/DOCUMENTATION.md +40 -2
- 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/cline-pass.js +125 -0
- package/server/lib/quota/providers/cline-pass.test.js +103 -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 +22 -0
- package/server/lib/quota/providers/neuralwatt.js +3 -6
- package/server/lib/quota/providers/neuralwatt.test.js +7 -7
- package/server/lib/quota/providers/ollama-cloud.js +32 -1
- package/server/lib/quota/providers/ollama-cloud.test.js +33 -1
- package/server/lib/quota/providers/opencode-go.js +3 -2
- package/server/lib/quota/providers/opencode-go.test.js +35 -6
- package/server/lib/quota/providers/openrouter.js +119 -24
- package/server/lib/quota/providers/openrouter.test.js +330 -0
- 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 +56 -1
- package/server/lib/relay/cross-compat.test.js +26 -0
- package/server/lib/relay/downstream-scheduler.js +154 -0
- package/server/lib/relay/downstream-scheduler.test.js +162 -0
- package/server/lib/relay/e2ee.js +10 -8
- package/server/lib/relay/flow-control.test.js +177 -0
- package/server/lib/relay/host-client.js +38 -9
- 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-codec.js +9 -0
- package/server/lib/relay/tunnel-host.js +69 -18
- 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 +15 -18
- 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 +91 -30
- 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 +7 -2
- package/server/lib/small-model/call.js +18 -7
- package/server/lib/small-model/call.test.js +58 -6
- package/server/lib/small-model/index.js +12 -16
- 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/small-model/runtime-providers.js +15 -7
- package/server/lib/small-model/runtime-providers.test.js +7 -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 +14 -10
- package/server/lib/terminal/runtime.js +190 -31
- package/server/lib/terminal/runtime.test.js +572 -38
- 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/DOCUMENTATION.md +33 -14
- 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 +11 -15
- package/server/lib/walkthrough/model-settings.test.js +1 -1
- package/server/lib/walkthrough/prompt.js +3 -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/sources.js +23 -2
- 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/DiffView-DluiRSla.js +0 -4
- 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/MarkdownImageGallery-ClOvuZxC.js +0 -1
- package/dist/assets/MarkdownRendererImpl-Dt9mjTRN.js +0 -12
- package/dist/assets/OnboardingScreen-D2DG7K6b.js +0 -1
- package/dist/assets/PierreDiffViewer-B7m3f0d7.js +0 -157
- 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/WalkthroughView-egQgxel3.js +0 -4
- package/dist/assets/contextPanelEmbeddedChat-C3fjDbdg.js +0 -1
- package/dist/assets/de-C1P6X5Rs.js +0 -9
- package/dist/assets/es-CDgaF1_t.js +0 -15
- package/dist/assets/fr-Bgxqvvz_.js +0 -13
- package/dist/assets/index-C57jT0Sa.css +0 -1
- package/dist/assets/index-DW_E3rnL.js +0 -7
- package/dist/assets/ja-BDRrEcNP.js +0 -15
- package/dist/assets/ko-Ba8sQV79.js +0 -15
- package/dist/assets/main-Bv5Pkngh.js +0 -928
- package/dist/assets/markdownCore-CZwzz5gw.js +0 -3
- package/dist/assets/patchFileDiff-yNfWXN4E.js +0 -10
- package/dist/assets/pl-Dioz29BI.js +0 -15
- package/dist/assets/pt-BR-DIs6ElwV.js +0 -15
- package/dist/assets/renderElectronMiniChatApp-BcKLHXKe.js +0 -2
- package/dist/assets/renderMobileApp-D9yQJy0L.js +0 -25
- package/dist/assets/runtimeEndpointReset-CjhvxLH0.js +0 -16
- package/dist/assets/scheduledTasksApi-DLW0mkQK.js +0 -1
- package/dist/assets/tr-DFnMlPxY.js +0 -6
- package/dist/assets/uk-ZrCNjM7Y.js +0 -15
- package/dist/assets/useAppFontEffects-CjrntdL0.js +0 -7310
- package/dist/assets/useInlineCommentController-CDEuSlPH.js +0 -2
- package/dist/assets/useRootScrollLock-BHYPkrLv.js +0 -1
- package/dist/assets/vendor-ghostty-web-CrxinGGH.js +0 -13
- package/dist/assets/vendor-zod-BLfBSgBh.js +0 -39
- package/dist/assets/zh-CN-iv_AV4EC.js +0 -15
- package/dist/assets/zh-TW-CzEUk38j.js +0 -15
- 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
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const TERMINAL_SHELL_IDS = ['bash', 'zsh', 'sh', 'fish', 'pwsh', 'powershell', 'cmd', 'dash', 'ksh', 'nu'];
|
|
2
2
|
const TERMINAL_SHELL_ID_SET = new Set(TERMINAL_SHELL_IDS);
|
|
3
|
+
const isString = (value) => String(value) === value;
|
|
3
4
|
|
|
4
5
|
export const normalizeTerminalShell = (value) => {
|
|
5
6
|
if (typeof value !== 'string') return null;
|
|
@@ -24,6 +25,22 @@ export const getTerminalShellLoginArgs = (executable, platform = process.platfor
|
|
|
24
25
|
return null;
|
|
25
26
|
};
|
|
26
27
|
|
|
28
|
+
export const buildTerminalShellLaunch = (executable, { mode = 'interactive', command = null, loginShell = false, platform = process.platform } = {}) => {
|
|
29
|
+
const loginArgs = loginShell ? getTerminalShellLoginArgs(executable, platform) : [];
|
|
30
|
+
if (!loginArgs) throw new Error(`Terminal shell "${shellIdFromPath(executable) ?? executable}" does not support login mode`);
|
|
31
|
+
|
|
32
|
+
if (mode === 'interactive') return { executable, args: loginArgs };
|
|
33
|
+
|
|
34
|
+
const trimmedCommand = isString(command) ? command.trim() : '';
|
|
35
|
+
if (!trimmedCommand) throw new Error('Terminal command is required');
|
|
36
|
+
|
|
37
|
+
const id = shellIdFromPath(executable);
|
|
38
|
+
if (id === 'nu') return { executable, args: [...loginArgs, '-c', trimmedCommand] };
|
|
39
|
+
if (id === 'pwsh' || id === 'powershell') return { executable, args: [...loginArgs, '-Command', trimmedCommand] };
|
|
40
|
+
if (id === 'cmd') return { executable, args: ['/d', '/s', '/c', trimmedCommand] };
|
|
41
|
+
return { executable, args: [...loginArgs, '-i', '-c', trimmedCommand] };
|
|
42
|
+
};
|
|
43
|
+
|
|
27
44
|
export const createTerminalShellResolver = ({ fs, path, searchPathFor, isExecutable, buildAugmentedPath = () => env.PATH || '', platform = process.platform, env = process.env }) => {
|
|
28
45
|
const resolveExecutable = (candidate) => {
|
|
29
46
|
if (!candidate) return null;
|
|
@@ -35,7 +52,7 @@ export const createTerminalShellResolver = ({ fs, path, searchPathFor, isExecuta
|
|
|
35
52
|
|
|
36
53
|
const defaultCandidates = () => platform === 'win32'
|
|
37
54
|
? [
|
|
38
|
-
env.
|
|
55
|
+
env.AIWORKER_TERMINAL_SHELL,
|
|
39
56
|
env.SHELL,
|
|
40
57
|
env.ComSpec,
|
|
41
58
|
path.join(env.SystemRoot || 'C:\\Windows', 'System32', 'WindowsPowerShell', 'v1.0', 'powershell.exe'),
|
|
@@ -43,7 +60,7 @@ export const createTerminalShellResolver = ({ fs, path, searchPathFor, isExecuta
|
|
|
43
60
|
'powershell.exe',
|
|
44
61
|
'cmd.exe',
|
|
45
62
|
]
|
|
46
|
-
: [env.
|
|
63
|
+
: [env.AIWORKER_TERMINAL_SHELL, env.SHELL, '/bin/zsh', '/bin/bash', '/bin/sh', 'zsh', 'bash', 'sh'];
|
|
47
64
|
|
|
48
65
|
const resolveCandidates = (candidates) => {
|
|
49
66
|
const seen = new Set();
|
|
@@ -68,7 +85,7 @@ export const createTerminalShellResolver = ({ fs, path, searchPathFor, isExecuta
|
|
|
68
85
|
|
|
69
86
|
const candidates = platform === 'win32'
|
|
70
87
|
? [...defaultCandidates(), ...TERMINAL_SHELL_IDS]
|
|
71
|
-
: [env.
|
|
88
|
+
: [env.AIWORKER_TERMINAL_SHELL, env.SHELL, ...configuredShells, ...TERMINAL_SHELL_IDS, '/bin/zsh', '/bin/bash', '/bin/sh'];
|
|
72
89
|
const autoExecutable = resolveCandidates(defaultCandidates())[0] ?? null;
|
|
73
90
|
const byId = new Map([
|
|
74
91
|
['auto', {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import * as shells from './shells.js';
|
|
4
|
+
|
|
5
|
+
const { createTerminalShellResolver, getTerminalShellLoginArgs } = shells;
|
|
4
6
|
|
|
5
7
|
const createResolver = ({ platform = 'linux', env = {}, augmentedPath = '/augmented/bin', executables = [] } = {}) => {
|
|
6
8
|
const available = new Set(executables);
|
|
@@ -55,7 +57,7 @@ describe('terminal shell resolver', () => {
|
|
|
55
57
|
|
|
56
58
|
it('uses environment overrides before platform defaults for auto', async () => {
|
|
57
59
|
const { resolver } = createResolver({
|
|
58
|
-
env: {
|
|
60
|
+
env: { AIWORKER_TERMINAL_SHELL: '/custom/zsh', SHELL: '/bin/bash' },
|
|
59
61
|
executables: ['/custom/zsh', '/bin/bash'],
|
|
60
62
|
});
|
|
61
63
|
|
|
@@ -70,4 +72,33 @@ describe('terminal shell resolver', () => {
|
|
|
70
72
|
expect(getTerminalShellLoginArgs('C:\\Program Files\\PowerShell\\7\\pwsh.exe', 'win32')).toBeNull();
|
|
71
73
|
expect(getTerminalShellLoginArgs('/bin/dash', 'linux')).toBeNull();
|
|
72
74
|
});
|
|
75
|
+
|
|
76
|
+
it('builds interactive shell launches by shell family', () => {
|
|
77
|
+
const buildLaunch = shells.buildTerminalShellLaunch;
|
|
78
|
+
|
|
79
|
+
expect(buildLaunch('/bin/bash', { mode: 'interactive', loginShell: true, platform: 'linux' })).toEqual({ executable: '/bin/bash', args: ['-l'] });
|
|
80
|
+
expect(buildLaunch('/opt/homebrew/bin/fish', { mode: 'interactive', loginShell: true, platform: 'darwin' })).toEqual({ executable: '/opt/homebrew/bin/fish', args: ['--login'] });
|
|
81
|
+
expect(buildLaunch('/usr/bin/nu', { mode: 'interactive', loginShell: true, platform: 'linux' })).toEqual({ executable: '/usr/bin/nu', args: ['--login'] });
|
|
82
|
+
expect(buildLaunch('/usr/bin/pwsh', { mode: 'interactive', loginShell: true, platform: 'linux' })).toEqual({ executable: '/usr/bin/pwsh', args: ['-Login'] });
|
|
83
|
+
expect(buildLaunch('C:\\Windows\\System32\\cmd.exe', { mode: 'interactive', loginShell: false, platform: 'win32' })).toEqual({ executable: 'C:\\Windows\\System32\\cmd.exe', args: [] });
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('builds command launches by shell family', () => {
|
|
87
|
+
const buildLaunch = shells.buildTerminalShellLaunch;
|
|
88
|
+
|
|
89
|
+
expect(buildLaunch('/bin/zsh', { mode: 'command', command: 'printf ready', loginShell: true, platform: 'linux' })).toEqual({ executable: '/bin/zsh', args: ['-l', '-i', '-c', 'printf ready'] });
|
|
90
|
+
expect(buildLaunch('/opt/homebrew/bin/fish', { mode: 'command', command: 'echo ready', loginShell: true, platform: 'darwin' })).toEqual({ executable: '/opt/homebrew/bin/fish', args: ['--login', '-i', '-c', 'echo ready'] });
|
|
91
|
+
expect(buildLaunch('/usr/bin/nu', { mode: 'command', command: 'ls', loginShell: true, platform: 'linux' })).toEqual({ executable: '/usr/bin/nu', args: ['--login', '-c', 'ls'] });
|
|
92
|
+
expect(buildLaunch('/usr/bin/pwsh', { mode: 'command', command: 'Get-ChildItem', loginShell: true, platform: 'linux' })).toEqual({ executable: '/usr/bin/pwsh', args: ['-Login', '-Command', 'Get-ChildItem'] });
|
|
93
|
+
expect(buildLaunch('C:\\Program Files\\PowerShell\\7\\pwsh.exe', { mode: 'command', command: 'Get-Date', loginShell: false, platform: 'win32' })).toEqual({ executable: 'C:\\Program Files\\PowerShell\\7\\pwsh.exe', args: ['-Command', 'Get-Date'] });
|
|
94
|
+
expect(buildLaunch('C:\\Windows\\System32\\cmd.exe', { mode: 'command', command: 'dir', loginShell: false, platform: 'win32' })).toEqual({ executable: 'C:\\Windows\\System32\\cmd.exe', args: ['/d', '/s', '/c', 'dir'] });
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('rejects unsupported login and command combinations', () => {
|
|
98
|
+
const buildLaunch = shells.buildTerminalShellLaunch;
|
|
99
|
+
|
|
100
|
+
expect(() => buildLaunch('/bin/sh', { mode: 'interactive', loginShell: true, platform: 'linux' })).toThrow('does not support login mode');
|
|
101
|
+
expect(() => buildLaunch('/bin/dash', { mode: 'command', command: 'pwd', loginShell: true, platform: 'linux' })).toThrow('does not support login mode');
|
|
102
|
+
expect(() => buildLaunch('/bin/bash', { mode: 'command', command: '', loginShell: false, platform: 'linux' })).toThrow('Terminal command is required');
|
|
103
|
+
});
|
|
73
104
|
});
|
|
@@ -47,13 +47,13 @@ export const normalizeCustomOpenAIBaseURL = (value) => {
|
|
|
47
47
|
return { error: 'Custom server URL must not include credentials' };
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
const isDesktop = (process.env.
|
|
51
|
-
const envFlagRaw = process.env.
|
|
50
|
+
const isDesktop = (process.env.AIWORKER_RUNTIME || '').trim().toLowerCase() === 'desktop';
|
|
51
|
+
const envFlagRaw = process.env.AIWORKER_ALLOW_REMOTE_OPENAI_COMPAT_URLS;
|
|
52
52
|
const hasExplicitFlag = typeof envFlagRaw === 'string' && envFlagRaw.trim().length > 0;
|
|
53
53
|
const allowRemote = hasExplicitFlag ? isEnvFlagEnabled(envFlagRaw) : isDesktop;
|
|
54
54
|
if (!allowRemote && !isAllowedLocalHost(parsed.hostname)) {
|
|
55
55
|
return {
|
|
56
|
-
error: 'Remote custom server URLs are disabled. Set
|
|
56
|
+
error: 'Remote custom server URLs are disabled. Set AIWORKER_ALLOW_REMOTE_OPENAI_COMPAT_URLS=true to allow this host.',
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
59
|
|
|
@@ -97,44 +97,44 @@ describe('tts routes', () => {
|
|
|
97
97
|
});
|
|
98
98
|
|
|
99
99
|
describe('normalizeCustomOpenAIBaseURL', () => {
|
|
100
|
-
const originalRuntime = process.env.
|
|
101
|
-
const originalAllowRemote = process.env.
|
|
100
|
+
const originalRuntime = process.env.AIWORKER_RUNTIME;
|
|
101
|
+
const originalAllowRemote = process.env.AIWORKER_ALLOW_REMOTE_OPENAI_COMPAT_URLS;
|
|
102
102
|
|
|
103
103
|
afterEach(() => {
|
|
104
104
|
// Restore env vars after each test
|
|
105
105
|
if (originalRuntime === undefined) {
|
|
106
|
-
delete process.env.
|
|
106
|
+
delete process.env.AIWORKER_RUNTIME;
|
|
107
107
|
} else {
|
|
108
|
-
process.env.
|
|
108
|
+
process.env.AIWORKER_RUNTIME = originalRuntime;
|
|
109
109
|
}
|
|
110
110
|
if (originalAllowRemote === undefined) {
|
|
111
|
-
delete process.env.
|
|
111
|
+
delete process.env.AIWORKER_ALLOW_REMOTE_OPENAI_COMPAT_URLS;
|
|
112
112
|
} else {
|
|
113
|
-
process.env.
|
|
113
|
+
process.env.AIWORKER_ALLOW_REMOTE_OPENAI_COMPAT_URLS = originalAllowRemote;
|
|
114
114
|
}
|
|
115
115
|
});
|
|
116
116
|
|
|
117
|
-
it('rejects remote URLs when
|
|
118
|
-
delete process.env.
|
|
119
|
-
delete process.env.
|
|
117
|
+
it('rejects remote URLs when AIWORKER_RUNTIME is not set (web)', () => {
|
|
118
|
+
delete process.env.AIWORKER_RUNTIME;
|
|
119
|
+
delete process.env.AIWORKER_ALLOW_REMOTE_OPENAI_COMPAT_URLS;
|
|
120
120
|
|
|
121
121
|
const result = normalizeCustomOpenAIBaseURL('https://my-tts-server.example.com/v1');
|
|
122
122
|
expect(result.error).toMatch(/Remote custom server URLs are disabled/);
|
|
123
123
|
expect(result.value).toBeUndefined();
|
|
124
124
|
});
|
|
125
125
|
|
|
126
|
-
it('allows remote URLs when
|
|
127
|
-
process.env.
|
|
128
|
-
delete process.env.
|
|
126
|
+
it('allows remote URLs when AIWORKER_RUNTIME is desktop', () => {
|
|
127
|
+
process.env.AIWORKER_RUNTIME = 'desktop';
|
|
128
|
+
delete process.env.AIWORKER_ALLOW_REMOTE_OPENAI_COMPAT_URLS;
|
|
129
129
|
|
|
130
130
|
const result = normalizeCustomOpenAIBaseURL('https://my-tts-server.example.com/v1');
|
|
131
131
|
expect(result.error).toBeUndefined();
|
|
132
132
|
expect(result.value).toBe('https://my-tts-server.example.com/v1');
|
|
133
133
|
});
|
|
134
134
|
|
|
135
|
-
it('allows remote URLs when
|
|
136
|
-
delete process.env.
|
|
137
|
-
process.env.
|
|
135
|
+
it('allows remote URLs when AIWORKER_ALLOW_REMOTE_OPENAI_COMPAT_URLS is true', () => {
|
|
136
|
+
delete process.env.AIWORKER_RUNTIME;
|
|
137
|
+
process.env.AIWORKER_ALLOW_REMOTE_OPENAI_COMPAT_URLS = 'true';
|
|
138
138
|
|
|
139
139
|
const result = normalizeCustomOpenAIBaseURL('https://my-tts-server.example.com/v1');
|
|
140
140
|
expect(result.error).toBeUndefined();
|
|
@@ -142,8 +142,8 @@ describe('normalizeCustomOpenAIBaseURL', () => {
|
|
|
142
142
|
});
|
|
143
143
|
|
|
144
144
|
it('allows localhost URLs regardless of runtime', () => {
|
|
145
|
-
delete process.env.
|
|
146
|
-
delete process.env.
|
|
145
|
+
delete process.env.AIWORKER_RUNTIME;
|
|
146
|
+
delete process.env.AIWORKER_ALLOW_REMOTE_OPENAI_COMPAT_URLS;
|
|
147
147
|
|
|
148
148
|
const result = normalizeCustomOpenAIBaseURL('http://localhost:8880/v1');
|
|
149
149
|
expect(result.error).toBeUndefined();
|
|
@@ -151,15 +151,15 @@ describe('normalizeCustomOpenAIBaseURL', () => {
|
|
|
151
151
|
});
|
|
152
152
|
|
|
153
153
|
it('strips query strings and trailing slashes', () => {
|
|
154
|
-
process.env.
|
|
154
|
+
process.env.AIWORKER_RUNTIME = 'desktop';
|
|
155
155
|
|
|
156
156
|
const result = normalizeCustomOpenAIBaseURL('https://my-server.com/v1/?key=123');
|
|
157
157
|
expect(result.value).toBe('https://my-server.com/v1');
|
|
158
158
|
});
|
|
159
159
|
|
|
160
160
|
it('denies remote URLs on desktop when env var is explicitly false', () => {
|
|
161
|
-
process.env.
|
|
162
|
-
process.env.
|
|
161
|
+
process.env.AIWORKER_RUNTIME = 'desktop';
|
|
162
|
+
process.env.AIWORKER_ALLOW_REMOTE_OPENAI_COMPAT_URLS = 'false';
|
|
163
163
|
|
|
164
164
|
const result = normalizeCustomOpenAIBaseURL('https://my-tts-server.example.com/v1');
|
|
165
165
|
expect(result.error).toMatch(/Remote custom server URLs are disabled/);
|
|
@@ -12,10 +12,10 @@ const URL_AUTH_TOKEN_TTL_MS = 60 * 1000;
|
|
|
12
12
|
const URL_AUTH_TOKEN_PREFIX = 'oc_url_';
|
|
13
13
|
|
|
14
14
|
const RATE_LIMIT_WINDOW_MS = 5 * 60 * 1000;
|
|
15
|
-
const RATE_LIMIT_MAX_ATTEMPTS = Number(process.env.
|
|
15
|
+
const RATE_LIMIT_MAX_ATTEMPTS = Number(process.env.AIWORKER_RATE_LIMIT_MAX_ATTEMPTS) || 10;
|
|
16
16
|
const RATE_LIMIT_LOCKOUT_MS = 15 * 60 * 1000;
|
|
17
17
|
const RATE_LIMIT_CLEANUP_MS = 60 * 60 * 1000;
|
|
18
|
-
const RATE_LIMIT_NO_IP_MAX_ATTEMPTS = Number(process.env.
|
|
18
|
+
const RATE_LIMIT_NO_IP_MAX_ATTEMPTS = Number(process.env.AIWORKER_RATE_LIMIT_NO_IP_MAX_ATTEMPTS) || 3;
|
|
19
19
|
|
|
20
20
|
const loginRateLimiter = new Map();
|
|
21
21
|
let rateLimitCleanupTimer = null;
|
|
@@ -310,6 +310,7 @@ const isUrlAuthWebSocketPath = (pathname) => {
|
|
|
310
310
|
|| pathname === '/api/openchamber/realtime-proxy/ws'
|
|
311
311
|
|| pathname === '/api/terminal/ws'
|
|
312
312
|
|| pathname === '/api/dictation/ws'
|
|
313
|
+
|| pathname === '/api/dev-tunnel'
|
|
313
314
|
|| pathname.startsWith('/api/preview/proxy/');
|
|
314
315
|
};
|
|
315
316
|
|
|
@@ -361,10 +362,10 @@ const normalizePassword = (candidate) => {
|
|
|
361
362
|
|
|
362
363
|
const isTrustedDeviceRequest = (value) => value === true;
|
|
363
364
|
|
|
364
|
-
const
|
|
365
|
-
? path.resolve(process.env.
|
|
366
|
-
: path.join(os.homedir(), '.config', '
|
|
367
|
-
const JWT_SECRET_FILE = path.join(
|
|
365
|
+
const AIWORKER_DATA_DIR = process.env.AIWORKER_DATA_DIR
|
|
366
|
+
? path.resolve(process.env.AIWORKER_DATA_DIR)
|
|
367
|
+
: path.join(os.homedir(), '.config', 'aiworker');
|
|
368
|
+
const JWT_SECRET_FILE = path.join(AIWORKER_DATA_DIR, 'jwt-secret');
|
|
368
369
|
|
|
369
370
|
function getOrCreateJwtSecret() {
|
|
370
371
|
const envSecret = process.env.OPENCODE_JWT_SECRET;
|
|
@@ -382,7 +383,7 @@ function getOrCreateJwtSecret() {
|
|
|
382
383
|
|
|
383
384
|
const secret = crypto.randomBytes(32).toString('hex');
|
|
384
385
|
try {
|
|
385
|
-
fs.mkdirSync(
|
|
386
|
+
fs.mkdirSync(AIWORKER_DATA_DIR, { recursive: true });
|
|
386
387
|
fs.writeFileSync(JWT_SECRET_FILE, secret, { mode: 0o600 });
|
|
387
388
|
console.log('[JWT] Generated and persisted new secret to', JWT_SECRET_FILE);
|
|
388
389
|
} catch (e) {
|
|
@@ -399,7 +400,7 @@ function persistJwtSecret(secret) {
|
|
|
399
400
|
throw error;
|
|
400
401
|
}
|
|
401
402
|
|
|
402
|
-
fs.mkdirSync(
|
|
403
|
+
fs.mkdirSync(AIWORKER_DATA_DIR, { recursive: true });
|
|
403
404
|
fs.writeFileSync(JWT_SECRET_FILE, secret, { mode: 0o600 });
|
|
404
405
|
return new TextEncoder().encode(secret);
|
|
405
406
|
}
|
|
@@ -984,7 +985,9 @@ export const createUiAuth = ({
|
|
|
984
985
|
handlePasskeyList,
|
|
985
986
|
handlePasskeyRevoke,
|
|
986
987
|
handleResetAuth,
|
|
987
|
-
ensureSessionToken:
|
|
988
|
+
ensureSessionToken: (req, _res) => {
|
|
989
|
+
const urlAuth = authenticateUrlAuthToken(req);
|
|
990
|
+
if (urlAuth) return clientSessionToken(urlAuth);
|
|
988
991
|
return resolveAuthenticatedSessionToken(req);
|
|
989
992
|
},
|
|
990
993
|
dispose,
|
|
@@ -4,7 +4,7 @@ import os from 'node:os';
|
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
|
|
6
6
|
const dataDir = fs.mkdtempSync(path.join(os.tmpdir(), 'openchamber-ui-auth-test-'));
|
|
7
|
-
process.env.
|
|
7
|
+
process.env.AIWORKER_DATA_DIR = dataDir;
|
|
8
8
|
|
|
9
9
|
afterAll(() => {
|
|
10
10
|
fs.rmSync(dataDir, { recursive: true, force: true });
|
|
@@ -221,6 +221,22 @@ describe('ui auth client credential seam', () => {
|
|
|
221
221
|
};
|
|
222
222
|
expect(await auth.ensureSessionToken(dictationWsReq, null)).toBe('client:device-1');
|
|
223
223
|
|
|
224
|
+
const devTunnelWsReq = {
|
|
225
|
+
method: 'GET',
|
|
226
|
+
path: '/api/dev-tunnel',
|
|
227
|
+
url: `/api/dev-tunnel?port=4322&oc_url_token=${encodeURIComponent(urlToken)}`,
|
|
228
|
+
headers: { upgrade: 'websocket' },
|
|
229
|
+
};
|
|
230
|
+
expect(await auth.ensureSessionToken(devTunnelWsReq, null)).toBe('client:device-1');
|
|
231
|
+
|
|
232
|
+
const devTunnelSubpathWsReq = {
|
|
233
|
+
method: 'GET',
|
|
234
|
+
path: '/api/dev-tunnel/private',
|
|
235
|
+
url: `/api/dev-tunnel/private?port=4322&oc_url_token=${encodeURIComponent(urlToken)}`,
|
|
236
|
+
headers: { upgrade: 'websocket' },
|
|
237
|
+
};
|
|
238
|
+
expect(await auth.ensureSessionToken(devTunnelSubpathWsReq, null)).toBe(null);
|
|
239
|
+
|
|
224
240
|
const dictationHttpReq = {
|
|
225
241
|
method: 'GET',
|
|
226
242
|
path: '/api/dictation/ws',
|
|
@@ -287,7 +303,7 @@ describe('ui auth client credential seam', () => {
|
|
|
287
303
|
body: {
|
|
288
304
|
password: 'secret',
|
|
289
305
|
issueClientToken: true,
|
|
290
|
-
clientLabel: '
|
|
306
|
+
clientLabel: 'AiWorker Desktop',
|
|
291
307
|
},
|
|
292
308
|
};
|
|
293
309
|
const res = createResponse();
|
|
@@ -295,7 +311,7 @@ describe('ui auth client credential seam', () => {
|
|
|
295
311
|
await auth.handleSessionCreate(req, res);
|
|
296
312
|
|
|
297
313
|
expect(res.body.clientToken).toBe('client-token');
|
|
298
|
-
expect(createClientInput.fallbackLabel).toBe('
|
|
314
|
+
expect(createClientInput.fallbackLabel).toBe('AiWorker Desktop');
|
|
299
315
|
const expiresAt = Date.parse(createClientInput.expiresAt);
|
|
300
316
|
expect(expiresAt).toBeGreaterThanOrEqual(before + 122_000);
|
|
301
317
|
expect(expiresAt).toBeLessThanOrEqual(Date.now() + 124_000);
|
|
@@ -11,13 +11,13 @@ import {
|
|
|
11
11
|
|
|
12
12
|
const DEFAULT_STORE_VERSION = 1;
|
|
13
13
|
const DEFAULT_CHALLENGE_TTL_MS = 5 * 60 * 1000;
|
|
14
|
-
const DEFAULT_RP_NAME = '
|
|
14
|
+
const DEFAULT_RP_NAME = 'AiWorker';
|
|
15
15
|
|
|
16
|
-
const
|
|
17
|
-
? path.resolve(process.env.
|
|
18
|
-
: path.join(os.homedir(), '.config', '
|
|
16
|
+
const AIWORKER_DATA_DIR = process.env.AIWORKER_DATA_DIR
|
|
17
|
+
? path.resolve(process.env.AIWORKER_DATA_DIR)
|
|
18
|
+
: path.join(os.homedir(), '.config', 'aiworker');
|
|
19
19
|
|
|
20
|
-
const PASSKEY_STORE_FILE = path.join(
|
|
20
|
+
const PASSKEY_STORE_FILE = path.join(AIWORKER_DATA_DIR, 'ui-passkeys.json');
|
|
21
21
|
|
|
22
22
|
const createUserId = () => crypto.randomBytes(32).toString('base64url');
|
|
23
23
|
|
|
@@ -331,7 +331,7 @@ export const createUiPasskeys = ({
|
|
|
331
331
|
rpID,
|
|
332
332
|
userID,
|
|
333
333
|
userName: 'openchamber-ui',
|
|
334
|
-
userDisplayName: '
|
|
334
|
+
userDisplayName: 'AiWorker UI',
|
|
335
335
|
attestationType: 'none',
|
|
336
336
|
excludeCredentials: getPasskeysForRpId(store, rpID).map((passkey) => ({
|
|
337
337
|
id: passkey.id,
|
|
@@ -471,7 +471,7 @@ export const createUiPasskeys = ({
|
|
|
471
471
|
const passkey = store.passkeys.find((item) => item.id === response?.id);
|
|
472
472
|
|
|
473
473
|
if (!passkey) {
|
|
474
|
-
const error = new Error('That passkey is not registered for this
|
|
474
|
+
const error = new Error('That passkey is not registered for this AiWorker instance');
|
|
475
475
|
error.statusCode = 404;
|
|
476
476
|
throw error;
|
|
477
477
|
}
|
|
@@ -52,20 +52,39 @@ written against staged code never silently re-anchors onto an unstaged edit.
|
|
|
52
52
|
| Kind | Sections | Notes |
|
|
53
53
|
|---|---|---|
|
|
54
54
|
| `working-tree` (`all` \| `staged` \| `working`) | `staged`, `working` | Untracked files are fetched individually because `git diff` omits them |
|
|
55
|
-
| `branch` | `branch` | `getRangeDiff`
|
|
56
|
-
| `
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
the current branch's
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
55
|
+
| `branch` | `branch` | `getRangeDiff` with `includeWorkingTree: true` compares the selected merge base with current files, including committed and local work in one net diff |
|
|
56
|
+
| `commit` | `commit` | `getCommitDiff` compares the full selected commit hash with its first parent; root commits compare with an empty tree |
|
|
57
|
+
| `pr` | `pr:<number>` | GitHub's committed pull-request diff, without local working-tree changes |
|
|
58
|
+
|
|
59
|
+
Changes and walkthrough resolve the current branch's base through
|
|
60
|
+
`packages/ui/src/hooks/useBranchComparisonBase.ts`. An explicit choice in Changes
|
|
61
|
+
outranks reflog detection. Both toolbars use
|
|
62
|
+
`packages/ui/src/components/views/git/BranchComparisonSelector.tsx` to select or
|
|
63
|
+
change the base directly. Walkthrough allows selecting Branch before a base is
|
|
64
|
+
known and waits for a valid choice before loading or generating. Opening
|
|
65
|
+
walkthrough from Changes carries the selected base and head; later selections
|
|
66
|
+
in either toolbar update both comparisons.
|
|
67
|
+
|
|
68
|
+
Commit mode uses the shared `CommitComparisonSelector` in both toolbars. It
|
|
69
|
+
lists the latest 50 commits reachable from the checked-out branch, with subject,
|
|
70
|
+
author, date, and short hash. Opening the picker refreshes that list; selecting a
|
|
71
|
+
commit changes the comparison, not the checkout. Changes hands the selected full
|
|
72
|
+
hash to walkthrough. The server accepts full object IDs for commit sources and
|
|
73
|
+
keys their cache entries and generation jobs as `commit:<hash>`, so reviews of
|
|
74
|
+
different commits cannot overwrite each other. Existing source keys keep their
|
|
75
|
+
format. Commit reads have no working-tree freshness dependency, and selecting a
|
|
76
|
+
commit never starts model generation.
|
|
77
|
+
|
|
78
|
+
The Git module owns exact-ref and working-tree comparison semantics. Local and
|
|
79
|
+
remote bases remain distinct, and a checkout during a branch review requires
|
|
80
|
+
the source to be resolved for the new branch rather than including another
|
|
81
|
+
branch's local files.
|
|
82
|
+
|
|
83
|
+
Successful status refreshes invalidate the visible branch comparison even when
|
|
84
|
+
file names and insertion/deletion counts stay the same. Walkthrough refreshes
|
|
85
|
+
its current hunk index while visible; regeneration remains user-initiated. The
|
|
86
|
+
content-addressed cache continues to reuse an old review only when its hunks
|
|
87
|
+
match, and otherwise reports stale anchors and uncovered current hunks.
|
|
69
88
|
|
|
70
89
|
The panel offers the current branch's pull request on its own: it registers with
|
|
71
90
|
the shared GitHub PR status store (`useGitHubPrStatusStore`) rather than waiting
|
|
@@ -474,6 +474,7 @@ async function runGeneration({ directory, source, repoRoot, key, force, explicit
|
|
|
474
474
|
prompt: options.prompt,
|
|
475
475
|
system: options.system,
|
|
476
476
|
directory,
|
|
477
|
+
sessionID: `openchamber-walkthrough-${cacheKey}`,
|
|
477
478
|
model: `${model.providerID}/${model.modelID}`,
|
|
478
479
|
responseSchema: options.responseSchema,
|
|
479
480
|
onOverflow: 'error',
|
|
@@ -4,7 +4,7 @@ import path from 'path';
|
|
|
4
4
|
import { afterAll, afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
5
5
|
|
|
6
6
|
const TEMP_DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'walkthrough-jobs-'));
|
|
7
|
-
process.env.
|
|
7
|
+
process.env.AIWORKER_DATA_DIR = TEMP_DATA_DIR;
|
|
8
8
|
|
|
9
9
|
// Mocking git rather than this module's own source loading: fewer of our own
|
|
10
10
|
// seams faked means the test exercises the real digest and prompt path.
|
|
@@ -4,7 +4,7 @@ import path from 'path';
|
|
|
4
4
|
import { afterAll, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
5
5
|
|
|
6
6
|
const TEMP_DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'walkthrough-language-'));
|
|
7
|
-
process.env.
|
|
7
|
+
process.env.AIWORKER_DATA_DIR = TEMP_DATA_DIR;
|
|
8
8
|
|
|
9
9
|
vi.mock('../git/service.js', () => ({
|
|
10
10
|
getRepositoryRoot: vi.fn(async () => '/repo'),
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import os from 'os';
|
|
3
3
|
import path from 'path';
|
|
4
|
+
import { readMergedSettingsSync } from '../opencode/settings-files.js';
|
|
4
5
|
|
|
5
6
|
// The walkthrough may run on a different model than the rest of the small-model
|
|
6
7
|
// callers. Those callers want cheap and fast; this one needs structured output
|
|
@@ -8,9 +9,9 @@ import path from 'path';
|
|
|
8
9
|
// means the user has to degrade one feature to fix the other.
|
|
9
10
|
|
|
10
11
|
const SETTINGS_FILE = path.join(
|
|
11
|
-
process.env.
|
|
12
|
-
? path.resolve(process.env.
|
|
13
|
-
: path.join(os.homedir(), '.config', '
|
|
12
|
+
process.env.AIWORKER_DATA_DIR
|
|
13
|
+
? path.resolve(process.env.AIWORKER_DATA_DIR)
|
|
14
|
+
: path.join(os.homedir(), '.config', 'aiworker'),
|
|
14
15
|
'settings.json',
|
|
15
16
|
);
|
|
16
17
|
|
|
@@ -23,16 +24,11 @@ const SETTINGS_FILE = path.join(
|
|
|
23
24
|
* not use the small model" with nothing to use instead.
|
|
24
25
|
*/
|
|
25
26
|
export function readWalkthroughModelOverride() {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
} catch {
|
|
34
|
-
// No settings file, unreadable, or malformed all mean the same thing: no
|
|
35
|
-
// override, use the small model.
|
|
36
|
-
return null;
|
|
37
|
-
}
|
|
27
|
+
// No settings file, unreadable, or malformed all mean the same thing: no
|
|
28
|
+
// override, use the small model.
|
|
29
|
+
const settings = readMergedSettingsSync({ fs, path, settingsFilePath: SETTINGS_FILE });
|
|
30
|
+
const override = typeof settings.walkthroughModelOverride === 'string'
|
|
31
|
+
? settings.walkthroughModelOverride.trim()
|
|
32
|
+
: '';
|
|
33
|
+
return override || null;
|
|
38
34
|
}
|
|
@@ -4,7 +4,7 @@ import path from 'path';
|
|
|
4
4
|
import { afterAll, beforeEach, describe, expect, it } from 'vitest';
|
|
5
5
|
|
|
6
6
|
const TEMP_DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'walkthrough-model-settings-'));
|
|
7
|
-
process.env.
|
|
7
|
+
process.env.AIWORKER_DATA_DIR = TEMP_DATA_DIR;
|
|
8
8
|
|
|
9
9
|
const { readWalkthroughModelOverride } = await import('./model-settings.js');
|
|
10
10
|
|
|
@@ -86,7 +86,9 @@ export function buildPrompt({ digest, fileCount, hunkCount, source, previousWalk
|
|
|
86
86
|
? `Uncommitted local changes (${source.scope === 'all' ? 'staged and unstaged' : source.scope}).`
|
|
87
87
|
: source.kind === 'branch'
|
|
88
88
|
? `All work on branch "${source.headRef}" that is not in "${source.baseRef}". Changes merged in from ${source.baseRef} are already excluded.`
|
|
89
|
-
:
|
|
89
|
+
: source.kind === 'commit'
|
|
90
|
+
? `Only the changes introduced by commit ${source.hash}, relative to its first parent (or the empty tree for a root commit).`
|
|
91
|
+
: `Pull request #${source.number}.`;
|
|
90
92
|
|
|
91
93
|
const prompt = `Reviewing: ${sourceLine}
|
|
92
94
|
|
|
@@ -24,8 +24,8 @@ describe('getPullRequestDiff', () => {
|
|
|
24
24
|
// wrapper made every repository look remote-less, which is what this suite
|
|
25
25
|
// exists to prevent.
|
|
26
26
|
resolveGitHubRepoFromDirectory.mockResolvedValue({
|
|
27
|
-
repo: { owner: '
|
|
28
|
-
remoteUrl: 'git@github.com:
|
|
27
|
+
repo: { owner: 'aiworker', repo: 'aiworker' },
|
|
28
|
+
remoteUrl: 'git@github.com:aiworker/openchamber.git',
|
|
29
29
|
});
|
|
30
30
|
});
|
|
31
31
|
|
|
@@ -37,10 +37,10 @@ describe('getPullRequestDiff', () => {
|
|
|
37
37
|
const result = await getPullRequestDiff('/repo', 2122);
|
|
38
38
|
|
|
39
39
|
expect(result.patch).toBe(PATCH);
|
|
40
|
-
expect(result.meta).toEqual({ owner: '
|
|
40
|
+
expect(result.meta).toEqual({ owner: 'aiworker', repo: 'aiworker', number: 2122 });
|
|
41
41
|
expect(request).toHaveBeenCalledWith('GET /repos/{owner}/{repo}/pulls/{pull_number}', {
|
|
42
|
-
owner: '
|
|
43
|
-
repo: '
|
|
42
|
+
owner: 'aiworker',
|
|
43
|
+
repo: 'aiworker',
|
|
44
44
|
pull_number: 2122,
|
|
45
45
|
headers: { accept: 'application/vnd.github.v3.diff' },
|
|
46
46
|
});
|
|
@@ -6,7 +6,7 @@ import express from 'express';
|
|
|
6
6
|
import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest';
|
|
7
7
|
|
|
8
8
|
// ---------------------------------------------------------------------------
|
|
9
|
-
// Regression for https://
|
|
9
|
+
// Regression for https://roweb.cn/roweb/openchamber/issues/2607
|
|
10
10
|
// "[Bug] Why say so?" (walkthrough panel)
|
|
11
11
|
//
|
|
12
12
|
// Before the fix, a walkthrough small model whose provider had no usable login
|
|
@@ -20,7 +20,7 @@ import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest';
|
|
|
20
20
|
|
|
21
21
|
const TEMP_HOME = fs.mkdtempSync(path.join(os.tmpdir(), 'oc-home-2607-'));
|
|
22
22
|
process.env.HOME = TEMP_HOME;
|
|
23
|
-
process.env.
|
|
23
|
+
process.env.AIWORKER_DATA_DIR = path.join(TEMP_HOME, '.config', 'aiworker');
|
|
24
24
|
|
|
25
25
|
const CATALOG = {
|
|
26
26
|
deepseek: {
|