@oh-my-pi/pi-coding-agent 17.0.9 → 17.1.1
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/CHANGELOG.md +78 -0
- package/README.md +1 -1
- package/dist/cli.js +4685 -4614
- package/dist/types/async/job-manager.d.ts +37 -1
- package/dist/types/cli/args.d.ts +2 -0
- package/dist/types/cli/bench-cli.d.ts +41 -0
- package/dist/types/commands/bench.d.ts +15 -3
- package/dist/types/commands/launch.d.ts +4 -0
- package/dist/types/config/model-registry.d.ts +3 -1
- package/dist/types/config/models-config-schema.d.ts +18 -6
- package/dist/types/config/models-config.d.ts +14 -5
- package/dist/types/config/provider-globals.d.ts +2 -2
- package/dist/types/config/service-tier.d.ts +5 -1
- package/dist/types/config/settings-schema.d.ts +374 -47
- package/dist/types/config/settings.d.ts +7 -0
- package/dist/types/dap/client.d.ts +20 -0
- package/dist/types/exec/bash-executor.d.ts +38 -0
- package/dist/types/exec/direnv.d.ts +33 -0
- package/dist/types/export/html/args.d.ts +15 -0
- package/dist/types/export/html/index.d.ts +11 -26
- package/dist/types/export/html/web-palette.d.ts +55 -116
- package/dist/types/extensibility/extensions/loader.d.ts +3 -0
- package/dist/types/extensibility/extensions/types.d.ts +17 -2
- package/dist/types/extensibility/legacy-pi-coding-agent-shim.d.ts +3 -0
- package/dist/types/extensibility/plugins/legacy-pi-compat.d.ts +13 -0
- package/dist/types/live/attestation.d.ts +2 -0
- package/dist/types/live/controller.d.ts +48 -0
- package/dist/types/live/protocol.d.ts +85 -0
- package/dist/types/live/protocol.test.d.ts +1 -0
- package/dist/types/live/transport.d.ts +35 -0
- package/dist/types/live/visualizer.d.ts +30 -0
- package/dist/types/lsp/client.d.ts +16 -1
- package/dist/types/mcp/config-writer.test.d.ts +1 -0
- package/dist/types/mcp/oauth-discovery.d.ts +2 -0
- package/dist/types/mcp/smithery-auth.d.ts +1 -1
- package/dist/types/mcp/smithery-auth.test.d.ts +1 -0
- package/dist/types/memory-backend/tool-names.d.ts +2 -0
- package/dist/types/modes/components/assistant-message.d.ts +1 -0
- package/dist/types/modes/components/custom-message.d.ts +1 -1
- package/dist/types/modes/components/login-dialog.d.ts +2 -2
- package/dist/types/modes/components/message-frame.d.ts +8 -4
- package/dist/types/modes/components/plan-review-overlay.d.ts +26 -0
- package/dist/types/modes/components/session-account-selector.d.ts +11 -0
- package/dist/types/modes/components/settings-defs.d.ts +7 -1
- package/dist/types/modes/components/status-line/component.jj-cache.test.d.ts +1 -0
- package/dist/types/modes/components/tool-execution.d.ts +9 -1
- package/dist/types/modes/controllers/command-controller.d.ts +1 -1
- package/dist/types/modes/controllers/event-controller.d.ts +6 -1
- package/dist/types/modes/controllers/live-command-controller.d.ts +14 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +1 -0
- package/dist/types/modes/interactive-mode.d.ts +6 -0
- package/dist/types/modes/theme/theme.d.ts +1 -1
- package/dist/types/modes/types.d.ts +4 -1
- package/dist/types/modes/utils/context-usage.d.ts +12 -2
- package/dist/types/plan-mode/plan-files.d.ts +10 -0
- package/dist/types/registry/agent-lifecycle.d.ts +21 -9
- package/dist/types/registry/agent-registry.d.ts +11 -4
- package/dist/types/sdk.d.ts +15 -1
- package/dist/types/secrets/index.d.ts +15 -2
- package/dist/types/secrets/obfuscator.d.ts +113 -15
- package/dist/types/session/acp-permission-gate.d.ts +19 -0
- package/dist/types/session/agent-session-events.d.ts +84 -0
- package/dist/types/session/agent-session-types.d.ts +321 -0
- package/dist/types/session/agent-session.d.ts +135 -753
- package/dist/types/session/async-job-delivery.d.ts +28 -0
- package/dist/types/session/auth-storage.d.ts +1 -1
- package/dist/types/session/bash-runner.d.ts +75 -0
- package/dist/types/session/blob-store.d.ts +11 -1
- package/dist/types/session/blob-store.test.d.ts +1 -0
- package/dist/types/session/checkpoint-entries.d.ts +28 -0
- package/dist/types/session/eval-runner.d.ts +51 -0
- package/dist/types/session/irc-bridge.d.ts +46 -0
- package/dist/types/session/messages.d.ts +24 -0
- package/dist/types/session/model-controls.d.ts +180 -0
- package/dist/types/session/prewalk.d.ts +46 -0
- package/dist/types/session/queued-messages.d.ts +22 -0
- package/dist/types/session/redis-session-storage.d.ts +1 -0
- package/dist/types/session/retry-fallback-chains.d.ts +74 -0
- package/dist/types/session/role-models.d.ts +15 -0
- package/dist/types/session/session-advisors.d.ts +228 -0
- package/dist/types/session/session-entries.d.ts +8 -0
- package/dist/types/session/session-handoff.d.ts +70 -0
- package/dist/types/session/session-history-format.d.ts +6 -1
- package/dist/types/session/session-maintenance.d.ts +246 -0
- package/dist/types/session/session-manager.d.ts +41 -0
- package/dist/types/session/session-memory.d.ts +56 -0
- package/dist/types/session/session-provider-boundary.d.ts +62 -0
- package/dist/types/session/session-stats.d.ts +48 -0
- package/dist/types/session/session-tools.d.ts +158 -0
- package/dist/types/session/session-workspace.d.ts +32 -0
- package/dist/types/session/stream-guards.d.ts +44 -0
- package/dist/types/session/streaming-output.d.ts +8 -0
- package/dist/types/session/todo-tracker.d.ts +56 -0
- package/dist/types/session/ttsr-coordinator.d.ts +51 -0
- package/dist/types/session/turn-recovery.d.ts +225 -0
- package/dist/types/slash-commands/helpers/session-pin.d.ts +9 -0
- package/dist/types/stt/index.d.ts +0 -2
- package/dist/types/stt/stt-controller.d.ts +7 -0
- package/dist/types/system-prompt.d.ts +2 -0
- package/dist/types/task/executor.d.ts +4 -1
- package/dist/types/task/output-manager.d.ts +3 -1
- package/dist/types/tiny/title-client.d.ts +10 -0
- package/dist/types/tools/approval.d.ts +1 -0
- package/dist/types/tools/browser/launch.d.ts +5 -0
- package/dist/types/tools/builtin-names.d.ts +1 -1
- package/dist/types/tools/computer/protocol.d.ts +43 -0
- package/dist/types/tools/computer/supervisor.d.ts +32 -0
- package/dist/types/tools/computer/worker-entry.d.ts +1 -0
- package/dist/types/tools/computer/worker.d.ts +15 -0
- package/dist/types/tools/computer-renderer.d.ts +22 -0
- package/dist/types/tools/computer.d.ts +71 -0
- package/dist/types/tools/context.d.ts +2 -0
- package/dist/types/tools/default-renderer.d.ts +21 -0
- package/dist/types/tools/image-gen.d.ts +4 -4
- package/dist/types/tools/image-providers.d.ts +38 -0
- package/dist/types/tools/index.d.ts +7 -0
- package/dist/types/tools/path-utils.d.ts +8 -0
- package/dist/types/tools/todo.d.ts +10 -4
- package/dist/types/tools/xdev.d.ts +5 -1
- package/dist/types/tts/streaming-player.d.ts +10 -29
- package/dist/types/tts/vocalizer.d.ts +5 -0
- package/dist/types/utils/jj.d.ts +29 -0
- package/dist/types/utils/lang-from-path.d.ts +1 -0
- package/dist/types/utils/title-generator.d.ts +30 -0
- package/dist/types/utils/tools-manager.d.ts +1 -2
- package/dist/types/vibe/runtime.d.ts +36 -8
- package/dist/types/web/search/index.d.ts +1 -1
- package/dist/types/web/search/provider.d.ts +15 -5
- package/dist/types/web/search/types.d.ts +94 -0
- package/package.json +12 -12
- package/scripts/generate-share-viewer.ts +4 -6
- package/src/advisor/__tests__/advisor.test.ts +643 -0
- package/src/advisor/runtime.ts +144 -43
- package/src/async/job-manager.ts +90 -2
- package/src/cli/args.ts +3 -0
- package/src/cli/auth-gateway-cli.ts +18 -3
- package/src/cli/bench-cli.ts +395 -29
- package/src/cli/flag-tables.ts +3 -0
- package/src/cli/gc-cli.ts +2 -2
- package/src/cli/setup-cli.ts +2 -14
- package/src/cli/usage-cli.ts +10 -1
- package/src/cli.ts +8 -0
- package/src/collab/host.ts +3 -2
- package/src/commands/bench.ts +18 -4
- package/src/commands/launch.ts +4 -0
- package/src/config/model-registry.ts +16 -2
- package/src/config/models-config-schema.ts +15 -4
- package/src/config/provider-globals.ts +9 -9
- package/src/config/service-tier.ts +26 -1
- package/src/config/settings-schema.ts +270 -51
- package/src/config/settings.ts +81 -2
- package/src/dap/client.ts +37 -4
- package/src/edit/index.ts +49 -12
- package/src/eval/executor-base.ts +1 -0
- package/src/eval/js/executor.ts +2 -0
- package/src/eval/py/executor.ts +103 -33
- package/src/exec/bash-executor.ts +90 -6
- package/src/exec/direnv.ts +145 -0
- package/src/export/html/args.ts +20 -0
- package/src/export/html/index.ts +45 -47
- package/src/export/html/template.css +19 -1
- package/src/export/html/template.html +6 -0
- package/src/export/html/template.js +21 -0
- package/src/export/html/tool-views.generated.js +31 -31
- package/src/export/html/web-palette.ts +116 -132
- package/src/export/share.ts +249 -49
- package/src/extensibility/extensions/loader.ts +29 -1
- package/src/extensibility/extensions/runner.ts +6 -0
- package/src/extensibility/extensions/types.ts +33 -2
- package/src/extensibility/extensions/wrapper.ts +68 -12
- package/src/extensibility/legacy-pi-coding-agent-shim.ts +7 -1
- package/src/extensibility/plugins/legacy-pi-compat.ts +19 -1
- package/src/hindsight/state.ts +64 -6
- package/src/internal-urls/local-protocol.ts +2 -1
- package/src/internal-urls/memory-protocol.ts +2 -2
- package/src/internal-urls/skill-protocol.ts +2 -2
- package/src/internal-urls/ssh-protocol.ts +2 -1
- package/src/internal-urls/vault-protocol.ts +2 -1
- package/src/live/attestation.ts +91 -0
- package/src/live/controller.ts +517 -0
- package/src/live/prompts/agent-final-message.md +3 -0
- package/src/live/prompts/live-instructions.md +23 -0
- package/src/live/protocol.test.ts +140 -0
- package/src/live/protocol.ts +233 -0
- package/src/live/transport.ts +422 -0
- package/src/live/visualizer.ts +214 -0
- package/src/lsp/client.ts +29 -9
- package/src/lsp/index.ts +19 -4
- package/src/main.ts +8 -1
- package/src/mcp/config-writer.test.ts +43 -0
- package/src/mcp/config-writer.ts +109 -82
- package/src/mcp/oauth-discovery.ts +10 -2
- package/src/mcp/smithery-auth.test.ts +29 -0
- package/src/mcp/smithery-auth.ts +3 -2
- package/src/memories/index.ts +40 -20
- package/src/memory-backend/tool-names.ts +2 -0
- package/src/mnemopi/backend.ts +24 -7
- package/src/modes/acp/acp-agent.ts +56 -10
- package/src/modes/acp/acp-event-mapper.ts +8 -1
- package/src/modes/components/agent-hub.ts +1 -1
- package/src/modes/components/assistant-message.ts +7 -2
- package/src/modes/components/custom-message.ts +4 -1
- package/src/modes/components/login-dialog.ts +14 -4
- package/src/modes/components/message-frame.ts +14 -8
- package/src/modes/components/plan-review-overlay.ts +350 -35
- package/src/modes/components/session-account-selector.ts +62 -0
- package/src/modes/components/settings-defs.ts +23 -1
- package/src/modes/components/settings-selector.ts +169 -1
- package/src/modes/components/status-line/component.jj-cache.test.ts +229 -0
- package/src/modes/components/status-line/component.ts +123 -2
- package/src/modes/components/tool-execution.ts +28 -112
- package/src/modes/controllers/command-controller.ts +56 -15
- package/src/modes/controllers/event-controller.ts +111 -16
- package/src/modes/controllers/extension-ui-controller.test.ts +1 -0
- package/src/modes/controllers/extension-ui-controller.ts +20 -4
- package/src/modes/controllers/input-controller.ts +47 -39
- package/src/modes/controllers/live-command-controller.ts +255 -0
- package/src/modes/controllers/mcp-command-controller.ts +10 -1
- package/src/modes/controllers/omfg-controller.ts +44 -40
- package/src/modes/controllers/selector-controller.ts +80 -10
- package/src/modes/controllers/session-focus-controller.ts +6 -1
- package/src/modes/interactive-mode.ts +176 -38
- package/src/modes/runtime-init.ts +2 -0
- package/src/modes/setup-wizard/scenes/web-search.ts +17 -9
- package/src/modes/theme/theme.ts +1 -1
- package/src/modes/types.ts +4 -1
- package/src/modes/utils/context-usage.ts +23 -7
- package/src/modes/utils/ui-helpers.ts +10 -5
- package/src/plan-mode/plan-files.ts +40 -0
- package/src/prompts/bench/cache-prefix-chunk.md +1 -0
- package/src/prompts/bench/cache-prefix.md +3 -0
- package/src/prompts/bench/cache-suffix.md +1 -0
- package/src/prompts/system/computer-safety.md +14 -0
- package/src/prompts/system/custom-system-prompt.md +1 -1
- package/src/prompts/system/project-prompt.md +8 -1
- package/src/prompts/system/subagent-async-pending.md +6 -0
- package/src/prompts/system/system-prompt.md +1 -1
- package/src/prompts/system/workflow-notice.md +48 -40
- package/src/prompts/system/xdev-mount-notice.md +4 -0
- package/src/prompts/tools/computer.md +26 -0
- package/src/prompts/tools/todo.md +3 -1
- package/src/registry/agent-lifecycle.ts +116 -46
- package/src/registry/agent-registry.ts +35 -8
- package/src/registry/persisted-agents.ts +26 -2
- package/src/sdk.ts +215 -136
- package/src/secrets/index.ts +127 -4
- package/src/secrets/obfuscator.ts +2328 -105
- package/src/session/acp-permission-gate.ts +165 -0
- package/src/session/agent-session-error-log.test.ts +1 -1
- package/src/session/agent-session-events.ts +66 -0
- package/src/session/agent-session-types.ts +343 -0
- package/src/session/agent-session.ts +1940 -12218
- package/src/session/artifacts.ts +6 -5
- package/src/session/async-job-delivery.ts +74 -0
- package/src/session/auth-storage.ts +1 -0
- package/src/session/bash-runner.ts +326 -0
- package/src/session/blob-store.test.ts +56 -0
- package/src/session/blob-store.ts +18 -2
- package/src/session/checkpoint-entries.ts +81 -0
- package/src/session/eval-runner.ts +217 -0
- package/src/session/indexed-session-storage.ts +9 -2
- package/src/session/irc-bridge.ts +203 -0
- package/src/session/messages.ts +266 -1
- package/src/session/model-controls.ts +714 -0
- package/src/session/prewalk.ts +252 -0
- package/src/session/queued-messages.ts +93 -0
- package/src/session/redis-session-storage.ts +51 -11
- package/src/session/retry-fallback-chains.ts +455 -0
- package/src/session/role-models.ts +85 -0
- package/src/session/session-advisors.ts +1679 -0
- package/src/session/session-context.ts +6 -3
- package/src/session/session-entries.ts +8 -0
- package/src/session/session-handoff.ts +308 -0
- package/src/session/session-history-format.ts +20 -9
- package/src/session/session-loader.ts +0 -46
- package/src/session/session-maintenance.ts +2983 -0
- package/src/session/session-manager.ts +390 -30
- package/src/session/session-memory.ts +222 -0
- package/src/session/session-provider-boundary.ts +307 -0
- package/src/session/session-stats.ts +293 -0
- package/src/session/session-tools.ts +980 -0
- package/src/session/session-workspace.ts +53 -0
- package/src/session/stream-guards.ts +417 -0
- package/src/session/streaming-output.ts +52 -5
- package/src/session/todo-tracker.ts +380 -0
- package/src/session/ttsr-coordinator.ts +496 -0
- package/src/session/turn-recovery.ts +1629 -0
- package/src/slash-commands/builtin-registry.ts +257 -20
- package/src/slash-commands/helpers/session-pin.ts +44 -0
- package/src/slash-commands/helpers/usage-report.ts +22 -3
- package/src/stt/downloader.ts +0 -2
- package/src/stt/index.ts +0 -2
- package/src/stt/stt-controller.ts +57 -146
- package/src/system-prompt.ts +45 -17
- package/src/task/executor.ts +285 -70
- package/src/task/index.ts +98 -105
- package/src/task/output-manager.ts +25 -3
- package/src/task/persisted-revive.ts +4 -3
- package/src/task/structured-subagent.ts +1 -0
- package/src/tiny/title-client.ts +22 -0
- package/src/tools/approval.ts +55 -10
- package/src/tools/bash-interactive.ts +116 -86
- package/src/tools/bash-skill-urls.ts +28 -2
- package/src/tools/bash.ts +339 -123
- package/src/tools/browser/launch.ts +9 -1
- package/src/tools/browser/tab-supervisor.ts +8 -5
- package/src/tools/browser.ts +94 -47
- package/src/tools/builtin-names.ts +1 -0
- package/src/tools/computer/protocol.ts +28 -0
- package/src/tools/computer/supervisor.ts +258 -0
- package/src/tools/computer/worker-entry.ts +25 -0
- package/src/tools/computer/worker.ts +135 -0
- package/src/tools/computer-renderer.ts +108 -0
- package/src/tools/computer.ts +433 -0
- package/src/tools/context.ts +2 -0
- package/src/tools/default-renderer.ts +139 -0
- package/src/tools/essential-tools.ts +1 -0
- package/src/tools/image-gen.ts +20 -28
- package/src/tools/image-providers.ts +50 -0
- package/src/tools/index.ts +14 -0
- package/src/tools/path-utils.ts +49 -2
- package/src/tools/read.ts +156 -88
- package/src/tools/renderers.ts +9 -1
- package/src/tools/todo.ts +101 -11
- package/src/tools/vibe.ts +1 -2
- package/src/tools/write.ts +51 -1
- package/src/tools/xdev.ts +121 -29
- package/src/tts/streaming-player.ts +82 -283
- package/src/tts/vocalizer.ts +18 -1
- package/src/utils/clipboard.ts +1 -30
- package/src/utils/jj.ts +125 -4
- package/src/utils/lang-from-path.ts +7 -0
- package/src/utils/mac-file-urls.applescript +37 -0
- package/src/utils/title-generator.ts +137 -1
- package/src/utils/tool-choice.ts +14 -0
- package/src/utils/tools-manager.ts +1 -19
- package/src/vibe/runtime.ts +852 -72
- package/src/web/search/index.ts +3 -6
- package/src/web/search/provider.ts +31 -16
- package/src/web/search/providers/xai.ts +7 -1
- package/src/web/search/types.ts +3 -0
- package/dist/types/stt/recorder.d.ts +0 -30
- package/dist/types/stt/transcriber.d.ts +0 -14
- package/dist/types/stt/wav.d.ts +0 -29
- package/dist/types/tts/player.d.ts +0 -32
- package/src/stt/recorder.ts +0 -551
- package/src/stt/transcriber.ts +0 -60
- package/src/stt/wav.ts +0 -173
- package/src/tts/player.ts +0 -137
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
TINY_TITLE_MODEL_OPTIONS,
|
|
27
27
|
TINY_TITLE_MODEL_VALUES,
|
|
28
28
|
} from "../tiny/models";
|
|
29
|
+
import { IMAGE_PROVIDER_CHOICES, type ImageProvider } from "../tools/image-providers";
|
|
29
30
|
import {
|
|
30
31
|
DEFAULT_TTS_LOCAL_MODEL_KEY,
|
|
31
32
|
DEFAULT_TTS_VOICE,
|
|
@@ -35,7 +36,7 @@ import {
|
|
|
35
36
|
TTS_LOCAL_VOICE_VALUES,
|
|
36
37
|
} from "../tts/models";
|
|
37
38
|
import { EDIT_MODES } from "../utils/edit-mode";
|
|
38
|
-
import {
|
|
39
|
+
import { SEARCH_PROVIDER_CHOICES, type SearchProviderId } from "../web/search/types";
|
|
39
40
|
import {
|
|
40
41
|
SERVICE_TIER_ANTHROPIC_OPTIONS,
|
|
41
42
|
SERVICE_TIER_ANTHROPIC_VALUES,
|
|
@@ -140,6 +141,7 @@ export const TAB_GROUPS: Record<SettingTab, readonly string[]> = {
|
|
|
140
141
|
"Available Tools",
|
|
141
142
|
"Todos",
|
|
142
143
|
"Grep & Browser",
|
|
144
|
+
"Computer",
|
|
143
145
|
"GitHub",
|
|
144
146
|
"Output Limits",
|
|
145
147
|
"Execution",
|
|
@@ -218,10 +220,18 @@ interface UiString extends UiBase {
|
|
|
218
220
|
options?: ReadonlyArray<SubmenuOption> | "runtime";
|
|
219
221
|
}
|
|
220
222
|
|
|
223
|
+
interface UiArray extends UiBase {
|
|
224
|
+
/** Membership choices. Without options, an array setting has no UI representation (config-file only). */
|
|
225
|
+
options?: ReadonlyArray<SubmenuOption>;
|
|
226
|
+
/** Selection order is meaningful; the editor renders positions and supports reordering. */
|
|
227
|
+
ordered?: boolean;
|
|
228
|
+
}
|
|
229
|
+
|
|
221
230
|
/** Wide ui shape exposed to consumers that walk the schema generically. */
|
|
222
231
|
export type AnyUiMetadata = UiBase & {
|
|
223
232
|
options?: ReadonlyArray<SubmenuOption> | "runtime";
|
|
224
233
|
secret?: boolean;
|
|
234
|
+
ordered?: boolean;
|
|
225
235
|
};
|
|
226
236
|
|
|
227
237
|
interface BooleanDef {
|
|
@@ -252,7 +262,7 @@ interface EnumDef<T extends readonly string[]> {
|
|
|
252
262
|
interface ArrayDef<T> {
|
|
253
263
|
type: "array";
|
|
254
264
|
default: T[];
|
|
255
|
-
ui?:
|
|
265
|
+
ui?: UiArray;
|
|
256
266
|
}
|
|
257
267
|
|
|
258
268
|
interface RecordDef<T> {
|
|
@@ -904,6 +914,18 @@ export const SETTINGS_SCHEMA = {
|
|
|
904
914
|
},
|
|
905
915
|
},
|
|
906
916
|
|
|
917
|
+
"tui.titleState": {
|
|
918
|
+
type: "boolean",
|
|
919
|
+
default: true,
|
|
920
|
+
ui: {
|
|
921
|
+
tab: "appearance",
|
|
922
|
+
group: "Display",
|
|
923
|
+
label: "Terminal Title Run State",
|
|
924
|
+
description:
|
|
925
|
+
"Show the agent run state in the terminal title's separator — an animated spinner while working, '>' when it's your turn, '!' when the agent is waiting on you",
|
|
926
|
+
},
|
|
927
|
+
},
|
|
928
|
+
|
|
907
929
|
"tui.hyperlinks": {
|
|
908
930
|
type: "enum",
|
|
909
931
|
values: ["off", "auto", "always"] as const,
|
|
@@ -1188,6 +1210,18 @@ export const SETTINGS_SCHEMA = {
|
|
|
1188
1210
|
},
|
|
1189
1211
|
},
|
|
1190
1212
|
|
|
1213
|
+
"workspace.additionalDirectories": {
|
|
1214
|
+
type: "array",
|
|
1215
|
+
default: [] as string[],
|
|
1216
|
+
ui: {
|
|
1217
|
+
tab: "context",
|
|
1218
|
+
group: "General",
|
|
1219
|
+
label: "Additional Workspace Dirs",
|
|
1220
|
+
description:
|
|
1221
|
+
"Extra workspace directories added to every session as additional roots (multi-root workspace). Managed live via /add-dir and /remove-dir. Paths resolve relative to cwd; absolute paths recommended. The agent is told these roots exist and can read/grep/glob them.",
|
|
1222
|
+
},
|
|
1223
|
+
},
|
|
1224
|
+
|
|
1191
1225
|
personality: {
|
|
1192
1226
|
type: "enum",
|
|
1193
1227
|
values: ["default", "friendly", "pragmatic", "none"] as const,
|
|
@@ -1460,6 +1494,65 @@ export const SETTINGS_SCHEMA = {
|
|
|
1460
1494
|
description: "Allow retry recovery to switch to configured fallback models",
|
|
1461
1495
|
},
|
|
1462
1496
|
},
|
|
1497
|
+
"retry.usageAwareFallback": {
|
|
1498
|
+
type: "boolean",
|
|
1499
|
+
default: false,
|
|
1500
|
+
ui: {
|
|
1501
|
+
tab: "model",
|
|
1502
|
+
group: "Retry & Fallback",
|
|
1503
|
+
label: "Usage-Aware Fallback",
|
|
1504
|
+
description:
|
|
1505
|
+
"Use reliable coding-plan quota reports to prefer same-provider accounts, then configured fallback models, before a hard usage limit. Ordinary configured API keys are excluded.",
|
|
1506
|
+
},
|
|
1507
|
+
},
|
|
1508
|
+
"retry.usageReservePct": {
|
|
1509
|
+
type: "number",
|
|
1510
|
+
default: 10,
|
|
1511
|
+
ui: {
|
|
1512
|
+
tab: "model",
|
|
1513
|
+
group: "Retry & Fallback",
|
|
1514
|
+
label: "Reserve Margin",
|
|
1515
|
+
description:
|
|
1516
|
+
"Treat a coding-plan model as near its limit below this remaining percentage. Unknown or unmapped usage keeps the primary model.",
|
|
1517
|
+
condition: "usageAwareFallbackEnabled",
|
|
1518
|
+
options: [
|
|
1519
|
+
{ value: "5", label: "5%", description: "Act only when nearly exhausted" },
|
|
1520
|
+
{ value: "10", label: "10%", description: "Balanced safety margin" },
|
|
1521
|
+
{ value: "15", label: "15%", description: "Conservative" },
|
|
1522
|
+
{ value: "20", label: "20%", description: "Early protection" },
|
|
1523
|
+
{ value: "25", label: "25%", description: "Very conservative" },
|
|
1524
|
+
],
|
|
1525
|
+
},
|
|
1526
|
+
},
|
|
1527
|
+
"retry.usageReservePolicy": {
|
|
1528
|
+
type: "enum",
|
|
1529
|
+
values: ["confirm", "auto", "fail-closed"] as const,
|
|
1530
|
+
default: "confirm",
|
|
1531
|
+
ui: {
|
|
1532
|
+
tab: "model",
|
|
1533
|
+
group: "Retry & Fallback",
|
|
1534
|
+
label: "Reserve Policy",
|
|
1535
|
+
description: "What to do when every same-provider coding-plan account is inside the reserve margin.",
|
|
1536
|
+
condition: "usageAwareFallbackEnabled",
|
|
1537
|
+
options: [
|
|
1538
|
+
{
|
|
1539
|
+
value: "confirm",
|
|
1540
|
+
label: "Confirm interactively",
|
|
1541
|
+
description: "Keep interactive sessions on the primary until confirmed; background agents auto-fallback",
|
|
1542
|
+
},
|
|
1543
|
+
{
|
|
1544
|
+
value: "auto",
|
|
1545
|
+
label: "Auto-fallback",
|
|
1546
|
+
description: "Always select the next eligible configured fallback",
|
|
1547
|
+
},
|
|
1548
|
+
{
|
|
1549
|
+
value: "fail-closed",
|
|
1550
|
+
label: "Fail closed",
|
|
1551
|
+
description: "Do not spend reserve quota or select a fallback",
|
|
1552
|
+
},
|
|
1553
|
+
],
|
|
1554
|
+
},
|
|
1555
|
+
},
|
|
1463
1556
|
"retry.fallbackChains": {
|
|
1464
1557
|
type: "record",
|
|
1465
1558
|
default: {} as Record<string, string[]>,
|
|
@@ -1773,6 +1866,18 @@ export const SETTINGS_SCHEMA = {
|
|
|
1773
1866
|
},
|
|
1774
1867
|
},
|
|
1775
1868
|
|
|
1869
|
+
"error.notify": {
|
|
1870
|
+
type: "enum",
|
|
1871
|
+
values: ["on", "off"] as const,
|
|
1872
|
+
default: "off",
|
|
1873
|
+
ui: {
|
|
1874
|
+
tab: "interaction",
|
|
1875
|
+
group: "Notifications",
|
|
1876
|
+
label: "Error Notification",
|
|
1877
|
+
description: "Notify when the agent stops with an error",
|
|
1878
|
+
},
|
|
1879
|
+
},
|
|
1880
|
+
|
|
1776
1881
|
"ask.timeout": {
|
|
1777
1882
|
type: "number",
|
|
1778
1883
|
default: 0,
|
|
@@ -2448,9 +2553,8 @@ export const SETTINGS_SCHEMA = {
|
|
|
2448
2553
|
"memories.summaryInjectionTokenLimit": { type: "number", default: 5000 },
|
|
2449
2554
|
|
|
2450
2555
|
// Memory backend selector — picks between local memories pipeline,
|
|
2451
|
-
// Mnemopi local SQLite, Hindsight remote memory, or off.
|
|
2452
|
-
// `memories.enabled`
|
|
2453
|
-
// migration for details.
|
|
2556
|
+
// Mnemopi local SQLite, Hindsight remote memory, or off. The legacy
|
|
2557
|
+
// `memories.enabled` flag is migration input only; see config/settings.ts.
|
|
2454
2558
|
"memory.backend": {
|
|
2455
2559
|
type: "enum",
|
|
2456
2560
|
values: ["off", "local", "hindsight", "mnemopi"] as const,
|
|
@@ -3108,6 +3212,17 @@ export const SETTINGS_SCHEMA = {
|
|
|
3108
3212
|
},
|
|
3109
3213
|
},
|
|
3110
3214
|
|
|
3215
|
+
"read.renderMarkdown": {
|
|
3216
|
+
type: "boolean",
|
|
3217
|
+
default: false,
|
|
3218
|
+
ui: {
|
|
3219
|
+
tab: "files",
|
|
3220
|
+
group: "Reading",
|
|
3221
|
+
label: "Markdown Previews",
|
|
3222
|
+
description: "Render Markdown read results as formatted terminal Markdown previews instead of raw source",
|
|
3223
|
+
},
|
|
3224
|
+
},
|
|
3225
|
+
|
|
3111
3226
|
"read.summarize.enabled": {
|
|
3112
3227
|
type: "boolean",
|
|
3113
3228
|
default: true,
|
|
@@ -3287,6 +3402,17 @@ export const SETTINGS_SCHEMA = {
|
|
|
3287
3402
|
description: "Automatically background long-running bash commands and deliver the result later",
|
|
3288
3403
|
},
|
|
3289
3404
|
},
|
|
3405
|
+
"bash.patterns": {
|
|
3406
|
+
type: "array",
|
|
3407
|
+
default: [],
|
|
3408
|
+
ui: {
|
|
3409
|
+
tab: "shell",
|
|
3410
|
+
group: "Bash",
|
|
3411
|
+
label: "Bash Approval Patterns",
|
|
3412
|
+
description:
|
|
3413
|
+
"Ordered bash command approval rules. Each item has match and approval fields; only '*' wildcards are supported.",
|
|
3414
|
+
},
|
|
3415
|
+
},
|
|
3290
3416
|
|
|
3291
3417
|
// Bash interceptor
|
|
3292
3418
|
"bashInterceptor.enabled": {
|
|
@@ -3301,6 +3427,29 @@ export const SETTINGS_SCHEMA = {
|
|
|
3301
3427
|
},
|
|
3302
3428
|
"bashInterceptor.patterns": { type: "array", default: DEFAULT_BASH_INTERCEPTOR_RULES },
|
|
3303
3429
|
|
|
3430
|
+
"bash.direnv": {
|
|
3431
|
+
type: "enum",
|
|
3432
|
+
values: ["auto", "off"] as const,
|
|
3433
|
+
default: "auto",
|
|
3434
|
+
ui: {
|
|
3435
|
+
tab: "shell",
|
|
3436
|
+
group: "Bash",
|
|
3437
|
+
label: "direnv Auto-Load",
|
|
3438
|
+
description:
|
|
3439
|
+
"Auto-load a repo's direnv/devenv `.envrc` into the bash session so devenv tools and env vars are present without manual `direnv exec`. Honors direnv's allow list: an `.envrc` you haven't `direnv allow`ed is never executed",
|
|
3440
|
+
},
|
|
3441
|
+
},
|
|
3442
|
+
"bash.direnvLoadTimeoutMs": {
|
|
3443
|
+
type: "number",
|
|
3444
|
+
default: 30_000,
|
|
3445
|
+
ui: {
|
|
3446
|
+
tab: "shell",
|
|
3447
|
+
group: "Bash",
|
|
3448
|
+
label: "direnv Load Timeout (ms)",
|
|
3449
|
+
description:
|
|
3450
|
+
"Max wait for the first `direnv export` (a cold devenv shell can be slow); on timeout the session runs without the direnv env",
|
|
3451
|
+
},
|
|
3452
|
+
},
|
|
3304
3453
|
// Shell output minimizer
|
|
3305
3454
|
"shellMinimizer.enabled": {
|
|
3306
3455
|
type: "boolean",
|
|
@@ -3682,6 +3831,66 @@ export const SETTINGS_SCHEMA = {
|
|
|
3682
3831
|
},
|
|
3683
3832
|
},
|
|
3684
3833
|
|
|
3834
|
+
"computer.enabled": {
|
|
3835
|
+
type: "boolean",
|
|
3836
|
+
default: false,
|
|
3837
|
+
ui: {
|
|
3838
|
+
tab: "tools",
|
|
3839
|
+
group: "Available Tools",
|
|
3840
|
+
label: "Computer",
|
|
3841
|
+
description: "Enable native host-desktop screenshots and input for OpenAI computer use",
|
|
3842
|
+
},
|
|
3843
|
+
},
|
|
3844
|
+
|
|
3845
|
+
"computer.backend": {
|
|
3846
|
+
type: "enum",
|
|
3847
|
+
values: ["auto", "native"] as const,
|
|
3848
|
+
default: "auto",
|
|
3849
|
+
ui: {
|
|
3850
|
+
tab: "tools",
|
|
3851
|
+
group: "Computer",
|
|
3852
|
+
label: "Computer Backend",
|
|
3853
|
+
description: "Select automatic or explicit platform-native desktop capture and input",
|
|
3854
|
+
options: [
|
|
3855
|
+
{ value: "auto", label: "Auto" },
|
|
3856
|
+
{ value: "native", label: "Native" },
|
|
3857
|
+
],
|
|
3858
|
+
},
|
|
3859
|
+
},
|
|
3860
|
+
|
|
3861
|
+
"computer.display": {
|
|
3862
|
+
type: "string",
|
|
3863
|
+
default: "all",
|
|
3864
|
+
ui: {
|
|
3865
|
+
tab: "tools",
|
|
3866
|
+
group: "Computer",
|
|
3867
|
+
label: "Computer Display",
|
|
3868
|
+
description: "Composite all displays or select a native display id",
|
|
3869
|
+
},
|
|
3870
|
+
},
|
|
3871
|
+
|
|
3872
|
+
"computer.maxWidth": {
|
|
3873
|
+
type: "number",
|
|
3874
|
+
default: 1920,
|
|
3875
|
+
ui: {
|
|
3876
|
+
tab: "tools",
|
|
3877
|
+
group: "Computer",
|
|
3878
|
+
label: "Computer Screenshot Width",
|
|
3879
|
+
description: "Maximum composite screenshot width in pixels",
|
|
3880
|
+
},
|
|
3881
|
+
},
|
|
3882
|
+
|
|
3883
|
+
"computer.maxHeight": {
|
|
3884
|
+
type: "number",
|
|
3885
|
+
default: 1200,
|
|
3886
|
+
ui: {
|
|
3887
|
+
tab: "tools",
|
|
3888
|
+
group: "Computer",
|
|
3889
|
+
label: "Computer Screenshot Height",
|
|
3890
|
+
description: "Maximum composite screenshot height in pixels",
|
|
3891
|
+
},
|
|
3892
|
+
},
|
|
3893
|
+
|
|
3685
3894
|
"checkpoint.enabled": {
|
|
3686
3895
|
type: "boolean",
|
|
3687
3896
|
default: false,
|
|
@@ -3947,6 +4156,40 @@ export const SETTINGS_SCHEMA = {
|
|
|
3947
4156
|
},
|
|
3948
4157
|
},
|
|
3949
4158
|
|
|
4159
|
+
"tools.xdevDocs": {
|
|
4160
|
+
type: "enum",
|
|
4161
|
+
values: ["inline", "builtins", "catalog"] as const,
|
|
4162
|
+
default: "builtins",
|
|
4163
|
+
ui: {
|
|
4164
|
+
tab: "tools",
|
|
4165
|
+
group: "Discovery & MCP",
|
|
4166
|
+
label: "xd:// Prompt Docs",
|
|
4167
|
+
description:
|
|
4168
|
+
"Choose which mounted-device docs and schemas are inlined in the system prompt. Built-ins keeps core tools inline while MCP and extension tools stay on-demand.",
|
|
4169
|
+
options: [
|
|
4170
|
+
{ value: "inline", label: "All Devices", description: "Inline docs and schemas for every mounted device." },
|
|
4171
|
+
{
|
|
4172
|
+
value: "builtins",
|
|
4173
|
+
label: "Built-ins Only",
|
|
4174
|
+
description: "Inline built-in docs; fetch MCP and extension docs on demand.",
|
|
4175
|
+
},
|
|
4176
|
+
{ value: "catalog", label: "Catalog Only", description: "List every device; fetch all docs on demand." },
|
|
4177
|
+
],
|
|
4178
|
+
},
|
|
4179
|
+
},
|
|
4180
|
+
|
|
4181
|
+
"tools.xdevInlineDevices": {
|
|
4182
|
+
type: "array",
|
|
4183
|
+
default: EMPTY_STRING_ARRAY,
|
|
4184
|
+
ui: {
|
|
4185
|
+
tab: "tools",
|
|
4186
|
+
group: "Discovery & MCP",
|
|
4187
|
+
label: "xd:// Inline Devices",
|
|
4188
|
+
description:
|
|
4189
|
+
"When xd:// Prompt Docs is Built-ins Only, inline dynamic devices whose names match these glob patterns (for example mcp__context_mode_*). Catalog Only ignores this setting.",
|
|
4190
|
+
},
|
|
4191
|
+
},
|
|
4192
|
+
|
|
3950
4193
|
// MCP
|
|
3951
4194
|
"mcp.enableProjectConfig": {
|
|
3952
4195
|
type: "boolean",
|
|
@@ -4195,7 +4438,7 @@ export const SETTINGS_SCHEMA = {
|
|
|
4195
4438
|
group: "Subagents",
|
|
4196
4439
|
label: "Batch Task Calls",
|
|
4197
4440
|
description:
|
|
4198
|
-
"Switch the task tool to its batch shape: one call carries {
|
|
4441
|
+
"Switch the task tool to its batch shape: one call carries { context, tasks[] } — one subagent per item, with an optional per-item agent (defaulting to the session spawn-policy agent), per-item isolation, and a required shared context prepended to every assignment. With async.enabled=true, each spawn runs as an independent background agent with the normal idle/parked lifecycle; otherwise the call blocks for merged results. Disable to restore the flat single-spawn schema.",
|
|
4199
4442
|
},
|
|
4200
4443
|
},
|
|
4201
4444
|
|
|
@@ -4458,7 +4701,7 @@ export const SETTINGS_SCHEMA = {
|
|
|
4458
4701
|
tab: "providers",
|
|
4459
4702
|
group: "Privacy",
|
|
4460
4703
|
label: "Hide Secrets",
|
|
4461
|
-
description: "Obfuscate secrets before sending to AI providers",
|
|
4704
|
+
description: "Obfuscate configured secrets and redact credential-shaped tokens before sending to AI providers",
|
|
4462
4705
|
},
|
|
4463
4706
|
},
|
|
4464
4707
|
|
|
@@ -4474,16 +4717,17 @@ export const SETTINGS_SCHEMA = {
|
|
|
4474
4717
|
"Maximum concurrent Ollama Cloud subagent runs per process; 0 disables the provider-specific limit",
|
|
4475
4718
|
},
|
|
4476
4719
|
},
|
|
4477
|
-
"providers.
|
|
4478
|
-
type: "
|
|
4479
|
-
|
|
4480
|
-
default: "auto",
|
|
4720
|
+
"providers.webSearchOrder": {
|
|
4721
|
+
type: "array",
|
|
4722
|
+
default: [] as SearchProviderId[],
|
|
4481
4723
|
ui: {
|
|
4482
4724
|
tab: "providers",
|
|
4483
4725
|
group: "Services",
|
|
4484
|
-
label: "Web Search Provider",
|
|
4485
|
-
description:
|
|
4486
|
-
|
|
4726
|
+
label: "Web Search Provider Order",
|
|
4727
|
+
description:
|
|
4728
|
+
"Prioritized providers for the web_search tool; unlisted providers retain their default order afterward",
|
|
4729
|
+
options: SEARCH_PROVIDER_CHOICES,
|
|
4730
|
+
ordered: true,
|
|
4487
4731
|
},
|
|
4488
4732
|
},
|
|
4489
4733
|
"providers.webSearchExclude": {
|
|
@@ -4494,6 +4738,7 @@ export const SETTINGS_SCHEMA = {
|
|
|
4494
4738
|
group: "Services",
|
|
4495
4739
|
label: "Excluded Web Search Providers",
|
|
4496
4740
|
description: "Providers that web_search should never use, even as fallbacks",
|
|
4741
|
+
options: SEARCH_PROVIDER_CHOICES,
|
|
4497
4742
|
},
|
|
4498
4743
|
},
|
|
4499
4744
|
"providers.webSearchGeminiModel": {
|
|
@@ -4534,46 +4779,17 @@ export const SETTINGS_SCHEMA = {
|
|
|
4534
4779
|
],
|
|
4535
4780
|
},
|
|
4536
4781
|
},
|
|
4537
|
-
"providers.
|
|
4538
|
-
type: "
|
|
4539
|
-
|
|
4540
|
-
default: "auto",
|
|
4782
|
+
"providers.imageOrder": {
|
|
4783
|
+
type: "array",
|
|
4784
|
+
default: [] as ImageProvider[],
|
|
4541
4785
|
ui: {
|
|
4542
4786
|
tab: "providers",
|
|
4543
4787
|
group: "Services",
|
|
4544
|
-
label: "Image Provider",
|
|
4545
|
-
description:
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
label: "Auto",
|
|
4550
|
-
description:
|
|
4551
|
-
"Priority: per-request provider > configured provider > active session provider > GPT model image tool > Codex subscription > Antigravity > xAI > OpenRouter > Gemini",
|
|
4552
|
-
},
|
|
4553
|
-
{
|
|
4554
|
-
value: "openai",
|
|
4555
|
-
label: "OpenAI",
|
|
4556
|
-
description:
|
|
4557
|
-
"OPENAI_API_KEY (gpt-image-2) or active GPT model; falls back to a connected Codex subscription",
|
|
4558
|
-
},
|
|
4559
|
-
{
|
|
4560
|
-
value: "openai-codex",
|
|
4561
|
-
label: "OpenAI Codex (ChatGPT)",
|
|
4562
|
-
description: "Uses a connected Codex / ChatGPT subscription — no OPENAI_API_KEY needed",
|
|
4563
|
-
},
|
|
4564
|
-
{
|
|
4565
|
-
value: "antigravity",
|
|
4566
|
-
label: "Antigravity",
|
|
4567
|
-
description: "Requires google-antigravity OAuth",
|
|
4568
|
-
},
|
|
4569
|
-
{
|
|
4570
|
-
value: "xai",
|
|
4571
|
-
label: "xAI Grok Imagine",
|
|
4572
|
-
description: "Requires xAI Grok OAuth or XAI_API_KEY",
|
|
4573
|
-
},
|
|
4574
|
-
{ value: "gemini", label: "Gemini", description: "Requires GEMINI_API_KEY" },
|
|
4575
|
-
{ value: "openrouter", label: "OpenRouter", description: "Requires OPENROUTER_API_KEY" },
|
|
4576
|
-
],
|
|
4788
|
+
label: "Image Provider Order",
|
|
4789
|
+
description:
|
|
4790
|
+
"Prioritized providers for image generation; unlisted providers follow the active session provider and the built-in order",
|
|
4791
|
+
options: IMAGE_PROVIDER_CHOICES,
|
|
4792
|
+
ordered: true,
|
|
4577
4793
|
},
|
|
4578
4794
|
},
|
|
4579
4795
|
"providers.fireworksTier": {
|
|
@@ -5263,6 +5479,9 @@ export interface RetrySettings {
|
|
|
5263
5479
|
baseDelayMs: number;
|
|
5264
5480
|
maxDelayMs: number;
|
|
5265
5481
|
modelFallback: boolean;
|
|
5482
|
+
usageAwareFallback: boolean;
|
|
5483
|
+
usageReservePct: number;
|
|
5484
|
+
usageReservePolicy: "confirm" | "auto" | "fail-closed";
|
|
5266
5485
|
}
|
|
5267
5486
|
|
|
5268
5487
|
export interface MemoriesSettings {
|
package/src/config/settings.ts
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
import * as fs from "node:fs";
|
|
15
15
|
import * as os from "node:os";
|
|
16
16
|
import * as path from "node:path";
|
|
17
|
+
import { configureCredentialRedaction } from "@oh-my-pi/pi-ai/providers/transform-messages";
|
|
17
18
|
import { configureProviderMaxInFlightRequests } from "@oh-my-pi/pi-ai/stream";
|
|
18
19
|
import {
|
|
19
20
|
getAgentDbPath,
|
|
@@ -33,7 +34,9 @@ import type { ModelRole } from "../config/model-roles";
|
|
|
33
34
|
import { loadCapability } from "../discovery";
|
|
34
35
|
import { isLightTheme, setAutoThemeMapping, setColorBlindMode, setSymbolPreset } from "../modes/theme/theme";
|
|
35
36
|
import { AgentStorage } from "../session/agent-storage";
|
|
37
|
+
import { AUTO_IMAGE_PROVIDER_ORDER, isImageProviderId } from "../tools/image-providers";
|
|
36
38
|
import { type EditMode, normalizeEditMode } from "../utils/edit-mode";
|
|
39
|
+
import { isSearchProviderId, SEARCH_PROVIDER_ORDER } from "../web/search/types";
|
|
37
40
|
import { withFileLock } from "./file-lock";
|
|
38
41
|
import {
|
|
39
42
|
type BashInterceptorRule,
|
|
@@ -361,6 +364,7 @@ export class Settings {
|
|
|
361
364
|
if (options.configFiles) configFiles.push(...options.configFiles);
|
|
362
365
|
this.#configFiles = configFiles.map(file => path.resolve(this.#cwd, expandTilde(file)));
|
|
363
366
|
this.#persist = !options.inMemory && options.readOnly !== true;
|
|
367
|
+
liveSettingsInstances.add(new WeakRef(this));
|
|
364
368
|
|
|
365
369
|
if (options.overrides) {
|
|
366
370
|
for (const [key, value] of Object.entries(options.overrides)) {
|
|
@@ -534,6 +538,23 @@ export class Settings {
|
|
|
534
538
|
}
|
|
535
539
|
}
|
|
536
540
|
|
|
541
|
+
/** Set once this instance is discarded; background saves become no-ops. */
|
|
542
|
+
#savesCancelled = false;
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
* Drop pending debounced saves and refuse any further background writes.
|
|
546
|
+
* Used when an instance is being discarded (test teardown): an armed timer
|
|
547
|
+
* or a chained in-flight save on a dropped instance would otherwise fire
|
|
548
|
+
* later and race the successor's file locks.
|
|
549
|
+
*/
|
|
550
|
+
cancelPendingSaves(): void {
|
|
551
|
+
this.#savesCancelled = true;
|
|
552
|
+
clearTimeout(this.#saveTimer);
|
|
553
|
+
this.#saveTimer = undefined;
|
|
554
|
+
clearTimeout(this.#projectSaveTimer);
|
|
555
|
+
this.#projectSaveTimer = undefined;
|
|
556
|
+
}
|
|
557
|
+
|
|
537
558
|
/**
|
|
538
559
|
* Flush any pending saves to disk.
|
|
539
560
|
* Call before exit to ensure all changes are persisted.
|
|
@@ -1595,6 +1616,45 @@ export class Settings {
|
|
|
1595
1616
|
delete raw["mcp.discoveryMode"];
|
|
1596
1617
|
delete raw["mcp.discoveryDefaultServers"];
|
|
1597
1618
|
|
|
1619
|
+
// providers.webSearch / providers.image (single preferred provider) →
|
|
1620
|
+
// providers.webSearchOrder / providers.imageOrder (priority lists). A
|
|
1621
|
+
// concrete legacy choice becomes the head of the new list with every
|
|
1622
|
+
// remaining provider appended in its built-in order, so the old
|
|
1623
|
+
// preference stays #1 and the fallback chain is written out explicitly.
|
|
1624
|
+
// "auto" (or an unknown id) just drops the key — the default chain.
|
|
1625
|
+
const providerPrefsObj = raw.providers as Record<string, unknown> | undefined;
|
|
1626
|
+
const migrateProviderPreference = (
|
|
1627
|
+
legacyKey: string,
|
|
1628
|
+
orderKey: string,
|
|
1629
|
+
expand: (value: string) => string[] | undefined,
|
|
1630
|
+
): void => {
|
|
1631
|
+
const flatLegacyKey = `providers.${legacyKey}`;
|
|
1632
|
+
const legacy = providerPrefsObj?.[legacyKey] ?? raw[flatLegacyKey];
|
|
1633
|
+
if (legacy === undefined) return;
|
|
1634
|
+
const existingOrder = providerPrefsObj?.[orderKey] ?? raw[`providers.${orderKey}`];
|
|
1635
|
+
const orderAlreadySet = Array.isArray(existingOrder) && existingOrder.length > 0;
|
|
1636
|
+
if (!orderAlreadySet && typeof legacy === "string") {
|
|
1637
|
+
const expanded = expand(legacy);
|
|
1638
|
+
if (expanded) {
|
|
1639
|
+
const root = providerPrefsObj ?? {};
|
|
1640
|
+
root[orderKey] = expanded;
|
|
1641
|
+
raw.providers = root;
|
|
1642
|
+
}
|
|
1643
|
+
}
|
|
1644
|
+
if (providerPrefsObj) delete providerPrefsObj[legacyKey];
|
|
1645
|
+
delete raw[flatLegacyKey];
|
|
1646
|
+
};
|
|
1647
|
+
migrateProviderPreference("webSearch", "webSearchOrder", value =>
|
|
1648
|
+
value !== "auto" && isSearchProviderId(value)
|
|
1649
|
+
? [value, ...SEARCH_PROVIDER_ORDER.filter(id => id !== value)]
|
|
1650
|
+
: undefined,
|
|
1651
|
+
);
|
|
1652
|
+
migrateProviderPreference("image", "imageOrder", value =>
|
|
1653
|
+
value !== "auto" && isImageProviderId(value)
|
|
1654
|
+
? [value, ...AUTO_IMAGE_PROVIDER_ORDER.filter(id => id !== value)]
|
|
1655
|
+
: undefined,
|
|
1656
|
+
);
|
|
1657
|
+
|
|
1598
1658
|
return raw;
|
|
1599
1659
|
}
|
|
1600
1660
|
|
|
@@ -1646,7 +1706,7 @@ export class Settings {
|
|
|
1646
1706
|
}
|
|
1647
1707
|
|
|
1648
1708
|
async #saveNow(): Promise<void> {
|
|
1649
|
-
if (!this.#persist || !this.#configPath) return;
|
|
1709
|
+
if (this.#savesCancelled || !this.#persist || !this.#configPath) return;
|
|
1650
1710
|
if (this.#modified.size === 0 && this.#modifiedGlobalModelRoles.size === 0) return;
|
|
1651
1711
|
|
|
1652
1712
|
const configPath = this.#configPath;
|
|
@@ -1750,7 +1810,7 @@ export class Settings {
|
|
|
1750
1810
|
}
|
|
1751
1811
|
|
|
1752
1812
|
async #saveProjectNow(): Promise<void> {
|
|
1753
|
-
if (!this.#persist || this.#modifiedProjectModelRoles.size === 0) return;
|
|
1813
|
+
if (this.#savesCancelled || !this.#persist || this.#modifiedProjectModelRoles.size === 0) return;
|
|
1754
1814
|
|
|
1755
1815
|
const projectConfigPath = path.join(this.#cwd, ".omp", "config.yml");
|
|
1756
1816
|
const modifiedModelRoles = [...this.#modifiedProjectModelRoles];
|
|
@@ -1919,6 +1979,9 @@ const SETTING_HOOKS: Partial<Record<SettingPath, SettingHook<any>>> = {
|
|
|
1919
1979
|
"providers.maxInFlightRequests": value => {
|
|
1920
1980
|
configureProviderMaxInFlightRequests(validateProviderMaxInFlightRequests(value));
|
|
1921
1981
|
},
|
|
1982
|
+
"secrets.enabled": value => {
|
|
1983
|
+
configureCredentialRedaction(value === true);
|
|
1984
|
+
},
|
|
1922
1985
|
"hindsight.bankId": () => hindsightScopeSignal.fire(),
|
|
1923
1986
|
"hindsight.bankIdPrefix": () => hindsightScopeSignal.fire(),
|
|
1924
1987
|
"hindsight.scoping": () => hindsightScopeSignal.fire(),
|
|
@@ -1978,6 +2041,13 @@ export const onHindsightScopeChanged = (cb: () => void) => hindsightScopeSignal.
|
|
|
1978
2041
|
// Global Singleton
|
|
1979
2042
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
1980
2043
|
|
|
2044
|
+
/**
|
|
2045
|
+
* Weak registry of every constructed instance so `resetSettingsForTest` can
|
|
2046
|
+
* disarm stray background saves on isolated instances too. WeakRefs never
|
|
2047
|
+
* retain instances; the set is cleared on every test reset.
|
|
2048
|
+
*/
|
|
2049
|
+
const liveSettingsInstances = new Set<WeakRef<Settings>>();
|
|
2050
|
+
|
|
1981
2051
|
let globalInstance: Settings | null = null;
|
|
1982
2052
|
let globalInstancePromise: Promise<Settings> | null = null;
|
|
1983
2053
|
let boundSettingsInstance: Settings | null = null;
|
|
@@ -1997,10 +2067,19 @@ export function isSettingsInitialized(): boolean {
|
|
|
1997
2067
|
* @internal
|
|
1998
2068
|
*/
|
|
1999
2069
|
export function resetSettingsForTest(): void {
|
|
2070
|
+
// Disarm every constructed instance's debounced saves — including isolated
|
|
2071
|
+
// (non-singleton) instances: an armed timer or chained in-flight save on a
|
|
2072
|
+
// dropped instance fires mid-way through the NEXT test and races its file
|
|
2073
|
+
// locks/spies (cross-file pollution).
|
|
2074
|
+
for (const ref of liveSettingsInstances) {
|
|
2075
|
+
ref.deref()?.cancelPendingSaves();
|
|
2076
|
+
}
|
|
2077
|
+
liveSettingsInstances.clear();
|
|
2000
2078
|
globalInstance = null;
|
|
2001
2079
|
globalInstancePromise = null;
|
|
2002
2080
|
clearBoundSettingsMethods();
|
|
2003
2081
|
configureProviderMaxInFlightRequests(undefined);
|
|
2082
|
+
configureCredentialRedaction(false);
|
|
2004
2083
|
}
|
|
2005
2084
|
|
|
2006
2085
|
/**
|