@oh-my-pi/pi-agent-core
Added
- Added repetition-loop detection to the streaming agent loop for Gemini-family providers. A runaway run of a repeated text or thinking unit is detected mid-stream from a bounded rolling tail (O(1) per delta), the provider request is aborted, the repeated tail is collapsed to a single representative copy, and the turn ends gracefully with an
errorstop reason. Legitimate all-numeric/whitespace/punctuation runs (hexdumps, zero-fills, numeric tables) are not misclassified as loops (#2549 by @usr-bin-roygbiv).
Fixed
- Fixed repetition loop handling to collapse repeated
thinkingblocks to a single representative copy when a loop is detected - Fixed repetition-loop detection to ignore repeats that contain only digits, whitespace, or punctuation so legitimate numeric outputs no longer stop with a repetition-loop error
- Fixed false-positive repetition-loop checks across
textandthinkingstream boundaries by tracking loop detection per block type
@oh-my-pi/pi-ai
Fixed
- Fixed the auth-broker (
OMP_AUTH_BROKER_URL) rejecting OAuth credentials that carry provider-specific extension fields (e.g. an MCP server'stokenUrl/clientId/clientSecret/resourceembedded for self-contained token refresh): the OAuth credential wire schema was.strict(), soPOST /v1/credentialfailed with400 unrecognized_keysand a broker-backed MCP reauth reported success while the reloaded credential lacked its refresh material and could no longer refresh. The OAuth wire schema now uses.loose()to preserve unknown fields — matching the field-preserving local SQLite store — so extra OAuth fields round-trip through broker set->get (envelope and API-key schemas stay strict).
@oh-my-pi/pi-catalog
Added
- Added
modelFamilyToken(modelId)to@oh-my-pi/pi-catalog/identity: a coarse vendor-lineage token (anthropic/openai/gemini/kimi/…) for "are two models the same family?" comparisons, backed byparseKnownModelcanonical-id normalization. Opaque and comparison-only; kind/variant collapsed onto the vendor token (#2406)
Changed
- Changed catalog metadata to update a model’s per-token pricing to input 0.09 and output 0.18
- Changed the same cataloged model’s maximum token limit from 384000 to 65536
Fixed
- Fixed MiniMax-M3 catalog context for
minimaxandminimax-cnto report the documented 1M long-context tier instead of the upstream 512K pricing boundary (#2576). - Fixed OpenCode Go MiMo catalog metadata so title generation and other tool-enabled calls omit unsupported
tool_choiceinstead of triggering provider 400s (#2509). - Fixed OpenCode Go
kimi-k2.7-codecatalog metadata so resolve-gate requests use automatic tool selection instead of Moonshot-rejected forcedtool_choice(#2546). - Fixed Anthropic compat for the
github-copilothost sosupportsEagerToolInputStreamingdefaults tofalsethere, matching the Copilot proxy which rejects the per-tooleager_input_streamingfield (#2558). - Scoped vLLM model cache validity to the discovery base URL so changed endpoints refetch immediately, and bounded built-in vLLM discovery requests with a timeout.
@oh-my-pi/pi-coding-agent
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.
@oh-my-pi/collab-web
Added
- Added
16pxfont-size overrides for all text inputs and textareas on mobile viewports to prevent iOS Safari from automatically zooming in the page on focus - Added top and bottom safe-area padding (
env(safe-area-inset-*)) to the header bar, connection card, and composer to prevent them from being covered by notches/home indicators - Added translucent click-outside-to-close backdrops for the mobile side rail and agent details drawer to match native mobile chat applications
- Disabled vertical bounce reload gesture (
overscroll-behavior-y: none) on the page body to prevent accidental pull-to-refresh page reloads during scrolling - Applied global touch responsiveness updates (
touch-action: manipulationand tap-highlight removals) to links and buttons to improve mobile responsiveness
Fixed
- Fixed mobile layout issues where the entire chat flow would overflow horizontally and text was rendered too large on iOS Safari (by setting
text-size-adjust: 100%) - Pinned the app shell grid to a single
minmax(0, 1fr)column so a long session title can no longer set a min-content floor that pushes the header, transcript, and composer wider than narrow or in-app mobile viewports; the title now ellipsizes instead of clipping every row's right edge - Made transcript rows stack vertically on small screens to optimize reading space, and prevented grid track expansion
- Hid non-essential metadata (such as the model name, thinking level, and working directory path) and context gauge tracks on mobile headers to prevent overflow
- Wrapped composer button labels to display icon-only on mobile devices for a more compact and readable layout
- Made the connect screen, ended session card, and notification toasts fully responsive for smaller device viewports
@oh-my-pi/hashline
Breaking Changes
- Rejected edits anchored to lines not displayed in the tagged read/search output, requiring unseen ranges to be re-read before reapplying
Changed
- Rejected
replace block,delete block, andinsert after blockoperations that resolve to a single line and instructed users to use the plain single-line form or anchor the true construct opener
Fixed
- Auto-repaired one-sided multi-line boundary echoes by dropping delimiter-neutral duplicated boundary lines and emitted a boundary-echo warning
- Normalized cwd-relative hashline paths to forward-slash form on Windows.
- Parser now treats a leading
\on inline payload bodies as the payload delimiter, matching standalone payload rows. - Restored the warning emitted when escaped indented payload rows (
\\ TEXT) are accepted as payload delimiters.
@oh-my-pi/pi-mnemopi
Added
- Added a wipe-and-rebuild reconcile (
reconcileEmbeddingModel) that runs when the configured embedding model changes. At store open, if the model stamped on storedmemory_embeddingsrows differs from the activecurrentEmbeddingModel(), the stale embeddings and their binary vectors are dropped and every existing memory is enqueued for background re-embedding (in bounded batches) at the new model/dimension. The destructive wipe is skipped whenever it could not be rebuilt — embeddings disabled via the runtime option or theMNEMOPI_NO_EMBEDDINGSenv, an unresolved (empty) active model, or a read-only open (reconcile: false, used by ephemeral stats readers that would exit before the async rebuild finished) — so a stale-but-valid corpus is never destroyed without a replacement. Recall degrades gracefully (FTS-only) for memories whose vectors are not yet rebuilt (#2476)
Fixed
- Normalized enhanced recall fact scoring against lexical coverage so high-confidence facts that only match generic query tokens no longer outrank exact working-memory hits. (#2441)
@oh-my-pi/pi-natives
Fixed
- Fixed shipped Linux native addons failing to load with
version 'GLIBC_2.39' not foundon distributions older than Ubuntu 24.04. After native builds moved onto the Ubuntu 24.04 (glibc 2.39) self-hosted runner, the x64 addon was a plain host build that linked the runner's glibc and the arm64 cross-build floated up to GLIBC_2.30; thelinux-x64(baseline + modern) andlinux-arm64addons are now built throughcargo-zigbuildagainst a pinned glibc 2.17 floor, restoring portability to any glibc ≥ 2.17 (CentOS 7 / Ubuntu 14.04 era). - Fixed
pi-nativesdeadlocking at addon load (dlopenhang) on some Linux hosts. The load-time Tokio runtime install added in 15.12.6 ran inside#[module_init], which executes while the dynamic-loader lock is held; building the multi-thread runtime there eagerly spawns worker threads, and a fresh worker blocking to acquire the loader lock the init thread still owns deadlocks the whole load (every native consumer hangs at startup). The runtime is now built from an exported__ompInstallTokioRuntimethat the JS loader calls once, immediately afterdlopenreturns and before any async native runs;#[module_init]only installs the crash handler. napi-rs materializes its runtime lazily on first async use (RTis aLazyLock) andcreate_custom_tokio_runtimeonly records the runtime, so the post-load install is still adopted — preserving the Windows commit-limit thread probing/back-off from 15.12.6 without spawning under the loader lock. - Fixed
blockRangeAt(and thus the edit tool'sreplace block/delete block/insert after blockops) returning no block for a construct whose opening line follows a blank line — most visibly in Swift, wherereplace blockon a SwiftUIvar body: some View {(or any statement/declaration after a blank line) failed with "could not resolve a syntactic block… (unsupported language, blank/closer line, or parse error)". tree-sitter-swift inserts a zero-width separator node at the start of a statement that follows a blank line; the resolver queried the first content column with a zero-width point range, whichts_node_named_descendant_for_point_rangeabsorbs into that invisible node and bubbles back up to the enclosing body (or the file root), so no block was found. The query now spans the first content character (a one-column-wide range) so it skips zero-width nodes and descends into the node that actually begins on the line. - Fixed native shell execution reporting
unterminated here document sequencefor a multi-command line that contains a here-doc with a quoted or escaped delimiter (<<'TAG',<<"TAG",<<\TAG) followed by another command (e.g. asqlite3 … <<'SQL' … SQLquery followed by anecho/second command). The output minimizer's segmented-chain runner rebuilds each&&/;/newline segment from the brush-parser AST viapipeline.to_string(), and thatDisplayimpl re-emits a quoted/escaped here-doc's closing delimiter with its quotes intact ('SQL'instead of the required bareSQL) — an invalid close tag that the re-run segment never matches. Here-doc-bearing pipelines are now ineligible for segmentation, so the command runs whole via the unsegmented path (where the executor parses it correctly); a lone here-doc was unaffected because it was never segmented. - Fixed native addon loading leaving stale
~/.omp/natives/<version>cache directories behind after updates; successful loads now remove older version directories best-effort. - Fixed Linux source-built native addons hanging during package import by keeping the Windows-only Tokio worker probe out of non-Windows module initialization (#2553).
- Fixed
pi-isoWindows clippy failures in symlink placeholder metadata, block-clone path resolution, and readonly cleanup handling (#2379 by @oldschoola). - Fixed Linux native builds hard-failing when
RUSTC_WRAPPER=sccachepoints at an unavailable shared cache backend. The native build script now retries thenapibuild once without the sccache wrapper after a cache-storage startup failure, so install smoke tests and local fallback builds can proceed while preserving the cached fast path when the backend is healthy. - Fixed shell cancellation cleanup failing to reap child processes inside containers whose guest kernel was built without
CONFIG_PROC_CHILDREN(e.g. some Kata/microVM guests): the Linux descendant walk relied solely on/proc/<pid>/task/<tid>/children, which does not exist there, sochildren()/live_descendants()returned empty and termination waves never reached the children. It now falls back to scanning/procand grouping by parent pid (the primitive the macOS path already uses) when nochildrenfile is readable, keeping the cheap per-task fast path on kernels that support it.
@oh-my-pi/snapcompact
Added
- Added two spacing-tuned frame variants to
SHAPE_VARIANTS:8on22-bw(8x13 glyphs on a 22px pitch — extra line spacing) and11on16-bw(8x13 glyphs on an 11px advance — extra letter spacing). Both pin the indexedstretch: falsepath, so the native renderer draws natural-size glyphs on the padded cell box (the Rust path already advances bycellWidthand the new variants validate horizontal padding) - Added
openai-codexto first-party provider image budgets so ChatGPT Plus/Pro Codex sessions use the same 200-image request cap as OpenAI API sessions instead of the unknown-provider floor.
Changed
- Changed the per-provider default shapes to the spacing-tuned cells. The previous shapes were tuned on the SQuAD prose eval, where dense cells won; a new tool-result legibility benchmark (
research/toolbench.py— realsearch/read/findoutput with structure-sensitive QA) showed the prose-era density erases the line numbers and indentation that code/search output depends on. Anthropic moves from6x12-dimto11on16-bw(opus-4.8 f1 .806 vs .755 for plain8on16-bwand .351 for6x12-dim, which fell below the OCR ~16px/char floor and abstained); OpenAI and Google move to8on22-bw(gemini-3.5-flash f1 .934 vs .807 for8on16-bwand .287 fordoc-8on16-sent-dim; same leading win on gpt-5.5/gpt-5.4-mini). Kimi and GLM keep their measured8on16-bw. The bigger cells pack fewer chars per frame, so inline frame-swapping now breaks even at a larger tool-result size
@oh-my-pi/omp-stats
Fixed
- Dropped
gitfrom the profanity list so normal repository mentions no longer count as profanity
@oh-my-pi/pi-tui
Added
- Added volatile speech-to-text preview support to
EditorwithsetVolatileText(text),clearVolatileText(), andcommitVolatileText(text)so hosts can replace, discard, or commit live dictated text at the cursor without appending - Added an always-on
LoopWatchdogarmed inTUI.start()/TUI.stop()that logsui.loop-blocked(rising-edge deduped, withblockedMsand the phase active during the elapsed interval) when a self-scheduled probe tick runs late, plus aui.select-filterbreadcrumb around theSelectListfuzzy filter. The phase is read viatakeRecentLoopPhase, so a synchronous block whose breadcrumb was pushed and popped before the delayed tick runs is still attributed to its phase instead of "unknown".stop()cancels the armed timer (viaclearTimeouton the default handle) so repeated start/stop cycles leave no pending probe, with the generation guard as a fallback (#2485) - Added
ctrl+jas a second default binding for thetui.input.newLineaction alongsideshift+enter, so terminals that cannot emitshift+enterstill have a newline key. On terminals with Kitty-protocol /modifyOtherKeysdisambiguationctrl+jinserts a newline whileEnterstill submits; on legacy terminals wherectrl+jandEnterare both byte-identicalLFit submits (documented limitation). User keybinding overrides still take precedence (#2473) - Added an
Editor.onLargePaste(text, lineCount)hook, fired for a "marker-sized" paste (the point where the editor would otherwise collapse it into a[Paste #N]token). Returningtruelets the host intercept the paste — e.g. to offer wrap-in-code-block / wrap-in-XML / attach-as-file choices — and suppresses the default marker (no undo state is recorded). AddedEditor.insertPaste(content)so the host can re-insert a (possibly transformed) collapsed paste marker without re-triggering the hook. - Added
Editor.deleteBeforeCursor(count), which removes up tocountcharacters immediately before the cursor on the current line (capped at the cursor column, single line, records one undo state). Hosts use it to "track back" optimistically-inserted characters — e.g. the coding-agent hold-Spacepush-to-talk gesture deleting the space-bar auto-repeat burst. - Added an optional
getNativeScrollbackSnapshotSafeEnd()to theNativeScrollbackLiveRegioncontract: a durable commit boundary (D ≥ the byte-stablecommitSafeEnd) for live rows whose current snapshot is permanent content but may still drift bytes later (a streaming markdown table re-aligning its columns). The engine commits these rows when they scroll above the window — never dropping them — but audit-exempt (tracked via a new byte-stableauditRowsprefix), so a later layout change of an already-committed row freezes a stale row in history (duplication never loss) instead of re-anchoring the committed-prefix audit and spraying duplicate snapshots. Components that omit it are unchanged:durableBoundary === byteStableBoundaryandauditRows === committedRows, so the ledger math is byte-identical.
Fixed
- Fixed overlays without an explicit
maxHeightdropping their bottom rows off-screen when taller than the terminal:#resolveOverlayLayoutnow defaults the height cap to the available rows, so a tall overlay is sliced to fit (and re-clamps on resize) instead of overflowing the visible region. - Fixed
Editor.#decoraterejecting keyword matches glued to the cursor:CURSOR_MARKERbegins with ESC (non-whitespace), so decorators with a right-boundary lookahead (e.g./(?<!\S)ultrathink(?!\S)/) failed at the seam and dropped highlighting until a trailing character was typed. The decorate hook now splits around the marker and decorates each user-text segment in isolation so word-boundary lookarounds resolve correctly on both sides (#2475). - Fixed non-multiplexer resize drags with width changes briefly showing terminal-reflowed wrapped fragments: transient resize frames now borrow the alternate screen and return to the normal screen for the settled authoritative replay.
- Fixed
isMultiplexerSession()only checking theTMUX/STY/ZELLIJenv vars and missing theTERM=tmux-*/screen-*fallback every sibling detector uses. When the multiplexer env was stripped butTERMsurvived (sudowithout-E,su, env-sanitizing launchers/ssh), the renderer misclassified the pane as a direct terminal and emitted ED3 (CSI 3 J) on resize/replace/resetDisplay, which wipes tmux pane history — scrollback only reappeared after a full rerender (Ctrl+L). The check now aligns withshouldEnableSynchronizedOutputByDefault,detectRectangularSgrSupport, andgetFallbackImageProtocolinterminal-capabilities.ts(#2544).
@oh-my-pi/pi-utils
Added
- Added profile-aware directory helpers and isolated profile state roots, while keeping the install ID shared across profiles.
- Added a named-profile API to the
dirsmodule —setProfile(),getActiveProfile(),getProfileRootDir(), andnormalizeProfileName()— plusresolveProfileEnv(), which selects the active profile fromOMP_PROFILE(canonical; takes precedence) thenPI_PROFILE(legacy fallback, consulted only whenOMP_PROFILEis unset). - Added support for a runtime
overridesmap inRuntimeInstallSpec, which is now written into generated runtimepackage.jsonmanifests to force dependency pins (including transitive ones) across the runtime tree - Added a lightweight loop-phase breadcrumb stack (
pushLoopPhase/popLoopPhase/currentLoopPhase, plustakeRecentLoopPhasewhich returns the live phase or the most recently popped one and clears it) so the TUI event-loop watchdog can attribute a main-thread block to the phase that caused it — including a synchronous phase already popped before the watchdog's delayed tick runs (#2485) - Added
FetchWithRetryOptions.timeout(forwarded to the underlyingfetchcall).falsedisables Bun's native ~300s pre-response timeout; a positive number overrides the ceiling. Bare browser/Node fetch ignores it (#2422) - Added the side-effect-free
@oh-my-pi/pi-utils/worker-hostmodule (declareWorkerHostEntry()/workerHostEntry()), extracted fromenv(still re-exported there) so worker spawn sites can resolve the self-dispatching CLI host entry without importingenv's side-effecting module graph.
Fixed
- Fixed profile directory isolation when a profile's agent
.envcustomizes directory roots: directory-affecting keys (XDG_DATA_HOME/XDG_STATE_HOME/XDG_CACHE_HOME, and a default-modePI_CODING_AGENT_DIR) are now honored. Theenvloader rebuilds thedirsresolver after applying.envfiles (refreshDirsFromEnv()), so a profile.envthat points XDG roots elsewhere no longer leaks state into the home-based config dir. - Made
TempDircleanup retry transient WindowsEBUSY/EPERM/ENOTEMPTYremoval failures so tests are less likely to fail when deleting just-used temp directories. - Fixed
installRuntimeModuleResolver()to keep bare requests from runtime-cache modules inside that registered runtime before falling back to host/workspace packages.
What's Changed
- fix(ci): aggregate release notes across silent intervening tags by @roboomp in #2597
- fix(snapcompact): budget openai-codex images by @MicroProofs in #2584
- fix(goals): avoid deactivating goal mode on wall-clock-only updates by @usr-bin-roygbiv in #2586
- fix(goals): retry turns failing with Gemini MALFORMED_FUNCTION_CALL by @usr-bin-roygbiv in #2587
- fix(coding-agent): stopped todo reminders self-escalating without user input by @roboomp in #2594
- fix(coding-agent): cap session_shutdown extension handler at 2s by @roboomp in #2601
- fix(editor): default to notepad on Windows when $VISUAL/$EDITOR are unset by @roboomp in #2605
New Contributors
- @MicroProofs made their first contribution in #2584
Full Changelog: v15.13.0...v15.13.1