@oh-my-pi/pi-coding-agent 15.10.1 → 15.10.3
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 +113 -1
- package/dist/types/cli/gallery-fixtures/types.d.ts +7 -1
- package/dist/types/cli/startup-cwd.d.ts +2 -0
- package/dist/types/commands/launch.d.ts +3 -0
- package/dist/types/config/keybindings.d.ts +2 -2
- package/dist/types/config/model-provider-priority.d.ts +1 -0
- package/dist/types/config/model-resolver.d.ts +4 -1
- package/dist/types/config/settings.d.ts +7 -2
- package/dist/types/debug/report-bundle.d.ts +3 -0
- package/dist/types/edit/file-snapshot-store.d.ts +18 -10
- package/dist/types/edit/index.d.ts +0 -1
- package/dist/types/eval/py/__tests__/prelude.test.d.ts +1 -0
- package/dist/types/extensibility/extensions/types.d.ts +4 -1
- package/dist/types/lsp/client.d.ts +10 -0
- package/dist/types/lsp/index.d.ts +0 -5
- package/dist/types/main.d.ts +14 -9
- package/dist/types/mcp/tool-bridge.d.ts +2 -0
- package/dist/types/modes/components/assistant-message.d.ts +0 -9
- package/dist/types/modes/components/custom-editor.d.ts +1 -1
- package/dist/types/modes/components/late-diagnostics-message.d.ts +20 -0
- package/dist/types/modes/components/read-tool-group.d.ts +6 -0
- package/dist/types/modes/components/session-selector.d.ts +16 -7
- package/dist/types/modes/components/status-line.d.ts +2 -0
- package/dist/types/modes/components/tool-execution.d.ts +0 -18
- package/dist/types/modes/controllers/event-controller.d.ts +17 -0
- package/dist/types/modes/interactive-mode.d.ts +1 -0
- package/dist/types/modes/magic-keywords.d.ts +1 -1
- package/dist/types/modes/markdown-prose.d.ts +1 -1
- package/dist/types/modes/types.d.ts +7 -0
- package/dist/types/modes/workflow.d.ts +3 -3
- package/dist/types/session/auth-storage.d.ts +1 -1
- package/dist/types/session/messages.d.ts +11 -8
- package/dist/types/session/session-manager.d.ts +5 -2
- package/dist/types/session/yield-queue.d.ts +10 -1
- package/dist/types/task/executor.d.ts +10 -0
- package/dist/types/tools/eval-render.d.ts +0 -1
- package/dist/types/tools/eval.d.ts +8 -0
- package/dist/types/tools/gh-cache-invalidation.d.ts +6 -0
- package/dist/types/tools/github-cache.d.ts +12 -0
- package/dist/types/tools/index.d.ts +31 -0
- package/dist/types/tools/path-utils.d.ts +13 -1
- package/dist/types/tools/read.d.ts +2 -1
- package/dist/types/tools/render-utils.d.ts +3 -1
- package/dist/types/tools/renderers.d.ts +0 -15
- package/dist/types/tools/search.d.ts +2 -2
- package/dist/types/tools/write.d.ts +0 -2
- package/dist/types/tools/yield.d.ts +8 -0
- package/dist/types/tui/code-cell.d.ts +0 -2
- package/dist/types/tui/hyperlink.d.ts +5 -7
- package/dist/types/tui/output-block.d.ts +0 -18
- package/package.json +9 -9
- package/src/cli/args.ts +3 -1
- package/src/cli/dry-balance-cli.ts +2 -4
- package/src/cli/gallery-cli.ts +4 -0
- package/src/cli/gallery-fixtures/codeintel.ts +0 -1
- package/src/cli/gallery-fixtures/fs.ts +68 -1
- package/src/cli/gallery-fixtures/types.ts +8 -1
- package/src/cli/startup-cwd.ts +68 -0
- package/src/commands/launch.ts +3 -0
- package/src/commit/agentic/agent.ts +1 -0
- package/src/commit/model-selection.ts +3 -2
- package/src/config/model-provider-priority.ts +55 -0
- package/src/config/model-registry.ts +4 -22
- package/src/config/model-resolver.ts +39 -7
- package/src/config/settings.ts +86 -41
- package/src/debug/index.ts +8 -0
- package/src/debug/raw-sse-buffer.ts +7 -4
- package/src/debug/report-bundle.ts +9 -0
- package/src/edit/file-snapshot-store.ts +33 -1
- package/src/edit/hashline/diff.ts +86 -0
- package/src/edit/hashline/execute.ts +14 -1
- package/src/edit/hashline/filesystem.ts +2 -1
- package/src/edit/index.ts +31 -17
- package/src/edit/renderer.ts +116 -31
- package/src/eval/__tests__/llm-bridge.test.ts +20 -0
- package/src/eval/js/context-manager.ts +32 -15
- package/src/eval/js/shared/prelude.txt +26 -10
- package/src/eval/llm-bridge.ts +14 -3
- package/src/eval/py/__tests__/prelude.test.ts +19 -0
- package/src/eval/py/executor.ts +23 -11
- package/src/eval/py/prelude.py +1 -1
- package/src/extensibility/extensions/types.ts +10 -1
- package/src/internal-urls/docs-index.generated.ts +7 -7
- package/src/lsp/client.ts +23 -11
- package/src/lsp/config.ts +11 -1
- package/src/lsp/index.ts +189 -61
- package/src/main.ts +144 -78
- package/src/mcp/tool-bridge.ts +2 -0
- package/src/memories/index.ts +2 -2
- package/src/modes/components/assistant-message.ts +3 -15
- package/src/modes/components/custom-editor.ts +143 -111
- package/src/modes/components/late-diagnostics-message.ts +60 -0
- package/src/modes/components/model-selector.ts +59 -13
- package/src/modes/components/oauth-selector.ts +33 -7
- package/src/modes/components/plan-review-overlay.ts +26 -5
- package/src/modes/components/read-tool-group.ts +415 -35
- package/src/modes/components/session-selector.ts +89 -35
- package/src/modes/components/status-line.ts +19 -4
- package/src/modes/components/tips.txt +1 -1
- package/src/modes/components/tool-execution.ts +7 -49
- package/src/modes/components/transcript-container.ts +108 -32
- package/src/modes/components/user-message.ts +1 -1
- package/src/modes/controllers/event-controller.ts +32 -1
- package/src/modes/controllers/input-controller.ts +56 -9
- package/src/modes/interactive-mode.ts +107 -20
- package/src/modes/magic-keywords.ts +1 -1
- package/src/modes/markdown-prose.ts +1 -1
- package/src/modes/theme/shimmer.ts +20 -9
- package/src/modes/types.ts +7 -0
- package/src/modes/utils/ui-helpers.ts +26 -5
- package/src/modes/workflow.ts +10 -10
- package/src/prompts/system/manual-continue.md +7 -0
- package/src/prompts/system/plan-mode-active.md +56 -72
- package/src/prompts/system/workflow-notice.md +1 -1
- package/src/prompts/tools/bash.md +9 -0
- package/src/prompts/tools/browser.md +1 -1
- package/src/prompts/tools/eval.md +5 -2
- package/src/prompts/tools/lsp-late-diagnostic.md +8 -0
- package/src/prompts/tools/read.md +2 -2
- package/src/sdk.ts +85 -10
- package/src/session/agent-session.ts +42 -15
- package/src/session/auth-storage.ts +2 -0
- package/src/session/messages.ts +21 -14
- package/src/session/session-manager.ts +98 -25
- package/src/session/yield-queue.ts +20 -2
- package/src/task/executor.ts +72 -36
- package/src/task/render.ts +3 -4
- package/src/tiny/title-client.ts +6 -1
- package/src/tools/bash.ts +7 -7
- package/src/tools/browser/tab-supervisor.ts +13 -1
- package/src/tools/browser/tab-worker.ts +33 -4
- package/src/tools/eval-render.ts +4 -23
- package/src/tools/eval.ts +13 -2
- package/src/tools/find.ts +148 -99
- package/src/tools/gh-cache-invalidation.ts +200 -0
- package/src/tools/github-cache.ts +25 -0
- package/src/tools/index.ts +32 -0
- package/src/tools/inspect-image.ts +2 -2
- package/src/tools/path-utils.ts +47 -24
- package/src/tools/plan-mode-guard.ts +52 -7
- package/src/tools/read.ts +41 -20
- package/src/tools/render-utils.ts +3 -1
- package/src/tools/renderers.ts +0 -15
- package/src/tools/search.ts +38 -3
- package/src/tools/ssh.ts +0 -1
- package/src/tools/todo.ts +1 -0
- package/src/tools/write.ts +5 -14
- package/src/tools/yield.ts +10 -1
- package/src/tui/code-cell.ts +1 -6
- package/src/tui/hyperlink.ts +13 -23
- package/src/tui/output-block.ts +2 -97
- package/src/utils/commit-message-generator.ts +2 -2
- package/src/utils/enhanced-paste.ts +30 -2
- package/src/web/search/providers/codex.ts +37 -8
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,118 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [15.10.3] - 2026-06-08
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added clickable file path hyperlinks to read tool outputs (read-call rows, grouped summaries, and inline previews) using resolved or absolute file targets with selector-based line anchors for quick navigation
|
|
10
|
+
- Added a resolved-span echo to `replace block`/`delete block` edits: a successful block op now prints `replace block N → resolved lines A-B (K lines)` between the section header and the diff preview, so the model can confirm tree-sitter matched the construct it intended (e.g. catch a decorator left outside the block) instead of inferring the span from the diff after the fact.
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- Changed the `find` tool to process each explicit multi-path target separately before merging results so searches stay scoped to the requested paths
|
|
15
|
+
- Changed multi-path `find` handling so invalid extra targets no longer fail the whole query and now return matches from valid targets only
|
|
16
|
+
- Changed background-job completion and late LSP diagnostic delivery to inject at the next agent step boundary (mid-run), via the new non-interrupting "aside" channel, instead of only when the agent reaches a yield/follow-up point. The model now sees these notifications between its own requests without the turn having to end first, and in-flight tools are never interrupted; `job`-poll acknowledgement still suppresses results the agent already saw.
|
|
17
|
+
- Changed late LSP diagnostics after edit or write to surface in the chat transcript as `Late diagnostics` entries rendered through the same grouped tree renderer the `edit`/`write` tools use (per-file nodes, severity icons, `:line:col` locations), and to honor the global tool-output expand toggle (collapsed entries cap at 5 diagnostics with a `… N more` hint)
|
|
18
|
+
- Changed delayed diagnostics delivery to batch late results in one message per flush instead of a raw hidden custom payload
|
|
19
|
+
- Changed hidden custom messages and file-mention context to reach providers as `developer` messages instead of user-authored turns, so system reminders no longer pollute compacted user history.
|
|
20
|
+
- Rewrote the plan-mode active prompt (`prompts/system/plan-mode-active.md`) from scratch to stop producing shallow plans. Reframed the artifact as an **execution spec** a fresh agent runs after the planning conversation is cleared/compacted (zero design decisions for the implementer) rather than a brevity-capped summary. Folded high-consensus requirements into the existing sections as inline, conditional rules — no new boilerplate sections: ordered Approach steps that keep the build/tests green after each step (sequencing); exact signatures/literals for new or load-bearing symbols (contracts); full callsite list + clean cutover for renames/signature-changes/removals; Verification that must exercise the new behavior (input → observable output) with run preconditions, not just build/typecheck; Assumptions restricted to user-overridable choices plus pre-decided fallbacks for load-bearing assumptions; a provenance rule (plan facts must come from a read this session; unverified claims flagged inline); and bans on conversation back-references and decision-free sections (Non-Goals/Alternatives/Risks/Future Work). Kept the decision-complete self-check and the brevity-vs-completeness tiebreak (completeness wins). Render contract (Handlebars vars/conditionals) unchanged; verified across all `planExists`/`reentry`/`iterative` branch combinations.
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- Fixed duplicate `find` matches in multi-target queries by deduplicating overlapping paths in merged results
|
|
25
|
+
- Fixed `find` partial updates to avoid repeated streamed rows while scans are still running
|
|
26
|
+
- Fixed stale late diagnostics from older edits being shown after a file was edited again
|
|
27
|
+
- Fixed read output paths so selector suffixes are preserved when corrected paths were returned without selectors
|
|
28
|
+
- Fixed `read` surfacing a misleading red "Operation aborted" on a plain-file or directory read when a turn was interrupted mid-read. Those reads are deterministic and fast, so `execute` now runs them to completion instead of cancelling them; slower/non-deterministic reads (archive, sqlite, document, image, summary, conflict scan, URL) stay cancellable.
|
|
29
|
+
- Fixed edit tool headers to hide first-change line suffixes, middle-elide long paths only when the header width needs it, show compact change stats, and target encoded `file://` hyperlinks.
|
|
30
|
+
- Fixed Esc interrupts rendering a redundant `Interrupted by user` assistant transcript line while preserving the interrupt reason for tool-result placeholders and continuation logic.
|
|
31
|
+
- LSP writethrough no longer burns the full diagnostics poll on every edit/write. `typescript-language-server` never echoes the document version in `publishDiagnostics` ([upstream #983](https://github.com/typescript-language-server/typescript-language-server/issues/983)), so the exact-version gate never passed; `waitForDiagnostics` now accepts an exact version match instantly and otherwise settles on the latest publish after a short quiescence window, dropping superseded in-flight diagnostics.
|
|
32
|
+
- LSP writethrough no longer blocks the whole edit/write on slow diagnostics: it now waits only a short inline window (~500ms) for a settled result, then hands the in-flight fetch to the deferred channel so a slow or cold language server (e.g. a large-project `tsserver`) delivers its diagnostics as a follow-up message instead of stalling the tool 3–5s on every edit. The background fetch also gets a longer budget so slow servers still surface late rather than being dropped.
|
|
33
|
+
- Fixed the `c`/`.` continue shortcut making the agent second-guess itself after an Esc interrupt. Continuing used to submit an *empty* user turn, which left the model with only the aborted-turn context — so it tended to restate the halted state and ask whether to proceed rather than just continuing. The shortcut now resumes with a hidden agent-authored `developer` directive ("keep going — don't stop to summarize or re-confirm the plan") instead of an empty turn. It still produces no visible transcript entry, same as before.
|
|
34
|
+
- Fixed native scrollback commit boundaries to be computed generically from finalized transcript blocks and observed append-only live growth, so tall final tool results and streaming previews keep their scrolled-off heads on ED3-risk terminals without per-tool append-only predicates; live blocks that re-layout remain deferred until finalization or the next checkpoint.
|
|
35
|
+
- Fixed read-group summaries for multi-path `read` results to use result-provided display targets so each resolved path is shown as its own row
|
|
36
|
+
- Fixed read-group range summaries to abbreviate long merged selectors with ellipsis to keep repeated-file range rows readable
|
|
37
|
+
- Fixed read-group TUI summaries so a single delimited `read` call renders as separate read rows, and repeated reads of the same file collapse under one file with full-file/range children.
|
|
38
|
+
- Fixed grouped `read` rows freezing on their pending "⏳ Read <path>" preview on ED3-risk terminals (ghostty/kitty/iTerm2/…) when a parallel sibling tool closed the read run and appended a block below the group before the read's result arrived. The read-group block now stays in the repaintable live region until its entries settle, so the late success result repaints instead of being stranded; a `seal()` escape hatch (turn end / transcript rebuild) still lets a never-delivered read freeze rather than pinning the live region.
|
|
39
|
+
- Fixed session search to return all sessions unchanged when the query is blank
|
|
40
|
+
- Fixed duplicate session suggestions by deduplicating history matches by session path when merging metadata and prompt-history results
|
|
41
|
+
- Fixed `/resume` search ranking so sessions whose prompts or metadata match the query now prefer prompt recency and recent literal matches instead of letting older earlier-title fuzzy matches outrank a just-used session.
|
|
42
|
+
- Fixed `omp --resume <id>` / `--fork <id>` crashing with `[Uncaught Exception]` when the id did not match a known session. `createSessionManager` now throws a dedicated `SessionResolutionError`, which `runRootCommand` catches to print `Error: Session "..." not found.` plus a hint to stderr and exit with code 1. The same path covers `--fork` combined with `--no-session` and the non-interactive cross-project / moved-cwd prompts that previously surfaced raw stack traces ([#2084](https://github.com/can1357/oh-my-pi/issues/2084)).
|
|
43
|
+
|
|
44
|
+
### Removed
|
|
45
|
+
|
|
46
|
+
- Removed the animated pending border ("shimmer") on running `bash`, `eval`, and `ssh` execution blocks. While pending, a block now shows a static accent border instead of sweeping a dark segment around its bottom edge; `display.shimmer` still governs the working-status line and `task` row animations.
|
|
47
|
+
- Removed the tool-level `nonAbortable` bypass so `write` and `edit` honor the active turn `AbortSignal`. `read` is abortable for everything that is slow or non-deterministic (URL/internal-URL reads, archive, sqlite, document conversion, image decode, structural summary, conflict scan, suffix glob); only the deterministic plain-file line/range reads and directory listings run to completion.
|
|
48
|
+
|
|
49
|
+
## [15.10.2] - 2026-06-08
|
|
50
|
+
|
|
51
|
+
### Added
|
|
52
|
+
|
|
53
|
+
- Added `raw-sse.txt` to debug report bundles, exporting recent raw provider SSE diagnostics when captured
|
|
54
|
+
- Added `/model` visibility for auto-selected role defaults: inferred `pi/smol`/`pi/slow`/designer choices now show as compact `[ROLE auto]` badges, while explicitly configured roles keep the existing solid badges and thinking labels.
|
|
55
|
+
- Added credential provenance to the `/login` and `/logout` provider picker: each authenticated provider now shows where its credential comes from — `(login)`, `(api key)`, `(env: VAR_NAME)`, `(config)`, `(--api-key)`, or `(custom provider)` — so a real OAuth login is distinguishable from an env var that merely aliases the provider (e.g. `COPILOT_GITHUB_TOKEN`). The origin is also matched by the picker's type-to-search filter.
|
|
56
|
+
|
|
57
|
+
### Changed
|
|
58
|
+
|
|
59
|
+
- Changed raw SSE debug export output to prepend dropped-record metadata so truncated sessions in debug bundles now report dropped record and character counts
|
|
60
|
+
- Changed settings reads to cache pre-split schema paths and resolved values, with coarse invalidation on source/cwd changes.
|
|
61
|
+
- Changed status-line rendering to cache merged effective settings until `updateSettings()` changes the configuration.
|
|
62
|
+
- Changed `CustomEditor` app shortcut dispatch to parse each input packet once and match against precomputed canonical key sets, preserving the existing shortcut precedence while avoiding repeated key reparses.
|
|
63
|
+
- Changed `lsp references` to retry only when no references or only the queried declaration are returned, using two fixed 250ms retries for project-aware servers
|
|
64
|
+
- Changed `read` handling of `https://github.com/<owner>/<repo>:raw` to use raw page rendering only, removing the GitHub API README fallback
|
|
65
|
+
- Changed model resolution to apply provider-priority ordering when selecting models for roles and ambiguous patterns, using `modelProviderOrder` settings and built-in provider priority so first-party providers are preferred over relays in tie cases
|
|
66
|
+
- Changed model canonical variant selection to use the same provider-priority ordering instead of candidate order when deduplicating equivalent upstream models
|
|
67
|
+
- Changed the working-message shimmer to sweep at a fixed velocity (cells/second) instead of a fixed sweep duration divided by the message length. The band now advances ≤1 cell per 30fps redraw frame and stays equally smooth on short and long messages — previously a longer message swept proportionally faster and stepped visibly because it outran the redraw cadence. Sweep/round-trip duration now scales with length. Additionally, when `display.shimmer = disabled` the working line is static, so the loader no longer schedules 30fps redraws for it and falls back to the spinner-only ~12.5fps cadence.
|
|
68
|
+
- Changed the eval fan-out trigger keyword from `workflow`/`workflows` to `workflowz`.
|
|
69
|
+
|
|
70
|
+
### Fixed
|
|
71
|
+
|
|
72
|
+
- Fixed working-message loader session accents so spinner/message color math is cached per session name, session-accent setting, and theme luminance while still updating immediately on renames, setting toggles, and theme changes.
|
|
73
|
+
- Fixed startup model fallback selection so sessions now prefer each provider’s configured default model before choosing the first available authenticated model
|
|
74
|
+
- Fixed implicit model selection path for tools and sessions by honoring persisted model-provider order when no explicit pattern is provided
|
|
75
|
+
- Fixed the working spinner appearing to ignore Esc for 2-3 seconds when an interrupt lands mid-tool. Esc fires the abort synchronously, but the agent loop only stops the loader at `agent_end`, which it cannot reach until every in-flight tool settles in `executeToolCalls`' `await Promise.allSettled(...)` — and process/subagent/kernel-owning tools tear down gracefully (SIGTERM, 2-3s grace, SIGKILL), so the loader kept showing the unchanged "Working…/<intent>" line and read as a dropped keypress. The loader now switches to "Interrupting…" the instant Esc requests the abort and freezes intent-driven label updates until the turn unwinds (`EventController.notifyInterrupting`), so the interrupt is acknowledged immediately even while teardown completes.
|
|
76
|
+
- Fixed a flaky JS eval worker startup that intermittently failed unrelated CI runs. The worker-ready wait reused Bun's 5s default per-test timeout as its floor, so a slow cold-start under `--isolate` + high concurrency was aborted mid-init; terminating a still-initializing Bun worker is the documented SIGILL/SIGTRAP crash trigger, which took down the whole test file. Worker init now floors at a fixed 15s infrastructure budget (independent of, and still dominated by, a larger per-cell `timeout`), and the JS eval test suites set a 20s file-local timeout so cold starts complete instead of being torn down.
|
|
77
|
+
- Fixed reviewer-style subagent yields crashing the calling eval cell when a caller-supplied output schema declares `additionalProperties: false` without a `findings` property. `normalizeCompleteData` now consults the active validator before splicing collected `report_finding` entries onto the yielded payload, so injection is suppressed when the schema would reject it — keeping the executor's post-mortem validation in lockstep with the in-tool `yield` validation that already accepted the same raw payload ([#2070](https://github.com/can1357/oh-my-pi/issues/2070))
|
|
78
|
+
- Fixed Anthropic empty `toolUse` stops without tool calls corrupting session history by retrying them and removing orphaned turns even at the retry cap.
|
|
79
|
+
- Fixed MCP tools hanging in non-yolo modes by declaring `approval = "write"` on `MCPTool` and `DeferredMCPTool`, and propagating the `approval` property through `customToolToDefinition()` in `sdk.ts`
|
|
80
|
+
- Fixed session resumption after a working directory is moved/renamed (e.g. `git worktree move`): `--continue` now re-roots the terminal's last session into the new directory when its original directory no longer exists, explicit `--resume <id> --session-dir <dir>` local matches re-root instead of reopening with the stale cwd, and cross-project `--resume <id>` offers to move (re-root) the session rather than only forking a duplicate copy when the source directory is gone
|
|
81
|
+
- Fixed Kitty OSC 5522 paste rejecting plain text as "no supported text or image data": the listing parser now decodes the `mime="."` DATA payload (whitespace-separated MIME list) Kitty actually sends, in addition to the per-type DATA packets described by the ancillary 5522-mode spec, and per-type spec listings now request the selected payload with `type=read:mime=...` instead of Kitty's dot-payload request shape ([#2051](https://github.com/can1357/oh-my-pi/issues/2051))
|
|
82
|
+
- Fixed follow-up shortcut submission of builtin slash commands so `/goal set ...` applies goal mode instead of queueing as plain text.
|
|
83
|
+
- Fixed Ctrl+Z crashing the agent on Windows with `TypeError: Unknown signal: SIGTSTP`. `InputController.handleCtrlZ` called `process.kill(0, "SIGTSTP")` unconditionally, but `SIGTSTP` is POSIX job-control and Bun/Node on Windows rejects the signal name from the JS side; the throw propagated out of the TUI input dispatcher as an uncaught exception. The handler now no-ops with a "Suspend (Ctrl+Z) is not supported on this platform" status on Windows, and on POSIX wraps `process.kill` in a try/catch that detaches the registered SIGCONT resume hook and re-`start()`s the TUI on failure so a rejected signal can never leave the UI stranded with a leaked listener ([#2036](https://github.com/can1357/oh-my-pi/issues/2036)).
|
|
84
|
+
- Fixed a relative `--cwd` target (e.g. `omp --cwd repo` launched from `/tmp`) leaking the raw relative string into the session config. `applyStartupCwd` chdired into the resolved directory via `setProjectDir` but left `parsed.cwd` as `"repo"`, so `buildSessionOptions` (which prefers `parsed.cwd` over `getProjectDir()`) handed downstream settings/discovery/session creation a value that re-resolved against the new process cwd (`/tmp/repo/repo`) or persisted a relative session cwd. `parsed.cwd` is now re-synced to the resolved absolute project dir after the chdir.
|
|
85
|
+
- Fixed the `--cwd` launch flag so it is parsed and can override the startup directory instead of always falling back to the current process directory or home auto-switch target.
|
|
86
|
+
- Fixed session auto-retry for generic `upstream_error: Upstream request failed` gateway failures.
|
|
87
|
+
- Stripped read-output line-number prefixes (`N:`) from auto-piped bare body rows in the hashline edit parser, so pasting `3:text` without a `+` prefix no longer injects `3:` as literal content. Uses single-pass stripping to avoid corrupting content whose own text starts with `digits:` ([#1492](https://github.com/can1357/oh-my-pi/issues/1492)).
|
|
88
|
+
- Fixed `eval` `llm()` returning HTTP 400 "Instructions are required" when called without a `system` prompt against providers (notably `openai-codex`) whose Responses transformer drops the `instructions` field on an empty system prompt. `runEvalLlm` now sends a minimal default system prompt ("You are a helpful assistant.") when no `system` is supplied, so `llm("question")` works against every provider; an explicit `system=` still wins.
|
|
89
|
+
- Fixed the Python `read(path, offset, limit)` prelude helper rejecting documented positional arguments with `TypeError: read() takes 1 positional argument but 3 were given`. The signature was keyword-only (`def read(path, *, offset=1, limit=None)`) while the eval helper table advertises positional optional args; agents that called `read("file.py", 10, 20)` literally crashed. The `*` is removed so both `read("f", 10, 20)` and `read("f", offset=10, limit=20)` work.
|
|
90
|
+
- Fixed `eval` reset cells failing with `"Python kernel reset already in progress"` / `"JS context reset already in progress"` when two cells happened to overlap on the same session (e.g. a rapid resubmit, or a parallel-cell race). The executor now coalesces concurrent resets — additional callers wait for the in-flight reset to finish and then run on the freshly restarted kernel — instead of throwing a user-visible error for what is purely an internal coordination state.
|
|
91
|
+
- Fixed the `eval` tool description advertising the `agent()` helper unconditionally even in subagent sessions whose parent forbids spawning. When `getSessionSpawns()` returns `""`, the prelude doc now omits `agent()` so the model is not promised a helper that can only ever throw "Cannot spawn 'task'. Allowed: none (spawns disabled for this agent)".
|
|
92
|
+
- Fixed plan mode rejecting `local://` plan-artifact edits when addressed via the absolute path the `read` tool echoes back in the `[path#tag]` header. `enforcePlanModeWrite` previously only matched the literal `local://` scheme; it now also accepts any absolute path whose realpath resolves inside the session's local sandbox root, so the absolute spelling and the `local://` spelling are interchangeable in plan mode.
|
|
93
|
+
- Fixed snapshot tags freshly minted by `read` being rejected as stale by a subsequent `edit` against the same file when the two sides reached the file via symlink-equivalent spellings (e.g. macOS `/tmp/…` vs `/private/tmp/…`, or `read local://foo.md` recording under the file's `fs.realpath` while `edit local://foo.md` looked up under the raw `path.resolve(localRoot, …)` form). The file snapshot store now keys every record/lookup through a `realpath`-canonicalized key (`canonicalSnapshotKey`), fusing all spellings of the same on-disk file onto one snapshot entry.
|
|
94
|
+
- Fixed `read` of a `github.com/<owner>/<repo>` URL with `:raw` returning the full JS-rendered HTML shell. Repo roots now resolve to the decoded README via the GitHub API (`/repos/<owner>/<repo>/readme`), falling back to the raw HTML only when the API returns no usable payload.
|
|
95
|
+
- Fixed `issue://` and `pr://` reads returning stale OPEN/CLOSED state after a successful `gh issue close` / `gh pr merge` (or any other state-changing `gh` invocation) in the same session. The `bash` tool now invalidates the matching `github-cache` rows before executing any `gh (issue|pr) <close|reopen|merge|delete|edit|comment|lock|unlock|pin|unpin|transfer|develop|ready|review>` command.
|
|
96
|
+
- Fixed line-range selectors on PDF/DOCX/PPTX/XLSX/RTF/EPUB reads being ignored. The markit-converted markdown body now flows through the same in-memory range slicer used for plain text, so `file.pdf:50-100` and `file.pdf:5-16,40-80` slice the converted body instead of returning the whole document.
|
|
97
|
+
- Fixed the `read` selector cheatsheet incorrectly promising "exactly one line" for `:N+1` while the implementation pads single-line reads with ≤1 leading and ≤3 trailing context; documented that multi-range selectors do not pad, giving callers a way to request exact bounds.
|
|
98
|
+
- Documented the `bash.autoBackground.enabled` behavior in the `bash` tool prompt so the `Background job <id> started: …` notice for foreground commands that exceed `autoBackgroundThresholdSeconds` no longer reads as a tool malfunction.
|
|
99
|
+
- Fixed `task` subagents whose in-tool `yield` validator had already accepted a payload after exhausting `MAX_SCHEMA_RETRIES` being rejected a second time by the post-mortem executor validator. The override now propagates through the yield tool's `details.schemaOverridden` flag, and the executor surfaces a `SUBAGENT_WARNING_SCHEMA_OVERRIDDEN` stderr line instead of re-emitting `schema_violation` for data the subagent already had to ship. Finalize also degrades to no validation (matching the yield tool's `looseRecordSchema` fallback) when the caller-supplied output schema fails to normalize.
|
|
100
|
+
- Fixed the `web_search` `codex` provider returning `(see attached image)` / `[Attached image]` / `See image above` and similar non-informational image-placeholder strings as the answer. Detection broadened to a small regex set, and when annotations did produce sources we now drop the placeholder prose from `answer` (returning sources only); when neither annotations nor a real answer materialize, we throw 502 to advance the provider chain.
|
|
101
|
+
- Fixed `search`, `find`, `ast_grep`, and `ast_edit` rejecting bracket-containing file paths (Next.js routes like `apps/[id]/page.tsx`) as glob patterns when the literal path exists on disk. `parseSearchPathPreferringLiteral` now prefers the literal interpretation for paths that resolve on disk and only falls back to glob expansion when the literal does not exist.
|
|
102
|
+
- Fixed `search` with an external `http(s)/ftp/ws/file://` URL in `paths` surfacing a misleading "Path not found" error. The tool now rejects external URLs with a clear "use `read` for URLs" message.
|
|
103
|
+
- Fixed `search` rejecting `skip: null` at the schema layer; `null` now normalizes to `0` alongside the omitted case, matching how callers serialize default pagination state.
|
|
104
|
+
- Fixed `search` returning zero matches with no explanation when explicit file targets exceed the native grep cap (4 MB). The tool now surfaces a `Skipped oversized files (>4MB grep limit; …)` notice listing the truncated paths.
|
|
105
|
+
- Fixed the archive-extraction error message in `search` recommending `grep` — which the system prompt forbids — instead of pointing to `read <archive>:<member>`.
|
|
106
|
+
- Fixed `browser` `tab.open(name, { viewport })` on an existing tab not applying the new viewport: `acquireTab`'s reuse path now resizes the page in addition to navigating.
|
|
107
|
+
- Fixed `browser` tab metadata leaking `user:pass@` basic-auth credentials in the URL surfaced to transcripts and observe snapshots; URLs are now redacted via `redactUrlCredentials()`.
|
|
108
|
+
- Fixed `browser` `tab.extract(format)` returning a `ReadableResult | null` shape that the tool prompt advertised as plain content. The helper now returns the markdown/text string directly (or throws a clear `ToolError` when extraction is empty), and the prompt matches.
|
|
109
|
+
- Fixed `lsp` requests timing out at a hard-coded 30 s ceiling when the caller supplied an explicit abort signal (e.g. the tool wall-clock). The signal is now the deadline; the 30 s default still applies when neither a signal nor an explicit `timeoutMs` is provided.
|
|
110
|
+
- Fixed `lsp status` reporting servers as `Active language servers: …` when the binary resolves on PATH but never spawns (rustup wrapper, missing toolchain component, etc.). Status now labels each entry as `(ready)` or `(configured, not started)`.
|
|
111
|
+
- Fixed `lsp rename_file` fanning `willRenameFiles` requests across every configured server (including ones with no jurisdiction over the file type) and burning the wall-clock timeout. The action now pre-filters configured LSPs to those whose `fileTypes` cover the source or destination path, falling back to a plain filesystem rename when no server claims the type.
|
|
112
|
+
- Fixed `lsp references` returning only the queried declaration (or only in-file results) on project-aware servers that had not finished indexing. The retry budget is raised from 2 → 3 with 250 / 500 / 1000 ms backoff, and the retry trigger now also fires when all results live in the queried file.
|
|
113
|
+
- Fixed `lsp config` accepting `fileTypes` entries with or without a leading dot inconsistently across actions; both `.ts` and `ts` are now normalized so a missing-dot entry no longer silently excludes a server from extension-based routing.
|
|
114
|
+
- Fixed `lsp request` error path swallowing the params that were sent, making shape/coercion bugs on raw LSP calls impossible to diagnose in one round-trip; the error now echoes a truncated copy of the request params.
|
|
115
|
+
- Fixed `find` with a single-star segment like `dir/*` recursing into subdirectories and returning nested matches. `parseFindPattern` already prepends `**/` for top-level globs (`*.ts` → `**/*.ts`), so anything reaching native without `**/` was deliberately scoped by the user; `recursive: false` is now passed to `natives.glob` to honor that scope.
|
|
116
|
+
|
|
5
117
|
## [15.10.1] - 2026-06-07
|
|
6
118
|
|
|
7
119
|
### Added
|
|
@@ -9570,4 +9682,4 @@ Initial public release.
|
|
|
9570
9682
|
- Git branch display in footer
|
|
9571
9683
|
- Message queueing during streaming responses
|
|
9572
9684
|
- OAuth integration for Gmail and Google Calendar access
|
|
9573
|
-
- HTML export with syntax highlighting and collapsible sections
|
|
9685
|
+
- HTML export with syntax highlighting and collapsible sections
|
|
@@ -14,14 +14,20 @@ export interface GalleryResult {
|
|
|
14
14
|
details?: unknown;
|
|
15
15
|
isError?: boolean;
|
|
16
16
|
}
|
|
17
|
+
export type GalleryFixtureState = "streaming" | "progress" | "success" | "error";
|
|
17
18
|
export interface GalleryFixture {
|
|
18
19
|
/** Display label for the tool header (defaults to the tool name). */
|
|
19
20
|
label?: string;
|
|
20
21
|
/** Edit mode for edit-like tools so the streaming preview dispatches correctly. */
|
|
21
22
|
editMode?: EditMode;
|
|
23
|
+
/**
|
|
24
|
+
* Custom gallery-only renderer for fixtures that are not one ToolExecutionComponent
|
|
25
|
+
* (for example the read-group transcript component).
|
|
26
|
+
*/
|
|
27
|
+
renderState?: (state: GalleryFixtureState, width: number, expanded: boolean) => string[] | Promise<string[]>;
|
|
22
28
|
/**
|
|
23
29
|
* Set for tools whose real `AgentTool` attaches `renderCall`/`renderResult`
|
|
24
|
-
* directly on the instance (e.g. `
|
|
30
|
+
* directly on the instance (e.g. `task`). The harness then attaches
|
|
25
31
|
* the registry renderer onto the fake tool so the component routes through
|
|
26
32
|
* the custom-tool branch — the same path production takes — instead of the
|
|
27
33
|
* built-in registry branch. The two branches can diverge, so exercising the
|
|
@@ -40,6 +40,9 @@ export default class Index extends Command {
|
|
|
40
40
|
"allow-home": import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"boolean"> & {
|
|
41
41
|
description: string;
|
|
42
42
|
};
|
|
43
|
+
cwd: import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"string"> & {
|
|
44
|
+
description: string;
|
|
45
|
+
};
|
|
43
46
|
mode: import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"string"> & {
|
|
44
47
|
description: string;
|
|
45
48
|
options: string[];
|
|
@@ -109,11 +109,11 @@ export declare const KEYBINDINGS: {
|
|
|
109
109
|
readonly description: "Delete character forward";
|
|
110
110
|
};
|
|
111
111
|
readonly "tui.editor.deleteWordBackward": {
|
|
112
|
-
readonly defaultKeys: ["ctrl+w", "alt+backspace", "ctrl+backspace"];
|
|
112
|
+
readonly defaultKeys: ["ctrl+w", "alt+backspace", "ctrl+backspace", "super+alt+backspace"];
|
|
113
113
|
readonly description: "Delete word backward";
|
|
114
114
|
};
|
|
115
115
|
readonly "tui.editor.deleteWordForward": {
|
|
116
|
-
readonly defaultKeys: ["alt+delete", "alt+d"];
|
|
116
|
+
readonly defaultKeys: ["alt+delete", "alt+d", "super+alt+delete", "super+alt+d"];
|
|
117
117
|
readonly description: "Delete word forward";
|
|
118
118
|
};
|
|
119
119
|
readonly "tui.editor.deleteToLineStart": {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function buildModelProviderPriorityRank(configuredProviderOrder?: readonly string[]): Map<string, number>;
|
|
@@ -30,7 +30,9 @@ export declare function resolveProviderModelReference(provider: string, modelId:
|
|
|
30
30
|
export interface ModelMatchPreferences {
|
|
31
31
|
/** Most-recently-used model keys (provider/modelId) to prefer when ambiguous. */
|
|
32
32
|
usageOrder?: string[];
|
|
33
|
-
/**
|
|
33
|
+
/** Provider precedence used for ambiguous unqualified model patterns. */
|
|
34
|
+
providerOrder?: readonly string[];
|
|
35
|
+
/** Providers to deprioritize when no recent usage or provider priority is available. */
|
|
34
36
|
deprioritizeProviders?: string[];
|
|
35
37
|
}
|
|
36
38
|
export type CanonicalModelRegistry = Partial<Pick<ModelRegistry, "resolveCanonicalModel" | "getCanonicalVariants" | "getCanonicalId">>;
|
|
@@ -38,6 +40,7 @@ export type ModelLookupRegistry = Pick<ModelRegistry, "getAvailable"> & Partial<
|
|
|
38
40
|
type CliModelRegistry = Pick<ModelRegistry, "getAll"> & Partial<CanonicalModelRegistry>;
|
|
39
41
|
type InitialModelRegistry = Pick<ModelRegistry, "getAvailable" | "find">;
|
|
40
42
|
type RestorableModelRegistry = Pick<ModelRegistry, "getAvailable" | "find" | "getApiKey">;
|
|
43
|
+
export declare function getModelMatchPreferences(settings?: Partial<Pick<Settings, "get" | "getStorage">>): ModelMatchPreferences;
|
|
41
44
|
/**
|
|
42
45
|
* Find an exact explicit provider/model match.
|
|
43
46
|
* Bare model ids are handled separately so canonical ids can coalesce variants.
|
|
@@ -131,7 +131,12 @@ export declare class Settings {
|
|
|
131
131
|
* Returns an unsubscribe function. Multiple sessions (main + subagents)
|
|
132
132
|
* can register independently without overwriting each other.
|
|
133
133
|
*/
|
|
134
|
-
export declare
|
|
134
|
+
export declare const onAppendOnlyModeChanged: (cb: (value: string) => void) => () => void;
|
|
135
|
+
/**
|
|
136
|
+
* Subscribe to session-accent setting changes.
|
|
137
|
+
* Returns an unsubscribe function. Callers should re-read settings in the callback.
|
|
138
|
+
*/
|
|
139
|
+
export declare const onStatusLineSessionAccentChanged: (cb: () => void) => () => void;
|
|
135
140
|
/**
|
|
136
141
|
* Subscribe to changes in the Hindsight bank-scoping settings. Lets the
|
|
137
142
|
* Hindsight backend rebuild the active `HindsightSessionState` when the
|
|
@@ -142,7 +147,7 @@ export declare function onAppendOnlyModeChanged(cb: (value: string) => void): ()
|
|
|
142
147
|
* Returns an unsubscribe function. The callback receives no arguments — the
|
|
143
148
|
* caller is expected to re-read the relevant settings via `Settings.get`.
|
|
144
149
|
*/
|
|
145
|
-
export declare
|
|
150
|
+
export declare const onHindsightScopeChanged: (cb: () => void) => () => void;
|
|
146
151
|
export declare function isSettingsInitialized(): boolean;
|
|
147
152
|
/**
|
|
148
153
|
* Reset the global singleton for testing.
|
|
@@ -11,6 +11,8 @@ export interface ReportBundleOptions {
|
|
|
11
11
|
heapSnapshot?: HeapSnapshot;
|
|
12
12
|
/** Work profile (for work scheduling reports) */
|
|
13
13
|
workProfile?: WorkProfile;
|
|
14
|
+
/** Raw provider SSE diagnostics captured by the session buffer */
|
|
15
|
+
rawSseText?: string;
|
|
14
16
|
}
|
|
15
17
|
export interface ReportBundleResult {
|
|
16
18
|
path: string;
|
|
@@ -33,6 +35,7 @@ export interface DebugLogSource {
|
|
|
33
35
|
* - env.json: Sanitized environment variables
|
|
34
36
|
* - config.json: Resolved settings
|
|
35
37
|
* - profile.cpuprofile: CPU profile (performance report only)
|
|
38
|
+
* - raw-sse.txt: Recent raw provider SSE diagnostics (when captured)
|
|
36
39
|
* - profile.md: Markdown CPU profile (performance report only)
|
|
37
40
|
* - heap.heapsnapshot: Heap snapshot (memory report only)
|
|
38
41
|
* - work.folded: Work profile folded stacks (work report only)
|
|
@@ -1,13 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Session-bound file snapshot store.
|
|
3
|
-
*
|
|
4
|
-
* Used by `read` and `search` to record exactly what the model saw, and by
|
|
5
|
-
* the hashline patcher to verify or recover from stale section tags (file
|
|
6
|
-
* changed externally between read and edit, or a prior in-session edit
|
|
7
|
-
* advanced the tag). The store is the {@link InMemorySnapshotStore}
|
|
8
|
-
* from `@oh-my-pi/hashline`; the only coding-agent-specific concern here
|
|
9
|
-
* is wiring it onto the per-session owner object.
|
|
10
|
-
*/
|
|
11
1
|
import { InMemorySnapshotStore } from "@oh-my-pi/hashline";
|
|
12
2
|
/**
|
|
13
3
|
* Upper bound on the file size we snapshot. A section tag is a content hash of
|
|
@@ -25,6 +15,24 @@ interface FileSnapshotStoreOwner {
|
|
|
25
15
|
* the session itself.
|
|
26
16
|
*/
|
|
27
17
|
export declare function getFileSnapshotStore(session: FileSnapshotStoreOwner): InMemorySnapshotStore;
|
|
18
|
+
/**
|
|
19
|
+
* Canonicalize an absolute path into the stable key the snapshot store uses.
|
|
20
|
+
*
|
|
21
|
+
* Different code paths reach the snapshot store via different path forms:
|
|
22
|
+
* `read local://foo.md` records under the file's `fs.realpath` (the local
|
|
23
|
+
* protocol handler resolves symlinks); a subsequent `edit` may address the
|
|
24
|
+
* same artifact via `local://foo.md`, whose resolver does NOT realpath, or
|
|
25
|
+
* via the absolute path returned in the `[path#tag]` header. macOS adds the
|
|
26
|
+
* same hazard at the working-tree level (`/tmp/...` vs `/private/tmp/...`).
|
|
27
|
+
* Collapsing every key through `realpath` makes those forms fuse onto one
|
|
28
|
+
* snapshot entry, so a freshly-minted tag is never rejected as stale just
|
|
29
|
+
* because the lookup spelled the same file differently.
|
|
30
|
+
*
|
|
31
|
+
* Non-existent paths (new-file writes) fall back to a realpath of the parent
|
|
32
|
+
* directory + basename, then to the input. This keeps creates and updates on
|
|
33
|
+
* the same canonical key.
|
|
34
|
+
*/
|
|
35
|
+
export declare function canonicalSnapshotKey(absolutePath: string): string;
|
|
28
36
|
/**
|
|
29
37
|
* Read the full text of `absolutePath` (within {@link SNAPSHOT_MAX_BYTES}),
|
|
30
38
|
* record it as a version snapshot, and return its content-hash tag. Returns
|
|
@@ -28,7 +28,6 @@ export declare class EditTool implements AgentTool<TInput> {
|
|
|
28
28
|
readonly name = "edit";
|
|
29
29
|
readonly label = "Edit";
|
|
30
30
|
readonly loadMode = "essential";
|
|
31
|
-
readonly nonAbortable = true;
|
|
32
31
|
readonly concurrency = "exclusive";
|
|
33
32
|
readonly strict = true;
|
|
34
33
|
constructor(session: ToolSession);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* - Register commands, keyboard shortcuts, and CLI flags
|
|
8
8
|
* - Interact with the user via UI primitives
|
|
9
9
|
*/
|
|
10
|
-
import type { AgentMessage, AgentToolResult, AgentToolUpdateCallback, ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
|
10
|
+
import type { AgentMessage, AgentToolResult, AgentToolUpdateCallback, ThinkingLevel, ToolApproval } from "@oh-my-pi/pi-agent-core";
|
|
11
11
|
import type { CompactionResult } from "@oh-my-pi/pi-agent-core/compaction";
|
|
12
12
|
import type { Api, AssistantMessageEvent, AssistantMessageEventStream, Context, ImageContent, Model, ProviderResponseMetadata, SimpleStreamOptions, Static, TextContent, TSchema } from "@oh-my-pi/pi-ai";
|
|
13
13
|
import type { OAuthCredentials, OAuthLoginCallbacks } from "@oh-my-pi/pi-ai/utils/oauth/types";
|
|
@@ -270,6 +270,9 @@ export interface ToolDefinition<TParams extends TSchema = TSchema, TDetails = un
|
|
|
270
270
|
defaultInactive?: boolean;
|
|
271
271
|
/** If true, tool may stage deferred changes that require explicit resolve/discard. */
|
|
272
272
|
deferrable?: boolean;
|
|
273
|
+
/** Tool approval tier. Defaults to `"exec"` when omitted.
|
|
274
|
+
* `"read"`: read-only operations. `"write"`: mutations. `"exec"`: code execution. */
|
|
275
|
+
approval?: ToolApproval;
|
|
273
276
|
/** MCP server name for discovery/search metadata when this tool fronts an MCP server. */
|
|
274
277
|
mcpServerName?: string;
|
|
275
278
|
/** Original MCP tool name for discovery/search metadata. */
|
|
@@ -45,6 +45,16 @@ export declare function refreshFile(client: LspClient, filePath: string, signal?
|
|
|
45
45
|
export declare function shutdownClient(key: string): Promise<void>;
|
|
46
46
|
/**
|
|
47
47
|
* Send an LSP request and wait for response.
|
|
48
|
+
*
|
|
49
|
+
* Timeout policy:
|
|
50
|
+
* - If `timeoutMs` is explicitly provided, that value is used.
|
|
51
|
+
* - Else, if `signal` is provided, no internal timer is installed (the caller
|
|
52
|
+
* owns the deadline via the signal — typically a wall-clock `AbortSignal.timeout`
|
|
53
|
+
* from the LSP tool). Installing a second hard-coded 30s timer here used to
|
|
54
|
+
* cause "timed out after 30000ms" errors even when the caller had requested
|
|
55
|
+
* `timeout: 60`.
|
|
56
|
+
* - Else (no signal, no explicit timeout), fall back to `DEFAULT_REQUEST_TIMEOUT_MS`
|
|
57
|
+
* to avoid leaking pending requests forever.
|
|
48
58
|
*/
|
|
49
59
|
export declare function sendRequest(client: LspClient, method: string, params: unknown, signal?: AbortSignal, timeoutMs?: number): Promise<unknown>;
|
|
50
60
|
/**
|
|
@@ -3,7 +3,6 @@ import type { BunFile } from "bun";
|
|
|
3
3
|
import { type Theme } from "../modes/theme/theme";
|
|
4
4
|
import type { ToolSession } from "../tools";
|
|
5
5
|
import { type LspServerStatus } from "./client";
|
|
6
|
-
import { renderCall, renderResult } from "./render";
|
|
7
6
|
import { type LspParams, type LspToolDetails, lspSchema } from "./types";
|
|
8
7
|
export type { LspServerStatus } from "./client";
|
|
9
8
|
export type { LspToolDetails } from "./types";
|
|
@@ -129,10 +128,6 @@ export declare class LspTool implements AgentTool<typeof lspSchema, LspToolDetai
|
|
|
129
128
|
timeout: import("zod/v4").ZodOptional<import("zod/v4").ZodNumber>;
|
|
130
129
|
payload: import("zod/v4").ZodOptional<import("zod/v4").ZodString>;
|
|
131
130
|
}, import("zod/v4/core").$strip>;
|
|
132
|
-
readonly renderCall: typeof renderCall;
|
|
133
|
-
readonly renderResult: typeof renderResult;
|
|
134
|
-
readonly mergeCallAndResult = true;
|
|
135
|
-
readonly inline = true;
|
|
136
131
|
readonly strict = true;
|
|
137
132
|
constructor(session: ToolSession);
|
|
138
133
|
static createIf(session: ToolSession): LspTool | null;
|
package/dist/types/main.d.ts
CHANGED
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Main entry point for the coding agent CLI.
|
|
3
|
-
*
|
|
4
|
-
* This file handles CLI argument parsing and translates them into
|
|
5
|
-
* createAgentSession() options. The SDK does the heavy lifting.
|
|
6
|
-
*/
|
|
7
1
|
import type { Args } from "./cli/args";
|
|
8
2
|
import { ModelRegistry } from "./config/model-registry";
|
|
9
3
|
import { Settings } from "./config/settings";
|
|
@@ -41,10 +35,21 @@ export interface AcpSessionFactoryOptions {
|
|
|
41
35
|
* tool registry and shadow the client-supplied servers (issue #1234).
|
|
42
36
|
*/
|
|
43
37
|
export declare function createAcpSessionFactory(args: AcpSessionFactoryOptions): AcpSessionFactory;
|
|
44
|
-
type
|
|
45
|
-
type
|
|
38
|
+
type SessionPromptResult = "accepted" | "declined" | "unavailable";
|
|
39
|
+
type SessionPrompt = (session: SessionInfo) => Promise<SessionPromptResult>;
|
|
40
|
+
/**
|
|
41
|
+
* Friendly CLI failure raised by {@link createSessionManager} when the user's
|
|
42
|
+
* session-resolution flags (`--resume`/`--fork`/cross-project prompts) cannot
|
|
43
|
+
* be satisfied. {@link runRootCommand} catches it and prints a clean stderr
|
|
44
|
+
* message instead of letting it surface as `[Uncaught Exception]`
|
|
45
|
+
* (see issue #2084).
|
|
46
|
+
*/
|
|
47
|
+
export declare class SessionResolutionError extends Error {
|
|
48
|
+
readonly hint?: string;
|
|
49
|
+
constructor(message: string, hint?: string);
|
|
50
|
+
}
|
|
46
51
|
/** Resolves CLI session flags into an existing, forked, in-memory, or cancelled session manager. */
|
|
47
|
-
export declare function createSessionManager(parsed: Args, cwd: string, activeSettings?: Settings, askToForkSession?:
|
|
52
|
+
export declare function createSessionManager(parsed: Args, cwd: string, activeSettings?: Settings, askToForkSession?: SessionPrompt, askToMoveSession?: SessionPrompt): Promise<SessionManager | undefined>;
|
|
48
53
|
interface RunRootCommandDependencies {
|
|
49
54
|
createAgentSession?: typeof createAgentSession;
|
|
50
55
|
discoverAuthStorage?: typeof discoverAuthStorage;
|
|
@@ -53,6 +53,7 @@ export declare class MCPTool implements CustomTool<TSchema, MCPToolDetails> {
|
|
|
53
53
|
readonly mcpToolName: string;
|
|
54
54
|
/** Server name */
|
|
55
55
|
readonly mcpServerName: string;
|
|
56
|
+
readonly approval: "write";
|
|
56
57
|
/** Render completed MCP calls with the result header replacing the pending call header. */
|
|
57
58
|
readonly mergeCallAndResult = true;
|
|
58
59
|
/** Create MCPTool instances for all tools from an MCP server connection */
|
|
@@ -79,6 +80,7 @@ export declare class DeferredMCPTool implements CustomTool<TSchema, MCPToolDetai
|
|
|
79
80
|
readonly mcpToolName: string;
|
|
80
81
|
/** Server name */
|
|
81
82
|
readonly mcpServerName: string;
|
|
83
|
+
readonly approval: "write";
|
|
82
84
|
/** Render completed MCP calls with the result header replacing the pending call header. */
|
|
83
85
|
readonly mergeCallAndResult = true;
|
|
84
86
|
/** Create DeferredMCPTool instances for all tools from an MCP server */
|
|
@@ -19,15 +19,6 @@ export declare class AssistantMessageComponent extends Container {
|
|
|
19
19
|
*/
|
|
20
20
|
setErrorPinned(pinned: boolean): void;
|
|
21
21
|
isTranscriptBlockFinalized(): boolean;
|
|
22
|
-
/**
|
|
23
|
-
* Assistant text/thinking streams in append-only: earlier rendered rows never
|
|
24
|
-
* re-layout, new content only grows the block at the bottom. The transcript
|
|
25
|
-
* reports this so the renderer may commit scrolled-off head rows of a long
|
|
26
|
-
* streamed reply to native scrollback instead of dropping them (see
|
|
27
|
-
* `NativeScrollbackLiveRegion#getNativeScrollbackCommitSafeEnd`). Volatile
|
|
28
|
-
* blocks (tool previews that collapse) intentionally do not implement this.
|
|
29
|
-
*/
|
|
30
|
-
isTranscriptBlockAppendOnly(): boolean;
|
|
31
22
|
markTranscriptBlockFinalized(): void;
|
|
32
23
|
setToolResultImages(toolCallId: string, images: ImageContent[]): void;
|
|
33
24
|
setUsageInfo(usage: Usage): void;
|
|
@@ -8,7 +8,7 @@ export declare function extractBracketedImagePastePath(data: string): string | u
|
|
|
8
8
|
export declare class CustomEditor extends Editor {
|
|
9
9
|
#private;
|
|
10
10
|
imageLinks?: readonly (string | undefined)[];
|
|
11
|
-
/** Gradient-highlight the "ultrathink" / "orchestrate" / "
|
|
11
|
+
/** Gradient-highlight the "ultrathink" / "orchestrate" / "workflowz" keywords as the user types
|
|
12
12
|
* them, skipping any occurrence inside code spans, fenced blocks, or XML sections. Also make
|
|
13
13
|
* pasted image placeholders visually distinct and hyperlink them once their blob file exists. */
|
|
14
14
|
decorateText: (text: string) => string;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Container } from "@oh-my-pi/pi-tui";
|
|
2
|
+
/** One file's worth of late LSP diagnostics, as carried on the transcript message. */
|
|
3
|
+
export interface LateDiagnosticsFile {
|
|
4
|
+
path?: string;
|
|
5
|
+
summary?: string;
|
|
6
|
+
errored?: boolean;
|
|
7
|
+
messages?: string[];
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Renders late LSP diagnostics (arrived after edit/write returned) in the
|
|
11
|
+
* transcript, reusing the same tree renderer the edit/write tools use so the
|
|
12
|
+
* styling stays consistent. Supports the global tool-output expand toggle.
|
|
13
|
+
*/
|
|
14
|
+
export declare class LateDiagnosticsMessageComponent extends Container {
|
|
15
|
+
#private;
|
|
16
|
+
private readonly files;
|
|
17
|
+
constructor(files: LateDiagnosticsFile[]);
|
|
18
|
+
setExpanded(expanded: boolean): void;
|
|
19
|
+
invalidate(): void;
|
|
20
|
+
}
|
|
@@ -16,6 +16,12 @@ export declare class ReadToolGroupComponent extends Container implements ToolExe
|
|
|
16
16
|
constructor(options?: ReadToolGroupOptions);
|
|
17
17
|
isTranscriptBlockFinalized(): boolean;
|
|
18
18
|
finalize(): void;
|
|
19
|
+
/**
|
|
20
|
+
* Force the group terminal even if an entry never received its result (the
|
|
21
|
+
* turn aborted or ended). Lets it freeze and stop pinning the transcript live
|
|
22
|
+
* region instead of lingering on a pending preview until the next thaw.
|
|
23
|
+
*/
|
|
24
|
+
seal(): void;
|
|
19
25
|
updateArgs(args: ReadRenderArgs, toolCallId?: string): void;
|
|
20
26
|
updateResult(result: {
|
|
21
27
|
content: Array<{
|
|
@@ -3,17 +3,26 @@ import type { SessionInfo } from "../../session/session-manager";
|
|
|
3
3
|
/** Returns the IDs of sessions whose recorded prompts match a query, best first. */
|
|
4
4
|
export type SessionHistoryMatcher = (query: string) => string[];
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
* both signals rather than replacing one with the other.
|
|
6
|
+
* Filter and rank session picker search results.
|
|
8
7
|
*
|
|
9
|
-
*
|
|
8
|
+
* Resume search narrows a recency-sorted list: once every query token appears
|
|
9
|
+
* as a literal substring, newer sessions should beat a slightly better fuzzy
|
|
10
|
+
* position match. Pure fuzzy/acronym matches still sort by fuzzy score after
|
|
11
|
+
* literal matches.
|
|
12
|
+
*/
|
|
13
|
+
export declare function rankSessionSearchMatches(allSessions: SessionInfo[], query: string): SessionInfo[];
|
|
14
|
+
/**
|
|
15
|
+
* Combine metadata matches with prompt-history matches for ranking, using both
|
|
16
|
+
* signals rather than replacing one with the other.
|
|
17
|
+
*
|
|
18
|
+
* - `fuzzy` is the ordered metadata/session-text result.
|
|
10
19
|
* - `historyIds` are session IDs whose recorded prompts matched the query,
|
|
11
20
|
* ordered by prompt-history rank (typically newest matching prompt first); duplicates are tolerated.
|
|
12
21
|
*
|
|
13
|
-
* Ranking:
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
22
|
+
* Ranking: prompt-history matches lead in history order, then remaining
|
|
23
|
+
* metadata matches keep their existing order. A metadata match is never dropped,
|
|
24
|
+
* and history matches not present in `allSessions` (e.g. deleted or out-of-scope
|
|
25
|
+
* sessions) are ignored since they cannot be resumed from here.
|
|
17
26
|
*/
|
|
18
27
|
export declare function mergeSessionRanking(allSessions: SessionInfo[], fuzzy: SessionInfo[], historyIds: string[]): SessionInfo[];
|
|
19
28
|
/**
|
|
@@ -30,11 +30,13 @@ export interface StatusLineSettings {
|
|
|
30
30
|
showHookStatus?: boolean;
|
|
31
31
|
sessionAccent?: boolean;
|
|
32
32
|
}
|
|
33
|
+
export type EffectiveStatusLineSettings = Required<Pick<StatusLineSettings, "leftSegments" | "rightSegments" | "separator" | "segmentOptions">> & StatusLineSettings;
|
|
33
34
|
export declare class StatusLineComponent implements Component {
|
|
34
35
|
#private;
|
|
35
36
|
private readonly session;
|
|
36
37
|
constructor(session: AgentSession);
|
|
37
38
|
updateSettings(settings: StatusLineSettings): void;
|
|
39
|
+
getEffectiveSettingsForTest(): EffectiveStatusLineSettings;
|
|
38
40
|
setAutoCompactEnabled(enabled: boolean): void;
|
|
39
41
|
setSubagentCount(count: number): void;
|
|
40
42
|
setSessionStartTime(time: number): void;
|
|
@@ -61,24 +61,6 @@ export declare class ToolExecutionComponent extends Container {
|
|
|
61
61
|
* past, or an explicit {@link seal} flips it to `true`.
|
|
62
62
|
*/
|
|
63
63
|
isTranscriptBlockFinalized(): boolean;
|
|
64
|
-
/**
|
|
65
|
-
* While a tool's preview is still streaming, a block whose preview is
|
|
66
|
-
* append-only (rows only grow at the bottom, never re-layout) lets the
|
|
67
|
-
* renderer commit the scrolled-off head of an over-tall preview to native
|
|
68
|
-
* scrollback instead of dropping it — the same anti-yank path a streaming
|
|
69
|
-
* assistant reply uses (see {@link TranscriptContainer} +
|
|
70
|
-
* `NativeScrollbackLiveRegion`). Covers both phases: a pre-result call preview
|
|
71
|
-
* (a `write` whose content streams in) and a partial-result preview that
|
|
72
|
-
* streams output below fixed input (an `eval`/`bash` whose stdout grows under
|
|
73
|
-
* its code cell). Gated on {@link isTranscriptBlockFinalized} so the boundary
|
|
74
|
-
* closes the instant the block reaches a terminal state — a final result that
|
|
75
|
-
* may collapse to a compact view, a backgrounded async tool, or a seal — and
|
|
76
|
-
* the renderer decides whether its current preview shape qualifies via
|
|
77
|
-
* `isStreamingPreviewAppendOnly` (typically: only the expanded full view,
|
|
78
|
-
* which is top-anchored; the collapsed tail window re-layouts but is bounded
|
|
79
|
-
* so it never overflows anyway).
|
|
80
|
-
*/
|
|
81
|
-
isTranscriptBlockAppendOnly(): boolean;
|
|
82
64
|
/**
|
|
83
65
|
* Mark the tool terminal even though no result arrived (the turn aborted or
|
|
84
66
|
* abandoned it) and stop animating, so it can freeze and stops pinning the
|
|
@@ -1,10 +1,27 @@
|
|
|
1
1
|
import type { InteractiveModeContext } from "../../modes/types";
|
|
2
2
|
import type { AgentSessionEvent } from "../../session/agent-session";
|
|
3
|
+
/**
|
|
4
|
+
* Loader label shown the instant a user interrupt (Esc) is requested, kept until
|
|
5
|
+
* the agent turn fully unwinds. Esc fires the abort synchronously, but the loop
|
|
6
|
+
* only stops the spinner at `agent_end`, which it cannot reach until every
|
|
7
|
+
* in-flight tool settles its abort in `executeToolCalls` (`Promise.allSettled`).
|
|
8
|
+
* Swapping the steady "Working…" for this acknowledges the keypress instead of
|
|
9
|
+
* reading as an ignored Esc for the seconds a slow tool takes to tear down.
|
|
10
|
+
*/
|
|
11
|
+
export declare const INTERRUPTING_WORKING_MESSAGE = "Interrupting\u2026";
|
|
3
12
|
export declare class EventController {
|
|
4
13
|
#private;
|
|
5
14
|
private ctx;
|
|
6
15
|
constructor(ctx: InteractiveModeContext);
|
|
7
16
|
dispose(): void;
|
|
17
|
+
/**
|
|
18
|
+
* Acknowledge a user interrupt (Esc) immediately: switch the loader to
|
|
19
|
+
* `INTERRUPTING_WORKING_MESSAGE` and freeze intent-driven working-message
|
|
20
|
+
* updates for the rest of the turn so a late `tool_execution_start` intent
|
|
21
|
+
* cannot repaint a "Working…/<intent>" line over the acknowledgment. Reset at
|
|
22
|
+
* the next `agent_start`. No-op outside an active turn or if already set.
|
|
23
|
+
*/
|
|
24
|
+
notifyInterrupting(): void;
|
|
8
25
|
subscribeToAgent(): void;
|
|
9
26
|
handleEvent(event: AgentSessionEvent): Promise<void>;
|
|
10
27
|
sendCompletionNotification(): void;
|
|
@@ -180,6 +180,7 @@ export declare class InteractiveMode implements InteractiveModeContext {
|
|
|
180
180
|
ensureLoadingAnimation(): void;
|
|
181
181
|
setWorkingMessage(message?: string): void;
|
|
182
182
|
applyPendingWorkingMessage(): void;
|
|
183
|
+
notifyInterrupting(): void;
|
|
183
184
|
showNewVersionNotification(newVersion: string): void;
|
|
184
185
|
clearEditor(): void;
|
|
185
186
|
updatePendingMessagesDisplay(): void;
|