@oh-my-pi/pi-ai
Fixed
- Fixed llama.cpp/OpenAI Responses parallel tool calls losing arguments when
function_call_arguments.doneevents omitoutput_indexanditem_id, by routing those identifierless final-argument events through the open function calls in item order. (#1970) - Fixed local Ollama (
openai-responses) turns failing with HTTP 400invalid reasoning value: "minimal"when a discovered model ran withminimal(orxhigh) thinking. Ollama's OpenAI-compatiblereasoning.effortonly acceptshigh|medium|low|max|none, so discovered reasoning-capable Ollama models now carry acompat.reasoningEffortMapremappingminimal → lowandxhigh → max; non-reasoning models are left untouched.
@oh-my-pi/pi-coding-agent
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.
@oh-my-pi/hashline
Breaking Changes
- Changed hashline file section headers from
¶PATH#TAGto[PATH#TAG]so model-authored edits use ASCII delimiters instead of a pilcrow sigil.
Fixed
- Fixed missing-header diagnostics and copied-content prefix stripping to consistently teach and recognize 4-hex snapshot tags.
@oh-my-pi/pi-tui
Added
- Added
setPaddingXtoBoxso horizontal padding can be updated programmatically after creation - Added
ScrollView, a fixed-height viewport component for pre-rendered lines with optional right-edge scrollbars and imperative scroll/page controls. - Added optional
Terminal.hasEagerEraseScrollbackRisk()so custom/test terminal implementations can override the global ED3-risk profile without mutating the sharedTERMINALobject.
Changed
- Changed
SelectListto render its visible window throughScrollView, replacing the(N/M)text scroll indicator with a uniform right-edge scrollbar (the type-to-search hint line is preserved).
Fixed
- Fixed unknown-viewport deferred renders freezing bottom-anchored live chrome; deferred history mutations can now repaint only the active-grid bottom row with relative cursor movement, so spinner/status tails keep advancing without rewriting rows a scrolled reader can still see.
- Fixed autocomplete popups freezing live repaint on ED3-risk macOS/POSIX terminals with unknown native viewport position; direct autocomplete shrink frames now repaint the live viewport without zero-byte deferral and preserve the old bottom anchor when padding can clear stale popup rows without duplicating committed scrollback.
- Fixed focused Up/Down navigation on ED3-risk macOS/POSIX terminals replaying the whole transcript after dirty foreground-stream renders; selector/editor frames now repaint non-destructively instead of emitting
CSI 3 Jon every arrow-key move (#1962). - Fixed tmux (and screen/zellij) pane scrollback losing the head of a long streamed assistant reply once it grew past the visible pane, and stranding the chrome/footer in pane history after a later collapse — producing the "repeating chunks and missing sections" reporters saw when scrolling back through tmux pane history (#1974). The renderer's foreground-streaming cap-to-viewport branch (introduced in 15.9.2 for ED3-risk hosts that can checkpoint-rebuild later) also activated inside multiplexers, where checkpoint reconcile is a no-op (
refreshNativeScrollbackIfDirtyshort-circuits because\x1b[3Jcannot erase pane history). Every streaming frame clippedlinesto the visible tail and reset#scrollbackHighWaterto 0, so any row that scrolled above the viewport top was committed nowhere — pane history stayed empty until streaming ended. Meanwhile#planLiveRegionPinnedRenderwas explicitly disabled for multiplexers, but its#emitLiveRegionPinnedRepaintis built from the exact primitives tmux accepts (relative cursor moves, per-line\x1b[2K,\r\nto scroll the sealed prefix past the viewport bottom) and never emits\x1b[2J/\x1b[3J. The pinned planner now runs in multiplexers too, the cap branch skips them, and the diff/append path commits incrementally into pane history; the actively-mutating live tail stays in the visible viewport only.
What's Changed
- fix(hashline): accept spaces in edit paths by @roboomp in #1766
- fix(keybindings): default Ctrl+Q for follow-up so Windows Terminal works by @roboomp in #1905
- fix(eval): stop detaching the Python kernel's console on Windows by @roboomp in #1961
- fix(tui): avoid dirty scrollback replay on arrow input by @roboomp in #1963
- fix(ai): preserve llama.cpp parallel tool arguments by @roboomp in #1971
- fix(tui): honor resume clear replay before initial paint by @roboomp in #1973
- fix(tui): commit tmux pane history during streaming via pinned emit by @roboomp in #1975
- fix(lsp): support rust-analyzer workspace loading by @roboomp in #1977
- test(tui): widened slash autocomplete settle slack past debounce jitter by @roboomp in #1981
- fix(coding-agent): guard task renderer against non-array yield slot by @roboomp in #1989
- fix(coding-agent): honor ttsr.enabled: false in TtsrManager by @QianYan-Art in #1988
- fix(coding-agent): allow retry without model fallback by @metaphorics in #1929
- Add ScrollView component by @enieuwy in #1969
New Contributors
- @QianYan-Art made their first contribution in #1988
Full Changelog: v15.9.5...v15.9.67