@oh-my-pi/pi-coding-agent 14.2.1 → 14.4.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 +143 -1
- package/package.json +19 -19
- package/src/autoresearch/prompt.md +1 -1
- package/src/cli/args.ts +10 -1
- package/src/cli/shell-cli.ts +15 -3
- package/src/commit/agentic/prompts/analyze-file.md +1 -1
- package/src/config/model-registry.ts +67 -15
- package/src/config/prompt-templates.ts +5 -5
- package/src/config/settings-schema.ts +63 -4
- package/src/cursor.ts +3 -8
- package/src/debug/system-info.ts +6 -2
- package/src/discovery/claude.ts +58 -36
- package/src/discovery/helpers.ts +3 -3
- package/src/discovery/opencode.ts +20 -2
- package/src/edit/diff.ts +50 -47
- package/src/edit/index.ts +87 -57
- package/src/edit/line-hash.ts +735 -19
- package/src/edit/modes/apply-patch.ts +0 -9
- package/src/edit/modes/atom.ts +658 -0
- package/src/edit/modes/chunk.ts +144 -78
- package/src/edit/modes/hashline.ts +223 -146
- package/src/edit/modes/patch.ts +5 -9
- package/src/edit/modes/replace.ts +6 -11
- package/src/edit/renderer.ts +112 -143
- package/src/edit/streaming.ts +385 -0
- package/src/exec/bash-executor.ts +58 -5
- package/src/export/html/template.generated.ts +1 -1
- package/src/export/html/template.js +4 -12
- package/src/extensibility/custom-tools/types.ts +2 -0
- package/src/extensibility/custom-tools/wrapper.ts +2 -1
- package/src/internal-urls/docs-index.generated.ts +7 -7
- package/src/internal-urls/pi-protocol.ts +0 -2
- package/src/lsp/client.ts +8 -1
- package/src/lsp/defaults.json +2 -1
- package/src/lsp/index.ts +1 -1
- package/src/mcp/render.ts +1 -8
- package/src/modes/acp/acp-agent.ts +76 -2
- package/src/modes/components/assistant-message.ts +5 -34
- package/src/modes/components/diff.ts +23 -14
- package/src/modes/components/footer.ts +21 -16
- package/src/modes/components/hook-editor.ts +1 -1
- package/src/modes/components/settings-defs.ts +6 -1
- package/src/modes/components/todo-reminder.ts +1 -8
- package/src/modes/components/tool-execution.ts +112 -105
- package/src/modes/controllers/input-controller.ts +1 -1
- package/src/modes/controllers/selector-controller.ts +1 -1
- package/src/modes/interactive-mode.ts +0 -2
- package/src/modes/print-mode.ts +8 -0
- package/src/modes/theme/mermaid-cache.ts +13 -52
- package/src/modes/theme/theme.ts +2 -2
- package/src/prompts/agents/librarian.md +1 -1
- package/src/prompts/agents/reviewer.md +4 -4
- package/src/prompts/ci-green-request.md +1 -1
- package/src/prompts/review-request.md +1 -1
- package/src/prompts/system/subagent-system-prompt.md +3 -3
- package/src/prompts/system/subagent-yield-reminder.md +11 -0
- package/src/prompts/system/system-prompt.md +4 -1
- package/src/prompts/tools/ask.md +3 -2
- package/src/prompts/tools/ast-edit.md +15 -19
- package/src/prompts/tools/ast-grep.md +18 -24
- package/src/prompts/tools/atom.md +96 -0
- package/src/prompts/tools/browser.md +1 -0
- package/src/prompts/tools/chunk-edit.md +58 -179
- package/src/prompts/tools/debug.md +4 -5
- package/src/prompts/tools/exit-plan-mode.md +4 -5
- package/src/prompts/tools/find.md +4 -8
- package/src/prompts/tools/github.md +18 -0
- package/src/prompts/tools/grep.md +8 -8
- package/src/prompts/tools/hashline.md +22 -89
- package/src/prompts/tools/{gemini-image.md → image-gen.md} +1 -1
- package/src/prompts/tools/inspect-image.md +6 -6
- package/src/prompts/tools/lsp.md +6 -0
- package/src/prompts/tools/patch.md +12 -19
- package/src/prompts/tools/python.md +3 -2
- package/src/prompts/tools/read-chunk.md +46 -8
- package/src/prompts/tools/read.md +9 -6
- package/src/prompts/tools/ssh.md +8 -17
- package/src/prompts/tools/todo-write.md +54 -41
- package/src/sdk.ts +22 -14
- package/src/session/agent-session.ts +61 -22
- package/src/session/session-manager.ts +228 -57
- package/src/session/streaming-output.ts +11 -0
- package/src/system-prompt.ts +7 -2
- package/src/task/executor.ts +44 -48
- package/src/task/render.ts +11 -13
- package/src/tools/ask.ts +7 -7
- package/src/tools/ast-edit.ts +45 -41
- package/src/tools/ast-grep.ts +77 -85
- package/src/tools/bash.ts +21 -9
- package/src/tools/browser.ts +32 -30
- package/src/tools/calculator.ts +4 -4
- package/src/tools/cancel-job.ts +1 -1
- package/src/tools/checkpoint.ts +2 -2
- package/src/tools/debug.ts +41 -37
- package/src/tools/exit-plan-mode.ts +1 -1
- package/src/tools/find.ts +4 -4
- package/src/tools/gh-renderer.ts +12 -4
- package/src/tools/gh.ts +514 -712
- package/src/tools/grep.ts +115 -130
- package/src/tools/{gemini-image.ts → image-gen.ts} +459 -60
- package/src/tools/index.ts +14 -32
- package/src/tools/inspect-image.ts +3 -3
- package/src/tools/json-tree.ts +114 -114
- package/src/tools/match-line-format.ts +9 -8
- package/src/tools/notebook.ts +8 -7
- package/src/tools/poll-tool.ts +2 -1
- package/src/tools/python.ts +9 -23
- package/src/tools/read.ts +32 -21
- package/src/tools/render-mermaid.ts +1 -1
- package/src/tools/render-utils.ts +18 -0
- package/src/tools/renderers.ts +2 -2
- package/src/tools/report-tool-issue.ts +3 -2
- package/src/tools/resolve.ts +1 -1
- package/src/tools/review.ts +12 -10
- package/src/tools/search-tool-bm25.ts +2 -4
- package/src/tools/sqlite-reader.ts +116 -3
- package/src/tools/ssh.ts +4 -4
- package/src/tools/todo-write.ts +172 -147
- package/src/tools/vim.ts +14 -15
- package/src/tools/write.ts +4 -4
- package/src/tools/{submit-result.ts → yield.ts} +11 -13
- package/src/utils/edit-mode.ts +2 -1
- package/src/utils/file-display-mode.ts +10 -5
- package/src/utils/git.ts +9 -5
- package/src/utils/shell-snapshot.ts +2 -3
- package/src/vim/render.ts +4 -4
- package/src/web/search/providers/codex.ts +129 -6
- package/src/prompts/system/subagent-submit-reminder.md +0 -11
- package/src/prompts/tools/gh-issue-view.md +0 -11
- package/src/prompts/tools/gh-pr-checkout.md +0 -12
- package/src/prompts/tools/gh-pr-diff.md +0 -12
- package/src/prompts/tools/gh-pr-push.md +0 -11
- package/src/prompts/tools/gh-pr-view.md +0 -11
- package/src/prompts/tools/gh-repo-view.md +0 -11
- package/src/prompts/tools/gh-run-watch.md +0 -12
- package/src/prompts/tools/gh-search-issues.md +0 -11
- package/src/prompts/tools/gh-search-prs.md +0 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,148 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
|
+
### Breaking Changes
|
|
5
|
+
|
|
6
|
+
- Replaced the legacy `gh_repo_view`, `gh_issue_view`, `gh_pr_view`, `gh_pr_diff`, `gh_pr_checkout`, `gh_pr_push`, `gh_run_watch`, `gh_search_issues`, and `gh_search_prs` tool names with only `github`, which requires updating existing callers that invoked the old `gh_*` tools
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- Added the unified `github` tool with op-based dispatch for repository, issue, pull request, search, checkout, push, and Actions watch workflows
|
|
11
|
+
- Added `op` routing so callers can select `repo_view`, `issue_view`, `pr_view`, `pr_diff`, `pr_checkout`, `pr_push`, `search_issues`, `search_prs`, or `run_watch` through a single tool entry point
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- Updated GitHub CLI render output to show `GitHub <op>` for tool calls dispatched through `github` operations
|
|
16
|
+
|
|
17
|
+
## [14.4.0] - 2026-04-26
|
|
18
|
+
|
|
19
|
+
### Breaking Changes
|
|
20
|
+
|
|
21
|
+
- Removed multi-pattern array input from `ast_grep` by changing `pat` to a single pattern string, so call sites using `pat: [...]` must be updated to send one query per invocation
|
|
22
|
+
- Removed `lang`, `glob`, and `sel` options from `ast_edit` and `ast_grep`, and moved those behaviors into the required `path` argument
|
|
23
|
+
- Required `path` for `ast_edit` and `ast_grep`, so invocations that relied on implicit repo-root searching are no longer valid
|
|
24
|
+
- Changed `todo_write` from multi-field verb payloads to an ordered array of flat operations, while retaining `replace` for harness bootstrap compatibility
|
|
25
|
+
- Renamed atom edit operations from `before` and `after` to `pre` and `post`, so existing `atom` payloads using the old operation keys must be updated
|
|
26
|
+
- Changed the hashline anchor format from `LINE#ID:content` to `LINEID:content` (no `#` separator, colon between anchor and content, no padding on line numbers); expanded the bigram alphabet from 40 hand-picked English bigrams to the full 647 single-token 2-letter bigrams — invalidates every previously captured `LINE#ID` reference
|
|
27
|
+
- Renamed the subagent completion contract from `submit_result` to `yield`, so subagent sessions must now finish with the `yield` tool and the `requireYieldTool` option; `submit_result`/`requireSubmitResultTool` and old completion calls are no longer recognized
|
|
28
|
+
- Changed the hashline and chunk anchor ID format from the prior hex-like tokens to two-letter BPE bigrams (for example `#th`), which invalidates previously captured `LINE#ID`/chunk selectors and requires re-reading to refresh anchors
|
|
29
|
+
|
|
30
|
+
### Added
|
|
31
|
+
|
|
32
|
+
- Added inline file overrides in atom locators (`loc: "a.ts:160sr"`) so cross-file edits can be written without a separate per-entry `path` field
|
|
33
|
+
- Added `openai` to the `providers.image` options, allowing image generation to be explicitly routed through the active GPT Responses/Codex model
|
|
34
|
+
- Added `between` atom edit operation to replace only the lines between two surviving anchors while preserving the boundary anchors
|
|
35
|
+
- Added conflict detection for `between` atom edits to require non-overlapping regions and forbid edits targeting lines strictly inside those regions
|
|
36
|
+
- Added `atom` edit mode to `edit` with single-anchor operations (`set`, `before`, `after`, `del`, `sub`, `ins`) for hashline-anchored line edits
|
|
37
|
+
- Added support for request-level `path` defaults in patch, replace, and chunk edits so shared file paths no longer need to be repeated in every entry
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
|
|
41
|
+
- Updated `atom` and `hashline` edit anchor validation to auto-rebase a stale anchor within ±2 lines when the same hash matches a unique nearby line, continuing the edit with a warning instead of immediate failure
|
|
42
|
+
- Changed bash command output labels from `[full result: artifact://…]` to `[raw output: artifact://…]` for artifact references produced from large command output
|
|
43
|
+
- Changed `todo_write` `done`, `rm`, and `drop` operations to target all tasks when neither `task` nor `phase` is provided, and made `append` create the target phase automatically when missing
|
|
44
|
+
- Updated `ast_edit` and `ast_grep` to pass file-selection intent through `path` (including inline globs and comma/space-separated path lists) instead of separate `glob` filters
|
|
45
|
+
- Changed `ast_grep` pagination API from `offset` to `skip`
|
|
46
|
+
- Flattened `todo_write` operation arguments to `{ op, task?, phase?, items? }[]` and removed task details from the persisted todo shape
|
|
47
|
+
- Changed `grep` truncation output to report `Result limit reached; narrow path.` and label match/result caps as `first N`
|
|
48
|
+
- Changed JSON tree output to truncate inline argument pairs by available width and add an ellipsis when values no longer fit in the display
|
|
49
|
+
- Changed JSON tree rendering to hide harness-internal `intent` and `__partialJson` fields from top-level tool output
|
|
50
|
+
- Simplified the `grep` tool schema by requiring `path`, folding glob and type filtering into path globs, auto-detecting multiline patterns, removing model-controlled context and limit options, and renaming result skipping to `skip`.
|
|
51
|
+
- Changed atom edit request format to use a shared `loc` selector, including range (`"160sr-9ab"`) and boundary (`"^"`, `"$"`) forms instead of per-operation anchor fields
|
|
52
|
+
- Changed atom edit payload fields so `set`, `pre`, and `post` now require line-array values and `sub` now takes a `[find, replace]` tuple, with boundary deletion now expressed as `set: []`
|
|
53
|
+
- Changed edit diff wrapping to preserve the active line-prefix separator (`|` or `│`) while keeping continuation lines aligned by line-number width
|
|
54
|
+
- Changed Vim focus and viewport rendering to align cursor/selection markers and line numbers in a single gutter format
|
|
55
|
+
- Changed auto image provider selection for `providers.image=auto` to try active GPT image generation before Antigravity, OpenRouter, and Gemini
|
|
56
|
+
- Updated atom and hashline anchor validation to require the full `line+suffix` anchor format and report missing-line-number errors more clearly, including guidance when only a 2-letter suffix is provided
|
|
57
|
+
- Changed read, grep, and ast-edit line-prefixed output to drop fixed-width line number padding, so anchors render in natural width without leading spaces
|
|
58
|
+
- Updated terminal diff rendering to use a continuous `│` gutter and hide repeated line numbers on adjacent diff lines
|
|
59
|
+
- Updated subagent reminders, prompts, and rendered subagent output to reference `yield` completion and report missing/final results from `yield` tool data
|
|
60
|
+
- Updated the `edit` workflow to treat `atom` mode like hashline mode for read output, so hashline anchors are shown when `atom` is selected
|
|
61
|
+
- Adjusted patch/replace/chunk tooling to accept optional entry paths and to apply a top-level path default
|
|
62
|
+
- Updated hashline/chunk selector parsing to the new stable bigram token set used for checksums
|
|
63
|
+
- Renamed the image generation implementation module to `image-gen` and routed active GPT Responses/Codex models through OpenAI's hosted `image_generation` tool with WebP output
|
|
64
|
+
|
|
65
|
+
### Removed
|
|
66
|
+
|
|
67
|
+
- Removed line-range support from `atom` mode selectors, including `loc` values like `160sr-170ab`, so edits must target a single anchor (`160sr`, `^`, or `$`) per entry
|
|
68
|
+
- Removed the atom `del` verb and now require anchored-line deletion to be requested with `set: []`
|
|
69
|
+
- Removed `todo_write` task details and the `add_notes` operation
|
|
70
|
+
|
|
71
|
+
### Fixed
|
|
72
|
+
|
|
73
|
+
- Improved no-op edit diagnostics for `atom` and `hashline` operations so edits that leave content unchanged now fail with contextual details (edit index, locator, and reason), including guidance for `replace_range` no-op cases
|
|
74
|
+
- Wrapped `todo_write` operations in an `ops` object so Codex/OpenAI function schemas always use a JSON Schema object.
|
|
75
|
+
- Fixed JSON tree rendering for tool arguments by excluding injected internal keys from displayed root records
|
|
76
|
+
- Printed assistant `errorMessage` text in print mode output to stderr so message-level errors are visible during non-interactive runs
|
|
77
|
+
- Displayed assistant `errorMessage` text in the assistant message component for completed tool responses with non-terminal stop reasons
|
|
78
|
+
- Fixed atom input handling to ignore null optional verb fields so entries with `pre`, `set`, `post`, or `sub` set to `null` remain valid
|
|
79
|
+
- Fixed status-line Git branch rendering to degrade gracefully when the process hits `ENFILE`/`EMFILE` while reading optional Git refs
|
|
80
|
+
- Changed hashline mismatch failure output to show a clean numbered context block with numbered gutter and full-anchor alignment guidance when edits are rejected after the file changed
|
|
81
|
+
- Fixed `atom` mode to apply multiple edits on the same anchor line without index-shift artifacts, so mixed operations like `before`, `after`, `set`, `sub`, `ins`, and `del` now resolve consistently
|
|
82
|
+
- Fixed `atom` mode `append_file` insertion to preserve a file’s trailing newline sentinel when appending content
|
|
83
|
+
- Fixed `read` output for raw archive entries so hashline anchors, line numbers, and chunked formatting are not injected into raw content
|
|
84
|
+
- Fixed hashline parsing so lines like `# Note:` or `# TODO:` are no longer misinterpreted and stripped as hashline prefixes
|
|
85
|
+
- Adjusted patch and replace validation to report a clear missing-path error when neither an entry path nor a top-level path is provided
|
|
86
|
+
|
|
87
|
+
## [14.3.0] - 2026-04-25
|
|
88
|
+
|
|
89
|
+
### Added
|
|
90
|
+
|
|
91
|
+
- Added Markdown pipe-table `row_N` chunk selectors for row-level table edits.
|
|
92
|
+
- Added `resolveToolAlias` export so tool names in CLI and session setup are normalized to canonical names, including mapping legacy `read` references to `open`
|
|
93
|
+
- Added new `open` and `open-chunk` tool prompt documentation pages to describe canonical `open` usage for local files/directories, chunk reads, and URLs
|
|
94
|
+
- Added full-output retrieval metadata to minimized shell command output by appending an `artifact://<id>` footer with byte counts, allowing users to open the original unminimized command output
|
|
95
|
+
- Added streaming preview API exports from the package (`resolveEditMode`, `EDIT_MODE_STRATEGIES`, and chunk preview helpers) so editors can reuse mode-aware edit preview logic programmatically
|
|
96
|
+
- Added `shellMinimizer` configuration options (`enabled`, `settingsPath`, `only`, `except`, and `maxCaptureBytes`) so users can control shell output minimization behavior
|
|
97
|
+
|
|
98
|
+
### Changed
|
|
99
|
+
|
|
100
|
+
- Changed the canonical file/URL reader tool from `read` to `open` across default tool lists and routing, including system prompts, plan mode, cursor handlers, and runtime tool registration
|
|
101
|
+
- Changed runtime and UI handling to render and track `open` tool calls as first-class (with `read` accepted as legacy alias), including ACP mapping, session observers, and streaming message groups
|
|
102
|
+
- Changed chunk edit guidance to document parser-specific region behavior, including TypeScript decorator/JSDoc sibling chunks, Python docstrings as body content, Python opaque nested chunks, Markdown whole-chunk fallbacks, ID volatility, and indentation display differences
|
|
103
|
+
- Changed chunk deletion in chunk edit mode to require explicit `delete: true`; `write: null` and bare `{ path }` entries now fail with guidance instead of deleting content.
|
|
104
|
+
- Changed chunk edit validation to reject entries with multiple operation fields instead of choosing one and ignoring the rest.
|
|
105
|
+
- Changed chunk edit validation to reject `write: ""` as an accidental destructive empty replacement; use the open tool for inspection or `delete: true` for deletion.
|
|
106
|
+
- Changed chunk edit responses to warn when appending or prepending to a container without `~`, since that inserts outside the container rather than inside its body.
|
|
107
|
+
- Changed fetch output logging so URL-fetch artifacts now use `.open.log` naming instead of `.read.log`
|
|
108
|
+
- Changed Bash interception guidance and errors to recommend `open` in place of `read` for cat/head/tail-style commands
|
|
109
|
+
- Changed exported SDK tool surface to expose `OpenTool` as canonical and keep `ReadTool` as a compatibility alias
|
|
110
|
+
- Changed session list loading to use parallel workers and fixed-size prefix reads per session file, reducing latency when loading many or large sessions
|
|
111
|
+
- Changed edit call rendering to use mode-aware streaming diff previews, including multi-file chunk edit previews grouped by file path while arguments are still streaming
|
|
112
|
+
- Changed shell execution in both interactive and non-interactive modes to route command output through the configured shell output minimizer
|
|
113
|
+
- Changed default behavior so shell output minimization can now be toggled from settings without code changes
|
|
114
|
+
- Changed shell output minimization to leave compound and piped commands unchanged; only a single eligible whole command is captured and minimized after it exits
|
|
115
|
+
|
|
116
|
+
### Removed
|
|
117
|
+
|
|
118
|
+
- Removed the chunk edit `read: true` operation; use the open tool to inspect chunks without modifying files.
|
|
119
|
+
- Removed the `replace: { old, new }` chunk edit operation. Use `write` or `insert` for chunk edits instead.
|
|
120
|
+
|
|
121
|
+
### Fixed
|
|
122
|
+
|
|
123
|
+
- Fixed startup crashes on Linux systems where Bun's `os.cpus()` fails on non-contiguous CPU numbering ([#779](https://github.com/can1357/oh-my-pi/issues/779))
|
|
124
|
+
- Fixed `gh_pr_push` so branches without `gh_pr_checkout` metadata fail instead of falling back to the tracked merge branch, and updated the GitHub tool setting copy to stop calling the tool group read-only ([#778](https://github.com/can1357/oh-my-pi/issues/778))
|
|
125
|
+
- Fixed session list metadata extraction to better populate session titles and first-user summaries from partial session data when full JSONL parsing is unavailable
|
|
126
|
+
- Fixed shell execution output to replace raw streamed bash output with the minimizer’s rewritten text before final output while still preserving the full original output as artifact metadata
|
|
127
|
+
- Fixed bash command minimization to save the full unminimized output as a `bash-original` artifact during AgentSession shell execution, enabling `artifact://` access to complete command output
|
|
128
|
+
- Fixed streaming chunk previews that could display an incomplete trailing edit as a deletion when partial JSON temporarily converted in-flight values to `null`
|
|
129
|
+
- Fixed edit streaming preview updates to cancel obsolete in-flight computations and avoid rendering stale previews as args change
|
|
130
|
+
- Fixed chunk edits to reject unsafe `^`/`~` writes on code leaf chunks instead of falling back to whole-chunk replacement and risking structural indentation corruption
|
|
131
|
+
- Fixed chunk `replace` operations to dedent multiline replacement snippets before reapplying the matched source indentation, preventing Python nested replacements from compounding indentation on repeated edits.
|
|
132
|
+
- Fixed Go chunk trees to classify `package` clauses separately from imports and to avoid duplicating method receivers in method summaries.
|
|
133
|
+
- Fixed chunk path-not-found guidance so it recommends `sel="?"` without claiming the already-shown listing must be re-read.
|
|
134
|
+
- Fixed Markdown chunk appends to preserve blank-line separators after line-oriented inserts such as table rows
|
|
135
|
+
- Fixed Markdown section region-fallback warnings to call out child chunks that will be replaced by whole-section edits.
|
|
136
|
+
- Fixed rejected chunk-edit errors to distinguish current file content from hypothetical post-edit parse-error previews and to state when a same-file batch was rolled back.
|
|
137
|
+
- Fixed unsafe Python head-region edits by rejecting decorated Python `^` writes and Python `^` deletes that can orphan indented bodies while still parsing.
|
|
138
|
+
- Fixed Markdown table-row appends so row-shaped content lands inside the table block instead of after the trailing blank-line separator.
|
|
139
|
+
- Fixed Markdown root writes to preserve fenced-code indentation verbatim.
|
|
140
|
+
- Fixed Rust enum-variant replacement matching so trailing commas are included consistently with whole-variant writes.
|
|
141
|
+
- Fixed streaming edit call headers to keep showing the target file path while the edit arguments are still arriving
|
|
142
|
+
- Fixed Mermaid fenced markdown rendering in assistant messages on terminals without image protocol support ([#650](https://github.com/can1357/oh-my-pi/issues/650))
|
|
143
|
+
- Fixed chunk edit path parsing so plan-mode edits to section-addressed `local://PLAN.md:<selector>` paths are classified as writes to the plan file
|
|
144
|
+
- Fixed SQLite `read` helper queries to reject `where=` clauses with SQL control syntax that could override the structured selector's pagination; raw SQL remains available through `q=SELECT ...`
|
|
145
|
+
- Fixed `models` provider transport overrides so `headers`-only entries apply without requiring `baseUrl`, including runtime `registerProvider()` overrides that now persist across `refresh()` / `refreshProvider()`, preserve existing `baseUrl` on subsequent headers-only updates, clear stale transport overrides when a provider is re-registered under a different extension source, and keep runtime transport headers authoritative when `modelOverrides` set overlapping header keys
|
|
4
146
|
|
|
5
147
|
## [14.2.0] - 2026-04-23
|
|
6
148
|
|
|
@@ -7127,4 +7269,4 @@ Initial public release.
|
|
|
7127
7269
|
- Git branch display in footer
|
|
7128
7270
|
- Message queueing during streaming responses
|
|
7129
7271
|
- OAuth integration for Gmail and Google Calendar access
|
|
7130
|
-
- HTML export with syntax highlighting and collapsible sections
|
|
7272
|
+
- HTML export with syntax highlighting and collapsible sections
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-coding-agent",
|
|
4
|
-
"version": "14.
|
|
4
|
+
"version": "14.4.0",
|
|
5
5
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://github.com/can1357/oh-my-pi",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -44,31 +44,31 @@
|
|
|
44
44
|
"generate-template": "bun scripts/generate-template.ts"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@agentclientprotocol/sdk": "0.
|
|
48
|
-
"@mozilla/readability": "^0.6",
|
|
49
|
-
"@oh-my-pi/omp-stats": "14.
|
|
50
|
-
"@oh-my-pi/pi-agent-core": "14.
|
|
51
|
-
"@oh-my-pi/pi-ai": "14.
|
|
52
|
-
"@oh-my-pi/pi-natives": "14.
|
|
53
|
-
"@oh-my-pi/pi-tui": "14.
|
|
54
|
-
"@oh-my-pi/pi-utils": "14.
|
|
55
|
-
"@sinclair/typebox": "^0.34",
|
|
56
|
-
"@xterm/headless": "^6.0",
|
|
57
|
-
"ajv": "^8.
|
|
58
|
-
"chalk": "^5.6",
|
|
59
|
-
"diff": "^
|
|
47
|
+
"@agentclientprotocol/sdk": "0.20.0",
|
|
48
|
+
"@mozilla/readability": "^0.6.0",
|
|
49
|
+
"@oh-my-pi/omp-stats": "14.4.0",
|
|
50
|
+
"@oh-my-pi/pi-agent-core": "14.4.0",
|
|
51
|
+
"@oh-my-pi/pi-ai": "14.4.0",
|
|
52
|
+
"@oh-my-pi/pi-natives": "14.4.0",
|
|
53
|
+
"@oh-my-pi/pi-tui": "14.4.0",
|
|
54
|
+
"@oh-my-pi/pi-utils": "14.4.0",
|
|
55
|
+
"@sinclair/typebox": "^0.34.49",
|
|
56
|
+
"@xterm/headless": "^6.0.0",
|
|
57
|
+
"ajv": "^8.20.0",
|
|
58
|
+
"chalk": "^5.6.2",
|
|
59
|
+
"diff": "^9.0.0",
|
|
60
60
|
"fflate": "0.8.2",
|
|
61
61
|
"handlebars": "^4.7.9",
|
|
62
|
-
"linkedom": "^0.18",
|
|
63
|
-
"lru-cache": "11.3.
|
|
64
|
-
"markit-ai": "0.5.
|
|
65
|
-
"puppeteer": "^24.
|
|
62
|
+
"linkedom": "^0.18.12",
|
|
63
|
+
"lru-cache": "11.3.5",
|
|
64
|
+
"markit-ai": "0.5.3",
|
|
65
|
+
"puppeteer": "^24.42.0",
|
|
66
66
|
"turndown": "7.2.4",
|
|
67
67
|
"turndown-plugin-gfm": "1.0.2",
|
|
68
68
|
"zod": "4.3.6"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
|
-
"@types/bun": "^1.3",
|
|
71
|
+
"@types/bun": "^1.3.13",
|
|
72
72
|
"@types/turndown": "5.0.6"
|
|
73
73
|
},
|
|
74
74
|
"engines": {
|
package/src/cli/args.ts
CHANGED
|
@@ -60,7 +60,16 @@ export function parseArgs(args: string[], extensionFlags?: Map<string, { type: "
|
|
|
60
60
|
};
|
|
61
61
|
|
|
62
62
|
for (let i = 0; i < args.length; i++) {
|
|
63
|
-
|
|
63
|
+
let arg = args[i];
|
|
64
|
+
|
|
65
|
+
// Support --flag=value syntax (e.g. --tools=ask,read)
|
|
66
|
+
if (arg.startsWith("--") && arg.includes("=")) {
|
|
67
|
+
const eqIdx = arg.indexOf("=");
|
|
68
|
+
const value = arg.slice(eqIdx + 1);
|
|
69
|
+
arg = arg.slice(0, eqIdx);
|
|
70
|
+
// Insert the value so the existing "args[++i]" logic picks it up
|
|
71
|
+
args.splice(i + 1, 0, value);
|
|
72
|
+
}
|
|
64
73
|
|
|
65
74
|
if (arg === "--help" || arg === "-h") {
|
|
66
75
|
result.help = true;
|
package/src/cli/shell-cli.ts
CHANGED
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import * as path from "node:path";
|
|
7
7
|
import { createInterface } from "node:readline/promises";
|
|
8
|
-
import { Shell } from "@oh-my-pi/pi-natives";
|
|
8
|
+
import { type MinimizerOptions, Shell } from "@oh-my-pi/pi-natives";
|
|
9
9
|
import { APP_NAME, getProjectDir } from "@oh-my-pi/pi-utils";
|
|
10
10
|
import chalk from "chalk";
|
|
11
|
-
import { Settings } from "../config/settings";
|
|
11
|
+
import { Settings, type ShellMinimizerSettings } from "../config/settings";
|
|
12
12
|
import { getOrCreateSnapshot } from "../utils/shell-snapshot";
|
|
13
13
|
|
|
14
14
|
export interface ShellCommandArgs {
|
|
@@ -41,6 +41,17 @@ export function parseShellArgs(args: string[]): ShellCommandArgs | undefined {
|
|
|
41
41
|
return result;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
function buildMinimizerOptions(group: ShellMinimizerSettings): MinimizerOptions | undefined {
|
|
45
|
+
if (!group.enabled) return undefined;
|
|
46
|
+
return {
|
|
47
|
+
enabled: true,
|
|
48
|
+
settingsPath: group.settingsPath || undefined,
|
|
49
|
+
only: group.only.length > 0 ? group.only : undefined,
|
|
50
|
+
except: group.except.length > 0 ? group.except : undefined,
|
|
51
|
+
maxCaptureBytes: group.maxCaptureBytes,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
44
55
|
export async function runShellCommand(cmd: ShellCommandArgs): Promise<void> {
|
|
45
56
|
if (!process.stdin.isTTY) {
|
|
46
57
|
process.stderr.write("Error: shell console requires an interactive TTY.\n");
|
|
@@ -51,7 +62,8 @@ export async function runShellCommand(cmd: ShellCommandArgs): Promise<void> {
|
|
|
51
62
|
const settings = await Settings.init({ cwd });
|
|
52
63
|
const { shell, env: shellEnv } = settings.getShellConfig();
|
|
53
64
|
const snapshotPath = cmd.noSnapshot || !shell.includes("bash") ? null : await getOrCreateSnapshot(shell, shellEnv);
|
|
54
|
-
const
|
|
65
|
+
const minimizer = buildMinimizerOptions(settings.getGroup("shellMinimizer"));
|
|
66
|
+
const shellSession = new Shell({ sessionEnv: shellEnv, snapshotPath: snapshotPath ?? undefined, minimizer });
|
|
55
67
|
|
|
56
68
|
let active = false;
|
|
57
69
|
let lastChar: string | null = null;
|
|
@@ -300,6 +300,7 @@ interface ProviderValidationModel {
|
|
|
300
300
|
|
|
301
301
|
interface ProviderValidationConfig {
|
|
302
302
|
baseUrl?: string;
|
|
303
|
+
headers?: Record<string, string>;
|
|
303
304
|
apiKey?: string;
|
|
304
305
|
api?: Api;
|
|
305
306
|
auth?: ProviderAuthMode;
|
|
@@ -321,9 +322,9 @@ function validateProviderConfiguration(
|
|
|
321
322
|
if (models.length === 0) {
|
|
322
323
|
if (mode === "models-config") {
|
|
323
324
|
const hasModelOverrides = config.modelOverrides && Object.keys(config.modelOverrides).length > 0;
|
|
324
|
-
if (!config.baseUrl && !config.compat && !hasModelOverrides && !config.discovery) {
|
|
325
|
+
if (!config.baseUrl && !config.headers && !config.compat && !hasModelOverrides && !config.discovery) {
|
|
325
326
|
throw new Error(
|
|
326
|
-
`Provider ${providerName}: must specify "baseUrl", "compat", "modelOverrides", "discovery", or "models"`,
|
|
327
|
+
`Provider ${providerName}: must specify "baseUrl", "headers", "compat", "modelOverrides", "discovery", or "models"`,
|
|
327
328
|
);
|
|
328
329
|
}
|
|
329
330
|
}
|
|
@@ -378,6 +379,7 @@ export const ModelsConfigFile = new ConfigFile<ModelsConfig>("models", ModelsCon
|
|
|
378
379
|
providerName,
|
|
379
380
|
{
|
|
380
381
|
baseUrl: providerConfig.baseUrl,
|
|
382
|
+
headers: providerConfig.headers,
|
|
381
383
|
apiKey: providerConfig.apiKey,
|
|
382
384
|
api: providerConfig.api as Api | undefined,
|
|
383
385
|
auth: (providerConfig.auth ?? "apiKey") as ProviderAuthMode,
|
|
@@ -770,6 +772,7 @@ export class ModelRegistry {
|
|
|
770
772
|
// models registered by extensions survive the model selector's offline reload.
|
|
771
773
|
#runtimeModelOverlays: CustomModelOverlay[] = [];
|
|
772
774
|
#runtimeProviderApiKeys: Map<string, string> = new Map();
|
|
775
|
+
#runtimeProviderOverrides: Map<string, ProviderOverride> = new Map();
|
|
773
776
|
#runtimeProvidersBySource: Map<string, Set<string>> = new Map();
|
|
774
777
|
#runtimeProviderSourceByName: Map<string, string> = new Map();
|
|
775
778
|
|
|
@@ -883,8 +886,8 @@ export class ModelRegistry {
|
|
|
883
886
|
const withConfigModels = this.#mergeCustomModels(resolvedDefaults, this.#customModelOverlays);
|
|
884
887
|
// Merge runtime extension models so they survive refresh() cycles
|
|
885
888
|
const combined = this.#mergeCustomModels(withConfigModels, this.#runtimeModelOverlays);
|
|
886
|
-
|
|
887
|
-
this.#models = this.#
|
|
889
|
+
const withModelOverrides = this.#applyModelOverrides(combined, this.#modelOverrides);
|
|
890
|
+
this.#models = this.#applyRuntimeProviderOverrides(withModelOverrides);
|
|
888
891
|
this.#rebuildCanonicalIndex();
|
|
889
892
|
}
|
|
890
893
|
|
|
@@ -1175,7 +1178,8 @@ export class ModelRegistry {
|
|
|
1175
1178
|
const withConfigModels = this.#mergeCustomModels(resolved, this.#customModelOverlays);
|
|
1176
1179
|
// Merge runtime extension models so they survive online discovery completion
|
|
1177
1180
|
const combined = this.#mergeCustomModels(withConfigModels, this.#runtimeModelOverlays);
|
|
1178
|
-
|
|
1181
|
+
const withModelOverrides = this.#applyModelOverrides(combined, this.#modelOverrides);
|
|
1182
|
+
this.#models = this.#applyRuntimeProviderOverrides(withModelOverrides);
|
|
1179
1183
|
this.#rebuildCanonicalIndex();
|
|
1180
1184
|
}
|
|
1181
1185
|
|
|
@@ -1657,6 +1661,32 @@ export class ModelRegistry {
|
|
|
1657
1661
|
});
|
|
1658
1662
|
}
|
|
1659
1663
|
|
|
1664
|
+
#mergeProviderOverride(baseOverride: ProviderOverride | undefined, override: ProviderOverride): ProviderOverride {
|
|
1665
|
+
return {
|
|
1666
|
+
baseUrl: override.baseUrl ?? baseOverride?.baseUrl,
|
|
1667
|
+
apiKey: override.apiKey ?? baseOverride?.apiKey,
|
|
1668
|
+
headers: override.headers ? { ...(baseOverride?.headers ?? {}), ...override.headers } : baseOverride?.headers,
|
|
1669
|
+
compat: override.compat ? mergeCompat(baseOverride?.compat, override.compat) : baseOverride?.compat,
|
|
1670
|
+
};
|
|
1671
|
+
}
|
|
1672
|
+
#applyProviderTransportOverride<T extends { baseUrl?: string; headers?: Record<string, string> }>(
|
|
1673
|
+
entry: T,
|
|
1674
|
+
override: Pick<ProviderOverride, "baseUrl" | "headers">,
|
|
1675
|
+
): T {
|
|
1676
|
+
return {
|
|
1677
|
+
...entry,
|
|
1678
|
+
baseUrl: override.baseUrl ?? entry.baseUrl,
|
|
1679
|
+
headers: override.headers ? { ...entry.headers, ...override.headers } : entry.headers,
|
|
1680
|
+
};
|
|
1681
|
+
}
|
|
1682
|
+
#applyRuntimeProviderOverrides(models: Model<Api>[]): Model<Api>[] {
|
|
1683
|
+
if (this.#runtimeProviderOverrides.size === 0) return models;
|
|
1684
|
+
return models.map(model => {
|
|
1685
|
+
const override = this.#runtimeProviderOverrides.get(model.provider);
|
|
1686
|
+
if (!override) return model;
|
|
1687
|
+
return this.#applyProviderTransportOverride(model, override);
|
|
1688
|
+
});
|
|
1689
|
+
}
|
|
1660
1690
|
#applyModelOverrides(models: Model<Api>[], overrides: Map<string, Map<string, ModelOverride>>): Model<Api>[] {
|
|
1661
1691
|
if (overrides.size === 0) return models;
|
|
1662
1692
|
return models.map(model => {
|
|
@@ -1916,6 +1946,12 @@ export class ModelRegistry {
|
|
|
1916
1946
|
return this.authStorage.hasOAuth(model.provider);
|
|
1917
1947
|
}
|
|
1918
1948
|
|
|
1949
|
+
#clearRuntimeProviderState(providerName: string): void {
|
|
1950
|
+
this.#runtimeProviderApiKeys.delete(providerName);
|
|
1951
|
+
this.#runtimeProviderOverrides.delete(providerName);
|
|
1952
|
+
this.#runtimeModelOverlays = this.#runtimeModelOverlays.filter(overlay => overlay.provider !== providerName);
|
|
1953
|
+
}
|
|
1954
|
+
|
|
1919
1955
|
/**
|
|
1920
1956
|
* Remove custom API/OAuth registrations for a specific extension source.
|
|
1921
1957
|
*/
|
|
@@ -1932,8 +1968,7 @@ export class ModelRegistry {
|
|
|
1932
1968
|
continue;
|
|
1933
1969
|
}
|
|
1934
1970
|
this.#runtimeProviderSourceByName.delete(providerName);
|
|
1935
|
-
this.#
|
|
1936
|
-
this.#runtimeModelOverlays = this.#runtimeModelOverlays.filter(overlay => overlay.provider !== providerName);
|
|
1971
|
+
this.#clearRuntimeProviderState(providerName);
|
|
1937
1972
|
}
|
|
1938
1973
|
this.#reloadStaticModels();
|
|
1939
1974
|
this.#rebuildCanonicalIndex();
|
|
@@ -1970,6 +2005,7 @@ export class ModelRegistry {
|
|
|
1970
2005
|
providerName,
|
|
1971
2006
|
{
|
|
1972
2007
|
baseUrl: config.baseUrl,
|
|
2008
|
+
headers: config.headers,
|
|
1973
2009
|
apiKey: config.apiKey,
|
|
1974
2010
|
api: config.api,
|
|
1975
2011
|
oauthConfigured: Boolean(config.oauth),
|
|
@@ -1993,6 +2029,7 @@ export class ModelRegistry {
|
|
|
1993
2029
|
});
|
|
1994
2030
|
}
|
|
1995
2031
|
|
|
2032
|
+
let sourceHandoff = false;
|
|
1996
2033
|
if (sourceId) {
|
|
1997
2034
|
this.#registeredProviderSources.add(sourceId);
|
|
1998
2035
|
const previousSourceId = this.#runtimeProviderSourceByName.get(providerName);
|
|
@@ -2002,12 +2039,18 @@ export class ModelRegistry {
|
|
|
2002
2039
|
if (previousProviders && previousProviders.size === 0) {
|
|
2003
2040
|
this.#runtimeProvidersBySource.delete(previousSourceId);
|
|
2004
2041
|
}
|
|
2042
|
+
this.#clearRuntimeProviderState(providerName);
|
|
2043
|
+
sourceHandoff = true;
|
|
2005
2044
|
}
|
|
2006
2045
|
const sourceProviders = this.#runtimeProvidersBySource.get(sourceId) ?? new Set<string>();
|
|
2007
2046
|
sourceProviders.add(providerName);
|
|
2008
2047
|
this.#runtimeProvidersBySource.set(sourceId, sourceProviders);
|
|
2009
2048
|
this.#runtimeProviderSourceByName.set(providerName, sourceId);
|
|
2010
2049
|
}
|
|
2050
|
+
if (sourceHandoff) {
|
|
2051
|
+
this.#reloadStaticModels();
|
|
2052
|
+
}
|
|
2053
|
+
|
|
2011
2054
|
if (config.apiKey) {
|
|
2012
2055
|
this.#customProviderApiKeys.set(providerName, config.apiKey);
|
|
2013
2056
|
// Persist runtime API keys so they survive #reloadStaticModels() cycles
|
|
@@ -2042,29 +2085,38 @@ export class ModelRegistry {
|
|
|
2042
2085
|
for (const overlay of newOverlays) {
|
|
2043
2086
|
nextModels.push(finalizeCustomModel(overlay, { useDefaults: true }));
|
|
2044
2087
|
}
|
|
2088
|
+
const runtimeTransportOverride = this.#runtimeProviderOverrides.get(providerName);
|
|
2089
|
+
const withRuntimeTransportOverride = runtimeTransportOverride
|
|
2090
|
+
? nextModels.map(model => {
|
|
2091
|
+
if (model.provider !== providerName) return model;
|
|
2092
|
+
return this.#applyProviderTransportOverride(model, runtimeTransportOverride);
|
|
2093
|
+
})
|
|
2094
|
+
: nextModels;
|
|
2045
2095
|
|
|
2046
2096
|
if (config.oauth?.modifyModels) {
|
|
2047
2097
|
const credential = this.authStorage.getOAuthCredential(providerName);
|
|
2048
2098
|
if (credential) {
|
|
2049
|
-
this.#models = config.oauth.modifyModels(
|
|
2099
|
+
this.#models = config.oauth.modifyModels(withRuntimeTransportOverride, credential);
|
|
2050
2100
|
this.#rebuildCanonicalIndex();
|
|
2051
2101
|
return;
|
|
2052
2102
|
}
|
|
2053
2103
|
}
|
|
2054
2104
|
|
|
2055
|
-
this.#models =
|
|
2105
|
+
this.#models = withRuntimeTransportOverride;
|
|
2056
2106
|
this.#rebuildCanonicalIndex();
|
|
2057
2107
|
return;
|
|
2058
2108
|
}
|
|
2059
2109
|
|
|
2060
|
-
if (config.baseUrl) {
|
|
2110
|
+
if (config.baseUrl || config.headers) {
|
|
2111
|
+
const transportOverride = { baseUrl: config.baseUrl, headers: config.headers };
|
|
2112
|
+
const nextRuntimeOverride = this.#mergeProviderOverride(
|
|
2113
|
+
this.#runtimeProviderOverrides.get(providerName),
|
|
2114
|
+
transportOverride,
|
|
2115
|
+
);
|
|
2116
|
+
this.#runtimeProviderOverrides.set(providerName, nextRuntimeOverride);
|
|
2061
2117
|
this.#models = this.#models.map(m => {
|
|
2062
2118
|
if (m.provider !== providerName) return m;
|
|
2063
|
-
return
|
|
2064
|
-
...m,
|
|
2065
|
-
baseUrl: config.baseUrl ?? m.baseUrl,
|
|
2066
|
-
headers: config.headers ? { ...m.headers, ...config.headers } : m.headers,
|
|
2067
|
-
};
|
|
2119
|
+
return this.#applyProviderTransportOverride(m, transportOverride);
|
|
2068
2120
|
});
|
|
2069
2121
|
this.#rebuildCanonicalIndex();
|
|
2070
2122
|
}
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
parseFrontmatter,
|
|
10
10
|
prompt,
|
|
11
11
|
} from "@oh-my-pi/pi-utils";
|
|
12
|
-
import { computeLineHash } from "../edit/line-hash";
|
|
12
|
+
import { computeLineHash, HASHLINE_CONTENT_SEPARATOR } from "../edit/line-hash";
|
|
13
13
|
import { jtdToTypeScript } from "../tools/jtd-to-typescript";
|
|
14
14
|
import { parseCommandArgs, substituteArgs } from "../utils/command-args";
|
|
15
15
|
|
|
@@ -40,13 +40,13 @@ function formatHashlineRef(lineNum: unknown, content: unknown): { num: number; t
|
|
|
40
40
|
const num = typeof lineNum === "number" ? lineNum : Number.parseInt(String(lineNum), 10);
|
|
41
41
|
const raw = typeof content === "string" ? content : String(content ?? "");
|
|
42
42
|
const text = raw.replace(/\\t/g, "\t").replace(/\\n/g, "\n").replace(/\\r/g, "\r");
|
|
43
|
-
const ref = `${num}
|
|
43
|
+
const ref = `${num}${computeLineHash(num, text)}`;
|
|
44
44
|
return { num, text, ref };
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
/**
|
|
48
48
|
* {{href lineNum "content"}} — compute a real hashline ref for prompt examples.
|
|
49
|
-
* Returns `"
|
|
49
|
+
* Returns `"lineNumBIGRAM"` (e.g., `"42nd"`) using the actual hash algorithm.
|
|
50
50
|
*/
|
|
51
51
|
prompt.registerHelper("href", (lineNum: unknown, content: unknown): string => {
|
|
52
52
|
const { ref } = formatHashlineRef(lineNum, content);
|
|
@@ -55,11 +55,11 @@ prompt.registerHelper("href", (lineNum: unknown, content: unknown): string => {
|
|
|
55
55
|
|
|
56
56
|
/**
|
|
57
57
|
* {{hline lineNum "content"}} — format a full read-style line with prefix.
|
|
58
|
-
* Returns `"
|
|
58
|
+
* Returns `"lineNumBIGRAM:content"` (colon between anchor and content).
|
|
59
59
|
*/
|
|
60
60
|
prompt.registerHelper("hline", (lineNum: unknown, content: unknown): string => {
|
|
61
61
|
const { ref, text } = formatHashlineRef(lineNum, content);
|
|
62
|
-
return `${ref}
|
|
62
|
+
return `${ref}${HASHLINE_CONTENT_SEPARATOR}${text}`;
|
|
63
63
|
});
|
|
64
64
|
|
|
65
65
|
/**
|
|
@@ -955,7 +955,7 @@ export const SETTINGS_SCHEMA = {
|
|
|
955
955
|
// Edit tool
|
|
956
956
|
"edit.mode": {
|
|
957
957
|
type: "enum",
|
|
958
|
-
values: ["replace", "patch", "hashline", "chunk", "vim", "apply_patch"] as const,
|
|
958
|
+
values: ["replace", "patch", "hashline", "chunk", "vim", "apply_patch", "atom"] as const,
|
|
959
959
|
default: "hashline",
|
|
960
960
|
ui: {
|
|
961
961
|
tab: "editing",
|
|
@@ -1021,7 +1021,7 @@ export const SETTINGS_SCHEMA = {
|
|
|
1021
1021
|
ui: {
|
|
1022
1022
|
tab: "editing",
|
|
1023
1023
|
label: "Hash Lines",
|
|
1024
|
-
description: "Include line hashes in read output for hashline edit mode (LINE
|
|
1024
|
+
description: "Include line hashes in read output for hashline edit mode (LINE+ID\\tcontent)",
|
|
1025
1025
|
},
|
|
1026
1026
|
},
|
|
1027
1027
|
|
|
@@ -1123,6 +1123,39 @@ export const SETTINGS_SCHEMA = {
|
|
|
1123
1123
|
},
|
|
1124
1124
|
"bashInterceptor.patterns": { type: "array", default: DEFAULT_BASH_INTERCEPTOR_RULES },
|
|
1125
1125
|
|
|
1126
|
+
// Shell output minimizer
|
|
1127
|
+
"shellMinimizer.enabled": {
|
|
1128
|
+
type: "boolean",
|
|
1129
|
+
default: true,
|
|
1130
|
+
ui: {
|
|
1131
|
+
tab: "editing",
|
|
1132
|
+
label: "Shell Minimizer",
|
|
1133
|
+
description: "Compress verbose shell output (git, npm, cargo, etc.) before returning it to the agent",
|
|
1134
|
+
},
|
|
1135
|
+
},
|
|
1136
|
+
"shellMinimizer.settingsPath": {
|
|
1137
|
+
type: "string",
|
|
1138
|
+
default: undefined,
|
|
1139
|
+
ui: {
|
|
1140
|
+
tab: "editing",
|
|
1141
|
+
label: "Minimizer Settings Path",
|
|
1142
|
+
description: "Optional TOML file with per-command minimizer overrides",
|
|
1143
|
+
submenu: true,
|
|
1144
|
+
},
|
|
1145
|
+
},
|
|
1146
|
+
"shellMinimizer.only": { type: "array", default: EMPTY_STRING_ARRAY },
|
|
1147
|
+
"shellMinimizer.except": { type: "array", default: EMPTY_STRING_ARRAY },
|
|
1148
|
+
"shellMinimizer.maxCaptureBytes": {
|
|
1149
|
+
type: "number",
|
|
1150
|
+
default: 4 * 1024 * 1024,
|
|
1151
|
+
ui: {
|
|
1152
|
+
tab: "editing",
|
|
1153
|
+
label: "Minimizer Capture Limit",
|
|
1154
|
+
description: "Maximum captured output bytes before falling back to raw streaming",
|
|
1155
|
+
submenu: true,
|
|
1156
|
+
},
|
|
1157
|
+
},
|
|
1158
|
+
|
|
1126
1159
|
// Python
|
|
1127
1160
|
"python.toolMode": {
|
|
1128
1161
|
type: "enum",
|
|
@@ -1315,7 +1348,8 @@ export const SETTINGS_SCHEMA = {
|
|
|
1315
1348
|
ui: {
|
|
1316
1349
|
tab: "tools",
|
|
1317
1350
|
label: "GitHub CLI",
|
|
1318
|
-
description:
|
|
1351
|
+
description:
|
|
1352
|
+
"Enable the github tool (op-based dispatch for repository, issue, pull request, diff, search, checkout, push, and Actions watch workflows)",
|
|
1319
1353
|
},
|
|
1320
1354
|
},
|
|
1321
1355
|
|
|
@@ -1612,6 +1646,22 @@ export const SETTINGS_SCHEMA = {
|
|
|
1612
1646
|
ui: { tab: "tasks", label: "Claude Project Commands", description: "Load commands from .claude/commands/" },
|
|
1613
1647
|
},
|
|
1614
1648
|
|
|
1649
|
+
"commands.enableOpencodeUser": {
|
|
1650
|
+
type: "boolean",
|
|
1651
|
+
default: true,
|
|
1652
|
+
ui: {
|
|
1653
|
+
tab: "tasks",
|
|
1654
|
+
label: "OpenCode User Commands",
|
|
1655
|
+
description: "Load commands from ~/.config/opencode/commands/",
|
|
1656
|
+
},
|
|
1657
|
+
},
|
|
1658
|
+
|
|
1659
|
+
"commands.enableOpencodeProject": {
|
|
1660
|
+
type: "boolean",
|
|
1661
|
+
default: true,
|
|
1662
|
+
ui: { tab: "tasks", label: "OpenCode Project Commands", description: "Load commands from .opencode/commands/" },
|
|
1663
|
+
},
|
|
1664
|
+
|
|
1615
1665
|
// ────────────────────────────────────────────────────────────────────────
|
|
1616
1666
|
// Providers
|
|
1617
1667
|
// ────────────────────────────────────────────────────────────────────────
|
|
@@ -1652,7 +1702,7 @@ export const SETTINGS_SCHEMA = {
|
|
|
1652
1702
|
},
|
|
1653
1703
|
"providers.image": {
|
|
1654
1704
|
type: "enum",
|
|
1655
|
-
values: ["auto", "gemini", "openrouter"] as const,
|
|
1705
|
+
values: ["auto", "openai", "gemini", "openrouter"] as const,
|
|
1656
1706
|
default: "auto",
|
|
1657
1707
|
ui: {
|
|
1658
1708
|
tab: "providers",
|
|
@@ -1956,6 +2006,14 @@ export interface BashInterceptorRule {
|
|
|
1956
2006
|
allowSubcommands?: string[];
|
|
1957
2007
|
}
|
|
1958
2008
|
|
|
2009
|
+
export interface ShellMinimizerSettings {
|
|
2010
|
+
enabled: boolean;
|
|
2011
|
+
settingsPath: string | undefined;
|
|
2012
|
+
only: string[];
|
|
2013
|
+
except: string[];
|
|
2014
|
+
maxCaptureBytes: number;
|
|
2015
|
+
}
|
|
2016
|
+
|
|
1959
2017
|
/** Map group prefix -> typed settings interface */
|
|
1960
2018
|
export interface GroupTypeMap {
|
|
1961
2019
|
compaction: CompactionSettings;
|
|
@@ -1973,6 +2031,7 @@ export interface GroupTypeMap {
|
|
|
1973
2031
|
modelRoles: Record<string, string>;
|
|
1974
2032
|
modelTags: ModelTagsSettings;
|
|
1975
2033
|
cycleOrder: string[];
|
|
2034
|
+
shellMinimizer: ShellMinimizerSettings;
|
|
1976
2035
|
}
|
|
1977
2036
|
|
|
1978
2037
|
export type GroupPrefix = keyof GroupTypeMap;
|