Restricted -sigspec parsing to the option position and consumed the -- end-of-options marker, so negative PIDs (process groups) and post-marker operands are signaled rather than parsed as signals. Added a process-group regression covering kill -TERM -- -<pgid> <pid>. Fixes #6779
1.5 MiB
Changelog
[Unreleased]
Fixed
- Fixed the bash tool's
killbuiltin rejecting numeric signals and multiple process operands, and changed its default signal fromSIGKILLto the standardSIGTERM. Negative PID operands (process groups perkill(2)) and the--end-of-options marker are now handled instead of being misparsed as signals (#6779).
[17.1.5] - 2026-07-27
Added
- Added a configurable per-request timeout for the
inspect_imagetool (inspect_image.timeoutMs, default 5 minutes; set to 0 to disable) so a stalled vision-model provider fails fast with a clear error instead of blocking until manual abort (#4165).
Changed
- Reduced default startup resident memory by constructing the default-off ComputerTool ArkType schema only on first parameter access, then reusing it across tool instances without changing validation or tool behavior (#6742 by @usr-bin-roygbiv).
- Reduced startup CPU and memory by loading the bundled changelog only when needed, while preserving source, npm bundle, standalone binary, and native absolute-path fallback resolution.
- Moved PTY log replay into the shared project launch broker, so normal CLI and Hub startup no longer load the xterm runtime while launch logs return validated rendered terminal rows.
Fixed
- Fixed DeepSeek V4 Flash and Step 3.7 Flash models using hashline edit mode by default despite repeatedly misreading its range grammar; both now use the simpler replace-mode fallback unless explicitly overridden (#6671).
- Fixed an Ask form appearing while the main prompt contains a draft hiding that text and consuming the next in-flight keystroke. The draft now remains visible and keeps receiving input until it is submitted or cleared; only then do form controls activate (#6737).
- Fixed
globrejecting safememory://root/<directory>/**patterns. Memory globs now resolve their directory prefix inside the project memory root while rejecting traversal and percent-encoded path separators across the complete glob path. - Fixed
omp --resume <id>prompting to fork sessions from another existing directory instead of switching the process and cwd-scoped settings into the resumed session's recorded directory (#6752). - Fixed deferred CLI model roles resolving ambiguous bare model IDs to a preferred but unauthenticated provider instead of the authenticated provider selected by the eager path (#6727).
- Fixed Windows sessions crashing with an unhandled
EPIPE: broken pipe, writewhen an LSP server closed its stdin between filesystem mutations; LSP writes now observe asynchronousFileSink.write()failures and route them through the existing request/notification failure path. - Fixed the bash tool's
statbuiltin failing on native Windows withstat: unsupported on this platform(exit 1) for every invocation. The vendoreduu-statnow ships a Windows-native backend that maps the GNU format directives ontostd::fs::Metadata, thewindows_by_handlemetadata extensions (inode, hard-link count, and device viaGetFileInformationByHandle), and the Win32 volume APIs for--file-systemmode; Unix behavior is unchanged (#6723). - Fixed auto-retry wedging the session after an assistant-tail removal miss: when a context rebuild recreated the failed turn's message object, the identity-keyed cleanup logged
assistant removal missedbut the retry still scheduledcontinue(), which rejected the terminal assistant error message locally (Cannot continue from message role: assistant) before any provider request —auto_retry_endnever fired, the TUI kept showing retry progress, and the in-flightprompt()hung until a manual follow-up. The retry path now strips a still-failed assistant tail positionally after the backoff, and a continuation that still fails locally closes the retry saga with a failedauto_retry_end(#5382). - Fixed native Anthropic web-search history being recursively truncated during session persistence or retained under a different user turn, preserving opaque replay bytes across reload and stripping them on reparent (#6703).
- Fixed malformed or temporarily unreadable
config.ymlfiles being treated as empty settings and then overwritten by the next setting change, which could permanently erase broker tokens, model roles, and provider configuration. Invalid YAML is now moved to a timestamped.broken-*backup, read failures abort without touching the source, pending changes remain retryable with the last successfully loaded settings, atomic writes preserve symlink targets and handle WindowsEPERMreplacement, concurrent startup failures are fully observed and quarantine races fail closed, andomp config set/resetwaits for persistence before reporting success. - Fixed mounted MCP tools being hard to invoke when server or plugin guidance names their original calls: sessions now include one bounded, exact original-name-to-
xd://route map for every live mounted MCP tool—including servers without initialize instructions—and refresh it as catalogs change without disabling schema virtualization. - Fixed
inspect_imageblocking indefinitely when the vision-model API stalls by combining the caller's abort signal with anAbortSignal.timeout()and surfacing a distinct timeoutToolError(separate from user-triggered abort) (#4165). - Fixed MiMo models using hashline edit mode by default despite needing the same replace-mode fallback as Kimi. (#3772)
- Fixed
omprefusing to start on Windows when nobash.exeis discoverable — most visibly with scoop-installed Git, whose manifest shimssh.exe/git.exebut neverbash.exe, so PATH lookup missed it. Startup threwNo bash shell foundwhile merely building the bash tool description, even though bash tool commands always execute in the embedded brush-core shell and need no host bash. Shell discovery now also checksGIT_INSTALL_ROOT, scoop and per-user Git for Windows install roots, andsh.exeon PATH, then falls back tocmd.exefor the spawn-only paths (interactive PTY, ACP client terminals) instead of failing; the cmd fallback is never used to wrap user-shell commands — brush runs the POSIX line directly. - Added a selectable voice setting for
/liverealtime sessions (#6566).
[17.1.4] - 2026-07-26
Added
omp usagenow surfaces auto-disabled credentials as red✗tombstone rows (identity, how long ago, the shortened upstream cause — e.g.Refresh token expired— and a re-login hint), including a provider section when no active credential remains. User-driven tombstones (replaced by newer credential,deleted by user) and API-key rows stay hidden. Requires a broker withGET /v1/credentials/disabled; older brokers degrade to no tombstone rows.omp usagewarns about Anthropic's ~30-day OAuth grant lifetime: accounts whose interactive login (authorizedAt) is within a week of the deadline get a yellow⚠ re-login within <time>line, and past-deadline accounts a red one. Grants die server-side exactly ~30 days after login regardless of refresh rotation, so this is the only warning before the broker auto-disables the row.
Changed
- Enabled Computer Use sessions now state the desktop-routing contract in the compact system prompt, retain their controller across model switches, expose effective native/function routing through
/computer status, and emit structured lifecycle diagnostics without logging captured content.
Fixed
- Fixed dragging an image whose path contains unescaped spaces (e.g. macOS screenshot names like
Screenshot 2026-07-24 at 1.55.12 PM.png) into the terminal — the bracketed-paste image extraction route now has the same whole-text-as-path fallback as the clipboard keybind route, so both routes share identical detection and attach the image instead of inserting the raw path as literal text (#6578). The shared fallback only claims payloads that hold a single path: one carrying a second absolute-path anchor after unescaped whitespace (/tmp/a.png /tmp/b shot.png— dragging two files at once when either name has spaces) now pastes as text on both routes instead of being fused into one unresolvable path, which on the clipboard route previously attached nothing and swallowed the text behind an "Image not found" status. - Fixed transient reasonless request aborts that arrived after a tool call finished streaming ending the turn instead of entering recovery, which left edit calls and task subagents dead until the user manually resumed. The session now continues from the synthetic unexecuted tool result under the normal retry policy without replaying completed side effects (#6668).
- Fixed prewalk silently dropping a same-model hand-off that only lowers the thinking level: the arm/switch guard compared model identity alone and discarded the resolved
thinkingLevel, so a legal effort-downgrade target (e.g.prewalk: "@task"resolving to the same model at a cheaper effort) never applied and the session paid the plan/continue nudges for nothing. Prewalk now compares(provider, id, effective thinking level), applies effort-only hand-offs, and emits a notice on a genuine no-op instead of returning silently (#6659). - Fixed
@czottmann/pi-automodefailing legacy extension validation because the pi-ai compatibility shim omittedclampThinkingLevel, then failing every classified tool call becausectx.modelRegistryomittedgetApiKeyAndHeaders. (#6648) - Fixed hide-secrets placeholders conflicting with hashline edit headers by replacing hash-delimited tokens with the unambiguous
$$HASH$$format (#6631). - Fixed the advisor silently swallowing its own quarantined turns: when an advisor called an ungranted tool (e.g.
bash) its whole turn was discarded before dispatch, so its advice never reached the primary agent and the failure surfaced only in advisor diagnostics — every other non-recovering failure branch notifies the host UI, but quarantine re-primed silently with no bound. A persistently-quarantining advisor now surfaces anotifyFailurewarning in the main UI (deduped, cleared on the next successful turn) and stops the unbounded silent re-prime loop (#6661). - Fixed the Docker
natives-builderstage failing to build releases ≥ 17.1.1: the native audio stack added bindgen (miniaudio needs libclang) and a bundled-opus CMake build (needs cmake + make), none of which were installed in the slim builder image. - Fixed a configured
modelRoles.defaultnaming an extension-registered model (listed inenabledModels) silently running on a different in-scope provider's model. The startup model scope is resolved before extensions callregisterProvider(), so the default role dropped out of scope andbuildSessionOptionspinnedoptions.modelto the first scoped model — which marked the model "explicit" and suppressed the post-extension default-role re-resolution. A configured default that can't be found in the startup scope is now deferred so it re-resolves against the fully registered, stillenabledModels-scoped catalog once extensions load (#6694). - Fixed Parakeet speech-to-text failing to load
sherpa-onnx-nodefrom Windows source workspaces when Bun installed the wrapper underpackages/coding-agent/node_modulesbut hoisted its native platform package to the repository root (#6690). - Fixed
omp usageduplicating org-less legacy accounts as "no usage data" rows whenever any sibling report carried an organization (mixed pools of pre-org-capture rows and fresh org-scoped logins): an org-less account is now covered by its own org-less report, while org-attributed sibling reports still never count as its coverage. omp usagerevalidates the broker credential snapshot before rendering: live usage reports were previously paired with a disk-cached account list up to an hour old, so a just-completed re-login (org-less row upserted to org-scoped) rendered as a phantom duplicate until the cache expired.- Fixed Advisor requests reaching Anthropic-compatible endpoints without a provider-facing session identity: the separately constructed advisor
Agentnever had a metadata resolver installed, so its outbound requests omitted themetadata.user_idsession id that the main and subagent agents carry. Each advisor now emits its ownadvisorProviderSessionIdviametadata.user_id, resolved live so a token refresh surfaces the currentaccount_uuid, giving Main, subagent, and Advisor traffic distinct, stable session ids for proxy routing and attribution (#6625). - Todo progress now stays in sync when using Cursor models: the Cursor exec bridge mirrors the provider's server-owned todo list into session state, refreshes the interactive todo panel, and persists each snapshot to the session branch so the list survives reloads, rewinds, compaction, and session switches. Existing phase grouping is preserved for tasks the session already knows. Previously the list was in-memory only and the panel stayed stale, because Cursor resolves the todo tool remotely and never emits the local
todotool result that both paths key off. - Cursor todo calls the server refuses or rejects no longer leave the todo card spinning: the bridge settles every completed native todo call, not just the ones carrying a list. Local phases and the session branch are left untouched in that case, and the settling result deliberately carries no
details.phases— echoing the current list back would let a call that changed nothing overwrite live panel state. - Fixed the todo renderer emitting mirrored label text verbatim. A Cursor snapshot carries provider-authored task content, phase names, and summary text, and the renderer interpolated all of it straight into terminal output, so a label holding ANSI/C0 sequences rewrote the terminal every time the list rendered or replayed. Every display path now goes through one sanitize-and-flatten-tabs helper — task labels, blocker notes, phase headers, the zero-task fallback, and the streaming call preview — while the raw values stay untouched as the lookup keys they are.
- Fixed a server-resolved Cursor todo card animating for the rest of the session when the server packed the call's start and completion into one HTTP/2 chunk. The bridge's
tool_execution_endis a synchronous callback fired mid-parse, while the streamedtoolcall_startthat creates the visible card is queued on the event stream and delivered a microtask later — the interactive controller handled the completion first, found no pending card, and dropped it, leaving the card that appeared moments later with nothing to settle it. An early completion is now held and attached the moment the streamed block creates its card, settling it without repeating the panel refresh or failure warning that already fired on first arrival. Card creation from cumulativemessage_updateframes is also guarded by the turn's timeline map, so a call settled mid-stream can no longer be recreated as a second, permanently pending card by the next update re-listing the same block. - Cursor todo failures no longer render unsanitized provider text into the status line. The bridge forwards the server's error string verbatim, so an ANSI escape or other C0/C1 control reached the terminal intact and could repaint outside the row, tabs punched holes in the single-line warning, and a long message overflowed it. The detail is now stripped of control sequences, collapsed, and truncated at the render boundary; the persisted result keeps the full-fidelity error for the transcript.
- Fixed disabling the Advisor from
/settingsupdating the persisted setting without stopping the live Advisor runtime until the session restarted:SelectorController.handleSettingChangehad no case foradvisor.enabled, unlike other session-managed toggles (autoCompact,steeringMode, ...), so the change never reachedsession.setAdvisorEnabled. - Fixed
bash.patternsdeny/promptrules matching only against the whole command string, so a dangerous command in any non-leading position of a compound line (e.g.cd /tmp && rm -rf /tmp/x,sleep 1 & rm -rf /tmp/x) silently bypassed adenyrule and, underapprovalMode: yolo, executed with no prompt.deny/promptrules now also match each command segment, split with a shell-aware tokenizer that honors every command boundary (&&,||,;,|, single&, subshells, newlines) and quoting;allowrules still require the whole command to match and never apply to compound lines (#6695). - Fixed
omp config listprinting credential settings in plain text.auth.broker.token,searxng.token,searxng.basicPasswordanddev.autoqaPush.tokenwere disclosed in both the human and--jsonoutput of a command that dumps every value without anyone asking for a specific credential. Credentials are now marked in the schema with a top-levelcredentialflag, which also covers settings that have no settings-panel entry and so cannot useui.secret. Human output shows dots; JSON omitsvalueand marks the entryredactedrather than substituting a placeholder a consumer could write back.omp config get <path>is unchanged, since that is an explicit request for one value. The settings panel now derives masking from the same flag, so a credential cannot render as plain text on one surface and dots on the other. Only a credential that is actually set is redacted, so a fresh configuration still reports unset credentials as unset rather than implying every one of them is configured. - Fixed
/new,/drop,/fork, and/movecrashing or doing unnecessary work when invoked during vibe mode; interactive session transitions now show the existing exit-vibe warning and leave the session unchanged, and reset loops disable themselves instead of resubmitting into that unchanged session (#6607). - Fixed legacy pi extensions failing extension validation when importing
estimateTokensfrom@earendil-works/pi-coding-agent(aliased to the legacy shim). Legacy pi re-exportedestimateTokensfrom its coding-agent package root; in omp it lives in@oh-my-pi/pi-agent-core/compactionand the coding-agent barrel does not forward it, so the shim'sexport * from "../index"left it off the surface and a named import threw Bun's static "Export named 'estimateTokens' not found" error (e.g.omp plugin install pi-blackhole). The shim now re-exports it (#6583). - Fixed plan approval presenting a completed plan instead of the newest draft when the submitted title did not match the draft filename (#6569).
- Fixed
omp auth-gateway serveadvertising only the compiled-in bundled catalog, so every model omp reaches through provider discovery (e.g. ids released after the build date) was invisible on/v1/modelsand returnedUnknown modelthrough/v1/chat/completionseven though the same broker credential answered it in the TUI. The gateway now sources its catalog fromModelRegistry— the same component the TUI/CLI use (bundled + cached + discovered) — keeping the credential scoping and qualified/bare-id registration, and rebuilds it periodically so a long-livedservetracks newly discovered models without a restart (#6615). - Fixed screenshot-relative pointer actions missing their visible targets when image transports that cannot preserve original detail silently downscaled a large computer screenshot; affected transports now establish the native coordinate frame below the verified image-resize threshold without changing the public capture defaults for other models (#6596 by @wolfiesch).
- Corrected Windows shell resolution errors to identify the active global, project, overlay, or runtime source for
shellPath, including profile and custom configuration directories, instead of directing every user to the retiredsettings.jsonfile (#6579). - Fixed
debug(js-debug/pwa-node) stateful commands misrouting after launch: a lazily-attached[worker N]child session (or the threadless root launcher) would steal the active-session focus from the stopped script child, sothreadslisted only the worker thread, post-launch breakpoints read back as pending/unbound, and there was no way to step/continue/evaluate the script's thread. Focus now follows stops rather than registrations, andthreadsaggregates every live thread across the session tree (#6663). - Fixed a turn-ending provider error being truncated to 8 lines in the transcript with no way to reveal the rest:
AssistantMessageComponentnow implementssetExpanded, so Ctrl+O (tool-output expansion) reveals the full error body and the collapsed view shows a… +N more lines (Ctrl+O to expand)hint (#6555). - Fixed direct binary updates trusting an executable that only reported the expected version. The updater now selects one exact asset from the tagged GitHub release, requires its published SHA-256 digest and size, and verifies both while streaming the download before installation. GitHub release metadata requests use
GITHUB_TOKENorGH_TOKENwhen available, allowing users behind an exhausted anonymous rate limit to authenticate. - Documented that the non-PTY shell's bundled
jqcommand is backed by jaq, including its null-indexing divergence and portable filter syntax (#6614). - Fixed
omp://tools/task.mdandomp://tools/eval.mddrifting from the 17.1.3 runtime:task.mdclaimed subagents force-disableasync.enabled/bash.autoBackground.enabled(both are inherited from the parent since 17.1.0) and omitted thetasktool'seffortparameter, andeval.mdomitted the still-working evalagent(model=…)per-call model selector (#6594). - Fixed advisor retry amplification after transient Codex SSE socket closures by limiting each advisor-level try to one provider transport attempt.
- Fixed
omp updateaborting withnpm error EEXISTon standalone binary installs whose directory coincides with the global npm/bun bin dir (for examplenpm prefix -gset to~/.local, which the installer also targets). The install-target resolver classified the binary as npm/bun-managed from directory containment alone, sonpm install -gtried to replace a regular file its symlink step would clobber; it now treats a plain executable (not a symlink) in a package-manager bin dir as the standalone binary and self-updates it in place (#6527 by @am423). - Fixed Codex subscription and proxy models being sent the unsupported native
{ type: "computer" }declaration based only on model ID. They now receive the callable function-tool fallback, including after switching from native OpenAI Responses history, while explicit endpoint metadata can still opt into the GA contract. Explicit native Codex replays preservecomputer_call/computer_call_outputpairing, normal CLI startup keeps the native desktop worker graph lazy, and packaged workers re-enter the single CLI host without the computer module claiming non-computer selectors. - Fixed isolated JavaScript eval subprocesses letting the global fatal-rejection handler race the cell rejection interceptor. A floated promise rejection is now folded into the owning cell result without killing its reusable worker process.
- Fixed
/contextcounting hidden, explicit-only skills (hide: true/disable-model-invocation) in the Skills category and subtracting that inflated estimate from the first system-prompt block, which reportedSystem prompt: 0 tokensand inflated Skills usage. Accounting now counts only the skills actually rendered into the system prompt — mirroringbuildSystemPrompt's filter, so hidden skills and all skills when thereadtool is unavailable contribute zero (#6498). - Fixed
pi-spritefailing plugin validation because the legacy Pi compatibility shims omittedcreateExtensionRuntimeand terminal capability/image-deletion helpers used by the extension (#6506). - Fixed Escape waiting for an in-flight
session_stopextension handler to exhaust its timeout; abort now cancels the active stop pass without reporting a false timeout or applying stale continuation context (#6489). - Fixed the agent not resuming after re-answering a past
askfrom the session tree. Committing a new answer via/treebranched a fresh siblingtoolResultand rebuilt context, but nothing ever continued the agent — unlike a liveask, whose continuation is intrinsic to the streaming run loop — so the model never consumed the new answer and the session sat idle until a manual prompt.navigateTreenow reports the commit (askReanswerCommitted) and the interactive/treehandler resumes the agent viaresumeAfterAskReanswer()after its transcript rebuild, so the resumed turn never renders against the stale pre-rebuild UI. Plain leaf moves and the read-onlyreopenAskprobe stay idle (#6483). - Fixed Ctrl+C and fatal shutdown entering an
ExtensionExitErrorrejection loop while an extension or hook was still loading (#6488).
[17.1.3] - 2026-07-24
Fixed
- Fixed the in-process
findbuiltin's-exec/-execdirchildren inheriting the omp process's real stdout/stderr, so commands likefind … -exec ls -ld {} \;spammed their output straight into the terminal (corrupting the TUI) instead of the tool's captured output, and bypassed shell redirects. Exec children now stream stdout/stderr back through the shell's scope streams (matchingxargs/ifne) and run with the shell's exported environment (env_clear+ scope snapshot) instead of the host process environment. - Fixed
ast_editerroring with "langis required" — an argument that no longer exists in the tool schema — whenpathsresolved to files of multiple languages (e.g. a crate directory with.rs+.toml). Mixed-language paths now rewrite per file: each file is parsed in its own inferred language, patterns are compiled per language, and a pattern that doesn't parse in some matched language simply skips those files. - Fixed the
retaintool's TUI renderer crashing when streaming arguments temporarily expose a non-arrayitemsvalue (#6528). - Fixed Edit and Write tools failing with
Settings not initializedin isolated sessions by using each tool session's settings for generated-file guards, with safe schema defaults for standalone guards and inline-image rendering (#6549).
[17.1.2] - 2026-07-24
Added
- Added in-process moreutils-style shell builtins to the bash tool's embedded shell:
ts(timestamp lines;-i/-selapsed modes,-mmonotonic clock,-rrelative rewriting of RFC3339/syslog timestamps,%.S/%.s/%.Tsubsecond extensions),sponge(soak stdin fully before atomically writing the target, sofoo file | ... | sponge fileworks;-aappends),ifne(run a command only when stdin is non-empty;-ninverts and passes non-empty stdin through),isutf8(streaming UTF-8 validation with line/char/byte diagnostics;-q,-l,-i),combine(booleanand/not/or/xoron the lines of two files,-for stdin), anderrno(errno name/number/description lookup with-llist and-ssearch; unix only). Like the uutils-backed builtins, they run in-process against the command's own stdio, resolve paths against the shell working directory, honor cancellation, and are disabled byPI_DISABLE_UUTILS_BUILTINS. - The bash tool prompt now lists the available shell builtins (
mkdirthroughjq,rm/mv/ln, and the moreutils set) so the model relies on them without existence checks; the line is dropped whenPI_DISABLE_UUTILS_BUILTINSdisables the builtins and omits unix-onlyerrnoon Windows. - Sessions using a broker-backed auth store now report each completed request's token usage and cost to the auth broker (batched, 10s cadence) so the broker can track actual token burn per client install
- Added a per-spawn
effortparameter to thetasktool ("lo"|"med"|"hi"): each selector maps onto the resolved model's supported thinking range (lowest, middle, and highest level — whatever the model tops out at, e.g.high,xhigh, ormax) and overrides the agent's default selector, includingauto. Omittingeffortkeeps the existing automatic per-prompt thinking classification. - Added
searxng.enginessetting for the SearXNG web search provider: a comma-separated list of engine names or bang shortcuts (e.g.ddg, br, startpage) sent as the API'sengines=parameter. Shortcuts are resolved to canonical engine names via the instance's/configendpoint (cached per endpoint; entries pass through verbatim if/configis unreachable). Bang syntax in queries (!ddg foo) continues to pass through to the instance, and external bangs (!!g) are now stripped client-side since SearXNG answers them with an HTTP redirect even for JSON requests. - Web search queries now understand Google-style directives on every provider:
site:/-site:(plusdomain:/host:aliases),after:/before:/since:/until:date bounds,inurl:/intitle:/intext:/allin*:,filetype:/ext:,lang:, quoted phrases (including smart quotes),+term,-/NOTexclusions, andOR/|groups. A shared parser (web/search/query.ts) structures the query once per request; each provider maps constraints onto native API filters where the upstream supports them (Perplexity domain/date/language filters on both the API-key and ask paths, Tavilyinclude_domains/exclude_domains+start_date/end_date, Exa domain lists + published-date bounds on API and MCP paths, Anthropicallowed_domains/blocked_domains, xAIfilters.allowed_domains/excluded_domains, Parallelsource_policy, Brave absolutefreshnessranges, Firecrawltbs=cdrdate ranges, JinaX-Site, SearXNGlanguage) and otherwise re-emits only the operator syntax its engine parses (full Google syntax for Gemini grounding, OpenAI, Kagi, and the credential-free scrapers — with scraper-hostile path-site:/inurl:operators demoted to plain keywords; conservative subsets for DuckDuckGo, Mojeek, Kimi, Z.AI, TinyFish, and Synthetic). The pipeline then applies a lenient post-filter to every response: constraints the engine ignored are enforced on the returned sources, and any constraint dimension that would eliminate every result is relaxed and reported to the model (Note: no results matched \site:...`; the constraint was relaxed`) instead of returning nothing. Directive-free queries are passed through byte-identical everywhere. - Eval and browser
runcode previews are now prettified for display: minified/compact agent-written cells are expanded by conservative streaming formatters (Python, JavaScript, Ruby, Julia) that indent block structure, split statements, normalize operator spacing (JS), and expand object literals wider than 100 columns onto one property per line — purely for rendering, the executed source is untouched. The formatters handle in-flight prefixes (unterminated strings/comments/blocks) without inventing closers, and layout decisions are prefix-stable so already-rendered lines never reflow while a call streams.
Changed
- Large pastes saved via the large-paste menu now insert
local://paste-N.mdreferences (previouslylocal://attachment-N), so the saved paste carries a markdown extension and a clearer name. - Raw SSE debug capture now trims over-budget events smartly instead of chopping off the tail: tool definitions inside
data:payloads are compacted first (name kept, schema/description elided — often enough to keep the whole payload as valid JSON), and anything still over the 64k cap keeps its head and tail with a: omp-debug-elided chars=Ncomment marking the removed middle, so trailing fields likeusagestay visible. - The
web_searchtool prompt now tells the model to never search for content that is programmatically accessible or has a known URL (GitHub, known arXiv papers, Wikipedia pages, official docs) and toreadthe URL directly instead.
Fixed
- Fixed
todocalls that omitophard-failing validation ("op must be operation to apply (was missing)"): the tool now validates leniently and infers the op for unambiguous payloads (list→init,phase+items→append, bareitemson an empty list →init);opstays required in the schema, and ambiguous op-less calls surface the schema error as a retryable tool error. - Fixed credential-free web search engines (SearXNG, DuckDuckGo, Google, Startpage, Ecosia, Mojeek, and the Public Web fan-out) returning zero results for queries with
site:paths (e.g.site:github.com/owner/repo) orinurl:operators: scraper engines only matchsite:against a bare domain and DuckDuckGo ignoresinurl:entirely, so such queries silently emptied the result set and fell through to the next provider in the chain. A sharedformatScraperQueryformatter now structurally demotes path-carryingsite:and allinurl:values to plain search terms (covering OR-grouped and quoted directives) while preserving bare-domainsite:filters, negated operators, and each engine's supported syntax; the pipeline post-filter still enforces the demoted constraints on returned sources. - Fixed
ast_editpreviews reading like applied edits to the model: the⟨proposed⟩badge was TUI-only, so the model-visible result (hashline header +-/+rows, identical to applied edit output) carried no staged-proposal signal. The preview result now leads with a "Staged as a proposal — files NOT modified yet" notice namingxd://resolve/xd://reject, the injected resolve reminder names the source tool, and theast_edittool prompt documents the two-phase flow. - Fixed the
hublaunchps/listresponse burying the active process behind every exited one and growing without bound in long-lived projects: the broker now lists non-terminal daemons first (oldest to newest) and caps exited/failed history at the 10 most recently exited, so the active launch is immediately visible and the response stays bounded. Broker recovery also preserves each already-terminal daemon's real exit time instead of overwriting it with the restart timestamp, so the history cap keeps the genuinely most-recently-exited processes after an idle-broker restart (#6517). - Fixed a tool call rendering twice in the transcript. A mid-stream
rebuildChatFromMessages(from/shake, auto-compaction, or a settings toggle) preserves the livependingToolscomponents across the clear+replay, but that preservation assumed every pending-tool component was still dangling. When a tool's result had already landed in the session entries while its component still lingered inpendingTools, the replay reconstructed the completed block and the preserved live component was re-appended, so the same block appeared twice; resolved components are now dropped from preservation and owned by the replay (#6516). - Fixed
--model default(and other bare role names) resolving to the bundledcursor/defaultcatalog model instead of the configuredmodelRoles.defaultrole.resolveCliModel's exact-match phase ran its unauthenticated catalog fallback before role resolution, so a bundled id colliding with a reserved role name shadowed a configured, runnable role — failing withNo API key found for cursoron machines without Cursor credentials. The catalog fallback is now deferred so an authenticated exact model still wins, a configured role beats an unauthenticated catalog-only id, and the catalog id is still recovered when no role matches (#6508).
Removed
- Removed the
modelparameter fromtaskandagent(): explicit per-spawn model selectors and fallback chains are no longer supported; spawns always use the agent's configured model
[17.1.1] - 2026-07-24
Added
- Added the
/session pinsubcommand and account picker to pin provider OAuth accounts for the current session - Added the disabled-by-default
computeressential tool with configurable enablement, backend, display, and maximum width/height settings. Native desktop execution runs through aDesktopSessionworker; observation uses read approval, input uses exec approval, and provider checks always prompt and fail closed. - Added the
/computerslash command (on/off/status/toggle) to enable or disable the computer tool for the current session without persisting settings. - Exposed
computerto models without native OpenAI computer-use support as a regular function tool with a typed GA action schema; the same native desktop backend and approval policy apply on both paths. - Hardened computer action ingress: action-specific fields, modifier/key arrays, coordinates, drag points, and scroll deltas fail closed before native input; numeric fields must be signed 32-bit integers and coordinates must be non-negative.
Changed
- Replaced Chromium-backed
/livemedia and external speech recorder/player subprocesses with the cross-platform native microphone, speaker, Opus, and WebRTC stack from@oh-my-pi/pi-natives.
Fixed
- Fixed live-call attestation depending on the ChatGPT desktop app being installed:
generateLiveAttestationnow mints DeviceCheck tokens in-process through the@oh-my-pi/pi-nativesdeviceCheckGenerateTokenbinding instead of probing/Applicationsfor the app'sdevicecheck.nodeaddon, so thex-oai-attestationheader works on hosts without the desktop app and drops thecreateRequireaddon probing; the attestation provider is now wired up to@oh-my-pi/pi-aifor ChatGPT-OAuth Codex requests. - Fixed
xd://device execution failures rendering aswriteerrors instead of using the mounted tool's own error renderer. - Fixed custom tools without bespoke renderers losing the default state-tinted card when mounted under
xd://; dispatched calls now keep their label, arguments, status, output preview, and expansion affordance instead of dumping a bare result line into the transcript. - Fixed the clipboard image-paste keybind mangling copied URL text into a bogus path error on macOS (e.g.
Image not found at /https/::i.can.ac:CE4Ek3.pngfor a copiedhttps://i.can.ac/CE4Ek3.png). AppleScript'sthe clipboard as «class furl»coerces plain text into a file URL by treating the string as an HFS path (:↔/swap), soreadMacFileUrlsFromClipboardreturned a garbage path that dead-ended inhandleImagePathPasteinstead of falling through to the text paste. The script now bails early viaclipboard info for «class furl»unless the pasteboard actually carries apublic.file-urlrepresentation, so URL/text clipboards paste as text. - Fixed spilled tool-output artifact descriptors leaking on error/abort paths.
OutputSink.dump()was the only path that closed the spillBun.FileSink, but the bash and Python executors re-throw on failure and theirfinallyblocks never closed the sink, so a large-output command that errored leaked the artifact descriptor until an unrelated read (e.g. aSKILL.mdload) hitEMFILE.OutputSinknow exposes an idempotentdispose()that closes the sink exactly once, wired into every executor'sfinally(#6463). - Fixed the first submitted prompt stalling while the local tiny-title worker started: the interactive submit handler now paints the pending user row before starting title generation, and startup prewarms an idle, unref'd worker so the first submit reuses a live subprocess instead of paying spawn latency ahead of the first frame (#6462).
- Fixed legacy Pi extensions failing validation when importing the upstream
keyTextkeybinding helper (#6470).
[17.1.0] - 2026-07-24
Breaking Changes
- Replaced the
providers.webSearchandproviders.imagesingle-preference configuration options withproviders.webSearchOrderandproviders.imageOrderpriority lists. Existing configurations migrate automatically on startup.
Added
- Added dynamic multi-root workspace context support, allowing users to manage multiple workspace directories mid-session via
/add-dir,/remove-dir, and/dirsslash commands, or seed them at launch using the--add-dirCLI flag. - Added
/live, a Codex-authenticated real-time voice interface that streams microphone audio over WebRTC and routes coding tasks through the active agent session. - Added opt-in usage-aware model fallback for rationed coding plans, including a
/usagecommand to view live quantitative usage data and automatic fallback chain traversal. - Added
error.notifyconfiguration to allow failed model turns to trigger distinct terminal or desktop notifications. - Added auto-following light and dark themes to HTML session exports, with a
/export --themesoption to bundle selected TUI themes. - Added owner-routed asynchronous job delivery, ensuring background bash and task results are injected directly into the owning subagent or agent session rather than the top-level session.
- Added background-on-steer capability for auto-backgrounded bash commands, allowing incoming user or peer messages to immediately background running commands.
- Added
friendlyNamesupport for hidden secrets, allowing model-visible placeholders to carry sanitized semantic labels, hashes, and case hints. - Added support for Jujutsu (
jj) repositories in the statuslinegitsegment, displaying the nearest bookmark or change ID and retrieving working-copy change counts. - Added
blockandunblockoperations for tasks, introducing ablockedstatus for tasks waiting on external input to exclude them from incomplete-todo reminders. - Added a toggle-list editor in
/settingsfor managing array-of-enum settings like search and image provider orders. - Added
models.ymlBedrock Converse prompt-cache capability overrides for bundled and opaque inference profiles. - Added
getServiceTiers()andsetServiceTier()extension APIs to read and modify the live per-family service tier for session requests. - Added opt-in
omp bench --cachefor independent cold/warm prompt-cache benchmarking with stable-prefix controls. - Added
tools.xdevDocsprompt-doc modes and thetools.xdevInlineDevicesglob allowlist to control which mounted device documentation is inlined into the system prompt. - Added the opt-in
read.renderMarkdownsetting for formatted Markdown read previews.
Changed
- Updated subagent behavior to inherit
async.enabledandbash.autoBackground.enabledfrom parent sessions, and refined subagent run completion to wait for background jobs to settle. - Added ordered
bash.patternscommand approval rules to allow, prompt, or deny bash commands by pattern. - Updated Markdown file handling so all Markdown flavors (
.markdown,.mdx,.mdc, etc.) respect theread.summarize.prosesetting. - Upgraded xAI web search to use
grok-4.5at low reasoning effort instead ofgrok-4.3. - Improved search provider resilience by cascading and falling back through other configured search providers when the preferred provider fails.
- Extended the bash tool's
direnvanddevenvauto-loading to all backends (including the ACP client terminal and interactive PTY) while honoringdirenv's local allow list.
Fixed
- Fixed a path traversal vulnerability in blob reference resolution by rejecting non-canonical hashes in
parseBlobRef. - Fixed multiple edge cases in the secret obfuscation and redaction engine, including handling of context-sensitive regexes, placeholder key requirements in unwritable directories, friendly-name forgery vulnerabilities, and regex match boundaries straddling existing placeholders.
- Fixed a first-use race condition in
ArtifactManagerwhere concurrent callers could allocate duplicate artifact IDs. - Fixed Vibe-mode session stability, resolving issues with workers disappearing across restarts, hanging during teardown, clobbering target tools during session switches, and resolving against incorrect models.
- Fixed concurrent MCP configuration mutations losing updates by serializing read-modify-write operations under a per-file lock with atomic writes.
- Fixed legacy extensions failing to load on npm/source-link installs due to transitive CommonJS dependency graph clobbering.
- Fixed
omp auth-gatewaycommands bypassing the process-scoped OAuth account pool configured via environment variables. - Fixed terminal transcript rendering issues where displaceable snapshots (like waiting polls and todo lists) spammed native scrollback.
- Fixed the terminal title to reflect the active agent run state (working, waiting, or blocked) when
tui.titleStateis enabled. - Fixed the
browsertool'sopenaction ignoring timeouts during browser acquisition and leaking orphaned browser instances. - Fixed the
writetool silently creating empty files when a read-tool selector was mis-dispatched as a write. - Fixed snapcompact archiving reproducing assistant reasoning (
¶think:sections) into replayed frames for Anthropic-dialect models. - Fixed Linux socket-mode DAP launches hanging indefinitely on connection failures.
- Fixed Plan Review annotations being discarded on dismissal and limited to headings.
- Fixed Assistant-mode TTS playback aborting prematurely when an agent continued after a tool call.
- Fixed absolute usage amounts rendering inconsistently across CLI, TUI, and ACP output surfaces.
- Fixed MCP sessions dropping tools from servers that finished connecting after the initial startup window.
[17.0.9] - 2026-07-23
Added
- Added per-call
modelselection to thetasktool, including per-item batch selectors, fallback chains, and explicit reasoning suffixes. - Added Firecrawl keyless mode: explicitly selecting
firecrawlas the web-search provider now works withoutFIRECRAWL_API_KEYby calling the Firecrawl REST API without anAuthorizationheader; the automatic provider chain remains credential-gated (#4332). - Added
mcp.renderMarkdownResults(enabled by default): non-JSON MCP text results render as Markdown in the terminal transcript; set it tofalseto keep raw text.
Changed
- Adjusted retry fallback handling to recognize discovery-only and runtime extension providers, preventing spurious unknown-provider warnings.
- Restored Auto QA's ask-the-user default:
dev.autoqadefaults totrueagain, so the firstxd://report_issuewrite pops the consent dialog instead of the feature being silently off. Denying consent (ordev.autoqa: false/PI_AUTO_QA=0) fully disables prompt injection; an explicitly configureddev.autoqa: trueoverrides a past denial. Also restored the #1224 guarantee lost in the xd:// device consolidation: the grievance row is inserted only after consent resolves to granted (orPI_AUTO_QA_PUSH=1), so nothing touches the local database while consent is unset or denied.
Fixed
- Fixed Auto QA grievance recording silently dropping every report since the xd:// device consolidation:
openAutoQaDbtreated the database file path (~/.omp/autoqa.db) as a directory and tried to openautoqa.db/autoqa.dbinside it, which fails on legacy installs (the flat file blocks the directory) and fresh ones alike (SQLite does not create parent directories). Also restored thebusy_timeoutpragma dropped in the same refactor (#2421). RenamedgetAutoQaDbDirtogetAutoQaDbPathto match what it returns. - Fixed the setup wizard hiding the selected row on short terminals (e.g. 24x80): the provider sign-in, theme, and web-search lists now fit their windows to the visible height, and decorative chrome (sign-in hint, theme mock preview) yields to the list when space is tight.
- Fixed restored sessions replaying terminal aborted or errored assistant turns, which could repeatedly fail continuation from an assistant role;
/retrynow consults the persisted transcript so the failed turn remains retryable without re-entering provider context. - Fixed
get_available_modelsandset_modelRPCs racing background model discovery on cold start by awaiting the in-flight refresh before reading the registry. RPC/ACP clients that query the catalog or select a model immediately after session ready previously saw only statically-bundled models until discovery completed seconds later. - Fixed deferred
--model <provider>/<pattern>CLI resolution failing on cold start with "Model not found" when the selector pointed at a discovery-backed provider (proxy / ollama / lm-studio / llama.cpp / litellm). The deferred retry now runs a cache-aware discovery pass before resolving, mirroring the default-role fallback's cold-cache race fix (issues #6114, #6162). - Fixed MCP tool calls that return a
WWW-Authenticatechallenge by preserving the structured metadata, completing the configured OAuth flow, and retrying the call once on the refreshed connection. - Fixed the Hindsight API token setting being absent from the Memory tab, so authenticated servers can be configured entirely in the TUI.
- Fixed aborted-task follow-up hints pointing at
history://transcripts that cannot resolve: the hint now reports the transcript as unavailable when the agent ref retains no session file, while still-resumable agents keep theirhubresume hint. - Fixed compiled binaries failing to load legacy Pi extensions with minified imports,
pi-ai/compat, or transitive runtime dependencies. The compatibility loader now follows compact static imports, resolves transitive on-disk ESM imports and CommonJS requires with package conditions, and restores the legacycopyToClipboardanddecodeKittyPrintableroot exports used bypi-vimmodeandpi-web-access. - Fixed a budget-aborted keep-alive subagent becoming an unkillable registration with no
hub-level stop. A subagent force-stopped for exceeding its soft request budget is kept resumable (statusidle, adopted by the lifecycle) so its context can be salvaged, but its async job row settles and is reaped after ~5 min — after whichhub cancel <id>could only reportBackground job not foundbecause it consulted the job manager alone.hub cancelnow falls through to the agent registration: for an id the caller spawned that has no live job, it aborts any in-flight turn, disposes the session, and drops the registration (the interactive Agent Hubxand collabkillalready did this; the model-facinghubdid not). Cross-agent kills stay impossible and Main/advisor refs are never targeted (#6315). - Fixed Agent Hub fallback rows hiding routing provenance and the resolved provider/model (#6316).
- Reduced format-on-write latency by avoiding cold language-server startup when diagnostics are disabled.
- Rewrote the
/guided-goalinterviewer rubric around loop-engineering: deterministic success criteria, verification commands, attempt caps, scope boundaries, and stop conditions. Ready objectives must use the five-section structured markdown form. - Added
task.isolation.apply(defaulttrue) to choose whether successful isolatedtaskruns automatically apply their changes to the parent checkout or retain patch/branch artifacts for later integration. - Added opt-in RPC protocol v2 negotiation with bounded, lossless chunking for stdout objects up to 64 MiB, plus stable cursor-based message pages for histories that should not travel as one response. Legacy JSONL clients remain on protocol v1, while the bundled TypeScript and Python RPC clients negotiate, reassemble, and drain message pages automatically.
- Fixed protocol v2 chunked framing materializing the whole base64 transport in memory: near-limit logical frames (~63 MiB) peaked around 686 MB RSS and over-ceiling frames allocated the full payload buffer before rejection. Chunk lines are now produced lazily from a single serialization, the 64 MiB ceiling is checked before any full-payload allocation, and RPC stdout writes honor backpressure line by line.
- Fixed the bundled TypeScript and Python RPC clients throwing when a
get_messages_pagecursor went stale mid-walk (e.g. a background bash appending a message between pages): the high-levelgetMessages()drains now discard partial pages and fall back to the legacy snapshot on bothsession_busyandstale_cursor, driven by a new machine-readablecodefield on RPC error responses. Direct page calls remain strict.
[17.0.8] - 2026-07-22
Added
- Added a
/treere-answer option for pastasktool results, allowing users to re-open the picker with original questions and branch the new answer as a sibling while keeping the original branch reachable. - Added configurable Hindsight client request deadlines via
hindsight.requestTimeoutMs,reflectTimeoutMs,recallTimeoutMs, andretainTimeoutMssettings (and matchingHINDSIGHT_*_TIMEOUT_MSenvironment variables). - Added
omp-linux-musl-x64andomp-linux-musl-arm64release binaries for Alpine and other musl-based Linux distributions, with automatic musl selection in the installer and self-updater.
Changed
- Optimized edit-tool previews, diff components, and intra-line word highlighting to compute line and word diffs natively, reducing synchronous diff times by 2-10x on large inputs.
- Updated diff generation and rendering components to rely exclusively on native UTF-16 diff bindings, removing
isWellFormed()guards and JS fallback code paths.
Removed
- Removed npm
diffdependency. - Fixed an issue where
Ctrl+Vclipboard paste was ignored while API-key and other modal prompts had focus. - Fixed
scripts/install.shincorrectly installing an x86_64 build on Apple Silicon when running under Rosetta. - Fixed the model picker hiding Codex models available through secondary configured ChatGPT/Codex OAuth accounts by unioning catalogs across all stored accounts.
- Fixed GitHub Copilot 1M-context models disappearing from the model picker on restart with a "Could not restore model" warning.
- Fixed
--model <role>startup selection skipping configured fallback chains when the primary model is unavailable. - Fixed global model role updates clobbering concurrent or external edits to
config.ymlby merging only the changed role instead of persisting a stale in-memory snapshot. - Fixed terminal provider errors on continuation turns after failed tool results silently ending runs without persisting the error diagnostics.
- Fixed repeated OpenRouter Gemini stream closures consuming the full retry budget by limiting recovery attempts before surfacing the error.
- Fixed Agent Hub performance freezes when opening large read-only Advisor transcripts by collapsing synthetic inputs into compact summary rows and rendering Markdown lazily on expansion.
- Fixed
/agentsincorrectly showing prewalk as disabled for the bundledtaskagent when enabled by its runtime default. - Fixed
hub startwaiting for the full timeout when a launched process exited or became ready quickly. - Fixed
tools.maxTimeoutfailing to clamp default tool timeouts when no explicit timeout was provided by the agent. - Fixed MCP argument-shaping parity between direct and subagent tool calls, ensuring strict servers do not reject proxied calls with unrecognized keys.
- Fixed a crash in extensions like
pi-mcp-adaptercaused by the TypeBox compatibility shim omittingType.Unsafe. - Fixed
omp modelshanging after output by properly clearing managed extension timers and shutting down sessions before returning. - Fixed HTML session exports causing browser call stack overflows when rendering deeply nested conversation trees.
- Fixed task agents ending prematurely on connection errors instead of entering the auto-retry path.
- Fixed a startup race condition where the default model role was incorrectly overridden by an unrelated provider's default on a cold cache.
- Fixed unqualified
--modelstartup selection preferring unauthenticated provider catalog entries over configured providers. - Fixed provider stream failures being invisible in the main log by logging a warning with error details when a turn ends in a provider error.
- Fixed parallel
todo donecalls losing completions due to asynchronous session events overwriting newer tool states. - Fixed
ompcrashing whengitis not installed or missing from the systemPATH. - Fixed
/changelogcommands reporting no entries in standalone binaries by embedding the release history as a fallback. - Fixed isolated branch merge-backs rejecting committed agent edits when the parent branch had unrelated uncommitted changes in the same file.
- Fixed the 30-second Hindsight client timeout aborting healthy
reflectoperations by applying dedicated, longer deadlines. - Fixed Mnemopi consolidation redundantly re-storing cumulative session transcripts after incremental auto-retain.
- Fixed turn-ending Codex rate-limit errors being hidden behind the Plan Review overlay.
- Fixed prewalked subagents continuing to display their starting model after switching to the target model.
- Fixed the Escape key aborting an ongoing agent turn instead of stopping text-to-speech playback.
- Fixed project system prompts shortening working directories to
~, which could cause models to generate incorrect absolute paths for tool calls. - Fixed the TUI
/usagematrix misaligning multi-account columns across quota windows. - Fixed near-miss
xd://write targets silently creating filesystem paths instead of throwing a corrective URI error. - Fixed the
tasktool rejecting valid batch calls with misleading validation errors when batching is disabled. - Fixed JS/TS
debuglaunches timing out on WSL2 with mirrored networking by waiting for the adapter's listening banner and handling transport closures immediately. - Fixed post-compaction transcript rebuilds blocking the main thread by reusing settled message components and layout caches.
- Fixed the fullscreen Plan Review overlay remaining interactive and appearing frozen during slow asynchronous operations by locking input and showing a submitting indicator.
- Fixed dynamic model discovery refreshes dropping provider-level compatibility overrides from
models.yml. - Fixed a startup crash that locked users out of the app when
prewalk.enabledwas set but the prewalk hand-off target had no configured API key. - Fixed in-progress aborts awaiting
session_stopextension handlers whose results would be discarded. - Fixed
/retryreporting "Nothing to retry" after a stream stalled or aborted mid-tool-call. - Fixed locally consumed extension commands triggering automatic title generation and exposing their command text to the title model.
[17.0.7] - 2026-07-21
Fixed
- Fixed Portkey/gateway custom models whose ids start with
@(e.g.@modal/GLM-5-2-FP8) being rewritten to unrelated bundled wire ids (e.g.glm-5-2), which caused400responses requiringx-portkey-configorx-portkey-provider.
[17.0.6] - 2026-07-20
- Fixed failed plan-mode exits leaving the session on the restored execution model while plan mode remained active and silently changing ambient
xd://tool presentation; rollback now restores the plan model, thinking level, and exact top-level-versus-mounted tool partition so exit can be retried safely (#6013).
Added
- Added native Warp CLI-agent events for rich session status, tool approvals, and completion notifications (#5592 by @metaphorics).
- Added Codex (ChatGPT subscription) support to
generate_image. The tool now resolves a connectedopenai-codexOAuth credential and drives OpenAI's hostedimage_generationtool through the ChatGPT backend (chatgpt.com/backend-api/codex/responses,chatgpt-account-idheader) independent of the active chat model — so image generation works on a ChatGPT/Codex subscription with no meteredOPENAI_API_KEY, even when the active model is Claude/Gemini/etc. A newproviders.image: "openai-codex"option forces it;autonow auto-detects a connected subscription (priority: active GPT image tool > Codex subscription > Antigravity > xAI > OpenRouter > Gemini), and theopenaipreference falls back to it when noOPENAI_API_KEY/active GPT model is present. - Added an optional
providerparameter togenerate_image(auto|openai|openai-codex|antigravity|xai|gemini|openrouter) that overrides theproviders.imagesetting for a single request — so "generate this using gemini / codex / xai" routes per-call without changing the global setting. Absent → theproviders.imagesetting applies, unchanged; the named provider uses the same resolution semantics (falls back to auto-detect if it has no credentials). File:tools/image-gen.ts(imageProviderSchema,findImageApiKeypreferencearg). - Added OpenTelemetry log and metric export alongside the existing trace export. When
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT(or the sharedOTEL_EXPORTER_OTLP_ENDPOINT) is set,ompregisters aLoggerProviderand forwards every centralized-logger event as an OTLP log record (severity + attributes + active span context for log↔trace correlation, min level viaOTEL_LOG_LEVEL, plus a structuredagent run completedsummary event). WhenOTEL_EXPORTER_OTLP_METRICS_ENDPOINT(or the shared endpoint) is set, it registers aMeterProviderwith aPeriodicExportingMetricReaderand records GenAI-semconvgen_ai.client.token.usagepluspi.omp.agent.*counters/histograms (runs, steps, chat/tool calls by name+status+finish reason, latencies, estimated cost, errors) from the agent run summary and per-chat usage hooks. Each signal honors its ownOTEL_*_EXPORTER=nonekill switch, the globalOTEL_SDK_DISABLED, and declines non-http/protobufprotocols independently (#4604). retry.fallbackChainswildcards now support id-prefixed targets and keys: a chain entry like"openrouter/google/*"re-prefixes the failing model's bare id (google-antigravity/gemini-x→openrouter/google/gemini-x), a plain"provider/*"entry falling back from an aggregator strips the vendor prefix when the target provider only knows the bare id (openrouter/google/x→google-vertex/x), and an id-prefixed key ("openrouter/google/*") scopes a chain to that provider's ids under the prefix.- The session tree selector (
/tree,/branch) now supports Shift+Enter to summarize-and-switch in one step: it forks from the selected entry with a branch summary, with no extra prompt and regardless ofbranchSummary.enabled. Plain Enter keeps the current behavior (direct switch by default; the summary prompt only whenbranchSummary.enabledis on). (#5152) - Added the turn's local timestamp (
YYYY-MM-DD HH:mm:ss, down to the second) to the per-turn token-usage row shown under assistant messages whendisplay.showTokenUsageis enabled.
Changed
- Reduced concurrent subagent update CPU by reconstructing recent output only at progress emission boundaries. (#5936)
- Fixed
docs/advisor-watchdog.mdoverstating advisor delivery for a normal yield: the severity table listedconcernas unconditionally interrupting and the prose promised a self-ended run could always be steered/resumed. Documented the #4840 terminal-answer exception (concernbecomes a passive card whileblockernormally steers, #5628) plus the plan-mode and deferred-ACP constraints that preserve would-be steers until the user resumes (#5913). - Fixed subagent (task) sessions triggering an unnecessary tiny-model session-title generation call on
todo init. Subagent sessions in a non-interactive host (print/RPC/ACP/eval/SDK/CI) have no operator-visible title and now skip the replan title refresh; interactive hosts keep it, since a live subagent focused from the Agent Hub renders its session name in the status line (#5910). - Fixed
tab.scroll()timing out after a queued wheel event waits too long for a busy renderer's acknowledgement (#5905). - Made the hashline seen-line guard opt-in and off by default (see
edit.enforceSeenLines), and stopped excluding column-clipped (>512-char) lines from a snapshot's seen set: a displayed line now counts as seen even when its display was column-truncated, so single-line edits on long lines found viaread/grepapply without a separate full-width re-read. - Changed the default
astGrep.enabledsetting tofalse - Batched todo operations with real tool calls to prevent solo todo turns and extra round trips
- Changed every bundled TTSR rule to warn without interrupting generation.
- Renamed the system prompt's project-context section wrapper from
<context>to<repo-rules>to stop it colliding with thetasktool'scontextparameter under in-band XML tool dialects: models were closing<parameter name="context">with a stray</context>(primed by the ambient section tag) and emitting sibling params as bare<tasks>elements, sotasksarrived missing. - Rendered
read xd://calls in the compact grouped read view instead of a full tool-execution card; other internal URLs (skill://,agent://, …) still render full so their resolved content stays visible.
Fixed
- Fixed the interactive
!/!!shell shortcut spawning fish as a login shell (fish -l -c …), which firedstatus is-loginblocks in user config (agent/keychain setup, PATH mutation) on every command. fish is now started with-iinstead — interactive shells source the sameconfig.fish/conf.dfiles (so aliases and functions from #1816 keep working) without login-shell side effects. zsh behavior (-l -i) is unchanged. - Fixed the status-line
tok/sbadge ignoring vibe worker sessions: in/vibemode the director is often idle while workers stream, so the badge showed a stale/zero rate while parallel work was actively generating tokens. The rate now aggregates the main session's live tok/s with every live vibe worker's tok/s, and falls back to the main session's own cached rate when no workers are streaming. - Fixed
plan.defaultOnStartupbeing ignored by headlessomp -psessions, so the initial prompt now runs in plan mode and the persisted session remains in plan mode for later review (#6017). - Fixed resuming an active plan session replacing its journal-restored model with the current
modelRoles.plansetting (#6015). - Fixed
--model <role>resolving a bare configuredmodelRoleskey. - Browser tool selectors now accept bare snapshot refs (
tab.click("e501"),@e501) everywherearia-ref=e501works — previously the tab-worker backend fell through to a CSS tag selector that could never match, burning the 2s zero-match watchdog with a misleading "matches no elements" hint.tab.select,tab.uploadFile,tab.press({ selector }),tab.screenshot({ selector }), andtab.dragnow resolve refs too. Unknown/stale refs fail immediately with the "refresh refs" error. tab.selectno longer double-reports the previously selected option of a single<select>: the returned selection is read back after the full assignment pass instead of mid-loop.- Fixed transcript blocks being visibly duplicated during streaming (whole tool boxes and assistant paragraphs recommitted below their first copy on the terminal tape) by removing transcript committed-prefix compaction entirely. Dropping committed rows from the transcript's local frame shifted the frame under the engine's committed-prefix ledger, so the audit re-anchored and recommitted rows the tape already held. The transcript now always keeps its full local frame; committed finalized blocks still skip
render()via the segment reuse bypass. Reverts the compaction half of #5930's fix (compose keeps the render bypass; the local frame is no longer truncated). - Fixed tmux pane growth during a live response blanking finalized chat history re-exposed from native scrollback by rebasing the in-place repaint's commit seam to the resized viewport tail (#6011).
- Fixed classifier refusals (e.g. Anthropic
stop_reason: "refusal") ending the turn with no visible error. Two independent regressions: (1) session events reached subscribers out of order when a turn's provider events landed in one tick — extension emits only await for event types with registered handlers, so the assistantmessage_endovertook its ownmessage_startand the TUI skipped the error render entirely (no pinned banner, no inlineError:line); subscriber fan-out is now serialized in emission order. (2) Refusal turns are pruned from active context at settle (#3591), which also erased them fromstate.messagesbeforeprompt()resolved — print mode printed nothing and exited 0, and the task executor'sgetLastAssistantMessage()saw the previous turn. The pruned refusal is now retained until the next run starts,getLastAssistantMessage()reports it, and print mode reads the settled assistant via that accessor (exit 1 + refusal message on stderr). Additionally,#lastAssistantMessageis now set synchronously onmessage_endto preventagent_endmaintenance from reading a stale assistant turn when tool results and stops land in the same tick. - Fixed
before_provider_requestextension contexts exposing the primary session model for cross-provider Advisor requests instead of the request model (#6006). - Fixed isolated
tasksubagents mutating the parent checkout and stacking parallel task branches. Copy isolation backends (reflink/apfs/btrfs/zfs/block-clone/rcopy) materialise the worktree by duplicating its.gitverbatim; when the parent is a linked git worktree its.gitis a pointer file, so the isolation shared the parent's HEAD/index/ref namespace and a task'sgit checkout/commitmoved the parent's branch (and the rcopygit worktree addpath leaked task branches into the shared namespace so a second task committed on top of the first).ensureIsolationnow runs a newgit.detachGitDirafterisoStart: each isolation becomes a standalone repo with a frozen HEAD/refs/index snapshot that borrows the source object database throughobjects/info/alternates, so isolated git operations stay private, every task branch is parented on the requested base, and patch/branch capture (git fetch <merged>) still resolves objects. (#6003) - Fixed
browser.runleaving Puppeteer request handlers and interception state with divergent lifetimes by removing run-scoped handlers, disabling interception, and releasing held requests on every exit path (#6004). - Fixed Codex web search to honor configured
openai-codexbase URLs, API keys, and headers without leaking official OAuth credentials to custom endpoints; explicitly selected providers now fail closed instead of silently falling back (#6001). - Fixed
launch startwaiting for a finite PTY command to exit when the broker's PID-file handoff was unavailable; PTY startup now reports the spawned PID directly and returns an authoritative running or exited snapshot promptly (#5996). - Fixed queued user steering aborting side-effecting
hub startcalls after the broker request may already have been written; only passive hub waits and followed logs are now interruptible (#5995). - Fixed JavaScript/TypeScript debugging by launching vscode-js-debug over TCP, handling recursive
startDebuggingchild sessions, synchronizing breakpoints across the session tree, and terminating every child connection (#5984). - Fixed rich ask options showing preview content only for the highlighted choice; every option now renders its preview inline, with pageable long content and accurate configured paging and cancel hints (#5988 by @metaphorics).
- Fixed legacy pi extensions failing extension validation when importing
getPackageDirorgetProjectDirfrom@earendil-works/pi-coding-agent(aliased to the legacy shim). The shim only re-exportedgetAgentDir; the two missing path helpers now resolve —getProjectDirfrom@oh-my-pi/pi-utils, andgetPackageDiras a string-valued wrapper over omp's canonical package-root helper that falls back to the executable's directory insidebun --compilebinaries (where the canonical helper returnsundefined), matching pi's string contract. Extensions like@gotgenes/pi-permission-systeminstall and load, andpath.join(getPackageDir(), …)no longer crashes in the shipped binary (#5968). - Fixed headless print mode disposing the session before a final advisor review completed, which could drop the advisor transcript and usage (#5942).
- Fixed capped zero-block assistant stops remaining in active/session history with the full failed-request usage, causing the next post-snapcompact
continueto re-enter context maintenance at the same boundary; capped empty turns are now discarded and the failure names model switching or/shake imagesas recovery options (#5959). - Long sessions no longer re-run
convertToLlmover settled history every turn. Conversion is memoized per message identity (plus the assistantinterruptedNextneighbor flag): an exact re-convert of the same array reuses the outerMessage[], append-only growth reuses the converted prefix via slice-on-growth, and the prune/shake/strip-images/prewalk-scrub rewrite seams invalidate the affected message before the next pass. On thellm-assemblybench (N=5000) steady/append convert and repeat estimate are all >10x faster with robust MAD-noise well under 20% (#5934). - Fixed
/exithanging on post-prompt work and stacking independent subsystem teardown delays by bounding the aborted-work drain, disposing independent session resources concurrently, and keeping long shutdown waits visible (#5932). - Fixed queued-message display updates being skipped by focused-editor keystroke frames by explicitly repainting the pending-message container (#5928).
- Fixed RPC and RPC-UI startup crashes when an in-process extension claimed Bun's singleton stdin stream before the protocol reader (#5898).
- Bash command timeouts now render with a warning (yellow) border instead of an error (red) border, reflecting that the timeout ran its course rather than the command failed.
isErrorremainstrueon the result so the model still knows the command did not complete normally. ThetimedOutflag is now propagated from the bash executor to distinguish timeouts from user aborts. - Fixed Cursor responses streams stalling after an exec-channel tool completed without automatically recovering. The session now continues from the already-buffered tool result instead of replaying the side-effecting request. (#5790)
- Fixed linked legacy pi extensions failing to load when they import
DefaultPackageManageror linkedom: the coding-agent compatibility shim now enumerates OMP extension paths with plugin metadata, and extension-graph CommonJS modules load through synchronous default-export bridges with linkedom's bundled canvas fallback. (#5658) - Fixed the advisor retrying terminal, non-retriable provider failures (e.g. blocked prompts) three times before giving up; such failures now drop the bounded batch after a single attempt while transient failures keep the 3-attempt retry path (#5468).
- Fixed reassigning the
planrole model mid-planning not taking effect on the active planning turn; the change now applies at the next turn boundary instead of only the next plan-mode entry (#5657). - Added managed
ctx.setInterval/ctx.setTimeout/ctx.clearTimerhelpers on the extension context. Callbacks scheduled through them run with the same isolation as handler dispatch — a throw or rejected promise is logged and reported through the extension error channel instead of escaping as a process-fataluncaughtException— and every outstanding timer isunref'd and cleared automatically onsession_shutdown(#5664). - Fixed an extension's self-scheduled
setInterval/setTimeoutcallback throwing being able to tear down the whole session. Such callbacks ran outside the handler-dispatch try/catch, surfaced as a process-leveluncaughtException, and the global postmortem handler treated them as fatal; extension authors now have sanctioned managed timers (see Added), and the constraint is documented indocs/extensions.md/docs/skills/authoring-extensions.md(#5664). - Fixed
/quitand/exitleaving failed or stalled automatic title-generation requests alive during session teardown; disposal now aborts both online provider and local tiny-model title requests (#5666). - Fixed
startup.quietstill rendering thexdev: xd://: mounted …status line when MCP tools connect; quiet startup now suppresses only the user-visible mount notice while retaining the hidden model-facing device update (#5670). - Fixed command error in
hubtool with a non-POSIX shell (#5682) - Fixed xdev-routed checkpoint and rewind writes not tracking checkpoint state and leaving rewinding results in rebuilt provider and session context.
- Fixed the built-in advisor silently doing nothing when its model routes through the
cursorprovider: the advisor runs in its ownAgentthat was constructed withoutcursorExecHandlers, so on Cursor — where every tool executes server-side and is dispatched back through the client's exec handlers — each advisor tool call (including the MCPadvisetool) came backtoolNotFound/"tool not available" and no advice was ever routed. The advisorAgentnow gets a Cursor exec bridge scoped to its own granted tool set, mirroring the primary agent. The bridge's nativedeleteframe is gated so a read-only advisor cannot delete workspace files it was never granted a mutating tool for (#5680). - Fixed the fullscreen plan-review overlay staying visible until the approved execution turn finished, so after picking "Approve and keep context" (or any approve option) work proceeded underneath while the operator was stuck on the plan-review screen. The overlay is now hidden once execution begins — after the async transcript rebuild, before the blocking synthetic prompt is dispatched — instead of only after the whole turn returns (#5688).
- Fixed MCP tools repeatedly unmounting and remounting mid-session when server names have overlapping sanitized prefixes (e.g.
atlassianalongside an importedatlassian:atlassian), and stale tools remaining registered after disconnecting a server with special characters in its name. - Fixed the
/usage showin use by this session:marker showing only the login email, so two same-email Anthropic credentials in different orgs (a Team seat and a personal Max plan) were indistinguishable. The marker now suffixes the active organization (email (OrgName)) via a sharedformatActiveAccountLabel, matching the account list and login-success surfaces (#5691). - Fixed Windows stdio MCP servers launched through
.cmd/.batshims failing withTransport closed; the launch now builds acmd.exe /d /e:ON /v:OFF /ccommand line escaped forcmd.exe's parser and spawned withwindowsVerbatimArguments, so the resolved command path and arguments (including%VAR%, quotes, and shell metacharacters) reach the server intact and cannot inject commands (BatBadBut / CVE-2024-24576) (#5696). - Fixed the TUI usage panel truncating organization suffixes from same-email account labels even when the terminal has enough width (#5701).
- Fixed a startup crash on Windows when running from a drive root (e.g.
R:\):fs.realpaththrowsEISDIRthere, butcanonicalProjectDirinlaunch/presence.tsandlaunch/client.tsonly recoveredENOENT. It now also falls back topath.resolve()onEISDIR(#5708 by @ve3xone). - Fixed unknown
__omp_worker_*CLI selectors exiting 0 with empty output instead of erroring; an unrecognized worker-host selector now writesError: unknown worker selector: …to stderr and exits nonzero, so a stale or mistyped selector can no longer look healthy to a parent process or install smoke path (#5712). - Fixed Plan Review capturing mouse drags as pointer events, preventing native terminal text selection (#5711).
- Fixed orphaned TUI processes with revoked terminal descriptors remaining alive after a fatal error and amplifying shared log-rotation races into runaway memory, file-descriptor, swap, and disk consumption (#5716).
- Fixed approved-plan execution looping through filesystem searches when a model rewrites the required
local://<slug>-plan.mdread as a same-basename working-directory path; a missing cwd-root alias now recovers the active session-local plan while preserving any real working-tree file (#5704). - Fixed Ask dialogs immediately accepting their highlighted single-select answer when they appear while the user is typing a space in the prompt editor (#5717).
- Stopped post-compaction auto-continue from opening another primary turn after a terminal text answer with no queued work, and moved automatic auto-learn capture into an abortable private agent with only
manage_skillandlearntools (#5715). - Fixed the
writeapproval gate misclassifyingxd://device writes asexecwhen the mounted tool declared a function-valued (argument-dependent)approval: the gate discarded the function and never decoded the device JSON payload, so read/write device operations prompted in non-yolo modes their approval mode permits. It now parses valid object payloads and evaluates the mounted tool's normal approval decision, while malformed JSON, non-object payloads, and unknown devices still fall back toexecand prompt (#5727). - Fixed custom LSP servers such as
roslyn-language-servercrashing after initialization when they request unconfiguredworkspace/configurationsections; missing settings now receive the spec-requirednullinstead of{}(#5745). - Fixed late user-initiated bash results and minimized-output artifacts being recorded in whichever session or branch was active when execution finished; bash now retains its originating transcript across
new_session/switch_session/branch/tree navigation, and an intentionally dropped session stays deleted instead of being recreated by a straggling result (#5743). - Fixed Claude Code marketplace plugins with
scope: "local"leaking skills, hooks, tools, commands, and MCP servers into unrelated projects (#5750). - Fixed headless
omp -pwaiting indefinitely after a completed turn when final mnemopi consolidation stalls; print mode now applies the same bounded consolidation shutdown budget as interactive exit and reaps the embed worker (#5753). - Fixed explicit-tool sessions bypassing
xd://presentation for ambient discoverable custom and MCP tools, which sent their schemas top-level and could exceed provider tool limits or trigger schema-compatibility errors. - Fixed
providers.webSearch: kimisending a Moonshot Open Platform credential (MOONSHOT_API_KEY/ storedmoonshotauth) to the Kimi Code search endpoint (api.kimi.com/coding/v1/search), which rejects it with401and silently falls back to another provider. Kimi web search now resolves and advertises Kimi Code credentials only — a Kimi Code Console key viaKIMI_SEARCH_API_KEY/MOONSHOT_SEARCH_API_KEYoromp /login kimi-code(#5762). - Fixed extension/SDK/RPC
registerTooldemoting essential built-ins (read/write/bash/edit/glob/…) todiscoverablewhen a re-registration omittedloadMode, which — withtools.xdevon — unmounted them from the top-level schema and broke thexd://transport (read xd:///write xd://), leaving the model with no callable coding essentials. OmittedloadModenow defaults to"essential"for known essential built-in names at every adapter boundary, andread/write(the transport itself) are never mounted under xdev regardless ofloadMode(#5764). - Fixed the advisor skipping the next real user instruction after auto-learn accepted and pruned a terminal empty assistant stop; advisor transcript cursors now detect rewritten prefixes and re-prime before slicing the next update (#5731).
- Fixed built-in advisors retrying a quota- or rate-limited provider until becoming unavailable instead of applying the matching
retry.fallbackChainsmodel chain; advisor fallbacks now emit the same applied and succeeded lifecycle events as primary-agent fallbacks (#5740). - Made the model selector status messages use the role tag (
SMOL,SLOW) instead of the display name (Fast,Thinking), matching the rest of the TUI and CLI/env role terminology (#5585). - Fixed Cursor models receiving only top-level tools by forwarding mounted
xd://devices, including user-configured MCP servers, through Cursor's request-context MCP catalog and execution bridge (#5650). - Fixed Windows bash crashes when a piped command times out while flushing output; explicit-timeout watchdogs now wait for bounded native teardown instead of returning mid-drain. (#5316)
- Fixed a race where hub/IRC
sendandensureLivecould hand out or inject into a subagent session mid-parkdispose: park now detaches and flips status toparkedbeforesession.dispose(), concurrentensureLivecancels a pre-detach park or waits then revives, and IRC delivery always gates throughensureLiveso receipts/unread counts stay truthful (#5633). - Migrated legacy
dev.autoqa.consent→dev.autoqaConsentandtodo.reminders.max→todo.remindersMaxon settings load so pre-v17 nested or quoted-dotted config no longer leaves the parent path as an object (which madedev.autoqatruthy and enabled Auto QA, and discarded the reminder limit). Explicit new keys win, a separately configured parent boolean is preserved, an irrecoverable object parent falls back to the schema default, and only the new keys persist on save (#5632). - Fixed all keyboard input dying after the first keypress when a
~/.claude/tools(or.omp/tools) module attaches a stdin consumer at import time — e.g. an MCPStdioServerTransportconstructed at module top level, or a bareprocess.stdin.resume(). The custom-tool/extension/hook/plugin loader guard now snapshots and restoresprocess.stdin(listeners, paused state, raw mode) around third-party module evaluation, so a hijacked stdin reader can no longer starve the TUI's own listener (#5618). - Fixed the ask tool's "Other" custom-input dialog rendering the title, options, and hint one column to the right of the
>input gutter; the prompt-style editor chrome now aligns to column 0 (#5313) - Fixed advisor context maintenance undercounting the provider context: the compaction decision now anchors on the advisor's provider-reported context usage (cached input + generated output) floored by a full local estimate that includes the advisor system prompt and tool schemas, rejects stale provider usage retained across advisor compaction, and recovers a provider overflow by clearing only the advisor's own context at the current primary cursor — retrying the bounded failing batch once against a fresh context without replaying old primary history and keeping later updates eligible (#5282)
- Fixed RPC mode (
--mode rpc) crashing the whole process with an uncaughtSyntaxError: Failed to parse JSONLon any non-JSON stdin line. Malformed lines are now reported via aFailed to parse commanderror frame and the frame loop keeps running. (#5194) - Fixed the status line loop indicator to distinguish waiting, running, and paused states and show the remaining loop budget (#5832 by @wolfiesch).
- Fixed single-model task agents ignoring an explicitly configured default retry fallback chain, which left subagents failed after their selected provider became unreachable instead of advancing to the configured fallback model.
- Fixed the
/extensionsdashboard tab labeled "Agents (standard)" being confused with the/agentssubagents feature — the.agent/.agentsconfig-standard provider now presents as "Agent Dirs (.agent/.agents)" since it lists skills, rules, prompts, commands, and context/system files, never subagents (#5821). - Fixed non-raw
readline selectors returning context outside the requested inclusive range (#5802). - Fixed LSP requests silently clamping explicit timeouts above 60 seconds by supporting documented budgets up to 300 seconds (#5804).
- Clarified async task and hub guidance: inspecting a settled job consumes its automatic delivery, job IDs expire from process memory after roughly five minutes, and completion does not verify claimed artifacts (#5869).
- Fixed
vibe_waitTV-wall panels stacking duplicate frozen frames in native scrollback while two or more workers were live (#5777). - Fixed async task job rows omitting resolved subagent model and reasoning badges when
task.showResolvedModelBadgeis enabled. (#5060) - Fixed raw Puppeteer
page/browserpromises from crashing inline browser workers or killing dedicated workers when a target closed before the caller awaited the promise. - Fixed auto-compaction dead-ending in a warning loop ("Compaction freed too little context to make progress") when the single most-recent turn is itself over budget so
prepareCompactionhas nothing to summarize (findCutPointnever cuts inside a tool result). This!preparationshort-circuit never ran the artifact-backedshakeelide rescue that #3786 added to the post-maintenance guard, so snapcompact/context-full maintenance paused with no attempt to shrink the oversized tail. The dead-end now runs the same elide pass, re-prepares on the shrunken branch, and falls through to a normal compaction when the tail became summarizable — only pausing (single warning) when nothing is elide-eligible. (#4786) - Fixed GitHub-hosted repository file reads falling back to
curlby adding a dedicatedgithubfile-read operation and explicit tool-routing guidance (#4805). - Bounded RPC JSONL frames to 1 MiB, compacted oversized
agent_endframes without losing complete Python prompt results, and guaranteed worker reaping plus pending-request rejection after output-reader failures or explicit stops (#5405). - Fixed
web_searchbeing unreachable under default config: withtools.xdev: true, the discoverableweb_searchtool was mounted underxd://and dropped from the top-level toolset, so models calling it directly got "Tool web_search not found". It is now pinned top-level viaXDEV_KEEP_TOP_LEVELwhile other discoverable tools keep mounting underxd://(#5973). - Fixed onboarding omitting model selection by adding a persisted default-model step (fresh installs only — the setup version is not bumped, so existing installs are not re-prompted), and documented custom
models.ymlprovider configuration and default-role selection (#5979). - Fixed
autoResumecrossing an explicit/newboundary: after/newa new session's JSONL is created lazily (only once assistant output exists), so exiting before any assistant message left the per-terminal breadcrumb pointing at a not-yet-materialized file.readTerminalBreadcrumbEntryrejected the missing target andcontinueRecent()fell back to the most-recent session — the pre-/newtranscript — processing the next prompt with stale context./newnow records a durablefreshbreadcrumb boundary thatcontinueRecent()honors (starting fresh) even when the target is absent, while a genuinely stale/deleted breadcrumb still falls back to the most-recent session (#5730). - Fixed subagents that repeatedly submit malformed
yieldresults from leaving the parent waiting forever; malformed submissions now repeat the required response format, and repeated invalid submissions fail the child with a clear error. (#4957) - Fixed configured or
-eextensions in compiled binaries failing to resolve bundled@oh-my-pi/*value imports through theomp-legacy-pi-bundled:registry, and surfaced extension load failures during interactive and-psession startup. (#4954)
Removed
- Fixed the Cursor-backed advisor losing entire turns when it selected server-native tools (
bash,grep, etc.) outside its grant: exec-resolved native blocks are already rejected in-band by the advisor-scoped bridge, so they no longer trip the unavailable-tool quarantine and discard theadviseemitted in the same turn (#5900). - Fixed custom
anthropic-messagesOAuth providers being unable to opt into configured Claude Code fingerprint header overrides. (#5888) - Fixed authoritative providers (e.g.
openai-codex) keeping unsupported bundled models selectable when a fresh model cache and an expired OAuth token coincided: built-in discovery now forces the OAuth refresh so the provider's model manager is constructed and prunes stale bundled entries (e.g.gpt-5.4-nano) instead of waiting out the cache TTL. (#5364)
[17.0.5] - 2026-07-18
Added
- Added support for Codex (ChatGPT subscription) in
generate_imagevia theproviders.image: "openai-codex"option, including automatic subscription detection and fallback logic. - Added an optional
providerparameter togenerate_imageto override the global image provider setting for a single request. - Added OpenTelemetry log and metric export capabilities alongside existing trace exports, supporting standard OTLP environment variables.
- Added support for id-prefixed targets and keys in
retry.fallbackChainswildcards (e.g.,"openrouter/google/*"). - Added support for
Shift+Enterin the session tree selector (/tree,/branch) to summarize and switch branches in a single step. - Added the
PI_CONFIG_FILESenvironment variable to load settings overlays before--configoverlays.
Changed
- Changed bundled TTSR rules to warn instead of interrupting generation.
- Renamed the system prompt's project-context section wrapper from
<context>to<repo-rules>to prevent XML tag collisions with in-band tool dialects. - Renamed the
/extensionsdashboard tab "Agents (standard)" to "Agent Dirs (.agent/.agents)" to clarify its purpose. - Optimized performance by reducing concurrent subagent update CPU usage, skipping unnecessary title generation in non-interactive hosts, and memoizing
convertToLlmconversions over settled history. - Improved the display of
read xd://calls by rendering them in a compact grouped view instead of full tool-execution cards. - Made the hashline seen-line guard opt-in and off by default via
edit.enforceSeenLines.
Fixed
- Fixed isolated
tasksubagents mutating the parent git checkout and stacking parallel task branches by detaching the git directory. - Fixed Windows compatibility issues, including
launch startdaemons opening visible console windows, startup crashes when running from a drive root, and command errors in thehubtool with non-POSIX shells. - Fixed Windows stdio MCP servers launched through
.cmd/.batshims failing withTransport closedby escaping arguments properly. - Fixed browser tool selectors (
tab.click,tab.select, etc.) to accept bare snapshot refs (e.g.,tab.click("e501"),@e501) and resolved crashes when handedElementHandleobjects. - Fixed classifier refusals (e.g., Anthropic
stop_reason: "refusal") ending turns with no visible error or exiting 0 in print mode. - Fixed transcript blocks being duplicated during streaming and tmux pane growth blanking finalized chat history.
- Fixed JS/TS debugging by launching vscode-js-debug over TCP and synchronizing breakpoints across the session tree.
- Fixed legacy pi extensions failing validation or loading when importing path helpers or package managers.
- Fixed
/loginand/logoutfailing to refresh model discovery with fresh credentials due to stale cached data. - Fixed Cursor models and advisors failing to receive or execute mounted
xd://devices and MCP tools. - Fixed MCP tools repeatedly unmounting/remounting with overlapping sanitized prefixes, and stale tools remaining after disconnecting.
- Fixed custom LSP servers crashing when requesting unconfigured
workspace/configurationsections. - Fixed keyboard input dying after the first keypress when custom tools or modules hijack stdin at import time.
- Fixed auto-compaction dead-ending in a warning loop when the most recent turn is over budget.
- Fixed GitHub-hosted repository file reads falling back to
curlby adding a dedicatedgithubfile-read operation. - Fixed active session markers and TUI usage panels truncating organization suffixes from same-email account labels.
- Fixed
writeapproval gates misclassifyingxd://device writes asexec. - Fixed bash command timeouts rendering with an incorrect error border, and resolved Windows bash crashes when piped commands time out.
- Migrated legacy nested/quoted-dotted config keys (e.g.,
dev.autoqa.consent->dev.autoqaConsent) on settings load. - Added managed
ctx.setInterval/ctx.setTimeout/ctx.clearTimerhelpers on extension contexts to prevent uncaught exceptions from crashing sessions.
[17.0.4] - 2026-07-18
Fixed
- Fixed bundled Linux ffmpeg recording by selecting its available ALSA input when PulseAudio support is absent, and surfaced recorder stderr when capture fails (#5907).
- Session load now skips the recursive async blob-ref resolver for entries with no
blob:sha256:references. A cheap synchronous precheck gates the walk per entry (preserving the previous per-entry initiation order under synchronous store mutation), so text-heavy histories no longer pay thePromise.alltree descent for every non-session entry (#5922). - Fixed
tasktool schemas emitting boolean subschemas that llama.cpp grammar generation cannot parse (#5957). - Fixed the transcript keeping finalized assistant blocks in the live compose walk after their rows entered native terminal scrollback, making each stream tick's
TranscriptContainer.renderdepth-linear in session length. Fully committed finalized blocks are now compacted out of the local frame regardless of post-finalize version tracking; a later mutation no longer recommits on ordinary frames (no duplication) and rehydrates on the next destructive full replay (no loss). Compose cost for a live tail tick is now flat as depth grows (bench/transcript-compose.bench.ts: ratio(N5000/N500) 2.30 → 0.90) (#5930). - Fixed
/quitand/exithanging during interactive shutdown by making the mnemopi dispose path retain the current session and flush in-flight extractions without sleeping the bank; the/memory enqueuepath and end-of-session backend enqueue still perform full cross-session consolidation. (#3641) - Fixed interactive bash shortcut
cdcommands leaving the OMP session and status-line working directory unchanged.
[17.0.3] - 2026-07-17
Changed
omp usageand the in-session/usageview now show the Anthropic organization next to the account for org-scoped credentials (with--redactmasking applied per part in the CLI, falling back to the org id when no display name is available), attribute "no usage data" rows per organization, and match the "in use by this session" marker by organization so only the active subscription is flagged. The OAuth login success message names the account and organization that was stored — a login landing on an unintended subscription is visible immediately./logoutlabels Anthropic accounts with their organization and marks only the credential of the active organization as active;omp token --listshows the organization next to each account. Two subscriptions sharing one email are distinguishable when selecting which to remove or mint a token for.omp auth-broker migrate --from-localdedupes Anthropic OAuth identities per organization, so a Team seat already on the broker no longer blocks uploading the personal plan under the same email.- The status line invalidates its cached usage when the session rotates to a different Anthropic organization (previously the old subscription's quota could linger for the cache TTL), and
omp auth-gateway checklabels each credential with its organization so a failing row says which subscription needs re-login. omp usage"no usage data" attribution is org-decisive whenever either the stored account or a report carries an organization: an org-less legacy credential whose own fetch failed is no longer hidden by an org-attributed sibling report sharing the same email.- Active-account matching for
/usage,/logout, andomp token --listnow treats a shared organization as a qualifier rather than a match: two Anthropic Team seats in one org (same org id, per-user pools) no longer flag each other's rows or reports as "in use by this session" — the base identity (account/email/project) is still required, with org-only sessions matching on the org alone. omp usage"no usage data" coverage now requires the member's own identity within a shared organization: a sibling Team member's same-org report no longer counts as coverage for an account whose own report is missing, while an org-only account remains covered by any same-org report.omp auth-broker migrate --from-localreruns now recognize an already-migrated org-only Anthropic row (login recovered neither email nor account) by its organization id instead of re-uploading it, which could overwrite the broker's newer refresh token with the stale local one.- Updated tangential agent forks to ignore parent session history and focus exclusively on the new request
- Hardened
/tanfork isolation: the clone's inherited todo list is cleared at fork (parent todo reminders no longer drag the tan back onto the parent's task), the fork notice warns that the parent is concurrently editing the same working directory, and the notice is re-injected after each compaction so the fork boundary survives summarization - Added visual markers in the transcript for elided tool calls that have no corresponding result
- Updated status event log to prioritize the most recent entries in the display window
- Updated the snapcompact shape preview transcript to use the compact scope format shown to models during compaction.
Fixed
- Fixed
xd://mount notices triggering unsolicited model turns by deferring hidden notices until the next user prompt. - Fixed
xd://device tools appearing in the direct tool inventory and prompting invalid function calls (#5797). - Fixed
history://read selectors being treated as part of the agent id instead of paging the transcript (#5806). - Narrowed the
history://contract in the system prompt to match the implementation: it serves registered agents process-wide plus persisted subagents discoverable from their artifact trees, but does not discover unregistered top-level sessions solely from persisted session files (#5839). - Fixed expanded
!bash andevaloutput keeping a stale… N more lines (ctrl+o to expand)footer after Ctrl+O revealed every line (#5842). - Fixed MCP reauthentication continuing to an authorization URL without
client_idafter dynamic client registration fails; the registration error now blocks the flow with the provider response details (#5852). - Fixed collapsed todo views hiding the in-progress task in large phases. Both the transient
Todotool result and the stickyTodosHUD now share one walking-viewport policy: completed/abandoned tasks are omitted, every active task (the in-progress one, or a pending task a live subagent is executing) is pulled to the head in todo order, remaining rows fill with the following pending tasks, and an explicit… N more active todossummary is shown when active work alone exceeds the preview cap (#5873). - Fixed legacy provider extensions failing to load when they use the historical synchronous auth-storage surface (#5879).
- Fixed orphaned detached MCP stdio server process trees surviving session dispose by escalating stdin-EOF → group SIGTERM → group SIGKILL on close() (#5578)
- Fixed
/newstarting an unsolicited old-context provider turn when a hidden steer (e.g. anxd://mount notice) was queued: the session transition is now an atomic boundary, so a queued steer/follow-up can no longer auto-resume against the pre-/newcontext while the session is disconnected mid-transition./compactstill resumes a steer/follow-up that arrives while it runs, draining the queue once it reconnects (#5800). - Fixed signed thinking-only Claude stops being discarded and retried as empty responses (#5881).
- Fixed repeated URL reads and URL-backed searches returning stale same-session responses instead of refetching the resource (#5803).
- Fixed
read/writenot recognizing ZIP-based.jar/.war/.ear/.apkfiles as archives, soread lib.jar:META-INF/MANIFEST.MFfailed with path-not-found (#5808). - Fixed legacy binary
.doc/.ppt/.xls/.rtfbeing advertised as convertible inread,fetch, and CLI@filehandling despite having no markit converter, which surfaced anUnsupported formaterror instead of falling through to normal file handling (#5808). - Fixed Kimi Code transport selection to follow live per-model protocol metadata by default while preserving explicit OpenAI and Anthropic overrides (#5893).
- Fixed repeated edit-tool rejections from local models by recovering comma-separated ranges and malformed trailers, while clarifying canonical string input and
.=syntax (#5805). - Fixed LSP diagnostics and edit-time diagnostics writethrough for pull-only servers that advertise
textDocument/diagnosticstatically or through dynamic registration (#5825). - Fixed local
!command output concatenating carriage-return progress updates by preserving them as readable line boundaries (#5845). - Fixed
hub/ircpeer discovery after process-crash resume by restoring persisted subagents as parked peers before listing the roster (#5864).
Removed
- Removed the unreliable Bing and Yahoo HTML-scraping web search providers
[17.0.2] - 2026-07-17
Added
- Added native Warp CLI-agent events for rich session status, tool approvals, and completion notifications.
- Added support for ChatGPT/Codex subscriptions in the
generate_imagetool, allowing image generation without a meteredOPENAI_API_KEYeven when using other active models. - Added an optional
providerparameter togenerate_imageto override the globalproviders.imagesetting for a single request. - Added OpenTelemetry log and metric export support alongside existing trace exports, enabling forwarding of centralized-logger events and GenAI-semconv metrics when configured.
- Enhanced
retry.fallbackChainswildcards to support id-prefixed targets and keys, allowing more flexible model fallback routing across different providers. - Added an opt-in per-project model role storage mode with global fallback from the model selector.
- Added per-advisor on/off toggle (
enabled: falseinWATCHDOG.yml): advisors stay in the roster but their runtime is never built — they show○in/advisor statusrather than disappearing. Existing configs are backward-compatible (defaults totruewhen absent). - Colored the status line's advisor
++badge by roster health (green all running, yellow quota-exhausted, red failed, dim paused); per-advisor glyphs (●/○/✕) show in/advisor status. - Added real provider quota display (usage percent, window, reset timer) to
/advisor statusand the/advisor configurepreview.
Changed
- Changed Bash command timeouts to render with a warning (yellow) border instead of an error (red) border, while still indicating to the model that the command did not complete normally.
- Made the hashline seen-line guard opt-in and off by default via
edit.enforceSeenLines, and improved handling of column-clipped lines so single-line edits on long lines apply without a full-width re-read. - Changed bundled TTSR rules to warn without interrupting generation.
- Renamed the system prompt's project-context section wrapper from
<context>to<repo-rules>to prevent collisions with thetasktool'scontextparameter. - Enriched
/advisor statusto show per-advisor status glyphs, model, spend breakdown, and quota window for every configured advisor (including disabled ones), replacing the previous single-advisor-only summary.
Fixed
- Fixed loading issues for linked legacy extensions importing
DefaultPackageManagerorlinkedom. - Fixed the advisor retrying terminal, non-retriable provider failures (e.g., blocked prompts), ensuring they fail immediately while transient failures still retry.
- Fixed an issue where reassigning the
planrole model mid-planning did not take effect until the next plan-mode entry; it now applies at the next turn boundary. - Added managed timer helpers (
ctx.setInterval,ctx.setTimeout,ctx.clearTimer) to the extension context to prevent self-scheduled callbacks from throwing uncaught exceptions and crashing the session. - Fixed
/quitand/exitleaving stalled automatic title-generation requests alive during session teardown. - Fixed
startup.quietstill rendering thexdev: xd://: mountedstatus line when MCP tools connect. - Fixed command errors in the
hubtool when using a non-POSIX shell. - Fixed xdev-routed checkpoint and rewind writes not tracking checkpoint state.
- Fixed the built-in advisor silently failing when its model routes through the Cursor provider by adding a Cursor execution bridge scoped to its granted tool set.
- Fixed the fullscreen plan-review overlay staying visible until the approved execution turn finished; it is now hidden as soon as execution begins.
- Fixed MCP tools repeatedly unmounting and remounting mid-session due to overlapping sanitized prefixes, and resolved stale tools remaining registered after disconnecting a server with special characters.
- Fixed the
/usage showmarker and TUI usage panel to display and preserve the active organization suffix (email (OrgName)) to distinguish between multiple credentials with the same email. - Fixed Windows stdio MCP servers launched through
.cmdor.batshims failing withTransport closedby properly escaping arguments and spawning withwindowsVerbatimArguments. - Fixed a startup crash on Windows when running from a drive root (e.g.,
R:\). - Fixed unknown
__omp_worker_*CLI selectors exiting with code 0 instead of throwing an error. - Fixed Plan Review capturing mouse drags as pointer events, which prevented native terminal text selection.
- Fixed orphaned TUI processes remaining alive after a fatal error and causing high resource consumption.
- Fixed approved-plan execution looping through filesystem searches when a model rewrites the required plan read path.
- Fixed Ask dialogs immediately accepting highlighted answers when they appear while the user is typing a space.
- Stopped post-compaction auto-continue from opening another primary turn after a terminal text answer with no queued work.
- Fixed the
writeapproval gate misclassifyingxd://device writes asexecwhen the mounted tool declared a function-valued approval. - Fixed custom LSP servers (such as
roslyn-language-server) crashing when requesting unconfigured workspace configuration sections. - Fixed late user-initiated bash results being recorded in whichever session or branch was active when execution finished; they now retain their originating transcript.
- Fixed Claude Code marketplace plugins with
scope: "local"leaking skills, hooks, tools, commands, and MCP servers into unrelated projects. - Fixed headless
omp -pwaiting indefinitely after a completed turn when final consolidation stalls. - Fixed explicit-tool sessions bypassing
xd://presentation for ambient discoverable custom and MCP tools. - Fixed
providers.webSearch: kimiincorrectly sending Moonshot credentials instead of Kimi Code credentials. - Fixed
registerTooldemoting essential built-in tools todiscoverablewhen a re-registration omittedloadMode. - Fixed the advisor skipping the next user instruction after auto-learn accepted and pruned a terminal empty assistant stop.
- Fixed built-in advisors retrying quota- or rate-limited providers instead of applying the matching
retry.fallbackChainsmodel chain. - Updated model selector status messages to use role tags (
SMOL,SLOW) instead of display names (Fast,Thinking) for consistency. - Fixed Cursor models receiving only top-level tools by forwarding mounted
xd://devices through Cursor's request-context MCP catalog. - Fixed Windows bash crashes when a piped command times out while flushing output.
- Fixed a race condition where hub/IRC
sendandensureLivecould inject into a subagent session during disposal. - Migrated legacy nested/dotted configuration keys (
dev.autoqa.consentandtodo.reminders.max) to flat keys (dev.autoqaConsentandtodo.remindersMax) on settings load. - Fixed keyboard input dying after the first keypress when a custom tool module attaches a stdin consumer at import time.
- Fixed the alignment of the ask tool's custom-input dialog to start at column 0.
- Fixed advisor context maintenance undercounting the provider context by anchoring compaction decisions on provider-reported context usage.
- Fixed RPC mode (
--mode rpc) crashing on non-JSON stdin lines; malformed lines are now reported as errors while the frame loop continues. - Fixed local llama.cpp Qwen-family models not honoring the
--thinking offflag. - Documented the
ultrathink,orchestrate, andworkflowzmagic keywords, including their effects, matching rules, and settings. - Fixed
/clearautocomplete selecting/autoresearchand updated/clearto start a new session as an alias for/new. - Fixed
/reviewaborting entirely when GitHub rejects a pull request's aggregate diff for exceeding the line limit by falling back to the paginated per-file endpoint. - Fixed
/q+ Enter running/queueinstead of/quitby adding an explicitqalias to/quit. - Fixed Ctrl+L (
app.display.reset) not refreshing the dark/light theme on certain terminals by issuing a background re-query before repainting. - Fixed a failing advisor stalling the primary agent: the per-turn catch-up gate parked the primary for up to its full 30s budget while a broken advisor (unsupported model, dead endpoint, render bug) retried — and an advisor exception could abort the primary's turn-end outright. A failing advisor now releases parked waiters the moment its turn fails (before any async hook), refuses new parks until a turn succeeds, and the turn-end boundary isolates advisor exceptions completely; a failed render restores the delta cursor so nothing is lost when the advisor recovers.
- Fixed advisors retrying a permanently rejected request forever (e.g.
invalid_request_error: model not supported with this account): unlike quota exhaustion — which pauses with a notice until an explicit reset — this class notified once and silently kept re-attempting every turn, re-building heavy context in a shared daemon. The runtime now hard-stops after a permanent rejection or three consecutive backlog-drop cycles, with a visible notice; an explicit reset (/new, config rebuild, restart) re-enables it.waitForCatchupresolves immediately while halted so the primary agent is never parked on a runtime that cannot drain.
[17.0.1] - 2026-07-16
Changed
omp usageand the in-session/usageview now show the Anthropic organization next to the account for org-scoped credentials (with--redactmasking applied per part in the CLI, falling back to the org id when no display name is available), attribute "no usage data" rows per organization, and match the "in use by this session" marker by organization so only the active subscription is flagged. The OAuth login success message names the account and organization that was stored — a login landing on an unintended subscription is visible immediately./logoutlabels Anthropic accounts with their organization and marks only the credential of the active organization as active;omp token --listshows the organization next to each account. Two subscriptions sharing one email are distinguishable when selecting which to remove or mint a token for.omp auth-broker migrate --from-localdedupes Anthropic OAuth identities per organization, so a Team seat already on the broker no longer blocks uploading the personal plan under the same email.- The status line invalidates its cached usage when the session rotates to a different Anthropic organization (previously the old subscription's quota could linger for the cache TTL), and
omp auth-gateway checklabels each credential with its organization so a failing row says which subscription needs re-login. omp usage"no usage data" attribution is org-decisive whenever either the stored account or a report carries an organization: an org-less legacy credential whose own fetch failed is no longer hidden by an org-attributed sibling report sharing the same email.- Active-account matching for
/usage,/logout, andomp token --listnow treats a shared organization as a qualifier rather than a match: two Anthropic Team seats in one org (same org id, per-user pools) no longer flag each other's rows or reports as "in use by this session" — the base identity (account/email/project) is still required, with org-only sessions matching on the org alone. omp usage"no usage data" coverage now requires the member's own identity within a shared organization: a sibling Team member's same-org report no longer counts as coverage for an account whose own report is missing, while an org-only account remains covered by any same-org report.omp auth-broker migrate --from-localreruns now recognize an already-migrated org-only Anthropic row (login recovered neither email nor account) by its organization id instead of re-uploading it, which could overwrite the broker's newer refresh token with the stale local one.- Updated tangential agent forks to ignore parent session history and focus exclusively on the new request
- Hardened
/tanfork isolation: the clone's inherited todo list is cleared at fork (parent todo reminders no longer drag the tan back onto the parent's task), the fork notice warns that the parent is concurrently editing the same working directory, and the notice is re-injected after each compaction so the fork boundary survives summarization - Added visual markers in the transcript for elided tool calls that have no corresponding result
- Updated status event log to prioritize the most recent entries in the display window
- Updated the snapcompact shape preview transcript to use the compact scope format shown to models during compaction.
Fixed
- Fixed
xd://mount notices triggering unsolicited model turns by deferring hidden notices until the next user prompt. - Fixed
xd://device tools appearing in the direct tool inventory and prompting invalid function calls (#5797). - Fixed
history://read selectors being treated as part of the agent id instead of paging the transcript (#5806). - Narrowed the
history://contract in the system prompt to match the implementation: it serves registered agents process-wide plus persisted subagents discoverable from their artifact trees, but does not discover unregistered top-level sessions solely from persisted session files (#5839). - Fixed expanded
!bash andevaloutput keeping a stale… N more lines (ctrl+o to expand)footer after Ctrl+O revealed every line (#5842). - Fixed MCP reauthentication continuing to an authorization URL without
client_idafter dynamic client registration fails; the registration error now blocks the flow with the provider response details (#5852). - Fixed collapsed todo views hiding the in-progress task in large phases. Both the transient
Todotool result and the stickyTodosHUD now share one walking-viewport policy: completed/abandoned tasks are omitted, every active task (the in-progress one, or a pending task a live subagent is executing) is pulled to the head in todo order, remaining rows fill with the following pending tasks, and an explicit… N more active todossummary is shown when active work alone exceeds the preview cap (#5873). - Fixed legacy provider extensions failing to load when they use the historical synchronous auth-storage surface (#5879).
- Fixed orphaned detached MCP stdio server process trees surviving session dispose by escalating stdin-EOF → group SIGTERM → group SIGKILL on close() (#5578)
- Fixed
/newstarting an unsolicited old-context provider turn when a hidden steer (e.g. anxd://mount notice) was queued: the session transition is now an atomic boundary, so a queued steer/follow-up can no longer auto-resume against the pre-/newcontext while the session is disconnected mid-transition./compactstill resumes a steer/follow-up that arrives while it runs, draining the queue once it reconnects (#5800). - Fixed signed thinking-only Claude stops being discarded and retried as empty responses (#5881).
- Fixed repeated URL reads and URL-backed searches returning stale same-session responses instead of refetching the resource (#5803).
- Fixed
read/writenot recognizing ZIP-based.jar/.war/.ear/.apkfiles as archives, soread lib.jar:META-INF/MANIFEST.MFfailed with path-not-found (#5808). - Fixed legacy binary
.doc/.ppt/.xls/.rtfbeing advertised as convertible inread,fetch, and CLI@filehandling despite having no markit converter, which surfaced anUnsupported formaterror instead of falling through to normal file handling (#5808). - Fixed Kimi Code transport selection to follow live per-model protocol metadata by default while preserving explicit OpenAI and Anthropic overrides (#5893).
- Fixed repeated edit-tool rejections from local models by recovering comma-separated ranges and malformed trailers, while clarifying canonical string input and
.=syntax (#5805). - Fixed LSP diagnostics and edit-time diagnostics writethrough for pull-only servers that advertise
textDocument/diagnosticstatically or through dynamic registration (#5825). - Fixed local
!command output concatenating carriage-return progress updates by preserving them as readable line boundaries (#5845). - Fixed
hub/ircpeer discovery after process-crash resume by restoring persisted subagents as parked peers before listing the roster (#5864).
Removed
- Removed the unreliable Bing and Yahoo HTML-scraping web search providers
[17.0.1] - 2026-07-16
Removed
- Fixed a crash when a plugin/custom tool renderer returns a component that throws during its later
render()pass (e.g.TypeError: th.bold is not a functionfrom a plugin that styles its header off an object without aboldmethod).ToolExecutionComponentnow wraps every renderer-returned call/result component so a throwingrender()degrades to the safe fallback (tool label or raw result text) instead of taking down the transcript (#4978). - Fixed
/loginfor paste-code providers (Codex, Anthropic, Gemini CLI, GitLab Duo, Antigravity, Devin) dropping the pasted fallback redirect URL: the login dialog captured focus but never mounted an input, and the "complete pairing with/login <url>" tip pointed at the hidden, unfocused editor. The dialog now mounts a focused input for the manual code/URL paste (#5339). - Fixed
/tanand/forkclones cold-missing the provider prompt cache: the per-turn supersede/useless-result prune rewrote the live context without persisting it, so file-based forks and resume rebuilt a divergent (un-pruned) prefix and re-wrote the entire cache - Fixed
/tanpinning the clone's prompt-cache key to the parent's session id instead of the parent's effective cache key, dropping shard affinity when the parent was itself a fork or tan - Fixed
/resumeand plan approval exposing the previous session while their asynchronous session replacement was still loading by keeping fullscreen overlays mounted until the rebuilt transcript is ready (#5319). - Fixed inconsistent history rendering when toggling the display setting for compacted items
- Fixed configured
retry.fallbackChainsnever engaging on non-retryable provider errors (e.g. "Cloud Code Assist API returned an empty response"): a hard error on a model covered by a fallback chain now switches to the next candidate instead of failing the turn, while still never backoff-retrying the failing model itself - Fixed transcript rebuilds (compaction,
/compact, and toggling history display) repainting content below stale scrollback when collapsing history; rebuilds now correctly clear the scrollback buffer when history is collapsed - Improved auto-compaction to automatically drop images and elide content when context is tight, and added persistent warning badges to the compaction divider when manual intervention is required
- Fixed backgrounded Bash blocks continuing to repaint with live and final job output; they now freeze with a compact job notice while completion is delivered separately
- Fixed the downshift plan nudge silently ending the run with no code written when the model answered with a text-only reply (no tool call): the agent loop treats a tool-call-free turn as a natural stop and never prompts again, which the nudge's own "write the plan in your next reply" instruction makes common. The nudge now explicitly tells the model this is a checkpoint, not a final answer, and the session forces one more turn whenever a post-nudge reply lands with zero tool calls
- Fixed launch tool rendering stacking a stale pending header over a bare
✓ Launchline and raw text: the tool now uses a merged registry renderer with one per-op status header (op, target,state · pid · uptimemeta), stripped log cursor suffixes, capped collapsed log/list previews, and a launch tool glyph - Fixed confusing launch start/wait results when readiness timed out with the log pattern already matched (readiness needs log AND port): the result printed a contradictory
Ready: <match>next toReadiness timed outwithout naming the failing condition. Daemon snapshots now carry the unmet conditions (readyPending), and start/wait results state exactly what never happened (e.g.port 3100 on 127.0.0.1 never accepted connections); the TUI shows awaiting on portbadge on starting daemons - Fixed the in-process
statbuiltin mangling BSD-style invocations likestat -f "%Sm %N" file(macOS muscle memory): GNU-fmeans--file-system, so the format string was treated as a file operand — printing filesystem info for the real operands and erroring withcannot read file system information for '%Sm %N'. A-fwhose format value contains%is now detected as BSD syntax and translated to the GNU equivalent (%Sm→%y,%N→%n,%z→%s, epoch/S-form times, owner/group/permission andH/Lsub-field directives,-L/-n/-q/-Fflag clusters, with%n/%tas literal newline/tab); directives with no GNU counterpart fail with a clearunsupported BSD format directiveerror - Fixed the remaining GNU-flavored shell builtins that broke under macOS/BSD muscle memory, using the same unambiguous-detection approach as the
statfix (only invocations that are invalid or nonsensical under GNU semantics are reinterpreted; unsupported BSD forms fail loudly instead of producing wrong output):date -r <epoch>formats the epoch when no such file exists (GNU-r FILEmtime preserved), signeddate -v±N<unit>adjustments translate to-drelative dates and-jis accepted (-j -fstrptime parse mode and field-set-verror clearly);sed -i '' 's/…/…/' filedrops the BSD empty backup-suffix token instead of treating it as the script;mktemp -t prefixwithout X's creates$TMPDIR/prefix.XXXXXXXXXX(the GNUtoo few X'serror path);tail -rreverses input by delegating totac(with-n/-c/-fcombinations erroring clearly);find -Emaps to-regextype posix-extendedahead of the expression;base64 -Ddecodes as an alias of-d; andln -sfhworks via a-halias of--no-dereference(clap's-hhelp short is dropped to match real GNU/BSD ln;--helpunchanged) - Fixed the browser tool crashing the whole process (parent session and every subagent) when a CDP world re-acquire failed mid-navigation: the stealth
puppeteer-corepatch called the baredebugErrorlogger, which isundefinedwhile thepuppeteer:errordebug channel is disabled (the default), turning a transient acquire failure into a fatalTypeErrorunhandled rejection. The patchedFrameManager/WebWorkeracquire paths now usedebugCatchError(#5296) - Fixed a role with a
:highthinking suffix resolving to a longer sibling model whose id embeds the tier name (e.g.kimi-for-coding:high→kimi-for-coding-highspeed). The thinking suffix is now stripped before any fuzzy match, soprovider/model:highkeeps the exact model at high effort (#5151).
Fixed
- Fixed the
omp grepCLI subcommand failing on paths with a stray leading colon (e.g.:/abs/path); it now routes the path argument throughexpandPathlikeread/edit/in-agentgrep. BroadenedexpandPath's leading-colon strip to also recover Windows-style shapes (:C:\repo\file,:.\src,:..\rel,:\\server\share) (#5624). - Fixed the
tailbuiltin exiting the entire omp process with code 13 on Windows when its output pipe broke (e.g.seq ... | tail -n 3 | head -n 0); a broken pipe now surfaces as a normal error instead of callingstd::process::exit(#5609). - Fixed a late advisor
blockerafter a terminal primary answer being deferred to the next user turn instead of continuing the current turn:resolveAdvisorDeliveryChannelpreserved every interrupting severity as a passive card once the primary ended with a terminal text answer and no queued work remained, so ablockerflagging a mistake in the final output sat idle until the next prompt. Ablockernow steers a triggered turn so the primary acknowledges and continues before the turn is considered done; a lateconcernstill preserves as a visible card (#5628). - Fixed independently keyed extension hook statuses sharing one truncated line; each status now renders on its own deterministic line (#5617).
- Fixed xAI web search bypassing configured
xai/xai-oauthproxy endpoints and headers, while preventing official OAuth tokens from being sent to custom endpoints (#5599). - Fixed
models.ymlrejecting the Anthropiccompat.supportsEagerToolInputStreamingoverride for custom endpoints (#5572). - Fixed long streamed table responses duplicating in terminal scrollback when later rows widened an earlier column.
- Fixed Bash internal URLs remaining unresolved when used as unquoted arguments inside command substitutions (#5535).
- Fixed the built-in
fdprintingfd: Broken pipe (os error 32)when a downstream pipeline reader exited early (e.g.fd … | head); it now exits silently with 141 (128+SIGPIPE), matching real fd. - Fixed prewalk repeatedly continuing after a bash-only task such as
commithad already completed (#5551).
Added
- Fixed the Codex
config.tomlMCP importer droppingcwdand leaving relativecommandvalues unrooted, which broke the bundled Codex Computer Use server (ENOENTon spawn); relativecommand/cwdnow resolve against the Codex config directory like the claude-plugins/omp-plugins providers (#5561). - Fixed streamed replace-mode edits with
ssh://paths terminating the active prompt before normal tool dispatch (#5552). - Fixed concurrent provider OAuth refreshes from invalidating Anthropic's rotating refresh token, and prevented background usage probes from permanently disabling credentials after refresh failures (#5396).
- Restored the regression test guarding compiled-binary web-search header generation:
browser-headers.tslazily constructsheader-generatorand falls back to a static Chrome profile when itsdata_filesare absent, but the test defending that contract had been removed. Without the guard, a compiled binary threwENOENTat import time, breaking the Bingweb_searchprovider (undefined is not a constructor) and extension loading /omp plugin install. (#5256) - Fixed browser tabs hanging indefinitely at
Closing <tab>when a worker, CDP target, browser process, or cmux surface stalls during teardown; close deadlines now release the operation with backend, tab, and pending-resource diagnostics. (#5259) - Fixed the
agent://<parent>/<child>slash form failing to resolve a nested subagent's output: the path segment was always treated as a jq JSON-extraction key against<parent>.md, so a precise-planner reading its own scout child (agent://Plan/Scout) gotNot found. The slash is now a hierarchy separator first (agent://Parent/Child→Parent.Child.md), falling back to JSON extraction only when no nested output matches the path. (#5238) - Fixed fullscreen Plan Review jumping to the top while scrolling when a transient terminal resize or Markdown reflow made the body temporarily non-scrollable. (#5232)
- Fixed
generate_imagepreferring Antigravity over the active session provider and stopping instead of trying the next credentialed provider after an image HTTP failure. (#5218) - Fixed
/reload-plugins, plugin setting changes, andmanage_skillwrites leaving runtime skills andskill://resolution stale until restart; sessions now rediscover enabled skills and rebuild/skill:<name>commands before the next prompt (#4996). - Fixed documented
omp marketplace/discover/upgrade/uninstall/enable/disableCLI verbs silently leaking to the model as a launch prompt instead of managing plugins.omp marketplace add xyz(and similar multi-word invocations following the documentedomp plugin <action>grammar) now surface a hint pointing at the realomp plugin <action>command, while genuine prose prompts beginning with these words still route tolaunch(#4845). - Fixed
/mcp,/mcp list, and/toolsoutput duplicating in terminal scrollback when invoked during agent streaming by deferring command panels until the active turn ends (#4806). - Fixed bash/eval/ssh output that was only per-line column-capped being misreported as byte-window truncation, which appended a bogus
Showing lines X-Y of Z (…B limit). Read artifact://N for full outputfooter even though every line was shown. Column-cap trimming now surfaces solely as theSome lines truncated to N charsnotice (#4735). - Fixed the
nerdstatus-line preset's session icon using a removed Nerd Fonts v2 codepoint instead of the current Nerd Fonts v3 mapping (#4795). - Fixed omp crashing at startup (
TypeError: undefined is not an object (evaluating 'this.#theme.symbols.boxRound')) after installing a plugin whose custom editor subclassesCustomEditor/Editorand forwards the upstream-pisuper(tui, theme, keybindings)constructor — the arg order thatsetEditorComponent's factory contract advertises.CustomEditornow resolves the realEditorThemeby shape rather than position and captures a leadingTUIfor plugin overrides (#4766). - Fixed
Otherresponse editors leaving Windows Terminal IME candidate windows at the terminal edge by forwarding dialog focus to the nested editor (#4760). - Rendered and persisted native OpenAI Responses
image_generation_callresults as session images (#4768). - Fixed ACP stdio EOF/EPIPE disconnects bypassing awaited session teardown and leaving in-flight tool calls pending in persisted rollouts (#4788).
- Routed the print-mode assistant-error/aborted exit, RPC
pi.shutdown()and stdin-EOF shutdowns, and the extension command-contextshutdown()through the awaited, idempotentsession.dispose()beforeprocess.exit(), so the bounded browser reaper (releaseTabsForOwner) always runs and OMP-owned Chromium no longer outlives the process (#5643).
[17.0.0] - 2026-07-15
Breaking Changes
- Merged the
irc,job, andlaunchtools into a single unifiedhubtool (loadMode: "essential"). Messaging, job control, and process supervision operations are now routed through this single tool. SDK:IrcTool,JobTool,LaunchTool,IrcDetails, andJobToolDetailshave been removed in favor ofHubTool,CoordinationDetails,LaunchToolDetails, andhubToolRendererfromtools/hub. - Removed the hidden
resolvetool. Staged actions are now finalized through three plain-text resolution devices:xd://resolve(apply preview),xd://reject(discard preview), andxd://propose(submit a plan slug/title for approval). Thewritetool is now auto-included whenever a deferrable tool is present or plan mode is enabled. SDK:ResolveToolandHIDDEN_TOOLS.resolvehave been removed in favor ofdispatchResolutionDevice()andqueueResolveHandler(). - Unified tool presentation on
loadMode(essential|discoverable), replacing the custom-toolxdev?: booleanopt-out. Custom, extension, MCP, RPC host, image-generation, and TTS tools now default todiscoverableand mount underxd://when enabled.generate_image,tts, and MCP tools are now exposed asxd://devices in default sessions instead of shipping their schemas top-level. - Removed the BM25 tool-discovery system, including the
search_tool_bm25tool, thetools.discoveryMode,mcp.discoveryMode, andmcp.discoveryDefaultServerssettings, and per-tool MCP selection. All connected MCP tools are now enabled and mounted under thexd://transport. SDK:search_tool_bm25, thetool-discoverymodule, and associatedAgentSessiondiscovery/MCP-selection methods have been removed. - Removed the legacy
report_findingtool. Reviewer agents now record findings through incrementalyieldsections. SDK:reportFindingToolandHIDDEN_TOOLS.report_findinghave been removed. - Removed the
sshagent tool (remote command execution). Thessh://read/write/search protocol, theomp sshhost-management CLI, and SSH host discovery are retained. SDK:SshTool,loadSshTool, thessh/ssh-executormodule, andAgentSession.refreshSshToolhave been removed. - Removed the
tools.essentialOverridesetting, themcp_tool_selectionsession message type, and thexdev--toolstoken.
Added
- Added
xd://virtual tool devices (controlled by thetools.xdevsetting, default on), allowing mounted tools to be discovered viaread xd://, documented viaread xd://<tool>, and executed viawrite xd://<tool>. - Added the
edit.enforceSeenLinessetting (default off) to gate the hashline seen-line guard. When enabled, edits anchored on lines that a priorreadorgrepnever displayed are rejected. - Added per-agent prewalk for subagents, featuring a
prewalkfrontmatter field, atask.agentPrewalksettings override toggled from the/agentsdashboard, and atask.prewalkboolean (default off) to arm the bundled generictaskagent.
Changed
- Renamed
"dev.autoqa.consent"to"dev.autoqaConsent"and"todo.reminders.max"to"todo.remindersMax"to eliminate nested configuration prefix collisions in standard JSON/YAML. - Made the hashline seen-line guard opt-in and off by default, and stopped excluding column-clipped (>512-char) lines from a snapshot's seen set, allowing single-line edits on long lines to apply without a full-width re-read.
- Changed the default
astGrep.enabledsetting tofalse. - Batched todo operations with real tool calls to prevent solo todo turns and extra round trips.
- Changed all bundled TTSR rules to warn instead of interrupting generation.
- Renamed the system prompt's project-context section wrapper from
<context>to<repo-rules>to prevent collisions with thetasktool'scontextparameter under in-band XML tool dialects. - Rendered
read xd://calls in a compact grouped read view instead of a full tool-execution card. - Updated
--toolsto reject unknown tool names with a usage error instead of silently narrowing the toolset. - Capped the
xd://device docs inlined into the system prompt to a 48k-char budget (10k per device) to prevent large MCP catalogs from bloating requests; devices past the cap are listed by name and summary and fetched on demand. External (dynamic-mount) tool descriptions embed at most 200 chars — schemas stay intact, full text viaread xd://<tool>. - Dead BM25-discovery settings keys (
tools.discoveryMode,tools.essentialOverride,mcp.discoveryMode,mcp.discoveryDefaultServers) are cleaned from configs on load;tools.xdevkeeps its default (true). - Mid-session
xd://mount changes (e.g. MCP connect/disconnect) no longer rewrite the system prompt: the delta is announced to the model as a steered system notice ("these tools became available" / "no longer mounted"), so the provider prompt cache stays intact; device docs join the prompt on the next unrelated rebuild.
Fixed
- Fixed a bug where a nested configuration value (like
dev.autoqa.consent/dev.autoqaConsent) would incorrectly satisfy a parent key lookup (likedev.autoqa), causing Auto QA to be enabled and prompt for consent by default when it should have been disabled. - Fixed compiled appserver startup deadlocking before socket creation when user extensions were present.
- Fixed Bash internal URLs remaining unresolved when used as unquoted arguments inside command substitutions.
- Fixed
--toolssilently dropping hidden tool names likexdevandyield. - Fixed the built-in
fdprinting broken pipe errors when a downstream pipeline reader exited early; it now exits silently with status 141. - Fixed prewalk repeatedly continuing after a bash-only task (such as
commit) had already completed. - Fixed the Bash tool hanging when in-process commands read process substitution operands.
- Fixed
/shareand/exportweb views rendering inline Markdown inside list items as literal text. - Fixed plan-mode re-entry dropping a new plan request when a prior plan artifact existed; re-entry now anchors on the new request and folds old-plan corrections into it.
- Fixed ACP clients rendering
xd://device dispatches as file edits; they now map to anexecute-kind tool call titled with the device URL. - Fixed non-yolo approval modes double-prompting for
xd://device dispatches. - Fixed TTSR rules with leading inline regex flags failing to compile and being silently dropped in Bun/JS environments, and recovered scope tokens and sibling values from malformed frontmatter.
[16.5.2] - 2026-07-14
Breaking Changes
- Removed the separate
selectorparameters fromreadandgrep; line ranges and read modes must now be appended topath.
Added
- Added a
generate_image.enabledsetting (Settings › Tools › Generate Image) to allow toggling the image generation tool.
Changed
- Expanded provider rate-limit response header ingestion to all supported providers with header parsers (previously Anthropic-only), enabling proactive account rotation for multi-account sessions before hitting 429 errors.
- Restored CPU model metadata in workstation prompts on non-Linux hosts.
Fixed
- Fixed
omp config list --jsonoutput truncation at 64 KiB when stdout is piped. - Fixed vim-style navigation (
h/j/k/l) under the Kitty keyboard protocol. - Fixed
/guided-goalthrowingModel not founderrors on websocket-only Codex models by routing the interview through the session's provider transport and reusing a single isolated side session. - Fixed
tool_resultextension handlers being unable to rewrite the model-visible content of a thrown tool failure. - Fixed intermittent Perplexity OAuth web search failures (401 errors) caused by transient transport drops on the ask endpoint.
- Fixed the
generate_imagetool ignoring--no-toolsand explicit tool whitelists. - Fixed markerless prose thinking preambles incorrectly becoming session titles when title models omit the
<title>marker. - Fixed the agent recreating a todo list immediately after a user clears it with
/todo rm. - Fixed internal-URL autocomplete (
agent://,skill://,omp://, etc.) not triggering inside slash command arguments. - Fixed the browser tool hanging indefinitely during tab closure when the headless Chromium process is wedged on Windows.
- Fixed
history://URLs failing to resolve for unregistered, released, or resumed subagents by falling back to scanning artifacts directories on disk. - Fixed eval cells treating
timeout: 0as a one-second deadline and reporting session-deadline cancellations as user aborts. - Fixed MCP OAuth dynamic client registration for pathful authorization-server issuers by preserving the discovered registration endpoint.
- Fixed the
launchtool failing to start Windows executables due to double-escaped PTY commands and arguments. - Fixed the built-in advisor warning
Advisor unavailablefor silent reviews: a content-less stop is a valid "nothing to add" outcome and is never retried or warned about, regardless of reported token usage (#5212 follow-up). - Fixed
read,edit, andgreptools failing on paths with a stray leading colon emitted by some models. - Fixed git plugin re-installs retaining stale commits by fetching Bun's cached clone before updating the lockfile pin.
- Fixed overlapping Bash timeout and interrupt cleanup to explicitly abort isolated shells instead of leaving child processes running.
- Fixed a bug where generic provider aborts arriving as
stopReason: "error"were not auto-retried. - Fixed switching from a vision model to a text-only model mid-session sending historical image blocks to the new provider.
- Fixed inline images in Agent Hub transcripts by routing replayed images through the shared image budget and Kitty placeholder renderer.
- Fixed OSC 5522 paste in direct API-key login prompts being routed to the hidden main chat editor instead of the focused credential field.
- Fixed plugin installation failures when an ES module extension synchronously requires CommonJS helpers.
- Fixed GitHub code search rejecting empty optional date placeholders.
- Fixed
/treenavigation onto a/skill:injection node landing on the incorrect entry. - Fixed interactive TUI sessions crashing with concurrent JS runtime errors when the JS eval worker falls back to the in-process inline path.
- Fixed compaction aborting instead of trying an authenticated fallback model when Amazon Bedrock credential resolution fails.
- Fixed full-context forks and
/tanclones cold-missing OpenAI prompt caches by properly persisting and inheriting provider prompt-cache keys. - Fixed Codex advisor requests using local session labels as provider session IDs.
- Fixed macOS stdio MCP servers launching in a detached session, allowing the TCC Apple Events permission prompt to trigger.
- Fixed the ask tool timeout to auto-select the recommended option when the UI selector does not settle.
- Fixed LSP workspace diagnostics for Go workspaces to correctly recognize
go.workroots and include all used modules. - Fixed interactive OAuth login success messages waiting on background model discovery.
- Fixed Windows bash tool crashes when an explicit timeout fires while a piped command is still streaming.
- Fixed subagent
yieldtool calls being discarded when the soft request budget hard-aborted the same assistant turn. - Fixed
--toolsfiltering in interactive sessions disabling deferred MCP tools. - Fixed kept-alive task subagents entering repeated provider-call loops after an IRC wake and terminal yield.
- Fixed manual
/compactwith the snapcompact strategy hard-failing on text-only active models. - Fixed the empty-editor
←←gesture trapping input when opening the Agent Hub from persisted/parked subagents. - Fixed eval
read()URI handling in Python and JS runtimes to correctly delegate URI reads and pass pagination arguments. - Fixed discovered plugin
.mcp.jsonstdio servers launching relativecommandorcwdvalues against the session cwd instead of the plugin's config directory. - Fixed Model Hub DEFAULT role assignments with
autoretaining a stale concrete reasoning suffix after restart. - Fixed configured
retry.fallbackChainsfailing to engage on non-retryable provider errors. - Fixed backgrounded Bash blocks continuing to repaint with live output after completion.
- Fixed
--reasoning-slide-plansilently ending the run with no code written when the model answered with a text-only reply. - Fixed launch tool rendering issues, including stacked pending headers and confusing start/wait results when readiness timed out.
- Fixed the in-process
statand other GNU-flavored shell builtins (such asdate,sed,mktemp,tail,find,base64, andln) mangling or failing on macOS/BSD-style invocations.
[16.5.1] - 2026-07-14
Changed
- Enhanced Anthropic credential and usage management to support organization-scoped accounts, including displaying organization names in /usage, /logout, omp token --list, and OAuth login success messages, resolving active-account matching for shared organizations, and deduplicating identities during migration.
[16.5.0] - 2026-07-13
Breaking Changes
- Replaced the
--reasoning-slide-*flag family with a unified--prewalkmechanism (--prewalk,--prewalk-into <model>, and--no-prewalk) to manage model handoffs during execution.
Added
- Added a new
--prewalkexecution flow (with--prewalk-into <model>and--no-prewalkoverrides) that starts tasks on a strong model for planning and todo initialization before handing off to a faster, cheaper model for implementation. - Added a status line annotation for the active prewalk phase (armed or active).
- Added the
tui.scrollbackRebuildsetting to gate the erase-and-replay native scrollback rebuild mechanism (defaults to off). - Added a display setting to toggle between collapsing or keeping compacted history inline in live session displays.
- Added a compact session-only model picker (Alt+P) for quick model switching, featuring
@search to quickly list and apply configured quick roles. - Redesigned Agent Hub entries into a cleaner two-line card layout showing identity, active model, reasoning level, age, and task description.
- Added a project-scoped
launchtool (gated bylaunch.enabled) for managing shared long-running services and debuggers, featuring readiness probes, bounded logs, PTY input, restart policies, and automatic teardown. - Added support for
detachedlaunches, allowing standalone services to survive broker shutdowns and reconnect to subsequent sessions.
Changed
- Updated JSON logs (
--mode json) to include provider payloads in auto-compaction events. - Updated tangential agent forks (
/tan) to ignore parent session history and focus exclusively on the new request, hardening isolation with cleared todo lists and concurrent editing warnings. - Added visual markers in the transcript for elided tool calls that have no corresponding result.
- Updated the status event log to prioritize the most recent entries in the display window.
- Upgraded
@agentclientprotocol/sdkto version 1.2.1.
Fixed
- Fixed terminal scrollback duplication issues with expanded streaming edit previews (Ctrl+O) by using a viewport-sized tail window.
- Fixed custom model role resolution and alias parsing, ensuring canonical role selectors (
@role) and thinking suffixes resolve correctly across all configuration surfaces. - Fixed quadratic growth in JSON logs by eliding redundant message snapshots and payloads.
- Fixed prompt cache misses and incorrect cache key pinning for
/tanand/forkclones. - Fixed inconsistent history rendering and scrollback repainting when toggling the display setting for compacted items.
- Fixed
retry.fallbackChainsfailing to engage on non-retryable provider errors, ensuring the agent correctly falls back to the next candidate model. - Improved auto-compaction to automatically drop images and elide content when context is tight, and added persistent warning badges when manual intervention is required.
- Fixed backgrounded Bash blocks continuing to repaint with live output; they now freeze with a compact job notice while completion is delivered separately.
- Fixed rendering, status display, and PTY control sequence formatting issues in the
launchtool. - Fixed in-process shell builtins (including
stat,date,sed,mktemp,tail,find,base64, andln) to correctly detect and translate macOS/BSD-style arguments and flags, preventing failures caused by GNU-only assumptions.
Removed
- Removed the
--prewalk-boomerangfeature and its associated configuration setting. - Removed the unreliable Bing and Yahoo HTML-scraping web search providers.
[16.4.8] - 2026-07-12
Added
- Added invocation-specific schemas to task subagents and unified task/eval agent execution, including host-enforced read-only plan-mode agents (#5279)
Fixed
- Fixed compatibility of GNU-flavored shell builtins (such as stat, date, sed, mktemp, tail, find, base64, and ln) when invoked with macOS/BSD-style arguments.
- Fixed subagent model and thinking level resolution to correctly respect the configured modelRoles.task selector instead of intermittently falling back to the parent session's model.
- Fixed TUI rendering issues, including preventing macOS runtime diagnostics from painting into the viewport, bounding transcript retention in long sessions, and fixing scrollback repainting when collapsing history.
- Fixed /tan and /fork clones failing to inherit or persist the parent session's prompt cache keys.
- Fixed Python and JavaScript evaluation kernels suspending the CLI on subprocess foregrounding, deadlocking on non-serializable values, or losing in-flight subagent work during external aborts.
- Fixed configured retry.fallbackChains failing to engage when encountering non-retryable provider errors.
- Improved auto-compaction to automatically drop images and elide content when context is tight, and added persistent warning badges to the compaction divider when manual intervention is required.
- Fixed the downshift plan nudge silently ending runs with no code written when the model answered with a text-only reply.
- Fixed launch tool rendering and status reporting, including resolving contradictory readiness timeout messages and preventing backgrounded Bash blocks from continuing to repaint.
- Fixed Advisor containment and timing issues, preventing hallucinated tool calls from contaminating later advice and ensuring late-arriving transcript deltas are coalesced before advisor calls.
- Fixed omp update on npm-managed Windows installations to prevent downloaded release binaries from overwriting npm launchers.
- Fixed --max-time duration values (e.g., 5s, 10m, 1h) being ignored instead of setting a session deadline.
- Fixed omp plugin install --force failing with a dependency loop when replacing an existing pinned Git plugin source.
- Fixed MCP tools receiving session image attachments as raw local:// URIs instead of resolving them to local filesystem paths.
- Fixed Pyright LSP semantic requests hanging during startup.
- Fixed Codex web search requests for GPT-5.6 Responses-Lite models.
- Fixed custom model/provider configuration discovery to correctly load ~/.omp/agent/models.yaml when models.yml is absent.
[16.4.8] - 2026-07-12
Added
- Added a predicate form to the browser run's
wait()helper:wait(fn, { timeout?, interval? })polls the function (sync or async) until truthy and resolves with that value, failing with a named timeout error (deadline clamped under the cell budget so it always beats the opaque whole-cell timeout) instead of Bun'ssleep expects a numberor a whole-cell stall from in-page polling Promises; bothwaitforms now register in the stall diagnosis of cell timeouts - Added
--reasoning-slide-modeland--reasoning-slide-turnsto switch a running agent from its initial model after a fixed number of completed assistant turns - Added
--reasoning-slide-plan(with--reasoning-slide-plan-at) to steer a hidden deep-planning nudge into the run before the reasoning slide; the switch is held until a substantial plan turn actually lands (bounded by a grace window) and the nudge is scrubbed from the LLM context at the switch so the fast model inherits only the produced plan - Added
--reasoning-slide-on-actionto trigger the reasoning slide at the first completed turn that ran an edit/write tool instead of a fixed turn count (bash is excluded — it doubles as exploration)
Changed
- Replaced the Alt+P /
/switchtemporary model selector's fullscreen /models hub with a compact full-width floating overlay anchored above the editor (~40% of the terminal height): just the searchable model list — no provider sidebar or role management — with the session's active model highlighted and preselected - Improved tab recovery after timeouts by automatically clearing pending navigation and JS dialogs
- Made
tab.gotonavigation failures catchable with a named error instead of triggering a whole-cell timeout - Made
tab.evaluaterun in the page's main JavaScript world so page-defined globals are available without a directive - Enhanced cell timeout messages to include identification of stalled operations and blocking JS dialogs
- Browser
runon a tab the supervisor force-killed now reports the kill reason instead of a bare "not alive" - Refined agent workflow to prioritize smoke testing and reduce mandatory upfront test generation
Fixed
- Fixed the eval tool's status-event tree truncating from the bottom: the newest
log()progress lines were hidden behind an… N moremarker while the oldest stayed visible; the tree now shows a tail window behind an… N earliermarker, and the expanded view widens to the viewport instead of a fixed 10 events - Fixed the
//!world=maindirective being silently ignored for string expressions passed to raw Puppeteer evaluation APIs - Fixed tab reuse issues where hung navigation or unhandled modals would cause initialization to stall and trigger a force-kill
- Improved search reliability for Perplexity provider by forcing retrieval for all queries
- Fixed JS eval cells losing top-level
functionandvardeclarations across cells when the defining cell contained top-levelawait— the async wrapper scoped them to the cell's IIFE instead of publishing them to the worker global
[16.4.7] - 2026-07-12
Added
- Enabled Home and End keyboard navigation in the model browser
- Added a
chotkey in the plan-review overlay that copies the current reviewed plan markdown to the system clipboard, including in-overlay edits.
Changed
- Streamlined list view styling by removing inline model role chips from row entries
- Reworked /models hub selection visuals: the background highlight band is reserved for mouse hover, the keyboard position is a cursor glyph drawn only in the pane that owns the arrow keys, and the sidebar's active scope renders as a bold accent label
- Removed the redundant "login" label from inactive (locked) provider entries in the Model Hub sidebar
Fixed
- Fixed PageUp/PageDown in the model browser wrapping past the list edges instead of clamping
- Fixed the hover highlight sticking to the last hovered model row when the pointer moved into the provider sidebar
[16.4.6] - 2026-07-12
Added
- Added
invalidateaction to the usage command to clear cached usage reports - Added model-oriented keys and wildcard entries to
retry.fallbackChains: aprovider/model-idkey attaches a fallback chain to that exact model, aprovider/*key covers every current or future model of a provider, and aprovider/*chain entry keeps the failing model's id while swapping the provider (google-antigravity/x→google/x) — so fallbacks survive role and model reassignments without config edits. Keys resolve by specificity: exact model, then provider wildcard, then role, thendefault. - Added fallback-chain editing to the /models Roles view: each role's
retry.fallbackChainsentries render as indented rows beneath it,fpicks a fallback model to append, Enter on an entry replaces it,x/backspace removes it, and[/](or shift+↑/↓) reorder the chain. - Added model-keyed fallback management to the /models Roles view: model and
provider/*chains render as a separate section below the roles (divider + "+ New fallback…" row for creating one by picking the protected model, then keying it by model or provider), with the same replace/remove/reorder editing as role chains; the model strip gainsfallbacks:<model>andfallbacks:<provider>/*chips as shortcuts. - Added
/queue <message>plus->/=>composer shorthand for follow-up messages that wait until the agent yields. The shorthand opens a dimQueueingheader and splits sequential numeric, Roman-numeral, or alphabetic lists into separately highlighted queue entries. - Added per-model TPS/TTFT tracking: every completed assistant turn folds its timing into recency-weighted aggregates in
~/.omp/agent.db, and the /models browser shows measured speed — a right-aligned118t/scolumn on wide terminals (plus TTFT, e.g.0.9s 118t/s, when wider) and~118t/s · 0.9s ttftfacts in the selection detail line — with no dependency on theomp statssession scan.
Changed
- Retain completed and abandoned tasks in session history for improved context on resume
- Changed the Model Hub
retry-fallbackstrip chip to append the model to the default fallback chain instead of prepending it, matching the chain-building order of the Roles view (already-registered models are a no-op). - Changed per-model perf recording (
recordModelPerf) to be deferred like prompt history: samples are batched and written toagent.dbin one transaction ~100ms later, keeping SQLite writes off the turn-completion hot path.
Fixed
- Fixed failure to trigger model fallback when the retry budget is exhausted by credential rotation
- Fixed uncontrollable mouse-wheel scrolling in the /models hub: the wheel moved the selection (one step per wheel event, so a single trackpad flick skipped many rows) and wrapped from the bottom back to the top. Wheel scrolling now pans the list viewport only, clamps at the ends, and leaves the selection where it is; keyboard navigation still scrolls the selection into view. Likewise, the wheel over the provider sidebar no longer switches the active scope (or triggers provider refreshes) — it just scrolls the sidebar.
- Fixed TPS being inflated several-fold when a provider hides reasoning tokens until late in the stream (e.g.
google/gemini-3.5vsgoogle-vertex/gemini-3.5reporting 648 vs 186 TPS for identical durations):omp bench, the per-turn usage row, and the /models perf aggregates now measure tokens/sec over the total request duration instead of the post-TTFT decode window, matchingomp stats. Stored perf aggregates are purged and re-backfilled from stats history with the corrected math on first launch. - Fixed the model-perf stats.db backfill freezing the TUI (~30s on multi-million-row stats databases) when /models triggered it: the import is now fire-and-forget, walks the newest rows in small chunks with event-loop yields between them, and is bounded to 90 days / 256 newest samples per model — beyond either bound the recency decay would erase the contribution anyway.
- Fixed compiled release binaries bundling
fastembedand baking the build-machine@anush008/tokenizerspath; native runtime dependencies now stay external for every compiled build path so Mnemopi resolves its on-demand install instead. (#5195) - Fixed
/btwside-channel turns on Codex models such asgpt-5.6-lunaby preserving the session websocket preference instead of forcing SSE, and made Esc dismiss the active/btwpanel before interrupting loop/maintenance work. (#5213) - Fixed the Model Hub role-assignment strip hiding the selected chip once the row overflowed; the strip now scrolls horizontally, truncating passed chips behind a leading ellipsis so the selection (plus one chip of lookahead) stays visible.
- Fixed mouse hover and clicks in the /models Roles view landing one row above the pointer (the row mapping subtracted the status row twice).
- Fixed model search keeping the most-recently-used model on top of the results: match quality now ranks first (an exact
gpt-5.5beats the activegpt-5.6-sol), with MRU order only breaking ties between equally good matches.
[16.4.5] - 2026-07-11
Breaking Changes
- Reworked the task tool wire schema: moved the top-level agent field into individual task items, renamed assignment to task and id to name, and removed the role and description fields. UI labels are now automatically generated from the task text.
Added
- Introduced a fullscreen, mouse-supported Model Hub (via /model) featuring a sidebar of scopes, metadata-aligned model tables, inline role/thinking assignment strips, custom role creation, quick-switch cycle editing, and manual provider refreshing.
- Added a /pause command to freeze all active agents (main, subagents, and advisor) at their next safe step, allowing manual repository edits mid-run before resuming.
- Added support for per-ID bulk conflict directives via write({ path: "conflict://*", content: "..." }) to resolve multiple conflicts in a single call.
- Added auto as a valid thinking-level in agent frontmatter, which is now the default for the bundled task subagent.
- Added rich, interactive, fixed-height ask dialogs featuring question tabs, option previews, notes, and multi-select toggles.
Changed
- Redesigned OAuth logins to run inside a cancellable dialog (aborted via Esc) rather than an inescapable pairing prompt.
- Reworked the subagent soft request budget to gracefully steer child agents to wrap up and yield partial findings instead of silently terminating them, and raised the default budget to 200 requests.
- Updated task rendering to retain the agent type badge on live progress and finished result rows.
Fixed
- Fixed issues where in-flight tool calls or task blocks would disappear from the chat during mid-turn transcript rebuilds or when background jobs settled.
- Fixed mixed blocking and non-blocking task batches degrading all spawns to synchronous execution; execution mode is now correctly handled per item.
- Fixed budget-stopped subagents becoming unreachable, allowing them to remain adopted and resumable via irc with full context.
- Fixed code duplication in write conflict:// when models pasted lines adjacent to the marker block.
- Fixed visible per-keystroke lag when searching in the /resume session picker by caching search targets and debouncing SQLite lookups.
- Fixed compiled Linux binary extension loading failures related to bundled web-search header generation data paths.
- Fixed job list and empty-poll snapshots returning empty output, ensuring running subagents without backing jobs are properly listed.
- Fixed agents getting stuck waiting for messages from peers that have already stopped running.
- Fixed compiled Linux binary extension loading when bundled web-search header generation cannot read
header-generatordata files from the build-time path. (#5178) - Fixed plugin custom tool loading to skip and report invalid feature entries instead of crashing startup when a plugin dependency tree leaves one feature unresolved. (#5189)
[16.4.4] - 2026-07-11
Changed
- Optimized session title generation and auto-thinking classification for sub-billion-parameter tiny models (such as LFM2) by rewriting system prompts, improving input truncation to preserve message context, and unifying preprocessing to filter out noise like ANSI codes, XML tags, and long commit hashes.
Fixed
- Fixed an issue where the Windows binary exited silently without running the CLI, which also caused
omp updateto roll back. - Fixed native Windows binary compatibility on older Windows 10 CPUs by building the
omp-windows-x64.exerelease asset with a baseline x64 runtime instead of AVX2. (#5172) - Fixed
GenerateImagerejecting OpenAI Codex-compatible proxy bearer keys when the token does not expose achatgpt-account-id. (#5174) - Fixed context promotion documentation to accurately reflect the
contextPromotionTargetruntime behavior andcontextPromotion.enableddefault. (#5163)
[16.4.3] - 2026-07-11
Added
- Added /vibe mode, allowing the model to act as a director driving persistent background worker sessions (fast and good tiers) with dedicated session tools (vibe_spawn, vibe_send, vibe_wait, vibe_kill, vibe_list) and a live TUI "TV wall" showing active worker activity, tool traces, and streamed output.
- Added multiple credential-free web search providers (Google, Bing, Yahoo, Startpage, Ecosia, Mojeek) with stealth-browser escalation, bot challenge detection, and recency filters, alongside a parallel public ("Public Web") provider that aggregates and deduplicates results across all engines.
- Added PCRE2 fallback support for grep lookaround and backreferences when the default Rust regex engine rejects a pattern.
- Added a helpful stderr hint when launching omp acp from an interactive terminal to clarify that the command communicates via JSON-RPC over stdout.
Changed
- Reduced browser action timeout from 15s to 8s to improve agent iteration speed.
- Refined agent delegation logic to prioritize top-level planning by the primary agent, discourage single-agent delegation, and handle prerequisite work inline.
- Optimized credential-free web search engine ordering and routing, prioritizing Startpage and Ecosia, and using randomized desktop Chrome profiles with stealth-browser escalation for blocked requests.
Fixed
- Fixed advisor config preserving an explicit empty tool list so
/advisor configcan disable all advisor tools. (#5155) - Fixed npm bundle generation failing on Linux with E2BIG by building dist/cli.js in-process via Bun.build instead of passing the embedded docs payload as a CLI --define argument.
- Fixed compiled-binary extensions failing to load native .node FFI dependencies by resolving platform-specific packages against the extension's own node_modules.
- Fixed a hang in omp search and omp q CLI commands by ensuring the AuthStorage connection is properly closed upon completion.
- Fixed write blocking for the full LSP diagnostics poll by deferring slow diagnostics to a late-diagnostics channel.
- Fixed multiple browser and puppeteer tool issues, including locator action timeouts, missing console/print output buffering, missing fill() method on element handles, and incorrect viewport screenshots on multi-tab setups.
- Improved browser selector error diagnostics to report match counts and abort early on empty matches instead of waiting for the full timeout.
- Fixed silent failures, duplicate error messages, and unhandled provider errors in ACP mode when errors occurred before streaming assistant text.
- Fixed glob reporting contradictory "no files found" messages on timeout by explicitly stating the scan was incomplete.
- Fixed read adding unwanted context padding to raw range selectors (e.g., raw:31-31).
- Fixed first-run interactive startup rendering the entire changelog when the last-seen marker is missing or unreadable (#5135).
- Fixed empty local-model stop responses exhausting retries without displaying a user-visible error (#5128).
- Fixed serialization of BigInt values in tool arguments during session compaction.
- Fixed GPT-5.6 over-delegating work by centralizing task fan-out and concurrency policy in the system prompt.
- Fixed session title generation including leaked thinking markup from OpenAI-compatible endpoints (#5122).
- Fixed bare skill:// path-only resolution for bash, grep, and glob to resolve to the skill directory instead of SKILL.md (#5087).
- Fixed macOS stdio MCP servers missing Apple Events TCC prompts by spawning MCP children via the correct Bun.spawn overload (#5085).
- Fixed the /move directory picker drawing a narrow 68-column frame inside wider overlays (#5067).
- Fixed snapcompact inline imaging for GitHub Copilot Business and Enterprise models (#4779).
- Fixed omp commit agent sessions to ensure valid proposals are committed before teardown, handle missing host outputs with non-zero exits, and prevent forcing GPG_TTY on signing-enabled repositories (#4794).
Removed
- Removed the bundled plan subagent from available task agents.
[16.4.2] - 2026-07-10
Fixed
- Fixed an issue where BigInt values in tool arguments failed to serialize during session compaction.
- Resolved an issue where GPT-5.6 over-delegated tasks by refining task fan-out and concurrency policies in the system prompt.
- Fixed a race condition in concurrent MCP OAuth token refreshes across processes, ensuring rotating refresh tokens are only refreshed once and preventing stale token errors from clearing valid credentials.
[16.4.1] - 2026-07-10
Changed
- Reduced agent bias against large diffs and refactors in advisor prompts
- Updated advisor blocker criteria to prioritize explicit user instructions over plan size
Fixed
- Fixed MCP OAuth dynamic client registration omitting discovered scopes on the RFC 7591 registration body. Providers such as Clerk bind DCR-created clients to only the scopes declared at registration, then reject the subsequent authorize request when it asks for
openid(fromscopes_supported). Registration now includesconfig.scopeswhen present, matching Claude Code and the scopes already sent on authorize.
[16.4.0] - 2026-07-10
Breaking Changes
- Renamed the bundled agent explore to scout, including its configuration keys, prompt files, and task definitions. Any configurations, allowlists, or invocations referencing explore must now use scout.
- Changed the public
selectLaunchAdapter()result fromDapResolvedAdapter | nulltoLaunchAdapterSelection; callers must handleadapter,unavailable, andnoneoutcomes.
Added
- Added a native, first-class max thinking tier for supported models, including a new thinkingBudgets.max configuration setting, support in CLI flags (--thinking, :max model suffixes), and terminal theme customization (thinkingMax border color and icons).
Fixed
- Fixed Go debug launches falling back to native debuggers when Delve is unavailable; nested modules and
go.workworkspaces now resolve local Delve adapters before PATH, newly installed adapters are detected without restart, and missing adapter errors include install or configuration guidance. (#5037) - Fixed a memory leak (large retained JavaScriptCore heaps) in the TUI during session transcript rebuilds and refreshes by properly handling snapcompact archive image frames.
- Fixed a crash in interactive TUI sessions (Cannot set cwd while another same-realm JS runtime is running) when the JS evaluation worker falls back to the in-process inline path.
- Fixed compaction aborting when Amazon Bedrock credential resolution fails, ensuring it now falls back to trying an authenticated model.
- Improved OpenAI prompt cache hit rates for full-context forks by persisting inherited provider prompt-cache keys separately from session IDs, and added a --prompt-cache-key flag for explicit cache affinity.
- Fixed Codex advisor requests incorrectly using local session labels as provider session IDs, switching to stable UUIDv7 provider identities.
- Fixed macOS stdio MCP servers launching in detached sessions, allowing tools like xcrun mcpbridge to successfully trigger TCC Apple Events permission prompts.
- Fixed the ask tool timeout behavior to automatically select the recommended option if the UI selector does not settle.
- Fixed LSP workspace diagnostics for Go workspaces to correctly recognize go.work roots and include all specified modules in go build package patterns.
- Fixed interactive OAuth login (/login xai-oauth) delaying success messages; credentials are now reported immediately while model metadata refreshes in the background.
- Fixed a crash in the Windows bash tool when a timeout occurs while a piped command is streaming output.
- Fixed subagent yield tool calls being discarded when a soft request budget aborts the assistant turn before the yield event completes.
- Fixed --tools filtering in interactive sessions incorrectly disabling deferred MCP tools from configured servers.
- Fixed kept-alive task subagents entering infinite provider-call loops after an IRC wake and terminal yield.
[16.3.15] - 2026-07-09
Changed
- Integrated testing guidance directly into the main system prompt for improved workflow cohesion
- Moved testing guidance into the main system prompt and removed the bundled Tester subagent.
[16.3.14] - 2026-07-09
Fixed
- Fixed issue where unfinalized tool blocks could incorrectly pin the live-region scroll seam
- Improved rendering of raw thinking blocks by stripping empty HTML comment noise
- Fixed display of thinking blocks consisting entirely of hidden comment noise
- Fixed gpt-5.6 reasoning summaries rendering literal
<!-- -->sentinel lines in thinking blocks; empty HTML comments (and the unterminated<!--tail while streaming) are now dropped from the thinking display, and blocks reduced to pure comment noise are hidden entirely.
[16.3.13] - 2026-07-09
Fixed
- Fixed
readandgreptreating empty optionalselectorfields emitted by models as invalid selectors instead of behaving like omitted selectors. (#4879) - Fixed
grepexplicit line selectors on directory searches so they filter each matched file by line number instead of aborting with a single-file-only error (#4898). - Fixed Read tool previews dropping explicit
selectorarguments, so line ranges andrawmodifiers render in terminal read call titles again (#4899). - Fixed named profiles dropping default user keybindings from
~/.omp/agent/keybindings.*; profile keybindings now inherit those defaults and override only the keys they define (#4867). - Fixed pi extensions calling
ctx.ui.addAutocompleteProvider(...)crashing at load withTypeError: ... is not a function— a failure that, for extensions guarding init in onetry/catch(e.g.@ff-labs/pi-fff), aborted the extension's entire initialization.ExtensionUIContextnow implements pi's autocomplete-provider API: interactive mode stacks each registered factory on top of the built-in editor provider (re-applied on every slash-command refresh, with throwing or malformed factories skipped), while RPC/ACP/headless contexts accept the factory as a no-op. (#4919) - Fixed bundled reviewer and plan subagents to inherit their model roles' explicit thinking effort suffixes instead of pinning
high(#4761). - Built-in provider model discovery now refreshes an expired stored OAuth credential before an online refresh needs it, instead of silently skipping the provider. The refresh is scoped to the providers actually being discovered (
refreshProvidercannot rotate unrelated credentials), fires underonline-if-uncachedonly when the model manager will actually fetch, and offline discovery stays peek-only (#4893). - Fixed Escape during an active TUI prompt requiring a second press before canceling; the first Escape now aborts the streaming turn immediately. (#4921)
- Fixed the streamed
writetool's collapsed pending tail preview leaving stale rows above the first partial-result frame in the TUI; the first result now replays the viewport like the SSH placeholder seam already did (#4477) - Fixed first-run setup ignoring a pre-seeded
config.yaml: the settings loader now treatsconfig.ymlandconfig.yamlas equivalent existing main config files, writes back to the existing extension, and only creates canonicalconfig.ymlfor fresh installs. (#4914) - Fixed extension
sendUserMessage()withoutdeliverAssurfacingAgentBusyErrorduring active streams; omitteddeliverAsnow queues a steer through the normal prompt flow, and ACP/RPC skill-command prompts queue while streaming (RPC honors the prompt command'sstreamingBehavior, defaulting to steer) (#4923).
[16.3.12] - 2026-07-08
Added
- Typing
#<number>(e.g.#3164) in the prompt now offers PR and Issue autocomplete candidates that rewrite to thepr:///issue://internal URL, resolved from the current repo's git remote via the existingreadtool → InternalUrlRouter →ghpipeline. Naming the type (pr #3164/issue #3164) constrains the candidates to that kind, and embedded hashes likeowner/repo#N,foo#N, or URL fragments are left untouched (#3218)
Changed
- Memoized non-message token totals (system prompt, tool schemas, skills) so the per-turn compaction and context-threshold paths recompute them at most once per input change instead of on every call.
getContextBreakdownand#estimateStoredContextTokenspreviously re-tokenized the system prompt and every tool's wire schema (per-toolJSON.stringify) several times per turn over inputs that change at most once per turn.
Fixed
- Improved handling of unawaited promises in JS eval cells to prevent process crashes
- Added warning logs for unhandled rejections originating from finished eval cells
- Improved advisor robustness by blocking exhausted accounts during consecutive turn failures
- Fixed advisor turns hammering the same usage-limited account: a failed advisor turn now marks the exhausted credential blocked (with the provider's retry hint and usage-report reset time), so the next retry rotates to a sibling instead of re-picking the blocked account every few seconds. Previously the in-stream auth retry rotated within a request but never blocked the last failing credential, and the advisor loop — unlike the primary retry pipeline — never called
markUsageLimitReached. - Added the account key to the
codex-auto-reset: skippeddebug log so skip reasons (e.g.weekly-not-exhausted) can be attributed to the evaluated account. - Fixed unawaited promise rejections in JS eval cells crashing the session: a floating rejection now fails the owning cell run (
Unhandled rejection (missing await?): …) instead of escaping to the globalunhandledRejectionhandler, which printed[Unhandled Rejection]and killed the process (inline fallback) or tore down the eval worker (dedicated worker). Rejections surfacing after a cell settled are downgraded to a warn log attributed to the finished cell. - Fixed project
.omp/RULES.mdsticky rules being shadowed by user~/.omp/agent/RULES.mdrules with the same synthesizedRULESname, so both user and project sticky rules now inject (#4739). - Fixed bash internal-URL expansion so unresolved literal
memory:///skill://text stays verbatim instead of aborting command execution (#4737). - Fixed
agent://<id>(and theoutput()eval helper) failing withNot foundfor a subagent spawned by another subagent (any spawn chain 2+ levels deep).artifactsDirsFromRegistryscanned only each ref's adopted (root-wide)ArtifactManagerdir, but a subagent's own children are written one level deeper under itssessionFile-derived dir — so a live, addressable nested peer's output was unresolvable. The resolver now collects both candidate dirs per registered agent. (#4650) - Fixed plan mode to document
local://artifacts as writable session-local planning files and to carry every pre-approvallocal://artifact into the fresh session created by Approve and Execute. - Fixed the browser tool failing to launch Microsoft Edge-only Windows installs with Puppeteer's empty
Code: 0launch error by keeping Edge's required--enable-automationdefault while preserving Chrome/Chromium stealth launch defaults. - Fixed bash/tool command environments inheriting Bun-autoloaded launch
.env.localvalues, so nested apps can load their own dotenv values without parent deployment variables taking precedence. (#4723) - Fixed legacy plugin validation for extension graphs that import JSON with
with { type: "json" }, leaving JSON files on Bun's native loader instead of parsing them as JavaScript (#4687). - Fixed pasted terminal transcripts beginning with a shell prompt (
$ ...) being mistaken for local Python shortcuts instead of being submitted as normal prompts (#4678). - Fixed wrapped OAuth copy-URL rows corrupting on paste: continuation chunks no longer carry a leading indent, so a multi-row terminal selection reassembles to the exact authorize URL (browsers strip newlines on paste but preserve or percent-encode embedded spaces, which previously corrupted the URL at every chunk boundary).
- Fixed Windows browser-launch failures being unobservable: the opener now uses
%SystemRoot%-resolved PowerShellStart-Process(via-EncodedCommand) instead ofrundll32, which exits 0 unconditionally. Failures ShellExecute itself reports — missing target, no handler executable, access denied — now surface as non-zero exits and are logged; the encoded payload also keeps OAuth query strings (&-bearing) opaque to shell metacharacter parsing. - Fixed system prompt date rendering to use the host local calendar date instead of UTC.
- Fixed
bashtooltimeout: 0so it disables the command deadline instead of falling back to the minimum timeout. - Fixed
readandgreprefusing to access filesystem paths whose names end in a selector-shaped suffix (e.g.test:1-2,log:raw) by preferring a literal match over the trailing:<selector>peel when the raw path exists on disk (#4618). - Fixed wrapped Edit-diff rows leaking inverse video into the result card's right-edge padding: a row that broke inside an intra-line highlight left inverse active at the row end, so the frame padding after it rendered as a default-foreground block (#4616 by @chan1103)
- Fixed Edit-diff continuation rows escaping into the line-number column when the row's gutter was left-padded (line number narrower than the widest in the diff) or blanked by the gutter dedup (the bare
+row of a single-line replacement); such rows now wrap behind a continuation gutter, while body lines that merely start with|keep wrapping generically (#4616 by @chan1103) - Fixed live advisors continuing to use a stale
modelRoles.advisorselection after/modelchanged the advisor model. (#4612) - Fixed Claude plugin slash commands and skills silently vanishing when the plugin manifest declares
commands/slash-commands/skillsas a JSON array — the shape the Claude plugins reference documents and real plugins likeaddyosmani/agent-skillsship.resolvePluginDirinpackages/coding-agent/src/discovery/claude-plugins.tstyped those fields asstringand dropped array values on the floor; it now normalizes both shapes, loads every in-root entry, and reports one out-of-plugin-root warning per bad entry. The resolver also now honours Claude's per-field merge semantic —skillsadds to the defaultskills/scan;commands/slash-commandsreplace the defaultcommands/— so plugins like{"skills":["./extra-skills"]}no longer lose their defaultskills/folder while{"commands":["./admin"]}still replacescommands/as documented. (#4609) - Fixed macOS Backspace on empty search not deleting sessions in the
/resumepicker; Fn+Backspace terminals that deliver\x7finstead of\e[3~now reach the delete confirmation dialog. (#4580 by @JagravNaik) - Fixed
/renametitle arguments treating#prompt-action tokens as autocomplete triggers instead of literal session title text. (#4600) - Fixed empty session
.jsonlfiles accumulating in~/.omp/agent/sessions/<cwd>/after a draft-then-clear exit cycle.SessionManager.saveDraft(text)materializes the session file so the draft sidecar has a parent; a subsequentsaveDraft("")unlinked the sidecar but left the metadata-only JSONL behind (title slot + session header + startup selector entries, ~500–750 B), and#shouldHaveSessionFile()could no longer prune it once#fileIsCurrent/#forceFileCreationwere latched.SessionManager.close()now drops only draft-owned metadata-only sessions with no saved draft sidecar to reattach to, while keeping real conversations, meaningful non-message entries such as handoff custom messages, explicitensureOnDisk()sessions, drafts still pending for--resume, and never-materialized sessions untouched (#4571). - Fixed the advisor being disabled for the entire session when the advisor role resolves to a reasoning model that exposes no controllable effort surface (Devin
devin/glm-5-2*:reasoning: true,thinking: undefined— Cascade routes by sibling model id rather than a wire param).#resolveAdvisorRuntimeDescriptorsinpackages/coding-agent/src/session/agent-session.tsused to hardcodeThinkingLevel.Medium, which trippedrequireSupportedEfforton the first advisor prompt withThinking effort medium is not supported by devin/glm-5-2. Supported efforts:(empty list). The advisor descriptor now clamps the requested effort against the resolved model viaresolveThinkingLevelForModeland forwards no explicit effort when the model has no controllable efforts — matching theauto-path fix (clampAutoThinkingEffort) and the Autonomous Memory stage fix (clampThinkingLevelForModel). Explicit:offstill disables reasoning, and models that supportmedium(e.g. Anthropic) keep receiving it (#4579). - Fixed legacy extension plugin validation failing with
Export named 'calculateCost' not found in module '.../legacy-pi-ai-shim.ts'when the extension importscalculateCost(ormodelsAreEqual/getBundledProviders) from@oh-my-pi/pi-ai. Those symbols were relocated to@oh-my-pi/pi-catalog/modelsduring the catalog split but were never bridged back through the legacypi-airoot shim; the shim now re-exports them alongside the existinggetModel/getModelsaliases so plugins written against pre-split pi-ai load again (#4584). - Fixed legacy extension plugin validation failing with
Export named 'calculateCost' not found in module '.../legacy-pi-ai-shim.ts'when the extension imports relocated catalog symbols such ascalculateCost,modelsAreEqual,getBundledProviders,getBundledModel, orgetBundledModelsfrom@oh-my-pi/pi-ai. Those symbols were relocated to@oh-my-pi/pi-catalog/modelsduring the catalog split but were never bridged back through the legacypi-airoot shim; the shim now re-exports them alongside the existinggetModel/getModelsaliases so plugins written against pre-split pi-ai load again (#4584). - Fixed legacy pi extension imports of
DefaultResourceLoaderfrom@mariozechner/pi-coding-agent/@earendil-works/pi-coding-agentby adding a compatibility loader shim that translatesresourceLoaderinto OMP's native session discovery options. (#4567) - Fixed legacy Pi extension reloads on POSIX so
loadLegacyPiModuleimports the entry through a cache-busting filesystem path, refreshes load-time graph hooks when reloads add new modules, and threads the current load's?mtimetag through the extension source graph — relative./helper.tssiblings,#alias/*package-imports, extension-local bare dependency entries, and their relative children all rekey per reload, so same-process re-imports pick up edits across the whole graph. (#4565) - Fixed bash tool pipeline execution preserving stale upstream output when the final stage was a stripped
head/taillimiter; the tool now runs the command as written soseq 1 5 | head -n2returns only1and2. (#4562) - Fixed the status-line token-rate segment rendering as
<number>/s, which Ghostty auto-detected as a hyperlink on Ctrl+hover. (#4541) - Fixed retry fallback model recovery by exposing
retry.fallbackChainsin/settings, adding a/modelaction to assign the selected default fallback model, and clearing a selected model's retry cooldown marker on manual model switches. (#4533) - Fixed
/handoffand auto-handoff skipping extension lifecycle hooks by emitting cancellablesession_before_switchhooks and asession_switchwithreason: "handoff"after the replacement session is ready (#4434). - Fixed TTSR stream interrupts so only the tool call whose stream matched a rule receives the rule-named abort result; sibling tool-call placeholders now use a neutral abort reason (#2783).
[16.3.11] - 2026-07-06
Changed
- Improved session title generation reliability by moving to marker-based parsing for all models
Fixed
- Fixed session titles occasionally showing raw
{"title": "..."}JSON. Online title generation now always uses the<title>...</title>marker prompt instead of a forcedset_titletool call — hosts that ignored or rejected forcedtool_choiceechoed the prompt's JSON example verbatim as the title — and JSON-shaped responses (bare, code-fenced, marker-wrapped, or truncated) are unwrapped to the bare title. - Fixed Linux startup prompt construction to read the CPU model from
/proc/cpuinfoinstead ofos.cpus(), avoiding per-core sysfs frequency probes on many-core hosts (#4712). - Fixed llama.cpp model discovery to honor per-model
architecture.input_modalitiesfrom/v1/models, so router presets that advertise image input are no longer treated as text-only (#4719).
[16.3.10] - 2026-07-06
Changed
- Limited subagent HUD display to 8 items with a summary for additional running subagents
- Improved TUI performance by coalescing agent registry and observer UI updates
Fixed
- Fixed high-subagent sessions overwhelming the TUI by bounding the running-subagent HUD and coalescing subagent progress repaint bursts.
- Fixed browser run cleanup crashing or wedging the whole omp session: run-end and tab-close aborts could reject fire-and-forget
wait()/facade/tab promises with no consumer, and the global unhandled-rejection handler then exited the process, killing every subagent sharing it. Run-scoped promises are now observed at creation and routine browser teardown aborts are downgraded to log lines (#4499, #4672). - Reduced CPU use while many task subagents stream progress by disabling the obsolete task partial-result spinner repaint loop (#4424).
- Capped collapsed nested subagent trees at the same per-level agent limit as top-level task rendering (failures prioritized, elided rows summarized), so deep many-subagent sessions no longer render unbounded progress trees on every repaint.
- Fixed skill card headers to render a single space between the
skilltag and skill name (#4662). - Fixed
get_session_statsRPC responses to include context-window usage so RPC clients can render context meters. - Fixed startup of cached llama.cpp vision models so the initial default/restored model refreshes
/propsmetadata before the session exposes it as text-only. - Fixed IRC-woken yielded subagents skipping empty-stop retry because stale yield-termination state carried into the wake turn (#4658).
- Fixed
irc waitskipping replies that arrived between wait calls by draining pending IRC asides before honoring queued-interrupt aborts (#4657).
[16.3.9] - 2026-07-06
Added
- Added a
--fileflag to thesaycommand to read input text directly from files. - Enabled streaming text synthesis in the
saycommand for gapless, long-form audio generation. - Added voice selection validation to the
saycommand.
Changed
- Improved the
saycommand to display the segment count and total duration upon completion.
Fixed
- Fixed an issue where local llama.cpp vision models remained text-only after a model refresh, ensuring they are correctly recognized as image-capable when configured as the default or vision role.
- Fixed
omp commitsplit plans aborting when lock files (such asbun.lockb) were staged alongside their manifests by correctly pairing lock files with their corresponding commit groups and properly handling binary files during split execution. - Fixed skill loading to ensure that disabling a higher-priority provider does not drop same-named skills from enabled lower-priority providers.
[16.3.8] - 2026-07-05
Fixed
- Fixed the browser tool silently launching without its Puppeteer stealth patch: the patch was keyed to
puppeteer-core@25.1.0while the resolved dependency had drifted to25.3.0, so Bun skipped it and Chrome ran with theRuntime.enableautomation tell re-enabled. Regenerated the stealth patch against 25.3.0 and pinnedpuppeteer-coreso the exact-version patch cannot silently deactivate on future drift.
[16.3.7] - 2026-07-05
Added
- Added support for reading full memory rows (working or episodic) via
read memory://<id>under the mnemopi backend, returning a YAML-frontmatter header with metadata to prevent blind overwrites during edits. - Updated the URI grammar to support
memory://root[/…]for file-backed summaries andmemory://<memory-id>for specific mnemopi IDs.
Changed
- Updated
recallandmemory_edittool prompts to document truncation markers and require reading a memory ID before updating a truncated preview. - Parallelized resolution of system files (
SYSTEM.md,APPEND_SYSTEM.md, andTITLE_SYSTEM.md) at startup to improve performance. - Optimized TUI performance and reduced CPU usage during streaming and live tool calls by scoping renders to changed subtrees, interning the working-message shimmer palette, and memoizing copy-selector preview highlights.
- Loaded persisted Agent Hub subagents asynchronously to prevent blocking the TUI on directory walks.
- Cached persisted message keys in
AgentSessionto avoid repeated branch walks on message completion. - Skipped TTSR delta buffering for text/thinking sources when no registered rules match.
Fixed
- Fixed macOS Backspace behavior in the
/resumepicker for terminals delivering\x7finstead of\e[3~. - Fixed queued follow-up message rows leaking into native terminal scrollback during live repaints by anchoring the pending-messages container.
- Fixed
/renametitle arguments treating#prompt-action tokens as autocomplete triggers instead of literal text. - Fixed empty session
.jsonlfiles accumulating in the sessions directory after a draft-then-clear exit cycle. - Fixed advisor being disabled for the entire session when resolving to a reasoning model with no controllable effort surface (e.g.,
devin/glm-5-2*). - Fixed legacy extension plugin validation failures by re-exporting relocated catalog symbols (such as
calculateCost,modelsAreEqual, andgetBundledProviders) through the legacypi-airoot shim. - Fixed legacy Pi extension imports of
DefaultResourceLoaderby adding a compatibility loader shim that translatesresourceLoaderinto native session discovery options. - Fixed legacy Pi extension reloads on POSIX to ensure same-process re-imports pick up edits across the entire dependency graph.
- Fixed bash tool pipeline execution preserving stale upstream output when the final stage was a stripped
headortaillimiter. - Fixed the status-line token-rate segment rendering as a clickable hyperlink in Ghostty.
- Fixed xAI
web_searchto prioritizexai-oauthcredentials before falling back toxaiAPI keys, and enforced result counts locally to avoid sending unsupported parameters. - Fixed token-usage badges disappearing on session resume for empty automated assistant turns.
- Fixed
/modelsearch escaping the active provider tab and silently persisting a same-named model from a different provider as the default role. - Fixed Esc key behavior to immediately silence active TTS audio playback (such as Kokoro) once an assistant reply finishes streaming.
- Fixed grep and bash tool guidance to instruct agents to use Rust-style patterns or
grep -Einstead of GNU BRE assumptions. - Fixed tool-call renderers crashing the TUI when providers send array/object
patharguments before schema validation. - Fixed
globtool rejecting slash-only root searches (e.g.,path:"/") with a documented error instead of returning empty results. - Fixed
omp readhanging on PDFs whose inline-image binary payloads contain delimiter-looking bytes. - Fixed
pi/<role>model resolution crashing on YAML list-valuedmodelRolesentries. - Fixed the snapcompact settings UI to expose
silver16-bwand improved renderability warnings to report unsupported glyphs. - Fixed session and status usage totals to preserve provider-reported orchestration tokens separately from input and cache-hit buckets.
- Fixed published
.d.tsdeclaration files to be consumable undermoduleResolution: "node16" | "nodenext"by rewriting relative specifiers to explicit.jsextensions. - Fixed
omitThinkingsettings propagation so settings-aware streams request hidden thinking summaries when explicitly enabled. - Preserved isolated branch-mode task output as a patch artifact when
commitToBranchfails, surfacing the captured patch path through the evaluation failure message. - Fixed task-class subagents dropping unresolved explicit model-role selectors before startup.
- Fixed large legacy snapcompact archives causing crashes on resume due to oversized archived frame payloads.
- Fixed LSP diagnostics staleness by sending watched-file change notifications to running language servers before reading edit-time diagnostics.
- Documented the bash tool timeout clamp (capped at 3600 seconds for async jobs) in the model-facing schema and prompt.
- Fixed
/fast onfor custom OpenAI-compatible providers serving OpenAI models, and reported unsupported models as unavailable. - Fixed extension
pasteToEditorandsetEditorTextprompt mutations leaving the editor visually stale by scheduling a repaint after mutations. - Fixed session title generation, commit-message generation, speech-enhancer rewrites, and classifiers silently truncating on non-reasoning-flagged models that still emit thinking output.
- Fixed plan-mode "Approve and compact context" discarding queued operator turns and leaking internal plan-distillation prompts to extension hooks.
- Fixed malformed
pi.sendMessagecustom-message payloads persisting bare session entries that crashed subsequent resumes. - Hid internal
display: falsesession-update reminders from compact history and advisor transcripts. - Fixed idle recap crashes caused by side-channel stream malformations.
- Applied WebSocket send backpressure with ordered drain retries to prevent unbounded buffer growth.
- Capped docs.rs gunzip decompressed size at 256 MB to prevent zip-bomb out-of-memory crashes.
- Deleted pre-created shell snapshot files when snapshot creation fails.
- Aborted underlying MCP calls when proxy tool timeouts fire.
- Surfaced unexpected JS eval worker exits via close listeners to prevent silent hangs.
- Cached failed
!commandconfig resolutions and timed out extension dynamic model fetches after 15 seconds.
[16.3.6] - 2026-07-04
Changed
- Hided abort labels for user-interruptions in the transcript to match silent abort behavior
- Updated transcript streaming to declare settled rows for scrollback exactness:
TranscriptContainerreports one boundary (finalized blocks plus the first live block'sgetTranscriptBlockSettledRows(), fed by markdown's frozen-token prefix — completed content blocks in a streaming reply render final and settle in full, so long replies and visible thinking reach terminal scrollback as exact bytes mid-stream). The heuristic commit machinery (deriveLiveCommitStateappend-only detection, stable-prefix ratchet, volatile cooldowns, rewrite floors),isTranscriptBlockCommitStable, and the per-rendererprovisionalPendingPreview/provisionalPartialResultflags are all removed. Ephemeral block retraction (displaceable todo/job cards, IRC cards) is now gated onTranscriptContainer.isBlockUncommitted()— cards whose rows already entered scrollback seal in place as history instead of being removed. - Recovered auto-retry errors now compact in the transcript: once a retry succeeds, the superseded error rows (e.g. Anthropic
429 rate_limit_errorduring account rotation) render as a single dim note likerate-limited; switched account; retriedacross live view, rebuilds, resume, and subagent/collab transcript views, and are excluded from model context on session resume. Terminal (unrecovered) errors keep full error rendering. The persisted marker isretryRecoveryon the assistant message andauto_retry_endsuccess events carry additiverecoveredErrorsdata.
Fixed
- Fixed raw
readranges not contributing to edit seen-line provenance, so re-reading an anchor range with:rawnow unblocks hashline edits without adding non-raw line prefixes. - Fixed replan-driven session title refresh updating the statusline but not the terminal window title: terminal-title updates now fire from the session-name-changed listener, so every
setSessionNamepath (first-input titling,/rename, plan seeding, replan refresh) sets the OSC title consistently. - Fixed user-interrupt aborts rendering the persisted
Interrupted by userlabel in assistant transcripts; replay and live views now suppress that redundant line again while preserving generic/custom abort labels. - Fixed streamed assistant text and thinking disappearing from terminal scrollback while a long turn ran, and Ctrl+O-expanded tool results showing up half-rendered above the viewport: everything that scrolls off the window now reaches native scrollback (exact bytes for settled content, a frozen what-you-saw snapshot for still-running blocks, repaired at most once when the block finalizes). Streaming eval/bash boxes no longer spray duplicated stale copies; user-initiated
!/$execution blocks report a finalization contract. - Fixed turn-ending provider errors rendering with a doubled blank gap above the
Error:block (caller and error block each added a spacer). - Fixed the write tool renderer crashing when persisted runtime content is a truthy non-string value; rendering now coerces display content before Windows CR normalization. (#4495)
- Fixed cmux-backend
browser({action:"run"})calls crashing the entire process with an unhandled rejection when the tab was released mid-run (e.g. a sibling subagent callingbrowser({action:"close", all:true})or a session-scoped tab reap).runInTabWithSnapshotintab-supervisor.tscreates aPromise.withResolvers()triple soreleaseTabcan signal in-flight runs, but the cmux branch used to awaitrunCmuxCode(...)directly and never awaited the local promise. WhenreleaseTabrejected that orphaned promise ("Tab ... was closed"), Bun surfaced it as an unhandled rejection and the top-level handler tore the whole session down, killing every other tab and subagent sharing it. Both backends now await the samepromise(sopending.rejectalways has an attached handler AND the caller seesTab "..." was closedimmediately instead of blocking to the run's timeout), and a newpending.closeAcis composed into the cmux run's abort signal sowait(...), in-flight cmux socket calls, and the facade proxies unwind promptly when the tab is closed rather than leaking to their own timeout (#4499).
[16.3.5] - 2026-07-04
Fixed
- Fixed Mnemopi auto-retention so protocol markers are stripped from embedding and FTS projections while stored transcripts remain readable. (#4395)
- Fixed mnemopi auto-retain storing cumulative full-session transcripts on every retention interval; subsequent retains now store only newly completed user-turn suffixes. (#4396)
- Fixed large
artifact://reads materializing entire MCP/tool artifacts before selector paging, preventing OOM crashes on unbounded raw reads and surfacing bounded read/search/copy guidance (#4482). - Fixed
/mcp reauthand/mcp adddropping OAuth scopes advertised viaWWW-Authenticate: Bearer scope="..."challenges and via protected-resource metadata (scopes_supported/scopes/scope), which caused tokens to be issued without the required scopes and reconnects to fail withinsufficient_scope(#4467) - Fixed task-branch merges aborting the whole cherry-pick range when a single commit was empty against HEAD (redundant with an already-applied change, or 3-way merged to HEAD); the sequencer now
--skips the empty commit and continues so later non-overlapping work still lands (#4438). - Fixed write/edit LSP diagnostics for TypeScript files outside any project root by suppressing project-resolution noise while preserving real syntax errors (#4401).
- Fixed
/mcp reauthagainst S256-only OAuth providers (Linear, and OAuth 2.1 flows generally) failing on Windows and other environments where the browser cannot auto-open. Two independent defects converged on Linear'sThe plain PKCE method is not allowed. Use S256 instead.error page:openPathinvoked barerundll32and silently swallowed the resultingExecutable not found in $PATHwhen the Windows machine PATH no longer referencedSystem32, andMCPAuthorizationLinkPromptcomposed aCopy URL:line wider than the viewport thatTUI#prepareLinethen silently truncated — trimming the trailingcode_challenge_method=S256(RFC 7636 §4.3 treats a request withcode_challengeand no method asplain). The MCP OAuth fallback,/login, setup wizard, auth-broker CLI, and login-dialog now advertise the shortOAuthAuthInfo.launchUrl(loopback/launchroute hosted byOAuthCallbackFlow) as the copy target; the OSC 8 hyperlink still carries the full URL for click-through; the MCP flow additionally stages the copy target on the clipboard via OSC 52; and the Windows opener now resolvesrundll32.exethrough%SystemRoot%\System32\, logging spawn failures and non-zero exits instead of dropping them (#4418). - Fixed
lsp rename_fileaborting when an LSP server returns duplicate byte-identical non-empty text edits for the same range, such as tsserverwillRenameFilesedits through barrel re-exports (#4458). - Fixed Linux x64
PI_TINY_DEVICE=cudatiny-model side runtimes missing ONNX Runtime CUDA provider binaries by repairing theonnxruntime-nodeCUDA sidecar install and preserving actionable CUDA diagnostics inomp tiny-models downloadoutput (#4475). - Improved reliability of edits when file snapshots share identical 16-bit hash tags
- Fixed ACP
terminal/createsending the bash tool's full shell line incommandwith noargs, which broke spec-conformant clients that spawncommand+argsdirectly (no implicit shell) — any command containing a space, pipe,&&, redirect, or$(...)failed withENOENTand the agent silently degraded to read-only tools. The bash tool now wraps the shell line before callingclientBridge.createTerminal, reusing the same shell binary + args the localbash-executorresolves viasettings.getShellConfig()(Git Bash /bash.exeon Windows,$SHELLwithshfallback on POSIX) so bash semantics —$VAR,$(...),source, POSIX quoting,-l— are preserved on both platforms. (#4333) - Fixed inference worker subprocesses (TTS, STT, tiny-model, mnemopi embeddings) discarding stderr, which left every unexpected exit — most visibly the local Kokoro TTS worker's recurring
exit code 7crash loop — undiagnosable from the parent's logs.createWorkerSubprocessnow pipes stderr without starting a live read while the worker is idle, then drains the stream afteronExit, emits captured lines tologger.debugunder an<exitLabel> stderrmessage, and keeps the last 16 KiB in a bounded ring that gets appended to theErrorsurfaced throughonError. The exit surface is synchronized with the post-exit drain viaSpawnedSubprocess.stderrDrained, so the full native trace shows up on thetts: worker errorline without reintroducing event-loop liveness from unref'd workers. (#4324) - Fixed Windows session tail loss after atomic compaction rewrites by fencing append writers during full-file replacement and gating the atomic publish on a
commitGuardthat the storage backend checks synchronously before rename, so a concurrentflushSync(Ctrl+C / session-exit) is not overwritten by the stale body serialized before it ran. Covers post-compaction prompts, tool results, title changes, and exit diagnostics on the current JSONL path (#4338).
[16.3.4] - 2026-07-03
Fixed
- Fixed
omp usagehiding sibling-only limits such as Claude 7 Day (Fable) on accounts whose current report omitted that scoped bucket; the account now renders an explicitnot reportedrow instead of looking like the usage refresh skipped the column.
[16.3.3] - 2026-07-02
Breaking Changes
- Removed _input as a supported alias for the edit tool input field
Changed
- Refined advisor note card visuals with a dedicated rail character and bold label headers
- Deferred session_stop extension hooks and incomplete-todo reminders until all agent-owned background jobs (such as async bash or task spawns) are fully idle
- Restyled the advisor note card so notes no longer blend into thinking output: bold label-tag header, heavier severity-tinted rail, and note body on the default text color instead of thinking-gray
Fixed
- Fixed TUI loading animation sometimes failing to render during interactive mode status updates
- Fixed race conditions and potential hangs during agent startup by improving process lifecycle management
- Fixed RpcClient startup errors intermittently losing the child's stderr (e.g. the "Unknown provider" message) by waiting for the process to exit — and its stderr to fully drain — before reporting a failed start; also fixed an unhandled rejection when the agent process is killed before becoming ready
- Improved reliability of file edits when snapshots share identical hash tags
- Fixed terminal creation in ACP by properly wrapping shell commands and arguments, resolving execution failures (such as ENOENT errors) on Windows and POSIX platforms
- Fixed inference worker subprocesses (such as TTS, STT, and embeddings) discarding stderr, ensuring unexpected crashes and exit traces are properly captured and surfaced in logs
- Fixed potential session data loss on Windows during atomic compaction rewrites by preventing concurrent writes from overwriting the session file during exit or compaction
- Fixed transcript scrollback boundaries to prevent duplicate rows from appearing when live blocks grow
- Fixed macOS SSHFS mount detection to avoid redundant remounting attempts when the mountpoint is unavailable
- Fixed SSH streamed placeholders and partial frames leaving stale rows in the TUI viewport and scrollback
- Fixed Gemini web search to correctly honor the configured search model (providers.webSearchGeminiModel or GEMINI_SEARCH_MODEL) for both OAuth and Developer API grounding requests
- Fixed omp install rejecting valid npm package specifications
- Improved MCP OAuth reauthorization error messages when dynamic client registration is closed, directing users to configure client credentials
- Fixed omp update -l to correctly support the plugin-update shorthand for upgrading marketplace plugins
- Fixed /advisor on command to correctly rebuild the advisor runtime and bind to the newly configured model
- Fixed edit tool failures on large source files after a structural-summary read by automatically merging unseen anchor lines into the snapshot
- Fixed potential hangs and process leaks in the Debug Adapter Protocol (DAP) client by introducing write timeouts and ensuring detached adapter processes are terminated on connection failures
- Fixed status-line GitHub PR lookup hangs by enforcing a command timeout
- Fixed potential pipe-buffer deadlocks during plugin installation, uninstallation, and updates by concurrently draining stdout and stderr
- Fixed SSH tool hangs on unreachable hosts by enforcing a 30-second timeout on pre-command connection and host probes
- Fixed models.yml schema validation to surface warnings for invalid custom provider configurations instead of silently ignoring them
- Fixed potential network hangs in omp update, Hindsight recall, and Smithery registry lookups by adding fetch timeouts
- Reduced TUI CPU overhead during streaming and idle waits by dropping the redundant pre-render on every session event, iterating shimmer text in place instead of allocating a code-point array per animation frame, and coalescing the live-tool spinner render cadence to its glyph-advance rate (#4353).
[16.3.2] - 2026-07-02
Breaking Changes
- Changed search tool
pathsparameter to a single semicolon-delimitedpathstring parameter
Changed
- Reduced extension startup cost, especially on Windows, by reading each extension source-graph module from disk once per load instead of twice (the graph scan now feeds the load-time rewrite hook) (#4196).
Fixed
- Fixed ALL-CAPS acronyms (e.g.
CNPG,ETL,JWT) being lowered to title case in auto-generated session titles.reconcileTitleCasing(packages/coding-agent/src/tiny/text.ts) now maps ALL-CAPS source tokens into anacronymstable and restores them when the model produces a title-cased artifact (Cnpg), while still declining restoration on shouty input (FIX the BUG NOW,ALL ERROR HANDLING) via a consecutive-ALL-CAPS heuristic. Title prompts also instruct the model to preserve ALL-CAPS acronyms verbatim. (#4220) - Fixed cold-start
--modelresolution for extension providers whose catalogs come only fromfetchDynamicModels, so fresh cached runtime models are available before session startup falls back or hard-fails. (#4216) - Fixed plugin and legacy extension discovery repeatedly re-reading plugin manifests and walking extension
node_modulesby caching results until plugin cache invalidation. (#4197) - Fixed
discoverExtensionPathsinvoking every registered extension-module provider (claude, codex, gemini, opencode) on startup and discarding all non-native results. The extension-module capability is now loaded withproviders: ["native"], skipping four foreign directory walks per session — noticeable on Windows where the walks are slowest (#4198). - Fixed
/moveoverlay running anfs.statSyncper directory entry per keystroke; the directory listing cache now storesDirent[]and classifies entries without a syscall, falling back tostatSynconly for symlink entries (#4199). - Fixed default model switches being persisted without changing the active goal-mode session when the current context exceeded the target model window. (#4219)
- Fixed live tool preview spinners staying pinned to their first frame for
evaland shell-style renderers. (#4170) - Fixed isolated task merges failing when the parent working tree carried WIP for a file the isolated subagent also touched.
commitPatchToBranchWorktreenow tries plain apply andgit apply --3wayfirst (agent-only outcome when the WIP-side blob is tracked in HEAD), then falls back to seeding the temp worktree with the baseline WIP so the delta patch's HEAD+WIP context matches, and rewinds WIP-only files afterward so they don't leak into the branch commit. Covers untracked WIP files, staged-new WIP files, and overlaps--3waycannot resolve. (#4136) - Fixed
discoverAgents()skippingagents/subdirectories inside OMP extension packages, so agents shipped byomp plugin install-ed npm plugins (e.g.loom) and--extension/extensions:settings roots now load the same way their siblingskills/,hooks/,tools/directories already do. The new scan goes throughlistOmpExtensionRoots, so Claude marketplace installs continue to flow through theclaude-pluginsprovider without being double-counted. (#3920) - Fixed plan mode hanging without converging on
ask/resolveafter advisor cards, idle IRC messages, or follow-on turns. Plan-mode decision enforcement ran on only the non-syntheticprompt()return; continuation/wake paths settled viaagent_endand bypassed it. Advisor cards and idle IRC are now recorded into context without waking an autonomous turn, and theask/resolvedecision is enforced at the universalagent_endterminal settle via a bounded-retry counter (provider-neutralrequired, both tools kept available) that reminds-then-forces a fixed number of times and then yields to the user — never looping, never silently ending plan mode un-converged. Anirc send await:trueto an idle plan-mode session now answers the sender through the existing ephemeral side-channel auto-reply instead of stranding it until its wait timeout, and a queued forced plan decision is dropped when its continuation is skipped or plan mode exits. (#3910) - Reduced subagent streaming CPU cost: the recent-output window no longer re-splits the full (up to 8 KB) tail on every streamed text token. Fragments without a newline extend the current last line in place, and a full recompute runs only when line boundaries actually change.
- Reduced task-render CPU cost: the task result frame (repainted ~30×/sec via the spinner) previously did 7+ full passes over the result set (
some/filter/reduce); a single pass now derives the status booleans, footer counts, and request total, and incremental review extraction reuses the yield data the caller already normalized instead of re-normalizing it. - Reduced model-resolution cost:
resolveModelRoleValuenow builds the preference context (an O(n) model-order map over all available models) once and reuses it across every fallback pattern instead of rebuilding it per pattern, andmatchModelhoists the case-folded pattern once instead of.toLowerCase()-ing it for every candidate across each filter pass. - Reduced read-tool allocation: line counting counts newlines directly instead of allocating via
split("\n"), and the hashline formatter no longer counts the same content twice. - Fixed the assistant-message streaming fast path dropping the transient flag, which disabled the transient render path (code-highlight skip and streaming prefix caches) on every same-shape streaming tick. In-flight renders now correctly skip per-tick syntax highlighting; highlighting applies once at message finalization.
- Fixed hidden goal-mode todo context: phase names and task text are now sanitized before prompt injection (no raw newlines or control characters forging extra context lines), and the block is only rendered with tool-accurate guidance when the
todotool is active or discoverable instead of unconditionally instructing the agent to call an unavailable tool. - Fixed custom tool loading treating
process.exit()from a tool module's import or factory as a host process exit instead of a recoverable load failure. Custom tools now load under the shared extension exit guard, so an exiting tool is skipped with a load error while remaining tools still load (#1704).
[16.3.1] - 2026-07-02
Breaking Changes
- Changed the
grep,glob, andast_greptools to take a single optionalpathargument instead of apathsarray.pathaccepts one path or a semicolon-delimited list (src; tests); omitting it searches the workspace root (.). Multi-path search, delimited expansion, and internal-URL scopes are unchanged. (ast_editcontinues to takepaths.)
Added
- Added
speech.enhancedsetting to rewrite assistant output into natural spoken prose - Added
speech.enhancedsetting: assistant output is rewritten into natural spoken prose by the tiny/smol model before synthesis — code blocks become one-clause descriptions, links speak their label or site name, numbers and symbols read naturally, lists become flowing sentences. Blocks are rewritten fence-aware and coalesced (bounded to two concurrent completions); any failed or timed-out rewrite falls back to the mechanical cleanup so speech never blocks on the model.
Changed
- Redesigned speech vocalization for low latency and clean spoken content. Assistant markdown now runs through a speakable-text pipeline before synthesis: code blocks and tables are silent, links speak their label, bare URLs speak their host, inline-code ticks/emphasis/heading/bullet markers are stripped, and long file paths collapse to their basename. Segmentation is now parent-side and emits at sentence boundaries immediately (the previous engine-side splitter held each sentence until the next one arrived), with clause-level cuts for long sentences and an idle flush when generation stalls mid-sentence. macOS gains a gapless streaming playback backend (ffmpeg AudioToolbox, sox fallback) instead of spawning
afplayper sentence.
Fixed
- Fixed stuttering/latency in speech by running synthesis chunks through the player gaplessly
- Fixed race condition causing EPIPE errors and broken pipes during speech playback
- Fixed interrupted speech audio by ensuring segments queue and drain in order
- Fixed speech vocalization starting only after the entire reply was synthesized: ONNX inference blocks the TTS worker's event loop, so per-segment IPC audio chunks queued unflushed and arrived in one burst. Streaming sends now drain the IPC channel before the next segment's inference, cutting time-to-first-audio to ~1.5s regardless of reply length.
- Fixed an unhandled
EPIPE: broken pipe, writerejection at the end of speech playback: the streaming player'sstop()raced an un-awaitedFileSink.end()against the backend SIGKILL, and mid-session writes never awaited the flush. Writes now await the flush (so a dead backend is detected and the chunk replays on the next candidate or the per-file path) andstop()swallows the expected teardown rejection.
[16.3.0] - 2026-07-02
Added
- Added
providers.anthropic.serverSideFallbackconfiguration option to opt into Anthropic's server-side-fallback beta chain, allowing Claude requests to automatically retry on alternative models when blocked by classifiers. - Added
task.softRequestBudgetNoticeconfiguration option to enable subagent soft-budget wrap-up steering notices while keeping the graceful abort guard active.
Changed
- Significantly optimized session loading and rendering performance, including a 10x speedup for streaming reveals on large messages, 35% faster session resumes for large files using native streaming JSONL parsing, and reduced overhead for edit-patch fallbacks.
- Improved TUI responsiveness and reduced CPU usage during long-running tool sessions by throttling status-line redraws and optimizing subagent persistence checks.
- Updated the tester subagent prompt to allow skipping tests for trivial changes.
- Improved DuckDuckGo web search error clarity and documented datacenter/shared-egress limitations in provider settings.
Fixed
- Fixed session persistence corrupting Anthropic, OpenAI, and Google signed thinking blocks and reasoning payloads, ensuring cryptographic signatures and encrypted content are preserved verbatim to prevent API replay rejections (HTTP 400).
- Fixed several issues with the
apply_patchand edit tools, including preventing dirty buffers on early aborts, rejecting overwrites of pre-existing files, stopping at the first failing file in multi-file operations, and pruning extremely large file snapshots to prevent session inflation. - Fixed process termination (SIGTERM, SIGHUP, uncaught exceptions) to ensure editor drafts are saved, sessions shut down cleanly, and background jobs are cleaned up.
- Fixed
/quitand/exitcommands blocking session closure by introducing a shutdown budget and backgrounding remaining tasks. - Fixed git clone and fetch operations being killed prematurely by applying a separate 30-minute deadline for network transfers instead of the standard 5-minute local-command timeout.
- Fixed git index corruption issues in
mergeTaskBranchesandapplyNestedPatcheswhen post-merge stash pops conflicted with the cherry-picked HEAD. - Fixed collaboration (
/collab) issues, including preventing teardowns from cancelling active host dialogs, sanitizing host-delivered errors for guests, and ensuring guest UI requests are correctly routed and rendered. - Fixed RPC mode deferred shutdown (
pi.shutdown()) andabort_bashcommands from being blocked by active background bash processes. - Fixed model discovery ignoring
NODE_EXTRA_CA_CERTSand resolved a rare Bun garbage collection segfault during discovery. - Fixed
task.maxConcurrencyandtask.maxRecursionDepthlimits being bypassed by sub-spawn paths or when queued spawns were cancelled. - Fixed various TUI and rendering issues, including macOS Ghostty
Command+Vimage pasting, CJK history rendering across compactions, status-line redraw crashes with BigInt values, and overlapping rows in the subagent progress tree. - Fixed
/copy codeand/copy cmdcommands being treated as normal prompts instead of copying the requested blocks. - Fixed legacy tool compatibility issues for
createReadTool,createGrepTool, and extension validation failures foromp install pi-lean-ctx. - Improved robustness of MCP authentication error detection, Smithery command authorization failures, and streaming preview responsiveness for write, edit, and eval tools.
- Fixed llama.cpp router/preset mode reporting 128k context in the status bar for every preset picked from
/modelregardless of the preset's configured--ctx-size. - Fixed post-rewind context to tell the agent the checkpoint completed and to make repeat
rewindcalls recover with guidance instead of a bare no-checkpoint error. - Fixed grep/ast_grep search scopes rejecting
www.and collapsed-scheme (https:/host) URL spellings. - Fixed ctrl+p role-model cycling getting stuck on one transition and skipping every other role.
- Fixed interactive bash status line not updating after directory changes (cd).
- Fixed session title refreshes ignoring user
TITLE_SYSTEM.mdoverrides during replans, and prevented auto-generated titles from incorrectly preserving all-caps text from user messages. - Fixed the live todo HUD going stale during long tool-use loops by adding mid-run reminders for incomplete items.
- Fixed
/shakeand mid-stream chat rebuilds erasing active LLM output. - Fixed Tavily web search to retry without recency filters if no content is returned.
- Fixed user-configured LiteLLM discovery providers keeping stale reseller display-name suffixes for up to 24 hours after upgrade by invalidating the warm model cache.
[16.2.13] - 2026-07-01
Fixed
- Fixed
models.ymlremote compaction schema support for V2 streaming endpoint fields. (#4146) - Fixed the SSH tool to reject
cwdvalues of~and~/...before sending guaranteed-bad quoted tilde paths to remote POSIX shells. (#4002)
[16.2.12] - 2026-07-01
Breaking Changes
- Removed the canonical-alias grouping and resolution layer. The
equivalencekey (overrides/exclude) inmodels.yml/models.jsonis now inert, and canonical-related methods have been removed fromModelRegistry. - Removed the "CANONICAL" tab from the interactive model selector and the
omp models canonicalsubcommand.
Changed
- Simplified model selection and matching by resolving bare model IDs in
--model,modelRoles, andenabledModelsvia exact/flat-ID and provider-preference matching instead of cross-spelling canonical coalescing. - Improved cold start performance by removing the catalog-wide canonical index build from the startup path.
Fixed
- Fixed the write tool not streaming execution progress to the TUI while files are being written.
- Fixed live tool-call argument previews disappearing while arguments stream.
- Fixed the LSP tool ignoring timeouts and abort signals during cold-starts and notification writes.
- Fixed the browser tool leaking Chromium/Puppeteer processes when operations are aborted or when an agent session is disposed.
- Added a configurable 30-second timeout (
extensionHandlerTimeoutMs) to extension tool call handlers to prevent hung third-party extensions from blocking execution, and fixed a timer leak keeping the CLI alive. - Fixed the built-in
fdtool ignoring shell cancellation (such as Ctrl-C or timeouts) during directory walks. - Fixed MCP stdio requests hanging indefinitely past their configured timeouts when the child subprocess stops draining stdin.
- Fixed Python eval shell helpers buffering child-process output by streaming chunks and truncating oversized output.
- Fixed cached model edit variants failing to update when changing project directories.
- Fixed subagents with structured output schemas failing validation by correctly wrapping the schema in the system prompt.
- Fixed MCP Streamable HTTP request and notification timeouts staying unarmed during stalled response body reads.
- Fixed evaluation and task spawn defaults to respect restricted agent spawn lists.
- Fixed timed-out
browser.runcalls leaving evaluated JavaScript continuations running. - Fixed performance degradation in session context and branch path reconstruction on deep linear histories.
- Fixed agents repeating the same tool call across turns without corrective steering by wiring the cross-turn tool-call loop guard into sessions.
- Fixed OpenAI-compatible model discovery (including LM Studio) reporting flat default context windows when proxies omit context length metadata, by resolving discovered IDs against the bundled model reference catalog to inherit accurate context windows, output limits, display names, modalities, and reasoning support.
[16.2.11] - 2026-07-01
Fixed
- Fixed model-discovery requests (Ollama, Llama.cpp, LM Studio, OpenAI, LiteLLM, vLLM) failing to clear timeouts after completion, preventing potential memory and timer leaks.
- Fixed grep and ripgrep built-in tools ignoring shell abort and timeout signals during recursive directory walks, allowing them to be interrupted immediately.
- Fixed omp setup speech returning prematurely before Whisper STT downloads complete, and improved error reporting for worker download failures.
- Fixed high memory usage in multi-target ast_grep searches by only retaining the final page window while preserving exact match and file counts.
- Fixed async job manager disposal and task cancellation handling to properly release session semaphores when aborted.
- Updated and expanded omp:// documentation coverage for managed memory, skill tools, image/speech generation, and package CLIs.
[16.2.10] - 2026-06-30
Changed
- Updated grep warnings to clarify that large files are partially searched rather than entirely skipped
- Renamed the filesystem walker worker count environment variable from PI_GREP_WORKERS to PI_WALK_WORKERS
- Centralized filesystem traversal policy in
pi-walker. - Changed the in-session
/resumesession picker to open as a fullscreen window on the terminal's alternate screen, matching the startup--resumepicker and/settings. It borrows the alt buffer for its lifetime (the transcript is untouched underneath) and enables mouse tracking — the wheel scrolls the list and a left click resumes the row under the pointer — with the keybinding hint and bottom border pinned to the screen bottom. Previously it mounted inline in the editor slot and rendered compactly without mouse support.
Fixed
- Fixed Git subcommands ignoring repository paths by stripping ambient Git environment variables
- Fixed concurrent bash commands cross-killing each other on cancel/timeout. Cancellation cleanup previously walked the whole host process tree and signalled every descendant spawned since a per-run baseline, so cancelling or timing out one command could SIGTERM an unrelated command's child still running in parallel (it looked "new" relative to the canceller's baseline). Each run now tracks only the processes it actually spawned (via a brush-core spawn-observer hook) and scopes its TERM/KILL waves to that set, leaving concurrent runs untouched.
- Fixed
/skill:<name>invocation losing the user's prompt context when the slash token was reached mid-prompt via the autocomplete. The slash-command parser now recognizes a/skill:<name>token surrounded by whitespace in non-slash, non-local-execution drafts (in addition to the leading form) and threads the surrounding prose through to the skill asargs, so the typed prompt survives both in the editor (see the TUI changelog) and in the dispatched skill message. Drafts that already begin with another slash command (/compact /skill:foo), a bash sigil (!echo /skill:foo,!!echo /skill:foo), or a python sigil ($ run.py /skill:foo,$$ run.py /skill:foo) keep their existing dispatcher precedence and are not hijacked by the mid-prompt skill parser. Applies to the interactive TUI, ACP, and RPC dispatch paths via the sharedparseSkillInvocationhelper inextensibility/skills(#3913). - Fixed the incomplete-todo reminder drifting to the bottom of the screen and piling up as dozens of duplicate copies in native scrollback. The reminder rendered in a dedicated anchored live-region container (
todoReminderContainer) pinned above the editor, so it re-rendered in place every frame and — being taller than the viewport on short terminals while the subagent/job HUD churned below it — had its top rows committed to scrollback again on each reflow. It is now committed once into the transcript as a regular block (the same path TTSR notifications use), so it stays anchored in history where it fired. - Fixed subagent frontmatter
thinkingLevelbeing overridden bymodelRoles.taskmodel suffixes. (#3915) - Fixed Ruff LSP auto-detection for Windows Python virtualenvs by checking
.venv/Scripts,venv/Scripts, and.env/Scriptsbefore falling back to PATH. (#3916)
[16.2.9] - 2026-06-30
Breaking Changes
- Renamed the built-in quick_task subagent to sonic; update any task spawns or configurations referencing quick_task by name.
Added
- Added the llama3.2:3b local model option for memory and auto-thinking tasks, utilizing a quantized ONNX model.
- Added a built-in Tester subagent designed to write high-signal tests for behavior, invariants, and edge cases while avoiding redundant or low-value tests.
- Added a Speech-to-Text submit trigger setting to auto-submit dictation on release, on complete sentences, or via a spoken submit command.
- Added a loop-guard mechanism that detects thinking/response loops and injects a system notice during auto-retries to guide the model to break the pattern and take a concrete next step.
Changed
- Renamed the Speech-to-Text (STT) setting label from "TTS Submit Trigger" to "Speech-to-Text Submit Trigger".
Fixed
- Fixed an issue where mid-run compaction was incorrectly skipped when a persisted assistant display variant shared a persistence key but differed in content from the live message.
- Fixed duplicate placeholder cards being created when streamed tool blocks started with an empty ID.
- Fixed omp debug --profile failing on Bun by treating the optional --allow-natives-syntax flag as best-effort when v8.setFlagsFromString is unavailable.
- Fixed release binaries missing the compiled tiny-model Transformers.js version pin, preventing runtime resolution issues on certain platforms like Homebrew Darwin arm64.
- Fixed MCP OAuth flows silently falling back to a random redirect port when the preferred port (default 3000) was busy, which caused authentication failures with strict providers. The flow now fails fast with a configuration error when a static client ID is pinned, while dynamic registration flows continue to use fallback ports.
- Fixed /mcp reauth and /mcp add commands ignoring the Escape key during OAuth authentication, allowing users to cancel the flow immediately instead of waiting for the timeout.
Removed
- Removed the built-in oracle subagent.
[16.2.8] - 2026-06-30
Added
- Added built-in Go coding rules including
go-add-cleanup,go-bench-loop,go-exp-promoted,go-ioutil,go-join-hostport,go-new-expr,go-rand-v2, andgo-range-int
Changed
- Relaxed strict bash tool constraints regarding the use of search, grep, ls, and find commands
Fixed
- Fixed auto-compaction dead-ends by automatically triggering a shake rescue to elide oversized tails
- Improved compaction warning message to suggest running
/shake imagesfor irreducible image tails - Fixed
grep/searchdirect execution to accept JSON-array stringpathsfor string-or-array inputs. (#3873) - Fixed auto-compaction dead-ending with "Compaction freed too little context to make progress" when a single recent turn (large tool output, heavy fenced/XML block) is itself bigger than the recovery band —
findCutPointcan't cut inside one message, so the summarizer had no lever left. The guard now runs an artifact-backedshakeelide pass over the oversized tail and re-tests headroom before pausing, and the remaining warning points at/shake imagesfor image-only tails it can't elide. (#3786) - Fixed reviewer/
tasksubagents whose incrementalyield(type: ["overall_correctness"],type: ["findings"], …) carried a value that mismatched the matching property's sub-schema being silently accepted and then post-mortem rejected withschema_violation— opaquely swapping the agent's accepted output for an error blob. The yield tool now validates each incremental section'sdataagainst its top-level property's sub-schema (items schema for array-typed labels) and surfaces the same retry feedback as terminal yields, so models likedeepseek-v4-prothat emit"Correct"/"correct."/"approved"for an enum field get up to three corrective retries; the existingMAX_SCHEMA_RETRIESoverride then accepts the value withSUBAGENT_WARNING_SCHEMA_OVERRIDDENinstead of losing the entire result. Unknown labels stay unconstrained (#3870). - Fixed streaming tool-call previews (notably
write) showing an empty body for the entire streaming phase by surfacing the partial JSON already in hand on the first reveal, then pacing only subsequent growth (#3881). - Fixed hashline edit mode preserving UTF-8 BOM bytes on edited files. (#3867)
- Fixed slow local LLM streams by forwarding persisted stream timeout settings (
providers.streamFirstEventTimeoutSeconds,providers.streamIdleTimeoutSeconds) into model requests, so users can widen or disable watchdogs without environment variables. (#3878) - Fixed the bash interceptor blocking
echo/printfredirects to/dev/null,/dev/tty,/dev/stdout, and/dev/stderrdevice sinks while still directing real file writes to the write tool. (#3763) - Fixed long snapcompact sessions re-sending multi-megabyte standing image archives on every provider request by enforcing a per-request frame byte budget, letting auto-compaction fall back to context-full summaries when snapcompact output is too large, and omitting legacy over-budget frames from rebuilt LLM contexts. (#3792)
[16.2.7] - 2026-06-30
Breaking Changes
- Replaced the global
serviceTierandfastModeScopesettings with granular, per-family settings (tier.openai,tier.anthropic, andtier.google) to control service tiers, subagents, advisors, and/fastmode targets.
Changed
- Improved binary file detection and terminal handling to prevent corruption from non-UTF-8 content, and updated file summaries to explicitly note skipped binary files.
- Enhanced context compaction (snapcompact) to resolve shapes contextually based on rendered text content.
Fixed
- Improved reliability of DuckDuckGo web searches by updating browser request headers and parameters
- Fixed an issue where CJK (Chinese, Japanese, Korean) history could become unrenderable during repeated context compactions.
- Fixed a memory exhaustion bug in the TUI when using
/resumeon large previous sessions. - Fixed an issue where the
ircinbox missed messages that arrived while the recipient agent was already running. - Fixed a startup hang caused by system-prompt GPU detection blocking and repeatedly running failed probes.
- Improved error reporting for
omp tiny-models downloadby displaying the actual worker-side download error. - Resolved status inconsistencies between
/extensions,/mcp list, and the dashboard, ensuring MCP server states, allowlists/denylists, and configuration files (likemcp.json) stay fully synchronized. - Improved branch-mode task merges to preserve the agent's original commit history (messages and authors) and fixed a bug where merges were rejected due to unrelated dirty changes in the parent checkout.
- Fixed an issue where the
Working...loader spinner would prematurely disappear or fail to re-arm after a subagent (task) tool completed or during transient overlays (such as auto-compaction or auto-retry).
[16.2.6] - 2026-06-29
Changed
- Optimized argument streaming performance by throttling JSON re-parsing for renderers that do not require raw input.
Fixed
- Fixed memory leaks in the benchmark CLI by ensuring provider sessions are properly closed upon completion.
- Fixed TUI rendering lag and shimmer frame starvation during streamed tool-call argument previews.
- Fixed llama.cpp discovery mapping unlimited output limits (max_tokens = -1 / n_predict = -1) to the generic 32K cap instead of the actual discovered runtime context window.
- Fixed memory exhaustion on Ctrl+C flush for large resumed sessions with repeated compaction summaries, and improved fork session previews starting with developer or assistant turns.
- Fixed omp search applying web search provider filters before resolving its implicit provider chain.
- Fixed Gemini web search to support standard GEMINI_API_KEY developer API credentials for native Google Search grounding, in addition to Cloud Code Assist OAuth.
- Fixed the bash interceptor blocking echo and printf redirects to standard device sinks (such as /dev/null, /dev/tty, /dev/stdout, and /dev/stderr).
- Fixed session file size inflation in the edit tool by pruning extremely large oldText and newText snapshots (over 32 KB) from tool-result details, while preserving visible diffs, paths, lines, and diagnostic metadata.
- Fixed Windows MCP stdio launches for PATH-resolved npx.cmd shims by preserving the cmd.exe wrapper path to keep subprocess stdio attached.
- Fixed the DuckDuckGo web_search provider returning empty results for non-encyclopedic queries by switching from the Instant Answer API to parsing the HTML frontend, and added clear error handling for bot-challenge throttling.
- Fixed Windows --extension paths with spaces or \?\ prefixes being truncated or incorrectly passed to Bun import/spawn APIs.
- Fixed /mcp reauth compatibility with Cloudflare by aligning OAuth prompt behavior with the reference MCP SDK and updating the client label to oh-my-pi.
[16.2.5] - 2026-06-28
Changed
- Status line now collapses a linked git worktree path to the project name with a worktree icon, leaving the git segment to show the branch once instead of repeating it in the path.
Fixed
- Fixed Ollama and llama.cpp discovery overestimating local context windows by using model training metadata instead of the runtime
num_ctx/n_ctx, which could let compaction retry prompts that llama.cpp rejects as over context. (#3752) - Fixed isolated subagent worktrees embedding long task ids and
mergedin the working path; isolation now uses compact hashed segments with anmmount dir. (#3756) - Fixed recoverable context-overflow compaction keeping the failed assistant error turn in visible session history after scheduling the retry. (#3747)
- Fixed editing a file read from outside the workspace (e.g.
~/.claude/settings.json) failing with "File not found": the read snapshot header now carries the full out-of-workspace path so the edit resolves it directly instead of against the working directory. - Fixed subagents spawned with an output schema (
agent(..., schema=...),taskwith structured output) failing withschema_violation: missing required fieldssince the typed-yield rework: atype: "result"finalize carrying the full object was assembled as a section namedresult, nesting the payload one level deep. String-typed yields are now treated as terminal finalizers (their data is the complete result), only array-typed yields form accumulating sections, and a data-less finalize keeps accumulated sections instead of collapsing to the last assistant turn. - Fixed the per-provider concurrency cap (e.g.
providers.ollama-cloud.maxConcurrency) bracketing the whole subagent lifecycle, which deadlocked any spawn tree wider than the cap because parents held every slot while waiting for children queued on the same cap. The semaphore now wraps each provider HTTP request, so a parent's slot frees between turns and child subagents can acquire while their parent's tool calls are running. (#3749) - Fixed Ctrl+Q / Ctrl+Enter follow-up submissions sending the literal
[Paste #N]marker instead of the expanded paste body (#3737).
[16.2.4] - 2026-06-28
Fixed
- Fixed todo-reminder HUD rendering outside durable chat history while preserving native collapsing and auto-clear behavior.
- Fixed goal-mode continuations losing track of persisted todo progress, ensuring autonomous goal turns reconcile stale in-progress items before moving to subsequent tasks.
- Fixed the /move command to correctly relocate the current session and its artifacts to the target directory, allowing /resume to work seamlessly from the new location.
- Fixed omp update leaving behind stale Bun install-cache directories for globally installed packages.
- Fixed a reconnection loop issue in /collab sessions caused by oversized entries (such as large tool outputs) by truncating replicated payloads that exceed 1 MB.
- Fixed autolearn and local memory writes mutating Anthropic prompt-cache prefixes mid-session, ensuring prompt injections remain session-stable.
[16.2.3] - 2026-06-28
Added
- Added support for multiple configurable advisors via WATCHDOG.yml/WATCHDOG.yaml files, allowing per-advisor models, tool subsets, and instructions.
- Added /advisor configure, a full-screen, mouse-driven TUI to easily manage the advisor roster, configure models, toggle tool permissions, and edit instructions.
- Added full unified edit diffs to advisor transcripts, allowing advisors to see changes directly without re-reading files.
- Added the statusLine.compactThinkingLevel setting to render the model segment's thinking level as a single leading glyph instead of a separate text suffix.
- Added support for tracking reasoning tokens in session and advisor statistics.
- Added Remote Compaction V2 streaming configuration settings (compaction.remoteStreamingV2Enabled and compaction.v2RetainedMessageBudget) to control token budgets and toggle V2 streaming for remote compaction.
- Added the edit.citationTags setting to emit model-facing hashline section headers as OpenAI citation markers with opaque source IDs, along with citation-marker unwrapping for hashline edit parsing, diff previews, and streaming matching.
- Added mutable session titles with automatic replan title refreshes and configurable idle recaps.
- Added support for incremental yield submissions with typed sections and final results for subagents.
Changed
- Reduced session file size by removing redundant thinking signatures already present in payloads
- Advisors can now be granted any built-in agent tool (including edit, write, and bash), removing the previous read-only restriction.
- Improved the debug log and raw SSE stream viewers with a wider, bordered overlay, clearer status indicators, dynamic layouts, and mouse support for scrolling and interaction.
- Updated the idle recap feature to use an LLM-generated summary of where things stand (anchored by the live goal and active todo task) instead of a static status line.
- Refined interrupted thinking system instructions to encourage smoother continuation.
Fixed
- Fixed array-typed output schema validation by correctly assembling incremental yields into lists.
- Fixed OpenAI/Codex compatibility by removing top-level schema combinators from tool parameters.
- Fixed validation errors for untyped final yields in strict-mode providers by allowing null types.
- Fixed Alt+M default-role model configuration being disabled by the current session's context size.
- Fixed MCP type: "sse" servers by adding the legacy HTTP+SSE endpoint handshake and streaming JSON-RPC response path.
- Fixed interrupted reasoning blocks being incorrectly stripped when they contained a valid signature.
- Fixed interrupted thinking being lost in LLM provider requests after user interrupts by properly stripping trailing reasoning blocks from assistant turns while preserving them in the UI and session history.
- Fixed the live todo HUD going stale during long tool-use loops by introducing a mid-run reconciliation reminder that prompts the agent to update incomplete items.
- Fixed resumed OpenAI and OpenAI-Codex sessions losing encrypted reasoning and native assistant turns during rehydration.
- Fixed the ask tool's custom answer editor dropping the original question and option list while typing.
- Fixed auto-snapcompact failing the session on local blockers (such as text-only active models, high non-ASCII transcripts, or context budget overflows) by gracefully downgrading automatic maintenance to context-full compaction.
- Fixed autoresearch's before_agent_start handler crashing when the system prompt was undefined.
- Fixed OMP exiting silently during startup when encountering standalone Codex hook scripts in ~/.codex/hooks/.
- Fixed unreachable keyboard shortcuts in HTML session exports by changing the "toggle thinking" and "toggle tools" shortcuts from Ctrl+T and Ctrl+O to bare T and O keys.
- Fixed user-invoked /skill: prompts reaching model providers as developer turns instead of user turns, including during compaction.
- Fixed reasoning streaming being locked off for OpenAI-compatible providers that stream reasoning content without advertising reasoning support in model metadata.
- Fixed /shake and other mid-stream chat rebuilds erasing live LLM output by preserving the in-flight streaming components and pending tools.
- Fixed the time_spent status-line segment ticking continuously during idle sessions by ensuring it only accumulates active agent execution windows and resets correctly across session switches.
- Fixed expanded pending SSH previews committing provisional rows to native scrollback before the final result render.
- Fixed ssh:// rejecting POSIX-capable remotes whose login-shell classification was ambiguous by verifying a working transfer shell directly and gating transfers on that capability.
Removed
- Removed history URI support for reading agent transcripts
[16.2.2] - 2026-06-27
Added
- Added a new
tinymodel role for consolidated online task handling. - Added a
textVerbositysetting to control OpenAI and Codex response detail.
Changed
- Simplified the status line subagent display by removing running state and hub hint indicators.
- Updated online title, memory, and classification tasks to prioritize the new
tinymodel role.
Fixed
- Improved reliability of auto-retry logic for aborted requests by standardizing error classification across model adapters and ensuring stale session states are reset.
- Enhanced MCP authentication error detection, header-based server discovery, and 401/403 authorization failure detection during Smithery commands and HTTP RPCs.
- Fixed auto-generated session titles incorrectly preserving user all-caps text, ensuring proper sentence casing while still respecting intentional mixed-case identifiers.
- Fixed Tavily web search with recency filters to automatically retry without a time range if Tavily returns an empty HTTP 200 response.
- Fixed TUI thought stream stalling and
ui.loop-blockedwarnings during subagent-heavy runs by optimizing the mid-run compaction persistence check. - Fixed marketplace-installed plugins incorrectly appearing in both the npm plugin list and the extension-package status provider.
- Fixed inconsistent OpenRouter prompt-cache hits on
/advisorturns by ensuring advisor agents inherit the same provider-shaping options, hooks, and settings as the main agent. - Fixed path-scoped TTSR (Targeted Tool Safety Rules) evaluation for
hashlineandapply_patchedit streams, ensuring rules are correctly applied to file paths parsed from section headers and envelope markers without leaking across file scopes.
[16.2.1] - 2026-06-27
Added
- Included project context files (AGENTS.md, etc.) in the advisor's system prompt to ensure adherence to user-defined project rules
- Added project context files (AGENTS.md and the like) to the advisor's system prompt, so the read-only reviewer judges against the user's standing project rules the same way the main agent does.
Fixed
- Fixed live ACP
generate_imageupdates resolving OMP-internal image blob refs before sending renderable image content to clients. (#3623) - Fixed Claude marketplace plugin
.mcp.jsonMCP servers to expand environment variables inurlandheadersbefore connecting. (#3621)
[16.2.0] - 2026-06-27
Breaking Changes
- Renamed the
searchtool togrepand thefindtool toglob. Existing user settings are automatically migrated to the new configuration keys.
Added
- Added
ssh://host/pathsupport toread,search, andwritetools for single text files and directory listings on pre-configured POSIX SSH hosts. - Added an interactive
/moveoverlay with path autocompletion and directory creation prompts, starting a fresh session in the target directory while leaving the previous session resumable. - Added support for file deletion and moving within file editing operations.
- Added
providers.maxInFlightRequestssetting to cap concurrent LLM requests per provider across local OMP processes. - Added support for
discovery.type: litellminmodels.ymlto automatically discover model metadata from LiteLLM gateways. - Added
models.ymlconfiguration optionsremoteCompactionandcompactionModelto run compaction on a separate model or opt into provider-native compaction. - Added project, user, and plugin-level
dap.jsonanddap.yamlsupport for defining or overriding debugger adapters used by thedebugtool. - Added TinyFish, DuckDuckGo, xAI, and Firecrawl web search providers.
- Added an Appearance setting for OSC 9;4 native terminal progress indicators during active agent turns and context maintenance.
- Added Loop Guard "Tool-Call Reminder" to automatically interrupt Gemini reasoning loops that generate excessive planning headers without acting.
Changed
- Redesigned the persistent Todo HUD as a compact connector tree with fixed-budget stage previews
- Anchored status and HUD containers to prevent redundant UI elements in terminal scrollback
- Redesigned the persistent Todo HUD to render active stages as a connector tree, capping the number of displayed stages and tasks to keep the plan overview concise and stable.
- Anchored the status row container directly between the HUD and the editor to prevent redundant UI elements from piling up in terminal scrollback.
- Optimized edit tool UI: delete and single-file move operations now render as compact status rows
- Improved terminal output for file-level edits (delete/move) to display accurate paths and state
- Refined edit renderer to prevent misleading "No changes" messages in multi-file operations
- Changed the
inlineToolDescriptorssetting from a boolean to a three-way enum (auto|on|off), defaulting toautoto inline descriptors only for Gemini models. - Added caching for successful document conversions (PDFs, Office documents, EPUBs) to avoid redundant conversions on repeated reads.
- Moved the
Working…activity indicator below the sticky todo and subagent HUDs so it sits just above the editor instead of floating atop the todo panel.
Fixed
- Fixed Z.AI web search to initialize the Streamable HTTP MCP session before calling
web_search_prime, preserving the returned session ID for authenticated tool calls. (#3619) - Fixed terminal hangs on Ctrl+Z (SIGTSTP) after running bash tool calls, and insulated MCP stdio servers from terminal job-control signals.
- Fixed macOS
Cmd+Vsilently dropping image-only clipboard pastes in supported terminals. - Fixed an infinite loop in auto-compaction when a single recent turn exceeded the compaction threshold.
- Fixed an issue where the advisor could enter a spam loop of repeated blocker injections, polluting the transcript.
- Fixed Claude API and Anthropic classifier refusals polluting the replayed session context or persisting as assistant dialogue.
- Fixed MCP tool calls failing with strict-schema servers by stripping internal metadata fields at the MCP boundary.
- Fixed a terminal freeze/hang when a subagent abort was triggered.
- Fixed thinking blocks appearing in the UI when thinking level is "off" for providers that return them anyway.
- Fixed GitLab Duo Agent namespace/project discovery and authentication flow hangs.
- Hardened and improved
ssh://protocol handling, including support for IPv6 brackets, percent-encoded hosts, port validation, and POSIX shell restrictions, while preventing unsupported tools from attempting SSH connections. - Fixed TUI usage display fraction resolution and added expiry dates for banked Codex rate-limit resets to the
/usagedisplay. - Fixed a rendering issue where long-running SSH commands left stale pending headers in terminal scrollback.
- Fixed garbled casing in auto-generated session titles by reconciling title tokens against the user's original messages.
- Fixed IRC broadcasts rendering twice in the main agent's transcript.
- Improved the persistent Todo HUD styling and progress indicators to make it self-describing and visually distinct.
- Fixed browser screenshots reporting
0x0dimensions when image headers expose real dimensions. - Fixed
snapcompactcompaction silently falling back to LLM summaries when local preflight rejects the archive. - Fixed
snapcompactcompaction silently falling back to an LLM summary when local preflight rejects the archive; manual and auto snapcompact now fail locally with the blocker instead of making provider calls. (#3599) - Fixed garbled casing in auto-generated session titles.
normalizeGeneratedTitle(packages/coding-agent/src/tiny/text.ts) used to force Title Case via a\b\p{Ll}regex, capitalizing function words ("for" → "For") and amplifying stray model capitals ("dAemon" → "DAemon"). It now reconciles each title token against the user's own message: tokens typed verbatim are kept; proper nouns the user cased distinctively are restored when the model flattened them ("tinyvmm" → "TinyVMM"); lowercase words carrying a stray interior capital the user never wrote are flattened ("dAemon" → "daemon"); and model-cased PascalCase proper nouns ("GitHub", "OAuth") are left untouched. Restoration is limited to distinctively cased source tokens so a message that merely starts with "For" can't force a mid-title "for" to "For". Applies to both the local tiny-model and online pi/smol title paths. - Fixed IRC broadcasts (
to: "all") rendering twice in the main agent's transcript. A subagent broadcast fans out onebus.sendper live peer, andlistVisibleToalways includesMain, so the main agent received the body once as its ownirc:incomingcard and once per other recipient as anirc:relayobservation of the sibling legs (Sender → Other) — identical text shown N+1 times.IrcTool.#executeSendnow setssuppressRelayon every broadcast leg whenMainis among the targets (it already has the body via its direct incoming card), andIrcBus.sendskips#relayToMainUifor suppressed legs. Direct sub→sub relays, direct messages toMain, andMain's own outbound sends are unaffected. - Fixed Claude API refusals polluting the replayed session context and causing later prompts to refuse again. (#3592)
- Fixed browser screenshots reporting
0x0dimensions whenBun.Imagerejects an image whose PNG/JPEG header still exposes real dimensions. (#3577) - Fixed Anthropic classifier refusals being persisted as assistant dialogue after no fallback handled them; refusal stops are now displayed as errors but pruned from active and saved context before the next prompt. (#3591)
- Fixed the
evaltool.*bridge leaking the harness-internali("intent") field into MCPtools/callrequests, so strict-schema servers (Linear, anything withadditionalProperties:false/ Zod.strict()) rejected every call with-32602 unrecognized_keys: ["i"]while the same call via the direct model tool-call path succeeded.MCPTool.execute/DeferredMCPTool.execute(packages/coding-agent/src/mcp/tool-bridge.ts) now stripINTENT_FIELDat the MCP boundary, so an MCP call behaves identically whether issued by the model directly or via the evaltool.*bridge; servers that legitimately declareias a real parameter keep it untouched. (#3575) - Fixed the advisor entering a spam loop in which it emitted hundreds of repeated
Stop.,Done., andNo issue; continue.<advisory severity="blocker">injections, polluting the primary transcript and destabilizing the watched agent after the task was already complete. The advisor system prompt's rules ("at most oneadviseper update", "NEVER send the same advice twice") are now enforced in code by a newAdvisorEmissionGuardon theenqueueAdviceboundary inAgentSession: it normalizes each note (case-insensitive, punctuation-folded), drops content-free self-talk filler (stop/done/no issue continue/lgtm/etc.), dedupes by exact normalized text across the session (bounded FIFO history), and rate-limits to one accepted note per advisor model prompt cycle. Reset on advisor reset (compaction, session switch,/new) so a re-primed reviewer can re-raise old issues. (#3520) - Fixed auto-compaction thrashing on a session whose single most-recent kept turn already exceeds the compaction threshold.
prepareCompactionkeeps that turn verbatim (findCutPointnever cuts at tool results), so the rewritten context stays above threshold; the context-full / snapcompact success tail scheduled the agent-authored auto-continue (and the overflow/incomplete retry) unconditionally, so the nextagent_endre-entered#checkCompactionover the same oversized tail and re-fired forever. This is the residual loop left after #3247 capped snapcompact's own frame projection — once the frame cap drops below one frame, snapcompact is skipped and the context-full summarizer path still made no headroom.#runAutoCompactionnow gates the threshold auto-continue on a post-maintenance headroom check (#compactionCreatedHeadroom, sharing shake'sCOMPACTION_RECOVERY_BANDhysteresis from #2275) and the overflow/incomplete retry on a separate fit check (#compactionCreatedRetryFit, measured after the failed turn is dropped) so a recoverable overflow that fits the window still retries; when a pass frees too little for the relevant path it pauses automatic maintenance and emits a single warning instead of looping. The post-turn threshold check also ignores an assistant's stale pre-compactionusageso the scheduled auto-continue cannot re-trip on the kept assistant's old high token count. The headroom check now treats any residual at or below the recovery band as progress: the band sits strictly under the compaction threshold, so a stale/tool-output prune that already pushed the trigger sub-band no longer makes a residual that merely holds the line report a false "no progress" and suppress a valid auto-continue. - Fixed the advisor prompt allowing confident root-cause claims about tool-call arguments absent from its reviewed transcript, so timeout advice now has to cite observed fields instead of inventing mechanisms like
paths[0]array flattening. (#3483) - Fixed eval
agent()helper subagents remaining visible as idle/IRC-revivable peers after the helper call returns; one-shot eval subagents now dispose and unregister at completion. (#3407) - Fixed the parent interactive prompt wedging (frozen, 0% CPU) after a subagent's yield-triggered abort. The executor's abort monitor and abort listener each called
session.abort()fire-and-forget, sorunSubprocesscould resolve and adopt the subagent before its abort cleanup finished clearing in-flight session state. Active-subagent aborts are now deduped through a single cached cleanup promise that the subprocess awaits (bounded) before finalizing. (#2805) - Fixed thinking blocks appearing in the UI when thinking level is "off". Some providers (MiniMax, GLM, DeepSeek) return thinking blocks even with reasoning disabled; thinking blocks are now auto-hidden when the thinking level is "off", regardless of the
hideThinkingBlocksetting. Toggling thinking block visibility while thinking is off shows a status message instead of silently no-op'ing. (#626) - Fixed the TUI usage display failing to resolve a used fraction for limits that only populate
remainingFraction(nousedFraction,used/limit, orpercent+used). The TUI's localresolveFractionwas missing the inverted-remaining fallback that the sharedresolveUsedFractionfrom@oh-my-pi/pi-aialready handles — replaced the local copy with the shared function so the TUI and CLI paths resolve fractions identically. - Fixed long-running SSH command boxes leaving a stale
⏳ SSH: [host]header above the final⇄ SSH: [host]header in terminal scrollback. The SSH renderer now keeps its partial-result chrome on the pending icon/state and opts the block out of stream-commit whileisPartialholds (via the newToolRenderer.provisionalPartialResultflag honored byToolExecutionComponent.isTranscriptBlockCommitStable), so the stable-prefix ratchet can't promote the partial header to native scrollback only to have the final render strand it above the settled frame (#3177). - Fixed Gemini over-planning runs that emit long chains of thinking headers (
**Refining …**,## Examining …) without ever issuing a tool call. The session now interrupts that stream, discards the partial reasoning turn, injects a hidden tool-call reminder, and continues with the corrective context instead of burning the full budget on planning. - Fixed
Cmd+Von macOS silently dropping image-only clipboard pastes (screenshot viaCmd+Shift+5"save to clipboard", Chrome image copy, …) — the user had to fall back toCtrl+V. Follow-up to #3506: that fix handled clipboards exposing a file URL or path; the screenshot path leaves only raw image bytes on the pasteboard. macOS terminals (iTerm2, Terminal.app, Warp, Ghostty without OSC 5522, Windows Terminal forwarding, …) interceptCmd+Vand readNSPasteboardTypeStringfirst; for an image-only clipboard that read returns"", so the terminal forwards a complete-but-empty bracketed paste (\x1b[200~\x1b[201~).CustomEditor.handleInputinserted the empty payload and the keystroke disappeared.CustomEditornow runs its ownBracketedPasteHandlerahead of the inherited handler so the assembled paste payload is routed regardless of whether the start marker, payload, and end marker arrive in one stdin chunk or are fragmented across several (Windows Terminal under load, certain SSH muxes, tmux extended-keys passthrough, …). Strict-zero-length assembled payloads route to the sameonPasteImagesmart reader theapp.clipboard.pasteImagekeybind uses (attaches the clipboard image, or falls back to the #1628 smart text paste / "clipboard is empty" diagnostic); explicit image-file paths route toonPasteImagePath(the #3506 path also benefits from split-chunk assembly); everything else hands off to the base editor'spasteTextso[Paste #N]markers, autocomplete, and undo state stay intact. Whitespace-only pastes are preserved as literal text. Trailing keystrokes that arrive in the same stdin read as the paste (a user hittingEnterright afterCmd+V) are queued behind the in-flight clipboard read and only dispatched once the image has reachedpendingImages, so submit can't fire against an empty draft and leave the image stranded on the next prompt. (#3601)
[16.1.23] - 2026-06-26
Added
- Added
compaction.midTurnEnabledfor mid-turn threshold auto-compaction before the next tool-loop provider request. (#3525) - Added
grep -q/--quiet/--silentand-x/--line-regexpto the in-processgrepbuiltin used by the bash tool.-qsuppresses all stdout and exits 0 on the first match (short-circuiting, with match status taking precedence over read errors per GNU);-xanchors each pattern to whole lines. Unblocks shell conditionals such asgrep -qx "$applet" <(strings bin). - Added plan-mode guidance (hashline edit mode only) steering the agent to revise the plan file section-by-section with
SWAP.BLK/DEL.BLK/INS.BLK.POSTanchored on markdown headings — a heading resolves its whole section (through nested deeper headings), so the agent can rewrite, drop, or append sections without rewriting the file. - Added
tui.renderMermaidto control Mermaid fenced-block ASCII rendering; disabling it also removes the Mermaid diagram hint from the generated system prompt so Mermaid blocks fall back to ordinary highlighted code fences. - Added
/resume <session-id>in the interactive command system, reusing the existing session-id/prefix resolver while bare/resumestill opens the selector. - Added manual
omp gcstorage maintenance withgc.*defaults for blob sweeping, cold-session archiving, and SQLite WAL checkpointing.
Fixed
- Fixed
/resume <session-id>in the interactive TUI only searching the active cwd's session directory; id-prefix lookup now falls back to sessions from other cwd buckets like CLI--resume <session-id>. - Fixed plan mode rejecting edits to plan artifacts when models refer to them by bare filenames
- Fixed absolute paths to session-owned artifacts being incorrectly routed through the editor bridge
- Fixed Windows stdio MCP wrapper chains spawning visible PowerShell/cmd windows on startup after the #3544 fix.
StdioTransport.connect()now probes whether OMP already has an inheritable console andresolveStdioSpawnCommandskipswindowsHide/CREATE_NO_WINDOWin that case, socmd.exe/PowerShell grandchildren reuse the terminal console instead of allocating visible conhosts during MCP startup or reconnects. (#3567) - Fixed Kimi-family models defaulting to hashline edit mode; they now fall back to
replaceunlessedit.modelVariants,PI_EDIT_VARIANT, orPI_STRICT_EDIT_MODEexplicitly opts into hashline. - Fixed MCP OAuth discovery rejecting Atlassian-style cross-host issuer metadata during the resource-server fallback probe; issuer matching now remains enforced for advertised auth-server candidates but no longer blocks fallback metadata where the resource host and authorization-server issuer differ. (#3551)
- Fixed plan approval applying the wrong execution model when the model-tier slider sat on the model that exit would restore. The match check now compares the selected role's effective thinking level against the pre-plan thinking level, so picking the active planning tier is retained and picking a same-model tier with an explicit thinking suffix (e.g.
default = sonnet:offwhile plan-mode raised thinking tohigh) goes throughapplyRoleModelinstead of silently restoring the pre-plan level. (#3554) - Fixed plan approval applying the wrong execution model when the model-tier slider sat on the model that exit would restore. The match check now compares the selected role's effective thinking level against the pre-plan thinking level, and a singleton cycle (only
modelRoles.planconfigured, default unset, sogetRoleModelCyclesynthesizes a lonedefaultentry from the active plan model and the slider stays hidden) is no longer pinned as the execution tier — approval falls through to the pre-plan restore instead of silently switching back to the plan model. (#3554) - Fixed the
evalJulia kernel showing only runner-internal backtrace frames (at top-level scope (./none:N),at main (…runner-…jl:635)) with no exception type or message, making cell errors undebuggable. The host renderer (packages/coding-agent/src/eval/kernel-base.ts) displays a non-emptytracebackverbatim and only falls back toename: evaluewhen it is empty; the Python and Ruby runners embed the rendered error intraceback, but the Julia runner (packages/coding-agent/src/eval/jl/runner.jl) builttracebackfrom stack frames only, so the message was dropped.emit_errornow seedstracebackwith theshowerroroutput (matching the REPL'sERROR:text) ahead of the frames. - Fixed Windows stdio MCP servers timing out (and popping a visible terminal) when their direct child was a
cmd.exewrapper that itself launched a console grandchild —nodewrappers,npx.cmd -y mcp-remote, similar nested shells.StdioTransport.connect()unconditionally passeddetached: truetoBun.spawn, but Windows has no SIGTSTP/SIGTTIN to escape;detachedonly maps toCreateProcess(DETACHED_PROCESS), which strips the parent's inherited console. The hidden directcmd.exelost its console, so the grandchild allocated a brand-new visible conhost whose stdout no longer routed through OMP's pipe — the proxy reported the bridge was up while OMP timed out waiting for the MCPinitializeresponse.resolveStdioSpawnCommandnow returnsdetached: falsefor every Windows return shape (direct.exe, cmd.exe-wrapped batch / unresolvable command, npm cmd-shim launched through node) and keepsdetached: trueon POSIX, where the original SIGTSTP/SIGTTIN reason still holds;connect()consumes the resolved flag. (#3544) - Fixed the LSP tool's per-cwd config cache (
getConfiginpackages/coding-agent/src/lsp/index.ts) never being invalidated, so.omp/lsp.json, root markers, and plugin LSP configs added after the first LSP call stayed invisible for the remainder of the process — even afterreload *. The cached observation persists across chat sessions because OMP is a single-process binary, so users were stuck onNo language servers configureduntil they killed the process. Thereloadhandler now drops the cwd's cache entry and re-runsloadConfigbefore iterating servers, so the explicit refresh request behaves as the prompt documents. (#3546) - Fixed stale snapcompact archive state being reintroduced at the AgentSession manual and auto LLM compaction save paths;
preserveData.snapcompactis now stripped after hook- and result-supplied preserve data are merged, so a prior snapcompact pass can no longer leak frames into a later context-full compaction. (#3561 by @serverinspector) - Fixed the snapcompact→context-full migration shipping the prior archive's plaintext to the summarization provider without secret redaction. When secrets are configured, the migrated archive's
text/textHead/textTailregions are now obfuscated alongside the previous summary, while opaque provider-replay state (OpenAI remote-compactionencrypted_content) stays byte-identical. (#3561) - Fixed fresh interactive launches ignoring
modelRoles.defaultwhen the configured default lives on an extension-registered provider (e.g. an openai-compat plugin'sposthog/claude-opus-4-8).createAgentSessionresolved the default role before extension factories registered their providers, so the role-pointed model wasn't visible there; on a fresh launch (no-c/--resume) the post-extension fallback then went straight topickDefaultAvailableModel, replacing the user's configured default with the first bundled provider default with auth (commonlyopenai/gpt-5.5whenOPENAI_API_KEYwas set). The fallback now retries the default-role lookup against the post-extension allowed-model set — including its explicit thinking selector — before falling back to a bundled provider default. (#3569)
[16.1.22] - 2026-06-26
Fixed
- Fixed Windows stdio MCP server launches showing a separate
cmd.exewindow for direct executable servers; MCP subprocesses now setwindowsHideon every Windows spawn path. (#3535) - Fixed MCP OAuth still failing with
Authorization failed: An unexpected error occurredagainst Plane'shttps://mcp.plane.so/http/mcpendpoint after #3502. The protected-resource metadata advertised the path-scoped issuerhttps://mcp.plane.so/http, butdiscoverOAuthEndpoints(packages/coding-agent/src/mcp/oauth-discovery.ts) probed/.well-known/oauth-authorization-serverat the origin root first and accepted the metadata served there — which describes a different issuer (https://mcp.plane.so/) whose/authorizeendpoint rejects every grant. Discovery now honors RFC 8414 §3.3 and skips authorization-server / OpenID Connect well-known documents whoseissuerfield doesn't match the queried base URL (trailing-slash insensitive). Servers that omitissuerkeep today's permissive behavior, so legacy flows are unaffected. (#3537)
[16.1.21] - 2026-06-26
Fixed
- Fixed
autolearn.autoContinue(the "Auto-run capture at stop" toggle) letting the synthetic capture turn keep working after thelearn/manage_skillcall instead of yielding. With the toggle on, the controller firesautolearn-nudge.mdas a singleattribution: "user"message on a new turn; the prompt opened with "Before you finish:" and gave no terminal contract, so the agent treated the synthetic prompt as the user's reply to its prior pending question (e.g. "Want me to commit and push?") and continued — pushing commits, running tools, etc. — without the user ever answering. The nudge is now split into two prompts: passive mode (the reminder rides the user's real next message) keeps additive framing — "answer the user normally; the capture is in addition to" — while auto-continue mode (autolearn-nudge-autocontinue.md) is explicitly terminal — "not a user reply; do not treat this as approval; capture, then stop; wait for the user's next prompt". Attribution staysuserto preserve llama.cpp warm-prefix reuse (#3456). (#3504) - Fixed the clipboard image-paste keybind dropping image-file-only pasteboards as literal text on macOS. When the clipboard exposes only the file URL (e.g. Finder
Cmd+Con a.png, certain screenshot tools),arboard::get_image()returnsContentNotAvailableandpbpaste(1)returns empty (it only surfaces plain text / RTF / EPS), soInputController.handleImagePasteeither fell through to the #1628 text fallback and pasted the path verbatim, or dead-ended with "Clipboard is empty". The keybind path now (1) reaches thepublic.file-urlrepresentation directly via a newreadMacFileUrlsFromClipboardAppleScript bridge on Darwin and routes the first image-shaped path throughhandleImagePathPaste, (2) reuses a newextractImagePathFromTexthelper so any clipboard-text path that survivedpbpasteis detected the same way the bracketed-paste handler already detects them — including a whole-text-as-path fallback for anchored paths whose unescaped spaces would otherwise be shredded by the bracketed-paste splitter (macOS screenshot names like/Users/me/Desktop/Screenshot 2026-06-25 at 1.23.45 PM.png), and (3) decodesfile://URLs to filesystem paths innormalizePastedPath(mirroring Codex'snormalize_pasted_pathincodex-rs/tui/src/clipboard_paste.rs). Keybind- and terminal-mediated paste now agree on raw image bytes, plain image paths,file://URLs, Finder-copied image files, and screenshot filenames with spaces alike. (#3506) - Fixed compiled-binary validation for legacy
pi.extensionspackages whose source imports worker-only coding-agent subpaths or extension-local package subpaths such astypebox/value;omp install @charmland/pi-hyper-provider,omp plugin doctor, and runtime provider discovery now use a main-thread-safe load path. (#3508) - Fixed repeated todo updates in one TUI turn stacking full todo panels; superseded todo snapshots now stay live until the next todo update replaces them or the turn ends. (#3516)
- Fixed MCP OAuth authorization failing with
Authorization failed: An unexpected error occurredagainst authorization servers (Plane is the live example) that reject redundant fallbackresourceindicators. OMP now drops same-origin resources only when it synthesized them from the server URL fallback (e.g.https://mcp.plane.so/http/mcp). Provider-advertised resources from OAuth/protected-resource discovery or an embedded authorization-URLresourcequery parameter are preserved even when they are same-origin or origin-only, so gateway-hosted MCP services can still request the audience they advertised. The refresh-token path uses the same policy, filtered against the authorization-server origin persisted on the credential asauthorizationUrl, withtokenUrl's origin as the legacy fallback when that field is absent. (#3502)
[16.1.20] - 2026-06-25
Fixed
- Fixed Ctrl+Z hanging the terminal after any tool call had run: the TUI tore down (
ui.stop()) but the process kept running inSl+state, leaving the user with a dead terminal recoverable only viakill -9. The embeddedbrush-coreshell behind every bash tool call installs a tokio SIGTSTP listener onProcess::wait(crates/brush-core-vendored/src/sys/unix/signal.rs::tstp_signal_listener→tokio::signal::unix::signal(SIGTSTP)); per tokio's contract, the first call for a SignalKind permanently replaces the kernel-default handler for the lifetime of the process. So the first bash invocation — even/usr/bin/true— silently overrode SIGTSTP's "stop" default, andInputController.handleCtrlZ's subsequentprocess.kill(0, "SIGTSTP")was swallowed by tokio. The handler now sendsSIGSTOP(uncatchable, unblockable, unignorable) to the foreground process group, so the kernel parks omp regardless of installed handlers and the shell sees the whole job stop even when omp runs behind a wrapper (npx,pnpm exec,bunx, …) or as one stage of a pipeline. MCP stdio servers now spawn detached into their own session — they're insulated both from terminal job-control signals (which used to stop their process trees and leave the JSONL read loop blocked on silent pipes) and from the new pgid=0 suspend itself (#3461). - Fixed image-only composer submissions while the agent is streaming being treated as empty input, which dropped the image or aborted the active turn when another message was queued. Pending pasted images now count as submit content for Enter and Ctrl+Enter follow-ups. (#3467)
- Fixed
omp gallery --stateaccepting lifecycle tokens that did not match displayed state labels and rendering unknown state values as· undefined; displayed labels now work as aliases, invalid values fail with a valid-token list, and failed gallery fixtures visibly render failures. (#3473) - Fixed the bash tool's snapshotted
mise()shell function dying withcommand: command not found:because$__MISE_EXEwas empty in the replay shell.generateSnapshotScriptcaptured the function viadeclare -f/typeset -fbut only ever re-exportedPATH, so every other env var the rc file set (notably the*_EXEsidecarmise activateexports) was lost; the function body then expandedcommand "$__MISE_EXE" "$@"tocommand "" …and died with exit 127. The snapshot script now scans captured function bodies for$VAR/${VAR…}references and re-emitsexport NAME='value'for each referenced var that is currently set (with a denylist for shell-internal names likePATH/HOME/BASH_*/LC_*plus a likely-secret denylist for*TOKEN*/*SECRET*/*API_KEY*/*PASSWORD*/*PRIVATE_KEY*/*ACCESS_KEY*/*CREDENTIAL*/*SESSION_KEY*), the snapshot scriptumask 077s itself and the JS caller chmods the snapshot file/dir to0600/0700so the new export pass can't leak secrets into a shared tmp dir. Fixes mise, asdf shims, direnv-style helpers, and other activation idioms that pair a function with a helper env var.getShellConfigFilenow also honoursenv.HOME(falling back toos.homedir()) so sandboxed callers can target a non-default rc. (#3470) - Fixed concise
history://transcript rendering forfindandsearchso scopedpathsarguments are visible instead of being hidden behind JSON fallback output or omitted when a searchpatternis present. (#3482) - Fixed manual
/compactleavingsession.isCompactingfalse while active-turn abort teardown awaited, so the first steer/follow-up typed during compaction startup now routes through the compaction queue instead of being lost. (#3485) - Fixed ollama-cloud task/subagent fan-out exceeding the provider's three-request concurrency cap by adding a provider-specific subagent limiter, and let configured task/smol/advisor model roles inherit the default retry fallback chain when they do not define their own chain. (#3464)
- Fixed the per-provider subagent concurrency limiter (e.g.
providers.ollama-cloud.maxConcurrency) being replaced with a fresh semaphore whenever the configured limit changed, which orphaned the in-flight slots on the old instance and let a runtime or mixed limit value exceed the cap. The limiter now resizes a single shared semaphore in place — raising the ceiling admits queued waiters immediately, lowering it drains in-flight holders without admitting past the new cap. (#3464) - Fixed a background-task spawn slot leaking from the
task.maxConcurrencylimiter when progress reporting threw between acquiring the slot and entering the guarded run:markRunning/reportProgressnow run inside the try whosefinallyreleases the semaphore, so a failed progress report can no longer permanently shrink subagent concurrency. (#3464) - Fixed active goal runs that successfully call
yieldand then receive a trailing empty assistantstopskipping threshold compaction; post-yield empty-stop suppression now still anchors active-goal compaction on the yield-bearing assistant turn, so long-running tasks continue after maintenance instead of settling early.
[16.1.19] - 2026-06-25
Fixed
- Fixed
omp install <plugin>failing extension validation in compiled-binary mode withCannot find module '@(scope)/pi-ai/oauth' from '<plugin>/src/oauth.ts'(and any other non-wildcard pi-* subpath import like@oh-my-pi/pi-coding-agent/tools). The bundled-registry override map seeded by__buildLegacyPiPackageRootOverridesonly covered the bare package roots, sorewriteLegacyPiImportsrewrote@(scope)/pi-ai/oauthto@oh-my-pi/pi-ai/oauth, fell through toBun.resolveSync(which bunfs can't satisfy on Bun 1.3.14+), then left the original specifier alone — at which point Bun's native resolver failed because most plugins declare@(scope)/pi-aias apeerDependencyonly and never materialize a real install. The newscripts/generate-legacy-pi-bundled-registry.tsreads every bundled pi-* package's non-wildcardexportsfield and emits both the heavylegacy-pi-bundled-registry.ts(static imports + map) and a lightlegacy-pi-bundled-keys.ts(statically imported bylegacy-pi-compat.tsto seed the override map without the cascade throughlegacy-pi-coding-agent-shim → ../index → export/html/...).scripts/build-binary.tsnow runs the generator beforebun build --compile. (#3442) - Fixed
skill://tool resolution losing loaded session skills when a tool runs outside the session-initialization module state. Internal URL resolution now prefers the caller'ssession.skillssnapshot before falling back to the process-global skill list, soread skill://<name>works across tool execution boundaries. (#3436) - Fixed
@imagementions on OpenAI Codex Responses (chatgpt.comgpt-5.5and siblings) failing withCodex error event: [OneOfParam] [input[N].content[…]] [invalid_enum_value] Invalid value: 'input_image'. Supported values are: 'input_text'..convertToLlmforfileMentionalways emitted adeveloper-role message, so the auto-attached image landed in a Responses content array that the Codex backend (and OpenAI Responses generally) only allows to carryinput_text. #3421's previous fix only stopped the Codex Responses Lite header from going out on image-bearing turns; the full transport kept rejecting the same payload.convertToLlmnow splits a mixed-contentfileMentioninto two messages — text-only files stay ondeveloper(so the auto-read context keeps instruction priority), while image-bearing files ride onuser(the only Responses content slot that acceptsinput_image). (#3443) - Fixed
local://binary attachments being decoded withBun.file().text()before read-tool file safeguards could reject or stream them.read local://...now routes file-backed resources through the normal filesystem reader, the protocol handler refuses known binary/container resources without materializing their bytes, and the streaming reader's NUL-byte refusal now also covers binary blobs whose first newline lies beyond the byte budget (videos, archives) — those previously bypassed the per-line scan and surfaced as decoded mojibake. (#3448)
[16.1.18] - 2026-06-25
Added
- Added --list flag to view stored OAuth accounts for a provider
- Added --account flag to select a specific OAuth account by index for token retrieval
- Added mouse support for navigation, selection, and toggling in the extensions dashboard
Changed
- Enabled fullscreen alternate-screen mode for the extensions dashboard
- Improved tab navigation to mute empty enabled providers while keeping disabled ones selectable
/extensions(the Extension Control Center) now opens as a fullscreen window on the terminal's alternate screen, matching/settings: it borrows the alt buffer for its lifetime (the transcript is untouched underneath) and uses the same modern chrome — a titled rounded frame, the sharedTabBarfor provider switching, and a divider/footer layout. The dashboard is now mouse-aware: the wheel scrolls the list (and the detail inspector, which gained its own scroll viewport), hovering highlights tabs and rows, and clicking selects a row or — when it is already selected — toggles it; clicking a provider tab switches to it. Empty enabled providers are unselectable while disabled providers stay selectable so their master switch can re-enable them.
Fixed
- Fixed
omp installof legacy pi extensions failing withCannot find module '/$bunfs/root/packages/coding-agent/src/extensibility/typebox.js'on every releasedomp-<platform>-<arch>binary. Commitdc5c93462fremoved worker entrypoints fromscripts/ci-release-build-binaries.ts; the inline comment then claimed the legacy-shim and package-barrel entrypoints (typebox.ts,legacy-pi-{ai,coding-agent}-shim.ts,packages/{agent,natives,tui,utils}/...) were "still" passed tobun build --compile, but they had never been re-added. The release binaries shipped without those files in bunfs, solegacy-pi-compat.tsredirectedtypeboximports to a bunfs path that didn't exist.__resolveTypeBoxShimPathnow mirrors__validateLegacyPiPackageRootOverrides(#2168) by dropping the override when the shim file is missing, so a missing shim falls through to nativenode_modulesresolution instead of emitting a dead bunfs URL (#3414). - Fixed every legacy
@(scope)/pi-*and@sinclair/typeboximport failing to load on theomp-darwin-arm64release binary (and any otherompbuilt with Bun 1.3.14).__validateLegacyPiPackageRootOverridesand therewriteLegacyPiImportsemit path both depended on--compileextras being reachable as/$bunfs/root/...filesystem entries, but Bun 1.3.14 stopped exposing them through every API (fs.existsSync,Bun.file().exists(),Bun.resolveSync,await import()on the bunfs path or itsfile://URL all fail; only/$bunfs/root/<binary-name>itself answers).legacy-pi-compat.tsnow keeps a JS-heap reference to every bundled pi-* surface in a lazy-loaded siblinglegacy-pi-bundled-registry.tsand serves them through anomp-legacy-pi-bundled:virtual namespace whoseBun.plugin().onLoadreturns synthetic re-exports — no bunfs path ever leaves the module in compiled mode, and dev / source-link / installed-package modes keep the historicalfile://rewrite. The matching--compileextras inscripts/build-binary.ts, the sharedscripts/binary-entrypoints.tslist, and the deadBUNFS_PACKAGE_ROOT/bunfsPath/__computeBunfsPackageRoot/__joinBunfsPathhelpers are gone. (#3423)
[16.1.17] - 2026-06-24
Fixed
- Fixed mnemopi auto-retain extracting facts/entities from assistant-authored transcript turns.
MnemopiSessionState.retainMessagesstill stores the full multi-role window for episodic recall, but passes only user-authored turns asextractText, so assistant prose containingalways/neverno longer becomes durable userInstruction:memory. (#3372) - Fixed lazy tool auto-downloads hanging when
Bun.write(dest, response)receives a streamingfetch()Response; tool assets now stream the response body to disk with the existing download abort signal and remove partial files on abort. (#3369) - Fixed profile-alias installer producing backslash-separated paths for bash/zsh/fish config files on Windows.
path.joinwas used unconditionally, producing Windows-style paths that POSIX shells can't resolve. The installer now usespath.posix.joinfor non-Windows platforms and normalizes script paths to forward slashes for POSIX shell alias blocks, soomp --aliasworks correctly in Git Bash and WSL. - Fixed pasted or dragged non-image file paths in the TUI prompt staying as inert raw text; existing files now attach as clean
local://attachment-N.<ext>references while image paths keep the image attachment flow. (#3360) - Slash commands are now recorded in input history (Up Arrow recall). Previously only 4 commands (
/plan,/goal,/mcp,/ssh) stored their text; all other built-in slash commands were silently skipped becauseexecuteBuiltinSlashCommandreturnedtruebeforeaddToHistorywas called. History is now centralized in the input controller after successful command dispatch. Commands that may carry secrets (/login <url>with OAuth callback params,/mcp add --token <token>) are excluded from history to prevent credential leakage (#3148) - Fixed the
asktool's "Other (type your own)" free-text editor (prompt-styleHookEditorComponent) ignoring Ctrl+Q and Ctrl+Enter, so Windows Terminal users who learned theapp.message.followUpchord from the main editor (#1903 / fixed by #1905) got zero feedback on submit. The hook-style and main-editor surfaces honoredmatchesAppFollowUp; the prompt-style handler did not, leaving plain Enter as the sole submit path and Ctrl+Enter falling through to Editor as a newline (silently swallowed by WT).#handlePromptStyleInputnow checksmatchesAppFollowUpfirst — mirroring#handleHookStyleInput— and the hint readsenter or ctrl+q submitso the chord is discoverable. (#3353) - Fixed the TUI freezing when a tool approval prompt fires while
/settings(or the Extensions/Agents dashboard) is open. The fullscreen overlay's close handler restored focus to the editor it had captured at open time, butExtensionUiControllerhad since swapped the editor out of the editor slot for the approval prompt — so on exit the visible prompt sat unreachable while keystrokes routed to the now-unmounted editor (no Enter/Up/Down/Esc response, only Ctrl+C escaped).SelectorControllernow restores focus to whatever currently owns the editor slot via afocusActiveEditorArea()helper, applied to settings, extensions dashboard, and agents dashboard close paths. (#3349) - Fixed
/settingscoercing enum/text values to display strings before handing them to the TUI list, preventing YAML numeric enum values from reaching native truncation (#3338). - Fixed all extension loading silently failing on the cross-compiled
omp-darwin-arm64release binary (downloaded directly or via a Homebrew tap wrapper) because__computeBunfsPackageRootmis-handledimport.meta.dir = "//root/omp-darwin-arm64". Bun 1.3.14 reports<bunfs-root>/<binary-name>for the compiled entry'simport.meta.dir, but the pre-fix function joinedmetaDir + "packages"and produced/root/omp-darwin-arm64/packages— the binary basename was baked into every bunfs path, so the TypeBox/legacy-pi shims and every@oh-my-pi/pi-*package-root override failedexistsSyncvalidation andresolveCanonicalPiSpecifierfell through to a bunfsBun.resolveSyncthat also could not find the module. The function now detects the bunfs-root + binary-basename shape (path.basename(path.dirname(metaDir)) === "root") and strips the trailing binary segment by slicing the originalmetaDir; the production bunfs shim join path also preserves Bun's bunfs-native//root/B:\~BUN\rootprefix thatpath.joinwould otherwise collapse. (#3329) - Fixed llama.cpp discovery to prefer per-model
/v1/modelsmeta.n_ctx/meta.n_ctx_trainvalues, refresh selected models after lazy load, and bypass fresh-cache reuse so server restarts update context windows. (#3310) - Fixed
task.maxConcurrency: 0serializing subagent spawns instead of running them unbounded. The settings UI labels0as "Unlimited", but the session-scoped spawnSemaphoreclampedmaxviaMath.max(1, max), so the second subagent body in a batch always waited for the first to release the seat. The constructor now treatsmax <= 0(and any non-finite input) as unbounded viaNumber.POSITIVE_INFINITY, matching the evalparallel()/pipeline()worker-pool semantics (#3305). - Fixed MCP tool calls forwarding empty optional placeholder arguments (
""and{}) totools/call; optional placeholders are now omitted while required fields and meaningful falsy values are preserved. (#3302) - Fixed the welcome
Tip:line rendering with hardcoded#b48cff/#9ccfffpastels plus a manual\x1b[2mdim, so any light theme dropped the body to ~1.5:1 contrast (well under WCAG AA).renderWelcomeTipinpackages/coding-agent/src/modes/components/welcome.tsnow paints the label throughtheme.fg("customMessageLabel", …)and the body throughtheme.fg("muted", …)(no manual dim), so the line tracks the active theme and stays legible on light backgrounds. (#3337) - Fixed
omp usageand the/usagecommand duplicating provider-wide disclaimer notes (e.g. OpenCode Go's "OMP-observed spend only") once per account × limit window. Provider-level notes now render once above the per-account sections in the TUI, CLI, and ACP render paths, and identical per-limit notes are deduplicated in the TUI aggregate renderer. (#3268) - Fixed the welcome panel advertising
? for keyboard shortcutsafter the?shortcut was deliberately removed (commitdcf482c4c). The tips section now points users at/hotkeysinstead. (#1614) - Fixed Devin provider models silently producing empty responses under the default
defaultThinkingLevel: auto. Devin models advertisereasoning: truebut nothinking.efforts(Cascade selects effort by routing to sibling model ids, not a wire param), sogetSupportedEfforts(model)was empty;clampAutoThinkingEffortreturned the classifier-picked effort as-is, which then trippedrequireSupportedEffortinpi-ai/stream.tswithThinking effort low is not supported by devin/<id>. Supported efforts:(silently swallowed by the TUI).clampAutoThinkingEffortnow returnsundefinedwhen the model has no controllable effort surface, matchingclampThinkingLevelForModel; the auto-thinking turn hook also short-circuits the classifier call for these models. (#3356) - Fixed
omp tiny-models downloadexiting before its unref'd worker subprocess could install the runtime or download model weights. The tiny-model client now references the worker while requests are pending so standalone CLI downloads wait forDownloaded .../Failed ...completion. (#3291) - Fixed marketplace plugin installs registering only in
installed_plugins.jsonand never in the runtime plugin tree, leaving slash commands and extensions unavailable afteromp plugin install name@marketplace. The runtime loader now also enumerates the project-scope plugins root (<projectAnchor>/.omp/plugins) so--scope projectinstalls surface alongside user-scope installs, with project entries shadowing same-named user entries (#3244). - Fixed
umansrequests with more than 10 live context images still sending every image despite the provider budget; outgoing provider contexts now drop the oldest images above the active provider cap while preserving text and newest images (#3230). - Fixed snapcompact auto-compaction looping the "snapcompact could not bring the context under the limit — using an LLM summary instead" warning on every threshold tick for sub-1M-token models (Claude Sonnet 4.5, GPT-5.x, Gemini 2.x).
snapcompact.compact()was called with nomaxFramesoverride, so it defaulted toMAX_FRAMES_DEFAULT = 80; the projection inAgentSessionchargesFRAME_TOKEN_ESTIMATE = 5024per frame block (the conservative high-res Anthropic ceiling), making 80 × 5024 ≈ 402k frame-token projections that always overflow a 200k budget.AgentSession.#computeSnapcompactMaxFramesnow sizes themaxFramescap from a shape-aware reserve —2 × geometry(shape).capacityworth of verbatim text-edge chars billed at the tiktoken cl100k 4-chars/token baseline (with a 1.15 multiplier for tokenizer drift), plus a 2k summary-template allowance — mirroring what#projectSnapcompactContextTokenswill charge once frames land. The shape comes from the samesnapcompact.resolveShape(model, settings)call the auto and manual paths pass intosnapcompact.compact(). The cap reserve applies only to the frame-cap math, not the skip decision: snapcompact is skipped outright only whenkept-recent + non-message ≥ ctxWindow − reserve(no headroom at all), so the frame-lesstext.length <= 2 * edgeCapshort-circuit inplanArchivecan still land a valid text-only archive when residual headroom is positive but below the cap reserve. The projection guard catches any actual frame-bearing archive that overflows. (#3247) - Fixed large-session TUI stalls by tailing appended transcript JSONL and collapsing compacted history on the live display surface (#3258).
- Fixed status-line
usagesegment ignoring Codex subscription limits that carry ascope.tier(#2877). - Fixed extension
tool_call/tool_resultevents for hashlineeditcalls to exposeevent.input.pathfor single-file edits andevent.input.pathsfor every parsed target, so planning-mode gates can allow one markdown plan edit but still block multi-file hashline calls that cannot be represented by one path (#1678). - Fixed scripted
evalagent()subagents continuing after a successfulyieldwhen a trailing empty assistantstoparrived after the executor's yield-triggered abort. The session'sagent_endmaintenance compared#assistantEndedWithSuccessfulYield(msg)against the trailing empty-stop message — not the prior yield-bearing one — so the empty-stop recovery path appended a retry reminder and scheduledagent.continue(), reviving the already-yielded child. The yield handler now sets a sticky#yieldTerminationPendingflag (cleared on the nextprompt()) that short-circuits empty-stop / unexpected-stop / compaction continuations for the rest of the run, so a successful yield is terminal regardless of trailing stops (#3389). - Fixed snapcompact rasterizing transcript frames into requests bound for GitHub Copilot business and enterprise endpoints, which then rejected the session permanently with
400 vision is not supported. The snapcompact vision gate now also short-circuits whenevermodel.provider === "github-copilot"and the resolvedbaseUrlis not the canonical personal-Copilot host, protecting cached/stale Model specs that still advertise["text","image"]on a non-personal endpoint. (#3387)
[16.1.16] - 2026-06-23
Breaking Changes
- Renamed the eval
agent()helper parametersagent_type→agentandreturn_handle→handleacross every workflow runtime (Python, JavaScript, Ruby, Julia), so the names are identical in every language (no camelCase/snake_case split) and the agent-selection parameter matches thetasktool'sagent. The__agent__eval bridge wire protocol was renamed to match. - Changed the
evaltool to take a single cell per call ({ language, code, title?, timeout?, reset? }) instead of acellsarray. State still persists per language across separate eval calls, tool calls, andtasksubagents, so each call is one logical step that reuses everything earlier calls defined — the array only encouraged re-importing/re-declaring the same setup in every batch. The schema, field descriptions, examples, systemeval.md/workflowzhelper docs, and the[i/n]cell-counter (now hidden for single cells) were updated to match; the renderer, ACP start-text, copy-targets, and collab-web tool view still parse legacy multi-cell transcripts.
Added
- Added
isolated,apply, andmergeoptions to evalagent()across every workflow runtime (Python, JavaScript, Ruby, Julia) soworkflowz-driven fan-outs can request the same copy-on-write worktree isolation thetasktool offers (strict opt-in viaisolated: true, matching thetasktool;apply: falsekeeps captured patches/branches without merging back;merge: falseforces patch mode). Extracted the task-isolation lifecycle intotask/isolation-runner.tsso the eval bridge andTaskToolshare one implementation (#3196)
Changed
- Made the session picker fullscreen with mouse support for clicking rows and scrolling
- Pinned the session picker footer to the bottom of the screen to prevent layout flickering
- Simplified
evaltool to accept a single logical step (code block) instead of an array of cells - Updated
evaltool documentation to emphasize incremental, single-step execution - Restricted
bashtool from usinglsorfind, requiring the use ofreadorfindtools - Simplified
todotool interface to accept a single operation directly instead of an array of ops - Reinforced routing of fragile, multi-step shell logic to the
evaltool overbash. The system-prompt tool policy,bash.md, andeval.mdnow treat loops, conditionals, heredocs, inline-e/-cscripts, multi-stage pipelines, and quote/JSON escaping as the signal to write anevalcell; bash's "compute a fact" carveout is narrowed to single short pipelines, andeval.mdnow actively claims that territory with runtime-templated examples (only enabled backends are advertised). - Made
evalan essential built-in tool (loadMode: "essential", added to the default essential tool set) so it stays active undertools.discoveryMode: "all"instead of being hidden behindsearch_tool_bm25. - Made the
--resumesession picker fullscreen on the terminal's alternate screen, so the list scrolls with the mouse wheel and a row resumes its session on left click. Rows are hit-tested against the live scroll window, and the keybinding hint + bottom border are now pinned to the screen bottom instead of drifting up and down as the visible window changes height.
Fixed
- Fixed
local://URLs decoding images as corrupted text (mojibake) instead of showing the image - Fixed
omp --resumehanging instead of exiting when the startup session picker is cancelled (Esc) or there are no sessions to resume. Startup arms long-lived handles (theme/appearance listeners, settings save timer, model registry), so the cancel/empty paths' barereturnleft the event loop alive and the process stuck after the picker cleared the alternate screen. These paths now exit cleanly viaprocess.exit(0), matching the--version/--exportearly-exit convention. The in-session/resumepicker is unaffected — it keeps its own cancel handler that just closes the overlay. - Fixed the
/resumesession picker scrolling down after a session is deleted. The delete-confirmation dialog was mounted as a sibling below the picker's bottom border, briefly growing the picker past the terminal height; the TUI committed the picker's header rows into native scrollback to fit, and when the dialog closedwindowTopstayed pinned at the new commit boundary, leaving the header stranded above the viewport. The picker now hosts theSessionListin a single content slot and swaps the dialog INTO that slot (replacing theSessionList) while it is open, so the dialog only competes with theSessionList's rendered budget — not theSessionListAND the picker chrome — and the picker frame stays inside the viewport. (#3283) - Fixed the
evaltool card not streaming a still-running cell's stdout: a long-running cell (e.g. atime.sleep()monitor loop) showed nothing until it returned or was interrupted, then dumped everything at once. The renderer draws cell output fromdetails.cells[i].output, which was only populated afterbackend.execute()resolved — live stdout streamed into the transient resultcontenttail (andrenderContext.output), which the per-cell render branch ignores. Streamed chunks now append to the active cell'soutput(a dedicated per-cell tail buffer, capped like the aggregate) as they arrive, so the card shows progress live; on completion the authoritative full output overwrites the live tail.log()/phase()/display()and status ops were unaffected because they already stream via the status channel. - Fixed Escape doing nothing in the Settings text-input fields (e.g. "Python Interpreter") on terminals with the kitty keyboard protocol active (ghostty/kitty). Inside the fullscreen settings overlay the protocol reports Escape as the CSI-u sequence
\x1b[27u, which the text-input submenu's raw\x1bcompare missed;handleInputOrEscapenow decodes Escape viamatchesKey, matching every other Escape-to-cancel path. - Fixed Julia
evalgraph/plot visualization (Plots.jl, GraphRecipes, Makie, etc.) never rendering inline. Two bugs: (1) the runner'sbuild_mime_bundle/emit_errordispatchedshow/showable/showerrordirectly from the long-livedmain()loop, whose world age is frozen before any cell ran, so richshow(::IO, ::MIME"image/png", …)methods registered when a plotting package isusing-ed inside a cell were invisible —showfell back to the default struct repr (which itself threw on Julia 1.12, aborting the whole result). These calls now route throughBase.invokelatest, and thetext/plainprobe is guarded so a failing repr can no longer suppress the image MIME. (2) The default GR backend popped up a nativegksqtGUI window on each plot; the runner now defaultsGKSwstype=100(headless, overridable) so plots render only as inline PNGs, mirroring the Python runner'sMPLBACKEND=Aggdefault. - Fixed streaming output blocks incorrectly calculating preview height, preventing flickering banners
- Fixed streaming
bash/evaltool output duplicating its… (N earlier lines, showing 10 of M) (ctrl+o to expand)preview into native scrollback. The collapsed output is a sliding tail window fixed at 10 lines, so when the box outgrew the live viewport (a tall command/output under a still-live predecessor such as a parallel tool) its mutating tail scrolled above the commit window and the renderer re-committed a fresh snapshot every frame, stacking dozens of stale preview banners and chunks. The output preview is now clamped to the viewport tail (Math.min(10, previewWindowRows())) and measured in visual rows at the box's inner content width (via the newoutputBlockContentWidthhelper), so on short terminals the volatile tail shrinks to stay on-screen and is never committed. Fixes the duplication introduced when scroll-off commits were made loss-free. - Prevented
/handofffrom executing while a response is streaming to avoid session corruption - Fixed
/handoffcold-missing the provider prompt cache. Handoff generation now builds its request through the same pipeline a live turn uses (convertMessagesToLlm+Agent.buildSideRequestContext+prepareSimpleStreamOptions, via the newgenerateHandoffFromContext), so it reuses the live system prompt, normalized tools, transformed/obfuscated message history, and — critically — a stablepromptCacheKeywith a unique sidesessionId. Previously the oneshot sent no cache-routing key and skipped thetransformContext/transformProviderContextand tool/message normalization the loop applies, so its prefix never matched what the turn populated and every handoff re-read the whole context uncached. Mirrors the cache-preserving path already used by/btwand/omfg. - Fixed
/handoff(and the RPChandoffcommand) resetting the agent while a response was still streaming, which let the live turn keep emitting into the torn-down session. Manual handoff now refuses while a prompt is in flight (matching/forkand/move); the auto-handoff path is unaffected. - Fixed Exa web search requests firing back-to-back with no client-side pacing by adding a configurable
exa.searchDelayMsdelay (default 1000ms) between Exa search requests. (#3271) - Fixed
askreturning(cancelled)or aborting the tool when Escape dismissedOther (type your own)custom input; it now returns to the option selector so the user can pick a listed answer instead. (#3269) - Fixed
/goalthreshold auto-compaction skipping real sessions through three paths: per-turn supersede/drop-useless pruning no longer deflates the threshold trigger below the last provider-billed context; active-goal text stops now attempt threshold maintenance before unexpected-stop retry continuations can return from post-turn handling; and emptytoolUsestops keep the existing cleanup pass that strips the orphan assistant from active context + session history before any compaction continuation. Active-goal compaction continuations now also resolve completed retry gates before returning, preventingisRetryingfrom staying stuck after a retry succeeds over the threshold. Addedagent_end maintenance routingandAuto-compaction threshold decisiondebug logs so future no-start reports identify the exact early-return branch and the billed/stored/resolved/post-maintenance token counts that fedshouldCompact. (#3174) - Fixed active
/goalruns that never reachedagent_endbecause the model kept emitting tool calls inside one agent run. Threshold maintenance now runs between tool-call turns, compacts the live loop context in place, and suppresses queued continuations that would race the still-running goal loop. (#3174)
Removed
- Removed
append,tree, anddiffeval helper functions from Python, JavaScript, and Ruby - Removed
sort,uniq, andcountertext processing eval helpers from Python, JavaScript, and Ruby - Removed the
append(path, content),tree(path, max_depth?, show_hidden?), anddiff(a, b)eval prelude helpers from every workflow runtime (Python, JavaScript, Ruby, Julia), along with their status renderers, icon entries, and tool/docsreferences. Usewrite/readfor file mutation andtool.<name>(...)for richer filesystem operations. - Removed the
sort(text, reverse?, unique?),uniq(text, count?), andcounter(items, limit?, reverse?)eval text helpers from the Python, JavaScript, and Ruby prelude surfaces (Julia never defined them), along with the JSHelperBundle/HelperOptionsmembers anddocsreferences. Sort/dedupe/count inline in cell code instead.
[16.1.15] - 2026-06-22
Added
- Added a
share.storesetting (blob"Encrypted Blob" |gist"GitHub Gist", defaultblob) controlling where/shareuploads the encrypted session blob — the share server (blob) or a secret GitHub gist with share-server fallback (gist).
Changed
- Changed
/shareto upload the encrypted session blob to the share server by default instead of a secret GitHub gist. Gist-hosted shares are fetched through the unauthenticated GitHub gist API from the viewer's browser, which GitHub rate-limits to 60 requests/hour per IP, so shared NATs and repeated reloads surfacedFailed to load session: Gist fetch failed: HTTP 403in the viewer. Opt back into gist hosting withshare.store: "gist".
Fixed
- Fixed
nohup/&background processes started inside an auto-backgrounded (:async:) bash turn being killed when that turn's shell was torn down. The per-job shell is now retained while a background process is still running (and reaped once it exits), so backgrounded commands survive across turns while still dying with the harness process. - Fixed
openai-completionsprovider session state surviving/modelswitches across different providers or base URLs.AgentSession.#closeProviderSessionsForModelSwitchonly evictedopenai-codex-responsesandopenai-responses:<provider>keys; entries keyedopenai-completions:<provider>:<resolvedBaseUrl>:<modelId>(cached strict-tools disable scopes and reasoning-effort fallbacks for the old transport) lingered indefinitely. Moving away from anopenai-completionsbackend now evicts every cached entry for the previous provider, including entries whose base URL was resolved at request time rather than read from the catalog, while same-backend model toggles keep their cached state (#3260) - Fixed MCP stdio servers failing on Windows when the launcher's PATH walk can't pin down a bare
npx/yarn/pnpm-style shim (emptyBun.env.PATHunder a restricted parent process, UNC mounts that rejectfs.access, locked-down shells).resolveStdioSpawnCommandused to fall back to the bare command name, whichBun.spawn→CreateProcesscan only resolve as<name>.exe— never.cmd/.bat— sonpx -y …died ~140ms after spawn withENOENT/EINVAL. The Windows resolver now routes any unresolvable bare command throughcmd.exe /d /s /cso Windows's own PATHEXT search picks up the shim. The reporter's diagnosis ("process.env not merged") was incorrect — the merge happens attransports/stdio.ts:316-319— but the symptom they hit is real (#3250). - Fixed bracketed paste treating a bare
.pngfilename as an image attachment path instead of normal prompt text. (#3253) - Fixed Perplexity web-search provider hijacking the auto fallback chain when only OpenRouter auth was configured.
PerplexityProvider.isAvailable()acceptedhasAuth("openrouter")as a credential, so any user with an OpenRouter key (for LLM access) had everywebSearch: autorequest silently routed through OpenRouter'sperplexity/sonar-pro— bypassing downstream providers like Gemini and producing unexpected OpenRouter billing. Auto-chain admission now requires a direct Perplexity credential (PERPLEXITY_COOKIES, OAuth, orPERPLEXITY_API_KEY); users who want the OpenRouter-backed Perplexity path can still opt in explicitly withwebSearch: perplexity(#3251) - Fixed configured model discovery caches to refresh when
models.yml/models.jsonis newer than the cached row, so updated local model metadata is not shadowed by freshmodels.dbentries. (#3242) - Fixed hide-secrets handling so advisor session updates are redacted before the advisor model sees them and opaque assistant thinking blocks are no longer deobfuscated.
- Filtered alias definitions brush's whitespace-only expander cannot execute (
(,),|,&,;,<,>,`) from the bash-tool shell snapshot, so user rc-files containing compound aliases like Fedora's defaultwhich='(alias; declare -f) | /usr/bin/which …'no longer poison the brush session witherror: command not found: (alias;(#3234).
[16.1.14] - 2026-06-22
Added
- Added a Ruby eval backend (
language: "rb"): a persistent subprocess Ruby kernel that shares the standard agent tool bridge and evaluation model, supporting IRB-style auto-display of results in a persistent session - Added a Julia eval backend (
language: "jl"): a persistent subprocess Julia kernel that shares the standard agent tool bridge and evaluation model, supporting Julia REPL-style auto-display of results in a persistent session - Added configuration options
eval.rbandeval.jlto enable or disable the Ruby and Julia backends (both opt-in, disabled by default), as well asruby.interpreterandjulia.interpreterpaths for explicit runtime control - Added a Ruby eval backend (
language: "rb"): a persistent subprocess Ruby kernel modeled on the Python kernel, speaking the same NDJSON protocol with isolated frame/stdout channels, clean SIGINT cancellation that preserves kernel state, and per-owner kernel cleanup. Ships the full prelude helper surface (display/read/write/append/tree/diff/env/output/sort/uniq/counter, thetool.<name>bridge proxy, andcompletion/agent/parallel/pipeline/log/phase/budget) over the shared loopback tool bridge, honorslocal://roots, and auto-displays the last expression IRB-style (suppressing assignments/definitions). Gated by theeval.rbsetting andPI_RBenv flag, with an optionalruby.interpreteroverride. - Added a Julia eval backend (
language: "jl"): a persistent subprocess Julia kernel with the same NDJSON/result-display/tool-bridge model as the Python and Ruby eval runtimes, includingeval.jl/PI_JLgating,julia.interpreteroverride support, persistent per-session state, clean cancellation, owner-based kernel cleanup,local://path roots, and the current Julia prelude helper surface (display/read/write/append/tree/diff/env/output, thetool.<name>bridge proxy, and bridge-backedcompletion/agent/parallel/pipeline/log/phase/budget, including structuredschemaparsing andreturn_handleDAG shaping). - The eval tool advertises only the runtimes enabled for the session: a disabled backend (rb/jl are off by default) is omitted from the tool's
languageenum, schema field descriptions, discovery summary, and prelude documentation, so disabled backends are never surfaced to the model
Changed
- Refactored internal evaluation logic to consolidate shared kernel management and IPC handling
- Refactored internal draft state to consolidate images and text into the editor component
- Unified transcript rendering logic for background jobs, IRC traffic, and file mentions
- Unified subprocess lifecycle management for mnemopi, speech, tiny-model, and TTS workers
- Softened the system-prompt and tool-prompt guidance that hard-forbade reaching for shell equivalents of dedicated tools (
grep/rg,sed/perl -i,cat/head/tail,find/fd). The "Specialized Tool Priority" section, thebash/search/find/read/replacetool prompts, and the FORBIDDEN/NEVER framing now state the dedicated tools as the preferred default rather than an absolute prohibition, so the agent no longer fights itself when a quick shell command is the right call. The opt-inbashInterceptor(default off) still hard-blocks these commands for users who enable it. - Unified subprocess lifecycle management for mnemopi, speech, tiny-model, and TTS workers
- Refined TUI dashboard and list component layout logic for consistent rendering
- Standardized scrollbar behaviors and keyboard navigation across all list components
- Optimized internal message framing logic for better performance when handling large data bursts
Removed
- Removed the
readHashLinessetting (the "Hash Lines" toggle under Files → Reading). Hashline read/search anchors ([PATH#TAG]snapshot headers plusLINE:content) are now driven solely byedit.mode === "hashline": the toggle was redundant when off (anchors are already suppressed for non-hashline edit modes) and a footgun when on (turning it off left the default hashline edit tool with no addressable anchors, sincereadthen skips recording the snapshot tag). Existing configs are migrated automatically by dropping the stale key.
[16.1.12] - 2026-06-21
Changed
- Refined secret obfuscation to only target message roles and fields containing operator secrets
- Restricted obfuscator to ignore secrets and regex matches shorter than 8 characters
- Optimized obfuscation to skip static system prompts and tool schemas in provider contexts
- Ensured image data bytes are never modified to prevent corrupted data URL payloads
Fixed
- Fixed secret obfuscation corrupting Codex image reads (and other provider requests) with
Invalid 'input[N].content[].image_url'. Expected a base64-encoded data URL ... but got an invalid base64-encoded value. The obfuscator deep-walked every string in the outbound request — including inline image base64 and opaque provider replay/signature fields — so a configured secret that happened to be a substring of the base64 (or of an ordinary word likeresponse) injected#HASH#placeholders mid-payload. Obfuscation is now opt-in and fully typed: only user messages, tool-result messages, and user-attributed developer messages (@filementions) are redacted; system prompts and tool schemas pass through untouched; image bytes and signature/encrypted-reasoning fields are never rewritten; and tool-call arguments are the only JSON walked. Configured plain secrets and regex matches shorter than 8 characters are now ignored to stop false matches on short words. - Fixed RPC/ACP startup clobbering explicit caller/project/global configuration for
task.isolation.{mode,merge,commits},task.eager,task.batch,task.maxConcurrency,task.maxRecursionDepth,task.disabledAgents,task.agentModelOverrides,memory.backend,memories.enabled,advisor.{enabled,subagents,syncBacklog,immuneTurns}, plus the RPC-onlyasync.{enabled,maxJobs}andbash.autoBackground.{enabled,thresholdMs}.applyDefaultSettingOverridesre-asserted the schema default as a runtime override after settings load, regressing theisConfigured()guard added for #2598 and ignoring every explicit value the embedder, project,--configoverlay, or global config had set. The guard is restored, so the host default now only fills holes (#3207).
[16.1.11] - 2026-06-21
Added
- Added
tab.waitForSelectorfor more robust element-wait behavior - Added
tab.waitForNavigationto monitor and await page transitions
Changed
- Standardized public HTML exports to use the brand web palette instead of the local TUI theme
- Updated export logic to allow choosing between brand-web or local TUI color palettes
- Clamped browser tool timeouts to fail fast with named errors instead of opaque cell timeouts
- Added strict validation to block unsupported Playwright-only selector engines in browser tools
Fixed
- Fixed Codex image reads re-encoding to WebP and then failing the next request with an invalid
input_image.image_url; Codex-bound images now stay in PNG/JPEG-compatible formats. - Fixed prompt-template and file slash-command submissions rendering both the raw slash invocation and the expanded prompt in the interactive transcript. (#3199)
- Fixed the
/modelthinking picker labeling the OpenAI GPT-5.5 top effort asmaxinstead of the catalog-declaredxhigh(#3194). - Fixed session-title generation silently falling back to the online
smolmodel (and billing whatever provider held the resolved API key — OpenRouter in the reporter's case) when the user had explicitly configured a localproviders.tinyModel:generateSessionTitleraced local against online with a 10s timeout and fired the online request immediately whenever the local worker returnednull(unknown key, model not downloaded, transformers.js failure). Now an explicit local-model choice is honored end-to-end — on local failure the session is left untitled with alogger.warninstead of billing the smol fallback (#3187) - Fixed OpenCode MCP discovery so array commands are normalized into a stdio executable plus arguments,
environmentis accepted as the OpenCode env key, and argument lists are omitted when empty. (#3180) - Fixed plan mode leaving
writehidden undertools.discoveryMode: "all", which made the agent attempt to create the plan file viaeditand stall. Plan-mode entry now force-activateswritewhenever the registry built it, matching thewrite+editinstructions in the plan-mode prompt (#3165) - Fixed
editandpatchtool writes bypassing the ACP client's open buffer when Zed (or another ACP client) advertises thefs.writeTextFilecapability: all three write-mode tools (edit,patch,replace) now route through the client bridge when it is available, so the editor's TypeScript diagnostics panel updates immediately instead of requiring a workspace reload. - Fixed the agent dashboard new-agent description and the hook editor (default hook-style mode) treating Ctrl+Q as plain text on Windows Terminal, leaving Windows users unable to submit because the terminal cannot deliver a distinct Ctrl+Enter event. Both forms now submit on the shared
app.message.followUpchord (Ctrl+Q or Ctrl+Enter), matching the main prompt editor and any user remap ofapp.message.followUp(#2118). - Fixed
pi.sendMessage({ display: true })rendering the custom message twice when fired from asession_startextension handler (or any other non-streaming dispatch before the initial transcript render).ExtensionUiController.#applyCustomMessageDisplayrebuilt the chat from the freshly-persisted session entry, andmain.ts's subsequentrenderInitialMessages(undefined, { preserveExistingChat: true })then both re-rendered from session entries AND re-appended the preserved chat children — duplicating the message. The rebuild now waits untilrenderInitialMessageshas completed at least once (tracked viaInteractiveModeContext.initialChatRendered); after that, post-init extension sends still rebuild as before so messages fromtool_result/agent_end/ etc. surface immediately (#1955). - Fixed Git-mutating automation silently mis-handling pure Jujutsu workspaces (
.jj/repo/present, no colocated.git/).task/worktree.ts#getRepoRootpreviously threw a generic "Git repository not found" for isolated subagent setup, andautoresearch/git.ts#ensureAutoresearchBranchreturned a soft "Not in a git repository" warning that let/autoresearchproceed with no branch isolation or auto-commits. Both paths now detect a pure jj workspace via the newjj.isPureJjRepohelper and surface an actionable Jujutsu-specific error pointing atjj git init --colocate. Colocated jj-git (both.jj/and.git/at the same root) and plain Git checkouts behave exactly as before (#1935). - Fixed
autothinking mode being silently dropped when a session is resumed (--continue/--resume/in-app switch). The session log persisted only the resolved per-turn effort, not theautoselector, so resume froze the session at the last concrete level and never reclassified again. The log now records the configured selector (autovs concrete) alongside the resolved effort, so resumedautosessions stay in auto (shown as pending until the next turn reclassifies) and manual concrete pins still restore as concrete — including a pin whose level matches the effortautohad just resolved to. - Fixed transcript scrollback stability on terminals with eager erase risk so completed assistant messages remain stable while new streaming lines are rendering
- Fixed Hindsight retain (and the shared mnemopi/Hindsight recall paths) framing assistant turns whose only content was punctuation/whitespace — most commonly the lone
.some providers emit for tool-call-only or thinking-only turns — into[role: assistant]\n.\n[assistant:end]blocks that polluted the bank, wasted retain tokens, and degraded recall.prepareRetentionTranscript,extractMessages, andflattenMessagesForRecallnow require at least one letter or digit per message via a sharedhasSubstantiveContentpredicate (#1806). - Fixed
/resumerendering forked child sessions without a fork tag, making them indistinguishable from their parent when titles match (#1792).
[16.1.10] - 2026-06-21
Added
- Added
tab.ariaSnapshot(selector?)to the browser tool for Playwright-format ARIA-tree YAML - Added
tab.ref("e5")and support foraria-ref=e5selectors in alltabaction methods
Changed
- Made
writeandfindtools essential so they are always available initially (survivingtools.discoveryMode === "all"hiding) to ensure instructions to write/find files are immediately executable (#3165)
Fixed
- Fixed streamed tool-call previews freezing on their placeholder body (
$ …,Write: …, an empty args tree) even after the tool finished: the pending card was created while arguments streamed, but when the closing full-argumentsmessage_updatenever arrived (smooth-streaming disabled leaving the throttled arguments stale, an owned-dialect projector, or a superseded/aborted turn that still ran the call) nothing re-applied the final args.tool_execution_start— the one event every execution path emits with validated full arguments right before the result — now reconciles them onto the existing pending card and cancels any in-flight reveal so a late tick can't re-truncate the body.
[16.1.9] - 2026-06-21
Added
- Added LLM request JSON export functionality to
/dump
Changed
- Improved browser stealth by suppressing common automation flags and patching property descriptors
- Enhanced stealth for
WebGL,Worker,IFrame,Screen, andAudioAPIs to evade detection - Updated
toStringpatching to register native function sources for improved fingerprint protection
Fixed
- Fixed
omp listandomp removesilently starting an interactive agent session (forwarding the bare verb to the model as a prompt) instead of surfacing the realomp plugin list/omp plugin uninstall <name>commands (#2935) - Fixed lazy-initialized LSP servers (basedpyright/pyright, and likely gopls/rust-analyzer) hanging on the first request: the message reader matched incoming messages against pending client requests by id before checking for a
method, so a server-originatedworkspace/configurationpull whose id collided with an in-flight request was swallowed as a bogus response, leaving the pull unanswered and the server wedged. The reader now routes any message carrying amethodas a server request before id-matching (#3001) - Fixed
omp --approval-mode=yolo acpand other global option flags placed before a subcommand being rewritten tolaunchwith the subcommand swallowed as prompt text; the CLI resolver now skips leading global flags (using the launch parser's value-consumption contract) and dispatches the real subcommand with the flags applied, so ACP mode honors the configured approval policy. (#2970) - Fixed
/mcp enableand/mcp disablereconnecting unrelated MCP servers by scoping toggle reconnect/disconnect work to the named server. (#3157) - Stopped the local llama.cpp no-auth login placeholder from being sent as a discovery bearer token.
Removed
- Removed
/debug dump-next-requestcommand - Removed Wafer Pass from CLI credential help; Wafer Serverless remains available.
[16.1.8] - 2026-06-20
Added
- Added "Prose Only Thinking" setting to opt-out of rendering code blocks within AI thinking traces
- Replaced code blocks in AI thinking traces with an ellipsis when "Prose Only Thinking" is enabled
- Added a live tokens-per-second readout to the thinking pulse, counting only provider-reported tokens (no character estimate, which undercounts a summarized reasoning trace) and hiding itself whenever the rate is zero. Live numbers therefore appear only for providers that report usage mid-turn; otherwise the bare pulse keeps signalling that the model is thinking.
- Updated the thinking pulse to a faster starburst whose rotation eases across each cycle (instead of ticking at a fixed rate), with a speed badge that fades from gray to the theme accent as the rate climbs.
- Added live state previews for high-value built-in slash commands in TUI autocomplete.
- Added a copy affordance for completed
/btwanswers so users can copy the visible side-answer text before branching or dismissing the panel.
Changed
- Updated
SnapcompactInlineand SDK session context building to support asynchronous rendering - Changed side-channel turns (
/btw,/omfg, and IRC auto-replies) to forward the main turn's tool catalog to preserve the prompt-cache layout, while injecting a reminder to suppress tool usage and discarding any generated tool calls. - Changed
/btw,/tan,/omfg,/memory,/rename, and/moveto save the typed command text to TUI prompt history so they can be recalled with the up arrow. - Changed the temporary model picker to label Alt+P selections as session-only and point users to Alt+M or
/modelfor role model assignment. (#2952) - Replaced
new Promise((resolve, reject) => ...)inAsyncDrainwithPromise.withResolvers()per the repo's promise-construction convention - Changed the default advisor interrupt cooldown to 3 turns and the default auto-compaction strategy to snapcompact, with non-vision and over-budget snapcompact runs still falling back to context-full summaries.
Fixed
- Fixed a TypeError in
EventControllertests where a missingsettingsproperty in theInteractiveModeContextmock object led to calling.geton undefined when streaming tool-call args. - Fixed auto-compaction status text to label snapcompact runs instead of reporting them as context-full maintenance.
- Fixed side-channel turns failing to correctly obfuscate secrets and tools when inheriting prompt cache layout
- Fixed MCP startup status to live-update from "Connecting…" to connected, still-connecting, or failed server states so completed connections do not leave a stale banner. (#3150)
- Fixed session history becoming desynchronized when using the
rewindtool - Fixed
rewindtool output and temporary assistant side-channel data polluting the prompt cache - Fixed
readagainst a SQLite table with many columns (e.g. 33) rendering every cell as an ellipsis and chopping the right edge. The ASCII table shrinker bottomed out atMIN_COLUMN_WIDTH=1so every multi-char cell collapsed to…, and the final line truncation then cut off the right side. The renderer now bumps the per-column floor to 3 and falls back to a verticalcolumn: valueblock layout per row when the column count exceeds the horizontal width budget. (#3107) - Fixed
skill://,local://,memory://, andvault://directory paths so read lists them and search/find can walk their backing directories. (#3116) - Fixed local tiny-model inference failures respawning
__omp_worker_tiny_inferencefor the same failed model, and blocked the unsupported Qwen3 1.7B ONNX memory model before load. (#3132) - Fixed
/joinfailing withtimed out waiting for the host's welcomeon collab sessions whose existing transcript was more than a few MB. The host now sends a smallwelcomeframe (header + state + agents +entryCount) followed by a train ofsnapshot-chunkframes (SNAPSHOT_CHUNK_BYTES = 512 KB), and the guest accumulates them under a per-chunk progress timeout that resets on each chunk arrival. The first welcome lands well under one second on the default relay, so the guest's 30s first-welcome budget is no longer spent transferring the snapshot. Requires the newCOLLAB_PROTO = 2on both sides; older hosts/guests are rejected with the existing protocol-mismatch error. (#3144) - Stopped Mnemopi retention from overflowing the embedding model's context window:
embed()now caps each input atMNEMOPI_EMBEDDING_MAX_INPUT_CHARS(default 8192 chars) and clips with a head/tail split so a long multi-turnMnemopiSessionState.retainMessagestranscript can't make llama.cpp's/embeddingsserver reject the request withrequest (N tokens) exceeds the available context sizeand silently drop vector recall for that memory. The head/tail clip keeps both the opening setup and the most recent turns so later episodes don't collapse onto the same prefix vector (#3126). - Fixed
/goalcontinuation turns that end with a successfulyieldskipping threshold auto-compaction while the active goal remains overcompaction.thresholdTokens. (#3146) - Fixed first-turn memory recall invalidating append-only prompt caches by promoting injected memory into the stable session prompt before the next turn. (#3111)
/resumeandomp --resumeno longer auto-switch to the "all projects" picker when the current folder has no sessions. The picker now stays scoped to the cwd and surfaces the existing "No sessions in current folder. Press Tab to view all." hint, so users in an empty project never see other projects' session history without asking. (#3099)- Fixed
/todo exportand/todo importin ACP/text and TUI modes to resolve paths from the active session cwd, accept quoted paths with spaces, and report invalid path schemes without crashing. - Fixed the SDK
buildSystemPrompthelper to render caller-provided tools instead of falling back to the default prompt inventory, and to keep no-tools-map skills visible whenreadis available through the fallback. - Fixed Esc in focused subagent views cancelling active context maintenance (compaction, handoff, and retry operations); pressing Esc now returns to the main view instead, without aborting the maintenance. The active auto-compaction and auto-retry loaders also suppress their "(esc to cancel)" hint while focused to avoid displaying a false affordance. (#2819)
- Fixed
/omfgsaved-state copy to advertiseEsc dismissafter saving and registering the rule live. - Fixed legacy Pi extensions importing
getModel/getModelsfrom the@oh-my-pi/pi-aipackage root failing to load, by restoring them as compatibility aliases for@oh-my-pi/pi-catalog'sgetBundledModel/getBundledModels. The rootStringEnumcompatibility shim also accepts TypeScript enum objects in addition to value arrays (#2907). - Fixed the Alt+M model-configuration menu so role assignment remains selectable for models whose context window is smaller than the current session; the context-size disabling still applies to the Alt+P temporary active-model switch (#2861).
- Fixed the advisor raising false
blockers in plan mode (e.g. "don't write a plan file") because it only saw a 120-char truncation of the injected plan-mode rules, which cut off atNEVER create, edit, or delete files — excep…and hid the "except the single plan file" carve-out. The advisor delta now expands the primary agent's constraint context (plan-mode-context,plan-mode-reference) verbatim inside an XML-escaped<primary-context>wrapper instead of a one-liner, andAdvisorRuntimededupes the re-injected prompts so an unchanged copy collapses to a marker rather than re-feeding the full rules every turn. - Fixed auto-compaction being suppressed when a
before_provider_requestextension shrinks the outgoing request below the real stored conversation (e.g. a context-compression proxy such as Headroom, or an aggressive obfuscator). The provider then reports deflated prompt tokens, so the threshold check never fired and the stored history grew unbounded until it overflowed the context window and could no longer be compacted at all. The compaction decision (both the pre-prompt and post-response paths) now floors the provider-reported context tokens by the agent's own local estimate of the stored conversation, so on-wire compression can no longer hide a too-large history from the auto-compactor. Context display and cost accounting still use the exact provider usage; only the compaction trigger takes the floor. - Fixed mnemopi proactive linking being configurable only through the
MNEMOPI_PROACTIVE_LINKINGenvironment variable, unlike the siblingmnemopi.polyphonicRecall/mnemopi.enhancedRecallsettings: added amnemopi.proactiveLinkingconfig.yml setting (off by default,/settings→ Memory → Mnemopi) that ingests new memories into the episodic graph as they are stored, linking them to related entities and memories;MNEMOPI_PROACTIVE_LINKINGstill overrides the configured value when set (#2440).
[16.1.7] - 2026-06-20
Fixed
- Fixed custom
models.ymlproviders rejecting thecompat.supportsImageDetailOriginaloverride, so Responses-compatible proxies that reject snapcompact's native-resolution image hint can clamp frames todetail: "auto". (#3092)
[16.1.6] - 2026-06-20
Added
- Enabled inline prompts with
/loopcommands (e.g.,/loop 10 fix the bug) - Added support for compound duration formats in
/loop(e.g.,1h30m)
[16.1.5] - 2026-06-19
Changed
- Removed the legacy
AgentSession.nextToolChoice()method. The per-turn tool-choice directive now flows solely throughnextToolChoiceDirective()(which folds in the hard-choice dequeue plus active-tool filtering as a private helper), eliminating the dual entry point that let callers consume the queue while bypassing the soft pending-preview lifecycle. The underlyingToolChoiceQueue.nextToolChoice()is unchanged.
[16.1.4] - 2026-06-19
Fixed
- Fixed
omp benchandomp dry-balancefailing to resolve models from extension providers - Improved error reporting for
omp benchruns that return no output or tokens - Cache-miss marker no longer fires on a cold turn whose predecessor only wrote the prompt cache (never read it back). The session's opening request always writes the prefix with
cacheRead 0, so a long-running first tool call (e.g.gh run watch) that outlived the provider's cache TTL surfaced a spurious⊘ cache missdivider right under the opening message. The marker now requires the previous turn to have actually read a warm prefix, so it flags only a demonstrably working cache going cold — and collapses a run of consecutive cold turns to a single marker at the moment the cache broke. - Fixed
omp benchandomp dry-balancefailing to resolve models from extension-registered providers (pi.registerProvider(...)). Both commands build a one-shotModelRegistrythat previously only knew built-in catalog providers, so aprovider/modelselector for a provider contributed by an extension under~/.omp/agent/extensions/errored with "Model not found". A newloadCliExtensionProvidershelper loads the session's extensions, drains their provider registrations into the registry, and discovers dynamic provider catalogs before resolving selectors — mirroring the interactive session andomp modelspaths. omp benchnow reports a run that streamed no content and measured no output tokens as a failure ("provider returned no output") instead of a misleading green check withtokens 0 / TPS 0.0.- Cleared stale pending-preview gates when
resolvefinds no runnable handler, and forwarded the missingpeekPendingInvokerandclearPendingInvokershooks on the production session so staged previews actually reach the resolve tool and the gate drains on dispatch failure. (#3061) - Deferred status-line usage refreshes off the render path and timeboxed the startup fetch so slow Anthropic quota lookups no longer block interactive startup. (#3057)
- Fixed image paste placeholders falling through to terminal hyperlink settings before
Settings.init(), so early editor rendering falls back to plain text instead of crashing. (#3064) - Fixed
omp plugin install github:owner/reposilently keeping the user on a stale commit when re-run on an already-installed GitHub plugin.bun install <spec>respects the existingbun.lockpin when the spec is unchanged and never re-resolves the remote ref, so the manager now follows a git re-install withbun update <name>to refresh the lockfile pin against the upstream. The install transaction also snapshotsbun.lockup front and routes feature validation, extension validation, and runtime-config save through one rollback path so a failed install can never leave the rejected commit pinned in the active tree or lockfile. First-time installs are unaffected. (#3063)
[16.1.3] - 2026-06-19
Changed
- Refactored Perplexity authentication logic to prioritize cookies over OAuth in search operations
- Updated
tokencommand to correctly display active Perplexity OAuth tokens when present
Fixed
- Enabled auto-retry for AI "thinking loop" errors encountered during model inference
- Cleared stale error banners automatically when triggered by an auto-retry recovery phase
- Preserved bundled
omitMaxOutputTokenspolicy when fresh cached provider discovery rows replace Ollama Cloud catalog models, so stalemodels.dbentries cannot re-enable context-window-sizednum_predictvalues. (#2984) - Normalized cached-only Ollama Cloud discovery rows to omit on-the-wire output-token caps even when the cached model id has no bundled catalog entry. (#2984)
- Fixed Ollama, LM Studio, and llama.cpp (plus loopback vLLM / sglang servers) reprocessing the full prompt on every turn because
provider.appendOnlyContext: autoonly recognized DeepSeek and Xiaomi as prefix-cache providers. The auto-detect now enables append-only mode forollama,ollama-cloud,lm-studio,llama.cpp, and any baseUrl resolving to a loopback/RFC1918/.localhost, so the system prompt + tool catalogue + prior-turn message bytes stay byte-stable across turns and llama.cpp's KV-cache prefix reuse can hit (#3033). - Isolated mnemopi's local embedding provider in a dedicated
Bun.spawnsubprocess soonnxruntime-nodeandfastembednever load into the main agent process. Previouslymemory.backend: mnemopicrashed Bun on Windows — standalone binaries faulted in the NAPIprocess.dlopenconstructor at session start, npm installs faulted in the NAPI finalizer at process teardown. Mirrors the tiny-model isolation pattern from #1607; the parent SIGKILLs the child on dispose so the destructor never runs in either address space (#3031). - Fixed image tool registration resolving image provider credentials during session startup, so broken or slow
google-antigravityOAuth state no longer blocks sessions that never invokegenerate_image(#3036). - Fixed LSP client returning
-32601 Method not foundfor defined server→client requests (window/showMessageRequest,window/showDocument,workspace/{semanticTokens,inlayHint,codeLens,codeAction,diagnostic}/refresh). Servers that stall waiting for a real reply (same failure mode as #3029) now receive the spec no-op result (#3044). - Fixed WebP images being sent unchanged to
local-servervision models, which can fail through llama.cpp/STB-backed decoders that do not support WebP (#2922). - Made
getSettingsListTheme,getEditorTheme,getSelectListTheme, andgetSymbolThemereturn a plain ASCII fallback instead of crashing with "undefined is not an object (evaluating 'theme.fg')" when the globalthemeis undefined — e.g. when a plugin calls them beforeinitTheme()completes or from a separate module instance under npm-global installs. (#2998) - Hardened TTS, STT, and tiny-title worker IPC
send()paths against async EPIPE rejections:Subprocess.send()is now wrapped so neither a synchronous "process exited" throw nor an asynchronous EPIPE rejection (when the pipe breaks between exit being observed and the next send) can escape as a fatal unhandled rejection. A dying Kokoro/TTS/STT worker can no longer crash the whole agent session mid-task. (#2997) - Fixed Windows test failures caused by path handling: tests now use
pathToFileURL,path.resolve, andpath.joininstead of hard-coded POSIX paths;shortenPath()normalizes backslashes to forward slashes after~and respects home directory boundaries; shell-escaped interpolated paths in bash tool tests to prevent Git Bash eating backslashes - Fixed
HistoryStorage.resetInstance()leaking its SQLite database handle on Windows by adding a#close()method that finalizes all prepared statements and closes the database;AgentStoragegained the sameresetInstance()/#close()pattern - Fixed
createAgentSessionleaking the internally-createdAuthStoragewhen session construction fails before the session takes ownership, causing EBUSY on Windows temp dir cleanup - Fixed
MnemopiBackend.removeDbFiles()throwing on Windows when the database handle is still being released; it is now truly best-effort (logs failures instead of silently swallowing) - Fixed Windows EBUSY test failures by replacing raw
fs.rmSync/fs.rmcleanup withTempDir(which retries) and best-effort.catch(() => {})where SQLite handles outlive the test - Fixed
TempDirprefix convention: non-@prefixes created temp dirs relative to cwd instead ofos.tmpdir(), causing module resolution failures on Windows - Fixed git line-ending mismatches in autoresearch tests by setting
core.autocrlf falsein test repo initialization - Fixed Bedrock inference-profile ARN models being dropped from the allowed-model set when models were scoped via
enabledModels, the SDK, or ACP, so an accepted ARN no longer resolves to an empty selection. (#3006)
[16.1.2] - 2026-06-19
Added
- Added a welcome-screen tip for the
/advisorruntime. Tips ending in a[NEW]marker now render a bold rainbowNEW!tag (it shimmers across the welcome intro's animation frames, then settles into a still rainbow) and are weighted to surface more often in the random tip rotation.
Changed
- Renamed the search tool's
iparameter tocaseand inverted its semantics to represent case-sensitive search. - Improved session history to export empty objects as
{}instead of empty strings - Refined system prompt and tool documentation to improve conciseness and clarity
- Simplified tool input descriptions for browser, eval, find, and memory-edit operations
- Refactored authentication storage discovery to share logic with other pi-ai tools
Fixed
- Fixed
omp benchresolving an ambiguous model selector — a bare or canonical id shared by several providers (e.g.gpt-oss-20boropenai/gpt-oss-20b) — to a provider you have no credentials for. Bench resolves against the full catalog (credentials are ignored), so the default pick was decided by provider-priority order alone. It now redirects such selectors to an equivalent model under a provider with configured auth (honoringmodelProviderOrderand canonical cross-provider variants), while an explicitprovider/idselector is still benchmarked verbatim so forced/unauthenticated runs keep working. - Resuming a session whose project directory no longer exists (deleted or renamed worktree) no longer crashes with an unhandled
ENOENT … chdirrejection. The resume now keeps the current working directory instead of trying tochdirinto the missing path, across the in-session selector, the--resumestartup picker, andSessionManager.open/continueRecent. - Fixed streaming reflowing Markdown — a fenced mermaid diagram or a GFM table — stranding stale fragments in native scrollback once the reply scrolled past the viewport (cleared only by a full repaint / Ctrl+L). While streaming, the assistant block defaulted to commit-stable, so the transcript advertised its scrolled-off rows as durable snapshot content and the renderer committed an intermediate layout to immutable terminal history; the later re-layout (a diagram reshaping, a table re-aligning its columns) then froze that superseded fragment in scrollback. A still-streaming reply whose Markdown carries a mermaid fence or a table — detected outside fenced code blocks so ordinary code snippets are unaffected — is now commit-unstable, so it stays wholly in the repaintable live region and commits once, at its final layout, when the turn finalizes.
- Fixed
SYSTEM.mdprompt customization going through the raw system prompt override path, which dropped sections rendered bycustom-system-prompt.mdsuch as skills and rules (#3014).
[16.1.1] - 2026-06-19
Changed
- Migrated legacy macOS power settings to a single sleep prevention enum
- Defaulted
display.cacheMissMarkersetting tofalseto suppress the cache-miss marker by default. - Replaced the four separate
power.preventIdleSleep,power.preventSystemSleep,power.declareUserActive, andpower.preventDisplaySleepboolean settings with a single cumulativepower.sleepPreventionenum (off→idle→display→system). Each level adds the caffeinate flags of all lower levels. Existing configs are migrated automatically.
Fixed
- Cache-miss marker no longer fires on providers with implicit, best-effort prompt caching (Google/Gemini, OpenAI, Fireworks). Those report
cacheWrite: 0and dropcacheReadto zero intermittently as routine propagation noise that self-heals the next turn. Only explicit, prefix-controlled caches (Anthropic/Bedrockcache_control), which re-create the prefix on a cold turn ascacheWrite > 0, now surface a marker — where a zerocacheReadgenuinely means the prefix broke. - Fixed advisor dependent settings staying visible while
advisor.enabledis off (#3027). - Fixed LSP servers that dynamically register capabilities, including Expert, hanging semantic requests after
client/registerCapabilitywas rejected (#3029).
[16.1.0] - 2026-06-19
Added
- Added a prompt-cache miss marker: a slim
⊘ cache miss · <n> tokensdivider above an assistant turn whose request lost the provider prompt cache. Detected from per-turn usage — the previous turn cached a meaningful prefix but this request read none of it back and reprocessed the prompt (e.g. after a thinking-level / service-tier / model change, tool or system-prompt change, or a history rewrite). Reports the reprocessed token count. Toggle with thedisplay.cacheMissMarkersetting (Appearance → Display, on by default).
Changed
- Optimized preview workflows by removing forced tool choices, reducing prompt cache invalidations
- Unified injected message styling with consistent rounded outlines and icon-tagged headers
- Refreshed branch summary messages with a uniform banner style to match compaction points
- Updated skill invocation UI with a compact header, home-shortened paths, and dynamic line counts
- Refined session context to utilize history blocks instead of raw images for snapcompact summaries
- Refreshed the skill-prompt transcript message to match the rest of the TUI: an icon-tagged
✦ skill <name>header (with invocation args trailing), a single meta line with a home-shortened, click-to-open path in the accent color and the prompt size in muted, and a rounded outline around the card. Replaces the old[skill]label with the flatSkill:/Path:/Prompt:key/value dump (which also leaked the absolute home directory). - Refreshed the default custom/hook transcript message frame to a rounded, icon-tagged card: the
[customType]bracket label is replaced by an<icon> <type>header (📦 for extension messages, 🪝 for legacy hook-role messages) with a subtle outline, matching the skill card. Covers every extension/hook custom type without a bespoke renderer. - Refreshed the branch-summary transcript message to render as the same slim divider banner as
/compact, handoff, and snapcompact (⑂ branch · ctrl+o, summary revealed on expand) instead of a[branch]box. - Optimized network traffic by stripping tool descriptions from provider tool schemas
- Renamed the prompt setting from
repeatToolDescriptions/ "Repeat Tool Descriptions" toinlineToolDescriptors/ "Inline Tool Descriptors" and enabled inline descriptors by default. - Snapcompact compaction summaries now reach the model as ordered history blocks instead of one lead-in text block plus appended images: plain text at the oldest edge, an imaged middle, then plain text at the newest edge. This matches the new text-first snapcompact archive layout and preserves chronological order in the provider prompt.
- Fixed
/dumpoutput repeating the tool inventory twice wheninlineToolDescriptorsis enabled. - Unified TUI border corners on the rounded style: tool-result frames, overlays, code fences, debug frames, and the interactive bash box now draw rounded corners (
╭╮╰╯) to match the editor and message cards, instead of mixing rounded boxes with sharp (┌┐└┘) ones.boxRoundnow carries the sharp tee/cross junction glyphs (no rounded variant exists), so dividers still honorboxSharp.tee*/crosstheme overrides. Markdown tables intentionally keep the fully sharpboxSharpset; its corner tokens now affect tables only.
[16.0.11] - 2026-06-19
Added
- Added
__advisor.jsonltranscript persistence for advisor model usage attribution and visibility in the Agent Hub - Added defensive reservation against naming a task
__advisorto prevent filesystem collisions with internal transcripts - Added
modeproperty to theCompactOptionsinterface for extension-based compaction control - Updated
/compactslash command to supportsoft,remote, andsnapcompactsubcommands for per-run strategy overrides - Added
/compactmode subcommands so a manual compaction can override the configuredcompaction.strategy/remoteEnabledfor that one run:/compact soft(summarize locally, skip remote endpoints),/compact remote(summarize via the remote endpoint / provider-native compaction; warns and falls back to a local summary when no remote path is available), and/compact snapcompact(archive history onto dense bitmap images, no LLM call). Bare/compactand/compact <focus text>keep their existing behavior;soft/remotestill accept trailing focus instructions,snapcompactrejects them. The subcommands are advertised to ACP clients and surface in TUI autocomplete. Extensions can pass the same selection viacompact(instructions, { mode }). - The advisor now persists its own turns to a subagent-style transcript (
<session>/__advisor.jsonl) so the advisor model's usage is attributed inomp statsand its transcript is observable in the Agent Hub (read-only). The transcript follows session switches (/new, resume, branch) and is drained/released before a/dropdeletes the old artifacts dir. The advisor remains a non-peer: it is hidden from agent-facing rosters (irclist,history://, subagent peer prompt, broadcast targets), is not messageable (irc send/ collab chat), and is not revivable/killable from the Hub or collab.
Changed
- Standardized file elision markers to a compact
[…Nln elided…]format - Updated transcript viewer to clear cached content if the session file is deleted while opened
- Refactored agent hub to use a fullscreen overlay for agent transcripts instead of inline chat
- Improved transcript rendering stability by using a non-incremental builder for viewer replays
- Advisor transcripts are now excluded from agent-facing surfaces like
irc,history://, and peer rosters - Advisor transcripts are read-only and cannot be messaged, revived, or killed via the Agent Hub or IRC
- Refined
/compactargument parsing to reject focus instructions for modes that do not support them (e.g.,snapcompact) - Protocol hosts (RPC/
rpc-ui/ACP) now host-default the full advisor settings group —advisor.syncBacklogandadvisor.immuneTurnsin addition toadvisor.enabled/advisor.subagents— so a host that opts the advisor in gets the default tuning instead of inheriting the user's local advisor preferences.
Fixed
- Fixed memory-leaking stale transcripts in the agent viewer when underlying files are deleted
- Fixed the Agent Hub transcript viewer rendering the transcript body one column right of the "Agent Hub" title (and the title appearing to shift when scrolled to the top): the fullscreen viewer added its own outer gutter on top of the transcript rows, which already carry a 1-column left pad, so the header and body no longer shared a gutter. The viewer now renders the scroll body at full width without the extra gutter, and the file-mention row carries the same 1-column pad as every other row.
- Fixed the bash tool failing with
pi-natives:command: syntax error at end of inputon a valid&&/;chain whose later pipeline stage is a compound command, e.g.echo x && git log | while read h; do …; done | head. The minimizer's segmented-chain runner rebuilds each chain segment from the brush AST viapipeline.to_string()and re-executes that string, butsimple_segmentonly validated the first pipeline stage — so a compound later stage (while/for/if/subshell) was re-serialized without its terminator and re-run as broken shell. Every stage is now required to be a Display-safe simple command, and — as a general guard against the recurring class of brushDisplayround-trip divergences (previously: quoted here-doc close tags, multi-byte char/byte offsets) — each reconstructed segment is now re-parsed and must match the original pipeline shape before the chain runner executes it; any divergence runs the command whole, unsegmented, instead of corrupting it. - Fixed
Ctrl+T(toggle thinking blocks) and the/settings"Hide Thinking Blocks" toggle only collapsing/expanding thinking in the live region: blocks that had scrolled into committed native scrollback on ED3-risk terminals kept their pre-toggle snapshot, so scrolling up showed the old thinking state. Both paths nowresetDisplay()after flipping each block's flag, forcing a full clear + replay of the whole transcript (matching the tool-output expansion toggle) so every block above the fold re-renders at its new height. - Fixed ACP mobile voice settings being unable to call
speech.models.listby exposing the local STT/TTS model and voice catalog without triggering setup or downloads (#3011). - Fixed the collapsed inline arg preview used by tools without a custom renderer (e.g.
advise, MCP tools) truncating every value at a fixed 24 columns, so a long note was cut tonote="Your “stric…"even on a wide card with empty space to spare. Each value now grows into the width the card actually has, reserving only a small slice for the keys that still follow so a long leading value can't hide them.
Removed
- Removed
display.tabWidthsetting and configurable tab width support
[16.0.10] - 2026-06-18
Added
- Updated the
pioption of thetools.formatsetting to use the new compact sigil-delimited owned tool-calling dialect (§/«…»/¤/‡‡) that uses ~46% fewer tokens than the legacy format on typical calls. - Integrated terminal QR codes directly into
/collaband/collab viewto display both deep links and scannable codes, and added acollab.webUrlsetting for separately hosted collab web clients.
Changed
- Updated description of Pi dialect in tool-calling settings to clarify compact sigil format
Fixed
- Fixed legacy
settings.json,models.json, andkeybindings.jsonmigration/loading to accept comments in JSON config files. - Support quoted file paths with spaces (such as default macOS screenshots) in file mentions and
@-prefixed CLI arguments (#2909). - Fixed the first steering/follow-up message typed as auto-compaction begins being dropped instead of queued; the compaction abort controller (which backs
isCompacting) is now installed before theauto_compaction_startevent fires, so input routed during that window lands in the compaction queue rather than the core agent queue. - Fixed queued steering/follow-up messages being silently cleared by the agent reset during a handoff; they are now captured and restored across the new-session reset.
- Fixed the
/loginprovider list still offering providers listed indisabledProviders(and their credential-alias logins, e.g.openai-codex-device→openai-codex) as login targets (#2906). - Fixed an owned MCP manager not being disconnected on
AgentSession.dispose(), orphaning stdio MCP subprocesses across session teardown (/exit, print mode, subagent teardown); the dispose-time disconnect is now bounded so a slow HTTP/SSE transport close cannot stall exit (#2839). - Fixed
inspect_imageresolving pasted image labels such asImage #1,[Image #1, WxH], andattachment://1against current chat attachments instead of falling back to<cwd>/Image #1(#2787). - Accepted
maxas an alias for the top thinking level (xhigh) in selectors and--thinking, so DeepSeek V4 Pro can be selected with its provider-facing maximum effort (#2727). - Fixed
--provider=amazon-bedrock --model <application-inference-profile ARN>being rejected as an unknown model before the Bedrock provider could send the ARN to Converse Stream. (#3004)
[16.0.9] - 2026-06-18
Added
- Added a
--print-thoughtsflag for single-shot print mode that includes sanitized thinking blocks in the text output; default print output stays the final answer only. When thinking is hidden by thehideThinkingBlocksetting,--print-thoughtsun-hides it for the print run so the flag is not a silent no-op (an explicit--hide-thinkingstill wins).
Fixed
- Fixed active
/goalmode being paused by internal compaction and session-switch lifecycle aborts, and made those switches persist wall-clock goal usage without charging time spent in another session to a preserved goal.
[16.0.8] - 2026-06-18
Changed
- Optimized app startup time by lazily loading site-specific scraper modules
- Refactored internal archive handling into a unified
src/utils/zip.tsmodule - Centralized all
fflate(ZIP) andBun.Archive(tar/tar.gz) operations intozip.ts - Optimized archive reading by using lazy, ranged central-directory access for ZIP files
- Updated internal image processing to no longer include metadata text for fetched images
- Optimized
omp://documentation indexing by compressing doc bodies into a lazily-inflated blob - Changed Mermaid fenced-block ASCII rendering to use the first-party vendored renderer in
@oh-my-pi/pi-utils(src/vendor/mermaid-ascii), dropping thebeautiful-mermaidnpm package, its transitiveelkjs(~3.13MB), and thebeautiful-mermaidbun patch; CJK/emoji width handling and the layout-direction override are preserved. - Changed
omp://documentation embedding to a gzipped base64 index (docs-index.generated.txt, populated at build time and reset afterward) inflated on first read, instead of a ~1.6MB raw TypeScript map. The compiled binary / npm bundle drops ~0.9MB; the dev tree and source checkouts readdocs/from disk. - Replaced the
markit-aipackage with a vendored in-house document engine (src/markit) for the document formats it converts: PDF (viamupdf), DOCX (viamammoth), and PPTX/XLSX/EPUB (viafast-xml-parser). Conversion output is preserved, including the PDF column/table-detection pipeline and HTML-table normalization;markit-ai's unused converters and their dependency tail are gone. Legacy.doc/.ppt/.xls/.rtfremain unsupported (a conversion error), as before. - Centralized ZIP handling behind a single
src/utils/zip.ts(fflate): the new document converters, thewritetool's in-place archive editing, and thereadtool's ranged archive reader now share one ZIP implementation instead of mixingjszipandfflate.
Fixed
- Fixed settings overlay crash when scrolling past the last row in list views
- Improved tool result formatting by correctly wrapping
<out>blocks in dim-ink toggles - Fixed auto-retry after transient model-stream socket closes to replay text/thinking-only partial assistant output, including turns where incomplete tool-call arguments were dropped; completed tool calls still block retry to avoid duplicating tool execution.
- Fixed
omp updatereportingEPERM: operation not permitted, unlink '<binary>.bak'on Windows when self-replacing a standalone binary, even though the new binary had already been installed. The backed-up old executable is still the running process image and cannot be unlinked until the process exits, so the post-verify backup cleanup is now best-effort, backups use a unique per-attempt name, and stale backups are swept on the next update (#845). - Fixed plan-mode
Refine planso the internal approval abort is hidden and the editor is ready for a follow-up prompt instead of showingOperation aborted(#2971). - Fixed TUI prompts beginning with shell-style variables such as
$HOMEbeing misrouted to Python eval; Python shortcuts now require$ <code>or$$ <code>. (#2944) - Fixed LM Studio runtime discovery to use native
/api/v0/modelsmetadata soinspect_imagecan select VLM models. (#2945) - Fixed
ompcrashing at startup withCannot find module './browser-data/browser-data.js'(e.g. on Termux/proot Linux arm64).tools/browser/attach.tsvalue-imported theTargetTypeenum frompuppeteer-core, which dragged the puppeteer-core barrel (and its@puppeteer/browsersChromium downloader) back onto the eager startup import graph — defeating the lazy-load deferral and turning any bundling quirk in that subtree into a fatal boot crash instead of a recoverable browser-tool error. The import is nowimport typeand the target check compares against the"page"literal, so puppeteer only loads on first browser use. - Fixed the standalone compiled binary aborting at startup with
error: Cannot find package 'mupdf'. The vendored document engine keptmupdfexternal, but a single-filebun --compilebinary has nonode_modulesto resolve it from, and the bundler resolves the otherwise-lazy import eagerly at boot.mupdf(and its WASM module, embedded at build time viascripts/embed-mupdf-wasm.ts) is now bundled into the binary, so startup and PDF/document conversion both work in the standalone binary; npm and source installs still loadmupdffromnode_modules.mupdfis also imported lazily inside the PDF converter now, which fixes a compiled-bundle init-order hazard —mupdf's top-level await made the bundled markit chunk's module init async, exposing the converters before their extension tables initialized — and keeps the ~10MB WASM off non-PDF document conversions.
Removed
- Removed the
markit-ai,exifr,music-metadata, and directjszipdependencies. As a side effect, fetching an image or audio URL no longer appends EXIF/audio metadata text; image inlining and resizing are unchanged, and document conversion (PDF/DOCX/PPTX/XLSX/EPUB) is unaffected.
[16.0.7] - 2026-06-18
Fixed
- Fixed
/modelin the TUI to open the model setup picker again, leaving/switchas the temporary session model switcher (#2933). - Fixed OpenCode Go sessions recording per-request cost history so
/usagecan show local cap utilization. (#2942)
[16.0.6] - 2026-06-18
Added
- Added
model.loopGuard.enabled(defaulttrue) andmodel.loopGuard.checkAssistantContent(defaulttrue) settings to configure thinking and assistant prose loop detection. - Added explicit ArkType schema descriptions to parameters across all agent tools to improve model tool-calling instructions and parameter guidance
- Added support for OpenRouter fallback in Perplexity web search when direct Perplexity API keys fail or are unavailable
- Added support for streaming the Perplexity Responses API (
/v1/responses) via thePI_PERPLEXITY_RESPONSES=1environment variable - Added
omp ttsrtop-level CLI command to inspect and test Time-Traveling Stream Rules - Added
omp ttsr listto enumerate all project/user-loaded TTSR rules with their conditions, scope, and source metadata - Added
omp ttsr testto run snippets through the real TTSR matching pipeline with inline text,--file <path>, or stdin via--file - - Added
--jsonoutput toomp ttsr testandomp ttsr listfor machine-readable reporting - Added
--rule,--source,--tool,--path, and--verboseoptions toomp ttsr testto control matching context and inspection details - Added
omp ttsrsubcommand for inspecting and testing Time-Traveling Stream Rules:omp ttsr listshows every TTSR-registered rule the current project/user config would load, andomp ttsr testfeeds a snippet (inline,--file, or stdin) through the real TTSR matching pipeline (TtsrManager.checkSnapshot/checkAstSnapshot) and reports which rules would trigger. A positional that resolves to a file defaults to tool/edit context;--source,--tool, and--pathoverride the inferred match context so glob/AST/scope-scoped rules evaluate the same way they do in a live session.--ruletests a single rule markdown file in isolation. - Added support for reading embedded PDF images via
read <pdf>:<image>.pngand listing available image members withread <pdf>: - Added a built-in
ts-no-inline-cast-accessTTSR rule that interrupts inline object-type assertions read immediately as a property ((x as { y: T }).y, including?.and bracket access), steering toward schema validation,in/typeofnarrowing, or a validated named type - Added
startup.showSplash(defaultfalse) to show the full setup splash animation on normal interactive startup whilestartup.quietstill suppresses startup chrome. (#2880) - Added
app.retryas anAlt+Rkeybinding for retrying the last failed or aborted assistant turn (#2790). - Added
b branchpromotion for completed/btwanswers, creating a branch that preserves the side-question input and full assistant response including thinking blocks.
Changed
- Enabled caching by default in the codebase search tool to improve search performance
- Replaced internal schema validation and
@sinclair/typeboxpolyfills across all agent tools and configurations from Zod to ArkType - Changed advisor model calls and overflow-compaction tasks to inherit and propagate primary telemetry spans, usage, and cost tracking
- Changed PDF read output to replace
<!-- image: ... -->placeholders with clickableread <pdf>:<image>.pnghandles, including line-range and multi-range reads - Changed the built-in
ts-no-anyrule to recommend a schema parse at trust boundaries andin-narrowing (instead of an inlineas-cast) when reading fields offunknown
Fixed
- Fixed legacy plugin validation for extensions that import
defineTool,StringEnum, frontmatter helpers,SettingsManager,createCodingTools, or the baretypeboxpackage through the hosted Pi compatibility shims (#2858). - Fixed edit seen-line guard mismatch assertion message formatting to report the actual state instead of generic failure notices
- Fixed hashline edit mode rendering in the TUI when
setIgnoreTighttriggers synchronous display rebuilds in the constructor before#editModeis assigned, which previously caused the tool envelope target path to display as…instead of the parsed hashline filename. - Fixed
omp ttsr scanto discover files with gitignore-aware native globbing, skip binary/oversized files before text decoding, use a scan-specific matcher, keep default output summary-only, and avoid retaining per-file AST snapshots during scans - Fixed Perplexity web search to use shared OpenAI streaming transports while preserving streamed sources, citations, and related questions
- Fixed
StatusLineComponentfire-and-forget async callbacks (#isDefaultBranch,#lookupPr,fs.watch) firing#onBranchChangeafterdispose(), which reached the globalsettingsproxy after tests calledresetSettingsForTest()and threw "Settings not initialized" between test files;dispose()now sets a disposed flag, clears#onBranchChange, and every post-await continuation checks the flag before touching settings or the callback - Fixed
read <pdf>:<member>errors for unknown PDF images to surface available extracted image names - Fixed puppeteer stealth scripts to use cached Reflect methods (
Reflect_get,Reflect_apply) andReflect.applyinstead of liveReflect/Function.prototype.applycalls, preventing page tampering from leaking through proxy traps. - Fixed Perplexity API-key web search to use shared OpenAI streaming transports while preserving streamed sources and OpenRouter fallback.
- Fixed subagents reporting success after a provider-error turn by preserving real run failures over earlier successful
yieldpayloads, and retried bare OpenAI-compatiblefinish_reason: "error"provider failures after partial text instead of stopping immediately - Fixed MCP servers that do not implement
resources/templates/list(JSON-RPC -32601) discarding their concrete resources; templates now fall back to an empty list (#2838 by @jms830) - Fixed provider setup sign-in URLs to attempt clipboard/OSC 52 copy and expose an Alt+C retry shortcut, so authentication is not blocked when TUI selection is unavailable (#2908).
- Fixed ACP approval-mode documentation to describe config inheritance,
omp acp --yolo/--auto-approveruntime overrides, client permission precedence, and headless prompt behavior (#2900). - Fixed
/guided-goalto fall back to the current session model when neither theplannorslowrole resolves, instead of aborting during setup (#2855). - Fixed auto context-full maintenance to stop retrying the same summarization timeout before falling back to the next compaction model (#2913).
- Fixed
/plan <prompt>and/goal <objective>to preserve the typed slash-command line in TUI input history when entering those modes from off (#2887). - Fixed
/modelin the TUI to open the active-session model switcher instead of the role-assignment picker (#2846). - Fixed Perplexity web search collapsing every upstream failure to a generic
401 No authentication method availableonce all auth methods failed: the fallback loop now rethrows the last classified provider error (402/credits-exhausted,429,5xx), so quota and rate-limit failures are no longer mis-reported as authorization errors. The generic 401 is now only a defensive fallback for the no-method-ran case.
Security
- Secured PDF image reads by validating requested image members against the extracted member list before opening files and refusing traversal-style names
[16.0.5] - 2026-06-17
Added
- Added
tui.tightsetting (defaultfalse) to enable tight layout by removing the 1-character horizontal padding from terminal output. - Added a
providers.antigravityEndpointsetting (auto,production,sandbox) to control google-antigravity routing for chat, search, image, and discovery calls - Added automatic endpoint-mode support for google-antigravity provider calls so users can force production-only or sandbox-only usage
- Added
images.describeForTextModelsoption (defaulttrue) to control automatic image description for attachments sent to models without vision input - Added automatic vision fallback prompts to describe images for text-only models
- Added
advisor.immuneTurnssetting (default1) to limit how often advisorconcern/blockernotes can interrupt the primary agent. - Added a main-session
session_stopextension event with continuation feedback and an 8-continuation loop cap (#2834). - Added
--max-time <seconds>so CLI sessions can stop after a wall-clock deadline.
Changed
- Changed google-antigravity usage report lookups to honor the selected antigravity endpoint mode when resolving the reporting base URL
- Changed context usage reporting to always return numeric token counts and percentages, so status-line and footer now show estimated values instead of
?immediately after compaction - Changed context usage reporting to use anchored snapshots and pending-prompts estimates, which now keeps
/context, status line, and model selector token counts in sync
Fixed
- Fixed Matplotlib figure display to emit PNG output immediately when
display(fig)is called, even if the figure is closed before the end-of-cell flush - Fixed persisted tool-result image payloads in
details.imagesto externalize and resolve through the session blob store, so generated-image details survive resume without stale blob refs or truncation - Fixed duplicate Matplotlib image output by skipping the automatic end-of-request figure flush for figures that were already displayed through
display(fig) - Fixed google-antigravity image generation and web search requests to fail over to the alternate antigravity endpoint on 429/server/network failures instead of stopping at the first endpoint
- Fixed context usage breakdown to use a completed assistant usage anchor from the current turn instead of a pending prompt snapshot so totals no longer overcount when a large in-turn tool step returns usage
- Fixed side-channel turns and advisor requests to keep using credential resolvers during retries, so Google
Resource exhausted429s can rotate to the next account instead of surfacing a terminal error banner - Fixed context token accounting to keep branch-local anchors during branching so sibling-branch messages no longer pollute context estimates
- Fixed context usage consistency so
/context, status line, and idle compaction logic now report the same used-token totals - Fixed status-line context cache invalidation when assistant reasoning signature data grows so displayed context usage updates accurately
- Fixed the status-line context% reading inflated during long tool turns and then dropping sharply on the next message even though no compaction ran. While a request was in flight
getContextBreakdownsummed a cl100k estimate of the entire tail on top of the stale turn-start prompt and never re-anchored to completed in-turn steps; it now prefers the real provider prompt-token count of any step that resolves at or after the pending cutoff. The status-line memo also keys on acontextUsageRevisionthat bumps when the in-flight snapshot is set/cleared, so a mid-turn estimate is invalidated on turn end/abort instead of surviving into idle until the next message - Fixed image attachment handling for text-only models by saving attachments to
local://and injecting generated descriptions so they are no longer lost when the target model cannot process images - Fixed the ssh tool rejecting valid Windows identity files before invoking OpenSSH by skipping Unix mode-bit key validation on native Windows (#2850).
- Fixed
web_search/omp qaborting before any provider ran when the global Settings singleton was not initialized;executeSearchnow readsproviders.antigravityEndpointonce and tolerates an uninitialized settings store instead of throwing - Fixed the new
git.enabledandimages.describeForTextModelssettings declaring section groups (Git,Vision) that were not registered inTAB_GROUPS, so they now render in their intended settings-panel sections - Fixed Python
display(fig)for Matplotlib figures to emit PNG output immediately, even when user code closes the figure before the end-of-cell flush. - Fixed persisted tool-result image payloads stored in
details.imagesto externalize and resolve through the session blob store, so generated-image details survive resume without stale blob refs or truncation. - Fixed the
tools.formatsetting schema sominimaxcan be selected as an owned tool-calling dialect, and taught auto mode to route tool-less MiniMax-family models to the MiniMax owned dialect. (#2759) - Fixed WSL2 TUI stutter by adding a
git.enabledsetting and skipping footer/status-line git probes when disabled or when no git-backed status segment is visible (#2847). - Fixed JSON-mode startup notices (export/resume/session-picker messages) writing to stdout before the JSON event stream; they now route to stderr so stdout remains newline-delimited JSON.
[16.0.4] - 2026-06-17
Fixed
- Fixed RPC/ACP startup forcing todo settings back to host defaults, so project-level
todo.enabled,todo.reminders, andtodo.eageropt-outs now suppress protocol-mode todo prompt injection; enabled todo reminders are now persisted to the JSONL transcript so the log matches the model-visible context (#2824). - Fixed default prompts to instruct the agent to read applicable
skill://<name>content before starting work, so discovered skills influence broad task requests like frontend generation (#2829). - Fixed hashline visible-line validation for ACP editor reads so
INS.POSTanchors displayed by bridge-backed range and multi-rangereadoutput are merged into the session snapshot beforeeditvalidates them (#2773).
[16.0.3] - 2026-06-16
Added
- Added support for LaTeX color commands (
\textcolor,\colorbox, and\fcolorbox) in user-visible terminal prose and final chat to colorize output
Changed
- Changed STT dependency setup to validate recorder and model assets per
stt.modelName, so switching speech models re-runs dependency checks and downloads for the new model - Changed STT startup with cached models to warm the speech model in the background and defer full model loading until transcription begins, reducing push-to-talk start latency
- Allowed user-visible terminal and final-chat responses to include LaTeX math delimiters/commands and Mermaid
```mermaiddiagrams - Changed the hold-
Spacepush-to-talk gesture to recognize a held bar from the regularity of the OS key auto-repeat rather than a raw space count or speed alone, so it no longer spams the editor, no longer eats deliberate space taps, and no longer triggers when the bar is smashed. Recording starts only after two consecutive inter-space deltas are "mechanical" — both fast (within ~120 ms) and near-identical, the metronomic signature of auto-repeat; the few pre-burst spaces typed are then tracked back out. Smashing (fast but jittery) and deliberate spacing (steady but slow) both keep typing real spaces and never start recording. - Updated markdown Mermaid rendering to color ASCII diagrams with the active theme and automatically choose a narrower layout that better fits the terminal width
- Made the watched-session transcript sent to the advisor (and shown by
/advisor dump) clearer: each turn now opens with a### Session updateheading; watched-agent roles render as inline**agent**:/**user**:labels instead of level-2 headings that collided with the advisor's own turns; consecutive same-role messages collapse under one label (the watched agent emits one assistant message per tool call); and batched updates are joined by a blank line rather than a---rule. - Changed the compact transcript tool-intent prefix (
history://,/advisor dump) from#to//so intent lines read as comments instead of rendering as Markdown H1 headings. - Changed the advisor advice injected into the primary transcript from a
Advisor (...): - [severity] noteprose block to one<advisory severity="…" guidance="weigh, don't blindly obey">…</advisory>element per note, with XML-escaped bodies. (Relocated the sharedescapeXmlTexthelper to@oh-my-pi/pi-utils.) - Reverted
/dumpand/advisor dump rawto the pre-16.x full verbose dump: system prompt, model/thinking config, tool inventory with parameters, and the message transcript rendered with markdown role headings (## User,## Assistant,### Tool Call: <name>with the call's_iintent as a//comment under the heading and the remaining arguments as a fenced YAML block,### Tool Result: <name>, plus## Bash Execution/## File Mention/summary sections) instead of the model's native-dialect turn envelopes and<invoke>/<parameter>XML tool calls. Dropped the compact default and the[raw]flag on/dump; the compact→ tool(...) ⇒ okhistory format is no longer reachable from/dump./advisor dumpstill defaults to compact, and/advisor dump rawnow renders the same markdown dump (previously the model's native-dialect envelopes).
Fixed
- Fixed Whisper STT cache detection to require both encoder and decoder
.onnxfiles, so partial model downloads now trigger a proper foreground download instead of being treated as fully cached - Fixed same-process
JsRuntimecleanup so disposing an older inline/direct runtime no longer deletes a newer runtime's JS helper globals; inactive cmux/direct runtimes now re-activate their globals before sequential use while overlapping cross-runtime runs fail explicitly. - Fixed magic-keyword steering notices (
ultrathink-notice,orchestrate-notice,workflow-notice) to be prepended before the related user message so they influence that same turn - Fixed dequeuing or popping queued user messages to remove their preceding hidden magic-keyword notice companions, preventing orphaned queued notices
- Fixed queued user steers to auto-resume after interrupts even when the transcript tail is a preserved advisor card or other non-conversational custom message
- Fixed queued user follow-up messages to remain queued after an interrupt and only run on explicit resume, even when an IRC wake leaves a provider-valid tail
- Fixed stranded IRC asides to wake a response turn after interruption instead of remaining pending
- Fixed accepted IRC asides to be flushed into the transcript during disposal instead of being discarded
- Fixed interactive submissions made while the TUI had no active input waiter: they now start a real prompt directly, with steer fallback if a background turn races in, instead of queueing behind a non-resumable idle transcript and appearing to do nothing.
- Fixed pressing Esc (or Alt+Up dequeue) while agent-authored messages were queued — advisor concern/blocker notes, hidden goal/plan/budget steers, IRC/extension asides — dumping their text into the user's editor. Editor restoration (
clearQueue()), pending chips (getQueuedMessages()), andpopLastQueuedMessage()now surface only genuinely user-authored queued messages (plain user turns andattribution: "user"custom messages like/skill). Plain Alt+Up dequeue leaves all other queued messages in place for the continuing stream; only the Esc interrupt path keeps just advisor cards (so abort's preservation still re-records them as visible advice) and drops other internal steers, so a user interrupt can't be silently undone by an auto-resume on leftover internal context.queuedMessageCountstill reflects all actual queued work (advisor cards included) sohasPendingMessages()/RPC and the empty-submit abort gate stay accurate. - Fixed advisor
concern/blockeradvice being withheld from the running agent and then dumped as one burst at the next user prompt after a deliberate interrupt. A user interrupt latches advisor auto-resume suppression, but a non-user resume (synthetic/auto-continue, or a queued steer draining after the abort) leaves the run streaming with that latch still set, so every interrupting note was parked hidden in the next-turn queue instead of steered into the live turn — the agent never heard the advisor mid-run and the backlog flushed all at once on the next prompt. Suppression now only withholds interrupting advice while the agent is idle (or still tearing the interrupted turn down); once a turn is streaming again the note is steered in live, since steering an active run never auto-resumes a stopped one. A concern that strands in the steer queue past the resumed turn's final poll is reclaimed as visible advice when the agent settles (mirroring abort), so it neither auto-resumes the stopped run nor lingers to flush at the next prompt. - Fixed
omp --continue/-csometimes resuming into a subagent transcript instead of the interactive session. Subagent (and HTML-export)SessionManager.open()calls run in the parent's terminal and were clobbering the per-TTY--continuebreadcrumb with their own artifact-dir session file; these headless opens now suppress the breadcrumb.continueRecent()also recovers already-poisoned breadcrumbs by resolving any session file inside a parent's artifacts dir (<parent>/<agentId>.jsonl) back up to the top-level session. - Fixed the Agent Hub stacking duplicate
Agent Hub · N runningframes and stranding garbage rows in scrollback while navigating with subagents still streaming. The hub was a non-fullscreen overlay composited over a live transcript, so each time a running subagent's progress grew the frame and scrolled the window the previously-painted hub copy was pushed permanently into the terminal's native scrollback (which the engine can't rewrite). It now renders inline in the editor slot — the same anchored region every other selector and theasktool use — riding the normal append-only commit path, so the transcript commits above it exactly once and the hub repaints in place instead of leaking copies. (Avoids borrowing the alternate screen.) - Fixed every subagent registering itself as its own parent in the agent registry (
parentId === id), so the Agent Hub rendered each agent assub · of <itself>and the ←← parent-navigation gesture looped on the same agent. The SDK was reusingparentTaskPrefix— the agent's own artifact/output-id prefix — as the registry parent link; spawns now pass a separateparentAgentId(the spawning agent's id:Mainfor top-leveltaskspawns, the parent subagent for nested spawns and evalagent(), the focused agent for/tan) and the registry records that as the parent. - Fixed messaging a
parkedsubagent that was restored from disk (Agent Hub scan, or a resumed/restarted session) failing withcannot be revived (no reviver registered)even though its transcript was intact. Such refs carry a session file but no in-memory reviver — the executor's live reviver closure dies with the spawning turn/process — so IRC sends and Agent Hub focus refused them.AgentLifecycleManager.ensureLivenow cold-revives them through a persisted-subagent reviver factory (installed by the top-level interactive/RPC session) that rebuilds the subagent from its JSONL the way--resumerebuilds a session: it reopens the file and replays it throughcreateAgentSession, but sources the runtime contract from a now-readablesession_initrecord (SessionManager.peekSessionInit) so tools, system prompt, output schema, and kind are restored rather than resurrected as a default top-level session.session_initnow also persists the effectivespawnsallowlist and read-summarization flag so a cold revive keeps the original capability surface (old files without them deny re-spawning rather than defaulting to wildcard). Isolated runs and pre-session_initfiles whose recorded workspace no longer exists stay transcript-only (history://). - Fixed the terminal window-title OSC writes (
setTerminalTitle/pushTerminalTitle/popTerminalTitle) leaking escape sequences to a developer's terminal duringbun test; they now skip when the terminal is headless (the test-runtime default), matching theProcessTerminalrender/probe suppression so interactive-mode tests no longer paint to the real terminal - Fixed empty CLI sessions being retained after opening
ompand exiting without a prompt (#2800). - Fixed
hooks/pre/*.tsandhooks/post/*.tsfiles discovered throughhookCapabilitybeing registered in discovery but never loaded into the extension runner, so theirtool_callhandlers now run without a manualsettings.jsonextensionsentry (#2796). - Fixed startup model fallback choosing the plain OpenAI
gpt-5.5provider before the Codex OAuth provider when both shared the same default model id, which could surface a misleading OpenAI 401 despite valid Codex credentials (#2807). - Fixed local auto-thinking classification for reasoning-capable tiny models by giving them the same safe answer budget as online reasoning classifiers, with a larger local floor for non-reasoning tiny models (#2808).
Removed
- Removed the built-in
render_mermaidtool and itsrenderMermaid.enabledsetting, so it can no longer be invoked directly
[16.0.2] - 2026-06-16
Added
- Added the
UMANS_WEBSEARCH_PROVIDERenvironment variable to CLI help for Umans gateway web search backend selection.
Changed
- The eager
task(task.eager: always) and eagertodo(todo.eager: preferred/always) hidden reminders now re-fire on the auto-continuation turn after a compaction (context-full / snapcompact / handoff / shake). Compaction summarizes away the first-message prelude, so the agent would otherwise silently lose the delegate-via-tasks / phased-todo guidance mid-work; the post-compaction todo nudge is reminder-only and never forces thetodotool onto the resumed turn.
Fixed
- Fixed edit-tool block operations on Emacs Lisp files:
.eland.emacspaths now resolve top-level forms forSWAP.BLK,DEL.BLK, andINS.BLK.POSTinstead of reporting an unsupported-language block-resolution error. - Fixed PDF reads leaking recoverable MuPDF WASM warnings into the terminal TUI by routing MuPDF output through the file logger before
markit-ailoads it (#2766). - Fixed
/exitand/quitwaiting one shutdown timeout per hanging extension by runningsession_shutdownhandlers within a shared shutdown window (#2736). - Fixed GitHub Copilot
.github/instructions/*.instructions.mddiscovery by loading those files as rules that honorapplyToscoping, including always-apply**files andrule://<name>access for glob-scoped entries (#2731). - Fixed Windows bash-tool child processes defaulting interpreter pipe I/O to the ANSI codepage by adding UTF-8 encoding defaults when the inherited environment is unset (#2701).
- Fixed
/advisor dump rawso Opus 4.5 thinking content that already includes literal<thinking>tags is not rendered with nested thinking tags (#2700). - The
plugin-extensions-discoverytest suite no longer writes fixtures into — andrm -rfs thenode_modulesof — the developer's real~/.omp/plugins. ItsXDG_DATA_HOMEisolation was a no-op on Windows (XDG is gated to Linux/macOS) and was bypassed in XDG-migrated Linux/macOS environments, so a local run could delete installed plugins. The suite now isolates the whole config root via anos.homedir()mock plus clearedXDG_*vars, with a pre-write guard that fails if resolution escapes the temp home (#2721). - Installed plugins whose
extensionsmanifest entry points at a directory of sub-extensions (the standard piextensions/<name>/index.tslayout, e.g.pi.extensions: ["./extensions"]) are no longer rejected at install (declared extension entry not found on disk) or silently dropped at load. The plugin manifest resolver now resolves a directory the same way as the configured-directory (-e) extension loader: the directory's ownpackage.jsonomp/piextensions(authoritative — a missing declared entry is reported instead of falling back to a decoyindex), then a directindex.{ts,js,mjs,cjs}, then a one-level scan of sub-extensions (#2713). - Fixed OpenRouter
@upstreamrouting selectors whose upstream slug also appears in the model id, soopenrouter/...@deepseek:highkeepsopenRouterRouting.onlyinstead of being consumed by provider-scoped fuzzy matching (#2708). - Fixed
omp plugin list --jsonomitting locally linked plugins that exist only inomp-plugins.lock.jsonandnode_modulessymlinks. (#2742) - Fixed task subagents to install their configured ordered model candidates as child-session retry fallback chains, so retryable provider failures can advance to the next subagent model instead of failing the worker (#2750).
- Fixed empty reasonless aborted assistant turns to auto-retry without switching model fallback, so transient provider-side aborts after tool results do not end headless sessions (#2685).
[16.0.1] - 2026-06-15
Breaking Changes
- Settings:
hooksandcustomToolsarrays replaced with singleextensionsarray - CLI:
--hookand--toolflags replaced with--extension/-e - Directories:
hooks/,tools/→extensions/;commands/→prompts/ - Types: See type renames above
- SDK: See SDK migration above
- Key detection functions removed from
@mariozechner/pi-tui: AllisXxx()key detection functions (isEnter(),isEscape(),isCtrlC(), etc.) have been removed. UsematchesKey(data, keyId)instead (e.g.,matchesKey(data, "enter"),matchesKey(data, "ctrl+c")). This affects hooks and custom tools that usectx.ui.custom()with keyboard input handling. (#405)
Added
- Added GitHub Copilot user-global discovery to the
githubprovider: it now loads user-global instructions from~/.copilot/copilot-instructions.md, honors theCOPILOT_HOMErelocation override, reads each directory listed inCOPILOT_CUSTOM_INSTRUCTIONS_DIRSfor anAGENTS.mdand.github/instructions/**/*.instructions.md(matching Copilot CLI), scans the project.github/instructions/tree recursively, and surfaces VS Code Copilot prompt files (*.prompt.md) from.github/prompts/as slash commands. Previously only the project.github/tree was scanned, so Copilot CLI users' cross-repo config was silently ignored. Closes #1913, #1915, #1916. - Added web search provider exclusions so
web_searchcan skip configured providers without disabling them for model use (#2608). - Added an optional
rolefield totaskspawns that gives each subagent a tailored specialist identity: the role is injected as a system-prompt specialization preamble and becomes the subagent's display name and telemetry identity in the registry, IRC roster, and Agent Hub, so delegated trees are no longer clones of one generic worker (#2467) - Added a non-blocking specialization advisory to the
tasktool: when a spawner with remaining depth capacity spawns generic role-less workers (atask/quick_taskspawn without arole, or the same agent cloned ≥2× all without roles), the result steers it toward tailored specialists. Gated so a leaf at max recursion depth is never nudged; the task-tool depth gate is extracted into a sharedcanSpawnAtDepthhelper (#2469) - Added a work-aware IRC roster:
irc listand the subagent peer roster now show each peer's current activity (a short gist of its latest intent/tool) alongside its role-derived display name, so a tree of tailored specialists is legible enough to coordinate. Backed by a new display-onlyactivityfield on the agent registry (#2470) - Added proactive IRC coordination: when one
taskcall spawns ≥2 live siblings with spawn capacity remaining, the result suggests coordinating overlapping work viairc(composed onto the specialization advisory), and the subagent COOP/ircprompts now actively steer discovery (list), coordination (message before overlapping edits), and follow-up (replyTo/await) instead of only assuming agents resolve collisions on their own (#2471) - Added
/reviewsupport for explicit GitHub pull request URLs and detected PR URLs from recent conversation context (#1743). - Added a
plan.defaultOnStartupsetting (Tasks tab, default off) that automatically enters plan mode at the start of a new interactive session. It applies to any session that opens with no prior history — including a--continue/auto-resume that finds no recent session and starts fresh — while sessions with restored history keep the mode reconciled from that history. It is a silent no-op when plan mode is globally disabled (plan.enabled), and the setting is hidden from the settings UI unless plan mode is enabled. - Added
UMANS_AI_CODING_PLAN_API_KEYto the CLI environment help (#2636 by @oldschoola). - Added
WebSearchProviderErrorclass with HTTP status for actionable provider error messages $ARGUMENTSsyntax for custom slash commands as alternative to$@for all arguments joined. Aligns with patterns used by Claude, Codex, and OpenCode. Both syntaxes remain fully supported. (#418 by @skuridin)- Configurable double-escape action: choose whether double-escape with empty editor opens
/tree(default) or/branch. Configure via/settingsordoubleEscapeActionin settings.json (#404) - Vertex AI provider (
google-vertex): access Gemini models via Google Cloud Vertex AI using Application Default Credentials (#300 by @default-anton) - Built-in provider overrides in
models.json: override justbaseUrlto route a built-in provider through a proxy while keeping all its models, or definemodelsto fully replace the provider (#406 by @yevhen) - Automatic image resizing: images larger than 2000x2000 are resized for better model compatibility. Original dimensions are injected into the prompt. Controlled via
/settingsorimages.autoResizein settings.json. (#402 by @mitsuhiko) - Alt+Enter keybind to queue follow-up messages while agent is streaming
ThemeandThemeColortypes now exported for hooks usingctx.ui.custom()- Terminal window title now displays "pi - dirname" to identify which project session you're in (#407 by @kaofelix)
- Hook API:
ctx.ui.setTitle(title)allows hooks to set the terminal window/tab title (#446 by @aliou) - Hook API:
before_agent_starthandlers can now returnsystemPromptAppendto dynamically append text to the system prompt for that turn. Multiple hooks' appends are concatenated. - Hook API:
before_agent_starthandlers can now return multiple messages (all are injected, not just the first) - New example hook:
tools.ts- Interactive/toolscommand to enable/disable tools with session persistence - New example hook:
pirate.ts- DemonstratessystemPromptAppendto make the agent speak like a pirate - Tool registry now contains all built-in tools (read, bash, edit, write, grep, find, ls) even when
--toolslimits the initially active set. Hooks can enable any tool from the registry viapi.setActiveTools(). - System prompt now automatically rebuilds when tools change via
setActiveTools(), updating tool descriptions and guidelines to match the new tool set - Hook errors now display full stack traces for easier debugging
- Clipboard image paste support via
Ctrl+V. Images are saved to a temp file and attached to the message. Works on macOS, Windows, and Linux (X11). (#419) - Configurable keybindings via
~/.pi/agent/keybindings.json. All keyboard shortcuts (editor navigation, deletion, app actions like model cycling, etc.) can now be customized. Supports multiple bindings per action. (#405 by @hjanuschka) /quitand/exitslash commands to gracefully exit the application. Unlike double Ctrl+C, these properly await hook and custom tool cleanup handlers before exiting. (#426 by @ben-vargas)
Changed
- Enriched the bundled
designer,reviewer, andtaskagent prompts:designergains a token-first four-phase design-system workflow (analyze → build-if-missing → compose-with-tokens → verify),reviewergains an evidence standard (a finding is not real until you can name the triggering input; passing tests are not proof of correctness), andtaskgains an evidence-bound completion requirement. - Updated the session-continuation tip to mention Zellij and WezTerm panes.
- Documented the
roletask parameter in the task-tool description (both the batch and single-spawn shapes) and made tailored specialists the default delegation guidance, so the model gives each spawn a specialist identity instead of cloning generic workers (#2468) - Changed the
evalagent()helper to acceptreturn_handle(Python) /returnHandle(JS): instead of bare text it returns a DAG node dict{ text, output, handle, id, agent }whosehandleis the spawned agent's recoverableagent://<id>URI, so a downstreampipeline/parallelstage can wire a large transcript by reference instead of re-inlining it. The default path is unchanged (bare text, or the parsed object underschema). - Changed
isAutoresearchShCommand()to use proper command-line argument parsing instead of regex, improving accuracy for complex shell invocations - Changed autoresearch initialization prompt to display collected tradeoff metrics in the setup summary
- Changed
command-initialize.mdtemplate to include guidance on preflight requirements, comparability invariants, and marking measurement-critical files as off-limits - Changed
command-initialize.mdto instruct users to write or updateautoresearch.program.mdwith durable heuristics and repo-specific strategy - Changed autoresearch resume guidance to emphasize continuing on the current protected branch rather than switching branches
- Changed autoresearch prompt to clarify that
autoresearch.mdholds durable conclusions whileautoresearch.ideas.mdis the scratch backlog - Changed autoresearch prompt guidance to require stable measurement harness and fixed benchmark inputs unless intentionally starting a new segment
- Changed autoresearch prompt to recommend keeping equal or near-equal results when they materially simplify implementation
- Changed
init_experimentto reset pending run state (checks, duration, ASI, artifact directory) when initializing a new segment - Changed
log_experimentto setautoResumeArmedflag after successfully logging a run to enable auto-resume on next agent turn - Changed
run_experimentto setautoResumeArmedflag and update dashboard after completing a run - Changed auto-resume logic to only prompt when a new pending run exists or when
autoResumeArmedis explicitly set, preventing duplicate prompts - Changed path normalization in contract validation to use
path.posix.normalize()for consistent path handling - Extended extension
registerProvider()typing with OAuth provider support and source-aware registration metadata. - Slash commands and hook commands now work during streaming: Previously, using a slash command or hook command while the agent was streaming would crash with "Agent is already processing". Now:
- Hook commands execute immediately (they manage their own LLM interaction via
pi.sendMessage()) - File-based slash commands are expanded and queued via steer/followUp
steer()andfollowUp()now expand file-based slash commands and error on hook commands (hook commands cannot be queued)prompt()accepts newstreamingBehavioroption ("steer"or"followUp") to specify queueing behavior during streaming- RPC
promptcommand now accepts optionalstreamingBehaviorfield (#420)
- Hook commands execute immediately (they manage their own LLM interaction via
- Editor component now uses word wrapping instead of character-level wrapping for better readability (#382 by @nickseelert)
- Extensions can have their own
package.jsonwith dependencies (resolved via jiti) - Documentation:
docs/hooks.mdanddocs/custom-tools.mdmerged intodocs/extensions.md - Examples:
examples/hooks/andexamples/custom-tools/merged intoexamples/extensions/ - README: Extensions section expanded with custom tools, commands, events, state persistence, shortcuts, flags, and UI examples
- SDK:
customToolsoption now acceptsToolDefinition[]directly (simplified fromArray<{ path?, tool }>) - SDK:
extensionsoption acceptsExtensionFactory[]for inline extensions - SDK:
additionalExtensionPathsreplaces bothadditionalHookPathsandadditionalCustomToolPaths - Removed image placeholders after copy & paste, replaced with inserting image file paths directly. (#442 by @mitsuhiko)
Fixed
- Fixed the advisor auto-resuming a run after the user deliberately interrupts it (Esc, or a cancel from collab/ACP/RPC/SDK/extension). A user interrupt now suppresses advisor
concern/blockerauto-resume until the user next resumes (a typed message,./ccontinue, or a steer/follow-up); the concern is still recorded as a visible, persisted advisor card — including one already steered into the run or arriving mid-abort — so it re-enters context on resume instead of being discarded. Natural yields are unchanged: the advisor can still steer and resume a stalled run. - Fixed
/advisor on|offnot being session-local by overriding the setting instead of modifying global configuration, and fixed changes not updating the TUI status line immediately. - Fixed
plan.defaultOnStartupsetting schema configuration missing the requiredui.groupproperty. - Fixed
web_searchusing stale or missing provider exclusions after/moveor resuming a session from another project. Provider preferences (providers.webSearchExclude,providers.webSearch,providers.image) are now reapplied when project settings reload on cwd change (#2611). - Fixed isolated task subagents with persisted transcripts resolving file tools against the parent repository instead of the isolated worktree, which made
rcopypatch capture report no changes after tool-based edits. - Fixed plugin config writes against older
omp-plugins.lock.jsonfiles that did not have a top-levelsettingsobject, which crashedomp plugin config setbefore persisting the option (#2236). - Fixed auto-retry regenerating a large
writecall after the provider stream timed out mid-tool-call (#2683). - Fixed soft-expired
issue://andpr://reads to refresh live before returning stale state, with an explicit stale warning when the live refresh fails (#2684). - Fixed Claude marketplace plugin skills appearing as bare slash commands while keeping real plugin
commands/entries available (#2645). - Fixed boundary duplication warnings to always display when replacement lines match the next surviving line, even when auto-correction is disabled
- Fixed secondary metrics validation to properly reject missing configured metrics and new metrics without force flag
- Fixed ASI data cloning to prevent prototype pollution attacks by filtering reserved property names
- Fixed CLI
--api-keyhandling for deferred model resolution by applying runtime API key overrides after extension model selection. - Fixed extension provider registration cleanup to remove stale source-scoped custom API/OAuth providers across extension reloads.
--list-modelsno longer shows Google Vertex AI models without explicit authentication configured- JPEG/GIF/WebP images not displaying in terminals using Kitty graphics protocol (Kitty, Ghostty, WezTerm). The protocol requires PNG format, so non-PNG images are now converted before display.
- Version check URL typo preventing update notifications from working (#423 by @skuridin)
- Large images exceeding Anthropic's 5MB limit now retry with progressive quality/size reduction (#424 by @mitsuhiko)
- Slash command argument substitution now processes positional arguments (
$1,$2, etc.) before all-arguments ($@,$ARGUMENTS) to prevent recursive substitution when argument values contain dollar-digit patterns like$100. (#418 by @skuridin) - Edit tool diff not displaying in TUI due to race condition between async preview computation and tool execution
/modelselector now opens instantly instead of waiting for OAuth token refresh. Token refresh is deferred until a model is actually used.- Shift+Space, Shift+Backspace, and Shift+Delete now work correctly in Kitty-protocol terminals (Kitty, WezTerm, etc.) instead of being silently ignored (#411 by @nathyong)
AgentSession.prompt()now throws if called while the agent is already streaming, preventing race conditions. Usesteer()orfollowUp()to queue messages during streaming.- Ctrl+C now works like Escape in selector components, so mashing Ctrl+C will eventually close the program (#400 by @mitsuhiko)
- External editor (Ctrl-G) now shows full pasted content instead of
[paste #N ...]placeholders (#444 by @aliou) - Subagent example README referenced incorrect filename
subagent.tsinstead ofindex.ts(#427 by @Whamp)
[16.0.0] - 2026-06-15
Breaking Changes
- Renamed the SDK tool format type and resolver from
ToolCallFormat/resolveToolCallSyntaxtoDialectFormat/resolveDialect, and the agent option fromtoolCallSyntaxtodialect. - Changed
/dumptranscript output to render messages with the selected model's native dialect turn and thinking envelopes instead of markdown role headings.
Added
- Added
advisor.syncBacklogsetting (off,1,3,5) to pause turn completion until advisor review backlog drops below the threshold, with a maximum 30-second wait - Added advisor backlog synchronization at turn end when enabled so the main session stays aligned with the advisor's pending review turns
- Added automatic discovery of WATCHDOG.md files from user and project locations so advisor guidance from local watchdog instructions is appended to its system prompt
- Added
/advisor on,/advisor off,/advisor status, and/advisor dump [raw]slash-command subcommands to manage the advisor at runtime - Added
advisor.enabledandadvisor.subagentssettings to enable the advisor and extend it to spawned task/eval subagents - Added advisor status badge (
++in success color) to the status line when an advisor is active - Added
/dump [raw]flag to toggle between compact and legacy uncompact transcript output formats - Added
/advisor on,/advisor off, and/advisor statusslash-command subcommands to enable or disable the advisor at runtime and view advisor status metrics - Added a passive advisor: assign a second model to the
advisorrole and enableadvisor.enabledto have it silently review each primary turn and inject severity-tagged advice notes via theadvisetool. Anitrides the non-interrupting aside queue (batched into one card at the next step boundary), while aconcernorblockerinterrupts the running agent through the steering channel — aborting in-flight tools, or resuming the agent when it has already yielded — so high-severity advice is acted on immediately. Advice renders in the primary transcript as a distinctAdvisorcard, and the advisor gets hard-isolated read-onlyread/search/findaccess — bound to its ownToolSessionso its reads never touch the primary's snapshot/seen-lines caches — to investigate the workspace before weighing in. The status line shows a++badge (in the success color, kept distinct from the model name) after the model name while an advisor is active, and/advisor dumpcopies the advisor's own transcript to the clipboard. Advisors are created only for the top-level session by default; enableadvisor.subagentsto extend them to spawned task/eval subagents. - Animated "thinking" pulse (
·‥…‥) shown in place of a hidden thinking block while the model is actively reasoning, so streaming progress is visible even withhideThinkingBlockenabled.
Changed
- Changed advisor prompting guidance to emit at most one
adviseper update and to prefer silence when the agent is on track - Changed
/dumpdefault output to compact markdown format; use/dump rawfor the legacy uncompact format - Changed
/dumpand/advisor dumpto default to compact transcript output and accept an optionalrawflag for the legacy uncompact format - Session dump output now renders message history using the model's native dialect turn envelope instead of markdown role headings
- Changed RPC, RPC-UI, and ACP hosts to default the advisor settings off instead of inheriting a user's interactive-session advisor preference.
Fixed
- Fixed advisor backlog tracking so failed advice prompts do not stall catch-up indefinitely by dropping pending backlog after repeated consecutive failures
- Fixed backlog accounting to decrement only after successful advisor prompts so sync waits correctly reflect advisor progress
- Fixed advisor context batching to still send pending review updates when context maintenance fails instead of dropping the batch
- Fixed explicit advisor enablement to clear protocol-default overrides so enabling the advisor applies immediately
- Fixed advisor message card notes getting truncated to two lines when the card is collapsed.
- Fixed advisor context handling to maintain its token budget by promoting or compacting/restarting advisor context while preserving advisor reasoning-off settings.
- Fixed
startup.quietleaving MCP and LSP startup status events visible during launch (#2639). - Registered the
Advisorgroup in themodelsettings tab so advisor settings render correctly in the settings panel. - Fixed Windows bash path handling so MSYS/Git-Bash drive aliases like
/d/projectand WSL-style/mnt/d/projectnormalize to native drive paths consistently across the bash tool cwd validation and brush filesystem builtins (#2634).
[15.13.3] - 2026-06-15
Added
- Unexpected stop detection: optional tiny/smol classifier that continues the turn when the assistant says it will act but emits no tool calls.
- Settings
features.unexpectedStopDetectionandproviders.unexpectedStopModel.
Changed
- Changed the
jobpoll to return early when a steering message is queued, draining the steer immediately instead of waiting out the poll window. - Capped unexpected-stop auto-continuation to three retry attempts before giving up on repeated stops
- Updated the
edittool's hashline prompt, grammar, and docs to recommend the.=inclusive range separator (SWAP 1.=3:); the legacy..form still parses. - Normalized all internal worker argv selectors under the
__omp_worker_prefix, skipping the async worker dispatch check during normal CLI startup.
Fixed
- Filtered out whitespace-only and dot-only (
.or…) assistant blocks so they are treated as empty and no longer appear as visible content in message rendering, streaming reveal counts, or session export output - Filtered placeholder-only thinking content from ACP notifications and message visibility checks so dot-only
reasoning_contentno longer triggers turn completion or read/run updates - Fixed ModelRegistry tests making outbound network calls by automatically stubbing fetch during test execution.
- Fixed
evalJS cells (and browser-tab worker startup) always stalling for the full init timeout — typically the cell's whole 30s budget — before silently falling back to the slower inline worker. The self-dispatching CLI host imports the worker module dynamically from its argv dispatch, so the worker's ownparentPort.on("message")attached only after Bun flushed the messages the parent posted before spawn; the synchronously-postedinithandshake was dropped and never answered withready. The host now installs a bufferingparentPortinbox synchronously in the entry's sync prefix (before importing the worker module) and the worker binds it on load, replaying the buffered handshake.omp --smoke-testnow also spawns the JS eval worker through the host entry and asserts it handshakes on a real worker thread. - Fixed pre-prompt context-full compaction on OpenAI Responses sessions to use provider-anchored context usage when available, so large encrypted reasoning signatures no longer trigger automatic maintenance while the visible context percentage remains below threshold (#2628).
[15.13.2] - 2026-06-15
Added
- Added tool examples data to exported RPC session tool metadata, so tool dumps and other clients can receive model-call examples
- Added
supportsToolsto model definitions and overrides so custom model configs can declare whether a model supports native tool calls - Added
tools.formatfor choosing native tool calling or a specific owned in-band format (glm,hermes,kimi,xml), withautofalling back to GLM only for models marked as not supporting native tools. - Added a conditional easter-egg tip recommending nerd fonts when using the unicode symbol preset.
- Added the
tools.abortOnFabricatedResultsetting (default on): with in-band tool calls, stop the model the moment it starts hallucinating a tool result mid-turn, or disable it to let the model finish and discard the fabricated continuation instead.
Changed
- Changed
/dumptool catalog output to render tools through the shared inventory renderer with readable TypeScript-style signatures and native-syntax<examples>blocks - Changed todo tool result rendering so that collapsed phases truncate from the beginning, showing the latest/active tasks and displaying the "more todos" summary at the top.
- Expanded
tools.formatto support additional in-band tool-call syntaxes, includinganthropic,deepseek,harmony,pi, andqwen3 - Changed the 13 tools that documented hand-written
<examples>blocks (eval,browser,todo,irc,ssh,ast_edit,ast_grep,debug,find,inspect_image,ask, plus thepatch/apply_patchedit modes) to define examples as typedexamplesdata on the tool (ToolExample<z.input<typeof schema>>); the AI layer now renders them in the model's native tool-call syntax and the markdown<examples>blocks were removed. - Changed the experimental owned tool-calling prompt from a GLM-only toggle to syntax-specific grammar prompts and result formats.
PI_OWNED_TOOLS=1still forces GLM;PI_OWNED_TOOLS=<syntax>forces that syntax. - Changed the large-paste menu to offer attachment XML blocks (
<attachment>), local-file attachments, or inline paste as explicit actions. - Changed the system-prompt tool inventory: moved the
# Inventoryblock to the bottom of the TOOLS section, and it now renders a compact tool-name list only when native tool calling is active and tool descriptions are not repeated; otherwise it emits full# Tool: <name>sections.
Fixed
- Fixed Auto-Promote Context being pre-empted by compaction: the pre-prompt context check ran compaction directly, so snapcompact (or any strategy) fired before promotion ever got a chance. It now tries promotion to a larger-context model first — mirroring the post-turn threshold path — and only compacts when no larger-context target is available. Snapcompact (auto and manual) also falls back to a context-full LLM summary when its frame archive plus kept history would still overflow the model's usable window, instead of leaving the session over the limit.
- Fixed
evalJS cells intermittently failing after ~15s with exit code 1 under load (e.g.bun test --parallel, where each file runs in a worker subprocess and the eval worker is nested). The host swallowed asynchronous worker spawn/load/crash failures —new Workerreports module-load errors via an asyncerrorevent, not a synchronous throw, so the spawntry/catch(and its inline-worker fallback) never fired, and noerror/messageerrorlistener was wired — leaving a dead worker indistinguishable from a slow one and blocking the full worker-init timeout. The init handshake now rejects immediately on a workererror/messageerrorevent and falls back to the inline worker, and thereadylistener is attached synchronously afternew Worker(Bun does not buffer messages posted before a listener exists) so a fast worker'sreadycan no longer be dropped.
[15.13.1] - 2026-06-15
Added
- Added isolated profile support via
--profile <name>/OMP_PROFILEand shell alias bootstrap via--alias <command>, including launch/ACP bootstrap handling, extension-flag-safe parsing, profile-scoped user config discovery, and symlinked extension-directory discovery. - Fixed paste and image placeholders crashing when the editor renders before theme initialization.
Changed
- Replaced the
omp benchdefault prompt with a concrete query-planning trace that requires deriving selectivities, cardinalities, and I/O/CPU costs from given schema and data. The old prompt was open-ended prose recall, which rewarded not-thinking: adaptive-thinking models (Opus 4.6+/Sonnet 4.6+) minimized reasoning on the trivial task and streamed faster, skewing throughput comparisons. The new task forces multi-step reasoning so adaptive thinking engages and the benchmark measures generation under real cognitive load. The prompt also demands explicit upfront deliberation and exhaustive enumeration/costing of every join order, so adaptive-thinking models cannot short-circuit to a quick answer and each model is measured over a sustained generation up to the token cap.
Fixed
- Fixed hashline edits from
read,search, andast-grepso replacements are rejected when they target lines not shown in the tool output - Fixed
/tanrefusing to launch while the main response was still streaming. The command exists to fork tangential work alongside an active session, so it now dispatches mid-stream and queues its handoff breadcrumb for the next turn instead of steering the in-flight one. - Fixed
/tanbackground agents never staying in the Agent Hub. The forked clone now uses an<agentId>.jsonlsession file (so the persisted-subagent scan keys it by the same id the live ref uses) and is parked rather than unregistered on completion, so it stays listed and its transcript stays readable. - Fixed the
/tandispatch breadcrumb rendering its full raw<system-notice>block in the transcript. It now shows a single compact line (Tangent dispatched [task] <jobId> — <work>), styled as a sibling of the "Background job completed" line. - Fixed profile bootstrap parsing so built-in string flags like
--planno longer consume the profile-boundary marker and drop the trailing user message - Fixed a bug where goal mode was incorrectly deactivated/set to 'none' on every wall-clock-only update (when tokenDelta <= 0) during tool execution flushes, preventing OMP from writing a mode change to 'none' in the session history database while keeping in-memory/UI state fresh.
- Fixed a bug where Gemini MALFORMED_FUNCTION_CALL tool-generation errors (which are transient) surfaced as terminal error blocks. Added "malformed function call" to the transient transport error classifier so the session automatically retries the turn.
- Fixed Ctrl+C teardown waiting up to 30s when an extension's
session_shutdownhandler hung — observed on Windows withomp-discord-presence0.1.2 stuck on a stale Discord IPC pipe.ExtensionRunner.emitpreviously shared the generic 30sEXTENSION_HANDLER_TIMEOUT_MSbudget for every event, including the fire-and-forget teardown event extensions cannot observe.session_shutdownnow uses a dedicated 2sSESSION_SHUTDOWN_HANDLER_TIMEOUT_MScap routed through a per-eventhandlerTimeoutForEvent()lookup, so a hung third-party handler can no longer hold dispose hostage. As a defence-in-depth ladder, a Ctrl+C arriving while interactive shutdown is already running now hard-exits with code 130 (the session JSONL has already been sync-flushed by the first press), surfaced via a new read-onlyInteractiveModeContext.isShuttingDown(#2600). - Fixed the external editor flow (Ctrl+G, plan editor,
/todo edit) warningNo editor configuredon Windows even when the user expected the system's native editor.getEditorCommand()now falls back tonotepadonwin32after consulting$VISUAL/$EDITOR(and trims those values so accidental whitespace is ignored), so Windows users get a working editor out of the box while POSIX still warns to nudge configuration (#2604). - Fixed Kokoro TTS setup loading the workspace/global
@huggingface/transformersruntime before the side-installed Kokoro runtime, which could leaveonnxruntime-node@1.26.0bound to an olderlibonnxruntime.so.1and fail withVERS_1.26.0missing (#2591). - Fixed
scripts/ci-release-notes.tsstranding curated changelog entries from intervening silent tags (avX.Y.Ztag pushed without a GitHub Release, e.g. thev15.12.5/v15.12.6casualties of the pre-#2564 release-cancellation bug). The generator now walks(latest-published-release, target]— resolved viagh release listfrom therelease_githubCI job — and merges every in-range## [X.Y.Z]section per package, grouped by### <category>with bullet-level dedupe so post-release changelog flattening cannot duplicate entries. Falls back to the legacy single-version extraction when no prior published release resolves, andOMP_RELEASE_NOTES_FLOOR=v15.12.4overrides the lookup for manual rebuilds (#2596). - Fixed
Test & smoke (TS)CI timeouts caused by parallel test files racing on the process-global Settings singleton.CustomEditornow accepts amagicKeywordsEnabledOverrideinjection point so the shimmer-gate test can assert behaviour without callingresetSettingsForTest()/Settings.init(); the "streaming tool call preview height" describe drops its gratuitous Settings reset+init. Production wiring is unchanged (#2582) - Fixed a collapsed, still-streaming tool preview (an
eval/bash/sshbox with output streaming in) reading as "weirdly truncated" — top border and head rows missing — once its box outgrew the viewport, snapping back to whole only while expanded withctrl+oand breaking again when collapsed. A streaming preview was classified commit-unstable whenever collapsed, so the transcript offered none of its rows to native scrollback; once the box outgrew the window its head fell into the gap between the commit boundary and the window top, committed nowhere and repainted nowhere. TheprovisionalPendingPreviewflag now applies only to the pending call preview (before any result) — once a streaming result exists the result renderer is the live, top-anchored shape and the block is commit-stable in both collapsed and expanded states, so its durable head always reaches scrollback. - Fixed a crash in subagent task execution and extensions when a string (instead of a string array) was returned or set for the system prompt. Gracefully wrap string values in arrays.
- Fixed the todo completion reminder escalating 1/3 → 2/3 → 3/3 within a single user pause:
#checkTodoCompletionappended a<system-reminder>and then scheduledagent.continue(), so a text-only acknowledgement ("paused at your instruction") triggered anotheragent_endthat re-ran the same check and fired the next reminder — no user input required.AgentSessionnow tracks#todoReminderAwaitingProgress: a reminder sets it, anytoolResult(real progress) or a new user prompt clears it, and#checkTodoCompletionstays silent while it is set. Escalation throughtodo.reminders.maxstill works when the agent makes tool-level progress between stops (#2590). - Fixed profile bootstrap so an extension-shadowed
--planflag no longer swallows a following global--profile. - Fixed MCP OAuth URL-keyed credentials to stay profile-scoped under shared auth-broker storage and to clear discovered definition-only server auth during
/mcp unauth. - Fixed
/mcp unauthdeleting another profile's MCP OAuth credential row under broker-backed auth storage: when a sharedmcp.jsonpins an explicitauth.credentialIdscoped to a different profile (mcp_oauth:profile:<other>:<url>), removal now skips ids scoped to a non-active profile, mirroring the read path that already refuses to use a foreign profile's id. Legacy url-keyed (mcp_oauth:<url>) and active-profile ids are still cleared. - Fixed auto-learn managed skills to use the active profile's agent directory, so authored profile skills keep priority over managed fallbacks.
[15.13.0] - 2026-06-14
Breaking Changes
- Replaced the
omp setup sttcommand withomp setup speech. The oldsttsetup component is gone (no alias);omp setup speechnow provisions the full speech stack — audio recorder, speech-to-text model, and text-to-speech model. - Renamed the
tts.enabledsetting tospeechgen.enabled(same boolean, default off; no alias). It still gates the on-demandttsspeech-generation tool, now labelled "Speech Generation" in the settings panel.
Added
- Added
paste.largeMenuThresholdsetting (0/100/250/500/1000, default 100) to control when large pasted content triggers the large-paste menu or stays as a normal[Paste]marker - Added a large-paste editor menu for pasted text over the threshold that lets users choose to wrap the paste in a fenced code block, wrap it in
<pasted_text>XML tags, or save it aslocal://attachment-Nfor on-demand reading - Added
snapcompact-savings.jsonljournaling for snapcompact tool-result compaction, recording session, provider, model, tool call, and estimated token savings whenever tool output is rendered as image frames - Added
subagent:<id>loop-phase breadcrumbs around in-process subagent event dispatch and finalization so the TUI event-loop watchdog can attribute a main-thread stall to subagent execution (#2485) highlightMagicKeywords(text, resetTo?, phase?)now accepts an optionalphase∈ [0, 1) that rotates the gradient cyclically; sent bubbles omit it (static palette unchanged).hasMagicKeyword(text)exported frommodes/magic-keywordsis the cheap shimmer-gate the editor uses on every render.- Added a
fastModeScopesetting (both|openai|claude, defaultboth) controlling which providers/fast on(and the fast-mode toggle) target.bothkeeps the prior unscoped priority behavior;openai/claudescope fast mode to one family./fast statusnow reports the active scope. - Added the
mnemopi.embeddingVariantsetting (en|multilingual) selecting a stronger SOTA local embedding model —en→BAAI/bge-base-en-v1.5(768d),multilingual→intfloat/multilingual-e5-large(1024d). Resolution precedence ismnemopi.embeddingModelsetting >MNEMOPI_EMBEDDING_MODELenv > variant default, so the documented env override is still honored. Changing the active model wipes and rebuilds stored embeddings on the next writable start (#2476) - Added a
/guided-goalslash command that interviews you to refine an objective before enabling goal mode, then seeds goal mode with the agreed objective. The bounded interview (up to six turns) runs on the plan or slow model and falls back with a hint when the goal is still too vague (#2502). - Added a large-paste menu: when a paste reaches
paste.largeMenuThresholdlines (default 100;0disables), the editor offers to wrap it in a code block, wrap it in<pasted_text>XML tags (both collapse to a[Paste]marker that expands on submit), or save it to the session'slocal://store and insert a cleanlocal://attachment-Nreference the agent canreadon demand. Esc keeps the previous inline-paste behavior, so the content is never lost. - Added
8on22-bw(leading) and11on16-bw(tracking) options to thesnapcompact.shapesetting, the spacing-tuned cells that are now the per-provider defaults (Anthropic → tracking, OpenAI/Google → leading) - Added a local on-device neural TTS backend for the
ttstool and aproviders.ttsswitch (auto|local|xai, defaultauto).localsynthesizes speech with Kokoro-82M — SoTA on-device TTS quality — viakokoro-json the shared ONNX runtime (@huggingface/transformers+onnxruntime-node) in a subprocess worker (mirroring the tiny-model worker), keeping the model warm across calls and emitting 24 kHz WAV/PCM16 with no network call;xaikeeps the existing Grok Voice cloud path;autoprefers local but routes.mp3requests to xAI when credentials exist (no local MP3 encoder is bundled, so a local.mp3request is written as a sibling.wav).kokoro-jsis never a hard dependency: it is lazilybun installed into a version-keyed runtime dir on first use (withonnxruntime-nodeforce-pinned to a Bun-safe version), so its transformers@3.x graph never pollutes the main tree. Newtts.localModel(defaultkokoro) andtts.localVoice(defaultaf_heart; American/British, female/male voices) settings select the on-device voice. - Added a unified, interactive
omp setup speechcommand that walks one reusable flow across all three speech dependencies: it lets you pick and persist the speech-to-text (stt.modelName) and text-to-speech (tts.localModel) models from a TUI list, then downloads both models plus an audio recorder with live progress. The recorder is now auto-provisioned cross-platform (a staticffmpegbinary is fetched via the shared tools-manager when no SoX/FFmpeg/arecord is present, with the PowerShell fallback on Windows) instead of dead-ending with "install sox manually".--checkand--jsonreport recorder + STT-model + TTS-model readiness without installing. - Added
omp say <text>, which synthesizes text with the local on-device TTS engine and plays it through the speakers (cross-platform:afplayon macOS,paplay/aplay/bundledffmpegon Linux, PowerShellMedia.SoundPlayeron Windows).--out <file>writes a WAV instead of playing,--voice/--modeloverride thetts.localVoice/tts.localModelsettings, and an uninstalled model prints an actionableomp setup speechhint. - Added streaming speech vocalization: with
speech.enabledon, the assistant speaks its reply through the speakers as it streams. Assistant text deltas are fed directly into the engine's incremental text input (Kokoro'sTextSplitterStreamvia the worker) as they arrive, rather than pre-chunked in JS and synthesized one batch call per sentence — the engine owns sentence segmentation and emits one audio chunk per sentence. A single persistent player (StreamingAudioPlayer) drains those chunks gaplessly (raw 32-bit-float PCM piped to oneffmpeg→PulseAudio/ALSA process on Linux; interruptible per-fileafplay/PowerShellSoundPlayeron macOS/Windows), replacing the spawn-a-player-per-sentence path that added latency and audible gaps. Overspeech is handled end to end: a new turn, a sent message, or an Esc/Ctrl+C interrupt stops playback instantly (the player process is killed rather than letting the current sentence finish); holding the push-to-talk key ducks the volume while you speak and restores it when you stop; and sequential utterances queue and drain in order instead of overlapping.speech.mode(all|assistant|yield, defaultassistant) picks what is spoken —alladds thinking,yieldspeaks only the final message at turn end — andspeech.voiceselects the Kokoro voice.ask-tool questions are spoken in every mode. Synthesis reuses the local Kokoro engine (tts.localModel) through a new streaming synthesis path (TtsClient.synthesizeStream) that pushes text in and streams audio chunks back over the worker protocol. - Added live (streaming) speech-to-text: with
stt.enabledon, transcription now appears in the composer as you speak instead of all at once after you stop. The recorder streams raw 16 kHz mono PCM from sox/ffmpeg/arecord stdout to the warm STT worker, where an energy-based endpointer (no extra model) splits speech into segments at natural pauses; each finalized segment is committed into the editor while the in-progress segment shows a live volatile preview that refreshes in place and is kept out of the undo history. Works with both the default Parakeet (sherpa-onnx) and the Whisper (transformers.js) tiers. Recorders that cannot stream to a pipe (the Windows PowerShell mci fallback) transparently fall back to single-shot transcription. - Added
skills.enableAgentsUserandskills.enableAgentsProjectsettings (default on) so the canonical OMP-native~/.agent[s]/skillsand project-walkup.agent[s]/skillsare configurable independently from the third-party Claude/Codex/Pi toggles. - Added a read-only
ctx.modelsfacade for extensions:list()(authenticated models),current()(live session model),resolve(spec)(a model string or role alias →Model, using the same settings-backed aliases and match preferences as core selection), andfamily(model)(opaque canonical-identity lineage token for cross-family comparisons). Lets extension tools select models the way core does without reaching into the mutable registry (#2406) - Added RPC prompt lifecycle hints so hosts can distinguish scheduled agent turns from local-only slash commands via
data.agentInvokedandprompt_result. - Added extension lifecycle events for tool approval prompts:
tool_approval_requestedbefore the approval wait andtool_approval_resolvedafter approve, deny, or approval prompt failure.
Changed
- Changed
handoffcustom messages (customType: "handoff") to render in the transcript as a compaction-style expandable divider in both the main session and Agent Hub views, and expanded handoff details now show the handoff context body without<handoff-context>tags - Changed the double-tap-← gesture (empty editor, main session) to stay inert when there are no subagents to show, instead of opening an empty Agent Hub roster. The explicit Agent Hub / observe keybindings still open the empty roster. The gating reuses the hub's own row count (after its persisted-subagent scan), so it matches exactly what the hub would display.
- Changed the
jobtool'sasync.pollWaitDurationsetting (relabeled Max Poll Time) to add asmartvalue, now the default. A fixed value (5s–5m) still blocks for exactly that long;smartadapts: a blocking poll starts at a 5s floor and climbs a ladder (5s → 10s → 30s → 1m → 5m) with each back-to-back poll, so a tight poll loop backs off and stops spending turns on "still running" frames, then resets to the 5s floor after ~1 minute without polling (i.e. when the agent steps away to do real work). Escalation is tracked per agent (owner-scoped onAsyncJobManager). - Added the
compat.supportsForcedToolChoicecustom-model flag for OpenAI-compatible models whose endpoints accept tools but reject forcedtool_choicevalues (#2546). - Changed speech-to-text to run fully local on-device with a tiered, multi-engine model picker. Transcription runs in a subprocess worker (mirroring the tiny-model worker; the native ONNX addons are hard-killed on shutdown to dodge the Bun NAPI-finalizer segfault) instead of shelling out to Python
openai-whisper, keeps the model warm across recordings, and decodes WAV to 16 kHz mono float32 in-process.stt.modelNamenow selects on-device tiers across two engines:parakeet(default) — NVIDIA Parakeet TDT 0.6B v3 (25 languages) via the nativesherpa-onnx-node, the Open ASR Leaderboard accuracy + throughput leader (lower WER than, and ~20× faster decoding than, Whisper large-v3) — plusfast/balanced/turbomapping to Whisper base/small/large-v3-turbo (multilingual, up to 99 languages) via@huggingface/transformers.omp setup speechno longer mentions pip/python-whisper and reports recorder + model-cache readiness. - Changed the speech-to-text trigger from the
Alt+Hkeybinding to a hold-Spacepush-to-talk gesture. Holding the space bar emits an OS auto-repeat burst; once more than 5 spaces land in the editor it recognizes the hold, deletes (tracks back) those inserted spaces, and starts recording, then stops and transcribes when the repeats stop (the space bar is released).app.stt.toggleis now unbound by default but can be rebound to a chord for press-to-toggle; the gesture is gated onstt.enabled, andShift+Spacestill inserts a literal space. task.eager("Prefer Task Delegation") andtodo.eager("Create Todos Automatically") are now three-level enums (default/preferred/always) instead of booleans. Fortodo.eager,preferredrenders a soft first-message reminder whilealwaysforces thetodotool (the previous "on" behavior); fortask.eager,preferredadds a soft (SHOULD) delegation nudge to the system prompt whilealwaysuses hard (MUST/ONLY) wording plus a first-turn delegation reminder. Existing boolean configs migrate automatically (true → always,false → default). On models that cannot be forced to calltodo,todo.eager: "always"now emits the first-turn reminder without forcing the call (previously such models received nothing) (#2539, #2540 by @metaphorics).- Fixed
/model-switching to a non-default OpenRouter model returning404 No route: POST /chat/completionswhen the provider is routed through the auth-gateway broker. The background catalog refresh re-ranmergeDiscoveredModelon every openrouter entry; for models whose bundled record already existed, the merge re-appliedbaseUrl,headers, andcompatbut droppedtransport: pi-nativebecause the raw/v1/modelspayload carries no transport hint. The next/modelswitch then picked the now-transport-less entry and routed through the default openai-completions client to${baseUrl}/chat/completions— a path the auth-gateway never serves.mergeDiscoveredModelnow propagates the override/existing transport on the rediscovery branch (#2555).
Fixed
- Fixed npm plugin installs to reject packages whose declared extension entry points cannot load because imports or nested dependencies are unresolved (#2312).
- Fixed the deferred MCP discovery banner (
Connecting to MCP servers: …) overdrawing the chat input bar.onMCPConnectingwrote the banner straight toprocess.stderrwhile the TUI owned the terminal; it now emits on anmcp:connectingevent channel thatInteractiveModerenders throughshowStatus(the status container), mirroring the existing LSP-startup pattern so the banner can never paint over the input box border (#2483) - Fixed Win+Shift+S screenshot paste on Windows dead-ending on
Image not found: Windows Terminal forwards a bracketed paste of the Snipping Tool's transient…\MicrosoftWindows.Client.Core_*\TempState\…file path, which is already gone (or never materialized) by the time omp reads it, sohandleImagePathPastefailed with ENOENT even though the screenshot bitmap was still on the clipboard. The handler now falls back to the clipboard image across every local read failure (missing file, undecodable file, or generic error) before degrading, and the fallback is skipped over SSH where the clipboard lives on the remote host rather than the terminal holding the screenshot. - Fixed npm prebuilt extension compatibility shims deriving their own package root through bare
@oh-my-pi/pi-coding-agentresolution, which could select an older Bun cache copy in global installs and reintroduce mixed-runtime plugin loading stack overflows. - Honor the
context_lengthreported by OpenAI-compatible/v1/modelsdiscovery (discovery: { type: "proxy" }anddiscovery: { type: "openai-models-list" }) when present, so aggregator-reported windows override the stale bundled reference; the value is validated through the positive-number guard so a0/negative/stringly-typed upstream value cleanly falls back to the bundled reference (then128000) instead of pinning a broken window (#2466 by @androw). - Fixed
web_searchSearXNG fallback when HTTP 200 responses contain no usable results plusunresponsive_engines; SearXNG now raises a transient provider error, and the fallback loop rejects any provider response with no renderable content before formatting an invisible success (#2571). - Fixed
readon a GitHub commit URL (github.com/<owner>/<repo>/commit/<sha>) returning the raw commit HTML page instead of structured content.parseGitHubUrlhad nocommitcase, so commit URLs fell through to generic HTML rendering; they now resolve via the commits API and render as markdown (subject, author, stats, parents, full commit message, and a per-file unified diff), matching the existing blob/tree/issue/PR handling. - Fixed release runs being silently cancelled by a later
mainpush, which left tagged versions (v15.12.6in the wild) without a GitHub Release or npm publish. The CI workflow'sconcurrencygroup was${{ github.workflow }}-${{ github.ref }}, and since the release-script commit +v*tag are pushed atomically torefs/heads/main, the release run shared theCI-refs/heads/maingroup with every subsequent push;cancel-in-progress: truethen killed it beforerelease_binary/release_github/release_npmcould run, and no future run carried the release tag at HEAD. The group now resolves to a per-sharelease-<sha>slot withcancel-in-progress: falsewhenever the push subject matcheschore: bump version to(the release-script convention) orgithub.refis av*tag (workflow_dispatchrecovery), so release runs are isolated from PR/main churn (#2564). - Allowed
compat.streamIdleTimeoutMs: 0inmodels.yml. The schema was.positive(), so the documented "set to 0 to disable" escape hatch was only reachable via the global env var (#2422) - Fixed LaTeX math delimiters (
$/$$) and commands (such as\text,\times) rendering raw in the terminal by instructing the model to write equations as plain text / Unicode in its replies. The instruction is scoped to conversational output, so it does not constrain LaTeX or Markdown/KaTeX content the agent is asked to write to files (#2550 by @usr-bin-roygbiv). - Fixed the MCP stdio transport
close()potentially hanging while awaiting a read loop that can block indefinitely; teardown now detaches the read loop instead of awaiting it (#2550 by @usr-bin-roygbiv). - Fixed per-project memory isolation pulling other projects' memories into recall. Legacy (pre-#2412) mnemopi banks were rescued into recall when any working-memory row tagged the active cwd, but recall reads a bank wholesale and cannot filter rows by cwd, so a mixed-cwd bank leaked unrelated projects' memories. A legacy bank is now rescued only when every row tags the active cwd (#2412).
- Fixed a prompt template whose name collides with a builtin slash-command alias (e.g. a
modelstemplate beside the builtin/model, which owns themodelsalias) appearing as a duplicate entry in the slash-command autocomplete picker. The picker's reserved-name filter now also excludes command aliases, matching runtime resolution (slash commands expand before prompt templates, so the template was already unreachable). - Fixed the tool-result renderer re-shaping on every
invalidate()(spinner tick, stream chunk, resize, keystroke), which made large grep/find/read results block the main thread for seconds and made typing sluggish.ToolExecutionComponent.#updateDisplay()now memoizes on a dirty key (result version, expand state, partial flag, spinner frame, image visibility, theme epoch, background-task freeze state, the resolved terminal image protocol, and a display-input version that covers streamed call args, the async edit-diff preview, and Kitty image conversions) and a#displayBuiltguard that also fast-paths the#contentTextfallback, so the O(result-size) shaping runs once per change instead of every frame without freezing streamed args, previews, converted images, a backgrounded task settling to its static form, or images that arrive before the async image-protocol probe resolves. Image-bearing results also re-shape on terminal resize (keyed on the resolved image dimensions only when images are present) so inline images rescale, while image-free results never re-shape on resize (#2484) - Fixed
setTheme()not bumping the theme epoch on its invalid-theme fallback path: a failed theme load swaps the active theme to the dark fallback, so memoized renderers (the tool-result renderer above) must re-shape — previously they kept the failed theme's stale colors until some other state changed (#2484) - Fixed tool-call spinners animating out of phase across parallel tool calls — each live tool block advanced its glyph from its own per-instance start time, so concurrent spinners showed different frames. Glyphs now derive from a single shared monotonic clock (
sharedSpinnerFrame), keeping every live block in lockstep. - Fixed the per-turn token-usage row (
display.showTokenUsage) churning and duplicating in scrollback, most visibly with parallel tool calls. The row was rendered inside the assistant block above the turn's tool blocks, so finalizing the block was deferred and late appends recommitted the already-committed tool rows. The assistant block now always finalizes as soon as a tool-call appears, and the usage row is emitted as a standalone finalized block below the turn's tool blocks across all three render paths (live, transcript rebuild, agent-hub). - Fixed the editor input box claiming a disproportionate share of small terminals (<=18 rows): the editor max-height floor (6 rows) ignored the available space. The height now yields to terminal size (
EDITOR_MIN_CHROME_ROWS), reserving rows for the transcript and status line whenever the terminal can host both; on terminals too small for both, the editor collapses to its real bordered minimum instead of overshooting a fictitious cap. - Fixed
ultrathink/orchestrate/workflowzkeywords not glowing while typing — the editor appended a CURSOR_MARKER (ESC-prefixed) after each render, so the magic-keyword regex's right-boundary(?!\S)tripped on ESC and dropped the gradient until a trailing character was typed. The marker-aware editor decorate (packages/tui) plus a phase-awarehighlightMagicKeywordsoverload restore the live glow and add a Claude-Code-style shimmer while the prompt is focused, gated onmagicKeywords.enabled(#2475). - Fixed the compaction flow (
/compactand plan-mode "Approve and compact context") leaving UI artifacts.executeCompactionadded aSpacer(1)to the transcript that the sibling handoff path never adds and that leaked as an orphan blank line whenever compaction was cancelled or failed; that spacer is removed. On success the compaction loader is now stopped and the status container cleared before the transcript is rebuilt, so the live loader row no longer flickers over the reconciled transcript near the status seam (the idempotentfinallystill covers the cancel/fail paths) (#2486) - Fixed plan approval's "Approve and compact context" running the compaction summarizer on the pre-plan model instead of the plan model, cold-missing the plan model's prompt cache. Compaction now runs on the plan model (warm cache); the switch to the execution/pre-plan model happens only after a successful compaction and before any input queued during compaction is dispatched, so the queued turn runs on the post-compaction model. A cancelled compaction now also restores the pre-plan model (it previously stranded the session on the plan model), while a failed compaction stays on the plan model with its context intact.
- Fixed
Alt+Up(dequeue) reporting "No queued messages to restore" for messages — including skills — typed while the session was compacting.restoreQueuedMessagesToEditornow drainscompactionQueuedMessagesalongside the agent queue, so theAlt+Up to edithint restores every pending message it advertises. - Fixed
restoreQueuedMessagesToEditor(Alt+Up dequeue and Esc-abort) producing colliding[Image #N]markers when the editor draft already held pending image(s): queued text was prepended but queued images were appended, so positional marker → image lookup at submit time resolved to the wrong image. Each queued message's image markers are now renumbered by the running pending-image count before merge so the combined text stays aligned with the mergedpendingImagesorder (#2531). - Fixed
AgentBusyError("Agent is already processing. Use steer() or followUp()...") surfacing on mode transitions — asFailed to finalize approved plan: ...when a plan was approved while the agent was still streaming the post-resolvecontinuation (or a turn started by the approve-time compaction/clear), and as an error toast when a loop auto-submit or goal continuation fired during a streaming/compaction race. Plan approval now aborts any in-flight turn before dispatching the executor's first prompt, andsubmitInteractiveInputroutes streaming-time loop, goal-continuation, and manual submissions through the follow-up queue (streamingBehavior: "followUp") instead of throwing (synthetic continue-shortcuts stay developer-attributed and keep their prior behavior). Extends the manual-/goalfix in #2454 to the continuation and plan-approval paths. - Fixed
/plancycling betweenplanandplan_pausedwith no path back to modenone.handlePlanModeCommandhad branches for entering and pausing but fell through to#enterPlanMode()when invoked from the paused state, so once a session entered plan mode the only operator-visible toggle re-entered it. The handler now matchesplanModePausedand fully exits — clearingplanModeHasEnteredand appending amode_changeto"none"— so/goal(and any other mode gated onplanModeEnabled || planModePaused) can run again after a third/plan(#2510). - Fixed HTML session export rendering empty text tokens (
text,userMessageText,customMessageText,toolTitle) as the dark-theme grey#e5e5e7on every theme not literally namedlight, making transcripts illegible on custom light themes likesandstone,limestone, andporcelain.getResolvedThemeColorsand the standaloneisLightThemehelper now classify against the resolvedstatusLineBgluminance (the same surfaceTheme.isLightuses), so the HTMLdefaultTextfalls back to#000000on light themes and the standalone helper stays in lockstep withTheme.isLight(#2516). - Fixed the Agent Hub opening on its own from a stray mouse click. The double-tap-← gesture (empty editor) fired on any two
leftkeys within 500ms, but terminals with "click to move cursor" / pointer features (iTerm2 option-click, WezTerm, kitty, tmux) synthesize a burst of arrow keys on click — delivered sub-millisecond apart in one stdin read — so a single click could pop the hub with no key ever pressed. The gesture now requires the second tap to land a human-plausible interval after the first (≥40ms, <500ms) and ignores any third-or-later rapid tap, so synthesized bursts are rejected while a deliberate double-tap still works. The same hardening applies to the focused-subagent ←← "return to main" gesture. - Fixed the
ctrl+pmodel-role cycle indicator (thedefault / gpt / fable / …chip track) stacking duplicate copies in the scrollback when other chat activity landed between two cycles. The track was emitted throughshowStatus, whose back-to-back coalescing only merges when the previous status is still the last transcript child; any interleaved append broke that identity check and appended a second track. It now renders into a dedicated anchored container above the editor (cleared and rebuilt in place each cycle, like the Todos HUD) and auto-clears after a short linger, so rapid presses or concurrent activity can never duplicate it. - Fixed the
Working…loader vanishing for the rest of a turn after an auto-compaction (context-overflow recovery) or auto-retry. Those overlays took over the shared status container with a barestatusContainer.clear(), which detached the working loader but leftloadingAnimationset; the resumed turn'sagent_start→ensureLoadingAnimation()is guarded byif (!this.loadingAnimation), so it skipped re-attaching the loader and the spinner stayed gone while the agent kept streaming. The overlay handlers now fully tear the working loader down (stop + dereference) via#stopWorkingLoader(), so the nextagent_startrecreates and re-attaches it. - Fixed JS eval helper optional arguments rejecting Python-style positional calls.
read(path, offset, limit)now works alongsideread(path, { offset, limit }),null/undefinedskip optional positional slots, and non-local URI reads such asartifact://...delegate through the read tool so line slicing works on spilled artifacts. - Fixed legacy extension compatibility remapping for
@*-pi-ai/utils/oauthimports so background workers load the relocated@oh-my-pi/pi-ai/oauthexports instead of resolving missingsrc/utils/oauth/*files (#2566). - Fixed eager todo initialization prompting GPT-5.5 to emit unsupported task metadata fields, which could leave fresh sessions stuck on the forced first
todocall (#2561). - Fixed Windows plan-mode task fan-out crashing the TUI when nested async task progress formed a cycle; task rendering now cuts recursive snapshots and long Windows
local://roots are shortened under temp storage (#2551). - Fixed a band of streaming assistant output being lost from native scrollback — committed nowhere, repainted nowhere — once a reply grew taller than the viewport. Markdown whose layout keeps changing above the streaming tail (most visibly a table whose columns re-align as rows arrive) never earns a byte-stable commit-safe end, so as its head scrolled above the window the rows fell into the gap between the commit boundary and the window top and vanished.
TranscriptContainernow reports agetNativeScrollbackSnapshotSafeEnd()for commit-stable live blocks (their whole body is durable content), and the renderer commits those scrolled-off rows audit-exempt — a later layout change of an already-committed row freezes a slightly-stale row in scrollback (duplication never loss) instead of dropping it. Provisional blocks (collapsing tool/edit previews) are unaffected. - Fixed unknown
---prefixed flags being silently consumed as prompt text, which let a stale or typoed flag start a real agent session (connecting to MCP servers, waiting on the model) instead of failing fast.parseArgsnow tracks unrecognized flag-shaped tokens andrunRootCommandcallsreportUnrecognizedFlagsimmediately after the post-extension reparse, exiting2withError: unknown flag: --…before any session, MCP, or initial-message work runs. Extension-registered flags still pass cleanly since the validation runs after the extension-aware reparse, and--is honored as a POSIX positional separator so flag-shaped prompts (omp -p -- --explain-this) survive the new guard (#2459). - Fixed
/goal <objective>and/goal set <objective>during streaming so goal context is steered immediately but objective submission waits for the active turn to finish instead of spammingAgentBusyError. The interactive goal-continuation timer is now streaming-aware too: if a turn starts inside the 800 ms idle window the timer was scheduled in, it drops the tick instead of submitting a stalegoal-continuationthat would resurface the sameAgentBusyError; the nextagent_endreschedules (#2454). - Fixed
~/.agent[s]/skillsnot appearing as/skill:<name>commands when every named source toggle (skills.enableCodexUser,skills.enableClaudeUser,skills.enableClaudeProject,skills.enablePiUser,skills.enablePiProject) was off:loadSkillsgated theagentsprovider onanyBuiltInSkillSourceEnabled, so a user who turned off the Claude/Codex/Pi sources to clean noise also lost their own canonical OMP-native skills. Theagentsprovider now reads the dedicatedenableAgentsUser/enableAgentsProjecttoggles, and the unknown-third-party fall-through gate is restricted to the named third-party toggles so keeping the default agents toggles on no longer silently re-enablesopencode/github/claude-plugins/geminiskill sources (#2401). - Fixed Claude Code marketplace plugin skills installed under
skills/<name>/SKILL.mdto also appear as bare slash commands such as/understand, matching Claude-native plugin docs. The slash command name is taken from the skill directory basename so display-style frontmatter names likename: Understand Anythingstill resolve to/understand(#2415). - Fixed ACP
/movebuiltin test expectations to compare the resolved destination path so the test is portable on Windows and Unix (#2381 by @oldschoola). - Fixed vLLM discovery so
providers.vllm.baseUrldrives the built-in endpoint, additional OpenAI-compatible vLLM provider IDs work throughopenai-models-list, and discoveredmax_model_lenor fallbackcontext_lengthvalues set context windows instead of falling back to 128k. - Fixed extension discovery ignoring package directories symlinked into an
extensions/directory.
Removed
- Removed the Python
openai-whisperdependency andpipinstall path from speech-to-text — the bundledtranscribe.pyand all Python/whisper probes inomp setup speechare gone; the recorder (SoX/FFmpeg/arecord) remains the only external tool. - Changed the speech-to-text trigger from the
Alt+Hkeybinding to a hold-Spacepush-to-talk gesture. Holding the space bar emits an OS auto-repeat burst; once more than 10 spaces land in the editor it recognizes the hold, deletes (tracks back) those inserted spaces, and starts recording, then stops and transcribes when the repeats stop (the space bar is released).app.stt.toggleis now unbound by default but can be rebound to a chord for press-to-toggle; the gesture is gated onstt.enabled, andShift+Spacestill inserts a literal space. - Added an experimental, opt-in auto-learn loop (default off,
autolearn.enabled). When enabled, after the agent stops it is nudged to capture reusable lessons: durable facts go to long-term memory and repeatable procedures become managed skills —SKILL.mdfiles written to an isolated~/.omp/agent/managed-skillsdirectory that is discovered and surfaced like authored skills but never overwrites user-authored skills (authored names always win). Two tools back this:manage_skill(create/update/delete managed skills) andlearn(record a lesson, optionally minting a managed skill in the same call).learnworks with thehindsight,mnemopi, or file-basedlocalmemory backend; underlocal, lessons append to alearned.mdin the project's memory root (kept separate from the consolidation artifacts so they survive a consolidation pass) and are injected into future sessions. The nudge is passive by default (a hidden reminder rides the next turn);autolearn.autoContinueinstead auto-runs one capture turn at stop, andautolearn.minToolCalls(default 5) gates trivial turns. Plan/goal-mode turns and subagents are never nudged. - Fixed
/plancycling betweenplanandplan_pausedwith no path back to modenone, while preserving prompted paused-mode requests. The no-arg third toggle now fully exits — clearingplanModeHasEnteredand appending amode_changeto"none"— and/plan <prompt>fromplan_pausedre-enters plan mode and submits the prompt as the first turn (#2510). - Fixed HTML session export rendering empty text tokens (
text,userMessageText,customMessageText,toolTitle) as the dark-theme grey#e5e5e7on every theme not literally namedlight, making transcripts illegible on custom light themes likesandstone,limestone, andporcelain.isLightThemenow classifies against the resolvedstatusLineBgluminance (the same surfaceTheme.isLightuses), while HTMLdefaultTextcontrasts the actual export surface (export.cardBg/export.pageBg/ deriveduserMessageBg) so light-status themes with dark export cards keep light transcript text (#2516).
[15.12.6] - 2026-06-14
Breaking Changes
- Removed the
writeLineandwriteLineSyncmethods from the publicSessionStorageWritercontract, requiring customSessionStoragebackends to switch to theappendAPI
Added
- Added package-level exports for
SessionContext, session entry types, session listing/loader helpers, and migration APIs viasession/session-context,session/session-entries,session/session-listing,session/session-loader, andsession/session-migrations - Added asynchronous session-write
append(...)-based persistence API in session storage implementations so callers can stream writes without sync line-appending methods
Changed
- Changed session persistence internals to expose
writeTextAtomic(...)on session storage writers for atomic whole-file replacements - Changed online session-title generation to support tool-choice-less title models. Providers/models that cannot be forced to call a tool (chat-completions hosts without
tool_choicesupport such as DeepSeek V4, and Claude Fable/Mythos) are now prompted to wrap the title in<title>...</title>markers instead of theset_titletool call; extraction is lenient, accepting a plain sentence or a truncated/unclosed tag. ATITLE_SYSTEM.mdoverride is reused in this mode with the marker instruction appended.
Fixed
- Fixed session JSONL persistence so the first assistant turn materializes the file synchronously, leaves the append writer open, and writes later entries with a sync append writer even during writer-close races instead of waiting on a queued rewrite.
- Fixed submitted user messages emitting OSC 133 command-start markers without a matching command-finished marker, which made some terminals group later transcript output under the first prompt instead of appending it normally.
- Fixed queued forced tool choices being rejected and requeued or dropped when their named tool is no longer active for the upcoming turn, preventing eager todo and pending-action reminders from forcing unavailable tools. (#1701)
Removed
- Removed the
re-roots past a cwd-less legacy session in a shared explicit sessionDirrelocation test case and thestores symlink-equivalent home cwd sessions under home-relative directoriesfile-operations test case.
[15.12.5] - 2026-06-13
Changed
- Terminal resize now repaints only the viewport while a drag is in flight and defers the full transcript replay until the drag settles. Outside a multiplexer, every SIGWINCH used to erase and replay the entire transcript at the new width — re-laying-out (and, for markdown, re-lexing) all of history on each event, work thrown away the instant the next event arrived and re-done dozens of times a second during a drag. The TUI now composes and paints only the visible tail mid-drag — a new
ViewportTailProviderfast path that the transcript implements by rendering blocks bottom-up and skipping everything above the fold, touching no commit/scrollback state — then runs the single authoritative rewrap + native-scrollback rebuild ~120 ms after the last resize event.
Fixed
- Updated
docs/models.mdanddocs/providers.mdto reference theomp modelssubcommand (andomp models canonical/omp models find) instead of the removed top-level--list-modelsflag (#2458) - Fixed unknown
---prefixed flags being silently consumed as prompt text, which let a stale or typoed flag start a real agent session (connecting to MCP servers, waiting on the model) instead of failing fast.parseArgsnow tracks unrecognized flag-shaped tokens andrunRootCommandcallsreportUnrecognizedFlagsimmediately after the post-extension reparse, exiting2withError: unknown flag: --…before any session, MCP, or initial-message work runs. Extension-registered flags still pass cleanly since the validation runs after the extension-aware reparse (#2459). - Fixed prompt templates discovered from
cwd/.omp/prompts/and the agent prompts directory not appearing in the slash-command autocomplete picker.InteractiveMode.refreshSlashCommandState()now feedssession.promptTemplatesinto the autocomplete provider alongside builtins and file-based slash commands; templates whose names collide with an existing command are skipped to mirror the runtime expansion order (expandSlashCommandprecedesexpandPromptTemplate) (#2462). - Fixed empty-Enter steering interrupts leaving the newest queued steer visible after aborting an auto-continued queued turn; queued turns now re-drain after every abort/settle cycle.
- Added an agent-visible notice when the write tool auto-marks shebang files executable, so agents do not redundantly run
chmod +x.
[15.12.4] - 2026-06-13
Breaking Changes
- Removed the top-level
--list-modelsflag path and migrated model listing to the newomp modelscommand
Added
- Added
omp modelscommand to list and manage models withls,find,canonical, andrefreshactions - Added
--jsonoutput plus-e/--extension,--no-extensions, and--configcontrols toomp modelslistings - Added
skills.enableAgentsUserandskills.enableAgentsProjectsettings (default on) so the canonical OMP-native~/.agent[s]/skillsand project-walkup.agent[s]/skillsare configurable independently from the third-party Claude/Codex/Pi toggles.
Changed
- Model registry merge and
omp models/ model picker handle unknown context/output limits (null) — unknown limits render as-instead of a fake222K/8.9K. - Changed
omp modelsto use cached provider data by default and requireomp models refreshfor a forced online re-fetch - Updated model-resolution errors to point to
omp modelswhen a provider or model is not found - Upgraded workspace catalog packages to their latest versions as of 3 days ago, and refactored the ACP agent implementation to be compatible with
@agentclientprotocol/sdkversion0.25.0. - Made the
zodversion requirement in the workspace catalog more tolerant (^4.0.0instead of4.4.3), and aligned type definitions in coding-agent extensibility modules. - Changed
/logoutto pick a stored account after the provider, so multi-account OAuth providers can remove one credential without logging out every account. - Changed the status-line context% to report the provider's real prompt-token count — anchored on the last assistant response, matching the
/contextpanel and the collab host broadcast — instead of an independent cl100k estimate of the whole conversation. The estimate could read several points high and climb past 100% on subscription/Codex models (whose advertised window, e.g.272K, is already the input budget after reserving max output) while the request was still well within the real limit. Right after compaction the segment now shows?until the next response re-establishes the true count, and the redundant per-message estimate cache was dropped in favor of memoizinggetContextUsage().
Fixed
- Fixed ACP thinking-delta mapping to tolerate live chunks that only carry delta text.
- Fixed image input to Ollama (local
ollama,ollama-cloud, and anyollama-chatmodel) failing with an opaque HTTP 400 when an attached image was encoded as WebP. Ollama decodes images through llama.cpp /stb_image, which is built without WebP support, so the resize pipeline now auto-excludes WebP for those models — the automatic equivalent ofOMP_NO_WEBP=1, applied across every image path (@filementions and prompt/paste/CLI attachments, theread/inspect_imagetools,evaldisplay images,fetched images, and browser screenshots). Other providers are unaffected and still honorOMP_NO_WEBP. - Fixed queued steering/follow-up display to derive from the agent-core queue, so queued chips clear when the core dequeues them and no longer strand after empty-Enter aborts.
- Fixed model auth gateway probing to avoid skipping candidates with unknown
maxTokenslimits (null) - Fixed model listings so providers registered via extensions are now included from
-eand configuredextensionssources - Fixed
/mcp reauth,/mcp test, and/mcp unauthto find and operate on MCP servers reported by/mcp listeven when they are only runtime-discovered and not stored in writable config, including namespaced plugin servers likecloudflare:cloudflare-api - Fixed MCP server name validation so colon-namespaced server IDs are accepted when persisting reauth overrides so namespaced OAuth MCP servers can be stored in user config as
server:subserverentries - Retried assistant turns that stop with reasoning/thinking only and no final text or tool call, so Gemini/Antigravity thought-only
STOPresponses continue instead of silently ending the session. - Fixed
~/.agent[s]/skillsnot appearing as/skill:<name>commands when every named source toggle (skills.enableCodexUser,skills.enableClaudeUser,skills.enableClaudeProject,skills.enablePiUser,skills.enablePiProject) was off:loadSkillsgated theagentsprovider onanyBuiltInSkillSourceEnabled, so a user who turned off the Claude/Codex/Pi sources to clean noise also lost their own canonical OMP-native skills. Theagentsprovider now reads the dedicatedenableAgentsUser/enableAgentsProjecttoggles, decoupled from the third-party fall-through (#2401). - Fixed Windows PowerShell image paste so Ctrl+V can fall back to the PowerShell clipboard bridge when the native clipboard reader reports no image (#2429).
- Fixed misaligned box borders in Mermaid ASCII rendering for CJK (Korean/Japanese/Chinese) and emoji labels — affects both fenced
mermaidcode blocks in assistant messages and therender_mermaidtool.beautiful-mermaid@1.1.3measures label width in UTF-16 code units while terminals render East Asian characters 2 columns wide; apatchedDependenciesentry rebuilds its ASCII renderer to measure terminal display columns (grapheme-cluster aware, wcwidth-style policy). The patch mirrors the upstream PR (lukilabs/beautiful-mermaid#128) and should be dropped once it ships in a release. - Fixed interrupt loader state getting stuck after queued-message aborts by removing the session-layer flush/latch path; empty Enter now aborts the active turn and lets the existing post-unwind queue drain resume normally.
- Fixed
/goal <objective>and/goal set <objective>during streaming so goal context is steered immediately but objective submission waits for the active turn to finish instead of spammingAgentBusyError(#2454). - Fixed concurrent
omp --sessionstartups (e.g. cmux pane restore after an unclean shutdown) crashing withSQLITE_BUSY_RECOVERYwhile the agent SQLite databases were still under WAL recovery. The auth credential store andAgentStorage.open()retry theSQLITE_BUSYfamily with bounded backoff, and every shared SQLite open path (AgentStorage, history, autoresearch, memories, github cache, auto-QA grievances, catalog model cache, stats) now installs the busy handler before the first lock-taking statement so transient WAL recovery contention waits instead of crashing (#2421). - Mnemopi
per-project/per-project-taggedbank derivation is now stable for one cwd, ignoring the surrounding git layout. Previously the bank id was hashed fromgit.repo.resolveSync(cwd)?.repoRoot ?? path.resolve(cwd), so adding or removing a.gitanywhere above the working directory silently repointed the same conversation to a new bank and stranded its memories (e.g./home/x/projects/repoflipping betweenprojects-…andrepo-…). The derivation inpackages/coding-agent/src/mnemopi/config.tsnow hashespath.resolve(cwd)directly, and session startup widens the recall set with any sibling bank under<dbDir>/banks/whoseworking_memoryrows already carry the active cwd inmetadata_json.$.cwd, so memories stranded by the old, less-stable derivation become visible again on the next session without manual migration (#2412). - Fixed model switching (Ctrl+P role cycling and the alt+p /
/switch//modelsselector) intermittently freezing the UI for several seconds.AgentSession.setModel/setModelTemporaryran an eagerawait modelRegistry.getApiKey(model)purely as an existence pre-flight and discarded the value — butgetApiKeydoes real work: it synchronously executes command-backed key programs (apiKey: "!cmd",execSyncwith a 10s timeout, blocking the event loop) and refreshes OAuth tokens over the network when one crosses the expiry window (the "fine for a few switches, then a multi-second stall" symptom). Switching now uses the synchronous, side-effect-freeModelRegistry.hasConfiguredAuthcheck; the concrete key (command execution + OAuth refresh) is still resolved lazily per request via the existing resolver, so an unconfigured provider still fails fast withNo API keywhile a healthy switch never touches the network or spawns a subprocess.hasConfiguredAuthno longer runs the command program or refreshes tokens either, matching its documented "probe without resolving an API key" contract. - Fixed session resume (
pi -c/--continue/--session) hanging for ~10s at startup — surfaced by the watchdog asStill starting … phase: createAgentSession > restoreSessionModel— when an OAuth token needed refreshing or the auth broker (OMP_AUTH_BROKER_URL) was unreachable. Picking which saved model to restore is a pure selection that only needs to know whether auth is configured, butrestoreSessionModelprobed each candidate with the asyncgetApiKey, which refreshes OAuth tokens over the network, executes command-backed key programs, and issues auth-broker requests — so a slow or unreachable endpoint stalled resume for the full refresh timeout per candidate. Startup model selection now uses the synchronous, side-effect-freeModelRegistry.hasConfiguredAuthprobe (the same fix already applied to interactive model switching); the concrete key is still resolved lazily on the first request via the resolver.
[15.12.3] - 2026-06-12
Fixed
- Restored the intended double-Esc default to
/treeand fixed the Esc-opened selector path to reset the terminal display instead of preserving stale scrollback when the selector opens.
[15.12.2] - 2026-06-12
Fixed
- Collab links now dot-join the room secret (
<roomId>.<key>,host/r/<roomId>.<key>) instead of using a second#: RFC 3986 forbids a raw#inside a URL fragment, so macOS Foundation (behind terminal click-to-open) percent-encoded the browser deep link's second#to%23and the web client rejected the session./join,omp join, and the web client still accept legacy#-joined links and leniently decode%23-mangled ones - Fixed
brew install can1357/tap/ompfailing on macOS withsandbox-exec … exited with 1: the generatedFormula/omp.rb(rendered byscripts/ci-update-brew-formula.ts) now stampsusing: :nounzipon every per-platformurlso Homebrew leaves the bare Mach-O/ELF asset in the staging CWD (the previousDir["omp-*"].firstreturnednilbecauseUnpackStrategy::Uncompressed#extract_nestedlynested the file outside it), and wrapsgenerate_completions_from_executableinwith_env(HOME: buildpath)so the popened binary's~/.omplookup goes to the writable staging dir instead of the sandbox-denied real home (#2398)
[15.12.1] - 2026-06-12
Added
- Added the
compaction.dropUselesssetting (default on): tool results flagged contextually useless are elided by the per-turn cache-aware prune pass and the pre-compaction threshold prune, replaced with[Uneventful result elided]. Built-in tools flag their uneventful outcomes — zero-match/zero-resultsearch/find/ast_grep/recall(warnings included; the follow-up call has already corrected course), empty LSP lookups,jobpolls where everything is still running (plus nothing-to-wait-for and unknown-id polls),ircwait timeouts and empty inbox drains, and zero-resultgithubsearches / run-watch give-ups
Fixed
- Restored the default double-Esc behavior to open the editable message-history selector instead of
/treeso pressing Esc twice can edit a previous message again (#2396).
[15.12.0] - 2026-06-12
Added
- Added
/collab viewcommand to create a read-only spectator join link - Added read-only hints and status text for guest-only participation in collab sessions
- Added
share.serverUrlandshare.redactSecretssettings: the share server/viewer base for/sharelinks (defaulthttps://my.omp.sh/s) and a toggle (default on) that runs the secret obfuscator over the shared snapshot before upload - HTML session exports now embed subagent transcripts: sub-session files stored next to the session (
<session>/<AgentId>.jsonl, recursively) ride along in the export payload, agent ids in task tool cards become drill-down links, and a breadcrumbed overlay renders each subagent's full transcript — including its own tool cards and deeper nested agents — with Esc/backdrop navigation - Added Agent Hub focus mode: Enter on a local agent now retargets the main view to that live subagent session with regular transcript rendering, steering, Esc-to-main return, ←← parent navigation, and a ghost status-line badge.
Changed
- Blocked cycling model and thinking presets while a focused subagent session is active and now prompts users to return to the main session first
- Changed
codexResets.autoRedeemfrom a boolean tounset/yes/no: unset runs the eligibility check and asks before spending a saved Codex reset, yes redeems without prompting, and no skips the check entirely - Changed collab links so full links with a write token grant mutation rights while links without a token now join as read-only
/shareno longer uploads a plaintext HTML export to a gist for gistpreview. It now snapshots the session JSON, gzips and seals it with a fresh AES-256-GCM key, and pushes the blob to a secret gist (whenghis authenticated) or to the share server (capped at 1 MB; oversized sessions are trimmed — images first, then long strings, then oldest entries). The share link ishttps://my.omp.sh/s/<id>#<key>: the viewer fetches the blob (hex ids from the gist API, others from the relay store) and decrypts it in-browser, so the key never leaves the client. Configured secrets are additionally redacted from the snapshot unlessshare.redactSecretsis off. Custom~/.omp/agent/share.{ts,js,mjs}handlers keep the legacy HTML-file contract;/sharealso works for in-memory (--no-session) sessions now/collabnow prints a join hint with both link forms: the compactomp joinlink for terminals and a click-to-join browser deep link (https://<relay-host>/#<link>, displayed scheme-less, OSC 8-linked) — the relay serves the collab web client at/, and the room id + key ride in the URL fragment, so they never appear in any HTTP request./join,omp join, and the web connect screen accept either form- npm installs no longer download fastembed's ~270MB ONNX native dependency tree eagerly:
fastembedandonnxruntime-nodeare external to the bundle and optional peers of@oh-my-pi/pi-mnemopi, fetched on demand only when Mnemopi local embeddings are first used - The
jobtool prompt now documents that omittingpollwaits on all running jobs, so agents stop enumerating every job id to poll everything - Collapsed task tool blocks now cap the per-agent list at 4 rows: the live progress view keeps the running/pending tail visible behind a
… N more agents (…)summary line with per-status counts, finalized batches keep failed/aborted rows visible while folding the slowest successes, and the streaming call preview caps at the same 4 (expand shows the full list) - The anchored Subagents HUD above the editor now lists only detached background spawns: sync task calls (the parent turn is blocked and the inline tool block already renders live progress) and eval
agent()helpers (rendered by their eval cell's own progress tree) no longer appear in the list - Completed rows in the
jobtool output now show the standard done checkmark instead of the watch glyph that replaced the spinner - HTML session exports render tool calls through the same React tool renderers the collab web client uses: per-tool views for all built-in tools (bash, edit diffs, todo boards, eval cells, task batches, LSP, search, browser screenshots, …) are bundled as an
<omp-tool-view>web component into the export instead of the previous string-built dummy renderers - Modernized the HTML export page chrome to match the tool-card design language: hairline borders, dense mono typography, compact role-tinted message cards, refined tree sidebar and filter controls, themed scrollbars, collapsed-by-default thinking blocks, and mobile sidebar drawer — derived from the active theme's variables so light and dark themes both render correctly
- Agent Hub's embedded chat overlay is now reserved for collab guest viewing; local agents open in the main session renderer instead.
Fixed
- Filtered silent abort markers from Agent Hub assistant output so failed turns now render as normal error text
- Reset focus-session state when switching transcript rendering between the main session and a focused subagent so streaming/progress context no longer leaks across sessions
- Fixed read-only collab sessions so prompting, interrupts, and other write actions are blocked with a read-only warning instead of being applied
- Fixed Mnemopi local embeddings in bundled and compiled installs failing with
Cannot find module '../bin/napi-v3/.../onnxruntime_binding.node': the Bun bundle inlined fastembed's loader so its relative native require resolved againstdist/cli.js.fastembed/onnxruntime-nodeare no longer bundled; on first use Mnemopibun installs the pinned pair into~/.omp/cache/fastembed-runtime/<version-key>and loads the binding from there (#2389) - Fixed the interactive Model scope startup banner so models without an explicit thinking level do not show
:undefined, and entries that were scoped without a:levelare no longer rendered with the global default thinking level (whichapplyRootSessionOptionspre-fills on the cycling array for Ctrl+P) (#2385).
[15.11.8] - 2026-06-12
Added
- Updated collab link handling to accept compact
roomId#keylinks and relay hosts without explicit scheme when joining or starting sessions - Added
/collab stopand/collab statusoptions to control and inspect active shared sessions - Added
/collab,/join, and/leavefor live session sharing: the host shares an end-to-end encrypted link (AES-256-GCM key only in the link fragment; the relay sees opaque bytes) and guests render the session natively in their own TUI — streaming text, tool cards, footer state, ctrl+o expansion,/dump— and can prompt or interrupt the host's agent. Guest prompts render with an author badge; session-mutating commands stay host-only. Defaults to the publicrelay.omp.shrelay (collab.relayUrl); a self-hostable Go relay lives in the pi-www repo asomp-collab-relay - Added
collab.relayUrlandcollab.displayNamesettings plus acollabstatus-line segment showing the participant count (host) or guest role. Guests mirror the host's real model/thinking state into their replica agent and the host's subagent ecosystem end-to-end: the live subagent HUD, the Agent Hub table with live progress, hub chat/kill/revive (routed to the host), and on-demand subagent transcript viewing - Added
omp join <link>subcommand that launches the interactive TUI and immediately runs/join <link>
Changed
- Moved collab live-session wire contracts into
@oh-my-pi/pi-wireand stopped broadcasting unsupported session events or entries to collab guests. - The Ctrl+P role-cycle track and the plan-approval model slider now color segments by track position from the theme's own palette (accent/success/warning/error + markdown/syntax hues, deduplicated per theme since many themes alias them) instead of role-keyed colors with a gray fallback for custom roles
- Interactive boot no longer blocks first paint on MCP server discovery. For UI sessions,
createAgentSessionreturns immediately and connects to configured MCP servers in the background; their tools and slash commands stream in through the existing live-refresh channel once connected. An explicitly requested MCP tool whose server has not finished connecting resolves to a deterministic "still connecting" placeholder instead of an "unknown tool" error, and each server's instructions join the system prompt once its background connection completes — carried in on the same live-refresh that registers its tools — so server-provided instructions are preserved, not dropped.tools.discoveryMode: "auto"is re-resolved once the background connect reports the real MCP tool count, so a toolset large enough to cross the threshold flips discovery on (registeringsearch_tool_bm25) instead of force-activating every tool, and a session disposed while servers are still connecting disconnects them instead of resurrecting their tools onto the dead session. Non-UI modes (print/rpc/acp) keep the blocking discovery path. Measured ~290 ms (≈24% of cold boot) off the first-paint critical path with MCP servers configured. - Assistant-message streaming is cheaper per token. During a stream the component now reuses its
Markdownsubtree across reveal ticks — only the growing block is re-rendered — instead of tearing down and re-lexing every block on each ~30 fps tick, and grapheme counting in the reveal controller is memoized. A completed thinking block that precedes a still-streaming answer is no longer re-highlighted every frame (~66% less render work on think-then-answer streams in benchmarks; single-block streams are unchanged). - Cold boot no longer builds the model catalog's canonical-equivalence index on the first-paint critical path. The
ModelRegistryconstructor builtbuildCanonicalModelIndexover the entire ~3,200-model catalog synchronously (~210 ms); it is now built lazily on first read (getCanonicalModels/getCanonicalVariants/getCanonicalId, reached by the model picker and byenabledModels/default-role pattern resolution), which a default interactive launch never touches before paint. Measured ~244 ms (≈16% of cold-boot wall) off first paint; the picker pays the one-time build on first open. - Repeat
readsummaries of an unchanged file no longer re-run the tree-sitter parse. The per-session summary is memoized on the content hash of the freshly-read bytes — the file is still read fresh on every call, so results stay correct without a staleness window — dropping a repeated same-file summary read from ~17 ms to ~2.5 ms. - Attributed the previously-unlabeled synchronous boot region in the
PI_TIMINGstartup table withmodelRegistry:init,buildCanonicalModelIndex, andinitTelemetryExportspans.
Fixed
- Fixed remote (SSH) image attachment silently inserting the local-machine path as plain text: when omp runs over SSH and the terminal forwards a bracketed-paste image path, the path is unreachable from the remote host. The path-as-text fallback is gone for unreachable paths and the status now points the user at the clipboard image-paste shortcut so the bytes actually cross the connection (#2375).
Security
- Rejected non-local
ws://relay URLs and invalid room keys when parsing collab links to prevent insecure or malformed session joins
[15.11.7] - 2026-06-12
Added
- Added mouse support to the setup wizard, including hover, wheel scrolling, and click-to-select for provider sign-in, web-search provider, glyph, and theme option lists
- Added pointer support for the providers tab bar so tabs can be selected by click and wheel scrolling works inside the active panel
- Added left-click navigation in setup wizard splash/outro screens to advance or exit without pressing Enter
- Added
benchCLI command to benchmark model selectors with a shared prompt and report time-to-first-token and throughput - Added
omp benchoptions--runs,--max-tokens,--prompt, and--jsonto control run count, response length, prompt text, and machine-readable output - Added benchmark failure reporting that shows per-run errors, flags failed runs in the summary, and exits with a non-zero status when any model benchmark fails
- Added
snapcompact.shapesetting to pick the frame variant snapcompact prints text with —auto(each provider's eval winner) or any research-eval variant: the square grids (8x8r/8x8u/6x6u/5x8× sentence-hue/black ink) and the per-model winners (6x12-dim,8x13-bw,8on16-bw,doc-8on16-bw,doc-8on16-sent,doc-8on16-sent-dim); applies to both the compaction archive and inline system-prompt/tool-result imaging
Changed
- Updated
snapcompact.shapeoption help text so theautomode and8on16-bwdescriptions now reflect OpenAI’s current default and GPT winner variants - Model selectors keyed by retired effort-tier variant ids keep resolving after catalog collapsing: reference resolution and bare-id matching consult the hand-table aliases (
gemini-3.5-flash-low,gemini-pro-agent, recycledgemini-3-flash) plus theX-thinking→Xgrammar for auto-collapsed pairs, with exact matches always winning while a raw id is live; explicit:effortsuffixes transfer unchanged. models.ymlmodelOverridesand rate-limit selector suppressions keyed by raw member ids re-key onto the collapsed model - Custom/config provider model lists now collapse
X/X-thinkingtwins at registry rebuild (collapseBuiltModelVariants), folding config-defined twins into one entry whose thinking toggle routes to the-thinkingbacking id
Fixed
- Fixed Ctrl+T thinking-block toggles clearing the pending user message and loader before the assistant stream starts (#2370).
- Fixed Windows CodeGraph MCP launches from npm
.cmdshims by resolving the shim's Node entry point and spawning it directly, keeping stdio attached to CodeGraph instead of the transientcmd.exewrapper (#2367). - Fixed snapcompact archives going partially unreadable on OpenRouter, which hard-caps requests at 8 images and silently drops the excess: compaction now passes a provider-aware frame budget (
providerFrameBudget) so the archive never exceeds the cap (unknown providers get a safe floor of 5), with overflow kept as a text tail on the summary instead of rendering frames the gateway would drop; inline system-prompt/tool-result imaging shares the same per-provider budget (providerImageBudget), so once existing images exhaust it (e.g. 8 archive frames on OpenRouter) tool results ship verbatim as text - Fixed Hindsight retains to send offset-aware local timestamps instead of UTC
Zstrings so extraction prompts keep the user's local time-of-day context (#2363). - Fixed tool calls taller than the viewport reading as cut off while streaming (the head reappeared only once the result landed): the 15.11.6 stranded-preview fix marked every collapsed pending tool preview commit-unstable, which also blocked durable top-anchored streams — e.g. a task call's context/assignment markdown — from reaching native scrollback mid-run. Commit stability is now classified per renderer (
ToolRenderer.provisionalPendingPreview): only the tail-window previews the result render re-anchors (edit/apply_patch streamed-diff tails, bash/ssh command caps, eval cells with interleaved outputs) stay provisional; every other pending preview commits its settled head mid-stream again - Fixed
omp benchreporting "tokens 0, TPS 0.0" successes on repeated OpenRouter runs: pi-ai opts every OpenRouter request into response caching, so bench's byte-identical request replayed a cached generation with zeroed usage at edge speed. Bench now sendsX-OpenRouter-Cache: falseso every run measures a fresh generation - Fixed
omp benchfailing with HTTP 400{"detail":"Instructions are required"}againstopenai-codexmodels: bench requests now carry a minimal default system prompt (same guard as eval's completion bridge) - Fixed pressing
Ctrl+T(toggle thinking blocks) — or hitting any other rebuild path such as the theme/preset selector — during the pre-streaming window after a submission erasing the just-submitted user message until the first assistant token arrived: the user message is rendered optimistically beforesession.prompt(...)lands it in session entries, sorebuildChatFromMessages()had no record of it; it now replays an in-flight optimistic submission after rebuilding the transcript, gated onoptimisticUserMessageSignature(cleared byEventControlleronce the realmessage_startlands) so it cannot duplicate post-streaming (#2372).
[15.11.6] - 2026-06-12
Changed
- Renamed the saved Codex reset command from
/reset-usageto/usage resetand added/usage showas an explicit alias for plain/usage.
Fixed
- Fixed the Subagents HUD order so progress updates no longer move active rows; batched subagents keep their task order.
- Fixed
/settingsdirty-value highlighting so changed values stay orange while the row has keyboard focus.
[15.11.5] - 2026-06-12
Added
- Added
codexResets.autoRedeem,codexResets.minBlockedMinutes, andcodexResets.keepCreditssettings so Codex users can opt in to automatic spending of saved rate-limit resets - Added automatic Codex reset redemption flow so a blocked weekly usage-limit request can be retried immediately after consuming a saved reset when auto-redeem is enabled
- Added
--historymode toomp usageto show recorded usage-limit history instead of a single live snapshot - Added
--days(-d) support foromp usage --historyto control the history window (default 7 days) - Added historical usage output for
omp usage --history, including per-limit sparklines with latest and peak percentages - Added
--jsonsupport inomp usage --historyto emit timestamped usage-history snapshot data - Added guidance and exit code 1 when no usage history is available for the selected window
- Added an anchored Subagents HUD above the editor (next to the Todos block) listing every running subagent as
Id: description; rows appear on spawn and the block clears itself when the last subagent finishes - Added
/reset-usagecommand to spend a saved Codex rate-limit reset by running/reset-usage <active|account id|email>, with a TUI selector flow for interactive reset redemption - Added
snapcompact.systemPromptenum modesnone,agents-md, andall, so users can disable system-prompt imaging, image only loaded AGENTS.md/context-file instruction sections, or image the full system prompt - Added
agents-mdsnapcompact mode that rasterizes AGENTS.md-style context sections from the system prompt into frames and appends them to the first user message /context(TUI panel and ACP report) now shows estimated snapcompact wire savings whensnapcompact.systemPromptorsnapcompact.toolResultsis enabled — per-feature text → frames token deltas, the reason a swap does not apply (savings margin, image budget, or text-only model), and the estimated size of the next request. The estimate and the live provider-request transform share one planner (planInlineSwaps) so displayed numbers cannot drift from wire behavior.- Added
/debug dump-requestand/debug next-requestas aliases for/debug dump-next-requestwhen arming a one-shot AI provider request dump - Added
/debug dump-next-request <path>to dump the next AI provider HTTP request JSON to a chosen file.
Changed
- Changed usage views (
/usagereports, status summaries, and account headers) to show available saved Codex rate-limit resets and point to/reset-usagefor spending them - Changed
/contextsystem-prompt savings lines to show the scope asAGENTS.mdorall, so savings estimates now indicate whether imaging applied only to context-file instructions or the entire prompt - Changed
/debughandling in interactive mode so/debugwith arguments now executes the requested debug subcommand instead of always opening the debug selector - Changed
/debug dump-next-requestpath handling to expand~and resolve relative paths against the current working directory - Changed the task tool's TUI block: the header now shows the task dispatch glyph (
tool.task) while agents are in flight instead of a spinner (async spawns return immediately, so a spinner misread the call as blocking), and per-agent rows use one static dot for every state — completed rows keep the same dot and settle from accent to the plain foreground color instead of switching to a different status glyph - Compressed the
eval,browser,read, andirctool prompts (6156 → 4932 tokens o200k, −20%): deduplicated claims across sections, tightened helper reference descriptions, trimmed redundant examples; input grammar, examples, and template conditionals (py/js/spawns, read display modes) unchanged - Changed the Nerd Font
tool.taskicon to the Octicons tasklist glyph.
Fixed
- Fixed settings search to rank matching tabs by relevance so exact matches appear before incidental matches
- Fixed the
/settingssearch bar ignoring regular editor hotkeys: the query is now a real single-line input with cursor movement (←/→, word jumps, Home/End), word deletion (Alt+Backspace,Ctrl+W), kill/yank, undo, and paste support - Fixed snapcompact
toolResultsimaging confusing models into reporting tool malfunctions: the note prepended to rasterized tool results now tells the model the result is in the PNG frame(s) below and that the image delivery is deliberate, not a tool error, instead of the bare[Rasterized]marker - Fixed tool-call boxes rendering "inside themselves" after slow tool runs: a pending collapsed preview that sat byte-static past the stable-prefix window (e.g. an edit's tail-window diff while the apply + LSP pass ran) had its settled head committed to native scrollback, and the result render then stranded that stale call-box fragment above the final block. Pending collapsed tool previews are now provisional (
isTranscriptBlockCommitStable) and never enter scrollback mid-run; expanded top-anchored streams keep committing mid-stream - Fixed the higher-level Responses retry classifier to recognize OpenAI Zero Data Retention rejections (
Previous response cannot be used for this organization due to Zero Data Retention) as stale-replay errors. The provider-level fix in@oh-my-pi/pi-aicovers the common case in a single turn; this layer additionally guarantees that any ZDR error that still bubbles up resets the Responses session and retries at zero backoff instead of falling back to a different model (#2341).
Removed
- Removed the todo task notes feature:
op: "note", thetextpayload, tasknotesstate, markdown note blocks, and note rendering are no longer supported.
[15.11.4] - 2026-06-12
Added
- Added mouse-driven interaction to
/settings, including tab and setting row hover highlighting, wheel scrolling, and left-click activation for entries and submenus - Added fullscreen
/settingsmouse-event handling so scrolling and clicks work in an alternate-screen overlay ModelRegistry.resolvernow accepts a model directly —resolver(model, sessionId)— derivingprovider,baseUrl, andmodelIdfrom it; all model-scoped call sites migrated from the verboseresolver(model.provider, { sessionId, baseUrl, modelId })form.- Added experimental
snapcompact.systemPromptandsnapcompact.toolResultssettings (off by default,/settings→ Context → Experimental) that render the system prompt and large historical tool results as dense snapcompact PNG frames on vision-capable models to cut token cost. Frames are built per-request in the provider-context transform, cached across turns, capped by a per-provider image budget, and gated on a token-savings estimate — they never reachsession.jsonl. - Added a Personality selector to
/settings(Model → Prompt):default(the previous built-in reply style),friendly,pragmatic, ornone. The selected spec renders into a dedicated<personality>system-prompt block (extracted from the former<reply-guidelines>section) and applies to the live session immediately; subagents always omit the block. - Added
mnemopi.polyphonicRecallandmnemopi.enhancedRecallconfig.yml settings (off by default,/settings→ Memory → Mnemopi) that enable the mnemopi 4-voice polyphonic recall engine and the tiered query result cache without environment variables;MNEMOPI_POLYPHONIC_RECALL/MNEMOPI_ENHANCED_RECALLstill override the configured values when set (#2323).
Changed
- Changed
/settingskeyboard navigation soTabandShift+Tabtoggle focus between section headings and setting rows in sectioned lists, with↑/↓jumping sections,←/→switching tabs, and status text reflecting the active controls - The
tasktool description now mandates batching parallel spawns into one call'stasks[](sharingcontextonce) instead of presenting multipletaskcalls per message as an equal alternative; separate calls are reserved for different agent types or unrelated context - Updated
/settingson-screen navigation hints to match the new section-focus behavior (↑/↓andTab/Enter) and tab-switching arrows - Changed
/settingsto open as a full-screen overlay on the alternate screen so it no longer shares space with the underlying transcript - Codex, Gemini, and Perplexity web search now route their OAuth bearers through the new
withOAuthAccessdriver: a 401 or usage-limit force-refreshes the same account and then rotates to a sibling instead of failing the search, while identity metadata (chatgpt-account-id, GoogleprojectId) is re-derived from the refreshed credential on every retry. - Kagi web search, the xAI TTS tool, and model-discovery list fetches now resolve their bearers through
withAuthwith an auth-storage resolver instead of a one-shot key snapshot, gaining the same force-refresh + rotate retry on 401. - Compaction, handoff, and branch-summarization call sites now hand the compactor a per-candidate API-key resolver (availability still gated on a key snapshot), so credential refresh happens before the #986 fallback-model loop advances.
- The mnemopi backend now passes an OpenRouter resolver for default embedding/extraction setups (AuthStorage-stored keys included), keeping pinned literal keys and custom endpoints unchanged.
- Reorganized the
/settingspanel for findability: every tab now has titled sections backed by a per-tab layout contract (TAB_GROUPS); on wide terminals the panel renders a section sidebar with the active section's settings beside it (narrow terminals keep a flat list with inline headings), and PgUp/PgDn jump section-to-section. The Editing tab became Files (edit/read/LSP) and a new Shell tab hosts bash, eval, and Python settings. Misplaced settings were rehomed: bash toggles united under Shell, tool approval mode and policies together under Interaction → Approvals, marketplace auto-update next to startup update checks, and the todo auto-clear delay beside the other todo settings. - Restyled the
/settingschrome: the tab strip moved below the content as a label-less footer, the panel keeps one constant height across navigation, value changes, and submenus (no more viewport jumps after each change), and typing now runs a global cross-tab search — results group under per-tab headings, the footer shows live match counts with non-matching tabs muted, Tab hops between matching tabs, and Esc exits search landing on the selected result's tab. - Normalized
/settingslabels and descriptions: consistent Title Case labels (e.g. "Todo Auto-Clear Delay", "GitHub View Cache"), uniform unit placement, articles and verb-first phrasing in descriptions ("If false…"/"Whether to…" rewritten), and a stale browser-tool description (Ulixee Hero) corrected to the actual puppeteer/Chromium implementation. /settingssection headings are now underlined — the active section's heading stays bold, and headings outside the active section render dim with the same underline — so section boundaries read at a glance./settings: Tab now toggles keyboard focus between section headings and the setting rows — while headings are focused, ↑/↓ jump whole sections and Enter/Esc drop back into the rows — instead of cycling tabs. ←/→ still switch tabs everywhere, tabs without sections (e.g. Plugins) keep Tab as tab-switching, and the footer hint follows the focus state.- Image-generation (Antigravity, xAI, OpenRouter, Gemini) and xAI TTS request failures now throw pi-ai's typed
ProviderHttpErrorcarrying status and response headers instead ofObject.assign-patchedErrors. - Collapsed bash, ssh, and eval previews now cap the command/code section to a viewport-sized tail window (terminal rows minus a chrome reserve) that renders identically while streaming and after completion, with
ctrl+oas the only way to uncap. Previously bash/ssh capped the command only while streaming and snapped it fully open the moment the tool finished, and eval never capped cell code at all. - The
jobrenderer now shimmers running-job labels while the poll block is live, freezing to static once the block seals, and drops the id column when the label repeats it — task jobs label themselves with their agent id, so rows read⟨task⟩ SessionTreeinstead ofSessionTree ⟨task⟩ SessionTree. - Task progress rows now render static text with the task icon instead of shimmering the description or showing the pending/hourglass status glyph.
app.clipboard.pasteImage(Ctrl+V) now falls back to pasting clipboard text when no image is present, so hosts that deliver only that chord (VS Code's integrated terminal forwardingCtrl+V, Windows clipboard history viaWin+V) cover both payload kinds; WSL text reads now reach the Windows clipboard through host PowerShell like image reads already did (#1628).- Changed
/usageto show the OAuth account currently selected for the active model provider when usage reports include multiple accounts, making multi-account sessions easier to verify without marking unrelated providers.
Fixed
- Fixed session tree connector rendering in
/treeand the HTML export: flattened chain rows under a last-sibling (└─) branch drew a dangling│in the corner column itself and shifted columns once the chain branched deeper; the chain anchor now sits one level right, below the branch head's content, so connectors terminate at└─and indentation stays stable (#2325). - Fixed prompt and image input typed while the agent is idle between turns from being dropped so steering now queues and auto-resumes processing once the session is ready
- Fixed image-bearing prompts queued during compaction registering their local-submission signature without the image count, so the delivery event treated them as foreign messages — clearing any draft typed since queuing and leaking the stale signature.
- Fixed Esc/Alt+Up queue restoration dropping attached images:
clearQueue()andpopLastQueuedMessage()now hand queued images back alongside the text, and the restore paths return them to the pending-image buffer instead of silently discarding them. - Fixed a failed steer submission in the no-input-waiter path discarding the message: the text and images are restored to the editor for retry instead of being lost to history-only recovery.
- Fixed local memory consolidation on Responses-style models that reject user-only requests by sending a dedicated stage-two system prompt.
- Fixed the settings sidebar divider alignment in
/settingsby locking sidebar width to the widest group name so switching tabs no longer shifts the layout - Fixed plan-review overlay mouse hit-testing so wheel, hover, TOC, and body clicks map to the intended regions
- Fixed
lsp.formatOnWritesending a hardcodedtabSize: 3, insertSpaces: trueon everytextDocument/formattingrequest, which silently re-indented 2-space YAML (and any LSP-formatted file) to 3-space on every write/edit through formatter-aware servers likeyaml-language-server. Format options are now resolved per-file from.editorconfig(indent_size,indent_style,tab_width), falling back to the indent sniffed from the in-memory content the agent is about to write, then to a 2-space default. The duplicateDEFAULT_FORMAT_OPTIONSconstant inlsp/index.tsandlsp/clients/lsp-linter-client.tsis replaced with a single sharedresolveFormatOptionshelper (#2329). - Fixed stale OpenAI Responses replay failures such as
Item with id 'rs_...' not found.by resetting the provider session and retrying without advancing fallback chains. - Fixed
/settingsEscape handling so an open submenu receives Esc and returns to the settings list before a second Esc closes the panel (#2331). - Fixed Escape not closing
/settingson the Plugins tab while the async plugin list is still loading:PluginSettingsComponentnow closes on Esc while no child view is mounted, and an npm plugin registry listing failure is caught (like marketplace failures) so a bad registry no longer leaves the tab permanently blank (#2331). - Fixed unconfigured
pi/smol,pi/slow, andpi/designeragent model roles using cloud-priority defaults before the user's configuredmodelRoles.default, which could route local-default setups to authenticated paid providers (#2336). - Fixed
issue://reads failing on older GitHub CLI releases that reject the optionalstateReasonissue JSON field; single issue reads now retry without it and issue listings no longer request it (#2333). - Fixed image generation ignoring
/login-stored OpenRouter and Google API keys: provider selection and requests now resolve through the model registry (with env-var fallback) instead of environment variables only. - Fixed detached (
taskasync spawn) progress snapshots repainting commit-eligible rows after the block leaves the live transcript region; later partial snapshots are dropped while the final completion snapshot still applies. - Fixed five consumers treating Zod tool-parameter schemas as plain JSON Schema objects, leaking schema-instance internals (
def,shape, methods stringified asundefined) or silently reading nothing:/dumpand the RPCget_statedumpToolspayload now convert parameters through the same wire-schema conversion providers receive; context-usage token estimation no longer stringifies the Zoddeftree (overcounting tool schema tokens in the status line); tool-discovery search indexing recoversschemaKeysfrom Zod tools (previously empty, weakening BM25 ranking); and the extension inspector panel renders Zod tool arguments instead of "(no arguments)".
[15.11.3] - 2026-06-11
Fixed
- Fixed stale
Working…loader rows being committed to native scrollback above the live loader: the interactive status container now reports a live-region seam while it has mounted content (#2328 by @35844493). - Fixed Mnemopi memory consolidation never running on session shutdown:
MnemopiSessionState.dispose()now drains pending fact extractions and runssleepAllSessionson every owned bank before closing handles (andAgentSession.dispose()awaits the result), matching the/memory enqueueslash command.mnemopiBackend.clearopts out viadispose({ consolidate: false })so the destructive/memory clearpath does not spend tokens consolidating memories that are wiped on the next line.consolidate()deliberately keeps noaliasOfshort-circuit so/memory enqueuefrom a subagent still flushes and sleeps the parent's shared banks (the alias guard lives indisposefor lifecycle, not inconsolidatefor content). Without this,episodic_memory,gists,consolidation_log,graph_edges, andtriplesstayed empty for every deployment because the SHMR/beam pipeline only ran when a user typed/memory enqueue|rebuild(#2320). - Fixed multi-path
searchcollapsing distinct scopes into one walk rooted at their unrequested common ancestor:paths: [".", "~/.gitconfig"]scanned the entire home directory (typically until the 30s grep timeout), and explicit file entries inside walker-pruned directories (e.g..git/config, gitignored files) silently never matched because they were folded into the directory walk's glob union. Multi-path scopes now fan out into per-target scans when the common ancestor is not itself a requested path, plain-file entries are read directly as their own targets, and matches from overlapping targets are deduplicated. - Fixed
lsp.formatOnWritesending a hardcodedtabSize: 3, insertSpaces: trueon everytextDocument/formattingrequest, which silently re-indented 2-space YAML (and any LSP-formatted file) to 3-space on every write/edit through formatter-aware servers likeyaml-language-server. Format options are now resolved per-file from.editorconfig(indent_size,indent_style,tab_width), falling back to the indent sniffed from the in-memory content the agent is about to write, then to a 2-space default. The duplicateDEFAULT_FORMAT_OPTIONSconstant inlsp/index.tsandlsp/clients/lsp-linter-client.tsis replaced with a single sharedresolveFormatOptionshelper (#2329).
[15.11.2] - 2026-06-11
Added
- Added the Expert Elixir language server (
expert, invoked asexpert --stdio) to the built-in LSP server list, auto-detected for Mix projects (mix.exs/mix.lock). When both are installed,elixir-lsremains the primary navigation server (Expert is ordered after it). - Added
magicKeywords.enabledand per-keywordmagicKeywords.ultrathink,magicKeywords.orchestrate, andmagicKeywords.workflowsettings to disable hidden magic-keyword notices and ultrathink auto-thinking escalation (#1796). - Added external-editor support for Plan Review section annotations, preserving multiline feedback for Refine plan (#2305).
- Added plain-RPC slash command discovery with command source metadata and startup/update notifications (#2261).
Changed
- Bash tool calls in one assistant message now run in parallel instead of serializing the batch: non-pty
bashis scheduled as a shared tool (pty: truestays exclusive), and overlapping calls on the same shell session key degrade to isolated one-shot shells so they cannot queue behind or abort each other
Fixed
- Fixed CDP attach target selection for Chromium/Edge endpoints that expose page targets through discovery before
browser.pages()is populated, and improvedws://app.cdp_urldiagnostics (#2246). - Fixed local memory consolidation on Responses-style models that reject user-only requests by sending a dedicated stage-two system prompt.
- Fixed extension, custom-tool, custom-command, and hook loaders injecting
pithrough bare@oh-my-pi/pi-coding-agentself-imports, which could pull a different cached package version into global installs during plugin load and trigger mixed-runtime stack overflows. - Marked unsmoothed assistant streaming renders as transient so streamed code blocks can avoid synchronous syntax highlighting until the message finalizes.
- Routed LSP hover code rendering through the shared cached highlighter instead of calling the native highlighter directly on each render.
- Kept smooth assistant streaming renders transient until
message_endso catch-up frames do not synchronously re-highlight still-growing code blocks. - Fixed the
jobtool's poll header repeating the running count ("waiting on 19 of 19 19 running"): the title now reads "waiting on N jobs" (or "waiting on N of M jobs" when some settled) and the dim meta lists only settled categories (done/failed/cancelled) - Fixed
ircsend await:trueto a busy peer stranding the sender until timeout when async execution is disabled: the recipient (e.g. Main blocked in a synchronous task spawn awaiting the sender's own batch) can never reach a step boundary to reply, so it now generates an ephemeral side-channel auto-reply from its context (the pre-mailboxrespondAsBackgroundbehavior), records it as anirc:autoreplyaside in its own history, and delivers it back over the bus withreplyTothreading - Fixed Windows-style backslash paths and globs being parsed as literal POSIX path segments by search/find tools (#2245).
[15.11.1] - 2026-06-11
Added
- Added the
statusLine.transparentappearance setting (default off): when enabled, the status line skips the theme'sstatusLineBgfill and powerline end caps so the bar inherits the terminal's default background — useful in Ghostty and other terminals whose theme background does not match the theme's hardcoded status-line color (#2306)
Changed
- Changed
display.smoothStreamingto animate streamed tool-call arguments (including write/edit/bash previews) at the smooth streaming cadence so partial tool input now appears progressively instead of in large jumps - Changed streamed updates for custom wire tools to render incremental raw input as
{ input }prefixes for preview async.enablednow defaults totrue, keeping background task execution and async bash available out of the box; disable it to force blocking subtasks (#2301).- Shortened the status line's background-job indicator to a dedicated gear icon plus count (e.g.
⚙ 1instead of👥 1 job running) and moved it left of the session name in the right segment group
Fixed
- Fixed the task tool's streaming call preview rendering the per-agent list above the shared context/assignment briefs: agent rows now render below them, matching the result layout, so the list no longer pushes the brief down as items stream in and then jumps below it once the first progress snapshot arrives
- Fixed interrupted or ending tool calls to flush streamed argument previews to the full received payload instead of freezing on a partial reveal chunk
- Fixed tool-argument reveal to avoid splitting UTF-16 surrogate pairs at frame boundaries
- Fixed input lag in long sessions whenever a spinner was visible: loader ticks forced a full TUI re-compose (re-walking every transcript block) 12.5 times per second. Animations that only change their own rows (status loaders, welcome intro, voice mic glyph,
/btwstreaming panel) now use the new component-scoped render path (TUI.requestComponentRender), which reuses every other root subtree's rows; resize, overlays, inline images, forced repaints, root-list changes, or any concurrent full request still compose the full frame - Fixed transcript rendering so blocks with rows committed to scrollback while still streaming rerender on the first finalized frame, so the final committed output is visible instead of stale in-flight lines
- Fixed committed transcript bypass logic to re-render finalized blocks when their version changes, so post-finalization updates like restored inline errors and late tool-result content now appear in scrollback
- Cached stable edit/write preview highlighting inside each tool component so steady-state frame renders do not re-enter the native syntax highlighter.
- Skipped rendering finalized transcript blocks whose rows are already committed to native scrollback, keeping long restored sessions from re-rendering historical tool blocks every frame.
- Fixed MCP OAuth authorization and token requests to include the required
resourceindicator for the target MCP server. - Restored
async.enabled=falseas the task tool's blocking mode, so subagents no longer become background jobs when async execution is disabled (#2301). - Fixed the
/treeselector and HTML session export dropping the inherited│gutter for chain rows under a last-sibling branch, so the conversation flow under a└─branch stays visually anchored to its parent message (#2298). - Fixed Anthropic web search requests to include
metadata.user_id, matching the main Messages path: API-key requests forward the active session id verbatim, OAuth requests build the Claude-Code-shaped{session_id, account_uuid?, device_id}JSON envelope so gateways see consistent attribution (#2295). - Fixed Anthropic classifier refusals to switch through configured retry fallback chains without same-model retries, and to keep the fallback pinned for the conversation. (#2290)
- Fixed the edit-tool hashline prompt to stop steering agents toward
insert after block N:on closing delimiter lines; opener-only block anchors now point visible closing-line insertions to plaininsert after M:. (#2292)
[15.11.0] - 2026-06-10
Breaking Changes
- Removed the
resumeoption from thetasktool API and its resume execution path; continue work on finished subagents by sending follow-up messages viaircinstead - Removed the
irc.enabledsetting: irc availability is now derived — the tool exists exactly when there is someone to message (the session can spawn subagents throughtask, or it is a subagent itself). A staleirc.enabledkey in config is ignored - The
tasktool was reworked to always run spawns in the background as independent, persistent agents: results arrive as async job deliveries (block withjob pollonly when genuinely needed). The wire schema is now shape-swapped by the newtask.batchsetting (default on):{ agent, context, tasks[] }— one subagent per task item, per-itemisolated, and a required sharedcontext— or, when disabled, a flat single-spawn shape{ agent, id?, description?, assignment, isolated? }with shared background passed vialocal://files instead - Removed the
task.simplesetting and the task tool's per-callschemaparameter outright: structured subagent output now comes only from the agent definition'soutputfrontmatter or the inherited session schema, and ad-hoc structured workflows use evalagent(prompt, schema). A staletask.simplekey in config is migrated away - Reworked
irctosend/wait/inbox/listops over a per-agent mailbox bus: the blockingawaitReplyauto-reply turn is removed —sendis fire-and-forget with delivery receipts, and replies are real turns by the recipient observed viawait(or thesendawait: truesugar) - Removed the
contextargument from evalagent()in both the JS and Python preludes: pass shared background via alocal://file referenced in the prompt - Replaced the standalone session-observer overlay with the Agent Hub:
app.session.observe(ctrl+s) now opens the hub, whose chat view absorbed the observer's transcript renderer
Added
- Snapcompact compaction now passes the session model so frames render in the provider-optimal shape (unscii
8x8r-bwfor Anthropic-family/unknown APIs,8x8r-sentfor Google, Lanczos-stretched6x6u-sentwithdetail: "original"for OpenAI), per the snapcompact 200k-token evals - Added per-turn supersede pruning of stale
readresults: when a file is re-read, older copies of the same path/selector are pruned from context at cache-favorable moments (small suffix, idle gap, or alongside overflow pruning). Gated by the newcompaction.supersedeReadssetting (default on) - Added soft request budgets for task subagents (explore/quick_task 40, others 90, configurable via
task.softRequestBudget, 0 disables): crossing the budget injects a one-time wrap-up steer into the child; crossing 1.5× aborts the run gracefully - Added cancelled/aborted subagent salvage: instead of
(no output), merged task results now carry the child's last activity snippet plus request/token stats, and per-child stats lines include request counts - Added a repeat-read notice to the
readtool: the third and later reads of the same file in a session append a one-line note suggesting range re-reads or the context echoed in edit results - Added a hard inline byte cap (~50KB) at the bash and browser tool-result boundaries with head/tail elision and an
artifact://footer for the full output, closing paths that previously let 100KB+ results land inline - Added the Agent Hub overlay (
ctrl+s,alt+a, or double-tap left arrow on an empty editor): a live table of registered subagents (status, unread IRC count, current task, last activity) with per-agent chat — Enter opens a transcript + input line that steers a running agent, prompts an idle one, and revives a parked one;rrevives andxaborts/releases the selected agent - Added the
snapcompactcompaction strategy (compaction.strategy: "snapcompact"): history is archived onto dense bitmap "snapcompact" frames a vision model reads back directly, instead of an LLM-generated summary — instant, free, and verbatim. Auto compaction (including overflow recovery) and manual/compactboth honor it; falls back to context-full with a visible warning notice when the current model is text-only (e.g. Codex API surfaces) or when/compactis given custom instructions. Frames survive context rebuilds and later compactions (budget eviction is middle-out: the session-head frame is pinned); the expanded compaction message notes the attached frame count - Added a persistent subagent lifecycle: finished subagents stay live as
idle, are parked to disk aftertask.agentIdleTtlMs(default 7 minutes;0keeps them live until exit), and are revived automatically when messaged or prompted from the Agent Hub - Added the
history://protocol:history://lists every registered agent andhistory://<agentId>renders a concise markdown transcript (tool calls collapsed to one line each, thinking elided) for live and parked agents alike - Added an IRC mailbox bus with bounded per-agent inboxes:
ircwaitblocks until a matching message arrives,inboxdrains or peeks pending messages, and sending to an idle or parked agent wakes or revives it for a real turn - Added a dedicated TUI renderer for the
irctool: directional send/receive headers with delivery-outcome coloring, quoted message bodies with expand-aware truncation, per-recipient receipt trees for broadcasts and failures, and status-badged peer listings with unread counts - Added the
task.batchsetting (default on): the task tool's batch shape{ agent, context, tasks[] }spawns one subagent per item — each its own independent background job with the normal idle/parked lifecycle and optional per-item isolation — and prepends the required sharedcontextto every spawned subagent's system prompt; disabling it restores the flat single-spawn schema
Changed
- Changed task-tool sync execution to fan out multiple
tasks[]items in parallel and return a merged result payload when no async job manager is available - Changed the compaction UX so the conversation no longer visually restarts: the TUI renders the full-history display transcript (
buildSessionContext({ transcript: true })), with each compaction shown as a slim inline divider —── 📷 compacted · ctrl+o ──— at the point it fired; expanding (ctrl+o) reveals the summary and snapcompact frame count. Applies to live compaction,/compact,/treenavigation, and session resume - Changed
async.enabledto gate async bash commands only — thetasktool now runs asynchronously regardless of the setting - Changed
irc.timeoutMsto be the default timeout forircwaitandsendwithawait: true - Moved the grouped path-tree helpers (
buildPathTree,walkPathTree, find's grouped output formatter — nowformatGroupedPaths) to@oh-my-pi/pi-utilsso compaction summaries can render file lists with the same prefix-folded tree as find/search;tools/findno longer exportsformatFindGroupedOutput - Changed TTSR rule notifications to combine rules into one block: a multi-rule match renders
name: descriptionrows (collapsed view caps at 4 rules with a+N morehint, ctrl+o expands), and consecutive notifications merge into the previous block while it is still the live transcript tail
Removed
- Removed the pre-initialization startup splash and input buffer, so commands typed during launch are no longer queued and are handled only after the interactive TUI initializes
Fixed
- Fixed
irclive message delivery so successfully handed-off messages are no longer enqueued as mailbox mail, so they do not inflate unreadirccounts - Fixed
irc sendwithawait: trueto wait for a fresh reply to the current call instead of consuming previously buffered messages - Fixed main-session chat output to stop duplicating outbound
ircsends from the main agent as relay cards - Fixed task-tool runtime compatibility so legacy flat
taskcalls (agent,assignment) still execute undertask.batcheven though the wire schema is batch-first - Fixed the
jobtool's TUI preview leaking the model-facing<task-result>envelope for settled task jobs — the preview now shows the inner output body, and pretty-printed JSON bodies are flattened onto one line instead of previewing a lone{ - Fixed npm CLI distribution bundles by embedding the stats dashboard client bundle so dashboard assets are served in prebuilt installs
- Fixed the
resolvetool's result block turning white after the leading icon: the accent-styled symbol embedded a foreground reset inside the inverse-rendered line, dropping the block color for the rest of the row - Fixed the CLI smoke-test command to start the stats server and verify dashboard HTML is served, catching bundled-asset regressions
- Added verification of a
<div id="root"></div>andindex.jsin smoke-test dashboard responses - Restored the checkmark glyph on ask-tool custom answers and the multi-select "Done selecting" option, which a status-glyph sweep had swapped for the ask tool icon
- Fixed the
thinking.autoPendingstatusbar indicator using question-mark glyphs (▣?, nf-md-help_box,[?]) in every symbol preset, which made the auto-thinking pending state indistinguishable from a terminal missing-glyph fallback. Replaced with clear loading indicators (⟳, fa-circle-o-notch,[~]) (#2267). - Fixed
tab.screenshot({ save })ignoring the save path's extension: an explicit.webp/.jpgdestination received hardcoded PNG bytes behind a mismatched name. The full-res capture format is now derived from the save path (png/jpeg/webp, puppeteer-native), and the reported mime type follows the bytes actually written; unknown or missing extensions still capture PNG - Fixed an infinite
compaction.strategy: shakeauto-continue loop in thinking-heavy sessions: the post-shake check now uses the provider-anchored trigger metric (instead of a local estimate that undercountsthinkingSignaturepayloads) and only treats pressure as resolved when residual context lands inside an 80% recovery band, so shake reliably falls back to context-full compaction when it cannot create real headroom (#2275).
[15.10.12] - 2026-06-10
Added
- Added RPC subagent subscription frames, snapshots, and transcript catch-up APIs for desktop clients embedding
omp --mode rpc. - Added opt-in
shellMinimizer.sourceOutlineLevelandshellMinimizer.legacyFilterssettings so shell minimization can tune source outlining and selectively fall back to conservative legacy routing. - Added repeatable
--config <path>CLI overlays for temporaryconfig.yml-style settings without editing the persistent global config (#1733). - Added
python.interpreterto pin eval's Python backend to an explicit interpreter and skip automatic runtime discovery (#1802). - Added
!commandresolution formodels.ymlproviderapiKeyvalues and provider/model headers (#1888). - Documented the oMLX setup path through existing OpenAI-compatible local discovery (#1957).
- Added
TITLE_SYSTEM.mddiscovery so users can override the automatic session-title generation prompt for online and local tiny title models without patching installed prompt files. The override is re-discovered when the session working directory changes via/cwd. - Added a structured memory runtime surface for extensions and UI integrations to query backend status, search memories, and save explicit memories across the configured memory backend.
- Added support for Git repositories using the
reftablestorage format by detectingextensions.refStorage = reftablein the repository configuration and falling back to shelling out to Git commands (git symbolic-ref,git rev-parse) for reference and HEAD resolution. - Added
/setup providers(also available as/setupor/providers) to reopen the interactive provider setup scene from an active TUI session, letting users sign in and choose a web search provider without rerunning the full onboarding flow.
Changed
- Bash execution now preserves minimized shell output inline while saving the untouched capture as an
artifact://…footer when shell minimization rewrites a command's output. - Task tool live progress now renders finished subagents first and keeps unfinished (pending/running) ones pinned at the bottom of the list.
OutputSinkartifact files (~/.omp/agent/artifacts/<id>.<tool>.log) are unbounded by default again, soartifact://<id>references preserve the complete raw stream. The head + rolling-tail capping machinery from #2081 (with its[ARTIFACT TRUNCATED: …]close notice) remains available as an opt-in viaartifactMaxBytes, and the head window now closes permanently on first overflow so later small chunks cannot be written out of order before the tail replay.
Fixed
- Fixed Ollama chat turns using the
:offthinking selector so requests explicitly send reasoning disablement instead of falling back to the provider default (#2239). - Fixed long-running sessions becoming sluggish because the status line recomputed context usage by walking the full message history on every refresh. Message-token totals are now cached incrementally, and status lines that do not render context segments skip context accounting entirely. (#2089)
- Fixed extension-registered slash commands being allowed to shadow builtin command names in the ACP/RPC command list: both the TUI and
getSessionSlashCommands()now filter against the shared builtin reserved-name registry. - Fixed ACP turns for extension slash commands finishing before nested
pi.sendUserMessage()prompts ran: the turn now drains scheduled extension prompts and prompt-event handlers before reportingend_turn, and prompts queued on a closed or disposed session fail fast with anACP_SESSION_CLOSEDerror instead of running against a dead session. - Fixed hide-secrets placeholders leaking into ephemeral side-channel turns (IRC replies, summary prompts): streamed text deltas are now deobfuscated before emission (withheld while a partial placeholder is still streaming) and the final assistant message is deobfuscated before reuse. Provider-context obfuscation moved into the agent loop's
transformProviderContexthook so request telemetry also captures the redacted context (#2146). - Fixed a failed
Settings.init()permanently poisoning subsequent initialization: the cached init promise is now cleared on error so a retry can succeed. - Fixed exiting plan mode without confirmation only when neither the default plan file nor slug-named local plan files contain draft content (#2024).
- Fixed
enabledModelsbeing ignored by the ACP model picker (Zed and other ACP clients) —AgentSession.getAvailableModels()now applies the configured allow-list, so only the models listed inenabledModelsappear in the UI. Also applies consistently to the RPCget_available_modelsendpoint and the/modelslash command. Glob selectors (anthropic/*), provider-scoped fuzzy patterns, and substring selectors now resolve in this synchronous path too, using the same scope semantics as startup resolution instead of being skipped with a warning. - ACP sessions now skip the client permission gate for bash/edit/delete/move when the user explicitly opts into yolo approval mode (
--yolo/--auto-approveor a configuredtools.approvalMode: yolo) and the effective per-tool policy is "allow"; default-config sessions keep the gate (#2097 by @Mokto) - Fixed hidden thinking blocks leaving placeholder
Thinking...lines in the transcript (#2068). - Fixed Hindsight
per-project-taggedscoping siloing retains/recalls per linked git worktree:projectLabel()now resolves the primary checkout root (or shared bare-repo common dir) via the new syncgit.repo.primaryRootSynchelper, so every worktree of one repo shares the sameproject:<name>tag andper-projectbank id (#2232). - Fixed MCP OAuth flows accepting pasted redirect URLs or authorization codes through
/loginin headless environments (#2122). - Forwarded model ids through
ModelRegistryAPI-key resolvers and Antigravity usage-limit rotation sopi-aican apply model-family-scoped OAuth quota backoff instead of treating allgoogle-antigravitycounters as credential-wide. (#2198) - Fixed bare
omp extensionsbeing treated as a chat prompt instead of returning an actionable plugin-command error (#2089). - Fixed hide-secrets redaction so configured secrets are scrubbed from provider-facing system prompts, tool definitions, developer/system-reminder messages, and assistant tool-call arguments before model requests (#2146).
- Fixed subagents looping indefinitely on byte-identical no-op
editcalls. The hashline executor previously surfaced a soft "your body row(s) are byte-identical to the file" hint that some models ignored; one captured session emitted 182 such repeats in 205 calls over 16 minutes before the user aborted. A new per-ToolSessionnoopLoopGuardnow tracks consecutive identical no-op payloads per canonical path and escalates to a thrownToolErrorafterNOOP_HARD_LIMIT(3) repeats, so the agent loop sees a tool failure and breaks the cycle (#2081). - Fixed the bash result renderer recomputing styled output (
split/replaceTabs/truncateToVisualLines) on every TUI repaint, which scaled with both transcript length and per-row output size. With a long captured session every keystroke walked hundreds of bash rows; the reporter on issue #2081 observed Ctrl+X/Ctrl+C feeling unresponsive because the main thread was pinned re-styling scrollback. The result renderer now caches its produced lines keyed by(width, previewLines, expanded, rawOutput, isPartial), mirroring the existing eval-renderer cache;invalidate()clears the cache as before. Hot-path repaints with unchanged inputs are now O(1) (#2081). - Fixed ACP
available_commands_updateto include extension-registered slash commands so clients like Zed surface them in the slash-command palette. - Fixed ACP cancel button leaving the session in a stuck state — a new prompt sent while a turn is still in-flight (e.g. immediately after pressing Stop in Zed before
session/cancelis processed) now implicitly cancels the running turn and queues the new message, instead of throwing an error that blocks further interaction. - Fixed interactive
!/!!shell shortcuts to run non-bash commands through the configured user shell, including interactive startup for zsh/fish aliases and functions (#1816).
[15.10.11] - 2026-06-10
Added
- Added
supportsReasoningParams,alwaysSendMaxTokens,strictResponsesPairing, and a recursivewhenThinkingoverlay (alongsidestreamIdleTimeoutMs/supportsLongPromptCacheRetention/requiresToolResultId/replayUnsignedThinking) to the OpenAI/Anthropiccompatschema so custom model entries can configure those provider-specific capabilities - Custom model
thinkingconfig now uses the catalog's explicit vocabulary:efforts(ordered list) plus optionaldefaultLevel,effortMap, andsupportsDisplayoverrides; the legacyminLevel/maxLevel/levelsrange shape is still accepted and normalized at parse time. Wire facts (effortMap/supportsDisplay) are backfilled from model identity when not set, so existing claude-proxy configs keep the 5-tier adaptive scale and summarized display without changes. - New
omp usagecommand: a detailed per-account breakdown of provider usage limits (bars, windows, reset times, plan metadata) covering every stored credential — accounts with no usage endpoint are listed as "no usage data" rows. Each provider section ends with per-window capacity stats ("capacity: 5h → 2.40/5 accounts used (2.60× quota left)"). Flags:--providerto filter,--jsonfor the broker-shaped report payload, and--redactto mask account emails/ids down to a two-char anchor plus a minimal middle-out differentiator (ca*9*) for screenshot-safe sharing. - Startup hangs are now self-diagnosing (speculative fix for the "zero output, hangs even on
omp -h" report class): a watchdog prints a stderr line every 10s naming the deepest in-flight startup phase (vialogger.openSpanPath()) until a mode runner takes over, pausing around legitimate interactive waits (fork/move prompts, the--resumesession picker);PI_DEBUG_STARTUPis restored as streaming synchronous[startup]phase markers covering command-module imports and the native addon load, which the post-startupPI_TIMINGtree structurally cannot show for a hang; and waiting on piped-stdin EOF announces itself after 1s instead of blocking silently. - npm installs now execute a prebundled single-file entry: the published
bin.omppoints atdist/cli.js(built byscripts/bundle-dist.tsduringprepack, ~18MB minified, natives/transformers/mupdf external), cutting npm-install cold start by roughly 3x versus transpiling the raw TypeScript graph per launch;src/**stays published for SDK consumers and worker fallbacks. The on-repo manifest keepsbin.ompatsrc/cli.ts— release rewrites it via thepublishBinoverride inscripts/ci-release-publish.ts— so source installs (bun link,install.sh --source) keep working without a build step - Plain interactive TTY launches render the full welcome box (logo held on the intro's first frame, model, tips, LSP servers, recent-sessions loading placeholder) before session construction, clearing the screen so the TUI's first paint replaces it in place; the welcome box now reserves fixed slot counts (4 recent sessions, 4 LSP servers) so its height no longer shifts between the splash, loading, and loaded states. First-run launches keep the dim two-line splash (
omp <version>/Initializing session…); resume/fork/continue flows, quiet mode,PI_TIMING, and non-TTY stdio still skip it - Added
/statsto launch the local stats dashboard from an active session, syncing session files first and opening the same browser dashboard asomp stats. /settingsnow supports type-to-search filtering on setting labels, paths, descriptions, and values; Escape clears an active search before closing the panel.- Added a read-only
viewop to thetodotool that echoes the current list without mutating state, so the agent can recover exact task text instead of guessing it from memory.
Changed
- Centralized model-identity logic in the new
@oh-my-pi/pi-catalogpackage:config/model-equivalence.ts,config/model-id-affixes.ts, andconfig/model-provider-priority.tswere removed in favor of@oh-my-pi/pi-catalog/identity, and the registry's proxy-reference lookup now shares the catalog's single lazily-built bundled-model walk (@oh-my-pi/pi-catalog/identitybundled accessors) with the canonical-equivalence index instead of walking the ~12K bundled models twice into duplicate maps - Split the configured/implicit provider discovery protocols (Ollama, llama.cpp, LM Studio, openai-models-list, proxy) out of
config/model-registry.tsintoconfig/model-discovery.ts; the registry keeps orchestration (caching, status tracking, merging) while the protocol clients take an injected fetch/auth context - Catalog values (bundled models,
modelsAreEqual,clampThinkingLevelForModel,getSupportedEfforts,DEFAULT_MODEL_PER_PROVIDER, Gemini/Antigravity wire headers) are now imported from@oh-my-pi/pi-catalog/<module>instead of the@oh-my-pi/pi-aibarrel, which no longer re-exports them; the resolver'sdefaultModelPerProvideralias was removed and its duplicated default-model fallback / scoped-model dedupe blocks were factored intopickDefaultAvailableModeland a sharedaddScopedModelhelper - Cached custom model alias maps and built them lazily on first custom model reference lookup, avoiding unnecessary startup model-registry initialization
- Cached resolved auth broker configuration and snapshot reads for the process lifetime so repeated startup paths reuse the same
OMP_AUTH_BROKER_*resolution instead of re-running config/token discovery - Reused task-agent discovery results for repeated
TaskTool.createcalls in the same working directory to avoid repeated plugin scans during subagent startup - SSH tool creation now formats host descriptions from synchronous host-info cache reads (memory hit or cached JSON) instead of per-host async reads — hosts without cached info render the existing placeholder; warm-cache descriptions are byte-identical
- Deferred heavy dependencies off the startup import graph to first feature use:
linkedom(web fetch feed parsing and scrapers),puppeteer-core/@puppeteer/browsers(browser launch),@mozilla/readability(page extraction),@xterm/headless(interactive bash PTY),@babel/parser(JS eval import rewriting), and the mnemopi memory engine (backend/state construction) - Renamed the
PI_TIMINGstartup phasediscoverModelstodiscoverAuthStorage— the timer only ever wrapped auth storage discovery - Worker threads (stats sync, browser tab, JS eval) and the tiny-model subprocess now re-enter the CLI entrypoint with hidden argv selectors (
__omp_*,--tiny-worker) via the declared worker-host entry (workerHostEntry()), collapsing the per-distribution spawn branches; outside a CLI host (bun test, SDK embedding) spawn sites fall back to loading the worker module directly, and both binary build scripts dropped their per-worker--compileentrypoint lists - The CLI entry no longer top-level-awaits
runCli— the floating call reports rejections to stderr and exits 1, keeping the entry module CJS-lowerable and the bundle parse-friendly - Tightened the system prompt and tool prompts: deduped restated warnings (bash "catch yourself" list, search/find shell-fallback recaps, read instruction/critical overlap, the AST metavariable primer duplicated across both ast tool descriptions), factored the repeated repo-default clause in the
ghsearch ops, dropped a deadrsedreference and an internaltool-timeouts.tspointer, and pruned internal mechanism the agent can't act on (screenshot temp-file/downscaling pipeline, browser spawn lifecycle,gh"replaces former op" history and run-watch grace period, output-minimizer heuristics, BM25 ranking name,task.maxConcurrencypointer) - Extended the prompt-efficiency pass to the full prompt surface (subagent/plan-mode/notice/title/commit system prompts, agent definitions, goals, memories, review and autoresearch prompts): RFC-keyed prescriptive prose, fixed garbled grammar and a stale
<PLAN_TITLE>placeholder in the plan-approval reminder, deduped intra-file restatements, and corrected thetodoop table's claim thatrmrequires atask/phase(barermclears the whole list) - Replace tool prompt no longer recommends
sed -i/cat-heredoc commands that the bash interceptor blocks; its bash-alternatives table now only lists non-intercepted commands - Capped concurrent IRC cards in the transcript's live region at 4: cards landing below a still-running tool cannot commit to native scrollback, so an unbounded burst pushed the live block's uncommitted rows above the window top (content read as cut off until the cards expired). The oldest live-region card now retires as soon as a new one would exceed the cap.
- Interactive PTY mode (
pty: true) no longer injects the non-interactive environment (TERM=dumb,GIT_EDITOR=true,PAGER=cat,NO_COLOR=1) that defeated its purpose — the PTY child now gets a realTERM=xterm-256color; and when a PTY is requested but unavailable (headless/RPC), the result now carries an explicit downgrade notice instead of silently running through a dumb pipe. - Raw sqlite
?q=queries are now capped at 1000 rows with an "add a LIMIT clause" notice —statement.all()on a multi-million-row table previously materialized every row, blocking the process for minutes. - Plain-file range reads no longer scan to EOF on files over 4MB just to count total lines (the count is reported as approximate), and multi-range reads slice from a single pass instead of re-streaming the file once per range.
gh run_watchnow polls adaptively (3s for the first minute, then 15s), survives rate-limit errors with backoff instead of dying and discarding accumulated context, reuses job data for completed runs, and gives up with a clear message after ~90s when a commit has no workflow runs at all (previously an infinite 3-second poll loop).- The legacy patch-mode fuzzy matcher pre-normalizes file and pattern lines once per seek with a Levenshtein lower-bound bail, replacing the per-position re-normalization that made a single mismatched hunk against a 10k-line file cost multi-second synchronous stalls; the streaming hashline preview also caches file text and tree-sitter block resolution across ticks instead of re-reading and re-parsing every target file per streamed chunk.
- The DAP client reader now uses chunk-list buffering and the output buffer is a chunk deque with a running byte count — debugging a chatty program previously cost O(n²)
Buffer.concatper chunk plus whole-buffer byte-scans per 1KB trim, freezing the session. - GitHub caching: the per-lookup auth key is memoized against
hosts.ymlmtime (was a blockingreadFileSyncon everyissue:///pr://read including cache hits), background refreshes are deduped by row identity, and PR diffs are stored once per row instead of twice (unified + rendered copies). - Task progress snapshots shallow-copy per-agent progress instead of
structuredClone-ing nested tool payloads (up to 500KB) on every progress event; streaming assistant-message reveal caches per-block grapheme counts and skips the markdown render LRU for in-flight partials, eliminating 2-3 full Intl.Segmenter walks per 33ms tick and tens of MB of retained stale partial snapshots on long replies. - Python eval cells: the availability probe is cached per cwd (was two interpreter spawns per cell even with a hot kernel), and stdout frames coalesce per write instead of one locked+flushed JSON frame each.
- Multi-entry edits now stop at the first failing entry and report exactly which entries were applied and which were not — continuing after a failure applied later entries authored against line numbers that assumed the failed entry succeeded, and a retry of the whole batch then double-applied the survivors.
- Decomposed
config/model-registry.tsfurther: model roles (MODEL_ROLES,getRoleInfo,getKnownRoleIds) moved toconfig/model-roles.ts, themodels.jsonconfig handle and provider validation moved toconfig/models-config.ts, the two provider+id merge scaffolds collapsed into onemergeByModelKeyhelper, the four ~15-field override/overlay enumerations now share aModelPatchtype applied by a singleapplyModelPatch(base, patch, transport)core (themergevsreplacetransport policies preserve the same-id custom-definition replacement semantics), and canonical-variant selection delegates to@oh-my-pi/pi-catalog/identity's newresolveCanonicalVariant - Resolver cleanup: five duplicated trailing-
:levelsuffix parses collapsed intosplitThinkingSuffix, the matching engine is now the documentedmatchModelcore with the selector grammar and entry points layered on top, andresolveCliModel's hand-rolled decomposed provider/id lookup reusesfindExactModelReferenceMatch; runtime discovery tests split out oftest/model-registry.test.tsintotest/model-discovery.test.ts TranscriptContainerassembles the transcript incrementally: each block's render is reference-compared and its stripped contribution, separator, and row placement are reused when unchanged, with the persistent row array truncated and re-pushed only from the first divergent block; the leading byte-identical row count is reported to the renderer through pi-tui's newRenderStablePrefixseam so off-screen transcript rows are no longer re-rendered, re-prepared, or re-audited every frame. Block components became reference-stable to make this effective:UserMessageComponentmemoizes its OSC 133 zone wrapping,WelcomeComponentandDynamicBordercache their renders, and dashboards copy before padding (render results arereadonlyunder the new pi-tui contract)- A live block whose trailing row grows in place as a visible prefix (token streaming into the cursor line) is now commit-safe through its full body instead of being held back by the volatile-tail margin — the growing row itself is the block's last and can never commit while it remains last, so a streaming reply's scrolled-off head reaches native scrollback (tmux pane history) mid-stream
- Rewrote the bash tool's coreutils guidance (tool prompt and system prompt) around an explicit litmus: pipelines that compute a new fact (
wc -l,sort | uniq -c,comm,diff) are legitimate bash, while commands that merely move, page, or trim bytes a dedicated tool can fetch remain banned — output trimming destroys data theartifact://capture would have saved. - Default API auto-retries now use 10 attempts with a 500ms Anthropic-style exponential backoff capped at 8s with jitter, so transient 502/gateway failures get a longer retry budget without multi-minute local sleeps.
Fixed
- Fixed
askquestion/result renders so option and answer rows are no longer duplicated when the component is re-rendered - Fixed streaming
write/diffpreviews to keep line-number gutter widths stable while content grows, preventing already-rendered preview rows from being reflowed mid-stream - Fixed the welcome screen showing "No LSP servers" when
lsp.lazyis enabled: recognized servers are now still discovered at startup and listed with a dim "available" dot (no warmup), and/statusreports them asavailableinstead of omitting the section - Fixed edit-tool diffs stacking adjacent
...markers around inserted block-context rows (each row added its own gap markers from a snapshot of the diff, so neighboring insertions doubled them, and a marker could be left stranded between contiguous lines): non-contiguous regions are now separated by a single blank row, normalized after insertion, and rendered as one dim…in the TUI and HTML export - Fixed an uncaught
questions.map is not a functionTUI crash in the ask tool's call renderer when a model double-encoded thequestionsarray as a JSON string (a bare string passes a truthy.lengthcheck but has no.map): the renderer now normalizes untrusted call args — parsing double-encodedquestions, dropping malformed entries/options, and falling back to the "No question provided" frame instead of throwing - Fixed direct
modelRolesconsumers so comma-separated fallback chains are split before model parsing, preserving explicit thinking selectors instead of treating the comma tail as an invalid suffix. - Fixed model-provider detection for append-only mode, authoritative Vertex endpoint checks, and upstream-routing selection by switching from URL substring checks to catalog host-matching helpers
- Fixed pasting into the ask tool's "Other (type your own)" text box (and hook input/editor dialogs) on terminals with OSC 5522 enhanced paste (kitty protocol): the enhanced-paste focus routing only targets components exposing a
pasteTexthook, and the dialog wrappers had none, so the payload was stuffed into the main prompt editor hidden behind the dialog.HookEditorComponentandHookInputComponentnow forwardpasteTextto their inner editor/input (pasting also resets the input dialog's timeout countdown like any keystroke). - Fixed auto-retry giving up after one attempt ("Provider requested Xms wait, exceeds retry.maxDelayMs") on a usage-limit 429 when every sibling account was only momentarily blocked: the retry delay now waits for the earliest sibling unblock when that comes sooner than the provider's multi-hour retry-after, so the next attempt picks up the recovered account instead of failing fast.
- Fixed Hindsight
per-project-taggedmental-model seeding so each project gets its own conventions/decisions models and session context only injects active-project or untagged models (#2218). - Fixed Windows stdio MCP
.cmdcommands by wrapping batch shims withcmd.exe /d /s /cusing the outer command quotes required bycmd /s, while preserving literal%and quoted JSON arguments for Codegraph MCP (#2220). - Fixed the bundled
exploreagent'sthinking-level: medfrontmatter — not a valid effort (minimal/low/medium/high/xhigh), so it silently parsed to undefined and the agent ran without its intended thinking level - Discovery context-file reads (
~/.claude,~/.cursor, project trees,@-imports) now stat-gate to regular files before reading: a FIFO/socket/char device dropped where a context file is expected previously blocked startup forever on a read that can never see EOF. - Fixed the read tool's provider-visible
pathschema and docs so web URLs and internal URI targets (omp://,issue://,pr://, etc.) are advertised alongside local files (#2215). - Kept IRC cards from being removed after their TTL once everything above them finalized: their rows may already be committed to native scrollback, and removing them was an interior deletion of the committed prefix that the engine could only repair by recommitting everything below the gap (duplicated blocks). Such cards now stay in the transcript as durable history.
- Fixed the recommit storm that sprayed stale snapshots of a running task's progress tree into native scrollback. The stable-prefix ratchet promoted any row quiet for one 30-frame window, so slowly ticking rows (per-agent tool/cost counters updating every few seconds) were repeatedly promoted, committed, rewritten, and recommitted by the engine audit for the whole run. The ratchet now floors itself permanently at the first row that mutates after being promoted — settled heads (a task's prompt/context) still reach scrollback, genuine tickers never re-promote.
- Fixed the artifact spill dropping the first ~20KB of output: head-retained bytes were never written to the artifact file, so for every bash/eval/ssh command exceeding the 50KB spill threshold, the
artifact://advertised as the "full capture" was permanently missing its head — the agent re-reading it got truncated data presented as lossless. - Fixed streaming-output chunk throttling dropping chunks instead of coalescing them: streaming previews and the auto-background "output so far" text the model reasons over contained output with arbitrary middles silently spliced out.
- Fixed
vault://writes bypassing both the approval ladder and plan mode: internal-URL writes were uniformly rated tierread(auto-allowed even in always-ask) and the internal-router branch returned before the plan-mode guard, so the model could silently overwrite real Obsidian notes; writes through schemes with a mutating handler are now tierwriteand plan-mode-enforced. - Fixed writes into
.tar.gz/.tgzarchives silently stripping gzip compression (the rewritten archive was a bare tar under the.gzname — masked on re-read because Bun auto-detects, broken fortar xzf/CI consumers), and made archive rewrites atomic via temp-file + rename so a crash mid-write can no longer destroy every other member; symlinked archive paths resolve to their target before the swap so the rename writes through instead of replacing the link with a regular file. - Fixed merge-conflict detection being completely inert on CRLF files: the scanner split on
\nand compared=== "=======", so=======\rnever matched and the agent edited around live conflict markers without warning; CRLF files now detect, splice, and round-trip their line endings correctly. - Fixed cross-line search (
\nin the pattern) silently returning zero matches: the native searcher was never switched to multi-line mode (only the regex flag was set), so the advertised feature matched nothing on real files while reporting a confident "No matches found". - Fixed search results lying about completeness: one hot file could consume the entire 2000-match global budget in path order making later files unreachable by any
skip(now capped per file with the footer hedgingof N+when truncated), paginating past the last page returned "No matches found" instead of "No more results", directory scans now report how many >4MB files were skipped instead of silently excluding them, adjacent matches in virtual resources no longer emit duplicated backwards-numbered context lines, and patterns are no longertrim()ed (only all-whitespace is rejected — leading/trailing whitespace is meaningful regex). - Fixed the search tool's native grep being uncancellable: neither the abort signal nor any timeout was threaded through, so Esc on a huge-tree search left the native walk burning CPU to completion; both now propagate (30s default timeout).
- Fixed archive and sqlite reads that could OOM or hang the process: tar/tgz archives are stat-gated at 256MB before being loaded, zip members reject attacker-declared uncompressed sizes over 64MB before allocation, and binary plain files now return a NUL-sniff notice instead of filling the line budget with mojibake.
- Fixed malformed internal-URL selectors (
artifact://3:-100) silently dumping the whole resource instead of erroring, selectors directly on an archive root (a.zip:500,a.zip:raw) being misparsed as member names, archive members minting editable hashline tags keyed to the archive path (they are immutable resources), URL selector tokens being case-sensitive (:RAW404ed),artifact://Nresolving into another session's artifacts in multi-session hosts, and not-found paths with archive/sqlite extensions stacking multiple 5s workspace-wide suffix globs (now shared per read, with glob metachars escaped sofoo[1].tscan match itself). - Fixed leading
cd X &&extraction breaking shell-expanded paths —cd "$(git rev-parse --show-toplevel)" && makefailed with "Working directory does not exist" because the captured path was resolved literally; extraction now defers to the shell when the path contains$, backticks, or(. - Fixed the echo/printf write-redirect interceptor rule blocking legitimate commands containing
>inside quotes (echo "a -> b",printf 'use 2>&1'); the rule is now quote-aware, and also catches>|clobber redirects and$VARtargets it previously missed. - Fixed every completed auto-backgrounded bash invocation leaking its persistent native
Shellin the process-global session map, and the running-job cap failing all bash commands outright — at capacity, commands now degrade to direct foreground execution (explicitasync: truestill errors). - Fixed a duplicate-delivery race where a bash job completing just inside the auto-background threshold could be returned as the tool result and re-injected as a completion notification, and fixed auto-background silently preempting the ACP client-terminal route when an editor advertises terminal capability.
- Fixed timed-out/cancelled PTY and client-bridge commands surfacing raw output with no annotation (the model couldn't distinguish timeout from failure and retried identically); the timeout/abort notice is now always appended.
- Fixed
askreporting timeout auto-selection as "User selected: X" — fabricated consent for consequential questions; the result now says "(auto-selected after timeout)" with atimedOutdetail flag, the transcript card marks the auto-selection distinctly, and a deliberate Esc seconds past the deadline is treated as a cancel instead of being reclassified as a timeout. - Fixed
todoaccepting duplicate task content/phase names ininit(duplicates were permanently unaddressable — every targeting op hit the first match while auto-promotion kept resurrecting the twin) and persisting half-applied batches on error; failed batches no longer mutate state. - Fixed the auto-generated-file guard caching markers by path alone with no invalidation — a file regenerated after first check stayed editable (and vice versa); entries are now validated against mtime+size.
- Fixed editor-bridged (ACP) writes skipping the post-write bookkeeping the direct path performs (
bumpFileMutationVersion, shebang chmod), so mutation-version consumers saw stale state depending on whether an editor was attached. - Fixed
conflict://*resolution failing spuriously when an out-of-band edit shifted a conflict block (stale duplicate registrations are now tolerated as already-resolved — but a DISTINCT conflict block that is merely byte-identical and still present in the file stays addressable), and partial conflict-resolution failures now setisErrorinstead of burying failed files mid-text in a success result. - Fixed patch-mode prefix/substring matches silently truncating line content the model never saw: every non-exact match strategy now emits a warning with strategy + similarity, and prefix/substring matches are rejected unless the discarded fragment survives in the replacement lines.
- Fixed ast-edit and file-mention snapshots being recorded under non-canonical paths (invisible to stale-tag recovery under symlinked cwds), and the ast-edit apply step leaving every just-issued preview tag stale — post-apply snapshots are re-recorded and fresh tags surfaced in the result.
- Fixed notebook cells containing literal
# %% [markdown]marker text being silently split into extra cells on any edit; marker-shaped source lines are now escaped on render and restored on parse. - Fixed the LSP client being published before
initializecompleted (concurrent callers hit "server not initialized" flakes on first use), reader-loop death leaving a permanent zombie client where every request times out at 30s forever (bad messages are now isolated per-message and a dead reader tears the client down for respawn), framing stalls on header blocks withoutContent-Length(now resynced past the junk in both LSP and DAP),lsp statushardcodingreadyfor every client including wedged ones, and shutdown skipping clients still mid-initialize (their server processes outlived exit). - Fixed numeric LSP code-action selectors being shadowed by substring title matches —
query: "2"could apply a different quickfix whose title contained "2"; numeric queries now select strictly by index. - Fixed
file://URIs built without percent-encoding: a%in a path threwURIErroron round-trip and a#truncated the server-side path, desynchronizing diagnostics and workspace edits; URIs from lax servers carrying a raw#/?now route to the lenient parser instead of parsing "successfully" as fragment/query and misrouting edits. - Fixed multiple LSP inserts at the same position applying in reverse of spec order (transposed import/reference insertions), and
applyWorkspaceEditnow overlap-validates every file before writing any, so a conflicting rename no longer leaves the workspace half-renamed. - Fixed
lsp reloadhanging for the whole tool timeout (didChangeConfigurationwas sent as a request; it is a notification), biome failures being silently reported as "no diagnostics", a hung language server adding up to 30s to every edit (writethrough init is now deadline-bounded at 5s with deterministic spawn failures negative-cached for 3 minutes), and DAPpause()burning its full timeout when the stopped event raced the subscription; concurrent DAP breakpoint mutations are also serialized per session (last-writer no longer silently drops the other's breakpoints), queued mutations honor the caller's abort at dequeue, and the DAP output buffer retains a full 128KB tail instead of dropping whole chunks below the cap. - Fixed concurrent isolated background tasks interleaving
git stash push/pop+ cherry-pick on the shared repository — the merge sequence now runs under the repo lock, eliminating a lost-uncommitted-changes race; a stash-pop failure after successful cherry-picks also no longer reports merged branches as "unmerged" (the duplicate-commit trap) and instead tells the user to pop the stash manually. - Fixed async task batches getting stuck "running" forever (unscheduled/failed-to-register tasks never counted toward completion), error-result jobs being marked
completed, semaphore-queued tasks counting against the 15-job global cap (batches >15 dropped the remainder and starved other async work), duplicate task ids skipping validation on the async path, and an abort racing subagent session startup leaking the late-created session's LSP/MCP processes. - Fixed task fail-fast abandoning in-flight siblings uncancelled (the worker signal now propagates), patch-mode merges blocking ALL successful siblings' patches when one task failed, and
$@command expansion interpreting$-replacement patterns in user input. - Fixed eval cells double-writing artifacts (the tool and the per-cell executor each opened a sink on the same artifact path, corrupting >50KB outputs), JS
parallel()early-rejecting in violation of its documented barrier (orphaning in-flightagent()thunks with worker-side promises hung forever), Python child subprocesses inheriting the NDJSON frame pipe (their stdout was dropped and could corrupt protocol frames — it is now captured and forwarded), JS cell timeouts silently wiping persistent VM state without annotation, and the JS console bridge throwing onconsole.dir/time/group/assert/trace. - Fixed
pr_pushnever invalidating the PR/diff cache (the canonical push-then-verify flow read a pre-push diff for up to 5 minutes), current-branchgh pr merge/closewith no positional never invalidating at all (exactly the staleness the cache layer claims to eliminate; numeric flag values like--milestone 3also no longer steal the positional), multi-PR checkouts discarding successful checkouts and racing in-flight git mutations on first failure (allSettledwith per-PR reporting), run-watch ending with a failure result and zero logs when an auto-retry raced the grace-period refetch, the per-watch completed-run job cache serving a rerun's FIRST-attempt jobs after the rerun completed (entries are evicted whenever a run is observed non-completed), pagination terminating on post-filter page length, millisecond precision leaking into GitHub search date qualifiers, leading-dash PR identifiers reachingghas flags, andissue://?state=typos silently coercing to the open list. - Fixed the Exa API key being written to the log file on every failed MCP request (the key rode the query string of logged URLs; key/token/secret/auth params are now redacted), and removed the web-search query rewrite that replaced every
202xsubstring with the current year — it corrupted CVE identifiers and made historical-year searches silently impossible. - Fixed reopening the sole browser tab with a different
dialogspolicy disposing Chromium and then using the dead handle, a stale tab release evicting a live replacement browser from the registry (spawning duplicate Chromium processes), and concurrent same-nameopencalls leaking a worker + refcount via a check-then-set race (acquisitions are now single-flight per name); queued opens honor an abort at dequeue, and an init-payload failure releases the temporary browser hold instead of pinning the refcount forever. - Fixed fetch decoding every response as UTF-8 regardless of declared charset (Shift_JIS/EUC-KR/GBK pages rendered as mojibake through the whole reader pipeline;
Content-Typeand<meta charset>are now honored viaTextDecoder), binary URLs being downloaded twice (body skipped on the first pass for convertible types), >50MB truncation being silent (now flagged in notes), all transport error detail being swallowed into a bare "Failed to fetch URL" (the cause is surfaced and 429s get oneRetry-After-honoring, abort-aware retry), MCP SSE keep-alive lines escaping as rawSyntaxErrors, MCP calls having no default timeout (now 60s), and a YouTube fetch budget expiry being misreported as a user abort that also skipped temp-file cleanup. - Fixed archive directory listings silently ignoring the selector offset —
a.zip:dir:50now starts the listing at the 50th entry instead of relisting from the top. - Fixed the model selector dropping an immediate Enter when cached models were available but the selector's offline refresh was still pending.
- Fixed dynamic
import(...)inside functions passed to the browser tool'stab.evaluate/page.evaluatefailing with__omp_import__ is not defined. The eval/browser JS runtime rewrites dynamic-import callees to the worker-injected__omp_import__helper, but puppeteer serializes evaluate callbacks withFunction.prototype.toString()and re-runs them inside the page, where the helper does not exist. The rewriter now substitutes a guarded shim that falls back to native dynamic import when the helper is absent, so serialized code works in the page realm while in-worker imports keep resolving against the session cwd. - Transcript block freezing is now unconditional instead of gated on ED3-risk terminal detection: every finalized block replays its frozen snapshot once it crosses out of the live region, on all terminals including Windows, because the rewritten renderer's committed scrollback is immutable everywhere. Still-mutating blocks (pending tools, streaming messages, async thinking renderers) anchor the live region and keep repainting until they finalize, which structurally fixes stale/duplicated output from late async expansions (#1823).
- Fixed the edit tool's post-edit diff preview occasionally echoing a context line twice with out-of-order numbering. Block-boundary context injection classified space-prefixed diff rows as old-file-only, so an unchanged line sitting in a net-offset region (old N / new N+k) was missing from the new file's visibility window;
findBlockContextLinesthen re-surfaced it under its post-edit number and the row was spliced in after the adjacent change run. New-file boundary lines are now translated back to pre-edit numbers (the compact-preview renumbering contract) and merged into a single old-numbered insertion pass — also fixing closers below a net-offset edit being dropped or renumbered incorrectly. - Fixed the Anthropic web-search provider claiming the Claude Code identity on API-key requests: the CC billing header + system instruction were injected whenever the model wasn't Haiku 3.5, regardless of auth mode. Injection is now OAuth-gated like the streaming path, and OAuth search requests patch the billing header's
cchattestation (viawrapFetchForCch) instead of shipping thecch=00000placeholder. - Fixed long streamed content appearing cut off mid-run: scrolled-off rows were erased from the viewport without ever being appended to terminal history. The transcript's commit boundary (
deriveLiveCommitState) was all-or-nothing per block — one perpetually rewriting row (a task tool's ticking progress tree, per-agent cost/tool counters, spinner stats) suspended scrollback commits for the entire block, so once the block outgrew the viewport its static head (e.g. a task's prompt/context markdown) was neither committed nor on screen until the tool sealed, and was lost outright if the session ended mid-run. A stable-prefix ratchet now promotes leading rows that stayed visibly identical for a full 30-frame window as commit-safe, so the settled head reaches native scrollback while only the genuinely volatile tail stays deferred; a rewrite above the promoted run retreats the boundary and the engine audit recommits (duplication, never loss). - Fixed local tiny-title worker stdout/stderr leaking raw native model output such as
</title>and cache/status lines into the interactive TUI scrollback (#2206). - Fixed task-agent discovery advertising Claude Code custom agents from
.claude/agents/*.mdas OMP subagents; direct task-agent discovery now only loads OMP-native.ompagent roots, while Claude marketplace plugin agents keep their existing provider path (#2209).
Removed
- Removed the
clearOnShrinksetting and itsPI_CLEAR_ON_SHRINKenvironment variable: the rewritten renderer always clears shrunken rows exactly, so the flicker/perf tradeoff the setting controlled no longer exists. Existing config entries are ignored. - Removed the prompt-submit native-scrollback reconciliation checkpoint and the eager streaming render mode from the interactive controllers — the renderer's append-only contract made both obsolete.
[15.10.10] - 2026-06-09
Added
- Added a read-only
viewop to thetodotool that echoes the current list without mutating state, so the agent can recover exact task text instead of guessing it from memory.
Changed
- Rewrote the bash tool's coreutils guidance (tool prompt and system prompt) around an explicit litmus: pipelines that compute a new fact (
wc -l,sort | uniq -c,comm,diff) are legitimate bash, while commands that merely move, page, or trim bytes a dedicated tool can fetch remain banned — output trimming destroys data theartifact://capture would have saved.
Fixed
- Fixed the model selector dropping an immediate Enter when cached models were available but the selector's offline refresh was still pending.
- Fixed dynamic
import(...)inside functions passed to the browser tool'stab.evaluate/page.evaluatefailing with__omp_import__ is not defined. The eval/browser JS runtime rewrites dynamic-import callees to the worker-injected__omp_import__helper, but puppeteer serializes evaluate callbacks withFunction.prototype.toString()and re-runs them inside the page, where the helper does not exist. The rewriter now substitutes a guarded shim that falls back to native dynamic import when the helper is absent, so serialized code works in the page realm while in-worker imports keep resolving against the session cwd. - Transcript block freezing is now unconditional instead of gated on ED3-risk terminal detection: every finalized block replays its frozen snapshot once it crosses out of the live region, on all terminals including Windows, because the rewritten renderer's committed scrollback is immutable everywhere. Still-mutating blocks (pending tools, streaming messages, async thinking renderers) anchor the live region and keep repainting until they finalize, which structurally fixes stale/duplicated output from late async expansions (#1823).
- Fixed the edit tool's post-edit diff preview occasionally echoing a context line twice with out-of-order numbering. Block-boundary context injection classified space-prefixed diff rows as old-file-only, so an unchanged line sitting in a net-offset region (old N / new N+k) was missing from the new file's visibility window;
findBlockContextLinesthen re-surfaced it under its post-edit number and the row was spliced in after the adjacent change run. New-file boundary lines are now translated back to pre-edit numbers (the compact-preview renumbering contract) and merged into a single old-numbered insertion pass — also fixing closers below a net-offset edit being dropped or renumbered incorrectly. - Fixed the Anthropic web-search provider claiming the Claude Code identity on API-key requests: the CC billing header + system instruction were injected whenever the model wasn't Haiku 3.5, regardless of auth mode. Injection is now OAuth-gated like the streaming path, and OAuth search requests patch the billing header's
cchattestation (viawrapFetchForCch) instead of shipping thecch=00000placeholder. - Fixed long streamed content appearing cut off mid-run: scrolled-off rows were erased from the viewport without ever being appended to terminal history. The transcript's commit boundary (
deriveLiveCommitState) was all-or-nothing per block — one perpetually rewriting row (a task tool's ticking progress tree, per-agent cost/tool counters, spinner stats) suspended scrollback commits for the entire block, so once the block outgrew the viewport its static head (e.g. a task's prompt/context markdown) was neither committed nor on screen until the tool sealed, and was lost outright if the session ended mid-run. A stable-prefix ratchet now promotes leading rows that stayed visibly identical for a full 30-frame window as commit-safe, so the settled head reaches native scrollback while only the genuinely volatile tail stays deferred; a rewrite above the promoted run retreats the boundary and the engine audit recommits (duplication, never loss). - Fixed local tiny-title worker stdout/stderr leaking raw native model output such as
</title>and cache/status lines into the interactive TUI scrollback (#2206). - Fixed task-agent discovery advertising Claude Code custom agents from
.claude/agents/*.mdas OMP subagents; direct task-agent discovery now only loads OMP-native.ompagent roots, while Claude marketplace plugin agents keep their existing provider path (#2209).
Removed
- Removed the
clearOnShrinksetting and itsPI_CLEAR_ON_SHRINKenvironment variable: the rewritten renderer always clears shrunken rows exactly, so the flicker/perf tradeoff the setting controlled no longer exists. Existing config entries are ignored. - Removed the prompt-submit native-scrollback reconciliation checkpoint and the eager streaming render mode from the interactive controllers — the renderer's append-only contract made both obsolete.
[15.10.9] - 2026-06-09
Fixed
- Fixed streaming thinking (and other styled assistant content) vanishing from native scrollback once it scrolled past the viewport top during a foreground turn. The transcript's append-only commit detector compared raw row bytes, so a styled paragraph wrapping onto a new row (the span-closing SGR and width padding move while the visible cells stay identical) or a streamed token pushing the last word down a line flagged the block as permanently volatile — the commit boundary froze and every later row that crossed the viewport top was committed nowhere. Rows are now compared by visible content, a wrap-shrink of the in-flight bottom line counts as append-only, and a genuine one-off interior rewrite only suspends commits until the block re-earns append-only (30 clean frames), after which the pinned emitter backfills the stalled gap contiguously. Periodically rewriting blocks (spinners, collapsing tool previews) never re-earn and stay deferred.
- Fixed bracketed pastes containing multiple image file paths so each image is attached in order instead of treating the whole paste as one unreadable path.
- Fixed MCP OAuth fallback prompts so the "Click here to authorize" label emits an auth-safe terminal hyperlink even when hyperlink auto-detection is unavailable, keeping non-browser MCP setup usable (#2196).
- Fixed
task-spawned subagents repeating filesystem scans the parent had already completed.ExecutorOptionsand thecreateAgentSession()call insiderunSubprocess()did not forwardrules, the discovered extension paths, or the discovered.omp/tools/paths, so each subagent re-ranloadCapability<Rule>(),discoverAndLoadExtensions(), and the full.omp/tools/walk. The toolsession now cachessession.rules,session.extensionPaths, andsession.customToolPaths;runSubprocess()threads them through; andcreateAgentSession()accepts newpreloadedExtensionPathsandpreloadedCustomToolPathsoptions backed by new exporteddiscoverExtensionPaths()anddiscoverCustomToolPaths()helpers. Crucially, only path lists are forwarded — never loaded instances. Each session rebuilds its ownExtensionandLoadedCustomToolobjects so the per-sessionExtensionAPI/CustomToolAPI(cwd, eventBus, runtime, exec, pushPendingAction, UI) targets the right session; forwarding loaded instances would have routed extension handlers and custom-tool execution back through the parent. The CLI'spreloadedExtensionsshort-circuit is preserved for same-process reuse and now shallow-clones the caller'sextensionsarray so inline-extension augmentation (autoresearch + custom-tools wrapper) cannot bleed back into it (#2190). - Fixed SSH tool cancellation hanging behind OpenSSH ControlMaster streams that stayed open after an Esc/user interrupt (#2180).
- Fixed Windows stdio MCP servers launched through PATH shims such as
codegraph.cmdso bare commands likecodegraphresolve viaPATHEXTbefore spawn (#2174). - Fixed compiled-binary extensions failing to load
@oh-my-pi/pi-*packages whenbun --compilequietly dropped one of the extra entrypoints (observed on macOS arm64 release builds): the legacy-pi compat shim's package-root override branch returned the bunfs path without checking the target was present, so the rewrite emitted afile://URL to a missing module and the #1216 fallback (scoped to the throwinggetResolvedSpecifierpath) never ran. Override targets are now validated against the on-disk filesystem at module init, missing entries are dropped, and resolution falls through to canonical lookup so Bun resolves the import from the extension's ownnode_modules(#2168).
[15.10.8] - 2026-06-09
Added
- Added an optional
fetchoption toCustomToolContextso custom tools can use a caller-provided HTTP implementation - Added optional
fetchoverrides toModelRegistryconstruction and MCP/web search/tool network calls, enabling callers to inject custom HTTP clients instead of relying on globalfetch - Added a
bash.enabledsetting to disable the model-facing bash tool while leaving user-initiated bang/RPC bash commands available. - Added an
@<upstream>model-selector suffix to pin an aggregator model to a single upstream provider per invocation, e.g.--model openrouter/z-ai/glm-4.7@cerebras(sets OpenRouterprovider.only; Vercel AI Gateway models map tovercelGatewayRouting.only). Resolved throughparseModelPattern, so it works for--model/--smol, model roles, and the SDK, and composes with a trailing thinking level (...@cerebras:high). The base must resolve to an aggregator (openrouter.ai/ai-gateway.vercel.sh); otherwise the@stays part of the id, so ids that legitimately contain@(claude-opus-4-8@default,workers-ai/@cf/...) are unaffected.
Fixed
- Fixed a turn-ending provider error (e.g. a 502 whose body is the proxy's full HTML page) flooding the transcript:
AnthropicApiErrorfolds the entire response body intoerrorMessage, and the inline transcript render reprinted it verbatim — every embedded blank line included — leaving a tall mostly-empty block ending in</html>. The inline error now drops blank lines, clamps to 8 lines, and width-truncates each line viagetPreviewLines, matching the pinned error banner.
[15.10.7] - 2026-06-08
Fixed
- Fixed MCP OAuth fallback rendering to show a short terminal hyperlink and keep the raw authorization URL on one unwrapped copy line (#2121).
- Fixed
ompstartup blocking 25–30 s on a single unresponsive MCP server when no cached tools were available for it.MCPManager.connectServersused to fall through to an unboundedPromise.allSettledover every still-pending server without a cached tool list, so one server stuck waiting on the per-request MCP timeout (OMP_MCP_TIMEOUT_MS, default 30 000 ms) gated the entire UI ready signal. Pending-without-cache servers are now left in flight: their tools surface via the existing background#onToolsChanged→refreshMCPToolspath the moment the connect completes, and failures continue to log through the background catch handler (#2100).
[15.10.6] - 2026-06-08
Added
- Added a
/plan-reviewcommand that manually (re-)opens the plan-review overlay while plan mode is active. Since there is no fixed plan filename, it reviews the newestlocal://<slug>-plan.mdthe agent wrote — useful for pulling the review back up after dismissing it, or reviewing a plan the agent wrote without callingresolve.
Changed
- Reverted the
tasktool's result-header glyph from the⇶signature icon back to the quietstatus.donebullet (•): white while a subagent is running, accent once it finishes. The reviewer verdict line and per-agent result lines use the same bullet.
Fixed
- Fixed
/loginAPI-key prompts (OpenCode Zen, Perplexity OTP, GitHub Enterprise URL, manual OAuth redirect URL, …) silently dropping pasted content on kitty/Linux/Wayland — and any other terminal supporting OSC 5522 enhanced paste.InputControllerenables kitty's enhanced clipboard protocol on TUI start and consumes the resulting OSC 5522 packets in anaddInputListenerthat runs before focus dispatch, so the paste never reached the modalInput's bracketed-paste handler; the routing then stuffed the text into the mainCustomEditorunconditionally, even whenselector-controllerhad detached the editor and focused a temporary OAuth input. The pasted API key accumulated in the hidden editor and only resurfaced in the main prompt when the user dismissed the modal with Enter or Esc. The enhanced-paste callback now consultsui.getFocused()and routes the text to the focused component when it exposes apasteTexthook, falling back to the editor only when no modal target is in focus; image pastes refuse with a status message instead of stuffing a binary blob into the hidden editor. (#2127) - Fixed an auto-compaction dead loop when
compaction.strategywasshakeand the configured threshold was low enough that a single shake pass could not bring the context below it (e.g. a 50K-token threshold on a session well above it). Each pass auto-continued, the next agent turn re-triggered the threshold check, and the second shake had nothing new to drop, so the session spun forever. The shake recovery path now estimates post-shake context and, when it is still above the threshold (or shake reclaimed nothing on overflow recovery), surfaces a one-shot warning and falls back to the summarization-drivencontext-fullcompaction so progress actually resumes (#2119). - Fixed
/skill:prompts so magic keywords and turn-budget directives in skill args inject the same hidden notices as normal user prompts, matching the editor highlight behavior (#2128). - Fixed MCP OAuth fallback rendering to show a short terminal hyperlink and keep the raw authorization URL on one unwrapped copy line (#2121).
- Fixed the
tasktool rendering a success bullet and asuccessframe state for detail-less error results (e.g. an argument-validation failure that never executes): the header now shows the error glyph with an error border anderrorstate, and surfaces the dispatched agent name. - Fixed Agent Control Center new-agent creation so Windows Ctrl+Enter sequences submitted as a single LF generate the agent instead of inserting a newline (#2118).
- Fixed plan-mode subagents preserving read-only specialty tools such as
report_findingwhile still stripping mutating tools (#1998). - Removed unreachable standalone Exa tool-suite exports and stale tool-count barrel exposure while keeping the live Exa
web_searchprovider helpers (#2093). - Fixed
omp commitsplit plans accepting hunk selectors that resolve to no parsed hunks, which crashed the apply step after the index reset and left the working tree fully unstaged (#2098).
[15.10.5] - 2026-06-08
Added
- Added Homebrew and mise package-manager update paths to the self-update command so installations launched from those tools are updated through their native workflows
- Added detection of Homebrew and mise install locations so self-update chooses the manager-specific updater when the active
ompbinary comes from a package-manager-managed path - Added
astConditionto TTSR rule frontmatter as a syntax-aware alternative to regexcondition, enabling AST-based matching for edit/write tool snapshots - Added a built-in
ts-redundant-clear-guardrule that flags redundant guards aroundclearTimeout,clearInterval, andclearImmediatecalls - Added a built-in
ts-no-test-timersrule that flags real timers (Bun.sleep,setTimeout,setInterval) in*.test.tsfiles, steering toward fake timers (vi.useFakeTimers()/vi.advanceTimersByTime()) - Added support for paste marker highlighting with accent styling (
[Paste #N, +X lines]/[Paste #N, Y chars]) in the prompt editor, matching the visual treatment of image references - Added pixel dimensions to pasted/loaded image placeholders in the prompt — the marker now reads
[Image #N, WxH](falling back to[Image #N]when the header can't be decoded). - The bundled shell now treats
nohupas a builtin:nohup … &runs the command without maskingSIGHUPor detaching it, so agent-started daemons stay tied to this agent's lifetime instead of leaking as orphans when the agent exits. Updated the bash tool prompt's daemon guidance to match (dropped thenohup … & / setsid … & / disowndetach recommendation in favor of a largetimeoutplus the persistent session). - Added per-tool
tool.*theme symbol keys (nerd/unicode/ascii presets) plus a quietstatus.doneglyph, so each tool's result header can carry a signature icon instead of a generic status mark
Changed
- Updated pi-ai OAuth imports to the renamed
@oh-my-pi/pi-ai/oauthsubpath (was@oh-my-pi/pi-ai/utils/oauth) across the login UI, MCP OAuth flow, model registry, setup wizard, and web-search Codex auth. The legacy-plugin specifier shim drops itspi-ai/oauth→pi-ai/utils/oauthsubpath rewrite, since the canonical@oh-my-pi/pi-ai/oauthexport now resolves directly. - Changed forced self-updates for Homebrew installs to run
brew reinstalland for mise installs to runmise install --forceaftermise upgradewhen--forceis requested - Changed TTSR rule bucketing and matching so rules with only
astConditionare treated as TTSR rules and evaluated in the interrupt flow using reconstructed edit/write source snapshots - Normalized image content before it enters model context so attached images are downscaled and preprocessed for prompts, steering messages, follow-ups, and custom agent messages
- Changed image marker format to include pixel dimensions when available (
[Image #N, WxH]), falling back to bare[Image #N]when header cannot be decoded - Changed the prompt editor to highlight large-paste placeholders (
[Paste #N, +X lines]/[Paste #N, Y chars]) with the same accent styling as image references (bold, no hyperlink), and to delete image/paste markers atomically: a single backspace or forward-delete removes the whole marker instead of leaving a broken[Paste #N, +X linesbehind. - Browser tool helpers (
tab.*) are now individually tracked and time-bounded: when aruncell hits its budget, the timeout error names the still-running helper(s) and how long each has been stalled (e.g.... (stalled on tab.screenshot({ selector: ".x" }) (29.9s))) instead of the opaqueBrowser code execution timed out after 30000ms. Page-coupled helpers that should resolve quickly (observe,screenshot,extract) also fail fast with a named per-op error atmin(cellBudget, 20s), leaving budget for the rest of the cell, rather than silently consuming the whole budget. - Derived the auth-broker OAuth callback ports (
CALLBACK_PORTS) and the paste-code login-provider set from the@oh-my-pi/pi-aiprovider registry, removing the duplicatedCALLBACK_SERVER_PROVIDERStables in the model selector and the setup-wizard sign-in scene. - Raised the
evaltool's per-celltimeoutceiling from 600s to 3600s (matchingbash), in both the Zod schema and theTOOL_TIMEOUTS.evalruntime clamp, so heavy local-compute cells can request budgets above 10 minutes. - Derived the auth-broker OAuth callback ports (
CALLBACK_PORTS) and the paste-code login-provider set from the@oh-my-pi/pi-aiprovider registry, removing the duplicatedCALLBACK_SERVER_PROVIDERStables in the model selector and the setup-wizard sign-in scene. - Reworked tool result-header glyphs to cut the overused success checkmark/dot: each tool now shows its own signature icon on success (terminal for bash, pencil for edit, magnifier/globe for search, plug for MCP, etc.; read keeps the read-group status dot), tools without a custom renderer fall back to a quiet
status.donedot, and error/warning/pending states keep the universal cross/warning/spinner - Changed steady-state health indicators (LSP server ready, OAuth logged-in, plugin-doctor checks) from a success checkmark to a colored
status.enableddot, so failures stand out instead of every line reading as a check - Changed one-shot MCP/SSH/debug confirmation messages from a generic checkmark to contextual action glyphs (add/remove, connect/enable/disable toggles, reload, job-completed), reflecting what happened rather than just "success"
- Derived the auth-broker OAuth callback ports (
CALLBACK_PORTS) and the paste-code login-provider set from the@oh-my-pi/pi-aiprovider registry, removing the duplicatedCALLBACK_SERVER_PROVIDERStables in the model selector and the setup-wizard sign-in scene.
Fixed
- Fixed package subpath exports for status-line, setup-wizard, tool-discovery, and gallery fixture modules so rewritten test imports resolve through
@oh-my-pi/pi-coding-agent. - Fixed runtime model provider discovery so extension-registered providers are now refreshed after extension load and extension-supplied models appear without restarting
- Fixed task-row shimmer timing so every running description starts its highlight on the first character together and reaches the last character together, regardless of text length.
- Fixed the
evaltool'sread/write/appendhelpers (both Python and JS backends) treatinglocal://(and other internal-URL) paths as plain filesystem paths.pathlib.Path/path.resolvecollapselocal://x.mdtolocal:/x.md, sowrite("local://x.md", …)created a junklocal:directory under the cwd instead of writing whereread local://x.mdresolves. The helpers now substitute injected on-disk roots for known schemes (currentlylocal://, pinned to the session's ownlocal://root), reject path traversal and unknownscheme://paths, and leave plain paths resolving against the cwd. - Fixed read and edit previews to surface the enclosing syntactic block's off-window boundary line (behind an ellipsis) when a shown line opens or closes a block whose other end falls outside the displayed range. Powered by a new tree-sitter
enclosingBlockBoundariesnative, so it covers brace languages and indentation languages (Python) using real syntactic spans, with a lexical bracket scan as fallback for unparseable sources. - Fixed
tab.screenshot({ selector })hanging for the entire cell budget on continuously-animating pages (WebGL /backdrop-filter"glass" effects). The element-screenshot path no longer routes through puppeteer'sscrollIntoViewIfNeeded(), whoseIntersectionObserverpromise can stall indefinitely under heavy rendering; it now does a single instantscrollIntoViewand captures withscrollIntoView: false(relying oncaptureBeyondViewport), so off-screen elements are still captured without the stall. - Fixed follow-up message submissions to forward pending clipboard-pasted images to
session.promptin both streaming and non-streaming flows - Fixed follow-up handling to clear consumed clipboard image state after submission so pasted images are not silently carried into later messages
- Fixed clipboard-pasted images being rejected when steering or following up during compaction. Instead of bailing with "Retry after it completes to send images", the message and its images are now queued via
queueCompactionMessageand forwarded to the session (steer/follow-up/prompt) when the compaction queue flushes. - Fixed edit tool result previews to show only current-file lines and collapse long inserted blocks instead of echoing removed content.
- Fixed
generateDiffStringto omit the mid-skip...placeholder between two nearby edits, conveying the elided gap via the jump in line numbers instead (consistent with how leading/trailing context skips already render). The placeholder row was indistinguishable from a genuine...context line and wasted a row in compact previews. - Fixed concurrent interactive dialogs clobbering each other on the shared editor surface.
ExtensionUiControllerpresents the selector / input / editor modals by swapping a component into the singleeditorContainerand stealing focus, with no serialization — so a secondselect/input/editorrequest (from a hook, extension, theasktool, or an internal flow) opened while one was already up would clear the container and re-focus, orphaning the first dialog. Its promise then hung until the caller's signal aborted (surfacing a strayAsk input was cancelledon top of the answered call). These modals are now serialized through#presentDialog: at most one shows at a time and the rest queue (FIFO); a queued request whose signal aborts before its turn resolvesundefinedand is never shown. The first dialog is still presented synchronously, so single-dialog timing is unchanged. - Fixed the
asktool potentially hanging when the model emitted twoaskcalls in one tool batch.asknow declaresconcurrency: "exclusive", so the agent loop serializes the batch and each question's selector runs to completion before the next starts, instead of racing for the shared selector surface. - Expanded
@path/to/fileimport references in CLAUDE.md / AGENTS.md / GEMINI.md (and the other discovered context-file flavors) when loading them into the system prompt, matching the convention used by Claude Code, Goose, and other agents. Imports resolve relative to the importing file's directory, support~/..., recurse up to 5 hops, and are skipped inside fenced code blocks and inline code spans so technical examples likenpm install @types/nodesurvive intact (#2111).
Removed
- Removed the special Anthropic
claude-opus-4-8tool-call batch cap; sessions no longer abort an in-flight provider stream after a fixed number of completed tool calls.
[15.10.4] - 2026-06-08
Added
- macOS release binaries are now signed with a Developer ID Application identity (hardened runtime + secure timestamp + JIT/library-validation entitlements) and notarized in CI when the
APPLE_*signing secrets are configured; releases auto-fall back to ad-hoc signing until then. This makes the shipped binaries Gatekeeper-acceptable, unblocking an official Homebrew submission (#776). Seedocs/macos-signing-notarization.md. - Added a Homebrew install path:
brew install can1357/tap/omp. The can1357/homebrew-tap formula installs the prebuilt release binary, and arelease_brewCI job regenerates it (version + per-asset sha256) from each published release viascripts/ci-update-brew-formula.ts(#776).
Changed
- Adjusted
completion()model resolution so thedefaulttier now prefers the session’s active model and falls back to the configured default role when needed - Rewrote the session auto-title prompt (
prompts/system/title-system.md) and theset_titletool description to ask for a concise, sentence-case title (3-7 words) that captures the session's topic/goal, with good/bad examples and explicit guidance to treat the first message as data (no following embedded links/instructions, no refusals, describe URL/reference asks). The local on-device title prompt (tiny-title-system.md) was aligned to the same 3-7 word, sentence-case convention. The deterministic greeting/low-signal filter and thenonedeferral sentinel are unchanged. - Renamed the eval oneshot helper from
llm()tocompletion()in both JavaScript and Python preludes, including status events, prompt docs, and runtime tests.
Fixed
- Fixed
completion()to always send a non-empty default system prompt whensystemis omitted so providers that require instructions no longer reject requests - Fixed structured
completion()mode to return parsed JSON from plain text output when the model skips the forcedrespondtool call - Fixed slow-tier
completion()reasoning requests to avoid unsupported effort settings by only enabling reasoning on reasoning-capable models and capping effort to supported levels - Fixed JS eval worker reset/dispose to close workers gracefully before forced termination, avoiding Bun 1.3.14 N-API teardown crashes with native modules such as
canvas.
[15.10.3] - 2026-06-08
Added
- 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
- Added a resolved-span echo to
replace block/delete blockedits: a successful block op now printsreplace 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.
Changed
- Changed the
findtool to process each explicit multi-path target separately before merging results so searches stay scoped to the requested paths - Changed multi-path
findhandling so invalid extra targets no longer fail the whole query and now return matches from valid targets only - 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. - Changed late LSP diagnostics after edit or write to surface in the chat transcript as
Late diagnosticsentries rendered through the same grouped tree renderer theedit/writetools use (per-file nodes, severity icons,:line:collocations), and to honor the global tool-output expand toggle (collapsed entries cap at 5 diagnostics with a… N morehint) - Changed delayed diagnostics delivery to batch late results in one message per flush instead of a raw hidden custom payload
- Changed hidden custom messages and file-mention context to reach providers as
developermessages instead of user-authored turns, so system reminders no longer pollute compacted user history. - 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 allplanExists/reentry/iterativebranch combinations.
Fixed
- Fixed duplicate
findmatches in multi-target queries by deduplicating overlapping paths in merged results - Fixed
findpartial updates to avoid repeated streamed rows while scans are still running - Fixed stale late diagnostics from older edits being shown after a file was edited again
- Fixed read output paths so selector suffixes are preserved when corrected paths were returned without selectors
- Fixed
readsurfacing 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, soexecutenow runs them to completion instead of cancelling them; slower/non-deterministic reads (archive, sqlite, document, image, summary, conflict scan, URL) stay cancellable. - 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. - Fixed Esc interrupts rendering a redundant
Interrupted by userassistant transcript line while preserving the interrupt reason for tool-result placeholders and continuation logic. - LSP writethrough no longer burns the full diagnostics poll on every edit/write.
typescript-language-servernever echoes the document version inpublishDiagnostics(upstream #983), so the exact-version gate never passed;waitForDiagnosticsnow accepts an exact version match instantly and otherwise settles on the latest publish after a short quiescence window, dropping superseded in-flight diagnostics. - 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. - 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-authoreddeveloperdirective ("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. - 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.
- Fixed read-group summaries for multi-path
readresults to use result-provided display targets so each resolved path is shown as its own row - Fixed read-group range summaries to abbreviate long merged selectors with ellipsis to keep repeated-file range rows readable
- Fixed read-group TUI summaries so a single delimited
readcall renders as separate read rows, and repeated reads of the same file collapse under one file with full-file/range children. - Fixed grouped
readrows freezing on their pending "⏳ Read " 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; aseal()escape hatch (turn end / transcript rebuild) still lets a never-delivered read freeze rather than pinning the live region. - Fixed session search to return all sessions unchanged when the query is blank
- Fixed duplicate session suggestions by deduplicating history matches by session path when merging metadata and prompt-history results
- Fixed
/resumesearch 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. - Fixed
omp --resume <id>/--fork <id>crashing with[Uncaught Exception]when the id did not match a known session.createSessionManagernow throws a dedicatedSessionResolutionError, whichrunRootCommandcatches to printError: Session "..." not found.plus a hint to stderr and exit with code 1. The same path covers--forkcombined with--no-sessionand the non-interactive cross-project / moved-cwd prompts that previously surfaced raw stack traces (#2084).
Removed
- Removed the animated pending border ("shimmer") on running
bash,eval, andsshexecution blocks. While pending, a block now shows a static accent border instead of sweeping a dark segment around its bottom edge;display.shimmerstill governs the working-status line andtaskrow animations. - Removed the tool-level
nonAbortablebypass sowriteandedithonor the active turnAbortSignal.readis 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.
[15.10.2] - 2026-06-08
Added
- Added
raw-sse.txtto debug report bundles, exporting recent raw provider SSE diagnostics when captured - Added
/modelvisibility for auto-selected role defaults: inferredpi/smol/pi/slow/designer choices now show as compact[ROLE auto]badges, while explicitly configured roles keep the existing solid badges and thinking labels. - Added credential provenance to the
/loginand/logoutprovider 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.
Changed
- Changed raw SSE debug export output to prepend dropped-record metadata so truncated sessions in debug bundles now report dropped record and character counts
- Changed settings reads to cache pre-split schema paths and resolved values, with coarse invalidation on source/cwd changes.
- Changed status-line rendering to cache merged effective settings until
updateSettings()changes the configuration. - Changed
CustomEditorapp 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. - Changed
lsp referencesto retry only when no references or only the queried declaration are returned, using two fixed 250ms retries for project-aware servers - Changed
readhandling ofhttps://github.com/<owner>/<repo>:rawto use raw page rendering only, removing the GitHub API README fallback - Changed model resolution to apply provider-priority ordering when selecting models for roles and ambiguous patterns, using
modelProviderOrdersettings and built-in provider priority so first-party providers are preferred over relays in tie cases - Changed model canonical variant selection to use the same provider-priority ordering instead of candidate order when deduplicating equivalent upstream models
- 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 = disabledthe working line is static, so the loader no longer schedules 30fps redraws for it and falls back to the spinner-only ~12.5fps cadence. - Changed the eval fan-out trigger keyword from
workflow/workflowstoworkflowz.
Fixed
- 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.
- Fixed startup model fallback selection so sessions now prefer each provider’s configured default model before choosing the first available authenticated model
- Fixed implicit model selection path for tools and sessions by honoring persisted model-provider order when no explicit pattern is provided
- 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 inexecuteToolCalls'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…/" 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. - 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-celltimeout), and the JS eval test suites set a 20s file-local timeout so cold starts complete instead of being torn down. - Fixed reviewer-style subagent yields crashing the calling eval cell when a caller-supplied output schema declares
additionalProperties: falsewithout afindingsproperty.normalizeCompleteDatanow consults the active validator before splicing collectedreport_findingentries 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-toolyieldvalidation that already accepted the same raw payload (#2070) - Fixed Anthropic empty
toolUsestops without tool calls corrupting session history by retrying them and removing orphaned turns even at the retry cap. - Fixed MCP tools hanging in non-yolo modes by declaring
approval = "write"onMCPToolandDeferredMCPTool, and propagating theapprovalproperty throughcustomToolToDefinition()insdk.ts - Fixed session resumption after a working directory is moved/renamed (e.g.
git worktree move):--continuenow 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 - 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 withtype=read:mime=...instead of Kitty's dot-payload request shape (#2051) - Fixed follow-up shortcut submission of builtin slash commands so
/goal set ...applies goal mode instead of queueing as plain text. - Fixed Ctrl+Z crashing the agent on Windows with
TypeError: Unknown signal: SIGTSTP.InputController.handleCtrlZcalledprocess.kill(0, "SIGTSTP")unconditionally, butSIGTSTPis 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 wrapsprocess.killin 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). - Fixed a relative
--cwdtarget (e.g.omp --cwd repolaunched from/tmp) leaking the raw relative string into the session config.applyStartupCwdchdired into the resolved directory viasetProjectDirbut leftparsed.cwdas"repo", sobuildSessionOptions(which prefersparsed.cwdovergetProjectDir()) 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.cwdis now re-synced to the resolved absolute project dir after the chdir. - Fixed the
--cwdlaunch 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. - Fixed session auto-retry for generic
upstream_error: Upstream request failedgateway failures. - Stripped read-output line-number prefixes (
N:) from auto-piped bare body rows in the hashline edit parser, so pasting3:textwithout a+prefix no longer injects3:as literal content. Uses single-pass stripping to avoid corrupting content whose own text starts withdigits:(#1492). - Fixed
evalllm()returning HTTP 400 "Instructions are required" when called without asystemprompt against providers (notablyopenai-codex) whose Responses transformer drops theinstructionsfield on an empty system prompt.runEvalLlmnow sends a minimal default system prompt ("You are a helpful assistant.") when nosystemis supplied, sollm("question")works against every provider; an explicitsystem=still wins. - Fixed the Python
read(path, offset, limit)prelude helper rejecting documented positional arguments withTypeError: 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 calledread("file.py", 10, 20)literally crashed. The*is removed so bothread("f", 10, 20)andread("f", offset=10, limit=20)work. - Fixed
evalreset 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. - Fixed the
evaltool description advertising theagent()helper unconditionally even in subagent sessions whose parent forbids spawning. WhengetSessionSpawns()returns"", the prelude doc now omitsagent()so the model is not promised a helper that can only ever throw "Cannot spawn 'task'. Allowed: none (spawns disabled for this agent)". - Fixed plan mode rejecting
local://plan-artifact edits when addressed via the absolute path thereadtool echoes back in the[path#tag]header.enforcePlanModeWritepreviously only matched the literallocal://scheme; it now also accepts any absolute path whose realpath resolves inside the session's local sandbox root, so the absolute spelling and thelocal://spelling are interchangeable in plan mode. - Fixed snapshot tags freshly minted by
readbeing rejected as stale by a subsequenteditagainst the same file when the two sides reached the file via symlink-equivalent spellings (e.g. macOS/tmp/…vs/private/tmp/…, orread local://foo.mdrecording under the file'sfs.realpathwhileedit local://foo.mdlooked up under the rawpath.resolve(localRoot, …)form). The file snapshot store now keys every record/lookup through arealpath-canonicalized key (canonicalSnapshotKey), fusing all spellings of the same on-disk file onto one snapshot entry. - Fixed
readof agithub.com/<owner>/<repo>URL with:rawreturning 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. - Fixed
issue://andpr://reads returning stale OPEN/CLOSED state after a successfulgh issue close/gh pr merge(or any other state-changingghinvocation) in the same session. Thebashtool now invalidates the matchinggithub-cacherows before executing anygh (issue|pr) <close|reopen|merge|delete|edit|comment|lock|unlock|pin|unpin|transfer|develop|ready|review>command. - 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-100andfile.pdf:5-16,40-80slice the converted body instead of returning the whole document. - Fixed the
readselector cheatsheet incorrectly promising "exactly one line" for:N+1while 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. - Documented the
bash.autoBackground.enabledbehavior in thebashtool prompt so theBackground job <id> started: …notice for foreground commands that exceedautoBackgroundThresholdSecondsno longer reads as a tool malfunction. - Fixed
tasksubagents whose in-toolyieldvalidator had already accepted a payload after exhaustingMAX_SCHEMA_RETRIESbeing rejected a second time by the post-mortem executor validator. The override now propagates through the yield tool'sdetails.schemaOverriddenflag, and the executor surfaces aSUBAGENT_WARNING_SCHEMA_OVERRIDDENstderr line instead of re-emittingschema_violationfor data the subagent already had to ship. Finalize also degrades to no validation (matching the yield tool'slooseRecordSchemafallback) when the caller-supplied output schema fails to normalize. - Fixed the
web_searchcodexprovider returning(see attached image)/[Attached image]/See image aboveand 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 fromanswer(returning sources only); when neither annotations nor a real answer materialize, we throw 502 to advance the provider chain. - Fixed
search,find,ast_grep, andast_editrejecting bracket-containing file paths (Next.js routes likeapps/[id]/page.tsx) as glob patterns when the literal path exists on disk.parseSearchPathPreferringLiteralnow prefers the literal interpretation for paths that resolve on disk and only falls back to glob expansion when the literal does not exist. - Fixed
searchwith an externalhttp(s)/ftp/ws/file://URL inpathssurfacing a misleading "Path not found" error. The tool now rejects external URLs with a clear "usereadfor URLs" message. - Fixed
searchrejectingskip: nullat the schema layer;nullnow normalizes to0alongside the omitted case, matching how callers serialize default pagination state. - Fixed
searchreturning zero matches with no explanation when explicit file targets exceed the native grep cap (4 MB). The tool now surfaces aSkipped oversized files (>4MB grep limit; …)notice listing the truncated paths. - Fixed the archive-extraction error message in
searchrecommendinggrep— which the system prompt forbids — instead of pointing toread <archive>:<member>. - Fixed
browsertab.open(name, { viewport })on an existing tab not applying the new viewport:acquireTab's reuse path now resizes the page in addition to navigating. - Fixed
browsertab metadata leakinguser:pass@basic-auth credentials in the URL surfaced to transcripts and observe snapshots; URLs are now redacted viaredactUrlCredentials(). - Fixed
browsertab.extract(format)returning aReadableResult | nullshape that the tool prompt advertised as plain content. The helper now returns the markdown/text string directly (or throws a clearToolErrorwhen extraction is empty), and the prompt matches. - Fixed
lsprequests 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 explicittimeoutMsis provided. - Fixed
lsp statusreporting servers asActive 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). - Fixed
lsp rename_filefanningwillRenameFilesrequests 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 whosefileTypescover the source or destination path, falling back to a plain filesystem rename when no server claims the type. - Fixed
lsp referencesreturning 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. - Fixed
lsp configacceptingfileTypesentries with or without a leading dot inconsistently across actions; both.tsandtsare now normalized so a missing-dot entry no longer silently excludes a server from extension-based routing. - Fixed
lsp requesterror 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. - Fixed
findwith a single-star segment likedir/*recursing into subdirectories and returning nested matches.parseFindPatternalready prepends**/for top-level globs (*.ts→**/*.ts), so anything reaching native without**/was deliberately scoped by the user;recursive: falseis now passed tonatives.globto honor that scope.
[15.10.1] - 2026-06-07
Added
- Added
display.smoothStreamingsetting (defaulttrue) to let users enable or disable smooth assistant-stream text reveal - Added
/tan <work>slash command to fork the current conversation into a background agent so tangential work can continue asynchronously while your main session stays active - Added a background
/tandispatch message that records the handoff in the transcript and marks the delegated work as non-blocking - Added
providerPromptCacheKeysupport toCreateAgentSessionOptionsso/tanbackground sessions can reuse the parent session’s prompt-cache lineage - Added session cloning for
/tanruns with copied artifacts and shared MCP proxy tools - Added
SessionManager.forkFrom’s optionalsuppressBreadcrumbmode to avoid breadcrumb updates when forking background/tansessions - Added OSC 5522 enhanced paste handling in
InputController, so terminal clipboard events are decoded as image or text payloads and inserted without passing raw paste sequences to the editor - Added bracketed image-path paste support in
CustomEditorso a single pasted image file path (PNG/JPEG/GIF/WEBP) is loaded from disk and inserted as an image candidate - Added direct support for
Image #Ninsertion from pasted local image paths by routing successful image-path pastes through the same image normalization and resize flow as clipboard image pastes - Added
/freshto rotate the provider-facing session id and clear in-memory provider stream/cache state without changing the local session file. - Added a
ChatBlocktranscript primitive (modes/components/chat-block.ts) and a singlectx.present(...)sink (withctx.resetTranscript()) so chat output is mounted in one place instead of the repeatedchatContainer.addChild(...)+ui.requestRender()pattern scattered across controllers.ChatBlockcarries a React/Svelte-style lifecycle —onMountstarts effects,onCleanupregisters teardown,finish()self-completes (stops timers and freezes the block at its final content), anddispose()/resetTranscript()tears everything down — so animated blocks own their own resources instead of leakingsetInterval/requestRenderbookkeeping into callers. The MCP "Connecting…" spinner is now such a block. - Added a
framedBlockoutput-block helper (tui/output-block.ts) plus aborderColoroverride andapplyBg: false(no background fill) on output blocks, arenderStatusLineiconOverride, and anicon.search(magnifier) theme symbol — so tool renderers can draw self-contained muted-outline frames and search-family tools can show a magnifier instead of a checkmark.
Changed
- Changed the bash tool frame to use a plain top rule instead of repeating "Bash" in the title bar, and folded minimizer raw-output artifact links into the status footer as
Artifact: <id>. - Changed grouped
readoutput to use a white filled-circle mark for the group/single-read success state and omit duplicate per-file success marks inside multi-read groups. - Changed assistant streaming output to reveal text incrementally at 30 FPS with grapheme-safe adaptive catch-up, instead of replacing the whole message chunk-by-chunk
- Changed shimmer-driven TUI animations (working text, pending bash/eval borders, and theme activity-spinner documentation) to render at 30fps instead of 60fps.
- Changed running
tasktool agent rows to use a static•marker and shimmer only the subagent name, leaving descriptions, stats, and nested tool detail text solid while removing the rotating status glyph from those rows. - Changed settings singleton method access to reuse bound methods for the active instance instead of allocating a new bound function on every
settings.getlookup. - Changed plan-mode approval to keep the drafted
local://<slug>-plan.mdfile at its original name as the canonical plan path, so approved plans are no longer renamed when leaving plan mode - Changed plan-mode write enforcement so only
local://artifact files are writable during planning, blocking working-tree edits and allowing scratch or draft plan files in the local artifact area - Changed the
todotool result renderer to stop redrawing every phase's full task list on each update: when a multi-phase list is rendered collapsed (the default, not manually expanded), only phases the latest update touched — the phase holding the in_progress task, any phase with a just-completed task, and phases named by the ops that ran (initcounts as touching all) — render their tasks; untouched phases collapse to a one-lineN. Name done/totalsummary. When call args are unavailable (e.g. transcript rebuilds) it falls back to the in_progress/completed-transition signals, and the manual expand toggle still shows every task. Also dropped the blank separator line previously inserted between phases. - Changed non-agent API operations (title and commit-message generation, image generation, web search, eval
llm(), auto-thinking classifier, memory consolidation) to use session-aware API key resolution with auth retries viaregistry.resolver()/authStorage.resolver(), refreshing the active credential before rotating to another account - Changed image generation to wrap every provider fetch branch in
withAuth, so 401 / usage-limit errors trigger credential force-refresh and rotation for authStorage-backed providers (OpenAI-hosted, antigravity, xai-oauth) while env-only providers (openrouter, gemini) stay single-attempt - Changed web-search providers using
authStorage.getApiKey(anthropic, exa, tavily, parallel, synthetic, zai, kimi) to wrap HTTP calls inwithAuthfor automatic credential rotation on 401 / usage-limit errors - Changed the directory grouping for
find,search,ast_grep,ast_edit, andlspdiagnostics from a single flat# dir/heading per immediate directory to a multi-level tree that folds the common path prefix into one heading. Previously every group repeated the full directory path — so results rooted outside cwd printed the absolute prefix (e.g./Users/me/proj/) on every heading and nested directories were never collapsed. Now a single-child directory chain folds into one heading (# packages/pkg/src/, including an absolute root for out-of-cwd results), subdirectories nest one#deeper (## nested/→### child.ts), and each directory's own files are listed before its subdirectories. TUI hyperlink reconstruction tracks the nested directory stack across the whole output so file and code-frame links keep resolving to the correct absolute paths. - Changed the plan-mode approval surface from an inline transcript block plus a separate bottom selector into a single fullscreen overlay (like
/copy) and overhauled its navigation. The overlay now renders the plan per-section throughScrollView(line-level ↑/↓ scroll, Shift+↑/↓ to scroll faster, PgUp/PgDn, g/G) with no stray per-line…, and — when the terminal is wide enough and the plan has ≥2 headings — shows a compact VS Code-style section sidebar (the redundant plan-title heading and any "Contents" label are omitted). Focus moves between regions with Tab/Shift+Tab (and flows at the edges: Down past the last section or the bottom of the body drops into the approval options; Up steps back), while the sidebar glows to track the scrolled section. The sidebar can fast-jump between sections, delete a section (withuundo), and annotate sections with feedback (a); deletions and annotations are collected into refinement feedback that is submitted back to the model when the operator picks "Refine plan". Mouse works too: clicking an approval option activates it, clicking a sidebar section jumps to it, and the wheel scrolls the plan. ←/→ always drive the model-tier slider, Enter confirms, the external-editor key opens the plan, and Esc cancels. The overlay borrows the terminal's alternate screen buffer for its lifetime (fullscreenoverlay), so the transcript stays put on the normal screen instead of bleeding through scrollback behind the modal. - Changed the interactive controllers (command, MCP, selector, extension-UI, event), debug panels, and the status/error/warning helpers to render chat output through
ctx.present(...)instead of appending tochatContainerand callingui.requestRender()directly; transcript rebuilds dispose live blocks viactx.resetTranscript()so animated blocks' timers stop on reset. - Changed tool-execution block rendering so the container (
ToolExecutionComponent) is a transparent passthrough — it no longer inserts a top/bottom blank line, adds left/right padding, or paints a state-colored background behind tool output. Tools with substantial body now self-frame with a muted outline and the tool title in the frame's top bar (edit/apply_patch,write,ask,todo,github,goal,inspect_image,search_tool_bm25,task), matching the already-framedbash/read/eval/debug/web_search/lspblocks, while streaming/in-progress and trivial results collapse to a clean status line. The search-family list tools (find,search,ast_grep) andjobrender frameless/minimal;find/search/ast_grepshow a magnifier on success instead of a checkmark, andjobdrops itsJob:label prefix (the per-job rows are self-describing). Thesearch_tool_bm25,github, andinspect_imageframes draw with no background fill, andinspect_image's label was shortened toInspect. - Changed the plan-mode active prompt (
prompts/system/plan-mode-active.md) to make plans decision-complete and cut filler. Added an Objective framing ("another engineer can execute end-to-end without making a single design decision"), a shared "Resolving Unknowns" section (explore discoverable facts before asking; reserveaskfor non-derivable preferences/tradeoffs with 2–4 options + a recommended default), and a single shared "The Plan" structure (Context / Approach grouped by behavior not file-by-file / ≤5 Critical files / Verification / Assumptions) that replaces the per-branch structure guidance previously duplicated across the iterative and parallel workflows. Added explicit prohibitions on sections that decide nothing (Non-Goals, Out of Scope, Alternatives Considered, Risks/Mitigations boilerplate, Future Work), on enumerating every file/line, and on inventing schema/validation/precedence policy the request never established. - Changed completion notifications (
completion.notify) to fire whenever the agent yields its turn, including in the foreground. Theagent_endnotification was previously gated behind background mode (isBackgrounded), so an ordinary foreground turn never emitted one; the gate is gone and the desktop toast now fires on every normal turn completion (still skipped for aborted/error turns and whencompletion.notifyisoff). - Changed the in-progress
tasktool block to keep the sharedcontextbrief (# Goal/# Constraintsbackground) visible after the first progress snapshot arrives, instead of dropping it the moment the streaming call view was replaced by the result frame, and to stop animating a spinner/clock next to theTaskframe header while running — the per-agent body lines already carry their own running spinner, so the header now shows a static state icon (matching the completed/failed header icons). The context is rendered through a sharedbuildContextSectionhelper that also undoes per-field double-encoding, so the brief reads cleanly in the result frame even thoughrenderResultreceives the raw (un-repaired) tool args. - Changed the messaging shown when you press Esc to interrupt a streaming turn from the ambiguous
Operation aborted/Tool execution was aborted: Request was abortedtoInterrupted by user, so a deliberate user interrupt no longer reads like an internal failure. Every Esc/flush interrupt path (onEscapewhile streaming, the queued-message restore-and-abort path, and the empty-submit queue flush) threads the reason throughAgentSession.abort({ reason })→Agent.abort(reason)so it rides theAbortControlleronto the aborted assistant message'serrorMessage; the turn label renders it verbatim on both the live and replay paths, and the synthetic placeholder results paired with in-flight tool calls now readTool execution was aborted: Interrupted by user. Aborts that carry no reason still fall back to the retry-awareOperation abortedgeneric. Transcript label resolution is centralized inresolveAbortLabel(session/messages.ts).
Removed
- Removed the
/background(and/bg) slash command and the background-mode subsystem it was the sole entry point for —InteractiveMode.isBackgrounded,createBackgroundUiContext,handleBackgroundEvent, and everyisBackgroundedguard across the input/event/extension-UI controllers and UI helpers. The command suspended the whole process group viaSIGTSTP(a leftover testing shortcut) instead of detaching the running agent, which is not the expected workflow — use terminal panes or a multiplexer instead.
Fixed
- Fixed inline
findandsearchresult blocks to align with groupedreadoutput and render their success headers with the normal tool-title color instead of accent blue. - Fixed the working-status shimmer to opt into the loader's 30fps animated-message repaint path while keeping both the status spinner and pending bash/eval tool spinners on their normal 80 ms glyph cadence.
- Fixed consecutive
readtool calls failing to collapse into a single grouped block when a reasoning model emits one read per completion ([thinking, read]). The read group was reset on every assistantmessage_start, so each read rendered as its own one-entryRead …line; now a read run accretes across completions and is broken only by a rendered non-empty text/thinking block, a non-read tool, or a user/IRC message — matching the transcript-rebuild path.ReadToolGroupComponentnow reports its live/finalized state so the growingRead (N)header repaints correctly on native-scrollback (risk) terminals. - Fixed the
tasktool shared-context brief rendering raw Markdown headings (# Goal,# Constraints) inside framed call/result blocks instead of using the normal Markdown renderer. - Fixed the animated pending border on
bash/evalblocks leaving a frozen dark "bar" segment behind after a backgrounded command finalized through the async update path. Once a command is auto-backgrounded (details.async.state === "running") the block stays "partial" in the TUI until the async job-manager delivers the final result, but it also gets committed to native scrollback — so a mid-sweep shimmer frame baked a stray darkened border segment into the committed copy. The border now stops animating (and the 60fps redraw loop stops) the moment a block enters the backgrounded state, so the committed frame is a clean static border. - Fixed cold
omplaunch to clear native terminal history on the first paint, avoiding a once-per-launch duplicate welcome/transcript copy before the normal session replay. - Fixed plan approval resolution so
resolvewithaction: "apply"can still find the plan file whenextra.titleis missing or stale by falling back to the current plan path and most-recent local plan artifacts - Fixed the search-family tool magnifier glyph (
find,search,ast_grep,search_tool_bm25) to use theaccenttitle color instead ofsuccessgreen, so the icon matches the tool title in the status header instead of standing out - Fixed TTSR stream interrupts to pass the matched rule name through the abort reason, so aborted in-flight tool placeholders say why they were stopped instead of
Request was aborted. - Fixed URL reads for binary/special payloads to reuse local readers: remote archives list their root entries, SQLite databases show their table overview, notebooks render as editable cells, and unrenderable binary returns a metadata notice instead of decoded byte garbage.
- Fixed pasted image-file paths that cannot be loaded to fall back to normal text paste with status feedback instead of disappearing.
- Fixed tool-output file paths not being clickable OSC 8
file://hyperlinks in several renderers.readtitles for plain text and image files (the common case) emitted no link at all because the renderer only linked when aresolvedPathwas recorded — which the ordinary file/image read paths never set, keeping the absolute path only inmeta.source; the renderer now falls back to that source path.writeheaders were never wrapped in a hyperlink and now link to the absolute path written (file, archive entry, SQLite, and conflict resolutions).edit/apply_patchheaders wrapped the model-supplied (often cwd-relative) argument path, producing a root-anchoredfile:///rel/pathURI; they now link the absolutedetails.pathinstead. Finally,search,ast_grep, andast_editproduced doubled link targets (/proj/src/src/file.ts) for searches scoped to a subdirectory, because the renderer resolved the cwd-relative display paths against the scope directory rather than cwd — the scoped-search base is now the session cwd (with the scoped file's absolute path still seeding single-file body lines). - Fixed
omp dry-balance --benchto recover from 401 token failures by re-minting the failing OAuth credential in place before switching accounts - Fixed the bash tool corrupting commands that embed multi-byte UTF-8 (e.g.
✓/×inside agrep -Epattern) ahead of a trailing| head/| tail. Thebash.stripTrailingHeadTailrewrite cut at char-offset positions reported bybrush-parserwhile slicing the command by byte offset, so the trailing-pipe strip landed mid-pattern and dropped the closing quote — turning… |✓|×|XCTAssert" | tail -80into… |✓|×-80and making execution fail withpi-natives:command: unterminated double quote. Fixed inpi_shell::fixup(@oh-my-pi/pi-natives). - Fixed
omp dry-balance --benchto recover from 401 token failures by re-minting the failing OAuth credential in place before switching accounts - Fixed duplicate file entries in grouped outputs for
find,search,ast_grep,ast_edit, andlspdiagnostics when the same path appeared multiple times - Fixed search, grep, and edit output rendering so repeated directory group blank-line boundaries no longer break nested path/link reconstruction
- Fixed
omp dry-balance --benchflooding the terminal with staircased, duplicated spinner/status lines (and an indented summary) when the tty has ONLCR/OPOST disabled (raw mode). The interactive progress region separated rows with a bare LF and repositioned with a column-preserving\x1b[<n>Acursor-up, both of which only land at column 0 when the terminal translates LF→CRLF; with that translation off, every 80 ms redraw cascaded down and to the right into scrollback. The live region now carriage-returns before every cleared row, terminates each row with CRLF, and caps each row to the terminal width so a wrapped line cannot desync the cursor-up from the logical line count. - Fixed inconsistent vertical spacing between transcript blocks: some blocks (tool results from
search/findand other renderer-backed tools) rendered with a doubled gap (a leadingSpacerplus the content box's ownpaddingY), while others (the groupedreadcard, file-mention lists, IRC cards) rendered with no gap at all. Vertical spacing is now owned entirely by the chat renderer:TranscriptContainerstrips each block's plain-blank top/bottom edges and inserts exactly one blank line between consecutive blocks, so every block is separated by a single consistent gap regardless of which component produced it. Individual components (assistant/user/tool/read-group/bash/eval/skill/custom/hook/compaction/branch/todo-reminder/plan-review messages) no longer emit their own leadingSpacer/paddingYfor separation, and multi-row groups (IRC cards, file-mention lists, completed-job batches, and the bordered command//changelog//context/version/OAuth/debug panels) are wrapped as singleTranscriptBlockchildren so the renderer spaces them as one unit. Background-colored box padding is preserved as block-internal design. - Fixed
resolvewithaction: "discard"surfacing a hardisError"No pending action to resolve" failure to the model when the agent asked to cancel a staged action (e.g. anast_editpreview) but nothing was pending. A discard is a request to reach the "no staged change" end-state, which already holds in that case, so it is now honored as a successful cancellation ("Nothing to discard; no pending action remains."withdetails.action: "discard") instead of an error.action: "apply"with no pending action still errors. - Fixed the collapsed tool-output expand hint rendering double brackets (e.g.
((Ctrl+O for more))) — theEXPAND_HINTtext already carried its own parentheses and thenformatExpandHintwrapped it again with the theme's bracket glyphs. The hint now resolves the key actually bound toapp.tools.expandat render time and reads⟨<key>: Expand⟩(e.g.⟨Ctrl+O: Expand⟩), so a single bracket pair surrounds it and a user remap of the expand keybinding is reflected instead of a hard-codedCtrl+O. - Fixed the
edit/apply_patchtool dropping its outlined frame while streaming/in-progress (only the final result was framed); the in-progress diff preview now renders inside the same muted frame as the completed result. - Fixed the
todoandjobtools rendering a success icon and success styling on a failed/error result; error results now show the error icon and a red frame border. - Fixed
debugtool refusing everydlvlaunch on Go modules. The launch handler ranvalidateLaunchProgrambefore adapter selection and rejected any directory program withlaunch program resolves to a directory, while dlv's defaultmode=debugrequires a Go package path (a directory or.gosource file). Adapter resolution now precedes validation, directory programs prefer adapters that advertiseacceptsDirectoryProgrambefore falling back to native extensionless debuggers, the rejection only fires when the resolved adapter does not advertise that flag (set ondlvindap/defaults.json), and dlv'smodeis derived from the program shape — directories and.gofiles launch asmode=debug, other files asmode=exec— soompcan debug both Go packages and pre-built binaries (#2020).
[15.10.0] - 2026-06-06
Breaking Changes
- Replaced the
providers.parallelFetchboolean setting with theproviders.fetchenum (auto/native/trafilatura/lynx/parallel/jina) that selects the URL reader-backend priority for theread/fetchtool, mirroringproviders.image/providers.webSearch. Existing configs are migrated automatically: the legacy key is dropped and the newautodefault applies.
Added
- Added a GitHub Actions read handler to the
read/web-fetch GitHub scraper. Fetchinggithub.com/{owner}/{repo}/actions/runs/{id}renders the run metadata plus a per-job breakdown (steps listed for any job that did not succeed), and…/actions/runs/{id}/job/{id}(also the API-style…/jobs/{id}) renders a single job's metadata, step table, and full plain-text logs. Logs are fetched via theactions/jobs/{id}/logsredirect usingGITHUB_TOKEN/GH_TOKENwhen present, with the per-line ISO timestamp prefix and leading BOM stripped; the section degrades to an explicit notice when logs are unavailable (no token, private repo, or expired/unfinalized run).
Changed
- Changed eval
agent()subagents so they are never subject to thetask.maxRuntimeMswall-clock cap. The parent cell's idle watchdog is already suspended for the entire bridge call (withBridgeTimeoutPause), so a long-running fan-out/recovery workflow must not be killed by a per-subagent runtime limit.runEvalAgentnow passesmaxRuntimeMs: 0torunSubprocess, which honors an explicitExecutorOptions.maxRuntimeMsoverride over the inherited setting. - Changed interactive timing behavior so
PI_TIMING=x pipreloads the module timer before the CLI graph loads and includes the(modules)report.PI_TIMING=fullnow also exits after printing, matchingPI_TIMING=x, so full module reports are usable for cold-start measurement without launching the TUI. Added the rootdev:timingscript for the same profiled startup path. - Changed coding-agent startup imports so normal TUI launch imports
InteractiveModedirectly, keeps print/RPC/ACP runners on their branch-only paths, and moves marketplace auto-update work behind a lightweight deferred starter. - Changed cold-launch setup gating so the full setup wizard (every scene plus the overlay and their TUI/OAuth/web-search/theme dependencies) is no longer statically imported by
main.ts. The current setup version now lives in a tiny dependency-freemodes/setup-versionmodule, and the wizard barrel is lazy-loaded only when the stored setup version is stale or the wizard is forced — the common up-to-date launch skips loading it entirely. - Changed cold-launch startup imports so the hot-path CLI files no longer pull the full
@oh-my-pi/pi-aibarrel:commands/launch.tsandcli/args.tsimportTHINKING_EFFORTS/Effortfrom the tiny@oh-my-pi/pi-ai/effortmodule, andconfig/model-registry.tsnow imports its ~20 symbols from narrow subpaths (api-registry,model-cache,model-manager,model-thinking,models,provider-models,types,utils/event-stream) instead of the barrel — so launching no longer eagerly loads every provider, auth, OAuth, and usage module re-exported by the barrel. - Changed the
read/fetchHTML reader-backend priority tonative > trafilatura > lynx > parallel > jina(wasparallel > jina > trafilatura > lynx > native). The in-process nativehtmlToMarkdownruns first — instant, no network, full-fidelity — so the common case no longer depends on a remote service, and a stalled remote backend can no longer mask it. Selecting a specific backend viaproviders.fetchtries it first, then the rest fall back. The low-quality gate (>100chars and notisLowQualityOutput) now applies uniformly to every backend; when none clears it, the highest-priority substantial-but-low-quality output is still surfaced so thellms.txt/ document-extraction fallbacks keep running.
Fixed
- Fixed eval
agent()failures surfacing as an opaqueRuntimeError: bridge call '__agent__' failedwith no reason. When a subagent aborted,runEvalAgentbuilt its failure message withresult.error ?? result.stderr ?? result.abortReason ?? …, butresult.stderris the empty string on a clean abort (andresult.erroris gated on a non-emptystderr), so the nullish chain stopped at""and never reachedabortReason. The empty string propagated through the loopback bridge and the Python prelude'sRuntimeError(msg or "bridge call … failed"), discarding the real reason. The chain now uses||so an emptystderrfalls through toabortReason. - Fixed subagent aborts being mislabeled as the generic "Cancelled by caller" when the abort originated inside the subagent's own turn (
stopReason: "aborted"with no caller signal and no runtime-limit timer).runSubprocessnow prefers the aborted assistant message'serrorMessage(e.g. "Request was aborted" or a specific stream error) for that case, while a real caller signal or wall-clock abort still reports its precise reason. - Fixed a long streaming tool preview that alone overflows the viewport dropping its scrolled-off head on ED3-risk terminals (ghostty/kitty/iTerm2/…). When expanded with
Ctrl+O, a streamingwrite(content streaming in) and a streamingeval(stdout streaming below its fixed code cell) render top-anchored and grow append-only, but the tool block never reported itself append-only to the transcript, so the renderer's commit-as-you-go boundary stopped at the block start and the earlier rows that scrolled above the viewport were committed nowhere — they vanished, leaving the preview looking like a viewport-tall circular buffer.ToolExecutionComponentnow implementsisTranscriptBlockAppendOnly()(gated onisTranscriptBlockFinalized(), so it also covers partial-result streams likeeval), delegating to a renderer-declaredisStreamingPreviewAppendOnlypredicate so the expanded stream commits its head exactly like a streamed assistant reply. Collapsed previews (bounded sliding tail windows) and finalized/result previews (which can collapse to a capped view) stay deferred. - Fixed
read/fetchsilently dropping whole list sections on pages with malformed list markup — stray<img>, text, or<video>nodes as direct children of<ul>(e.g. the Alacritty changelog). The Jina reader (previously tried before the local renderers) mis-extracts such lists, returning emptyAdded/Changedsections; the native in-process renderer now runs first and preserves the full content. - Fixed
/usageaggregate amount fallback using rawlimits.lengthas account count — now counts uniqueaccountIdvalues from limit scopes, so N limits from a single account no longer display as "N accts". - Fixed
/usageaccount labeling falling back to "account N" for providers that useprojectIdas their primary identity (e.g. Google Antigravity, Gemini CLI) —projectIdfrom report metadata is now considered before the generic fallback. - Fixed the
todotool's TUI renderer crashing withTypeError: args?.ops?.map is not a functionwhen a streaming tool-call delta surfaced a non-arrayopsfield (mid-streamparseStreamingJsonshapes like{ ops: "[{" }, or[null]entries before fields arrive). The renderer now treats non-arrayops, non-object entries, and non-arrayitemsas missing structure instead of crashing, which also stops the spam-warn cascade that followed each malformed delta. Paired with the Anthropic-side reasoning-replay fix inpackages/ai(#2005). - Fixed Python eval
agent()collapsing subagent runtime-limit aborts (and other empty-stderr aborts) into a genericRuntimeError: bridge call '__agent__' failed.runEvalAgentcoalesced the failure message with??, which stopped at the emptystderrand never reachedabortReason, shipping an empty error through the loopback bridge. The bridge now prefersabortReasonfor aborts and trims emptystderr/errorout of the fallback chain, so Python surfaces the actionable reason (e.g.Subagent runtime limit exceeded (task.maxRuntimeMs=900000)) (#2006).
[15.9.69] - 2026-06-06
Added
- Added anonymous fallback for Perplexity web search, allowing
web_searchand explicit Perplexity provider usage when no Perplexity credentials are configured - Added
galleryCLI command to render built-in tool renderer output across streaming, in-progress, success, and failure states - Added
omp galleryfiltering and rendering options (--tool,--state,--width,--expanded, and--plain) for focused renderer previews and plain-text output - Added
omp galleryfidelity for tools whose renderers are attached on the tool instance (lsp,task): the gallery now drives them through the same custom-tool render branch production uses, so regressions in that path surface in the gallery rather than only in a live session. - Added
omp gallery --screenshot, which renders the gallery through a real virtual terminal (VHS) and writes PNG screenshot(s) instead of ANSI, so agents (and anything that can only read raw bytes) can actually see the rendered output. The capture forces truecolor and matches the active theme/symbol preset; tall galleries split across multiple images (whole renderers are never cut). Tune with--out,--font, and--font-size; requiresvhsonPATHand fails with install guidance when absent. - Added
app.display.reset, bound toCtrl+Lby default, to force an immediate terminal display reset/redraw without resizing the window.
Changed
- Changed authenticated Perplexity ask requests to default to the
experimentalmodel preference, matching the anonymous fallback. - Changed Perplexity explicit provider availability checks so the setup wizard can mark
perplexityas available for manual selection without credentials, while auto provider discovery still requires auth - Changed the default persistent model selector shortcut from
Ctrl+LtoAlt+M, leavingCtrl+Lfor display reset. Existing user remaps inkeybindings.ymlare preserved. - Changed the edit tool result header to carry the diff change stats (
+N / -M / K hunks) inline next to the file path, and removed the redundant lone language-icon metadata row and the blank line between the header and the diff body, so a single-hunk edit renders as✔ Edit: <icon> path:LINE ⟨+3 / 1 hunk⟩immediately followed by the diff. - Changed the
web_searchtool result rendering: the answer text now shows in full instead of being truncated to a "… N more lines" preview (theomp qCLI still caps its compact output), each source renders as a singletitle (domain) · ageline with the URL linked on the title (dropping the snippet and bare-URL rows), and the metadata block collapses to oneProvider: <model> @ <provider> (<auth>)line plusUsage:(removing the redundant Sources/Citations/Request/Queries rows).
Fixed
- Fixed Perplexity
perplexity_askresponse parsing so OAuth, cookie, and anonymous searches correctly extract answer text and sources from JSON payloads - Fixed framed read results rendering with an extra blank row above and below the output block.
- Fixed collapsed search result previews that could show only "… N more matches" when the first grouped section exceeded the preview budget. Collapsed search output now compacts to match rows, fills the budget with visible hits before the summary, and keeps truncation details out of the bottom user-visible notice.
- Fixed the expanded search result view dumping every match when all hits live in one file. A single file's matches collapse into one blank-line group, and the expanded tree list ignored the line budget, so a hot file whose matches span its whole length rendered every row (e.g. lines 374–2858). Expanded search output is now bounded by a larger-than-collapsed budget (
EXPANDED_LINES × 2), keeps surrounding context rows, and appends a… N more matchessummary when truncated. - Fixed boolean environment flag overrides that were ORed with settings, so
PI_INTENT_TRACING=0,PI_AUTO_QA=0, and per-backend eval flags now take precedence when present while falling back to config when unset. - Fixed custom-rendered tools that set
mergeCallAndResult(e.g.lsp) rendering a redundant tool-name line above the framed result once a result arrived.ToolExecutionComponent's custom-tool branch now emits the fallback label only when the tool has norenderCalland the call is not suppressed by an existing result, matching the built-in renderer branch. - Fixed the
writetool result rendering with a green success checkmark even when the write failed.writeToolRenderer.renderResultnow branches onresult.isError, rendering the error status icon plus the failure message instead of the success header and content preview. - Fixed Perplexity OAuth/cookie web search returning a refusal answer ("I don't currently have access to the web-search tools in this turn") despite returning real sources.
callPerplexityOAuthwas prepending the API-styleweb-searchsystem prompt to the query (query_str = systemPrompt + "\n\n" + query), but the consumerwww.perplexity.ai/rest/sse/perplexity_askendpoint has no system-message slot and reads the prepended instruction as a meta-prompt, making the model decline. The OAuth/cookie path now sends the bare query; the API-key path still passes the system prompt as a propersystemmessage. - Fixed Perplexity OAuth web search always returning the free
turbomodel instead of the account's Pro model (e.g.pplx_pro_upgraded/Sonar). Thewww.perplexity.ai/rest/sse/perplexity_askendpoint authenticates via the__Secure-next-auth.session-tokencookie and ignores theAuthorization: Bearerheader entirely — so sending the OAuth session token as a bearer was treated as an anonymous request, which silently downgrades toturboregardless ofmodel_preference. The stored Perplexity OAuth token is itself the next-auth session JWT (the macOS app injects the same value as that cookie), socallPerplexityAsknow sends it as the__Secure-next-auth.session-tokencookie, unlocking Pro model selection.
[15.9.67] - 2026-06-06
Added
- Added
timeout-pauseandtimeout-resumeeval bridge status events emitted aroundagent()/llm()operations - Added a
/copypicker:/copynow opens a fullscreen, outlined tree of recent assistant messages with their code blocks nested beneath (like/tree). Navigate with ↑↓, and Enter copies the highlighted node — a whole message, an individual code block, "All N blocks", or a bash/eval command interleaved with the assistant turn that issued it. A live preview pane shows the selected target, wrapping prose and syntax-highlighting code/commands.
Changed
- Changed eval timeout accounting so delegated bridge calls now suspend the cell watchdog and start a fresh timeout window when runtime control returns
- Changed
IdleTimeoutto support reference-counted pauses so overlapping delegated bridge calls keep timeout paused until all calls complete - Changed the default
app.message.followUpbinding fromCtrl+Enteralone to[Ctrl+Q, Ctrl+Enter]so the follow-up shortcut works in Windows Terminal, which does not deliver a distinctCtrl+Enterevent to console apps.Ctrl+Qmirrors the GitHub Copilot CLI default for the same action; existing remaps in~/.omp/agent/keybindings.ymlare untouched, and if another user-remapped action already claimsCtrl+Q, that user binding wins while follow-up keepsCtrl+Enter.Ctrl+Qis also reserved byExtensionRunnerso an extension cannot register that chord and be silently overwritten by the built-in follow-up handler (#1903). - Changed all scrollable TUI pickers and viewports to render through the shared
ScrollViewright-edge scrollbar for a uniform look, replacing their ad-hoc(N/M)/[a-b/total]text indicators (search hints and the tree filter-mode label are preserved). Covers the session/resume picker, model selector, OAuth provider selector, history search, session tree selector, agent dashboard list, extension list, user-message selector, the raw SSE debug viewer, the autoresearch dashboard overlay, and the session observer overlay. - Changed the
/modeland/switchselectors to dim and skip models whose context windows are smaller than the current chat context. - Changed
/copycommand targets to appear inline with recent assistant messages instead of as a separate "Last bash command" row at the end of the picker.
Fixed
- Fixed the idle
Working...loader freezing on ED3-risk terminals with unobservable native scrollback by keeping foreground live-region rendering enabled fromagent_startuntilagent_end, before the first assistant or tool event arrives. - Fixed framed tool output blocks rendering one column inset inside tool boxes; modern bordered blocks now span the same width as legacy background-filled tool boxes.
- Fixed potential
TimeoutErroraborts for shorttimeouteval cells during long bridgedagent()/llm()work where no progress events are emitted until completion - Fixed retry recovery to allow automatic retries without switching models when
retry.modelFallbackis disabled. - Fixed
ttsr.enabled: falsebeing ignored at runtime. TTSR rules were still being registered withTtsrManager.addRuleand matched against stream deltas even when the global toggle was off, so disabling TTSR did not suppress rule injection or stream abort. The manager now gatesaddRule,hasRules, and#matchBufferon the enabled flag, so disabling fully short-circuits the TTSR path. Condition rules fall through to the rulebook bucket instead of being silently swallowed. (#1767) - Fixed the Python eval kernel hanging on Windows during
import pandas/import numpy, with SIGINT unable to recover the cell.PythonKernel.start()spawned the runner withwindowsHide: true, which in Bun maps to the Win32CREATE_NO_WINDOWflag and detaches the long-lived child from any inherited console — so native extensions likenumpy/_core/_multiarray_umath.pyd(and its bundled OpenBLAS/SLEEF thread-pool init) could deadlock insideLoadLibraryExW, andGenerateConsoleCtrlEvent-based SIGINT delivery silently became a no-op. The kernel now hides its window only when the host itself has no console to share (service / piped launch); an interactive TUI launch lets the kernel inherit the parent's console, matching the behavior ofpython.exeinvoked fromcmd.exe(#1960). - Fixed
taskrenderer crashing the TUI withTypeError: completeData?.map is not a functionwhen a subagent'sextractedToolData.yieldslot held a non-array value.renderAgentResult(and the live-progress sibling) cast the slot toArray<{ data }>and called?.map, but optional chaining short-circuits only onnull/undefined, so a plain object made.mapundefinedand threw — taking down everyreviewtask render. Both sites now go throughnormalizeYieldData, which wraps a single object as a 1-element array and drops primitives (#1987) - Fixed
sdk-async-job-manager-singletontests flaking under the full parallel suite. The fourcreateAgentSession-based cases ran on the default 5000ms per-test timeout, which two real session startups can exceed whentest:tssaturates the machine across packages; on timeout the still-running test body andafterEachreset raced, surfacing a spurious "Unhandled error between tests" on theAsyncJobManager.instance()assertion. They now carry an explicit 60000ms timeout, matching the convention used by the other session-creating tests in this suite. - Fixed streaming
eval,bash,ssh, andtaskcall previews overflowing the live transcript viewport and cutting off their top while pending. A volatile tool block taller than the viewport could strand its scrolled-off head out of native scrollback on ED3-risk terminals (committed nowhere, repainted nowhere) until the result landed. The pendingevalsource preview now follows the streaming edge in a bounded 12-line tail window (newest lines pinned to the bottom, "… N earlier lines" on top) so you can watch the code being written without the box overflowing;bash/sshcommands andtaskcontext use a bounded head+tail window.Ctrl+Ostill lifts the cap for a full view. - Fixed the streaming
writecall preview ignoringCtrl+Oso the expand toggle was a no-op while a file was being written. Unlike theeval/bash/ssh/taskstreaming previews,formatStreamingContentnever received theexpandedflag, leaving the preview pinned to a bounded 12-line tail window even after pressingCtrl+O— so on a large write you could not widen past the streaming edge until the tool result landed. The preview now lifts the cap to the full file (head through tail) when expanded, matching the documented streaming-preview behavior of the other tools. - Fixed turn-ending provider errors rendering twice — once as the transcript's inline
Error: …line and again in the pinned banner above the editor (added in 15.9.5). The inline line is now suppressed while the same error is mirrored in the banner and restored to the transcript when the banner clears at the next turn, so the error stays in history without the duplicate render at the error moment.
Removed
- Removed the
/copy last|code|all|cmdsubcommands; every copy target is now reachable by picking it in the/copytree.
[15.9.5] - 2026-06-05
Added
- Added a persistent error banner pinned above the editor when an assistant turn ends on a provider error (e.g. Anthropic's "Output blocked by content filtering policy"). The transcript
Error: …line scrolls away as the conversation grows, so terminal turns that ended on a stream error could pass unnoticed; the banner stays in the fixed region above the input and is cleared when the next turn starts. - Added bold, underlined, clickable
[Image #N]placeholders in the draft editor and sent user-message bubbles, backed by extension-bearing blob-store sidecar files so terminalfile://links open in image viewers. - Added the active model identifier (
provider/id) to the system prompt's<workstation>block so the agent knows which model it is running as. Gated by the newincludeModelInPromptsetting (default on); the base prompt is rebuilt on a mid-session model switch so the surfaced identifier stays current. - Added
OLLAMA_HOSTsupport for implicit local Ollama discovery whenOLLAMA_BASE_URLis unset, so OMP picks up the same host setting used by Ollama. - Added
OLLAMA_CONTEXT_LENGTHas a positive-integer context-window override for implicit local Ollama discovery, so users can correct OMP context budgeting without writing per-model overrides.
Changed
- Changed
tools.discoveryModeto default toauto, which keeps discovery off for small tool sets and automatically switches to MCP-only tool discovery when more than 40 tools are registered.
Fixed
- Fixed user-message rendering to materialize image links from embedded image blocks when rebuilding chat output, so image placeholders remain clickable after replayed or restored messages
- Fixed queued/steering user messages carrying a pasted image rendering out of order — sometimes dropping the user bubble below the very tool output it was sent to steer.
EventController.#handleMessageStartawaited async image-link materialization between the usermessage_startandaddMessageToChat; sinceAgentSession.#emitdispatches TUI listeners fire-and-forget, that mid-handler yield let the next synchronously-handled events (assistantmessage_start, tool execution start/end) append their components first, scrambling transcript order and live-region block boundaries. The bubble is now appended synchronously, with clickable image links still materialized via the synchronous blob-store fallback. - Fixed tool execution cards to finalize promptly when a turn is abandoned or completed so stale streaming previews and frozen spinner frames no longer keep transcript rows in the live region
- Fixed
readandsearchTUI rendering to emit OSC 8 hyperlinks for HTTP URLs,local://resources backed by files, and filesystem search targets, including line-specific links for search match rows. - Fixed aborted streaming assistant messages staying frozen before their red "Operation aborted" label when status rows were appended underneath on ED3-risk terminals.
- Fixed
omp/omp -cstacking a fresh welcome screen and transcript on top of the previous run's leftover terminal scrollback. The cold-launch transcript render was the only session-load path that did not passclearTerminalHistory, so the TUI's scrollback-preserving initial paint left the prior run's welcome + conversation above the new one; the cold launch now clears native scrollback before painting, matching every in-process session switch. - Fixed a long streamed assistant reply dropping its earlier lines on ED3-risk terminals (Ghostty/kitty/iTerm2) once it grew past the viewport — the head scrolled off the top and never reached scrollback, so the reply rendered as a ~viewport-tall circular buffer of only its latest lines.
AssistantMessageComponentnow reports itself as an append-only transcript block andTranscriptContainersurfaces the resulting commit-safe boundary, so the renderer commits the scrolled-off head to native scrollback instead of discarding it (volatile tool previews stay deferred as before).
Security
- Blocked OSC 8 hyperlink wrapping for URI targets containing terminal control bytes to avoid rendering malformed control-sequence links
[15.9.4] - 2026-06-05
Fixed
- Fixed chat transcript updates after submitting input so frozen scrollback is only thawed when native scrollback replay succeeds, preventing misplaced or duplicated rows when the viewport is not at the tail
- Fixed
readof.ziparchives to list the central directory without inflating every member, so large or corrupt zip payloads no longer freeze directory reads; member contents are inflated only when a specific entry is read. - Fixed the Python
evalkernel being hard-killed (and its persistent session state lost) when a cell blocked inparallel()/agent()was interrupted. Eachagent()/tool.*call blocks a kernel worker thread in a synchronousurllibrequest to the host bridge, andparallel()'sThreadPoolExecutorexit joins those threads — so the kernel cannot unwind aKeyboardInterruptuntil every in-flight bridge call returns. A wide subagent fan-out's teardown routinely outlasted the kernel's 5s SIGINT-escalation window, so the kernel was force-killed (surfacing[kernel] Python kernel shutdown) while the subagents were still winding down. The host bridge now resolves an in-flight call the instant the cell's signal aborts, so the kernel unwinds cleanly and keeps its state; the already-signaled subagent continues tearing down in the background. - Fixed
githubtoolrun_watchop ignoring the explicitrepoargument and silently watching the cwd-inferred repository in nested/umbrella workspaces.executeRunWatchpassedundefinedfor the user-suppliedrepotoresolveGitHubRepo, so a call like{op: "run_watch", repo: "owner/cxf", branch: "main"}fell back togh repo viewin cwd and streamedwatching <sha> on <cwd-repo>against the wrong repository. The explicitreponow takes precedence over the cwd inference, and the no-branch/no-runpath refuses to derive the watched commit fromgit HEADunless the cwd actually points at the resolved repo — otherwise it raises aToolErrortelling the caller to passbranchorruninstead of silently rebinding to an unrelated commit (#1949). - Fixed
omp plugin install <local-path>failing withInvalid package name: .(and similar) for cwd-relative (.,./pkg), absolute (/abs,C:\…,\\unc), and tilde-prefixed (~/pkg) specs.classifyInstallTargetnow returns alocalarm in addition tomarketplace/npm, andplugin installroutes those specs toPluginManager.link()— the same code path asomp plugin link. (#1945) - Fixed the
web_searchresult renderer capping the synthesized answer at 12 lines even when expanded, while the Sources list expanded in full — so a long answer stayed truncated ("… N more lines") afterCtrl+O, making the expand toggle look like a no-op and dwarfing the answer next to its sources. The answer now renders the full text (markdown-formatted) when expanded and a short markdown preview when collapsed, matching the sources' collapse/expand behavior. The answer is also rendered through the Markdown component instead of dimmed raw lines, so headings, bold, lists, and code in the answer display formatted.
[15.9.3] - 2026-06-05
Fixed
- Fixed
@-mention auto-read injecting an unrelated, same-named file when a mention did not point at a real path — e.g. an npm scope like@scope/, a partial path, or a bare token.generateFileMentionMessagesresolution previously fell back to prefix and repo-wide fuzzy matching (globbing the whole project on every such mention) and auto-read the single "best" guess. Resolution is now exact-only: a mention is auto-read only when it resolves to an existing file or directory; otherwise it is left as prose. The TUI@-selector already inserts the real, complete path before send, so post-send guessing was both unnecessary and the source of the wrong-file reads. Directories still resolve and are listed. Removes the per-mention**/*project scan.
[15.9.2] - 2026-06-05
Added
- Added an encrypted local auth-broker snapshot cache for
discoverAuthStorage, withOMP_AUTH_BROKER_SNAPSHOT_TTL_MSandOMP_AUTH_BROKER_SNAPSHOT_CACHE, so fresh cached broker credentials can boot without a blocking/v1/snapshotfetch and survive broker-down startup windows. - Added
dry-balanceCLI command to perform a dry-run OAuth account balancing check across configurable random session IDs, with sample and concurrency options, JSON output, and success/failure summary reporting - Added
--jsonoutput mode and machine-readable result format toomp dry-balancefor automated use - Added
omitMaxOutputTokenstomodels.ymlmodel definitions andmodelOverrides, so users can opt a model out of the on-the-wiremax_output_tokens/max_tokenscap while keeping the catalogmaxTokensfor local budgeting. Intended for Ollama-style proxies whose upstream output limit OMP cannot discover. (#1881)
Fixed
- Fixed TTSR rule-violation injections leaking the absolute home directory to the model: the
ttsr-interrupt/ttsr-tool-reminderblocks rendered the matched rule'spathas its absolute on-disk path (e.g./Users/me/Projects/app/.omp/rules/no-any.md). The path is now relativized to the session cwd when the rule lives in the project (.omp/rules/no-any.md), or~-relative when it lives under home, so no absolute path is fed into the agent's context outside the system prompt. - Fixed
AsyncJobManager.instance()being cleared while the owning top-level session was still live, which broke thetaskasync path with "Async execution is enabled but no async job manager is available" until process restart. Any in-process secondary top-levelcreateAgentSession()call (e.g. the Agent Control Center's create flow inagent-dashboard.ts) constructed a freshAsyncJobManager, overwrote the singleton, and then cleared it on its own dispose. Secondary sessions now leave the live singleton untouched, and their dispose-time cleanup is scoped so it can no longer cancel the primary session's running bash/task jobs.bash/task/jobtools and session job snapshots now resolve the manager through session-scoped async manager wiring rather thanAsyncJobManager.instance(), so a secondary in-process top-level session cannot accidentally register background work on the owning session's manager or report the owning session's jobs; subagents still inherit the parent's manager via their scoped async manager. Startup failures after a top-level session installs its manager now clear and dispose that manager before the next session decides whether it can create its own (#1923). - Fixed the
tasktool returning a hardAsync execution is enabled but no async job manager is available.error whenasync.enabledwas true butAsyncJobManager.instance()returnedundefined, leavingtasknon-functional for the rest of the session. The tool now falls back to the existing synchronous execution path (which still runs subagents concurrently viamapWithConcurrencyLimit), and logs a warning so the missing-manager state stays diagnosable (#1922). - Fixed Hindsight retain/recall/reflect calls staying pinned to the bank that was selected when the session started after the operator edited
hindsight.bankId,hindsight.bankIdPrefix, orhindsight.scopingmid-session. The backend now subscribes to those settings viaonHindsightScopeChangedand rebuilds the activeHindsightSessionStateagainst the recomputed scope, disposing the old state after flushing its queue so in-flight tool-initiated retains still land in the bank they were enqueued for. Also renamedensureBankMissiontoensureBankExistsso a blankbankMissionno longer skips bank creation entirely, and called it before mental-model bootstrap socreateMentalModelis never the first POST against a missing bank.AgentSession.disposenow flushes the retain queue before clearing#hindsightSessionState, since the queue's identity guard would otherwise drop the spliced batch (#1902). - Fixed
/treerendering a bare "No entries found" line on a fresh session where the only persisted entries are themodel_change+thinking_level_changewritten bysdk.tsat startup — both are hidden by the tree-selector's default filter, so#filteredNodes.length === 0whiletree.length === 2and the controller'stree.length === 0short-circuit never fired. The selector now splits the empty-state into three distinct shapes — truly empty tree, search query with no matches, and filter mode rejecting every entry — surfacing the cause and the recovery key (Alt+Ato show all,Backspaceto clear a stale search) so users on a fresh session can see immediately that the panel isn't broken (#1909). - Fixed remote MCP OAuth refresh failures leaving stale credentials in
agent.db: when the token endpoint returns a definitive failure (invalid_grant,invalid_token,revoked, plain 401/403 not classified as transient),MCPManager#resolveAuthConfignow drops the credential viaAuthStorage.remove(credentialId)and skips re-attaching the deadAuthorization: Bearer …header. Previously a revoked refresh token kept producing401 invalid_tokenon every MCP request and survived restarts, so users had to hand-clear the credential row to recover; the next connect now surfaces a clean auth error and/mcp reauth <server>(or/mcp unauth) recovers without restarting. Transient refresh failures (network/fetch failed/ECONNREFUSED) still fall back to the existing access token (#1908). - Fixed
omp://docsandomp://docs/...internal documentation URLs in the distributed package to resolve through the embedded documentation index instead of failing withDocumentation file not found(#1898). - Fixed the
githubdiscovery provider silently ignoring.github/skills/<name>/SKILL.md, GitHub's documented Agent Skills layout. The provider now registers askillscapability (priority 30, project-only) that scans.github/skills/non-recursively viascanSkillsFromDirwithrequireDescription: true, matching the Agent Skills spec and the siblingnative/omp-pluginsproviders (#1906). - Fixed inline images rendering as a wall of empty PUA box glyphs with laggy scrolling on Kitty-protocol terminals that do not honor Unicode placeholders (most notably WezTerm and tmux/screen passthrough to a non-Kitty outer terminal). The 15.9 placeholder rollout enabled the
U=1/U+10EEEE grid for every Kitty-protocol path; it now defaults on only forkittyandghostty, withPI_NO_KITTY_PLACEHOLDERS=1as a hard opt-out andPI_KITTY_PLACEHOLDERS=1as opt-in for terminals (e.g. wezterm nightlies) that have since added support (#1877). - Fixed auto session-title generation failures being swallowed without an actionable diagnostic. Title generation now logs structured start, missing-model/API-key, provider-error, empty-result, and exception outcomes with the session id and resolved title model; the interactive auto-title caller also logs uncaught persistence/generation errors instead of dropping them. (#1892)
- Fixed
TranscriptContainerreporting the live block boundary to the TUI again, so ED3-risk foreground streaming can append newly sealed transcript blocks to native scrollback once while deferring only the active live block.
[15.9.1] - 2026-06-04
Added
- Added deferred session-title generation so greetings no longer become the session title. A first user message that is only a greeting / acknowledgement / filler ("hi", "thanks", "ok", a bare number, emoji-only, etc.) is now detected deterministically and skips titling entirely — no title model is invoked. Title generation then retries on each subsequent user message while the session stays unnamed, so the title is deduced from the first message that actually describes work. A capable online title model may additionally answer
noneto decline a non-greeting taskless message (normalized to "no title").
Changed
- Changed mid-turn user steers to reach the model inside a wire-only interjection envelope, while transcripts and persisted session history keep the user's original text.
- Changed the system prompt to treat user requests for parallel work as
tasksubagent fan-out rather than parallel tool calls. - Changed the Agent Control Center's new-agent description field to use the multiline TUI editor, with Enter inserting lines and Ctrl+Enter generating the spec.
- Changed the Agent Control Center and Extension Control Center to accept Left/Right arrow keys for switching tabs (source / provider), in addition to Tab / Shift+Tab — matching the model and settings selectors, whose
TabBaralready supported arrow navigation. - Refreshed the Ctrl+R history search overlay: the selected row now renders as a full-width
selectedBghighlight bar, matched query tokens are highlighted in the accent color, each result shows a right-aligned relative timestamp, and the panel gained an icon'd accent title plus a two-tone keyhint footer. The selector also gained PageUp/PageDown (via the configurabletui.select.pageUp/pageDownkeybindings) and Home/End navigation. - Changed Perplexity API-key web search to return more comprehensive results:
web_search_options.search_context_sizeis nowhigh(wasmedium) for maximum retrieval grounding, the defaultnum_search_resultsis20(was10) so twice as many sources are surfaced, andreturn_related_questionsis enabled with the response'srelated_questionsnow parsed intorelatedQuestions(previously dropped). On an identical query this lifted the result from 10 sources / ~410 output tokens to 20 sources / ~1900 output tokens with a structured, multi-section answer; latency tracks model output length, not context size, so the 60s hard timeout headroom is unchanged.
Fixed
- Fixed a streamed assistant message freezing at a partial prefix (e.g. only "Nat" of "Natives built, now…") on ED3-risk terminals (Ghostty/kitty/iTerm2/Alacritty), with the final text appearing only after a resize.
TranscriptContainerfreezes each non-live block by replaying its last live render, but render coalescing can finalize a block's content and append the next block within the same throttled frame — so the block was sealed at its stale mid-stream snapshot and never repainted until the nextthaw. The block that was live on the previous render is now recomputed once on the live→frozen transition, sealing it at its final content. - Fixed ACP/RPC stdio startup so protocol frames are no longer consumed as one-shot piped prompt input before the JSON-RPC transport starts.
- Fixed
omp completionsto await the completion script write before exiting. - Fixed
AssistantMessageComponentexposing its stable-prefix completion API again so streamed assistant messages remain unstable until explicitly completed. - Fixed session restoration to ignore transient fallback model switches (such as automatic context-promotion or retry fallback) so resumed or resumed-switch sessions revert to the configured default model unless the last change was a user-selected temporary model
- Fixed in-session
/resumeto restore both the last user-selected temporary model and persisted plan/goal mode state instead of falling back to the default model with plan mode off. - Fixed the
/resumesession picker overflowing short viewports: the visible window was hardcoded to 5 entries (and assumed 3 lines each), but titled sessions render 4 lines, so on a typical-height terminal the picker's header and search box scrolled off the top and the first entry was hidden until you scrolled the terminal up. The visible-entry count is now derived from the live terminal height (budgeting the worst-case 4-line titled entry plus the picker's chrome), so the whole picker fits the viewport and grows on taller terminals. - Fixed the Agent Control Center and Extension Control Center dashboards overflowing the terminal: they were mounted inline below the chat transcript, so the combined height exceeded the viewport — the tab bar and controls scrolled off the top into native scrollback, and every state change yanked the view back to the bottom. Both dashboards now render as full-screen overlays sized to the live terminal height (
process.stdout.rows), re-fit on resize, fill the viewport, and reserve space for the footer keyhints so the controls stay visible. - Fixed Ctrl+R history search results to remain globally sorted by prompt recency after merging FTS prefix matches with substring fallback matches.
- Fixed Exa web search with no stored or environment credential to use the public Exa MCP fallback again, preserving the auth storage →
EXA_API_KEY→mcp.exa.airesolution order (#1860). - Fixed ACP plan-mode writes to
local://PLAN.mdso session-local plan artifacts are written to OMP's local artifact root instead of being routed through the editorwriteTextFilebridge, avoiding Zen'sInternal errorand making the plan readable after creation (#1863). - Fixed ACP plan mode stranding the agent at plan approval: entering
mode: "plan"now registers a standingresolvehandler so the agent'sresolve { action: "apply" }no longer fails withNo pending action to resolve. Nothing to apply or discard.The handler validates the plan file, asks the ACP client to confirm viaunstable_createElicitationwhen the client supports forms, renames the approved plan tolocal://<title>.md, and exits plan mode so the agent regains write tools for execution (#1869). - Fixed
provider.appendOnlyContext: "auto"staying inactive for Xiaomi Token Plan/SGLang endpoints, preserving prefix-cache hits without forcing append-only mode globally (#1851). - Fixed
models.ymlcompatibility parsing to preservecompat.cacheControlFormat: "anthropic"for custom OpenAI-compatible Claude proxies. (#1845) - Fixed the TUI's
Settings → Pluginspanel reporting "No plugins installed" when only marketplace plugins were installed. The panel now mergesPluginManager.list()withMarketplaceManager.listInstalledPlugins()— the same data source the/plugins listslash command andomp plugin listCLI already used — and tags each row with an[npm]/[marketplace]kind badge, a scope tag, and a shadow indicator for project-shadowed user installs. Selecting a marketplace row opens a newMarketplacePluginDetailComponentwhose singleEnabledtoggle callsMarketplaceManager.setPluginEnabled(pluginId, enabled, scope), with read-only metadata (version, install path, installed-at, last-updated, git commit SHA) listed below the toggle. The empty-state now lists both install commands (omp plugin install <package>andomp plugin install <name>@<marketplace>) (#1842). - Fixed scoped mnemopi recall in
MnemopiSessionState.collectScopedRecallResults/recallResultsScopedto await the asyncMnemopi.recallEnhancedso the new auto-derivedqueryEmbeddingflows through. Without this, the embedding-enabled mnemopi backend silently kept running FTS-only on every recall. (#1832) - Fixed the SSH tool renderer inlining multiline remote commands into its single-line status header, which produced a malformed cell where the bordered output block opened mid-command. The renderer now drops the command from the header (which keeps only
[host]) and renders the full command in a framed section aboveOutput, mirroring the bash renderer.renderStatusLinealso flattens any embedded CR/LF indescription,meta, andtitleso no tool can accidentally expand the header into multiple rows (#1828). - Fixed
tsc --noEmitagainstpackages/coding-agent/tsconfig.jsonreporting 56 errors under TypeScript 5.x (builtin-registry.ts× 46,agent-session-openai-responses-replay.test.ts× 10). The repo's own gate (tsgo/ TypeScript 6.x) already accepted the() => voidslash-command handlers, but 5.x rejects them because it does not coerce avoid-returning function value into a() => T | undefinedslot. TheSlashCommandSpec.handle/handleTuisignatures and the test'screatePersistedSessionpopulatecallback are now expressed as a union of two function types (one returning aSlashCommandResult/ target, one returningvoid), so the existing handler bodies typecheck on both compilers (#1821). - Fixed
omp updateleaving@oh-my-pi/pi-nativesand the platform-specific@oh-my-pi/pi-natives-<tag>leaf at the previous version onbun install -gupdates, so the next launch loaded a stale.nodefile and aborted atvalidateLoadedBindingswithThe .node file on disk is from a different release than this loader.omp updatenow pins the native addon core and the platform leaf to the same version it installs for@oh-my-pi/pi-coding-agent(#1824).
[15.9.0] - 2026-06-04
Breaking Changes
- Removed synchronous
readTextSyncfromSessionStorageand core implementations (MemorySessionStorage,FileSessionStorage,RedisSessionStorage,SqlSessionStorage), requiring callers to use async text reads - Replaced the public
SessionStoragereadTextPrefix(path, maxBytes)andreadTextSuffix(path, maxBytes)methods withreadTextSlices(path, prefixBytes, suffixBytes): Promise<[string, string]>; custom session storage backends must implement the new combined slice API.
Added
- Added env-driven OpenTelemetry trace export. When
OTEL_EXPORTER_OTLP_ENDPOINT(orOTEL_EXPORTER_OTLP_TRACES_ENDPOINT) is set,ompregisters a global OTLP/proto trace exporter and switches on the agent loop's telemetry, so theinvoke_agent/chat/execute_toolspans actually reach a collector instead of a no-op tracer. Honors the standardOTEL_*env contract (endpoint, headers,OTEL_SERVICE_NAME,OTEL_SDK_DISABLEDandOTEL_TRACES_EXPORTER=noneparsed case-insensitively) and theOTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENTcapture toggle; it is a no-op when no endpoint is configured. Only thehttp/protobuftransport is supported — agrpcorhttp/jsonOTEL_EXPORTER_OTLP*_PROTOCOLdeclines rather than misrouting spans. This makes the existing telemetry usable from headless hosts that runompas a spawned child process, where an in-processTracerProviderregistered by the parent can't reach the child. Uses the@opentelemetry/exporter-trace-otlp-proto2.x line, which exports cleanly under Bun.
Fixed
- Fixed the status line session name (and the editor border / status-line gap fill) being nearly illegible on light themes.
- Added
IndexedSessionStorageandSessionStorageBackendexports to support shared metadata-indexed session backends - Added the
tui.maxInlineImagessetting (default8) capping how many inline images render as live terminal graphics. Once a new image pushes the count past the cap, the oldest images are hidden via a full redraw — replaced by their[Image: …]text placeholder and purged from the terminal's graphics store — so long sessions with many screenshots/diagrams stop piling up images (and, on Kitty, stop leaving scrollback ghosts). Set to0to keep every image inline. - Added a "View: terminal state" item to the
/debugmenu that prints the detected terminal, live geometry and cell size, multiplexer, and the negotiated subprotocols actually in use — graphics (Kitty/iTerm2/Sixel), desktop notifications (BEL/OSC 9/OSC 99, plus whether OSC 99 was confirmed via a device-attributes probe), OSC 8 hyperlinks, 24-bit color, DECCARA rectangular-SGR background fills, and DEC 2026 synchronized output — alongside the scrollback-clear strategy (CSI 22 JvsCSI 2 Jredraw / ED3 eager-erase risk) and the rawTERM/TERM_PROGRAM/COLORTERMdetection signals. - Added a "Test: terminal protocols" item to the
/debugmenu that renders one live sample of every special escape protocol the renderer can emit — SGR text attributes (bold/italic/underline/strikethrough/inverse/dim), themed and 24-bit truecolor, OSC 8 hyperlinks, OSC 66 text sizing (large text), and an inline graphics swatch via the active image protocol (Kitty/iTerm2/Sixel, with a text fallback) — and fires a desktop notification, so you can eyeball which protocols the current terminal actually honors. The sample image is a gradient PNG generated in-process, so the graphics test needs no asset on disk. - Added the
tui.textSizingsetting (default off) that renders Markdown H1 headings at 2x scale via Kitty's OSC 66 text-sizing protocol. It replaces the undocumentedPI_TUI_TEXT_SIZINGenv var with a real setting, and only takes effect on Kitty terminals (where OSC 66 is implemented) — it is ignored everywhere else so headings never emit raw escape bytes. - Added a lifecycle status to the
/resumesession picker. Each session's tail (last 32 KiB) is now read alongside the existing header window in a single pass, and its final message classified asdone(the agent ended its turn and yielded control back),interrupted(a trailing tool call or tool result the loop never continued from),aborted,error, orpending(a trailing user message with no reply). The status renders as a colored segment on each session's metadata line. When the final message is larger than the tail window the status is omitted rather than guessed. - Added support for
disable-model-invocation: truefrontmatter field from the Agent Skills standard. Skills using this field are now hidden from the system prompt listing, matching the behavior ofhide: true.
Changed
- Changed the
tasktool description to tag read-only agents and explicitly forbid assigning them file edits/commands or offloading reasoning toquick_task/explore. - Changed Redis and SQL session storage initialization to load only indexed metadata (
size,mtimeMs) instead of full session content - Changed
SessionStorageread paths to rely on backend-backed metadata/indexed storage, so session content is fetched on demand rather than cached as full in-memory mirrors - Changed session-list slice reads to go through
SessionStorage.readTextSlicesacross all backends, removing the file-only single-open branch and caller-managed buffers.FileSessionStoragenow reads both windows viapeekFileEnds, while Redis and SQL backends encode session content once per combined read. - Changed the
asktool transcript renderer to mark single-choice questions with circular radio glyphs (○/◉) instead of the rectangular checkbox glyphs (☐/☑) it shares with multi-select questions, so a "pick one" combo box visually reads as a radio group rather than a checklist. Multi-select questions keep checkboxes. Added aradio.selected/radio.unselectedsymbol pair across the unicode, nerd-font, and ASCII presets. - Changed the
asktool transcript renderer to mark the chosen answer inside the question form rather than re-listing the questions in a detached summary block below it. Once a question is answered, the standalone prompt preview is dropped and the result redraws the same form — every offered option still shown, with the selected one(s) filled in (◉/☑, highlighted) and the rest dimmed (○/☐); custom free-text answers and cancellations render in place as the final entry. This removes the duplicate question/option listing that previously appeared once as the call preview and again as the result. - Changed task-completion and
askdesktop notifications to structured terminal notifications (title, body, type, and a focus-on-click action). On Kitty these render through OSC 99 as a proper title/body with click-to-focus; terminals without confirmed OSC 99 support collapse them to the previous single-line message (BEL/OSC 9). - Updated the "each kitty/tmux split" tip to include cmux.
Fixed
- Fixed tiny-model startup in compiled binaries by resolving
@huggingface/transformersand its runtime dependencies from the installed cache usingpackage.jsonexports/mainmetadata, preventing module-resolution failures when launching models - Fixed tiny runtime installation flow in compiled binaries by using the build-time resolved
@huggingface/transformersversion and ensuring the runtime lock directory’s parent exists before acquiring the install lock, preventing mismatch and setup failures on fresh installs - Fixed the terminal protocol debug probe reusing one stable Kitty graphics id across repeated panels, which could move/replace an earlier swatch instead of rendering a new one.
- Fixed selector dialogs (the
asktool, hook prompts) collapsing to a single visible option on shorter terminals when options carried long descriptions: the highlighted option's wrapped description consumed the entire row budget, hiding every other option and making the menu feel unnavigable (down moved the lone visible entry, left/right did nothing). When the fully-expanded list overflows,HookSelectorComponentnow renders a compact list — every option label stays on screen and only the highlighted option expands its description, truncated to the remaining rows — so the whole menu is always visible and the detail pane follows the cursor. - Fixed
readfailing with "Path not found" on web URLs whose scheme//collapsed to a single/(e.g.https:/github.com/...), which happens when a URL is routed through Node'spath.normalize/path.resolve. The fetch URL recognizer now accepts a single-slash scheme and repairs it back to//before fetching, so collapsed URLs resolve instead of falling through to filesystem lookup. - Fixed subagent slow-model priority falling through to older Claude Opus aliases when Opus 4.8 is available by adding Opus 4.8 and 4.7 aliases ahead of older Opus fallbacks (#1753).
- Fixed the web-search provider selectors in TUI settings/setup to derive from the shared provider metadata, so newly added providers cannot be omitted from the preference list.
[15.8.3] - 2026-06-03
Fixed
- Fixed Jujutsu workspace detection failing in non-default workspaces created by
jj workspace add, whose.jj/repois a FILE pointing at the shared repo dir rather than a directory. Detection now matches jj's own criterion (.jj/repopresent, file or dir) instead of requiring a.jj/repo/storedirectory, andjj.repo.resolve'sstoreDirfollows the file indirection to the shared store.
Changed
- Changed the
todo-writeprompt to require initializing every item from a user-supplied multi-step plan as an individual todo task before execution - Changed context compaction (prune/shake) to protect reads of the active plan file the same way it already protects
skill://reads, so the plan stays intact through automatic and manual compaction. Both the canonicallocal://PLAN.mdalias and the session's current plan reference path (e.g. a titledlocal://<title>.mdafter approval) are kept, tolerating read selectors andlocal:/scheme spelling.
[15.8.2] - 2026-06-03
Added
- Added a bundled TypeScript rule that warns against leaving
@deprecatedcompatibility shims behind instead of finishing a refactor.
Fixed
- Fixed
/review's uncommitted-change mode in Jujutsu repositories to readjj diff --gitfrom the current workspace, so non-default JJ workspaces include their working-copy changes instead of falling back to the colocated Git checkout. - Fixed empty assistant stop retry continuations preserving auto-retry state until a non-empty assistant turn completes or recovery reaches its retry cap.
- Fixed TTSR rule conditions never matching streamed
edit/writetool calls whose wire format obscures the real content (hashline+body rows, apply_patch envelopes, JSON-escapedwritecontent). The edit and write tools now expose amatcherDigestnormalization and TTSR matches against the introduced source text, so rule regexes stay universal regardless of the active edit mode.
Changed
- Changed the JJ utility API to mirror Git's scoped helpers: repository operations now live under
jj.repo(root,resolve,is,clearRootCache), and diff file listing is available asjj.diff.changedFiles. - Changed the
search_tool_bm25tool description to name the hidden discoverable built-in tools (e.g.write,find,search,lsp,task) whentools.discoveryMode: "all"is active, so a model can form a targeted discovery query by name instead of guessing or falling back to shell.mcp-onlymode is unchanged (no built-ins are advertised) and theTotal discoverable tools available: Ncount still includes them.
[15.8.1] - 2026-06-02
Fixed
- Fixed an unhandled
EPIPErejection when an MCP stdio server exits between returning theinitializeresponse and the client'snotifications/initializedsend.StdioTransport.notify()and#sendResponse()now route stdin writes through a shared helper that catches synchronous sink failures:notify()tears the transport down (firingonClose) and surfaces aTransport closed while sending notificationrejection soconnectToServer()treats the handshake as a failed connection instead of returning a "connected" handle wrapping a dead transport;#sendResponse()stays silent because a dead subprocess has no use for the response.StdioTransport.close()is now the authoritative resource teardown — it no longer early-returns when#handleClose()has already flipped#connected, so the subprocess and read loop are always cleaned up (including in theconnectToServer()failure path) (#1710). - Fixed startup model resolution ignoring cached discovery rows for special built-in providers (
google-antigravity,google-gemini-cli,openai-codex) until the background refresh completed (#1721). - Fixed Windows clipboard-image paste keeping
Ctrl+Vunregistered by default. The TUI now registersCtrl+Vplus the Windows Terminal-safeAlt+Vfallback, and the keybinding docs call out when to use the fallback (#1708).
[15.8.0] - 2026-06-02
Added
- Added an all-projects scope to the session picker (
pi --resume//resume). PressTabto toggle between the current folder's sessions and every session across all projects; the all-projects list is loaded lazily and shows each session's directory. When the current folder has no sessions the picker now opens straight into all-projects scope instead of printing "No sessions found". - Migrated the Kagi web search provider to Kagi's V1 Search API (
POST /api/v1/search), replacing the sunset V0 endpoint while keeping thekagiprovider id,KAGI_API_KEYcredential, and/login kagiflow unchanged (#1272 by @thismat) - Added Anthropic
anthropic-ratelimit-unified-*response-header warming for/usageand the status-line usage segment, throttled to reduce direct OAuth/usageprobes during active use.
Changed
- Changed Anthropic API request metadata
user_id.device_idto be derived from the persistent install ID so it remains stable across Anthropic account changes on the same install - Changed the eval
parallel()/pipeline()helpers to drop theirconcurrencyargument and run as wide as atasktool batch. The worker-pool ceiling now tracks thetask.maxConcurrencysetting (default 32;0= run every item at once) resolved live from the host via a new__concurrency__bridge, instead of the old per-callconcurrencyoption that defaulted to 4 and capped at 16. This stops eval fan-outs from under-using the parallelism the session is configured for. - Changed subagent /
agent://output ids from a numeric prefix scheme (0-Anna,1-Bob, nested0-Anna.1-Bob) to a name-first scheme: the requested name is used verbatim and a-2/-3/… suffix is added only when the same name recurs within a session (Anna,Anna-2,Anna-3). Nested ids stay grouped under the parent (Anna.Bob) and the live task widget renders them asAnna>Bob. The main agent's IRC id is nowMain(was0-Main).AgentOutputManagerstill scans existing.mdoutputs on resume so it never reuses a name that would clobber a prior output. - Changed resuming a session that belongs to a different project to switch the process into that project's working directory.
pi --resumeand the in-session/resumepicker nowchdirinto the resumed session'scwdand re-scope every cwd-derived input — project dir, project settings (.claude/settings.yml,.omp/settings.json, path-scopedenabledModels/disabledProviders), plugin roots, capabilities, slash commands, and the ssh tool — so tools, discovery, configuration, and commands all follow the resumed project. TheSessionManageradopts the resumed session's owncwd/session directory on load (rolled back if the switch fails). - Documented
ANTHROPIC_SEARCH_API_KEYandANTHROPIC_SEARCH_BASE_URLmore thoroughly indocs/environment-variables.md, surfaced them indocs/tools/web_search.md's Anthropic provider section, and addedANTHROPIC_SEARCH_BASE_URLtoomp --help's env-var summary so the search-only overrides are discoverable alongsideANTHROPIC_SEARCH_API_KEY(#1694). - Migrated the Kagi web search provider to Kagi's V1 Search API (
POST /api/v1/search), replacing the sunset V0 endpoint while keeping thekagiprovider id,KAGI_API_KEYcredential, and/login kagiflow unchanged (#1272 by @thismat)
Fixed
- Fixed
read,search,find,ast_grep, andast_editrecovering when a model flattens multiple existing paths into one comma-, semicolon-, or space-delimited string while preserving real paths that contain delimiters. - Fixed Exa web search reporting available without Exa credentials, which could route searches into the unauthenticated public MCP fallback and stall before trying the next provider. Availability and
searchExa()now resolve through the standardAuthStoragecascade (EXA_API_KEYenv or stored credential) (#1695). - Fixed Anthropic web search ignoring
ANTHROPIC_SEARCH_BASE_URLwhen credentials came from stored Anthropic auth or generic Anthropic env fallback rather thanANTHROPIC_SEARCH_API_KEY(#1694). - Fixed
web_searchreturning 401 from corporate Anthropic API gateways.ANTHROPIC_CUSTOM_HEADERSis now forwarded to web-search requests wheneverANTHROPIC_BASE_URLpoints to a non-Anthropic host, not only in Foundry mode (#1693). - Fixed opening exported local files from WSL by sending existing paths through
wslpath -wand launchingwslviewdirectly when available, avoidingxdg-open's broken file-handler path translation (#950 by @rxreyn3). - Fixed
/move(and cross-project resume) not re-scoping the live project settings to the destination directory. Changing a session's working directory now reloads the project settings layer in place (viaSettings.reloadForCwd) so project-scoped configuration and path-scopedenabledModels/disabledProvidersfollow the move instead of remaining pinned to the launch directory. - Fixed
read <db.sqlite>freezing the TUI on large databases. Listing tables ran an unboundedSELECT COUNT(*)per table, and sincebun:sqliteexecutes synchronously on the same JS thread that drives rendering and input, a multi-GB database's full-table scans blocked the UI for seconds. The listing now reads the planner'ssqlite_stat1estimate for tables above a scan cap (shown as~N rows) and only counts exactly when a table is provably small, reading at mostcap + 1rows (a capped table showsN+ rows). On an 8.4 GB stats database the listing dropped from multi-second full scans to ~2 ms. - Fixed a module-load crash (
ReferenceError: Cannot access 'evalToolRenderer' before initialization) triggered whenevertools/evalwas imported beforetools/renderers. The eval JS backend statically pulls the agent/task/sdk/extension chain, which re-enters the root barrel →modes/components→tool-execution→rendererswhileeval.tswas still initializing, sorenderers.tsreadevalToolRendererin its TDZ. The eval TUI renderer is now split into a dependency-lighttools/eval-render.tsthatrenderers.tsimports directly (decoupling pure rendering from the eval runtime);eval.tsre-exportsevalToolRenderer/EVAL_DEFAULT_PREVIEW_LINESfor compatibility. - Fixed
/logoutoffering providers that were only authenticated by env/config fallbacks, which made OpenCode Go/Zen appear to remain logged in after their stored credentials were removed (#1658). - Fixed
omp --resume <id>crashing with an uncaught exception when an interactive user declined the cross-project fork prompt.createSessionManagernow returnsundefinedfor that cancellation, while non-interactive invocations still fail with a diagnostic when they cannot answer the fork prompt (#1668). - Fixed
history.dbnever recording the originating session id: thesession_idcolumn documented for 15.6.0 was missing from the shipped storage layer, so the column was never created/populated on the write path and every prompt row hadsession_idNULL. Restored thesession_idcolumn, schema migration (ALTER TABLE history ADD COLUMN session_idfor pre-existing databases), andHistoryEntry.sessionId; wired interactive mode to registersetSessionResolver(...)so prompts are stamped with the session active at submission time (tracking fork/resume switches); and re-enabled prompt-history ranking in the--resumeand in-session session pickers viaHistoryStorage.matchingSessionIds(). - Fixed
/quitshutdown leaving the parent shell prompt at the top of the viewport after the final TUI teardown render on Linux terminals (#1620). - Fixed
omp updatefailing withNo version matching "X" found for specifier "@oh-my-pi/pi-coding-agent" (but package exists)when bun saw an older catalog than the update check did. The version is resolved by queryinghttps://registry.npmjs.org/directly, butbun install -gwould then consult its on-disk manifest snapshot or a configured npm mirror (corporate proxy, Taobao, …) that hadn't replicated the release. The bun install step now runs with--no-cache --registry=https://registry.npmjs.org/so it hits exactly the registry the version check used (#1686). - Fixed ACP mode resetting configured async/background job settings to disabled RPC defaults, so explicit ACP background-job opt-ins are preserved during startup (#1324).
- Fixed legacy Pi extensions loading their
__dirname-relative assets as empty — e.g.@plannotator/pi-extensionreadingplannotator.html/review-editor.htmlviareadFileSync(join(__dirname, …)), which leftplanHtmlContentempty and dropped the plugin into its "no UI support" auto-approve path. The compat layer previously mirrored every extension module into a flat temp directory, soimport.meta.url(and thus__dirname) pointed at the mirror root and sibling asset readsENOENTed. Extensions now load in place from their real on-disk location —import.meta.urlis the real source file, so asset reads resolve exactly as under the original Pi runtime. ABun.plugin()onLoadhook scoped to the entry's relative-import graph (the exact set of source modules, never the host, other extensions,node_modulesdeps, or unrelated project files) rewrites only the legacy@(scope)/pi-*and@sinclair/typeboximports; relative siblings, the extension's ownnode_modulesdeps, and bundled assets all resolve natively, with no temp-directory mirroring and no asset copying (#1674). - Fixed plan approval keep-context usage to use the execution model context window, avoid zero-usage aborted turns, and disable keeping context when preserved context exceeds 95%.
[15.7.6] - 2026-06-01
Added
- Added
askoption descriptions so agents can keep short labels and render explanatory text as separate muted rows in the selector. - Added an extension API for rendering supplemental UI below visible assistant thinking blocks.
- Added default-on
lsp.diagnosticsDeduplicatesupport so post-edit LSP diagnostics already shown for a file are suppressed within the session and only new or changed diagnostics are surfaced.
Fixed
- Fixed a single ESC press both dismissing the @/slash autocomplete popup and aborting the running agent operation. ESC now drains the popup first; only when no popup is visible does it route to the global interrupt handler (matching the standard TUI/IDE pattern). The
shouldBypassAutocompleteOnEscapeeditor hook is removed — it had become the trigger for this bug (#1655). - Fixed Claude Code slash command discovery to load subdirectory commands recursively while preserving basename commands (e.g.
/apply) and adding namespace aliases (e.g./opsx:apply) for tools that install colon-namespaced workflows (#1523). - Fixed the
evaltool's per-celltimeoutkilling cells that were not stalled. The timeout is now a plain wall-clock budget on the cell's own work that is paused only while a host-sideagent()/parallel()/llm()bridge call is in flight — those calls pump a heartbeat that re-arms the watchdog, so a long fanout or a slow (e.g. reasoning-tier) completion runs to completion instead of being aborted mid-flight (a subagent's time-to-first-token, a long quiet nested tool, or an entire oneshotllm()request no longer trip it). Nothing else re-arms the budget: ordinary compute,print/stdout,log()/phase(), and non-agent tool calls all count against it, so a cell that is not delegating to an agent/llm is bounded by the regular wall-clock timeout (and the timeout message no longer says "of inactivity"). The heartbeat is a pure keepalive — never persisted or rendered.
[15.7.5] - 2026-06-01
Fixed
- Fixed streaming assistant responses leaving duplicated tail rows in WSL/Windows Terminal scrollback by enabling eager native-scrollback rebuilds while assistant text is actively streaming (#1615).
- Fixed the
tasktool mangling subagent prompts when a model double-JSON-encodes a string argument:contextand each task'sassignment/descriptionare now repaired when they arrive uniformly double-escaped (literal\n,\",\uXXXX), so the subagent receives the intended prose and the call preview renders real newlines. The repair is guarded by a JSON-string round-trip and a double-encode signature, so legitimate backslashes/quotes (Windows paths, regexes, embedded quotes) are left untouched, and it is scoped to these natural-language fields only (never code-bearing tools). - Fixed
pr://PR views omitting formal review submissions and approvals when comments are enabled (#1600). - Fixed subagent yield-reminder loop logging benign user/compaction aborts as
ERROR. The catch aroundsession.prompt/waitForIdleintask/executor.tsnow demotesToolAbortErrorand signal-aborted exits todebugand keepsERRORfor genuine prompt failures only (#1623). - Fixed
read local://<file>resolving to the wrong session's artifacts directory in multi-session ACP hosts (e.g. cmux).LocalProtocolHandler.resolvenow honorscontext.localProtocolOptionssupplied by the calling tool before falling back to the process-wide override or the firstmain-kind session in the globalAgentRegistry;read,find,search,ast_grep, andast_editthread their session's options through so alocal://PLAN.mdlookup hits the calling session'slocalroot instead of a sibling session's (#1608). - Fixed
ompsegfaulting on exit on Windows after the tiny title/memory model loadedonnxruntime-node(issue #1606). The tiny model now runs in a Bun subprocess instead of a Worker thread, so the NAPI finalizer that crashes during shutdown never executes in the agent's address space; the subprocess isSIGKILL'd on dispose to skip every native destructor on every platform. - Fixed unbounded MCP reconnect loop that could fork-bomb the host when a stdio MCP server completes the
initialize/tools/listhandshake and then exits.MCPManagernow enforces a per-server crash circuit breaker (5 reconnects per 30 s window) on the automatictransport.onClosepath; manual/mcp reconnectresets the window so users can recover after fixing the misconfiguration (#1592).
[15.7.4] - 2026-05-31
Removed
- Removed
/shake summary, theshake-summaryauto-compaction strategy, and theproviders.shakeSummaryModelsetting. Use/shakeorcompaction.strategy: shakefor mechanical artifact-backed elision without local-model CPU.
Fixed
- Fixed plugin install failing for sources pinned to a SHA:
git.clone()no longer adds--depth 1whenoptions.shais set, so the checkout of arbitrary commits succeeds instead of bailing out with "shallow clone may not contain this commit" (#1589).
[15.7.3] - 2026-05-31
Added
- Added support for decimal and
k/msuffix turn-budget directives, enabling budgets like+1.5kand+2min eval message parsing - Changed eval budget resolution to honor a user
+Nkdirective over an active Goal Mode limit while falling back to Goal Mode when no per-turn ceiling is set - Added
agent()eval optionsagent_type/agentType,model,context, andlabel, and returned structured JSON whenschemais provided in JS and Python eval cells - Added a live, Task-tool-style progress tree for eval
agent()calls, drawn below the notebook (code cell) box. Each subagent surfaces as a status line (icon · id · tool count · context · cost, plus duration on completion) with its current tool/intent while running, and updates mid-execution rather than only at the cell's final result. Progress events coalesce per subagent id so the persisted event list stays bounded across many throttled ticks. - Added
agent()to theevalruntime so JS and Python cells can spawn one subagent through the existing task executor; JS eval also gained boundedparallel()andpipeline()helpers for orchestrating subagent calls. - Added a
workflowmagic keyword (mirrorsorchestrate/ultrathink): the standalone word glows amber→green in the editor and appends a hidden notice steering the model to author deterministic multi-subagent fan-outs ineval(agent/parallel/pipeline). Matching is whitespace-delimited and case-sensitive (lowercase only); the singular and plural both trigger, but capitalized forms, inflections likeworkflowed, and path-embedded occurrences likeworkflow.tsdo not. - Added
parallel()andpipeline()to the Pythonevalruntime (thread-pool over the synchronousagent()bridge), mirroring the JS helpers: bounded pool (default 4, max 16), input-order preservation, a barrier between everypipelinestage, and contextvar propagation soagent()works inside worker threads. - Added
log(),phase(), and abudgetobject to bothevalruntimes (Python and JS).log/phaseemit progress/phase status lines;budget.total/budget.spent()/budget.remaining()/budget.hardexpose a real per-turn output-token budget. A+Nkdirective in the user's message sets an advisory budget (the model self-limits viabudget.remaining());+Nk!(or an active Goal Mode budget) makes it a hard ceiling that blocks further evalagent()spawns once reached.budget.spent()counts output tokens spent this turn across the main loop and all eval-spawned subagents. - Added search support for virtual internal URLs (including
omp://roots) by resolving and scanning in-memory internal resources as search targets alongside filesystem paths - Added expansion of virtual internal URL search targets so
searchcan match multiple internal documents when givenomp:// - Added
/omfg <complaint>slash command that drafts a TTSR rule from a complaint, validates it against the current conversation, saves it to project or~/.omp/agent/rules, and registers it live. - Added
/shakeslash command and theshake/shake-summarycompaction strategies that reduce context by mechanically dropping heavy content instead of LLM summarization./shake(alias/shake elide) strips heavy tool-call results and large fenced/XML blocks, offloads the originals to one session artifact, and leaves a recoverableartifact://<id>placeholder;/shake summarycompresses the same regions with a local on-device model (providers.shakeSummaryModel, defaultqwen3-1.7b) and falls back to elide per region when the model is unavailable;/shake imagesstrips image blocks. Auto-maintenance honors theshake/shake-summarystrategies (16k protect window); on context overflow a shake that reclaims nothing falls back to context-full summarization. - Added
providers.shakeSummaryModelsetting selecting the local on-device model used by/shake summaryand theshake-summarycompaction strategy. Runs entirely on-device (downloads on first use) and never calls a remote/cloud LLM.
Changed
- Changed the eval cell
timeoutfrom a hard wall-clock deadline to an inactivity (idle) budget: a cell is now interrupted only after going the full window with no progress signal, and every status event —agent()progress snapshots,log()/phase(), and tool-bridge activity — re-arms the watchdog. Longagent()/parallel()fanouts that keep reporting progress no longer time out mid-run (previously the kernel was killed at the fixed deadline even while subagents were actively progressing). Rawprint/stdout does not reset the watchdog, so pure-compute runaway loops stay bounded; the timeout is driven entirely by the abort signal, so neither runtime arms a competing fixed timer. - Fixed turn-budget parsing to match
+Nkdirectives only at token boundaries, preventing values likeversion 1.2.3,c++, and+500kfoofrom triggering a budget rule - Changed overflowing provider, hook-option, branch-message, agent, extension, and session-tree pickers to support fuzzy type-to-filter search.
- Changed Shift+Ctrl+P to cycle role models backward instead of cycling forward without persisting.
- Changed empty prompt input so
?inserts a literal question mark instead of opening/hotkeys; use/hotkeysexplicitly for the shortcut reference. - Changed
searchoutput to preserve full virtual and internal URL paths in grouped results anddetails.filesinstead of collapsing them to file basenames - Changed
/omfgto run up to three generation attempts with validation feedback and only prompt saving when no draft matches assistant history - Changed
/omfgto show a live draft panel with generation/validation/saving status and allow canceling an active rule request withEsc - Changed keybindings config to use
~/.omp/agent/keybindings.yml, with automatic migration from legacykeybindings.jsonand continued support forkeybindings.yaml. - Changed the local SQLite memory backend identifier from
mnemosynetomnemopi. Existing configs are migrated automatically on load:memory.backend: mnemosynebecomesmnemopiand themnemosyne.*settings block is renamed tomnemopi.*(skipped when an explicitmnemopiblock already exists). - Changed the
ultrathink/orchestrate/workflowmagic keywords to be markdown-aware: the standalone word now also glows in the rendered user message bubble (matching the live editor), and neither the glow nor the hidden steering notice triggers when the keyword sits inside a fenced code block, an inline`code`span, or an XML/HTML section.
Fixed
- Fixed Ctrl+O tool-result expansion on POSIX terminals so offscreen tool blocks rebuild native scrollback instead of leaving stale collapsed rows above the viewport.
- Fixed final
agent()completion status emissions in eval cells so the last live progress snapshot now preserves accumulated subagent metrics such as tool count and cost - Fixed
agent()in eval to enforce plan-mode, spawn allowlist, and disabled-agent checks before launching subagents - Fixed recursive
agent()calls from eval by enforcing the existing max subagent depth limit - Fixed runtime model switches (Ctrl+P cycling,
--model,/model, model picker selections, and programmatic changes) so they no longer overwrite the persistedmodelRoles.default; only the model picker's explicit "Set as default" action and settings changes persist the default. - Fixed
searchto honor line-range suffixes on virtual internal URL targets so matches outside the requested ranges are no longer returned - Fixed
searchto handle internal URLs without source files without incorrectly reportingPath not found, returning matches from virtual content instead - Fixed
/omfgparsing to tolerate fenced or noisy model output, normalize generated rule names, and reject invalid regex conditions before saving - Fixed auto-thinking sessions to persist the concrete resolved effort after classification, so resuming the session restores that level instead of returning to pending
auto. - Fixed extension-registered CLI flags (e.g.
--spawn-peer <value>) leaking into the initial prompt: argv is re-parsed once the extension flag set is known so flag values are consumed instead of becoming messages or being misread as@filearguments. Registered flags shadow same-named built-ins, so a colliding flag (e.g. plan-mode's--plan) is parsed with the extension's semantics rather than being consumed by the built-in branch (which would otherwise eat the following message and corrupt the built-in field). Extension flags and@filearguments are now resolved before the session is created, so an unreadable initial@fileexits without leaving a junk session/terminal breadcrumb behind. (#1503) - Fixed footer status-line truncation: the left stats and right model segments now truncate by terminal cell width (via
truncateToWidth) and strip all VT/ANSI escapes (viastripVTControlCharacters) instead of a SGR-only regex plus code-pointsubstring, so wide glyphs, OSC hyperlinks, and non-SGR sequences can no longer overflow the line. - Fixed the streaming edit diff preview rendering a tall, half-empty box (and the earlier "box grows and shrinks repeatedly" stutter). A whole-file Myers re-diff is recomputed on every streamed chunk and its alignment is not monotonic in payload length, so a hunk-aware window that kept whole change segments gained and lost rows tick to tick; the prior high-water row reservation hid that stutter but padded the reserved height with blank rows, leaving a large empty rectangle whenever the diff shrank below its peak. The preview now pins a fixed-height trailing window to the bottom of the diff ("accept from the back"), so the box stays a steady, full window of real diff context instead of blank padding.
- Fixed duplicated/stale scrollback above a streaming tool result on POSIX terminals (macOS/Linux). A tool whose output grows and re-lays-out (e.g. an edit diff gaining hunks) re-renders rows that already scrolled into native scrollback; the unknown-viewport anti-yank deferral left the old copy in place while the new one rendered below, showing the block twice. The event controller now enables the TUI's eager native-scrollback rebuild while a foreground tool is executing (
setEagerNativeScrollbackRebuild), so those offscreen re-renders rebuild history cleanly — a snap to the tail is acceptable mid-tool. Background-running tools and plain assistant-text streaming keep the no-yank deferral; the mode resets at each turn start.
Removed
- Removed the
/drop-imagesslash command; use/shake images, which strips every image from the session through the samedropImages()path.
[15.7.2] - 2026-05-31
Added
- Added
providers.autoThinkingModelsetting so users can choose theautothinking classifier backend (online smol or local tiny-memory model) - Added an
autothinking level that classifies each real user turn and resolves to a concrete low-through-xhigh effort, with online smol classification by default and an opt-in local on-device classifier.
Changed
- Updated the interactive thinking selectors in model/model-role pickers and ACP thinking options to include
autoas a selectable level - Updated footer and status-line rendering to show
autowhile auto-thinking is being resolved andauto → <level>once it resolves - Changed the local tiny-model device default to CPU on every platform; explicit
providers.tinyModelDevice/PI_TINY_DEVICEvalues still opt into accelerated ONNX providers.
Fixed
- Prevented auto-thinking classification from running on non-user synthetic turns and non-reasoning models, keeping the session on its provisional concrete effort
- Added a bounded auto-thinking classification path that falls back to the provisional effort on failures/timeouts so prompts continue without interruption
- Bypassed auto classifier for
ultrathinkprompts and resolved directly to the highest supported auto effort - Fixed the JavaScript
evalkernel crashing the whole process with a segfault (SIGTRAP,getImportedModuleon a null record) when imported code reached a local module whose relative-import graph contains a cycle — e.g.await import("…/edit/streaming.ts"), or any workspace path with cyclic re-exports. TheLocalModuleLoaderlinked and evaluated each local module individually inside the recursivevm.SourceTextModulelinker callback, which re-entered Bun'snode:vmmodule linker mid-instantiation and detonated JSC on the first cycle. The loader now constructs the entire local module graph first and drives a singlelink()+evaluate()from the graph root, so cyclic graphs instantiate in one pass; external (node_modules) modules stay eagerly loaded since they carry no imports and cannot form a cycle. - Fixed the streaming
editpreview rendering a blank box for hashline edits whose payload sits on the trailing in-flight line (the common single-opreplace/insertcase). The preview path trimmed that still-typing line before diffing, so a single-payload op collapsed to a "No changes" result — shown as an empty box — for almost the entire stream. Hashline previews now feed the raw in-flight text throughapplyPartialTo, whose streaming-tolerant parser drops a payload-less trailing op and projects a partially-typed payload line as it grows, so the diff appears and fills in live. Transient errors from the actively-typed trailing section are also suppressed while streaming (regardless of section count) so a mid-typed op can't wipe an already-good preview frame; real errors still surface once args are complete.
[15.7.0] - 2026-05-31
Added
- Added a
Web searchsetup tab that lets users choose the preferredproviders.webSearchprovider during onboarding - Added manual authorization-code/redirect URL prompts for OAuth providers that require non-callback login in the setup wizard
- Added an
omp completions <bash|zsh|fish>command that prints a shell completion script generated from the live command/flag metadata, so completions never drift from the actual CLI. Subcommands, flags, and enum values complete statically;--model/--smol/--slow/--planresolve against the bundled model catalog and--resumeagainst on-disk sessions via a hidden__completehelper. - Added a
/switchslash command that opens the temporary model selector for the current session, mirroring thealt+pkeybinding. - Added
replace block N:anddelete block Noperators to theedittool: they resolve the syntactic block beginning on line N via tree-sitter (nativeblockRangeAt) and replace or delete its full line span, so a construct can be rewritten or removed without counting its closing line. Unresolvable blocks (unsupported language, blank/closing-delimiter line, or a parse error) are rejected with guidance to use an explicitreplace N..M:/delete N..Mrange. - Added an animated pending border for
bashandevalexecution blocks: while a command/cell is running, a single dark segment glides clockwise around the block's outer edge (top → right → bottom → left), replacing the previous static accent border. Motion is eased per edge (decelerating into each corner) and timed against a fixed lap duration mapped onto the live perimeter, so streaming a new output line or resizing the terminal nudges the segment proportionally instead of resetting its position. Driven by the existing spinner cadence and gated on thedisplay.shimmersetting (no motion whendisabled). - Added
providers.tinyModelDeviceandproviders.tinyModelDtypesettings (Providers tab) controlling local tiny-model acceleration for session titles and Mnemosyne memory tasks.providers.tinyModelDeviceselects the ONNX execution provider (defaultkeeps the platform pick — DirectML on Windows, CUDA on Linux x64, CPU elsewhere);providers.tinyModelDtypeselects quantization/precision (defaultkeeps each model's shippedq4, e.g.fp16trades speed for fidelity). ThePI_TINY_DEVICE/PI_TINY_DTYPEenv vars override the matching setting. Also addedPI_TINY_DTYPEas the env counterpart toPI_TINY_DEVICE; an unrecognized device/precision fails loudly at worker startup instead of silently loading a different one. - Added a bundled set of default rules shipped with the agent (TypeScript/Rust convention rules registered as TTSR conditions). They load via the new lowest-priority
builtin-defaultsdiscovery provider, so any user/project/tool rule of the same name overrides the bundled copy. Disable the whole set withttsr.builtinRules: false, or drop individual rules (bundled or your own) by name viattsr.disabledRules.
Changed
- Changed setup onboarding to a tabbed
Set up your providersscene with dedicatedSign inandWeb searchpanels - Changed the glyph mode picker to preselect the currently configured symbol preset instead of always defaulting to Unicode and to show live glyph samples in the picker rows
- Changed OAuth sign-in flow in the setup wizard so users can authenticate multiple providers before leaving with Escape
- Changed the plan-approval model-tier slider and the
ctrl+p/alt+prole-cycle status to share one status-line-style chip track: each tier renders in its own role color and the active tier is filled as a powerline chip with a luminance-matched label. The role-cycle status now shows only the chip track — the resolved model and thinking level already live on the status line — instead of the verboseSwitched to <role>: <model> (cycle: …)line. - Changed the in-flight
bashtool-call preview to render as a full bordered block as soon as the call appears, instead of a one-lineBash: $ …status that only expanded into a block once the command produced its first output chunk. Silent commands (e.g.sleep 30) now show the framed command block — with the animated pending border — for their whole runtime. - Changed local tiny-model inference to request a worker-safe accelerated ONNX execution provider where available (DirectML on Windows, CUDA on Linux x64), with CPU retry if acceleration cannot initialize.
PI_TINY_DEVICE=cpurestores CPU-only behavior;PI_TINY_DEVICE=metalis accepted as a WebGPU alias but guarded back to CPU in the production macOS worker because WebGPU currently hard-crashes Bun on worker teardown.
Fixed
- Used the native block resolver for hashline operations so
replace blockedits now derive block ranges from file-aware parsing - Fixed OAuth login handling to cancel cleanly when users press Esc or Ctrl+C during authentication
- Fixed the
readtool description advertisinginspect_image("for visual analysis, callinspect_image") even when theinspect_imagetool was disabled, which left the model hunting for a tool absent from its function list. The image section is now gated oninspect_image.enabled: when disabled it instead states that reading an image path returns the decoded image inline. - Fixed session-title generation latching onto literal text inside fenced code blocks — a pasted UI mockup containing "Welcome to Claude Code v2.1.158" titled the session "Setup Screen for Claude Code v2.1.158" instead of capturing the actual request. The first user message now has fenced code blocks stripped before titling (both the online
pi/smoland local on-device model paths share the same preprocessing), with a fallback to the original message when stripping would leave too little to title from (e.g. a message that is essentially just a code block). - Fixed slash-command autocomplete repaint requests so Windows Terminal sessions with unknown native viewport state keep updating the input box and candidate list. (#1550)
- Fixed Python
evalfailing the whole session when the managed~/.omp/python-envinterpreter exists on disk but no longer runs (e.g. a staleuv-managed Python that was removed or upgraded). Availability resolution now enumerates every candidate — active/project venv, the managed env, then the system interpreter — and probes each in priority order, falling through to the first that actually executes instead of failing fast on the first resolved path. The kernel spawns whichever interpreter the probe selected, so a working system Python takes over transparently.
Removed
- Removed the
recipetool and itsrecipe.enabledsetting. Task-runner targets (just/package.json/Cargo/make/Taskfile) are invoked directly throughbash.
[15.6.0] - 2026-05-30
Added
- Added prompt-mode autocomplete for supported internal URL schemes (
skill://,rule://,agent://,artifact://,local://,memory://, andomp://) so typing those tokens now suggests existing resources as completion candidates - Added fuzzy matching and ranked suggestion ordering for internal URL completion, including rule and skill descriptions, with accepted completion replacing just the typed token and inserting the chosen URL followed by a space
- Changed internal URL completions now include nested
local://path suggestions from the configured local workspace - Added Mnemosyne memory inference model selection with an online mode or local transformers.js options (
qwen3-1.7b,gemma-3-1b,qwen2.5-1.5b,lfm2-1.2b) so memory extraction and consolidation can run via the shared tiny-model worker - Changed memory tiny-model handling to route local memory prompts through the same queueed tiny-model worker pipeline with bounded completion output
- Added a Providers → Tiny Model setting for session titles, defaulting to the online
pi/smolpath with five optional local CPU transformers.js models. A local model — and the one-time@huggingface/transformersruntime install in compiled binaries — is downloaded and loaded only when explicitly selected (or viaomp tiny-models download); the default online path never spawns the title worker for inference. Selecting a local model adds a delayedpi/smolfallback so titles never block, plus in-chat download progress. - Added a persistent live agent roster pinned below the editor (focus it with
Ctrl+SorAlt+Down), including view-as switching into delegated agent sessions with human-readable delegate names and UI pinning to suppress idle reaping while viewed. The roster stays hidden until at least one delegated agent exists and releases focus back to the editor once the last one is gone. - Recorded the originating session ID alongside each prompt in
history.db(newsession_idcolumn, surfaced asHistoryEntry.sessionId), so recalled prompts can be traced back to the session they came from. Existing history databases gain the column automatically on next launch. - Added compact inline TUI renderers for the
retain,recall, andreflectmemory tools.retainnow shows one themed bullet line per stored item (truncated to width) under a status header with the stored/queued count, andrecall/reflectcollapse to a single query header (recall reports the match count and hides recalled memories until expanded) instead of dumping the raw JSON argument tree. - Added a randomly picked tip beneath the welcome screen, sourced from an embedded
tips.txt(one tip per line). The line is italicized with a purpleTip:label and a dimmed light-blue body, and the tip is chosen once per welcome instance so intro-animation and LSP re-renders don't shuffle it. - Added a Mnemosyne-only
memory_editagent tool for updating, forgetting, or invalidating recalled memories by id, and added/memory statsplus/memory diagnoseslash commands for backend maintenance visibility. - Added an
orchestratemagic keyword that mirrorsultrathink: dropping the standalone word in a message paints it with a cool teal→violet gradient in the editor and appends a hidden system notice that switches the model into the multi-phase, parallel-subagent orchestration contract. Matching is word-bounded and case-insensitive, soorchestrated/orchestratingnever trigger it. - Added a model-tier slider to the plan-approval prompt ("Plan mode - next step"). Left/right arrows move it from any list position to pick which configured role model (
cycleOrder, e.g.smol › default › slow) executes the approved plan, with each tier colored by its role and the resolved model name shown beneath the track. The chosen tier is applied before dispatch and carries through the fresh/compacted execution session; the slider is hidden when fewer than two role models resolve.
Changed
- Changed
ircto treat the attached human as a first-classUserpeer, merging human prompts intoirc call Userwith optional structured question payloads and adding/dm <agent> <message>for user-to-agent routing without switching views. - Changed the
--resumesession picker (and the in-session resume selector) to also rank sessions by prompt-history matches fromhistory.db, not just the session-list metadata. Because the session list only indexes the first 4KB of each file, this surfaces sessions by prompts typed deep into long conversations. Sessions matched by both signals lead, then metadata-only matches, then history-only matches — no metadata match is dropped. - Changed the
tasktool's streaming call preview to list each dispatched agent'sidand UI description as a tree instead of a bareN agentscount, so the individual agents are visible while the tool-call arguments are still streaming. The collapsed view caps at 12 entries (… N more agents); the expanded view shows all. - Changed Mnemosyne
recalltool output to include memory ids for explicit recall results so agents can targetmemory_edit; auto-injected memory context andreflectremain id-free. - Changed the system prompt to advertise
memory://rootonly when the local memory backend is active. - Changed
todo_writeresult rendering to animate completed items in place: the checkbox flips checked first, then the strikethrough reveals across the task text.
Removed
- Removed the standalone
ask,task, andyieldtools along with their obsolete prompts, docs, and tests; delegation now routes through persistentdelegateagents plus IRC coordination. - Removed the
/orchestrateslash command; orchestration is now triggered by theorchestratekeyword (see Added) so the contract rides alongside the user's own prompt instead of replacing it. - Removed the sticky Todos panel all-done drop/collapse animation; completed todo state now stays visible until the next explicit todo update changes it.
Fixed
- Fixed Mnemosyne session shutdown to flush queued memory extractions before exit so the last turn’s facts are not lost
- Fixed a native crash (
malloc: pointer being freed was not allocated/NAPI FATAL ERROR) when quitting after the local transformers.js title model had run. The tiny-title worker no longer callspipeline.dispose()on shutdown — disposing the onnxruntime session freed native memory that Bun's worker/NAPI teardown then freed again. The worker is torn down immediately after, so the OS reclaims the model memory regardless. - Fixed the tiny-title download progress bar flashing on every first message even when the local model was already downloaded. A cached model emits the same
download/progressevents as a real download, so the bar is now revealed only when in-flight progress events keep arriving past a short grace window — cache hits finish (or fall silent during onnxruntime init) before then and never show the bar. - Fixed the Mnemosyne memory backend lifecycle so auto-retain counts the full session transcript, delegated agents inherit the parent Mnemosyne state,
/memory clearremoves scoped project-bank databases, session disposal closes Mnemosyne SQLite handles, session switches rekey/reset Mnemosyne tracking, and project bank names include an absolute-root hash with safe bank-name sanitization. - Fixed the streaming edit preview showing no diff for single-line hashline edits. The preview-diff coalescing keyed only on the arg text, so the final (args-complete) pass — which computes an untrimmed diff — was skipped because the payload was byte-identical to the last streamed chunk whose trailing line had been trimmed. The dedup key now pairs the streaming state with a content hash.
- Fixed
Escin a delegated agent view returning to the main session instead of aborting the delegated agent's active turn. - Fixed the subagent stats line to separate the cost with the theme dot separator (was a stray literal
.) and to render context usage as<pct>%/<window>(e.g.21.3%/272K) matching the status line gauge, via a sharedformatContextUsagehelper now used by the footer, status-line segment, session observer overlay, andtaskrenderer. - Fixed the agent roster staying pinned under the editor when all delegated agents are idle or dormant; it now reappears when explicitly focused with
Alt+Down/ session observe. - Fixed selector-style UI components to honor
tui.select.upandtui.select.downkeybindings instead of hard-coding raw Up/Down arrow bytes (#1535). - Fixed the bash (and
recipe) tool result footer not rendering for failed commands. A non-zero exit threw aToolError, which dropped the result details, so the styled⟨Wall … | Timeout …⟩footer was replaced by the rawWall time: … seconds/Command exited with code Nlines. Non-zero exits now resolve as a non-throwing error result that keepswallTimeMs/timeoutSeconds/exitCode, and the footer shows⟨Wall … | Timeout … | Exit: N⟩with the textual notices folded out of the output pane. Aborts, timeouts, and missing-exit-status still throw as before. - Fixed selector-style UI components to honor
tui.select.upandtui.select.downkeybindings instead of hard-coding raw Up/Down arrow bytes (#1535).
[15.5.15] - 2026-05-30
Changed
- Enabled the agent loop's tool-call batch cap for Anthropic Claude sessions, cutting oversized streamed tool-use bursts into runnable batches before continuing the conversation.
Removed
- Removed the
calctool (deterministic arithmetic evaluator) and itscalc.enabledsetting. The model can compute viaevalinstead.
Fixed
- Fixed Anthropic Claude tool-call batching to clear and reapply the Claude-specific batch cap whenever the session model changes
[15.5.14] - 2026-05-29
Added
- Added progress status output for
llm()calls ineval, including the resolved model, tier, and returned character count - Added an
llm(prompt, opts)helper to bothevalruntimes (JavaScript and Python) for oneshot, stateless LLM calls.opts.modelselects a tier —"smol"(pi/smol),"default"(the session's active model, falling back topi/default), or"slow"(pi/slow, with high reasoning effort on reasoning-capable models). Passsystemfor a system prompt and a plain JSON-Schemaschemato force a structured response (the helper returns the parsed object instead of the completion string). Calls carry no conversation history and expose no agent-visible tools; they route host-side through the existing tool bridge under the reserved name__llm__(packages/coding-agent/src/eval/llm-bridge.ts).
Fixed
- Fixed a rewind/restore loop when the session leaf lands on an assistant turn that emitted tool calls (e.g. selecting such a turn in
/tree, or restoring a session whose head is a mid-batch turn). That turn's tool results are persisted as its children — below the leaf — so they fall off the leaf→root path thatbuildSessionContextwalks, leaving the assistant turn'stool_useblocks dangling as the final message.transformMessagesthen fabricated one synthetic"aborted"/"No result provided"result per call plus a<turn-aborted>developer note, which both rendered as phantom failed calls on a turn that "hadn't run anything yet" and re-injected the whole failed batch into the model's context, prompting it to re-issue the batch (the spiral).buildSessionContextnow strips danglingtool_useblocks from a trailing assistant turn (dropping the turn entirely if nothing else remains), so a rewound turn resumes cleanly from its reasoning/text. Live turns are unaffected — their results persist and the leaf advances past the assistant before any rebuild. - Fixed external extension loading on Windows compiled binaries: bare
@oh-my-pi/pi-*value imports (e.g.import { AssistantMessageEventStream } from "@oh-my-pi/pi-ai") failed withCannot find package '\$bunfs\root\packages\…'becauselegacy-pi-compat.tsbuilt shim override paths from a hardcoded POSIX/$bunfs/root/packagesliteral. Win32 normalised the leading slash to a backslash and the resulting path never resolved against the real bunfs mount (<drive>:\~BUN\root\…). The bunfs package root is now derived fromimport.meta.dir, so override paths stay platform-native on Windows, Linux, and macOS (#1514). - Fixed the interactive prompt showing no cursor in Ghostty. A prior change wired the editor's cursor mode to a new
getUseTerminalCursorMarker()(which always reported the requested preference) instead of the resolved hardware-cursor visibility, so when Ghostty force-hid the hardware cursor the editor stayed in terminal-cursor (marker-only) mode and drew no glyph — leaving no visible caret with eithershowHardwareCursor/PI_HARDWARE_CURSORvalue. The editor now followsui.getShowHardwareCursor(): a hidden hardware cursor falls back to the steady software-cursor glyph (which still emitsCURSOR_MARKERfor IME positioning).
Changed
- Changed the
evaltool'sdisplay()JSON tree in the transcript to use the sharedrenderJsonTreeLinesrenderer (the same one behind tool args, MCP results, and subagent output) instead of its own format. This drops the redundantObject(N)/Array(N)type labels and the per-outputJSON output Nheader in favor of type icons plus bare keys; thedisplay[N]header is now shown only when a cell emits more than onedisplay()value. - Removed the animated spinner from the sticky
Todospanel. In-progress tasks and pending tasks with a matching in-flight subagent still highlight (accent colour + the statictheme.status.runningglyph), but no longer tick throughtheme.spinnerFrames, so the panel paints once per state change instead of on an 80 ms timer. Subagent auto-checkmarking, the advancing window (selectStickyTodoWindow),todoMatchesAnyDescriptionhighlighting, and the all-done close animation are unchanged.
[15.5.13] - 2026-05-29
Breaking Changes
- Changed hashline edit syntax to verb-based v4: body-bearing ops are
replace N..M:,insert before N:,insert after N:,insert head:, andinsert tail:, while bodylessdelete N..Mhandles deletion. Removed>A..Brepeat rows and the oldprepend:/append:virtual insert headers;-rows remain rejected with a teaching error.
Changed
- Changed hashline tag generation to use full-file snapshots for read/search/ast-grep and related outputs, so hashline anchors now validate only when the complete file matches
- Changed hashline tagging to omit file headers for files over 4 MiB or that cannot be snapshotted, so those files are returned without editable hashline anchors
- Changed hashline context generation for line edits from partial/sparse snippets to complete-file fingerprints, reducing stale anchors for partially read files
Fixed
- Restored automatic repair of
editrange hunks that break bracket balance — the failure class that previously left a duplicated closing line (a</>/);/}echoed just below the range) or dropped one (the range swallowed a});the payload never restated), leaving the file syntactically broken until a follow-up edit. The hashline applier now normalizes each replacement so its payload preserves the deleted region's delimiter balance, dropping a duplicated bordering closer or sparing a deleted one, and surfaces a warning on the tool result. Always on and balance-validated (noedit.hashlineAutoDropPureInsertDuplicatessetting); see@oh-my-pi/hashlinefor the contract.
[15.5.12] - 2026-05-29
Added
- Added the
omp-pluginsdiscovery provider, which scans every extension package directory configured viaextensions:(in~/.omp/agent/settings.jsonor<cwd>/.omp/settings.json) or--extension/-eon the CLI forskills/,hooks/pre|post/,tools/,commands/,rules/,prompts/, and.mcp.json. Prior to this, only the extension's TypeScript factory module ran; every sibling capability the docs (https://omp.sh/docs/extension-authoring) advertised was silently ignored (#1496). - Added the top-level
omp install <target>subcommand documented at https://omp.sh/docs/extension-authoring. Local paths route toomp plugin link(so the directory is symlinked into the plugin set), and npm/marketplace specs route toomp plugin install. Before this,installwas not a registered subcommand and the CLI runner silently forwardedinstall ./my-extensiontolaunchas an initial LLM prompt (#1496).
Changed
- Changed the sticky
Todospanel above the editor to advance as tasks close, instead of pinning to the first 5 tasks of the active phase.selectStickyTodoWindownow shows up to 5 open (pending / in_progress) tasks in original phase order and reports the count of remaining open tasks for the+N morehint, so everytodo_writeflip produces a visible row shift. Closed-phase tail falls back to the last 5 tasks (with the+N moreline suppressed) untilgetActivePhasewalks to the next phase. - Linked the sticky
Todospanel to the liveSessionObserverRegistryso pending todos that have an in-flight subagent doing their work light up green with an animated spinner — the sametheme.spinnerFrames("status" preset) thetasktool uses for its agent rows — instead of staying greyed out as if nothing is happening. A new exportedtodoMatchesAnyDescription(content, descriptions)does case- and whitespace-insensitive equality first with a 6-char minimum-overlap substring fallback in either direction, so "Sonnet #2: shallow bug scan" and a subagent description of "Sonnet #2" still link up. Completed todos now render withtheme.status.success(✔ /\uf00c/[ok]per symbol preset, still wrapped in thesuccesscolour so themed palettes can keep their purple/green/whatever) and in_progress rows render withtheme.status.running, matching thetasktool's icon vocabulary. The spinner interval only ticks while at least one visible open todo has a matched active subagent, and self-stops once subagents finish, so plain in_progress todos do not animate forever in the absence of subagent activity. - Extracted the top-level CLI command table from
src/cli.tsinto a side-effect-freesrc/cli-commands.tsso test code can introspect the registered subcommands without triggering the entrypoint's top-level await.
[15.5.11] - 2026-05-29
Added
- Added
SqlSessionStorage, abun:sql-backed implementation ofSessionStoragethat persists session JSONL into PostgreSQL, MySQL/MariaDB, or SQLite. Pass a connectedBun.SQLinstance (the constructor acceptspostgres://,mysql://, orsqlite:URLs) toSqlSessionStorage.create({ client, table?, adapter?, createTable? })and hand the returned storage to anySessionManagerfactory. The dialect is auto-detected fromclient.options.adapterand used to pick the correct DDL plus upsert-with-append syntax (ON CONFLICT … DO UPDATEfor PG/SQLite,ON DUPLICATE KEY UPDATEfor MySQL), so the agent's append-only persist pattern works in a single round-trip per line. Same in-memory mirror anddrain()semantics as the Redis backend; blobs and tool artifacts still live on disk viaArtifactManager/BlobStore. - Added
RedisSessionStorage, abun:redis-backed implementation of theSessionStorageinterface that lets API consumers route session JSONL through Redis instead of local disk. Pass a connectedBun.RedisClient(or any compatible adapter) toRedisSessionStorage.create({ client, prefix? })and hand the returned storage toSessionManager.create(cwd, sessionDir, storage)(or any other static factory that accepts a storage argument). An in-memory mirror is loaded on creation so the interface's synchronous methods (existsSync,statSync,listFilesSync, …) keep their contracts;drain()waits for queued background writes. Tool artifacts and image blobs still live on disk viaArtifactManager/BlobStore— Redis only owns the session JSONL keyspace under the configured prefix. - Exported the
SessionStorage/SessionStorageWriter/FileSessionStorage/MemorySessionStoragesymbols (already reachable via the./session/session-storagesubpath) from the package root so SDK consumers can construct alternative storage backends without deep-importing. - Added a fresh
¶<relative-path>#TAGsnapshot header to thewritetool's success text in hashline display mode, covering plain disk writes, ACP-bridge writes, and conflict resolutions (bulk resolutions emit a trailingSnapshots:block with one header per successfully written file). The header records a current snapshot in the file-snapshot store so the nexteditcan land without an extrareadround-trip. Suppressed when the session is not in hashline mode and skipped for archive/SQLite writes and host-managed internal URL targets where hashline anchors do not apply.
Changed
- The
edittool's stale-snapshot rejection message now distinguishes "file changed between read and edit" (the section's hash was recorded in this session but the file has since drifted — a prior in-session edit advanced it, or an external write changed it) from "hash #X is not from this session" (a fabricated or carried-over cross-session tag), the latter carrying explicit "never invent the tag" guidance. Both messages include the current file hash plus 2 lines of context around each anchor so the next attempt has everything it needs. Snapshot-based recovery still runs first; the sharper diagnostics only surface when recovery cannot reconcile the edit.
Fixed
- Fixed Autonomous Memory phase 1/phase 2 failing with
Thinking effort low is not supported by <provider>/<model>on models whose supported reasoning efforts excludelow/medium(e.g.deepseek/deepseek-v4-pro). Both stage1 (Effort.Low) and consolidation (Effort.Medium) call sites inpackages/coding-agent/src/memories/index.tsnow route throughclampThinkingLevelForModel, lifting the requested effort to the model's lowest supported level instead of lettingrequireSupportedEffortthrow (#1480).
[15.5.10] - 2026-05-28
Added
- Added
/drop-imagesslash command that strips everyImageContentblock from the current session's branch —user/developer/custom/hookMessage/toolResultcontent arrays plustoolResult.details.imagesandfileMention.files[].image— rewrites the session JSONL, rebuilds the agent's in-memory message list, tears down Codex Responses provider sessions, and rebuilds the TUI chat container so the change is visible immediately. ACP clients receive the same handler (returns"Dropped N images …"/"No images found …"throughruntime.output). Stripping content that would leave atoolResultorusermessage with zero blocks inserts a single[image removed]placeholder so providers do not reject empty content arrays.
Fixed
- Fixed compaction surfacing raw HTTP 401/403 envelopes (e.g.
Compaction failed: 401 {"type":"error","error":{"type":"authentication_error",…}}) instead of routing to an authenticated fallback model. The compaction layer now attaches the provider-reported HTTP status onto the thrown error, andAgentSession's auth-failure detector branches onerror.status === 401 || 403in addition to the existingauth_unavailableregex. When a fallback model role (e.g.modelRoles.smol) is configured, compaction retries it transparently; otherwise the user sees the actionable "Compaction requires usable credentials for …" hint instead of the raw provider envelope.
[15.5.8] - 2026-05-28
Breaking Changes
- Changed hashline edit parsing to require wrapped hunk headers such as
@@ A..B @@(including@@ BOF @@and@@ EOF @@), with empty@@ A..B @@blocks deleting the anchored range and legacy inline payload forms treated as malformed
Added
- Added
vault.enabledsetting (Tools → Obsidian Vault, defaultfalse) gating thevault://internal URL. When disabled,VaultProtocolHandler.resolve/write,resolveVaultUrlToPath, andhasObsidian()all refuse — the latter hides thevault://entry from the system prompt's Handlebars{{#if hasObsidian}}block. Tests can opt in viavi.spyOn(vaultProtocol, "isVaultEnabled").mockReturnValue(true). - Added support for
vault://URLs in path resolution utilities, including plan mode and internal selector parsing soreadand edit paths can target Obsidian vault files directly - Added
vault://internal URLs for editable Obsidian vault files, with filesystem-backed read/write/listing and CLI-backed vault index operations. - Added strict-mode indicators to
omp auth-gateway checkoutput by appending[strict]to strict-mode text headers and adding a top-levelstrictfield in--jsonoutput omp auth-gateway check --strictexercises each broker-supplied credential against its provider's chat-completion endpoint (cheapest bundled chat model per provider, with 15s/attempt timeout and up to 4 catalog fall-throughs on "model not found / invalid model" errors). Surfaces failures where the usage endpoint reports 200 but the chat endpoint 401s the same bearer (revoked OAuth scope, mislabeled provider row, …). Output gains a[chat: ok|FAIL|skip]column in text mode and acompletionfield on each credential in--jsonmode; the chat-failed count contributes to the non-zero exit code.
Changed
- Changed hashline apply behavior to preserve duplicated boundary and context lines in replacement and insert payloads instead of auto-absorbing or dropping them
- Updated hashline syntax: replaced
↑/↓payload sigils with^repeat syntax and|literal rows for clearer edit semantics - Changed hashline delete syntax from bare
A:orA-B:to explicitA-B:-inline delete marker - Modified hashline anchor syntax to require explicit range notation
A-B:instead of shorthandA:for single-line operations - Updated hashline description in settings to clarify pure insert context behavior without arrow notation
Removed
- Removed the
edit.hashlineAutoDropPureInsertDuplicatessetting - Removed the
edit.hashlineAutoDropPureInsertDuplicatessetting from configuration and execution paths - Removed the
edit.hashlineAutoDropPureInsertDuplicatessetting - Removed the
edit.hashlineAutoDropPureInsertDuplicatessetting from configuration and execution paths
Fixed
- Fixed agent yielding silently on
response.incomplete(OpenAI Responses / CodexstopReason: "length"). The agent now treats output-side incompletion as a recovery case: drops the truncated/reasoning-only assistant turn, attempts context promotion to a larger model, and falls back to compaction or handoff.AutoCompactionStartEvent.reasonand the custom-toolauto_compaction_start.triggerdiscriminator gain an"incomplete"value. The handoff strategy is honored for"incomplete"(unlike"overflow", where the input is broken and handoff would hit the same wall). - Fixed
evaltool to resize large displayed images and append dimension notes to text output - Fixed
writetool to strip malformed or loose hashline section headers before writing file content - Fixed
evaltool image rendering to resize displayed images before returning them and append image-dimension notes to text output - Fixed
writetool output sanitation to strip malformed or loose hashline section headers before writing file content - Fixed
omp auth-broker servecrashing at startup withlogger.setTransports is not a function— switched the call site toimport { setTransports } from "@oh-my-pi/pi-utils/logger", bypassing theloggernamespace re-export that some Bun versions failed to expose at runtime - Fixed
omp auth-gatewayreturning502 upstream_errorand refusing to rotate credentials when a provider responded with a non-401 usage-limit error (Codexusage_limit_reached, Anthropicusage_limit_reached, Googleresource_exhausted).classifyGatewayErrornow reusespi-ai's centralisUsageLimitErrorheuristic and reports those failures as429 rate_limit_error.streamSimple's pre-emit retry hook fires on usage-limit phrasing in addition to HTTP 401; the gateway's refresh callback branches on the error type and callsAuthStorage.markUsageLimitReached(provider, sessionId, { retryAfterMs })— temporarily blocking just the exhausted credential and surfacing the next sibling — instead ofinvalidateCredentialMatching, which would have suspect/deleted the row. The same branching is wired into the coding-agentstreamFncallback so subscription multi-account rotation works the same on both surfaces. - Fixed
extractRetryHintnot recognising Codex'sTry again in ~N min./… hour/… hoursphrasing, which left the gateway and TUI without a server-suggested retry window when an upstream account hit its usage cap. The sharedtry again inpattern now acceptsmin,minutes,mins,h,hr,hour,hoursunits in addition toms/s/sec, and tolerates a leading~and embedded whitespace. - Fixed the auth-gateway threading
sessionId: undefinedintoAuthStorage.getApiKey, which left#sessionLastCredentialempty and mademarkUsageLimitReacheda no-op for gateway-mediated requests. Both/v1/chat/completions-style endpoints and the/v1/pi/streamfast path now derive a stablesessionIdfrom the client'sprompt_cache_key(or the existing model+system+tools+first-message hash when absent) and reuse the same identity for credential-stickiness and prefix-cache routing. - Fixed
evaltool to resize large displayed images and append dimension notes to text output - Fixed
writetool to strip malformed or loose hashline section headers before writing file content - Fixed
evaltool image rendering to resize displayed images before returning them and append image-dimension notes to text output - Fixed
writetool output sanitation to strip malformed or loose hashline section headers before writing file content - Fixed
omp auth-broker servecrashing at startup withlogger.setTransports is not a function— switched the call site toimport { setTransports } from "@oh-my-pi/pi-utils/logger", bypassing theloggernamespace re-export that some Bun versions failed to expose at runtime - Fixed user shortcut Python execution to namespace session IDs like eval, so both paths share one kernel
Security
- Secured
vault://reads and writes by validating URL paths and blocking traversal, absolute paths, and symlink escapes outside the selected vault root
[15.5.7] - 2026-05-27
Added
providers.openrouterVariantsetting (Settings → Providers → "OpenRouter Routing") to default OpenRouter requests to a routing-variant suffix (:nitro,:floor,:online,:exacto). Selectors that already name a variant (e.g.openrouter/anthropic/claude-haiku:nitro) keep precedence.generate_imagesupports xAI Grok Imagine viaproviders.image=xai. Supportsgrok-imagine-image(default) andgrok-imagine-image-qualityat aspect ratios1:1,16:9,9:16,4:3,3:4,3:2,2:3. Uses the xAI Grok OAuth credential when available, otherwiseXAI_API_KEY.- New
ttstool synthesises speech via xAI Grok Voice behind the disabled-by-defaulttts.enabledsetting. Built-in voicesara,eve(default),leo,rex,sal; custom voice IDs also accepted. Output codec inferred from theoutput_pathsuffix (.wav→wav, elsemp3). Up to 15,000 characters per request.
Fixed
- Fixed plan-mode re-entry after approval reopening a fresh
local://PLAN.mdinstead of the approved titled plan artifact, which could duplicate plan content and fail approval on an existing destination. - Fixed
readURL reader mode aborting after a stalled Jina request instead of falling back to trafilatura/lynx/native: Jina (and Parallel extract) now have their own per-attempt sub-budget capped at 10s, the catch handler honours only real user cancellation, and the in-process native renderer is always attempted on already-loaded HTML (#1449)
[15.5.6] - 2026-05-27
Added
- Support for multi-range line selectors on URLs (e.g.,
:5-10,20-30) to fetch and display multiple non-contiguous sections - Support for combining
:rawmode with line range selectors on URLs (e.g.,:raw:1-120or:1-120:raw) - Support for line range selectors on directory listings (e.g.,
:30-40to view lines 30–40 of a directory tree) - Clear error message when requesting a line offset beyond the end of a directory listing
Changed
- URL selector parsing now supports multiple trailing selector tokens (e.g.,
:raw:N-M), applying them left-to-right
Fixed
- Fixed
:rawselector being ignored for JSON and feed URLs, causing them to be pretty-printed or converted to markdown instead of returning raw content - Fixed directory listing line selectors silently dropping the offset parameter and only applying the limit
[15.5.5] - 2026-05-27
Changed
- Removed the model-facing
pathproperty from hashline edit tool parameters; hashline edit targets now come from¶PATHheaders ininput.
Fixed
- Fixed legacy pi-* extension loading regression where
import { Type } from "@(scope)/pi-ai"(e.g.@earendil-works/pi-aiused by@plannotator/pi-extension) failed withExport named 'Type' not foundafter pi-ai 15.1.0 removed the rootTyperuntime export; the legacy-pi compat layer now redirects bare@oh-my-pi/pi-airoot imports through a sibling shim that re-exports the canonical pi-ai surface plus the Zod-backedTyperuntime from the same TypeBox shim served to@sinclair/typeboximports (#1437)
[15.5.4] - 2026-05-27
Breaking Changes
- Removed the package root
hashlineexport so imports from the top-level entrypoint can no longer accesshashlinehelpers directly
Added
- Added
read.summarize.minTotalLinessetting (default 100) to set the minimum file length that triggers read summarization - Added
<file>:<lines>support tosearchpaths, allowing file-scoped constraints such as:N-M,:N+K, and comma-separated ranges
Changed
- Changed multi-section hashline
editexecution to defer LSP diagnostics flushing until the final section is written - Changed read to return verbatim contents for files shorter than
read.summarize.minTotalLinesinstead of summarizing them - Changed
searchpath line-range filtering to include only matches and context lines that fall inside the requested ranges
Fixed
- Fixed multi-section hashline edits to reject duplicate canonical targets and preflight write guards before any section is committed
- Fixed
createAgentSession()dropping the hiddenresolvetool from the registry when no active tool setsdeferrable: true, even though plan mode dispatches the plan-approvalresolve { action: "apply", ... }call through a standing handler. Read-only plan-mode toolsets (e.g.read,search,find,web_search) silently activated plan mode withoutresolve, leaving the agent unable to submit the finalized plan and forcing the user to exit plan mode manually.resolveis now kept wheneverplan.enabledis true, so the standing handler always has a callable tool (#1428) - Fixed
ompstartup and/changelogreading the host project'sCHANGELOG.mdas omp's —getPackageDir()no longer falls back to the user'scwdwhen no owningpackage.jsonis locatable, preventing spuriouslastChangelogVersionwrites (#1423)
[15.5.3] - 2026-05-27
Breaking Changes
- Disallowed inline payload on hashline
↑,↓, and:operations (including BOF/EOF inserts), requiring payload text to be supplied on standalone+continuation rows
Changed
- Warned when legacy inline
LINE:TEXTlines are accepted as payload continuations only when inside a pending multi-lineA-B:replacement
[15.5.2] - 2026-05-26
Breaking Changes
- Changed the hashline patch format so payload continuation lines now require a leading
+, rejecting unprefixed multiline payload rows that were previously accepted as fallback payload text
Changed
- Changed hashline payload parsing so blank lines are only preserved when prefixed with
+, so blank separator lines between operations are ignored unless explicitly marked - Changed payload escaping so a line beginning with
+is now represented as++...while the leading marker is stripped before writing - Changed the default
task.simplemode fromdefaulttoschema-free, so task-callschemainputs are disabled by default while sharedcontextand user prompt/session-defined output schemas remain available - Changed
tools.approvalMode: yoloto auto-approve tool calls even when a tool marksoverride: true; usertools.approval.<tool>policies (allow/prompt/deny) now remain the only controls for yolo mode. - Changed the hashline edit executor to coalesce two consecutive
A-B:ops on the identical range last-wins (the model painted a before/after pair) and append a warning, instead of throwinganchor line X is already targeted by the :/! op on line Y. Other overlap shapes (different ranges,A-B:+!,!+!) still throw.
Fixed
- Fixed nested replace parsing so line-anchored
N:rows inside a pendingA-B:replacement now trigger overlap errors instead of being silently folded into the replacement payload
[15.5.1] - 2026-05-26
Breaking Changes
- Removed the
href,hrefr, andhlineHandlebars prompt helpers along with the shared hashline anchor state; none were referenced by any built-in or user prompt template
[15.5.0] - 2026-05-26
Added
- Added per-tool approval declarations so each built-in, custom, or extension tool can declare its capability tier and approval prompt details.
- Added
OMP_MCP_TIMEOUT_MSenvironment variable to override MCP client request timeout for every server (in milliseconds); set to0to 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). - Added
omp auth-broker list(with--jsonfor machine-readable output) to enumerate supported OAuth providers, replacingbunx @oh-my-pi/pi-ai list. - Added interactive provider selection to
omp auth-broker loginandomp auth-broker logoutwhen invoked without a provider argument (replacing the equivalentbunx @oh-my-pi/pi-ai login/logoutflows). The logout picker is sourced from stored credentials so it only lists providers the user is actually signed in to. - Added directory matches to the
findtool: glob searches now return directories alongside files, with directory hits emitted with a trailing/marker.findfor**/testsno longer requires a follow-upreadto surface a directory hit; tool prompt and output docs were updated to reflect that paths may be either kind. - 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.
Changed
- Changed tool-approval prompts to use an explicit
Approve/Denyselector and surface the denial reason as contextual help text instead of a bare confirm/cancel toggle. - Changed approval safety overrides to prompt even in
yolo/--auto-approvesessions, so critical tool-declared patterns no longer run unattended. - Changed
omp auth-broker loginto drive the per-provider OAuth/API-key flow in-process viaAuthStorage.login()instead of spawning thepi-aiCLI subprocess. Thepi-aibin is being removed; the same login surface now lives entirely insideomp. - Changed the default per-line truncation cap for search/grep output (
DEFAULT_MAX_COLUMN) from1024to512characters to keep wide minified single-line bundles from blowing out the model's context. - Changed
edit.hashlineAutoDropPureInsertDuplicatesto also fire onA-B:payloadreplacement 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 ofA-B:foowhere the user meantA-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.
Fixed
- Fixed the agent loop and bash executor busy-spinning when scheduler waits returned early. napi
uv_async_sendcallbacks can wake the event loop after only ~1–2 ms even when the caller asked for a longer sleep, soyieldIfDue()now compensates by retryingBun.sleep()until the requested wall-clock duration has elapsed, and the bash executor wraps itsrunPromise/timeout/abort race in anExponentialYield(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 viaAbortSignalso they don't keep firing after a winner is selected (#1396 by @hezhiyang2000, closes #1384). - Fixed streaming edit previews going blank for inline-payload ops.
LINE↓payload/A-B:payloadare 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 rawA-B: bla bla blainput. Inline-body content onop-insertandop-replacetokens is now emitted as a+payloadline on the same op tick. - Fixed
/usageand the status-line reset countdown rendering stale negative deltas after a Codex window had elapsed: Codex keeps reporting the prior window'sreset_atuntil a new request opens a fresh window, which turned theresets in …suffix into a meaningless negative duration.formatDurationnow clamps non-positive, NaN, and infinite inputs to0ms, and both renderers suppress theresets in …suffix entirely onceresetsAt <= now. - Fixed auto-handoff race at the context threshold: when
compaction.strategy = handofffired atagent_endwith an active checkpoint or incomplete todos, the deferred handoff post-prompt task and the rewind/todo-completion path both scheduled work concurrently, so a freshagent.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).#checkCompactionnow reports whether it deferred a handoff and theagent_endhandler short-circuits the rewind/todo passes;#scheduleAgentContinuealso skips whenisCompacting || isGeneratingHandoff. The pre-prompt#checkCompactioncall now forces inline execution (allowDefer = false) so the new turn cannot begin until the maintenance settles. - Fixed
/exitand 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 awaitinggenerateHandoffrejects andPromise.allSettledcan resolve. Tool work (bash/eval/python) is intentionally still left for the existing dispose paths so shared kernels continue to survive across session dispose.
[15.4.3] - 2026-05-26
Fixed
- Fixed Google Vertex cached project discovery replacing the bundled fallback catalog so
/modelsdoes not keep showing outdated Gemini entries after authoritative Vertex discovery (#1412).
[15.4.2] - 2026-05-26
Fixed
- Fixed plan-mode subagents being unable to terminate because
yieldwas registered but missing from the active tool set whenrequireYieldToolwas combined with an explicittoolNameslist (#1408)
[15.4.1] - 2026-05-26
Breaking Changes
- The
vimedit mode option is no longer available; configurations usingedit.mode: vimwill be automatically mapped tohashlinemode - 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. UseLINE↓contentfor a one-line insert,LINE↓firstline\nsecondlinefor two lines; bareLINE↓/LINE↑/LINE:(no inline payload) still insert/replace with one blank line as before.
Added
- Added
irc.timeoutMssetting to configure IRC message timeout duration with a default of 120 seconds - Added timeout enforcement for IRC send operations to prevent indefinite hangs when recipients are unresponsive
- Added evaluator state inheritance for
task-spawned subagents so JavaScript and Python variables are visible between a parent agent and its child sessions - Added
hashline-peredit mode to restore the legacy per-line hashline dialect alongside the default file-hash dialect - Added file-hash computation and validation for hashline sections to detect stale edits
- Added file-read snapshot caching with multi-snapshot ring per path for recovery from agent's own writes
- Added delete operation (
!) support to hashline grammar for explicit line deletion - Added structural bracket/brace balance warnings when deleting lines with unclosed constructs
- Added file-hash computation and validation for hashline sections to detect stale edits
- Added file-read snapshot caching with multi-snapshot ring per path for recovery from agent's own writes
- Added delete operation (
!) support to hashline grammar for explicit line deletion - Added structural bracket/brace balance warnings when deleting lines with unclosed constructs
Changed
- Changed Python shared eval sessions to be keyed by
sessionIdandcwdso code state no longer leaks across different directories when reusing a session - Changed shared JavaScript and Python startup to deduplicate concurrent first-time session initialization so parallel first calls share one warm session
- Changed shared JavaScript and Python execution output handling so interleaved async runs keep their
displayoutput scoped to the originating run - Changed Python tool bridge to use per-run identifiers alongside session IDs for correct routing of tool responses and output in concurrent evaluations
- Changed JavaScript and Python
evalexecution to allow overlapping asynchronous cells on the same session ID to run concurrently instead of being strictly queued - Updated the edit mode option set to support
replace,patch,hashline, andapply_patchvariants - Bare
A:/A-B:(no payload, no inline body) now replaces the line/range with a single blank line, symmetric with bareA↑/A↓inserting a blank line; previously rejected as ambiguous - Simplified hashline anchor format from
LINE+HASHto bareLINEnumbers in edit operations - Updated hashline file headers to include 4-hex file hash:
¶PATH#HASHformat for anchored edits - Changed hashline line separator from
|to:in editable output (e.g.,42:contentinstead of42ab|content) - Removed per-line hash validation; file-level hash now validates entire section integrity
- Updated read/search output to emit file-hash headers (
¶PATH#HASH) followed by numbered lines for hashline mode - Modified hashline grammar to accept optional file hash in headers and removed hash requirements from line anchors
- Changed hashline diff preview format to use
LINE:contentinstead ofLINE+HASH|content - Updated prompt documentation to reflect new
¶PATH#HASHheader and bare line-number syntax - Bare
A:/A-B:(no payload, no inline body) now replaces the line/range with a single blank line, symmetric with bareA↑/A↓inserting a blank line; previously rejected as ambiguous - Simplified hashline anchor format from
LINE+HASHto bareLINEnumbers in edit operations - Updated hashline file headers to include 4-hex file hash:
¶PATH#HASHformat for anchored edits - Changed hashline line separator from
|to:in editable output (e.g.,42:contentinstead of42ab|content) - Removed per-line hash validation; file-level hash now validates entire section integrity
- Updated read/search output to emit file-hash headers (
¶PATH#HASH) followed by numbered lines for hashline mode - Modified hashline grammar to accept optional file hash in headers and removed hash requirements from line anchors
- Changed hashline diff preview format to use
LINE:contentinstead ofLINE+HASH|content - Updated prompt documentation to reflect new
¶PATH#HASHheader and bare line-number syntax
Removed
- Removed the
installH2Fetch()activation from CLI startup; HTTPS fetches now use Bun's default transport - Removed the
vimedit mode along with theVimToolmodule, prompt, and supporting buffer/engine/renderer stack - Removed per-line hash anchors (2-letter bigram hashes) from hashline format
- Removed
RANGE_INTERIOR_HASHconstant; multi-line ranges no longer use**filler - Removed
HashMismatchtype and hash mismatch error reporting; replaced with file-level validation - Removed per-line hash anchors (2-letter bigram hashes) from hashline format
- Removed
RANGE_INTERIOR_HASHconstant; multi-line ranges no longer use**filler - Removed
HashMismatchtype and hash mismatch error reporting; replaced with file-level validation
Fixed
- Fixed JavaScript module reloading to refresh local re-exports when transitive dependency files are edited
- Fixed Python tool calls in warm kernels to initialize once bridge environment variables appear after startup and to return a clear
tool bridge is unavailableerror when missing - Fixed IRC
sendhandling to preserve recipient incoming messages when auto-reply timeouts instead of dropping them - Fixed Python session disposal to cancel all concurrent active executions in a shared kernel
- Fixed JavaScript
evalimports to preserve module-level singletons across re-imports of unchanged local files and reload them only after edits - Fixed concurrent Python evaluator tool calls to use per-run identifiers so tool responses and output are routed to the correct execution
- Fixed the
searchtool argument validation to accept a single stringpathsvalue as a one-path search.
[15.4.0] - 2026-05-26
Breaking Changes
- Replaced the hashline patch format from
§,«,»,≔, and..to¶,↑,↓,→with range separators written asA-B, requiring users to migrate hashline edit inputs
Added
- Added
codexandgeminito the web search provider settings so users can configure OpenAI and Gemini web search directly from provider selection - Added OpenAI (
codex) and Gemini web search options with updated setup descriptions foromp /login openai-codexand Gemini OAuth login - Added pretty-printing for wide JSON
data:payloads in the raw provider-stream debug viewer so streamed event bodies expand across multipledata:lines instead of getting clipped by the per-line truncator, and updated the viewer header to readraw provider stream (SSE + WS)now that Codex WebSocket frames also flow through the buffer
Changed
- Updated hashline operation syntax to support inline payload text on the same op line for insert and replace (
ANCHOR↑/↓/...→) while still accepting payload lines that follow - Updated hashline anchor parsing so copied
|TEXTdecorations remain cosmetic and payload must be provided on or after the operator - Unified subagent output-schema validation into a single shared module (
tools/output-schema-validator.ts) used by both the in-processyieldtool (validates before the subagent yields) and the executor's post-mortemfinalizeSubprocessOutputpath (validates after subprocess exit). Previously each side ran its ownnormalizeSchema→jtdToJsonSchema→validateJsonSchemaValuechain in parallel, which was semantically equivalent but invited drift: a future tweak on one side could silently disagree with the other and cause yields that pass in-tool to fail post-mortem (or vice versa). The unification preserves both call sites' existing behavior (yield throws an actionable per-issue error for the model; executor produces aschema_violationoutcome with the first issue and missing-required fields) by exposing two output formatters (formatAllValidationIssuesfor retries,formatValidationIssueHeadlinefor headlines). - Changed web search provider credential lookup to use the shared
AuthStoragepipeline (getApiKey/getOAuthAccess) for API-key and OAuth auth instead of directAgentStorageaccess - Changed the
codexweb search provider display label fromCodextoOpenAI - Updated
anthropicandopenai/geminiweb search option descriptions to reflect their nativeweb_search/OAuth requirements
Fixed
- Fixed hashline inline payload parsing so same-line payloads containing whitespace, including tab-indented text, are preserved instead of being rejected
- Fixed Bun HTTP/2 transport errors (
HTTP2StreamReset,HTTP2RefusedStream, andHTTP2EnhanceYourCalm) to be treated as transient so the assistant now retries automatically instead of stopping on these recoverable failures - 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
- Updated Tavily missing-credential feedback to prompt users to configure an API-key provider setting instead of referencing
agent.dbdirectly - Refreshed expired OpenAI Codex OAuth tokens during
web_searchexecution and persisted the updated credentials so searches continue working after token expiry - Fixed built-in
exploreagent failing every invocation withschema_violation: files.0.ref: must not be presenton releases prior to 15.3.2 by renaming thefiles[].refproperty tofiles[].pathin the agent's output schema;refis 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). - Increased the
yieldtool'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-mortemschema_violationcheck 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.
[15.3.2] - 2026-05-25
Added
- Added inline
|TEXTpayload support to»and«hashline insert operations, allowing single-line inserts on the op line and still supporting additional payload lines - Added support for using inline payloads with BOF/EOF inserts so
|TEXTis treated as inserted content at file boundaries - Added live nested-
taskrendering: while a subagent is mid-flight, the parent UI now surfaces both completed nestedtasksub-calls and the in-flight nested snapshot (forwarded fromtool_execution_update), matching the finished-result tree - Added
omp auth-gateway check(and matchingGET /v1/credentials/checkendpoint) — probes each broker-supplied credential against its provider's auth-verifying usage endpoint and prints per-credential health, so when a multi-account pool starts returning 401s you can identify which row in the broker is the bad one. The existing/v1/usageendpoint silently drops failed credentials, which is the wrong shape for diagnosing auth — the new endpoint captures errors and surfaces the credential's id, provider, type, email/accountId, and the upstream error string. CLI groups results per-provider, exits non-zero when any credential failed, and supports--jsonfor scripting. The probe also exercises OAuth refresh on expired tokens, so a working refresh + working access reports asokand a revoked refresh token reports asoauth refresh failed: …instead of being masked by the cached expired access token.
Fixed
- Fixed parsing of inline
|TEXTpayloads containing whitespace on»and«inserts, which previously failed with unrecognized-op errors - Fixed anchored insert handling so an inline
|TEXTbody matching the anchor line is treated as anchor decoration and no longer inserted as a duplicate
[15.3.0] - 2026-05-25
Added
- Added
OMP_NO_WEBPenvironment variable to disable WebP encoding in image resize, fixing HTTP 400 errors when attaching browser snapshots to vision models running on local llama.cpp (which uses STB library that lacks WebP support) - Fixed loop mode submitting the next prompt while a background async-job delivery turn (idle flush) was still pending, which could cause the job result to be silently dropped and make the session appear to keep firing while work was ongoing (#1294)
- Fixed clipboard image paste (Ctrl+V) silently failing on WSL2 by routing image reads through a
powershell.exebridge when WSL interop is detected, sincearboardreturnsContentNotAvailableunder WSLg (#1280) - Fixed extension
ctx.ui.notify()messages emitted duringsession_startbeing cleared before the first interactive render (#1316). - Fixed append-only context mode not being recomputed after model switches — the mode was frozen at session construction time using the initial model's provider, so
provider.appendOnlyContext=autoleft append-only enabled after switching away from DeepSeek (or disabled after switching to DeepSeek) for the rest of the session
Fixed
- Fixed clipboard image paste (Ctrl+V) silently failing on WSL2 by routing image reads through a
powershell.exebridge when WSL interop is detected, sincearboardreturnsContentNotAvailableunder WSLg (#1280)
[15.2.4] - 2026-05-22
Breaking Changes
- Replaced the legacy
@@header and+/</=/-hashline syntax with the new§PATHheader and«/»/≔operation format, so existing hashline scripts and prompts using old symbols must be updated
Added
- Added one-anchor
≔ANCHORshorthand equivalent to≔ANCHOR..ANCHORfor single-line replace/delete
Changed
- Changed
≔A..Bso an omitted payload now deletes the range, and added an explicit empty payload line to keep a literal blank replacement line
Removed
- Removed the
hsepprompt helper andPI_HL_SEPpayload-prefix configuration because hashline payloads are no longer line-prefixed
Fixed
- Fixed hashline payload handling in parser and streaming preview to preserve blank lines as actual payload text until the next op, file header, or envelope marker
[15.2.3] - 2026-05-22
Breaking Changes
- Changed PR and task-isolation worktree directory layout to hash-based
~/.omp/wt/<identifier>-<path-hash>style paths, replacing the previous nested encoded-repo layout
Added
- Added
omp worktreecommand (aliaswt) to list and manage agent-managed worktrees under~/.omp/wt - Added
omp worktree clearto remove orphaned worktree directories, with--allto include live PR-checkouts,--dry-runfor preview, and--jsonreporting - Added machine-readable JSON output to
omp worktree listfor scripted inspection - Added
display.shimmerappearance setting withclassic,kitt(Knight Rider K.I.T.T. scanner), anddisabledmodes
Changed
- Changed the welcome intro animation to a 3-second eased gradient sweep with a diagonal shine highlight across the logo
- Changed background job completion follow-ups to batch multiple finished jobs into a single
async-resultmessage, showing each completed job and its result in one place - Changed MCP notification follow-ups to combine multiple resource updates into a single consolidated message and suppress duplicate server/uri entries
- Updated PR checkout to reuse
hashPath-based worktree roots when creating and scanning worktrees for cleanup - Updated
worktreecleanup logic to gracefully prune parent git metadata after removing worktree directories - Reworked working-message shimmer animation for 60fps rendering: ANSI sequences are coalesced per same-tier run instead of emitted per code point, palettes compile once and cache per active theme, and the band position is now fractional so motion is smooth at any frame rate
- Switched MCP health-check and "Connecting to…" spinners from hard-coded ASCII (
|/-\) totheme.spinnerFramesso they pick up the active symbol preset (braille on unicode/nerd, ASCII when explicitly themed)
Fixed
- Fixed PR checkout failures when the default worktree path was already registered or occupied by stale leftovers by automatically selecting suffixed alternatives (
-2,-3, etc.) - Fixed Memory tab in the settings UI not revealing or hiding the Hindsight-only rows (
Hindsight API URL,Hindsight Bank ID,Hindsight Scoping, etc.) whenMemory Backendwas switched via the inline submenu. The selector now rebuilds its item list after every change so condition-gated rows appear/disappear immediately instead of requiring a tab switch
[15.2.2] - 2026-05-22
Fixed
- Fixed
RULES.mdnot being injected. The documented sticky-rules file at~/.omp/agent/RULES.mdand<repo>/.omp/RULES.mdwas never read by any discovery provider; only.omp/rules/*.mdwas scanned. The native provider now loads both as always-apply rules so they re-attach every turn as documented (#1266).
[15.2.1] - 2026-05-21
Fixed
- Fixed compaction routing to the wrong provider when
modelRoles.defaultis set to a different model than the active chat. Auto- and manual compaction now prefer the active session's model and only fall back to role-based candidates when the current model has no usable credentials. Previously, an Anthropic chat withmodelRoles.default = openai/gpt-5would compact through OpenAI (including the remote-compaction endpoint), even though the live conversation never used OpenAI. - Fixed context overflow not being detected when the session's model (e.g.
hf:zai-org/GLM-5.1viasyntheticprovider) returns a 400 with the upstream "400 status code (no body)" message wrapped inside a JSON envelope. TheisContextOverflowcheck now matches the no-body status phrase anywhere in the error string rather than requiring it at the very start, so auto-compaction fires correctly instead of leaving the session silently stuck (#1251). - Fixed
formatCapturedHttpErrornot extracting the error text from{"error":"string"}response bodies (only object-valuederrorfields were previously handled), resulting in raw JSON in error messages instead of the human-readable string.
[15.2.0] - 2026-05-21
Changed
- Changed the interactive working loader and slash-command progress bars to use the active theme's accent shimmer instead of static muted text.
Fixed
- Fixed false-positive hashline
~ TEXTseparator-padding warning firing on YAML, JSON, Python, Markdown, TOML, and other indent-sensitive file edits. The padding check is now skipped entirely for indentation-sensitive extensions (.py,.yml/.yaml,.md/.mdx,.json/.jsonc/.json5,.toml,.rst,.tf,.nix,.coffee,.haml/.slim/.pug,.sass/.styl,.nim,.cr,.elm,.fs, …), and tightened on every other extension to flag only the~ betatypo shape (exactly one leading space before non-space content) rather than any leading-space payload. - Fixed goal state machine:
getnow returns paused goals (was returning null forenabled=false),completenow works on paused goals after interrupts,createis allowed after a previous goal reachescompletestatus, and the goal tool is re-added to the active tool set on session reload when a paused goal is persisted. Addedresumeanddropops to the goal tool so the agent can re-engage or discard a paused goal without requiring user slash commands. (#1249)
[15.1.9] - 2026-05-21
Fixed
- Fixed
disabledProvidersstill probing local discovery endpoints for Ollama, llama.cpp, and LM Studio during background model refresh. Disabled providers are now excluded before implicit and built-in discovery managers are created. (#1232) - Fixed
omp acpauto-discovering host.mcp.jsonservers in parallel with the ACP client'ssession/new.mcpServers, which shadowed client-supplied MCP tools insearch_tool_bm25and the session tool registry. The ACP session factory now forcesenableMCP: false, so MCP ownership stays withAcpAgent#configureMcpServers. Non-ACP modes keep on-disk discovery. (#1234) - Fixed binary
omp updaterollbacks so a downloaded replacement that fails post-install version verification no longer remains installed over the previous working binary. (#1240) - Fixed
/force <tool>rejecting Ollama/local models before the requested tool could run; Ollama now receives a named forced choice that the provider transport narrows to the selected tool. (#1236) - Fixed
web_searchfreezing the session when an upstream provider stalled. Bun's WinHTTP backend on Windows can silently dropAbortSignalonce a TCP/TLS connection hangs (oven-sh/bun#15275, oven-sh/bun#18536), so Esc never reached the in-flight fetch and the only recovery was Ctrl+C +omp --resume. Every web-search provider's outboundfetch(anthropic, brave, codex, exa, gemini, jina, kagi, kimi, parallel, perplexity, searxng, synthetic, tavily, z.ai) now composes the caller signal with a 60s hard timeout via a sharedwithHardTimeouthelper, guaranteeing the request settles within a minute even when Bun's abort fails to propagate. Independently,executeSearch's provider-fallback loop was masking real cancellations as ordinary provider errors and returning "All web search providers failed"; it now re-throws asToolAbortErrorthe moment the caller's signal aborts, so the session sees a clean cancel on every platform. (#1221)
[15.1.8] - 2026-05-20
Fixed
- Fixed streaming edit previews for
apply_patchandhashlinejittering as the model typed+addedlines. Two root causes addressed: (1) the trailing partial line of the streaming text input is now trimmed at each tick so a half-typed+addedline no longer flickers; (2) the preview is rendered in the model's input order during streaming instead of re-deriving a unified diff viaDiff.structuredPatch, whose coalescing previously reshuffled existing+addedlines downward each time a new-removedline arrived. Existing additions now stay put and the preview only grows at the bottom while streaming. A residual trailing-removed/hunk-header block whose matching+addedcompanion has not yet arrived is also suppressed until the additions land. - Fixed Perplexity web search appearing "logged out" roughly an hour after
omp auth login perplexity. The search provider'sfindOAuthTokenwas honoring the bogusexpires = login_time + 1hwritten by older logins (Perplexity JWTs typically omitexpbecause sessions are server-side) and silently dropping the credential. The loader now decodes the JWT'sexpclaim directly and only skips when the JWT itself is expired; tokens without anexpclaim are treated as non-expiring.
[15.1.7] - 2026-05-19
Fixed
- Fixed
debuglaunch/attach failures soconfigurationDoneno longer masks the underlying DAP launch error, early stop-outcome watchers cannot emit unhandled rejections, and directory-valued launch programs are rejected before adapter selection. (#1187) - Fixed hashline edit payloads that use a readability space after
~by warning on separator-padding-shaped payload blocks and tightening the model prompt. (#1166) - Fixed ACP bash permission requests to include execute tool metadata and command content so clients can render command approval prompts consistently. (#1189)
- Fixed the status-line fast-mode indicator (
⚡) rendering for scoped service tiers (openai-only,claude-only) even when the active model's provider didn't realize them — e.g.serviceTier: "openai-only"would still show the indicator next to a Claude model the wire request couldn't apply fast mode to. The indicator now consults a newAgentSession.isFastModeActive()predicate that runs the configured tier throughresolveServiceTier(tier, model.provider)and only lights up when the result is"priority"for the current model.isFastModeEnabled()keeps its scope-aware semantics so/fast on|off|toggleand/fast statuscontinue to reflect the user's configured intent.
Added
- Added scoped service tier values to the
serviceTiersetting:priority (OpenAI only)andpriority (Claude only). They let you opt into premium processing on one provider family without paying premium costs on the other when switching models mid-session./fast oncontinues to set the unscoped"priority"(active everywhere supported);/fast statusandisFastModeEnabled()now reportonfor any scoped value too.
Changed
- Changed
/fastto be a single provider-agnostic toggle: enabling the command setsserviceTier: "priority"for every provider, and the anthropic-messages provider translatespriorityintospeed: "fast"plus thefast-mode-2026-02-01beta. Anthropic fast mode is currently supported on Claude Opus 4.6 and 4.7; the server rejects other models, which triggers the provider's auto-fallback (request retried without the priority signal,providerSessionState.fastModeDisabledpersisted for the rest of the session). The session listens for the"priority"marker inAssistantMessage.disabledFeatures, syncs/fastoff, and emits a warning notice. Re-running/fast onclears the per-session disable so the next request actually re-tries priority.
[15.1.6] - 2026-05-19
Fixed
- Fixed plan-mode
resolvelooping when grammar-constrained models (e.g. Qwen3.6-35B-MTP via llama.cpp) emitextra: { title: {} }instead of a string — the openRecord<string, unknown>schema forextralets such models drop in an empty object, and the apply guard then hard-threw on every retry. Plan approval now derives the title fromextra.titlewhen usable, falling back to the plan's first# Heading, then the plan filename stem (local://PLAN.md→PLAN), then the literal"plan". Prompt language relaxed from "MUST" to "SHOULD" forextra.title. (#1179)
[15.1.5] - 2026-05-19
Fixed
- Fixed
ast_grepandast_edittool details retaining every per-file parse error — a scan over hundreds of files with syntax-error nodes inflateddetails.parseErrorsto one entry per file, leaking into traces and the renderer's "X more" overflow. Errors are now capped atPARSE_ERRORS_LIMIT(20) at the source, with the original total preserved in a newparseErrorsTotalfield for accurate count labels.
[15.1.4] - 2026-05-19
Fixed
- Fixed
normalizePlanTitlerejecting plan titles that contain spaces or common punctuation (e.g. "My Feature Plan") — spaces are now converted to hyphens and other invalid characters are dropped, so models that produce natural-language plan titles no longer loop forever trying to callresolve. (#1176) - Fixed
asktool prompt example showing the legacyquestion/optionstop-level format instead of the currentquestions: [{id, question, options}]array format; models that closely followed the example generated calls that always failed schema validation. (#1176) - Fixed ACP command and custom tool-call notifications to carry the original tool arguments in replayed and final updates, so command text is preserved and raw input is no longer wrapped
- Fixed ACP async-job draining to be scoped by session owner so
getAsyncJobSnapshotanddrainAsyncJobDeliveriesForAcpno longer consume or expose jobs from other sessions - Fixed async job status reporting to include in-flight completions so queued/delivering indicators remain accurate while callbacks are still running
- Fixed
deferAgentInitiatedTurnshandling during ACP async-job draining so background completion follow-up turns are delivered even when agent-initiated turns are deferred - Fixed ACP ordinary file-editing calls (
edit,write,ast_edit) incorrectly requestingsession/request_permissionbefore every call, while keeping permission prompts for edit operations that delete or move files; permission requests now report the gated tool call aspendingso clients can render the approval UI instead of returningPermission request cancelledwithout a visible prompt. (#1134 by @jiwangyihao) - Fixed the session tree selector to preserve a readable message column when deeply nested branch gutters would otherwise consume the viewport. (#1144)
[15.1.3] - 2026-05-17
Breaking Changes
- Renamed the embedded-documentation internal URL scheme from
pi://toomp://.OmpProtocolHandlerreplacesPiProtocolHandler; update any external references accordingly. - Removed the
StringEnumre-export from@oh-my-pi/pi-coding-agent. Custom tools and extensions should usez.enum([...])directly via the injectedpi.zod. - Replaced the
evaltool's LARK-grammarinputstring with a structuredcellsarray. Each cell is{ language: "py" | "js", code, title?, timeout?, reset? }. Removed the implicit/sniffed language path, the*** Cell/*** End/*** Abortmarkers, and the per-cellt:<duration>unit suffixes —timeoutis now seconds (1-600).
Added
- Added
providers.<name>.transport: "pi-native"tomodels.yml. When set, every model under that provider routes its streaming dispatch through the auth-gateway'sPOST /v1/pi/streamendpoint instead of the per-provider SDK. The provider'sbaseUrlmust point at a compatibleomp auth-gatewayandapiKeymust carry the gateway bearer. The slot'smodels.jsonstill resolves locally for pricing/capabilities/thinking config; only the wire dispatch is redirected. Use case: containerized omp installs (robomp slots, swarm extension) where the slot must stay credential-free and a sidecar gateway holds the real provider tokens. Also surfaced astransportonProviderConfigInputfor extension-registered providers. - Added optional backend push for the auto-QA grievance database (
dev.autoqaPush.enabled,dev.autoqaPush.endpoint,dev.autoqaPush.token; env overridesPI_AUTO_QA_PUSH,PI_AUTO_QA_PUSH_URL,PI_AUTO_QA_PUSH_TOKEN). When enabled, everyreport_tool_issuecall schedules a background flush thatPOSTs pending rows to the configured endpoint and deletes them on HTTP 2xx. Each push carries a stable per-install UUID (installId) generated on first use and persisted at~/.omp/install-idviagetInstallId()(new export from@oh-my-pi/pi-utils), so the receiver can dedup retries across host renames andautoqa.dbwipes. Single-flight, 5s request timeout, 30s in-memory cooldown after failure, and a row-id watermark so rows inserted during an in-flight push survive and ship next time. Tool execution remains non-blocking and never throws. ModelRegistrynow promotesmodels.ymlproviders.<name>.apiKeyentries toAuthStorage's new config-override tier (above OAuth, below--api-key). Pinning a bearer inmodels.ymlwas previously a no-op when the broker had an OAuth credential for the same provider — the OAuth access token won and got sent unmodified to whateverbaseUrlyou redirected to, which an auth-gateway in front of that endpoint rightly rejected with 401. The override is now honored, and is cleared/repopulated atomically onmodels.ymlreload (#reloadStaticModelscallsclearConfigApiKeysbefore re-parsing). Use case: routeanthropic/openai-codextohttp://llm-gateway.internal:4000with the gateway's own bearer.- Added
omp auth-brokersubcommand for running and consuming a hosted credential vault. serve [--bind=host:port]— boots a local broker against the SQLite store at$AGENT_DB_PATH.token [--regenerate]— prints (and rotates) the bearer token stored at~/.omp/auth-broker.token.login <provider> [--via=user@host] [--dry-run]— drives the OAuth flow locally or via SSH-Ltunnel into a remote broker (callback ports pinned per provider).logout <provider>— disables every credential for the given provider in the local SQLite store.import <file|dir> [--provider=<id>] [--include-disabled] [--dry-run]— imports CLIProxyAPI-style JSON credential dumps (~/.cliproxy/auth/*.json). WhenOMP_AUTH_BROKER_URLis configured, credentials are uploaded to the remote broker viaPOST /v1/credential; otherwise they go into the local SQLite store. JSONtypeis mapped to omp providers (claude→anthropic,codex→openai-codex,gemini[-cli]→google-gemini-cli,antigravity→google-antigravity);--provideroverrides the mapping for unrecognized types.status— pings the configured remote broker (OMP_AUTH_BROKER_URL).- Added remote credential vault support to
discoverAuthStorage. Configure via env (OMP_AUTH_BROKER_URL/OMP_AUTH_BROKER_TOKEN) or by settingauth.broker.urlandauth.broker.tokenin~/.omp/agent/config.yml(hidden from the settings UI; supports!commandresolution). Falls back to~/.omp/auth-broker.tokenwhen no token is provided inline. Otherwise behavior is unchanged. - Added
omp auth-broker migrate --from-local [--include-env] [--include-oauth] [--dry-run]— uploads local SQLite credentials (and optionally env-var API keys) to the configured broker. Skips anything already on the broker via identity-key matching. OAuth is skipped by default (handled viacliproxyimport). Idempotent on re-runs. - Added
omp auth-gatewaysubcommand for running a forward-proxy that hides access tokens from less-trusted clients: serve [--bind=…]— boots the gateway against the configured broker. Listens on127.0.0.1:4000by default.token [--regenerate]— manages the gateway bearer token at~/.omp/auth-gateway.token(separate from the broker bearer).status— verifies gateway config and authenticated broker readiness.- One wire surface:
POST /v1/chat/completions(OpenAI chat-completions),POST /v1/messages(Anthropic messages),POST /v1/responses(OpenAI Responses),GET /v1/usage(aggregated, 5-min per-credential cache),GET /v1/models(catalog). Model id in the request body selects which omp provider/model services it; the gateway translates wire format ↔ omp canonicalContextand dispatches throughpi-aistreamSimple(). Container deployments (robomp, etc.) get inference auth without ever holding access tokens or the broker bearer.
Changed
- Changed TTSR
interruptModesemantics so a non-interrupting decision on a tool-source match now folds the rule reminder into that specific tool'stoolResultcontent instead of queuing a loop-wide deferred follow-up turn. Text/thinking matches keep the previous deferred-injection behavior.
Fixed
- Fixed streaming API requests to recover from provider auth errors by invalidating stale credentials and retrying with a fresh key
- Fixed
auth-brokermigration,auth-gatewaystartup, anddiscoverAuthStorageto fail fast with a clear error when the broker snapshot endpoint returns a non-200 response - Fixed
omp auth-broker migrateto skip local placeholder<authenticated>API credentials (not real keys) when exporting to a remote broker - Fixed
auth-gatewaytoken initialization to avoid clobbering an existing token when multiple processes initialize it concurrently - Fixed
omp auth-gatewayrequest handling to reject unsupported OpenAI/Anthropic protocol controls with 400 instead of accepting and ignoring them, propagate upstream error/abort terminal states as failures, preserve Responses reasoning and completed text items, accept string/system Responses messages, and keep Anthropic tool-result ordering valid. - Fixed gateway usage reporting to include cached-token totals for OpenAI Chat/Responses and to serve the last good cached report during transient upstream usage fetch failures.
- Fixed auth-gateway request cancellation for requests that are already aborted before dispatch.
- Fixed
/loginand/logoutprovider selector overflowing tall provider lists off-screen on small terminals. The selector now scrolls a 10-item window centered on the highlighted entry, shows a(n/total)indicator when windowed, and accepts PageUp/PageDown for faster navigation.
[15.1.2] - 2026-05-15
Fixed
- Fixed SSH host additions/removals made inside a running session not refreshing the live
sshtool./ssh addand/ssh removenow update the model-visible host list immediately, while/reload-pluginsand/moverefresh SSH discovery for external or project-scope config changes without restart. - Fixed loose object output schemas in
YieldToolso non-strict schemas (for exampleadditionalProperties: true) are preserved and accepted instead of being forced into strict mode - Fixed unconstrained output schema modes (
outputSchema: trueor absent/non-strict schemas) to run in loose mode for successful results - Fixed bash tool calls with
pty: truehanging indefinitely on Windows by falling back to the non-PTY executor instead of entering the ConPTY-backed interactive path. (#1103)
Changed
- Updated MCP and theme schema metadata to reference JSON Schema draft-2020-12
[15.1.0] - 2026-05-15
Breaking Changes
- Changed the extension and hook runtime API by moving schema typing from direct TypeBox imports to
TSchemafrom@oh-my-pi/pi-ai, requiring callers who use TypeScript imports ofTypeto migrate via provided injected modules
Added
- Added a cancellable handoff progress indicator in
/handoffthat displays while handoff generation runs and can be aborted withEsc - Added
apiKeyas a supported provider override field in model config, allowing API-key-only overrides to provide fallback credentials for built-in models - Added
supportsMultipleSystemMessages,allowsSyntheticReasoningContentForToolCalls,disableReasoningOnToolChoice, andlevelsmodel-thinking compatibility fields to model configuration schemas - Added
zodto the Extension, Custom Tool, Hook, and Custom Command APIs aspi.zodso extension and plugin authors can define tool schemas with Zod without separate imports - Added
pi.zodas a canonical schema API for examples and extension plugins while keepingtypeboxavailable as legacy compatibility - Added a
telemetryoption tocreateAgentSessionfor passing OpenTelemetry configuration through to the underlying Agent
Changed
- Changed handoff generation to run as a one-shot handoff request and switch to the new session only after it completes, avoiding an extra assistant handoff turn in chat history
- Changed
pi.typebox.Type.Compositeto merge all object schemas in the provided list, enabling more than two object inputs - Changed
pi.typebox.Type.Recordto validate record keys against the provided key schema instead of forcing string keys - Changed
pi.typebox.Type.ArraywithuniqueItems: trueto reject duplicate items while preserving the constraint in wire schemas - Changed
pi.typebox.Type.ObjectwithadditionalProperties: falseto reject unknown properties during parsing - Changed
pi.typebox.Type.Enumin the compatibility shim to preserve numeric TypeScript enum values - Changed tool parameter schemas across the agent to use the shared Pi schema pipeline (
TSchemaplus Zod/JSON Schema validation) instead of direct AJV/TypeBox compilation for stricter schema validation compatibility - Changed GitHub tool input schema shape to expose operation fields in a flat schema form without legacy
run_watch-style nesting - Changed Python session pooling to remove the previous 4-session retention cap and 5-minute idle-session eviction, so kernels now stay alive for a session until explicitly disposed via
disposeKernelSessionsByOwnerordisposeAllKernelSessions - Changed kernel cleanup behavior to avoid automatic eviction by idle timeout and capacity pressure, so additional Python sessions are not queued behind retained-session shutdown retries
- Replaced the bundled
@sinclair/typeboxruntime dependency with an in-repo Zod-backed shim exposed throughpi.typebox.Type.*. Common builders (Object,String,Number,Integer,Boolean,Array,Tuple,Union,Intersect,Literal,Enum,Optional,Nullable,Record,Partial,Required,Pick,Omit,Composite, …) keep their existing call signatures but now return Zod schemas that flow through the same validation/wire pipeline aspi.zod. Bare@sinclair/typeboximports inside extensions are transparently remapped to the same shim by the runtime plugin shim, so plugins that authored againstimport { Type } from "@sinclair/typebox"keep working unchanged. Plugins that relied on TypeBox-only submodule APIs (@sinclair/typebox/compiler,@sinclair/typebox/value,TypeRegistry, theSymbol(TypeBox.Kind)marker) must vendor@sinclair/typeboxin their own package — only the root import is remapped.
Deprecated
- Deprecated direct TypeBox-only examples for plugin schemas by updating example documentation to prefer
pi.zod
Fixed
- Fixed auto-triggered handoff flow to perform only a single handoff-generation model call instead of an extra prompt cycle
- Fixed handoff cancellation behavior so a pre-cancelled signal returns
Handoff cancelledwithout starting generation and aborting handoff now propagates through the handoff request signal - Fixed
create_conventional_analysisparsing to ignore harmless extra fields and still parse the required conventional fields - Fixed BashTool async request validation flow so async execution remains disabled and returns the explicit
Async bash execution is disablederror - Fixed
task.simpleinvalidschemaandcontextargument handling to still reject unsupported fields after tool-argument validation - Fixed subagent execution hangs by enforcing
task.maxRuntimeMsas a wall-clock limit even when inference streaming stalls, so stuck subagents now abort and report runtime-limit exceeded - Fixed tool schema compatibility validation by routing TypeBox schemas through shared conversion and Zod-based validation to avoid strict-schema provider mismatches
- Fixed Python execution cancellation and timeouts by escalating to kernel shutdown if
SIGINTdid not terminate a running cell within 2 seconds, preventing indefinite hangs in queued or stuck sessions - Fixed cleanup blocking during long-running executions by forcing a kernel shutdown path when interrupt-based cancellation is ignored
- Fixed bash output emitting a spurious
[… 0 lines elided (NB) …]marker (and reordering the artifact link before the command output) when the shell minimizer rewrote a small command's output. AfterOutputSink.replace()swapped the minimized text into the buffer, the subsequentsink.push("[raw output: artifact://N]\n")chunk was funneled back into the (now empty) head-retention window while the pre-replace#totalBytesstill tracked the original raw stream — sodump()composed<head=artifact-link> + <middle-elision marker against stale totals> + <tail=minimized text>instead of<minimized text> + <artifact link>.replace()now realigns#totalBytes/#totalLines/#sawData/#truncatedto the authoritative buffer and disables head retention for the lifetime of the sink, so further pushes append to the tail buffer in order. The bash executor also drops the leading\non the artifact-link push when the minimized text already ends with one so the separator stays single-newline. - Fixed legacy plugin extensions failing to load on Windows when they import a bare-specifier dependency from their own
node_modules(e.g.import YAML from "yaml"insupipowers). The legacy-pi mirror resolved the dependency to its absolute path and then ran the path throughisUrlLikeSpecifier, whose^[A-Za-z][A-Za-z\d+.-]*:regex matched the Windows drive letter (C:) and short-circuited thepathToFileURLconversion. The raw path was emitted into the mirrored TS source asimport x from "C:\\Users\\...\\dep\\dist\\index.js", where\n,\U,\yand other backslash sequences were eaten by the TS string-literal parser, producing nonsense package specifiers likeC:Usersjames.ompagentextensionssupipowers\node_modulesyamldistindex.jsthat Bun's resolver rejected withCannot find package ….isUrlLikeSpecifiernow rejects^[A-Za-z]:[\\/]first, so Windows absolute paths flow throughpathToFileURLlike every other absolute path and reach the mirror as properfile:///C:/...URLs. - Fixed Python session queued executions silently resurrecting kernels after
disposeAllKernelSessionsordisposeKernelSessionsByOwnerremoved the session: queued work now checks the session is still registered before replacing or executing on a kernel and rejects with cancellation otherwise - Fixed Python session disposal treating an unconfirmed
PythonKernel.shutdown()result as success: sessions whose kernel shutdown returns{ confirmed: false }(or rejects) are now retained in the registry and awarnis logged so a later dispose can retry instead of orphaning the subprocess - Fixed
task.maxRuntimeMslosing wall-clock aborts that fired during pre-prompt session setup by re-checking the abort signal immediately before issuing the model prompt, so a stalled subagent now exits with the runtime-limit reason instead of hanging through setup races - Fixed late
yieldevents landing after a wall-clock timeout from flipping a timed-out subagent to a successful exit, so the reportedabortedflag and exit code now always reflect the runtime-limit breach while yield payloads remain inextractedToolData - Fixed async-task progress consumer to copy
contextTokensandcontextWindowfrom the completedSingleResultontoAgentProgress, so UI gauges keep showing per-turn context after a backgrounded task finishes - Fixed the status-line
pathsegment ignoringstripWorkPrefix: falsewhen selecting the folder icon for scratch directories. The icon selection now respects the same gate as the scratch path stripping, so disablingstripWorkPrefixkeeps the regularfoldericon even when the project directory is inside a scratch root. - Fixed
YieldToolconstructor to fall back to the loose record schema when the sessionoutputSchemacontains unresolved$refstrings (e.g. external or cyclic references that survive dereferencing), instead of installing a validator that would reject every payload with an unresolved-reference error - Fixed
pi.typebox.Type.StringdroppingminLength/maxLength/patternconstraints when aformat(e.g.email,url,uuid) was also supplied; length and pattern checks are now applied to the format-specific schema instead of being gated on aninstanceof z.ZodStringcheck that never matched the format subclasses. - Fixed
pi.typebox.Type.Objectstripping unknown properties when constructed without explicitadditionalProperties. TypeBox preserves extras by default, so the shim now installs.loose()for the omitted/truecases while keeping.strict()foradditionalProperties: falseand.catchall(schema)for a schema value.
[15.0.2] - 2026-05-15
Added
- Added the
set_host_uri_schemesRPC command so hosts can register and replace writable/read-only internal URI schemes with scheme metadata (writable,immutable) at runtime - Enabled the
writetool to dispatchwrite(url, content)to registered internal URL handlers, allowing edits to non-filesystem resources via host-managed URI schemes - Added host-owned internal URI read/write over RPC, including abort support, so URI operations are resolved by the host transport for
readandwriterequests - Added handling of host URI request results in RPC mode so host services can stream completion frames for internal URI operations
- Added scratch-directory awareness to the status-line
pathsegment. When the project directory is inside an OS-level scratch root (the platformos.tmpdir(),/tmpand/var/tmpplus their macOS/private/...aliases,~/tmp, or — on Windows —%TEMP%/%TMP%/%SystemRoot%\Temp), the segment now (1) renders the newicon.scratchFoldersymbol instead oficon.folder, and (2) strips the scratch root from the displayed path so only the trailing folder (and any subpath beneath it) is shown — mirroring how/workand~/Projectsare already abbreviated. Both behaviors honor the existingstripWorkPrefixoption. Icon defaults: 🗑 (emoji), `` (nf-fa-trash) for Nerd Font,[T]for ASCII,◌in the poimandres themes; themes can overrideicon.scratchFolderindependently oficon.folder.
Changed
- Changed the
githubtool's search ops (search_issues,search_prs,search_code,search_commits) to default thereposcope to the current checkout'sowner/repowhenrepois omitted. The auto-scope is skipped when the query already carries an explicitrepo:/org:/user:/owner:qualifier or whengh repo viewcannot resolve a github remote (in which case the search proceeds across all of GitHub as before).search_reposis unchanged — repository-scoping there must live in the query. - Changed bash command preprocessing to strip trailing
| headand| tailpipelines (including|&) from each top-level segment in command chains separated by;,&&,||, or& - Changed bash fixup notices to state that stderr is already merged into stdout and to reflect that fixes were applied for multiple stripped segments when several transforms fire
- Changed shell-minimizer per-line truncation marker from a bare
…to…[+N], whereNis the count of dropped Unicode scalars. The bracketed tally disambiguates minimizer-driven cuts from genuine…characters in the source (paths, JSON, stack traces, etc.) and gives the agent an exact count so it can decide whether the missing tail is recoverable inline or warrants reading the[raw output: artifact://<id>]footer the bash wrapper already emits when the minimizer rewrites output. Affects pipeline Stage 5 (truncate_lines_atindefs/*.toml) and the internal callers infilters/git.rs,filters/listing.rs, andfilters/lint.rs. (#1046) - Changed bash command preprocessing to use the real
brush-parserAST viapi-nativesapplyBashFixupsinstead of a hand-rolled top-level mask scanner. The previous regex/character-walking implementation reimplemented quote/heredoc/$(...)tracking with conservative bail-outs (notably refusing to fixup commands containing here-strings); the AST-driven version inherits the full shell parser, so semantics-preserving rewrites like stripping| head -5offcat <<<'content' | head -5now succeed instead of being skipped. No public API change —applyBashFixups(command)returns the same{ command, stripped }shape.
Fixed
- Fixed bash command fixups to remove a redundant standalone trailing
2>&1redirect when no other pipe or redirection remains - Fixed command-fixup notices to list all stripped segments instead of reporting only one
- Fixed summarized
readoutput stalling agents on elided regions by appending an explicit footer like[NN lines across MM elided regions; read <path>:raw or a line range like <path>:1-9999 for verbatim content]. The footer fires whenever the structural summarizer elided at least one span, so the model gets a concrete recovery selector instead of having to guess from a bare.../{ .. }marker. SurfaceselidedLinesonReadToolDetails.summaryalongside the existingelidedSpans. (#1046) - Updated the
readtool prompt to describe the new elision footer and instruct the model to follow:raw(or an explicit line range) when the elided body is actually needed, rather than guessing. - Fixed plugin extensions failing to load when their
peerDependenciesreference internalpi-*packages under any scope other than@mariozechner(e.g.Cannot find module '@earendil-works/pi-tui'from@juicesharp/rpiv-ask-user-question, orCannot find module '@oh-my-pi/pi-utils'from@oh-my-pi/swarm-extension). The legacy-pi specifier shim now treats@mariozechner,@earendil-works, and the canonical@oh-my-piitself as aliases for the same set of bundled in-process packages (pi-agent-core,pi-ai,pi-coding-agent,pi-natives,pi-tui,pi-utils), and additionally rewrites the upstream-onlypi-ai/oauthsubpath onto ourpi-ai/utils/oauthlayout. Restored theKeyruntime helper export on@oh-my-pi/pi-tuito match upstream — plugins usingKey.enter/Key.ctrl("c")(e.g.@plannotator/pi-extension,@juicesharp/rpiv-ask-user-question) no longer fail withExport named 'Key' not found. End-to-end verified against@juicesharp/rpiv-ask-user-question,@oh-my-pi/swarm-extension, and@plannotator/pi-extension— each now loads cleanly with all of its tools/commands/handlers registered. Plugins importing any of those scopes are remapped to the omp binary's own copy at load time, so peer deps are no longer dragged in from npm and there is exactly one module instance per package regardless of which scope name the plugin's manifest happened to declare. - Fixed
omp commithanging after a successful commit instead of returning to the shell. The command now mirrors therunPrintModeexit pattern and callspostmortem.quit(0)once the pipeline resolves so lingering HTTP/2 keep-alive sockets, the Settings autosave timer, and other AgentSession background handles don't keep the event loop pinned. (#1041) - Fixed hashline payload parsing to silently treat truly-blank lines as empty
~-prefixed payload lines when more payload follows in the same run. The previous behavior broke at the blank ("payload line has no preceding +, <, or = operation.") even though the intent is obvious — the only ambiguity is between in-payload blanks and end-of-section blanks, and a one-line lookahead resolves it: blanks that precede a non-payload op still end the run cleanly as section separators. Recovers the common case of forgetting the leading separator on a blank inserted line without changing how trailing blanks between ops behave. - Rewrote the hashline edit prompt examples to use an ASCII-only
TITLE = "Mr"→"Mrs"/"Dr"motif instead of the previous" • "and"·"separators. Some agents had been copying the middle-dot literal characters into real edits as if they were format scaffolding (e.g. emitting payload lines like~ ·), since the demo inserts were near-twins of the existing string. The new example keeps every original op shape (single-line replace, multiline replace, insert AFTER/BEFORE, append, delete, blank, plus both anti-patterns) but uses content that is obviously domain-specific and clearly distinct from any payload separator. Pure prompt change; no parser, schema, or runtime behavior is affected. - Fixed startup fallback-chain validation to recognize cached runtime-discovered standard provider models, including Ollama Cloud models listed by
--list-models, soretry.fallbackChainsno longer warns that validollama-cloud/<model>selectors are unknown. (#1052) - Fixed
discoverAgents()ignoringdisabledProvidersfor theclaude-pluginsprovider. Plugin roots from~/.claude/plugins/were scanned unconditionally, so agents from Claude Code marketplace plugins continued to appear in/agentsand the Agent Control Center even whendisabledProviders: [claude-plugins]was set. The discovery path now checksisProviderEnabled("claude-plugins")before callinglistClaudePluginRoots(), matching how every other capability respects the disabled-providers set. (#1075) - Fixed
$env:VARPowerShell variables being mangled on Windows when commands invoked PowerShell as a subprocess (e.g.powershell -Command "Write-Host $env:SystemRoot"). Brush-core applied POSIX parameter expansion to$envbefore spawning the child, leaving a dangling:NAME. The fix lives inpi-shellat env-var application time: every brush session now definesenv=$envas an internal shell variable so$env:NAMEexpands to the literal$env:NAMEtoken that PowerShell expects. The fallback is not exported, only influences brush's own expansion, and is shadowed by any user assignment toenv(e.g.env=prod; echo "$env:8080"still printsprod:8080), so the POSIX bash contract is preserved. (#1079)
[15.0.1] - 2026-05-14
Breaking Changes
- Removed the dedicated
exit_plan_modetool and its prompt, requiring plan-mode completion to use the existingresolvetool path instead
Added
- Added optional
extrametadata object to theresolvetool so callers can pass context-specific payloads, including plan approval titles - Added
hide: truefrontmatter option for skillSKILL.mdfiles. Hidden skills are still loaded and remain reachable viaskill://<name>URLs and (when enabled)/skill:<name>slash commands, but are omitted from the rendered system prompt's<skills>listing so the model won't auto-discover them. Use for skills the user opts into explicitly rather than ones the model should pick up from descriptions. - Added middle elision for streaming tool outputs (bash, ssh, python, js eval) and post-execution tool result spill. When
tools.artifactHeadBytesis set (default 20 KB), large outputs now keep both the first N KB and the last N KB with an inline[… N lines elided (M KB) …]marker between them, instead of dropping everything before the trailing tail. Settingtools.artifactHeadBytes = 0reverts to the previous tail-only behavior. The full output is still mirrored to the session artifact (artifact://<id>) regardless of elision mode. ExposestruncateMiddleandformatMiddleElisionMarkerfrom@oh-my-pi/pi-coding-agent/session/streaming-output, extendsOutputSinkOptionswithheadBytes, and addsdirection: "middle"plusheadRange/tailRange/elidedLines/elidedBytestoTruncationMeta. - Added per-line column cap shared across streaming tool outputs (
bash,ssh,python,js eval) and thereadtool. Lines wider thantools.outputMaxColumnsbytes (default 768) are ellipsis-truncated at write time and remaining bytes up to the next\nare dropped — bounded memory even on multi-MB single-line outputs (e.g.cat /dev/urandom). The cap lives onOutputSinkas the newmaxColumnsoption, persists state across chunk boundaries so split-mid-line writes still respect the budget, and exposescolumnDroppedBytes/columnTruncatedLinesonOutputSummary. Middle-elision byte math subtracts column drops so the "elided from middle" count stays honest.readreuses the same setting but trims its already-collected lines viatruncateLine. Skipped when the read selector is:raw. The artifact file (artifact://<id>) keeps the full uncapped stream. Settools.outputMaxColumns = 0to disable. - Added Bun HTTP/2 fetch opt-in. Dev scripts (
bun run dev,bun run stats) now passbun --experimental-http2-fetchso everyfetch()advertisesh2in the TLS ALPN list and falls back to HTTP/1.1 when the server doesn't select it. Multiplexing collapses parallel requests to the same origin onto one TLS connection. For the installedompbinary, exportBUN_FEATURE_FLAG_EXPERIMENTAL_HTTP2_CLIENT=1in your shell to enable the same behavior (the flag has to be set before Bun starts;process.envfrom inside JS is too late). Requires Bun 1.3.14. - Added per-subagent cost display (
$X.XXin the task progress tree and the session-observer stats line). Cost is accumulated incrementally frommessage_endevents and shown only when non-zero, using thestatusLineCosttheme color. Providers that do not report per-turn cost data (e.g. subscription/OAuth usage) continue to show nothing.
Changed
- Changed plan-mode completion to use
resolve { action: "apply", reason, extra: { title } }to request plan approval rather than callingexit_plan_mode - Changed resolve pending-action previews to trim and truncate long
reasontext for cleaner status-line rendering - Raised the image downscaling default JPEG quality from 75 to 80 in
resizeImageoutput generation - Changed image resize metadata notes from coordinate-scale hints to a simple
Image resized from <original> to <displayed>message and hide the note when the resized dimensions are unchanged - Removed
utils/image-convert.tsand itsconvertToPnghelper; callers now inlinenew Bun.Image(bytes).png().toBase64()fromBun.Image(Bun 1.3.14+). - Changed image decode/resize/encode in
utils/image-resize.tsfrom the nativePhotonImagebinding toBun.Image. Same PNG/JPEG/WebP quality+dimension ladder, but pipelines run off-thread on Bun's statically-linked codecs with no native-addon round-trip. Bumped the minimum Bun runtime requirement to 1.3.14. - Changed
searchpagination in multi-file scopes soskipnow skips entire files and pages results in groups of up to 20 files, with output guiding the nextskipvalue viaShowing files X-Y of N - Changed multi-file search result selection to cap each file at 20 matches and round-robin across files, so one noisy file no longer suppresses visibility of hits in other files and truncation now reports per-file limits
- Changed search truncation metadata/renderer output from match/result-based limits to file-based limits (
fileLimitReached,perFileLimitReached) and updated truncation labels accordingly - Lowered
read.defaultLimitdefault from500to300lines, and split the per-range context padding into asymmetricRANGE_LEADING_CONTEXT_LINES = 1/RANGE_TRAILING_CONTEXT_LINES = 3(was symmetricRANGE_CONTEXT_LINES = 3). Replay analysis over post-summarizer sessions (scripts/session-stats/optimize_read_config.py) showed that bare-path reads are over-provisioned at the median (file p50 = 220 lines) and that most follow-up reads are disjoint hops rather than adjacent extensions — so a smaller default plus narrower leading context reclaims tokens without measurably changing first-cover rate. Trailing context stays at 3 lines to keep anchor-stale recovery on narrow reads. Explicitread.defaultLimitoverrides in settings are honoured unchanged.
Fixed
- Fixed abrupt process termination data loss during session persistence by moving steady-state session writes to a synchronous path that writes each entry to the kernel page cache before returning
- Fixed
--helpstartup to avoid a config/model-registry load cycle so the root CLI help command now exits successfully in a clean environment - Queued
/skill:<name> [args]invocations now show as compactSteer: /skill:<name> [args]/Follow-up: /skill:<name> [args]chips in the pending-messages bar and disappear when the agent consumes the queued message (parity with plain-text steer/follow-up). Previously the queued skill was invisible while queued and rendered as a full skill block at consumption with no chip ever appearing. - Plan-mode "Approve and compact context" no longer surfaces a red "Operation aborted" line on the plan-mode assistant message; the silent transition into compaction now renders cleanly on both live and replay paths. Real user-cancel aborts on unrelated turns and the existing "Compaction cancelled" path are unchanged.
- Auto-recover conflict-resolution
write/readpaths that the agent malformed as<file>:conflict://<N>(or<file>:conflict://*) by mixing the:conflictsread selector with theconflict://scheme. The stripped<file>:prefix is stored onParsedConflictUri.recoveredPrefixand, for writes, surfaces as a trailing note in the result text so the agent learns the correct shape. Cleanconflict://…URIs are unchanged. - Fixed hashline edit renderer leaving a stray
@in the displayed file path when the agent emitted a canonical@@ PATHheader (or any@-run longer than one). Titles likeEdit: @ packages/foo.tsnow render asEdit: packages/foo.ts, matching the actual parser inhashline/input.tswhich already strips every leading@before resolving the path. Purely cosmetic — the edit itself was always routed to the correct file. - Fixed model contextWindow and maxTokens defaulting to
UNK_CONTEXT_WINDOW(222222) /UNK_MAX_TOKENS(8888) when cached or freshly-discovered provider models replace bundled models throughModelRegistry.#mergeResolvedModels. The merge now preserves the bundled model's values when the replacement only has sentinel fallbacks. - Fixed headless
browser.opentab startup on slow Chromium target enumeration by making worker-side stealth user-agent target setup selective, bounded, and best-effort for non-active targets. Worker startup errors are now surfaced directly instead of degrading into the generic tab worker initialization timeout. - Fixed token display for sessions and subagents inflating far beyond the context window.
token_totalstatus-line segment and the subagent overlay token counter now showinput + output + cacheWriteinstead ofinput + output + cacheRead + cacheWrite. With prompt caching,cacheReadper turn equals the full cached context — summing it across all turns produces a cumulative total that is N×context_size (e.g. a 5-turn session with a 1 M-token context reported ~5 M tokens). Cache activity is still visible via the dedicatedcache_read/cache_writestatus-line segments; billing cost is unaffected. - Fixed ACP clients missing
config_option_updatenotifications when the thinking level changed via any path other than the client's ownsession/set_session_config_optioncall (slash commands, model auto-adjust, extension UI).AgentSessionnow emits athinking_level_changedevent fromsetThinkingLevel, andAcpAgentsubscribes to each managed session for the session's lifetime and pushes a freshconfig_option_updatewhenever the effective level changes — independent of any active prompt turn. The subscription is installed inside#scheduleBootstrapUpdates's 50 ms timer so it shares the same race guard that prevents Zed'sReceived session notification for unknown sessiondrop when notifications fire beforesession/new(or fork) returns; the pre-bootstrap thinking level is reported in the response'sconfigOptions. Thesession/set_session_config_optionhandler keeps its own push only when the subscription has not yet been installed, so client-driven thinking changes still notify pre-bootstrap, post-bootstrap they flow through the subscription exactly once. Subscriptions are released in#disposeSessionRecord. - Fixed MCP OAuth refresh failing with
HTTP 401 invalid_clientfor servers that require Dynamic Client Registration (RFC 7591) and have nooauth.clientIdconfigured (e.g.mcp.linear.app).MCPOAuthFlowregistered a fresh public PKCE client on each authorize and discarded the issuedclient_idonce the flow object went out of scope; refresh then called the provider's/tokenendpoint without aclient_id. The flow now exposesresolvedClientId/registeredClientSecretgetters,MCPCommandController#handleOAuthFlowreturns them alongsidecredentialId, and both the initial-connect and/mcp reauthpaths persist them intoauth.{clientId,clientSecret}(used at refresh) andoauth.{clientId,clientSecret}(used by subsequent/mcp reauthto skip re-registration). TheMCPAddWizardonOAuthcallback type is nowPromise<MCPAddWizardOAuthResult>and#launchOAuthFlowfolds the registered credentials into wizard state. Servers with a statically-configuredoauth.clientId(Notion, Slack, Datadog) are unaffected —#tryRegisterClientshort-circuits and the write-back is a no-op. (#1061 by @ldx).
[15.0.0] - 2026-05-13
Breaking Changes
- Removed
op: issue_viewandop: pr_viewfrom thegithubtool. Read single issues/PRs via thereadtool againstissue://<N>/pr://<N>(or the long formissue://<owner>/<repo>/<N>/pr://<owner>/<repo>/<N>); append?comments=0to drop the comments section. Theissueandcommentsparameters were removed from the tool schema since no remaining op consumes them. Mutating ops (pr_create,pr_checkout,pr_push),repo_view,search_*, andrun_watchare unchanged. - Removed
op: pr_diff(along with thenameOnlyandexcludeschema fields) from thegithubtool. Read PR diffs through the newpr://URL family:pr://<N>/difffor the changed-file listing,pr://<N>/diff/<i>for a single file slice (1-indexed), andpr://<N>/diff/allfor the verbatim unified diff. Long-formpr://<owner>/<repo>/<N>/diff[/…]works the same way. All three variants share onegh pr diffinvocation through a newpr-diffcache row, so the listing and per-file slices reconstruct from cached bytes without re-shelling. Diff content is served astext/plainso thereadtool's line selectors (e.g.pr://<N>/diff/all:200-400) page the cached output without falsely advertising hashline anchors. - Renamed ACP custom extension methods from
omp/*to_omp/*to comply with the ACP spec's_-prefix requirement for non-spec methods; existing callers must update method names
Added
- Added markdown rendering for
readresults when content type istext/markdown, so GitHub internal-URL outputs are shown as formatted markdown instead of plain code blocks - Added
pr://<N>/diff,pr://<N>/diff/<i>, andpr://<N>/diff/allinternal-URL shapes covering changed-file listings, per-file slices, and the full unified diff. They share onepr-diffSQLite cache row with the same TTL knobs aspr://<N>views (github.cache.softTtlSec/github.cache.hardTtlSec/github.cache.enabled). Single PR views now advertise the diff entry point via aDiff: pr://<owner>/<repo>/<N>/diffnote. Cache schema bumped touser_version = 3; older rows are dropped on first open to add credential-scoped keys and relax thekindCHECK constraint. - Added
issue:///pr://internal-URL schemes that share a SQLite-backed cache with the rest of thegithubtool. Single-item reads (issue://<N>,issue://<owner>/<repo>/<N>) return rendered markdown and withingithub.cache.softTtlSec(default 5 minutes) skip theghround-trip entirely; withingithub.cache.hardTtlSec(default 7 days) the cached row is returned and a background refresh is scheduled. Root and repo-scoped reads (issue://,pr://owner/repo) issue a livegh issue list/gh pr listfor browsing, supporting?state=open|closed|allfor issues,?state=open|closed|merged|allfor PRs, and?limit=,?author=,?label=query params. Rendered output lands in~/.omp/cache/github-cache.db(override viaOMP_GITHUB_CACHE_DB); disable the cache entirely withgithub.cache.enabled = false. Cwd→default-repo lookups (gh repo view) are memoized per-process. - Added new
Approve and compact contextchoice to the ExitPlanMode approval selector. Sits betweenApprove and execute(purge session) andApprove and keep context(full transcript) — runs/compacton the plan-mode transcript with a planning-specific summarization hint, then dispatches the plan-approved execution turn so it lands on a fresh cache anchor with the summarized rationale carried over. Cancelling the compaction (Esc or any other abort source) defers the execution dispatch and surfaces a warning so the operator can resubmit manually; non-abort failures proceed best-effort. - Added
CompactionCancelledErrortyped sentinel andCompactionOutcome("ok" | "cancelled" | "failed") return type to@oh-my-pi/pi-coding-agent/session/compaction.CommandController.executeCompactionandhandleCompactCommandnow return the outcome instead ofvoidso callers can discriminate user-driven aborts from generic failures without inspecting error messages. - Added a
credential_disabledextension event so extensions can subscribe viapi.on("credential_disabled", handler)and react whenAuthStorageautomatically soft-disables a credential (e.g. OAuthinvalid_grant). Replaces the currentagent_enderrorMessage regex pattern downstream extensions have to match against. Handler payload is{ type, provider, disabledCause }.createAgentSession()subscribes the per-session extension runner to the sharedAuthStorageviaauthStorage.onCredentialDisabled(...)at the very top of session creation — before any startup model probes run — so events fire on every disable regardless of whether the embedder also has a constructoronCredentialDisabledhandler attached. The SDK forwards throughExtensionRunner.emitCredentialDisabled(event), which buffers events untilrunner.initialize(...)runs in the mode controller and then flushes them throughemit()so extension handlers see populated UI/runtime context (rather than the constructor's no-op default withhasUI=false, an unset model, and no-op runtime actions). Onsession.dispose()the subscription is unsubscribed; the embedder's constructor-attached listener keeps firing through its own permanent subscription. The outercreateAgentSession()catch also releases the subscription if startup throws before the dispose-wrap is wired, so repeated retries don't accumulate dead listeners. - Added
omp acpsubcommand for launching as an ACP (Agent Client Protocol) server over stdio - Added explicit
typediscriminators to ACPinitializeauth methods, including aterminalsetup method gated onclientCapabilities.auth.terminal - Added ACP equivalents for the remaining TUI slash commands (
/jobs,/changelog,/dump,/copy,/hotkeys,/extensions,/agents,/model,/plan,/loop,/btw,/login,/logout,/resume,/tree,/branch,/new,/drop,/handoff,/fork,/session delete,/export,/share,/todo,/memory,/move,/mcp,/ssh,/marketplace,/plugins) so ACP clients reach feature parity with the TUI for non-interactive flows - Added ACP
planmode: whenplan.enabledsetting is on, ACPsession/new/load/resume/forkadvertise aplanmode alongsidedefault;session/set_modetoggles plan-mode state so the next agent turn injects the plan-mode system prompt - Added ACP
ClientBridgeabstraction (packages/coding-agent/src/session/client-bridge.ts) that routes tool I/O through the connected client when capabilities are advertised atinitialize; populated fromAgentSideConnectionin ACP mode - Added ACP
terminal/*routing forbash: when the client advertisesterminal: true, the tool creates a client-side terminal, embeds itsterminalIdon the live tool card, polls output, and releases the handle on exit or abort - Added ACP
fs/read_text_fileandfs/write_text_filerouting for thereadandwritetools: when the client advertisesfs.readTextFile/fs.writeTextFile, plain-text reads/writes go through the editor (surfacing unsaved buffer content and letting the editor track agent writes); falls back to disk only for reads, throws on bridge write failures - Added ACP
session/request_permissiongate aroundbash,edit,write, andast_editwhen an ACP client is connected; remembersallow_always/reject_alwaysdecisions per tool for the session lifetime - Added
diffToolCallContentemission for edit tool results: per-fileoldText/newTextis threaded throughEditToolPerFileResult/EditToolDetailsso ACP clients can render inline diffs - Added richer ACP
StopReasonmapping (max_tokens,refusal,cancelled) derived from the last assistant message's internal stop reason; previously onlyend_turn/cancelledwere emitted - Added
_meta.messageCountand_meta.sizeonsession/listSessionInfoentries - Added ACP
tool_call_updatelocationsrefresh from in-flight tool args and final result details so clients can "follow along" multi-file edits in real time
Changed
- Changed issue and pull-request list entries to link to repository-qualified URLs (for example
issue://owner/repo/<N>) so list items open correctly outside the default repo - Aligned prompt instruction language by defining
NEVERandAVOIDas strict aliases forMUST NOTandSHOULD NOTin the system prompt, and standardized agent, tool, and system prompt templates to use those terms consistently - Changed
--mode acpto apply the same stdout-quiet overrides as--mode rpcso no banner or status text leaks into the JSON-RPC channel - Changed ACP startup to no longer require a configured model so registry validators and clients can complete
initializeandauthenticatebefore any model is selected
Fixed
- Deferred flushing of buffered
credential_disabledevents during extension runner initialization to a microtask so handler failures are now routed throughonError()registrations made immediately afterinitialize(), preserving extension error reporting - Fixed
evaltool dynamicawait import("./relative.ts")calls failing withCannot find module ... from .../eval/js/shared/runtime.ts. The static-import rewriter only handledImportDeclarationnodes, so dynamic-import call expressions resolved their specifier against the worker module's URL instead of the session cwd. The rewriter now walks the full AST and additionally swapsimportcallees inCallExpressionnodes for__omp_import__, which forwards the optional options bag verbatim to nativeimport()so{ with: { type: "json" } }round-trips. RenamedrewriteStaticImports→rewriteImports. - Fixed
pr://<owner>/<repo>/diffURLs for repositories nameddiffto continue resolving to PR list lookups instead of being parsed as short-form diff links - Fixed
issue://<N>/diffshort form previously misparsing as a repo named<N>/diffand surfacing a confusing GraphQL "Could not resolve to a Repository" error. The numeric-host disambiguation that already routedpr://<N>/diffthrough the diff path now applies to both schemes, soissue://<N>/diff[/…]falls through to the existing "Issue views do not have a diff; use pr://///diff for pull requests." rejection — matching the long-formissue://<owner>/<repo>/<N>/diffbehavior.<scheme>://<owner>/difflistings for a repo literally nameddiffare unchanged. - Fixed PR unified diff parsing so changed-file headers with quoted paths (such as paths containing spaces) are now detected correctly and hunk content lines beginning with
---/+++are counted in additions/deletions - Fixed GitHub view caching to account for active credential identity and avoid serving cached issue/PR data across different account/token contexts
- Fixed
readcall tracking so calls without an explicit path or URL target no longer appear as regular file reads in the execution tracker - Fixed
createAgentSession()subscribing thecredential_disabledbridge to a freshly discoveredAuthStorageorphan when an embedder supplied onlyoptions.modelRegistry(nooptions.authStorage). Refresh failures emitted bymodelRegistry.getApiKey()flow throughmodelRegistry.authStorage, so a divergent local instance silently swallowed every disable event and also leaked into themcpManagerand session result. The SDK now reconcilesauthStoragetomodelRegistry.authStorageup front and rejects mismatchedoptions.authStorage/options.modelRegistry.authStoragepairs at session construction. - Fixed
runSubagent(subagent task executor) carrying the same latentAuthStorage/ModelRegistrydivergence ascreateAgentSession(): when onlyoptions.modelRegistrywas supplied, the executor previously fell through to a freshdiscoverAuthStorage()and handed that orphan intocreateAgentSession()alongside a registry whose.authStoragewas a different instance. The executor now reconciles tomodelRegistry.authStoragebefore any further work and rejects mismatchedoptions.authStorage/options.modelRegistry.authStoragepairs the same way the SDK does, so subagents can no longer silently observe a different storage view than their parent. - Fixed
githubtool'ssearch_issues/search_prs/search_code/search_commits/search_reposops always returning 0 results when the query contained more than one qualifier (e.g.is:merged is:pr,is:open author:foo).gh search …since theadvanced_search=truerollout in gh 2.92 silently wraps multi-token positional queries in parentheses and quotes everything after the first qualifier as that qualifier's value (is:"merged is:pr"), which GitHub then matches as a literal state filter that no PR can satisfy. The tool now callsgh api -X GET /search/<endpoint> -f q=… -F per_page=…directly so the qualifiers reach GitHub's search API verbatim.is:issue/is:prandrepo:<owner>/<repo>are appended internally to preserve the previous CLI-flag behavior; the user-facing query string in the formatted output is unchanged.statefor merged PRs is derived frompull_request.merged_atso the renderedState:line staysmerged/closed/openas before. - Fixed
readtool renderer rendering failed reads with a success check (✓) and styling the error message as file content while the surrounding box was red. The renderer now branches onisErrorfor both file and URL paths: header shows✘ Read <path>with a proper error icon and the underlying message is rendered as an error line.renderReadUrlResultgot the same treatment so failed URL reads also get the cross icon instead of falling through to the"No response data"Text fallback. Mirrors thebash/findrenderer error pattern. - Fixed ACP mode to advertise and handle non-TUI builtin slash commands and
/skill:<name>commands - Fixed ACP
session/resumeandsession/closeto dispatch correctly under SDK 0.21 by renamingunstable_resumeSession/unstable_closeSessionto the stableresumeSession/closeSessionmethod names the SDK now routes to - Fixed ACP
tool_call/tool_call_updatelocationsto always emit absolute paths (resolved against the session cwd) so editor clients can reliably open or focus the referenced file - Fixed ACP edit
diffmetadata for moves to point at the destination path rather than the now-deleted source so post-edit "open file" actions land on the new file - Fixed ACP
session/request_permissionlocationsto be absolute and to honor therequestPermissioncapability bit instead of only checking for the method, matching the read/write/bash capability gating - Fixed ACP
authenticateto rejectmethodIdvalues that were not advertised byinitializeso malformed clients fail fast instead of being treated as authenticated - Fixed ACP mode changes made via
session/set_session_config_option(MODE_CONFIG_ID) to also emit acurrent_mode_updatenotification, matchingsession/set_modeso clients trackingmodes.currentModeIdstay in sync - Fixed
/modelACP builtin to emit aconfig_option_updateafter switching models so clients show the new model in config selectors immediately - Fixed
/mcp list(ACP) to redact query strings and userinfo from server URLs before emitting them, so API keys embedded in URLs (e.g.?exaApiKey=…) are not leaked to clients - Fixed
/mcp test|resources|prompts(ACP) to wire the auth storage beforeprepareConfigso OAuth-backed MCP servers can refresh tokens and injectAuthorizationheaders - Fixed
/mcp list,/mcp test,/mcp resources,/mcp prompts,/mcp enable, and/mcp disable(ACP) to preserve project-over-user precedence when the same server name is defined in both scopes, matching the runtime capability merge so toggling the duplicated name flips the effective entry - Fixed
/ssh add --portparsing to reject non-integer values (e.g.22oops) instead of silently coercing them viaNumber.parseInt - Fixed
/ssh listto deduplicate hosts shared between project and user scopes, listing project entries first to match capability-loader precedence - Fixed
/export(ACP) to reject clipboard aliases (--copy,clipboard,copy) instead of using them as the output filename - Fixed ACP builtin commands (
/compact,/force,/move,/browser) to surface underlying failures viaoutput()instead of swallowing them - Fixed
/session save|delete(ACP) to route through the activeSessionManagerso the persist writer is consulted and stale storage references are removed - Fixed
/reload-plugins,/marketplace install|uninstall|upgrade, and/plugins enable|disable(ACP) to refresh slash command registries and emitavailable_commands_updateafter plugin state changes - Fixed ACP
usage()text emission to be awaited so help and error output is not dropped or reordered when commands return immediately - Fixed ACP
bashtool to release the client terminal handle onterminal/outputorwaitForExitfailures, and to race output polling against abort so a stuck RPC cannot delay cancellation - Fixed ACP
resourcecontent blocks withimage/*MIME types to be routed into the LLMimagesarray instead of being dropped as opaque blobs - Fixed
pr://andissue://URLs accepting empty,., or..path segments.pr://owner//77,pr://owner/repo/77/diff//2, andpr://owner/../77/diffpreviously slipped past the.filter(Boolean)split and were forwarded togh; now they throwInvalid <scheme>:// URL: empty or unsafe path segmentbefore any subprocess work. - Fixed
readofissue:///pr://URLs ignoring the read tool'sAbortSignal. Aborting a longpr://<N>/diff/allor stale issue fetch now propagates into the resolver and short-circuits at the handler entry; previously theghround-trip and cache write ran to completion. - Fixed
read <path>:raw(and theraw: truearg) still rendering markdown internal-URL content through the formatted markdown renderer. The TUI now respects the raw selector and falls back to the code-cell renderer so verbatim bytes are shown when requested. - Fixed
evaltool JS cells crashing with astructuredCloneerror when an awaited final expression returned a non-cloneable value (module namespace, function, symbol, etc.).displayValuenow falls back to a text representation and logs at debug instead of throwing. - Fixed
evaltool JS rewriter missing the final expression when followed by trailing empty statements (e.g.await Promise.resolve(1);;).returnFinalExpressionnow scans backward pastEmptyStatementnodes before deciding there is no final expression. - Fixed
githubview cache evicting valid rows on open whenever a longer-than-defaultgithub.cache.hardTtlSecwas configured.openDb()no longer sweeps with the 7-day default before settings load; the per-lookupsweepIfDue()enforces the configured retention exclusively. - Fixed extension
ctx.shutdown()being a no-op in the primary interactive path. The handler ininitHooksAndCustomToolsnow setsshutdownRequested(mirroring the backgrounded-reinit path), and the main REPL loop drains the flag at the post-stream idle boundary so queued steering messages still flush before teardown. - Fixed plan-mode "Approve and compact context" dispatching queued user input against the stale plan-mode reference path.
setPlanReferencePath(finalPlanFilePath)now runs beforehandleCompactCommandflushes the compaction queue, so any message typed during compaction is delivered with the approved plan context attached. - Fixed
.omp/commands/fix-issues.mdand.omp/commands/review-prs.mdstill instructing agents to call the removedgithub issue_view/pr_view/pr_diffops; they now referenceread issue://<N>andread pr://<N>[/diff[/all|<i>]]. - Fixed
ExtensionRunner.initialize()flushing bufferedcredential_disabledevents before mode controllers had a chance to register theironErrorlistener. Mode controllers callrunner.initialize(...)immediately followed byrunner.onError(...)synchronously; the flush now runs in a microtask after splicing the buffer, so a synchronously throwingcredential_disabledhandler is routed through the registered error listener instead of being silently dropped.
Security
- Secured the GitHub cache store with strict file permissions (
0600files) and private permissions for newly created cache directories (0700) to reduce local cache exposure
[14.9.9] - 2026-05-12
Added
- Added new
task.isolation.modevaluesauto,apfs,btrfs,zfs,reflink,overlayfs,projfs,block-clone, andrcopyfor native PAL-backed task isolation backends - Added automatic PAL-backed isolation backend selection so
task.isolation.modeuses the host's best-available backend - Added input-token and output-token totals to
omp stats --summary.
Changed
- Changed
task.isolation.enabled=truemigration to map totask.isolation.mode = "auto"instead of legacyworktreeisolation - Updated isolation configuration UI labels and descriptions to expose new back-end names (
overlayfs,projfs, etc.) and removed references to deprecated values in guidance text
Fixed
- Fixed worktree delta capture to include previously untracked file state by baselining untracked patches for both snapshots
- Fixed task isolation startup to try alternate PAL backends when the preferred one is unavailable, allowing successful fallback instead of immediate failure
- Mapped legacy
task.isolation.modevaluesworktree,fuse-overlay, andfuse-projfsto their new equivalents during settings migration to preserve behavior with older configs
[14.9.8] - 2026-05-12
Breaking Changes
- Changed the
evaltool input format to a single-line*** Cell <lang>:"<title>" [t:<duration>] [rst]header per cell, replacing the*** Begin <LANG>/*** End <LANG>envelope and the standalone*** Title:/*** Timeout:/*** Resetdirectives. The lark grammar enforces a fixed attribute order; the runtime parser remains lenient (alias keys, bare positional tokens, single-quoted titles).
Added
- Added
:conflictsread selector (read <path>:conflicts) to return a one-line index of all unresolved merge conflicts with stable#NIDs for quick inspection - Added bulk conflict resolution with
write({ path: "conflict://*", content })to resolve all currently registered conflicts across files in one call, expanding@ours/@theirs/@base/@bothper conflict and returning per-file counts - Added
readsupport forconflict://<N>andread conflict://<N>/<scope>to inspect unresolved conflict regions captured by a prior read, includingours,theirs, andbaseside views with original file line alignment - Added shorthand content tokens
@ours,@theirs,@both, and@baseto conflict-resolution writes usingpath: "conflict://<N>"so replacement content can be composed from recorded conflict sections - Added conflict count metadata to read results so conflict files now show a warning badge (
⚠ N) in the read tool UI - Added support for explicit boolean
rstvalues (rst:true,rst:false,rst:1,rst:0,rst:yes,rst:no,rst:on,rst:off) in*** Cellheaders - Added detection of unresolved git merge conflicts in
readoutput: each marker block is registered with a session-stable id and surfaced in a footer withours/theirspreviews. Resolve a block by callingwrite({ path: "conflict://<id>", content })— the tool splices the recorded marker region (markers and all sides) with the supplied content and routes through the normal writethrough (LSP format/diagnostics, fs-cache invalidation).
Changed
- Changed
readconflict warning footers to showX of Yunresolved conflicts when a range only captures part of a file and provide aread <path>:conflictshint for the full list - Changed conflict scanning in conflict read paths to inspect the whole file (with a 10 MB cap) so totals better reflect hidden conflicts and truncated scans are called out
- Changed conflict marker scanning during
readto only register fully formed, column-0 merge-marker blocks, so indented or malformed marker-like lines are no longer treated as conflicts - Changed
writeconflict resolution to validateconflict://IDs and report clear errors for malformed or unknown conflict URIs - Changed the HTML transcript renderer to parse the new
*** Cellheaders while keeping the older*** Begin <LANG>and===== ... =====formats renderable for historical sessions. - Changed the
evaltool parser so a stray non-marker line between cells no longer crashes withnull is not an object (evaluating 'BEGIN_RE.exec(lines[i])[1]'); stray content is consumed without aborting parsing. - Changed
*** Endto be an optional, undocumented per-cell terminator (kept in the lark to satisfy GPT-trained models' natural terminator habit during constrained sampling).
Fixed
- Fixed single-conflict
writeretries to re-locate the recorded conflict block by exact marker content so shifted line numbers from out-of-band edits no longer prevent resolution - Fixed
read conflict://*handling by rejecting wildcard reads with a clear write-only guidance error - Fixed conflict resolution to verify the live file still contains recorded
<<<<<<<and>>>>>>>markers before splicing, preventing stale conflict IDs from silently corrupting out-of-band-edited files - Fixed
@basetoken handling so two-way conflicts without a base section now return a clear error - Improved
*** Cellheader parsing to reject invalidrstvalues with a clearinvalid rst valueerror
[14.9.7] - 2026-05-12
Breaking Changes
- Changed the
timeoutMsexecution option to no longer be enforced during worker-based JS runs, so callers must rely on external cancellation signals for time limits - Replaced the Jupyter kernel gateway + WebSocket protocol behind the Python
evalbackend with a subprocess-backed runner that speaks NDJSON over stdin/stdout; removed thejupyter_kernel_gateway/ipykernelpip dependencies, thepython.sharedGatewaysetting, theomp jupyterCLI command, and thePI_PYTHON_GATEWAY_URL/PI_PYTHON_GATEWAY_TOKENenvironment variables
Added
- Added Python
tool.<name>(args)support toexecutePythonsessions so evaluated Python code can invoke session tools through the preludetoolproxy - Added per-execution Python tool bridge session registration and loopback endpoint wiring so Python tool calls resolve to host tools and return tool results
- Added status-event forwarding for Python tool bridge calls so
toolinvocations can emit execution status updates - Added browser-tab JavaScript execution through the shared runtime so tab runs now expose the standard helper globals (
read,write,sort,uniq,counter,diff,tree,env,output,display, andtool) - Added static ESM
importsupport to browser-tab JavaScript by rewriting top-level imports and resolving them against the tab session context - Added substring fallback matching to
HistoryStorage.searchso infix and short-token queries that FTS5 prefix matching misses are still returned - Added a live single-line sync progress display to the stats command showing current/total sessions while syncing
- Added automatic inline JS evaluation fallback when worker creation failed so script execution still works in environments without worker support
Changed
- Changed
setup pythonto only verify a reachable Python 3 interpreter instead of installing Jupyter dependencies - Changed
infooutput to remove the obsolete Python Gateway status block now that shared gateway management is no longer available - Changed JavaScript execution in
executeJsto expose the worker\u2019s realprocessobject instead of a restricted, frozen subset - Changed JavaScript evaluation to run per session in a worker-backed runner with explicit initialization and teardown handling
- Changed the Python backend to launch one
python -u runner.pysubprocess per kernel; cancellation now sendsSIGINTwhich raises a realKeyboardInterruptin user code, and the same subprocess is reused across cells in session mode - Changed Python magic handling so
%pip,%cd,%env,%pwd,%ls,%time,%timeit,%who,%reset,%load,%run,%%bash,%%capture,%%timeit,%%writefile, and!shellwork without depending on IPython
Fixed
- Fixed Python output rendering so
text/markdowntakes precedence overtext/plainand status bundles are emitted as status updates rather than plain text - Fixed query tokenization in
HistoryStorage.searchso punctuation-delimited terms likegit-commitare aligned with indexing and matched correctly - Fixed history search result merging to de-duplicate matches and return full-text matches before substring-only matches while still respecting the requested limit
- Fixed JS run cancellation so aborting a run now also cancels in-flight tool calls and terminates the active worker session
- Fixed top-level
const,let, andclassdeclarations in evaluated JavaScript to persist across subsequent runs by rewriting top-level declarations
[14.9.5] - 2026-05-12
Breaking Changes
- Removed the
jobs://internal URL protocol; inspect background jobs via thejobtool'slist: trueoperation instead
Added
- Added
sinceanduntildate-range filters tosearch_issues,search_prs,search_commits, andsearch_repos, accepting relative durations (m/h/d/w/mo/y), ISO dates, and ISO datetimes - Added
dateFieldsupport for date filtering (createdorupdated) so search results can be constrained by creation, update, pushed (for repos), or committer date (for commits) - Added owner-based scoping to async job registration and queries so background jobs can be registered with an
ownerIdand filtered per agent ingetRunningJobs,getRecentJobs,getAllJobs, andcancelAll - Added agent ownership metadata to async jobs started by
taskandbashtools so their lifecycle and cancellation is attributed to the creating agent - Added
list: trueoperation to thejobtool, returning an immediate snapshot of every job spawned by the calling agent without waiting (replaces the deletedjobs://URL) - Added per-agent visibility scoping to the
jobtool solist,poll, andcancelonly see and act on jobs owned by the calling agent; cross-agent operations now returnnot_found
Changed
- Changed
search_issues,search_prs,search_commits, andsearch_reposto allow date-only queries wherequeryis omitted ifsince/untilis provided - Changed
search_codeto return a validation error whensince/untilis supplied because GitHub code search does not support date qualifiers - Changed async job manager ownership so subagents inherit the parent session’s global
AsyncJobManagerinstead of creating and owning separate instances - Changed session lifecycle cleanup so the global async-job manager is disposed only by the owning top-level session
- Changed subagent session switches and handoff paths to stop global async-job cancellation and cancel only jobs owned by that session
- Changed
agent://andartifact://URL resolution to search artifact outputs across all active sessions instead of only the current session, allowing parent and subagent sessions to read each other’s generated outputs by ID - Changed
memory://URL resolution to walk all active sessions’ memory roots and return the first matching file, so worktree-based subagents can access their own memory views as well as shared roots - Changed internal URL routing to use a shared process-global
InternalUrlRouterand protocol handlers, so built-in tools resolveagent://,artifact://,memory://,skill://,rule://,mcp://, andlocal://URLs without requiring session-specific router wiring - Changed
mcp://handler to use the globally registered MCP manager so MCP resource links work for agents sharing session context - Changed the
ask.timeoutdefault from30(seconds) to0(wait indefinitely). Auto-selecting the recommended option after a fixed delay was surprising users mid-deliberation; the timer is now strictly opt-in. The legacy auto-select behavior is preserved whenask.timeoutis set to a non-zero value, and theasktool's prompt has been updated so the model expects unlimited reply time by default.
Fixed
- Added
ModelRegistry.hasConfiguredAuth(model)to mirror the upstream@mariozechner/pi-coding-agentAPI surface; external plugins and downstream wrappers that pre-flight auth before launching a subagent no longer crash withthis._modelRegistry.hasConfiguredAuth is not a functionon the direct agent-launch path. (#993) - Fixed an ESM circular-import TDZ that crashed test suites when modules from the
task/andtools/graphs were evaluated together (e.g.executor-warnings.test.ts+task-simple-mode.test.ts) by deferringBUILTIN_TOOLS.task'sTaskTool.createdereference to factory-call time and sourcingtruncateTailfromsession/streaming-outputinstead of thetools/barrel - Treat keyless-by-design providers (llama.cpp, ollama, lm-studio) as authenticated in subagent model resolution; fixes silent fallback to parent remote model when a local model is configured. (#1008)
- Fixed subagent disposal and session transitions that previously canceled all running async jobs, preventing inadvertent termination of a parent agent’s background work
- Fixed multi-entry edits silently rendering a fake success when every entry failed (e.g. all hit the auto-generated guard), by surfacing
isError: truefrom the single-path edit orchestrator so the renderer takes the error branch instead of falling through to the streaming-preview fallback that displays the proposed diff - Fixed the auto-generated streaming guard being gated behind
edit.streamingAbort(default false), so it now pre-empts streaming edit tool calls targeting auto-generated files regardless of that setting - Fixed subagents launched in the same parallel batch not seeing each other in their initial
# IRC Peerssystem-prompt block by pre-registering the agent in the globalAgentRegistrybeforerebuildSystemPromptruns and attaching the live session afterwards - Fixed plugin manifest extensions whose entry points at a directory (e.g.
pi-goal's"pi": { "extensions": [".pi/extensions/pi-goal"] }) failing to load withFailed to load extension: Directories cannot be read like files. The plugin path resolver now resolves directory entries to theirindex.{ts,js,mjs,cjs}file, matching the behavior of native auto-discovery viaresolveExtensionEntries. - Fixed the SSH tool on native Windows by avoiding OpenSSH ControlMaster multiplexing, which Win32-OpenSSH does not support and reports as
getsockname failed(#154). - Fixed
/exportand/treenot showing developer-role messages (including the plan content injected after/planapproval) so the HTML export and TUI session tree now render developer messages dimmed with their actual content instead of hiding them entirely (#753) - Fixed
Timed out initializing browser tab workeron prebuilt binaries by rewritingspawnTabWorkerto import the worker entry withwith { type: "file" }so Bun's--compilebundler statically discovers and embedstab-worker-entry.tsin the single-file binary (#1011)
[14.9.3] - 2026-05-10
Breaking Changes
- Changed the
evaltool input format to canonical*** Begin <LANG>...*** End <LANG>cells with*** Title,*** Timeout, and*** Resetdirectives, so legacy===== ... =====eval inputs are no longer accepted for execution - Removed the
sectionSeparatorre-export fromconfig/prompt-templates, so existing imports from@oh-my-pi/pi-coding-agent/config/prompt-templatesnow need to resolvesectionSeparatorfrom its utility package
Added
- Added support for the
*** Abortrecovery marker in eval and hashline parsing to terminate processing safely when stream corruption is detected - Added support for wrapping hashline edits in
*** Begin Patchand*** End Patchmarkers so patch input with these envelopes is parsed and applied - Added support in the HTML export renderer for the new
*** Begin/*** Endeval cell format - Added a dedicated
[now]prompt block tobuildSystemPromptoutput containing current date, current working directory, and required end-of-turn continuation/verification guidance - Added a new
[project]prompt block wrapper around workstation and workspace context and ensured it is emitted as a separate system prompt segment - Added dedicated HTML rendering for
evaltool calls, including cell-by-cell parsing of===== ... =====blocks with inferred Python/JS/TypeScript highlighting - Added dedicated rendering support for
search,recipe, andirctool calls in transcript exports - Added a collapsible
Available Toolssection with a tool count and chip-style compact tool names - Added macOS power assertion settings
power.preventIdleSleep,power.preventSystemSleep,power.declareUserActive, andpower.preventDisplaySleepso users can control what types of sleep are blocked during sessions
Changed
- Kept legacy
===== ... =====eval transcripts renderable in HTML while adding parsing for the new*** Beginformat for newer transcripts - Changed the system prompt’s Bash usage guidance to explicitly forbid specific anti-patterns (
sed/awkline-range reads, stderr redirects, and| head|tailpagination) and require using dedicated tools for those operations - Changed delegated subagent prompts so shared task context is now rendered only in the system-level
[context]block, while the user-facing task message now contains only the assignment prompt text - Changed system prompt rendering to use block markers such as
[env],[contract],[role],[coop], and[closure]for more explicit structural instructions - Changed the working-directory value in rendered prompts to use
shortenPathbefore interpolation - Updated subagent prompt assembly to compose prompt blocks and place the
[now]block after the subagent-specific instructions - Changed GitHub (
gh) tool cards to include operation, PR, branch, and truncated query/title/body details - Changed tool-call output to display internal
_iintent separately and hide it from rendered argument JSON - Changed
ast_editandfind/searchrendering to show resolved path values and option flags such aslimit,no-hidden, andno-reply - Changed power assertion behavior to take effect only while a prompt is in flight, replacing session-level persistent assertions
Removed
- Removed the unused
headandtailparameters from thebashtool schema, along with the deadnormalizeBashCommand/applyHeadTailpost-processing module — output truncation is already handled by the harness's streaming tail buffer and artifact spillover, so the agent should rely onread(or the artifact link) instead of inline truncation pipes.
Fixed
- Fixed eval tool outputs to append a truncation warning and ask users to re-issue remaining work when parsing is aborted by
*** Abort - Fixed hashline parsing and input splitting to stop at
*** Abortand ignore trailing edits after the marker - Fixed subagent task prompt construction so a trailing
[now]block in the base prompts is preserved and not swallowed when renderingsubagent-system-prompt - Fixed edit rendering so provided
inputtext is shown in the export even without a file path - Fixed
args.pathshandling inast_editandfindso multiple paths are shown as a comma-separated list - Fixed power assertion state handling so subsequent prompts are no longer blocked after an aborted or canceled prompt
- Fixed IRC background exchange poll loop leaking after session disposal:
#scheduleBackgroundExchangeFlushnow stops immediately whendispose()is called, preventing stalesetTimeoutcallbacks from firing against a torn-down agent
[14.9.2] - 2026-05-10
Added
- Added
agentsMdFilestoWorkspaceTreeso AGENTS.md discovery results are returned with the workspace scan output
Changed
- Changed startup workspace discovery to use one native
listWorkspacewalk for both the rendered tree and AGENTS.md directory-context candidates, removing the layeredgit ls-filesorchestration and secondary AGENTS.md glob.
Fixed
- Fixed AGENTS.md context discovery to include AGENTS.md files that are explicitly gitignored while still excluding AGENTS.md files under ignored directories
- Fixed task tool renderer spamming
Tool renderer failed: undefined is not an object (evaluating 'args.tasks.length')warnings while ataskcall was streaming in (thetasksarray is undefined until the partial JSON parser closes it); the renderer now tolerates an absenttasksfield and shows0 agentsuntil the array arrives (#985). - Fixed MCP HTTP streamable transport spamming
HTTP SSE stream error: ReadableStream already has a controllerafter every JSON-RPC request whose response was returned astext/event-stream. The transport used to break out of the SSE iterator once the matching response was captured and then re-openresponse.bodyfor a background drain, but the body had already been piped through aTransformStreamand could not be re-read. The drain now runs from a single iterator that resolves the response promise inline and continues to dispatch piggybacked notifications on the same stream.
[14.9.0] - 2026-05-10
Breaking Changes
- Moved hashline APIs to the dedicated
@oh-my-pi/pi-coding-agent/hashlinemodule, moved hash helpers to@oh-my-pi/pi-coding-agent/hashline/hash, and removed the legacyedit/modes/hashlineandedit/line-hashsource subpaths.
Removed
- Removed hashline auto-rebase. Anchor mismatches now reject immediately so the model re-reads instead of silently relocating an edit to a hash-collision within ±5 lines, which could otherwise apply the change to the wrong region. Stale-anchor recovery via the cached read snapshot is unaffected.
Fixed
- Fixed compaction crashing with
auth_unavailablewhen the current model's provider has no credentials configured; compaction now falls back to an available model role (or fails fast with a clear error) instead of attempting a doomed provider call (#986). - Fixed top-level static import rewriting in JS evaluation to use parser-based detection so only real import declarations are rewritten and
importtext inside strings, comments, or template literals is preserved - Fixed
import ... withattribute handling in rewritten ESM imports so static imports with module attributes now become dynamic imports with matchingwithoptions - Fixed model resolution silently falling back to a different provider (e.g. Amazon Bedrock) when
modelRolesspecified a fully-qualified<provider>/<id>whose exact pair was not in the bundled catalog. Explicit provider prefixes are now honored or surface a clear error (#980). - Fixed session count inflation on Anthropic backend caused by a fresh random
metadata.user_idbeing generated on every API request; all requests within one conversation now share a stablemetadata.user_idderived from the session ID, matching the expected one-session-per-conversation counting - Fixed plan mode review resubmits to append each refreshed
local://PLAN.mdpreview to the chat history, preserving the full refined plan in terminal scrollback. - Fixed compaction requests (manual and auto) not carrying
metadata.user_id, leaving them unattributed on the backend - Fixed direct session-bound LLM calls (
/btwephemeral turns viarunEphemeralTurn, branch summarization, session title generation) bypassing the agent and emitting a fresh randommetadata.user_idper request on Anthropic OAuth: the session-levelprepareSimpleStreamOptionshelper now stamps the agent's session metadata onto direct calls, andgenerateBranchSummaryplusgenerateSessionTitleaccept and forward an explicitmetadataoption from the call site - Fixed
metadata.user_idlacking the authenticatedaccount_uuidon Anthropic OAuth requests; sessions now install a dynamic resolver viaAgent#setMetadataResolverthat builds{ session_id, account_uuid? }per request, looking the live OAuth account UUID up fromAuthStorageso it stays in sync with token refreshes and login/logout transitions instead of stranding a stale value - Fixed multi-file legacy Pi extensions failing to load when sibling
.tsfiles import each other via relative paths (#983). - Fixed sub-agent dispatch silently routing to a model whose provider has no working credentials (e.g. an unqualified
modelRoles.taskid likeqwen3.6-plus-freeresolving to a provider the user is not authenticated against). Task dispatch now falls back to the parent session's active model — which by definition has working auth — when the resolved subagent model has none (#985). - Fixed legacy Pi plugin extensions failing to load on Windows when their entry path contains a drive letter (#990 by @jiwangyihao).
Added
- Added a debug-panel raw SSE stream viewer so stuck model/tool-call streams can be inspected live from the TUI.
- Added
get_login_providersRPC command to list registered OAuth providers with their current authentication status (id,name,available,authenticated) - Added
loginRPC command to trigger OAuth login for a given provider; emits anopen_urlextension UI event (fire-and-forget) carrying the auth URL and optional instructions so headless clients can open the browser, then resolves when the callback-server flow completes - Added
open_urlvariant toRpcExtensionUIRequestfor the above - Added
getLoginProviders()andlogin(providerId)methods toRpcClient
[14.8.0] - 2026-05-09
Added
- Added hashline stale-anchor recovery by replaying edits against a session-scoped
read/searchsnapshot and 3-way-merging them onto the current file when anchors no longer match
Fixed
- Fixed legacy pi extensions failing to import their own bare-specifier dependencies (e.g.
import x from "pkg"): files loaded via theomp-legacy-pi-file:namespace now pre-resolve bare imports against the extension's directory so the extension's ownnode_modulesis honored.
Changed
- Changed hashline success output to include a warning when stale-anchor recovery is used
[14.7.8] - 2026-05-08
Fixed
- Fixed indefinite startup hang on large repos introduced in 14.7.6 (#975) on two fronts: (1)
createAgentSessionwas awaitingbuildAgentsMdSearchandbuildWorkspaceTreedirectly in its blockingPromise.all, bypassing the existing 5s preparation deadline that previously protected startup — both scans are now raced against a 5s deadline and fall back to the system-prompt fallback path on timeout; (2)buildWorkspaceTreenow derives its listing fromgit ls-files --cached --others --exclude-standardwhen the workspace is a git worktree, which is O(index size) and avoids the per-call full-tree gitignore-aware native scan that the previous implementation triggered. Repos without git, or where the call fails / times out, transparently fall back to the previous native-glob path.
[14.7.6] - 2026-05-07
Changed
- Changed the "Hide Thinking Blocks" setting (Ctrl+T) to also instruct the provider to omit thinking/reasoning summaries from responses, instead of just hiding them client-side. Anthropic sees
thinking.display = "omitted"(where supported); OpenAI Responses / Azure / Codex requests dropreasoning.summaryentirely.
Fixed
- Fixed the
Hide Thinking Blockstoggle so changing it updates the active session’s request settings immediately, ensuring new responses reflect the current hide-thinking preference - Fixed system prompt preparation to keep successful context data and only fall back to minimal defaults for preparation steps that fail
- Fixed system prompt preparation timeout to apply per-step instead of all-or-nothing: a single slow step (e.g.
buildAgentsMdSearchon a huge directory tree,buildWorkspaceTree,loadProjectContextFiles) now falls back to its own minimal default while the other steps still populate, and the warning names which steps timed out. - Fixed subagents re-running expensive workspace scans (
buildAgentsMdSearch,buildWorkspaceTree) on every spawn: parents now forward their already-resolvedAGENTS.mdsearch and workspace tree to subagents throughcreateAgentSession, matching howcontextFiles,skills, andpromptTemplatesare already inherited. On large monorepos this removes seconds of redundant work pertaskinvocation and prevents the per-subagent system-prompt timeout warnings.
[14.7.5] - 2026-05-07
Added
- Added optional
/looplimits:/loop 10stops after 10 auto-iterations, while duration forms such as/loop 10mand/loop 10minstop after the time limit.
Changed
- Changed
/loopto include the configured limit and remaining budget in the enabled status message
Fixed
- Fixed
/loophandling of malformed count or duration arguments by showing usage errors instead of enabling unbounded loop mode - Fixed inherited disabled macOS malloc stack logging variables leaking into shell sessions and spamming Bun subprocess output with
MallocStackLoggingwarnings.
[14.7.4] - 2026-05-07
Breaking Changes
- Removed the dedicated
notebooktool;.ipynbreads and edits now go throughreadandedit.
Changed
- Changed diff previews to syntax-highlight contiguous context lines in the unchanged sections when file language can be detected
- Changed
readtool behavior for.ipynb:rawrequests to return raw notebook content instead of converting via markit - Changed
.ipynbedit and read handling to route through notebook serialization helpers - Changed
.ipynbreads to return an editable cell text representation and apply edits back to notebook JSON while preserving cell metadata and outputs where possible.
Removed
- Removed the
notebook.enabledconfiguration option from tool settings
Fixed
- Fixed hashline edit streaming preview collapsing to a header-only "opaque box" when a second
@PATHsection header arrived mid-stream — earlier completed sections now stay rendered while the trailing section is still being typed.
[14.7.2] - 2026-05-06
Breaking Changes
- Removed the exported
BUILTIN_TOOL_METADATAAPI, includingBuiltinEntry-style metadata exports and discoverable-built-in helper exports, which will break consumers relying on those symbols
Changed
- Updated discoverable tool search (
search_tool_bm25and related discovery metadata) to read each tool’s ownsummaryfield when present, improving discoverability descriptions for built-in tools
Fixed
- Fixed SearXNG web search Basic Auth validation to reject RFC 7617 control characters and clarified the equivalent
config.ymland environment variable settings. - Fixed extension commands that return without starting a model turn leaving the interactive
Working…spinner active indefinitely. (#927) - Fixed
authHeader: trueprovider overrides without custommodelsso built-in model transport headers receiveAuthorization: Bearer <resolved-key>(#929).
[14.7.1] - 2026-05-06
Added
- Added
pr_createoperation to the GitHub tool to create pull requests with title/body (orfill), base/head branch, draft, reviewer, assignee, and label options and return a summarized result including the new PR URL - Added
read.summarize.prosesetting to keep Markdown and plain-text reads out of the structural summarizer by default.
Changed
- Changed the
PI_GREP_WORKERSenvironment variable help text to state that it sets filesystem walker workers, defaults to 4, and uses0for automatic worker selection - Changed hashline replacement and pure-insert auto-absorb to also drop a single duplicated structural-closing line (
},);,], etc.) on either boundary when keeping it would unbalance brackets. The pure-insert variant fires regardless ofedit.hashlineAutoDropPureInsertDuplicates, while the existing 2+ line generic absorb stays gated on that setting.
[14.7.0] - 2026-05-04
Breaking Changes
- Changed session system-prompt APIs to use ordered string block arrays by requiring
buildSystemPrompt,CreateAgentSessionOptions.systemPrompt,Session.rebuildSystemPrompt, and extensionbefore_agent_start/getSystemPrompthooks to accept and returnsystemPrompt: string[]instead of a plain system-prompt string or separateprojectPromptfield - Changed
buildSystemPromptand sessionrebuildSystemPromptAPIs to return{ systemPrompt, projectPrompt }, requiring callers expecting a plain system prompt string to update to the new shape - Removed the top-level
selparameter from thereadtool schema, requiring callers to migrate topath-embedded selectors (for examplepath:50-100,path:raw, orhttps://...:L1-L40)
Added
- Added a separate
projectPromptartifact containing per-session project context (workstation, context files, AGENTS.md rules, workspace tree, and append prompt) so dynamic context is decoupled from the static system prompt - Added
Project prompttoken accounting to context-usage breakdowns and charts - Added
tools.elideFileMutationInputssetting to optionally elide largewrite,edit, andapply_patchpayloads in history after successful mutations - Added hashline-style return data for elided
writecalls so tools can include the resulting file content without leaking full input text - Added
buildDirectoryTreeandDirectoryTreeexports to generate configurable directory trees with options for depth, entry limits, hidden-file handling, and truncation caps - Added
buildWorkspaceTreeandWorkspaceTreeexports so callers can precompute and pass a workspace context to prompt generation - Added
workspaceTreesupport tobuildSystemPromptoptions to reuse a prebuilt directory snapshot - Added
read.summarize.enabled,read.summarize.minBodyLines, andread.summarize.minCommentLinessettings to control whetherreadreturns structural summaries and how many multiline body/comment lines are collapsed - Added
edit.hashlineAutoDropPureInsertDuplicatessetting to opt into dropping 2+ pure-insert hashline payload lines that duplicate adjacent file context; default isfalse.
Changed
- Updated session dump and HTML export output to serialize ordered system-prompt blocks (including project context) and removed the dedicated project-prompt dump section
- Renamed context-usage system-prompt accounting from a separate
projectPromptbucket tosystemContextto match the new multi-block prompt structure - Changed prompt delivery to inject non-empty
projectPromptas a leadingdevelopermessage before conversation messages instead of merging it into the base system prompt - Added
projectPromptto session dumps to expose the injected per-session project context separately - Changed write success output and preview rendering to display hashline-formatted written content from captured file text when mutation inputs are elided
- Changed
readdirectory rendering to return a two-level recency-sorted directory tree (including nested folders) instead of a flat alphabetical entry list, while still applying configurable truncation - Changed generated system prompts to include a working-directory tree block after directory context, showing recent files/directories (depth ≤ 3) and truncation notices when entries are elided
- Changed
readsummary rendering to merge opening- and closing-brace boundaries around elided sections into a single..line (including closers like};or})), reducing those segments to one concise anchored summary line - Changed default
readoutput for parseable code files without an explicit selector to return a structural summary instead of full verbatim lines, while still supporting full output for:rawand explicit ranges - Changed truncation/pagination hints in read, archive, and SQLite outputs to use colon syntax (
Use :<offset>) when continuing reads - Changed the read tool UI preview title to include summary elision counts when a summary is returned
- Changed hashline pure-insert duplicate auto-drop to be opt-in through
edit.hashlineAutoDropPureInsertDuplicatesinstead of always enabled.
Fixed
- Fixed selector parsing for colon-containing paths by only splitting
:<sel>when the suffix matches a valid line-range orrawpattern, preventing paths likedb.sqlite:users:42from being misread as selectors
[14.6.6] - 2026-05-04
Added
- Added Ctrl+D draft persistence: pressing Ctrl+D with text in the editor now exits the app and saves the unsent text as a per-session draft. Resuming the same session (e.g. via
--resume) restores the draft into the editor (one-shot, removed after restore).
[14.6.4] - 2026-05-03
Added
- Added
hindsight.mentalModelsEnabled,hindsight.mentalModelAutoSeed,hindsight.mentalModelRefreshIntervalMs, andhindsight.mentalModelMaxRenderCharssettings to control curated Hindsight mental-model activation, seeding, refresh cadence, and prompt render budget - Added
<mental_models>injection to developer instructions, loading bank-level curated summaries as stable background context - Added built-in
/memory mmcommands (list,show,refresh,history,seed,reload,delete) to inspect and manage mental models on the active bank - Added scope-aware mental-model seeding for
global,per-project, andper-project-taggedbanks, including built-in seed models like user preferences, project conventions, and project decisions - Added warning output when hashline block replacements auto-absorbed duplicate boundary lines
Changed
- Changed
/memory clearand/memory enqueueto apply only to the current agent session’s Hindsight cache instead of all live Hindsight sessions - Changed the prompt assembly order so
<mental_models>blocks are appended before<memories>recall blocks in developer instructions
Fixed
- Fixed Hindsight memory prompt injection and recall/retain tool execution to resolve against the active session state, preventing context from an unrelated session from being used
- Fixed subagent
/tasksessions to persist memories into the parent agent’s Hindsight bank by explicit parent state wiring - Fixed per-session memory retention behavior when switching or resuming sessions by rekeying Hindsight state and resetting conversation-tracking counters so first-turn recall and nth-turn retain cadence no longer leak across conversations
- Fixed the first-turn startup race so
<mental_models>appears in the opening system prompt when mental-model loading is enabled - Fixed retention hygiene by stripping
<mental_models>blocks from retained content to prevent curated summaries from feeding back into future memory writes - Fixed
<mental_models>rendering to honor the configured character budget and truncate with an explicit truncation marker when the snapshot exceeds limits - Fixed hashline replacements so duplicated payload boundary lines adjacent to a replaced block are absorbed into the replacement range instead of being duplicated
[14.6.3] - 2026-05-03
Breaking Changes
- Renamed hashline separator configuration from
PI_HASHLINE_SEPtoPI_HL_SEPand changed the default payload separator from\\to>
Added
- Added inline hashline edit syntax so
< ANCHOR${sep}TEXTprepended text to an anchored line and+ ANCHOR${sep}TEXTappended text to it without requiring a multi-line payload block - Added a
memory.backendsetting (off, local, hindsight) under a new Memory settings tab to control which memory subsystem is active - Added Hindsight memory settings (
hindsight.*) for API connection, bank identification, and recall/retain policy - Added
retain,recall, andreflecttools for direct long-term memory search, retention, and reflection when using the Hindsight backend - Added
hindsight.scopingsetting (global,per-project,per-project-tagged) that controls whether memories are shared across projects, isolated per cwd, or tagged so global + project memories merge on recall (default:per-project-tagged) - Added
search_code,search_commits, andsearch_reposops to thegithubtool so the search surface mirrorsgh search's subcommands
Changed
- Changed
hindsighttool retains to enqueue memory writes and returnMemory queued.immediately instead of waiting on a network request - Changed
hindsighttool memory writes to use automatic background batching (up to 16 items or 5 seconds) so tool calls do not block - Changed failed
hindsightqueue flushes to be surfaced as UI warning notices rather than failing the foregroundhindsighttool call - Changed hashline read/search previews and diff output to keep
|as the anchor-to-text separator while using the separate configured edit payload separator - Mapped invalid
hindsight.scopingsettings back to the defaultper-project-taggedbehavior with a warning - Changed
/memory view,/memory clear, and/memory enqueueto route through the selected memory backend instead of being hardcoded to local memories - Changed compaction context assembly to include backend-provided recall context when available
- Updated multi-path
search,find,ast-edit, andast-grepcalls to skip missing base paths, returning matches from remaining paths and reporting skipped paths in output - Replaced
hindsight.dynamicBankId(boolean) with the explicithindsight.scopingenum; legacy values are migrated automatically (dynamicBankId=true→scoping="per-project") - Changed
search_reposto run as a global repository search using query qualifiers without applying therepofilter
Deprecated
- Set explicit
hindsight.scopingnow takes precedence over legacyhindsight.dynamicBankIdwhen migrating old settings
Removed
- Removed legacy
hindsight.dynamicBankIdandhindsight.agentNamefields from the active settings model - Removed
hindsight.agentNameand theHINDSIGHT_AGENT_NAME/HINDSIGHT_CHANNEL_ID/HINDSIGHT_USER_IDenv vars; the legacyagent::project::channel::userbank tuple is gone. A user-setagentNameis migrated ontohindsight.bankId.
Fixed
- Fixed pending
hindsightqueued memory writes to flush on agent end, clear, and enqueue operations so tool-invoked facts are not dropped when sessions transition - Fixed retained memory writes from the
hindsighttool to include session context and tags consistently in background batches - Fixed inline hashline modify operations to fail fast when combined with a delete or replace on the same target line
- Fixed hashline parsing of payload blocks to handle a shared extra leading symbol prefix (such as markdown
>>) on all payload lines by stripping it as an auto-correction instead of rejecting the edit - Forwarded project scoping tags to
hindsightretain, recall, and reflect operations so manual memory commands honor the active tagging mode - Fixed legacy migrations by mapping existing
memories.enabledvalues tomemory.backendon load to preserve prior enable/disable behavior - Fixed memory retention so recalled
<memories>blocks and legacy<hindsight_memories>/<relevant_memories>blocks are stripped before storing transcripts and do not feed back as new memory - Fixed
search_codeoutput to include each match path, repository, shortened SHA, and a one-line matching fragment - Fixed
search_commitsoutput to show shortened SHAs with commit message first lines - Fixed
search_reposoutput formatting to return repository summaries including language, stars, forks, issues, visibility, and key status fields
[14.6.2] - 2026-05-03
Added
- Added
statusLine.sessionAccentto disable session-name accent coloring for the editor border and status line gap (#918)
Fixed
- Disabled repeated OSC 11 background-color polling under WSL to avoid Windows terminal tab crashes while keeping initial and event-driven appearance detection (#914)
- Fixed SSH ControlMaster socket paths to use OpenSSH's connection hash (
%C) so connections to the same host with different users, ports, or jump hosts do not share a master session.
[14.6.1] - 2026-05-02
Changed
- Updated GitHub call headers to display operation-specific titles and contextual metadata such as repository, branch, issue/PR IDs, and search query snippets for supported operations
- Changed non-run-watch result rendering to honor terminal width, truncate long lines, and show a
+N more linesexpansion hint when output exceeds the preview limit
Fixed
- Fixed GitHub tool output fallbacks that previously always showed a GitHub Run Watch heading so they now show the actual operation and clear
no output/request failedstatus messaging
[14.6.0] - 2026-05-02
Breaking Changes
- Reworked autoresearch storage and protocol. State now lives in
~/.omp/autoresearch/<project>.db(SQLite) and per-run logs in~/.omp/autoresearch/<project>/runs/<id>/benchmark.log. The repo-side artifactsautoresearch.md,autoresearch.sh,autoresearch.checks.sh,autoresearch.program.md,autoresearch.ideas.md,autoresearch.jsonl,.autoresearch/, andautoresearch.config.jsonare no longer read or written; they are deleted by/autoresearch clear. Any existing data is not migrated. - Removed the autoresearch edit guard.
write/edit/ast_editare no longer blocked based on scope. Scope/off-limits are now post-hoc accountability fields onlog_experiment. - Replaced rigid
init_experimentcontract validation with a simpler schema:name,goal,primary_metric,metric_unit,direction,secondary_metrics,scope_paths,off_limits,constraints,max_iterations,new_segment. Removedfrom_autoresearch_md,abandon_unlogged_runs,force, andpreferred_commandflags — the harness./autoresearch.shis the canonical workload, edit it and bump segment when you need to change it. run_experimentno longer accepts acommandparameter. The tool always runsbash autoresearch.sh. To change the workload, edit the harness and callinit_experiment new_segment: true. Removedforce,checks_timeout_seconds, and the legacyautoresearch.checks.shauto-execution; run validation through the regularbashtool.- Replaced
log_experimentASI requirements andforce/skip_restoreflags withjustification(post-hoc explanation for scope deviations) andflag_runs(mark earlier runs suspect to exclude them from baseline math). ASI is now opaque metadata. /autoresearch clearnow resets the worktree to the session's recorded baseline commit (when on anautoresearch/*branch or with--reset-tree), closes the active session, and deletes any leftover legacy autoresearch repo artifacts./autoresearchnow refuses on a dirty worktree with an explicit error instead of silently continuing on the current branch. Commit or stash before invoking — the session needs a clean baseline on a dedicatedautoresearch/*branch.- Split
/autoresearchinto a two-phase protocol. Phase 1 (no session) prompts the agent to build the benchmark harness as./autoresearch.sh(must exit 0 and printMETRIC <name>=<value>). Callinginit_experimentends Phase 1: it requires./autoresearch.shto exist, auto-commits any pending harness changes on anautoresearch/*branch, then records that commit as the baseline. Phase 2 is the existing iteration loop. - Autoresearch sessions are now scoped to the git branch they were created on. Switching off the
autoresearch/*branch hides the dashboard widget, detaches the experiment tools, and skips the autoresearch system prompt; switching back resumes seamlessly./autoresearchon a fresh branch starts a fresh session instead of resurrecting a session bound to a different branch. log_experiment discardno longer rewinds priorkeepcommits. On anautoresearch/*branch it now resets the worktree toHEAD(andgit cleans untracked) instead ofgit reset --hard $baseline_commit. Discard reverts only the current iteration's uncommitted edits; previously kept improvements stay on the branch./autoresearch clearcontinues to reset to the recorded baseline commit when explicitly requested.- Autoresearch SQLite storage is now created lazily on first
init_experiment. Runningompin a project that never invokes/autoresearchno longer creates a per-folder DB. - Changed
search,find,ast_grep, andast_editto acceptpaths: string[]instead of comma- or whitespace-delimited path strings.
Added
- Added
update_notestool withbody(replace) andappend_idea(append a bullet under an## Ideassection). Notes are injected into the system prompt every iteration and replace the file-basedautoresearch.md/.program.md/.ideas.mdecosystem.
Changed
- Updated
log_experimentsummary output to include the count of scope deviations detected for a run - Used the active session context in autoresearch resume instructions instead of referencing deleted repo-side files
- Removed
PI_STRICT_EDIT_MODE; model-specific edit mode fallbacks are no longer disableable by environment flag.
Fixed
- Atom edit auto-rebase warning now dedupes by
(originalLid, rebasedLine)pair. Previously,@Lidfollowed by N+TEXTlines emitted N identical "Auto-rebased anchor" warnings (one per cloned cursor anchor); now emits exactly one per distinct rebase. - Atom/hashline diff preview no longer renders deleted lines with a 2-space hash placeholder (
-20 |old) that visually mimicked a Lid. Removed lines now use--as the placeholder (-20--|old), making them unambiguously non-Lid. - Atom/hashline diff preview no longer folds size-mismatched
-/+runs into a confusing mix of*(paired modification) lines plus surplus-/+lines. The*collapse now applies only to clean 1:1 line replacements (same number of dels and adds); range replaces with N→M (N≠M) render as plain unified-diff-then+runs. - Atom edits now warn when
@Lidlands on a brace-opening line and the inserted content is at sibling indent (≤ anchor indent) — a foot-gun where the agent meant^<nextSibling>but the inserts ended up as the first body element of the{...}block. - Atom auto-fix warning for adjacent-duplicate cleanup is now formatted as
AUTO-FIX applied — verify the result. Removed ...instead of the easier-to-missAuto-fixed: removed ..., and explains that{}/()/[]balance was the trigger. - Fixed multi-target
search,ast-grep, andast-editpath handling by running each resolved target separately under root-level path resolution - Fixed pagination and match/replacement summaries for multi-target AST and text searches so totals and affected file counts include all targets
- Fixed returned file paths for multi-target
searchandast-grepresults by normalizing them to the original search scope - Fixed
log_experiment keepsilently dropping the iteration's diff on an autoresearch branch. The previous logic filtered out every path that was already dirty whenrun_experimentran — but in the iteration cycle the agent's edits always land beforerun_experiment, so the entire iteration was filtered away and nothing was committed. On an autoresearch branch,keepnow treats every currently-dirty path as the iteration's change and commits it.
[14.5.14] - 2026-05-01
Changed
- Changed markdown conversion and archive tooling to defer loading heavy dependencies (Turndown, fflate, and browser agent content) until first use, reducing startup overhead for CLI startup and command initialization
Fixed
- Fixed changelog state tracking by flushing
lastChangelogVersionto settings immediately when showing new entries, so the updated version is persisted across restarts
[14.5.13] - 2026-05-01
Breaking Changes
- Removed the built-in
pythontool in favor ofeval, so tool allowlists and tool-call handlers referencingpythonneed to migrate - Removed the
python.toolModesetting and replaced mode control with separateeval.pyandeval.jstoggles - Changed the tool runtime config surface by migrating
pythonexecution timeout/export behavior toevaland replacing./ipy/*internal exports with./eval/*paths - Changed the
evaltool wire format to a singleinputstring composed of markdown fenced code blocks (with per-fence language, timeout, title, and reset metadata in the info string) instead of top-levelcells,language,timeout, andresetfields
Added
- Added a JavaScript backend to the
evaltool with an in-process VM runtime and JS helper bridge (read,write,glob, etc.) - Added
eval.pyandeval.jssettings so Python and JavaScriptevalbackends can be enabled or disabled independently - Added
rename_fileaction to the Lsp tool to rename files and directories with LSPworkspace/willRenameFilesandworkspace/didRenameFilesflow, applying returned workspace edits before moving files - Added
apply: falsepreview mode forrename_fileso users can see planned LSP edits without performing filesystem changes - Added
requestaction to invoke arbitrary LSP methods, with automatictextDocument/positionparameter construction fromfile/line/symboland support for explicit JSONpayload - Added
capabilitiesaction to display language server capabilities (for a file or all configured servers) through the LSP tool
Changed
- Changed AGENTS.md discovery to respect
.gitignorefiles during project context collection so ignored context files are no longer loaded - Changed eval tool initialization to skip Python kernel preflight when the JavaScript backend is enabled, avoiding unnecessary startup checks
- Changed model registry refresh flow to defer rebuilding the canonical model index until refresh operations complete, reducing refresh churn
- Changed execution/tool discovery flow so
execmaps toevalwhen anyevalbackend is enabled, whilebashstays independently available - Changed
evaldispatch to automatically fall back to JavaScript when Python is unavailable and JavaScript backend is enabled - Parallelized plugin root preloading with other startup initialization in
runRootCommandto reduce startup latency - Parallelized session bootstrap work in
createAgentSession, including AGENTS.md scanning, context discovery, prompt template loading, slash command loading, and skill discovery, to reduce time to first available session
Fixed
- Fixed eval startup messaging to report
evalas unavailable when Python is unreachable and JavaScript backend is disabled
[14.5.12] - 2026-04-30
Breaking Changes
- Removed the legacy browser action verbs (
goto,observe,click,type,fill,press,scroll,drag,wait_for_selector,extract_readable, andscreenshot) in favor of invoking those workflows throughrun
Added
- Added a
browsertoolopen/run/closeflow with arunaction that executes async JavaScript and providespage,browser,tab,display,assert, andwaitin scope - Added named tabs on
openwith default namemainso browser state can be reused acrossruncalls and subagents - Added support for
app.pathandapp.cdp_urlonopento launch/connect to CDP-capable desktop apps
Changed
- Changed browser tool output rendering to display
runcalls as JavaScript code cells with status and output previews while showingopen/closeas compact status lines - Changed
opento open or reuse named tabs andcloseto supportall: trueandkill-based process termination behavior - Changed app attachment behavior to reuse an existing CDP endpoint when available and avoid unnecessary respawn of matching app processes
- Changed tab closing so closing a tab no longer implicitly affects unnamed sessions when multiple tabs are used
- Changed browser export rendering to label outputs under the
browsertool and include app metadata badges
Fixed
- Fixed Electron/CDP attachment target selection to skip helper windows and pick the most likely user-visible page target
- Fixed connection startup by waiting for the CDP endpoint and surfacing a timeout error when it does not become available
- Fixed plan mode to auto-redirect
writeandeditcalls targeting a barePLAN.md(or any same-basename cwd-relative path) to the canonicallocal://PLAN.mdplan artifact instead of rejecting them
[14.5.11] - 2026-04-30
Breaking Changes
todo_write: renamedreplaceop toinitand reshaped its input tolist: [{phase: string, items: string[]}]. Tasks no longer accept astatusfield; all startpendingand the first auto-promotes toin_progress. Theappendop'sitemsis nowstring[](was{id, label}[])todo_write: removed the synthetictask-N/phase-Nids — task identity is now itscontentand phase identity is itsname. Thetaskfield onstart/done/drop/noteand thephasefield ondone/drop/rm/appendtake those values directlytodo_write: phase names no longer accept a numeric/roman prefix (I.,1.,Phase 1:, …). The renderer numbers phases visually (Ⅰ. Ⅱ. Ⅲ. …) and the model-facing state stores the bare noun phrase
Changed
- Changed
/todotask and phase operations to target items by fuzzy content or phase name matching instead of numeric IDs - Changed initial todo markdown export template heading from
# I. Todosto# Todos
Fixed
- Fixed todo auto-clear scheduling to identify completed tasks by phase and content so only the matching task is cleared after delays
[14.5.10] - 2026-04-30
Breaking Changes
- Removed the
worktreeparameter fromgithubpr_checkout. Worktrees are now always written to~/.omp/wt/<encoded-primary-repo>/pr-<number>/, derived from the primary repository path - Stopped reading the
branchparameter forgithubpr_checkout. The local branch is now alwayspr-<number>; thebranchschema field is still accepted bypr_push,repo_view, andrun_watch
Added
- Added
checkoutssummary entries topr_checkoutresults, including each checkout's branch, worktree path, remote, and reuse status - Added combined summaries for
pr_viewandpr_diffwhenpris an array, so multi-request responses now include all requested pull requests in one return - Added array support to the
prparameter ongithubpr_view,pr_diff, andpr_checkoutso a single call can fetch, diff, or check out multiple pull requests in one batch - Added a per-repo serialization lock (
withRepoLock) so concurrentpr_checkoutcalls against the same repository no longer race on git's internal.git/config.lock, commit-graph, and worktree lock files
Changed
- Changed the diff preview shown after edits so changed lines are never collapsed: removed runs and the global preview budget no longer truncate, only unchanged context still collapses
- Changed adjacent
-/+pairs in edit previews to fold into a single*<line><hash>|<new-content>modification line so 1:1 line replacements stay compact - Changed
git.remote.addto be idempotent when the remote already exists with the same URL (instead of failing withremote ... already exists), and to surface a clear error when the existing URL differs - Changed
pr_checkoutto rungh pr viewcalls in parallel for batch invocations while serializing the in-repo git mutations to keep the operation race-free - Changed
pr_checkoutto auto-derive the worktree location and local branch name (see Breaking Changes), removing the per-call overrides that previously let callers pin a worktree path or local branch
Removed
- Removed the
./hooksand./hooks/*package export entries - Removed the
Suspicious duplicatewarning emitted after edits — it produced too many false positives (e.g. legitimate adjacent\t});\n\t});); the auto-fix path that uses bracket balance to safely de-duplicate is unchanged
Fixed
- Fixed bash interceptor rules to also check the original command before
cdnormalization, so leadingcd ... &&wrappers no longer bypass interception - Fixed LSP client shutdown to properly await the language server's exit instead of fire-and-forget, preventing premature process termination on SIGINT and SIGTERM
- Fixed concurrent bash commands being tracked independently so aborting one no longer silently drops tracking of others
[14.5.9] - 2026-04-30
Added
- Added the
/contextslash command to display an estimated context-usage breakdown panel for the current session - Added
-LidA..LidBsyntax to delete inclusive line ranges in a single atom operation - Added
LidA..LidB=TEXTrange-replace syntax with\TEXTand\continuation lines for multi-line replacement blocks - Added shorthand cursor+insert operations in atom edits, including
^Lid(insert before anchor),^+TEXT,$+TEXT, andLid+TEXT/@Lid+TEXT - Added standalone file-op fallback so
!rmand!mv DESTinputs can be normalized into sections when using split input parsing
Changed
- Changed token counting to use tokenizer-based estimates instead of a character-per-4 heuristic for context and compaction calculations
- Changed hashline anchor auto-rebase tolerance from ±2 lines to ±5 lines for stale Lid recovery
- Changed atom input handling so
#-prefixed lines are treated as comments and ignored - Changed execution when all edits are no-op
Lid=TEXTreplacements to return success with a no-change explanation instead of throwing
Fixed
- Fixed malformed range and unified-diff-like atom syntax by rejecting reversed ranges, mismatched range endpoint hashes, and forms like
+Lid|TEXT,+Lid=TEXT, and-LidA..LidB|TEXTwith explicit actionable errors - Fixed hash mismatch errors to include likely-shifted anchor hints when a unique matching line is found elsewhere in the file
[14.5.8] - 2026-04-29
Breaking Changes
- Changed the task runner toggle from
just.enabledtorunCommand.enabled, so existing configurations usingjust.enabledmust be migrated - Removed the legacy
justtool and replaced it withrun_command - Renamed the built-in tool API from
justtorun_command, so clients requesting/handling the old tool name must update
Added
- Added a new
run_commandtool that runs project tasks via a singleopargument, auto-detecting and supporting recipes from justfiles,package.jsonscripts (including workspace packages), Cargo bin/example/test targets, Makefiles, and Taskfiles - Added support for explicit runner-qualified tasks via
run_commandwithrunnerId:tasksyntax in the prompt guidance
Changed
- Changed automatic tool availability so requesting
bashcan now auto-includerun_commandwhen a supported task runner manifest is detected in the working directory - Changed task resolution to disambiguate identical task names across multiple runners and show runner-aware command execution errors
Fixed
- Fixed editor draft being erased when a user message queued during streaming was eventually submitted; the queue/steer path now preserves any new prompt the user has typed since queuing, matching the existing optimistic-send protection.
[14.5.7] - 2026-04-29
Fixed
- Fixed hook editors to recognize Ctrl+Enter when terminals include NumLock or keypad Enter metadata.
[14.5.6] - 2026-04-29
Changed
- Removed the atom edit mode's multi-anchor auto-rebase rejection so stale-but-uniquely-rebasable block edits apply with warnings instead of failing.
[14.5.5] - 2026-04-29
Breaking Changes
- Rejected atom diffs with unrecognized operations (including lone '-' lines) by throwing parse errors instead of treating them as inserts
Added
- Added duplicate-line post-edit detection that warns on newly introduced adjacent identical lines and auto-removes one duplicate when bracket-balance is restored
- Added a warning when suspicious adjacent duplicates are introduced after edits so users can review potential stale-line issues
Changed
- Changed anchor rebase handling to fail when multiple mutating anchors would need auto-rebase, preventing silent misapplied contiguous block rewrites
Fixed
- Fixed bracket-corruption caused by botched block rewrites by automatically removing a newly introduced duplicate adjacent line when removing it restores the original
{},(), and[]balance and by warning when automatic removal is unsafe
[14.5.4] - 2026-04-28
Breaking Changes
- Changed the
atomedit mode from JSON{ path, edits }calls to the compact file-orientedinputpatch language that was previously exposed asatomd;atomdis no longer a separate edit variant - Renamed MCP tool identifiers from the
mcp_<server>_<tool>format tomcp__<server>_<tool>so custom tool names, active tool lists, and persisted MCP selections must be updated to the new prefix - Renamed the built-in content-search tool from
greptosearch, including SDK/tool event names and settings keys (search.enabled,search.contextBefore,search.contextAfter), so integrations usinggrepandgrep.*references must be updated
Added
- Added internal URL support to the
searchtool, allowingartifact://-style paths that resolve to local files to be searched directly - Added IRC relay observation in the main agent UI so every IRC exchange between agents is rendered in the main transcript, even when the main agent is not a direct participant
- Added stateful
href/hrefrprompt helpers that can reuse anchors remembered from priorhlinehelper calls
Changed
- Changed file-path rendering across search, find, AST, LSP, and related edit outputs to display targets as cwd-relative paths when they resolve inside the working directory and keep absolute paths for files outside the cwd
- Changed system prompt guidance so in-cwd tool paths must be passed as cwd-relative paths and absolute paths only for out-of-cwd targets or
~expansion - Updated
editstreaming diff previews forpatch,replace, andhashlineto produce a single request-level preview for the new single-filepathmode - Bumped default
read.defaultLimitfrom 300 to 500 lines, and scaled the read tool's byte budget with the line limit (max(50KB, lines * 512)) so the configured line count is no longer truncated by the shared 50KB cap
Fixed
- Fixed atom edit streaming previews to use atom headers for file names instead of apply_patch parsing errors.
- Fixed collapsed search result rendering so summary and truncation rows stay within the collapsed output budget
- Updated search path handling to support path lists and internal file paths while preserving previous search behavior
[14.5.3] - 2026-04-27
Added
- Added bracketed
locforms(anchor),[anchor],[anchor,(anchor,anchor], andanchor)toatomspliceediting so a single anchor can target a block body, whole node, or partial node region - Added automatic block-delimiter inference for block splices using file extension, defaulting to
{and using(for Lisp-family files - Added optional
pre/postarguments to thehrefprompt helper so hashline references can be wrapped as bracketed or parenthesized anchors - Added destination-aware indent handling for block replacements by detecting file indent style and reapplying tabs/spaces to spliced body text
Changed
- Changed bracketed atom locators to be
splice-only and rejectpre,post, orsedon region locators - Changed
applyAtomEditsto forbid mixingsplice_blockwith other anchor-scoped edit verbs in one call - Changed
splice_blockresolution behavior to include selected block range and enclosing-count context in warning output - Changed balanced-block parsing to support
kindselection ({,(,[), nesting depth, and safer same-line enclosing selection
Removed
- Removed the
sedFoption for literal matching;sednow accepts onlypat,rep, and optionalg, withF-style literal matching no longer supported
Fixed
- Fixed
splice_blockmulti-line replacements to replace the exact target region and avoid duplicate braces or duplicated signature lines from bare-anchorspliceattempts - Fixed false-positive “unbalanced” replacement-body warnings caused by braces in regex/string/comment text by skipping those constructs during block scanning
- Fixed
splice_blockfor same-line(bodies so inline call sites likeint(port)can be replaced correctly
[14.5.2] - 2026-04-26
Breaking Changes
- Removed support for sed-style string expressions and required
sedto be specified as an object withpatandrep(and optionalg,F,iflags)
Changed
- Changed atom
sedreplacements to be global by default and requireg:falsefor first-match-only replacements - Changed anchor validation so multiple
sedoperations can target the same line and run sequentially - Changed cross-entry conflict resolution so
deledits on an anchor are ignored when that line is also replaced bysedorsplicein another edit entry
Fixed
- Fixed zero-length regex
sedpatterns (for example(),^,$) to fall back to literal substring matching instead of producing insertion-like replacements - Fixed
sedchaining so each edit on the same anchor applies to the latest line state from prior replacements
[14.5.1] - 2026-04-26
Removed
- Removed
\tescaped-tab indentation autocorrect from hashline and atom edit modes (and thePI_HASHLINE_AUTOCORRECT_ESCAPED_TABSenvironment toggle); literal\tin edit content is now preserved verbatim - Removed the suspicious-
\uDDDDwarning preflight from hashline edits - Removed the hand-rolled JSON unescape fallback in the streaming edit-arg renderer; partial fragments that fail
JSON.parseare now surfaced raw rather than partially decoded with a non-spec-compliant unescaper that mishandled lone surrogates
[14.4.3] - 2026-04-26
Added
- Added
irctool for agent-to-agent messaging withlistandsendoperations, including optional broadcast toalland optional suppression of reply waits - Added
irc.enabledtool setting (defaulttrue) to toggle agent-to-agent messaging - Added live in-chat rendering of IRC incoming and auto-reply messages so peer messages now appear in the session transcript
Changed
- Changed peer-aware prompts for subagents to include currently live agent peers and IRC usage guidance when available
- Changed the
/btwhelper to use a session-side ephemeral turn path that preserves streaming-context handling and updates the existing request handling behavior - Merged the
pollandcancel_jobtools into a singlejobtool that acceptspollandcancelarrays; the renamed tool reuses the richer poll renderer for both polling and cancellation calls
Fixed
- Fixed IRC messaging to use a background ephemeral turn path so a recipient can reply even while its main loop is busy
- Fixed
/btwhandling of empty prompts and missing model configuration by rejecting invalid requests before starting a stream - Fixed
/btwrequest replacement so issuing a new query cleanly aborts the previous active request
[14.4.2] - 2026-04-26
Breaking Changes
- Changed
/todo appendfrom JSON payload input to/todo append [<phase>] <task...>with optional quoted tokens and automatic phase creation
Added
- Added
noteto todo-write operations so you can append follow-up text notes to a task viaop: "note"andtext - Added markdown note-block support to
/todo exportand/todo importso task notes are written as blockquote lines and reloaded with the todo list - Added
/todo export <path>to write the current todo list as Markdown to a file, defaulting toTODO.mdwhen no path is provided - Added
/todo import <path>to replace the current todo list from a Markdown file, defaulting toTODO.mdwhen no path is provided - Added live poll progress updates so the UI now emits intermediate job state while waiting for jobs to finish
- Added a dedicated TUI renderer for the
polltool that displays job status, counts, duration, and result/error previews - Added a
/todoslash command to view and modify todos withedit,copy,start,done,drop,rm,append, andreplaceoperations - Added
/todo editto open the current todo list in$EDITORas Markdown and sync the edited checklist back into the session - Added
/todo copyto copy the rendered Markdown todo list to the clipboard
Changed
- Changed todo list rendering and summaries to show a
+Nnote marker on task lines and display attached notes for tasks in progress - Changed
/todo start,/todo done,/todo drop, and/todo rmto resolve task/phase targets by fuzzy id/name matching instead of strict identifiers - Removed
/todo replacefrom supported slash commands - Changed todo list restoration to include user todo-edit custom session entries so slash-command and editor-based todo updates persist after reload
- Restored sensible defaults for
grep.contextBefore(1) andgrep.contextAfter(3) so grep matches show context lines by default after thepre/postparameters were folded into settings
Removed
- Removed the
chunkedit mode, chunk-awarereadselectors, chunk-awaregreprendering, and theomp readchunk CLI subcommand - Removed the
read.prosechunks,read.explorechunks, andread.anchorstylesettings - Removed the underlying
chunknative module and AST-based chunk schema generation frompi-natives
Fixed
- Fixed poll final output to reflect live job data from the async job manager, improving status and result visibility
- Fixed job duration and output reporting to use current job snapshots instead of initial poll input metadata
- Fixed
pollwait duration parsing to fall back to30swhen the provided value is an empty string
[14.4.1] - 2026-04-26
Breaking Changes
- Replaced the legacy
gh_repo_view,gh_issue_view,gh_pr_view,gh_pr_diff,gh_pr_checkout,gh_pr_push,gh_run_watch,gh_search_issues, andgh_search_prstool names with onlygithub, which requires updating existing callers that invoked the oldgh_*tools
Added
- Added a
sedverb to theatomedit tool for line-local substitutions using sed-style syntax (s/pattern/replacement/) withg,i, andFflags and model-tolerant delimiter choices - Added the unified
githubtool with op-based dispatch for repository, issue, pull request, search, checkout, push, and Actions watch workflows - Added
oprouting so callers can selectrepo_view,issue_view,pr_view,pr_diff,pr_checkout,pr_push,search_issues,search_prs, orrun_watchthrough a single tool entry point
Changed
- Changed hashline-based read and match output formatting to use
LINE+ID|contentas the anchor/content separator, and updated match/context markers to>for matches and:for context - Updated GitHub CLI render output to show
GitHub <op>for tool calls dispatched throughgithuboperations
Removed
- Removed the built-in
taploLanguage Server entry from default LSP settings, so TOML files no longer have default TOML server startup
Fixed
- Fixed
atomlocparsing so path-qualified anchors likepath:263ti| ...and single-anchor locs containing hyphens no longer mis-parse as ranges - Fixed hashline anchor handling in
atomedits so a provided content hint after the anchor (|or:suffix) can rebond a stale hash to the intended line - Fixed
atomsedexecution to tolerate common model-emitted forms such as/pat/rep/, and to apply safe literal fallbacks for regex failures or metacharacter-heavy patterns while still erroring when no match is possible
[14.4.0] - 2026-04-26
Breaking Changes
- Removed multi-pattern array input from
ast_grepby changingpatto a single pattern string, so call sites usingpat: [...]must be updated to send one query per invocation - Removed
lang,glob, andseloptions fromast_editandast_grep, and moved those behaviors into the requiredpathargument - Required
pathforast_editandast_grep, so invocations that relied on implicit repo-root searching are no longer valid - Changed
todo_writefrom multi-field verb payloads to an ordered array of flat operations, while retainingreplacefor harness bootstrap compatibility - Renamed atom edit operations from
beforeandaftertopreandpost, so existingatompayloads using the old operation keys must be updated - Changed the hashline anchor format from
LINE#ID:contenttoLINEID:content(no#separator, colon between anchor and content, no padding on line numbers); expanded the bigram alphabet from 40 hand-picked English bigrams to the full 647 single-token 2-letter bigrams — invalidates every previously capturedLINE#IDreference - Renamed the subagent completion contract from
submit_resulttoyield, so subagent sessions must now finish with theyieldtool and therequireYieldTooloption;submit_result/requireSubmitResultTooland old completion calls are no longer recognized - Changed the hashline and chunk anchor ID format from the prior hex-like tokens to two-letter BPE bigrams (for example
#th), which invalidates previously capturedLINE#ID/chunk selectors and requires re-reading to refresh anchors
Added
- Added inline file overrides in atom locators (
loc: "a.ts:160sr") so cross-file edits can be written without a separate per-entrypathfield - Added
openaito theproviders.imageoptions, allowing image generation to be explicitly routed through the active GPT Responses/Codex model - Added
betweenatom edit operation to replace only the lines between two surviving anchors while preserving the boundary anchors - Added conflict detection for
betweenatom edits to require non-overlapping regions and forbid edits targeting lines strictly inside those regions - Added
atomedit mode toeditwith single-anchor operations (set,before,after,del,sub,ins) for hashline-anchored line edits - Added support for request-level
pathdefaults in patch, replace, and chunk edits so shared file paths no longer need to be repeated in every entry
Changed
- Updated
atomandhashlineedit anchor validation to auto-rebase a stale anchor within ±2 lines when the same hash matches a unique nearby line, continuing the edit with a warning instead of immediate failure - Changed bash command output labels from
[full result: artifact://…]to[raw output: artifact://…]for artifact references produced from large command output - Changed
todo_writedone,rm, anddropoperations to target all tasks when neithertasknorphaseis provided, and madeappendcreate the target phase automatically when missing - Updated
ast_editandast_grepto pass file-selection intent throughpath(including inline globs and comma/space-separated path lists) instead of separateglobfilters - Changed
ast_greppagination API fromoffsettoskip - Flattened
todo_writeoperation arguments to{ op, task?, phase?, items? }[]and removed task details from the persisted todo shape - Changed
greptruncation output to reportResult limit reached; narrow path.and label match/result caps asfirst N - Changed JSON tree output to truncate inline argument pairs by available width and add an ellipsis when values no longer fit in the display
- Changed JSON tree rendering to hide harness-internal
intentand__partialJsonfields from top-level tool output - Simplified the
greptool schema by requiringpath, folding glob and type filtering into path globs, auto-detecting multiline patterns, removing model-controlled context and limit options, and renaming result skipping toskip. - Changed atom edit request format to use a shared
locselector, including range ("160sr-9ab") and boundary ("^","$") forms instead of per-operation anchor fields - Changed atom edit payload fields so
set,pre, andpostnow require line-array values andsubnow takes a[find, replace]tuple, with boundary deletion now expressed asset: [] - Changed edit diff wrapping to preserve the active line-prefix separator (
|or│) while keeping continuation lines aligned by line-number width - Changed Vim focus and viewport rendering to align cursor/selection markers and line numbers in a single gutter format
- Changed auto image provider selection for
providers.image=autoto try active GPT image generation before Antigravity, OpenRouter, and Gemini - Updated atom and hashline anchor validation to require the full
line+suffixanchor format and report missing-line-number errors more clearly, including guidance when only a 2-letter suffix is provided - Changed read, grep, and ast-edit line-prefixed output to drop fixed-width line number padding, so anchors render in natural width without leading spaces
- Updated terminal diff rendering to use a continuous
│gutter and hide repeated line numbers on adjacent diff lines - Updated subagent reminders, prompts, and rendered subagent output to reference
yieldcompletion and report missing/final results fromyieldtool data - Updated the
editworkflow to treatatommode like hashline mode for read output, so hashline anchors are shown whenatomis selected - Adjusted patch/replace/chunk tooling to accept optional entry paths and to apply a top-level path default
- Updated hashline/chunk selector parsing to the new stable bigram token set used for checksums
- Renamed the image generation implementation module to
image-genand routed active GPT Responses/Codex models through OpenAI's hostedimage_generationtool with WebP output
Removed
- Removed line-range support from
atommode selectors, includinglocvalues like160sr-170ab, so edits must target a single anchor (160sr,^, or$) per entry - Removed the atom
delverb and now require anchored-line deletion to be requested withset: [] - Removed
todo_writetask details and theadd_notesoperation
Fixed
- Improved no-op edit diagnostics for
atomandhashlineoperations so edits that leave content unchanged now fail with contextual details (edit index, locator, and reason), including guidance forreplace_rangeno-op cases - Wrapped
todo_writeoperations in anopsobject so Codex/OpenAI function schemas always use a JSON Schema object. - Fixed JSON tree rendering for tool arguments by excluding injected internal keys from displayed root records
- Printed assistant
errorMessagetext in print mode output to stderr so message-level errors are visible during non-interactive runs - Displayed assistant
errorMessagetext in the assistant message component for completed tool responses with non-terminal stop reasons - Fixed atom input handling to ignore null optional verb fields so entries with
pre,set,post, orsubset tonullremain valid - Fixed status-line Git branch rendering to degrade gracefully when the process hits
ENFILE/EMFILEwhile reading optional Git refs - Changed hashline mismatch failure output to show a clean numbered context block with numbered gutter and full-anchor alignment guidance when edits are rejected after the file changed
- Fixed
atommode to apply multiple edits on the same anchor line without index-shift artifacts, so mixed operations likebefore,after,set,sub,ins, anddelnow resolve consistently - Fixed
atommodeappend_fileinsertion to preserve a file’s trailing newline sentinel when appending content - Fixed
readoutput for raw archive entries so hashline anchors, line numbers, and chunked formatting are not injected into raw content - Fixed hashline parsing so lines like
# Note:or# TODO:are no longer misinterpreted and stripped as hashline prefixes - Adjusted patch and replace validation to report a clear missing-path error when neither an entry path nor a top-level path is provided
[14.3.0] - 2026-04-25
Added
- Added Markdown pipe-table
row_Nchunk selectors for row-level table edits. - Added
resolveToolAliasexport so tool names in CLI and session setup are normalized to canonical names, including mapping legacyreadreferences toopen - Added new
openandopen-chunktool prompt documentation pages to describe canonicalopenusage for local files/directories, chunk reads, and URLs - Added full-output retrieval metadata to minimized shell command output by appending an
artifact://<id>footer with byte counts, allowing users to open the original unminimized command output - Added streaming preview API exports from the package (
resolveEditMode,EDIT_MODE_STRATEGIES, and chunk preview helpers) so editors can reuse mode-aware edit preview logic programmatically - Added
shellMinimizerconfiguration options (enabled,settingsPath,only,except, andmaxCaptureBytes) so users can control shell output minimization behavior
Changed
- Changed the canonical file/URL reader tool from
readtoopenacross default tool lists and routing, including system prompts, plan mode, cursor handlers, and runtime tool registration - Changed runtime and UI handling to render and track
opentool calls as first-class (withreadaccepted as legacy alias), including ACP mapping, session observers, and streaming message groups - Changed chunk edit guidance to document parser-specific region behavior, including TypeScript decorator/JSDoc sibling chunks, Python docstrings as body content, Python opaque nested chunks, Markdown whole-chunk fallbacks, ID volatility, and indentation display differences
- Changed chunk deletion in chunk edit mode to require explicit
delete: true;write: nulland bare{ path }entries now fail with guidance instead of deleting content. - Changed chunk edit validation to reject entries with multiple operation fields instead of choosing one and ignoring the rest.
- Changed chunk edit validation to reject
write: ""as an accidental destructive empty replacement; use the open tool for inspection ordelete: truefor deletion. - Changed chunk edit responses to warn when appending or prepending to a container without
~, since that inserts outside the container rather than inside its body. - Changed fetch output logging so URL-fetch artifacts now use
.open.lognaming instead of.read.log - Changed Bash interception guidance and errors to recommend
openin place ofreadfor cat/head/tail-style commands - Changed exported SDK tool surface to expose
OpenToolas canonical and keepReadToolas a compatibility alias - Changed session list loading to use parallel workers and fixed-size prefix reads per session file, reducing latency when loading many or large sessions
- Changed edit call rendering to use mode-aware streaming diff previews, including multi-file chunk edit previews grouped by file path while arguments are still streaming
- Changed shell execution in both interactive and non-interactive modes to route command output through the configured shell output minimizer
- Changed default behavior so shell output minimization can now be toggled from settings without code changes
- Changed shell output minimization to leave compound and piped commands unchanged; only a single eligible whole command is captured and minimized after it exits
Removed
- Removed the chunk edit
read: trueoperation; use the open tool to inspect chunks without modifying files. - Removed the
replace: { old, new }chunk edit operation. Usewriteorinsertfor chunk edits instead.
Fixed
- Fixed startup crashes on Linux systems where Bun's
os.cpus()fails on non-contiguous CPU numbering (#779) - Fixed
gh_pr_pushso branches withoutgh_pr_checkoutmetadata fail instead of falling back to the tracked merge branch, and updated the GitHub tool setting copy to stop calling the tool group read-only (#778) - Fixed session list metadata extraction to better populate session titles and first-user summaries from partial session data when full JSONL parsing is unavailable
- Fixed shell execution output to replace raw streamed bash output with the minimizer’s rewritten text before final output while still preserving the full original output as artifact metadata
- Fixed bash command minimization to save the full unminimized output as a
bash-originalartifact during AgentSession shell execution, enablingartifact://access to complete command output - Fixed streaming chunk previews that could display an incomplete trailing edit as a deletion when partial JSON temporarily converted in-flight values to
null - Fixed edit streaming preview updates to cancel obsolete in-flight computations and avoid rendering stale previews as args change
- Fixed chunk edits to reject unsafe
^/~writes on code leaf chunks instead of falling back to whole-chunk replacement and risking structural indentation corruption - Fixed chunk
replaceoperations to dedent multiline replacement snippets before reapplying the matched source indentation, preventing Python nested replacements from compounding indentation on repeated edits. - Fixed Go chunk trees to classify
packageclauses separately from imports and to avoid duplicating method receivers in method summaries. - Fixed chunk path-not-found guidance so it recommends
sel="?"without claiming the already-shown listing must be re-read. - Fixed Markdown chunk appends to preserve blank-line separators after line-oriented inserts such as table rows
- Fixed Markdown section region-fallback warnings to call out child chunks that will be replaced by whole-section edits.
- Fixed rejected chunk-edit errors to distinguish current file content from hypothetical post-edit parse-error previews and to state when a same-file batch was rolled back.
- Fixed unsafe Python head-region edits by rejecting decorated Python
^writes and Python^deletes that can orphan indented bodies while still parsing. - Fixed Markdown table-row appends so row-shaped content lands inside the table block instead of after the trailing blank-line separator.
- Fixed Markdown root writes to preserve fenced-code indentation verbatim.
- Fixed Rust enum-variant replacement matching so trailing commas are included consistently with whole-variant writes.
- Fixed streaming edit call headers to keep showing the target file path while the edit arguments are still arriving
- Fixed Mermaid fenced markdown rendering in assistant messages on terminals without image protocol support (#650)
- Fixed chunk edit path parsing so plan-mode edits to section-addressed
local://PLAN.md:<selector>paths are classified as writes to the plan file - Fixed SQLite
readhelper queries to rejectwhere=clauses with SQL control syntax that could override the structured selector's pagination; raw SQL remains available throughq=SELECT ...
[14.2.0] - 2026-04-23
Added
- Added an
apply_patchedit mode that accepts Codex*** Begin Patchenvelopes, shares patch-mode execution and diagnostics, and renders streaming per-file diffs in the TUI.
Changed
- Changed Spark models to default to
apply_patchedit mode instead ofreplace. - Tightened the contract for
SearchParams.recencyinweb/search/providers/base.ts: providers MUST interpret recency as a pure time filter and MUST NOT use it as an implicit signal to change topic scope, content domain, or ranking strategy. - Inline read tool previews are now optional via
read.toolResultPreviewand default to off
Fixed
- Fixed
apply_patchstreaming previews to avoid showing the missing*** End Patchparse error while the patch body is still arriving. - Fixed diagnostics rendering to replace tabs before TUI output, preventing compiler messages from breaking tree alignment.
- Fixed compiled
ompbinaries to ignore project-localbunfig.tomland.envautoloading at startup, preventing unrelated project config from crashing or preloading code into the CLI - Fixed edit tool diff and replace operations to report missing-file failures as
File not found: <path>errors instead of raw filesystem ENOENT errors - Fixed
local://URL path leak on Linux where//collapsing to/producedlocal:/pathforms that bypassed the internal protocol handler and leaked as filesystem paths, breaking plan mode file resolution - Fixed Darwin compiled binaries failing to start under Bun 1.3.12 by ad-hoc signing local and release binary builds after applying Bun's no-codesign workaround (#754)
- Fixed Tavily web search silently returning off-topic news articles when
--recencywas set. The provider was unconditionally couplingtopic: "news"to recency, which scoped Tavily's index to news publications and excluded documentation, release notes, GitHub, and all non-news technical content. Technical queries with--recencynow return the correct corpus. - Fixed status-line sanitization to strip OSC, DCS, PM, APC, and 8-bit CSI escape sequences instead of leaving payload fragments in the UI
- Fixed inline read tool previews to avoid rendering duplicate summary rows above the same code cell
[14.1.3] - 2026-04-17
Breaking Changes
- Replaced the legacy
todo_writeops-based API (replace,update,add_task, andremove_task) with direct top-level fields, requiring migration of any callers using the old request shape - Removed in-place updates to existing task
content,details, andnotesviatodo_write; note changes now append throughadd_notes - Phased task definitions in
todo_writenow rejectnoteson initial creation, so notes must be added later withadd_notes
Added
- Added
complete,start,abandon,remove,add_notes, andadd_tasksparameters totodo_writeso callers can complete, jump to, drop, and annotate tasks without op wrappers - Added direct
add_phasesupport as a top-level argument for inserting a new phase intodo_write - Added
task.simplewithdefault,schema-free, andindependentmodes so the task tool can disable task-callschemaand sharedcontextinputs while preserving agent-defined and inherited subagent schemas
Changed
- Changed
add_tasksto insert tasks by phase name or ID and allow multiple tasks to be added in one call
Fixed
- Fixed task calls in
schema-freeandindependentmodes to return clear mode-specific errors when disallowedcontextorschemainputs are provided - Fixed newly generated session IDs to use UUIDv7 for new, forked, and branched sessions while preserving resumed session IDs
[14.1.1] - 2026-04-14
Breaking Changes
- Removed the standalone
vimtool from built-in tool lists, so vim-style editing is now invoked througheditinvimmode - Removed the
searchDbfield from session and extension tool contexts, so custom tools and extensions no longer receive a shared native search DB handle fromToolSession,CustomToolContext,ExtensionContext, andCreateAgentSessionOptions - Changed the
vimtool API to require eitheropen: "path"orkbd: [...]per call and removed directline/colcursor parameters fromopen, so callers must position the cursor via key sequences after opening - Changed the
editschemas for patch, replace, hashline, and chunk modes from top-level request fields toeditsarray entries, requiring path/mode details on each edit and breaking callers that send legacy top-levelpath,old_text,new_text,op,move, ordeletepayloads
Added
- Added Vim ex aliases
:del,:ya,:co, and:moas shorthand for existing delete, yank, copy, and move commands - Added support for additional Vim ex command aliases
:write/write!,:edit/edit!, and:update/:upin command parsing - Added support for vim
:globaland:vglobal//variants as:g/pattern/dand:v/pattern/dparsing and execution - Added support for extra Vim operations by treating
x,X,s,S,C, andDas delete/change operator aliases - Added support for new Vim motions
gE/ge,g_,g*,g#, and| - Added support for
C-fandC-bpage motions in vim mode - Added
C-uandC-oin vim insert mode to clear to line start and execute a one-off normal-mode command before returning to insert - Added insert-mode visual operators
J,u,U,p, andPto join lines, convert case, and replace the selected region with register content - Added normal-mode line motions
+,-, and_to move to line offsets at the first non-blank character - Added
*and#normal-mode commands to search forward or backward for the word under the cursor - Added
gJto join a line range,gvto restore the last visual selection, andZZ/ZQshortcuts for save-and-exit or exit-without-save in vim mode - Added paragraph text object
pforip/ap-style paragraph selection - Added support for Vim ex line-address forms like
.,$,+N/-N, destination addresses such as:t$, and ranged:globalcommands - Added Vim ex
:join/:jand:join!/:j!support to join addressed lines with or without whitespace normalization - Added a warning when chunk edits write to the
~selector with body lines that appear over-indented, instructing users to start top-level body text at column 0 - Added validation feedback for suspect indentation in chunk-mode
~body writes so users can align content with the tool's automatic base indentation - Added support for multi-file
editcalls across replace, patch, hashline, and chunk modes by groupingeditsentries by file path and returning combined per-file results - Added per-edit
pathsupport in chunk entries so each operation can target explicit files when submitting mixed edits in a single request - Added support for
computeHashlineDiffto accept hashline edits withlocandcontentpayloads without requiring pre-resolvedopfields - Added
/rename <title>slash command to set an explicit session name, updating the session header and terminal tab title (#658) - Added
session_namestatus line segment: displays the session name in the status bar right side with a stable hash-derived accent color unique to each name; shown in all presets when a name is set
Changed
- Changed vim path normalization to accept colon-prefixed
pathvalues instead of rejecting them as Vim commands - Changed default
providers.openaiWebsocketssetting tooffwhen unset, so OpenAI websocket transport is now disabled unless explicitly enabled - Changed Vim ex
:update/:upexecution to skip writing unchanged buffers and report buffer unchanged status - Changed Vim page-scroll commands
C-f,C-b,C-u, andC-dto move in viewport-height based increments instead of fixed constants - Changed
zcommand behavior sozt,zb, andz.now align cursor movement to first non-blank in the line - Changed
:g/:vglobal command handling to process matching lines safely by working in reverse order and preserving file structure - Changed vim tab breadcrumb rendering from
→to→in the editor view - Changed custom tool and task execution contexts to no longer expose a shared
searchDbaccessor, removing direct access to native grep/glob/fuzzyFind search backends from extension callbacks - Changed the
tasktoolschemafield to require JSON-encoded JTD schema text instead of a schema object, matching prompt guidance and task-subagent invocation - Changed chunk edit payloads to encode selectors as
path: "file:selector"and updated chunk tool guidance and examples to match - Updated
editcall/result rendering to show per-file diff sections and append a(+N more)hint when edits target multiple files - Grouped chunk-mode
grepresults by directory, file, and chunk so directory searches now render as hierarchical sections (#/##) with per-chunk anchor lines - Updated chunk-mode
grepoutput to include match lines under their containing chunk entries with consistent line-number alignment based on file length - Changed eager todo enforcement to only apply on the first user message of a conversation, skipping subsequent user turns that may correct, clarify, or redirect the prior task
Removed
- Removed live in-progress Vim tool previews during streaming call execution, so the TUI now shows only the last completed file viewport until the call finishes
Fixed
- Fixed vim-mode multi-step line edits by auto-reordering ascending line-positioned commands to descending order before execution
- Fixed Vim viewport rendering to display the inline highlighted cursor character and keep long cursor lines centered around the cursor in tool previews
- Fixed Vim
:globalcommand defaults to handle only supported subcommands and report unsupported ones explicitly - Fixed Vim ex execution so parsed
:update,:yank, and:putcommands now run instead of falling through - Fixed vim tool rendering so streamed calls preview the live target viewport and large insert payloads update incrementally instead of popping in all at once
- Fixed session event delivery so streaming
message_update/tool-call previews reach the TUI immediately instead of waiting for extension handlers to finish - Fixed HTML session export rendering so background-job wait calls render as
pollinstead of staleawait, while still recognizing legacy exported sessions - Fixed OpenRouter model resolution to accept dated routed selectors such as
openrouter/z-ai/glm-4.7-20251222:nitro, inheriting metadata from the base catalog model when the exact variant is not listed yet - Fixed pre-execution edit preview routing so replace/patch/hashline mode diffs are computed from the new structured edit entries
- Adjusted chunk/hashline/prompt guidance and validation to align with the refactored per-entry schema
- Fixed chunk streaming output detection to verify chunk edits with
chunkToolEditSchema, preventing non-chunk edit payloads from being rendered as chunk diffs - Fixed tool execution output to return the original
toolResulttext content from tools instead of sanitizing it before sending completion messages - Fixed session accent rendering in the status line and editor to reset only foreground color (
\x1b[39m) so applying a session color no longer clears other ANSI styles - Session name sanitization: strip C0/C1 control characters (including ANSI ESC) from session names at storage time and in status line rendering, preventing escape sequence injection into TUI output
- Auto-generated session titles no longer overwrite a name set via
/rename:setSessionNamenow tracks whether the name was set by the user or auto-generated and silently ignores auto titles once a user name is in place; terminal title follows the same guard - Session accent border color now applied on session resume and after auto-title generation, not only after an explicit
/rename - Fixed retained Python kernel ownership so
AgentSession.dispose()only shuts down kernels owned by that session, including warmup-created kernels
[14.1.0] - 2026-04-11
Added
- Added richer tool rendering details in session export HTML, including metadata badges, argument formatting, and todo task tree styling for exported tool and workflow messages
- Added a persistent
jstool backed bynode:vm, with cross-sessionhighwayKV/pubsub, tool calls from inside JS cells, and$/$$interactive JavaScript execution - Added SQLite database read support to the
readtool for.sqlite,.sqlite3,.db, and.db3files with table listing, schema + sample output, row lookup, paginated query filtering, and read-onlyq=SELECTmode - Added SQLite mutation support to the
writetool sodb.sqlite:tableinserts JSON5 rows anddb.sqlite:table:keyupdates or deletes rows via row key - Added rendering of usage report entries for accounts with no usage limits, including account label and optional plan type with a
-- no limitsindicator - Updated account label resolution to fall back to email or accountId so unlabeled unlimited-plan accounts display a meaningful name
- Added canonical model equivalence and provider coalescing across
models.yml,enabledModels,--models,/model, and--list-models - Added
equivalenceoverrides/exclusions tomodels.ymlandmodelProviderOrdertoconfig.ymlfor global canonical-provider preference
Changed
- Enabled
awaitandcancel_jobto be available whenbash.autoBackground.enabledis set, so auto-backgrounded bash jobs can be awaited or cancelled without enablingasync.enabled - Updated bash auto-background behavior so short commands returned inline output when they completed before the configured threshold, while longer runs moved to background jobs automatically
- Replaced the LLM-callable Python execution path with JavaScript execution in the shared VM context, including updated renderers, prompts, session messages, and extension events
- Updated interactive and CLI model listings/selectors to work with canonical model ids while resolving them to concrete provider variants for actual execution
- Updated role assignment persistence so selected model settings now store the selector used by users, including thinking-level suffixes, while runtime continues to run against the resolved concrete provider model
- Updated model scope resolution to expand exact canonical model ids into all matching provider variants when filtering supported model sets
- Changed the agent to avoid giving time estimates or task-duration predictions in user responses, focusing on required work instead
- Changed generated code guidance to avoid speculative abstractions and extra compatibility scaffolding, favoring direct implementations that match current needs
- Changed model role resolution so roles can store either canonical model ids or explicit
provider/modelselectors while sessions continue to record the concrete model actually used - Updated bash execution to optionally auto-background long-running commands through the existing background-job pipeline, with dedicated settings for enabling the behavior and adjusting the delay
Fixed
- Fixed session export rendering so JavaScript execution messages now use
jsExecutionlabels and content instead ofpythonExecution, matching current tool behavior - Fixed JavaScript cell execution to auto-display returned values once and preserve persistent VM bindings across calls until reset
- Fixed
.db/.db3reads to verify SQLite file headers and fall back to normal file reading when the extension matches but the content is not a SQLite database - Fixed SQLite selector parsing and resolution to correctly route requests to database operations at the file-extension boundary instead of misrouting through plain file/archive handlers
- Fixed unsupported or unsafe selectors by rejecting missing tables, composite primary keys for row lookups, unknown query parameters, and row operations on non-existent tables
- Fixed model resolution for commit message generation, title generation, memory consolidation, and image inspection when role strings use canonical ids instead of raw provider/model values
- Fixed default-model updates so previously configured thinking levels were preserved when reassigning a role
- Fixed model scope and selection handling in CLI/session startup paths that previously failed to resolve aliases consistently across features
- Fixed short-lived git subprocesses to disable
core.fsmonitorandcore.untrackedCache, avoiding unnecessary repository watchers and cache work during agent git operations
Security
- Blocked destructive SQL execution in read-mode SQLite access by using read-only connections and rejecting bound-parameter raw SQL
[14.0.5] - 2026-04-11
Added
- Added
designermodel role for UI/UX design tasks with Gemini 3.1 Pro as default model - Added support for model role fallback lists — roles can now resolve to multiple model patterns with automatic fallback to next available model
- Added
extractReadableFromHtmlutility function to extract readable content from HTML with Readability article extraction and CSS selector fallback - Added support for GFM (GitHub Flavored Markdown) features including tables, strikethrough, and task lists in HTML-to-markdown conversion
- Added
resolveDiagnosticTargetsutility function to handle glob pattern resolution with fallback to literal file paths for bracket-style paths
Changed
- Clarified fenced code block editing behavior in markdown — the tool now preserves literal indentation inside fenced blocks, with content written verbatim as supplied
- Updated guidance for inserting content after markdown section headings to use
afteron the heading chunk rather thanbefore/prependon the section itself - Reduced default image resize limits to 1568px (from 2000px) and 500KB (from 4.5MB) to match Anthropic's internal downscaling threshold and reduce payload sizes in tool calls
- Adjusted screenshot compression to use 1024px max dimensions and 150KB budget for more aggressive optimization of browser screenshots in LLM requests
- Updated JPEG quality defaults from 80 to 75 and refined quality ladder steps (70, 60, 50, 40) for tighter byte budgets
- Improved image resize fast-path to skip re-encoding when images are already within dimensions and at ≤25% of byte budget, avoiding unnecessary processing of small icons and diagrams
- Clarified that chunk names are truncated and must be copied from
reador?output rather than constructed from source identifiers - Enhanced guidance for editing fenced code blocks in markdown to preserve exact whitespace using
rawreads, as the tool normalizes tabs to spaces which can damage indentation-sensitive content - Updated designer agent to use
pi/designerrole alias instead of explicit model list - Refactored model role resolution to support multiple fallback patterns per role, improving model availability handling
- Replaced regex-based HTML-to-markdown conversion with Turndown library and GFM plugin for more accurate formatting of complex HTML structures
- Simplified no-changes response to omit redundant response text when chunk content already matches
- Clarified region suffix behavior on leaf and compound statement chunks —
~and^now fall back to whole-chunk replacement with explicit guidance to supply complete structural content - Updated CRC refresh guidance to direct users to use CRCs from edit responses or run
read(path="file", sel="?") - Added clarification that region suffixes fall back to whole-chunk replacement for prose and data formats (markdown, YAML, JSON, fenced code blocks, frontmatter)
- Documented
L20shorthand syntax for single-line reads extending to end-of-file, withL20-L20for one-line windows - Refactored diagnostic target resolution to use new
resolveDiagnosticTargetsfunction, consolidating glob pattern detection and file matching logic - Updated chunk selector syntax from
@regionformat to~(body) and^(head) suffixes for more concise region targeting - Simplified chunk edit documentation to use new
~and^region syntax instead of@head,@body,@tail,@declkeywords - Replaced internal
raceAbortfunction with importedraceWithAbortutility from pi-utils - Refactored cleanup timer to use async iterator pattern with
timers.setIntervalinstead ofsetInterval - Made
#cleanupIdleSessionssynchronous and moved async cleanup loop logic to new#runCleanupLoopmethod - Replaced regex-based
htmlToBasicMarkdownwith a Turndown + GFM plugin pipeline (tables, strikethrough, task lists, nested lists now convert correctly). Added directturndownandturndown-plugin-gfmdependencies
Fixed
- Fixed chunk edit tool to report file-not-found error distinctly when attempting to use chunk selectors on non-existent files, with guidance to use write tool or verify the path
- Fixed stale child selector reuse to correctly match chunks by checksum when multiple sibling chunks with the same name exist under the same parent
- Fixed stale diagnostics being reused after unrelated file publishes by clearing cached diagnostics before refreshing file state
- Fixed Codex search to use streamed answer text when final answer is an image placeholder or empty
[14.0.4] - 2026-04-10
Added
- Added
PI_CHUNK_AUTOINDENTenvironment variable to control whether chunk read/edit tools normalize indentation to canonical tabs or preserve literal file whitespace - Added dynamic chunk tool prompts that automatically adjust guidance based on
PI_CHUNK_AUTOINDENTsetting without exposing a tool parameter - Added
<instruction-priority>,<output-contract>,<default-follow-through>,<tool-persistence>, and<completeness-contract>sections to system prompt for improved long-horizon agent workflows
Changed
- Updated chunk edit tool to apply
normalizeIndentsetting during edit operations, enabling literal whitespace preservation whenPI_CHUNK_AUTOINDENT=0 - Refactored environment variable parsing to use
$flag()and$envpos()utilities from pi-utils for consistent boolean and integer handling across codebase - Updated system prompt communication guidelines to emphasize conciseness and information density, and added guidance on avoiding repetition of user requests
- Enhanced system prompt with explicit rules for design integrity, verification before yielding, and handling of missing context via tool-based retrieval
- Added
PI_CHUNK_AUTOINDENTto control whether chunk read/edit tools normalize indentation, and updated chunk prompts to switch guidance automatically based on that setting - Refined the default system prompt with explicit instruction-priority, output-contract, tool-persistence, completeness, and verification rules for long-horizon GPT-5.4-style agent workflows
Fixed
- Fixed typo in system prompt: 'backwards compatibiltity' → 'backwards compatibility'
[14.0.3] - 2026-04-09
Fixed
- Fixed cached Ollama discovery rows so upgraded installs switch to the OpenAI Responses transport instead of staying on the old completions transport
[14.0.2] - 2026-04-09
Added
- Added
/forceslash command to force the next agent turn to use a specific tool - Added
ToolChoiceQueuefor managing tool-choice directives with lifecycle callbacks and requeue semantics - Added
setForcedToolChoice()method to AgentSession to programmatically force tool invocations - Added
toolChoiceQueueproperty to AgentSession for direct queue access - Added
peekQueueInvoker()method to AgentSession to retrieve in-flight tool invocation handlers - Added
queueResolveHandler()function as the canonical entry point for preview/apply workflows - Added
buildToolChoice()andsteer()methods to ToolSession for tool-choice queue integration - Added
getToolChoiceQueue()method to ToolSession for accessing the tool-choice queue - Added support for embedded URL selectors (
:rawand:L#-L#line ranges) in read command paths - Added
parseReadUrlTargetfunction to parse and validate URL read targets with line range support - Added
declregion to chunk selector for targeting declarations without leading trivia - Exported
hookssubpath for extensibility API access - Added
buildscript for compiling binary artifacts
Changed
- Refactored pending action handling from
PendingActionStoretoToolChoiceQueuewith generator-based directives - Changed tool-choice override mechanism from simple override to a queue-based system with callbacks
- Updated
ResolveToolto dispatch to in-flight queue invokers instead of popping from a pending action store - Updated custom tool loader to accept
pushPendingActioncallback instead ofPendingActionStoreinstance - Updated
AstEditToolto usequeueResolveHandler()for preview/apply semantics - Changed eager-todo prelude to use the tool-choice queue instead of simple override
- Updated todo reminder suppression to check for user-forced directives via
consumeLastServedLabel() - Made model-specific edit mode defaults conditional on
PI_STRICT_EDIT_MODEenvironment variable for greater flexibility in edit mode selection - Updated slash command handlers to support returning remaining text as prompt input instead of consuming input entirely
- Enhanced slash command parser to recognize both whitespace and colon (
:) as command argument separators - Updated indentation guidance for chunk edit content to use single leading spaces per indent level instead of tabs
- Updated read CLI to delegate URL inputs through the read tool pipeline instead of treating them as local file paths
- Updated chunk edit documentation to clarify region semantics and emphasize using the narrowest region for edits
- Improved chunk selector guidance with visual diagram showing region boundaries
- Renamed
build:binaryscript tobuild - Refactored
checkscript to include linting via Biome and type checking - Added
check:types,lint,fmt, andfixscripts for improved developer workflow - Simplified TypeScript configuration by extending workspace-level config
Removed
- Removed
PendingActionStoreclass and related pending-action module - Removed
pendingActionStoreparameter from AgentSession config - Removed
pendingActionStorefrom ToolSession interface - Removed
consumeNextToolChoiceOverride()method from AgentSession (replaced bynextToolChoice())
Fixed
- Fixed tool-choice queue cleanup on agent loop abort to prevent orphaned in-flight directives
- Fixed requeue semantics to preserve
onInvokedandonRejectedcallbacks across multiple abort cycles
[14.0.1] - 2026-04-08
Changed
- Improved auto-generated file detection to gracefully handle ENOENT errors when peeking file content, preventing unnecessary abort failures
- Optimized context emission by skipping message cloning when no extensions have context handlers
- Improved message cloning resilience by falling back to shallow array clone when structured cloning fails due to non-cloneable objects
- Made
assertEditableFileContentsynchronous instead of async for improved performance in streaming edit checks - Enhanced streaming edit abort detection to check for auto-generated files as soon as the file path is available, rather than waiting for the full diff
- Improved file prefix reading in session storage to use
peekFileutility from @oh-my-pi/pi-utils for better efficiency - Moved image metadata detection to @oh-my-pi/pi-utils package for shared use across projects
- Simplified image loading API by removing redundant metadata parameters and consolidating image utilities
- Updated imports to use readImageMetadata and parseImageMetadata from @oh-my-pi/pi-utils instead of local implementations
Removed
- Removed image-input.ts utility module; functionality consolidated into image-loading.ts
- Removed mime.ts utility module; MIME detection moved to @oh-my-pi/pi-utils
- Removed ImageMetadata interface and ReadImageMetadataOptions from local codebase
Fixed
- Fixed streaming edit abort for auto-generated files by adding LRU caching and early path-based detection to prevent unnecessary edits
[14.0.0] - 2026-04-08
Breaking Changes
- Simplified chunk edit operations: removed
append_child,prepend_child,append_sibling,prepend_sibling, andreplace_bodyops in favor of unifiedreplace,before,after,prepend, andappendwith region targeting (@head,@body,@tail) - Chunk edit
targetformat changed: now acceptsselector#CRC@regionfor mutations andselector@regionfor insertions; removed separatecrcandanchorfields from edit operations - Removed checksum requirement from insert operations (
before,after,prepend,append); onlyreplacerequires#CRCsuffix
Added
- Auto QA tool (
report_tool_issue) for automated tracking of unexpected tool behavior; enabled viaPI_AUTO_QA=1environment variable ordev.autoqasetting dev.autoqasetting to enable automated tool issue reporting for all agents- System prompt guidance when
report_tool_issuetool is available, encouraging agents to report tool behavior discrepancies - LSP server discovery at startup via
discoverStartupLspServers()to detect configured language servers without blocking initialization - LSP startup event channel (
lsp:startup) for asynchronous server warmup notifications with completion or failure status LspStartupServerInfotype for tracking LSP server status including connecting, ready, and error states- LSP server status display in
/infocommand showing connecting, ready, and error states with color-coded indicators - Multi-session support in ACP mode: agents can now manage multiple concurrent sessions with independent state, models, and configurations
- Session forking in ACP mode:
unstable_forkSessioncreates a new session from an existing one's history - Session resumption in ACP mode:
unstable_resumeSessionreloads a previously saved session - Session closure in ACP mode:
unstable_closeSessioncleanly shuts down a session and releases resources - Model state reporting in ACP mode:
SessionModelStatewith available models and current selection in session responses - Direct model setting in ACP mode:
unstable_setSessionModelRPC command for changing the active model - Turn-level usage tracking in ACP mode: prompt responses now include
usagewith input/output/cached token counts - Message ID tracking in ACP mode: stable message IDs for assistant chunks enabling client-side message correlation
- Settings cloning:
Settings.cloneForCwd()method to create isolated settings instances for different working directories - Extension flag value retrieval:
ExtensionRunner.getFlagValues()to inspect current flag state - Exported autoresearch module and submodules via
./autoresearchand./autoresearch/*package paths - Exported autoresearch tools via
./autoresearch/tools/*package path - Exported CLI commands via
./cli/commands/*package path - Exported DAP module and submodules via
./dapand./dap/*package paths - Exported edit module and submodules via
./edit,./edit/*, and./edit/modes/*package paths - Exported bundled ci-green custom command via
./extensibility/custom-commands/bundled/ci-greenpackage path - Exported extensibility plugins marketplace via
./extensibility/plugins/marketplaceand./extensibility/plugins/marketplace/*package paths - Exported ACP mode via
./modes/acpand./modes/acp/*package paths - Exported web utilities via
./web/*package path - Exported line-hash utilities from edit module via
./edit/line-hash - Host-owned custom tools support: RPC clients can now register custom tools via
setCustomTools()and the RPC server will invoke them over the transport withhost_tool_callrequests - RPC host tool framework:
RpcHostToolBridgefor managing host tool execution,RpcHostToolDefinitionfor tool metadata, and bidirectionalhost_tool_call,host_tool_cancel,host_tool_update, andhost_tool_resultframes - RPC client tool API:
defineRpcClientTool()helper,RpcClientCustomToolinterface, andRpcClientToolContextfor implementing host-side tool execution with update streaming and abort support set_host_toolsRPC command to replace the active set of host-owned tools before the next model callrefreshRpcHostTools()method onAgentSessionto integrate host tools into the active tool registry with conflict detection and auto-activation of non-hidden tools- Instruction breakpoints support:
set_instruction_breakpointandremove_instruction_breakpointdebug actions for setting breakpoints at specific instruction addresses - Data breakpoints support:
data_breakpoint_info,set_data_breakpoint, andremove_data_breakpointdebug actions for monitoring variable/memory access - Memory introspection:
read_memoryandwrite_memorydebug actions for inspecting and modifying debugger memory - Disassembly support:
disassembledebug action for viewing assembly instructions with symbol resolution - Module and source introspection:
modulesandloaded_sourcesdebug actions for querying loaded modules and source files - Custom DAP requests:
custom_requestdebug action for sending arbitrary Debug Adapter Protocol commands - Reverse request handling in DAP client:
onReverseRequest()method for responding to adapter-initiated requests likerunInTerminalandstartDebugging - DAP reverse request support: adapters can now request terminal spawning and child debug sessions via
runInTerminalandstartDebuggingreverse requests - Instruction pointer reference in debug snapshots:
instructionPointerReferencefield in session summaries for low-level debugging - Hit condition support for instruction and data breakpoints:
hit_conditionparameter for conditional breakpoint triggering - RPC
set_todoscommand andtodoPhasesinget_state, allowing hosts to pre-seed and inspect session todo state over the protocol - Deferred diagnostics support in LSP writethrough:
onDeferredDiagnosticscallback anddeferredSignalinWritethroughOptionsallow callers to receive diagnostics that arrive after the main 5-second timeout - Language detection for
.pm(Perl modules),.astro(Astro framework), and special filenamescontainerfileandjustfile - Workspace-scoped diagnostics and reload actions via
*file parameter;diagnosticsaction now supports*for workspace-wide diagnostics across all configured servers - Socket-mode DAP adapter support for debuggers like dlv that communicate via network sockets instead of stdio; Linux uses unix domain sockets, macOS/other platforms use TCP with client-addr dialing
- Improved extensionless binary debugging: native debuggers (gdb, lldb-dap) and adapters with root markers are now preferred over unrelated adapters like debugpy
- Debug tool with DAP (Debug Adapter Protocol) support for launching and attaching debuggers, setting breakpoints, stepping through execution, inspecting threads/stack/variables, and evaluating expressions
- Debug adapter configuration for gdb, lldb-dap, debugpy, and dlv with language/file-type matching and root marker detection
- Debug session management with support for source and function breakpoints, conditional breakpoints, stack trace inspection, scope/variable exploration, and program output capture
debug.enabledsetting to control debug tool availability- Chunk read formatting:
anchorStyle(full / kind / bare),read.anchorstylesetting, andchunkedflag on file display mode read.prosechunksandread.explorechunkssettings for prose chunk trees and checksum-free explore trees- Handlebars helpers
anchorandsel(with templateanchorStylecontext) for chunk examples in prompts - Chunk-mode grep lines as
path:selector>LINE|content; unified grep tool template behindIS_CHUNK_MODE lru-cachefor chunk tree caching- Chunk-mode
readoutput: recursive rendering with$XXXXchecksum suffixes, inline large-chunk previews, and normalized#path$XXXXselectors between read and edit - Autoresearch:
init_experimentoptionsnew_segment,from_autoresearch_md,abandon_unlogged_runs;log_experimentoptionsskip_restoreand broaderforce;run_experimentforce(with warnings); pre-run dirty-path tracking;abandonUnloggedAutoresearchRunsandabandonedAton runs - LSP: diagnostic versioning (
versionSupport, stored document version per diagnostic set), andwaitForDiagnostics/getDiagnosticsForFileoptions (expectedDocumentVersion,allowUnversioned)
Changed
- Extracted working directory formatting logic into
formatToolWorkingDirectory()utility for consistent path display across tools - Bash command rendering now sanitizes tabs and shortens home directory paths in command previews
- Chunk edit tool schema: renamed
targetparameter toselfor consistency with read tool terminology - Chunk edit tool:
opparameter is now required (previously optional withreplacedefault) - Chunk edit documentation: updated all region references from
@innerto@bodyfor clearer semantics - Chunk edit documentation: expanded with comprehensive real-world examples showing full read output, operation effects, and indentation rules
- Chunk edit documentation: simplified indentation guidance to write content at indent-level 0 with automatic re-indentation by the tool
- Chunk edit documentation: clarified that
@regiononly works on container chunks, not leaf chunks - Chunk edit documentation: emphasized that CRCs change after every edit and must be refreshed from latest responses
- Read chunk tool documentation: updated selector examples to use
@bodyinstead of@inner - Chunk edit region terminology updated:
@innerrenamed to@bodyfor clearer semantics in container chunks - Chunk edit documentation restructured with comprehensive examples showing full read output, operation effects, and indentation rules
- Chunk edit indentation guidance simplified: content should be written at indent-level 0 and the tool automatically applies correct base indentation
- Chunk edit examples expanded with realistic TypeScript code samples demonstrating replace, insert, prepend, append, and delete operations
- Python tool description now dynamically reflects prelude documentation availability instead of static text
- Python tool now automatically warms the environment on first execution if prelude helpers are unavailable, ensuring documentation is loaded before use
- Tool creation now auto-injects
report_tool_issuewhen auto QA is enabled, regardless of requested tool list - Chunk edit region names standardized to
@head,@body, and@tailfor clearer semantics - Chunk edit documentation clarified: region defaults to full chunk when omitted; leaf chunks no longer support region targeting
- Chunk read documentation updated: selector examples now use region-specific selectors based on
@head,@body, and@tail - LSP server connecting status in welcome banner now uses muted pending symbol instead of warning symbol for clearer visual distinction
- Codex websocket prewarm now runs asynchronously in the background instead of blocking session creation, allowing faster startup
- Codex websocket status updates now display in interactive mode when prewarm completes or fails
- LSP server warmup now runs asynchronously in the background instead of blocking session creation, allowing faster startup
- LSP servers returned from
createAgentSession()now includeconnectingstatus during initial warmup phase - Interactive mode now subscribes to LSP startup events and displays status updates and error messages to the user
- LSP server status in
/infocommand now distinguishes between connecting (yellow), ready (green), and error (red) states - ACP agent now manages multiple sessions instead of a single session; session lifecycle and configuration are now per-session
- ACP session creation now uses a factory function to support creating new sessions for different working directories
- ACP event mapping now accepts optional
getMessageIdcallback for stable message ID assignment to assistant chunks
Removed
- Deleted
src/utils/prompt-format.tsmodule; prompt formatting logic moved topi-utils - Deleted
src/utils/frontmatter.tsmodule; frontmatter parsing logic moved topi-utils - Removed
waitForChildProcessutility (child process termination now handled by nativekillTreefrom pi-natives) grep-chunk.md(folded into unified grep template)startMacAppearanceObserverexport (useMacAppearanceObserver.start())copyToClipboardexport from pi-nativesPI_CHUNK_SPLICESenv andchunkSplicesEnabled()- Autoresearch
segmentFingerprintand related config hashing
Fixed
- Chunk edit parameter validation: corrected detection of chunk edit operations to check for
selfield instead oftarget - Chunk edit streaming previews: updated to reference
selparameter instead oftarget - Python prelude introspection now respects execution timeout and signal options, preventing hangs during environment warmup
- Welcome banner LSP server status now updates in real-time when background startup warmup completes, eliminating stale connecting status displays
- Welcome banner LSP startup rows now re-render when background warmup finishes, use the pending status symbol while servers are still connecting, and no longer add a redundant
LSP readystatus line on successful startup - ACP session initialization now registers connection cleanup handlers to dispose all sessions on disconnect
- Reorganized package.json exports: moved
./editexports before./plan-modefor better logical grouping - Notebook conversion logic now checks for raw read mode or non-chunk mode before converting via markit, allowing chunk-mode reads of
.ipynbfiles to use chunk parsing instead of conversion - Go receiver methods now render as top-level siblings instead of nested under their receiver type in chunk read output
- Moved prompt formatting and rendering utilities from
coding-agenttopi-utilspackage;renderPromptTemplate()andformatPromptContent()now accessed viaprompt.render()andprompt.format()from@oh-my-pi/pi-utils - Moved
parseFrontmatter()utility fromcoding-agenttopi-utilspackage; now imported from@oh-my-pi/pi-utilsinstead of local utils - Consolidated prompt template handling:
TemplateContexttype now available asprompt.TemplateContextfrom@oh-my-pi/pi-utils - DAP initialization now advertises support for
runInTerminalandstartDebuggingreverse requests, and memory references - Debug tool schema expanded with new parameters for instruction/data breakpoints, memory operations, and custom requests
- DAP session state now tracks instruction and data breakpoints separately from source breakpoints
- Replaced
Bun.which()with$which()from pi-utils for command resolution - Chunk edit tool documentation restructured: replaced operation-specific examples with region-based guidance and canonical indentation rules
- Chunk read documentation updated: selectors now support region syntax (e.g.,
class_Foo.fn_bar#ABCD@body) and canonical target listings show supported regions per chunk - Chunk edit schema simplified:
targetdescription now documents region format;opandcontentdescriptions clarified for region-aware operations - Chunk edit streaming previews updated: labels now reflect region-aware operations (e.g.,
appendinstead ofappend child,insert afterwithout anchor reference) - Removed CRC parsing from
parseChunkSelector()andparseChunkReadPath(): selectors no longer extract embedded checksums - Chunk edit normalization simplified: no longer requires async checksum resolution or context-dependent operation mapping
- RPC mode now automatically disables session title generation by default; hosts can opt in with
PI_RPC_EMIT_TITLE=1environment variable to receive title updates - RPC mode now resets workflow-altering
todo.*,task.*, andasync.*settings to built-in defaults instead of inheriting user overrides - RPC mode now disables automatic session title generation by default and suppresses
setTitleextension UI requests unless hosts opt in withPI_RPC_EMIT_TITLE=1 - Reorganized edit tool implementation from
patch/toedit/directory structure with dedicated mode subdirectories (edit/modes/chunk.ts,edit/modes/hashline.ts,edit/modes/patch.ts,edit/modes/replace.ts) - Updated package.json exports to use
./editpath instead of./patchfor edit tool and related utilities - Chunk edit tool documentation simplified: removed line-based edit examples, clarified
targetformat with full path and CRC suffix, added guidance forreplace_bodyoperation to preserve declarations - LSP diagnostics timeout reduced from 10 seconds to 5 seconds for faster feedback; slow diagnostics now fetch in background via deferred mechanism
- Diagnostics action error messaging clarified: requires
fileparameter or*for workspace scope; improved guidance in error responses - Workspace symbols and reload actions now accept
*to operate across all configured servers instead of requiring a file path - DAP session initialization now subscribes to stop events before launching/attaching to avoid missing stopOnEntry events
- Stack frame fetching moved outside the event dispatch loop to prevent deadlocks and improve responsiveness
- Evaluate requests now default to the top stopped frame when frameId is not explicitly provided
- Eager todo enforcement now skips prompts ending with question marks or exclamation marks, treating them as queries or commands rather than statements requiring task planning
- Chunk read output now displays fully-qualified anchor paths (e.g.,
[class_Worker.fn_run#CRC]) instead of bare names, making targets unambiguous for edits - Chunk edit tool documentation clarified:
targetmust be the fully-qualified path with#CRCsuffix; added guidance to runread(path="file", sel="?")for canonical target listings when anchor style is unclear - Chunk read tool documentation updated:
selparameter now documents the?selector for canonical target listings, and clarifies that default output shows full paths - Chunk edit schema and tool contract: explicit
op(replace,append,prepend,after,before); usereplacewith emptycontentto remove a chunk (no separatedeleteop); sibling inserts useanchorinstead of separate after/before target fields; insert ops omit CRC where appropriate, mutations require checksum on target - Chunk path handling: parse selector and CRC separately, sanitize selectors (strip filename prefixes, uppercase checksums), accept embedded
#CRCon targets, auto-accept stale CRC for later ops in the same batch on the same chunk - Chunk UX: streaming and final edit previews show chunk edits next to hashline edits with op-specific labels; prompt docs shortened with rules table,
…in examples, and helper-based path/anchor samples log_experimentonly reverts files modified by the run; prompts and errors document that pre-existing dirty files are preserved; richer pending-run error context;init_experimentno-ops when the contract matches unlessnew_segment; secondary metrics informational only (noforcefor drift)- Autoresearch:
log_experimentreloads benchmark/scope/constraints fromautoresearch.mdafter resolving a pending run;/autoresearchwithoutautoresearch.mdfollows/plan-style toggle and message flow; setup moved into autoresearch system prompt (removedcommand-initialize.md) - Native/shell alignment:
GrepOutputModefrom pi-natives; shell andgetDiagnosticsForFilecallbacks use error-first(err, chunk);getDiagnosticsForFiletakes an options object - Clipboard:
copyToClipboard/readImageFromClipboardlive inutils/clipboard.ts(OSC 52 and Termux) - macOS: session-wide power assertion while the agent runs;
MacAppearanceObserver.start()with error-first callback;detectMacOSAppearance()returns enum values - ACP session cleanup now properly cancels in-flight prompts and disposes resources when sessions are closed or connection aborts
- Removed unused
_createErrorToolResulthelper function from RPC host-tools module - Fixed Go receiver method indentation in append operations to preserve relative indentation from the anchor chunk
- Fixed Go type chunk line counts to report only the type body lines instead of including grouped receiver methods
- Fixed enum variant insertion to avoid adding extra blank lines between variants
- Chunk read output now correctly preserves embedded CRC in selectors (e.g.,
class_Foo.fn_bar#ZZPM) instead of stripping them during path parsing - Chunk edit error messages now consistently report checksum mismatches with format
Checksum mismatchinstead of variable phrasing - Chunk-mode read output now correctly displays scoped response trees showing only touched chunks and adjacent siblings, preventing unrelated distant chunks from appearing in responses
- DAP stopped event handling no longer blocks the message reader, preventing potential deadlocks during rapid event sequences
- Chunk-mode whole-chunk replaces now preserve attached leading comments and docblocks when replacement content starts at the declaration, preventing accidental comment loss during agent edits
- Chunk edit error messages now consistently report checksum mismatches with the format
did not match checksum "XXXX"instead of variable phrasing - Chunk selector validation for edits now rejects non-canonical selectors (suffix-only like
fn_runor prefix-stripped likerun), requiring fully-qualified paths to prevent ambiguity - Plan review previews now re-append at the chat tail on refresh, keeping them adjacent to the active selector instead of updating off-screen
log_experimentvalidates and reverts run-scoped file changes without clobbering unrelated dirty worktree state- Chunk edit targets that embed CRC in the selector (e.g.
fn_foo#ABCD) parse correctly - Shell paths check errors before consuming chunk output (bash executor, config resolution)
/autoresearchtoggles like/planwhen empty; slash completion no longer suggestsoff/clearon an empty prefix after the command- Chunk-mode read/edit edge cases (zero-width gap replaces, stale batch diagnostics, grouped Go receivers, line-count headers, parse error locations)
[13.19.0] - 2026-04-05
Added
- Added idle auto-compaction settings and scheduling so sessions can compact after inactive turns without auto-continuing.
- Added
onExternalEditorcallback to extension UI dialog options for handling external editor shortcut in select dialogs - Added external editor shortcut support in plan review selector, allowing users to open and edit the plan in their configured editor
- Added
matchesAppExternalEditorkeybinding matcher to detect external editor shortcut (Ctrl+G or configured binding) - Added
trimTrailingNewlineoption toopenInEditorfunction to preserve trailing newlines when editing files - Added GitHub CLI utilities to git module (
utils/git.github) withavailable(),run(),json(), andtext()methods for GitHub CLI operations - Exported git utilities from main package entry point for use by extensions
- Added comprehensive git utility module (
utils/git) with organized namespaces for common git operations (branch, commit, diff, log, patch, ref, stage, status, head, repository)
Changed
- Changed idle compaction settings (
compaction.idleThresholdTokensandcompaction.idleTimeoutSeconds) from enum to numeric type for flexible configuration - Modified secret obfuscation to deobfuscate restored session messages for local display while keeping outbound LLM messages obfuscated
- Updated stash pop operation to preserve staged changes with
--indexflag when restoring after task branch merges - Changed secret placeholders to deterministic hash-style redaction tokens and deobfuscated assistant output for local display.
- Updated hook editor and hook selector components to use
matchesAppExternalEditormatcher for consistent external editor keybinding detection - Modified plan review flow to read the latest plan content from disk before approval, allowing changes made in external editor to be reflected
- Enhanced plan review help text to dynamically display the configured external editor keybinding
- Refactored git operations to use centralized utility module instead of
ControlledGitclass throughout codebase - Replaced
ControlledGitdependency injection pattern with directcwdparameter in commit agent tools - Migrated git HEAD resolution in footer and status-line components to use new synchronous and asynchronous utilities
- Updated git status summary calculation in status-line component to use new git utility API
- Simplified git branch operations in task execution and cleanup to use new utility functions
- Refactored patch application logic in task worktree to use new git patch utilities
Removed
- Removed
gh-cli.tsmodule; GitHub CLI functionality now available viautils/git.github - Removed
ControlledGitclass and associated git wrapper infrastructure fromcommit/gitmodule - Removed
mergeStdoutStderrhelper function from autoresearch git utilities - Removed
findGitHeadPathAsyncandfindGitHeadPathSyncfrom modes/shared module (replaced by git utilities) - Removed
./commit/gitexport from package.json (internal diff parsing still available via./commit/git/*)
Fixed
- Fixed idle compaction timer to properly cancel when event controller is disposed, preventing memory leaks
- Fixed session resumption to preserve the last non-empty session when starting a fresh session
- Fixed stash detection to use git ref resolution instead of output parsing for reliable stash state tracking
- Fixed isolated task merge-back to preserve task outputs on merge failure and stash dirty worktrees before cherry-pick.
- Fixed web search source rendering to truncate long title, metadata, and URL lines before they overflow the UI.
- Fixed PR checkout tool to resolve symlinks in worktree paths, ensuring consistent path references in results and metadata
- Fixed
readoutput for file-backed internal URLs likelocal://...to include hashline prefixes in hashline edit mode, preserving usable line refs for follow-up edits - Fixed the plan review selector to support the external editor shortcut for opening and updating the current plan from the approval screen
[13.18.0] - 2026-04-02
Breaking Changes
- Removed standalone
fetchtool; URL fetching is now integrated into thereadtool
Added
- Added URL reading capability to
readtool with support for web pages, GitHub issues, Stack Overflow, Wikipedia, Reddit, NPM, arXiv, technical blogs, RSS/Atom feeds, and JSON endpoints - Added
offsetandlimitparameter support for paginating cached URL fetch results - Added URL caching mechanism to avoid redundant network requests when reading the same URL multiple times
Changed
- Renamed
fetch.enabledsetting toRead URLswith updated description to reflect integration with read tool - Updated
readtool to accepttimeoutandrawparameters for URL handling - Updated
readtool to supportfile://URLs for local file paths - Removed
fetchtool from agent tool lists (explore, librarian, oracle, plan, reviewer agents)
Fixed
- Fixed
readtool to properly handlefile://URL scheme by converting to filesystem paths
[13.17.5] - 2026-04-01
Added
- Added support for writing to ZIP archives using fflate library for cross-platform compatibility
Changed
- Modified archive writing to detect and handle ZIP files separately from Bun archives
Removed
- Removed GhPrPushTool test case
[13.17.4] - 2026-04-01
Added
- Support for writing to archive entries in
.tar,.tar.gz,.tgz, and.zipfiles usingarchive.ext:path/inside/archivesyntax - Ability to create new archives when writing to archive subpaths that don't yet exist
[13.17.3] - 2026-04-01
Added
- Added support for converting Jupyter notebooks (
.ipynb) to markdown via markit - Added
markit-ainpm package for native document and notebook conversion - Added support for reading files from
.tar,.tar.gz,.tgz, and.ziparchives using virtual subpaths likearchive.ext:path/to/file - Added ability to list archive contents and navigate subdirectories within supported archive formats
- Added archive-aware
readsupport for.tar,.tar.gz,.tgz, and.zip, including virtual subpaths likearchive.ext:path/to/file - Added
/toolsslash command to show the tools currently visible to the agent in the interactive session
Changed
- Replaced Python-based markitdown CLI tool with native
markit-ailibrary for document conversion - Updated document conversion to use markit library instead of external markitdown command
- Removed markitdown from Python tools manager (no longer needed as external dependency)
- Updated
readtool documentation to reflect archive support and usage patterns
[13.17.2] - 2026-04-01
Added
- Added
/marketplace helpcommand to display usage guide for all marketplace operations - Added dedicated
gh-renderer.tsmodule for rich terminal rendering of GitHub Actions workflow runs with live status snapshots and job details - Added
gh_pr_checkouttool to check out GitHub pull requests into dedicated git worktrees with contributor push metadata - Added
gh_pr_pushtool to push checked-out pull request branches back to their source branches - Added
gh_repo_viewtool to read GitHub repository metadata using the local GitHub CLI - Added
gh_issue_viewtool to read GitHub issues with optional comment context - Added
gh_pr_viewtool to read GitHub pull requests with optional comment context - Added
gh_pr_difftool to read GitHub pull request diffs with optional file filtering - Added
gh_search_issuestool to search GitHub issues with repository scoping - Added
gh_search_prstool to search GitHub pull requests with repository scoping - Added
gh_run_watchtool to watch GitHub Actions workflow runs, fast-fail on job failures, and stream tailed logs for failed jobs - Added
github.enabledsetting to enable read-onlygh_*GitHub CLI tools for repository, issue, pull request, diff, and search workflows - Added bundled
/greencommand to generate iterative CI fix prompts with optional tag instructions when HEAD is tagged - Added
github.enabledsetting to enable read-onlygh_*GitHub CLI tools for repository, issue, pull request, diff, and search workflows - Added
gh_repo_viewtool to read GitHub repository metadata using the local GitHub CLI - Added
gh_issue_viewtool to read GitHub issues with optional comment context - Added
gh_pr_viewtool to read GitHub pull requests with optional comment context - Added
gh_pr_difftool to read GitHub pull request diffs with optional file filtering - Added
gh_search_issuestool to search GitHub issues with repository scoping - Added
gh_search_prstool to search GitHub pull requests with repository scoping - Added
gh_run_watchtool to watch GitHub Actions workflow runs, fast-fail on job failures, and stream tailed logs for failed jobs - Added bundled
/greencommand to generate iterative CI fix prompts with optional tag instructions when HEAD is tagged - Project-scoped marketplace plugin installs:
omp plugin install --scope project name@marketplaceand/marketplace install --scope project name@marketplaceinstall plugins into the nearest.omp/or.git-rooted project directory instead of the user directory (#581) --scope user|projectflag added to/marketplace uninstall,/marketplace upgrade,/plugins enable, and/plugins disableto disambiguate when a plugin is installed in both scopesomp plugin upgrade --scope projectwith no plugin ID warns that--scopeis ignored for bulk upgrades- Added opt-in
gh_*GitHub CLI tools behind thegithub.enabledsetting for repository, issue, pull request, diff, and search workflows - Added opt-in
gh_run_watchto fast-fail GitHub Actions runs, stream job status snapshots, and return tailed logs for failed jobs - Added bundled
/greencommand to generate the iterative “fix CI until green” prompt, with final tag instructions included only whenHEADalready has a tag
Changed
- Improved marketplace catalog parsing to skip invalid plugin entries with warnings instead of failing the entire catalog load
- Enhanced
/marketplace discovercommand to suggest adding the official marketplace when no plugins are available - Improved
/marketplacecommand messaging with clearer guidance for first-time setup and available commands - Enhanced
gh_run_watchtool call rendering to display animated spinner status and target description (run ID, branch, or current HEAD) with improved visual hierarchy - Enhanced
gh_pr_viewtool to include inline review comments alongside pull request reviews for improved discussion context - Improved
gh_run_watchtool output rendering with dedicated visual component for streaming run snapshots and job status updates
Fixed
- Fixed marketplace error messages to display error details instead of object stringification
- Fixed artifact storage for non-persistent sessions to use in-memory fallback instead of returning undefined, enabling proper spill truncation for all session types
- Fixed prompt file formatting to include trailing newlines at EOF for consistency across all prompt markdown files
- Fixed
gh_pr_diffto preserve raw patch content instead of normalizing tabs and whitespace - Fixed
gh_pr_viewto include inline review comments alongside pull request reviews and issue-style comments for discussion context - Fixed
gh_run_watchto resolve explicit branch watches against the selected branch head instead of localHEAD - Fixed
gh_run_watchto hide repo and polling internals from the tool schema and save full failed-job logs as session artifacts alongside the inline tailed output - Fixed
gh_*tool outputs to spill full large results to artifacts instead of pre-truncating the head with unusableoffset=guidance - Fixed bundled
/greento watch the workflow runs for the currentHEADcommit instead of whichever branch run was newest - Fixed OpenAI Responses session rehydration to strip stale assistant replay payloads before resumed requests (#594 by @daandden)
- Fixed inline image rendering to cap image height and preserve multiplexer scrollback during terminal resizes (#587 by @smileynet)
[13.17.1] - 2026-04-01
Removed
- Removed
code_searchtool for code snippet and documentation search
Fixed
- Fixed edit tool diff rendering to wrap long diff lines with continuation gutters instead of truncating them at terminal width (#578)
- Fixed
--list-modelsand/modelprovider filtering to hide models from disabled providers (#588) - Fixed edit tool diffstats to use diff-specific add/remove theme colors instead of success/error status colors (#589)
[13.17.0] - 2026-03-30
Added
- Added
marketplace.autoUpdatesetting (off/notify/auto, defaultnotify) for automatic plugin update checking on startup - Added background marketplace catalog refresh on startup when catalogs are stale (>24h)
- Added
/marketplace upgrade [name@marketplace]slash command to upgrade outdated plugins - Added
omp plugin upgrade [name@marketplace]CLI command for plugin upgrades - Added
checkForUpdates(),upgradePlugin(),upgradeAllPlugins(), andrefreshStaleMarketplaces()to MarketplaceManager - Added marketplace plugin system: registry types, ID helpers, atomic read/write for
marketplaces.jsonandinstalled_plugins.json(Claude Code-compatible format) - Added
MarketplaceManagerorchestrator for marketplace and plugin lifecycle (add/remove/update marketplaces, install/uninstall/enable plugins) - Added marketplace fetcher with source classification (GitHub, git, URL, local) and catalog validation
- Added plugin source resolver with
pathIsWithincontainment checks and versioned cache manager - Added CLI commands:
omp plugin marketplace add|remove|update|list,omp plugin discover [marketplace] - Added
classifyInstallTarget()to distinguishname@marketplacefrom npm install targets - Extended
listClaudePluginRoots()to read OMP's installed plugins registry alongside Claude Code's, with OMP as authoritative for duplicate plugin IDs - Added
--plugin-dir <path>repeatable CLI flag for loading plugins from local directories - Added
/reload-pluginsslash command that invalidates fs content cache and plugin roots cache - Added
printPluginHelp()entries for marketplace and discover commands - Added MCP server loading from marketplace plugin
.mcp.jsonfiles with${CLAUDE_PLUGIN_ROOT}variable substitution - Added skill and command namespacing for marketplace plugins (
plugin-name:skill-name) - Added LSP config loading from marketplace plugin roots via
getPreloadedPluginRoots() - Wired
--plugin-dirruntime injection into plugin roots at session startup with highest precedence - Added git (GitHub, SSH, HTTPS) and HTTP URL marketplace source fetching
- Added
/marketplaceTUI slash command with subcommands: add, remove, update, list, discover, install, uninstall, installed - Added
/pluginsTUI slash command to view all installed plugins (npm + marketplace) and enable/disable marketplace plugins
Changed
- Changed marketplace clone promotion to occur after duplicate and drift checks, improving safety of concurrent marketplace operations
Removed
- Removed grep.app code search provider support; code search now uses Exa exclusively
- Removed
providers.codeSearchsetting and related configuration options
Fixed
- Fixed git-subdir plugin source resolution to properly clean up temporary clone directories on path validation errors
- Fixed LSP config loading to use correct filenames variable when scanning plugin roots
- Fixed plugin selector UI to request render on cancel, preventing stale display state
- Fixed marketplace install command error handling to display user-friendly error messages instead of crashing
- Fixed MCP tools from newly added servers not being activated after
/mcp add—refreshMCPToolspreserves prior MCP tool selections, so brand-new servers had their tools registered in the registry but never passed to the agent; tools are now explicitly activated on successful connection - Fixed
skill://URI resolver to handle namespaced skills via longest-prefix matching against registered skill names
[13.16.5] - 2026-03-29
Fixed
- Fixed
--model provider/idresolving to wrong provider when model ID exists in multiple catalogs (#560)
[13.16.4] - 2026-03-28
Changed
- Renamed hashline helper functions from
hlineref/hlinefulltohref/hlinefor brevity - Simplified hashline edit location API: replaced separate
lineandblockproperties with unifiedrangeproperty accepting{ pos, end }for all range-based edits - Updated hashline prompt documentation to reflect new
rangesyntax and clarified editing guidelines
Fixed
- Added detection for
kysely-codegengenerated files in auto-generated file guard
[13.16.1] - 2026-03-27
Added
- Added
searchDbparameter toPromptActionAutocompleteProviderconstructor for native search database integration in autocomplete workflows - Added
searchDbparameter to enable native search database integration for grep and find operations - Exported
SearchDbtype from tools module for type-safe search database usage
Changed
- Updated grep tool to accept and utilize
searchDbparameter for improved search performance - Updated find tool to pass
searchDbparameter to underlying search operations - Updated grep tool description to remove ripgrep-specific implementation detail
[13.16.0] - 2026-03-27
Added
- Implemented root path alias: bare
/in tool inputs now resolves to the session working directory instead of the filesystem root - Added
browser.screenshotDirsetting to configure screenshot save directory with path expansion
Changed
- Improved hashline tool documentation with clearer guidance on block boundary handling and closing delimiter duplication prevention
- Updated screenshot path resolution to use
resolveToCwdfor consistent workspace-relative path handling - Updated hook editor hint text to include
ctrl+g external editoroption when using prompt style - Refactored question result formatting to consistently include question ID in output
[13.15.3] - 2026-03-26
Added
- Added configurable
app.model.selectTemporarykeybinding for temporary model selection.
[13.15.0] - 2026-03-23
Breaking Changes
- Changed hashline edit schema from flat
op/pos/end/linesfields to structuredloc/contentformat with location-specific objects - Renamed hashline edit operations:
replace_line→{ line: anchor },replace_range→{ block: { pos, end } },append_at→{ append: anchor },prepend_at→{ prepend: anchor },append_file→"append",prepend_file→"prepend" - Changed
linesparameter tocontentin hashline edit entries - Renamed hashline edit operation types:
append→append_at,prepend→prepend_at,append_eof→append_file,prepend_bof→prepend_file - Changed hashline edit operation types from
replace(with optionalend) to explicitreplace_lineandreplace_rangeoperations - Added required
append_eofandprepend_bofoperations for file-level edits;appendandprependnow require an anchor position - Made
posparameter required forreplace_line,append, andprependoperations;append_eofandprepend_bofno longer accept anchors
Added
- Added prompt for tradeoff metrics during autoresearch setup to collect secondary metrics alongside primary metric
- Added validation of contract path specifications to reject absolute paths and parent directory references
- Added stricter benchmark command validation in
isAutoresearchShCommand()to reject chained commands, pipes, and redirects - Added protection against prototype pollution in ASI data and metric cloning by filtering
__proto__,constructor, andprototypekeys - Added
autoResumeArmedflag to track when autoresearch should automatically resume pending runs - Added
lastAutoResumePendingRunNumberto prevent duplicate auto-resume prompts for the same pending run - Added
git clean -Xinvocation during failed experiment rollback to remove ignored build artifacts - Added validation to reject
init_experimentwhen a previous run is still pending and unlogged - Added autoresearch contract system for validating benchmark commands, metrics, scope paths, off-limits paths, and constraints with fingerprint tracking to detect configuration drift
- Added
autoresearch.program.mdsupport for repo-local playbook overlays that guide session strategy while preservingautoresearch.mdas source of truth - Added pending run artifact tracking and recovery to resume incomplete experiments from
.autoresearch/runs/directory with run numbers and benchmark logs - Added run directory organization with numbered run artifacts, benchmark logs, and optional checks logs for experiment traceability
- Added segment fingerprinting to detect when benchmark configuration changes between runs and warn about potential incomparability
- Added support for secondary metrics tracking alongside primary metric with configurable direction (lower/higher is better)
- Added
getCurrentAutoresearchBranch()helper to detect and validate existing autoresearch branches for session resumption - Added
PendingRunSummarytype to track unlogged run state including parsed metrics, ASI data, and pass/fail status - Added hidden next-turn message delivery via
deliverAs: 'nextTurn'with optionaltriggerTurnto queue context for next LLM call without exposing in editable queue - Added
#queueHiddenNextTurnMessage()and#promptQueuedHiddenNextTurnMessages()to AgentSession for autonomous tool reactions - Added resume context support in
command-resume.mdtemplate for user-provided guidance when resuming sessions - Added current segment snapshot display in autoresearch prompt showing recent runs, baseline metrics, and best results
- Added pending run indicator in autoresearch prompt to guide users to complete unlogged experiments before starting new benchmarks
- Added local playbook section in autoresearch prompt when
autoresearch.program.mdexists - Added tab replacement in dashboard and tool output rendering to prevent display corruption from shell commands with tabs
- Added boundary duplication warning when replace_range or replace_line operations include a last inserted line that matches the next surviving line, helping detect off-by-one range errors
- Added git branch isolation for autoresearch sessions via
ensureAutoresearchBranch()to safely revert failed experiments - Added branch status line to autoresearch initialization and resume prompts showing created or reused branch name
- Added
Files in Scope,Off Limits, andConstraintssections to autoresearch.md template for explicit scope definition - Added validation of ASI metadata requirements in
log_experimenttool, requiring hypothesis for all runs and rollback context for failed runs - Added keybinding matcher utilities
matchesAppInterrupt()andmatchesSelectCancel()for consistent escape key handling across components - Added support for customizable
app.interruptandtui.select.cancelkeybindings in interactive components - Added
defaultInactiveproperty toToolDefinitionto allow tools to be registered but excluded from the initial active set, with extension responsibility for activation/deactivation - Added dynamic tool activation/deactivation in autoresearch mode via
setActiveTools()API - Added separate initialization and resume workflows for autoresearch with
command-initialize.mdandcommand-resume.mdprompts - Added intent dialog to prompt users for autoresearch optimization goals when starting fresh
- Added automatic detection of existing
autoresearch.mdto resume from previous sessions without re-prompting for intent - Added autoresearch extension with autonomous experiment loop capabilities
- Added
init_experimenttool to initialize and reset autoresearch sessions with configurable metrics - Added
log_experimenttool to record experiment results with metric parsing and confidence tracking - Added
run_experimenttool to execute commands and capture metrics with timeout and crash detection - Added autoresearch dashboard controller for displaying experiment results and optimization progress
- Added support for secondary metrics tracking alongside primary metric
- Added
ExtensionWidgetContentandExtensionUiComponentFactorytypes for flexible widget configuration - Added
ExtensionWidgetOptionsinterface withplacementparameter to position widgets above or below editor - Added
WidgetPlacementtype supporting 'aboveEditor' and 'belowEditor' placement options - Added
hookWidgetContainerAboveandhookWidgetContainerBelowcontainers to InteractiveMode for separate widget management - Added autoresearch mode for autonomous experiment loops with init_experiment, log_experiment, and run_experiment tools
- Added autoresearch dashboard widget displaying experiment results, metrics, and optimization progress
- Added support for metric tracking with configurable direction (lower/higher is better) and secondary metrics
- Added widget placement options to position extensions above or below the editor via
placementparameter - Added
ExtensionWidgetContentandExtensionWidgetOptionstypes for flexible widget configuration - Added ACP (Agent Client Protocol) mode for headless agent operation via
--mode acp - Added support for Agent Client Protocol SDK integration with session management, MCP server configuration, and streaming communication
- Added
ensureOnDisk()method to SessionManager to persist sessions immediately for ACP discovery
Changed
- Changed autoresearch initialization to collect and validate benchmark command, metric definition, scope paths, off-limits list, and constraints before
init_experiment - Changed
init_experimentto require exact benchmark command, metric definition, scope, off-limits, and constraints matching collected contract - Changed
log_experimentto record run number, benchmark command, scope paths, off-limits list, constraints, and segment fingerprint with each result - Changed
run_experimentto organize output in numbered run directories with separate benchmark and checks logs for artifact preservation - Changed autoresearch dashboard to show pending run indicator when unlogged experiment exists
- Changed autoresearch resume workflow to detect and offer recovery of pending run artifacts before continuing experiment loop
- Changed
ExperimentResultto includerunNumber,benchmarkCommand,scopePaths,offLimits,constraints, andsegmentFingerprintfields - Changed
RunningExperimentto trackrunDirectoryandrunNumberfor artifact organization - Changed
AutoresearchRuntimeto includelastRunArtifactDir,lastRunNumber,lastRunSummary,benchmarkCommand,secondaryMetrics,scopePaths,offLimits,constraints, andsegmentFingerprint - Changed autoresearch prompts to emphasize
autoresearch.mdas source of truth for benchmark, scope, and constraints - Changed
command-initialize.mdto display collected setup (benchmark command, metric, direction, scope, off-limits, constraints) before initialization - Changed
resume-message.mdto reference pending run artifacts and guide completion of unlogged experiments - Changed
sendMessage()API documentation to clarifydeliverAs: 'nextTurn'behavior for hidden context delivery - Changed
SendMessageHandlertype documentation to explain hidden next-turn message queuing during prompt teardown - Changed autoresearch startup to create or reuse a dedicated
autoresearch/...git branch before enabling the experiment loop - Changed autoresearch to refuse startup when unrelated worktree changes would make auto-reverts unsafe
- Changed autoresearch prompts to emphasize scope and constraints as source of truth for session direction
- Changed component escape key handling to use keybinding manager for
app.interruptandtui.select.cancelwith fallback to raw Escape matching - Updated autoresearch prompt guidance to require explicit files in scope, off-limits paths, and session constraints
- Changed autoresearch command to use intent-based initialization instead of goal parameter, with user input dialog for new sessions
- Changed autoresearch startup to create or reuse a dedicated
autoresearch/...git branch before enabling the experiment loop, and to refuse startup when unrelated worktree changes would make auto-reverts unsafe - Changed autoresearch startup to activate experiment tools (
init_experiment,run_experiment,log_experiment) only when autoresearch mode is enabled - Changed autoresearch shutdown to deactivate experiment tools when mode is disabled or cleared
- Changed autoresearch session rehydration to dynamically manage experiment tool activation based on session state
- Changed autoresearch prompts and notes guidance to require explicit files in scope, off-limits paths, and session constraints
- Refactored hashline edit validation to enforce stricter anchor requirements per operation type
- Updated edit application logic to handle explicit file-level operations (
append_eof,prepend_bof) separately from anchor-based operations - Changed
setWidgetAPI to acceptExtensionWidgetOptionsparameter for placement control - Changed widget placement logic to manage widgets above and below editor separately
- Changed hashline edit application to preserve duplicated boundary lines exactly as provided instead of auto-correcting them
- Updated RPC mode to support widget placement option in
setWidgetrequests - Changed hashline edit application to preserve duplicated boundary lines exactly as provided instead of auto-correcting them
- Changed widget API to support placement options and component factories in addition to string arrays
- Updated extension UI controller to manage widgets above and below the editor separately
- Updated ask tool rendering to support markdown formatting in questions and option labels
- Refactored hook input and selector components to render titles as markdown for richer text formatting
- Changed session collection to include sessions with zero messages, enabling ACP mode to create discoverable sessions immediately
- Changed session persistence logic to use atomic file rewrite when flushing unflushed sessions to prevent duplication
- Removed hashline edit autocorrection for duplicated boundary lines; escaped-tab autocorrection remains available for leading
\\tsequences
Removed
- Removed
command-start.mdprompt template in favor of separate initialize and resume workflows - Removed auto-correction of off-by-one range edits that duplicated closing braces or boundary lines
- Removed
shouldAutocorrectfunction and related boundary line deduplication logic from hashline editor - Removed auto-correction of off-by-one range edits that duplicated closing braces or boundary lines
Fixed
- Fixed autoresearch resume to detect and recover pending run artifacts that were left unlogged from previous sessions
- Fixed dashboard overlay to display when running experiment even with zero completed results
- Fixed tab character rendering in dashboard command display and tool output summaries
- Fixed autoresearch logging to require durable ASI metadata (hypothesis, rollback_reason, next_action_hint) for every run including rollback context for discarded, crashed, and checks-failed experiments
- Fixed autoresearch logging to require durable ASI metadata for every run, including rollback context for discarded, crashed, and checks-failed experiments
[13.14.0] - 2026-03-20
Added
- Auto-reconnect MCP servers on connection loss with proactive SSE stream monitoring and retry backoff
- Tool-level reconnect: retriable connection errors (ECONNREFUSED, ECONNRESET, stale session 404/502/503) trigger automatic reconnection and single retry
/mcp reconnect <name>command for manual server recovery after extended outages
Changed
- Extended transport reconnect handling to all transport types (not just HTTP/SSE), ensuring stdio and other transports trigger automatic reconnection on connection loss
- Improved reconnect robustness by aborting retry attempts when MCP server configuration changes during reconnection sequence
- Updated explore agent thinking level from off to med for improved reasoning
- Simplified explore agent output schema: consolidated file references into single
reffield with optional line ranges instead of separatepath,line_start,line_endfields - Removed
codesection from explore agent output (critical code excerpts no longer extracted) - Removed
dependenciessection from explore agent output - Removed
riskssection from explore agent output - Removed
start_heresection from explore agent output
Fixed
- Fixed reconnect retry loop continuing after configuration changes by checking epoch before each reconnection attempt
roots/listtimeout on MCP server initialization:connectToServernow always installs a default handler forpingandroots/list- Fixed resumed GitHub Copilot conversations that could fail with
401 input item does not belong to this connectionon the first follow-up after process restart (#488) - Fixed STT Alt+H mic cursor rendering to measure the actual microphone glyph width, preventing one-column TUI overflow crashes when the active symbol preset uses a wide icon (#484)
[13.13.2] - 2026-03-18
Added
- Added automatic stripping of hashline display prefixes (LINE#ID:) from write tool content when hashline edit mode is enabled, preventing the model from accidentally copying display markers into files
- Added
mcpServerNameandmcpToolNameoptional properties to custom tools for MCP server discovery and search metadata
[13.13.1] - 2026-03-18
Added
- Automatic deduplication of identical context files by content, keeping the closest (lowest depth) copy when duplicates are discovered
[13.13.0] - 2026-03-18
Added
- Added
edit.blockAutoGeneratedsetting to control whether auto-generated file detection is enforced (enabled by default) - Improved auto-generated file detection to use language-specific comment parsing instead of broad regex patterns, reducing false positives
- Added auto-generated file detection to prevent accidental modification of generated code (protoc, sqlc, buf, swagger, etc.)
- Added validation in Edit and Write tools to block modifications to files with auto-generated markers or naming patterns
Changed
- Enhanced auto-generated marker detection to only scan leading header comments rather than entire file prefix, improving accuracy for files with generated markers in code
[13.12.10] - 2026-03-17
Added
- Added
argsfield to ShellResult to capture the executed command - Added
exit_codeproperty to ShellResult as an alias forreturncode - Added
check_returncode()method to ShellResult to raise CalledProcessError on non-zero exit codes
Changed
- Renamed
codefield toreturncodein ShellResult (accessible viacodeproperty for backward compatibility) - Updated
run()command documentation to clarify available ShellResult fields
[13.12.9] - 2026-03-17
Added
- Added
/session deletecommand to delete current session with confirmation and return to session selector - Added session deletion in session selector via Delete key with confirmation dialog
Changed
- Changed session deletion callback to return a boolean indicating success, allowing callers to distinguish between failed deletions and upstream cancellations
Fixed
- Fixed OAuth redirect URI validation to preserve exact configured values without adding trailing slashes
- Fixed session deletion error handling to display error messages in the session selector UI instead of silently failing
- Added
oauth.redirectUri,oauth.clientSecret, andoauth.callbackPathsupport for MCP server OAuth config so providers can use exact registered redirect URIs while preserving local callback listener settings (#445)
[13.12.8] - 2026-03-16
Breaking Changes
- Changed
SessionManager.create()to require explicitsessionDirparameter instead of optional—callers must now passSessionManager.getDefaultSessionDir(cwd)to use default behavior - Changed
SessionManager.continueRecent()to require explicitsessionDirparameter instead of optional—callers must now passSessionManager.getDefaultSessionDir(cwd)to use default behavior - Changed
SessionManager.forkFrom()to require explicitsessionDirparameter instead of optional—callers must now passSessionManager.getDefaultSessionDir(cwd)to use default behavior - Changed
SessionManager.list()signature to accept onlysessionDirparameter instead ofcwdand optionalsessionDir—callers must now compute and pass the session directory explicitly
Added
- Added
SessionManager.getDefaultSessionDir()static method to explicitly resolve the canonical default session directory for a working directory - Added support for quoted paths in grep, ast_grep, and find tools to handle directory names with spaces
- Added
normalizePathLikeInpututility function to consistently handle quoted and whitespace-trimmed path inputs
Changed
- Made
sessionDirparameter optional inSessionManager.create(),SessionManager.continueRecent(), andSessionManager.forkFrom()—callers can now omit it to use the default session directory - Changed
SessionManager.list()signature to acceptcwdas the first parameter instead of requiring an explicitsessionDir—callers can now omitsessionDirto use the default for the given working directory - Updated
SessionManager.getDefaultSessionDir()to accept optionalagentDirparameter for computing session directories within a custom agent root - Improved status line path display to strip display roots using canonical path resolution, correctly handling symlink aliases to home and Projects directories
- Improved error messaging in ast_grep when no matches are found with parse errors, now suggests narrowing
path/globor settinglangto resolve mis-scoped queries
Fixed
- Fixed SDK-created default sessions to honor the configured
agentDirfor session storage, preventing tests from writing stray session directories into the real~/.omp/agent/sessionsroot - Fixed session directory resolution to correctly handle symlink-equivalent paths, ensuring aliased home and temp directories resolve to the same session storage location as their real targets
[13.12.7] - 2026-03-16
Changed
- Modified
getSelectedMCPToolNames()to return only active MCP tools in non-discovery sessions, filtering by tool registry availability - Updated
search_tool_bm25tool instantiation to conditionally create the tool only when MCP discovery mode is enabled and execution hooks are available - Changed search results to exclude already-selected MCP tools before applying the limit parameter, allowing discovery of additional tools in subsequent searches
Fixed
- Fixed MCP tool selection tracking to properly distinguish between discovery-enabled and non-discovery sessions, preventing orphaned tool selections after manual deactivation
[13.12.6] - 2026-03-15
Changed
- Updated llama.cpp model discovery to read context window from the
/propsendpoint'sdefault_generation_settings.n_ctxfield instead of using hardcoded 128000 default - Updated llama.cpp model discovery to detect vision capabilities from the
/propsendpoint'smodalities.visionfield instead of defaulting to text-only input - Changed llama.cpp
maxTokenscalculation to respect discovered context window limits, capping at 8192 or the server's context window, whichever is smaller
Fixed
- Fixed llama.cpp auto-discovery to read context window and vision support from the native
/propsendpoint instead of relying on hardcoded defaults
[13.12.5] - 2026-03-15
Added
- Automatic discovery of Ollama model context window from model metadata, enabling accurate token limit configuration
- Added
attributionoption toPromptOptionsto explicitly control billing/initiator attribution for prompts - Added automatic clearing of completed and abandoned todo tasks after ~1 minute
Changed
- Ollama model registration now uses discovered context window instead of hardcoded 128000 token default
- Ollama model maxTokens now respects discovered context window constraints
- Improved session directory migration to handle legacy absolute paths with double-dash format, automatically relocating them to new canonical locations
- Enhanced session directory encoding to use
-tmp-prefix for temporary directories instead of legacy double-dash format for better clarity - Updated
SessionManager.create()to require bothcwdandsessionDirparameters for explicit session directory control - Improved session directory naming for temporary working directories using
-tmp-prefix instead of legacy--format - Made
cwdandsessionDirfields mutable in SessionManager to support session relocation without type casting - Changed subagent prompts to explicitly set
attribution: "agent"for accurate billing attribution - Strip already-completed tasks when restoring session from branch history
Fixed
- Fixed automatic migration of legacy session directories to new
-tmp-prefixed naming scheme for temp-root sessions
[13.12.4] - 2026-03-15
Added
- Exposed
settingsinstance inCustomToolContextfor session-specific configuration access
Changed
- Improved artifact spill configuration to use session settings with schema defaults as fallback
- Refactored type annotations for better type safety in tool result handling
[13.12.2] - 2026-03-15
Added
- Added
compaction.thresholdTokenssetting as a fixed token limit alternative to percentage-based compaction threshold - Added more artifact spill threshold options (1 KB to 1 MB) with size descriptions
- Added more artifact tail bytes and tail lines options with descriptions
- Added
toExtensionIdcapability method to enable granular disabling of individual capabilities by ID - Added support for disabling specific capabilities (skills, tools, hooks, rules, prompts, instructions, slash commands, MCP servers, extension modules, and context files) via
disabledExtensionssetting - Added
includeDisabledanddisabledExtensionsoptions toLoadOptionsfor capability loading - Added plugin manifest support for
extensionsentry points to allow plugins to contribute extension modules - Added
extensionsfield to plugin features for feature-specific extension entry points - Added automatic discovery of extension modules from installed plugins during extension loading
- Added
disabledExtensionssetting to allow disabling specific extensions and skills by ID - Added support for filtering skills by disabled extension IDs with
skill:prefix
Changed
- Changed capability loading to filter out disabled items based on extension IDs before returning results
- Changed plugin loader to support
extensionsas a manifest entry type alongside tools, hooks, and commands - Changed extension discovery to include extension entry points from all enabled plugins
- Changed context file path handling to use
path.basename()for consistent cross-platform filename extraction
Fixed
- Fixed skill loading to properly respect disabled skill names when loading from custom directories
[13.12.1] - 2026-03-15
Added
- Support for move-only operations that preserve exact bytes including binary files
Fixed
- Fixed handling of file moves when no edits are specified, now correctly preserves binary content
- Fixed validation to reject move operations where source and destination paths are identical
[13.12.0] - 2026-03-14
Added
- Added per-rule TTSR interrupt mode override via
interruptModefield in rule frontmatter to allow fine-grained control over when TTSR interrupts stream processing - Added
taskmodel role to allow configuring a dedicated model for subtask execution viamodelRoles.tasksetting - Added
moveCursorToMessageEndandmoveCursorToMessageStartprompt actions to navigate to the beginning and end of the entire message - Added support for provider-level
compatconfiguration to apply OpenAI compatibility settings across all models from a provider - Added
reasoningEffortMapconfiguration option to map reasoning effort levels to provider-specific values - Added support for
supportsUsageInStreaming,requiresToolResultName,requiresAssistantAfterToolResult,requiresThinkingAsText,thinkingFormat, andsupportsStrictModeOpenAI compatibility options - Added support for provider-configurable
OpenAICompat.extraBodyto inject request-body fields for custom gateway/proxy routing - Added
close()method to SessionManager for properly closing persistent writers after flushing pending data - Added
omp config init-xdgcommand to initialize XDG Base Directory structure on Linux - Added
getHistoryDbPath(),getModelDbPath(),getMemoriesDir(),getTerminalSessionsDir()path helpers
Changed
- Path resolution on Linux redirects to XDG locations when
XDG_DATA_HOME/XDG_STATE_HOME/XDG_CACHE_HOMEenvironment variables are set - Changed TTSR interrupt logic to respect per-rule
interruptModesettings, falling back to globalttsr.interruptModewhen rule-level override is not specified - Reorganized settings tabs from 12 tabs (display, agent, input, tools, config, services, bash, lsp, ttsr, status) to 8 focused tabs (appearance, model, interaction, context, editing, tools, tasks, providers) for improved discoverability
- Consolidated status line settings into the Appearance tab instead of a separate Status tab
- Reorganized sampling parameters (temperature, topP, topK, minP, presencePenalty, repetitionPenalty) into the Model tab
- Moved edit tool settings (mode, fuzzyMatch, fuzzyThreshold, streamingAbort) to the Editing tab
- Moved read tool settings (readLineNumbers, readHashLines, read.defaultLimit) to the Editing tab
- Moved LSP settings (lsp.enabled, lsp.formatOnWrite, lsp.diagnosticsOnWrite, lsp.diagnosticsOnEdit) to the Editing tab
- Moved bash interceptor settings to the Editing tab
- Moved Python settings (python.toolMode, python.kernelMode, python.sharedGateway) to the Editing tab
- Moved task delegation settings (task.isolation.*, task.eager, task.maxConcurrency, task.maxRecursionDepth) to the Tasks tab
- Moved skill and command settings to the Tasks tab
- Moved provider selection settings (providers.webSearch, providers.codeSearch, providers.image, etc.) to the Providers tab
- Moved Exa settings to the Providers tab
- Moved secret handling settings to the Providers tab
- Moved speech-to-text settings to the Interaction tab
- Moved context promotion, compaction, branch summary, memories, and TTSR settings to the Context tab
- Updated tab icon symbols across unicode, nerd, and ASCII presets to match new tab structure
- Changed default agent model from
defaulttopi/taskto enable independent model configuration for subtasks - Changed agent model resolution to support single-pattern inheritance fallback, allowing
pi/taskagents to inherit the active session model when the task role is unconfigured - Changed system prompt to use ISO 8601 date format (YYYY-MM-DD) instead of locale-specific formatting
- Changed system prompt template to use
{{date}}instead of{{dateTime}}for current date display - Changed tool download timeout from 15 seconds to 120 seconds to accommodate slower network conditions
- Changed working directory paths in system prompt to use forward slashes for consistency across platforms
- Modified bash executor to fall back to one-shot shell execution after a persistent session hard timeout, preventing subsequent commands from hanging
Removed
- Removed bash executor hard timeout recovery test file (functionality already documented in existing entries)
Fixed
- Fixed bash execution to fall back to one-shot shell runs after a persistent session hard timeout, preventing later commands from hanging until restart
- Fixed timeout handling in RpcClient to properly clear timeouts and prevent resource leaks
- Fixed AgentSession disposal to call SessionManager's
close()method when available, ensuring proper cleanup of persistent writers - Removed redundant
path.join()call wrappinggetHistoryDbPath()in history-storage.ts
[13.11.1] - 2026-03-13
Added
- Added
llama.cppas local provider - Added
code_searchtool supporting both Exa and grep.app providers for code snippet and documentation search - Added
providers.codeSearchsetting to configure code search provider (exa or grep) - Added grep.app integration for public code search with result ranking by context relevance
Changed
- Updated compact diff preview to include line hashes for visibility and integrity verification of unchanged and added lines
- Modified compact diff preview to track line number synchronization between old and new files when processing insertions and deletions
- Simplified web search tools: removed
web_search_deep,web_search_crawl,web_search_linkedin, andweb_search_companytools - Removed
exa.enableLinkedinandexa.enableCompanysettings; LinkedIn and company research are no longer available - Refactored code search to use pluggable provider system instead of Exa-only implementation
Removed
- Removed Exa LinkedIn search tool (
exa_linkedin) - Removed Exa company research tool (
exa_company) - Removed Exa deep search tool (
exa_search_deep) - Removed Exa URL crawl tool (
exa_crawl)
Fixed
- Fixed line number parsing in compact diff preview to handle variable-width line number fields with leading whitespace
[13.11.0] - 2026-03-12
Added
- Added Parallel as a web search provider with support for fast and research modes
- Added Parallel extract API integration for URL content fetching and YouTube video extraction
- Added
providers.parallelFetchsetting to enable/disable Parallel extract for URL fetching - Added
/login parallelcommand support for Parallel API authentication - Added subcommands to
/copycommand:code(copy last code block),all(copy all code blocks),cmd(copy last bash/python command), andlast(copy full message) - Added support for copying last executed bash or python command via
/copy cmdsubcommand - Added
assignmentfield to task progress and result objects to track the raw per-task assignment text separately from the full templated task - Added
detailsfield to todo items for storing implementation specifics, file paths, and edge cases (shown only when task is active) - Added support for multi-line details in todo items with automatic indentation in interactive and reminder displays
- Added
todo.eagersetting to automatically create a comprehensive todo list after the first user message - Added
buildNamedToolChoiceutility function to build provider-aware tool choice constraints for named tools - Support for comma/space-separated path lists in
find,grep,ast_grep, andast_edittools (e.g.,apps/,packages/,phases/orapps/ packages/ phases/) - New
resolveMultiSearchPathandresolveMultiFindPatternfunctions to handle multi-path search inputs with automatic common base path detection
Changed
- Updated HTML-to-text rendering to prefer Parallel extract when credentials are available, before falling back to jina, trafilatura, or lynx
- Updated YouTube scraper to prefer Parallel extract when credentials are available, before falling back to yt-dlp
- Updated web search provider priority order to include Parallel between Exa and Kagi
- Updated hashline tool documentation with explicit guidance on
replaceoperation semantics, clarifying thatlinesmust not extend pastendto avoid unintended line duplication - Improved diagnostic message formatting to group errors by file path with indented details for better readability
- Modified eager todo prelude to use hidden custom message type instead of visible developer message, preventing duplicate prompt text in session history
- Updated eager todo prompt to remove dynamic user request injection, simplifying the template and preventing request repetition in displayed messages
- Modified eager todo enforcement to prepend the todo reminder to the first user turn instead of executing it as a separate synthetic turn, reducing unnecessary prompt calls
- Updated task rendering to display assignment text instead of full task template when available, reducing noise in progress and result displays
- Modified task section rendering to show trimmed assignment text without stripping context blocks, simplifying the display logic
- Updated todo item display to show
detailsfield indented below active tasks in both interactive mode and todo reminder component - Modified tool choice resolution to support per-turn tool choice overrides via
consumeNextToolChoiceOverride() - Updated tool documentation to clarify that
pathparameter accepts files, directories, glob patterns, or comma/space-separated path lists - Refactored path resolution logic in
find,grep,ast_grep, andast_edittools to use unified multi-path handling
Fixed
- Fixed hashline line normalization to trim trailing whitespace and strip carriage returns instead of removing all whitespace, preserving intentional spacing in code
- Fixed noop detection in hashline replace operations to check array length equality before comparing lines, preventing false noop classification when single-line replacements expand to multiple lines
- Fixed path resolution to accept bare directory names without trailing slashes in comma/space-separated path lists (e.g.,
apps packages phases) - Per-role
modelRolesthinking selectors now propagate through commit/title helper model selection, legacy commit analysis, and agentic commit sessions while preserving default thinking inheritance when no role override is configured
[13.10.1] - 2026-03-10
Added
- Exported
submitInteractiveInput()function for programmatic submission of user input in interactive mode - Added proactive OAuth token refresh for MCP server connections with 5-minute expiry buffer
- Added reactive 401/403 retry with automatic token refresh on HTTP MCP transports
- Added
refreshMCPOAuthToken()for standard OAuth 2.0 refresh_token grants - Persisted
tokenUrl,clientId, andclientSecretin MCP auth config for cross-session token refresh
[13.10.0] - 2026-03-10
Fixed
- Preserved text signature metadata (id and phase) when building OpenAI native history during session compaction
[13.9.16] - 2026-03-10
Breaking Changes
- Web search tool no longer accepts
providerparameter in tool calls; use internal provider resolution instead - Removed
no_fallbackoption from search parameters
Added
- Added
before_provider_requestextension event to intercept and modify provider request payloads before sending - Added
emitBeforeProviderRequest()method to ExtensionRunner for chaining payload transformations across extensions - Added
refreshInBackground()method to ModelRegistry for non-blocking model discovery - Added
refreshProvider()method to refresh models for a specific provider on demand - Added
getDiscoverableProviders()method to list all configured discoverable providers - Added
getProviderDiscoveryState()method to inspect provider discovery status, cache age, and errors - Added provider discovery state tracking with status indicators (idle, ok, cached, unavailable, unauthenticated)
- Added model caching with 24-hour TTL to preserve discovered models across sessions
- Added provider-specific empty state messages in model selector showing cache age and discovery status
- Added live provider refresh when switching provider tabs in model selector
Changed
- Changed model discovery to load cached models immediately before attempting live refresh, improving startup performance
- Changed model selector to refresh offline by default when reloading config, deferring live discovery to background
- Changed model discovery timeout from 3000ms to 250ms for faster failure detection
- Changed model discovery error handling to preserve cached models when live refresh fails
- Changed
refresh()strategy parameter to support 'offline' mode for config-only reloads - Changed main.ts to defer model refresh until needed (--list-models or background refresh)
- Changed SDK session creation to use background refresh instead of blocking on model discovery
- Removed
providerparameter from web search tool schema; provider selection now handled internally - Removed
no_fallbackparameter from web search parameters; fallback behavior now automatic based on provider availability - Renamed
SearchParamstype toSearchToolParamsfor tool execution; introducedSearchQueryParamsfor CLI queries with optional provider selection
Fixed
- Fixed model discovery to continue using cached models when provider is temporarily unavailable
- Fixed unauthenticated provider discovery to preserve cached models instead of discarding them
- Fixed model selector to show discovery status messages when provider has no models
[13.9.15] - 2026-03-10
Added
- Added
ensureLoadingAnimation()method to manage loading animation lifecycle and prevent duplicate spinners
Changed
- Refactored loading animation initialization to use centralized
ensureLoadingAnimation()method in event and input controllers - Updated
showError()to properly clean up loading animation state when errors occur
[13.9.12] - 2026-03-09
Added
- Added Tavily as a supported web search provider with
TAVILY_API_KEYcredential discovery and provider fallback support - Added
#-triggered prompt action suggestions in the editor, with keybinding hints for line navigation and prompt copy actions - Added Tavily as a supported web search provider with
TAVILY_API_KEYcredential discovery and provider fallback support (#313)
Removed
- Removed Kagi Universal Summarizer integration from fetch tool—HTML rendering now uses jina, trafilatura, and lynx only
- Removed
fetch.useKagiSummarizersetting - Removed Kagi summarization from YouTube video handling
Fixed
- Canonicalized bash executor working directories before handing them to brush so
pwdstays aligned with canonical Git worktree paths in symlinked workspaces
[13.9.10] - 2026-03-08
Added
- Added
envparameter to bash tool to pass environment variables safely without shell re-parsing, preventing quote and special character bugs with multiline or untrusted values - Added support for rendering partial
envassignments in command preview while tool arguments are still streaming - Added
envsupport to the bash tool so commands can reference safe shell variables without inline quoting bugs for multiline or quote-heavy values
Changed
- Changed bash tool to display environment variable assignments in command preview when
envparameter is used
[13.9.8] - 2026-03-08
Added
- Added docs.rs scraper for extracting Rust crate documentation from rustdoc JSON, including support for modules, functions, structs, traits, enums, and other Rust items with caching
[13.9.7] - 2026-03-08
Added
- Added
skipPostPromptRecoveryWaitoption to handoff operations to defer recovery work until after handoff completion - Added deferred auto-compaction scheduling to allow threshold-triggered handoffs to complete while the original prompt is still unwinding
Changed
- Extracted handoff document template to dedicated prompt file for improved maintainability and template variable support
- Changed handoff prompt generation to use template rendering with support for custom focus instructions
- Refactored internal prompt-in-flight tracking from boolean flag to counter to properly handle nested prompt operations
- Moved llms.txt endpoint discovery to fallback strategy when rendered page content is low quality, prioritizing page-specific content over site-wide files
- Enhanced llms.txt endpoint detection to scope candidates to the requested URL path, searching section-specific files before site-wide ones
[13.9.6] - 2026-03-08
Added
- Added
globparameter toast_grepandast_edittools for additional glob filtering relative to thepathparameter - Added
combineSearchGlobsutility function to merge glob patterns frompathandglobparameters
Changed
- Renamed
patternsparameter topatinast_greptool for consistency - Renamed
selectorparameter toselinast_grepandast_edittools for brevity - Updated tool documentation with expanded guidance on AST pattern syntax, metavariable usage, and contextual matching strategies
- Updated
greptool to combine glob patterns frompathandglobparameters instead of throwing an error when both are provided
[13.9.4] - 2026-03-07
Added
- Automatic detection of Ollama model capabilities including reasoning/thinking support and vision input via the
/api/showendpoint - Improved Kagi API error handling with extraction of detailed error messages from JSON and plain text responses
Changed
- Updated Kagi provider description to clarify requirement for Kagi Search API beta access
[13.9.3] - 2026-03-07
Breaking Changes
- Changed
ThinkingLeveltype to be imported from@oh-my-pi/pi-agent-coreinstead of@oh-my-pi/pi-ai - Changed thinking level representation from string literals to
Effortenum values (e.g.,Effort.Highinstead of"high") - Changed
getThinkingLevel()return type toThinkingLevel | undefinedto support models without thinking support - Changed model
reasoningproperty tothinkingproperty withThinkingConfigfor explicit effort level configuration - Changed
thinkingLevelin session context to be optional (ThinkingLevel | undefined) instead of always present
Added
- Added
thinking.tsmodule withgetThinkingLevelMetadata()andresolveThinkingLevelForModel()utilities for thinking level handling - Added
ThinkingConfigsupport to model definitions for specifying supported thinking effort levels per model - Added
enrichModelThinking()function to apply thinking configuration to models during registry initialization - Added
clampThinkingLevelForModel()function to constrain thinking levels to model-supported ranges - Added
getSupportedEfforts()function to retrieve available thinking efforts for a model - Added
Effortenum import from@oh-my-pi/pi-aifor type-safe thinking level representation - Added
/fastslash command to toggle OpenAI service tier priority mode for faster response processing - Added
serviceTiersetting to control OpenAI processing priority (none, auto, default, flex, scale, priority) - Added
compaction.remoteEnabledsetting to control use of remote compaction endpoints - Added remote compaction support for OpenAI and OpenAI Codex models with encrypted reasoning preservation
- Added fast mode indicator (⚡) to model segment in status line when priority service tier is active
- Added context usage threshold levels (normal, warning, purple, error) with token-aware thresholds for better context awareness
- Added
isFastModeEnabled(),setFastMode(), andtoggleFastMode()methods to AgentSession for fast mode control
Changed
- Changed credential deletion to disable credentials with persisted cause instead of permanent deletion
- Added
disabledCauseparameter to credential deletion methods to track reason for disabling - Changed thinking level parsing to use
parseEffort()from local thinking module instead ofparseThinkingLevel()from pi-ai - Changed model list display to show supported thinking efforts (e.g., "low,medium,high") instead of yes/no reasoning indicator
- Changed footer and status line to check
model.thinkinginstead ofmodel.reasoningfor thinking level display - Changed thinking selector to work with
Efforttype instead ofThinkingLevelfor available levels - Changed model resolver to return
undefinedfor thinking level instead of"off"when no thinking is specified - Changed compaction reasoning parameters to use
Effortenum values instead of string literals - Changed RPC types to use
Effortfor cycling thinking levels andThinkingLevel | undefinedfor session state - Changed theme thinking border color function to accept both
ThinkingLevelandEfforttypes - Changed context usage coloring in footer and status line to use token-aware thresholds instead of fixed percentages
- Changed compaction to preserve OpenAI remote compaction state and encrypted reasoning across sessions
- Changed compaction to skip emitting kept messages when using OpenAI remote compaction with preserved history
- Changed session context to include
serviceTierfield for tracking active service tier across session branches - Changed
compact()function to acceptremoteInstructionsoption for custom remote compaction prompts - Changed model registry to apply hardcoded policies (gpt-5.4 context window) consistently across all model loading paths
Fixed
- Fixed OpenAI remote compaction to correctly append incremental responses instead of replacing entire history
- Fixed thinking level display logic in main.ts to correctly check for undefined instead of "off"
- Fixed model registry to preserve explicit thinking configuration on runtime-registered models
- Fixed usage limit reset time calculation to use absolute
resetsAttimestamps instead of deprecatedresetInMsfield - Fixed compaction summary message creation to no longer be automatically added to chat during compaction (now handled by session manager)
[13.9.2] - 2026-03-05
Added
- Support for Python code execution messages with output display and error handling
- Support for mode change entries in session exports
- Support for TTSR injection and session initialization entries in tree filtering
Changed
- Updated label lookup to use
targetIdfield instead ofparentIdfor label references - Changed model change entry display to use
modelfield instead of separateproviderandmodelIdfields - Simplified model change rendering by removing OpenAI Codex bridge prompt display
- Updated searchable text extraction to include Python code from
pythonExecutionmessages
Removed
- Removed
codexInjectionInfofrom session data destructuring - Removed OpenAI Codex-specific bridge prompt UI from model change entries
Fixed
- Auto-corrected off-by-one range start errors in hashline edits that would duplicate preceding lines
[13.9.0] - 2026-03-05
Added
- Added
read.defaultLimitsetting to configure default number of lines returned by read tool when no limit is specified (default: 300 lines) - Added preset options for read default limit (200, 300, 500, 1000, 5000 lines) in settings UI
Changed
- Updated read tool prompt to distinguish between default limit and maximum limit per call
- Moved
ThinkingLeveltype from@oh-my-pi/pi-agent-coreto@oh-my-pi/pi-aifor centralized thinking level definitions - Replaced local thinking level validation with
parseThinkingLevel()andALL_THINKING_LEVELSfrom@oh-my-pi/pi-ai - Updated thinking level option providers to use
THINKING_MODE_DESCRIPTIONSfrom@oh-my-pi/pi-aifor consistent descriptions - Renamed
RoleThinkingModetype toThinkingModeand changed default value from'default'to'inherit'for clarity - Replaced
formatThinkingEffortLabel()utility withformatThinking()from@oh-my-pi/pi-ai - Renamed
extractExplicitThinkingLevel()toextractExplicitThinkingSelector()in model resolver - Updated thinking level clamping to use
getAvailableThinkingLevel()from@oh-my-pi/pi-ai
Removed
- Removed
thinking-effort-label.tsutility file (functionality moved to@oh-my-pi/pi-ai) - Removed local
VALID_THINKING_LEVELSconstant definitions across multiple files - Removed
isValidThinkingLevel()function (replaced byparseThinkingLevel()from@oh-my-pi/pi-ai) - Removed
parseThinkingLevel()helper from discovery module (now uses centralized version from@oh-my-pi/pi-ai)
Fixed
- Fixed provider session state not being cleared when branching or navigating tree history, preventing resource leaks with codex provider sessions
[13.8.0] - 2026-03-04
Added
- Added
buildCompactHashlineDiffPreview()function to generate compact diff previews for model-visible tool responses, collapsing long unchanged runs and consecutive additions/removals to show edit shape without full file content - Added project-level discovery for
.agent/and.agents/directories, walking up from cwd to repo root (matching behavior of other providers like.omp,.claude,.codex). Applies to skills, rules, prompts, commands, context files (AGENTS.md), and system prompts (SYSTEM.md)
Changed
- Changed edit tool response to include diff summary with line counts (+added -removed) and a compact diff preview instead of warnings-only output
- Limited auto context promotion to models with explicit
contextPromotionTarget; models without a configured target now compact on overflow instead of switching to arbitrary larger models (#282)
Fixed
- Fixed
:thinkingsuffix inmodelRolesconfig values silently breaking model resolution (e.g.,slow: anthropic/claude-opus-4-6:high) and being stripped on Ctrl+P role cycling
[13.7.6] - 2026-03-04
Added
- Exported
dedupeParseErrorsutility function to deduplicate parse error messages while preserving order
Fixed
- Reduced duplicate parse error messages when multiple patterns fail on the same file
- Normalized parse error output in ast-grep to remove pattern-specific prefixes and show only file-level errors
[13.7.4] - 2026-03-04
Added
- Added
fetch.useKagiSummarizersetting to toggle Kagi Universal Summarizer usage in the fetch tool.
Fixed
- Fixed incorrect message history reference in session title generation that could cause missing or stale titles on first message
- Added startup check requiring Bun 1.3.7+ for JSONL session parsing (
Bun.JSONL.parseChunk) and clear upgrade guidance so/resumeand--resumedo not silently report missing sessions on older Bun runtimes
[13.7.3] - 2026-03-04
Added
- Added Kagi Universal Summarizer integration for URL summarization, now prioritized before Jina and other methods
- Added Kagi Universal Summarizer support for YouTube video summaries when credentials are available
- Exported
searchWithKagiandsummarizeUrlWithKagifunctions from newweb/kagimodule for direct API access - Added
KagiApiErrorexception class for Kagi API-specific error handling
Changed
- Updated hashline prompt documentation with clearer operation syntax and improved examples showing full edit structure with path and edits array
- Refactored
hlinerefHandlebars helper to return JSON-quoted strings for safer embedding in JSON blocks within prompts - Improved
hashlineParseTextto correctly preserve blank lines and trailing empty strings in array input while stripping trailing newlines from string input - Optimized duplicate line detection in range replacements to use trimmed comparison, reducing false positives from whitespace differences
- Refactored Kagi search provider to use shared Kagi API utilities from
web/kagimodule - Changed HTML-to-text rendering priority order to try Kagi first, then Jina, Trafilatura, and Lynx
Fixed
- Fixed
isEscapedTabAutocorrectEnabledenvironment variable parsing to use switch statement for clearer logic and consistent default behavior
[13.7.2] - 2026-03-04
Added
- Added support for direct OAuth provider login via
/login <provider>command (e.g.,/login kagi) - Added optional
providerIdparameter toshowOAuthSelector()to enable direct provider selection without UI selector
Changed
- Simplified web search result formatting to omit empty sections and metadata when not present
[13.7.0] - 2026-03-03
Fixed
- Fixed
asktimeout handling to auto-select the recommended option instead of aborting the turn, while preserving explicit user-cancel abort behavior (#266)
[13.6.2] - 2026-03-03
Fixed
- Fixed LM Studio API key retrieval to use configured provider name instead of hardcoded 'lm-studio'
- Fixed resource content handling to properly check for empty text values (null/undefined)
- Fixed resource refresh tracking to prevent stale promise reuse when server connection changes
- Fixed update target resolution to properly handle cases where binary path cannot be resolved
[13.6.1] - 2026-03-03
Fixed
- Fixed
omp updatesilently succeeding without actually updating the binary when the update channel (bun global vs compiled binary) doesn't match the installation method (#247) - Added post-update verification that checks the resolved
ompbinary reports the expected version, with actionable warnings on mismatch omp updatenow detects when theompin PATH is not managed by bun and falls back to binary replacement instead of updating the wrong location
[13.6.0] - 2026-03-03
Added
- Added
mcp://internal URL protocol for reading MCP server resources directly via the read tool (e.g.,read(path="mcp://resource-uri")) - Added LM Studio integration to the model registry and discovery flow.
- Added support for authenticating with LM Studio using the
/login lm-studiocommand. - Added
fuse-projfstask isolation mode for Windows ProjFS-backed overlays. - Added
/mcp registry search <keyword>integration with Smithery, including interactive result selection, editable server naming before deploy, SmitheryconfigSchemaprompts, and immediate runtime reload so selected MCP tools are available without restarting - Added OAuth failure fallback in
/mcp registry searchdeploy flow to prompt for manual bearer tokens and validate them before saving configuration - Added Smithery auth support for
/mcp registry searchwith cached API key login (/mcp registry login,/mcp registry logout) and automatic login prompt/retry on auth or rate-limit responses
Changed
- Updated MCP resource update notifications to recommend using
read(path="mcp://<uri>")instead of the deprecatedread_resourcetool - Updated Anthropic Foundry environment variable documentation and CLI help text to the canonical names:
CLAUDE_CODE_USE_FOUNDRY,CLAUDE_CODE_CLIENT_CERT, andCLAUDE_CODE_CLIENT_KEY - Documented Foundry-specific Anthropic runtime configuration (
FOUNDRY_BASE_URL,ANTHROPIC_FOUNDRY_API_KEY,ANTHROPIC_CUSTOM_HEADERS,NODE_EXTRA_CA_CERTS) in environment variable reference docs fuse-overlaytask isolation now targetsfuse-overlayfson Unix hosts only; on Windows it falls back toworktreewith a<system-notification>suggestingfuse-projfs.fuse-projfsnow performs Windows ProjFS preflight checks and falls back toworktreewhen host or repository prerequisites are unavailable.- Cross-repo patch capture now uses the platform null device (
NULon Windows,/dev/nullelsewhere) forgit diff --no-index.
Removed
- Removed
read_resourcetool; MCP resource reading is now integrated into thereadtool viamcp://URLs
Fixed
- Fixed MCP resource subscription handling to prevent unsubscribing when notifications are re-enabled after being disabled
- Fixed LM Studio base URL validation to preserve invalid configured URLs instead of silently falling back to localhost
- Fixed URI template matching to correctly handle expressions that expand to empty strings
[13.5.6] - 2026-03-01
Changed
- Updated OAuth client name from 'oh-my-pi MCP' to 'Codex' for dynamic client registration
Fixed
- Fixed exit_plan_mode handler to abort active agent turn before opening plan approval selector, ensuring proper session cleanup
[13.5.5] - 2026-03-01
Added
- Added Kagi web search provider (Search API v0) with related searches support and automatic
KAGI_API_KEYdetection
[13.5.4] - 2026-03-01
Added
- Added
authServerUrlfield toAuthDetectionResultto capture OAuth server metadata fromMcp-Auth-Serverheaders - Added
extractMcpAuthServerUrl()function to parse and validateMcp-Auth-ServerURLs from error messages - Added support for
/.well-known/oauth-protected-resourcediscovery endpoint to resolve authorization servers - Added recursive auth server discovery to follow
authorization_serversreferences when discovering OAuth endpoints - Added
omp agents unpackCLI subcommand to export bundled subagent definitions to~/.omp/agent/agentsby default, with--projectsupport for./.omp/agents
Changed
- Enhanced
discoverOAuthEndpoints()to accept optionalauthServerUrlparameter and query both auth server and resource server for OAuth metadata - Improved OAuth metadata extraction to handle additional field name variations (
clientId,default_client_id,public_client_id) - Refactored OAuth endpoint discovery logic into reusable
findEndpoints()helper for consistent metadata parsing across multiple sources - Task subagents now strip inherited
AGENTS.mdcontext files and the task tool prompt no longer warns against repeating AGENTS guidance, aligning subagent context with explicit task inputs (#233)
Fixed
- Fixed MCP OAuth discovery to honor
Mcp-Auth-Servermetadata and resolve authorization endpoints from the declared auth server, restoring Figma MCP login URLs withclient_id(#235)
[13.5.3] - 2026-03-01
Added
- Auto-include
ast_grepandast_edittools when their text-based counterparts (grep,edit) are requested and the AST tools are enabled - Enforced tool decision in plan mode—agent now requires calling either
askorexit_plan_modewhen a turn ends without a required tool call - Auto-correction of escaped tab indentation in edits (enabled by default, controllable via
PI_HASHLINE_AUTOCORRECT_ESCAPED_TABSenvironment variable) - Warning when suspicious Unicode escape placeholder
\uDDDDis detected in edit content
Changed
- Updated bash tool description to conditionally show
ast_grepandast_editguidance based on tool availability in the session - Replaced timeout-based cancellation with AbortSignal-based cancellation in the
asktool for more reliable user interaction handling - Updated
asktool to distinguish between user-initiated cancellation and timeout-driven auto-selection, with only user cancellation aborting the turn - Updated hashline documentation to clarify that
\tin JSON represents a real tab character, not a literal backslash-t sequence
Fixed
- Fixed race condition in dialog overlay handling where multiple concurrent resolutions could occur
- Cancelling the
asktool now aborts the current turn instead of returning a normal cancelled selection, while timeout-driven auto-cancel still returns without aborting
[13.5.2] - 2026-03-01
Added
- Added
checkpointtool to create context checkpoints before exploratory work, allowing you to investigate with many intermediate tool calls and minimize context cost afterward - Added
rewindtool to end an active checkpoint and replace intermediate exploration messages with a concise investigation report - Added
checkpoint.enabledsetting to control availability of the checkpoint and rewind tools - Added
render_mermaidtool to convert Mermaid graph source into ASCII diagram output - Added
renderMermaid.enabledsetting to control availability of the render_mermaid tool
Changed
- Changed Mermaid rendering from PNG images to ASCII diagrams in theme rendering
- Changed
prerenderMermaid()function to synchronously render ASCII instead of asynchronously rendering PNG
[13.5.0] - 2026-03-01
Added
- Added
hlinejsonrefHandlebars helper for embedding hashline references inside JSON blocks in prompts - Added
librarianagent for researching external libraries and APIs by reading source code - Added
oracleagent for deep reasoning on debugging, architecture decisions, and technical advice - Added
dependenciesandrisksoutput fields to explore agent for better context handoff - Added support for
lsp,fetch,web_search, andast_greptools to explore, plan, and reviewer agents
Changed
- Enhanced hashline tool documentation with explicit prohibition on formatting-only edits
- Added mandatory rule requiring indentation in
linesto match surrounding context exactly fromreadoutput - Changed explore agent output field
querytosummarywith expanded description for findings and conclusions
[13.4.1] - 2026-03-01
Fixed
- Pending resolve reminders now trigger as soon as a preview action is queued, before the next assistant turn, with regression coverage in
agent-session-resolve-remindertests
[13.4.0] - 2026-03-01
Breaking Changes
ast_grepparameterpattern(string) replaced bypatterns(string[])ast_editparameterspattern+rewritereplaced byops: Array<{ pat: string; out: string }>
Added
- Added
resolvetool to apply or discard pending preview actions with required reasoning - AST edit now registers pending actions after preview, allowing explicit apply/discard workflow via
resolvetool - Custom tools can register pending actions via
pushPendingAction(action)inCustomToolAPI, enabling theresolveworkflow for custom preview-apply flows deferrable?: booleanfield added toAgentTool,CustomTool, andToolDefinitioninterfaces; tools that set it signal they may stage pending actionsHIDDEN_TOOLSandResolveToolexported from@oh-my-pi/pi-coding-agentSDK for manual tool compositionPendingActionStorenow uses a LIFO stack (push/peek/pop); multiple deferrable tools can stage actions that resolve in reverse order of registration- Added
gemini,codex, andsyntheticas supported values for theproviders.webSearchsetting ast_greptool now accepts apatternsarray (replaces singlepattern); multiple patterns run in one native pass and results are merged before offset/limitast_edittool now accepts anopsarray of{ pat, out }entries (replacespattern+rewrite); duplicate patterns are rejected upfront- AST find output now uses
>>prefix on match-start lines and pads line numbers; directory-tree grouping with# dir/## └─ fileheaders for directory-scoped searches - AST replace output now renders diff-style (
-before/+after) change previews grouped by directory - Both AST tools now report
scopePath,files, and per-file match/replacement counts in tool details - Task item
idmax length raised from 32 to 48 characters - Anthropic web search provider now uses
buildAnthropicSearchHeaders(dedicated search header builder separate from inference headers) - Gemini web search provider: endpoint fallback (daily → sandbox) with retry on 429/5xx
- Gemini web search now injects Antigravity system instruction and aligned request metadata (
requestType,userAgent,requestId) for Antigravity credentials buildGeminiRequestTools()helper for composable Gemini tool configuration (googleSearch, codeExecution, urlContext)- Web search schema exposes
max_tokens,temperature, andnum_search_resultsas tool parameters - Web search provider fallback: when an explicit provider is unavailable, resolves the auto chain instead of returning empty results
Changed
- Simplified
resolvetool output rendering to use inline highlighted format instead of boxed layout - Updated
resolvetool to parse source tool name from label using colon separator for cleaner display resolvetool is now conditionally injected: included only when at least one active tool hasdeferrable: true(previously always included)discoverAndLoadCustomTools/loadCustomToolsaccept an optionalpendingActionStoreparameter to wirepushPendingActionfor custom tools- AST edit tool no longer accepts
previewparameter; all AST edit calls now return previews by default - AST edit workflow changed: preview is always shown, then use
resolvetool to apply or discard changes - Agent now suggests calling
resolvetool after AST edit preview with system reminder ast_grep:include_metaparameter removed; metavariable captures are now always included in outputast_edit:dry_runrenamed topreview;max_filesremoved from schema and capped globally via$PI_MAX_AST_FILES(default 1000);max_replacementsrenamed tolimitast_grepandast_edit: parse errors in tool output are now capped atPARSE_ERRORS_LIMIT(20); excess errors are summarised asN / total parse issuesrather than flooding the context- Updated
ast_grepandast_edittool prompt examples to use concise, idiomatic patterns
Removed
- Removed
normativeRewritesetting that rewrote tool call arguments to normalized format in session history - Removed
buildNormativeUpdateInput()helper and normative patch transformation logic
Fixed
ast_editno longer rejects emptyoutvalues; an empty string now deletes matched nodesast_editno longer trimspatandoutvalues, preserving intentional whitespacegemini_imagetool: correctedresponseModalitiesvalues from'Image'/'Text'to uppercase'IMAGE'/'TEXT'matching the API enum
[13.3.14] - 2026-02-28
Added
- Expanded AST tool language support from 7 to all 25 ast-grep tree-sitter languages (Bash, C, C++, C#, CSS, Elixir, Go, Haskell, HCL, HTML, Java, JavaScript, JSON, Kotlin, Lua, Nix, PHP, Python, Ruby, Rust, Scala, Solidity, Swift, TSX, TypeScript, YAML)
- AST find now emits all lines of multiline matches with hashline tags (LINE#HASH:content) consistent with read/grep output
- Added AST pattern syntax reference (metavariables, wildcards, variadics) to system prompt
- Added examples and scoping guidance to ast-find and ast-replace tool prompts
- Added
provider-schema-compatibility.test.ts: integration test that instantiates every builtin and hidden tool, runs their parameter schemas throughadaptSchemaForStrict,sanitizeSchemaForGoogle, andprepareSchemaForCCA, and asserts zero violations against each provider's compatibility rules
Fixed
- Non-code files (.md, .zip, .bin, .gitignore, etc.) are now silently skipped by AST tools instead of producing misleading parse errors
- Fixed
greppath wildcard handling so file patterns passed viapath(for exampleschema-review-*.test.ts) are resolved as glob filters instead of failing path existence checks
[13.3.11] - 2026-02-28
Fixed
- Restored inline rendering for
readtool image results in assistant transcript components, including streaming and rebuilt session history paths. - Fixed shell-escaped read paths (for example, pasted
\-escaped screenshot filenames) by resolving unescaped fallback candidates before macOS filename normalization variants.
[13.3.8] - 2026-02-28
Added
- Added
ast_findtool for structural code search using AST matching via ast-grep, enabling syntax-aware pattern discovery across codebases - Added
ast_replacetool for structural AST-aware rewrites via ast-grep, enabling safe syntax-level codemods without text-based fragility - Added
astFind.enabledandastReplace.enabledsettings to control availability of AST tools - Added system prompt guidance to prefer AST tools over bash text manipulation (grep/sed/awk/perl) for syntax-aware operations
- Extracted prompt formatting logic into reusable
formatPromptContent()utility with configurable render phases and formatting options - Added
type_definitionaction to navigate to symbol type definitions with source context - Added
implementationaction to find concrete implementations of symbols with source context - Added
code_actionsaction to list and apply language server code fixes, refactors, and import suggestions - Added
symbolparameter to automatically resolve column position by searching for substring on target line - Added
occurrenceparameter to disambiguate repeatedsymbolmatches on the same line - Added source code context display (3 lines) for definition, type definition, and implementation results
- Added context display for first 50 references with remaining references shown location-only to balance detail and performance
- Added support for glob patterns in
fileparameter for diagnostics action (e.g.,src/**/*.ts) - Added
waitForIdle()method to ensure prompt completion waits for all deferred recovery work (TTSR continuations, context promotions, compaction retries) to fully settle - Added
getLastAssistantMessage()method to retrieve the most recent assistant message from session state without manual array indexing - Implemented TTSR resume gate to ensure
prompt()blocks until TTSR interrupt continuations complete, preventing race conditions between TTSR injections and subsequent prompts - Added
tools.maxTimeoutsetting to enforce a global timeout ceiling across all tool calls
Changed
- Replaced
globSyncfromglobpackage with nativeBun.GlobAPI for glob pattern matching - Replaced
fileTypeFromBufferfromfile-typepackage with inline MIME type detection for JPEG, PNG, GIF, and WebP formats - Reduced MIME type sniffing buffer size from 4100 bytes to 12 bytes for improved performance
- Changed mermaid cache key type from
stringtobigintfor more efficient hashing - Replaced
smol-tomldependency with nativeBun.TOML.parse()for TOML parsing, reducing external dependencies - Replaced
node-html-parserdependency withlinkedomfor HTML parsing, improving performance and reducing bundle size - Updated HTML parsing API calls from
node-html-parsertolinkedomacross all web scrapers (arXiv, IACR, Go pkg, Read the Docs, Twitter, Wikipedia) - Changed element text extraction from
.textproperty to.textContentproperty for compatibility with linkedom DOM API - Optimized document link extraction to use regex-based parsing with deduplication and a 20-link limit instead of full DOM traversal
- Unified
pathparameter in ast_find and ast_replace tools to accept files, directories, or glob patterns directly, eliminating the separateglobparameter - Removed
strictnessparameter from ast_find and ast_replace tools - Removed
fail_on_parse_errorparameter from ast_replace tool (now always false) - Updated ast_find and ast_replace prompt guidance to clarify that
pathaccepts glob patterns and no longer requires separate glob specification - Refactored prompt template rendering to use unified
formatPromptContent()function with phase-aware formatting (pre-render vs post-render) - Updated
format-prompts.tsscript to use centralized prompt formatting utility instead of inline implementation - Replaced
columnparameter withsymbolparameter for more intuitive position specification - Removed
filesparameter; use glob patterns infileparameter instead - Removed
end_lineandend_characterparameters; range operations now use single position - Changed
include_declarationparameter to always be true for references (removed from API) - Updated LSP client capabilities to advertise support for
typeDefinitionandimplementationrequests - Improved definition results to include source context alongside location information
- Refactored deferred continuation scheduling to use centralized post-prompt task tracking instead of raw
setTimeout()calls, improving reliability of concurrent recovery operations - Updated subagent executor to explicitly await
waitForIdle()after each prompt and reminder, ensuring terminal assistant state is determined only after all background work completes - Replaced
#waitForRetry()with#waitForPostPromptRecovery()to handle both retry and TTSR resume gates, ensuring prompt completion waits for all post-prompt recovery operations - Introduced structured post-prompt recovery task tracking in
AgentSessionand added explicit session completion APIs (waitForIdle(),getLastAssistantMessage()) for callers that need deterministic turn finalization - Updated intent field parameter name from
agent__intentto_ifor cleaner tool call contracts - Refined intent parameter guidance to require concise 2-6 word sentences in present participle form
- Centralized per-tool timeout constants and clamping into
tool-timeouts.ts
Removed
- Removed
file-typedependency, reducing external dependencies - Removed
globdependency in favor of nativeBun.GlobAPI - Removed
ignoredependency and ignore file handling utilities - Removed
markeddependency - Removed
zoddependency - Removed
msand@types/msdev dependencies - Removed
rootDirandignoreMatcherparameters fromloadFilesFromDir()(kept for API compatibility) - Removed
smol-tomldependency from package.json - Removed
node-html-parserdependency from package.json - Removed
filesarray parameter for batch file operations - Removed
column,end_line, andend_characterparameters in favor of symbol-based positioning - Removed
include_declarationparameter from references action
Fixed
- Fixed TTSR violations during subagent execution aborting the entire subagent run;
#waitForPostPromptRecovery()now also awaits agent idle after TTSR/retry gates resolve, preventingprompt()from returning while a fire-and-forgetagent.continue()is still streaming - Fixed deferred TTSR/context-promotion continuations still racing
prompt()completion by tracking compaction checks and deferredagent.continue()tasks under a shared post-prompt recovery orchestrator - Fixed subagent reminder/finalization sequencing to await session-level idle recovery between prompts before determining terminal assistant stop state
- Fixed
code_actionsapply mode to execute command-based actions viaworkspace/executeCommand - Fixed diagnostics glob detection to recognize bracket character class patterns (e.g.,
src/[ab].ts) - Fixed LSP render metadata sanitization for
symbolvalues to prevent tab/newline layout breakage - Fixed LSP diagnostics glob requests that appeared stuck by capping glob expansion and shortening per-file diagnostic waits in batch mode
- Fixed workspace symbol search to query all configured LSP servers and filter out non-matching results
- Fixed
references/rename/hoversymbol targeting to error whensymbolis missing on the line oroccurrenceis out of bounds - Fixed
reloadwithout a file to reload all active configured language servers instead of only the first server - Fixed
todo_writetask normalization to auto-activate the first remaining task and include explicit remaining-items output in tool results, removing the need for an immediate follow-up start update
[13.3.7] - 2026-02-27
Breaking Changes
- Removed
preloadedSkillsoption fromCreateAgentSessionOptions; skills are no longer inlined into system prompts - Removed
skillsfield from Task schema; subagents now always inherit the session skill set instead of per-task skill selection - Removed Task tool per-task
tasks[].skillssupport; subagents now always inherit the session skill set - Removed
preloadedSkillssystem prompt plumbing and template sections; skills are no longer inlined as a separate preloaded block
Changed
- Refactored schema reference resolution to inline all
$refdefinitions instead of preserving them at the root level, eliminating unresolved references in tool parameters - Added
lenientArgValidationflag to SubmitResultTool to allow the agent loop to bypass strict argument validation errors - Modified schema validation to allow non-conforming output on second validation failure, enabling recovery from strict schema constraints after initial rejection
- Updated JTD-to-TypeScript conversion to gracefully fall back to 'unknown' type when conversion fails, preventing template rendering errors
- Changed JTD-to-JSON Schema conversion to normalize nested JTD fragments within JSON Schema nodes, enabling mixed schema definitions
- Changed output schema validation to gracefully fall back to unconstrained object when schema is invalid, instead of rejecting submissions
- Changed schema sanitization to remove strict-mode incompatible constraints (minLength, pattern, etc.) from tool parameters while preserving them for runtime validation
- Simplified task execution to always pass available session skills to subagents instead of resolving per-task skill lists
- Added
KILO_API_KEYto CLI environment variable help text for Kilo Gateway provider setup (#193)
Removed
- Removed preloaded skills section from system prompt templates; skills are now referenced only as available resources
Fixed
- Fixed schema compilation validation by adding explicit AJV compilation check to catch unresolved
$refreferences and other schema errors before tool execution - Fixed handling of circular and deeply nested output schemas to prevent stack overflow and enable successful result submission with fallback unconstrained schema
- Fixed processing of non-object output schemas (arrays, primitives, booleans) to accept valid result submissions without blocking
- Fixed handling of mixed JTD and JSON Schema output definitions to properly convert all nested JTD elements (e.g.,
elements→items,int32→integer) - Fixed strict schema generation for output schemas with only required fields, enabling proper Claude API compatibility
- Fixed handling of union type schemas (e.g., object|null) to normalize them into strict-mode compatible variants
[13.3.6] - 2026-02-26
Breaking Changes
- Changed
submit_resulttool parameter structure from top-leveldataorerrorfields to nestedresultobject containing eitherresult.dataorresult.error
[13.3.5] - 2026-02-26
Added
- Added support for setting array and record configuration values using JSON syntax
Changed
- Increased default async max jobs limit from 15 to 100 for improved concurrent task handling
Fixed
- Improved config display formatting to properly render arrays and objects as JSON instead of
[object Object] - Enhanced type display in config list output to show correct type indicators for number, array, and record settings
[13.3.3] - 2026-02-26
Added
- Support for
moveparameter incomputeHashlineDiffto enable file move operations alongside content edits
Changed
- Modified no-op detection logic to allow move-only operations when file content remains unchanged
[13.3.1] - 2026-02-26
Added
- Added
topPsetting to control nucleus sampling cutoff for model output diversity - Added
topKsetting to sample from top-K tokens for controlled generation - Added
minPsetting to enforce minimum probability threshold for token selection - Added
presencePenaltysetting to penalize introduction of already-present tokens - Added
repetitionPenaltysetting to penalize repeated tokens in model output
Fixed
- Fixed skill discovery to continue loading project skills when user skills directory is missing
[13.3.0] - 2026-02-26
Breaking Changes
- Renamed
task.isolation.enabled(boolean) setting totask.isolation.mode(enum:none,worktree,fuse-overlay). Existingtrue/falsevalues are auto-migrated toworktree/none.
Added
- Added
PERPLEXITY_COOKIESenv var for Perplexity web search via session cookies extracted from desktop app - Added
fuse-overlayisolation mode for subagents usingfuse-overlayfs(copy-on-write overlay, no baseline patch apply needed) - Added
task.isolation.mergesetting (patchorbranch) to control how isolated task changes are integrated back.branchmode commits each task to a temp branch and cherry-picks for clean commit history - Added
task.isolation.commitssetting (genericorai) for commit messages on isolated task branches and nested repos.aimode uses a smol model to generate conventional commit messages from diffs - Nested non-submodule git repos are now discovered and handled during task isolation (changes captured and applied independently from parent repo)
- Added
task.eagersetting to encourage the agent to delegate work to subagents by default - Added manual OAuth login flow that lets users paste redirect URLs with /login for callback-server providers and prevents overlapping logins
Fixed
- Fixed nested repo changes being lost when tasks commit inside the isolation (baseline state is now committed before task runs, so delta correctly excludes it)
- Fixed nested repo patches conflicting when multiple tasks contribute to the same repo (baseline untracked files no longer leak into patches)
- Nested repo changes are now committed after patch application (previously left as untracked files)
- Failed tasks no longer create stale branches or capture garbage patches (gated on exit code)
- Merge failures (e.g. conflicting patches) are now non-fatal — agent output is preserved with
merge failedstatus instead offailed - Stale branches are cleaned up when
commitToBranchfails - Commit message generator filters lock files from diffs before AI summarization
[13.2.1] - 2026-02-24
Fixed
- Fixed changelog tools to enforce category-specific arrays and reuse the shared category list for generation
- Non-interactive environment variables (pager, editor, prompt suppression) were not applied to non-PTY bash execution, causing commands to potentially block on pagers or prompts
Changed
- Extracted non-interactive environment config from
bash-interactive.tsinto sharednon-interactive-env.tsmodule, applied consistently to all bash execution paths
[13.2.0] - 2026-02-23
Breaking Changes
- Made
descriptionfield required in CustomTool interface
[13.1.2] - 2026-02-23
Breaking Changes
- Removed
timeoutparameter from await tool—tool now waits indefinitely until jobs complete or the call is aborted - Renamed
job_idsparameter tojobsin await tool schema - Removed
timedOutfield from await tool result details
[13.1.1] - 2026-02-23
Fixed
- Fixed bash internal URL expansion to resolve
local://targets to concrete filesystem paths, including newly created destination files for commands likemv src.json local://dest.json - Fixed bash local URL resolution to create missing parent directories under the session local root before command execution, preventing
mvdestination failures for new paths
[13.1.0] - 2026-02-23
Breaking Changes
- Renamed
fileparameter topathin replace, patch, and hashline edit operations
Added
- Added clarification in hashline edit documentation that the
endtag must include closing braces/brackets when replacing blocks to prevent syntax errors
Changed
- Restructured task tool documentation for clarity, moving parameter definitions into a dedicated section and consolidating guidance on context, assignments, and parallelization
- Reformatted system prompt template to use markdown headings instead of XML tags for skills, preloaded skills, and rules sections
- Renamed
deviceScaleFactorparameter todevice_scale_factorin browser viewport configuration for consistency with snake_case naming convention - Moved intent field documentation from per-tool JSON schema descriptions into a single system prompt block, reducing token overhead proportional to tool count
[13.0.1] - 2026-02-22
Changed
- Simplified hashline edit schema to use unified
first/lastanchor fields instead of operation-specific field names (tag,before,after) - Improved resilience of anchor resolution to degrade gracefully when anchors are missing or invalid, allowing edits to proceed with available anchors
- Updated hashline tool documentation to reflect new unified anchor syntax across all operations (replace, append, prepend, insert)
[13.0.0] - 2026-02-22
Added
- Added
getTodoPhases()andsetTodoPhases()methods to ToolSession API for managing todo state programmatically - Added
getLatestTodoPhasesFromEntries()export to retrieve todo phases from session history - Added
local://protocol for session-scoped scratch space to store large intermediate artifacts, subagent handoffs, and reusable planning artifacts - Added
titleparameter toexit_plan_modetool to specify the final plan artifact name when approving a plan - Added
LocalProtocolHandlerfor resolvinglocal://URLs to session-scoped file storage - Added
renameApprovedPlanFilefunction to finalize approved plans with user-specified titles
Changed
- Changed todo state management from file-based (
todos.json) to in-memory session cache for improved performance and consistency - Changed todo phases to sync from session branch history when branching or rewriting entries
- Changed
TodoWriteToolto update session cache instead of writing to disk, with automatic persistence through session entries - Changed XML tag from
<swarm-context>to<context>in subagent prompts and task rendering - Changed system reminder XML tags from underscore to kebab-case format (
<system-reminder>) - Changed plan storage from
plan://protocol tolocal://PLAN.mdfor draft plans andlocal://<title>.mdfor finalized approved plans - Changed plan mode to use session artifacts directory for plan storage instead of separate plans directory
- Updated system prompt to document
local://protocol and internal URL expansion behavior - Updated
exit_plan_modetool documentation to requiretitleparameter and explain plan finalization workflow - Updated
writetool documentation to recommendlocal://for large temporary artifacts and subagent handoffs - Updated
tasktool documentation to recommend usinglocal://for large intermediate outputs in subagent context - Replaced
docs://protocol withpi://for accessing embedded documentation files - Renamed
DocsProtocolHandlertoPiProtocolHandlerfor internal documentation URL resolution - Removed
artifactsDirparameter from Python executor options; artifact storage now usesartifactPathonly - Renamed prompt file from
read_path.mdtoread-path.mdfor consistency - Updated system prompt XML tags to use kebab-case (e.g.,
system-reminder,system-interrupt) for consistency - Refactored bash tool to use
NO_PAGER_ENVconstant for environment variable management - Updated internal URL expansion to support optional
noEscapeparameter for unescaped path resolution
Removed
- Removed
plan://protocol handler and related plan directory resolution logic - Removed
PlanProtocolHandlerandresolvePlanUrlToPathexports from internal URLs module
Fixed
- Fixed todo reminder XML tags from underscore to kebab-case format (
system-reminder)
[12.19.3] - 2026-02-22
Added
- Added
ptyparameter to bash tool to enable PTY mode for commands requiring a real terminal (e.g., sudo, ssh, top, less)
Changed
- Changed bash tool to use per-command PTY control instead of global virtual terminal setting
Removed
- Removed
bash.virtualTerminalsetting; use theptyparameter on individual bash commands instead
[12.19.1] - 2026-02-22
Removed
- Removed
replaceTextedit operation from hashline mode (substring-based text replacement) - Removed autocorrect heuristics that attempted to detect and fix line merges and formatting rewrites in hashline edits
[12.19.0] - 2026-02-22
Added
- Added
poll_jobstool to block until background jobs complete, providing an alternative to pollingread jobs://in loops - Added
task.maxConcurrencysetting to limit the number of concurrently executing subagent tasks - Added support for rendering markdown output from Python cells with proper formatting and theme styling
- Added async background job execution for bash commands and tasks with
async: trueparameter - Added
cancel_jobtool to cancel running background jobs - Added
jobs://internal protocol to inspect background job status and results - Added
/jobsslash command to display running and recent background jobs in interactive mode - Added
async.enabledandasync.maxJobssettings to control background job execution - Added background job status indicator in status line showing count of running jobs
- Added support for GitLab Duo authentication provider
- Added clearer truncation notices across tools with consistent line/size context and continuation hints
Changed
- Updated bash and task tool guidance to recommend
poll_jobsinstead of pollingread jobs://in loops when waiting for async results - Improved parallel task execution to schedule multiple background jobs independently instead of batching all tasks into a single job, enabling true concurrent execution
- Enhanced task progress tracking to report per-task status (pending, running, completed, failed, aborted) with individual timing and token metrics for each background task
- Updated background task messaging to provide real-time progress counts (e.g., '2/5 finished') and distinguish between single and multiple task jobs
- Hid internal
agent__intentparameter from tool argument displays in UI and logs to reduce visual clutter - Updated Python tool to detect and handle markdown display output separately from plain text
- Updated bash tool to support async execution mode with streaming progress updates
- Updated task tool to support async execution mode for parallel subagent execution
- Modified subagent settings to disable async execution in child agents to prevent nesting
- Updated tool execution component to handle background async task state without spinner animation
- Changed event controller to keep background tool calls pending until async completion
- Updated status line width calculation to accommodate background job indicator
- Updated the system prompt pipeline to reduce injected environment noise and make instructions more focused on execution quality
- Updated system prompt/workflow guidance to emphasize root-cause fixes, code quality, and explicit handoff/testing expectations
- Changed default value of
todo.reminderssetting from false to true to enable todo reminders by default - Improved truncation/output handling for large command results to reduce memory pressure and keep previews responsive
- Updated internal artifact handling so tool output artifacts stay consistent across session switches and resumes
Removed
- Removed git context (branch, status, commit history) from system prompt — version control information is no longer injected into agent instructions
Fixed
- Fixed task progress display to hide tool count and token metrics when zero, reducing visual clutter in status output
- Fixed Lobsters scraper to correctly parse API responses where user fields are strings instead of objects, resolving undefined user display in story listings
- Fixed artifact manager caching to properly invalidate when session file changes, preventing stale artifact references
- Fixed truncation behavior around UTF-8 boundaries and chunked output accounting
- Fixed
submit_resultschema generation to use valid JSON Schema when no explicit output schema is provided
[12.18.1] - 2026-02-21
Added
- Added Buffer.toBase64() polyfill for Bun compatibility to enable base64 encoding of buffers
[12.18.0] - 2026-02-21
Added
- Added
overlayoption to custom UI hooks to display components as bottom-centered overlays instead of replacing the editor - Added automatic chat transcript rebuild when returning from custom or debug UI to prevent message duplication
Changed
- Changed custom UI hook cleanup to conditionally restore editor state only when not using overlay mode
- Extracted environment variable configuration for non-interactive bash execution into reusable
NO_PAGER_ENVconstant - Replaced custom timing instrumentation with logger.timeAsync() and logger.time() from pi-utils for consistent startup profiling
- Removed PI_DEBUG_STARTUP environment variable in favor of logger.debug() for conditional debug output
- Consolidated timing calls throughout initialization pipeline to use unified logger-based timing system
Removed
- Deleted utils/timings.ts module - timing functionality now provided by pi-utils logger
Fixed
- Fixed potential race condition in bash interactive component where output could be appended after the component was closed
[12.17.2] - 2026-02-21
Changed
- Modified bash command normalization to only apply explicit head/tail parameters from tool input, removing automatic extraction from command pipes
- Updated shell snapshot creation to use explicit timeout and kill signal configuration for more reliable process termination
Fixed
- Fixed persistent shell session state not being reset after command abort or hard timeout, preventing stale environment variables from affecting subsequent commands
- Fixed hard timeout handling to properly interrupt long-running commands that exceed the grace period beyond the configured timeout
[12.17.1] - 2026-02-21
Added
- Added
filterBrowseroption to filter out browser automation MCP servers when builtin browser tool is enabled - Added
isBrowserMCPServer()function to detect browser automation MCP servers by name, URL, or command patterns - Added
filterBrowserMCPServers()function to remove browser MCP servers from loaded configurations - Added
BrowserFilterResulttype for browser MCP server filtering results
[12.17.0] - 2026-02-21
Added
- Added timeout protection (5 seconds) for system prompt preparation with graceful fallback to minimal context on timeout
Changed
- Replaced glob-based AGENTS.md discovery with depth-limited directory traversal (depth 1-4) for improved performance and control
- Refactored system prompt preparation to parallelize file loading operations with a 5-second timeout to prevent startup hangs
- Unified
renderCallsignatures to(args, options, theme)across all tool renderers and extension types
[12.16.0] - 2026-02-21
Added
- Added
peekApiKeymethod to AuthStorage for non-blocking API key retrieval during model discovery without triggering OAuth token refresh - Exported
finalizeSubprocessOutputfunction to handle subprocess output finalization with submit_result validation - Exported
SubmitResultIteminterface for type-safe submit_result tool data extraction - Added automatic reminders when subagent stops without calling submit_result tool (up to 3 reminders before aborting)
- Added system warnings when subagent calls submit_result with null/undefined data or exits without calling submit_result after reminders
Changed
- Changed model refresh behavior to support configurable strategies: uses 'online' mode when listing models and 'online-if-uncached' mode otherwise for improved performance
- Changed default thinking level from 'off' to 'high' for improved reasoning and planning
- Changed model discovery to use non-blocking API key peek instead of full key retrieval, improving performance by avoiding unnecessary OAuth token refreshes
- Simplified submit_result termination logic to immediately abort on successful tool execution instead of waiting for message_end event
- Updated submit_result tool to only terminate on successful execution (when isError is false), allowing retries on tool errors
- Refactored subprocess output finalization logic into dedicated
finalizeSubprocessOutputfunction for better testability and maintainability - Improved handling of missing submit_result calls by automatically aborting with exit code 1 after 3 reminder prompts
Fixed
- Fixed submit_result retry behavior to properly handle tool execution errors and allow the subagent to retry before aborting
- Fixed submit_result tool extraction to properly validate status field and only accept 'success' or 'aborted' results
[12.15.1] - 2026-02-20
Changed
- Replaced nerd font pie-chart spinner with clock-outline icons for smoother looping
- Moved status icon to front of code-cell headers in formatHeader
Fixed
- Fixed ReadToolGroupComponent to show status icon before title instead of trailing
- Fixed bash-interactive status badge to dim only bracket characters, not the enclosed text
[12.15.0] - 2026-02-20
Added
- Added
includeDisabledparameter tolistAuthCredentials()to optionally retrieve disabled credentials - Added
disableAuthCredential()method for soft-deleting auth credentials while preserving database records
Changed
- Changed auth credential removal to use soft-delete (disable) instead of hard-delete when OAuth refresh fails, keeping credentials in database for audit purposes
- Changed default value of
tools.intentTracingsetting from false to true
[12.14.1] - 2026-02-19
Fixed
- Fixed
omp statsfailing on npm/bun installs by including required stats build files in published@oh-my-pi/omp-statspackage (#113 by @masonc15)
[12.14.0] - 2026-02-19
Added
- Support for
docs://internal URL protocol to access embedded documentation files (e.g.,docs://sdk.md) - Added
generate-docs-indexnpm script to automatically index and embed documentation files at build time - Support for executable tool files (.ts, .js, .sh, .bash, .py) in custom tools discovery alongside markdown files
- Display streamed tool intent in working message during agent execution
- Added
tools.intentTracingsetting to enable intent tracing, which asks the agent to describe the intent of each tool call before executing it - Support for file deletion in hashline edit mode via
delete: trueparameter - Support for file renaming/moving in hashline edit mode via
renameparameter - Optional content-replace edit variant in hashline mode (enabled via
PI_HL_REPLACETXT=1environment variable) - Support for grepping internal URLs (artifact://) by resolving them to their backing files
Changed
- System prompt now identifies agent as operating inside Oh My Pi harness and instructs reading docs:// URLs for omp/pi topics
- Tool discovery now accepts executable script extensions (.ts, .js, .sh, .bash, .py) in addition to .json and .md files
- Updated bash and read tool documentation to reference
docs://URL support - Hashline format separator changed from pipe (
|) to colon (:) for improved readability (e.g.,LINE#ID:contentinstead ofLINE#ID|content) - Hashline hash representation changed from 4-character base36 to 2-character hexadecimal for more compact line references
- Hashline edit API: renamed
deleteparameter tormfor consistency with standard file operations - Hashline edit API: renamed
renameparameter tomvfor consistency with standard file operations - Hashline edit API: content-replace operations now require explicit
op: "replaceText"field to distinguish from other edit types - Hashline documentation terminology updated: references to 'anchors' replaced with 'tags' for clearer semantics
- Intent tracing now uses
_intentfield name in tool schemas - Hashline edit API: renamed
setoperation totarget/new_contentfor clearer semantics - Hashline edit API: renamed
set_rangeoperation tofirst/last/new_content - Hashline edit API: renamed
insertoperation fields frombodytoinserted_linesand madeinserted_linesrequired non-empty - Hashline edit API: flattened
replaceoperation to top-level fields (old_text,new_text,all) when enabled - Hashline edit validation now provides more specific error messages indicating which variant is expected
Fixed
- Grep tool now properly handles internal URL resolution when searching artifact paths
- Working message intent updates now fall back to tool execution events when streamed tool arguments omit the intent field
[12.13.0] - 2026-02-19
Breaking Changes
- Removed automatic line relocation when hash references become stale; edits with mismatched line hashes now fail with an error instead of silently relocating to matching lines elsewhere in the file
Added
- Added
sshcommand for managing SSH host configurations (add, list, remove) - Added
/sshslash command in interactive mode to manage SSH hosts with subcommands - Added support for SSH host configuration at project and user scopes (.omp/ssh.json and ~/.omp/agent/ssh.json)
- Added
--host,--user,--port,--key,--desc,--compat, and--scopeflags for SSH host configuration - Added discovery of SSH hosts from project configuration files alongside manually configured hosts
- Added NanoGPT as a login provider (
/login nanogpt) with API key prompt flow linking tohttps://nano-gpt.com/api(#111)
Changed
- Updated hashline reference format from
LINE:HASHtoLINE#IDthroughout the codebase for improved clarity - Renamed hashline edit operations:
set_line→set,replace_lines→set_range,insert_after→insertwith support forbeforeandbetweenanchors - Changed hashline edit
bodyfield from string to array of strings for clearer multiline handling - Updated handlebars helpers: renamed
hashlinetohlinerefand addedhlinefullfor formatted line output - Improved insert operation to support
before,after, andbetween(both anchors) positioning modes - Made autocorrect heuristics (boundary echo stripping, indent restoration) conditional on
PI_HL_AUTOCORRECTenvironment variable - Updated SSH host discovery to load from managed omp config paths (.omp/ssh.json and ~/.omp/agent/ssh.json) in addition to legacy root-level ssh.json and .ssh.json files
- Improved terminal output handling in interactive bash sessions to ensure all queued writes complete before returning results
Fixed
- Fixed insert-between operation to properly validate adjacent anchor lines and strip boundary echoes from both sides
- Fixed terminal output handling to properly queue and serialize writes, preventing dropped or corrupted output in interactive bash sessions
[12.12.1] - 2026-02-19
Added
- Added Kimi (Moonshot) as a web search provider with OAuth and API key support (#110 by @oglassdev)
Changed
- Changed web search auto-resolve priority to prefer Perplexity first
Fixed
- Fixed Mermaid pre-render failures from repeatedly re-triggering background renders (freeze loop) and restored resilient rendering when diagram conversion/callbacks fail (#109).
[12.12.0] - 2026-02-19
Added
- Display streaming text preview during agent specification generation to show real-time progress
- Added
onRequestRendercallback to agent dashboard for triggering UI updates during async operations - Added agent creation flow (press N in dashboard) to generate custom agents from natural language descriptions
- Added ability to save generated agents to project or user scope with automatic identifier and system prompt generation
- Added scope toggle (Tab) during agent creation to choose between project-level and user-level agent storage
- Added agent regeneration (R key) to refine generated specifications without restarting the creation flow
- Added model suggestions in model override editor to help users discover available models
- Added success notices to confirm agent creation and model override updates
Changed
- Updated agent creation flow to show review screen before generation completes, improving UX feedback
- Changed generation status hint to display "Generating..." while specification is being created
- Improved system prompt preview formatting with text wrapping and line truncation indicators
Fixed
- Fixed interactive-mode editor height to stay bounded and resize-aware, preventing off-screen cursor drift during long prompt/history navigation (#99).
[12.11.3] - 2026-02-19
Fixed
- Fixed model selector search initialization to apply the latest live query after asynchronous model loading.
- Fixed Codex provider session lifecycle on model switches and history rewrites to clear stale session metadata before continuing the conversation.
[12.11.0] - 2026-02-19
Added
- Support for Synthetic model provider in web search command
- Model sorting by priority field and version number in model selector for improved model ranking
- Support for Synthetic model provider with API key authentication
- Support for Hugging Face model provider with API key authentication
- Support for NVIDIA model provider with API key authentication
- Support for Ollama model provider with optional API key authentication
- Support for Cloudflare AI Gateway model provider with API key authentication
- Support for Qwen Portal model provider with API key authentication
- Support for LiteLLM model provider with API key authentication
- Support for Moonshot model provider with API key authentication
- Support for Qianfan model provider with API key authentication
- Support for Together model provider with API key authentication
- Support for Venice model provider with API key authentication
- Support for vLLM model provider with API key authentication
- Support for Xiaomi model provider with API key authentication
Changed
- Refactored custom model building logic into reusable
buildCustomModelfunction for consistency across provider configurations - Replaced generic error with AgentBusyError when attempting to send messages while agent is processing
- Added automatic retry logic with idle waiting when agent is busy during prompt operations, with 30-second timeout
Fixed
- Fixed model discovery to use default refresh mode instead of explicit 'online' parameter
[12.10.1] - 2026-02-18
Added
- Added
/loginsupport for Cerebras and Synthetic API-key providers
[12.10.0] - 2026-02-18
Breaking Changes
- Changed keyless provider auth sentinel from
"<no-auth>"tokNoAuth("N/A") forModelRegistry.getApiKey()andModelRegistry.getApiKeyForProvider()
Added
- Added
--no-rulesCLI flag to disable rules discovery and loading - Added
sessionDiroption to RpcClientOptions for specifying agent session directory - Added
Symbol.disposemethod to RpcClient for resource cleanup support - Added
rulesoption to CreateAgentSessionOptions for explicit rule configuration - Added
sessionDiroption to RpcClientOptions for specifying agent session directory - Added
Symbol.disposemethod to RpcClient for resource cleanup support - Added
conditionandscopefields to rule frontmatter for advanced TTSR matching and stream filtering - Added
ttsr.interruptModesetting to control when TTSR rules interrupt mid-stream vs inject warnings after completion - Added support for loading rules, prompts, commands, context files (AGENTS.md), and system prompts (SYSTEM.md) from ~/.agent/ directory (with fallback to ~/.agents/)
- Added scoped stream buffering for TTSR matching to isolate prose, thinking, and tool argument streams
- Added file-path-aware TTSR scope matching for tool calls with glob patterns (e.g.,
tool:edit(*.ts)) - Added legacy field support:
ttsr_triggerandttsrTriggerare accepted as fallback forcondition
Changed
- Changed TTSR injection tracking to record all turns where rules were injected (instead of only the last turn) to support repeat-after-gap mode across resumed sessions
- Changed TTSR injection messages to use custom message type with metadata instead of synthetic user messages for better session tracking
- Changed TTSR rule injection to persist injected rule names in session state for restoration when resuming sessions
- Changed model discovery to automatically discover built-in provider models (Anthropic, OpenAI, Groq, Cerebras, Xai, Mistral, OpenCode, OpenRouter, Vercel AI Gateway, Kimi Code, GitHub Copilot, Google, Cursor, Google Antigravity, Google Gemini CLI, OpenAI Codex) when credentials are configured
- Changed
getModel()andgetModels()imports togetBundledModel()andgetBundledModels()across test utilities - Changed TTSR rule matching from single
ttsrTriggerregex to multipleconditionpatterns with scope filtering - Changed TTSR buffer management to use per-stream-key buffers instead of a single global buffer
- Changed rule discovery to use unified
buildRuleFromMarkdownhelper across all providers (builtin, cline, cursor, windsurf, agents) - Changed TTSR injection to defer warnings until stream completion when
interruptModeis notalways - Changed
TtsrManager.addRule()to return boolean indicating successful registration instead of void
Fixed
- Fixed TTSR repeat-after-gap mode to correctly calculate gaps when rules are restored from previous sessions
- Fixed TTSR matching to respect tool-specific scope filters, preventing cross-tool rule contamination
- Fixed path normalization in TTSR glob matching to handle both relative and absolute path variants
[12.9.0] - 2026-02-17
Added
- Added OpenCode discovery provider to load configuration from ~/.config/opencode/ and .opencode/ directories
- Added support for loading MCP servers from opencode.json mcp key
- Added support for loading skills from ~/.config/opencode/skills/ and .opencode/skills/
- Added support for loading slash commands from ~/.config/opencode/commands/ and .opencode/commands/
- Added support for loading extension modules (plugins) from ~/.config/opencode/plugins/ and .opencode/plugins/
- Added support for loading context files (AGENTS.md) from ~/.config/opencode/
- Added support for loading settings from opencode.json configuration files
Changed
- Improved path display in status line to strip both
/work/and~/Projects/prefixes when abbreviating paths - Refactored session directory naming to use single-dash format for home-relative paths and double-dash format for absolute paths, with automatic migration of legacy session directories on first access
[12.8.2] - 2026-02-17
Changed
- Changed system environment context to use built-in
osvalues for distro, kernel, and CPU model instead of native system-info data - Changed environment info generation to stop including unavailable native system detail fallbacks
Removed
- Removed the
Diskfield from generated environment information
[12.8.0] - 2026-02-16
Changed
- Improved
/changelogperformance by displaying only the most recent 3 versions by default, with a--fullflag for the complete history (#85 by @tctev) - Centralized builtin slash command definitions and handlers into a shared registry, replacing the large input-controller if-chain dispatch
[12.7.5] - 2026-02-16
Changed
- Updated SMOL_MODEL_PRIORITY to include additional model variants (gpt-5.3-spark, cerebras/zai-glm-4.7, haiku-4-5, haiku-4.5) for improved fast model discovery
- Updated SLOW_MODEL_PRIORITY to include additional model variants (gpt-5.3-codex, gpt-5.3, gpt-5.1-codex, gpt-5.1, opus-4.6, opus-4-6, opus-4.5, opus-4-5, opus-4.1, opus-4-1) for improved comprehensive model discovery
[12.7.3] - 2026-02-16
Fixed
- Suppressed hashline output for subagents without the edit tool (e.g. explore agents)
[12.7.1] - 2026-02-16
Changed
- Restructured execution procedure guidance to emphasize scope assessment and continuous tool-driven progress over planning-first approach
- Updated task tracking instructions to prohibit metadata-only turns and require immediate completion marking of todo items
- Clarified parallel execution guidance to distinguish between genuine parallelization and sequential work, with explicit criteria for Task tool usage
- Modified output style requirements to mandate stating intent before tool calls and reordered style constraints for clarity
- Reinforced requirement that every turn must include at least one tool call advancing the deliverable, with explicit failure condition for planning-only turns
[12.7.0] - 2026-02-16
Added
- Added Z.AI web search provider support via remote MCP endpoint (webSearchPrime)
- Added
zaias a selectable web search provider option in settings - Added Z.AI to automatic provider fallback chain for web search
[12.6.0] - 2026-02-16
Added
- Added runtime tests covering extension provider registration and deferred model pattern resolution behavior.
Changed
- Improved welcome screen responsiveness to dynamically show or hide the right column based on available terminal width
Fixed
- Fixed welcome screen layout to gracefully handle small terminal widths and prevent rendering errors on narrow displays
- Fixed welcome screen title truncation to prevent overflow when content exceeds available width
- Fixed deferred
--modelresolution so extension-provided models are matched before fallback selection and unresolved explicit patterns no longer silently fallback.
[12.5.1] - 2026-02-15
Added
- Added
repeatToolDescriptionssetting to render full tool descriptions in the system prompt instead of a tool name list
[12.5.0] - 2026-02-15
Breaking Changes
- Replaced
themesetting withtheme.darkandtheme.light(auto-migrated)
Added
- Added
previewTheme()function for non-destructive theme preview during settings browsing - Added animated microphone icon with color cycling during voice recording
- Added support for discovering skills via symbolic links in skill directories
- Added
abort_and_promptRPC command for atomic abort-and-reprompt without race conditions (#357) - Added automatic dark/light theme switching via SIGWINCH with separate
theme.dark/theme.lightsettings, replacing the singlethemesetting (#65) - Added speech-to-text (STT) feature with
Alt+Hkeybinding and/sttslash command - Added cross-platform audio recording: SoX, FFmpeg, arecord (Linux), PowerShell mciSendString (Windows fallback)
- Added recording tool fallback chain — automatically tries each available tool in order
- Added Python openai-whisper integration for transcription with automatic
pip install - Added custom WAV-to-numpy pipeline in
transcribe.pybypassing ffmpeg dependency - Added STT settings:
stt.enabled,stt.language,stt.modelName - Added STT status line segment showing recording/transcribing state
- Added
/sttcommand withon,off,status,setupsubcommands - Added auto-download of recording tools (best-effort FFmpeg via winget on Windows)
- Added interactive debug log viewer with selection, copy, and expand/collapse controls
- Added inline filtering and count display to the debug log viewer
- Added pid filter toggle and load-older pagination controls to the debug log viewer
- Enabled loading older debug logs from archived files in viewer
- Added file hyperlinks for debug report paths in viewer
Changed
- Changed theme preview to support asynchronous theme loading with request deduplication to prevent race conditions
- Enhanced theme preview cancellation to restore the previously active theme instead of the last selected value
- Refactored file discovery to use native glob with gitignore support instead of manual directory traversal, improving performance and consistency
- Updated dependencies: glob to ^13.0.3, marked to ^17.0.2, puppeteer to ^24.37.3
- Optimized skill and file discovery using native glob (Rust ignore crate) — reduces startup time by ~80% (1254ms → 6ms for skills)
- Enhanced hashline reference parsing to handle prefixes like
>>>and>>in line references - Strengthened type safety in hashline edit formatting with defensive null checks for incomplete edits
- Changed STT status messages to display via state change callbacks instead of explicit status calls
- Changed cursor visibility behavior during voice recording to hide hardware and terminal cursors
Removed
- Removed dedicated STT status line segment in favor of animated cursor-based feedback
Fixed
- Fixed theme preview updates being applied out-of-order when rapidly browsing theme options
- Fixed skill discovery to correctly extract skill names from directory paths when frontmatter name is missing
- Fixed
session.abort()not clearingpromptInFlightflag due to microtask ordering, which blocked subsequent prompts - Sanitized debug log display to strip control codes, normalize tabs, and trim width
[12.4.0] - 2026-02-14
Changed
- Moved
sanitizeTextfunction from@oh-my-pi/pi-utilsto@oh-my-pi/pi-nativesfor better code organization - Replaced internal
#normalizeOutputmethods withsanitizeTextutility function in bash and Python execution components - Added line length clamping (4000 characters) to bash and Python execution output to prevent display of excessively long lines
- Modified memory storage to isolate memories by project working directory, preventing cross-project memory contamination
Fixed
- Fixed bash interactive tool to gracefully handle malformed output chunks by normalizing them before display
- Fixed fetch tool incorrectly treating HTML content as plain text or markdown
- Fixed output truncation notice displaying incorrect byte limit when maxBytes differs from outputBytes
- Fixed Cloudflare returning corrupted bytes when compression is negotiated in web scraper requests
[12.3.0] - 2026-02-14
Added
- Added autonomous memory extraction and consolidation system with configurable settings
- Added
/memoryslash command with subcommands:view,clear,reset,enqueue,rebuild - Added memory injection payload that automatically includes learned context in system prompts
- Added two-phase memory pipeline: Stage 1 extracts durable knowledge from session history, Phase 2 consolidates into reusable skills and guidance
- Added memory storage layer with SQLite-backed job queue for distributed memory processing
- Added configurable memory settings: concurrency limits, lease timeouts, token budgets, and rollout age constraints
Changed
- Modified system prompt building to inject memory guidance when memories are enabled
- Changed
resolvePromptInputto handle multiline input and improve error handling for file reads
[12.2.0] - 2026-02-13
Added
- Added
providerSessionStateproperty to AgentSession for managing provider-scoped transport and session caches - Added automatic cleanup of provider session state resources on session disposal
- Added
providers.openaiWebsocketssetting to prefer websocket transport for OpenAI Codex models - Added provider details display in session info showing authentication mode, transport, and connection settings
- Added automatic prewarm of OpenAI Codex websocket connections on session creation for improved performance
- Added real-time authentication validation in OAuth provider selector with visual status indicators (checking, valid, invalid)
- Added
validateAuthandrequestRenderoptions to OAuthSelectorComponent for custom authentication validation and UI refresh callbacks
Changed
- Changed
providers.openaiWebsocketssetting from boolean to enum with values "auto", "off", "on" for more granular websocket policy control (auto uses model defaults, on forces websocket, off disables it) - Enhanced provider details display to include live provider session state information
- Enhanced session info output to display active provider configuration and authentication details
- Replaced
process.cwd()withgetProjectDir()throughout codebase for improved project directory detection and handling - Made
SessionManager.list()async to support asynchronous session discovery operations - Preserved internal whitespace and indentation in bash command normalization to support heredocs and indentation-sensitive scripts
- Improved git context loading performance with configurable timeouts and parallel status/commit queries
- Enhanced git context reliability with better error handling for timeout and command failures
- Changed OAuth provider selector to display live authentication status instead of static login state
- Changed logout flow to refresh OAuth provider authentication state before showing selector
Fixed
- Improved error reporting in fetch tool to include HTTP status codes when URL fetching fails
- Fixed fetch tool to preserve actual response metadata (finalUrl, contentType) instead of defaults when requests fail
[12.1.0] - 2026-02-13
Added
- Filesystem scan cache invalidation helpers (
invalidateFsScanAfterWrite,invalidateFsScanAfterDelete,invalidateFsScanAfterRename) to properly invalidate shared caches after file mutations - Named discovery profile for file mention candidates to standardize cache visibility and ignore semantics across callers
- Comprehensive
models.ymlprovider integration guide documenting custom model registration, provider overrides, API adapters, merge behavior, and practical integration patterns for Ollama, vLLM, LM Studio, and proxy endpoints - Claude Code marketplace plugin discovery: automatically loads skills, commands, hooks, tools, and agents from
~/.claude/plugins/cache/based oninstalled_plugins.jsonregistry (#48)
Changed
- Moved directory path utilities from
src/config.tsto@oh-my-pi/pi-utils/dirsfor shared use across packages - Updated imports throughout codebase to use centralized directory path functions from
@oh-my-pi/pi-utils/dirs - Updated interactive bash terminal UI label from 'InteractiveTerm' to 'Console' for clarity
- Enhanced bash execution environment with comprehensive non-interactive defaults for pagers, editors, and package managers to prevent command blocking and interactive prompts
- Updated custom models configuration to use
~/.omp/agent/models.yml(YAML format) while maintaining backward compatibility with legacymodels.json
[12.0.0] - 2026-02-12
Added
- Added
getAllServerNames()method to MCPManager for enumerating all known servers
Changed
- Changed default edit mode from
patchtohashlinefor more precise code modifications - Changed
readHashLinessetting default from false to true to enable hash line reading by default
Fixed
- Fixed
omp setupcrashing with uncaught exception when no component argument provided; now shows help (#35) - Fixed
/mcp listshowing "No MCP servers configured" when servers are loaded from discovery sources like.claude.json,.cursor/mcp.json,.vscode/mcp.json(#34) - Fixed model selector sorting to show newest models first within each provider instead of alphabetical;
-latestaliases now appear before dated versions (#37)
[11.14.4] - 2026-02-12
Added
- Exported
renderPromptTemplatefunction for programmatic prompt template rendering - Exported
computeLineHashfunction from patch utilities - Added
./cliexport path for direct CLI module access
Changed
- Replaced jsdom with linkedom for improved HTML parsing performance and reduced memory footprint
Removed
- Removed @types/jsdom dependency
[11.14.1] - 2026-02-12
Changed
- Improved Bun binary detection to check
Bun.env.PI_COMPILEDenvironment variable - Enhanced Bun package manager update to install specific version instead of latest
- Added post-update verification for Bun installations to warn if expected version was not installed
Fixed
- Fixed Bun update process to properly handle version pinning and report installation mismatches
[11.14.0] - 2026-02-12
Added
- Added SwiftLint linter client with JSON reporter support for Swift file linting
- Added
--no-ptyflag to disable PTY-based interactive bash execution - Added
PI_NO_PTYenvironment variable to disable PTY-based interactive bash execution - Added
bash.virtualTerminalsetting to control PTY-backed interactive execution for bash commands - Added interactive PTY-based bash execution with real-time terminal rendering and input forwarding
- Added sourcekit-lsp language server support for Swift files
Changed
- Changed
bash.virtualTerminaldefault fromontoofffor standard non-interactive bash execution - Changed SwiftLint configuration to use
lintcommand with JSON reporter instead ofanalyzefor improved diagnostic parsing - Changed diff line format from space-separated (
+123 content) to pipe-delimited (+123|content) for improved parsing reliability - Changed bash tool to use interactive PTY execution by default when UI is available, falling back to standard execution when disabled
[11.13.1] - 2026-02-12
Added
- Added
/moveslash command to move session to a different working directory - Added
moveTo()method to SessionManager for relocating sessions with file migration and header updates - Added
refreshSlashCommandState()method to reload slash commands and autocomplete when working directory changes - Added
setSlashCommands()method to AgentSession for updating file-based slash commands - Added OAuth authentication support for Perplexity web search via
www.perplexity.ai/rest/sse/perplexity_askendpoint - Added automatic OAuth token refresh with 5-minute expiry buffer for Perplexity authentication
- Added
authModefield to search responses to indicate authentication method used (oauth or api_key) - Added display of authentication mode in search result output
- Added support for streaming SSE responses from Perplexity OAuth API with proper event merging
Changed
- Changed Perplexity provider to support both API key and OAuth authentication methods
- Changed
isAvailable()method to async to check for both API key and OAuth token availability - Changed error message to guide users to set PERPLEXITY_API_KEY or login via OAuth
- Changed
callPerplexitytocallPerplexityApito clarify it uses the API key endpoint
[11.13.0] - 2026-02-12
Breaking Changes
- Removed support for
.piconfiguration directory alias; use.ompinstead
Added
- Added
openPathutility function to centralize cross-platform URL and file path opening
Changed
- Refactored browser/file opening across multiple modules to use unified
openPathutility for improved maintainability
[11.12.0] - 2026-02-11
Added
- Added
resolveFileDisplayModeutility to centralize file display mode resolution across tools (read, grep, file mentions) - Added automatic hashline formatting to @file mentions when hashline mode is active
- Added
replacehashline edit operation for substr-style fuzzy text replacement without line references, with optionalallflag for replace-all behavior - Added
noopEditsarray toapplyHashlineEditsreturn value to report edits that produced no changes, including edit index, location, and current content for diagnostics - Added validation to detect and reject hashline edits using wrong-format fields (
old_text/new_textfrom replace mode,difffrom patch mode) with helpful error messages - Added
additionalProperties: trueto all hashline edit schemas (single,range,insertAfter, and root) to tolerate extra fields from models - Added whitespace normalization in line reference parsing to tolerate spaces around colons (e.g.,
5 : abnow parses as5:ab) - Added
remapsproperty toHashlineMismatchErrorproviding quick-fix mapping of stale line references to corrected hashes - Added warnings detection in
applyHashlineEditsto alert users when edits affect significantly more lines than expected, indicating possible unintended reformatting - Added diagnostic output showing target line content when an edit produces no changes, helping users identify hash mismatches or incorrect replacement content
- Added
{{hashline}}Handlebars helper to compute accurateLINE:HASHreferences for prompt examples and documentation - Added deduplication of identical hashline edits targeting the same line(s) in a single call
- Added
replacementas accepted alias forcontentininsertAfteroperations - Added graceful degradation of
rangeedits with missingendfield to single-line edits - Added
additionalProperties: trueto hashline edit schemas to tolerate extra fields from models
Changed
- Reverted hashline display format from
LINE:HASH content(two spaces) back toLINE:HASH|content(pipe separator) for consistency with legacy format - Changed hashline display format from
LINE:HASH| contenttoLINE:HASH content(two spaces instead of pipe separator) for improved readability - Removed
linesandhashesparameters fromreadtool—file display mode (line numbers, hashlines) now determined automatically by settings and edit mode - Simplified
readtool prompt to reflect automatic display mode detection based on configuration - Updated
greptool to respect file display mode settings, showing hashline-prefixed output when hashline mode is active - Renamed hashline edit operation keys from
single/range/insertAftertoset_line/replace_lines/insert_afterfor clearer semantics - Renamed hashline edit fields:
loc→anchor,replacement→new_text,content→textfor consistency across all operation types - Separated hashline anchor-based edits (
set_line,replace_lines,insert_after) from content-replace edits (replace) in application pipeline - Improved no-op edit diagnostics to use
noopEditsarray fromapplyHashlineEdits, providing precise line-by-line comparison when replacements match current content - Enhanced error messages for wrong-format hashline edits to guide users toward correct operation syntax
- Strengthened hashline prompt guidance to emphasize that
replacementmust differ from current line content and clarify no-op error recovery procedures - Improved hashline prompt to clarify atomicity: all edits in one call are validated against the original file state, with line numbers and hashes referring to the pre-edit state
- Added explicit instruction in hashline prompt to preserve exact whitespace and formatting when replacing lines, changing only the targeted token/expression
- Added guidance in hashline prompt for swap operations: use two
singleoperations in one call rather than attempting to account for line number shifts - Strengthened anti-reformatting instructions in hashline prompt to reduce formatting-only failures
- Improved no-op error recovery guidance in hashline prompt to prevent infinite retry loops
- Renamed hashline edit operation keys from
replaceLine/replaceLinestosingle/rangefor clearer semantics - Renamed hashline edit field
contenttoreplacementinsingleandrangeoperations to distinguish frominsertAfter.content - Improved no-op edit diagnostics to show specific line-by-line comparisons when replacements match current content, helping users identify hash mismatches or formatting issues
- Enhanced no-op error messages to distinguish between literally identical replacements and content normalized back by heuristics
- Reverted hash algorithm from 3-character base-36 back to 2-character hexadecimal for line references
- Enhanced range validation during hashline edits to detect and reject relocations that change the scope of affected lines
- Improved wrapped-line restoration logic to only attempt merging when source lines exhibit continuation patterns
- Updated hashline tool documentation to emphasize direction-locking mutations and clarify recovery procedures for hash mismatches
- Changed
applyHashlineEditsreturn type to include optionalwarningsarray for reporting suspicious edit patterns - Improved hash relocation logic to recompute touched lines after hash-based line number adjustments, preventing incorrect merge heuristics
- Enhanced error messages for no-op edits to include preview of target lines with their current hashes and content
- Changed hashline edit format from
src/dstobject structure to direct operation schemas (replaceLine,replaceLines,insertAfter) - Changed hash algorithm from 2-character hexadecimal to 3-character base-36 alphanumeric for improved readability and collision resistance
- Improved hash mismatch handling to automatically relocate stale line references when the hash uniquely identifies a moved line
- Changed
HashlineEditfromsrc/dstformat to direct operation schemas:replaceLine,replaceLines,insertAfter - Changed hash algorithm from hexadecimal (base-16) to base-36 alphanumeric for shorter, more readable line references
- Increased maximum wrapped-line restoration from 6 to 10 lines to handle longer reflowed statements
- Updated prompt examples to use
{{hashline}}Handlebars helper for generating correct line references in tool instructions
Removed
- Removed
insertBeforehashline edit operation for inserting content before a line - Removed
substrhashline edit operation for substring-based line replacement - Removed
insertBeforeandsubstrhashline edit variants
Fixed
- Fixed
parseLineRefto handle both legacy pipe-separator format (LINE:HASH| content) and new two-space format (LINE:HASH content) for backward compatibility - Fixed resource leak in browser query handler by properly disposing owned proxy elements for non-winning candidates
- Fixed script evaluation to support async functions and await expressions in browser evaluate operations
- Fixed
rangeedits with missingendfield to gracefully degrade to single-line edits instead of crashing - Fixed
insertAfteroperations to accept bothcontentandreplacementfield names for consistency with other edit types - Fixed deduplication logic to correctly identify and remove identical hashline edits targeting the same line(s) in a single call
- Fixed range-based edits to prevent invalid mutations when hash relocation changes the number of lines in the target range
- Fixed multi-edit application to use original file state for all anchor references, preventing incorrect line numbers when earlier edits change file length
[11.10.4] - 2026-02-10
Added
- Hashline diff computation with
computeHashlineDifffunction for preview rendering of hashline-mode edits - Streaming preview display for hashline edits in tool execution UI showing edit sources and destinations
- Streaming hash line computation with progress updates via
onUpdatecallback in read tool - Optional
onCollectedLinecallback parameter tostreamLinesFromFilefor line collection tracking
Changed
- Edit tool renderer now displays computed preview diffs for hashline operations before execution
- Read tool now streams hash lines incrementally instead of computing them all at once, improving responsiveness for large files
- Refactored hash line formatting to use async
streamHashLinesFromLinesfor better performance
[11.10.3] - 2026-02-10
Added
- Exported
./patch/*subpath for direct access to patch utilities
[11.10.2] - 2026-02-10
Added
- Exported
streamHashLinesFromUtf8andstreamHashLinesFromLinesfunctions for streaming hashline-formatted output with configurable chunking - Added
HashlineStreamOptionsinterface to control streaming behavior (startLine, maxChunkLines, maxChunkBytes) - Added
streamHashLinesFromUtf8function to incrementally format content with hash lines from a UTF-8 byte stream - Added
streamHashLinesFromLinesfunction to incrementally format content with hash lines from an iterable of lines
Changed
- Updated hashline format to use 2-character hex hashes instead of 4-character hashes for more compact line references
- Modified
computeLineHashto normalize whitespace in line content and removed line number from hash seed for consistency - Improved CLI argument parsing to explicitly handle
--help,--version, and subcommand detection instead of prefix-based routing
Removed
- Removed
@types/diffdev dependency - Removed AggregateError unwrapping from console.warn in CLI initialization
[11.10.1] - 2026-02-10
Changed
- Migrated CLI framework from oclif to lightweight pi-utils CLI runner
- Replaced oclif command registration with explicit command entries in cli.ts
- Changed default root command name from 'index' to 'launch'
- Updated all command imports to use @oh-my-pi/pi-utils/cli instead of @oclif/core
Removed
- Removed @oclif/core and @oclif/plugin-autocomplete dependencies
- Removed oclif configuration from package.json
- Removed custom oclif help renderer (oclif-help.ts)
[11.10.0] - 2026-02-10
Breaking Changes
- Changed
HashlineEdit.srcfrom string format (e.g.,"5:ab","5:ab..9:ef") to structuredSrcSpecobject with discriminated union types ({ kind: "single", ref: "..." },{ kind: "range", start: "...", end: "..." }, etc.) - Changed
HashlineEditAPI fromold: string | string[]/new: string | string[]tosrc: string/dst: string; src uses range syntax"5:ab"(single),"5:ab..9:ef"(range),"5:ab.."(insert after), or"..5:ab"(insert before) - Removed support for comma and newline-separated line reference lists in hashline edits; use range syntax instead
- Removed
afterfield fromHashlineEdit; insert-after is now expressed via open range syntaxsrc: "5:ab.." - Changed
HashlineEditAPI fromold: string | string[]/new: string | string[]tosrc: string/dst: string; multi-line content uses\n-separated strings, empty string""for insert/delete operations - Replaced
edit.patchModeboolean setting withedit.modeenum; existingedit.patchMode: trueconfigurations should useedit.mode: patch - Changed
getEditModelVariants()return type fromRecord<string, "patch" | "replace">toRecord<string, EditMode | null> - Removed
afterfield fromHashlineEdit; insert-after is now expressed via open range syntaxsrc: "5:ab.." - Changed
HashlineEdit.srcfrom newline-separated line ref lists to range syntax:"5:ab"(single),"5:ab..9:ef"(range),"5:ab.."(insert after); comma and newline-separated lists are no longer supported
Added
- Added substring-based source matching for hashline edits when line reference format is invalid, allowing fallback to unique substring search within the file
- Added automatic detection and repair of single-line merges where models absorb adjacent lines, preventing content duplication
- Added normalization of unicode-confusable hyphens (en-dash, em-dash, etc.) to ASCII hyphens when edits would otherwise be no-ops
- Added heuristics to restore original indentation and preserve wrapped line formatting in hashline edits
- Added abort signal support to MCP server connection and tool listing operations, allowing requests to be cancelled via Escape key during testing
- Added
MCPRequestOptionsinterface withsignalproperty to support request cancellation via AbortSignal - Added abort signal support to MCP tool execution, allowing requests to be cancelled via Escape-to-interrupt or other abort mechanisms
- Added
HashlineMismatchErrorclass that displays grep-style output with>>>markers showing correctLINE:HASHreferences when hash validation fails - Added
HashMismatchtype to represent individual hash mismatches with line number, expected hash, and actual hash - Added hashline edit mode for line-addressed edits using content hashes (LINE:HASH format) with integrity verification
- Added
readHashLinessetting to include line hashes in read output for hashline edit mode - Added
edit.modesetting (enum: replace, patch, hashline) to select edit tool variant, replacingedit.patchModeboolean - Added
hashesparameter to read tool to output line hashes in formatLINE:HASH| content - Added automatic hash line output when using hashline edit mode or
readHashLinessetting is enabled - Added
computeLineHash,formatHashLines,parseLineRef,validateLineRef, andapplyHashlineEditsfunctions for hashline operations - Added
HashlineEditandHashlineInputtypes for structured hashline edit operations - Added
normalizeEditModefunction to validate and normalize edit mode strings - Added subcommand definitions for
/mcpcommand with 10 subcommands (add, list, remove, test, reauth, unauth, enable, disable, reload, help) including usage hints for argument completion - Added inline hint support for slash commands with simple arguments (
/export [path],/compact [focus instructions],/handoff [focus instructions]) - Added subcommand dropdown completion for
/browsercommand (headless, visible modes) - Added
SubcommandDefinterface for declarative subcommand definitions with name, description, and usage hints - Added
subcommandsandinlineHintproperties toBuiltinSlashCommandinterface for enhanced command metadata - Added
getArgumentCompletionsandgetInlineHintfunctions to materialized slash commands for autocomplete and ghost text hints - Added
temperaturesetting to control sampling temperature (0 = deterministic, 1 = creative, -1 = provider default) - Added temperature option selector in settings UI with preset values (Default, 0, 0.2, 0.5, 0.7, 1)
Changed
- Relaxed comma validation in
srcto allow trailing content after line references (e.g.,14:abexport function foo()), while still rejecting inputs that appear to contain multiple line refs - Improved
parseLineRefto accept hash prefixes shorter than the full hash length, allowing partial hash matches - Enhanced error message for hash mismatches to guide users toward re-reading the file and using updated LINE:HASH references
- Updated hashline tool documentation to clarify that accidental trailing text after LINE:HASH will be extracted, and to discourage merging multiple lines into single-line replacements
- Treated same-line ranges (e.g.,
5:ab..5:cd) as single-line replacements instead of range operations - Enhanced hashline edit robustness with heuristics to strip anchor line echoes and range boundary echoes that models may copy into replacement content
- Improved whitespace preservation in hashline edits to handle mismatched line counts using loose matching strategy
- Strengthened hashline edit validation to reject malformed src specs (embedded newlines, commas, invalid ranges)
- Enhanced MCP connection timeout handling to properly respect abort signals and distinguish between timeout and user-initiated cancellation
- Improved MCP test command UI to show cancellation hint (esc to cancel) and handle graceful cancellation without blocking cleanup
- Updated HTTP transport session termination to use AbortSignal.timeout() for reliable cleanup with timeout protection
- Enhanced bash executor to properly handle abort signals by registering abort event listeners and cleaning up resources in finally block
- Improved bash tool error handling to distinguish between user-initiated aborts (via AbortSignal) and other cancellations, throwing ToolAbortError for aborted requests
- Enhanced MCP request handling to propagate abort signals through HTTP, SSE, and stdio transports with proper cleanup
- Improved stdio transport request handling to use Promise.withResolvers for cleaner async flow and better abort signal integration
- Updated HTTP transport to combine operation abort signals with timeout signals using AbortSignal.any() for unified cancellation
- Modified SSE response parsing to support abort signals and distinguish between timeout and user-initiated cancellation
- Improved hashline edit robustness by automatically stripping
LINE:HASH|display prefixes and unified-diff+markers that models may copy into replacement content - Enhanced replace edits to preserve original whitespace on lines where only whitespace differs, preventing spurious formatting diffs when models reformat code
- Enhanced system prompt to display tool descriptions alongside tool names for improved clarity on available capabilities
- Reduced hash length from 4 to 2 hex characters (16-bit hashes) for more concise line references
- Updated
HashlineEdittype to acceptstring | string[]foroldandnewfields, allowing single-line edits without array wrapping - Enhanced
parseLineRefto strip display-format suffix (e.g.,5:ab| content→5:ab), allowing models to copy full read output format - Improved
validateLineRefto throwHashlineMismatchErrorwith context lines instead of generic error, providing grep-style output with correct hashes - Modified hash computation to strip trailing carriage returns before hashing for consistent line hash values
- Renamed
HashlineEditfields fromsrc/dsttoold/newfor clarity in replace, delete, and insert operations - Enhanced hash validation in
applyHashlineEditsto collect all mismatches before throwing, providing comprehensive error reporting with context lines - Changed
edit.patchModeboolean setting toedit.modeenum (replace, patch, hashline) with default value patch - Changed edit tool to support three modes (replace, patch, hashline) instead of two, with dynamic mode selection based on model and settings
- Changed read tool to prioritize hash lines over line numbers when both are requested
- Changed
getEditVariantForModelto returnEditMode | nulland removed hardcoded Kimi model detection - Renamed
settingsInstanceparameter tosettingsinCreateAgentSessionOptionsfor consistency - Updated all internal references from
settingsInstancetosettingsthroughout SDK and components
Fixed
- Fixed substring source matching to reject ambiguous matches and provide helpful error messages showing all occurrences
- Fixed substring source matching to require exactly one matching line in the file
- Fixed MCP test command to properly clean up connections even when cancelled or aborted, preventing resource leaks
[11.9.0] - 2026-02-10
Added
- Added
/mcpslash command for runtime MCP server management (add, list, remove, enable, disable, test, reauth) - Added interactive multi-step wizard for adding MCP servers with transport auto-detection
- Added OAuth auto-discovery and authentication flow for MCP servers requiring authorization
- Added MCP config file writer for persisting server configurations at user and project level
- Added
enabledandtimeoutfields to MCP server configuration - Added runtime MCP manager reload and active tool registry rebind without restart
- Added MCP command guide documentation
Changed
- Replaced
setTimeoutwithBun.sleep()for improved performance in file lock retry logic - Refactored component invalidation handling to use dedicated helper function for cleaner code
- Improved error handling in worktree baseline application to use
isEnoent()utility instead of file existence checks - Updated bash tool to use standard Node.js
fs.promises.stat()withisEnoent()error handling - Replaced
tmpdir()named import withosnamespace import for consistency - Migrated logging from
chalkandconsole.errorto structured logger from@oh-my-pi/pi-utils
Fixed
- Improved browser script evaluation to handle both expression and statement forms, fixing evaluation failures for certain script types
- Fixed unsafe OAuth endpoint extraction that could redirect token exchange to attacker-controlled URLs
- Fixed PKCE code verifier stored via untyped property; now uses typed private field
- Fixed refresh token fallback incorrectly using access token when no refresh token provided
- Fixed MCP config files written with default permissions; now enforces 0o700/0o600 for secret protection
- Fixed add wizard ignoring user-chosen environment variable name and auth header name
- Fixed reauth endpoint discovery misclassifying non-OAuth servers as discovery failures
- Fixed resolved OAuth tokens leaking into connection config, causing cache churn on token rotation
- Fixed unvalidated type assertions for
enabled/timeoutconfig fields from user-controlled JSON - Fixed uncaught exceptions in
/mcp addquick-add flow crashing the interactive loop - Fixed greedy
/mcpprefix match routing/mcpfooto MCP controller - Fixed stdio transport timeout timer leak keeping process alive after request completion
Removed
- Removed
GrepOperationsinterface from public API exports - Removed
GrepToolOptionsinterface from public API exports - Removed unused
_optionsparameter fromGrepToolconstructor
[11.8.1] - 2026-02-10
Added
- Added current date to system prompt context in YYYY-MM-DD format for date-aware agent reasoning
- Added file size display in UI when files are skipped due to size limits
- Added support for gigabyte (GB) file size formatting in truncate utility
Changed
- Changed skipped file messages to include file size information for better visibility into why files were excluded
- Changed file processing to skip reading files exceeding 5MB (text) or 25MB (images) and include them as path-only references instead
- Changed @mention auto-reading to skip files exceeding 5MB (text) or 25MB (images) to prevent out-of-memory issues with large files
- Clarified that subagents automatically inherit full system prompt including AGENTS.md, context files, and skills — do not repeat project rules or conventions in task context
- Updated task context guidance to focus on session-specific information subagents lack, eliminating redundant documentation of project constraints already available to them
- Refined constraints template to emphasize task-specific rules and session decisions rather than global project conventions
- Expanded anti-patterns section to explicitly flag redundant context that wastes tokens by repeating AGENTS.md rules, project constraints, and tool preferences
Fixed
- Fixed bash tool hanging when commands spawn background jobs by properly detecting foreground process completion
- Fixed bash tool occasionally hanging after command completion when background jobs keep stdout/stderr open
- Fixed crash when auto-reading @mentions for very large files by skipping content injection with an explicit "skipped" note
- Improved bash tool output draining after foreground completion to reduce tail output truncation
[11.8.0] - 2026-02-10
Added
- Added
ctx.reload()method to extension command context to reload extensions, skills, prompts, and themes from disk - Added
ctx.ui.pasteToEditor()method to paste text into the editor with proper handling (e.g., large paste markers in interactive mode) - Added extension UI sub-protocol for RPC mode enabling dialog methods (
select,confirm,input,editor) and fire-and-forget UI methods via client communication - Added support for tilde (
~) expansion in custom skill directory paths - Added example extension demonstrating
ctx.reload()usage with both command and LLM-callable tool patterns
Changed
- Changed
ctx.hasUIbehavior: nowtruein RPC mode (previouslyfalse), with dialog methods working via extension UI sub-protocol - Changed warning output for invalid CLI arguments to use structured logging instead of console.error
- Changed help text to indicate command-specific help is available via
<command> --help - Changed tool result event handlers to chain like middleware, allowing each handler to see and modify results from previous handlers with partial patch support
Fixed
- Fixed archive extraction security vulnerability by validating that extracted paths do not escape the extraction directory
- Fixed archive format validation to reject unsupported formats before extraction attempt
- Fixed archive extraction error handling to provide clear error messages on failure
[11.7.0] - 2026-02-07
Changed
- Enhanced error messages for failed Python cells to include full combined output context instead of just the error message
- Updated error cell output styling to use error color theme instead of standard tool output color for better visual distinction
Fixed
- Improved error handling in Python cell execution to preserve and display combined output from previous cells when an error occurs
- Fixed tab character rendering in Python tool output display to properly format whitespace in cell output and status events
[11.6.1] - 2026-02-07
Fixed
- Fixed potential crash when rendering results with undefined details.results
[11.6.0] - 2026-02-07
Fixed
- Fixed task tool renderer not sanitizing tabs, causing visual holes in TUI output
- Fixed task tool expanded view showing redundant
<swarm_context>block that is shared across all tasks - Fixed assistant message spacer appearing before tool executions when no visible content follows thinking block
- Fixed extension runner
emit()type safety with narrowed event/result types - Fixed extension runner
tool_resultevent chaining across multiple extensions via dedicatedemitToolResult() - Fixed queued messages not delivered after auto-compaction completes
Added
- Added
/quitslash command as alias for/exit - Added per-model overrides (
modelOverrides) inmodels.jsonfor customizing built-in model properties - Added
mergeCustomModelsto merge custom models with built-ins by provider+id instead of replacing
[11.5.2] - 2026-02-07
Fixed
- Fixed TUI crash when ask tool renders long user input exceeding terminal width by using Text component for word wrapping instead of raw line output
[11.5.0] - 2026-02-06
Added
- Added terminal breadcrumb tracking to remember the last session per terminal, enabling
--continueto work correctly with concurrent sessions in different terminals
Changed
- Changed screenshot format to always use PNG instead of supporting JPEG with quality parameter
- Changed default extract_readable format from text to markdown
- Changed screenshot storage to use temporary directory with Snowflake IDs instead of artifacts directory
- Changed ResizedImage interface to return buffer as Uint8Array with lazy-loaded base64 data getter for improved memory efficiency
Removed
- Removed JPEG quality parameter from screenshot options
- Removed format selection for screenshots (now PNG only)
- Removed ability to save screenshots to custom paths or artifacts directory
[11.4.1] - 2026-02-06
Fixed
- Fixed tab character display in error messages and bash tool output by properly replacing tabs with spaces
[11.4.0] - 2026-02-06
Added
- Visualize leading whitespace (indentation) in diff output with dim glyphs—tabs display as
→and spaces as·for improved readability
Fixed
- Fixed patch applicator to correctly handle context-only hunks (pure context lines between @@ markers) without altering indentation in tab-indented files
- Fixed indentation conversion logic to infer tab width from space-to-tab patterns using linear regression (ax+b model) when pattern uses spaces and actual file uses tabs
- Fixed tab character rendering in tool output previews and code cell displays, ensuring tabs are properly converted to spaces for consistent terminal display
- Fixed
newSession()to properly await session manager operations, ensuring new session is fully initialized before returning - Fixed session formatting to use XML structure for tools and tool invocations instead of YAML, improving compatibility with structured output parsing
[11.3.0] - 2026-02-06
Added
- Added resumption hint printed to stderr on session exit showing command to resume the session (e.g.,
Resume this session with claude --resume <session-id>) - New
BlobStoreclass for content-addressed storage of large binary data (images) externalized from session files - New
getBlobsDir()function to get path to blob store directory - Support for externalizing large images to blob store during session persistence, reducing JSONL file size
- New blob reference format (
blob:sha256:<hash>) for tracking externalized image data in sessions - Exported
ModeChangeEntrytype for tracking agent mode transitions - Support for restoring plan mode state when resuming sessions
- New
appendModeChange()method in SessionManager to record mode transitions - New
modeandmodeDatafields in SessionContext to track active agent mode - Support for
PI_PACKAGE_DIRenvironment variable to override package directory (useful for Nix/Guix store paths) - New keybindings for session management:
toggleSessionNamedFilter(Ctrl+N),newSession,tree,fork, andresumeactions - Support for shell command execution in configuration values (API keys, headers) using
!prefix, with result caching - New
clearOnShrinkdisplay setting to control whether empty rows are cleared when content shrinks - New
SlashCommandInfo,SlashCommandLocation, andSlashCommandSourcetypes for extension slash command discovery - New
getCommands()method in ExtensionAPI to retrieve available slash commands - New
switchSession()action in ExtensionCommandContext to switch between sessions - New
SwitchSessionHandlertype for extension session switching handlers - New
getSystemPrompt()method in ExtensionUIContext to access current system prompt - New
getToolsExpanded()andsetToolsExpanded()methods in ExtensionUIContext for tool output expansion control - New
WriteToolCallEventtype for write tool call events - New
isToolCallEventType()type guard for tool call events - Support for image content in RPC
steerandfollowUpcommands - New
GitSourcetype andparseGitUrl()function for parsing git URLs in plugin system - Tool input types exported:
BashToolInput,FindToolInput,GrepToolInput,ReadToolInput,WriteToolInput - Support for
@prefix normalization in file paths (strips leading@character) - New
parentSessionPathfield in SessionInfo to track forked session origins - Skill file relative path resolution against skill directory in system prompt
- Support for Termux/Android package installation guidance for missing tools
- Support for puppeteer query handlers (aria/, text/, xpath/, pierce/) in selector parameters across all browser actions
- Automatic normalization of legacy p- prefixed selectors (p-aria/, p-text/, p-xpath/, p-pierce/) to modern puppeteer query handler syntax
- Improved click action with intelligent element selection that prioritizes visible, actionable candidates and retries until timeout
- Enhanced actionability checking for click operations, validating visibility, pointer events, opacity, viewport intersection, and element occlusion
Changed
- Modified
--resumeflag to accept optional session ID or path (e.g.,--resume abc123or--resume /path/to/session.jsonl), with session picker shown when no value provided - Consolidated
--sessionflag as an alias for--resumewith value for improved CLI consistency - Removed read tool grouping reset logic that was breaking grouping when text or thinking blocks appeared between tool calls
- Image persistence now externalizes images ≥1KB to content-addressed blob store instead of compressing inline
- Session loading now automatically resolves blob references back to base64 image data
- Session forking now resolves blob references in copied entries to ensure data integrity
- Screenshot tool now automatically compresses images for API content using the same resizing logic as pasted images, reducing payload size while maintaining quality
- Improved text truncation across tool renderers to respect terminal width constraints and prevent output overflow
- Enhanced render caching to include width parameter for accurate cache invalidation when terminal width changes
- HTML export filter now treats
mode_changeentries as settings entries alongside model changes and thinking level changes - Replaced ellipsis string (
...) with Unicode ellipsis character (…) throughout UI text and truncation logic for improved typography - Improved render performance by introducing caching for tool output blocks and search results to avoid redundant text width and padding computations
- Enhanced read tool grouping to reset when non-tool content (text/thinking blocks) appears between read calls, preventing unintended coalescing
- Improved string preview formatting in scalar values to show line counts and truncation indicators for multi-line strings
- Refactored tool execution component to use shared mutable render state for spinner frames and expansion state, reducing closure overhead
- Enhanced error handling in tool renderers with logging for renderer failures instead of silent fallbacks
- Made shell command execution in configuration values asynchronous to prevent blocking the TUI
- Improved
@prefix normalization to only strip leading@for well-known path syntaxes (absolute paths, home directory, internal URL shorthands) to avoid mangling literal paths - Enhanced git URL parsing to strip credentials from repository URLs and validate URL-encoded hash fragments
- Improved null data handling in task submission to preserve agent output when
submit_resultis called with null/undefined data, enabling fallback text extraction instead of discarding output - Updated default model IDs across providers: Claude Sonnet 4.5 → Claude Opus 4.6, Gemini 2.5 Pro → Gemini 3 Pro variants, and others
- Made model definition fields optional with sensible defaults for local models (Ollama, LM Studio, etc.)
- Modified custom tool execute signature to reorder parameters:
(toolCallId, params, signal, onUpdate, ctx)instead of(toolCallId, params, onUpdate, ctx, signal) - Changed
--versionand--list-modelsflags to exit withprocess.exit(0)instead of returning - Improved
--exportflag to exit withprocess.exit(0)on success - Enhanced tree selector to preserve last selected ID across filter changes
- Modified tree navigation to use real leaf ID instead of skipping metadata entries
- Improved footer path truncation logic to prevent invalid truncation at boundary
- Enhanced model selector to display selected model name when no matches found
- Improved RPC client
steer()andfollowUp()methods to accept optional image content - Updated extension loader to check for explicit extension entries in root directory before discovering subdirectories
- Removed line limiting in custom message component when collapsed
- Improved API key resolution to support shell command execution via
resolveConfigValue() - Enhanced session branching to preserve parent session path reference
- Updated selector parameter descriptions to document support for CSS selectors and puppeteer query handlers
- Modified viewport handling in headless mode to respect custom viewport parameters while disabling viewport in headed mode for better window management
- Improved click action to use specialized text query handler logic with retry mechanism for better reliability with dynamic content
Fixed
- Fixed background color stability in output blocks when inner content contains SGR reset sequences, preventing background color from being cleared mid-line
- Fixed spurious ellipsis appended to output lines that were already padded to terminal width by trimming trailing spaces before truncation check
- Fixed config file parsing to properly handle missing files instead of treating them as errors
- Fixed truncation indicator in truncate tool to use ellipsis character (…) instead of verbose '[truncated]' suffix
- Fixed concurrent shell command execution by de-duplicating in-flight requests for the same command
- Fixed git URL parsing to properly handle URL-encoded characters in hash fragments and reject invalid encodings
- Fixed task executor to properly handle agents calling
submit_resultwith null data by treating it as missing and attempting to extract output from conversation text rather than silently failing - Fixed HTML export template to safely handle invalid argument types in tool rendering
- Fixed path shortening in HTML export to handle non-string paths
- Fixed custom message rendering to properly display full content without artificial line limits
- Fixed tree navigation to only restore editor text when editor is empty
- Fixed session creation to properly track parent session when forking
- Fixed thinking level initialization to only append change entry for new sessions without existing thinking entries
- Fixed tool expansion state management to properly propagate through UI context
- Fixed click action to properly handle text/ query handlers with timeout and retry logic instead of failing immediately
- Fixed viewport application to only apply when in headless mode or when explicitly requested, preventing conflicts in headed browser mode
Security
- Added support for shell command execution in configuration values with caching to enable secure credential resolution patterns
[11.2.1] - 2026-02-05
Fixed
- Fixed CLI invocation with flags only (e.g.
pi --model=codex) to route to the default command instead of erroring
[11.2.0] - 2026-02-05
Added
- Added
omp commitcommand to generate commit messages and update changelogs with--push,--dry-run,--no-changelog, and model override flags - Added
omp configcommand to manage configuration settings with actions: list, get, set, reset, path - Added
omp grepcommand to test grep tool with pattern matching, glob filtering, context lines, and output modes - Added
omp jupytercommand to manage the shared Jupyter gateway with status and kill actions - Added
omp plugincommand to manage plugins with install, uninstall, list, link, doctor, features, config, enable, and disable actions - Added
omp setupcommand to install dependencies for optional features like Python - Added
omp shellcommand for interactive shell console with working directory and timeout configuration - Added
omp statscommand to view usage statistics with dashboard server, JSON output, and summary options - Added
omp updatecommand to check for and install updates with force and check-only modes - Added
omp web-searchcommand (aliasomp q) to test web search providers with provider selection, recency filtering, and result limits - Migrated CLI from custom argument parser to oclif framework for improved command structure and help system
- Added
omp qCLI subcommand for testing web search providers with query, provider, recency, and limit options - Added web search provider information API with authentication requirements and provider metadata
- Added support for
hourrecency filter option in Perplexity web search - Support for image file mentions—images are now automatically detected, resized, and attached when referenced with @filepath syntax
- Image dimension information displayed in file mention UI to show image properties alongside text files
Changed
- Refactored web search provider system to use individual provider classes in separate files for improved maintainability
- Moved
SearchProviderbase class andSearchParamsinterface to dedicatedproviders/base.tsmodule - Updated web search execution to pass
maxOutputTokens,numSearchResults, andtemperatureparameters to providers - Changed Perplexity search context size from 'high' to 'medium' and added search classifier, reasoning effort, and language preference settings
- Increased Perplexity default max tokens from 4096 to 8192 for more comprehensive responses
- Updated Anthropic and Gemini search providers to support
max_tokensandtemperatureparameters for finer control over response generation - Simplified
AuthStorage.create()to accept direct agent.db path - Renamed web search types and exports for consistency:
WebSearchProvider→SearchProviderId,WebSearchResponse→SearchResponse,WebSearchTool→SearchTool, and related functions - Refactored web search provider system to use centralized provider registry with
getSearchProvider()andresolveProviderChain()for improved provider management - Updated web search system prompt to emphasize comprehensive, detailed answers with concrete data and specific examples over brevity
- Simplified Exa API key discovery to check environment variables only, removing .env file fallback logic
- Refactored
ModelRegistryinstantiation to use direct constructor instead ofdiscoverModels()helper function across codebase - Refactored CLI entry point to use oclif command framework instead of custom subcommand routing
- Reorganized subcommands into individual command files under
src/commands/directory for better maintainability - Updated extension flag handling to parse raw arguments directly instead of using custom flag definitions
- Refactored web search provider definitions into centralized provider-info module for better maintainability
- Updated web search result rendering to support long-form answers with text wrapping in CLI mode
- Removed related questions section from web search result rendering
- Updated Perplexity API types to support extended message content formats including images, files, and PDFs
- Updated Perplexity search to use 'pro' search type for improved search quality and relevance
- File mention messages now support both text content and image attachments, with optional line count for text files
- Updated file mention processing to respect image auto-resize settings
Removed
- Removed legacy auth.json file—credentials are stored exclusively in agent.db
Fixed
- Fixed type handling in model selector error message display to properly convert error objects to strings
- Fixed web search to use search results when Perplexity API returns no citations, ensuring search results are always available to users
- Fixed model switches deferred during streaming to apply correctly when the stream completes, preventing model changes from being lost
- Fixed plan mode toggles during streaming to inject plan-mode context immediately, preventing file edits while in plan mode
- Fixed plan mode model switches during streaming to defer model changes until the current turn completes
[11.1.0] - 2026-02-05
Added
- Added
sortDiagnostics()utility function to sort diagnostics by severity, location, and message for consistent output ordering - Added
task.isolation.enabledsetting to control whether subagents run in isolated git worktrees - Added dynamic task schema that conditionally includes
isolatedparameter based on isolation setting - Added
openInEditor()utility function to centralize external editor handling with support for custom file extensions and stdio configuration - Added
getEditorCommand()utility function to retrieve the user's preferred editor from $VISUAL or $EDITOR environment variables
Changed
- Changed diagnostic output to sort results by severity (errors first), then by file location and message for improved readability
- Changed task tool to validate isolation setting and reject
isolatedparameter when isolation is disabled - Changed task API to use
assignmentfield instead ofargsfor per-task instructions, with sharedcontextprepended to every task - Changed task template rendering to use structured context/assignment separation with
<swarm_context>wrapper instead of placeholder-based substitution - Changed task item schema to require
assignmentstring (complete per-task instructions) instead of optionalargsobject - Changed
TaskItemto removeargsfield and addassignmentfield for clearer per-task instruction semantics - Changed agent frontmatter to use
thinking-levelfield name instead ofthinkingLevelfor consistency - Refactored task rendering to display full task text instead of args in progress and result views
- Changed
SubmenuSettingDef.getOptions()method tooptionsgetter property for cleaner API access - Converted static option providers from functions to direct array definitions for improved performance
- Added
createSubmenuSettingDef()helper function to support both static and dynamic option providers - Modified
setThinkingLevel()API to accept optionalpersistparameter (defaults to false) for controlling whether thinking level changes are saved to settings - Refactored hook editor and input controller to use shared external editor utilities, reducing code duplication
Removed
- Removed
contextparameter fromExecutorOptions— context now prepended at template level before task execution - Removed
argsfield fromAgentProgressandSingleResultinterfaces - Removed placeholder-based template rendering in favor of structured context/assignment model
[11.0.3] - 2026-02-05
Added
- Added new subcommands to help text:
commitfor AI-assisted git commits,statsfor AI usage statistics dashboard, andjupyterfor managing the shared Jupyter gateway - Added
grepsubcommand to help text for testing the grep tool - Added
browsertool documentation for browser automation using Puppeteer - Added
todo_writetool documentation for managing todo and task lists - Added documentation for additional LLM provider API keys (Groq, Cerebras, xAI, OpenRouter, Mistral, z.ai, MiniMax, OpenCode, Cursor, Vercel AI Gateway) in environment variables reference
- Added documentation for cloud provider configuration (AWS Bedrock, Google Vertex AI) in environment variables reference
- Added documentation for search provider API keys (Perplexity, Anthropic Search) in environment variables reference
- Added documentation for model override environment variables (
PI_SMOL_MODEL,PI_SLOW_MODEL,PI_PLAN_MODEL) in CLI help text - Added comprehensive environment variables reference documentation at
docs/environment-variables.mdcovering API keys, configuration, debugging, and testing variables - Added theme system with 44 customizable color tokens, two built-in themes (dark/light), and auto-detection based on terminal background
- Added
/themecommand to interactively select and switch between themes - Added support for custom themes in
~/.pi/agent/themes/*.jsonwith live editing - changes apply immediately when files are saved - Added
userMessageTexttheme token for customizing user message text color - Added
toolTitleandtoolOutputtheme tokens for separate coloring of tool execution box titles and output
Changed
- Updated help text to reflect expanded tool availability - default now enables all tools instead of just read, bash, edit, write
- Updated available tools list in help documentation to include python, notebook, task, fetch, web_search, browser, and ask
- Simplified main description in help text from 'AI coding assistant with read, bash, edit, write tools' to 'AI coding assistant'
- Updated
--toolsoption documentation to clarify default behavior and list all available tools - Changed all environment variable access from
process.envtoBun.envthroughout the codebase for Bun runtime compatibility - Updated documentation to reference
Bun.envinstead ofprocess.envin examples and comments
Fixed
- Fixed
Textcomponent to properly implementinvalidate()method, ensuring theme changes apply correctly to all UI elements - Fixed
TruncatedTextcomponent to properly pad all lines to exactly match the specified width, preventing rendering artifacts - Fixed
TruncatedTextcomponent to stop at the first newline and only display the first line - Fixed invalid or malformed themes to fall back gracefully to dark theme instead of crashing the application
[11.0.2] - 2026-02-05
Fixed
- Fixed role model cycling to expand role aliases (e.g., roles pointing at
pi/plan) so slow/default/smol cycles resolve correctly
[11.0.0] - 2026-02-05
Added
- Added UI dropdown options for
task.maxRecursion Depthsetting with presets (Unlimited, None, Single, Double, Triple) - Added UI dropdown options for
grep.contextBeforesetting with presets (0-5 lines) - Added UI dropdown options for
grep.contextAftersetting with presets (0-10 lines) - Added
task.maxRecursionDepthsetting to control how many levels deep subagents can spawn their own subagents (0=none, 1=one level, 2=two levels, -1=unlimited) - Added support for nested task artifact naming with parent task prefixes (e.g., "0-Auth.1-Subtask") to organize hierarchical task outputs
- Added
taskDepthandparentTaskPrefixoptions toCreateAgentSessionOptionsfor tracking subagent recursion depth and organizing nested artifacts - Added
task.maxConcurrencysetting to control concurrent limit for subagents (default: 32) - Added UI options for task concurrency configuration with presets from unlimited to 64 tasks
- Added support for loading skills from
~/.agents/skills
Changed
- Simplified
task.maxRecursionDepthdescription in settings UI to remove specific value examples - Made thinking level persistence optional via
persistparameter insetThinkingLevel()method, allowing temporary thinking level changes without saving to settings - Updated thinking level cycling to no longer persist changes to settings, enabling quick iteration through thinking levels without modifying user preferences
- Replaced nanoid with Snowflake for ID generation throughout codebase for improved performance and collision resistance
- Updated session ID format in documentation from nanoid to snowflake hex string (e.g., "a1b2c3d4e5f60001")
- Renamed environment variable prefix from
OMP_toPI_throughout codebase (e.g.,OMP_DEBUG_STARTUP→PI_DEBUG_STARTUP,OMP_PYTHON_GATEWAY_URL→PI_PYTHON_GATEWAY_URL) - Removed
envsetting from configuration schema; environment variables are no longer automatically applied from settings - Changed
venvPathproperty in PythonRuntime from nullable to optional (returnsundefinedinstead ofnull) - Simplified notification settings from protocol-specific options (bell, osc99, osc9) to simple on/off toggle for
completion.notifyandask.notify - Moved notification protocol detection and sending to
TERMINALAPI from local utility functions - Changed task tool spawns configuration from "explore" to "*" to allow subagents to spawn any agent type
- Changed system prompt to enable parallel delegation guidance for all agents (removed coordinator-only restriction)
- Changed task tool to automatically disable itself when maximum recursion depth is reached, preventing infinite nesting
- Changed task concurrency from hardcoded constant to configurable setting via
task.maxConcurrency - Changed concurrency limit calculation to support unlimited concurrency when set to 0
Removed
- Removed nanoid dependency from package.json
- Removed
terminal-notify.tsutility module withdetectNotificationProtocol(),sendNotification(), andisNotificationSuppressed()functions - Removed
MAX_PARALLEL_TASKSconstant and associated task count validation limit
Fixed
- Fixed MCP tool name generation to properly sanitize server and tool names, preventing invalid characters and duplicate prefixes in tool identifiers
- Fixed task ID display formatting to show hierarchical structure for nested tasks (e.g., "0.1 Auth>Subtask" instead of "0-Auth.1-Subtask")
- Improved frontmatter parsing error messages to include source context for better debugging
[10.6.1] - 2026-02-04
Added
- Added
commitmodel role for dedicated commit message generation - Exported
resolveModelOverridefunction from model resolver for external use
Changed
- Updated model role resolution to accept optional
roleOrderparameter for custom role priority - Made
tagandcolorproperties optional inModelRoleInfointerface - Updated model selector to safely handle roles without tag or color definitions
- Refactored role label display to use centralized
MODEL_ROLESregistry instead of hardcoded strings - Refactored model role system to use centralized
MODEL_ROLESregistry with consistent tag, name, and color definitions - Simplified model role resolution to use
MODEL_ROLE_IDSarray instead of hardcoded role checks - Updated model selector to dynamically generate menu actions from
MODEL_ROLESregistry
Removed
- Removed support for
omp/model role prefix; usepi/prefix instead
[10.6.0] - 2026-02-04
Breaking Changes
- Removed
output_modeparameter from grep tool—results now always use content mode with formatted match output - Renamed grep context parameters from
context_pre/context_posttopre/post - Removed
n(show line numbers) parameter—line numbers are now always displayed in grep results
Added
- Added Jina as a web search provider option alongside Exa, Perplexity, and Anthropic
- Added support for Jina Reader API integration with automatic provider detection when JINA_API_KEY is configured
Changed
- Reformatted grep output to display matches grouped by file with numbered match headers and aligned context lines
- Updated grep output to use
>>prefix for match lines and aligned spacing for context lines for improved readability - Changed multiline matching to automatically enable when pattern contains literal newlines (
) - Split grep context parameter into separate
context_preandcontext_postoptions for independent control of lines before and after matches - Updated grep tool to use configurable default context settings from
grep.contextBeforeandgrep.contextAfterconfiguration - Added configurable grep context defaults and reduced the default to 1 line before, 3 lines after
- Enabled the browser tool by default
Removed
- Removed
filesWithMatchesandcountoutput modes from grep tool
[10.5.0] - 2026-02-04
Breaking Changes
- Changed
asktool to requirequestionsarray parameter; single-question mode withquestion,options,multi, andrecommendedparameters is no longer supported - Removed support for local Python kernel gateway startup; shared gateway is now required
Added
- Added browser tool powered by Ulixee Hero with support for navigation, DOM interaction, screenshots, and readable content extraction
- Added
/browsercommand to toggle browser headless vs visible mode in interactive sessions - Added
browser.enabledandbrowser.headlesssettings to control browser automation behavior - Added Python prelude caching to improve startup performance by storing compiled prelude helpers and module metadata
- Added
OMP_DEBUG_STARTUPenvironment variable for conditional startup performance debugging output - Added autonomous memory system with storage, memory tools, and context injection
Changed
- Updated task tool guidance to enforce small, well-defined task scope with maximum 3-5 files per task to prevent timeouts and improve parallel execution
- Updated browser viewport to use 1.25x device scale factor for improved rendering on high-DPI displays
- Modified device pixel ratio detection to respect actual screen capabilities instead of forcing 1x ratio
- Updated system prompt guidance to state assumptions and proceed without asking for confirmation, reducing unnecessary round-trips
- Tightened
asktool conditions to require multiple approaches with significantly different tradeoffs before prompting user - Strengthened
asktool guidance to default to action and only ask when genuinely blocked by decisions with materially different outcomes - Changed refactor workflow to automatically remove now-unused elements and note removals instead of asking for confirmation
- Enforced exclusive concurrency mode for all file-modifying tools (edit, write, bash, python, ssh, todo-write) to prevent concurrent execution conflicts
- Updated
asktool guidance to prioritize proactive problem-solving and default to action, asking only when truly blocked by decisions that materially change scope or behavior - Changed Python kernel initialization to require shared gateway mode; local gateway startup has been removed
- Changed shared gateway error handling to retry on server errors (5xx status codes) before failing
Fixed
- Fixed glob search returning no results when all files are ignored by gitignore by automatically retrying without gitignore filtering
[10.3.2] - 2026-02-03
Added
- Added
renderCallandrenderResultmethods to MCP tools for structured TUI display of tool calls and results - Added new
mcp/render.tsmodule providing JSON tree rendering for MCP tool output with collapsible/expandable views
Changed
- Updated
renderResultsignature in custom tools and extensions to accept optionalargsparameter for context-aware rendering - Changed environment variable from
ENV_AGENT_DIRconstant to hardcodedOMP_CODING_AGENT_DIRstring in config and CLI help text - Fixed method binding in extension and hook tool wrappers to preserve
thiscontext forrenderCallandrenderResultmethods
[10.3.1] - 2026-02-03
Fixed
- Fixed timeout handling in LSP write-through operations to properly clear formatter and diagnostics results when operations exceed the 10-second timeout
[10.3.0] - 2026-02-03
Removed
- Removed
shellForceBasicsetting that forced bash/sh shell selection - Removed
bash.persistentShellexperimental setting for shell session reuse
[10.2.3] - 2026-02-02
Added
- Added
find.enabled,grep.enabled,ls.enabled,notebook.enabled,fetch.enabled,web_search.enabled,lsp.enabled, andcalc.enabledsettings to control availability of individual tools - Added conditional tool documentation in system prompt that dynamically lists only enabled specialized tools
- Added
todos.enabledsetting to control availability of the todo_write tool for task tracking - Added
toolsfield to agent frontmatter for declaring agent-specific tool capabilities
Changed
- Consolidated
symbolsaction to handle both file-based document symbols and workspace symbol search (query-based) - Consolidated
diagnosticsaction to handle both single-file and workspace-wide diagnostics (no file = workspace) - Simplified
reloadaction to gracefully reload language server with fallback to kill - Updated LSP tool documentation to reflect simplified operation set and consolidated actions
- Reorganized settings tabs from 8 to 9 tabs with clearer categorization: Display, Agent, Input, Tools, Config, Services, Bash, LSP, and TTSR
- Moved behavior-related settings to new Agent tab for better organization
- Moved input/interaction settings to new Input tab
- Moved tool configuration settings to new Config tab
- Moved provider and service settings to new Services tab
- Added visual icons to settings tabs using theme symbols for improved UI clarity
- Changed default settings tab from Behavior to Display on startup
- Updated
readtool to handle directory paths by returning formatted listings with modification times instead of redirecting tols - Updated tool documentation to reflect that
readnow handles both files and directories - Updated system prompt tool precedence section to conditionally display only available specialized tools based on enabled settings
- Renamed todo completion settings from
todoCompletion.*totodos.reminders.*andtodos.enabledfor clearer organization - Updated todo reminder logic to check both
todos.remindersandtodos.enabledsettings independently
Removed
- Removed Rust-analyzer specific LSP operations:
flycheck,expand_macro,ssr,runnables,related_tests, andreload_workspace - Removed
workspace_diagnosticsaction; usediagnosticswithout file parameter instead - Removed
workspace_symbolsaction; usesymbolswith query parameter and no file instead - Removed
actions,incoming_calls, andoutgoing_callsLSP operations - Removed
replacement,kind,action_index,end_line, andend_characterparameters from LSP tool - Removed Python prelude helper functions:
pwd(),mkdir(),ls(),head(),tail(),sh(),cat(),touch(),wc(),basenames(), andbatch() - Removed type guard functions (
isBashToolResult,isReadToolResult,isEditToolResult,isWriteToolResult,isGrepToolResult,isFindToolResult,isLsToolResult) from public API exports - Removed
lstool—directory listing is now handled by thereadtool - Removed
ls.enabledsetting and related configuration options - Removed
bashInterceptor.simpleLssetting that redirected simplelscommands to the dedicated tool - Removed project tree snapshot generation from system prompt (unused feature)
Fixed
- Fixed tool parameter schemas displaying internal TypeBox metadata fields in system prompt
[10.2.1] - 2026-02-02
Breaking Changes
- Removed
strippedRedirectfield fromNormalizedCommandinterface returned bynormalizeBashCommand() - Removed automatic stripping of
2>&1stderr redirections from bash command normalization
[10.1.0] - 2026-02-01
Added
- Added work scheduling profiler to debug menu for analyzing CPU scheduling patterns over the last 30 seconds
- Added support for work profile data in report bundles including folded stacks, summary, and flamegraph visualization
[10.0.0] - 2026-02-01
Added
- Added
shellsubcommand for interactive shell console testing with brush-core - Added
--cwd/-Coption to set working directory for shell commands - Added
--timeout/-toption to configure per-command timeout in milliseconds - Added
--no-snapshotoption to skip sourcing snapshot from user shell
Fixed
findnow returns a single match when given a file path instead of failing with "not a directory"
[9.8.0] - 2026-02-01
Breaking Changes
- Removed persistent shell session support; bash execution now uses native bindings via brush-core for improved reliability
Added
- Added
sessionKeyoption to bash executor to isolate shell sessions per agent instance - Added shell snapshot support for bash execution to preserve shell state across commands
- Added
onChunkcallback support for streaming command output in real-time
Changed
- Refactored bash executor to queue output chunks asynchronously for improved reliability
- Updated bash executor to pass environment variables separately as
sessionEnvto native bindings - Migrated system information collection to use native bindings from brush-core instead of shell command execution
- Updated CPU information to report core count alongside model name
- Simplified OS version reporting to use Node.js built-in APIs
- Migrated bash command execution from ptree-based persistent sessions to native shell bindings with streaming support
- Simplified bash executor to use brush-core native API instead of managing long-lived shell processes
- Routed clipboard copy and image paste through native arboard bindings instead of shell commands
- Embedded native addon payload for compiled binaries and extract to
~/.omp/natives/<version>on first run
Removed
- Removed shell configuration from environment information display
- Removed
shell-session.tsmodule providing persistent shell session management - Removed shell session test suite for persistent execution patterns
[9.6.2] - 2026-02-01
Changed
- Replaced hardcoded ellipsis strings with Unicode ellipsis character (…) throughout rendering code
- Removed
format.ellipsissymbol from theme configuration; ellipsis now uses literal Unicode character - Updated
truncate()function totruncateToWidth()with simplified API accepting default ellipsis parameter - Simplified
formatMoreItems()function signature by removing theme parameter dependency
Removed
- Removed
format.ellipsissymbol key from theme symbol maps (Unicode, Nerd, and ASCII presets) - Removed
ellipsisproperty fromSymbolThemetype
[9.6.1] - 2026-02-01
Fixed
- Fixed output handling to prioritize text/markdown over text/plain when both are available, ensuring Markdown content is displayed correctly
- Fixed bash command normalization to preserve newlines in heredocs and multiline commands
[9.6.0] - 2026-02-01
Breaking Changes
- Replaced
SettingsManagerclass with newSettingssingleton providing sync get/set API with background persistence - Changed settings access from method calls (e.g.,
getTheme()) to path-based access (e.g.,settings.get("theme")) - Removed
settingsManagerparameter fromCreateAgentSessionOptionsin favor ofsettingsInstance - Removed
loadSettings()export from public API - Removed example file
examples/sdk/10-settings.tsdemonstrating old SettingsManager API
Added
- New
Settingssingleton class with sync get/set operations and background persistence - Added
Settings.isolated()factory for creating isolated settings instances in tests - Added
Settings.init()for initializing global settings instance - Added
settingsglobal export for convenient access to settings singleton - New
settings-schema.tsproviding unified, type-safe settings definitions with UI metadata - Added "none" option to
doubleEscapeActionsetting to disable double-escape behavior entirely (#973 by @juanibiapina)
Changed
- Unified settings schema into single source of truth with
settings-schema.tsreplacing scattered definitions - Refactored settings CLI to use new schema-based path resolution instead of SETTINGS_DEFS
- Updated config command examples to use new nested path syntax (e.g.,
compaction.enabledinstead ofautoCompact) - Changed
InteractiveModeContext.settingsManagertoInteractiveModeContext.settings - Updated all internal settings access throughout codebase to use new
settings.get()andsettings.set()API - Moved
DEFAULT_BASH_INTERCEPTOR_RULESfrom settings-manager to bash-interceptor module
Removed
- Deleted
settings-manager.ts(2035 lines) - functionality replaced by new Settings singleton - Removed
SettingsManager.create(),SettingsManager.acquire(), andSettingsManager.inMemory()factory methods - Removed individual getter/setter methods from settings API (e.g.,
getTheme(),setTheme(),getCompactionSettings())
Fixed
- Respect .gitignore, .ignore, and .fdignore files when scanning package resources for skills, prompts, themes, and extensions
[9.5.1] - 2026-02-01
Changed
- Changed persistent shell from opt-out to opt-in (default: off) for improved reliability; enable via Settings > Bash > Persistent shell or
OMP_SHELL_PERSIST=1 - Added new "Bash" settings tab grouping shell-related settings (force basic shell, persistent shell, interceptor, intercept ls)
[9.5.0] - 2026-02-01
Added
- Added
headandtailparameters to bash tool to limit output lines without breaking streaming - Added automatic normalization of bash commands to extract
| head -n Nand| tail -n Npatterns into native parameters - Added
maxResultsparameter to find tool to limit result set at the native layer - Added context-structure template showing required sections (Goal, Constraints, Existing Code, API Contract) with examples of good vs bad context
- Added explicit dependency test: 'Can agent B write correct code without seeing agent A's output?' to determine sequencing
- Added detailed phased execution pattern with four phases (Foundation, Parallel Implementation, Integration, Dependent Layer) and WASM-to-N-API migration example
- Added table of dependency patterns that must be sequential (API creation before bindings, interface definition before implementation, etc.)
- Added phased execution guidance for migrations and refactors to prevent parallel work on dependent layers
- Added example demonstrating phased execution pattern for porting WASM to N-API with sequential foundation, parallel implementation, integration, and dependent layer phases
Changed
- Improved find tool performance by delegating mtime-based sorting to native layer instead of post-processing results in JavaScript
- Simplified find tool result processing by removing redundant filesystem stat calls when native metadata is available
- Updated bash tool documentation to recommend using
headandtailparameters instead of piping through head/tail commands - Updated binary build process to exclude worker files from compilation, reducing binary size
- Modified update mechanism to download and install native addon alongside CLI binary for platform-specific functionality
- Updated find tool to emit streaming match updates via callback, allowing real-time progress feedback during file searches
- Modified find tool to use native match metadata (mtime, fileType) from WASM layer instead of redundant filesystem stats, improving performance
- Restructured Task tool documentation to emphasize context quality and explicit API contracts for subagent success
- Updated task execution guidance to require structured context with Goal, Constraints, Existing Code, and API Contract sections
- Reorganized parallelization rules with explicit dependency patterns and phased execution guidance for migrations
- Clarified that response format requirements must go in schema parameter, never in context descriptions
- Centralized Python runtime resolution into shared
ipy/runtime.tsmodule, removing duplicate code from kernel and gateway coordinator
Removed
- Removed Nushell language server configuration from LSP defaults
Fixed
- Fixed race condition in shell session where command completion could occur before stream data was fully processed
- Fixed Python gateway spawning console window on Windows by using windowless Python interpreter (pythonw.exe)
[9.4.0] - 2026-01-31
Changed
- Migrated environment variable handling to use centralized
getEnv()andgetEnvApiKey()utilities from pi-ai package for consistent API key resolution across web search providers and image tools - Simplified web search error messages to remove provider-specific configuration hints
- Replaced manual space padding with
padding()utility function from pi-tui across UI components for consistent whitespace handling - Improved rendering performance for Python cell output by implementing caching in the table and cell results renderers
- Updated task tool documentation to clarify that subagents can access parent conversation context via a searchable file, reducing need to repeat information in context parameter
- Updated plan mode prompt to guide model toward using
edittool for incremental plan updates instead of defaulting towrite
Removed
- Removed environment variable denylist that blocked API keys from being passed to subprocesses; API keys are now controlled via allowlist only
[9.3.1] - 2026-01-31
Added
- Added
getCompactContext()API to retrieve parent conversation context for subagents, excluding system prompts and tool results - Added automatic
submit_resulttool injection for subagents with explicit tool lists - Added
contextFileparameter to pass parent conversation context to subagent sessions
Changed
- Updated subagent system prompt to reference parent conversation context file when available
- Enhanced subagent system prompt formatting with clearer backtick notation for tool and parameter names
Removed
- Removed schema override notification from task summary prompt
[9.2.5] - 2026-01-31
Changed
- Clarified that user instructions about delegation override tool-use defaults
- Updated coordinator guidance to emphasize Task tool preference for substantial work with improved emphasis on context window limitations
- Enhanced
contextparameter documentation to require self-contained information for subagents, including file contents and user requirements
[9.2.4] - 2026-01-31
Fixed
- Prevented interactive commands from blocking on stdin by redirecting from /dev/null in POSIX and Fish shell sessions
[9.2.3] - 2026-01-31
Added
- Persistent shell session support for bash tool with environment variable preservation across commands
- New
shellForceBasicsetting to force bash/sh even if user's default shell is different (default: true) - New
OMP_SHELL_PERSISTenvironment variable to control persistent shell behavior (set to 0 to disable)
Changed
- Bash tool now reuses a persistent shell session by default on Unix systems for improved performance and state preservation
- Replaced Bun file APIs with Node.js
fsmodule for better cross-runtime compatibility - LSP configuration loading is now synchronous instead of async
- Shell snapshot generation now sanitizes
BASH_ENVandENVvariables to prevent shell exit issues - Shell snapshot caching now per-shell-binary instead of global to avoid cross-shell contamination
- System prompt restructured with coordinator-specific guidance for parallel task delegation
- Bash tool now reuses a persistent shell session by default on Unix. Set
OMP_SHELL_PERSIST=0to disable or fall back to per-command execution on Windows/unsupported shells. - Added a shellForceBasic setting to force bash/sh and keep environment changes across bash commands (default: true).
Fixed
- Shell snapshots now filter unsafe bash options (onecmd, monitor, restricted) to prevent session exits
- Git branch detection in status line now works synchronously without race conditions
- Shell session initialization properly restores trap handlers and shell functions after command execution
- Sanitized
BASH_ENV/ENVduring persistent shell startup and snapshot creation to prevent basic shells from exiting immediately. - Cached shell snapshots per shell binary to avoid sourcing zsh snapshots in bash sessions.
- Filtered unsafe bash options (onecmd/monitor/restricted) out of shell snapshots to prevent session exits.
[9.2.2] - 2026-01-31
Added
- Added grep CLI subcommand (
omp grep) for testing pattern matching - Added fuzzy matching for model resolution with scoring and ranking fallback
- Added 'Open: artifact folder' menu option to debug selector for quick access to session artifacts
- Added Kimi API format setting for selecting between OpenAI and Anthropic formats
- Added Codex and Gemini web search providers with OAuth and grounding support
- Added /debug command with interactive menu for profiling, heap snapshots, session dumps, and diagnostics
- Added configurable ask timeout and notification settings
- Added gitignore-aware project tree scanning with ripgrep integration
- Added project tree visualization to system prompts with configurable depth and entry limits
- Added reset() method to CountdownTimer with integration into HookSelectorComponent
- Added custom message support to AgentSession via promptCustomMessage() method
- Added skill message component for rendering /skill command messages as compact entries
- Added model preference matching system for intelligent model selection based on usage history
- Added designer agent with UI/UX review and accessibility audit capabilities
- Added model-specific edit variant configuration for patch/replace modes
- Added automatic browser opening when stats dashboard starts
- Added model statistics table and TTFT/throughput metrics to stats dashboard
- Added artifact allocation for truncated fetch responses to preserve full content
- Added 30-second timeout to ask tool with auto-selection of recommended option
- Added recommended parameter (0-indexed) to ask tool for specifying default option
- Added JTD to TypeScript converter for rendering schemas in system prompts
- Added tools list to system prompt for better agent awareness
- Added synthetic message flag for system-injected prompts
- Added session compaction enhancements with auto-continue, tool pruning, and remote endpoint support
- Added detection and rendering of missing complete tool warning in subagent output
- Added outline UI components for bordered list containers
- Added macOS NFD normalization and curly quote variant resolution for file paths
- Enhanced session compaction with dynamic token ratio adjustment and improved summary preservation
Changed
- Simplified find tool API by consolidating path and pattern parameters
- Replaced bulk file loading with streaming for read tool to reduce memory overhead
- Migrated grep and find tools to WASM-based implementation
- Replaced ripgrep-based file listing with glob-based file discovery for project scans
- Updated minimum Bun runtime requirement to >=1.3.7
- Renamed task parameter from output to schema
- Renamed complete tool to submit_result for clarity and consistency
- Improved output preview logic: shows full output for ≤30 lines, truncates to 10 lines for larger output
Fixed
- Enhanced error reporting with debug stack trace when DEBUG env is set
- Improved OAuth token refresh error handling to distinguish transient vs definitive failures
- Added windowsHide option to child process spawn calls to prevent console windows on Windows
- External edits to config.yml are now preserved when omp reloads or saves settings
- Exposed LSP server startup errors in session display and logs
- Improved error handling and security in agent storage initialization with restrictive file permissions
- Fixed LSP server display showing unknown when server warmup fails
- Preserved null timeout when user disables ask timeout setting
- Removed incorrect timeout unit conversion logic in cursor, fetch, gemini-image, and ssh tools
- Blocked /fork command while streaming to prevent split session logs
[9.0.0] - 2026-01-29
Fixed
- External edits to
config.ymlare now preserved when omp reloads or saves unrelated settings. Previously, editing config.yml directly (e.g., removing a package frompackagesarray) would be silently reverted on next omp startup when automatic setters likesetLastChangelogVersion()triggered a save. (#1046 by @nicobailonMD)
[8.13.0] - 2026-01-29
Added
- Added
/debugcommand with interactive menu for bug report generation:Report: performance issue- CPU profiling with reproduction flowReport: dump session- Immediate session bundle creationReport: memory issue- Heap snapshot with bundleView: recent logs- Display last 50 log entriesView: system info- Show environment detailsClear: artifact cache- Remove old session artifacts
Fixed
- Fixed LSP server errors not being visible in
/sessionoutput or logs when startup fails
[8.12.7] - 2026-01-29
Fixed
- Fixed LSP servers showing as "unknown" in status display when server warmup fails
- Fixed Read tool loading entire file into memory when offset/limit was specified
[8.12.2] - 2026-01-28
Changed
- Replaced ripgrep-based file listing with fs.glob for project scans and find/read tooling
[8.11.14] - 2026-01-28
Changed
- Rendered /skill command messages as compact skill entries instead of full prompt text
[8.8.8] - 2026-01-28
Added
- Added
/forkcommand to create a new session with the exact same state (entries and artifacts) as the current session
Changed
- Renamed the
completetool tosubmit_resultfor subagent result submission
[8.6.0] - 2026-01-27
Added
- Added
planmodel role for specifying the model used by the plan agent - Added
--planCLI flag andOMP_PLAN_MODELenvironment variable for ephemeral plan model override - Added plan model selection in model selector UI with PLAN badge
Changed
- Task tool subagents now execute in-process instead of using worker threads
Fixed
- Queued skill commands as follow-ups when the agent is already streaming to avoid load failures
- Deduplicated repeated review findings in subagent progress rendering
- Restored MCP proxy tool timeout handling to prevent subagent hangs
[8.5.0] - 2026-01-27
Added
- Added subagent support for preloading skill contents into the system prompt instead of listing available skills
- Added session init entries to capture system prompt, task, tools, and output schema for subagent session logs
Fixed
- Reduced Task tool progress update overhead to keep the UI responsive during high-volume streaming output
- Fixed subagent session logs dropping pre-assistant entries (user/task metadata) before the first assistant response
Removed
- Removed enter-plan-mode tool
[8.4.5] - 2026-01-26
Added
- Model usage tracking to record and retrieve most recently used models
- Model sorting in selector based on usage history
Changed
- Renamed
head_limitparameter tolimitin grep and find tools for consistency - Added
contextas an alias for theccontext parameter in grep tool - Made hidden files inclusion configurable in find tool via
hiddenparameter (defaults to true) - Added support for reading ignore patterns from .gitignore and .ignore files in find tool
Fixed
- Respected .gitignore rules when filtering find tool results by glob pattern
[8.4.2] - 2026-01-25
Changed
- Clarified and condensed plan mode prompts for improved clarity and consistency
[8.4.1] - 2026-01-25
Added
- Added core plan mode with plan file approval workflow and tool gating
- Added plan:// internal URLs for plan file access and subagent plan-mode system prompt
- Added plan mode toggle shortcut with paused status indicator
Fixed
- Fixed plan reference injection and workflow prompt parameters for plan mode
- Fixed tool downloads hanging on slow/blocked GitHub by adding timeouts and zip extraction fallback
- Fixed missing UI notification when tools are downloaded or installed on demand
[8.4.0] - 2026-01-25
Added
- Added extension API to set working/loading messages during streaming
- Added task worker propagation of context files, skills, and prompt templates
- Added subagent option to skip Python preflight checks when Python tooling is unused
- Model field now accepts string arrays for fallback model prioritization
Changed
- Merged patch application warnings into edit tool diagnostics output
- Cached Python prelude docs for subagent workers to avoid repeated warmups
- Simplified image placeholders inserted on paste to match Claude-style markers
Fixed
- Rewrote empty or corrupted session files to restore valid headers
- Improved patch applicator ambiguity errors with match previews and overlap detection
- Fixed Task tool agent model resolution to honor comma-separated model lists
[8.3.0] - 2026-01-25
Changed
- Added request parameter tracking to LSP tool rendering for better diagnostics visibility
- Added async diff computation and Kitty protocol support to tool execution rendering
- Refactored patch applicator with improved fuzzy matching (7-pass sequence matching with Levenshtein distance) and indentation adjustment
- Added inline rendering flag to bash and fetch tool renderers
- Extracted constants for preview formatting to improve code maintainability
- Exposed mergeCallAndResult and inline rendering options from tools to their wrappers
- Added timeout validation and normalization for tool timeout parameters
Fixed
- Fixed output block border rendering (bottom-right corner was missing)
- Added background control parameter to output block rendering
[8.2.2] - 2026-01-24
Removed
- Removed git utility functions (_git, git_status, git_diff, git_log, git_show, git_file_at, git_branch, git_has_changes) from IPython prelude
[8.2.0] - 2026-01-24
Added
- Added
omp commitcommand to generate conventional commits with changelog updates - Added agentic commit mode with commit-specific tools and
--legacyfallback - Added configurable settings for map-reduce analysis including concurrency, timeout, file thresholds, and token limits
- Added support for excluding YAML lock files (
.lock.yml,.lock.yaml,-lock.yml,-lock.yaml) from commit analysis - Added new TUI component library with reusable rendering utilities including code cells, file lists, tree lists, status lines, and output blocks
- Added renderCodeCell component for displaying code with optional output sections, supporting syntax highlighting and status indicators
- Added renderFileList component for rendering file/directory listings with language icons and metadata
- Added renderTreeList component for hierarchical tree-based item rendering with expand/collapse support
- Added renderStatusLine component for standardized tool status headers with icons, descriptions, and metadata
- Added renderOutputBlock component for bordered output containers with structured sections
- Added renderOutputBlock to Bash tool for improved output formatting with status indicators
- Added
--legacyflag toomp commitfor using the deterministic pipeline instead of agentic mode - Added split commit support to automatically create multiple atomic commits for unrelated changes
- Added git hunk inspection tools for fine-grained diff analysis in commit generation
- Added commit message validation with filler word and meta phrase detection
- Added automatic unicode normalization in commit summaries
- Added real-time progress output to agentic commit mode showing thinking status, tool calls, and completion summary
- Added hunk-level staging support in split commits allowing partial file changes per commit
- Added dependency ordering for split commits ensuring commits are applied in correct sequence
- Added circular dependency detection with validation errors for split commit plans
- Added parallel file analysis with cross-file context awareness via
analyze_filestool - Added AGENTS.md context file discovery for commit generation
- Added progress indicators during changelog generation and model resolution
- Added propose_changelog tool for agent-provided changelog entries in agentic commit workflow
- Added fallback commit generation when agentic mode fails, using file pattern analysis and heuristic-based type inference
- Added trivial change detection to automatically classify whitespace-only and import-reorganization commits
- Added support for pre-computed file observations in commit agent to skip redundant analyze_files calls
- Added diff content caching with smart file prioritization to optimize token usage in large changesets
- Added lock file filtering (17 patterns including Cargo.lock, package-lock.json, bun.lock) from commit analysis
- Added changelog deletion support to remove outdated entries via the changelog proposal interface
- Added support for pre-computed changelog entries in commit agent to display existing unreleased sections for potential deletion
- Added
ExistingChangelogEntriesinterface to track changelog sections by path for changelog proposal context - Added conditional
analyze_filesskipping in commit agent when pre-analyzed observations are provided - Added guidance to commit agent prompts instructing subagents to write files directly instead of returning changes for manual application
- Added mermaid diagram rendering with terminal graphics support (Kitty/iTerm2) for markdown output
- Added renderMermaidToPng utility for converting mermaid code blocks to terminal-displayable PNG images via mmdc CLI
- Added mermaid block extraction with content-addressed hashing for deduplication and cache lookup
- Added background mermaid pre-rendering in assistant messages for responsive diagram display
- Added two-level mermaid caching with pending deduplication to prevent redundant renders
- Added Python kernel session pooling with MAX_KERNEL_SESSIONS limit and automatic eviction of oldest sessions
- Added automatic idle kernel session cleanup timer (5-minute timeout, 30-second interval)
- Added types/assets/index.d.ts for global TypeScript module declarations supporting
.md,.py, and.wasm?rawimports - Added bunfig.toml loader configuration for importing markdown, Python, and WASM files as text modules
- Added color manipulation utilities (hexToHsv, hsvToHex, shiftHue) to pi-utils for accessible theme adjustments
- Added color-blind mode setting for improved accessibility
- Added filesystem error type guards (isEnoent, isEacces, isPerm, isEnotempty, isFsError, hasFsCode) to pi-utils for safe error handling
- Added tarball installation test Dockerfile to validate npm publish/install flow
Changed
- Changed changelog diff truncation limit to be configurable via settings
- Changed tool result rendering to use new TUI component library across multiple tools (bash, calculator, fetch, find, grep, ls, notebook, python, read, ssh, write, lsp, web search) for consistent output formatting
- Changed Bash tool output rendering to use renderOutputBlock with proper section handling and width-aware truncation
- Changed Python tool output rendering to use renderCodeCell component for code cell display with status indicators
- Changed Read tool output rendering to use renderCodeCell with syntax highlighting and warnings display
- Changed Write tool output rendering to use renderCodeCell for code display with streaming preview support
- Changed Fetch tool output rendering to use renderOutputBlock with metadata and content preview sections
- Changed LSP tool output rendering to use renderStatusLine and renderOutputBlock for structured output display
- Changed Web Search result rendering to use renderOutputBlock with answer, sources, related questions, and metadata sections
- Changed Find, Grep, and Ls tools to use renderFileList and renderTreeList for consistent file/item listing
- Changed Calculator tool result rendering to use renderTreeList for result item display
- Changed Notebook and TodoWrite tools to use new TUI rendering components for consistent output format
- Refactored render-utils to move tree-related utilities to TUI module (getTreeBranch, getTreeContinuePrefix)
- Changed import organization in sdk.ts for consistency
- Changed tool result rendering to merge call and result displays, showing tool arguments (command, pattern, query, path) in result headers for Bash, Calculator, Fetch, Find, Grep, Ls, LSP, Notebook, Read, SSH, TodoWrite, Web Search, and Write tools
- Changed Read tool title to display line range when offset or limit arguments are provided
- Changed worker instantiation to use direct URL import instead of pre-bundled worker files
- Changed
omp committo use agentic mode by default with tool-based git inspection - Changed agentic commit progress output to show real-time thinking previews and structured tool argument details
- Changed agentic commit progress output to display full multi-line assistant messages and render tool arguments with tree-style formatting for improved readability
- Changed agentic commit progress output to render assistant messages as formatted Markdown with proper word wrapping
- Changed output block border color to reflect state (error, success, warning) for improved visual feedback
- Changed LSP hover rendering to display documentation text before code blocks in both collapsed and expanded views
- Changed Write tool to show streaming preview of content being written with syntax highlighting
- Changed Read tool to display resolved path information when reading from URLs or symlinks
- Changed Calculator tool result display to show both expression and output (e.g.,
2+2 = 4) instead of just the result - Changed Python tool output to group status information under a labeled section for clearer organization
- Changed SSH tool output to apply consistent styling to non-ANSI output lines
- Changed Todo Write tool to respect expanded/collapsed state and use standard preview limits
- Changed Web Search related questions to respect expanded/collapsed state instead of always showing all items
- Changed empty and error state rendering across multiple tools (Find, Grep, Ls, Notebook, Calculator, Ask) to include consistent status headers
- Changed split commit to support hunk selectors (all, indices, or line ranges) instead of whole-file staging
- Changed
analyze_filetool toanalyze_filesfor batch parallel analysis of multiple files - Switched agentic commit from auto-generated changelogs to agent-proposed entries with validation and retry logic
- Commit agent now resolves a separate smaller model for commit generation instead of reusing the primary model
- Normalized code formatting and indentation across tool renderers and UI components
- Changed git-file-diff tool to prioritize files by type and respect token budget limits with intelligent truncation
- Changed git-overview tool to filter and report excluded lock files separately from staged files
- Changed analyze-file tool to include file type inference and enriched related files with line counts
- Changed propose-changelog tool to support optional deletion entries for removing existing changelog items
- Changed commit agent to accept pre-computed file observations and format them into session prompts
- Changed changelog skip condition in
applyChangelogProposalsto also check for empty deletions object - Changed
createCommitTools()to build tools array incrementally with conditionalanalyze_filesinclusion based onenableAnalyzeFilesflag - Changed system prompt guidance to clarify that pre-computed observations prevent redundant
analyze_filescalls - Removed map-reduce preprocessing phase from commit agent for faster iteration
- Changed commit agent to process full diff text directly instead of pre-computed file observations
- Changed commit agent initialization to load settingsManager, authStorage, modelRegistry, and stagedFiles in parallel
- Changed commit agent prompt to remove pre-computed observations guidance and encourage direct analyze_files usage
- Changed AuthStorage from constructor-based instantiation to async factory method (AuthStorage.create())
- Changed Python kernel resource management with gateway shutdown on session disposal
- Updated TypeScript configuration for better publish-time configuration handling with tsconfig.publish.json
- Updated TypeScript and Bun configuration for monorepo-wide build consistency and reduced boilerplate
- Removed WASM base64 encoding build script; imports now use Bun loader with
wasm?rawquery parameter - Unified TypeScript checking pipeline with tsgo-based configuration instead of per-package tsconfig.publish.json boilerplate
- Refactored scanDirectoryForSkills to use async/await with concurrent directory scanning via Promise.all
- Improved error logging in settings manager for config file access failures
- Migrated node module imports from named to namespace imports across all packages for consistency with project guidelines
- Improved filesystem error handling in extension loader with additional type guards (isEacces, hasFsCode) for permission and EPERM errors
- Changed model discovery to synchronous file operations for more immediate initialization
Fixed
- Fixed database busy errors during concurrent access by adding retry logic with exponential backoff when opening storage
- Find tool now rejects searches from root directory and enforces a 5-second timeout on fd operations
- Commit command now exits cleanly with exit code 0 on success
- Handle undefined code parameter in code cell renderer
- Fixed indentation formatting in split-commit tool function signature
- Fixed changelog application to process proposals containing only deletion entries without additions
- Fixed indentation formatting in Python tool output renderer
- Fixed Python kernel resource management with proper timing instrumentation for performance monitoring
- Fixed model discovery to re-check file existence after JSON to YAML migration
- Fixed branch change callbacks in footer component to properly update state after git resolution
- Added guard clause in plugin-settings to prevent null reference when settings list is undefined
- Fixed agent task discovery to support symlinks and improved error handling for file access failures
[8.0.0] - 2026-01-23
Added
- Added antigravity provider support for image generation with Google Cloud authentication
- Added support for google-antigravity API credentials in model registry
- Added antigravity-specific request handling with SSE streaming
- Added projectId parameter to antigravity credentials parsing
- Added antigravity provider to preferred image provider selection
- Added list-limit utility for consistent result limiting across tools
- Added output-utils module with tail buffer and artifact allocation helpers
- Added tool-result module for standardized tool result construction
- Added truncation summary options to OutputMetaBuilder for better output tracking
- Added artifact storage system for truncated tool outputs with artifact:// URL protocol
- Added structured output metadata system with fluent OutputMetaBuilder for consistent notices
- Added standardized tool error types (ToolError, MultiError, ToolAbortError) for better error handling
- Added internal URL routing system with protocol handlers:
agent://<id>- access agent output artifactsagent://<id>/<path>andagent://<id>?q=<query>- JSON extraction from agent outputsskill://<name>andskill://<name>/<path>- read skill files and relative pathsrule://<name>- read rule content- URL resolution includes filesystem path in output for bash/python interop
- Added fetch tool for URL content retrieval with enhanced processing capabilities
- Added
isolatedoption to task tool for git worktree execution with automatic patch generation and application - Added format-prompts script to standardize prompt file formatting
Changed
- Updated default line limit from 4000 to 3000 lines for output truncation
- Reordered truncation notice to show offset continuation before artifact reference
- Applied meta notice wrapper to all tools in createTools function
- Updated test expectations to reflect new 3000 line limit
- Removed output tool from schema validation test list
- Replaced inline output truncation notices with structured metadata system across all tools
- Updated bash, python, and ssh executors to track detailed output statistics (total lines/bytes vs output lines/bytes)
- Modified artifact storage to use pre-allocated paths instead of inline file writing
- Changed message format to use meta field instead of fullOutputPath for truncation information
- Updated interactive components to display truncation metadata from structured format
- Standardized tool result building with new ToolResultBuilder for consistent metadata handling
- Simplified Python gateway coordination by removing reference counting and client tracking
- Updated Python gateway to use global shared instance instead of per-process coordination
- Modified Python kernel initialization to set working directory and environment per kernel
- Updated interactive status display to show Python and venv paths instead of client count
- Changed system prompt to clarify CHECKPOINT step 0 timing
- Updated Python environment warming to use await instead of void for proper error handling
- Updated interactive mode shutdown to use postmortem.quit instead of process.exit
- Updated bash tool documentation to clarify specialized tool usage
- Updated task tool documentation to escape placeholder syntax in examples
- Updated Python environment warming to use await instead of void for proper error handling
- Updated interactive mode shutdown to use postmortem.quit instead of process.exit
- Updated bash tool documentation to clarify specialized tool usage
- Updated task tool documentation to escape placeholder syntax in examples
- Updated all tools to use structured metadata instead of inline notices for truncation, limits, and diagnostics
- Replaced manual error formatting with ToolError.render() and standardized error handling
- Enhanced bash and python executors to save full output as artifacts when truncated
- Improved abort signal handling across all tools with consistent ToolAbortError
- Renamed task parameter from
varstoargsthroughout task tool interface and updated template rendering to support built-in{{id}}and{{description}}placeholders - Simplified todo-write tool by removing active_form parameter, using single content field for task descriptions
- Updated system prompt structure with
<important>and<avoid>tags, clearer critical sections, and standardized whitespace handling - Renamed web_fetch tool to fetch and removed internal URL handling (use read tool instead)
- Standardized tool parameter names from camelCase to snake_case across edit, grep, python, and todo-write tools
- Unified timeout parameters across all tools with auto-conversion from milliseconds and reasonable clamping (1s-3600s for bash/ssh, 1s-600s for python/gemini-image)
- Simplified web-search tool by removing advanced parameters (
max_tokens,model,search_domain_filter,search_context_size,return_related_questions) and usingrecencyinstead ofsearch_recency_filter - Restructured tool documentation with standardized
<instruction>,<output>,<critical>, and<avoid>sections across all 18 tools - Updated find tool to always sort results by modification time
- Updated bash prompt to use
cwdparameter instead ofworkdir - Improved output truncation limits: bash to 50KB/2000 lines, python to 100KB
- Removed model parameter from task and gemini-image tools to use session/provider defaults
- Improved MCP tool name handling with explicit server and tool name properties
- Marked read tool as non-abortable to improve performance
- Converted dynamic imports to static imports in installer and exa tools
Removed
- Removed output tool (replaced by
agent://URLs via read tool) - Removed web_fetch tool (replaced by fetch tool)
Fixed
- Fixed Python kernel environment initialization for external and shared gateways
- Fixed gateway status reporting to include Python and virtual environment paths
- Fixed inconsistent error formatting across tools by standardizing on ToolError types
- Fixed timeout parameter handling to auto-convert milliseconds to seconds and clamp to reasonable ranges
- Fixed whitespace formatting in json-query.ts comment
- Fixed interactive shutdown to await postmortem cleanup so Python kernel gateways are terminated
- Fixed shared Python gateway reuse across working directories by initializing kernel cwd and env per kernel
- Fixed Python gateway coordination to use a single global gateway without ref counting
[7.0.0] - 2026-01-21
Added
- Added usage report deduplication to prevent duplicate account entries
- Added debug logging for usage fetch operations to aid diagnostics
- Added provider sorting in usage display by total usage amount
- Added
isolatedparameter to task tool for running each task in separate git worktrees - Added git worktree management for isolated task execution with patch generation
- Added patch application system that applies changes only when all patches are valid
- Added working directory information to environment info display
- Added
/usagecommand to display provider usage and limits - Added support for multiple usage providers beyond Codex
- Added usage report caching with configurable TTL
- Added visual usage bars and account aggregation in usage display
- Added
fetchUsageReports()method to agent session - Added
output()function to read task/agent outputs by ID with support for multiple formats and queries - Added session file support to Python executor for accessing task outputs
- Added support for jq-like queries when reading JSON outputs
- Added offset and limit parameters for reading specific line ranges from outputs
- Added "." and "c" shortcuts to continue agent without sending visible message
- Added debug logging for usage fetch results to aid /usage diagnostics
Changed
- Updated discoverSkills function to return object with skills property
- Enhanced usage report merging to combine limits and metadata from duplicate accounts
- Improved OAuth credential handling to preserve existing fields when updating
- Removed cd function from Python prelude to encourage using cwd parameter
- Updated task tool to generate and apply patches when running in isolated mode
- Enhanced task tool rendering to display isolated execution status and patch paths
- Updated system prompt structure and formatting for better readability
- Reorganized tool hierarchy and discipline sections
- Added parallel work guidance for task-based workflows
- Enhanced verification and integration methodology sections
- Updated skills and rules formatting for cleaner presentation
- Added stronger emphasis on completeness and quality standards
- Refactored usage tracking from Codex-specific to generic provider system
- Updated usage limit detection to work with multiple provider APIs
- Changed usage cache to use persistent storage instead of in-memory only
- Limited diagnostic messages to 50 items to prevent overwhelming output when processing files with many issues
- Changed
/dumpcommand to include complete agent context: system prompt, model config, available tools with schemas, and all message types (bash/python executions, custom messages, branch summaries, compaction summaries, file mentions) - Changed
/dumpformat to use YAML instead of JSON for tool schemas and arguments (more readable)
Fixed
- Fixed TypeScript error in bash executor by properly typing caught exception
- Fixed usage display ordering to show providers with lowest usage first
- Fixed task tool result rendering to show fallback text when no results are available
- Fixed external editor to work properly on Unix systems by correctly handling terminal I/O
- Fixed external editor to show warning message when it fails to open instead of silently failing
- Fixed find tool to properly handle no matches case without treating as error
- Fixed find tool to wait for fd exit so error messages no longer report exit null
- Fixed read tool to properly handle no matches case without treating as error
- Fixed orphaned Python kernel gateway processes not being killed on process exit
- Fixed /usage provider ordering to sort by aggregate usage (most used last)
- Fixed /usage account dedupe to collapse identical accounts using usage metadata
[6.9.69] - 2026-01-21
Added
- Added cell-by-cell status tracking with duration and exit code for Python execution
- Added syntax highlighting for Python code in execution display
- Added template system with {{placeholders}} for task tool context
- Added task variables support for filling context placeholders
- Added enhanced task progress display with variable values
- Added concurrent work handling guidance in system prompt
- Added extension system support for user Python execution events
- Added Python mode border color theming across all themes
- Added Python execution indicator to welcome screen help text
- Added
omp statscommand for viewing AI usage statistics dashboard - Added support for JSON output and console summary of usage statistics
- Added configurable port option for stats dashboard server
- Added multi-cell Python execution with sequential processing in persistent kernel
- Added cell titles for better Python code organization and debugging
- Added
$command prefix for user-initiated Python execution in shared kernel - Added
$$prefix variant for Python execution excluded from LLM context
Changed
- Updated Python execution to display cells in bordered blocks with status indicators
- Changed task tool to use template-based context instead of simple concatenation
- Enhanced Python execution component with proper syntax highlighting
- Improved patch applicator to preserve exact indentation when intended
- Updated task tool schema to require vars instead of task field
- Updated Python execution component to use pythonMode theming instead of bashMode
- Enhanced UI helpers to handle pending Python components properly
- Changed Python tool to use
cellsarray instead of singlecodeparameter - Renamed
workdirparameter tocwdin Bash and Python tools for consistency - Updated Python tool to display cell-by-cell output when multiple cells are provided
Fixed
- Fixed indentation preservation for exact matches and indentation-only patches
- Fixed Python execution status updates to show real-time cell progress
- Fixed indentation adjustment logic to handle edge cases with mixed indentation levels
- Fixed patch indentation normalization for fuzzy matches, tab/space diffs, and ambiguous context alignment
[6.9.0] - 2026-01-21
Removed
- Removed Git tool and all related functionality
- Removed voice control and TTS features
- Removed worktree management system
- Removed bundled wt custom command
- Removed voice-related settings and configuration options
- Removed @oh-my-pi/pi-git-tool dependency
[6.8.5] - 2026-01-21
Breaking Changes
- Changed timeout parameter from seconds to milliseconds in Python tool
- Updated PythonExecutorOptions interface to use timeoutMs instead of timeout
Changed
- Updated default timeout to 30000ms (30 seconds) for Python tool
- Improved streaming output handling and buffer management
[6.8.4] - 2026-01-21
Changed
- Updated output sink to properly handle large outputs
- Improved error message formatting in SSH executor
- Updated web fetch timeout bounds and conversion
Fixed
- Fixed output truncation handling in streaming output
- Fixed timeout handling in web fetch tool
- Fixed async stream dumping in executors
[6.8.3] - 2026-01-21
Changed
- Updated keybinding system to normalize key IDs to lowercase
- Changed label edit shortcut from 'l' to 'Shift+L' in tree selector
- Changed output file extension from
.out.mdto.mdfor artifacts
Removed
- Removed bundled worktree command from custom commands loader
Fixed
- Fixed keybinding case sensitivity issues by normalizing all key IDs
- Fixed task artifact path handling and simplified file structure
[6.8.2] - 2026-01-21
Fixed
- Improved error messages when multiple text occurrences are found by showing line previews and context
- Enhanced patch application to better handle duplicate content in context lines
- Added occurrence previews to help users disambiguate between multiple matches
- Fixed cache invalidation for streaming edits to prevent stale data
- Fixed file existence check for prompt templates directory
- Fixed bash output streaming to prevent premature stream closure
- Fixed LSP client request handling when signal is already aborted
- Fixed git apply operations with stdin input handling
Security
- Updated Anthropic authentication to handle manual code input securely
[6.8.1] - 2026-01-20
Fixed
- Fixed unhandled promise rejection when tool execution fails by adding missing
.catch()to floating.finally()chain increateAbortablePromise
[6.8.0] - 2026-01-20
Added
- Added streaming abort setting to control edit tool behavior when patch preview fails
Changed
- Replaced internal logger with @oh-my-pi/pi-utils logger across all modules
- Updated process spawning to use cspawn and ptree utilities from pi-utils
- Migrated file operations to use async fs/promises and Bun file APIs
- Refactored promise handling to use Promise.withResolvers and utility functions
- Updated timeout and abort handling to use standardized utility functions
- Refactored authentication login method to use OAuthController interface instead of individual callbacks
Fixed
- Fixed Python package installation to handle async operations properly
- Fixed streaming output truncation to use consistent column limits
- Fixed shell command execution to properly handle process cleanup and timeouts
- Fixed SSH connection management to properly await async operations
- Fixed voice supervisor process cleanup to use proper async handling
- Added automatic regex pattern validation in grep tool to handle invalid patterns by switching to literal mode
Security
- Updated temporary file cleanup to use secure async removal methods
[6.7.67] - 2026-01-19
Added
- Added normative rewrite setting to control tool call argument normalization in session history
- Added read line numbers setting to prepend line numbers to read tool output by default
- Added streaming preview for edit and write tools with spinner animation
- Added automatic anchor derivation for normative patches when anchors not specified
Changed
- Enhanced edit and write tool renderers to show streaming content preview
- Updated read tool to respect default line numbers setting
- Improved normative patch anchor handling to support undefined anchors
[6.7.0] - 2026-01-19
Added
- Normative patch generation to canonicalize edit tool output with tool call argument rewriting for session history
- Patch matching fallback variants: trimmed context, collapsed duplicates, single-line reduction, comment-prefix normalization
- Extended anchor syntax: ellipsis placeholders,
top of file/start of file,@@ line N, nested@@anchors, space-separated hierarchical contexts - Relaxed fuzzy threshold fallback and unique substring acceptance for context matching
- Added
--no-titleflag to disable automatic session title generation - Environment variables for edit tool configuration (OMP_EDIT_VARIANT, OMP_EDIT_FUZZY, OMP_EDIT_FUZZY_THRESHOLD)
- Configurable fuzzy matching threshold setting (0.85 lenient to 0.98 strict)
- Apply-patch mode for edit tool (
edit.patchModesetting) with create, update, delete, and rename operations - Added MCP tool caching for faster startup with cached tool definitions
Changed
- Patch applicator now supports normalized input, implicit context lines, and improved indentation adjustment
- Patch operation schema uses 'op' instead of 'operation' and 'rename' instead of 'moveTo'
- Fuzzy matching tries comment-prefix normalized matches before unicode normalization
- Updated patch prompts with clearer anchor selection rules and verbatim context requirements
- Changed default behavior of read tool to omit line numbers by default
- Changed default edit tool mode to use apply-patch format instead of oldText/newText
- Converted tool implementations from factory functions to class-based architecture
- Refactored edit tool with modular patch architecture (moved from
edit/topatch/module) - Enhanced patch parsing: unified diff format, Codex-style patches, nested anchors, multi-file markers
- Improved fuzzy matching with multiple match tracking, ambiguity detection, and out-of-order hunk processing
- Better diff rendering: smarter truncation, optional line numbers, trailing newline preservation
- Improved error messages with hierarchical context display using
>separator - Centralized output sanitization in streaming-output module
- Enhanced MCP startup with deferred tool loading and cached fallback
Fixed
- Patch application handles repeated context blocks, preserves original indentation on fuzzy match
- Ambiguous context matching resolves duplicates using adjacent @@ anchor positioning
- Patch parser handles bare *** terminators, model hallucination markers, line hint ranges
- Function context matching handles signatures with and without empty parentheses
- Fixed session title generation to respect OMP_NO_TITLE environment variable
- Fixed Python module discovery to use import.meta.dir for ES module compatibility
- Fixed LSP writethrough batching to flush when delete operations complete a batch
- Fixed line number validation, BOM detection, and trailing newline preservation in patches
- Fixed hierarchical context matching and space-separated anchor parsing
- Fixed fuzzy matching to avoid infinite loops when
allowFuzzyis disabled - Fixed tool completion logic to only mark tools as complete when streaming is not aborted or in error state
- Fixed MCP tool path formatting to correctly display provider information
[6.2.0] - 2026-01-19
Changed
- Improved LSP batching to coalesce formatting and diagnostics for parallel edits
- Updated edit and write tools to support batched LSP operations
Fixed
- Coalesced LSP formatting/diagnostics for parallel edits so only the final write triggers LSP across touched files
[6.1.0] - 2026-01-19
Added
- Added lspmux integration for LSP server multiplexing to reduce startup time and memory usage
- Added LSP tool proxy support for subagent workers
- Updated LSP status command to show lspmux connection state
- Added maxdepth and mindepth parameters to find function for depth-controlled file search
- Added counter function to count occurrences and sort by frequency
- Added basenames function to extract base names from paths
Changed
- Simplified rust-analyzer default configuration by removing custom initOptions and settings
[6.0.0] - 2026-01-19
Added
- Added Cursor and OpenAI Codex OAuth providers
- Added Windows installer bash shell auto-configuration
- Added dedicated TTSR settings tab (separated from Voice/TTS)
Fixed
- Fixed TTSR abbreviation expansion from TTSR to Time Traveling Stream Rules
[5.8.0] - 2026-01-19
Changed
- Updated WASM loading to use streaming for development environments with base64 fallback
- Added scripts directory to published package files
[5.7.68] - 2026-01-18
Changed
- Updated WASM loading to use base64-encoded WASM for better compatibility with compiled binaries
Fixed
- Fixed WASM loading issues in compiled binary builds
[5.7.67] - 2026-01-18
Changed
- Replaced external photon-node dependency with vendored WebAssembly implementation
- Updated image processing to use local photon library for better performance
[5.6.70] - 2026-01-18
Added
- Added support for loading Python prelude extension modules from user and project directories
- Added automatic discovery of Python modules from
.omp/modulesand.pi/modulesdirectories - Added prioritized module loading with project-level modules overriding user-level modules
[5.6.7] - 2026-01-18
Added
- Added Python shared gateway setting to enable resource-efficient kernel reuse across sessions
- Added Python tool cancellation support with proper timeout and cleanup handling
- Added enhanced Python prelude helpers including file operations, text processing, and Git utilities
- Added Python tool documentation rendering with categorized helper functions
- Added session-scoped Python kernel isolation with workdir-aware session IDs
- Added structured status events for Python prelude functions with TUI rendering
- Added status event display system with operation icons and formatted descriptions
- Added support for rich output using IPython.display.display() in Python tool
- Added setup subcommand to install dependencies for optional features
- Added Python setup component to install Jupyter kernel dependencies
- Added setup command help with component and option documentation
- Added Python tool dependency check in help output
- Added file locking mechanism for shared Python gateway to prevent race conditions
- Added Python gateway status monitoring with URL, PID, client count, and uptime information
- Added comprehensive Git helpers to Python prelude including status, diff, log, show, branch, and file operations
- Added line-based operations to Python prelude including line extraction, deletion, insertion, and pattern matching
- Added automatic categorization system for Python prelude functions with discoverable documentation
- Added enhanced
/statuscommand display showing Python gateway, LSP servers, and MCP server connections - Added shared Python gateway coordinator for resource-efficient kernel management across sessions
- Added Python shared gateway setting with session-scoped kernel reuse and fallback behavior
- Added automatic idle shutdown for shared Python gateway after 30 seconds of inactivity
- Added environment filtering for shared Python gateway to exclude sensitive API keys
- Added virtual environment detection and automatic PATH configuration for Python gateway
- Added IPython-backed Python tool with streaming output, image/JSON rendering, and Jupyter kernel gateway integration
- Added Python prelude with 30+ shell-like utility functions for file operations
- Added Python tool exposure settings with session-scoped kernel reuse and fallback behavior
- Added streaming output system with automatic spill-to-disk for large outputs
- Added extension input interception with source metadata and command argument completion
- Added extension command context
compact()helper plus context usage accessors - Added ExtensionAPI
setLabel()for extension and entry labels - Added startup quiet setting to suppress welcome screen and startup messages
- Added support for auto-discovering APPEND_SYSTEM.md files
- Added support for piped input in non-interactive mode (auto-print mode)
- Added global session listing across all project directories with enhanced search metadata
- Added session fork prompt when resolving sessions from other projects
- Added key hint formatting utilities plus public exports for getShellConfig/getAgentDir/VERSION
- Added bash tool timeout display in tool output
- Added fuzzy text normalization for improved edit diff matching
- Added $@ argument slicing syntax in prompt templates
- Added configurable keybindings for expand tools and dequeue actions
- Added process title update on CLI startup
Changed
- Updated Python tool description to display categorized helper functions with improved formatting
- Enhanced Python kernel startup to use shared gateway by default for better resource utilization
- Improved Python prelude functions to emit structured status events instead of text output
- Updated agent prompts to use bash tool instead of exec for git operations
- Changed default Python tool mode from ipy-only to both to enable shell execution
- Enhanced Python gateway coordination with Windows environment support and stale process cleanup
- Updated Python prelude functions to emit structured status events instead of text output
- Enhanced Python tool renderer to display status events alongside output
- Improved Python tool output formatting with status event integration
- Improved shared Python gateway coordination with environment validation and stale process cleanup
- Updated Python prelude to rename
bash()function tosh()for consistency - Changed default Python tool mode from "ipy-only" to "both" to enable both IPython and shell execution
- Enhanced Python gateway metadata tracking to include Python path and virtual environment information
- Improved Python kernel startup to use shared gateway by default for better resource utilization
- Updated Python tool to support proxy execution mode for worker processes
- Enhanced Python kernel availability checking with faster validation
- Optimized Python environment warming to avoid blocking during tool initialization
- Reorganized settings interface into behavior, tools, display, voice, status, lsp, and exa tabs
- Migrated environment variables from PI_ to OMP_ prefix with automatic migration
- Updated model selector to use TabBar component for provider navigation
- Changed role badges to inverted style with colored backgrounds
- Added support for /models command alias in addition to /model
- Improved error retry detection to include fetch failures
- Enhanced session selector search and overflow handling
- Updated skill command execution to include skill path metadata
- Surfaced loaded prompt templates during initialization
- Updated compaction summarization to use serialized prompt text
- Cleaned up Python prelude
sh()andrun()output to only show stdout/stderr without noisy metadata
Fixed
- Fixed Python kernel cancellation handling and WebSocket cleanup for in-flight executions
- Fixed Python tool session scoping to include workdir and honor sharedGateway settings
- Fixed gist sharing output draining to avoid truncated URLs
- Fixed streaming output byte accounting and UTF-8 decoder flushing
- Fixed Python prelude integration tests to detect virtual environments and cover helper exports
- Fixed Python kernel cancellation/timeout handling and WebSocket close cleanup for in-flight executions
- Fixed Python output byte accounting and UTF-8 decoder flushing in streaming output
- Fixed shared Python gateway coordination (Windows env allowlist, lock staleness, refcount recovery)
- Fixed Python tool session scoping to include workdir and honor sharedGateway settings
- Fixed subagent Python proxy session isolation and cancellation/timeout propagation
- Fixed print-mode cleanup to dispose Python sessions before exit
- Fixed gist share output draining to avoid truncated URLs
- Fixed explore agent tool list to use bash for git operations
- Fixed Python prelude integration tests to detect venv-only Python and cover helper exports
Security
- Enhanced Python gateway environment filtering to exclude sensitive API keys and Windows system paths
[5.5.0] - 2026-01-18
Changed
- Updated task execution guidelines to improve prompt framing and parallelization instructions
[5.4.2] - 2026-01-16
Changed
- Updated model resolution to accept pre-serialized settings for better performance
- Improved system prompt guidance for position-addressed vs content-addressed file edits
- Enhanced edit tool documentation with clear use cases for bash alternatives
[5.3.0] - 2026-01-15
Changed
- Expanded bash tool guidance to explicitly list appropriate use cases including file operations, build commands, and process management
[5.2.1] - 2026-01-14
Fixed
- Fixed stale diagnostic results by tracking diagnostic versions before file sync operations
- Fixed race condition where LSP diagnostics could return outdated results after file modifications
[5.2.0] - 2026-01-14
Added
- Added
withLinesparameter to read tool for optional line number output (default: true, cat -n format)
Changed
- Changed find/grep/ls tool output to render inline without background box for cleaner visual flow
Fixed
- Fixed task tool abort to return partial results instead of failing (completed tasks preserved, cancelled tasks shown as skipped)
- Fixed TUI crash when bash output metadata lines exceed terminal width on narrow terminals
- Fixed find tool not matching
**/filenamepatterns (was incorrectly using--full-pathfor glob depth wildcards)
[5.1.1] - 2026-01-14
Fixed
- Fixed clipboard image paste getting stuck on Wayland when no image is present (was falling back to X11 and timing out)
[5.1.0] - 2026-01-14
Changed
- Updated light theme colors for WCAG AA compliance (4.5:1 contrast against white background)
- Changed dequeue hint text from "restore" to "edit all queued messages"
Fixed
- Fixed session selector staying open when current folder has no sessions (shows hint to press Tab)
- Fixed print mode JSON output to emit session header at start
- Fixed "database is locked" SQLite errors when running subagents by serializing settings to workers instead of opening the database
- Fixed
/newcommand to create a new session file (previously reused the same file when--sessionwas specified) - Fixed session selector page up/down navigation
[5.0.1] - 2026-01-12
Changed
- Replaced wasm-vips with Photon for more stable WASM image processing
- Added graceful fallback to original images when image resizing fails
- Added error handling for image conversion failures in interactive mode to prevent crashes
- Replace wasm-vips with Photon for more stable WASM image processing (fixes worker thread crashes)
[5.0.0] - 2026-01-12
Added
- Implemented
xhighthinking level for Anthropic models with increased reasoning limits
[4.8.3] - 2026-01-12
Changed
- Replace sharp with wasm-vips for cross-platform image processing without native dependencies
[4.8.1] - 2026-01-12
Fixed
- Prevent bun from statically resolving sharp import to fix runtime errors on arm64
[4.8.0] - 2026-01-12
Fixed
- Move
sharpto optional dependencies with all platform binaries to fix arm64 runtime errors
[4.7.0] - 2026-01-12
Added
- Add
omp configsubcommand for managing settings (list,get,set,reset,path) - Add
todoCompletionsetting to warn agent when it stops with incomplete todos (up to 3 reminders) - Add multi-part questions support to
asktool viaquestionsarray parameter
Changed
- Updated multi-select cursor behavior in
asktool to stay on the toggled option instead of jumping to top - Single-file reads now render inline (e.g.,
Read AGENTS.md:23) instead of tree structure
Fixed
- Subagent model resolution now respects explicit provider prefix (e.g.,
zai/glm-4.7no longer matchescerebras/zai-glm-4.7) - Auto-compaction now skips to next model candidate when retry delay exceeds 30 seconds
[4.6.0] - 2026-01-12
Added
- Add
/skill:nameslash commands for quick skill access (toggle viaskills.enableSkillCommandssetting) - Add
cwdto SessionInfo for session list display - Add custom summarization instructions option in tree selector
- Add Alt+Up (dequeue) to restore all queued messages at once
- Add
shutdownRequestedandcheckShutdownRequested()for extension-initiated shutdown
Fixed
- Component
invalidate()now properly rebuilds content on theme changes - Force full re-render after returning from external editor
[4.4.8] - 2026-01-12
Changed
- Changed review finding priority format from numeric (0-3) to string labels (P0-P3) for clearer severity indication
- Replaced Type.Union with Type.Literal patterns with StringEnum helper across tool schemas for cleaner enum definitions
[4.4.5] - 2026-01-11
Changed
- Removed
format: "date-time"from timestamp type conversion in JTD to JSON Schema transformation - Reorganized system prompt to display context, environment, and tools sections before discipline guidelines
- Updated system prompt to show file paths more clearly in output
- Improved YAML frontmatter parsing with better error messages including source file information
Fixed
- Fixed frontmatter parsing to properly report source location when YAML parsing fails
[4.4.4] - 2026-01-11
Added
- Added
todo_writetool for creating and managing structured task lists during coding sessions - Added persistent todo panel above the editor that displays task progress
- Added
Ctrl+Tkeybinding to toggle todo list expansion - Added grouped display for consecutive Read tool calls, showing multiple file reads in a compact tree view
- Added
todo_writetool and persistent todo panel above the editor
Changed
- Changed
Ctrl+Enterto insert a newline when not streaming (previouslyAlt+Enter) - Changed
Ctrl+Tfrom toggling thinking block visibility to toggling todo list expansion - Changed system prompt to use more direct, field-oriented language with emphasis on verification and assumptions
- Changed temporary model selector keybinding from Ctrl+Y to Alt+P
- Changed expand hint text from "Ctrl+O to expand" to "Ctrl+O for more"
- Changed Read tool result display to hide content by default, showing only file path and status
- Changed
Ctrl+Tto toggle todo panel expansion
Removed
- Removed
yamlpackage dependency in favor of Bun's built-in YAML parser
Fixed
- Fixed Alt+Enter to insert a newline when not streaming, instead of submitting the message
- Fixed Alt+Enter inserting a new line when not streaming instead of submitting a message
- Fixed Cursor provider to avoid advertising the Edit tool, relying on full-file Write operations instead
- Fixed prompt template loading to strip leading HTML comment metadata blocks
[4.3.2] - 2026-01-11
Changed
- Increased default bash output preview from 5 to 10 lines when collapsed
- Updated expanded bash output view to show full untruncated output when available
[4.3.1] - 2026-01-11
Changed
- Expanded system prompt with defensive reasoning guidance and assumption checks
- Allowed agent frontmatter to override subagent thinking level, clamped to model capabilities
Fixed
- Ensured reviewer agents use structured output schemas and include reported findings in task outputs
[4.3.0] - 2026-01-11
Added
- Added Cursor provider support with browser-based OAuth authentication
- Added default model configuration for Cursor provider (claude-sonnet-4-5)
- Added execution bridge for Cursor tool calls including read, ls, grep, write, delete, shell, diagnostics, and MCP operations
Fixed
- Improved fuzzy matching accuracy for edit operations when file and target have inconsistent indentation patterns
[4.2.3] - 2026-01-11
Changed
- Changed default for
hiddenoption in find tool fromfalsetotrue, now including hidden files by default
Fixed
- Fixed serialized auth storage initialization so OAuth refreshes in subagents don't crash
[4.2.2] - 2026-01-11
Added
- Added persistent cache storage for Codex usage data that survives application restarts
- Added
--no-lspto disable LSP tools, formatting, diagnostics, and warmup for a session
Changed
- Changed
SettingsManager.create()to be async, requiringawaitwhen creating settings managers - Changed
loadSettings()to be async, requiringawaitwhen loading settings - Changed
discoverSkills()to be async, requiringawaitwhen discovering skills - Changed
loadSlashCommands()to be async, requiringawaitwhen loading slash commands - Changed
buildSystemPrompt()to be async, requiringawaitwhen building system prompts - Changed
loadSkills()to be async, requiringawaitwhen loading skills - Changed
loadProjectContextFiles()to be async, requiringawaitwhen loading context files - Changed
getShellConfig()to be async, requiringawaitwhen getting shell configuration - Changed capability provider
load()methods to be async-only, removing synchronousloadSyncAPI - Updated
planagent with enhanced structured planning process, parallel exploration viaexploreagent spawning, and improved output format with examples - Removed
planneragent command template, consolidating planning functionality into theplanagent
[4.2.1] - 2026-01-11
Added
- Added automatic discovery and listing of AGENTS.md files in the system prompt, providing agents with an authoritative list of project-specific instruction files without runtime searching
- Added
plannerbuilt-in agent for comprehensive implementation planning with slow model
Changed
- Refactored skill discovery to use unified
loadSkillsFromDirhelper across all providers, reducing code duplication - Updated skill discovery to scan only
skills/*/SKILL.mdentries instead of recursive walks in Codex provider - Added guidance to Task tool documentation to isolate file scopes when assigning tasks to prevent agent conflicts
- Updated Task tool documentation to emphasize that subagents have no access to conversation history and require all relevant context to be explicitly passed
- Revised task agent prompt to clarify that subagents have full tool access and can make file edits, run commands, and create files
- OpenAI Codex: updated to use bundled system prompt from upstream
- Changed
completetool to makedataparameter optional when aborting, while still requiring it for successful completions - Skills discovery now scans only
skills/*/SKILL.mdentries instead of recursive walks
Removed
- Removed
architect-plan,implement, andimplement-with-criticbuilt-in agent commands
Fixed
- Fixed editor border rendering glitch after canceling slash command autocomplete
- Fixed login/logout credential path message to reference agent.db
[4.2.0] - 2026-01-10
Added
- Added
/dumpslash command to copy the full session transcript to the clipboard - Added automatic Nerd Fonts detection for terminals like iTerm, WezTerm, Kitty, Ghostty, and Alacritty to set appropriate symbol preset
- Added
NERD_FONTSenvironment variable override (1or0) to manually control Nerd Fonts symbol preset - Added Handlebars templating engine for prompt template rendering with
{{arg}}helper for positional arguments - Added support for custom share scripts at ~/.omp/agent/share.ts to replace default GitHub Gist sharing
Changed
- Changed rules system to use
readtool for loading rule content instead of dedicatedrulebooktool - Separated
/exportand/dumpcommands—/exportnow only exports to HTML file, while/dumpcopies session transcript to clipboard - Updated
/exportcommand to no longer accept--copyflag (use/dumpinstead) - Changed prompt template rendering to use Handlebars instead of simple string replacement
- Updated prompt layout optimization to normalize indentation and collapse excessive blank lines
- Changed auth migration to merge credentials per-provider instead of skipping when any credentials exist in database
- Migrated settings and auth credential storage from JSON files to SQLite database (agent.db)
- Updated credential migration message to reference agent.db instead of auth.json
- Renamed Glob tool references to Find tool throughout prompts and documentation
- Updated project context formatting to use XML-style tags for clearer structure
- Refined bash tool guidance to prefer dedicated tools (read/grep/find/ls) over bash for file operations
- Updated system prompt with clearer tone guidelines emphasizing directness and conciseness
- Revised workflow instructions to require explicit planning for non-trivial tasks
- Enhanced verification guidance to prefer external feedback loops like tests and linters
- Added explicit alignment and prohibited behavior sections to improve response quality
Removed
- Removed
rulebooktool - rules are now loaded via thereadtool instead of a dedicated tool
Fixed
- Fixed message submission lag caused by synchronous history database writes by deferring DB operations with setImmediate
Security
- Hardened file permissions on agent database directory (700) and database file (600) to restrict access
[4.1.0] - 2026-01-10
Added
- Added persistent prompt history with SQLite-backed storage and Ctrl+R search
Fixed
- Fixed credential blocking logic to correctly check for remaining available credentials instead of always returning true
[4.0.1] - 2026-01-10
Added
- Added usage limit error detection to enable automatic credential switching when Codex accounts hit rate limits
- Added Codex usage API integration to proactively check account limits before credential selection
- Added credential backoff tracking to temporarily skip rate-limited accounts during selection
- Multi-credential usage-aware selection for OpenAI Codex OAuth accounts with automatic fallback when rate limits are reached
- Consistent session-to-credential hashing (FNV-1a) for stable credential assignment across sessions
- Codex usage API integration to detect and cache rate limit status per account
- Automatic mid-session credential switching when usage limits are hit
Changed
- Changed credential selection to use deterministic FNV-1a hashing for consistent session-to-credential mapping
- Changed OAuth credential resolution to try credentials in priority order, skipping blocked ones
[4.0.0] - 2026-01-10
Added
- Exported
InteractiveModeOptionstype for programmatic SDK usage - Exported additional UI components for extensions:
ArminComponent,AssistantMessageComponent,BashExecutionComponent,BranchSummaryMessageComponent,CompactionSummaryMessageComponent,CustomEditor,CustomMessageComponent,FooterComponent,ExtensionEditorComponent,ExtensionInputComponent,ExtensionSelectorComponent,LoginDialogComponent,ModelSelectorComponent,OAuthSelectorComponent,SessionSelectorComponent,SettingsSelectorComponent,ShowImagesSelectorComponent,ThemeSelectorComponent,ThinkingSelectorComponent,ToolExecutionComponent,TreeSelectorComponent,UserMessageComponent,UserMessageSelectorComponent - Exported
renderDiff,truncateToVisualLines, and related types for extension use setFooter()andsetHeader()methods onExtensionUIContextfor custom footer/header componentssetEditorComponent()method onExtensionUIContextfor custom editor componentssupportsUsageInStreamingmodel config option to controlstream_options: { include_usage: true }behavior- Terminal setup documentation for Kitty keyboard protocol configuration (Ghostty, wezterm, Windows Terminal)
- Documentation for paid Cloud Code Assist subscriptions via
GOOGLE_CLOUD_PROJECTenv var - Environment variables reference section in README
--no-toolsflag to disable all built-in tools, enabling extension-only setups--no-extensionsflag to disable extension discovery while still allowing explicit-epathsblockImagessetting to prevent images from being sent to LLM providersthinkingBudgetssetting to customize token budgets per thinking levelPI_SKIP_VERSION_CHECKenvironment variable to disable new version notifications at startup- Anthropic OAuth support via
/loginto authenticate with Claude Pro/Max subscription - OpenCode Zen provider support via
OPENCODE_API_KEYenv var andopencode/<model-id>syntax - Session picker (
pi -r) and--sessionflag support searching/resuming by session ID (UUID prefix) - Session ID forwarding to LLM providers for session-based caching (used by OpenAI Codex for prompt caching)
dequeuekeybinding (Alt+Up) to restore queued steering/follow-up messages back into the editor- Pluggable operations for built-in tools enabling remote execution via SSH or other transports (
ReadOperations,WriteOperations,EditOperations,BashOperations,LsOperations,GrepOperations,FindOperations) /model <search>pre-filters the model selector or auto-selects on exact match; useprovider/modelsyntax to disambiguate- Managed binaries directory (
~/.omp/bin/) for fd and rg tools FooterDataProviderfor custom footers withgetGitBranch(),getExtensionStatuses(), andonBranchChange()ctx.ui.custom()accepts{ overlay: true }option for floating modal componentsctx.ui.getAllThemes(),ctx.ui.getTheme(name),ctx.ui.setTheme(name | Theme)for theme managementsetActiveTools()for dynamic tool managementsetModel(),getThinkingLevel(),setThinkingLevel()methods for runtime model and thinking level changesctx.shutdown()for requesting graceful shutdownpi.sendUserMessage()for sending user messages from extensions- Extension UI dialogs (
select,confirm,input) supporttimeoutoption with live countdown display - Extension UI dialogs accept optional
AbortSignalto programmatically dismiss dialogs - Async extension factories for dynamic imports and lazy-loaded dependencies
user_bashevent for intercepting user!/!!commands- Built-in renderers used automatically for tool overrides without custom
renderCall/renderResult InteractiveMode,runPrintMode(),runRpcMode()exported for building custom run modes- Copy link button on messages for deep linking to specific entries
- Codex injection info display showing system prompt modifications
- URL parameter support for
leafIdandtargetIddeep linking - Wayland clipboard support for
/copycommand using wl-copy with xclip/xsel fallback
Changed
- Bash tool output truncation now recalculates on terminal resize instead of using cached width
- Web search tool headers updated to match Claude Code client format for better compatibility
discoverSkills()return type documented as{ skills: Skill[], warnings: SkillWarning[] }in SDK docs- Default model for OpenCode provider changed from
claude-sonnet-4-5toclaude-opus-4-5 - Terminal color mode detection defaults to truecolor for modern terminals instead of 256color
- System prompt restructured with XML tags and clearer instructions format
before_agent_startevent receivessystemPromptin the event object and returnssystemPrompt(full replacement) instead ofsystemPromptAppenddiscoverSkills()returns{ skills: Skill[], warnings: SkillWarning[] }instead ofSkill[]ctx.ui.custom()factory signature changed from(tui, theme, done)to(tui, theme, keybindings, done)ExtensionRunner.initialize()signature changed from options object to positional params(actions, contextActions, commandContextActions?, uiContext?)
Fixed
- Wayland clipboard copy (
wl-copy) no longer blocks when the process doesn't exit promptly - Empty
--toolsflag now correctly enables all built-in tools instead of disabling them - Bash tool handles spawn errors gracefully instead of crashing the agent
- Components properly rebuild their content on theme change via
invalidate()override setTheme()triggers a full rerender so previously rendered components update with new theme colors- Session ID updates correctly when branching sessions
- External edits to
settings.jsonwhile pi is running are preserved when pi saves settings - Default thinking level from settings applies correctly when
enabledModelsis configured - LM Studio compatibility for OpenAI Responses tool strict mapping
- Symlinked directories in
prompts/folders are followed when loading prompt templates - String
systemPromptincreateAgentSession()works as a full replacement instead of having context files and skills appended - Update notification for bun binary installs shows release download URL instead of npm command
- ESC key works during "Working..." state after auto-retry
- Abort messages show correct retry attempt count
- Antigravity provider returning 429 errors despite available quota
- Malformed thinking text in Gemini/Antigravity responses where thinking content appeared as regular text
--no-skillsflag correctly prevents skills from loading in interactive mode- Overflow-based compaction skips if error came from a different model or was already handled
- OpenAI Codex context window reduced from 400k to 272k tokens to match Codex CLI defaults
- Context overflow detection recognizes
context_length_exceedederrors - Key presses no longer dropped when input is batched over SSH
- Clipboard image support works on Alpine Linux and other musl-based distros
- Queued steering/follow-up messages no longer wipe unsent editor input
- OAuth token refresh failure no longer crashes app at startup
- Status bar shows correct git branch when running in a git worktree
- Ctrl+V clipboard image paste works on Wayland sessions
- Extension directories in
settings.jsonrespectpackage.jsonmanifests
[3.37.0] - 2026-01-10
Changed
- Improved bash command display to show relative paths for working directories within the current directory, and hide redundant
cdprefix when working directory matches current directory
[3.36.0] - 2026-01-10
Added
- Added
calctool for basic mathematical calculations with support for arithmetic operators, parentheses, and hex/binary/octal literals - Added support for multiple API credentials per provider with round-robin distribution across sessions
- Added file locking for auth.json to prevent concurrent write corruption
- Added clickable OAuth login URL display in terminal
- Added
workdirparameter to bash tool to execute commands in a specific directory without requiringcdcommands
Changed
- Updated bash tool rendering to display working directory context when
workdirparameter is used
Fixed
- Fixed completion notification to only send when interactive mode is in foreground
- Improved completion notification message to include session title when available
[3.35.0] - 2026-01-09
Added
- Added retry logic with exponential backoff for auto-compaction failures
- Added fallback to alternative models when auto-compaction fails with the primary model
- Added support for
pi/<role>model aliases in task tool (e.g.,pi/slow,pi/default) - Added visual cycle indicator when switching between role models showing available roles
- Added automatic model inheritance for subtasks when parent uses default model
- Added
--separator in grep tool to prevent pattern interpretation as flags
Changed
- Changed role model cycling to remember last selected role instead of matching current model
- Changed edit tool to merge call and result displays into single block
- Changed model override behavior to persist in settings when explicitly set via CLI
Fixed
- Fixed retry-after parsing from error messages supporting multiple header formats (retry-after, retry-after-ms, x-ratelimit-reset)
- Fixed image attachments being dropped when steering/follow-up messages are queued during streaming
- Fixed image auto-resize not applying to clipboard images before sending
- Fixed clipboard image attachments being dropped when steering/follow-up messages are queued while streaming
- Fixed clipboard image attachments ignoring the auto-resize setting before sending
[3.34.0] - 2026-01-09
Added
- Added caching for system environment detection to improve startup performance
- Added disk usage information to automatic environment detection in system prompt
- Added
compatoption for SSH hosts to wrap commands in a POSIX shell on Windows systems - Added automatic working directory handling for PowerShell and cmd.exe on Windows SSH hosts
- Added automatic environment detection to system prompt including OS, distro, kernel, CPU, GPU, shell, terminal, desktop environment, and window manager information
- Added SSH tool with project ssh.json/.ssh.json discovery, persistent connections, and optional sshfs mounts
- Added SSH host OS/shell detection with compat mode and persistent host info cache
Changed
- Changed GPU detection on Linux to prioritize discrete GPUs (NVIDIA, AMD) over integrated graphics and skip server management adapters
- Changed SSH host info cache to use versioned format for automatic refresh on schema changes
- Changed SSH compat shell detection to actively probe for bash/sh availability on Windows hosts
- Changed SSH tool description to show detected shell type and available commands per host
[3.33.0] - 2026-01-08
Added
- Added
envsupport insettings.jsonfor automatically setting environment variables on startup - Added environment variable management methods to SettingsManager (get/set/clear)
Fixed
- Fixed bash output previews to recompute on resize, preventing TUI line width overflow crashes
- Fixed session title generation to retry alternate smol models when the primary model errors or is rate-limited
- Fixed file mentions to resolve extensionless paths and directories, using read tool truncation limits for injected content
- Fixed interactive UI to show auto-read file mention indicators
- Fixed task tool tree rendering to use consistent tree connectors for progress, findings, and results
- Fixed last-branch tree connector symbol in the TUI
- Fixed output tool previews to use compact JSON when outputs are formatted with leading braces
[3.32.0] - 2026-01-08
Added
- Added progress indicator when starting LSP servers at session startup
- Added bundled
/initslash command available by default
Changed
- Changed LSP server warmup to use a 5-second timeout, falling back to lazy initialization for slow servers
Fixed
- Fixed Task tool subagent model selection to inherit explicit CLI
--modeloverrides
[3.31.0] - 2026-01-08
Added
- Added temporary model selection:
Ctrl+Yopens model selector for session-only model switching (not persisted to settings) - Added
setModelTemporary()method to AgentSession for ephemeral model changes - Added empty Enter to flush queued messages: pressing Enter with empty editor while streaming aborts current stream
- Added auto-chdir to temp directories when starting in home unless
--allow-homeis set - Added upfront diff parsing and filtering for code review command to exclude lock files, generated code, and binary assets
Fixed
- Fixed auto-chdir to only use existing directories and fall back to
tmpdir() - Added automatic reviewer agent count recommendation based on diff weight and file count
- Added file grouping guidance for parallel review distribution across multiple agents
- Added diff preview mode for large changesets that exceed size thresholds
- Added in-memory session storage implementation for testing and ephemeral sessions
- Added
createToolUIKithelper to consolidate common UI formatting utilities across tool renderers - Added configurable bash interceptor rules via
bashInterceptor.patternssetting for custom command blocking - Added
bashInterceptor.simpleLssetting to control interception of bare ls commands - Added LSP server configuration via external JSON defaults file for easier customization
- Added abort signal propagation to web scrapers for improved cancellation handling
- Added
diagnosticsVersiontracking to LSP client for more reliable diagnostic polling - Added 80+ specialized web scrapers for structured content extraction from popular sites including GitHub, GitLab, npm, PyPI, crates.io, Wikipedia, YouTube, Stack Overflow, Hacker News, Reddit, arXiv, PubMed, and many more
- Added site-specific API integrations for package registries (npm, PyPI, crates.io, Hex, Hackage, NuGet, Maven, RubyGems, Packagist, pub.dev, Go packages)
- Added scrapers for social platforms (Mastodon, Bluesky, Lemmy, Lobsters, Dev.to, Discourse)
- Added scrapers for academic sources (arXiv, bioRxiv, PubMed, Semantic Scholar, ORCID, CrossRef, IACR)
- Added scrapers for security databases (NVD, OSV, CISA KEV)
- Added scrapers for documentation sites (MDN, Read the Docs, RFC Editor, W3C, SPDX, tldr, cheat.sh)
- Added scrapers for media platforms (YouTube, Vimeo, Spotify, Discogs, MusicBrainz)
- Added scrapers for AI/ML platforms (Hugging Face, Ollama)
- Added scrapers for app stores and marketplaces (VS Code Marketplace, JetBrains Marketplace, Firefox Add-ons, Open VSX, Flathub, F-Droid, Snapcraft)
- Added scrapers for business data (SEC EDGAR, OpenCorporates, CoinGecko)
- Added scrapers for reference sources (Wikipedia, Wikidata, OpenLibrary, Choose a License)
- Fixed session persistence to call fsync before renaming temp file for durability
- Fixed duplicate persistence error logging by tracking whether error was already reported
- Fixed byte counting in task output truncation to correctly handle multi-byte Unicode characters
- Fixed parallel task execution to propagate abort signals and fail fast on first error
- Fixed task worker abort handling to properly clean up on cancellation
- Fixed parallel task execution to fail fast on first error instead of waiting for all workers
- Fixed byte counting in task output truncation to handle multi-byte Unicode characters correctly
Changed
- Changed
Ctrl+Pto cycle through role models (slow → default → smol) instead of all available models - Changed
Shift+Ctrl+Pto cycle role models temporarily (not persisted) - Changed Extension Control Center to scale with terminal height instead of fixed 25-line limit
- Changed review command to parse git diff upfront and provide structured context to reviewer agents
- Changed session persistence to use structured logging instead of console.error for persistence failures
- Changed find tool to use fd command for .gitignore discovery instead of Bun.Glob for better abort handling
- Changed LSP config loading to only mark overrides when servers are actually defined
- Changed task tool to require explicit task
idfield instead of auto-generating names from agent type - Changed grep and find tools to use native Bun file APIs instead of Node.js fs module for improved performance
- Changed YouTube scraper to use async command execution with proper stream handling
- Improved rust-analyzer diagnostic polling to use version-based stability detection instead of time-based delays
- Changed theme icons for extension types to use Unicode symbols (✧, ⚒) instead of text abbreviations (SK, TL, MCP)
- Changed task tool to use short CamelCase task IDs instead of agent-based naming (e.g., 'SessionStore' instead of 'explore_0')
- Changed task tool to accept single
agentparameter at top level instead of per-task agent specification - Changed reviewer agent to use
completetool instead ofsubmit_reviewfor finishing reviews - Changed theme icons for extensions to use Unicode symbols instead of text abbreviations
- Changed LSP file type matching to support exact filename matches in addition to extensions
- Improved rust-analyzer diagnostic polling to use version-based stability detection
- Refactored web-fetch tool to use modular scraper architecture for improved maintainability
Removed
- Removed
submit_reviewtool - reviewers now finish viacompletetool with structured output
[3.30.0] - 2026-01-07
Added
- Added environment variable configuration for task limits:
OMP_TASK_MAX_PARALLEL,OMP_TASK_MAX_CONCURRENCY,OMP_TASK_MAX_OUTPUT_BYTES,OMP_TASK_MAX_OUTPUT_LINES, andOMP_TASK_MAX_AGENTS_IN_DESCRIPTION - Added specialized web-fetch handlers for 50+ platforms including GitHub, GitLab, npm, PyPI, crates.io, Stack Overflow, Wikipedia, arXiv, PubMed, Hacker News, Reddit, Mastodon, Bluesky, and many more
- Added automatic yt-dlp installation for YouTube transcript extraction
- Added YouTube video support with automatic transcript extraction via yt-dlp
Changed
- Changed task executor to gracefully handle worker termination with proper cleanup and timeout handling
Fixed
- Fixed Lobsters front page handler to use correct API endpoint (
/hottest.jsoninstead of invalid.json) - Fixed task worker error handling to prevent hanging on worker crashes, uncaught errors, and unhandled rejections
- Fixed double-stringified JSON output from subagents being returned as escaped strings instead of parsed objects
- Fixed markitdown tool installation to use automatic tool installer instead of requiring manual installation
[3.25.0] - 2026-01-07
Added
- Added
completetool for structured subagent output with JSON schema validation - Added
queryparameter to output tool for jq-like JSON querying - Added
output_schemaparameter to task tool for structured subagent completion - Added JTD (JSON Type Definition) to JSON Schema converter for schema flexibility
- Added memorable two-word task identifiers (e.g., SwiftFalcon) for better task tracking
Changed
- Changed task output IDs from
agent_indexformat to memorable names for easier reference - Changed subagent completion flow to require explicit
completetool call with retry reminders - Simplified worker agent system prompt to be more concise and focused
[3.24.0] - 2026-01-07
Added
- Added
ToolSessioninterface to unify tool creation with session context including cwd, UI availability, and rulebook rules - Added Bun Worker-based execution for subagent tasks, replacing subprocess spawning for improved performance and event streaming
- Added
toolNamesoption to filter which built-in tools are included in agent sessions - Added
BUILTIN_TOOLSregistry constant for programmatic access to available tool factories - Added unit tests for
createToolsfunction covering tool filtering and conditional tool creation
Changed
- Changed subagent execution from spawning separate
ompprocesses to running in Bun Workers with direct event streaming - Changed tool factories to accept
ToolSessionparameter instead of separate cwd and options arguments - Changed
createToolsto return tools as a Map and support conditional tool creation based on session context - Changed system prompt builder to dynamically generate tool descriptions from the tool registry
- Changed task tool description to be generated from a template with dynamic agent list injection
- Changed tool creation to use a unified
ToolSessioninterface instead of separate parameters for cwd, options, and callbacks - Changed
createToolsto return tools as a Map instead of an array for consistent tool registry access - Changed system prompt builder to receive tool registry Map for dynamic tool description generation
- Changed subprocess usage tracking to accumulate incrementally from message_end events rather than parsing stored events after completion
Removed
- Removed
browserembedded agent from task tool agent discovery - Removed
recursiveproperty from agent definitions - Removed environment variables
OMP_NO_SUBAGENTS,OMP_BLOCKED_AGENT, andOMP_SPAWNSfor subagent control - Removed pre-instantiated tool exports (
readTool,bashTool,editTool,writeTool,grepTool,findTool,lsTool) in favor of factory functions - Removed
createCodingToolsandcreateReadOnlyToolshelper functions - Removed
codingToolsandreadOnlyToolsconvenience exports - Removed
wrapToolsWithExtensionsfunction from extensions API - Removed
hiddenproperty support from custom tools - Removed subagent and question custom tool examples
Fixed
- Fixed memory accumulation in task subprocess by streaming events directly to disk instead of storing in memory
- Fixed session persistence to exclude transient streaming data (partialJson, jsonlEvents) that was causing unnecessary storage bloat
- Fixed createTools respecting explicit tool lists instead of returning all non-hidden tools
[3.21.0] - 2026-01-06
Changed
- Switched from local
@oh-my-pi/pi-aito upstream@mariozechner/pi-aipackage - Refactored tool renderers to be co-located with their respective tool implementations for improved code organization
- Changed web search to try all configured providers in sequence with fallback before reporting errors
- Changed default Anthropic web search model from
claude-sonnet-4-5-20250514toclaude-haiku-4-5 - Changed read tool to show first 50KB of oversized lines instead of directing users to bash sed
- Changed web_fetch to use
Bun.which()instead of spawningwhich/wherefor command detection - Changed web_fetch to check Content-Length header before downloading to reject oversized files early
- Changed generate_image tool to save images to temp files and report paths instead of inline base64
- Changed system prompt with tool usage guidance (ground answers with tools, minimize context, iterate on results)
- Changed Task tool prompt with plan-then-execute guidance and output tool hints
- Changed edit tool success message to report count when replacing multiple occurrences with
all: true - Changed default image generation model to
gemini-3-pro-image-preview - Changed error message for multiple occurrences to suggest using
all: trueoption - Changed web_fetch tool label from
web_fetchtoWeb Fetchfor improved display - Changed argument substitution order in slash commands to process positional args ($1, $2) before wildcards ($@, $ARGUMENTS) to prevent re-substitution issues
- Changed image tool name from
gemini_imagetogenerate_imagewith labelGenerateImage
Added
- Added
webSearchProvidersetting to override auto-detection priority (Exa > Perplexity > Anthropic) - Added
imageProvidersetting to override auto-detection priority (OpenRouter > Gemini) - Added
git.enabledsetting to enable/disable the structured git tool - Added
offsetandlimitparameters to Output tool for paginated reading of large outputs - Added provider fallback chain for web search that tries all configured providers before failing
- Added bash interceptor rule to block git commands when structured git tool is enabled
- Added validation requiring
messageparameter for git commit operations (prevents interactive editor) - Added output ID hints in multi-agent Task results pointing to Output tool for full logs
- Added fuzzy matching support for
all: truemode in edit tool, enabling replacement of similar text blocks with whitespace differences - Added
allparameter to edit tool for replacing all occurrences instead of requiring unique matches - Added OpenRouter support for image generation when
OPENROUTER_API_KEYis set - Added ImageMagick fallback for image processing when sharp module is unavailable
- Added slash commands to the extensions inspector panel for visibility and management
- Added support for file-based slash commands from
commands/directories - Added
$ARGUMENTSplaceholder for slash command argument substitution, aligning with Claude and Codex conventions
Fixed
- Fixed read tool markitdown truncation message using broken template string (missing
${around format call) - Fixed web_fetch URL normalization order to run before special handlers
- Fixed TUI image display for generate_image tool by sourcing images from details.images in addition to content blocks
- Fixed context file preview in inspector panel to display content correctly instead of attempting async file reads
- Fixed Linux ARM64 installs failing on fresh Debian when the
sharpmodule is unavailable during session image compression
[3.20.1] - 2026-01-06
Fixed
- Fixed find tool failing to match patterns with path separators (e.g.,
reports/**) by enabling full-path matching in fd
Changed
- Changed multi-task display to show task descriptions instead of agent names when available
- Changed ls tool to show relative modification times (e.g., "2d ago", "just now") for each entry
[3.20.0] - 2026-01-06
Added
- Added extensions API with auto-discovery (
.omp/extensions) and--extension/-eloading for custom tools, commands, and lifecycle hooks - Added prompt templates loaded from global and project
.omp/promptsdirectories with/templateexpansion in the input box - Built-in provider overrides in
models.json: override justbaseUrlto route a built-in provider through a proxy while keeping all its models, or definemodelsto fully replace the provider - Shell commands without context contribution: use
!!commandto execute a bash command that is shown in the TUI and saved to session history but excluded from LLM context. Useful for running commands you don't want the AI to see - Added VoiceSupervisor class for realtime voice mode using OpenAI Realtime API with continuous mic streaming and semantic VAD turn detection
- Added VoiceController class for steering user input and deciding presentation of assistant responses
- Added echo suppression and noise floor filtering for microphone input during voice playback
- Added fallback transcript handling when realtime assistant produces no tool call or audio output
- Added voice progress notifications that speak partial results after 15 seconds of streaming
- Added platform-specific audio tool detection with helpful installation instructions for missing tools
- Added realtime voice mode using OpenAI gpt-5-realtime with continuous mic streaming, interruptible input, and supervisor-controlled spoken updates
- Added
gemini_imagetool for Gemini Nano Banana image generation whenGEMINI_API_KEY(orGOOGLE_API_KEY) is set - Added
descriptionfield to task tool for displaying short user-facing summaries in progress output - Added
getApiKeyForProvider()method to ModelRegistry for retrieving API keys by provider name - Added voice settings configuration for transcription model, TTS model, voice, and audio format
- Added shared render utilities module with standardized formatting functions for truncation, byte/token/duration display, and tree rendering
- Added
resolveOmpCommand()helper to resolve subprocess command from environment or entry point - Added
/background(or/bg) command to detach UI and continue agent execution in the background - Added completion notification system with configurable methods (bell, osc99, osc9, auto, off) when agent finishes
- Added
completionNotificationsetting to configure how the agent notifies on completion - Added
OMP_NOTIFICATIONSenvironment variable to suppress notifications globally - Added
/wtslash command for git worktree management with create, list, merge, remove, status, spawn, and parallel operations - Added worktree library with collapse strategies (simple, merge-base, rebase) for merging changes between worktrees
- Added worktree session tracking for managing agent tasks across isolated worktrees
- Added structured git tool with safety guards, caching, and GitHub operations
- Added
cycleRoleModels()method to cycle through configured role-based models in a fixed order with deduplication - Added language-specific file icons to LSP diagnostics output showing file locations
- Added language-specific file icon to edit tool header display
Changed
- Changed voice mode toggle from Caps Lock to Ctrl+Y with auto-send on silence behavior
- Changed default TTS model from gpt-4o-mini-tts to tts-1
- Changed voice mode description to reflect realtime input/output with auto-send on silence
- Updated hotkeys help to show Ctrl+Y for voice mode toggle instead of Caps Lock
- Voice mode now uses OpenAI Realtime (gpt-5-realtime) with Ctrl+Y toggle and auto-send on silence
- Updated web search tool to support
autoas explicit provider option for auto-detection - Standardized tool result rendering across grep, find, ls, notebook, ask, output, and web search tools with consistent tree formatting and expand hints
- Updated grep and find tool output to display language-specific icons for files and folder icons for directories
- Updated file listing to display language-specific icons based on file extension instead of generic file icons
Fixed
- Fixed task tool race condition where subprocess stdout events were skipped due to
resolvedflag being set before stream readers finished, causing completed tasks to display "0 tools · 0 tokens" /modelselector now opens instantly instead of waiting for OAuth token refresh. Token refresh is deferred until a model is actually used- Fixed cross-platform browser opening to work on Windows (via cmd /c start) and fail gracefully when unavailable
[3.15.1] - 2026-01-05
Added
- Added 65 new built-in color themes including dark variants (abyss, aurora, cavern, copper, cosmos, eclipse, ember, equinox, lavender, lunar, midnight, nebula, rainforest, reef, sakura, slate, solstice, starfall, swamp, taiga, terminal, tundra, twilight, volcanic), light variants (aurora-day, canyon, cirrus, coral, dawn, dunes, eucalyptus, frost, glacier, haze, honeycomb, lagoon, lavender, meadow, mint, opal, orchard, paper, prism, sand, savanna, soleil, wetland, zenith), and material themes (alabaster, amethyst, anthracite, basalt, birch, graphite, limestone, mahogany, marble, obsidian, onyx, pearl, porcelain, quartz, sandstone, titanium)
Fixed
- Fixed status line end cap rendering to properly apply background colors and use correct powerline separator characters
[3.15.0] - 2026-01-05
Added
- Added spinner type variants (status and activity) with distinct animation frames per symbol preset
- Added animated spinner for task tool progress display during subagent execution
- Added language/file type icons for read tool output with support for 35+ file types
- Added async cleanup registry for graceful session flush on SIGINT, SIGTERM, and SIGHUP signals
- Added subagent token usage aggregation to session statistics and task tool results
- Added streaming NDJSON writer for session persistence with proper backpressure handling
- Added
flush()method to SessionManager for explicit control over pending write completion - Added
/exitslash command to exit the application from interactive mode - Added fuzzy path matching suggestions when read tool encounters file-not-found errors, showing closest matches using Levenshtein distance
- Added
status.shadowedsymbol for theme customization to properly indicate shadowed extension state - Added Biome CLI-based linter client as alternative to LSP for more reliable diagnostics
- Added LinterClient interface for pluggable formatter/linter implementations
- Added status line segment editor for arranging and toggling status line components
- Added status line presets (default, minimal, compact, developer, balanced) for quick configuration
- Added status line separator styles (powerline, powerline-thin, arrow, slash, pipe, space)
- Added configurable status line segments including time, hostname, and subagent count
- Added symbol customization via theme overrides for icons, separators, and glyphs
- Added 30+ built-in color themes including Catppuccin, Dracula, Nord, Gruvbox, Tokyo Night, and more
- Added configurable status line with customizable segments, presets, and separators
- Added status line segment editor for arranging and toggling status line components
- Added symbol preset setting to switch between Unicode, Nerd Font, and ASCII glyphs
- Added file size limit (20MB) for image files to prevent memory issues during serialization
Changed
- Changed
isErrorproperty in tool result events to be optional instead of required - Changed
SessionManager.open()andSessionManager.continueRecent()to async methods for proper initialization - Changed session file writes to use atomic rename pattern with fsync for crash-safe persistence
- Changed read tool display to show file type icons and metadata inline with path
- Changed
AgentSession.dispose()to async method that flushes pending writes before cleanup - Changed read tool result display to hide content by default with expand hint, showing only metadata until expanded
- Changed diagnostics display to group messages by file with tree structure and severity icons
- Changed diff stats formatting to use colored +/- indicators with slash separators
- Changed session persistence to use streaming writes instead of synchronous file appends for better performance
- Changed read tool to automatically redirect to ls when given a directory path instead of a file
- Changed tool description prompts to be more concise with clearer usage guidelines and structured formatting
- Moved tool description prompts from inline strings to external markdown files in
src/prompts/tools/directory for better maintainability - Changed Exa web search provider from MCP protocol to direct REST API for simpler integration
- Changed web search result rendering to handle malformed response data with fallback text display
- Changed compaction prompts to preserve tool outputs, command results, and repository state in context summaries
- Changed init prompt to include runtime/tooling preferences section and improved formatting guidelines
- Changed reviewer prompt to require evidence-backed findings anchored to diff hunks with stricter suggestion block formatting
- Changed system prompt to include explicit core behavior guidelines for task completion and progress updates
- Changed task prompt to emphasize end-to-end task completion and tool verification
- Moved all prompt templates from inline strings to external markdown files in
src/prompts/directory for better maintainability - Changed tool result renderers to use structured tree layouts with consistent expand hints and truncation indicators
- Changed grep, find, and ls tools to show scope path and detailed truncation reasons in output
- Changed web search and web fetch result rendering to display structured metadata sections with bounded content previews
- Changed task/subagent progress rendering to use badge-style status labels and structured output sections
- Changed notebook tool to display cell content preview with line counts
- Changed ask tool result to show checkbox-style selection indicators
- Changed output tool to include provenance metadata and content previews for retrieved outputs
- Changed collapsed tool views to show consistent "Ctrl+O to expand" hints with remaining item counts
- Changed Biome integration to use CLI instead of LSP to avoid stale diagnostics issues
- Changed hardcoded UI symbols throughout codebase to use theme-configurable glyphs
- Changed tree drawing characters to use theme-defined box-drawing symbols
- Changed status line rendering to support left/right segment positioning with separators
- Changed hardcoded UI symbols to use theme-configurable glyphs throughout the interface
- Changed tree drawing characters to use theme-defined box-drawing symbols
- Changed CLI image attachments to resize if larger than 2048px (fit within 1920x1080) and convert >2MB images to JPEG
Removed
- Removed custom renderers for ls, find, and grep tools in favor of generic tool display
Fixed
- Fixed spinner animation crash when spinner frames array is empty by adding length check
- Fixed session persistence to properly await all queued writes before closing or switching sessions
- Fixed session persistence to truncate oversized content blocks before writing to prevent memory exhaustion
- Fixed extension list and inspector panel to use correct symbols for disabled and shadowed states instead of reusing unrelated status icons
- Fixed token counting for subagent progress to handle different usage object formats (camelCase and snake_case)
- Fixed image file handling by adding 20MB size limit to prevent memory issues during serialization
- Fixed session persistence to truncate oversized entries before writing JSONL to prevent out-of-memory errors
[3.14.0] - 2026-01-04
Added
- Added
getUsageStatistics()method to SessionManager for tracking cumulative token usage and costs across session messages
Changed
- Changed status line to display usage statistics more efficiently by using centralized session statistics instead of recalculating from entries
[3.9.1337] - 2026-01-04
Changed
- Changed default for
lsp.formatOnWritesetting fromtruetofalse - Updated status line thinking level display to use emoji icons instead of abbreviated text
- Changed auto-compact indicator from "(auto)" text to icon
Fixed
- Fixed status line not updating token counts and cost after starting a new session
- Fixed stale diagnostics persisting after file content changes in LSP client
[3.8.1337] - 2026-01-04
Added
- Added automatic browser opening after exporting session to HTML
- Added automatic browser opening after sharing session as a Gist
Fixed
- Fixed session titles not persisting to file when set before first flush
[3.7.1337] - 2026-01-04
Added
- Added
EditMatchErrorclass for structured error handling in edit operations - Added
utilsmodule export withonceanduntilAbortedhelper functions - Added in-memory LSP content sync via
syncContentandnotifySavedclient methods
Changed
- Refactored LSP integration to use writethrough callbacks for edit and write tools, improving performance by syncing content in-memory before disk writes
- Simplified FileDiagnosticsResult interface with renamed fields:
diagnostics→messages,hasErrors→errored,serverName→server - Session title generation now triggers before sending the first message rather than after agent work begins
Fixed
- Fixed potential text decoding issues in bash executor by using streaming TextDecoder instead of Buffer.toString()
[3.5.1337] - 2026-01-03
Added
- Added session header and footer output in text mode showing version, model, provider, thinking level, and session ID
- Added Extension Control Center dashboard accessible via
/extensionscommand for unified management of all providers and extensions - Added ability to enable/disable individual extensions with persistent settings
- Added three-column dashboard layout with sidebar tree, extension list, and inspector panel
- Added fuzzy search filtering for extensions in the dashboard
- Added keyboard navigation with Tab to cycle panes, j/k for navigation, Space to toggle, Enter to expand/collapse
Changed
- Redesigned Extension Control Center from 3-column layout to tabbed interface with horizontal provider tabs and 2-column grid
- Replaced sidebar tree navigation with provider tabs using TAB/Shift+TAB cycling
Fixed
- Fixed title generation flag not resetting when starting a new session
[3.4.1337] - 2026-01-03
Added
- Added Time Traveling Stream Rules (TTSR) feature that monitors agent output for pattern matches and injects rule reminders mid-stream
- Added
ttsr_triggerfrontmatter field for rules to define regex patterns that trigger mid-stream injection - Added TTSR settings for enabled state, context mode (keep/discard partial output), and repeat mode (once/after-gap)
Fixed
- Fixed excessive subprocess spawns by caching git status for 1 second in the footer component
[3.3.1337] - 2026-01-03
Changed
- Improved
/statuscommand output formatting to use consistent column alignment across all sections - Updated version update notification to suggest
omp updateinstead of manual npm install command
[3.1.1337] - 2026-01-03
Added
- Added
spawnsfrontmatter field for agent definitions to control which sub-agents can be spawned - Added spawn restriction enforcement preventing agents from spawning unauthorized sub-agents
Fixed
- Fixed duplicate skill loading when the same SKILL.md file was discovered through multiple paths
[3.0.1337] - 2026-01-03
Added
- Added unified capability-based discovery system for loading configuration from multiple AI coding tools (Claude Code, Cursor, Windsurf, Gemini, Codex, Cline, GitHub Copilot, VS Code)
- Added support for discovering MCP servers, rules, skills, hooks, tools, slash commands, prompts, and context files from tool-specific config directories
- Added Discovery settings tab in interactive mode to enable/disable individual configuration providers
- Added provider source attribution showing which tool contributed each configuration item
- Added support for Cursor MDC rule format with frontmatter (description, globs, alwaysApply)
- Added support for Windsurf rules from .windsurf/rules/*.md and global_rules.md
- Added support for Cline rules from .clinerules file or directory
- Added support for GitHub Copilot instructions with applyTo glob patterns
- Added support for Gemini extensions and system.md customization files
- Added support for Codex AGENTS.md and config.toml settings
- Added automatic migration of
PI_*environment variables toOMP_*equivalents for backwards compatibility - Added multi-path config discovery supporting
.omp,.pi, and.claudedirectories with priority ordering - Added
getConfigDirPaths(),findConfigFile(), andreadConfigFile()functions for unified config resolution - Added documentation for config module usage patterns
Changed
- Changed MCP tool name parsing to use last underscore separator for better server name handling
- Changed /config output to show provider attribution for discovered items
- Renamed CLI binary from
pitoompand updated all command references - Changed config directory from
.pito.ompwith fallback support for legacy paths - Renamed environment variables from
PI_*toOMP_*prefix (e.g.,OMP_SMOL_MODEL,OMP_SLOW_MODEL) - Changed model role alias prefix from
pi/toomp/(e.g.,omp/slowinstead ofpi/slow)
[2.1.1337] - 2026-01-03
Added
- Added
pi updatecommand to check for and install updates from GitHub releases or via bun
Changed
- Changed HTML export to use compile-time bundled templates via Bun macros for improved performance
- Changed
exportToHtmlandexportFromFilefunctions to be async - Simplified build process by embedding assets (themes, templates, agents, commands) directly into the binary at compile time
- Removed separate asset copying steps from build scripts
[2.0.1337] - 2026-01-03
Added
- Added shell environment snapshot to preserve user aliases, functions, and shell options when executing bash commands
- Added support for
PI_BASH_NO_CI,PI_BASH_NO_LOGIN, andPI_SHELL_PREFIXenvironment variables for shell customization - Added zsh support alongside bash for shell detection and configuration
Changed
- Changed shell detection to prefer user's
$SHELLwhen it's bash or zsh, with improved fallback path resolution - Changed Edit tool to reject
.ipynbfiles with guidance to use NotebookEdit tool instead
[1.500.0] - 2026-01-03
Added
- Added provider tabs to model selector with Tab/Arrow navigation for filtering models by provider
- Added context menu to model selector for choosing model role (Default, Smol, Slow) instead of keyboard shortcuts
- Added LSP diagnostics display in tool execution output showing errors and warnings after file edits
- Added centralized file logger with daily rotation to
~/.pi/logs/for debugging production issues - Added
loggerproperty to hook and custom tool APIs for error/warning/debug logging - Added
outputtool to read full agent/task outputs by ID when truncated previews are insufficient - Added
tasktool to reviewer agent, enabling parallel exploration of large codebases during reviews - Added subprocess tool registry for extracting and rendering tool data from subprocess agents in real-time
- Added combined review result rendering showing verdict and findings in a tree structure
- Auto-read file mentions: Reference files with
@path/to/file.extsyntax in prompts to automatically inject their contents, eliminating manual Read tool calls - Added
hiddenproperty for custom tools to exclude them from default tool list unless explicitly requested - Added
explicitToolsoption tocreateAgentSessionfor enabling hidden tools by name - Added example review tools (
report_finding,submit_review) with structured findings accumulation and verdict rendering - Added
/reviewexample command for interactive code review with branch comparison, uncommitted changes, and commit review modes - Custom TypeScript slash commands: Create programmable commands at
~/.pi/agent/commands/[name]/index.tsor.pi/commands/[name]/index.ts. Commands export a factory returning{ name, description, execute(args, ctx) }. Return a string to send as LLM prompt, or void for fire-and-forget actions. Full access toHookCommandContextfor UI dialogs, session control, and shell execution. - Claude command directories: Markdown slash commands now also load from
~/.claude/commands/and.claude/commands/(parallel to existing.pi/commands/support) commands.enableClaudeUserandcommands.enableClaudeProjectsettings to disable Claude command directory loading/export --copyoption to copy entire session as formatted text to clipboard
Changed
- Changed model selector keyboard shortcuts from S/L keys to a context menu opened with Enter
- Changed model role indicators from symbols (✓ ⚡ 🧠) to labeled badges ([ DEFAULT ] [ SMOL ] [ SLOW ])
- Changed model list sorting to include secondary sort by model ID within each provider
- Changed silent error suppression to log warnings and debug info for tool errors, theme loading, and command loading failures
- Changed Task tool progress display to show agent index (e.g.,
reviewer(0)) for easier Output tool ID derivation - Changed Task tool output to only include file paths when Output tool is unavailable, providing Read tool fallback
- Changed Task tool output references to use simpler ID format (e.g.,
reviewer_0) with line/char counts for Output tool integration - Changed subagent recursion prevention from blanket blocking to same-agent blocking. Non-recursive agents can now spawn other agent types (e.g., reviewer can spawn explore agents) but cannot spawn themselves.
- Changed
/reviewcommand from markdown to interactive TypeScript with mode selection menu (branch comparison, uncommitted changes, commit review, custom) - Changed bundled commands to be overridable by user/project commands with same name
- Changed subprocess termination to wait for message_end event to capture accurate token counts
- Changed token counting in subprocess to accumulate across messages instead of overwriting
- Updated bundled
revieweragent to use structured review tools with priority-based findings (P0-P3) and formal verdict submission - Task tool now streams artifacts in real-time: input written before spawn, session jsonl written by subprocess, output written at completion
Removed
- Removed separate Exa error logger in favor of centralized logging system
- Removed
findings_countparameter fromsubmit_reviewtool - findings are now counted automatically - Removed artifacts location display from task tool output
Fixed
- Fixed race condition in event listener iteration by copying array before iteration to prevent mutation during callbacks
- Fixed potential memory leak from orphaned abort controllers by properly aborting existing controllers before replacement
- Fixed stream reader resource leak by adding proper
releaseLock()calls in finally blocks - Fixed hook API methods throwing clear errors when handlers are not initialized instead of silently failing
- Fixed LSP client race conditions with concurrent client creation and file operations using proper locking
- Fixed Task tool progress display showing stale data by cloning progress objects before passing to callbacks
- Fixed Task tool missing final progress events by waiting for readline to close before resolving
- Fixed RPC mode race condition with concurrent prompt commands by serializing execution
- Fixed pre-commit hook race condition causing
index.lockerrors when GitKraken/IDE git integrations detect file changes during formatting - Fixed Task tool output artifacts (
out.md) containing duplicated text from streaming updates - Fixed Task tool progress display showing repeated nearly-identical lines during streaming
- Fixed Task tool subprocess model selection ignoring agent's configured model and falling back to settings default. The
--modelflag now acceptsprovider/modelformat directly. - Fixed Task tool showing "done + succeeded" when aborted; now correctly displays "⊘ aborted" status
[1.341.0] - 2026-01-03
Added
- Added interruptMode setting to control when queued messages are processed during tool execution.
- Implemented getter and setter methods in SettingsManager for interrupt mode persistence.
- Exposed interruptMode configuration in interactive settings UI with immediate/wait options.
- Wired interrupt mode through AgentSession and SDK to enable runtime configuration.
- Model roles: Configure different models for different purposes (default, smol, slow) via
/modelselector - Model selector key bindings: Enter sets default, S sets smol, L sets slow, Escape closes
- Model selector shows role markers: ✓ for default, ⚡ for smol, 🧠 for slow
pi/<role>model aliases in Task tool agent definitions (e.g.,model: pi/smol, haiku, flash, mini)- Smol model auto-discovery using priority chain: haiku > flash > mini
- Slow model auto-discovery using priority chain: gpt-5.2-codex > codex > gpt > opus > pro
- CLI args for model roles:
--smol <model>and--slow <model>(ephemeral, not persisted) - Env var overrides:
PI_SMOL_MODELandPI_SLOW_MODEL - Title generation now uses configured smol model from settings
- LSP diagnostics on edit: Edit tool can now return LSP diagnostics after editing code files. Disabled by default to avoid noise during multi-edit sequences. Enable via
lsp.diagnosticsOnEditsetting. - LSP workspace diagnostics: New
lsp action=workspace_diagnosticscommand checks the entire project for errors. Auto-detects project type and uses appropriate checker (rust-analyzer/cargo for Rust, tsc for TypeScript, go build for Go, pyright for Python). - LSP local binary resolution: LSP servers installed in project-local directories are now discovered automatically. Checks
node_modules/.bin/for Node.js projects,.venv/bin//venv/bin/for Python projects, andvendor/bundle/bin/for Ruby projects before falling back to$PATH. - LSP format on write: Write tool now automatically formats code files using LSP after writing. Uses the language server's built-in formatter (e.g., rustfmt for Rust, gofmt for Go). Controlled via
lsp.formatOnWritesetting (enabled by default). - LSP diagnostics on write: Write tool now returns LSP diagnostics (errors/warnings) after writing code files. This gives immediate feedback on syntax errors and type issues. Controlled via
lsp.diagnosticsOnWritesetting (enabled by default). - LSP server warmup at startup: LSP servers are now started at launch to avoid cold-start delays when first writing files.
- LSP server status in welcome banner: Shows which language servers are active and ready.
- Edit fuzzy match setting: Added
edit.fuzzyMatchsetting (enabled by default) to control whether the edit tool accepts high-confidence fuzzy matches for whitespace/indentation differences. Toggle via/settings. - Multi-server LSP diagnostics: Diagnostics now query all applicable language servers for a file type. For TypeScript/JavaScript projects with Biome, this means both type errors (from tsserver) and lint errors (from Biome) are reported together.
- Comprehensive LSP server configurations for 40+ languages including Rust, Go, Python, Java, Kotlin, Scala, Haskell, OCaml, Elixir, Ruby, PHP, C#, Lua, Nix, and many more. Each server includes sensible defaults for args, settings, and init options.
- Extended LSP config file search paths: Now searches for
lsp.json,.lsp.jsonin project root and.pi/subdirectory, plus user-level configs in~/.pi/and home directory.
Changed
- LSP settings moved to dedicated "LSP" tab in
/settingsfor better organization - Improved grep tool description to document pagination options (
headLimit,offset) and clarify recursive search behavior - LSP idle timeout now disabled by default. Configure via
idleTimeoutMsin lsp.json to auto-shutdown inactive servers. - Model settings now use role-based storage (
modelRolesmap) instead of singledefaultProvider/defaultModelfields. Supports multiple model roles (default, small, etc.) - Session model persistence now uses
"provider/modelId"string format with optional role field
Fixed
- Recent sessions now show in welcome banner (was never wired up).
- Auto-generated session titles: Sessions are now automatically titled based on the first message using a small model (Haiku/GPT-4o-mini/Flash). Titles are shown in the terminal window title, recent sessions list, and --resume picker. The resume picker shows title with dimmed first message preview below.
[1.340.0] - 2026-01-03
Changed
- Replaced vendored highlight.js and marked.js with CDN-hosted versions for smaller exports
- Added runtime minification for HTML, CSS, and JS in session exports
- Session share URL now uses gistpreview.github.io instead of shittycodingagent.ai
[1.339.0] - 2026-01-03
Added
- MCP project config setting to disable loading
.mcp.json/mcp.jsonfrom project root - Support for both
mcp.jsonand.mcp.jsonfilenames (prefersmcp.jsonif both exist) - Automatic Exa MCP server filtering with API key extraction for native integration
[1.338.0] - 2026-01-03
Added
- Bash interceptor setting to block shell commands that have dedicated tools (disabled by default, enable via
/settings)
Changed
- Refactored settings UI to declarative definitions for easier maintenance
- Shell detection now respects
$SHELLenvironment variable before falling back to bash/sh - Tool binary detection now uses
Bun.which()instead of spawning processes
Fixed
- CLI help text now accurately lists all default tools
[1.337.1] - 2026-01-02
Added
- MCP support and plugin system for external tool integration
- Git context to system prompt for repo awareness
- Bash interception to guide tool selection
- Fuzzy matching to handle indentation variance in edit tool
- Specialized Exa tools with granular toggles
/sharecommand for exporting conversations to HTML- Edit diff preview before tool execution
Changed
- Renamed package scope to @oh-my-pi for consistent branding
- Simplified toolset and enhanced navigation
- Improved process cleanup with tree kill
- Updated CI/CD workflows for GitHub Actions with provenance-signed npm publishing
Fixed
- Template string interpolation in image read output
- Prevented full re-renders during write tool streaming
- Edit tool failing on files with UTF-8 BOM
[1.337.0] - 2026-01-02
Initial release under @oh-my-pi scope. See previous releases at badlogic/pi-mono.
[1.5.1] - 2026-01-03
Added
- Added shell environment snapshot to preserve user aliases, functions, and shell options when executing bash commands
- Added support for
PI_BASH_NO_CI,PI_BASH_NO_LOGIN, andPI_SHELL_PREFIXenvironment variables for shell customization - Added zsh support alongside bash for shell detection and configuration
Changed
- Changed shell detection to prefer user's
$SHELLwhen it's bash or zsh, with improved fallback path resolution - Changed Edit tool to reject
.ipynbfiles with guidance to use NotebookEdit tool instead
[1.5.0] - 2026-01-03
Added
- Added provider tabs to model selector with Tab/Arrow navigation for filtering models by provider
- Added context menu to model selector for choosing model role (Default, Smol, Slow) instead of keyboard shortcuts
- Added LSP diagnostics display in tool execution output showing errors and warnings after file edits
- Added centralized file logger with daily rotation to
~/.pi/logs/for debugging production issues - Added
loggerproperty to hook and custom tool APIs for error/warning/debug logging - Added
outputtool to read full agent/task outputs by ID when truncated previews are insufficient - Added
tasktool to reviewer agent, enabling parallel exploration of large codebases during reviews - Added subprocess tool registry for extracting and rendering tool data from subprocess agents in real-time
- Added combined review result rendering showing verdict and findings in a tree structure
- Auto-read file mentions: Reference files with
@path/to/file.extsyntax in prompts to automatically inject their contents, eliminating manual Read tool calls - Added
hiddenproperty for custom tools to exclude them from default tool list unless explicitly requested - Added
explicitToolsoption tocreateAgentSessionfor enabling hidden tools by name - Added example review tools (
report_finding,submit_review) with structured findings accumulation and verdict rendering - Added
/reviewexample command for interactive code review with branch comparison, uncommitted changes, and commit review modes - Custom TypeScript slash commands: Create programmable commands at
~/.pi/agent/commands/[name]/index.tsor.pi/commands/[name]/index.ts. Commands export a factory returning{ name, description, execute(args, ctx) }. Return a string to send as LLM prompt, or void for fire-and-forget actions. Full access toHookCommandContextfor UI dialogs, session control, and shell execution. - Claude command directories: Markdown slash commands now also load from
~/.claude/commands/and.claude/commands/(parallel to existing.pi/commands/support) commands.enableClaudeUserandcommands.enableClaudeProjectsettings to disable Claude command directory loading/export --copyoption to copy entire session as formatted text to clipboard
Changed
- Changed model selector keyboard shortcuts from S/L keys to a context menu opened with Enter
- Changed model role indicators from symbols (✓ ⚡ 🧠) to labeled badges ([ DEFAULT ] [ SMOL ] [ SLOW ])
- Changed model list sorting to include secondary sort by model ID within each provider
- Changed silent error suppression to log warnings and debug info for tool errors, theme loading, and command loading failures
- Changed Task tool progress display to show agent index (e.g.,
reviewer(0)) for easier Output tool ID derivation - Changed Task tool output to only include file paths when Output tool is unavailable, providing Read tool fallback
- Changed Task tool output references to use simpler ID format (e.g.,
reviewer_0) with line/char counts for Output tool integration - Changed subagent recursion prevention from blanket blocking to same-agent blocking. Non-recursive agents can now spawn other agent types (e.g., reviewer can spawn explore agents) but cannot spawn themselves.
- Changed
/reviewcommand from markdown to interactive TypeScript with mode selection menu (branch comparison, uncommitted changes, commit review, custom) - Changed bundled commands to be overridable by user/project commands with same name
- Changed subprocess termination to wait for message_end event to capture accurate token counts
- Changed token counting in subprocess to accumulate across messages instead of overwriting
- Updated bundled
revieweragent to use structured review tools with priority-based findings (P0-P3) and formal verdict submission - Task tool now streams artifacts in real-time: input written before spawn, session jsonl written by subprocess, output written at completion
Removed
- Removed separate Exa error logger in favor of centralized logging system
- Removed
findings_countparameter fromsubmit_reviewtool - findings are now counted automatically - Removed artifacts location display from task tool output
Fixed
- Fixed race condition in event listener iteration by copying array before iteration to prevent mutation during callbacks
- Fixed potential memory leak from orphaned abort controllers by properly aborting existing controllers before replacement
- Fixed stream reader resource leak by adding proper
releaseLock()calls in finally blocks - Fixed hook API methods throwing clear errors when handlers are not initialized instead of silently failing
- Fixed LSP client race conditions with concurrent client creation and file operations using proper locking
- Fixed Task tool progress display showing stale data by cloning progress objects before passing to callbacks
- Fixed Task tool missing final progress events by waiting for readline to close before resolving
- Fixed RPC mode race condition with concurrent prompt commands by serializing execution
- Fixed pre-commit hook race condition causing
index.lockerrors when GitKraken/IDE git integrations detect file changes during formatting - Fixed Task tool output artifacts (
out.md) containing duplicated text from streaming updates - Fixed Task tool progress display showing repeated nearly-identical lines during streaming
- Fixed Task tool subprocess model selection ignoring agent's configured model and falling back to settings default. The
--modelflag now acceptsprovider/modelformat directly. - Fixed Task tool showing "done + succeeded" when aborted; now correctly displays "⊘ aborted" status
[0.50.1] - 2026-01-26
Fixed
- Git extension updates now handle force-pushed remotes gracefully instead of failing (#961 by @aliou)
- Extension
ctx.newSession({ setup })now properly syncs agent state and renders messages after setup callback runs (#968) - Fixed extension UI bindings not initializing when starting with no extensions, which broke UI methods after
/reload - Fixed
/hotkeysoutput to title-case extension hotkeys (#969 by @Perlence) - Fixed model catalog generation to exclude deprecated OpenCode Zen models (#970 by @DanielTatarkin)
- Fixed git extension removal to prune empty directories
[0.50.0] - 2026-01-26
New Features
- Pi packages for bundling and installing extensions, skills, prompts, and themes. See docs/packages.md.
- Hot reload (
/reload) of resources including AGENTS.md, SYSTEM.md, APPEND_SYSTEM.md, prompt templates, skills, themes, and extensions. See README.md#commands and README.md#context-files. - Custom providers via
pi.registerProvider()for proxies, custom endpoints, OAuth or SSO flows, and non-standard streaming APIs. See docs/custom-provider.md. - Azure OpenAI Responses provider support with deployment-aware model mapping. See docs/providers.md#azure-openai.
- OpenRouter routing support for custom models via
openRouterRouting. See docs/providers.md#api-keys and docs/models.md. - Skill invocation messages are now collapsible and skills can opt out of model invocation via
disable-model-invocation. See docs/skills.md#frontmatter. - Session selector renaming and configurable keybindings. See README.md#commands and docs/keybindings.md.
models.jsonheaders can resolve environment variables and shell commands. See docs/models.md#value-resolution.--verboseCLI flag to override quiet startup. See README.md#cli-reference.
Read the fully revamped docs in README.md, or have your clanker read them for you.
SDK Migration Guide
There are multiple SDK breaking changes since v0.49.3. For the quickest migration, point your agent at packages/coding-agent/docs/sdk.md, the SDK examples in packages/coding-agent/examples/sdk, and the SDK source in packages/coding-agent/src/core/sdk.ts and related modules.
Breaking Changes
- Header values in
models.jsonnow resolve environment variables (if a header value matches an env var name, the env var value is used). This may change behavior if a literal header value accidentally matches an env var name. (#909) - External packages (npm/git) are now configured via
packagesarray in settings.json instead ofextensions. Existing npm:/git: entries inextensionsare auto-migrated. (#645) - Resource loading now uses
ResourceLoaderonly and settings.json uses arrays for extensions, skills, prompts, and themes (#645) - Removed
discoverAuthStorageanddiscoverModelsfrom the SDK.AuthStorageandModelRegistrynow default to~/.pi/agentpaths unless you pass anagentDir(#645)
Added
- Session renaming in
/resumepicker viaCtrl+Rwithout opening the session (#863 by @svkozak) - Session selector keybindings are now configurable (#948 by @aos)
disable-model-invocationfrontmatter field for skills to prevent agentic invocation while still allowing explicit/skill:namecommands (#927)- Exposed
copyToClipboardutility for extensions (#926 by @mitsuhiko) - Skill invocation messages are now collapsible in chat output, showing collapsed by default with skill name and expand hint (#894)
- Header values in
models.jsonnow support environment variables and shell commands, matchingapiKeyresolution (#909) - Added HTTP proxy environment variable support for API requests (#942 by @haoqixu)
- Added OpenRouter provider routing support for custom models via
openRouterRoutingcompat field (#859 by @v01dpr1mr0s3) - Added
azure-openai-responsesprovider support for Azure OpenAI Responses API. (#890 by @markusylisiurunen) - Added changelog link to update notifications (#925 by @dannote)
- Added
--verboseCLI flag to override quietStartup setting (#906 by @Perlence) markdown.codeBlockIndentsetting to customize code block indentation in rendered output- Extension package management with
pi install,pi remove,pi update, andpi listcommands (#645) - Package filtering: selectively load resources from packages using object form in
packagesarray (#645) - Glob pattern support with minimatch in package filters, top-level settings arrays, and pi manifest (e.g.,
"!funky.json","*.ts") (#645) /reloadcommand to reload extensions, skills, prompts, and themes (#645)pi configcommand with TUI to enable/disable package and top-level resources via patterns (#938)- CLI flags for
--skill,--prompt-template,--theme,--no-prompt-templates, and--no-themes(#645) - Package deduplication: if same package appears in global and project settings, project wins (#645)
- Unified collision reporting with
ResourceDiagnostictype for all resource types (#645) - Show provider alongside the model in the footer if multiple providers are available
- Custom provider support via
pi.registerProvider()withstreamSimplefor custom API implementations - Added
custom-provider.tsexample extension demonstrating custom Anthropic provider with OAuth
Changed
/resumepicker sort toggle moved toCtrl+Sto freeCtrl+Rfor rename (#863 by @svkozak)- HTML export: clicking a sidebar message now navigates to its newest leaf and scrolls to it, instead of truncating the branch (#853 by @mitsuhiko)
- HTML export: active path is now visually highlighted with dimmed off-path nodes (#929 by @hewliyang)
- Azure OpenAI Responses provider now uses base URL configuration with deployment-aware model mapping and no longer includes service tier handling
/reloadnow re-renders the entire scrollback so updated extension components are visible immediately (#928 by @ferologics)- Skill, prompt template, and theme discovery now use settings and CLI path arrays instead of legacy filters (#645)
Fixed
- Extension
setWorkingMessage()calls inagent_starthandlers now work correctly; previously the message was silently ignored because the loading animation didn't exist yet (#935) - Fixed package auto-discovery to respect loader rules, config overrides, and force-exclude patterns
- Fixed /reload restoring the correct editor after reload (#949 by @Perlence)
- Fixed distributed themes breaking
/export(#946 by @mitsuhiko) - Fixed startup hints to clarify thinking level selection and expanded thinking guidance
- Fixed SDK initial model resolution to use
findInitialModeland default to Claude Opus 4.5 for Anthropic models - Fixed no-models warning to include the
/modelinstruction - Fixed authentication error messages to point to the authentication documentation
- Fixed bash output hint lines to truncate to terminal width
- Fixed custom editors to honor the
paddingXsetting (#936 by @Perlence) - Fixed system prompt tool list to show only built-in tools
- Fixed package manager to check npm package versions before using cached copies
- Fixed package manager to run
npm installafter cloning git repositories with a package.json - Fixed extension provider registrations to apply before model resolution
- Fixed editor multi-line insertion handling and lastAction tracking (#945 by @Perlence)
- Fixed editor word wrapping to reserve a cursor column (#934 by @Perlence)
- Fixed editor word wrapping to use single-pass backtracking for whitespace handling (#924 by @Perlence)
- Fixed Kitty image ID allocation and cleanup to prevent image ID collisions
- Fixed overlays staying centered after terminal resizes (#950 by @nicobailon)
- Fixed streaming dispatch to use the model api type instead of hardcoded API defaults
- Fixed Google providers to default tool call arguments to an empty object when omitted
- Fixed OpenAI Responses streaming to handle
arguments.doneevents on OpenAI-compatible endpoints (#917 by @williballenthin) - Fixed OpenAI Codex Responses tool strictness handling after the shared responses refactor
- Fixed Azure OpenAI Responses streaming to guard deltas before content parts and correct metadata and handoff gating
- Fixed OpenAI completions tool-result image batching after consecutive tool results (#902 by @terrorobe)
- Off-by-one error in bash output "earlier lines" count caused by counting spacing newline as hidden content (#921)
- User package filters now layer on top of manifest filters instead of replacing them (#645)
- Auto-retry now handles "terminated" errors from Codex API mid-stream failures
- Follow-up queue (Alt+Enter) now sends full paste content instead of
[paste #N ...]markers (#912) - Fixed Alt-Up not restoring messages queued during compaction (#923 by @aliou)
- Fixed session corruption when loading empty or invalid session files via
--sessionflag (#932 by @armanddp) - Fixed extension shortcuts not firing when extension also uses
setEditorComponent()(#947 by @Perlence) - Session "modified" time now uses last message timestamp instead of file mtime, so renaming doesn't reorder the recent list (#863 by @svkozak)
[0.49.3] - 2026-01-22
Added
markdown.codeBlockIndentsetting to customize code block indentation in rendered output (#855 by @terrorobe)- Added
inline-bash.tsexample extension for expanding!{command}patterns in prompts (#881 by @scutifer) - Added
antigravity-image-gen.tsexample extension for AI image generation via Google Antigravity (#893 by @benvargas) - Added
PI_SHARE_VIEWER_URLenvironment variable for custom share viewer URLs (#889 by @andresaraujo) - Added Alt+Delete as hotkey for delete word forwards (#878 by @Perlence)
Changed
- Tree selector: changed label filter shortcut from
ltoShift+Lso users can search for entries containing "l" (#861 by @mitsuhiko) - Fuzzy matching now scores consecutive matches higher for better search relevance (#860 by @mitsuhiko)
Fixed
- Fixed error messages showing hardcoded
~/.pi/agent/paths instead of respectingPI_CODING_AGENT_DIR(#887 by @aliou) - Fixed
writetool not displaying errors in the UI when execution fails (#856) - Fixed HTML export using default theme instead of user's active theme (#870 by @scutifer)
- Show session name in the footer and terminal / tab title (#876 by @scutifer)
- Fixed 256color fallback in Terminal.app to prevent color rendering issues (#869 by @Perlence)
- Fixed viewport tracking and cursor positioning for overlays and content shrink scenarios
- Fixed autocomplete to allow searches with
/characters (e.g.,folder1/folder2) (#882 by @richardgill) - Fixed autolinked emails displaying redundant
(mailto:...)suffix (#888 by @terrorobe) - Fixed
@file autocomplete adding space after directories, breaking continued autocomplete into subdirectories
[0.49.2] - 2026-01-19
Added
- Added widget placement option for extension widgets via
widgetPlacementinpi.addWidget()(#850 by @marckrenn) - Added AWS credential detection for ECS/Kubernetes environments:
AWS_CONTAINER_CREDENTIALS_RELATIVE_URI,AWS_CONTAINER_CREDENTIALS_FULL_URI,AWS_WEB_IDENTITY_TOKEN_FILE(#848) - Add "quiet startup" setting to
/settings(#847 by @unexge)
Changed
- HTML export now includes JSONL download button, jump-to-last-message on click, and fixed missing labels (#853 by @mitsuhiko)
- Improved error message for OAuth authentication failures (expired credentials, offline) instead of generic 'No API key found' (#849 by @zedrdave)
Fixed
- Fixed
/modelselector scope toggle so you can switch between all and scoped models when scoped models are saved (#844) - Fixed OpenAI Responses 400 error "reasoning without following item" when replaying aborted turns (#838)
- Fixed pi exiting with code 0 when cancelling resume session selection
Removed
- Removed
strictResponsesPairingcompat option from models.json schema (no longer needed)
[0.49.1] - 2026-01-18
Added
- Added
strictResponsesPairingcompat option for custom OpenAI Responses models on Azure (#768 by @nicobako) - Session selector (
/resume) now supports path display toggle (Ctrl+P) and session deletion (Ctrl+D) with inline confirmation (#816 by @w-winter) - Added undo support in interactive mode with Ctrl+- hotkey. (#831 by @Perlence)
Changed
- Share URLs now use hash fragments (
#) instead of query strings (?) to prevent session IDs from being sent to buildwithpi.ai (#829 by @terrorobe) - API keys in
models.jsoncan now be retrieved via shell command using!prefix (e.g.,"apiKey": "!security find-generic-password -ws 'anthropic'"for macOS Keychain) (#762 by @cv)
Fixed
- Fixed IME candidate window appearing in wrong position when filtering menus with Input Method Editor (e.g., Chinese IME). Components with search inputs now properly propagate focus state for cursor positioning. (#827)
- Fixed extension shortcut conflicts to respect user keybindings when built-in actions are remapped. (#826 by @richardgill)
- Fixed photon WASM loading in standalone compiled binaries.
- Fixed tool call ID normalization for cross-provider handoffs (e.g., Codex to Antigravity Claude) (#821)
[0.49.0] - 2026-01-17
Added
pi.setLabel(entryId, label)in ExtensionAPI for setting per-entry labels from extensions (#806)- Export
keyHint,appKeyHint,editorKey,appKey,rawKeyHintfor extensions to format keybinding hints consistently (#802 by @dannote) - Exported
VERSIONfrom the package index and updated the custom-header example. (#798 by @tallshort) - Added
showHardwareCursorsetting to control cursor visibility while still positioning it for IME support. (#800 by @ghoulr) - Added Emacs-style kill ring editing with yank and yank-pop keybindings, plus legacy Alt+letter handling and Alt+D delete word forward support in the interactive editor. (#810 by @Perlence)
- Added
ctx.compact()andctx.getContextUsage()to extension contexts for programmatic compaction and context usage checks. - Added documentation for delete word forward and kill ring keybindings in interactive mode. (#810 by @Perlence)
Changed
- Updated the default system prompt wording to clarify the pi harness and documentation scope.
- Simplified Codex system prompt handling to use the default system prompt directly for Codex instructions.
Fixed
- Fixed photon module failing to load in ESM context with "require is not defined" error (#795 by @dannote)
- Fixed compaction UI not showing when extensions trigger compaction.
- Fixed orphaned tool results after errored assistant messages causing Codex API errors. When an assistant message has
stopReason: "error", its tool calls are now excluded from pending tool tracking, preventing synthetic tool results from being generated for calls that will be dropped by provider-specific converters. (#812) - Fixed Bedrock Claude max_tokens handling to always exceed thinking budget tokens, preventing compaction failures. (#797 by @pjtf93)
- Fixed Claude Code tool name normalization to match the Claude Code tool list case-insensitively and remove invalid mappings.
Removed
- Removed
pi-internal://path resolution from the read tool.
[0.48.0] - 2026-01-16
Added
- Added
quietStartupsetting to silence startup output (version header, loaded context info, model scope line). Changelog notifications are still shown. (#777 by @ribelo) - Added
editorPaddingXsetting for horizontal padding in input editor (0-3, default: 0) - Added
shellCommandPrefixsetting to prepend commands to every bash execution, enabling alias expansion in non-interactive shells (e.g.,"shellCommandPrefix": "shopt -s expand_aliases") (#790 by @richardgill) - Added bash-style argument slicing for prompt templates (#770 by @airtonix)
- Extension commands can provide argument auto-completions via
getArgumentCompletionsinpi.registerCommand()(#775 by @ribelo) - Bash tool now displays the timeout value in the UI when a timeout is set (#780 by @dannote)
- Export
getShellConfigfor extensions to detect user's shell environment (#766 by @dannote) - Added
thinkingTextandselectedBgto theme schema (#763 by @scutifer) navigateTree()now supportsreplaceInstructionsoption to replace the default summarization prompt entirely, andlabeloption to attach a label to the branch summary entry (#787 by @mitsuhiko)
Fixed
- Fixed crash during auto-compaction when summarization fails (e.g., quota exceeded). Now displays error message instead of crashing (#792)
- Fixed
--session <UUID>to search globally across projects if not found locally, with option to fork sessions from other projects (#785 by @ribelo) - Fixed standalone binary WASM loading on Linux (#784)
- Fixed string numbers in tool arguments not being coerced to numbers during validation (#786 by @dannote)
- Fixed
--no-extensionsflag not preventing extension discovery (#776) - Fixed extension messages rendering twice on startup when
pi.sendMessage({ display: true })is called duringsession_start(#765 by @dannote) - Fixed
PI_CODING_AGENT_DIRenv var not expanding tilde (~) to home directory (#778 by @aliou) - Fixed session picker hint text overflow (#764)
- Fixed Kitty keyboard protocol shifted symbol keys (e.g.,
@,?) not working in editor (#779 by @iamd3vil) - Fixed Bedrock tool call IDs causing API errors from invalid characters (#781 by @pjtf93)
Changed
- Hardware cursor is now disabled by default for better terminal compatibility. Set
PI_HARDWARE_CURSOR=1to enable (replacesPI_NO_HARDWARE_CURSOR=1which disabled it).
[0.47.0] - 2026-01-16
Breaking Changes
- Extensions using
Editordirectly must now passTUIas the first constructor argument:new Editor(tui, theme). Thetuiparameter is available in extension factory functions. (#732)
Added
- OpenAI Codex official support: Full compatibility with OpenAI's Codex CLI models (
gpt-5.1,gpt-5.2,gpt-5.1-codex-mini,gpt-5.2-codex). Features include static system prompt for OpenAI allowlisting, prompt caching via session ID, and reasoning signature retention across turns. SetOPENAI_API_KEYand use--provider openai-codexor select a Codex model. (#737) pi-internal://URL scheme in read tool for accessing internal documentation. The model can read files from the coding-agent package (README, docs, examples) to learn about extending pi.- New
inputevent in extension system for intercepting, transforming, or handling user input before the agent processes it. Supports three result types:continue(pass through),transform(modify text/images),handled(respond without LLM). Handlers chain transforms and short-circuit on handled. (#761 by @nicobailon) - Extension example:
input-transform.tsdemonstrating input interception patterns (quick mode, instant commands, source routing) (#761 by @nicobailon) - Custom tool HTML export: extensions with
renderCall/renderResultnow render in/shareand/exportoutput with ANSI-to-HTML color conversion (#702 by @aliou) - Direct filter shortcuts in Tree mode: Ctrl+D (default), Ctrl+T (no-tools), Ctrl+U (user-only), Ctrl+L (labeled-only), Ctrl+A (all) (#747 by @kaofelix)
Changed
- Skill commands (
/skill:name) are now expanded in AgentSession instead of interactive mode. This enables skill commands in RPC and print modes, and allows theinputevent to intercept/skill:namebefore expansion.
Fixed
- Editor no longer corrupts terminal display when loading large prompts via
setEditorText. Content now scrolls vertically with indicators showing lines above/below the viewport. (#732) - Piped stdin now works correctly:
echo foo | piis equivalent topi -p foo. When stdin is piped, print mode is automatically enabled since interactive mode requires a TTY (#708) - Session tree now preserves branch connectors and indentation when filters hide intermediate entries so descendants attach to the nearest visible ancestor and sibling branches align. Fixed in both TUI and HTML export (#739 by @w-winter)
- Added
upstream connect,connection refused, andreset before headerspatterns to auto-retry error detection (#733) - Multi-line YAML frontmatter in skills and prompt templates now parses correctly. Centralized frontmatter parsing using the
yamllibrary. (#728 by @richardgill) ctx.shutdown()now waits for pending UI renders to complete before exiting, ensuring notifications and final output are visible (#756)- OpenAI Codex provider now retries on transient errors (429, 5xx, connection failures) with exponential backoff (#733)
[0.46.0] - 2026-01-15
Fixed
- Scoped models (
--modelsorenabledModels) now remember the last selected model across sessions instead of always starting with the first model in the scope (#736 by @ogulcancelik) - Show
bun installinstead ofnpm installin update notification when running under Bun (#714 by @dannote) /skillprompts now include the skill path (#711 by @jblwilliams)- Use configurable
expandToolskeybinding instead of hardcoded Ctrl+O (#717 by @dannote) - Compaction turn prefix summaries now merge correctly (#738 by @vsabavat)
- Avoid unsigned Gemini 3 tool calls (#741 by @roshanasingh4)
- Fixed signature support for non-Anthropic models in Amazon Bedrock provider (#727 by @unexge)
- Keyboard shortcuts (Ctrl+C, Ctrl+D, etc.) now work on non-Latin keyboard layouts (Russian, Ukrainian, Bulgarian, etc.) in terminals supporting Kitty keyboard protocol with alternate key reporting (#718 by @dannote)
Added
- Edit tool now uses fuzzy matching as fallback when exact match fails, tolerating trailing whitespace, smart quotes, Unicode dashes, and special spaces (#713 by @dannote)
- Support
APPEND_SYSTEM.mdto append instructions to the system prompt (#716 by @tallshort) - Session picker search: Ctrl+R toggles sorting between fuzzy match (default) and most recent; supports quoted phrase matching and
re:regex mode (#731 by @ogulcancelik) - Export
getAgentDirfor extensions (#749 by @dannote) - Show loaded prompt templates on startup (#743 by @tallshort)
- MiniMax China (
minimax-cn) provider support (#725 by @tallshort) gpt-5.2-codexmodels for GitHub Copilot and OpenCode Zen providers (#734 by @aadishv)
Changed
- Replaced
wasm-vipswith@silvia-odwyer/photon-nodefor image processing (#710 by @can1357) - Extension example:
plan-mode/shortcut changed from Shift+P to Ctrl+Alt+P to avoid conflict with typing capital P (#746 by @ferologics) - UI keybinding hints now respect configured keybindings across components (#724 by @dannote)
- CLI process title is now set to
pifor easier process identification (#742 by @richardgill)
[0.45.7] - 2026-01-13
Added
[0.45.6] - 2026-01-13
Added
ctx.ui.custom()now acceptsoverlayOptionsfor overlay positioning and sizing (anchor, margins, offsets, percentages, absolute positioning) (#667 by @nicobailon)ctx.ui.custom()now acceptsonHandlecallback to receive theOverlayHandlefor controlling overlay visibility (#667 by @nicobailon)- Extension example:
overlay-qa-tests.tswith 10 commands for testing overlay positioning, animation, and toggle scenarios (#667 by @nicobailon) - Extension example:
doom-overlay/- DOOM game running as an overlay at 35 FPS (auto-downloads WAD on first run) (#667 by @nicobailon)
[0.45.5] - 2026-01-13
Fixed
- Skip changelog display on fresh install (only show on upgrades)
[0.45.4] - 2026-01-13
Changed
- Light theme colors adjusted for WCAG AA compliance (4.5:1 contrast ratio against white backgrounds)
- Replaced
sharpwithwasm-vipsfor image processing (resize, PNG conversion). Eliminates native build requirements that caused installation failures on some systems. (#696)
Added
- Extension example:
summarize.tsfor summarizing conversations using custom UI and an external model (#684 by @scutifer) - Extension example:
question.tsenhanced with custom UI for asking user questions (#693 by @ferologics) - Extension example:
plan-mode/enhanced with explicit step tracking and progress widget (#694 by @ferologics) - Extension example:
questionnaire.tsfor multi-question input with tab bar navigation (#695 by @ferologics) - Experimental Vercel AI Gateway provider support: set
AI_GATEWAY_API_KEYand use--provider vercel-ai-gateway. Token usage is currently reported incorrectly by Anthropic Messages compatible endpoint. (#689 by @timolins)
Fixed
- Fix API key resolution after model switches by using provider argument (#691 by @joshp123)
- Fixed z.ai thinking/reasoning: thinking toggle now correctly enables/disables thinking for z.ai models (#688)
- Fixed extension loading in compiled Bun binary: extensions with local file imports now work correctly. Updated
@mariozechner/jitito v2.6.5 which bundles babel for Bun binary compatibility. (#681) - Fixed theme loading when installed via mise: use wrapper directory in release tarballs for compatibility with mise's
strip_components=1extraction. (#681)
[0.45.2] - 2026-01-13
Fixed
- Extensions now load correctly in compiled Bun binary by using jiti for module resolution with proper alias handling
[0.45.1] - 2026-01-13
Changed
/sharenow outputsbuildwithpi.aisession preview URLs instead ofshittycodingagent.ai
[0.45.0] - 2026-01-13
Added
- MiniMax provider support: set
MINIMAX_API_KEYand useminimax/MiniMax-M2.1(#656 by @dannote) /scoped-models: Alt+Up/Down to reorder enabled models. Order is preserved when saving with Ctrl+S and determines Ctrl+P cycling order. (#676 by @thomasmhr)- Amazon Bedrock provider support (experimental, tested with Anthropic Claude models only) (#494 by @unexge)
- Extension example:
sandbox/for OS-level bash sandboxing using@anthropic-ai/sandbox-runtimewith per-project config (#673 by @dannote)
[0.44.0] - 2026-01-12
Breaking Changes
pi.getAllTools()now returnsToolInfo[](withnameanddescription) instead ofstring[]. Extensions that only need names can use.map(t => t.name). (#648 by @carsonfarmer)
Added
- Session naming:
/name <name>command sets a display name shown in the session selector instead of the first message. Useful for distinguishing forked sessions. Extensions can usepi.setSessionName()andpi.getSessionName(). (#650 by @scutifer) - Extension example:
notify.tsfor desktop notifications via OSC 777 escape sequence (#658 by @ferologics) - Inline hint for queued messages showing the
Alt+Uprestore shortcut (#657 by @tmustier) - Page-up/down navigation in
/resumesession selector to jump by 5 items (#662 by @aliou) - Fuzzy search in
/settingsmenu: type to filter settings by label (#643 by @ninlds)
Fixed
- Session selector now stays open when current folder has no sessions, allowing Tab to switch to "all" scope (#661 by @aliou)
- Extensions using theme utilities like
getSettingsListTheme()now work in dev mode with tsx
[0.43.0] - 2026-01-11
Breaking Changes
- Extension editor (
ctx.ui.editor()) now uses Enter to submit and Shift+Enter for newlines, matching the main editor. Previously used Ctrl+Enter to submit. Extensions with hardcoded "ctrl+enter" hints need updating. (#642 by @mitsuhiko) - Renamed
/branchcommand to/fork(#641)- RPC:
branch→fork,get_branch_messages→get_fork_messages - SDK:
branch()→fork(),getBranchMessages()→getForkMessages() - AgentSession:
branch()→fork(),getUserMessagesForBranching()→getUserMessagesForForking() - Extension events:
session_before_branch→session_before_fork,session_branch→session_fork - Settings:
doubleEscapeAction: "branch" | "tree"→"fork" | "tree"
- RPC:
SessionManager.list()andSessionManager.listAll()are now async, returningPromise<SessionInfo[]>. Callers must await them. (#620 by @tmustier)
Added
/resumeselector now toggles between current-folder and all sessions with Tab, showing the session cwd in the All view and loading progress. (#620 by @tmustier)SessionManager.list()andSessionManager.listAll()accept optionalonProgresscallback for progress updatesSessionInfo.cwdfield containing the session's working directory (empty string for old sessions)SessionListProgresstype export for progress callbacks/scoped-modelscommand to enable/disable models for Ctrl+P cycling. Changes are session-only by default; press Ctrl+S to persist to settings.json. (#626 by @CarlosGtrz)model_selectextension hook fires when model changes via/model, model cycling, or session restore withsourcefield andpreviousModel(#628 by @marckrenn)ctx.ui.setWorkingMessage()extension API to customize the "Working..." message during streaming (#625 by @nicobailon)- Skill slash commands: loaded skills are registered as
/skill:namecommands for quick access. Toggle via/settingsorskills.enableSkillCommandsin settings.json. (#630 by @Dwsy) - Slash command autocomplete now uses fuzzy matching (type
/skbrato match/skill:brave-search) /treebranch summarization now offers three options: "No summary", "Summarize", and "Summarize with custom prompt". Custom prompts are appended as additional focus to the default summarization instructions. (#642 by @mitsuhiko)
Fixed
- Session picker respects custom keybindings when using
--resume(#633 by @aos) - Custom footer extensions now see model changes:
ctx.modelis now a getter that returns the current model instead of a snapshot from when the context was created (#634 by @ogulcancelik) - Footer git branch not updating after external branch switches. Git uses atomic writes (temp file + rename), which changes the inode and breaks
fs.watchon the file. Now watches the directory instead. - Extension loading errors are now displayed to the user instead of being silently ignored (#639 by @aliou)
[0.42.5] - 2026-01-11
Fixed
- Reduced flicker by only re-rendering changed lines (#617 by @ogulcancelik). No worries tho, there's still a little flicker in the VS Code Terminal. Praise the flicker.
- Cursor position tracking when content shrinks with unchanged remaining lines
- TUI renders with wrong dimensions after suspend/resume if terminal was resized while suspended (#599)
- Pasted content containing Kitty key release patterns (e.g.,
:3Fin MAC addresses) was incorrectly filtered out (#623 by @ogulcancelik)
[0.42.4] - 2026-01-10
Fixed
- Bash output expanded hint now says "(ctrl+o to collapse)" (#610 by @tallshort)
- Fixed UTF-8 text corruption in remote bash execution (SSH, containers) by using streaming TextDecoder (#608)
[0.42.3] - 2026-01-10
Changed
- OpenAI Codex: updated to use bundled system prompt from upstream
[0.42.2] - 2026-01-10
Added
/model <search>now pre-filters the model selector or auto-selects on exact match. Useprovider/modelsyntax to disambiguate (e.g.,/model openai/gpt-4). (#587 by @zedrdave)FooterDataProviderfor custom footers:ctx.ui.setFooter()now receives a thirdfooterDataparameter providinggetGitBranch(),getExtensionStatuses(), andonBranchChange()for reactive updates (#600 by @nicobailon)Alt+Uphotkey to restore queued steering/follow-up messages back into the editor without aborting the current run (#604 by @tmustier)
Fixed
- Fixed LM Studio compatibility for OpenAI Responses tool strict mapping in the ai provider (#598 by @gnattu)
[0.42.1] - 2026-01-09
Fixed
- Symlinked directories in
prompts/folders are now followed when loading prompt templates (#601 by @aliou)
[0.42.0] - 2026-01-09
Added
- Added OpenCode Zen provider support. Set
OPENCODE_API_KEYenv var and useopencode/<model-id>(e.g.,opencode/claude-opus-4-5).
[0.41.0] - 2026-01-09
Added
- Anthropic OAuth support is back! Use
/loginto authenticate with your Claude Pro/Max subscription.
[0.40.1] - 2026-01-09
Removed
- Anthropic OAuth support (
/login). Use API keys instead.
[0.40.0] - 2026-01-08
Added
- Documentation on component invalidation and theme changes in
docs/tui.md
Fixed
- Components now properly rebuild their content on theme change (tool executions, assistant messages, bash executions, custom messages, branch/compaction summaries)
[0.39.1] - 2026-01-08
Fixed
setTheme()now triggers a full rerender so previously rendered components update with the new theme colorsmac-system-theme.tsexample now polls every 2 seconds and usesosascriptfor real-time macOS appearance detection
[0.39.0] - 2026-01-08
Breaking Changes
before_agent_startevent now receivessystemPromptin the event object and returnssystemPrompt(full replacement) instead ofsystemPromptAppend. Extensions that were appending must now useevent.systemPrompt + extrapattern. (#575)discoverSkills()now returns{ skills: Skill[], warnings: SkillWarning[] }instead ofSkill[]. This allows callers to handle skill loading warnings. (#577 by @cv)
Added
ctx.ui.getAllThemes(),ctx.ui.getTheme(name), andctx.ui.setTheme(name | Theme)methods for extensions to list, load, and switch themes at runtime (#576)--no-toolsflag to disable all built-in tools, allowing extension-only tool setups (#557 by @cv)- Pluggable operations for built-in tools enabling remote execution via SSH or other transports (#564). Interfaces:
ReadOperations,WriteOperations,EditOperations,BashOperations,LsOperations,GrepOperations,FindOperations user_bashevent for intercepting user!/!!commands, allowing extensions to redirect to remote systems (#528)setActiveTools()in ExtensionAPI for dynamic tool management- Built-in renderers used automatically for tool overrides without custom
renderCall/renderResult ssh.tsexample: remote tool execution via--ssh user@host:/pathinteractive-shell.tsexample: run interactive commands (vim, git rebase, htop) with full terminal access via!iprefix or auto-detection- Wayland clipboard support for
/copycommand using wl-copy with xclip/xsel fallback (#570 by @OgulcanCelik) - Experimental:
ctx.ui.custom()now accepts{ overlay: true }option for floating modal components that composite over existing content without clearing the screen (#558 by @nicobailon) AgentSession.skillsandAgentSession.skillWarningsproperties to access loaded skills without rediscovery (#577 by @cv)
Fixed
- String
systemPromptincreateAgentSession()now works as a full replacement instead of having context files and skills appended, matching documented behavior (#543) - Update notification for bun binary installs now shows release download URL instead of npm command (#567 by @ferologics)
- ESC key now works during "Working..." state after auto-retry (#568 by @tmustier)
- Abort messages now show correct retry attempt count (e.g., "Aborted after 2 retry attempts") (#568 by @tmustier)
- Fixed Antigravity provider returning 429 errors despite available quota (#571 by @ben-vargas)
- Fixed malformed thinking text in Gemini/Antigravity responses where thinking content appeared as regular text or vice versa. Cross-model conversations now properly convert thinking blocks to plain text. (#561)
--no-skillsflag now correctly prevents skills from loading in interactive mode (#577 by @cv)
[0.38.0] - 2026-01-08
Breaking Changes
ctx.ui.custom()factory signature changed from(tui, theme, done)to(tui, theme, keybindings, done)for keybinding access in custom componentsLoadedExtensiontype renamed toExtensionLoadExtensionsResult.setUIContext()removed, replaced withruntime: ExtensionRuntimeExtensionRunnerconstructor now requiresruntime: ExtensionRuntimeas second parameterExtensionRunner.initialize()signature changed from options object to positional params(actions, contextActions, commandContextActions?, uiContext?)ExtensionRunner.getHasUI()renamed tohasUI()- OpenAI Codex model aliases removed (
gpt-5,gpt-5-mini,gpt-5-nano,codex-mini-latest). Use canonical IDs:gpt-5.1,gpt-5.1-codex-mini,gpt-5.2,gpt-5.2-codex. (#536 by @ghoulr)
Added
--no-extensionsflag to disable extension discovery while still allowing explicit-epaths (#524 by @cv)- SDK:
InteractiveMode,runPrintMode(),runRpcMode()exported for building custom run modes. Seedocs/sdk.md. PI_SKIP_VERSION_CHECKenvironment variable to disable new version notifications at startup (#549 by @aos)thinkingBudgetssetting to customize token budgets per thinking level for token-based providers (#529 by @melihmucuk)- Extension UI dialogs (
ctx.ui.select(),ctx.ui.confirm(),ctx.ui.input()) now support atimeoutoption with live countdown display (#522 by @nicobailon) - Extensions can now provide custom editor components via
ctx.ui.setEditorComponent(). Seeexamples/extensions/modal-editor.tsanddocs/tui.mdPattern 7. - Extension factories can now be async, enabling dynamic imports and lazy-loaded dependencies (#513 by @austinm911)
ctx.shutdown()is now available in extension contexts for requesting a graceful shutdown. In interactive mode, shutdown is deferred until the agent becomes idle (after processing all queued steering and follow-up messages). In RPC mode, shutdown is deferred until after completing the current command response. In print mode, shutdown is a no-op as the process exits automatically when prompts complete. (#542 by @kaofelix)
Fixed
- Default thinking level from settings now applies correctly when
enabledModelsis configured (#540 by @ferologics) - External edits to
settings.jsonwhile pi is running are now preserved when pi saves settings (#527 by @ferologics) - Overflow-based compaction now skips if error came from a different model or was already handled by a previous compaction (#535 by @mitsuhiko)
- OpenAI Codex context window reduced from 400k to 272k tokens to match Codex CLI defaults and prevent 400 errors (#536 by @ghoulr)
- Context overflow detection now recognizes
context_length_exceedederrors. - Key presses no longer dropped when input is batched over SSH (#538)
- Clipboard image support now works on Alpine Linux and other musl-based distros (#533)
[0.37.6] - 2026-01-06
Added
- Extension UI dialogs (
ctx.ui.select(),ctx.ui.confirm(),ctx.ui.input()) now accept an optionalAbortSignalto programmatically dismiss dialogs. Useful for implementing timeouts. Seeexamples/extensions/timed-confirm.ts. (#474) - HTML export now shows bridge prompts in model change messages for Codex sessions (#510 by @mitsuhiko)
[0.37.5] - 2026-01-06
Added
- ExtensionAPI:
setModel(),getThinkingLevel(),setThinkingLevel()methods for extensions to change model and thinking level at runtime (#509) - Exported truncation utilities for custom tools:
truncateHead,truncateTail,truncateLine,formatSize,DEFAULT_MAX_BYTES,DEFAULT_MAX_LINES,TruncationOptions,TruncationResult - New example
truncated-tool.tsdemonstrating proper output truncation with custom rendering for extensions - New example
preset.tsdemonstrating preset configurations with model/thinking/tools switching (#347) - Documentation for output truncation best practices in
docs/extensions.md - Exported all UI components for extensions:
ArminComponent,AssistantMessageComponent,BashExecutionComponent,BorderedLoader,BranchSummaryMessageComponent,CompactionSummaryMessageComponent,CustomEditor,CustomMessageComponent,DynamicBorder,ExtensionEditorComponent,ExtensionInputComponent,ExtensionSelectorComponent,FooterComponent,LoginDialogComponent,ModelSelectorComponent,OAuthSelectorComponent,SessionSelectorComponent,SettingsSelectorComponent,ShowImagesSelectorComponent,ThemeSelectorComponent,ThinkingSelectorComponent,ToolExecutionComponent,TreeSelectorComponent,UserMessageComponent,UserMessageSelectorComponent, plus utilitiesrenderDiff,truncateToVisualLines docs/tui.md: Common Patterns section with copy-paste code for SelectList, BorderedLoader, SettingsList, setStatus, setWidget, setFooterdocs/tui.md: Key Rules section documenting critical patterns for extension UI developmentdocs/extensions.md: Exhaustive example links for all ExtensionAPI methods and events- System prompt now references
docs/tui.mdfor TUI component development
[0.37.4] - 2026-01-06
Added
- Session picker (
pi -r) and--sessionflag now support searching/resuming by session ID (UUID prefix) (#495 by @arunsathiya) - Extensions can now replace the startup header with
ctx.ui.setHeader(), seeexamples/extensions/custom-header.ts(#500 by @tudoroancea)
Changed
- Startup help text: fixed misleading "ctrl+k to delete line" to "ctrl+k to delete to end"
- Startup help text and
/hotkeys: added!!shortcut for running bash without adding output to context
Fixed
- Queued steering/follow-up messages no longer wipe unsent editor input (#503 by @tmustier)
- OAuth token refresh failure no longer crashes app at startup, allowing user to
/loginto re-authenticate (#498)
[0.37.3] - 2026-01-06
Added
- Extensions can now replace the footer with
ctx.ui.setFooter(), seeexamples/extensions/custom-footer.ts(#481) - Session ID is now forwarded to LLM providers for session-based caching (used by OpenAI Codex for prompt caching).
- Added
blockImagessetting to prevent images from being sent to LLM providers (#492 by @jsinge97) - Extensions can now send user messages via
pi.sendUserMessage()(#483)
Fixed
- Add
minimatchas a direct dependency for explicit imports. - Status bar now shows correct git branch when running in a git worktree (#490 by @kcosr)
- Interactive mode: Ctrl+V clipboard image paste now works on Wayland sessions by using
wl-pastewithxclipfallback (#488 by @ghoulr)
[0.37.2] - 2026-01-05
Fixed
- Extension directories in
settings.jsonnow respectpackage.jsonmanifests, matching global extension behavior (#480 by @prateekmedia) - Share viewer: deep links now scroll to the target message when opened via
/share - Bash tool now handles spawn errors gracefully instead of crashing the agent (missing cwd, invalid shell path) (#479 by @robinwander)
[0.37.1] - 2026-01-05
Fixed
- Share viewer: copy-link buttons now generate correct URLs when session is viewed via
/share(iframe context)
[0.37.0] - 2026-01-05
Added
- Share viewer: copy-link button on messages to share URLs that navigate directly to a specific message (#477 by @lockmeister)
- Extension example: add
claude-rulesto load.claude/rules/entries into the system prompt (#461 by @vaayne) - Headless OAuth login: all providers now show paste input for manual URL/code entry, works over SSH without DISPLAY (#428 by @ben-vargas, #468 by @crcatala)
Changed
- OAuth login UI now uses dedicated dialog component with consistent borders
- Assume truecolor support for all terminals except
dumb, empty, orlinux(fixes colors over SSH) - OpenAI Codex clean-up: removed per-thinking-level model variants, thinking level is now set separately and the provider clamps to what each model supports internally (initial implementation in #472 by @ben-vargas)
Fixed
- Messages submitted during compaction are queued and delivered after compaction completes, preserving steering and follow-up behavior. Extension commands execute immediately during compaction. (#476 by @tmustier)
- Managed binaries (
fd,rg) now stored in~/.pi/agent/bin/instead oftools/, eliminating false deprecation warnings (#470 by @mcinteerj) - Extensions defined in
settings.jsonwere not loaded (#463 by @melihmucuk) - OAuth refresh no longer logs users out when multiple pi instances are running (#466 by @Cursivez)
- Migration warnings now ignore
fd.exeandrg.exeintools/on Windows (#458 by @carlosgtrz) - CI: add
examples/extensions/with-depsto workspaces to fix typecheck (#467 by @aliou) - SDK: passing
extensions: []now disables extension discovery as documented (#465 by @aliou)
[0.36.0] - 2026-01-05
Added
- Experimental: OpenAI Codex OAuth provider support: access Codex models via ChatGPT Plus/Pro subscription using
/login openai-codex(#451 by @kim0)
[0.35.0] - 2026-01-05
This release unifies hooks and custom tools into a single "extensions" system and renames "slash commands" to "prompt templates". (#454)
Before migrating, read:
- docs/extensions.md - Full API reference
- README.md - Extensions section with examples
- examples/extensions/ - Working examples
Extensions Migration
Hooks and custom tools are now unified as extensions. Both were TypeScript modules exporting a factory function that receives an API object. Now there's one concept, one discovery location, one CLI flag, one settings.json entry.
Automatic migration:
commands/directories are automatically renamed toprompts/on startup (both~/.pi/agent/commands/and.pi/commands/)
Manual migration required:
- Move files from
hooks/andtools/directories toextensions/(deprecation warnings shown on startup) - Update imports and type names in your extension code
- Update
settings.jsonif you have explicit hook and custom tool paths configured
Directory changes:
# Before
~/.pi/agent/hooks/*.ts → ~/.pi/agent/extensions/*.ts
~/.pi/agent/tools/*.ts → ~/.pi/agent/extensions/*.ts
.pi/hooks/*.ts → .pi/extensions/*.ts
.pi/tools/*.ts → .pi/extensions/*.ts
Extension discovery rules (in extensions/ directories):
- Direct files:
extensions/*.tsor*.js→ loaded directly - Subdirectory with index:
extensions/myext/index.ts→ loaded as single extension - Subdirectory with package.json:
extensions/myext/package.jsonwith"pi"field → loads declared paths
// extensions/my-package/package.json
{
"name": "my-extension-package",
"dependencies": { "zod": "^3.0.0" },
"pi": {
"extensions": ["./src/main.ts", "./src/tools.ts"]
}
}
No recursion beyond one level. Complex packages must use the package.json manifest. Dependencies are resolved via jiti, and extensions can be published to and installed from npm.
Type renames:
HookAPI→ExtensionAPIHookContext→ExtensionContextHookCommandContext→ExtensionCommandContextHookUIContext→ExtensionUIContextCustomToolAPI→ExtensionAPI(merged)CustomToolContext→ExtensionContext(merged)CustomToolUIContext→ExtensionUIContextCustomTool→ToolDefinitionCustomToolFactory→ExtensionFactoryHookMessage→CustomMessage
Import changes:
// Before (hook)
import type { HookAPI, HookContext } from "@mariozechner/pi-coding-agent";
export default function (pi: HookAPI) { ... }
// Before (custom tool)
import type { CustomToolFactory } from "@mariozechner/pi-coding-agent";
const factory: CustomToolFactory = (pi) => ({ name: "my_tool", ... });
export default factory;
// After (both are now extensions)
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
export default function (pi: ExtensionAPI) {
pi.on("tool_call", async (event, ctx) => { ... });
pi.registerTool({ name: "my_tool", ... });
}
Custom tools now have full context access. Tools registered via pi.registerTool() now receive the same ctx object that event handlers receive. Previously, custom tools had limited context. Now all extension code shares the same capabilities:
pi.registerTool()- Register tools the LLM can callpi.registerCommand()- Register commands like/mycommandpi.registerShortcut()- Register keyboard shortcuts (shown in/hotkeys)pi.registerFlag()- Register CLI flags (shown in--help)pi.registerMessageRenderer()- Custom TUI rendering for message typespi.on()- Subscribe to lifecycle events (tool_call, session_start, etc.)pi.sendMessage()- Inject messages into the conversationpi.appendEntry()- Persist custom data in session (survives restart/branch)pi.exec()- Run shell commandspi.getActiveTools()/pi.setActiveTools()- Dynamic tool enable/disablepi.getAllTools()- List all available toolspi.events- Event bus for cross-extension communicationctx.ui.confirm()/select()/input()- User promptsctx.ui.notify()- Toast notificationsctx.ui.setStatus()- Persistent status in footer (multiple extensions can set their own)ctx.ui.setWidget()- Widget display above editorctx.ui.setTitle()- Set terminal window titlectx.ui.custom()- Full TUI component with keyboard handlingctx.ui.editor()- Multi-line text editor with external editor supportctx.sessionManager- Read session entries, get branch history
Settings changes:
// Before
{
"hooks": ["./my-hook.ts"],
"customTools": ["./my-tool.ts"]
}
// After
{
"extensions": ["./my-extension.ts"]
}
CLI changes:
# Before
pi --hook ./safety.ts --tool ./todo.ts
# After
pi --extension ./safety.ts -e ./todo.ts
Prompt Templates Migration
"Slash commands" (markdown files defining reusable prompts invoked via /name) are renamed to "prompt templates" to avoid confusion with extension-registered commands.
Automatic migration: The commands/ directory is automatically renamed to prompts/ on startup (if prompts/ doesn't exist). Works for both regular directories and symlinks.
Directory changes:
~/.pi/agent/commands/*.md → ~/.pi/agent/prompts/*.md
.pi/commands/*.md → .pi/prompts/*.md
SDK type renames:
FileSlashCommand→PromptTemplateLoadSlashCommandsOptions→LoadPromptTemplatesOptions
SDK function renames:
discoverSlashCommands()→discoverPromptTemplates()loadSlashCommands()→loadPromptTemplates()expandSlashCommand()→expandPromptTemplate()getCommandsDir()→getPromptsDir()
SDK option renames:
CreateAgentSessionOptions.slashCommands→.promptTemplatesAgentSession.fileCommands→.promptTemplatesPromptOptions.expandSlashCommands→.expandPromptTemplates
SDK Migration
Discovery functions:
discoverAndLoadHooks()→discoverAndLoadExtensions()discoverAndLoadCustomTools()→ merged intodiscoverAndLoadExtensions()loadHooks()→loadExtensions()loadCustomTools()→ merged intoloadExtensions()
Runner and wrapper:
HookRunner→ExtensionRunnerwrapToolsWithHooks()→wrapToolsWithExtensions()wrapToolWithHooks()→wrapToolWithExtensions()
CreateAgentSessionOptions:
.hooks→ removed (use.additionalExtensionPathsfor paths).additionalHookPaths→.additionalExtensionPaths.preloadedHooks→.preloadedExtensions.customToolstype changed:Array<{ path?; tool: CustomTool }>→ToolDefinition[].additionalCustomToolPaths→ merged into.additionalExtensionPaths.slashCommands→.promptTemplates
AgentSession:
.hookRunner→.extensionRunner.fileCommands→.promptTemplates.sendHookMessage()→.sendCustomMessage()
Session Migration
Automatic. Session version bumped from 2 to 3. Existing sessions are migrated on first load:
- Message role
"hookMessage"→"custom"
[0.34.1] - 2026-01-04
Changed
- Expanded keybinding documentation to list all 32 supported symbol keys with notes on ctrl+symbol behavior (#450 by @kaofelix)
[0.34.0] - 2026-01-04
Added
- Hook API:
before_agent_starthandlers can now returnsystemPromptAppendto dynamically append text to the system prompt for that turn. Multiple hooks' appends are concatenated. - Hook API:
before_agent_starthandlers can now return multiple messages (all are injected, not just the first) - New example hook:
tools.ts- Interactive/toolscommand to enable/disable tools with session persistence - New example hook:
pirate.ts- DemonstratessystemPromptAppendto make the agent speak like a pirate - Tool registry now contains all built-in tools (read, bash, edit, write, grep, find, ls) even when
--toolslimits the initially active set. Hooks can enable any tool from the registry viapi.setActiveTools(). - System prompt now automatically rebuilds when tools change via
setActiveTools(), updating tool descriptions and guidelines to match the new tool set - Hook errors now display full stack traces for easier debugging
Changed
- Removed image placeholders after copy & paste, replaced with inserting image file paths directly. (#442 by @mitsuhiko)
Fixed
- Fixed potential text decoding issues in bash executor by using streaming TextDecoder instead of Buffer.toString()
- External editor (Ctrl-G) now shows full pasted content instead of
[paste #N ...]placeholders (#444 by @aliou)
[0.33.0] - 2026-01-04
Breaking Changes
- Key detection functions removed from
@mariozechner/pi-tui: AllisXxx()key detection functions (isEnter(),isEscape(),isCtrlC(), etc.) have been removed. UsematchesKey(data, keyId)instead (e.g.,matchesKey(data, "enter"),matchesKey(data, "ctrl+c")). This affects hooks and custom tools that usectx.ui.custom()with keyboard input handling. (#405)
Added
- Clipboard image paste support via
Ctrl+V. Images are saved to a temp file and attached to the message. Works on macOS, Windows, and Linux (X11). (#419) - Configurable keybindings via
~/.pi/agent/keybindings.json. All keyboard shortcuts (editor navigation, deletion, app actions like model cycling, etc.) can now be customized. Supports multiple bindings per action. (#405 by @hjanuschka) /quitand/exitslash commands to gracefully exit the application. Unlike double Ctrl+C, these properly await hook and custom tool cleanup handlers before exiting. (#426 by @ben-vargas)
Fixed
- Subagent example README referenced incorrect filename
subagent.tsinstead ofindex.ts(#427 by @Whamp)
[0.32.3] - 2026-01-03
Fixed
--list-modelsno longer shows Google Vertex AI models without explicit authentication configured- JPEG/GIF/WebP images not displaying in terminals using Kitty graphics protocol (Kitty, Ghostty, WezTerm). The protocol requires PNG format, so non-PNG images are now converted before display.
- Version check URL typo preventing update notifications from working (#423 by @skuridin)
- Large images exceeding Anthropic's 5MB limit now retry with progressive quality/size reduction (#424 by @mitsuhiko)
[0.32.2] - 2026-01-03
Added
$ARGUMENTSsyntax for custom slash commands as alternative to$@for all arguments joined. Aligns with patterns used by Claude, Codex, and OpenCode. Both syntaxes remain fully supported. (#418 by @skuridin)
Changed
- Slash commands and hook commands now work during streaming: Previously, using a slash command or hook command while the agent was streaming would crash with "Agent is already processing". Now:
- Hook commands execute immediately (they manage their own LLM interaction via
pi.sendMessage()) - File-based slash commands are expanded and queued via steer/followUp
steer()andfollowUp()now expand file-based slash commands and error on hook commands (hook commands cannot be queued)prompt()accepts newstreamingBehavioroption ("steer"or"followUp") to specify queueing behavior during streaming- RPC
promptcommand now accepts optionalstreamingBehaviorfield (#420)
- Hook commands execute immediately (they manage their own LLM interaction via
Fixed
- Slash command argument substitution now processes positional arguments (
$1,$2, etc.) before all-arguments ($@,$ARGUMENTS) to prevent recursive substitution when argument values contain dollar-digit patterns like$100. (#418 by @skuridin)
[0.32.1] - 2026-01-03
Added
- Shell commands without context contribution: use
!!commandto execute a bash command that is shown in the TUI and saved to session history but excluded from LLM context. Useful for running commands you don't want the AI to see. (#414)
[0.32.0] - 2026-01-03
Breaking Changes
- Queue API replaced with steer/followUp: The
queueMessage()method has been split into two methods with different delivery semantics (#403):steer(text): Interrupts the agent mid-run (Enter while streaming). Delivered after current tool execution.followUp(text): Waits until the agent finishes (Alt+Enter while streaming). Delivered only when agent stops.
- Settings renamed:
queueModesetting renamed tosteeringMode. Added newfollowUpModesetting. Old settings.json files are migrated automatically. - AgentSession methods renamed:
queueMessage()→steer()andfollowUp()queueModegetter →steeringModeandfollowUpModegetterssetQueueMode()→setSteeringMode()andsetFollowUpMode()queuedMessageCount→pendingMessageCountgetQueuedMessages()→getSteeringMessages()andgetFollowUpMessages()clearQueue()now returns{ steering: string[], followUp: string[] }hasQueuedMessages()→hasPendingMessages()
- Hook API signature changed:
pi.sendMessage()second parameter changed fromtriggerTurn?: booleantooptions?: { triggerTurn?, deliverAs? }. UsedeliverAs: "followUp"for follow-up delivery. Affects both hooks and internalsendHookMessage()method. - RPC API changes:
queue_messagecommand →steerandfollow_upcommandsset_queue_modecommand →set_steering_modeandset_follow_up_modecommandsRpcSessionState.queueMode→steeringModeandfollowUpMode
- Settings UI: "Queue mode" setting split into "Steering mode" and "Follow-up mode"
[0.31.1] - 2026-01-02
Fixed
- Model selector no longer allows negative index when pressing arrow keys before models finish loading (#398 by @mitsuhiko)
- Type guard functions (
isBashToolResult, etc.) now exported at runtime, not just in type declarations (#397)
[0.31.0] - 2026-01-02
This release introduces session trees for in-place branching, major API changes to hooks and custom tools, and structured compaction with file tracking.
Session Tree
Sessions now use a tree structure with id/parentId fields. This enables in-place branching: navigate to any previous point with /tree, continue from there, and switch between branches while preserving all history in a single file.
Existing sessions are automatically migrated (v1 → v2) on first load. No manual action required.
New entry types: BranchSummaryEntry (context from abandoned branches), CustomEntry (hook state), CustomMessageEntry (hook-injected messages), LabelEntry (bookmarks).
See docs/session.md for the file format and SessionManager API.
Hooks Migration
The hooks API has been restructured with more granular events and better session access.
Type renames:
HookEventContext→HookContextHookCommandContextis now a new interface extendingHookContextwith session control methods
Event changes:
- The monolithic
sessionevent is now split into granular events:session_start,session_before_switch,session_switch,session_before_branch,session_branch,session_before_compact,session_compact,session_shutdown session_before_switchandsession_switchevents now includereason: "new" | "resume"to distinguish between/newand/resume- New
session_before_treeandsession_treeevents for/treenavigation (hook can provide custom branch summary) - New
before_agent_startevent: inject messages before the agent loop starts - New
contextevent: modify messages non-destructively before each LLM call - Session entries are no longer passed in events. Use
ctx.sessionManager.getEntries()orctx.sessionManager.getBranch()instead
API changes:
pi.send(text, attachments?)→pi.sendMessage(message, triggerTurn?)(createsCustomMessageEntry)- New
pi.appendEntry(customType, data?)for hook state persistence (not in LLM context) - New
pi.registerCommand(name, options)for custom slash commands (handler receivesHookCommandContext) - New
pi.registerMessageRenderer(customType, renderer)for custom TUI rendering - New
ctx.isIdle(),ctx.abort(),ctx.hasQueuedMessages()for agent state (available in all events) - New
ctx.ui.editor(title, prefill?)for multi-line text editing with Ctrl+G external editor support - New
ctx.ui.custom(component)for full TUI component rendering with keyboard focus - New
ctx.ui.setStatus(key, text)for persistent status text in footer (multiple hooks can set their own) - New
ctx.ui.themegetter for styling text with theme colors ctx.exec()moved topi.exec()ctx.sessionFile→ctx.sessionManager.getSessionFile()- New
ctx.modelRegistryandctx.modelfor API key resolution
HookCommandContext (slash commands only):
ctx.waitForIdle()- wait for agent to finish streamingctx.newSession(options?)- create new sessions with optional setup callbackctx.branch(entryId)- branch from a specific entryctx.navigateTree(targetId, options?)- navigate the session tree
These methods are only on HookCommandContext (not HookContext) because they can deadlock if called from event handlers that run inside the agent loop.
Removed:
hookTimeoutsetting (hooks no longer have timeouts; use Ctrl+C to abort)resolveApiKeyparameter (usectx.modelRegistry.getApiKey(model))
See docs/hooks.md and examples/hooks/ for the current API.
Custom Tools Migration
The custom tools API has been restructured to mirror the hooks pattern with a context object.
Type renames:
CustomAgentTool→CustomToolToolAPI→CustomToolAPIToolContext→CustomToolContextToolSessionEvent→CustomToolSessionEvent
Execute signature changed:
// Before (v0.30.2)
execute(toolCallId, params, signal, onUpdate)
// After
execute(toolCallId, params, onUpdate, ctx, signal?)
The new ctx: CustomToolContext provides sessionManager, modelRegistry, model, and agent state methods:
ctx.isIdle()- check if agent is streamingctx.hasQueuedMessages()- check if user has queued messages (skip interactive prompts)ctx.abort()- abort current operation (fire-and-forget)
Session event changes:
CustomToolSessionEventnow only hasreasonandpreviousSessionFile- Session entries are no longer in the event. Use
ctx.sessionManager.getBranch()orctx.sessionManager.getEntries()to reconstruct state - Reasons:
"start" | "switch" | "branch" | "tree" | "shutdown"(no separate"new"reason;/newtriggers"switch") dispose()method removed. UseonSessionwithreason: "shutdown"for cleanup
See docs/custom-tools.md and examples/custom-tools/ for the current API.
SDK Migration
Type changes:
CustomAgentTool→CustomToolAppMessage→AgentMessagesessionFilereturnsstring | undefined(wasstring | null)modelreturnsModel | undefined(wasModel | null)Attachmenttype removed. UseImageContentfrom@oh-my-pi/pi-aiinstead. Add images directly to message content arrays.
AgentSession API:
branch(entryIndex: number)→branch(entryId: string)getUserMessagesForBranching()returns{ entryId, text }instead of{ entryIndex, text }reset()→newSession(options?)where options has optionalparentSessionfor lineage trackingnewSession()andswitchSession()now returnPromise<boolean>(false if cancelled by hook)- New
navigateTree(targetId, options?)for in-place tree navigation
Hook integration:
- New
sendHookMessage(message, triggerTurn?)for hook message injection
SessionManager API:
- Method renames:
saveXXX()→appendXXX()(e.g.,appendMessage,appendCompaction) branchInPlace()→branch()reset()→newSession(options?)with optionalparentSessionfor lineage trackingcreateBranchedSessionFromEntries(entries, index)→createBranchedSession(leafId)SessionHeader.branchedFrom→SessionHeader.parentSessionsaveCompaction(entry)→appendCompaction(summary, firstKeptEntryId, tokensBefore, details?)getEntries()now excludes the session header (usegetHeader()separately)getSessionFile()returnsstring | undefined(undefined for in-memory sessions)- New tree methods:
getTree(),getBranch(),getLeafId(),getLeafEntry(),getEntry(),getChildren(),getLabel() - New append methods:
appendCustomEntry(),appendCustomMessageEntry(),appendLabelChange() - New branch methods:
branch(entryId),branchWithSummary()
ModelRegistry (new):
ModelRegistry is a new class that manages model discovery and API key resolution. It combines built-in models with custom models from models.json and resolves API keys via AuthStorage.
import { discoverAuthStorage, discoverModels } from "@oh-my-pi/pi-coding-agent";
const authStorage = discoverAuthStorage(); // ~/.pi/agent/auth.json
const modelRegistry = discoverModels(authStorage); // + ~/.pi/agent/models.json
// Get all models (built-in + custom)
const allModels = modelRegistry.getAll();
// Get only models with valid API keys
const available = await modelRegistry.getAvailable();
// Find specific model
const model = modelRegistry.find("anthropic", "claude-sonnet-4-20250514");
// Get API key for a model
const apiKey = await modelRegistry.getApiKey(model);
This replaces the old resolveApiKey callback pattern. Hooks and custom tools access it via ctx.modelRegistry.
Renamed exports:
messageTransformer→convertToLlmSessionContextaliasLoadedSessionremoved
See docs/sdk.md and examples/sdk/ for the current API.
RPC Migration
Session commands:
resetcommand →new_sessioncommand with optionalparentSessionfield
Branching commands:
branchcommand:entryIndex→entryIdget_branch_messagesresponse:entryIndex→entryId
Type changes:
- Messages are now
AgentMessage(wasAppMessage) promptcommand:attachmentsfield replaced withimagesfield usingImageContentformat
Compaction events:
auto_compaction_startnow includesreasonfield ("threshold"or"overflow")auto_compaction_endnow includeswillRetryfieldcompactresponse includes fullCompactionResult(summary,firstKeptEntryId,tokensBefore,details)
See docs/rpc.md for the current protocol.
Structured Compaction
Compaction and branch summarization now use a structured output format:
- Clear sections: Goal, Progress, Key Information, File Operations
- File tracking:
readFilesandmodifiedFilesarrays indetails, accumulated across compactions - Conversations are serialized to text before summarization to prevent the model from "continuing" them
The before_compact and before_tree hook events allow custom compaction implementations. See docs/compaction.md.
Interactive Mode
/tree command:
- Navigate the full session tree in-place
- Search by typing, page with ←/→
- Filter modes (Ctrl+O): default → no-tools → user-only → labeled-only → all
- Press
lto label entries as bookmarks - Selecting a branch switches context and optionally injects a summary of the abandoned branch
Entry labels:
- Bookmark any entry via
/tree→ select →l - Labels appear in tree view and persist as
LabelEntry
Theme changes (breaking for custom themes):
Custom themes must add these new color tokens or they will fail to load:
selectedBg: background for selected/highlighted items in tree selector and other componentscustomMessageBg: background for hook-injected messages (CustomMessageEntry)customMessageText: text color for hook messagescustomMessageLabel: label color for hook messages (the[customType]prefix)
Total color count increased from 46 to 50. See docs/theme.md for the full color list and copy values from the built-in dark/light themes.
Settings:
enabledModels: allowlist models insettings.json(same format as--modelsCLI)
Added
ctx.ui.setStatus(key, text)for hooks to display persistent status text in the footer (#385 by @prateekmedia)ctx.ui.themegetter for styling status text and other output with theme colors/sharecommand to upload session as a secret GitHub gist and get a shareable URL via shittycodingagent.ai (#380)- HTML export now includes a tree visualization sidebar for navigating session branches (#375)
- HTML export supports keyboard shortcuts: Ctrl+T to toggle thinking blocks, Ctrl+O to toggle tool outputs
- HTML export supports theme-configurable background colors via optional
exportsection in theme JSON (#387 by @mitsuhiko) - HTML export syntax highlighting now uses theme colors and matches TUI rendering
- Snake game example hook: Demonstrates
ui.custom(),registerCommand(), and session persistence. See examples/hooks/snake.ts. thinkingTexttheme token: Configurable color for thinking block text. (#366 by @paulbettner)
Changed
- Entry IDs: Session entries now use short 8-character hex IDs instead of full UUIDs
- API key priority:
ANTHROPIC_OAUTH_TOKENnow takes precedence overANTHROPIC_API_KEY - HTML export template split into separate files (template.html, template.css, template.js) for easier maintenance
Fixed
- HTML export now properly sanitizes user messages containing HTML tags like
<style>that could break DOM rendering - Crash when displaying bash output containing Unicode format characters like U+0600-U+0604 (#372 by @HACKE-RC)
- Footer shows full session stats: Token usage and cost now include all messages, not just those after compaction. (#322)
- Status messages spam chat log: Rapidly changing settings (e.g., thinking level via Shift+Tab) would add multiple status lines. Sequential status updates now coalesce into a single line. (#365 by @paulbettner)
- Toggling thinking blocks during streaming shows nothing: Pressing Ctrl+T while streaming would hide the current message until streaming completed.
- Resuming session resets thinking level to off: Initial model and thinking level were not saved to session file, causing
--resume/--continueto default tooff. (#342 by @aliou) - Hook
tool_resultevent ignores errors from custom tools: Thetool_resulthook event was never emitted when tools threw errors, and always hadisError: falsefor successful executions. Now emits the event with correctisErrorvalue in both success and error cases. (#374 by @nicobailon) - Edit tool fails on Windows due to CRLF line endings: Files with CRLF line endings now match correctly when LLMs send LF-only text. Line endings are normalized before matching and restored to original style on write. (#355 by @Pratham-Dubey)
- Edit tool fails on files with UTF-8 BOM: Files with UTF-8 BOM marker could cause "text not found" errors since the LLM doesn't include the invisible BOM character. BOM is now stripped before matching and restored on write. (#394 by @prathamdby)
- Use bash instead of sh on Unix: Fixed shell commands using
/bin/shinstead of/bin/bashon Unix systems. (#328 by @dnouri) - OAuth login URL clickable: Made OAuth login URLs clickable in terminal. (#349 by @Cursivez)
- Improved error messages: Better error messages when
apiKeyormodelare missing. (#346 by @ronyrus) - Session file validation:
findMostRecentSession()now validates session headers before returning, preventing non-session JSONL files from being loaded - Compaction error handling:
generateSummary()andgenerateTurnPrefixSummary()now throw on LLM errors instead of returning empty strings - Compaction with branched sessions: Fixed compaction incorrectly including entries from abandoned branches, causing token overflow errors. Compaction now uses
sessionManager.getPath()to work only on the current branch path, eliminating 80+ lines of duplicate entry collection logic betweenprepareCompaction()andcompact() - enabledModels glob patterns:
--modelsandenabledModelsnow support glob patterns likegithub-copilot/*or*sonnet*. Previously, patterns were only matched literally or via substring search. (#337)
[0.30.2] - 2025-12-26
Changed
- Consolidated migrations: Moved auth migration from
AuthStorage.migrateLegacy()to newmigrations.tsmodule.
[0.30.1] - 2025-12-26
Fixed
- Sessions saved to wrong directory: In v0.30.0, sessions were being saved to
~/.pi/agent/instead of~/.pi/agent/sessions/<encoded-cwd>/, breaking--resumeand/resume. Misplaced sessions are automatically migrated on startup. (#320 by @aliou) - Custom system prompts missing context: When using a custom system prompt string, project context files (AGENTS.md), skills, date/time, and working directory were not appended. (#321)
[0.30.0] - 2025-12-25
Breaking Changes
- SessionManager API: The second parameter of
create(),continueRecent(), andlist()changed fromagentDirtosessionDir. When provided, it specifies the session directory directly (no cwd encoding). When omitted, uses default (~/.pi/agent/sessions/<encoded-cwd>/).open()no longer takesagentDir. (#313)
Added
--session-dirflag: Use a custom directory for sessions instead of the default~/.pi/agent/sessions/<encoded-cwd>/. Works with-c(continue) and-r(resume) flags. (#313 by @scutifer)- Reverse model cycling and model selector: Shift+Ctrl+P cycles models backward, Ctrl+L opens model selector (retaining text in editor). (#315 by @mitsuhiko)
[0.29.1] - 2025-12-25
Added
- Automatic custom system prompt loading: Pi now auto-loads
SYSTEM.mdfiles to replace the default system prompt. Project-local.pi/SYSTEM.mdtakes precedence over global~/.pi/agent/SYSTEM.md. CLI--system-promptflag overrides both. (#309) - Unified
/settingscommand: New settings menu consolidating thinking level, theme, queue mode, auto-compact, show images, hide thinking, and collapse changelog. Replaces individual/thinking,/queue,/theme,/autocompact, and/show-imagescommands. (#310)
Fixed
- Custom tools/hooks with typebox subpath imports: Fixed jiti alias for
@sinclair/typeboxto point to package root instead of entry file, allowing imports like@sinclair/typebox/compilerto resolve correctly. (#311 by @kim0)
[0.29.0] - 2025-12-25
Breaking Changes
- Renamed
/clearto/new: The command to start a fresh session is now/new. Hook event reasonsbefore_clear/clearare nowbefore_new/new. Merry Christmas @mitsuhiko! (#305)
Added
- Auto-space before pasted file paths: When pasting a file path (starting with
/,~, or.) after a word character, a space is automatically prepended. (#307 by @mitsuhiko) - Word navigation in input fields: Added Ctrl+Left/Right and Alt+Left/Right for word-by-word cursor movement. (#306 by @kim0)
- Full Unicode input: Input fields now accept Unicode characters beyond ASCII. (#306 by @kim0)
Fixed
- Readline-style Ctrl+W: Now skips trailing whitespace before deleting the preceding word, matching standard readline behavior. (#306 by @kim0)
[0.28.0] - 2025-12-25
Changed
- Credential storage refactored: API keys and OAuth tokens are now stored in
~/.pi/agent/auth.jsoninstead ofoauth.jsonandsettings.json. Existing credentials are automatically migrated on first run. (#296) - SDK API changes (#296):
- Added
AuthStorageclass for credential management (API keys and OAuth tokens) - Added
ModelRegistryclass for model discovery and API key resolution - Added
discoverAuthStorage()anddiscoverModels()discovery functions createAgentSession()now acceptsauthStorageandmodelRegistryoptions- Removed
configureOAuthStorage(),defaultGetApiKey(),findModel(),discoverAvailableModels() - Removed
getApiKeycallback option (useAuthStorage.setRuntimeApiKey()for runtime overrides) - Use
getModel()from@oh-my-pi/pi-aifor built-in models,modelRegistry.find()for custom models + built-in models - See updated SDK documentation and README
- Added
- Settings changes: Removed
apiKeysfromsettings.json. Useauth.jsoninstead. (#296)
Fixed
- Duplicate skill warnings for symlinks: Skills loaded via symlinks pointing to the same file are now silently deduplicated instead of showing name collision warnings. (#304 by @mitsuhiko)
[0.27.9] - 2025-12-24
Fixed
- Model selector and --list-models with settings.json API keys: Models with API keys configured in settings.json (but not in environment variables) now properly appear in the /model selector and
--list-modelsoutput. (#295)
[0.27.8] - 2025-12-24
Fixed
- API key priority: OAuth tokens now take priority over settings.json API keys. Previously, an API key in settings.json would trump OAuth, causing users logged in with a plan (unlimited tokens) to be billed via PAYG instead.
[0.27.7] - 2025-12-24
Fixed
- Thinking tag leakage: Fixed Claude mimicking literal
</thinking>tags in responses. Unsigned thinking blocks (from aborted streams) are now converted to plain text without<thinking>tags. The TUI still displays them as thinking blocks. (#302 by @nicobailon)
[0.27.6] - 2025-12-24
Added
- Compaction hook improvements: The
before_compactsession event now includes:previousSummary: Summary from the last compaction (if any), so hooks can preserve accumulated contextmessagesToKeep: Messages that will be kept after the summary (recent turns), in addition tomessagesToSummarizeresolveApiKey: Function to resolve API keys for any model (checks settings, OAuth, env vars)- Removed
apiKeystring in favor ofresolveApiKeyfor more flexibility
- SessionManager API cleanup:
- Renamed
loadSessionFromEntries()tobuildSessionContext()(builds LLM context from entries, handling compaction) - Renamed
loadEntries()togetEntries()(returns defensive copy of all session entries) - Added
buildSessionContext()method to SessionManager
- Renamed
[0.27.5] - 2025-12-24
Added
- HTML export syntax highlighting: Code blocks in markdown and tool outputs (read, write) now have syntax highlighting using highlight.js with theme-aware colors matching the TUI.
- HTML export improvements: Render markdown server-side using marked (tables, headings, code blocks, etc.), honor user's chosen theme (light/dark), add image rendering for user messages, and style code blocks with TUI-like language markers. (@scutifer)
Fixed
- Ghostty inline images in tmux: Fixed terminal detection for Ghostty when running inside tmux by checking
GHOSTTY_RESOURCES_DIRenv var. (#299 by @nicobailon)
[0.27.4] - 2025-12-24
Fixed
- Symlinked skill directories: Skills in symlinked directories (e.g.,
~/.pi/agent/skills/my-skills -> /path/to/skills) are now correctly discovered and loaded.
[0.27.3] - 2025-12-24
Added
- API keys in settings.json: Store API keys in
~/.pi/agent/settings.jsonunder theapiKeysfield (e.g.,{ "apiKeys": { "anthropic": "sk-..." } }). Settings keys take priority over environment variables. (#295)
Fixed
- Allow startup without API keys: Interactive mode no longer throws when no API keys are configured. Users can now start the agent and use
/loginto authenticate. (#288) --system-promptfile path support: The--system-promptargument now correctly resolves file paths (like--append-system-promptalready did). (#287 by @scutifer)
[0.27.2] - 2025-12-23
Added
- Skip conversation restore on branch: Hooks can return
{ skipConversationRestore: true }frombefore_branchto create the branched session file without restoring conversation messages. Useful for checkpoint hooks that restore files separately. (#286 by @nicobarray)
[0.27.1] - 2025-12-22
Fixed
- Skill discovery performance: Skip
node_modulesdirectories when recursively scanning for skills. Fixes ~60ms startup delay when skill directories contain npm dependencies.
Added
- Startup timing instrumentation: Set
PI_TIMING=1to see startup performance breakdown (interactive mode only).
[0.27.0] - 2025-12-22
Breaking
- Session hooks API redesign: Merged
branchevent intosessionevent.BranchEvent,BranchEventResulttypes andpi.on("branch", ...)removed. Usepi.on("session", ...)withreason: "before_branch" | "branch"instead.AgentSession.branch()returns{ cancelled }instead of{ skipped }.AgentSession.reset()andswitchSession()now returnboolean(false if cancelled by hook). RPC commandsreset,switch_session, andbranchnow includecancelledin response data. (#278)
Added
- Session lifecycle hooks: Added
before_*variants (before_switch,before_clear,before_branch) that fire before actions and can be cancelled with{ cancel: true }. Addedshutdownreason for graceful exit handling. (#278)
Fixed
- File tab completion display: File paths no longer get cut off early. Folders now show trailing
/and removed redundant "directory"/"file" labels to maximize horizontal space. (#280) - Bash tool visual line truncation: Fixed bash tool output in collapsed mode to use visual line counting (accounting for line wrapping) instead of logical line counting. Now consistent with bash-execution.ts behavior. Extracted shared
truncateToVisualLinesutility. (#275)
[0.26.1] - 2025-12-22
Fixed
- SDK tools respect cwd: Core tools (bash, read, edit, write, grep, find, ls) now properly use the
cwdoption fromcreateAgentSession(). Added tool factory functions (createBashTool,createReadTool, etc.) for SDK users who specify customcwdwith explicit tools. (#279)
[0.26.0] - 2025-12-22
Added
- SDK for programmatic usage: New
createAgentSession()factory with full control over model, tools, hooks, skills, session persistence, and settings. Philosophy: "omit to discover, provide to override". Includes 12 examples and comprehensive documentation. (#272) - Project-specific settings: Settings now load from both
~/.pi/agent/settings.json(global) and<cwd>/.pi/settings.json(project). Project settings override global with deep merge for nested objects. Project settings are read-only (for version control). (#276) - SettingsManager static factories:
SettingsManager.create(cwd?, agentDir?)for file-based settings,SettingsManager.inMemory(settings?)for testing. AddedapplyOverrides()for programmatic overrides. - SessionManager static factories:
SessionManager.create(),SessionManager.open(),SessionManager.continueRecent(),SessionManager.inMemory(),SessionManager.list()for flexible session management.
[0.25.4] - 2025-12-22
Fixed
- Syntax highlighting stderr spam: Fixed cli-highlight logging errors to stderr when markdown contains malformed code fences (e.g., missing newlines around closing backticks). Now validates language identifiers before highlighting and falls back silently to plain text. (#274)
[0.25.3] - 2025-12-21
Added
- Gemini 3 preview models: Added
gemini-3-pro-previewandgemini-3-flash-previewto the google-gemini-cli provider. (#264 by @LukeFost) - External editor support: Press
Ctrl+Gto edit your message in an external editor. Uses$VISUALor$EDITORenvironment variable. On successful save, the message is replaced; on cancel, the original is kept. (#266 by @aliou) - Process suspension: Press
Ctrl+Zto suspend pi and return to the shell. Resume withfgas usual. (#267 by @aliou) - Configurable skills directories: Added granular control over skill sources with
enableCodexUser,enableClaudeUser,enableClaudeProject,enablePiUser,enablePiProjecttoggles, pluscustomDirectoriesandignoredSkillssettings. (#269 by @nicobailon) - Skills CLI filtering: Added
--skills <patterns>flag for filtering skills with glob patterns. Also addedincludeSkillssetting and glob pattern support forignoredSkills. (#268)
[0.25.2] - 2025-12-21
Fixed
- Image shifting in tool output: Fixed an issue where images in tool output would shift down (due to accumulating spacers) each time the tool output was expanded or collapsed via Ctrl+O.
[0.25.1] - 2025-12-21
Fixed
- Gemini image reading broken: Fixed the
readtool returning images causing flaky/broken responses with Gemini models. Images in tool results are now properly formatted per the Gemini API spec. - Tab completion for absolute paths: Fixed tab completion producing
//tmpinstead of/tmp/. Also fixed symlinks to directories (like/tmp) not getting a trailing slash, which prevented continuing to tab through subdirectories.
[0.25.0] - 2025-12-20
Added
- Interruptible tool execution: Queuing a message while tools are executing now interrupts the current tool batch. Remaining tools are skipped with an error result, and your queued message is processed immediately. Useful for redirecting the agent mid-task. (#259 by @steipete)
- Google Gemini CLI OAuth provider: Access Gemini 2.0/2.5 models for free via Google Cloud Code Assist. Login with
/loginand select "Google Gemini CLI". Uses your Google account with rate limits. - Google Antigravity OAuth provider: Access Gemini 3, Claude (sonnet/opus thinking models), and GPT-OSS models for free via Google's Antigravity sandbox. Login with
/loginand select "Antigravity". Uses your Google account with rate limits.
Changed
- Model selector respects --models scope: The
/modelcommand now only shows models specified via--modelsflag when that flag is used, instead of showing all available models. This prevents accidentally selecting models from unintended providers. (#255)
Fixed
- Connection errors not retried: Added "connection error" to the list of retryable errors so Anthropic connection drops trigger auto-retry instead of silently failing. (#252)
- Thinking level not clamped on model switch: Fixed TUI showing xhigh thinking level after switching to a model that doesn't support it. Thinking level is now automatically clamped to model capabilities. (#253)
- Cross-model thinking handoff: Fixed error when switching between models with different thinking signature formats (e.g., GPT-OSS to Claude thinking models via Antigravity). Thinking blocks without signatures are now converted to text with
<thinking>delimiters.
[0.24.5] - 2025-12-20
Fixed
- Input buffering in iTerm2: Fixed Ctrl+C, Ctrl+D, and other keys requiring multiple presses in iTerm2. The cell size query response parser was incorrectly holding back keyboard input.
[0.24.4] - 2025-12-20
Fixed
- Arrow keys and Enter in selector components: Fixed arrow keys and Enter not working in model selector, session selector, OAuth selector, and other selector components when Caps Lock or Num Lock is enabled. (#243)
[0.24.3] - 2025-12-19
Fixed
- Footer overflow on narrow terminals: Fixed footer path display exceeding terminal width when resizing to very narrow widths, causing rendering crashes. /arminsayshi
[0.24.2] - 2025-12-20
Fixed
- More Kitty keyboard protocol fixes: Fixed Backspace, Enter, Home, End, and Delete keys not working with Caps Lock enabled. The initial fix in 0.24.1 missed several key handlers that were still using raw byte detection. Now all key handlers use the helper functions that properly mask out lock key bits. (#243)
[0.24.1] - 2025-12-19
Added
- OAuth and model config exports: Scripts using
AgentSessiondirectly can now importgetAvailableModels,getApiKeyForModel,findModel,login,logout, andgetOAuthProvidersfrom@oh-my-pi/pi-coding-agentto reuse OAuth token storage and model resolution. (#245) - xhigh thinking level for gpt-5.2 models: The thinking level selector and shift+tab cycling now show xhigh option for gpt-5.2 and gpt-5.2-codex models (in addition to gpt-5.1-codex-max). (#236 by @theBucky)
Fixed
- Hooks wrap custom tools: Custom tools are now executed through the hook wrapper, so
tool_call/tool_resulthooks can observe, block, and modify custom tool executions (consistent with hook type docs). (#248 by @nicobailon) - Hook onUpdate callback forwarding: The
onUpdatecallback is now correctly forwarded through the hook wrapper, fixing custom tool progress updates. (#238 by @nicobailon) - Terminal cleanup on Ctrl+C in session selector: Fixed terminal not being properly restored when pressing Ctrl+C in the session selector. (#247 by @aliou)
- OpenRouter models with colons in IDs: Fixed parsing of OpenRouter model IDs that contain colons (e.g.,
openrouter:meta-llama/llama-4-scout:free). (#242 by @aliou) - Global AGENTS.md loaded twice: Fixed global AGENTS.md being loaded twice when present in both
~/.pi/agent/and the current directory. (#239 by @aliou) - Kitty keyboard protocol on Linux: Fixed keyboard input not working in Ghostty on Linux when Num Lock is enabled. The Kitty protocol includes Caps Lock and Num Lock state in modifier values, which broke key detection. Now correctly masks out lock key bits when matching keyboard shortcuts. (#243)
- Emoji deletion and cursor movement: Backspace, Delete, and arrow keys now correctly handle multi-codepoint characters like emojis. Previously, deleting an emoji would leave partial bytes, corrupting the editor state. (#240)
[0.24.0] - 2025-12-19
Added
- Subagent orchestration example: Added comprehensive custom tool example for spawning and orchestrating sub-agents with isolated context windows. Includes scout/planner/reviewer/worker agents and workflow commands for multi-agent pipelines. (#215 by @nicobailon)
getMarkdownTheme()export: Custom tools can now importgetMarkdownTheme()from@oh-my-pi/pi-coding-agentto use the same markdown styling as the main UI.pi.exec()signal and timeout support: Custom tools and hooks can now pass{ signal, timeout }options topi.exec()for cancellation and timeout handling. The result includes akilledflag when the process was terminated.- Kitty keyboard protocol support: Shift+Enter, Alt+Enter, Shift+Tab, Ctrl+D, and all Ctrl+key combinations now work in Ghostty, Kitty, WezTerm, and other modern terminals. (#225 by @kim0)
- Dynamic API key refresh: OAuth tokens (GitHub Copilot, Anthropic OAuth) are now refreshed before each LLM call, preventing failures in long-running agent loops where tokens expire mid-session. (#223 by @kim0)
/hotkeyscommand: Shows all keyboard shortcuts in a formatted table.- Markdown table borders: Tables now render with proper top and bottom borders.
Changed
- Subagent example improvements: Parallel mode now streams updates from all tasks. Chain mode shows all completed steps during streaming. Expanded view uses proper markdown rendering with syntax highlighting. Usage footer shows turn count.
- Skills standard compliance: Skills now adhere to the Agent Skills standard. Validates name (must match parent directory, lowercase, max 64 chars), description (required, max 1024 chars), and frontmatter fields. Warns on violations but remains lenient. Prompt format changed to XML structure. Removed
{baseDir}placeholder in favor of relative paths. (#231)
Fixed
- JSON mode stdout flush: Fixed race condition where
pi --mode jsoncould exit before all output was written to stdout, causing consumers to miss final events. - Symlinked tools, hooks, and slash commands: Discovery now correctly follows symlinks when scanning for custom tools, hooks, and slash commands. (#219, #232 by @aliou)
Breaking Changes
- Custom tools now require
index.tsentry point: Auto-discovered custom tools must be in a subdirectory with anindex.tsfile. The old pattern~/.pi/agent/tools/mytool.tsmust become~/.pi/agent/tools/mytool/index.ts. This allows multi-file tools to import helper modules. Explicit paths via--toolorsettings.jsonstill work with any.tsfile. - Hook
tool_resultevent restructured: TheToolResultEventnow exposes full tool result data instead of just text. (#233)- Removed:
result: stringfield - Added:
content: (TextContent | ImageContent)[]- full content array - Added:
details: unknown- tool-specific details (typed per tool via discriminated union ontoolName) ToolResultEventResult.resultrenamed toToolResultEventResult.text(removed), usecontentinstead- Hook handlers returning
{ result: "..." }must change to{ content: [{ type: "text", text: "..." }] } - Built-in tool details types exported:
BashToolDetails,ReadToolDetails,GrepToolDetails,FindToolDetails,LsToolDetails,TruncationResult - Type guards exported for narrowing:
isBashToolResult,isReadToolResult,isEditToolResult,isWriteToolResult,isGrepToolResult,isFindToolResult,isLsToolResult
- Removed:
[0.23.4] - 2025-12-18
Added
- Syntax highlighting: Added syntax highlighting for markdown code blocks, read tool output, and write tool content. Uses cli-highlight with theme-aware color mapping and VS Code-style syntax colors. (#214 by @svkozak)
- Intra-line diff highlighting: Edit tool now shows word-level changes with inverse highlighting when a single line is modified. Multi-line changes show all removed lines first, then all added lines.
Fixed
- Gemini tool result format: Fixed tool result format for Gemini 3 Flash Preview which strictly requires
{ output: value }for success and{ error: value }for errors. Previous format using{ result, isError }was rejected by newer Gemini models. (#213, #220) - Google baseUrl configuration: Google provider now respects
baseUrlconfiguration for custom endpoints or API proxies. (#216, #221 by @theBucky) - Google provider FinishReason: Added handling for new
IMAGE_RECITATIONandIMAGE_OTHERfinish reasons. Upgraded @google/genai to 1.34.0.
[0.23.3] - 2025-12-17
Fixed
- Check for compaction before submitting user prompt, not just after agent turn ends. This catches cases where user aborts mid-response and context is already near the limit.
Changed
- Improved system prompt documentation section with clearer pointers to specific doc files for custom models, themes, skills, hooks, custom tools, and RPC.
- Cleaned up documentation:
theme.md: Added missing color tokens (thinkingXhigh,bashMode)skills.md: Rewrote with better framing and exampleshooks.md: Fixed timeout/error handling docs, added import aliases sectioncustom-tools.md: Added intro with use cases and comparison tablerpc.md: Added missinghook_errorevent documentationREADME.md: Complete settings table, condensed philosophy section, standardized OAuth docs
- Hooks loader now supports same import aliases as custom tools (
@sinclair/typebox,@oh-my-pi/pi-ai,@oh-my-pi/pi-tui,@oh-my-pi/pi-coding-agent).
Breaking Changes
- Hooks:
turn_endevent'stoolResultstype changed fromAppMessage[]toToolResultMessage[]. If you have hooks that handleturn_endevents and explicitly type the results, update your type annotations.
[0.23.2] - 2025-12-17
Fixed
- Fixed Claude models via GitHub Copilot re-answering all previous prompts in multi-turn conversations. The issue was that assistant message content was sent as an array instead of a string, which Copilot's Claude adapter misinterpreted. Also added missing
Openai-Intent: conversation-editsheader and fixedX-Initiatorlogic to check for any assistant/tool message in history. (#209) - Detect image MIME type via file magic (read tool and
@fileattachments), not filename extension. - Fixed markdown tables overflowing terminal width. Tables now wrap cell contents to fit available width instead of breaking borders mid-row. (#206 by @kim0)
[0.23.1] - 2025-12-17
Fixed
- Fixed TUI performance regression caused by Box component lacking render caching. Built-in tools now use Text directly (like v0.22.5), and Box has proper caching for custom tool rendering.
- Fixed custom tools failing to load from
~/.pi/agent/tools/when pi is installed globally. Module imports (@sinclair/typebox,@oh-my-pi/pi-tui,@oh-my-pi/pi-ai) are now resolved via aliases.
[0.23.0] - 2025-12-17
Added
- Custom tools: Extend pi with custom tools written in TypeScript. Tools can provide custom TUI rendering, interact with users via
pi.ui(select, confirm, input, notify), and maintain state across sessions viaonSessioncallback. See docs/custom-tools.md and examples/custom-tools/. (#190) - Hook and tool examples: Added
examples/hooks/andexamples/custom-tools/with working examples. Examples are now bundled in npm and binary releases.
Breaking Changes
- Hooks: Replaced
session_startandsession_switchevents with unifiedsessionevent. Useevent.reason("start" | "switch" | "clear") to distinguish. Event now includesentriesarray for state reconstruction.
[0.22.5] - 2025-12-17
Fixed
- Fixed
--sessionflag not saving sessions in print mode (-p). The session manager was never receiving events because no subscriber was attached.
[0.22.4] - 2025-12-17
Added
--list-models [search]CLI flag to list available models with optional fuzzy search. Shows provider, model ID, context window, max output, thinking support, and image support. Only lists models with configured API keys. (#203)
Fixed
- Fixed tool execution showing green (success) background while still running. Now correctly shows gray (pending) background until the tool completes.
[0.22.3] - 2025-12-16
Added
- Streaming bash output: Bash tool now streams output in real-time during execution. The TUI displays live progress with the last 5 lines visible (expandable with ctrl+o). (#44)
Changed
- Tool output display: When collapsed, tool output now shows the last N lines instead of the first N lines, making streaming output more useful.
- Updated
@oh-my-pi/pi-aiwith X-Initiator header support for GitHub Copilot, ensuring agent calls are not deducted from quota. (#200 by @kim0)
Fixed
- Fixed editor text being cleared during compaction. Text typed while compaction is running is now preserved. (#179)
- Improved RGB to 256-color mapping for terminals without truecolor support. Now correctly uses grayscale ramp for neutral colors and preserves semantic tints (green for success, red for error, blue for pending) instead of mapping everything to wrong cube colors.
/think offnow actually disables thinking for all providers. Previously, providers like Gemini with "dynamic thinking" enabled by default would still use thinking even when turned off. (#180 by @markusylisiurunen)
[0.22.2] - 2025-12-15
Changed
- Updated
@oh-my-pi/pi-aiwith interleaved thinking enabled by default for Anthropic Claude 4 models.
[0.22.1] - 2025-12-15
Dedicated to Peter's shoulder (@steipete)
Changed
- Updated
@oh-my-pi/pi-aiwith interleaved thinking support for Anthropic models.
[0.22.0] - 2025-12-15
Added
- GitHub Copilot support: Use GitHub Copilot models via OAuth login (
/login-> "GitHub Copilot"). Supports both github.com and GitHub Enterprise. Models are sourced from models.dev and include Claude, GPT, Gemini, Grok, and more. All models are automatically enabled after login. (#191 by @cau1k)
Fixed
- Model selector fuzzy search now matches against provider name (not just model ID) and supports space-separated tokens where all tokens must match
[0.21.0] - 2025-12-14
Added
- Inline image rendering: Terminals supporting Kitty graphics protocol (Kitty, Ghostty, WezTerm) or iTerm2 inline images now render images inline in tool output. Aspect ratio is preserved by querying terminal cell dimensions on startup. Toggle with
/show-imagescommand orterminal.showImagessetting. Falls back to text placeholder on unsupported terminals or when disabled. (#177 by @nicobailon) - Gemini 3 Pro thinking levels: Thinking level selector now works with Gemini 3 Pro models. Minimal/low map to Google's LOW, medium/high map to Google's HIGH. (#176 by @markusylisiurunen)
Fixed
- Fixed read tool failing on macOS screenshot filenames due to Unicode Narrow No-Break Space (U+202F) in timestamp. Added fallback to try macOS variant paths and consolidated duplicate expandPath functions into shared path-utils.ts. (#181 by @nicobailon)
- Fixed double blank lines rendering after markdown code blocks (#173 by @markusylisiurunen)
[0.20.1] - 2025-12-13
Added
- Exported skills API:
loadSkillsFromDir,formatSkillsForPrompt, and related types are now exported for use by other packages (e.g., mom).
[0.20.0] - 2025-12-13
Breaking Changes
- Pi skills now use
SKILL.mdconvention: Pi skills must now be namedSKILL.mdinside a directory, matching Codex CLI format. Previously any*.mdfile was treated as a skill. Migrate by renaming~/.pi/agent/skills/foo.mdto~/.pi/agent/skills/foo/SKILL.md.
Added
- Display loaded skills on startup in interactive mode
[0.19.1] - 2025-12-12
Fixed
- Documentation: Added skills system documentation to README (setup, usage, CLI flags, settings)
[0.19.0] - 2025-12-12
Added
- Skills system: Auto-discover and load instruction files on-demand. Supports Claude Code (
~/.claude/skills/*/SKILL.md), Codex CLI (~/.codex/skills/), and Pi-native formats (~/.pi/agent/skills/,.pi/skills/). Skills are listed in system prompt with descriptions, agent loads them via read tool when needed. Supports{baseDir}placeholder. Disable with--no-skillsorskills.enabled: falsein settings. (#169) - Version flag: Added
--version/-vflag to display the current version and exit. (#170)
[0.18.2] - 2025-12-11
Added
- Auto-retry on transient errors: Automatically retries requests when providers return overloaded, rate limit, or server errors (429, 500, 502, 503, 504). Uses exponential backoff (2s, 4s, 8s). Shows retry status in TUI with option to cancel via Escape. Configurable in
settings.jsonviaretry.enabled,retry.maxRetries,retry.baseDelayMs. RPC mode emitsauto_retry_startandauto_retry_endevents. (#157) - HTML export line numbers: Read tool calls in HTML exports now display line number ranges (e.g.,
file.txt:10-20) when offset/limit parameters are used, matching the TUI display format. Line numbers appear in yellow color for better visibility. (#166)
Fixed
- Branch selector now works with single message: Previously the branch selector would not open when there was only one user message. Now it correctly allows branching from any message, including the first one. This is needed for checkpoint hooks to restore state from before the first message. (#163)
- In-memory branching for
--no-sessionmode: Branching now works correctly in--no-sessionmode without creating any session files. The conversation is truncated in memory. - Git branch indicator now works in subdirectories: The footer's git branch detection now walks up the directory hierarchy to find the git root, so it works when running pi from a subdirectory of a repository. (#156)
[0.18.1] - 2025-12-10
Added
- Mistral provider: Added support for Mistral AI models. Set
MISTRAL_API_KEYenvironment variable to use.
Fixed
- Fixed print mode (
-p) not exiting after output when custom themes are present (theme watcher now properly stops in print mode) (#161)
[0.18.0] - 2025-12-10
Added
- Hooks system: TypeScript modules that extend agent behavior by subscribing to lifecycle events. Hooks can intercept tool calls, prompt for confirmation, modify results, and inject messages from external sources. Auto-discovered from
~/.pi/agent/hooks/*.tsand.pi/hooks/*.ts. Thanks to @nicobailon for the collaboration on the design and implementation. (#145, supersedes #158) pi.send()API: Hooks can inject messages into the agent session from external sources (file watchers, webhooks, CI systems). If streaming, messages are queued; otherwise a new agent loop starts immediately.--hook <path>CLI flag: Load hook files directly for testing without modifying settings.- Hook events:
session_start,session_switch,agent_start,agent_end,turn_start,turn_end,tool_call(can block),tool_result(can modify),branch. - Hook UI primitives:
ctx.ui.select(),ctx.ui.confirm(),ctx.ui.input(),ctx.ui.notify()for interactive prompts from hooks. - Hooks documentation: Full API reference at
docs/hooks.md, shipped with npm package.
[0.17.0] - 2025-12-09
Changed
- Simplified compaction flow: Removed proactive compaction (aborting mid-turn when threshold approached). Compaction now triggers in two cases only: (1) overflow error from LLM, which compacts and auto-retries, or (2) threshold crossed after a successful turn, which compacts without retry.
- Compaction retry uses
Agent.continue(): Auto-retry after overflow now uses the newcontinue()API instead of re-sending the user message, preserving exact context state. - Merged turn prefix summary: When a turn is split during compaction, the turn prefix summary is now merged into the main history summary instead of being stored separately.
Added
isCompactingproperty on AgentSession: Check if auto-compaction is currently running.- Session compaction indicator: When resuming a compacted session, displays "Session compacted N times" status message.
Fixed
- Block input during compaction: User input is now blocked while auto-compaction is running to prevent race conditions.
- Skip error messages in usage calculation: Context size estimation now skips both aborted and error messages, as neither have valid usage data.
[0.16.0] - 2025-12-09
Breaking Changes
- New RPC protocol: The RPC mode (
--mode rpc) has been completely redesigned with a new JSON protocol. The old protocol is no longer supported. Seedocs/rpc.mdfor the new protocol documentation andtest/rpc-example.tsfor a working example. IncludesRpcClientTypeScript class for easy integration. (#91)
Changed
- README restructured: Reorganized documentation from 30+ flat sections into 10 logical groups. Converted verbose subsections to scannable tables. Consolidated philosophy sections. Reduced size by ~60% while preserving all information.
[0.15.0] - 2025-12-09
Changed
- Major code refactoring: Restructured codebase for better maintainability and separation of concerns. Moved files into organized directories (
core/,modes/,utils/,cli/). ExtractedAgentSessionclass as central session management abstraction. Splitmain.tsandtui-renderer.tsinto focused modules. SeeDEVELOPMENT.mdfor the new code map. (#153)
[0.14.2] - 2025-12-08
Added
/debugcommand now includes agent messages as JSONL in the output
Fixed
- Fix crash when bash command outputs binary data (e.g.,
curldownloading a video file)
[0.14.1] - 2025-12-08
Fixed
- Fix build errors with tsgo 7.0.0-dev.20251208.1 by properly importing
ReasoningEfforttype
[0.14.0] - 2025-12-08
Breaking Changes
- Custom themes require new color tokens: Themes must now include
thinkingXhighandbashModecolor tokens. The theme loader provides helpful error messages listing missing tokens. See built-in themes (dark.json, light.json) for reference values.
Added
- OpenAI compatibility overrides in models.json: Custom models using
openai-completionsAPI can now specify acompatobject to override provider quirks (supportsStore,supportsDeveloperRole,supportsReasoningEffort,maxTokensField). Useful for LiteLLM, custom proxies, and other non-standard endpoints. (#133, thanks @fink-andreas for the initial idea and PR) - xhigh thinking level: Added
xhighthinking level for OpenAI codex-max models. Cycle through thinking levels with Shift+Tab;xhighappears only when using a codex-max model. (#143) - Collapse changelog setting: Add
"collapseChangelog": trueto~/.pi/agent/settings.jsonto show a condensed "Updated to vX.Y.Z" message instead of the full changelog after updates. Use/changelogto view the full changelog. (#148) - Bash mode: Execute shell commands directly from the editor by prefixing with
!(e.g.,!ls -la). Output streams in real-time, is added to the LLM context, and persists in session history. Supports multiline commands, cancellation (Escape), truncation for large outputs, and preview/expand toggle (Ctrl+O). Also available in RPC mode via{"type":"bash","command":"..."}. (#112, original implementation by @markusylisiurunen)
[0.13.2] - 2025-12-07
Changed
- Tool output truncation: All tools now enforce consistent truncation limits with actionable notices for the LLM. (#134)
- Limits: 2000 lines OR 50KB (whichever hits first), never partial lines
- read: Shows
[Showing lines X-Y of Z. Use offset=N to continue]. If first line exceeds 50KB, suggests bash command - bash: Tail truncation with temp file. Shows
[Showing lines X-Y of Z. Full output: /tmp/...] - grep: Pre-truncates match lines to 500 chars. Shows match limit and line truncation notices
- find/ls: Shows result/entry limit notices
- TUI displays truncation warnings in yellow at bottom of tool output (visible even when collapsed)
[0.13.1] - 2025-12-06
Added
- Flexible Windows shell configuration: The bash tool now supports multiple shell sources beyond Git Bash. Resolution order: (1) custom
shellPathin settings.json, (2) Git Bash in standard locations, (3) any bash.exe on PATH. This enables Cygwin, MSYS2, and other bash environments. Configure with~/.pi/agent/settings.json:{"shellPath": "C:\\cygwin64\\bin\\bash.exe"}.
Fixed
- Windows binary detection: Fixed Bun compiled binary detection on Windows by checking for URL-encoded
%7EBUNin addition to$bunfsand~BUNinimport.meta.url. This ensures the binary correctly locates supporting files (package.json, themes, etc.) next to the executable.
[0.12.15] - 2025-12-06
Fixed
- Editor crash with emojis/CJK characters: Fixed crash when pasting or typing text containing wide characters (emojis like ✅, CJK characters) that caused line width to exceed terminal width. The editor now uses grapheme-aware text wrapping with proper visible width calculation.
[0.12.14] - 2025-12-06
Added
- Double-Escape Branch Shortcut: Press Escape twice with an empty editor to quickly open the
/branchselector for conversation branching.
[0.12.13] - 2025-12-05
Changed
- Faster startup: Version check now runs in parallel with TUI initialization instead of blocking startup for up to 1 second. Update notifications appear in chat when the check completes.
[0.12.12] - 2025-12-05
Changed
- Footer display: Token counts now use M suffix for millions (e.g.,
10.2Minstead of10184k). Context display shortened from61.3% of 200kto61.3%/200k.
Fixed
- Multi-key sequences in inputs: Inputs like model search now handle multi-key sequences identically to the main prompt editor. (#122 by @markusylisiurunen)
- Line wrapping escape codes: Fixed underline style bleeding into padding when wrapping long URLs. ANSI codes now attach to the correct content, and line-end resets only turn off underline (preserving background colors). (#109)
Added
- Fuzzy search models and sessions: Implemented a simple fuzzy search for models and sessions (e.g.,
codexmaxnow findsgpt-5.1-codex-max). (#122 by @markusylisiurunen) - Prompt History Navigation: Browse previously submitted prompts using Up/Down arrow keys when the editor is empty. Press Up to cycle through older prompts, Down to return to newer ones or clear the editor. Similar to shell history and Claude Code's prompt history feature. History is session-scoped and stores up to 100 entries. (#121 by @nicobailon)
/resumeCommand: Switch to a different session mid-conversation. Opens an interactive selector showing all available sessions. Equivalent to the--resumeCLI flag but can be used without restarting the agent. (#117 by @hewliyang)
[0.12.11] - 2025-12-05
Changed
- Compaction UI: Simplified collapsed compaction indicator to show warning-colored text with token count instead of styled banner. Removed redundant success message after compaction. (#108)
Fixed
- Print mode error handling:
-pflag now outputs error messages and exits with code 1 when requests fail, instead of silently producing no output. - Branch selector crash: Fixed TUI crash when user messages contained Unicode characters (like
✔or›) that caused line width to exceed terminal width. Now uses propertruncateToWidthinstead ofsubstring. - Bash output escape sequences: Fixed incomplete stripping of terminal escape sequences in bash tool output.
stripAnsimisses some sequences like standalone String Terminator (ESC \), which could cause rendering issues when displaying captured TUI output. - Footer overflow crash: Fixed TUI crash when terminal width is too narrow for the footer stats line. The footer now truncates gracefully instead of overflowing.
Added
authHeaderoption in models.json: Custom providers can set"authHeader": trueto automatically addAuthorization: Bearer <apiKey>header. Useful for providers that require explicit auth headers. (#81)--append-system-promptFlag: Append additional text or file contents to the system prompt. Supports both inline text and file paths. Complements--system-promptfor layering custom instructions without replacing the base system prompt. (#114 by @markusylisiurunen)- Thinking Block Toggle: Added
Ctrl+Tshortcut to toggle visibility of LLM thinking blocks. When toggled off, shows a static "Thinking..." label instead of full content. Useful for reducing visual clutter during long conversations. (#113 by @markusylisiurunen)
[0.12.10] - 2025-12-04
Added
- Added
gpt-5.1-codex-maxmodel support
[0.12.9] - 2025-12-04
Added
/copyCommand: Copy the last agent message to clipboard. Works cross-platform (macOS, Windows, Linux). Useful for extracting text from rendered Markdown output. (#105 by @markusylisiurunen)
[0.12.8] - 2025-12-04
- Fix: Use CTRL+O consistently for compaction expand shortcut (not CMD+O on Mac)
[0.12.7] - 2025-12-04
Added
- Context Compaction: Long sessions can now be compacted to reduce context usage while preserving recent conversation history. (#92, docs)
/compact [instructions]: Manually compact context with optional custom instructions for the summary/autocompact: Toggle automatic compaction when context exceeds threshold- Compaction summarizes older messages while keeping recent messages (default 20k tokens) verbatim
- Auto-compaction triggers when context reaches
contextWindow - reserveTokens(default 16k reserve) - Compacted sessions show a collapsible summary in the TUI (toggle with
okey) - HTML exports include compaction summaries as collapsible sections
- RPC mode supports
{"type":"compact"}command and auto-compaction (emits compaction events)
- Branch Source Tracking: Branched sessions now store
branchedFromin the session header, containing the path to the original session file. Useful for tracing session lineage.
[0.12.5] - 2025-12-03
Added
- Forking/Rebranding Support: All branding (app name, config directory, environment variable names) is now configurable via
piConfiginpackage.json. Forks can changepiConfig.nameandpiConfig.configDirto rebrand the CLI without code changes. Affects CLI banner, help text, config paths, and error messages. (#95)
Fixed
- Bun Binary Detection: Fixed Bun compiled binary failing to start after Bun updated its virtual filesystem path format from
%7EBUNto$bunfs. (#95)
[0.12.4] - 2025-12-02
Added
- RPC Termination Safeguard: When running as an RPC worker (stdin pipe detected), the CLI now exits immediately if the parent process terminates unexpectedly. Prevents orphaned RPC workers from persisting indefinitely and consuming system resources.
[0.12.3] - 2025-12-02
Fixed
- Rate limit handling: Anthropic rate limit errors now trigger automatic retry with exponential backoff (base 10s, max 5 retries). Previously these errors would abort the request immediately.
- Usage tracking during retries: Retried requests now correctly accumulate token usage from all attempts, not just the final successful one. Fixes artificially low token counts when requests were retried.
[0.12.2] - 2025-12-02
Changed
- Removed support for gpt-4.5-preview and o3 models (not yet available)
[0.12.1] - 2025-12-02
Added
- Models: Added support for OpenAI's new models:
gpt-4.1(128K context)gpt-4.1-mini(128K context)gpt-4.1-nano(128K context)o3(200K context, reasoning model)o4-mini(200K context, reasoning model)
[0.12.0] - 2025-12-02
Added
-p, --printFlag: Run in non-interactive batch mode. Processes input message or piped stdin without TUI, prints agent response directly to stdout. Ideal for scripting, piping, and CI/CD integration. Exits after first response.-P, --print-streamingFlag: Like-p, but streams response tokens as they arrive. Use--print-streaming --no-markdownfor raw unformatted output.--print-turnFlag: Continue processing tool calls and agent turns until the agent naturally finishes or requires user input. Combine with-pfor complete multi-turn conversations.--no-markdownFlag: Output raw text without Markdown formatting. Useful when piping output to tools that expect plain text.- Streaming Print Mode: Added internal
printStreamingoption for streaming output in non-TUI mode. - RPC Mode
printCommand: Send{"type":"print","content":"text"}to get formatted print output viaprint_outputevents. - Auto-Save in Print Mode: Print mode conversations are automatically saved to the session directory, allowing later resumption with
--continue. - Thinking level options: Added
--thinking-off,--thinking-minimal,--thinking-low,--thinking-medium,--thinking-highflags for directly specifying thinking level without the selector UI.
Changed
- Simplified RPC Protocol: Replaced the
promptwrapper command with direct message objects. Send{"role":"user","content":"text"}instead of{"type":"prompt","message":"text"}. Better aligns with message format throughout the codebase. - RPC Message Handling: Agent now processes raw message objects directly, with
timestampauto-populated if missing.
[0.11.9] - 2025-12-02
Changed
- Change Ctrl+I to Ctrl+P for model cycling shortcut to avoid collision with Tab key in some terminals
[0.11.8] - 2025-12-01
Fixed
- Absolute glob patterns (e.g.,
/Users/foo/**/*.ts) are now handled correctly. Previously the leading/was being stripped, causing the pattern to be interpreted relative to the current directory.
[0.11.7] - 2025-12-01
Fixed
- Fix read path traversal vulnerability. Paths are now validated to prevent reading outside the working directory or its parents. The
readtool can read fromcwd, its ancestors (for config files), and all descendants. Symlinks are resolved before validation.
[0.11.6] - 2025-12-01
Fixed
- Fix
--system-prompt <path>allowing the path argument to be captured by the message collection, causing "file not found" errors.
[0.11.5] - 2025-11-30
Fixed
- Fixed fatal error "Cannot set properties of undefined (setting '0')" when editing empty files in the
edittool. - Simplified
edittool output: Shows only "Edited file.txt" for successful edits instead of verbose search/replace details. - Fixed fatal error in footer rendering when token counts contain NaN values due to missing usage data.
[0.11.4] - 2025-11-30
Fixed
- Fixed chat rendering crash when messages contain preformatted/styled text (e.g., thinking traces with gray italic styling). The markdown renderer now preserves existing ANSI escape codes when they appear before inline elements.
[0.11.3] - 2025-11-29
Fixed
- Fix file drop functionality for absolute paths
[0.11.2] - 2025-11-29
Fixed
- Fixed TUI crash when pasting content containing tab characters. Tabs are now converted to 4 spaces before insertion.
- Fixed terminal corruption after exit when shell integration sequences (OSC 133) appeared in bash output. These sequences are now stripped along with other ANSI codes.
[0.11.1] - 2025-11-29
Added
- Added
fdintegration for file path autocompletion. Now usesfdfor faster fuzzy file search
Fixed
- Fixed keyboard shortcuts Ctrl+A, Ctrl+E, Ctrl+K, Ctrl+U, Ctrl+W, and word navigation (Option+Arrow) not working in VS Code integrated terminal and some other terminal emulators
[0.11.0] - 2025-11-29
Added
- File-based Slash Commands: Create custom reusable prompts as
.txtfiles in~/.pi/slash-commands/. Files become/filenamecommands with first-line descriptions. Supports{{selection}}placeholder for referencing selected/attached content. /branchCommand: Create conversation branches from any previous user message. Opens a selector to pick a message, then creates a new session file starting from that point. Original message text is placed in the editor for modification.- Unified Content References: Both
@pathin messages and--file pathCLI arguments now use the same attachment system with consistent MIME type detection. - Drag & Drop Files: Drop files onto the terminal to attach them to your message. Supports multiple files and both text and image content.
Changed
- Model Selector with Search: The
/modelcommand now opens a searchable list. Type to filter models by name, use arrows to navigate, Enter to select. - Improved File Autocomplete: File path completion after
@now supports fuzzy matching and shows file/directory indicators. - Session Selector with Search: The
--resumeand--sessionflags now open a searchable session list with fuzzy filtering. - Attachment Display: Files added via
@pathare now shown as "Attached: filename" in the user message, separate from the prompt text. - Tab Completion: Tab key now triggers file path autocompletion anywhere in the editor, not just after
@symbol.
Fixed
- Fixed autocomplete z-order issue where dropdown could appear behind chat messages
- Fixed cursor position when navigating through wrapped lines in the editor
- Fixed attachment handling for continued sessions to preserve file references
[0.10.6] - 2025-11-28
Changed
- Show base64-truncated indicator for large images in tool output
Fixed
- Fixed image dimensions not being read correctly from PNG/JPEG/GIF files
- Fixed PDF images being incorrectly base64-truncated in display
- Allow reading files from ancestor directories (needed for monorepo configs)
[0.10.5] - 2025-11-28
Added
- Full multimodal support: attach images (PNG, JPEG, GIF, WebP) and PDFs to prompts using
@pathsyntax or--fileflag
Fixed
@-references now handle special characters in file names (spaces, quotes, unicode)- Fixed cursor positioning issues with multi-byte unicode characters in editor
[0.10.4] - 2025-11-28
Fixed
- Removed padding on first user message in TUI to improve visual consistency.
[0.10.3] - 2025-11-28
Added
- Added RPC mode (
--rpc) for programmatic integration. Accepts JSON commands on stdin, emits JSON events on stdout. See RPC mode documentation for protocol details.
Changed
- Refactored internal architecture to support multiple frontends (TUI, RPC) with shared agent logic.
[0.10.2] - 2025-11-26
Added
- Added thinking level persistence. Default level stored in
~/.pi/settings.json, restored on startup. Per-session overrides saved in session files. - Added model cycling shortcut:
Ctrl+Icycles through available models (or scoped models with-mflag). - Added automatic retry with exponential backoff for transient API errors (network issues, 500s, overload).
- Cumulative token usage now shown in footer (total tokens used across all messages in session).
- Added
--system-promptflag to override default system prompt with custom text or file contents. - Footer now shows estimated total cost in USD based on model pricing.
Changed
- Replaced
--modelsflag with-m/--modelsupporting multiple values. Specify models asprovider/model@thinking(e.g.,anthropic/claude-sonnet-4-20250514@high). Multiple-mflags scope available models for the session. - Thinking level border now persists visually after selector closes.
- Improved tool result display with collapsible output (default collapsed, expand with
Ctrl+O).
[0.10.1] - 2025-11-25
Added
- Add custom model configuration via
~/.pi/models.json
[0.10.0] - 2025-11-25
Initial public release.
Added
- Interactive TUI with streaming responses
- Conversation session management with
--continue,--resume, and--sessionflags - Multi-line input support (Shift+Enter or Option+Enter for new lines)
- Tool execution:
read,write,edit,bash,glob,grep,think - Thinking mode support for Claude with visual indicator and
/thinkingselector - File path autocompletion with
@prefix - Slash command autocompletion
/exportcommand for HTML session export/modelcommand for runtime model switching/sessioncommand for session statistics- Model provider support: Anthropic (Claude), OpenAI, Google (Gemini)
- Git branch display in footer
- Message queueing during streaming responses
- OAuth integration for Gmail and Google Calendar access
- HTML export with syntax highlighting and collapsible sections
[0.9.3] - 2025-11-24
Added
- Added Anthropic Claude Opus 4.5 support
[0.9.2] - 2025-11-24
Fixed
- Edit Tool Dollar Sign Bug: Fixed critical bug in the
edittool whereString.replace()was interpreting$as a special replacement pattern (e.g.,$$,$&,$'). When trying to insert$into code (like adding a dollar sign to a template literal), the replacement would silently fail and produce unchanged content, but the tool would incorrectly report success. Now usesindexOf+substringfor raw string replacement without special character interpretation. Also added verification that content actually changed, rejecting with a clear error if the replacement produces identical content. (#53)
[0.9.0] - 2025-11-21
Added
/clearCommand: New slash command to reset the conversation context and start a fresh session. Aborts any in-flight agent work, clears all messages, and creates a new session file. (#48)- Model Cycling with Thinking Levels: The
--modelsflag now supports thinking level syntax (e.g.,--models sonnet:high,haiku:low). When cycling models withCtrl+P, the associated thinking level is automatically applied. The first model in the scope is used as the initial model when starting a new session. Both model and thinking level changes are now saved to session and settings for persistence. (#47) --thinkingFlag: New CLI flag to set thinking level directly (e.g.,--thinking high). Valid values:off,minimal,low,medium,high. Takes highest priority over all other thinking level sources. (#45)
Breaking
- Interactive Mode with Initial Prompt: Passing a prompt on the command line (e.g.,
pi "List files") now starts interactive mode with the prompt pre-submitted, instead of exiting after completion. Use--printor-pto get the previous non-interactive behavior (e.g.,pi -p "List files"). This matches Claude CLI (-p) and Codex (exec) behavior. (#46)
Fixed
- Slash Command Autocomplete: Fixed issue where pressing Enter on a highlighted slash command suggestion (e.g., typing
/modwith/modelhighlighted) would submit the partial text instead of executing the selected command. Now Enter applies the completion and submits in one action. (#49) - Model Matching Priority: The
--modelsflag now prioritizes exact matches over partial matches. Supportsprovider/modelIdformat (e.g.,openrouter/openai/gpt-5.1-codex) for precise selection. Exact ID matches are tried before partial matching, so--models gpt-5.1-codexcorrectly selectsgpt-5.1-codexinstead ofopenai/gpt-5.1-codex-mini. - Markdown Link Rendering: Fixed links with identical text and href (e.g.,
https://github.com/badlogic/pi-mono/pull/48/files) being rendered twice. Now correctly compares raw text instead of styled text (which contains ANSI codes) when determining if link text matches href.
[0.8.5] - 2025-11-21
Fixed
- Path Completion Hanging: Fixed catastrophic regex backtracking in path completion that caused the terminal to hang when text contained many
/characters (e.g., URLs). Replaced complex regex with simple string operations. (#18) - Autocomplete Arrow Keys: Fixed issue where arrow keys would move both the autocomplete selection and the editor cursor simultaneously when the file selector list was shown.
[0.8.4] - 2025-11-21
Fixed
- Read Tool Error Handling: Fixed issue where the
readtool would return errors as successful text content instead of throwing. Now properly throws errors for file not found and offset out of bounds conditions.
[0.8.3] - 2025-11-21
Improved
- Export HTML: Limited container width to 700px for better readability. Fixed message statistics to match
/sessioncommand output with proper breakdown of User/Assistant/Tool Calls/Tool Results/Total messages. - Dark Theme: Increased visibility of editor border (darkGray from #303030 to #505050) and thinking minimal indicator (from #4e4e4e to #6e6e6e).
[0.8.0] - 2025-11-21
Added
- Theme System: Full theming support with 44 customizable color tokens. Two built-in themes (
dark,light) with auto-detection based on terminal background. Use/themecommand to select themes interactively. Custom themes in~/.pi/agent/themes/*.jsonsupport live editing - changes apply immediately when the file is saved. Themes use RGB hex values for consistent rendering across terminals. VS Code users: setterminal.integrated.minimumContrastRatioto1for proper color rendering. See Theme Documentation for details.
[0.7.29] - 2025-11-20
Improved
- Read Tool Display: When the
readtool is called with offset/limit parameters, the tool execution now displays the line range in a compact format (e.g.,read src/main.ts:100-200for offset=100, limit=100).
[0.7.28] - 2025-11-20
Added
- Message Queuing: You can now send multiple messages while the agent is processing without waiting for the previous response to complete. Messages submitted during streaming are queued and processed based on your queue mode setting. Queued messages are shown in a pending area below the chat. Press Escape to abort and restore all queued messages to the editor. Use
/queueto select between "one-at-a-time" (process queued messages sequentially, recommended) or "all" (process all queued messages at once). The queue mode setting is saved and persists across sessions. (#15)
[0.7.27] - 2025-11-20
Fixed
- Slash Command Submission: Fixed issue where slash commands required two Enter presses to execute. Now pressing Enter on a slash command autocomplete suggestion immediately submits the command, while Tab still applies the completion for adding arguments. (#30)
- Slash Command Autocomplete: Fixed issue where typing a typo then correcting it would not show autocomplete suggestions. Autocomplete now re-triggers when typing or backspacing in a slash command context. (#29)
[0.7.26] - 2025-11-20
Added
- Tool Output Expansion: Press
Ctrl+Oto toggle between collapsed and expanded tool output display. Expands all tool call outputs (bash, read, write, etc.) to show full content instead of truncated previews. (#31) - Custom Headers: Added support for custom HTTP headers in
models.jsonconfiguration. Headers can be specified at both provider and model level, with model-level headers overriding provider-level ones. This enables bypassing Cloudflare bot detection and other proxy requirements. (#39)
Fixed
- Chutes AI Provider: Fixed 400 errors when using Chutes AI provider. Added compatibility fixes for
storefield exclusion,max_tokensparameter usage, and system prompt role handling. (#42 by @butelo) - Mistral/Chutes Syntax Error: Fixed syntax error in merged PR that used
iifinstead ofif. - Anthropic OAuth Bug: Fixed bug where
process.env.ANTHROPIC_API_KEY = undefinedset the env var to string "undefined" instead of deleting it. Now usesdeleteoperator.
[0.7.25] - 2025-11-20
Added
- Model Cycling: Press
Ctrl+Pto quickly cycle through models. Use--modelsCLI argument to scope to specific models (e.g.,--models claude-sonnet,gpt-4o). Supports pattern matching and smart version selection (prefers aliases over dated versions). (#37 by @fightbulc)
[0.7.24] - 2025-11-20
Added
- Thinking Level Cycling: Press
Shift+Tabto cycle through thinking levels (off → minimal → low → medium → high) for reasoning-capable models. Editor border color changes to indicate current level (gray → blue → cyan → magenta).
[0.7.23] - 2025-11-20
Added
- Update Notifications: Interactive mode now checks for new versions on startup and displays a notification if an update is available.
Changed
- System Prompt: Updated system prompt to instruct agent to output plain text summaries directly instead of using cat or bash commands to display what it did.
Fixed
- File Path Completion: Removed 10-file limit in tab completion selector. All matching files and directories now appear in the completion list.
- Absolute Path Completion: Fixed tab completion for absolute paths (e.g.,
/Applications). Absolute paths in the middle of text (like "hey /") now complete correctly. Also fixed crashes when trying to stat inaccessible files (like macOS.VolumeIcon.icns) during directory traversal.
[0.7.22] - 2025-11-19
Fixed
- Long Line Wrapping: Fixed crash when rendering long lines without spaces (e.g., file paths). Long words now break character-by-character to fit within terminal width.
[0.7.21] - 2025-11-19
Fixed
- Terminal Flicker: Fixed flicker at bottom of viewport (especially editor component) in xterm.js-based terminals (VS Code, etc.) by using per-line clear instead of clear-to-end sequence.
- Background Color Rendering: Fixed black cells appearing at end of wrapped lines when using background colors. Completely rewrote text wrapping and background application to properly handle ANSI reset codes.
- Tool Output: Strip ANSI codes from bash/tool output before rendering to prevent conflicts with TUI styling.
[0.7.20] - 2025-11-18
Fixed
- Message Wrapping: Fixed word-based text wrapping for long lines in chat messages. Text now properly wraps at word boundaries while preserving ANSI styling (colors, bold, italic, etc.) across wrapped lines. Background colors now extend to the full width of each line. Empty lines in messages now render correctly with full-width background.
[0.7.18] - 2025-11-18
Fixed
- Bash Tool Error Handling: Bash tool now properly throws errors for failed commands (non-zero exit codes), timeouts, and aborted executions. This ensures tool execution components display with red background when bash commands fail.
- Thinking Traces Styling: Thinking traces now maintain gray italic styling throughout, even when containing inline code blocks, bold text, or other inline formatting
[0.7.17] - 2025-11-18
Added
- New Model: Added
gemini-3-pro-previewto Google provider. - OAuth Authentication: Added
/loginand/logoutcommands for OAuth-based authentication with Claude Pro/Max subscriptions. Tokens are stored in~/.pi/agent/oauth.jsonwith 0600 permissions and automatically refreshed when expired. OAuth tokens take priority over API keys for Anthropic models.
Fixed
- Anthropic Aborted Thinking: Fixed error when resubmitting assistant messages with incomplete thinking blocks (from aborted streams). Thinking blocks without valid signatures are now converted to text blocks with
<thinking>delimiters, preventing API rejection. - Model Selector Loading: Fixed models not appearing in
/modelselector until user started typing. Models now load asynchronously and re-render when available. - Input Paste Support: Added bracketed paste mode support to
Inputcomponent, enabling paste of long OAuth authorization codes.
[0.7.16] - 2025-11-17
Fixed
- Tool Error Display: Fixed edit tool (and all other tools) not showing error state correctly in TUI. Failed tool executions now properly display with red background and show the error message. Previously, the
isErrorflag from tool execution events was not being passed to the UI component, causing all tool results to show with green (success) background regardless of whether they succeeded or failed.
[0.7.15] - 2025-11-17
Fixed
- Anthropic OAuth Support: Added support for
ANTHROPIC_OAUTH_TOKENenvironment variable. The agent now checks for OAuth tokens before falling back to API keys for Anthropic models, enabling OAuth-based authentication.
[0.7.14] - 2025-11-17
Fixed
- Mistral API Compatibility: Fixed compatibility with Mistral API by excluding the
storefield and usingmax_tokensinstead ofmax_completion_tokens, and avoiding thedeveloperrole in system prompts. - Error Display: Fixed error message display in assistant messages to include proper spacing before the error text.
- Message Streaming: Fixed missing
message_startevent when no partial message chunks were received during streaming.
[0.7.13] - 2025-11-16
Fixed
- TUI Editor: Fixed unicode input support for umlauts (äöü), emojis (😀), and other extended characters. Previously the editor only accepted ASCII characters (32-126). Now properly handles all printable unicode while still filtering out control characters. (#20)
[0.7.12] - 2025-11-16
Added
- Custom Models and Providers: Support for custom models and providers via
~/.pi/agent/models.jsonconfiguration file. Add local models (Ollama, vLLM, LM Studio) or any OpenAI-compatible, Anthropic-compatible, or Google-compatible API. File is reloaded on every/modelselector open, allowing live updates without restart. (#21) - Added
gpt-5.1-codexmodel to OpenAI provider (400k context, 128k max output, reasoning-capable).
Changed
- Breaking: No longer hardcodes Anthropic/Claude as default provider/model. Now prefers sensible defaults per provider (e.g.,
claude-sonnet-4-5for Anthropic,gpt-5.1-codexfor OpenAI), or requires explicit selection in interactive mode. - Interactive mode now allows starting without a model, showing helpful error on message submission instead of failing at startup.
- Non-interactive mode (CLI messages, JSON, RPC) still fails early if no model or API key is available.
- Model selector now saves selected model as default in settings.json.
models.jsonvalidation errors (syntax + schema) now surface with precise file/field info in both CLI and/modelselector.- Agent system prompt now includes absolute path to its own README.md for self-documentation.
Fixed
- Fixed crash when restoring a session with a custom model that no longer exists or lost credentials. Now gracefully falls back to default model, logs the reason, and appends a warning message to the restored chat.
- Footer no longer crashes when no model is selected.
[0.7.11] - 2025-11-16
Changed
- The
/modelselector now filters models based on available API keys. Only models for which API keys are configured in environment variables are shown. This prevents selecting models that would fail due to missing credentials. A yellow hint is displayed at the top of the selector explaining this behavior. (#19)
[0.7.10] - 2025-11-14
Added
/branchcommand for creating conversation branches. Opens a selector showing all user messages in chronological order. Selecting a message creates a new session with all messages before the selected one, and places the selected message in the editor for modification or resubmission. This allows exploring alternative conversation paths without losing the current session. (fixes #16)
[0.7.9] - 2025-11-14
Changed
- Editor: updated keyboard shortcuts to follow Unix conventions:
- Ctrl+W deletes the previous word (stopping at whitespace or punctuation)
- Ctrl+U deletes from cursor to start of line (at line start, merges with previous line)
- Ctrl+K deletes from cursor to end of line (at line end, merges with next line)
- Option+Backspace in Ghostty now behaves like Ctrl+W (delete word backwards)
- Cmd+Backspace in Ghostty now behaves like Ctrl+U (delete to start of line)
[0.7.8] - 2025-11-13
Changed
- Updated README.md with
/changelogslash command documentation
[0.7.7] - 2025-11-13
Added
- Automatic changelog display on startup in interactive mode. When starting a new session (not continuing/resuming), the agent will display all changelog entries since the last version you used. The last shown version is tracked in
~/.pi/agent/settings.json. /changelogcommand to display the changelog in the TUI- OpenRouter Auto Router model support (#5)
- Windows Git Bash support with automatic detection and process tree termination (#1)
Changed
- BREAKING: Renamed project context file from
AGENT.mdtoAGENTS.md. The system now looks forAGENTS.mdorCLAUDE.md(withAGENTS.mdpreferred). ExistingAGENT.mdfiles will need to be renamed toAGENTS.mdto continue working. (fixes #9) - BREAKING: Session file format changed to store provider and model ID separately instead of as a single
provider/modelIdstring. Existing sessions will not restore the model correctly when resumed - you'll need to manually set the model again using/model. (fixes #4) - Improved Windows Git Bash detection logic with better error messages showing actual paths searched (#13)
Fixed
- Fixed markdown list rendering bug where bullets were not displayed when list items contained inline code with cyan color formatting
- Fixed context percentage showing 0% in footer when last assistant message was aborted (#12)
- Fixed error message loss when
turn_endevent contains an error. Previously, errors inturn_endevents (e.g., "Provider returned error" from OpenRouter Auto Router) were not captured inagent.state.error, making it appear as if the agent completed successfully. (#6)
[0.7.6] - 2025-11-13
Previous releases did not maintain a changelog.