@oh-my-pi/pi-coding-agent 16.1.22 → 16.2.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/CHANGELOG.md +99 -1
- package/dist/cli.js +4387 -4164
- package/dist/types/advisor/__tests__/emission-guard.test.d.ts +1 -0
- package/dist/types/advisor/emission-guard.d.ts +73 -0
- package/dist/types/advisor/index.d.ts +1 -0
- package/dist/types/advisor/runtime.d.ts +7 -0
- package/dist/types/advisor/watchdog.d.ts +2 -0
- package/dist/types/cli/flag-tables.d.ts +1 -0
- package/dist/types/cli/gallery-fixtures/search.d.ts +1 -1
- package/dist/types/cli/gc-cli.d.ts +58 -0
- package/dist/types/collab/display-name.d.ts +3 -0
- package/dist/types/collab/host.d.ts +0 -2
- package/dist/types/commands/gc.d.ts +37 -0
- package/dist/types/commands/worktree.d.ts +0 -3
- package/dist/types/config/inline-tool-descriptors-mode.d.ts +13 -0
- package/dist/types/config/model-discovery.d.ts +6 -1
- package/dist/types/config/model-registry.d.ts +6 -2
- package/dist/types/config/model-resolver.d.ts +12 -0
- package/dist/types/config/models-config-schema.d.ts +29 -2
- package/dist/types/config/models-config.d.ts +22 -1
- package/dist/types/config/settings-schema.d.ts +145 -21
- package/dist/types/config/settings.d.ts +13 -0
- package/dist/types/dap/config.d.ts +1 -1
- package/dist/types/edit/hashline/filesystem.d.ts +4 -2
- package/dist/types/edit/renderer.d.ts +4 -0
- package/dist/types/extensibility/extensions/types.d.ts +17 -17
- package/dist/types/extensibility/hooks/types.d.ts +10 -10
- package/dist/types/extensibility/plugins/marketplace/types.d.ts +1 -0
- package/dist/types/internal-urls/__tests__/ssh-protocol.test.d.ts +1 -0
- package/dist/types/internal-urls/index.d.ts +1 -0
- package/dist/types/internal-urls/registry-helpers.d.ts +2 -0
- package/dist/types/internal-urls/router.d.ts +1 -1
- package/dist/types/internal-urls/ssh-protocol.d.ts +10 -0
- package/dist/types/internal-urls/types.d.ts +19 -2
- package/dist/types/irc/bus.d.ts +6 -0
- package/dist/types/mcp/transports/stdio.d.ts +25 -1
- package/dist/types/modes/components/__tests__/move-overlay.test.d.ts +1 -0
- package/dist/types/modes/components/custom-editor.d.ts +7 -0
- package/dist/types/modes/components/move-overlay.d.ts +23 -0
- package/dist/types/modes/components/plugin-selector.d.ts +2 -1
- package/dist/types/modes/components/queue-mode-selector.d.ts +2 -1
- package/dist/types/modes/components/select-list-mouse-routing.d.ts +2 -0
- package/dist/types/modes/components/settings-defs.d.ts +4 -1
- package/dist/types/modes/components/settings-selector.d.ts +2 -0
- package/dist/types/modes/components/show-images-selector.d.ts +2 -1
- package/dist/types/modes/components/status-line/component.d.ts +2 -0
- package/dist/types/modes/components/status-line/types.d.ts +2 -0
- package/dist/types/modes/components/theme-selector.d.ts +2 -1
- package/dist/types/modes/components/thinking-selector.d.ts +2 -1
- package/dist/types/modes/controllers/command-controller.d.ts +10 -1
- package/dist/types/modes/controllers/streaming-reveal.d.ts +6 -0
- package/dist/types/modes/interactive-mode.d.ts +10 -1
- package/dist/types/modes/internal-url-autocomplete.d.ts +1 -1
- package/dist/types/modes/running-subagent-badge.d.ts +6 -0
- package/dist/types/modes/theme/mermaid-rendering.test.d.ts +1 -0
- package/dist/types/modes/theme/theme.d.ts +2 -1
- package/dist/types/modes/types.d.ts +9 -1
- package/dist/types/sdk.d.ts +2 -2
- package/dist/types/session/agent-session.d.ts +2 -1
- package/dist/types/session/session-listing.d.ts +10 -1
- package/dist/types/session/session-manager.d.ts +13 -0
- package/dist/types/slash-commands/builtin-registry.d.ts +1 -1
- package/dist/types/ssh/__tests__/connection-manager-args.test.d.ts +1 -0
- package/dist/types/ssh/__tests__/file-transfer-posix-guard.test.d.ts +1 -0
- package/dist/types/ssh/connection-manager.d.ts +2 -0
- package/dist/types/ssh/file-transfer.d.ts +79 -0
- package/dist/types/ssh/utils.d.ts +6 -0
- package/dist/types/system-prompt.d.ts +5 -0
- package/dist/types/task/executor.d.ts +16 -0
- package/dist/types/tiny/text.d.ts +1 -1
- package/dist/types/tools/builtin-names.d.ts +5 -1
- package/dist/types/tools/{find.d.ts → glob.d.ts} +15 -15
- package/dist/types/tools/{search.d.ts → grep.d.ts} +14 -14
- package/dist/types/tools/index.d.ts +3 -3
- package/dist/types/tools/path-utils.d.ts +29 -0
- package/dist/types/tools/plan-mode-guard.d.ts +7 -0
- package/dist/types/tools/read.d.ts +2 -2
- package/dist/types/tools/render-utils.d.ts +8 -0
- package/dist/types/tools/renderers.d.ts +11 -0
- package/dist/types/tools/ssh.d.ts +2 -0
- package/dist/types/tools/todo.d.ts +0 -16
- package/dist/types/tools/write.d.ts +2 -2
- package/dist/types/utils/active-repo-context.d.ts +8 -0
- package/dist/types/utils/image-resize.d.ts +1 -0
- package/dist/types/utils/markit-cache.d.ts +23 -0
- package/dist/types/utils/markit.d.ts +5 -1
- package/dist/types/utils/prompt-path.d.ts +1 -0
- package/dist/types/web/search/providers/duckduckgo.d.ts +14 -0
- package/dist/types/web/search/providers/firecrawl.d.ts +28 -0
- package/dist/types/web/search/providers/tinyfish.d.ts +29 -0
- package/dist/types/web/search/providers/xai.d.ts +13 -0
- package/dist/types/web/search/types.d.ts +18 -2
- package/package.json +30 -15
- package/scripts/bench-guard.ts +1 -1
- package/scripts/build-binary.ts +9 -9
- package/scripts/bundle-dist.ts +2 -2
- package/src/advisor/__tests__/advisor.test.ts +40 -4
- package/src/advisor/__tests__/emission-guard.test.ts +147 -0
- package/src/advisor/advise-tool.ts +1 -1
- package/src/advisor/emission-guard.ts +172 -0
- package/src/advisor/index.ts +1 -0
- package/src/advisor/runtime.ts +11 -0
- package/src/advisor/watchdog.ts +12 -1
- package/src/cli/args.ts +5 -2
- package/src/cli/auth-broker-cli.ts +17 -0
- package/src/cli/config-cli.ts +4 -0
- package/src/cli/flag-tables.ts +7 -4
- package/src/cli/gallery-cli.ts +14 -2
- package/src/cli/gallery-fixtures/edit.ts +60 -0
- package/src/cli/gallery-fixtures/fs.ts +17 -17
- package/src/cli/gallery-fixtures/search.ts +4 -4
- package/src/cli/gc-cli.ts +939 -0
- package/src/cli/usage-cli.ts +20 -1
- package/src/cli/web-search-cli.ts +1 -1
- package/src/cli-commands.ts +1 -0
- package/src/collab/display-name.ts +13 -0
- package/src/collab/guest.ts +5 -1
- package/src/collab/host.ts +2 -13
- package/src/commands/gc.ts +46 -0
- package/src/commands/worktree.ts +6 -0
- package/src/config/inline-tool-descriptors-mode.ts +27 -0
- package/src/config/model-discovery.ts +77 -8
- package/src/config/model-registry.ts +89 -11
- package/src/config/model-resolver.ts +39 -1
- package/src/config/models-config-schema.ts +41 -5
- package/src/config/models-config.ts +4 -1
- package/src/config/settings-schema.ts +130 -27
- package/src/config/settings.ts +216 -7
- package/src/cursor.ts +1 -1
- package/src/dap/config.ts +152 -8
- package/src/dap/session.ts +1 -1
- package/src/discovery/helpers.ts +3 -1
- package/src/edit/hashline/diff.ts +14 -3
- package/src/edit/hashline/execute.ts +42 -6
- package/src/edit/hashline/filesystem.ts +49 -8
- package/src/edit/index.ts +1 -0
- package/src/edit/modes/patch.ts +11 -1
- package/src/edit/renderer.ts +140 -13
- package/src/eval/__tests__/agent-bridge.test.ts +101 -0
- package/src/eval/__tests__/julia-prelude.test.ts +18 -0
- package/src/eval/agent-bridge.ts +26 -3
- package/src/eval/jl/runner.jl +7 -1
- package/src/eval/js/tool-bridge.ts +2 -2
- package/src/export/html/index.ts +1 -1
- package/src/export/html/template.js +3 -1
- package/src/export/html/tool-views.generated.js +20 -20
- package/src/extensibility/extensions/types.ts +22 -22
- package/src/extensibility/hooks/types.ts +11 -11
- package/src/extensibility/plugins/legacy-pi-bundled-keys.ts +10 -3
- package/src/extensibility/plugins/legacy-pi-bundled-registry.ts +31 -10
- package/src/extensibility/plugins/marketplace/manager.ts +22 -0
- package/src/extensibility/plugins/marketplace/types.ts +1 -0
- package/src/internal-urls/__tests__/ssh-protocol.test.ts +331 -0
- package/src/internal-urls/docs-index.generated.txt +2 -2
- package/src/internal-urls/docs-index.ts +2 -3
- package/src/internal-urls/index.ts +1 -0
- package/src/internal-urls/registry-helpers.ts +19 -4
- package/src/internal-urls/router.ts +5 -3
- package/src/internal-urls/ssh-protocol.ts +367 -0
- package/src/internal-urls/types.ts +19 -2
- package/src/irc/bus.ts +11 -3
- package/src/lsp/index.ts +8 -1
- package/src/mcp/oauth-discovery.ts +20 -20
- package/src/mcp/tool-bridge.ts +32 -2
- package/src/mcp/transports/stdio.test.ts +20 -3
- package/src/mcp/transports/stdio.ts +45 -14
- package/src/memories/index.ts +1 -1
- package/src/modes/acp/acp-event-mapper.ts +2 -2
- package/src/modes/components/__tests__/move-overlay.test.ts +166 -0
- package/src/modes/components/agent-hub.ts +3 -0
- package/src/modes/components/agent-transcript-viewer.ts +9 -7
- package/src/modes/components/custom-editor.ts +90 -5
- package/src/modes/components/move-overlay.ts +282 -0
- package/src/modes/components/plan-review-overlay.ts +35 -35
- package/src/modes/components/plugin-selector.ts +6 -1
- package/src/modes/components/queue-mode-selector.ts +6 -1
- package/src/modes/components/select-list-mouse-routing.ts +35 -0
- package/src/modes/components/session-selector.ts +11 -10
- package/src/modes/components/settings-defs.ts +14 -1
- package/src/modes/components/settings-selector.ts +196 -29
- package/src/modes/components/show-images-selector.ts +6 -1
- package/src/modes/components/status-line/component.ts +108 -28
- package/src/modes/components/status-line/segments.ts +5 -1
- package/src/modes/components/status-line/types.ts +2 -0
- package/src/modes/components/theme-selector.ts +6 -1
- package/src/modes/components/thinking-selector.ts +6 -1
- package/src/modes/components/tool-execution.ts +25 -9
- package/src/modes/components/tree-selector.ts +5 -5
- package/src/modes/controllers/command-controller.ts +140 -47
- package/src/modes/controllers/event-controller.ts +59 -3
- package/src/modes/controllers/input-controller.ts +70 -4
- package/src/modes/controllers/selector-controller.ts +15 -2
- package/src/modes/controllers/streaming-reveal.ts +17 -0
- package/src/modes/controllers/tool-args-reveal.ts +1 -1
- package/src/modes/interactive-mode.ts +142 -59
- package/src/modes/internal-url-autocomplete.ts +17 -2
- package/src/modes/prompt-action-autocomplete.ts +3 -1
- package/src/modes/running-subagent-badge.ts +13 -0
- package/src/modes/setup-wizard/scenes/glyph.ts +2 -13
- package/src/modes/setup-wizard/scenes/providers.ts +2 -1
- package/src/modes/setup-wizard/scenes/theme.ts +6 -12
- package/src/modes/setup-wizard/scenes/web-search.ts +8 -13
- package/src/modes/setup-wizard/wizard-overlay.ts +6 -5
- package/src/modes/theme/mermaid-rendering.test.ts +53 -0
- package/src/modes/theme/theme.ts +42 -15
- package/src/modes/types.ts +9 -1
- package/src/modes/utils/interactive-context-helpers.ts +1 -1
- package/src/priority.json +15 -0
- package/src/prompts/advisor/active-repo-watchdog.md +6 -0
- package/src/prompts/advisor/system.md +21 -7
- package/src/prompts/agents/designer.md +1 -1
- package/src/prompts/agents/explore.md +1 -1
- package/src/prompts/agents/librarian.md +2 -2
- package/src/prompts/agents/plan.md +2 -2
- package/src/prompts/agents/reviewer.md +1 -1
- package/src/prompts/agents/task.md +2 -2
- package/src/prompts/system/active-repo-context.md +4 -0
- package/src/prompts/system/gemini-tool-call-reminder.md +9 -0
- package/src/prompts/system/plan-mode-active.md +12 -3
- package/src/prompts/system/project-prompt.md +2 -2
- package/src/prompts/system/system-prompt.md +8 -6
- package/src/prompts/tools/bash.md +2 -2
- package/src/prompts/tools/checkpoint.md +1 -1
- package/src/prompts/tools/{find.md → glob.md} +1 -1
- package/src/prompts/tools/{search.md → grep.md} +3 -3
- package/src/prompts/tools/read.md +4 -2
- package/src/sdk.ts +98 -29
- package/src/session/agent-session.ts +828 -191
- package/src/session/session-history-format.ts +2 -2
- package/src/session/session-listing.ts +35 -2
- package/src/session/session-manager.ts +46 -0
- package/src/slash-commands/builtin-registry.ts +158 -22
- package/src/slash-commands/helpers/usage-report.ts +23 -2
- package/src/ssh/__tests__/connection-manager-args.test.ts +69 -0
- package/src/ssh/__tests__/file-transfer-posix-guard.test.ts +68 -0
- package/src/ssh/connection-manager.ts +12 -15
- package/src/ssh/file-transfer.ts +209 -0
- package/src/ssh/utils.ts +24 -0
- package/src/system-prompt.ts +60 -28
- package/src/task/executor.ts +96 -36
- package/src/task/index.ts +3 -3
- package/src/task/render.ts +14 -13
- package/src/task/worktree.ts +38 -1
- package/src/tiny/text.ts +49 -4
- package/src/tiny/worker.ts +3 -3
- package/src/tools/acp-bridge.ts +6 -1
- package/src/tools/bash.ts +2 -2
- package/src/tools/builtin-names.ts +26 -2
- package/src/tools/{find.ts → glob.ts} +48 -42
- package/src/tools/{search.ts → grep.ts} +311 -129
- package/src/tools/index.ts +13 -14
- package/src/tools/irc.ts +6 -2
- package/src/tools/path-utils.ts +64 -1
- package/src/tools/plan-mode-guard.ts +26 -13
- package/src/tools/read.ts +35 -6
- package/src/tools/render-utils.ts +14 -0
- package/src/tools/renderers.ts +15 -4
- package/src/tools/ssh.ts +17 -2
- package/src/tools/todo.ts +4 -26
- package/src/tools/write.ts +25 -9
- package/src/utils/active-repo-context.ts +143 -0
- package/src/utils/edit-mode.ts +19 -2
- package/src/utils/image-resize.ts +88 -7
- package/src/utils/lang-from-path.ts +3 -3
- package/src/utils/markit-cache.ts +166 -0
- package/src/utils/markit.ts +86 -18
- package/src/utils/prompt-path.ts +3 -0
- package/src/utils/shell-snapshot.ts +1 -1
- package/src/utils/title-generator.ts +1 -1
- package/src/web/search/provider.ts +54 -34
- package/src/web/search/providers/duckduckgo.ts +140 -0
- package/src/web/search/providers/firecrawl.ts +144 -0
- package/src/web/search/providers/tinyfish.ts +159 -0
- package/src/web/search/providers/xai.ts +292 -0
- package/src/web/search/providers/zai.ts +142 -56
- package/src/web/search/types.ts +6 -2
|
@@ -132,7 +132,7 @@ export const TAB_GROUPS: Record<SettingTab, readonly string[]> = {
|
|
|
132
132
|
tools: [
|
|
133
133
|
"Available Tools",
|
|
134
134
|
"Todos",
|
|
135
|
-
"
|
|
135
|
+
"Grep & Browser",
|
|
136
136
|
"GitHub",
|
|
137
137
|
"Output Limits",
|
|
138
138
|
"Execution",
|
|
@@ -278,6 +278,7 @@ export interface ModelTagsSettings {
|
|
|
278
278
|
// under `as const` while still letting SettingValue infer the correct element type.
|
|
279
279
|
const EMPTY_STRING_ARRAY: string[] = [];
|
|
280
280
|
const EMPTY_STRING_RECORD: Record<string, string> = {};
|
|
281
|
+
const EMPTY_NUMBER_RECORD: Record<string, number> = {};
|
|
281
282
|
const DEFAULT_CYCLE_ORDER: string[] = ["smol", "default", "slow"];
|
|
282
283
|
const EMPTY_MODEL_TAGS_RECORD: ModelTagsSettings = {};
|
|
283
284
|
const HINDSIGHT_RECALL_TYPES_DEFAULT: string[] = ["world", "experience"];
|
|
@@ -289,13 +290,13 @@ export const DEFAULT_BASH_INTERCEPTOR_RULES: BashInterceptorRule[] = [
|
|
|
289
290
|
},
|
|
290
291
|
{
|
|
291
292
|
pattern: "^\\s*(grep|rg|ripgrep|ag|ack)\\s+",
|
|
292
|
-
tool: "
|
|
293
|
-
message: "Use the `
|
|
293
|
+
tool: "grep",
|
|
294
|
+
message: "Use the `grep` tool instead of grep/rg. It respects .gitignore and provides structured output.",
|
|
294
295
|
},
|
|
295
296
|
{
|
|
296
297
|
pattern: "^\\s*(find|fd|locate)\\s+.*(-name|-iname|-type|--type|-glob)",
|
|
297
|
-
tool: "
|
|
298
|
-
message: "Use the `
|
|
298
|
+
tool: "glob",
|
|
299
|
+
message: "Use the `glob` tool instead of find/fd. It respects .gitignore and is faster for glob patterns.",
|
|
299
300
|
},
|
|
300
301
|
{
|
|
301
302
|
pattern: "^\\s*sed\\s+(-i|--in-place)",
|
|
@@ -455,6 +456,18 @@ export const SETTINGS_SCHEMA = {
|
|
|
455
456
|
|
|
456
457
|
disabledProviders: { type: "array", default: EMPTY_STRING_ARRAY },
|
|
457
458
|
|
|
459
|
+
"providers.maxInFlightRequests": {
|
|
460
|
+
type: "record",
|
|
461
|
+
default: EMPTY_NUMBER_RECORD,
|
|
462
|
+
ui: {
|
|
463
|
+
tab: "providers",
|
|
464
|
+
group: "Services",
|
|
465
|
+
label: "Max In-Flight Requests",
|
|
466
|
+
description:
|
|
467
|
+
'Maximum concurrent LLM requests per provider id (for example "openai" or "anthropic"), shared across local OMP processes with this config root. Omitted providers are unlimited.',
|
|
468
|
+
},
|
|
469
|
+
},
|
|
470
|
+
|
|
458
471
|
disabledExtensions: { type: "array", default: EMPTY_STRING_ARRAY },
|
|
459
472
|
|
|
460
473
|
modelRoles: { type: "record", default: EMPTY_STRING_RECORD },
|
|
@@ -778,6 +791,17 @@ export const SETTINGS_SCHEMA = {
|
|
|
778
791
|
"Maximum number of inline images kept as live terminal graphics (default 8). Older images fall back to a text placeholder via a full redraw once the limit is exceeded. Set to 0 to keep every image (no limit).",
|
|
779
792
|
},
|
|
780
793
|
|
|
794
|
+
"terminal.showProgress": {
|
|
795
|
+
type: "boolean",
|
|
796
|
+
default: false,
|
|
797
|
+
ui: {
|
|
798
|
+
tab: "appearance",
|
|
799
|
+
group: "Display",
|
|
800
|
+
label: "Native Terminal Progress",
|
|
801
|
+
description: "Emit OSC 9;4 indeterminate progress while the agent or context maintenance is running",
|
|
802
|
+
},
|
|
803
|
+
},
|
|
804
|
+
|
|
781
805
|
"tui.textSizing": {
|
|
782
806
|
type: "boolean",
|
|
783
807
|
default: false,
|
|
@@ -790,6 +814,17 @@ export const SETTINGS_SCHEMA = {
|
|
|
790
814
|
},
|
|
791
815
|
},
|
|
792
816
|
|
|
817
|
+
"tui.renderMermaid": {
|
|
818
|
+
type: "boolean",
|
|
819
|
+
default: true,
|
|
820
|
+
ui: {
|
|
821
|
+
tab: "appearance",
|
|
822
|
+
group: "Display",
|
|
823
|
+
label: "Render Mermaid Diagrams",
|
|
824
|
+
description: "Render Mermaid fenced code blocks as ASCII diagrams",
|
|
825
|
+
},
|
|
826
|
+
},
|
|
827
|
+
|
|
793
828
|
"tui.hyperlinks": {
|
|
794
829
|
type: "enum",
|
|
795
830
|
values: ["off", "auto", "always"] as const,
|
|
@@ -950,15 +985,37 @@ export const SETTINGS_SCHEMA = {
|
|
|
950
985
|
},
|
|
951
986
|
},
|
|
952
987
|
|
|
953
|
-
|
|
988
|
+
"model.loopGuard.toolCallReminder": {
|
|
954
989
|
type: "boolean",
|
|
955
|
-
default:
|
|
990
|
+
default: true,
|
|
991
|
+
ui: {
|
|
992
|
+
tab: "model",
|
|
993
|
+
group: "Thinking",
|
|
994
|
+
label: "Loop Guard Tool-Call Reminder",
|
|
995
|
+
description:
|
|
996
|
+
"When a Gemini reasoning stream emits many consecutive planning headers without calling a tool, interrupt it and inject a reminder to issue a tool call (requires Loop Guard)",
|
|
997
|
+
},
|
|
998
|
+
},
|
|
999
|
+
|
|
1000
|
+
inlineToolDescriptors: {
|
|
1001
|
+
type: "enum",
|
|
1002
|
+
values: ["auto", "on", "off"] as const,
|
|
1003
|
+
default: "auto",
|
|
956
1004
|
ui: {
|
|
957
1005
|
tab: "model",
|
|
958
1006
|
group: "Prompt",
|
|
959
1007
|
label: "Inline Tool Descriptors",
|
|
960
1008
|
description:
|
|
961
|
-
"Render full tool descriptors in the system prompt and strip top-level/nested descriptions from provider tool schemas so descriptor text is sent once",
|
|
1009
|
+
"Render full tool descriptors in the system prompt and strip top-level/nested descriptions from provider tool schemas so descriptor text is sent once. Auto enables this for Gemini models and disables it otherwise",
|
|
1010
|
+
options: [
|
|
1011
|
+
{
|
|
1012
|
+
value: "auto",
|
|
1013
|
+
label: "Auto",
|
|
1014
|
+
description: "Inline descriptors for Gemini models; keep them in tool schemas otherwise",
|
|
1015
|
+
},
|
|
1016
|
+
{ value: "on", label: "On", description: "Always inline descriptors in the system prompt" },
|
|
1017
|
+
{ value: "off", label: "Off", description: "Keep descriptors in provider tool schemas only" },
|
|
1018
|
+
],
|
|
962
1019
|
},
|
|
963
1020
|
},
|
|
964
1021
|
|
|
@@ -1700,6 +1757,17 @@ export const SETTINGS_SCHEMA = {
|
|
|
1700
1757
|
},
|
|
1701
1758
|
},
|
|
1702
1759
|
|
|
1760
|
+
"compaction.midTurnEnabled": {
|
|
1761
|
+
type: "boolean",
|
|
1762
|
+
default: true,
|
|
1763
|
+
ui: {
|
|
1764
|
+
tab: "context",
|
|
1765
|
+
group: "Compaction",
|
|
1766
|
+
label: "Mid-Turn Compaction",
|
|
1767
|
+
description: "Check thresholds at safe mid-turn tool-loop boundaries before the next provider request",
|
|
1768
|
+
},
|
|
1769
|
+
},
|
|
1770
|
+
|
|
1703
1771
|
"compaction.strategy": {
|
|
1704
1772
|
type: "enum",
|
|
1705
1773
|
values: ["context-full", "handoff", "shake", "snapcompact", "off"] as const,
|
|
@@ -3206,37 +3274,37 @@ export const SETTINGS_SCHEMA = {
|
|
|
3206
3274
|
},
|
|
3207
3275
|
},
|
|
3208
3276
|
|
|
3209
|
-
//
|
|
3210
|
-
"
|
|
3277
|
+
// Grep, glob, and AST tools
|
|
3278
|
+
"glob.enabled": {
|
|
3211
3279
|
type: "boolean",
|
|
3212
3280
|
default: true,
|
|
3213
3281
|
ui: {
|
|
3214
3282
|
tab: "tools",
|
|
3215
3283
|
group: "Available Tools",
|
|
3216
|
-
label: "
|
|
3217
|
-
description: "Enable the
|
|
3284
|
+
label: "Glob",
|
|
3285
|
+
description: "Enable the glob tool for glob-based file lookup",
|
|
3218
3286
|
},
|
|
3219
3287
|
},
|
|
3220
3288
|
|
|
3221
|
-
"
|
|
3289
|
+
"grep.enabled": {
|
|
3222
3290
|
type: "boolean",
|
|
3223
3291
|
default: true,
|
|
3224
3292
|
ui: {
|
|
3225
3293
|
tab: "tools",
|
|
3226
3294
|
group: "Available Tools",
|
|
3227
|
-
label: "
|
|
3228
|
-
description: "Enable the
|
|
3295
|
+
label: "Grep",
|
|
3296
|
+
description: "Enable the grep tool for regex content search",
|
|
3229
3297
|
},
|
|
3230
3298
|
},
|
|
3231
3299
|
|
|
3232
|
-
"
|
|
3300
|
+
"grep.contextBefore": {
|
|
3233
3301
|
type: "number",
|
|
3234
3302
|
default: 1,
|
|
3235
3303
|
ui: {
|
|
3236
3304
|
tab: "tools",
|
|
3237
|
-
group: "
|
|
3238
|
-
label: "
|
|
3239
|
-
description: "Lines of context before each
|
|
3305
|
+
group: "Grep & Browser",
|
|
3306
|
+
label: "Grep Context Before",
|
|
3307
|
+
description: "Lines of context before each grep match",
|
|
3240
3308
|
options: [
|
|
3241
3309
|
{ value: "0", label: "0 lines" },
|
|
3242
3310
|
{ value: "1", label: "1 line" },
|
|
@@ -3247,14 +3315,14 @@ export const SETTINGS_SCHEMA = {
|
|
|
3247
3315
|
},
|
|
3248
3316
|
},
|
|
3249
3317
|
|
|
3250
|
-
"
|
|
3318
|
+
"grep.contextAfter": {
|
|
3251
3319
|
type: "number",
|
|
3252
3320
|
default: 3,
|
|
3253
3321
|
ui: {
|
|
3254
3322
|
tab: "tools",
|
|
3255
|
-
group: "
|
|
3256
|
-
label: "
|
|
3257
|
-
description: "Lines of context after each
|
|
3323
|
+
group: "Grep & Browser",
|
|
3324
|
+
label: "Grep Context After",
|
|
3325
|
+
description: "Lines of context after each grep match",
|
|
3258
3326
|
options: [
|
|
3259
3327
|
{ value: "0", label: "0 lines" },
|
|
3260
3328
|
{ value: "1", label: "1 line" },
|
|
@@ -3432,7 +3500,7 @@ export const SETTINGS_SCHEMA = {
|
|
|
3432
3500
|
default: true,
|
|
3433
3501
|
ui: {
|
|
3434
3502
|
tab: "tools",
|
|
3435
|
-
group: "
|
|
3503
|
+
group: "Grep & Browser",
|
|
3436
3504
|
label: "Headless Browser",
|
|
3437
3505
|
description: "Launch browser in headless mode (disable to show browser UI)",
|
|
3438
3506
|
},
|
|
@@ -3443,7 +3511,7 @@ export const SETTINGS_SCHEMA = {
|
|
|
3443
3511
|
default: true,
|
|
3444
3512
|
ui: {
|
|
3445
3513
|
tab: "tools",
|
|
3446
|
-
group: "
|
|
3514
|
+
group: "Grep & Browser",
|
|
3447
3515
|
label: "cmux Browser",
|
|
3448
3516
|
description:
|
|
3449
3517
|
"Use cmux WKWebView surfaces for browser automation when a cmux socket is available. Set PI_BROWSER_CMUX=0 or PI_BROWSER_CMUX=1 to override.",
|
|
@@ -3454,7 +3522,7 @@ export const SETTINGS_SCHEMA = {
|
|
|
3454
3522
|
default: undefined,
|
|
3455
3523
|
ui: {
|
|
3456
3524
|
tab: "tools",
|
|
3457
|
-
group: "
|
|
3525
|
+
group: "Grep & Browser",
|
|
3458
3526
|
label: "Screenshot Directory",
|
|
3459
3527
|
description:
|
|
3460
3528
|
"Directory to save screenshots. If unset, screenshots go to a temp file. Supports ~. Examples: ~/Downloads, ~/Desktop, /sdcard/Download (Android)",
|
|
@@ -3586,7 +3654,7 @@ export const SETTINGS_SCHEMA = {
|
|
|
3586
3654
|
group: "Discovery & MCP",
|
|
3587
3655
|
label: "Essential Tools Override",
|
|
3588
3656
|
description:
|
|
3589
|
-
"Override the always-loaded built-in tools (default: read, bash, edit, write,
|
|
3657
|
+
"Override the always-loaded built-in tools (default: read, bash, edit, write, glob, eval). Leave empty to use defaults.",
|
|
3590
3658
|
},
|
|
3591
3659
|
},
|
|
3592
3660
|
|
|
@@ -3789,6 +3857,18 @@ export const SETTINGS_SCHEMA = {
|
|
|
3789
3857
|
},
|
|
3790
3858
|
},
|
|
3791
3859
|
|
|
3860
|
+
"worktree.base": {
|
|
3861
|
+
type: "string",
|
|
3862
|
+
default: undefined,
|
|
3863
|
+
ui: {
|
|
3864
|
+
tab: "tasks",
|
|
3865
|
+
group: "Isolation",
|
|
3866
|
+
label: "Worktree Base Directory",
|
|
3867
|
+
description:
|
|
3868
|
+
"Base directory for agent-managed worktrees — task-isolation copies, `github` PR checkouts, and `omp worktree` cleanup all live here. Unset uses ~/.omp/wt. Must be an absolute or ~-relative path; relative paths are ignored. The OMP_WORKTREE_DIR env var overrides this.",
|
|
3869
|
+
},
|
|
3870
|
+
},
|
|
3871
|
+
|
|
3792
3872
|
"task.eager": {
|
|
3793
3873
|
type: "enum",
|
|
3794
3874
|
values: ["default", "preferred", "always"] as const,
|
|
@@ -4630,6 +4710,18 @@ export const SETTINGS_SCHEMA = {
|
|
|
4630
4710
|
default: "unset" as const,
|
|
4631
4711
|
},
|
|
4632
4712
|
|
|
4713
|
+
"gc.blobs": { type: "boolean", default: true },
|
|
4714
|
+
|
|
4715
|
+
"gc.archive": { type: "boolean", default: true },
|
|
4716
|
+
|
|
4717
|
+
"gc.wal": { type: "boolean", default: true },
|
|
4718
|
+
|
|
4719
|
+
"gc.coldArchiveAfterDays": { type: "number", default: 30 },
|
|
4720
|
+
|
|
4721
|
+
"gc.retainNewestGlobal": { type: "number", default: 20 },
|
|
4722
|
+
|
|
4723
|
+
"gc.retainNewestPerCwd": { type: "number", default: 10 },
|
|
4724
|
+
|
|
4633
4725
|
"thinkingBudgets.minimal": { type: "number", default: 1024 },
|
|
4634
4726
|
|
|
4635
4727
|
"thinkingBudgets.low": { type: "number", default: 2048 },
|
|
@@ -4731,6 +4823,7 @@ export interface CompactionSettings {
|
|
|
4731
4823
|
thresholdTokens: number;
|
|
4732
4824
|
reserveTokens: number;
|
|
4733
4825
|
keepRecentTokens: number;
|
|
4826
|
+
midTurnEnabled: boolean;
|
|
4734
4827
|
handoffSaveToDisk: boolean;
|
|
4735
4828
|
autoContinue: boolean;
|
|
4736
4829
|
remoteEnabled: boolean;
|
|
@@ -4875,6 +4968,15 @@ export interface CodexResetsSettings {
|
|
|
4875
4968
|
keepCredits: number;
|
|
4876
4969
|
}
|
|
4877
4970
|
|
|
4971
|
+
export interface GcSettings {
|
|
4972
|
+
blobs: boolean;
|
|
4973
|
+
archive: boolean;
|
|
4974
|
+
wal: boolean;
|
|
4975
|
+
coldArchiveAfterDays: number;
|
|
4976
|
+
retainNewestGlobal: number;
|
|
4977
|
+
retainNewestPerCwd: number;
|
|
4978
|
+
}
|
|
4979
|
+
|
|
4878
4980
|
/** Map group prefix -> typed settings interface */
|
|
4879
4981
|
export interface GroupTypeMap {
|
|
4880
4982
|
compaction: CompactionSettings;
|
|
@@ -4894,6 +4996,7 @@ export interface GroupTypeMap {
|
|
|
4894
4996
|
cycleOrder: string[];
|
|
4895
4997
|
shellMinimizer: ShellMinimizerSettings;
|
|
4896
4998
|
codexResets: CodexResetsSettings;
|
|
4999
|
+
gc: GcSettings;
|
|
4897
5000
|
}
|
|
4898
5001
|
|
|
4899
5002
|
export type GroupPrefix = keyof GroupTypeMap;
|
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 { configureProviderMaxInFlightRequests } from "@oh-my-pi/pi-ai/stream";
|
|
17
18
|
import {
|
|
18
19
|
getAgentDbPath,
|
|
19
20
|
getAgentDir,
|
|
@@ -22,6 +23,7 @@ import {
|
|
|
22
23
|
isEnoent,
|
|
23
24
|
logger,
|
|
24
25
|
procmgr,
|
|
26
|
+
setWorktreesDir,
|
|
25
27
|
} from "@oh-my-pi/pi-utils";
|
|
26
28
|
import { JSONC, YAML } from "bun";
|
|
27
29
|
import { type Settings as SettingsCapabilityItem, settingsCapability } from "../capability/settings";
|
|
@@ -29,6 +31,7 @@ import type { ModelRole } from "../config/model-roles";
|
|
|
29
31
|
import { loadCapability } from "../discovery";
|
|
30
32
|
import { isLightTheme, setAutoThemeMapping, setColorBlindMode, setSymbolPreset } from "../modes/theme/theme";
|
|
31
33
|
import { AgentStorage } from "../session/agent-storage";
|
|
34
|
+
import { normalizeToolName } from "../tools/builtin-names";
|
|
32
35
|
import { type EditMode, normalizeEditMode } from "../utils/edit-mode";
|
|
33
36
|
import { withFileLock } from "./file-lock";
|
|
34
37
|
import {
|
|
@@ -61,6 +64,8 @@ export interface SettingsOptions {
|
|
|
61
64
|
agentDir?: string;
|
|
62
65
|
/** Don't persist to disk (for tests) */
|
|
63
66
|
inMemory?: boolean;
|
|
67
|
+
/** Read config sources without opening storage or writing migrations */
|
|
68
|
+
readOnly?: boolean;
|
|
64
69
|
/** Initial overrides */
|
|
65
70
|
overrides?: Partial<Record<SettingPath, unknown>>;
|
|
66
71
|
/** Extra config.yml-style overlays loaded after global/project settings */
|
|
@@ -105,6 +110,33 @@ function setByPath(obj: RawSettings, segments: string[], value: unknown): void {
|
|
|
105
110
|
current[segments[segments.length - 1]] = value;
|
|
106
111
|
}
|
|
107
112
|
|
|
113
|
+
export function normalizeProviderMaxInFlightRequests(value: unknown): Record<string, number> {
|
|
114
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
115
|
+
const normalized: Record<string, number> = {};
|
|
116
|
+
for (const [provider, rawLimit] of Object.entries(value)) {
|
|
117
|
+
if (typeof rawLimit !== "number" || !Number.isFinite(rawLimit) || rawLimit <= 0) continue;
|
|
118
|
+
normalized[provider] = Math.max(1, Math.floor(rawLimit));
|
|
119
|
+
}
|
|
120
|
+
return normalized;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export function validateProviderMaxInFlightRequests(value: unknown): Record<string, number> {
|
|
124
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
125
|
+
const invalidProviders: string[] = [];
|
|
126
|
+
const normalized: Record<string, number> = {};
|
|
127
|
+
for (const [provider, rawLimit] of Object.entries(value)) {
|
|
128
|
+
if (typeof rawLimit !== "number" || !Number.isFinite(rawLimit) || rawLimit <= 0) {
|
|
129
|
+
invalidProviders.push(provider);
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
normalized[provider] = Math.max(1, Math.floor(rawLimit));
|
|
133
|
+
}
|
|
134
|
+
if (invalidProviders.length > 0) {
|
|
135
|
+
throw new Error(`Provider request limits must be positive numbers: ${invalidProviders.join(", ")}`);
|
|
136
|
+
}
|
|
137
|
+
return normalized;
|
|
138
|
+
}
|
|
139
|
+
|
|
108
140
|
const PATH_SCOPED_ARRAY_SETTINGS = new Set<SettingPath>(["enabledModels", "disabledProviders"]);
|
|
109
141
|
type PathScopedStringArrayEntry = {
|
|
110
142
|
path?: unknown;
|
|
@@ -136,11 +168,17 @@ function stringArrayFromUnknown(value: unknown): string[] {
|
|
|
136
168
|
return [];
|
|
137
169
|
}
|
|
138
170
|
|
|
171
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
172
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
173
|
+
}
|
|
174
|
+
|
|
139
175
|
function shallowStringRecord(value: unknown): Record<string, string> {
|
|
140
|
-
if (!
|
|
176
|
+
if (!isRecord(value)) return {};
|
|
141
177
|
|
|
142
178
|
const result: Record<string, string> = {};
|
|
143
|
-
for (const
|
|
179
|
+
for (const key in value) {
|
|
180
|
+
if (!Object.hasOwn(value, key)) continue;
|
|
181
|
+
const item = value[key];
|
|
144
182
|
if (typeof item === "string") {
|
|
145
183
|
result[key] = item;
|
|
146
184
|
}
|
|
@@ -228,7 +266,7 @@ export class Settings {
|
|
|
228
266
|
this.#agentDir = path.normalize(options.agentDir ?? getAgentDir());
|
|
229
267
|
this.#configPath = options.inMemory ? null : path.join(this.#agentDir, "config.yml");
|
|
230
268
|
this.#configFiles = options.configFiles?.map(file => path.resolve(this.#cwd, expandTilde(file))) ?? [];
|
|
231
|
-
this.#persist = !options.inMemory;
|
|
269
|
+
this.#persist = !options.inMemory && options.readOnly !== true;
|
|
232
270
|
|
|
233
271
|
if (options.overrides) {
|
|
234
272
|
for (const [key, value] of Object.entries(options.overrides)) {
|
|
@@ -270,6 +308,23 @@ export class Settings {
|
|
|
270
308
|
);
|
|
271
309
|
}
|
|
272
310
|
|
|
311
|
+
/**
|
|
312
|
+
* Load effective settings from config.yml and project providers without
|
|
313
|
+
* opening agent.db, migrating legacy settings, or writing marker files.
|
|
314
|
+
*/
|
|
315
|
+
static loadReadOnly(options: SettingsOptions = {}): Promise<Settings> {
|
|
316
|
+
const instance = new Settings({ ...options, readOnly: true });
|
|
317
|
+
return instance.#loadReadOnly();
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Load a persisted settings instance without touching the global singleton.
|
|
322
|
+
*/
|
|
323
|
+
static loadIsolated(options: SettingsOptions = {}): Promise<Settings> {
|
|
324
|
+
const instance = new Settings(options);
|
|
325
|
+
return instance.#load();
|
|
326
|
+
}
|
|
327
|
+
|
|
273
328
|
/**
|
|
274
329
|
* Create an isolated instance for testing.
|
|
275
330
|
* Does not affect the global singleton.
|
|
@@ -336,7 +391,7 @@ export class Settings {
|
|
|
336
391
|
// Trigger hook if exists
|
|
337
392
|
const hook = SETTING_HOOKS[path];
|
|
338
393
|
if (hook) {
|
|
339
|
-
hook(
|
|
394
|
+
hook(next, prev);
|
|
340
395
|
}
|
|
341
396
|
this.#fireEffectiveSettingChanged(path, next, prev);
|
|
342
397
|
}
|
|
@@ -481,10 +536,10 @@ export class Settings {
|
|
|
481
536
|
*/
|
|
482
537
|
getEditVariantForModel(model: string | undefined): EditMode | null {
|
|
483
538
|
if (!model) return null;
|
|
484
|
-
const variants = (this.#merged
|
|
485
|
-
|
|
539
|
+
const variants = shallowStringRecord(getByPath(this.#merged, ["edit", "modelVariants"]));
|
|
540
|
+
const modelLower = model.toLowerCase();
|
|
486
541
|
for (const pattern in variants) {
|
|
487
|
-
if (
|
|
542
|
+
if (modelLower.includes(pattern.toLowerCase())) {
|
|
488
543
|
const value = normalizeEditMode(variants[pattern]);
|
|
489
544
|
if (value) {
|
|
490
545
|
return value;
|
|
@@ -583,6 +638,19 @@ export class Settings {
|
|
|
583
638
|
return this;
|
|
584
639
|
}
|
|
585
640
|
|
|
641
|
+
async #loadReadOnly(): Promise<Settings> {
|
|
642
|
+
const projectPromise = this.#loadProjectSettings();
|
|
643
|
+
|
|
644
|
+
if (this.#configPath) {
|
|
645
|
+
this.#global = await this.#loadYaml(this.#configPath);
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
this.#project = await projectPromise;
|
|
649
|
+
this.#configOverlay = await this.#loadConfigOverlays();
|
|
650
|
+
this.#rebuildMerged();
|
|
651
|
+
return this;
|
|
652
|
+
}
|
|
653
|
+
|
|
586
654
|
async #loadYaml(filePath: string): Promise<RawSettings> {
|
|
587
655
|
try {
|
|
588
656
|
const content = await Bun.file(filePath).text();
|
|
@@ -816,6 +884,14 @@ export class Settings {
|
|
|
816
884
|
raw["snapcompact.systemPrompt"] = raw["snapcompact.systemPrompt"] ? "all" : "none";
|
|
817
885
|
}
|
|
818
886
|
|
|
887
|
+
// inlineToolDescriptors: boolean -> enum (auto | on | off). The old
|
|
888
|
+
// `true`/`false` mapped directly onto inline-on/inline-off, so preserve
|
|
889
|
+
// the user's explicit choice; new installs get the `auto` default that
|
|
890
|
+
// turns it on only for Gemini models.
|
|
891
|
+
if (typeof raw.inlineToolDescriptors === "boolean") {
|
|
892
|
+
raw.inlineToolDescriptors = raw.inlineToolDescriptors ? "on" : "off";
|
|
893
|
+
}
|
|
894
|
+
|
|
819
895
|
// statusLine: rename "plan_mode" segment to "mode"
|
|
820
896
|
const statusLineObj = raw.statusLine as Record<string, unknown> | undefined;
|
|
821
897
|
if (statusLineObj) {
|
|
@@ -949,6 +1025,124 @@ export class Settings {
|
|
|
949
1025
|
delete raw["power.preventDisplaySleep"];
|
|
950
1026
|
}
|
|
951
1027
|
|
|
1028
|
+
// Migration for renamed settings grep.* and glob.* from search.* and find.*:
|
|
1029
|
+
// 1. Nested settings: find -> glob, search -> grep (per-property merge to avoid clobbering)
|
|
1030
|
+
const ensureRawObject = (key: "glob" | "grep"): Record<string, unknown> => {
|
|
1031
|
+
const current = raw[key];
|
|
1032
|
+
if (isRecord(current)) {
|
|
1033
|
+
return current;
|
|
1034
|
+
}
|
|
1035
|
+
const created: Record<string, unknown> = {};
|
|
1036
|
+
raw[key] = created;
|
|
1037
|
+
return created;
|
|
1038
|
+
};
|
|
1039
|
+
|
|
1040
|
+
if ("find" in raw) {
|
|
1041
|
+
const findObj = raw.find;
|
|
1042
|
+
if (isRecord(findObj)) {
|
|
1043
|
+
const globObj = ensureRawObject("glob");
|
|
1044
|
+
const findKeys: Array<"enabled"> = ["enabled"];
|
|
1045
|
+
for (const key of findKeys) {
|
|
1046
|
+
if (key in findObj && !(key in globObj)) {
|
|
1047
|
+
globObj[key] = findObj[key];
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
delete raw.find;
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
if ("search" in raw) {
|
|
1055
|
+
const searchObj = raw.search;
|
|
1056
|
+
if (isRecord(searchObj)) {
|
|
1057
|
+
const grepObj = ensureRawObject("grep");
|
|
1058
|
+
const searchKeys: Array<"enabled" | "contextBefore" | "contextAfter"> = [
|
|
1059
|
+
"enabled",
|
|
1060
|
+
"contextBefore",
|
|
1061
|
+
"contextAfter",
|
|
1062
|
+
];
|
|
1063
|
+
for (const key of searchKeys) {
|
|
1064
|
+
if (key in searchObj && !(key in grepObj)) {
|
|
1065
|
+
grepObj[key] = searchObj[key];
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
delete raw.search;
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
// 2. Flat settings keys: map them to the proper nested target so get/set resolves them correctly
|
|
1073
|
+
if ("find.enabled" in raw) {
|
|
1074
|
+
const globObj = ensureRawObject("glob");
|
|
1075
|
+
if (!("enabled" in globObj)) {
|
|
1076
|
+
globObj.enabled = raw["find.enabled"];
|
|
1077
|
+
}
|
|
1078
|
+
delete raw["find.enabled"];
|
|
1079
|
+
}
|
|
1080
|
+
if ("search.enabled" in raw) {
|
|
1081
|
+
const grepObj = ensureRawObject("grep");
|
|
1082
|
+
if (!("enabled" in grepObj)) {
|
|
1083
|
+
grepObj.enabled = raw["search.enabled"];
|
|
1084
|
+
}
|
|
1085
|
+
delete raw["search.enabled"];
|
|
1086
|
+
}
|
|
1087
|
+
if ("search.contextBefore" in raw) {
|
|
1088
|
+
const grepObj = ensureRawObject("grep");
|
|
1089
|
+
if (!("contextBefore" in grepObj)) {
|
|
1090
|
+
grepObj.contextBefore = raw["search.contextBefore"];
|
|
1091
|
+
}
|
|
1092
|
+
delete raw["search.contextBefore"];
|
|
1093
|
+
}
|
|
1094
|
+
if ("search.contextAfter" in raw) {
|
|
1095
|
+
const grepObj = ensureRawObject("grep");
|
|
1096
|
+
if (!("contextAfter" in grepObj)) {
|
|
1097
|
+
grepObj.contextAfter = raw["search.contextAfter"];
|
|
1098
|
+
}
|
|
1099
|
+
delete raw["search.contextAfter"];
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
// 3. Tool-name arrays use wire IDs too. Preserve user overrides across
|
|
1103
|
+
// the rename without duplicating entries if they already added grep/glob.
|
|
1104
|
+
const migrateToolNameList = (names: unknown): unknown => {
|
|
1105
|
+
if (!Array.isArray(names)) return names;
|
|
1106
|
+
const out: unknown[] = [];
|
|
1107
|
+
const seen = new Set<string>();
|
|
1108
|
+
for (const name of names) {
|
|
1109
|
+
const migrated = typeof name === "string" ? normalizeToolName(name) : name;
|
|
1110
|
+
if (typeof migrated === "string") {
|
|
1111
|
+
if (seen.has(migrated)) continue;
|
|
1112
|
+
seen.add(migrated);
|
|
1113
|
+
}
|
|
1114
|
+
out.push(migrated);
|
|
1115
|
+
}
|
|
1116
|
+
return out;
|
|
1117
|
+
};
|
|
1118
|
+
const ensureToolsObject = (): Record<string, unknown> => {
|
|
1119
|
+
const current = raw.tools;
|
|
1120
|
+
if (current && typeof current === "object" && !Array.isArray(current)) {
|
|
1121
|
+
return current as Record<string, unknown>;
|
|
1122
|
+
}
|
|
1123
|
+
const created: Record<string, unknown> = {};
|
|
1124
|
+
raw.tools = created;
|
|
1125
|
+
return created;
|
|
1126
|
+
};
|
|
1127
|
+
const toolsObj = raw.tools as Record<string, unknown> | undefined;
|
|
1128
|
+
if (toolsObj && "essentialOverride" in toolsObj) {
|
|
1129
|
+
toolsObj.essentialOverride = migrateToolNameList(toolsObj.essentialOverride);
|
|
1130
|
+
}
|
|
1131
|
+
if ("tools.essentialOverride" in raw) {
|
|
1132
|
+
const nestedToolsObj = ensureToolsObject();
|
|
1133
|
+
if (!("essentialOverride" in nestedToolsObj)) {
|
|
1134
|
+
nestedToolsObj.essentialOverride = migrateToolNameList(raw["tools.essentialOverride"]);
|
|
1135
|
+
}
|
|
1136
|
+
delete raw["tools.essentialOverride"];
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
// Also clean up any empty nested objects we might have created or left behind
|
|
1140
|
+
if (raw.glob && typeof raw.glob === "object" && Object.keys(raw.glob).length === 0) {
|
|
1141
|
+
delete raw.glob;
|
|
1142
|
+
}
|
|
1143
|
+
if (raw.grep && typeof raw.grep === "object" && Object.keys(raw.grep).length === 0) {
|
|
1144
|
+
delete raw.grep;
|
|
1145
|
+
}
|
|
952
1146
|
// readHashLines: removed. Hashline anchors are now driven solely by
|
|
953
1147
|
// edit.mode === "hashline"; the separate read toggle only ever produced
|
|
954
1148
|
// the incoherent "hashline edits without addressable anchors" state.
|
|
@@ -1152,9 +1346,23 @@ const SETTING_HOOKS: Partial<Record<SettingPath, SettingHook<any>>> = {
|
|
|
1152
1346
|
appendOnlyModeSignal.fire(value);
|
|
1153
1347
|
}
|
|
1154
1348
|
},
|
|
1349
|
+
"providers.maxInFlightRequests": value => {
|
|
1350
|
+
configureProviderMaxInFlightRequests(validateProviderMaxInFlightRequests(value));
|
|
1351
|
+
},
|
|
1155
1352
|
"hindsight.bankId": () => hindsightScopeSignal.fire(),
|
|
1156
1353
|
"hindsight.bankIdPrefix": () => hindsightScopeSignal.fire(),
|
|
1157
1354
|
"hindsight.scoping": () => hindsightScopeSignal.fire(),
|
|
1355
|
+
"worktree.base": value => {
|
|
1356
|
+
const dir = typeof value === "string" && value.trim() ? value : undefined;
|
|
1357
|
+
// Always call so an unset/empty value clears a previously-applied override.
|
|
1358
|
+
// setWorktreesDir expands `~`, rejects relative paths, and returns the
|
|
1359
|
+
// applied absolute path (or undefined when cleared/rejected).
|
|
1360
|
+
if (dir && !setWorktreesDir(dir)) {
|
|
1361
|
+
logger.warn("Settings: worktree.base must be an absolute or ~-relative path; ignoring", { value: dir });
|
|
1362
|
+
} else if (!dir) {
|
|
1363
|
+
setWorktreesDir(undefined);
|
|
1364
|
+
}
|
|
1365
|
+
},
|
|
1158
1366
|
};
|
|
1159
1367
|
/** Fires when `provider.appendOnlyContext` changes at runtime. */
|
|
1160
1368
|
const appendOnlyModeSignal = new SettingSignal<[value: string]>("provider.appendOnlyContext");
|
|
@@ -1216,6 +1424,7 @@ export function resetSettingsForTest(): void {
|
|
|
1216
1424
|
globalInstance = null;
|
|
1217
1425
|
globalInstancePromise = null;
|
|
1218
1426
|
clearBoundSettingsMethods();
|
|
1427
|
+
configureProviderMaxInFlightRequests(undefined);
|
|
1219
1428
|
}
|
|
1220
1429
|
|
|
1221
1430
|
/**
|
package/src/cursor.ts
CHANGED
|
@@ -178,7 +178,7 @@ export class CursorExecHandlers implements ICursorExecHandlers {
|
|
|
178
178
|
async grep(args: Parameters<NonNullable<ICursorExecHandlers["grep"]>>[0]) {
|
|
179
179
|
const toolCallId = decodeToolCallId(args.toolCallId);
|
|
180
180
|
const searchPath = args.glob ? `${args.path || "."}/${args.glob}` : args.path || ".";
|
|
181
|
-
const toolResultMessage = await executeTool(this.options, "
|
|
181
|
+
const toolResultMessage = await executeTool(this.options, "grep", toolCallId, {
|
|
182
182
|
pattern: args.pattern,
|
|
183
183
|
paths: [searchPath],
|
|
184
184
|
case: args.caseInsensitive === true ? false : undefined,
|