@oh-my-pi/pi-coding-agent 15.4.3 → 15.5.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 +75 -5
- package/dist/types/cli/args.d.ts +2 -0
- package/dist/types/cli/auth-broker-cli.d.ts +1 -1
- package/dist/types/commands/launch.d.ts +8 -0
- package/dist/types/config/settings-schema.d.ts +42 -1
- package/dist/types/edit/index.d.ts +2 -0
- package/dist/types/extensibility/custom-tools/types.d.ts +8 -2
- package/dist/types/extensibility/hooks/types.d.ts +4 -0
- package/dist/types/lsp/index.d.ts +9 -1
- package/dist/types/mcp/client.d.ts +2 -1
- package/dist/types/mcp/oauth-discovery.d.ts +4 -3
- package/dist/types/mcp/timeout.d.ts +9 -0
- package/dist/types/mcp/types.d.ts +1 -1
- package/dist/types/sdk.d.ts +2 -0
- package/dist/types/session/streaming-output.d.ts +1 -1
- package/dist/types/task/index.d.ts +2 -0
- package/dist/types/task/types.d.ts +4 -0
- package/dist/types/tools/approval.d.ts +46 -0
- package/dist/types/tools/ask.d.ts +1 -0
- package/dist/types/tools/ast-edit.d.ts +2 -0
- package/dist/types/tools/ast-grep.d.ts +1 -0
- package/dist/types/tools/bash.d.ts +11 -1
- package/dist/types/tools/browser.d.ts +2 -0
- package/dist/types/tools/calculator.d.ts +1 -0
- package/dist/types/tools/checkpoint.d.ts +2 -0
- package/dist/types/tools/debug.d.ts +9 -1
- package/dist/types/tools/eval.d.ts +2 -0
- package/dist/types/tools/find.d.ts +10 -0
- package/dist/types/tools/gh.d.ts +2 -1
- package/dist/types/tools/hindsight-recall.d.ts +1 -0
- package/dist/types/tools/hindsight-reflect.d.ts +1 -0
- package/dist/types/tools/hindsight-retain.d.ts +1 -0
- package/dist/types/tools/inspect-image.d.ts +1 -0
- package/dist/types/tools/irc.d.ts +1 -0
- package/dist/types/tools/job.d.ts +1 -0
- package/dist/types/tools/read.d.ts +1 -0
- package/dist/types/tools/recipe/index.d.ts +1 -0
- package/dist/types/tools/render-mermaid.d.ts +1 -0
- package/dist/types/tools/resolve.d.ts +1 -0
- package/dist/types/tools/search-tool-bm25.d.ts +1 -0
- package/dist/types/tools/search.d.ts +1 -0
- package/dist/types/tools/ssh.d.ts +2 -0
- package/dist/types/tools/todo-write.d.ts +1 -0
- package/dist/types/tools/write.d.ts +2 -0
- package/dist/types/tools/yield.d.ts +1 -0
- package/dist/types/web/search/index.d.ts +1 -0
- package/package.json +7 -7
- package/src/cli/args.ts +14 -0
- package/src/cli/auth-broker-cli.ts +171 -22
- package/src/commands/auth-broker.ts +3 -0
- package/src/commands/launch.ts +16 -0
- package/src/config/mcp-schema.json +2 -2
- package/src/config/model-registry.ts +19 -4
- package/src/config/settings-schema.ts +59 -1
- package/src/config/settings.ts +2 -1
- package/src/dap/session.ts +35 -2
- package/src/discovery/builtin.ts +2 -2
- package/src/discovery/mcp-json.ts +1 -1
- package/src/edit/index.ts +26 -0
- package/src/edit/modes/patch.ts +1 -1
- package/src/edit/streaming.ts +12 -2
- package/src/exec/bash-executor.ts +6 -2
- package/src/extensibility/custom-commands/bundled/review/index.ts +18 -14
- package/src/extensibility/custom-tools/types.ts +16 -2
- package/src/extensibility/extensions/wrapper.ts +36 -1
- package/src/extensibility/hooks/types.ts +8 -1
- package/src/hashline/apply.ts +47 -2
- package/src/internal-urls/docs-index.generated.ts +8 -7
- package/src/lsp/edits.ts +82 -29
- package/src/lsp/index.ts +38 -1
- package/src/lsp/utils.ts +1 -1
- package/src/main.ts +6 -0
- package/src/mcp/client.ts +8 -6
- package/src/mcp/oauth-discovery.ts +120 -32
- package/src/mcp/oauth-flow.ts +34 -6
- package/src/mcp/timeout.ts +59 -0
- package/src/mcp/transports/http.ts +42 -44
- package/src/mcp/transports/stdio.ts +8 -5
- package/src/mcp/types.ts +1 -1
- package/src/modes/components/hook-editor.ts +11 -3
- package/src/modes/components/mcp-add-wizard.ts +6 -2
- package/src/modes/components/model-selector.ts +33 -11
- package/src/modes/controllers/command-controller.ts +6 -4
- package/src/modes/controllers/mcp-command-controller.ts +8 -4
- package/src/prompts/review-custom-request.md +22 -0
- package/src/prompts/review-headless-request.md +16 -0
- package/src/prompts/review-request.md +2 -3
- package/src/prompts/system/project-prompt.md +4 -0
- package/src/prompts/tools/debug.md +1 -0
- package/src/prompts/tools/find.md +4 -2
- package/src/prompts/tools/hashline.md +1 -0
- package/src/sdk.ts +47 -73
- package/src/session/agent-session.ts +93 -27
- package/src/session/streaming-output.ts +1 -1
- package/src/slash-commands/helpers/usage-report.ts +3 -1
- package/src/task/executor.ts +11 -0
- package/src/task/index.ts +19 -0
- package/src/task/render.ts +12 -2
- package/src/task/types.ts +4 -0
- package/src/tools/approval.ts +185 -0
- package/src/tools/ask.ts +1 -0
- package/src/tools/ast-edit.ts +25 -1
- package/src/tools/ast-grep.ts +1 -0
- package/src/tools/bash.ts +69 -1
- package/src/tools/browser/tab-supervisor.ts +1 -1
- package/src/tools/browser.ts +15 -0
- package/src/tools/calculator.ts +1 -0
- package/src/tools/checkpoint.ts +2 -0
- package/src/tools/debug.ts +38 -0
- package/src/tools/eval.ts +15 -0
- package/src/tools/find.ts +17 -8
- package/src/tools/gh.ts +21 -1
- package/src/tools/hindsight-recall.ts +1 -0
- package/src/tools/hindsight-reflect.ts +1 -0
- package/src/tools/hindsight-retain.ts +1 -0
- package/src/tools/image-gen.ts +1 -0
- package/src/tools/inspect-image.ts +1 -0
- package/src/tools/irc.ts +1 -0
- package/src/tools/job.ts +1 -0
- package/src/tools/path-utils.ts +14 -1
- package/src/tools/read.ts +1 -0
- package/src/tools/recipe/index.ts +1 -0
- package/src/tools/render-mermaid.ts +1 -0
- package/src/tools/report-tool-issue.ts +1 -0
- package/src/tools/resolve.ts +1 -0
- package/src/tools/review.ts +1 -0
- package/src/tools/search-tool-bm25.ts +1 -0
- package/src/tools/search.ts +1 -0
- package/src/tools/ssh.ts +8 -0
- package/src/tools/todo-write.ts +1 -0
- package/src/tools/write.ts +12 -1
- package/src/tools/yield.ts +1 -0
- package/src/web/search/index.ts +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,11 +2,38 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [15.5.0] - 2026-05-26
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added per-tool approval declarations so each built-in, custom, or extension tool can declare its capability tier and approval prompt details.
|
|
10
|
+
- Added `OMP_MCP_TIMEOUT_MS` environment variable to override MCP client request timeout for every server (in milliseconds); set to `0` to disable client-side timeouts. Invalid (negative or non-numeric) values are ignored with a warning and fall back to the per-server timeout or default 30s ([#1415](https://github.com/can1357/oh-my-pi/pull/1415)).
|
|
11
|
+
- Added `omp auth-broker list` (with `--json` for machine-readable output) to enumerate supported OAuth providers, replacing `bunx @oh-my-pi/pi-ai list`.
|
|
12
|
+
- Added interactive provider selection to `omp auth-broker login` and `omp auth-broker logout` when invoked without a provider argument (replacing the equivalent `bunx @oh-my-pi/pi-ai login`/`logout` flows). The logout picker is sourced from stored credentials so it only lists providers the user is actually signed in to.
|
|
13
|
+
- Added directory matches to the `find` tool: glob searches now return directories alongside files, with directory hits emitted with a trailing `/` marker. `find` for `**/tests` no longer requires a follow-up `read` to surface a directory hit; tool prompt and output docs were updated to reflect that paths may be either kind.
|
|
14
|
+
- Added the RFC 8414 §3.1 path-ful issuer form (`/.well-known/oauth-authorization-server<issuer-path>`) as a third candidate in MCP OAuth discovery, after origin-root and path-prefixed well-known URLs, so deployments that publish authorization-server metadata at the path-ful location resolve correctly. Single-segment authorization URLs (e.g. `https://gateway/my-service`) are now treated as the gateway prefix instead of being dropped back to the origin root.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- Changed tool-approval prompts to use an explicit `Approve`/`Deny` selector and surface the denial reason as contextual help text instead of a bare confirm/cancel toggle.
|
|
19
|
+
- Changed approval safety overrides to prompt even in `yolo` / `--auto-approve` sessions, so critical tool-declared patterns no longer run unattended.
|
|
20
|
+
- Changed `omp auth-broker login` to drive the per-provider OAuth/API-key flow in-process via `AuthStorage.login()` instead of spawning the `pi-ai` CLI subprocess. The `pi-ai` bin is being removed; the same login surface now lives entirely inside `omp`.
|
|
21
|
+
- Changed the default per-line truncation cap for search/grep output (`DEFAULT_MAX_COLUMN`) from `1024` to `512` characters to keep wide minified single-line bundles from blowing out the model's context.
|
|
22
|
+
- Changed `edit.hashlineAutoDropPureInsertDuplicates` to also fire on `A-B:payload` replacement ops when a single non-structural boundary payload line duplicates the line immediately above the deleted range (prefix) or immediately below it (suffix). Catches the common mistake of `A-B:foo` where the user meant `A-B!` but typed a payload that happens to match adjacent context. The existing 2+-line block absorb and balance-validated structural single-line absorb already covered the multi-line and structural-delimiter cases; this closes the single-line non-structural gap.
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- Fixed the agent loop and bash executor busy-spinning when scheduler waits returned early. napi `uv_async_send` callbacks can wake the event loop after only ~1–2 ms even when the caller asked for a longer sleep, so `yieldIfDue()` now compensates by retrying `Bun.sleep()` until the requested wall-clock duration has elapsed, and the bash executor wraps its `runPromise`/timeout/abort race in an `ExponentialYield` (20 ms → 10 s) so long-running commands stop hot-looping on the race. Yields are additionally throttled by a module-level 50 ms gate, and losing timers in the race are aborted via `AbortSignal` so they don't keep firing after a winner is selected ([#1396](https://github.com/can1357/oh-my-pi/pull/1396) by [@hezhiyang2000](https://github.com/hezhiyang2000), closes [#1384](https://github.com/can1357/oh-my-pi/issues/1384)).
|
|
27
|
+
- Fixed streaming edit previews going blank for inline-payload ops. `LINE↓payload` / `A-B:payload` are valid single-line writes, but the natural-order preview was skipping the entire op token until a newline arrived — so the first character the model typed after the sigil only appeared after the next line ended, and the renderer would fall back to rendering the raw `A-B: bla bla bla` input. Inline-body content on `op-insert` and `op-replace` tokens is now emitted as a `+payload` line on the same op tick.
|
|
28
|
+
- Fixed `/usage` and the status-line reset countdown rendering stale negative deltas after a Codex window had elapsed: Codex keeps reporting the prior window's `reset_at` until a new request opens a fresh window, which turned the `resets in …` suffix into a meaningless negative duration. `formatDuration` now clamps non-positive, NaN, and infinite inputs to `0ms`, and both renderers suppress the `resets in …` suffix entirely once `resetsAt <= now`.
|
|
29
|
+
- Fixed auto-handoff race at the context threshold: when `compaction.strategy = handoff` fired at `agent_end` with an active checkpoint or incomplete todos, the deferred handoff post-prompt task and the rewind/todo-completion path both scheduled work concurrently, so a fresh `agent.continue()` streamed a new assistant turn alongside the handoff LLM call (visible as the "Auto-handoff" loader plus an assistant message still streaming, with the chat container then rebuilt mid-stream). `#checkCompaction` now reports whether it deferred a handoff and the `agent_end` handler short-circuits the rewind/todo passes; `#scheduleAgentContinue` also skips when `isCompacting || isGeneratingHandoff`. The pre-prompt `#checkCompaction` call now forces inline execution (`allowDefer = false`) so the new turn cannot begin until the maintenance settles.
|
|
30
|
+
- Fixed `/exit` and Ctrl+C-double-tap hanging when a deferred handoff was mid-flight: `AgentSession.dispose()` now aborts retry/compaction (auto-compaction + handoff) and the agent stream before draining `#cancelPostPromptTasks`, so the post-prompt task awaiting `generateHandoff` rejects and `Promise.allSettled` can resolve. Tool work (bash/eval/python) is intentionally still left for the existing dispose paths so shared kernels continue to survive across session dispose.
|
|
31
|
+
|
|
5
32
|
## [15.4.3] - 2026-05-26
|
|
6
33
|
|
|
7
34
|
### Fixed
|
|
8
35
|
|
|
9
|
-
- Fixed Google Vertex cached project discovery replacing the bundled fallback catalog so `/models` does not keep showing outdated Gemini entries after authoritative Vertex discovery ([#1412](https://github.com/can1357/oh-my-pi/issues/1412)).
|
|
36
|
+
- Fixed Google Vertex cached project discovery replacing the bundled fallback catalog so `/models` does not keep showing outdated Gemini entries after authoritative Vertex discovery, while keeping the bundled fallback in place when the cached snapshot is stale or non-authoritative (e.g. after an ADC discovery failure) ([#1412](https://github.com/can1357/oh-my-pi/issues/1412)).
|
|
10
37
|
|
|
11
38
|
## [15.4.2] - 2026-05-26
|
|
12
39
|
|
|
@@ -17,12 +44,10 @@
|
|
|
17
44
|
## [15.4.1] - 2026-05-26
|
|
18
45
|
|
|
19
46
|
### Breaking Changes
|
|
20
|
-
|
|
21
47
|
- The `vim` edit mode option is no longer available; configurations using `edit.mode: vim` will be automatically mapped to `hashline` mode
|
|
22
48
|
- Hashline payload semantics are now strictly inline-first: the first payload line is whatever follows the sigil on the op line itself, and subsequent lines append after it. A newline immediately after `↑`/`↓`/`:` is no longer a free separator — it produces a blank first payload line. Use `LINE↓content` for a one-line insert, `LINE↓firstline\nsecondline` for two lines; bare `LINE↓` / `LINE↑` / `LINE:` (no inline payload) still insert/replace with one blank line as before.
|
|
23
49
|
|
|
24
50
|
### Added
|
|
25
|
-
|
|
26
51
|
- Added `irc.timeoutMs` setting to configure IRC message timeout duration with a default of 120 seconds
|
|
27
52
|
- Added timeout enforcement for IRC send operations to prevent indefinite hangs when recipients are unresponsive
|
|
28
53
|
- Added evaluator state inheritance for `task`-spawned subagents so JavaScript and Python variables are visible between a parent agent and its child sessions
|
|
@@ -35,6 +60,9 @@
|
|
|
35
60
|
- Added file-read snapshot caching with multi-snapshot ring per path for recovery from agent's own writes
|
|
36
61
|
- Added delete operation (`!`) support to hashline grammar for explicit line deletion
|
|
37
62
|
- Added structural bracket/brace balance warnings when deleting lines with unclosed constructs
|
|
63
|
+
- Added resource metadata URL (RFC 9728) support to OAuth discovery for chaining authorization server resolution from protected-resource metadata ([1407](https://github.com/can1357/oh-my-pi/pull/1407) by [@faizhasim](https://github.com/faizhasim))
|
|
64
|
+
- Added path-prefixed well-known URL fallback in OAuth discovery to support authorization servers behind gateways with sub-path routing ([1407](https://github.com/can1357/oh-my-pi/pull/1407) by [@faizhasim](https://github.com/faizhasim))
|
|
65
|
+
- Added relative URL resolution for `Mcp-Auth-Server` header values against the server URL ([1407](https://github.com/can1357/oh-my-pi/pull/1407) by [@faizhasim](https://github.com/faizhasim))
|
|
38
66
|
|
|
39
67
|
### Changed
|
|
40
68
|
|
|
@@ -62,9 +90,11 @@
|
|
|
62
90
|
- Modified hashline grammar to accept optional file hash in headers and removed hash requirements from line anchors
|
|
63
91
|
- Changed hashline diff preview format to use `LINE:content` instead of `LINE+HASH|content`
|
|
64
92
|
- Updated prompt documentation to reflect new `¶PATH#HASH` header and bare line-number syntax
|
|
93
|
+
- Updated `discoverOAuthEndpoints` to accept `resourceMetadataUrl` parameter and prioritize the resource-metadata chain ([1407](https://github.com/can1357/oh-my-pi/pull/1407) by [@faizhasim](https://github.com/faizhasim))
|
|
94
|
+
- Updated `parseMcpAuthServerUrl` and `extractMcpAuthServerUrl` to accept optional `serverUrl` for relative URL resolution ([1407](https://github.com/can1357/oh-my-pi/pull/1407) by [@faizhasim](https://github.com/faizhasim))
|
|
95
|
+
- Updated `MCPOAuthFlow.#resolveRegistrationEndpoint` to try origin-root well-known first, then fall back to path-prefixed well-known ([1407](https://github.com/can1357/oh-my-pi/pull/1407) by [@faizhasim](https://github.com/faizhasim))
|
|
65
96
|
|
|
66
97
|
### Removed
|
|
67
|
-
|
|
68
98
|
- Removed the `installH2Fetch()` activation from CLI startup; HTTPS fetches now use Bun's default transport
|
|
69
99
|
- Removed the `vim` edit mode along with the `VimTool` module, prompt, and supporting buffer/engine/renderer stack
|
|
70
100
|
- Removed per-line hash anchors (2-letter bigram hashes) from hashline format
|
|
@@ -76,6 +106,7 @@
|
|
|
76
106
|
|
|
77
107
|
### Fixed
|
|
78
108
|
|
|
109
|
+
- Fixed missing `await` on `#tryWellKnownForRegistration` call in `#resolveRegistrationEndpoint` that caused path-prefixed well-known fallback to never actually execute, returning the unresolved Promise object instead of the registration endpoint ([1407](https://github.com/can1357/oh-my-pi/pull/1407) by [@faizhasim](https://github.com/faizhasim))
|
|
79
110
|
- Fixed JavaScript module reloading to refresh local re-exports when transitive dependency files are edited
|
|
80
111
|
- Fixed Python tool calls in warm kernels to initialize once bridge environment variables appear after startup and to return a clear `tool bridge is unavailable` error when missing
|
|
81
112
|
- Fixed IRC `send` handling to preserve recipient incoming messages when auto-reply timeouts instead of dropping them
|
|
@@ -83,7 +114,6 @@
|
|
|
83
114
|
- Fixed JavaScript `eval` imports to preserve module-level singletons across re-imports of unchanged local files and reload them only after edits
|
|
84
115
|
- Fixed concurrent Python evaluator tool calls to use per-run identifiers so tool responses and output are routed to the correct execution
|
|
85
116
|
- Fixed the `search` tool argument validation to accept a single string `paths` value as a one-path search.
|
|
86
|
-
|
|
87
117
|
## [15.4.0] - 2026-05-26
|
|
88
118
|
|
|
89
119
|
### Breaking Changes
|
|
@@ -92,9 +122,24 @@
|
|
|
92
122
|
|
|
93
123
|
### Added
|
|
94
124
|
|
|
125
|
+
- Added resolved subagent model badge to the task widget status line showing `<provider>/<id>` (with optional `:<thinkingLevel>` suffix when thinking is set explicitly), opt-in via `task.showResolvedModelBadge` Appearance setting (default off)
|
|
95
126
|
- Added `codex` and `gemini` to the web search provider settings so users can configure OpenAI and Gemini web search directly from provider selection
|
|
96
127
|
- Added OpenAI (`codex`) and Gemini web search options with updated setup descriptions for `omp /login openai-codex` and Gemini OAuth login
|
|
97
128
|
- Added pretty-printing for wide JSON `data:` payloads in the raw provider-stream debug viewer so streamed event bodies expand across multiple `data:` lines instead of getting clipped by the per-line truncator, and updated the viewer header to read `raw provider stream (SSE + WS)` now that Codex WebSocket frames also flow through the buffer
|
|
129
|
+
- Added per-tool approval policies with a `--auto-approve` (alias `--yolo`) CLI flag to bypass confirmation prompts for automation. Each tool call resolves a policy of `allow` / `deny` / `prompt` via a six-level lookup: overriding action exceptions, validated user config, non-overriding action exceptions, built-in defaults, validated user `_default`, and a system `prompt` fallback.
|
|
130
|
+
- Added `tools.approval.<toolName>: allow | deny | prompt` user config support via the settings schema. Invalid values (non-strings, unknown literals) are now ignored and fall through to the built-in default instead of being silently honoured — preventing a typo from locking the user out of a tool or bypassing approval for one.
|
|
131
|
+
- Added action-based exception registry covering LSP read-only actions (`diagnostics`/`definition`/`references`/etc. → `allow`), DAP debug inspection actions (`threads`/`stack_trace`/`variables`/`scopes`/`read_memory`/etc. → `allow`), and critical bash patterns (`rm -rf /`, `sudo rm`, fork bombs, `chmod -R 777 /`, `chown -R user /`, `curl ... | bash`, `bash <(curl ...)`, writes to `/etc/passwd|shadow|sudoers`, `shutdown`/`reboot`/`halt`/`init 0`/`kill -9 1`, `nc -e`/`nc -c` reverse shells → always `prompt`, even when bash is user-allowed).
|
|
132
|
+
- Added approval check in `ExtensionToolWrapper.execute()` ahead of extension `tool_call` handlers, with an actionable error in non-interactive sessions (`--auto-approve` / `tools.approval.<tool>: allow` guidance).
|
|
133
|
+
- Added MCP-tool labelling and bash/ssh command truncation in the approval prompt so `mcp__<server>__<tool>` calls are tagged as MCP server tools and a heredoc-sized command body doesn't blow out the confirmation dialog.
|
|
134
|
+
- Added `docs/approval-mode.md` user guide and a 57-case unit suite covering the resolution order, every critical-bash pattern (with benign-keyword negatives to lock false-positives out), user-config validation, and prompt formatting.
|
|
135
|
+
- Added `tools.approvalMode` global setting (Interaction tab in `/settings`) with values `auto` | `prompt` | `custom`. Defaults to `auto` so the agent runs every tool call without interruption — matching the `--auto-approve` / `--yolo` CLI flag. `prompt` uses built-in per-tool defaults only (read/find/search auto-allow; bash/edit/write/eval/ssh require confirmation; `tools.approval.<tool>` config is ignored). `custom` makes the `tools.approval.<tool>` config the source of truth — your settings win over built-in defaults, which fall back only for tools you haven't configured. CLI `--auto-approve` always wins. Critical safety patterns (e.g. `rm -rf /`, `curl … | bash`, fork bombs) keep prompting even when the tool is user-allowed.
|
|
136
|
+
- Extended `CRITICAL_BASH_PATTERNS` to cover `source <(curl …)` / `. <(curl …)` and `eval "$(curl …)"` / `eval $(curl …)` / ``eval `curl …` `` (all common remote-fetch-then-execute shapes that the original `bash <(curl …)` regex missed), `chmod -R` symbolic modes (`u+x`, `u+rwx,o+w`) targeting filesystem root, and `tee` / `tee -a` writes to `/etc/{passwd,shadow,sudoers}`. Benign forms (`source ./local.sh`, `find . -name foo`, `chmod -R u+x ./build`, `tee /var/log/app.log`, `eval "$VAR"`) are pinned negative in the suite so future expansion can't regress false-positive rate.
|
|
137
|
+
- Extended `formatApprovalPrompt` with payload previews for `eval` (language + first cell's code), `task` (agent + first task's id + assignment), `ast_edit` (first op's pattern / replacement / paths), `browser` (action + tab + url + code), and `write` content (alongside path). Previously these all rendered as bare `Allow tool: <name>` lines, giving the user no signal about what they were authorizing.
|
|
138
|
+
- Decoupled the per-tool approval gate from extension-loading state: `ExtensionRunner` and the `ExtensionToolWrapper` per-tool gate are now constructed unconditionally in `createAgentSession`, regardless of whether any extensions are loaded. Previously the runner was created only when `extensionsResult.extensions.length > 0`, which silently disabled the entire approval system if no extensions (including `createAutoresearchExtension`) were loaded; a regression test in `approval-mode.test.ts` now locks the invariant.
|
|
139
|
+
|
|
140
|
+
### Fixed
|
|
141
|
+
|
|
142
|
+
- Fixed `isMcpToolName` over-matching any tool name containing `__` (an extension legally named `my__feature` or `pkg__util__do` was getting falsely labelled `Origin: MCP server tool` in the approval prompt). Restricted to the canonical `mcp__` prefix only.
|
|
98
143
|
|
|
99
144
|
### Changed
|
|
100
145
|
|
|
@@ -112,9 +157,34 @@
|
|
|
112
157
|
- Fixed web search OAuth-backed providers (including Codex and Gemini) to use broker-managed token retrieval and account metadata, avoiding direct token-store refresh behavior that could cause search authentication failures
|
|
113
158
|
- Updated Tavily missing-credential feedback to prompt users to configure an API-key provider setting instead of referencing `agent.db` directly
|
|
114
159
|
- Refreshed expired OpenAI Codex OAuth tokens during `web_search` execution and persisted the updated credentials so searches continue working after token expiry
|
|
160
|
+
- Fixed the browser tool's existing-tab re-navigation path (`tab-supervisor.acquireTab`) still defaulting to `waitUntil: "networkidle2"` while the new-tab worker switched to `"load"`. Identical `acquireTab({url})` calls behaved differently depending on whether the named tab was fresh or being reused — fresh tabs returned quickly, second invocations hung on dev servers with persistent WebSocket / HMR connections. Both paths now agree on `"load"`.
|
|
161
|
+
- Fixed the `patch` tool's post-write verification `ToolError` embedding the absolute `resolvedPath` in its user-facing message; the outer composer in `executeSinglePathEntries` then prepended `Error editing ${path}: …`, double-embedding the path and leaking `$HOME` into the TUI. The error message now uses the caller-supplied relative `path` (matching the success branches); `resolvedPath` is retained only in the structured `context` metadata for log correlation.
|
|
162
|
+
- Fixed `splitInternalUrlSel` keeping `mcp://` resource URIs fully opaque, including selector-shaped suffixes like `:raw`, `:1-50`, and `/:raw`. `McpProtocolHandler` resolves resources by verbatim URI match (`r.uri === uri`), so peeling before resource lookup can make valid server-defined resource IDs unreachable. MCP read-selector support now requires a future resolver-aware path that can try the exact URI before interpreting any suffix as a selector; non-MCP internal URL selectors are unchanged.
|
|
163
|
+
- Fixed three correctness issues in the `find` tool. (1) `onMatch` guard checked the outer task `signal?.aborted` instead of `combinedSignal.aborted` (which also includes the per-call timeout signal), so late matches accumulated past the timeout. (2) Timeout-drained partial results were emitted in insertion order while the normal path sorts by mtime descending; callers relying on "most recently modified first" got an inconsistent ordering when the call timed out. The timeout drain now tracks per-entry mtime in a parallel array and applies the same comparator. (3) `validateFindPathInputs` now skips backslash-escaped commas (`\,`) when checking for top-level commas, matching `search.ts:containsTopLevelComma`.
|
|
164
|
+
- Fixed `throwPreferredDapStartError` using a single `await Promise.resolve()` (one microtask) to let a concurrent launch/attach rejection settle before deciding which error to surface. That worked for synchronous-rejection test fakes but not real adapter I/O: the launch failure arrives via socket and lands several ticks after the `configurationDone` failure. `DapStartRequestFailure` now carries a `settled?: Promise<void>` that resolves when the underlying request settles either way, and `throwPreferredDapStartError` races against it with a 50 ms ceiling. The preferred error message (the underlying launch/attach failure rather than the cascade) now surfaces under real I/O.
|
|
165
|
+
- Fixed `adapter: "debugpy"` over-promising in the `debug` tool. `resolveAdapter("debugpy", cwd)` only checks for `python` in `PATH`; it does not verify that the `debugpy` module is importable. Both failure modes — `python` missing and `debugpy` module missing — used to collapse onto a generic `"No suitable debug adapter found"` error. The launch/attach action now throws a targeted `ToolError` naming `python` when `resolveAdapter` returns null for an explicit `adapter: "debugpy"`, and the `DapSessionManager` spawn-catch detects `"No module named debugpy"` in adapter stderr and surfaces a `pip install debugpy` hint. The Python debug tool documentation lists the install hint so the prompt and runtime diagnostics agree.
|
|
166
|
+
- Fixed the LSP symbol-resolver `BARE_IDENTIFIER_RE` (`/^[A-Za-z_][\w]*$/`) rejecting `$`-prefixed identifiers (`$store`, `$count`, RxJS observables, Svelte stores, Angular signals). Without the word-boundary check, searching for `$store` on a line containing `bar$store` returned the offset inside the compound identifier rather than the standalone occurrence, feeding a wrong column to the LSP server. Pattern now `/^[$A-Za-z_][\w$]*$/`; the companion `IDENTIFIER_CHAR_RE` already contained `$`.
|
|
167
|
+
- Fixed `applyWorkspaceEdit` writing all text edits before walking `documentChanges` for resource operations. LSP §3.16.2 requires clients to apply `documentChanges` in declared order, so any server emitting `{kind: "create", uri: X}` followed by a `TextDocumentEdit` for `X` (e.g. "Extract to new file" code actions, some rename responses) broke: the edit ran against a non-existent file, then the create happened. `applyWorkspaceEdit` now walks `documentChanges` once in declared order; per-URI text edits are coalesced into a pending Map and flushed immediately before any subsequent resource op for the same URI. Legacy `changes`-map-only payloads are unchanged. Folder-level `rename`/`delete` ops now flush every pending URI under the affected subtree (not just the exact target) so child-file edits queued before a parent-folder move land at the original location instead of dangling against a non-existent path on the final flush. Rename ops additionally flush pending edits queued against `renameOp.newUri` (and its descendants) **before** `fs.rename` runs, so edits intended for the pre-rename target file are applied before the rename clobbers or replaces it (relevant under `options.overwrite`/`options.ignoreIfExists`). When a `WorkspaceEdit` payload supplies both `changes` and `documentChanges`, the `documentChanges` arm is now used exclusively per LSP §3.16.2 ("if documentChanges are supplied … servers should use them in preference to changes"); previously the two were merged.
|
|
168
|
+
|
|
169
|
+
### Fixed
|
|
170
|
+
|
|
115
171
|
- Fixed built-in `explore` agent failing every invocation with `schema_violation: files.0.ref: must not be present` on releases prior to 15.3.2 by renaming the `files[].ref` property to `files[].path` in the agent's output schema; `ref` is a JTD-reserved keyword (RFC 8927) and collides with JSON Type Definition's schema-reference form, so the converter previously dropped it from the generated JSON Schema. Defense-in-depth alongside the 15.3.2 converter fix ([#1379](https://github.com/can1357/oh-my-pi/issues/1379)).
|
|
116
172
|
- Increased the `yield` tool's schema-validation retry budget from 1 to 3 so subagents whose first structured-output attempt mismatches the declared output schema get up to three retries before the parent's post-mortem `schema_violation` check hard-fails the task. The tool now also surfaces remaining retry attempts and an explicit "call yield again with the corrected shape" directive in each rejection message, giving the model the context it needs to converge — particularly helpful for models like GLM that tend to invent per-element field names instead of following the declared schema.
|
|
117
173
|
- Fixed CLI PDF file arguments being decoded as raw bytes for local vision models; `.pdf` and other supported document files now go through the same Markit conversion path as the `read` tool before entering the prompt ([#1401](https://github.com/can1357/oh-my-pi/issues/1401)).
|
|
174
|
+
- Fixed the `bash` tool hanging until the 305 s hard timeout when a command writes a file via heredoc on Windows (bodies > ~4 KiB) or macOS (bodies > 16-64 KiB). Root cause was in the embedded brush shell; see `@oh-my-pi/pi-natives` changelog for the underlying fix.
|
|
175
|
+
|
|
176
|
+
### Fixed
|
|
177
|
+
|
|
178
|
+
- Fixed `/review` custom prompt orchestration text to use static prompt templates and consistently instruct reviewer task delegation.
|
|
179
|
+
- Fixed `/review` custom-instructions submission on terminals that cannot distinguish Ctrl+Enter by using prompt-style input where Enter submits and Shift+Enter inserts a newline.
|
|
180
|
+
- Fixed hook editor submissions sending large-paste placeholders such as `[paste #1 +27 lines]` instead of the pasted content.
|
|
181
|
+
- Added per-tool approval policies with a `--auto-approve` (alias `--yolo`) CLI flag to bypass confirmation prompts for automation. Each tool call resolves a policy of `allow` / `deny` / `prompt` via a six-level lookup: overriding action exceptions, validated user config, non-overriding action exceptions, built-in defaults, validated user `_default`, and a system `prompt` fallback.
|
|
182
|
+
- Added `tools.approval.<toolName>: allow | deny | prompt` user config support via the settings schema. Invalid values (non-strings, unknown literals) are now ignored and fall through to the built-in default instead of being silently honoured — preventing a typo from locking the user out of a tool or bypassing approval for one.
|
|
183
|
+
- Added action-based exception registry covering LSP read-only actions (`diagnostics`/`definition`/`references`/etc. → `allow`), DAP debug inspection actions (`threads`/`stack_trace`/`variables`/`scopes`/`read_memory`/etc. → `allow`), and critical bash patterns (`rm -rf /`, `sudo rm`, fork bombs, `chmod -R 777 /`, `chown -R user /`, `curl ... | bash`, `bash <(curl ...)`, writes to `/etc/passwd|shadow|sudoers`, `shutdown`/`reboot`/`halt`/`init 0`/`kill -9 1`, `nc -e`/`nc -c` reverse shells → always `prompt`, even when bash is user-allowed).
|
|
184
|
+
- Added approval check in `ExtensionToolWrapper.execute()` ahead of extension `tool_call` handlers, with an actionable error in non-interactive sessions (`--auto-approve` / `tools.approval.<tool>: allow` guidance).
|
|
185
|
+
- Added MCP-tool labelling and bash/ssh command truncation in the approval prompt so `mcp__<server>__<tool>` calls are tagged as MCP server tools and a heredoc-sized command body doesn't blow out the confirmation dialog.
|
|
186
|
+
- Added `docs/approval-mode.md` user guide and a 57-case unit suite covering the resolution order, every critical-bash pattern (with benign-keyword negatives to lock false-positives out), user-config validation, and prompt formatting.
|
|
187
|
+
- Added `tools.approvalMode` global setting (Interaction tab in `/settings`) with values `auto` | `prompt` | `custom`. Defaults to `auto` so the agent runs every tool call without interruption — matching the `--auto-approve` / `--yolo` CLI flag. `prompt` uses built-in per-tool defaults only (read/find/search auto-allow; bash/edit/write/eval/ssh require confirmation; `tools.approval.<tool>` config is ignored). `custom` makes the `tools.approval.<tool>` config the source of truth — your settings win over built-in defaults, which fall back only for tools you haven't configured. CLI `--auto-approve` always wins. Critical safety patterns (e.g. `rm -rf /`, `curl … | bash`, fork bombs) keep prompting even when the tool is user-allowed.
|
|
118
188
|
|
|
119
189
|
## [15.3.2] - 2026-05-25
|
|
120
190
|
### Added
|
package/dist/types/cli/args.d.ts
CHANGED
|
@@ -40,6 +40,8 @@ export interface Args {
|
|
|
40
40
|
noRules?: boolean;
|
|
41
41
|
listModels?: string | true;
|
|
42
42
|
noTitle?: boolean;
|
|
43
|
+
autoApprove?: boolean;
|
|
44
|
+
approvalMode?: "always-ask" | "write" | "yolo";
|
|
43
45
|
messages: string[];
|
|
44
46
|
fileArgs: string[];
|
|
45
47
|
/** Unknown flags (potentially extension flags) - map of flag name to value */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type AuthBrokerAction = "serve" | "token" | "login" | "logout" | "status" | "import" | "migrate";
|
|
1
|
+
export type AuthBrokerAction = "serve" | "token" | "login" | "logout" | "status" | "import" | "migrate" | "list";
|
|
2
2
|
export interface AuthBrokerCommandArgs {
|
|
3
3
|
action: AuthBrokerAction;
|
|
4
4
|
flags: {
|
|
@@ -111,6 +111,14 @@ export default class Index extends Command {
|
|
|
111
111
|
"no-title": import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"boolean"> & {
|
|
112
112
|
description: string;
|
|
113
113
|
};
|
|
114
|
+
"auto-approve": import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"boolean"> & {
|
|
115
|
+
aliases: string[];
|
|
116
|
+
description: string;
|
|
117
|
+
};
|
|
118
|
+
"approval-mode": import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"string"> & {
|
|
119
|
+
options: string[];
|
|
120
|
+
description: string;
|
|
121
|
+
};
|
|
114
122
|
};
|
|
115
123
|
static examples: string[];
|
|
116
124
|
static strict: boolean;
|
|
@@ -1924,7 +1924,7 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
1924
1924
|
readonly ui: {
|
|
1925
1925
|
readonly tab: "editing";
|
|
1926
1926
|
readonly label: "Hashline Duplicate Insert Drop";
|
|
1927
|
-
readonly description: "Drop
|
|
1927
|
+
readonly description: "Drop payload lines that duplicate adjacent file context \u2014 2+-line context echoes on `\u2191`/`\u2193` inserts, and a single boundary line at either edge of an `A-B:` replacement";
|
|
1928
1928
|
};
|
|
1929
1929
|
};
|
|
1930
1930
|
readonly "edit.blockAutoGenerated": {
|
|
@@ -2135,6 +2135,38 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
2135
2135
|
readonly description: "Whether to keep IPython kernel alive across calls";
|
|
2136
2136
|
};
|
|
2137
2137
|
};
|
|
2138
|
+
readonly "tools.approval": {
|
|
2139
|
+
readonly type: "record";
|
|
2140
|
+
readonly default: {};
|
|
2141
|
+
readonly ui: {
|
|
2142
|
+
readonly tab: "tools";
|
|
2143
|
+
readonly label: "Tool Approval Policies";
|
|
2144
|
+
readonly description: "Per-tool approval policies. Set to 'allow' to auto-approve, 'prompt' to require confirmation, or 'deny' to block. Overrides are honored in every approval mode.";
|
|
2145
|
+
};
|
|
2146
|
+
};
|
|
2147
|
+
readonly "tools.approvalMode": {
|
|
2148
|
+
readonly type: "enum";
|
|
2149
|
+
readonly values: readonly ["always-ask", "write", "yolo"];
|
|
2150
|
+
readonly default: "yolo";
|
|
2151
|
+
readonly ui: {
|
|
2152
|
+
readonly tab: "interaction";
|
|
2153
|
+
readonly label: "Tool Approval";
|
|
2154
|
+
readonly description: "Default approval behaviour for tool calls. 'Always ask' auto-approves read-only tools only. 'Write' auto-approves read and workspace-write tools. 'Yolo' auto-approves every tier unless a tool declares a safety override. `tools.approval.<tool>` overrides are honored in every mode.";
|
|
2155
|
+
readonly options: readonly [{
|
|
2156
|
+
readonly value: "always-ask";
|
|
2157
|
+
readonly label: "Always ask";
|
|
2158
|
+
readonly description: "Auto-approve read-only tools; require confirmation for write and exec tools.";
|
|
2159
|
+
}, {
|
|
2160
|
+
readonly value: "write";
|
|
2161
|
+
readonly label: "Write";
|
|
2162
|
+
readonly description: "Auto-approve read-only and write tools; require confirmation for exec tools such as bash, eval, browser, task, recipe, and ssh.";
|
|
2163
|
+
}, {
|
|
2164
|
+
readonly value: "yolo";
|
|
2165
|
+
readonly label: "Yolo";
|
|
2166
|
+
readonly description: "Auto-approve read, write, and exec tools. Safety overrides declared by tools (for example critical bash patterns) still require confirmation.";
|
|
2167
|
+
}];
|
|
2168
|
+
};
|
|
2169
|
+
};
|
|
2138
2170
|
readonly "todo.enabled": {
|
|
2139
2171
|
readonly type: "boolean";
|
|
2140
2172
|
readonly default: true;
|
|
@@ -2887,6 +2919,15 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
2887
2919
|
}];
|
|
2888
2920
|
};
|
|
2889
2921
|
};
|
|
2922
|
+
readonly "task.showResolvedModelBadge": {
|
|
2923
|
+
readonly type: "boolean";
|
|
2924
|
+
readonly default: false;
|
|
2925
|
+
readonly ui: {
|
|
2926
|
+
readonly tab: "appearance";
|
|
2927
|
+
readonly label: "Show Resolved Model Badge";
|
|
2928
|
+
readonly description: "Display the actual model ID used by each subagent in the task widget status line";
|
|
2929
|
+
};
|
|
2930
|
+
};
|
|
2890
2931
|
readonly "skills.enabled": {
|
|
2891
2932
|
readonly type: "boolean";
|
|
2892
2933
|
readonly default: true;
|
|
@@ -22,6 +22,8 @@ type EditParams = ReplaceParams | PatchParams | HashlineParams | ApplyPatchParam
|
|
|
22
22
|
export declare class EditTool implements AgentTool<TInput> {
|
|
23
23
|
#private;
|
|
24
24
|
private readonly session;
|
|
25
|
+
readonly approval: (args: unknown) => "read" | "write";
|
|
26
|
+
readonly formatApprovalDetails: (args: unknown) => string[];
|
|
25
27
|
readonly name = "edit";
|
|
26
28
|
readonly label = "Edit";
|
|
27
29
|
readonly loadMode = "essential";
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Custom tools are TypeScript modules that define additional tools for the agent.
|
|
5
5
|
* They can provide custom rendering for tool calls and results in the TUI.
|
|
6
6
|
*/
|
|
7
|
-
import type { AgentToolResult, AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
|
|
7
|
+
import type { AgentToolResult, AgentToolUpdateCallback, ToolApproval, ToolApprovalDecision, ToolTier } from "@oh-my-pi/pi-agent-core";
|
|
8
8
|
import type { CompactionResult } from "@oh-my-pi/pi-agent-core/compaction";
|
|
9
9
|
import type { Model, Static, TSchema } from "@oh-my-pi/pi-ai";
|
|
10
10
|
import type { Component } from "@oh-my-pi/pi-tui";
|
|
@@ -20,7 +20,7 @@ import type { TodoItem } from "../../tools/todo-write";
|
|
|
20
20
|
export type CustomToolUIContext = HookUIContext;
|
|
21
21
|
export type { ExecOptions, ExecResult } from "../../exec/exec";
|
|
22
22
|
/** Re-export for custom tools to use in execute signature */
|
|
23
|
-
export type { AgentToolResult, AgentToolUpdateCallback };
|
|
23
|
+
export type { AgentToolResult, AgentToolUpdateCallback, ToolApproval, ToolApprovalDecision, ToolTier };
|
|
24
24
|
/** Pending action entry consumed by the hidden resolve tool */
|
|
25
25
|
export interface CustomToolPendingAction {
|
|
26
26
|
/** Human-readable preview label shown in resolve flow */
|
|
@@ -74,6 +74,8 @@ export interface CustomToolContext {
|
|
|
74
74
|
abort(): void;
|
|
75
75
|
/** Settings instance for the current session. Prefer over the global singleton. */
|
|
76
76
|
settings?: Settings;
|
|
77
|
+
/** Whether to auto-approve all destructive tool operations (--auto-approve CLI flag) */
|
|
78
|
+
autoApprove?: boolean;
|
|
77
79
|
}
|
|
78
80
|
/** Session event passed to onSession callback */
|
|
79
81
|
export type CustomToolSessionEvent = {
|
|
@@ -174,6 +176,10 @@ export interface CustomTool<TParams extends TSchema = TSchema, TDetails = any> {
|
|
|
174
176
|
mcpServerName?: string;
|
|
175
177
|
/** Original MCP tool name for discovery/search metadata. */
|
|
176
178
|
mcpToolName?: string;
|
|
179
|
+
/** Capability tier declaration used by approval gates. Omitted means "exec". */
|
|
180
|
+
approval?: ToolApproval;
|
|
181
|
+
/** Lines appended after the standard approval prompt header. */
|
|
182
|
+
formatApprovalDetails?: (args: unknown) => string | string[] | undefined;
|
|
177
183
|
/**
|
|
178
184
|
* Execute the tool.
|
|
179
185
|
* @param toolCallId - Unique ID for this tool call
|
|
@@ -90,10 +90,14 @@ export interface HookUIContext {
|
|
|
90
90
|
* Supports Ctrl+G to open external editor ($VISUAL or $EDITOR).
|
|
91
91
|
* @param title - Title describing what is being edited
|
|
92
92
|
* @param prefill - Optional initial text
|
|
93
|
+
* @param options - Optional dialog controls such as an abort signal
|
|
94
|
+
* @param editorOptions - Optional editor behavior; `promptStyle` makes Enter submit and Shift+Enter insert a newline
|
|
93
95
|
* @returns Edited text, or undefined if cancelled (Escape)
|
|
94
96
|
*/
|
|
95
97
|
editor(title: string, prefill?: string, options?: {
|
|
96
98
|
signal?: AbortSignal;
|
|
99
|
+
}, editorOptions?: {
|
|
100
|
+
promptStyle?: boolean;
|
|
97
101
|
}): Promise<string | undefined>;
|
|
98
102
|
/**
|
|
99
103
|
* Get the current theme for styling text with ANSI codes.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
|
|
1
|
+
import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback, ToolApprovalDecision } from "@oh-my-pi/pi-agent-core";
|
|
2
2
|
import type { BunFile } from "bun";
|
|
3
3
|
import { type Theme } from "../modes/theme/theme";
|
|
4
4
|
import type { ToolSession } from "../tools";
|
|
@@ -7,6 +7,12 @@ import { renderCall, renderResult } from "./render";
|
|
|
7
7
|
import { type LspParams, type LspToolDetails, lspSchema } from "./types";
|
|
8
8
|
export type { LspServerStatus } from "./client";
|
|
9
9
|
export type { LspToolDetails } from "./types";
|
|
10
|
+
/**
|
|
11
|
+
* LSP actions that do not mutate the workspace or language-server state.
|
|
12
|
+
* Anything not in this set (rename, code_actions with apply, rename_file,
|
|
13
|
+
* reload, raw request, etc.) is classified as write-tier.
|
|
14
|
+
*/
|
|
15
|
+
export declare const LSP_READONLY_ACTIONS: ReadonlySet<string>;
|
|
10
16
|
export interface LspStartupServerInfo {
|
|
11
17
|
name: string;
|
|
12
18
|
status: "connecting" | "ready" | "error";
|
|
@@ -89,6 +95,8 @@ export declare function createLspWritethrough(cwd: string, options?: Writethroug
|
|
|
89
95
|
export declare class LspTool implements AgentTool<typeof lspSchema, LspToolDetails, Theme> {
|
|
90
96
|
private readonly session;
|
|
91
97
|
readonly name = "lsp";
|
|
98
|
+
readonly approval: (args: unknown) => ToolApprovalDecision;
|
|
99
|
+
readonly formatApprovalDetails: (args: unknown) => string[];
|
|
92
100
|
readonly label = "LSP";
|
|
93
101
|
readonly loadMode = "discoverable";
|
|
94
102
|
readonly summary = "Query LSP (language server) for diagnostics, hover info, and references";
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { MCPGetPromptResult, MCPPrompt, MCPRequestOptions, MCPResource, MCPResourceReadResult, MCPResourceTemplate, MCPServerCapabilities, MCPServerConfig, MCPServerConnection, MCPToolCallResult, MCPToolDefinition } from "./types";
|
|
2
2
|
/**
|
|
3
3
|
* Connect to an MCP server.
|
|
4
|
-
* Has a 30 second timeout to prevent blocking startup.
|
|
4
|
+
* Has a 30 second timeout by default to prevent blocking startup.
|
|
5
|
+
* Set OMP_MCP_TIMEOUT_MS=0 to disable MCP client-side timeouts.
|
|
5
6
|
*/
|
|
6
7
|
export declare function connectToServer(name: string, config: MCPServerConfig, options?: {
|
|
7
8
|
signal?: AbortSignal;
|
|
@@ -15,9 +15,10 @@ export interface AuthDetectionResult {
|
|
|
15
15
|
authType?: "oauth" | "apikey" | "unknown";
|
|
16
16
|
oauth?: OAuthEndpoints;
|
|
17
17
|
authServerUrl?: string;
|
|
18
|
+
resourceMetadataUrl?: string;
|
|
18
19
|
message?: string;
|
|
19
20
|
}
|
|
20
|
-
export declare function extractMcpAuthServerUrl(error: Error): string | undefined;
|
|
21
|
+
export declare function extractMcpAuthServerUrl(error: Error, serverUrl?: string): string | undefined;
|
|
21
22
|
/**
|
|
22
23
|
* Detect if an error indicates authentication is required.
|
|
23
24
|
* Checks for common auth error patterns.
|
|
@@ -32,9 +33,9 @@ export declare function extractOAuthEndpoints(error: Error): OAuthEndpoints | nu
|
|
|
32
33
|
* Analyze an error to determine authentication requirements.
|
|
33
34
|
* Returns structured info about what auth is needed.
|
|
34
35
|
*/
|
|
35
|
-
export declare function analyzeAuthError(error: Error): AuthDetectionResult;
|
|
36
|
+
export declare function analyzeAuthError(error: Error, serverUrl?: string): AuthDetectionResult;
|
|
36
37
|
/**
|
|
37
38
|
* Try to discover OAuth endpoints by querying the server's well-known endpoints.
|
|
38
39
|
* This is a fallback when error responses don't include OAuth metadata.
|
|
39
40
|
*/
|
|
40
|
-
export declare function discoverOAuthEndpoints(serverUrl: string, authServerUrl?: string): Promise<OAuthEndpoints | null>;
|
|
41
|
+
export declare function discoverOAuthEndpoints(serverUrl: string, authServerUrl?: string, resourceMetadataUrl?: string): Promise<OAuthEndpoints | null>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare function resolveMCPTimeoutMs(configTimeout?: number): number;
|
|
2
|
+
export declare function isMCPTimeoutEnabled(timeoutMs: number): boolean;
|
|
3
|
+
export declare function describeMCPTimeout(timeoutMs: number): string;
|
|
4
|
+
export declare function getNeverAbortSignal(): AbortSignal;
|
|
5
|
+
export declare function createMCPTimeout(timeoutMs: number, signal?: AbortSignal): {
|
|
6
|
+
signal?: AbortSignal;
|
|
7
|
+
clear: () => void;
|
|
8
|
+
isTimeoutAbort: (error: unknown) => boolean;
|
|
9
|
+
};
|
|
@@ -45,7 +45,7 @@ export interface MCPAuthConfig {
|
|
|
45
45
|
interface MCPServerConfigBase {
|
|
46
46
|
/** Whether this server is enabled (default: true) */
|
|
47
47
|
enabled?: boolean;
|
|
48
|
-
/**
|
|
48
|
+
/** MCP request timeout in milliseconds (default: 30000, 0 to disable) */
|
|
49
49
|
timeout?: number;
|
|
50
50
|
/** Authentication configuration (optional) */
|
|
51
51
|
auth?: MCPAuthConfig;
|
package/dist/types/sdk.d.ts
CHANGED
|
@@ -125,6 +125,8 @@ export interface CreateAgentSessionOptions {
|
|
|
125
125
|
* `@opentelemetry/api` package returns a no-op tracer in that case.
|
|
126
126
|
*/
|
|
127
127
|
telemetry?: AgentTelemetryConfig;
|
|
128
|
+
/** Whether to auto-approve all tool calls (--auto-approve CLI flag). Default: false */
|
|
129
|
+
autoApprove?: boolean;
|
|
128
130
|
}
|
|
129
131
|
/** Result from createAgentSession */
|
|
130
132
|
export interface CreateAgentSessionResult {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
|
|
2
2
|
export declare const DEFAULT_MAX_LINES = 3000;
|
|
3
3
|
export declare const DEFAULT_MAX_BYTES: number;
|
|
4
|
-
export declare const DEFAULT_MAX_COLUMN =
|
|
4
|
+
export declare const DEFAULT_MAX_COLUMN = 512;
|
|
5
5
|
export interface OutputSummary {
|
|
6
6
|
output: string;
|
|
7
7
|
truncated: boolean;
|
|
@@ -20,6 +20,8 @@ export declare class TaskTool implements AgentTool<TaskToolSchemaInstance, TaskT
|
|
|
20
20
|
#private;
|
|
21
21
|
private readonly session;
|
|
22
22
|
readonly name = "task";
|
|
23
|
+
readonly approval: "exec";
|
|
24
|
+
readonly formatApprovalDetails: (args: unknown) => string[];
|
|
23
25
|
readonly label = "Task";
|
|
24
26
|
readonly summary = "Spawn a subagent to complete a parallel task";
|
|
25
27
|
readonly strict = true;
|
|
@@ -188,6 +188,8 @@ export interface AgentProgress {
|
|
|
188
188
|
cost: number;
|
|
189
189
|
durationMs: number;
|
|
190
190
|
modelOverride?: string | string[];
|
|
191
|
+
/** Resolved model display string in the form `<provider>/<id>`, optionally suffixed with `:<thinkingLevel>` when the level was set explicitly. Undefined when the model could not be resolved. */
|
|
192
|
+
resolvedModel?: string;
|
|
191
193
|
/** Data extracted by registered subprocess tool handlers (keyed by tool name) */
|
|
192
194
|
extractedToolData?: Record<string, unknown[]>;
|
|
193
195
|
/**
|
|
@@ -245,6 +247,8 @@ export interface SingleResult {
|
|
|
245
247
|
/** Model's context window in tokens, when known. */
|
|
246
248
|
contextWindow?: number;
|
|
247
249
|
modelOverride?: string | string[];
|
|
250
|
+
/** Resolved model display string in the form `<provider>/<id>`, optionally suffixed with `:<thinkingLevel>` when the level was set explicitly. Omitted from tool-result JSON when undefined to keep wire payloads small. */
|
|
251
|
+
resolvedModel?: string;
|
|
248
252
|
error?: string;
|
|
249
253
|
aborted?: boolean;
|
|
250
254
|
abortReason?: string;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool approval resolution.
|
|
3
|
+
*
|
|
4
|
+
* Approval policy is declared by each tool. This module only knows how to:
|
|
5
|
+
* - normalize user `tools.approval.<tool>: allow | deny | prompt` overrides,
|
|
6
|
+
* - compare a tool capability tier against the active approval mode,
|
|
7
|
+
* - format the generic approval prompt body.
|
|
8
|
+
*/
|
|
9
|
+
import type { AgentTool, ToolTier } from "@oh-my-pi/pi-agent-core";
|
|
10
|
+
export type { ToolApproval, ToolApprovalDecision, ToolTier } from "@oh-my-pi/pi-agent-core";
|
|
11
|
+
export type ApprovalPolicy = "allow" | "deny" | "prompt";
|
|
12
|
+
export type ApprovalMode = "always-ask" | "write" | "yolo";
|
|
13
|
+
type ApprovalSubject = Pick<AgentTool, "name" | "approval" | "formatApprovalDetails">;
|
|
14
|
+
export interface ResolvedApproval {
|
|
15
|
+
policy: ApprovalPolicy;
|
|
16
|
+
tier: ToolTier;
|
|
17
|
+
reason?: string;
|
|
18
|
+
override: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Resolve approval policy for a tool call.
|
|
22
|
+
*
|
|
23
|
+
* Resolution order:
|
|
24
|
+
* 1. Tool `approval(args)` decision, defaulting to tier "exec" when omitted.
|
|
25
|
+
* 2. User per-tool override, if set and valid.
|
|
26
|
+
* 3. Active mode tier comparison.
|
|
27
|
+
*
|
|
28
|
+
* Tool decisions with `override: true` force a prompt in every mode unless the
|
|
29
|
+
* user explicitly denies the tool; deny remains the strongest policy.
|
|
30
|
+
*/
|
|
31
|
+
export declare function resolveApproval(tool: ApprovalSubject, args: unknown, mode: ApprovalMode, userConfig?: Record<string, unknown>): ResolvedApproval;
|
|
32
|
+
/**
|
|
33
|
+
* Check if a tool call requires user approval.
|
|
34
|
+
*
|
|
35
|
+
* @throws Error if policy is 'deny'
|
|
36
|
+
* @returns Object with required flag and optional reason for the prompt
|
|
37
|
+
*/
|
|
38
|
+
export declare function requiresApproval(tool: ApprovalSubject, args: unknown, mode: ApprovalMode, userConfig?: Record<string, unknown>): {
|
|
39
|
+
required: boolean;
|
|
40
|
+
reason?: string;
|
|
41
|
+
};
|
|
42
|
+
export declare function truncateForPrompt(value: string, maxChars?: number): string;
|
|
43
|
+
/**
|
|
44
|
+
* Format the approval prompt body shown to the user.
|
|
45
|
+
*/
|
|
46
|
+
export declare function formatApprovalPrompt(tool: ApprovalSubject, args: unknown, reason?: string): string;
|
|
@@ -61,6 +61,7 @@ export declare class AskTool implements AgentTool<typeof askSchema, AskToolDetai
|
|
|
61
61
|
#private;
|
|
62
62
|
private readonly session;
|
|
63
63
|
readonly name = "ask";
|
|
64
|
+
readonly approval: "read";
|
|
64
65
|
readonly label = "Ask";
|
|
65
66
|
readonly summary = "Ask the user a clarifying question";
|
|
66
67
|
readonly description: string;
|
|
@@ -38,6 +38,8 @@ export interface AstEditToolDetails {
|
|
|
38
38
|
export declare class AstEditTool implements AgentTool<typeof astEditSchema, AstEditToolDetails> {
|
|
39
39
|
private readonly session;
|
|
40
40
|
readonly name = "ast_edit";
|
|
41
|
+
readonly approval: (args: unknown) => "read" | "write";
|
|
42
|
+
readonly formatApprovalDetails: (args: unknown) => string[];
|
|
41
43
|
readonly label = "AST Edit";
|
|
42
44
|
readonly summary = "Perform AST-aware code edits (structural refactoring)";
|
|
43
45
|
readonly description: string;
|
|
@@ -35,6 +35,7 @@ export interface AstGrepToolDetails {
|
|
|
35
35
|
export declare class AstGrepTool implements AgentTool<typeof astGrepSchema, AstGrepToolDetails> {
|
|
36
36
|
private readonly session;
|
|
37
37
|
readonly name = "ast_grep";
|
|
38
|
+
readonly approval: "read";
|
|
38
39
|
readonly label = "AST Grep";
|
|
39
40
|
readonly summary = "Search code with AST patterns (structural grep)";
|
|
40
41
|
readonly description: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
|
|
1
|
+
import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback, ToolApprovalDecision } from "@oh-my-pi/pi-agent-core";
|
|
2
2
|
import type { Component } from "@oh-my-pi/pi-tui";
|
|
3
3
|
import * as z from "zod/v4";
|
|
4
4
|
import type { RenderResultOptions } from "../extensibility/custom-tools/types";
|
|
@@ -6,6 +6,14 @@ import { type Theme } from "../modes/theme/theme";
|
|
|
6
6
|
import type { ToolSession } from ".";
|
|
7
7
|
import { type OutputMeta } from "./output-meta";
|
|
8
8
|
export declare const BASH_DEFAULT_PREVIEW_LINES = 10;
|
|
9
|
+
/**
|
|
10
|
+
* Bash patterns that force an approval prompt even in yolo mode.
|
|
11
|
+
*
|
|
12
|
+
* Kept intentionally tight — the cost of a false positive is one extra prompt;
|
|
13
|
+
* the cost of a false negative is data loss or a compromised host. New patterns
|
|
14
|
+
* should target shapes that are virtually never legitimate in automation.
|
|
15
|
+
*/
|
|
16
|
+
export declare const CRITICAL_BASH_PATTERNS: readonly [RegExp, RegExp, RegExp, RegExp, RegExp, RegExp, RegExp, RegExp, RegExp, RegExp, RegExp, RegExp, RegExp, RegExp, RegExp, RegExp, RegExp, RegExp, RegExp, RegExp];
|
|
9
17
|
declare const bashSchemaBase: z.ZodObject<{
|
|
10
18
|
command: z.ZodString;
|
|
11
19
|
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
@@ -52,6 +60,8 @@ export declare class BashTool implements AgentTool<BashToolSchema, BashToolDetai
|
|
|
52
60
|
#private;
|
|
53
61
|
private readonly session;
|
|
54
62
|
readonly name = "bash";
|
|
63
|
+
readonly approval: (args: unknown) => ToolApprovalDecision;
|
|
64
|
+
readonly formatApprovalDetails: (args: unknown) => string[];
|
|
55
65
|
readonly label = "Bash";
|
|
56
66
|
readonly loadMode = "essential";
|
|
57
67
|
readonly description: string;
|
|
@@ -68,6 +68,8 @@ export declare class BrowserTool implements AgentTool<typeof browserSchema, Brow
|
|
|
68
68
|
#private;
|
|
69
69
|
private readonly session;
|
|
70
70
|
readonly name = "browser";
|
|
71
|
+
readonly approval: "exec";
|
|
72
|
+
readonly formatApprovalDetails: (args: unknown) => string[];
|
|
71
73
|
readonly label = "Browser";
|
|
72
74
|
readonly loadMode = "discoverable";
|
|
73
75
|
readonly summary = "Control a headless browser to navigate and interact with web pages";
|
|
@@ -27,6 +27,7 @@ type CalculatorParams = z.infer<typeof calculatorSchema>;
|
|
|
27
27
|
*/
|
|
28
28
|
export declare class CalculatorTool implements AgentTool<typeof calculatorSchema, CalculatorToolDetails> {
|
|
29
29
|
readonly name = "calc";
|
|
30
|
+
readonly approval: "read";
|
|
30
31
|
readonly label = "Calc";
|
|
31
32
|
readonly summary = "Evaluate a mathematical expression";
|
|
32
33
|
readonly loadMode = "discoverable";
|
|
@@ -31,6 +31,7 @@ export interface RewindToolDetails {
|
|
|
31
31
|
export declare class CheckpointTool implements AgentTool<typeof checkpointSchema, CheckpointToolDetails> {
|
|
32
32
|
private readonly session;
|
|
33
33
|
readonly name = "checkpoint";
|
|
34
|
+
readonly approval: "read";
|
|
34
35
|
readonly label = "Checkpoint";
|
|
35
36
|
readonly summary = "Create a git-based checkpoint to save and restore session state";
|
|
36
37
|
readonly description: string;
|
|
@@ -47,6 +48,7 @@ export declare class CheckpointTool implements AgentTool<typeof checkpointSchema
|
|
|
47
48
|
export declare class RewindTool implements AgentTool<typeof rewindSchema, RewindToolDetails> {
|
|
48
49
|
private readonly session;
|
|
49
50
|
readonly name = "rewind";
|
|
51
|
+
readonly approval: "read";
|
|
50
52
|
readonly label = "Rewind";
|
|
51
53
|
readonly summary = "Rewind to a previously created checkpoint";
|
|
52
54
|
readonly description: string;
|