@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,8 +1,19 @@
|
|
|
1
|
+
import { execFileSync } from 'node:child_process';
|
|
2
|
+
import { mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync } from 'node:fs';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import { dirname, join } from 'node:path';
|
|
5
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
1
6
|
import { describe, expect, it } from 'vitest';
|
|
2
7
|
|
|
8
|
+
import {
|
|
9
|
+
DEFAULT_INPUT_HISTORY_LIMIT,
|
|
10
|
+
} from './input-history-scope.js';
|
|
3
11
|
import { createSettingsHelpers } from './settings-helpers.js';
|
|
4
12
|
import { createSettingsNormalizationRuntime } from './settings-normalization-runtime.js';
|
|
5
13
|
|
|
14
|
+
const testFilePath = fileURLToPath(import.meta.url);
|
|
15
|
+
const packagesWebDir = join(dirname(testFilePath), '..', '..', '..');
|
|
16
|
+
|
|
6
17
|
const createTestHelpers = () => createSettingsHelpers({
|
|
7
18
|
normalizePathForPersistence: (value) => value,
|
|
8
19
|
normalizeDirectoryPath: (value) => value,
|
|
@@ -58,6 +69,79 @@ const createTestHelpersWithRealSanitizers = () => {
|
|
|
58
69
|
};
|
|
59
70
|
|
|
60
71
|
describe('settings helpers', () => {
|
|
72
|
+
it('round-trips telemetry opt-in with the hidden list and preserves it across unrelated writes', () => {
|
|
73
|
+
const helpers = createTestHelpers();
|
|
74
|
+
const legacy = helpers.sanitizeSettingsUpdate({ workStatusHiddenSections: [] });
|
|
75
|
+
expect(legacy.workStatusHiddenSectionsExplicit).toBeUndefined();
|
|
76
|
+
const changes = helpers.sanitizeSettingsUpdate({ workStatusHiddenSections: [], workStatusHiddenSectionsExplicit: true });
|
|
77
|
+
const saved = helpers.mergePersistedSettings(legacy, changes);
|
|
78
|
+
const reloaded = helpers.formatSettingsResponse(JSON.parse(JSON.stringify(saved)));
|
|
79
|
+
expect(reloaded.workStatusHiddenSections).toEqual([]);
|
|
80
|
+
expect(reloaded.workStatusHiddenSectionsExplicit).toBe(true);
|
|
81
|
+
const next = helpers.mergePersistedSettings(reloaded, helpers.sanitizeSettingsUpdate({ workStatusPanelEnabled: false }));
|
|
82
|
+
expect(helpers.formatSettingsResponse(next).workStatusHiddenSectionsExplicit).toBe(true);
|
|
83
|
+
expect(helpers.sanitizeSettingsUpdate({ workStatusHiddenSectionsExplicit: 'true' }).workStatusHiddenSectionsExplicit).toBeUndefined();
|
|
84
|
+
});
|
|
85
|
+
it('imports from the packed @aiworker/web tarball without escaping the published package', async () => {
|
|
86
|
+
const tempRoot = mkdtempSync(join(tmpdir(), 'settings-helpers-pack-'));
|
|
87
|
+
const packDir = join(tempRoot, 'pack');
|
|
88
|
+
const extractDir = join(tempRoot, 'extract');
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
mkdirSync(packDir);
|
|
92
|
+
mkdirSync(extractDir);
|
|
93
|
+
execFileSync('npm', ['pack', '--silent', '--pack-destination', packDir], {
|
|
94
|
+
cwd: packagesWebDir,
|
|
95
|
+
stdio: 'pipe',
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
const tarballName = readdirSync(packDir).find((entry) => entry.endsWith('.tgz'));
|
|
99
|
+
expect(tarballName).toBeTruthy();
|
|
100
|
+
|
|
101
|
+
execFileSync('tar', ['-xzf', join(packDir, tarballName), '-C', extractDir], {
|
|
102
|
+
stdio: 'pipe',
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
const extractedModule = await import(
|
|
106
|
+
pathToFileURL(join(extractDir, 'package', 'server', 'lib', 'opencode', 'settings-helpers.js')).href
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
const helpers = extractedModule.createSettingsHelpers({
|
|
110
|
+
normalizePathForPersistence: (value) => value,
|
|
111
|
+
normalizeDirectoryPath: (value) => value,
|
|
112
|
+
normalizeTunnelBootstrapTtlMs: (value) => value,
|
|
113
|
+
normalizeTunnelSessionTtlMs: (value) => value,
|
|
114
|
+
normalizeTunnelProvider: (value) => value,
|
|
115
|
+
normalizeTunnelMode: (value) => value,
|
|
116
|
+
normalizeOptionalPath: (value) => value,
|
|
117
|
+
normalizeManagedRemoteTunnelHostname: (value) => value,
|
|
118
|
+
normalizeManagedRemoteTunnelPresets: () => undefined,
|
|
119
|
+
normalizeManagedRemoteTunnelPresetTokens: () => undefined,
|
|
120
|
+
sanitizeTypographySizesPartial: () => undefined,
|
|
121
|
+
normalizeStringArray: (input) => input,
|
|
122
|
+
sanitizeModelRefs: () => undefined,
|
|
123
|
+
sanitizeSkillCatalogs: () => undefined,
|
|
124
|
+
sanitizeProjects: () => undefined,
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
expect(helpers.sanitizeSettingsUpdate({ inputHistoryScope: 'global' })).toEqual({
|
|
128
|
+
inputHistoryScope: 'global',
|
|
129
|
+
});
|
|
130
|
+
expect(helpers.sanitizeSettingsUpdate({ inputHistoryScope: 'session' })).toEqual({
|
|
131
|
+
inputHistoryScope: 'session',
|
|
132
|
+
});
|
|
133
|
+
expect(helpers.sanitizeSettingsUpdate({ inputHistoryLimit: 40 })).toEqual({
|
|
134
|
+
inputHistoryLimit: 40,
|
|
135
|
+
});
|
|
136
|
+
expect(helpers.formatSettingsResponse({})).toMatchObject({
|
|
137
|
+
inputHistoryScope: 'session',
|
|
138
|
+
inputHistoryLimit: DEFAULT_INPUT_HISTORY_LIMIT,
|
|
139
|
+
});
|
|
140
|
+
} finally {
|
|
141
|
+
rmSync(tempRoot, { recursive: true, force: true });
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
|
|
61
145
|
it('accepts only booleans for draft starter visibility', () => {
|
|
62
146
|
const helpers = createTestHelpers();
|
|
63
147
|
|
|
@@ -66,6 +150,14 @@ describe('settings helpers', () => {
|
|
|
66
150
|
expect(helpers.sanitizeSettingsUpdate({ draftStartersVisible: 'false' })).toEqual({});
|
|
67
151
|
});
|
|
68
152
|
|
|
153
|
+
it('sanitizes both Enter settings independently', () => {
|
|
154
|
+
const helpers = createTestHelpers();
|
|
155
|
+
|
|
156
|
+
expect(helpers.sanitizeSettingsUpdate({ enterToSend: true })).toEqual({ enterToSend: true });
|
|
157
|
+
expect(helpers.sanitizeSettingsUpdate({ enterToSendConfigured: false })).toEqual({ enterToSendConfigured: false });
|
|
158
|
+
expect(helpers.sanitizeSettingsUpdate({ enterToSend: 'true', enterToSendConfigured: 1 })).toEqual({});
|
|
159
|
+
});
|
|
160
|
+
|
|
69
161
|
it('sanitizes shared sidebar display preferences', () => {
|
|
70
162
|
const helpers = createTestHelpers();
|
|
71
163
|
|
|
@@ -88,6 +180,15 @@ describe('settings helpers', () => {
|
|
|
88
180
|
})).toEqual({});
|
|
89
181
|
});
|
|
90
182
|
|
|
183
|
+
it('persists valid tool JSON view modes', () => {
|
|
184
|
+
const helpers = createTestHelpers();
|
|
185
|
+
|
|
186
|
+
expect(helpers.sanitizeSettingsUpdate({ toolJsonViewMode: 'summary' })).toEqual({ toolJsonViewMode: 'summary' });
|
|
187
|
+
expect(helpers.sanitizeSettingsUpdate({ toolJsonViewMode: 'formatted' })).toEqual({ toolJsonViewMode: 'formatted' });
|
|
188
|
+
expect(helpers.sanitizeSettingsUpdate({ toolJsonViewMode: 'raw' })).toEqual({ toolJsonViewMode: 'raw' });
|
|
189
|
+
expect(helpers.sanitizeSettingsUpdate({ toolJsonViewMode: 'unknown' })).toEqual({});
|
|
190
|
+
});
|
|
191
|
+
|
|
91
192
|
it('accepts only booleans for wide chat layout', () => {
|
|
92
193
|
const helpers = createTestHelpers();
|
|
93
194
|
|
|
@@ -134,6 +235,74 @@ describe('settings helpers', () => {
|
|
|
134
235
|
expect(helpers.sanitizeSettingsUpdate({ messageStreamTransport: 'websocket' })).toEqual({});
|
|
135
236
|
});
|
|
136
237
|
|
|
238
|
+
it('accepts inputHistoryScope as a persisted shared setting', () => {
|
|
239
|
+
const helpers = createTestHelpers();
|
|
240
|
+
|
|
241
|
+
expect(helpers.sanitizeSettingsUpdate({ inputHistoryScope: 'global' })).toEqual({
|
|
242
|
+
inputHistoryScope: 'global',
|
|
243
|
+
});
|
|
244
|
+
expect(helpers.sanitizeSettingsUpdate({ inputHistoryScope: 'session' })).toEqual({
|
|
245
|
+
inputHistoryScope: 'session',
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
it('accepts valid inputHistoryLimit values as a persisted shared setting', () => {
|
|
250
|
+
const helpers = createTestHelpers();
|
|
251
|
+
|
|
252
|
+
expect(helpers.sanitizeSettingsUpdate({ inputHistoryLimit: 1 })).toEqual({
|
|
253
|
+
inputHistoryLimit: 1,
|
|
254
|
+
});
|
|
255
|
+
expect(helpers.sanitizeSettingsUpdate({ inputHistoryLimit: 40 })).toEqual({
|
|
256
|
+
inputHistoryLimit: 40,
|
|
257
|
+
});
|
|
258
|
+
expect(helpers.sanitizeSettingsUpdate({ inputHistoryLimit: 100 })).toEqual({
|
|
259
|
+
inputHistoryLimit: 100,
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
it('rejects invalid inputHistoryLimit values', () => {
|
|
264
|
+
const helpers = createTestHelpers();
|
|
265
|
+
|
|
266
|
+
expect(helpers.sanitizeSettingsUpdate({ inputHistoryLimit: 0 })).toEqual({});
|
|
267
|
+
expect(helpers.sanitizeSettingsUpdate({ inputHistoryLimit: 101 })).toEqual({});
|
|
268
|
+
expect(helpers.sanitizeSettingsUpdate({ inputHistoryLimit: 1.5 })).toEqual({});
|
|
269
|
+
expect(helpers.sanitizeSettingsUpdate({ inputHistoryLimit: '40' })).toEqual({});
|
|
270
|
+
expect(helpers.sanitizeSettingsUpdate({ inputHistoryLimit: Number.NaN })).toEqual({});
|
|
271
|
+
expect(helpers.sanitizeSettingsUpdate({ inputHistoryLimit: Number.POSITIVE_INFINITY })).toEqual({});
|
|
272
|
+
expect(helpers.sanitizeSettingsUpdate({ inputHistoryLimit: Number.NEGATIVE_INFINITY })).toEqual({});
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
it('rejects invalid inputHistoryScope values', () => {
|
|
276
|
+
const helpers = createTestHelpers();
|
|
277
|
+
|
|
278
|
+
expect(helpers.sanitizeSettingsUpdate({ inputHistoryScope: 'workspace' })).toEqual({});
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
it('defaults inputHistoryScope to session in formatted settings responses', () => {
|
|
282
|
+
const helpers = createTestHelpers();
|
|
283
|
+
|
|
284
|
+
expect(helpers.formatSettingsResponse({ inputHistoryScope: 'global' })).toMatchObject({
|
|
285
|
+
inputHistoryScope: 'global',
|
|
286
|
+
});
|
|
287
|
+
expect(helpers.formatSettingsResponse({})).toMatchObject({
|
|
288
|
+
inputHistoryScope: 'session',
|
|
289
|
+
});
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
it('defaults missing inputHistoryLimit to 40 in formatted settings responses and preserves valid values', () => {
|
|
293
|
+
const helpers = createTestHelpers();
|
|
294
|
+
|
|
295
|
+
expect(helpers.formatSettingsResponse({})).toMatchObject({
|
|
296
|
+
inputHistoryLimit: DEFAULT_INPUT_HISTORY_LIMIT,
|
|
297
|
+
});
|
|
298
|
+
expect(helpers.formatSettingsResponse({ inputHistoryLimit: 1 })).toMatchObject({
|
|
299
|
+
inputHistoryLimit: 1,
|
|
300
|
+
});
|
|
301
|
+
expect(helpers.formatSettingsResponse({ inputHistoryLimit: 100 })).toMatchObject({
|
|
302
|
+
inputHistoryLimit: 100,
|
|
303
|
+
});
|
|
304
|
+
});
|
|
305
|
+
|
|
137
306
|
it('sanitizes the persisted terminal shell', () => {
|
|
138
307
|
const helpers = createTestHelpers();
|
|
139
308
|
|
|
@@ -316,6 +485,27 @@ describe('settings helpers', () => {
|
|
|
316
485
|
});
|
|
317
486
|
});
|
|
318
487
|
|
|
488
|
+
it('accepts and rejects invalid Enter-to-send preference values', () => {
|
|
489
|
+
const helpers = createTestHelpers();
|
|
490
|
+
|
|
491
|
+
expect(helpers.sanitizeSettingsUpdate({ enterToSend: true, enterToSendConfigured: true })).toEqual({
|
|
492
|
+
enterToSend: true,
|
|
493
|
+
enterToSendConfigured: true,
|
|
494
|
+
});
|
|
495
|
+
expect(helpers.sanitizeSettingsUpdate({ enterToSend: false, enterToSendConfigured: true })).toEqual({
|
|
496
|
+
enterToSend: false,
|
|
497
|
+
enterToSendConfigured: true,
|
|
498
|
+
});
|
|
499
|
+
expect(helpers.sanitizeSettingsUpdate({ enterToSend: false, enterToSendConfigured: false })).toEqual({
|
|
500
|
+
enterToSend: false,
|
|
501
|
+
enterToSendConfigured: false,
|
|
502
|
+
});
|
|
503
|
+
expect(helpers.sanitizeSettingsUpdate({ enterToSend: 'true' })).toEqual({});
|
|
504
|
+
expect(helpers.sanitizeSettingsUpdate({ enterToSend: 1 })).toEqual({});
|
|
505
|
+
expect(helpers.sanitizeSettingsUpdate({ enterToSendConfigured: 'true' })).toEqual({});
|
|
506
|
+
expect(helpers.sanitizeSettingsUpdate({ enterToSendConfigured: 1 })).toEqual({});
|
|
507
|
+
});
|
|
508
|
+
|
|
319
509
|
it('accepts dismissed OpenCode update toast version as a persisted shared setting', () => {
|
|
320
510
|
const helpers = createTestHelpers();
|
|
321
511
|
|
|
@@ -353,24 +543,24 @@ describe('settings helpers', () => {
|
|
|
353
543
|
|
|
354
544
|
it('includes transient desktop LAN access runtime status in desktop settings response', () => {
|
|
355
545
|
const helpers = createTestHelpers();
|
|
356
|
-
const previousRuntime = process.env.
|
|
357
|
-
const previousActive = process.env.
|
|
358
|
-
const previousReason = process.env.
|
|
546
|
+
const previousRuntime = process.env.AIWORKER_RUNTIME;
|
|
547
|
+
const previousActive = process.env.AIWORKER_DESKTOP_LAN_ACCESS_ACTIVE;
|
|
548
|
+
const previousReason = process.env.AIWORKER_DESKTOP_LAN_ACCESS_BLOCKED_REASON;
|
|
359
549
|
try {
|
|
360
|
-
process.env.
|
|
361
|
-
process.env.
|
|
362
|
-
process.env.
|
|
550
|
+
process.env.AIWORKER_RUNTIME = 'desktop';
|
|
551
|
+
process.env.AIWORKER_DESKTOP_LAN_ACCESS_ACTIVE = 'false';
|
|
552
|
+
process.env.AIWORKER_DESKTOP_LAN_ACCESS_BLOCKED_REASON = 'missing-password';
|
|
363
553
|
|
|
364
554
|
const response = helpers.formatSettingsResponse({ desktopLanAccessEnabled: true });
|
|
365
555
|
expect(response.desktopLanAccessActive).toBe(false);
|
|
366
556
|
expect(response.desktopLanAccessBlockedReason).toBe('missing-password');
|
|
367
557
|
} finally {
|
|
368
|
-
if (typeof previousRuntime === 'string') process.env.
|
|
369
|
-
else delete process.env.
|
|
370
|
-
if (typeof previousActive === 'string') process.env.
|
|
371
|
-
else delete process.env.
|
|
372
|
-
if (typeof previousReason === 'string') process.env.
|
|
373
|
-
else delete process.env.
|
|
558
|
+
if (typeof previousRuntime === 'string') process.env.AIWORKER_RUNTIME = previousRuntime;
|
|
559
|
+
else delete process.env.AIWORKER_RUNTIME;
|
|
560
|
+
if (typeof previousActive === 'string') process.env.AIWORKER_DESKTOP_LAN_ACCESS_ACTIVE = previousActive;
|
|
561
|
+
else delete process.env.AIWORKER_DESKTOP_LAN_ACCESS_ACTIVE;
|
|
562
|
+
if (typeof previousReason === 'string') process.env.AIWORKER_DESKTOP_LAN_ACCESS_BLOCKED_REASON = previousReason;
|
|
563
|
+
else delete process.env.AIWORKER_DESKTOP_LAN_ACCESS_BLOCKED_REASON;
|
|
374
564
|
}
|
|
375
565
|
});
|
|
376
566
|
|
|
@@ -534,3 +724,155 @@ describe('settings helpers', () => {
|
|
|
534
724
|
});
|
|
535
725
|
});
|
|
536
726
|
});
|
|
727
|
+
|
|
728
|
+
describe('settings registry gate', () => {
|
|
729
|
+
const registryPath = join(dirname(testFilePath), 'settings-registry.json');
|
|
730
|
+
const registry = JSON.parse(readFileSync(registryPath, 'utf8'));
|
|
731
|
+
const persistableKeys = Object.entries(registry.fields)
|
|
732
|
+
.filter(([, field]) => !field.computed && !field.local && field.owner !== 'desktop-shell')
|
|
733
|
+
.map(([key]) => key);
|
|
734
|
+
|
|
735
|
+
// One valid value per persistable registry key. The test below fails when a
|
|
736
|
+
// key is added to the registry without a line here, and when the sanitizer
|
|
737
|
+
// stops accepting a key the registry still lists — that is the drift the
|
|
738
|
+
// registry exists to end.
|
|
739
|
+
const validValues = {
|
|
740
|
+
themeId: 'openchamber-dark', useSystemTheme: true, themeVariant: 'dark', lightThemeId: 'openchamber-light', darkThemeId: 'openchamber-dark',
|
|
741
|
+
splashBgLight: '#fff', splashFgLight: '#000', splashBgDark: '#000', splashFgDark: '#fff',
|
|
742
|
+
lastDirectory: '/home/testuser/project', homeDirectory: '/home/testuser', opencodeBinary: '/usr/local/bin/opencode',
|
|
743
|
+
projects: [{ id: 'p', path: '/home/testuser/project' }], activeProjectId: 'p',
|
|
744
|
+
securityScopedBookmarks: ['bookmark'], pinnedDirectories: ['/home/testuser/project'],
|
|
745
|
+
desktopLanAccessEnabled: true, desktopKeepAwakeEnabled: true, desktopMinimizeToTrayEnabled: true, desktopMacMenuBarEnabled: true,
|
|
746
|
+
desktopUiPassword: 'secret', githubClientId: 'client', githubScopes: 'repo', skillCatalogs: [{ id: 'c', label: 'C', source: 'https://x' }],
|
|
747
|
+
defaultGitIdentityId: 'global', permissionAutoAccept: { sessions: { s: true }, revision: 1 },
|
|
748
|
+
agentControlToolEnabled: true, agentWebToolEnabled: true, agentMemoryToolEnabled: true, openCodeUpdateToastDismissedVersion: '1.0.0',
|
|
749
|
+
autoDeleteEnabled: true, autoDeleteAfterDays: 30, sessionRetentionAction: 'archive', terminalShell: 'zsh', terminalLoginShells: ['zsh'],
|
|
750
|
+
openInAppId: 'vscode', dictationEnabled: true, sttProvider: 'local', sttServerUrl: 'http://localhost:8001/v1', sttModel: 'm', sttLocalModel: 'm', sttLanguage: 'en',
|
|
751
|
+
tunnelProvider: 'cloudflare', tunnelMode: 'quick', tunnelBootstrapTtlMs: 600000, tunnelSessionTtlMs: 86400000, managedLocalTunnelConfigPath: '/tmp/x',
|
|
752
|
+
managedRemoteTunnelHostname: 'x.example', managedRemoteTunnelToken: 'token', managedRemoteTunnelPresets: [{ id: 'a', name: 'A', hostname: 'a.example' }],
|
|
753
|
+
managedRemoteTunnelSelectedPresetId: 'a', managedRemoteTunnelPresetTokens: { a: 'token' },
|
|
754
|
+
sidebarProjectDisplayMode: 'all', sidebarSessionGroupingMode: 'flat', sidebarProjectSortOrder: 'manual', sidebarShowRecentSection: true,
|
|
755
|
+
workStatusPanelEnabled: true, workStatusHiddenSections: ['mcp'], workStatusHiddenSectionsExplicit: true,
|
|
756
|
+
showReasoningTraces: true, streamingAutoFollowEnabled: true, collapsibleThinkingBlocks: true, showTextJustificationActivity: true,
|
|
757
|
+
chatRenderMode: 'live', activityRenderMode: 'summary', mermaidRenderingMode: 'svg', userMessageRenderingMode: 'markdown', collapsibleUserMessages: true,
|
|
758
|
+
stickyUserHeader: true, promptNavigatorEnabled: true, wideChatLayoutEnabled: true, showSplitAssistantMessageActions: true, showToolFileIcons: true,
|
|
759
|
+
codeBlockLineWrap: true, showTurnChangedFiles: true, showExpandedBashTools: true, showExpandedEditTools: true, toolJsonViewMode: 'raw',
|
|
760
|
+
timeFormatPreference: '24h', weekStartPreference: 'monday', messageStreamTransport: 'ws', diffLayoutPreference: 'inline', diffWrapLines: true,
|
|
761
|
+
gitChangesViewMode: 'tree', gitmojiEnabled: true, defaultFileViewerPreview: true, directoryShowHidden: true, filesViewShowGitignored: true,
|
|
762
|
+
fileEditorKeymap: 'vim', autoSaveEnabled: true, autoCreateWorktree: true, sessionTabsEnabled: true, showOpenCodeRestartConfirm: true,
|
|
763
|
+
allowPromptingSubagentSessions: true, inputSpellcheckEnabled: true, enterToSend: true, enterToSendConfigured: true, persistChatDraft: true,
|
|
764
|
+
largeTextPasteBehavior: 'attach', followUpBehavior: 'steer', queueModeEnabled: true, inputHistoryScope: 'global', inputHistoryLimit: 40,
|
|
765
|
+
draftStarters: [{ type: 'command', name: 'plan-feature' }], draftStartersVisible: true, draftStartersCraftGoalAdded: true, draftStartersScheduleTaskAdded: true,
|
|
766
|
+
fontSize: 100, terminalFontSize: 14, editorFontSize: 14, uiFont: 'inter', monoFont: 'jetbrains-mono', padding: 100, cornerRadius: 8,
|
|
767
|
+
shortcutOverrides: { 'chat.send': 'mod+enter' },
|
|
768
|
+
defaultModel: 'anthropic/claude', defaultVariant: 'high', defaultAgent: 'build', smallModelUseDefault: false, smallModelOverride: 'anthropic/haiku',
|
|
769
|
+
walkthroughModelOverride: 'anthropic/claude', zenModel: 'zen/model',
|
|
770
|
+
favoriteModels: [{ providerID: 'anthropic', modelID: 'claude' }], hiddenModels: [{ providerID: 'openai', modelID: 'gpt' }], collapsedModelProviders: ['openai'],
|
|
771
|
+
recentModels: [{ providerID: 'anthropic', modelID: 'claude' }], recentAgents: ['build'], recentEfforts: { 'anthropic/claude': ['high'] }, providerOrder: ['anthropic'],
|
|
772
|
+
sessionRecapEnabled: true, sessionSuggestionEnabled: true, sessionGoalEnabled: true, sessionGoalDefaultBudgetEnabled: true, sessionGoalDefaultBudget: 5,
|
|
773
|
+
summarizeLastMessage: true, summaryThreshold: 100, summaryLength: 50, maxLastMessageLength: 200, showDeletionDialog: true,
|
|
774
|
+
nativeNotificationsEnabled: true, notificationMode: 'always', notifyOnSubtasks: true, notifyOnCompletion: true, notifyOnError: true, notifyOnQuestion: true,
|
|
775
|
+
notificationTemplates: { completion: { title: 't', message: 'm' } }, showOpenCodeUpdateNotifications: true, reportUsage: true,
|
|
776
|
+
usageDisplayMode: 'usage', usageDropdownProviders: ['anthropic'], usageSelectedModels: { anthropic: ['claude'] }, usageCollapsedFamilies: { anthropic: ['f'] },
|
|
777
|
+
usageExpandedFamilies: { anthropic: ['f'] }, usageModelGroups: { anthropic: { customGroups: [{ id: 'g', label: 'G', models: ['claude'], order: 0 }] } },
|
|
778
|
+
globalBehaviorPrompt: 'Be brief.', responseStyleEnabled: true, responseStylePreset: 'concise', responseStyleCustomInstructions: 'x', optimizeSystemPrompt: true,
|
|
779
|
+
pwaAppName: 'AiWorker', pwaOrientation: 'portrait', mobileKeyboardMode: 'native', desktopWindowControlsPosition: 'left', desktopWindowControlsStyle: 'classic',
|
|
780
|
+
inputBarOffset: 10,
|
|
781
|
+
};
|
|
782
|
+
|
|
783
|
+
it('accepts a valid value for every persistable registry key (no server-side drift)', () => {
|
|
784
|
+
// The shared test helpers stub the injected list sanitizers to `undefined`
|
|
785
|
+
// (they are covered by their own suites); here they must pass values through
|
|
786
|
+
// so a key is judged by the sanitizer's own branch, not by a stub.
|
|
787
|
+
const helpers = createSettingsHelpers({
|
|
788
|
+
normalizePathForPersistence: (value) => value,
|
|
789
|
+
normalizeDirectoryPath: (value) => value,
|
|
790
|
+
normalizeTunnelBootstrapTtlMs: (value) => value,
|
|
791
|
+
normalizeTunnelSessionTtlMs: (value) => value,
|
|
792
|
+
normalizeTunnelProvider: (value) => value,
|
|
793
|
+
normalizeTunnelMode: (value) => value,
|
|
794
|
+
normalizeOptionalPath: (value) => value,
|
|
795
|
+
normalizeManagedRemoteTunnelHostname: (value) => value,
|
|
796
|
+
normalizeManagedRemoteTunnelPresets: (value) => value,
|
|
797
|
+
normalizeManagedRemoteTunnelPresetTokens: (value) => value,
|
|
798
|
+
normalizeStringArray: (input) => input,
|
|
799
|
+
sanitizeModelRefs: (value) => value,
|
|
800
|
+
sanitizeSkillCatalogs: (value) => value,
|
|
801
|
+
sanitizeProjects: (value) => value,
|
|
802
|
+
});
|
|
803
|
+
const missingFixture = persistableKeys.filter((key) => !(key in validValues));
|
|
804
|
+
expect(missingFixture).toEqual([]);
|
|
805
|
+
|
|
806
|
+
const rejected = persistableKeys.filter((key) => {
|
|
807
|
+
const result = helpers.sanitizeSettingsUpdate({ [key]: validValues[key] });
|
|
808
|
+
// `queueModeEnabled` is absorbed into `followUpBehavior` on purpose.
|
|
809
|
+
const landedAs = key === 'queueModeEnabled' ? 'followUpBehavior' : key;
|
|
810
|
+
return result[landedAs] === undefined;
|
|
811
|
+
});
|
|
812
|
+
expect(rejected).toEqual([]);
|
|
813
|
+
});
|
|
814
|
+
|
|
815
|
+
it('drops keys the registry does not list, computed flags, and desktop-shell-owned keys', () => {
|
|
816
|
+
const helpers = createTestHelpers();
|
|
817
|
+
expect(helpers.sanitizeSettingsUpdate({
|
|
818
|
+
markdownDisplayMode: 'raw',
|
|
819
|
+
toolCallExpansion: 'collapsed',
|
|
820
|
+
expandedEditorToolbar: true,
|
|
821
|
+
typographySizes: { base: 14 },
|
|
822
|
+
gitProviderId: 'anthropic',
|
|
823
|
+
gitModelId: 'claude',
|
|
824
|
+
messageLimit: 200,
|
|
825
|
+
agentMemoryFeatureAvailable: true,
|
|
826
|
+
desktopHosts: [],
|
|
827
|
+
notARealKey: 1,
|
|
828
|
+
})).toEqual({});
|
|
829
|
+
});
|
|
830
|
+
|
|
831
|
+
it('never returns secret keys from a formatted response', () => {
|
|
832
|
+
const helpers = createTestHelpers();
|
|
833
|
+
const secretKeys = Object.entries(registry.fields).filter(([, field]) => field.secret).map(([key]) => key);
|
|
834
|
+
expect(secretKeys).toContain('managedRemoteTunnelToken');
|
|
835
|
+
expect(secretKeys).toContain('desktopUiPassword');
|
|
836
|
+
expect(secretKeys).toContain('managedRemoteTunnelPresetTokens');
|
|
837
|
+
const response = helpers.formatSettingsResponse({
|
|
838
|
+
managedRemoteTunnelToken: 'token',
|
|
839
|
+
desktopUiPassword: 'pw',
|
|
840
|
+
managedRemoteTunnelPresetTokens: { a: 'tok' },
|
|
841
|
+
themeId: 'x',
|
|
842
|
+
});
|
|
843
|
+
for (const key of secretKeys) {
|
|
844
|
+
expect(response).not.toHaveProperty(key);
|
|
845
|
+
}
|
|
846
|
+
expect(response.hasManagedRemoteTunnelToken).toBe(true);
|
|
847
|
+
expect(response.hasDesktopUiPassword).toBe(true);
|
|
848
|
+
expect(helpers.formatSettingsResponse({ desktopUiPassword: '' }).hasDesktopUiPassword).toBe(false);
|
|
849
|
+
});
|
|
850
|
+
|
|
851
|
+
it('accepts the newly shared profile fields', () => {
|
|
852
|
+
const helpers = createTestHelpersWithRealSanitizers();
|
|
853
|
+
expect(helpers.sanitizeSettingsUpdate({
|
|
854
|
+
providerOrder: ['b', 'a', 'a'],
|
|
855
|
+
diffWrapLines: true,
|
|
856
|
+
persistChatDraft: false,
|
|
857
|
+
largeTextPasteBehavior: 'inline',
|
|
858
|
+
fileEditorKeymap: 'vim',
|
|
859
|
+
allowPromptingSubagentSessions: true,
|
|
860
|
+
showOpenCodeRestartConfirm: false,
|
|
861
|
+
codeBlockLineWrap: true,
|
|
862
|
+
streamingAutoFollowEnabled: false,
|
|
863
|
+
autoSaveEnabled: false,
|
|
864
|
+
})).toEqual({
|
|
865
|
+
providerOrder: ['b', 'a'],
|
|
866
|
+
diffWrapLines: true,
|
|
867
|
+
persistChatDraft: false,
|
|
868
|
+
largeTextPasteBehavior: 'inline',
|
|
869
|
+
fileEditorKeymap: 'vim',
|
|
870
|
+
allowPromptingSubagentSessions: true,
|
|
871
|
+
showOpenCodeRestartConfirm: false,
|
|
872
|
+
codeBlockLineWrap: true,
|
|
873
|
+
streamingAutoFollowEnabled: false,
|
|
874
|
+
autoSaveEnabled: false,
|
|
875
|
+
});
|
|
876
|
+
expect(helpers.sanitizeSettingsUpdate({ largeTextPasteBehavior: 'maybe', fileEditorKeymap: 'emacs' })).toEqual({});
|
|
877
|
+
});
|
|
878
|
+
});
|