github can1357/oh-my-pi v15.13.1

latest releases: v16.0.0, v15.13.3, v15.13.2...
12 hours ago

@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 error stop 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 thinking blocks 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 text and thinking stream 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's tokenUrl/clientId/clientSecret/resource embedded for self-contained token refresh): the OAuth credential wire schema was .strict(), so POST /v1/credential failed with 400 unrecognized_keys and 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 by parseKnownModel canonical-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 minimax and minimax-cn to 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_choice instead of triggering provider 400s (#2509).
  • Fixed OpenCode Go kimi-k2.7-code catalog metadata so resolve-gate requests use automatic tool selection instead of Moonshot-rejected forced tool_choice (#2546).
  • Fixed Anthropic compat for the github-copilot host so supportsEagerToolInputStreaming defaults to false there, matching the Copilot proxy which rejects the per-tool eager_input_streaming field (#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_PROFILE and 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 bench default 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, and ast-grep so replacements are rejected when they target lines not shown in the tool output
  • Fixed /tan refusing 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 /tan background agents never staying in the Agent Hub. The forked clone now uses an <agentId>.jsonl session 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 /tan dispatch 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 --plan no 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_shutdown handler hung — observed on Windows with omp-discord-presence 0.1.2 stuck on a stale Discord IPC pipe. ExtensionRunner.emit previously shared the generic 30s EXTENSION_HANDLER_TIMEOUT_MS budget for every event, including the fire-and-forget teardown event extensions cannot observe. session_shutdown now uses a dedicated 2s SESSION_SHUTDOWN_HANDLER_TIMEOUT_MS cap routed through a per-event handlerTimeoutForEvent() 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-only InteractiveModeContext.isShuttingDown (#2600).
  • Fixed the external editor flow (Ctrl+G, plan editor, /todo edit) warning No editor configured on Windows even when the user expected the system's native editor. getEditorCommand() now falls back to notepad on win32 after 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/transformers runtime before the side-installed Kokoro runtime, which could leave onnxruntime-node@1.26.0 bound to an older libonnxruntime.so.1 and fail with VERS_1.26.0 missing (#2591).
  • Fixed scripts/ci-release-notes.ts stranding curated changelog entries from intervening silent tags (a vX.Y.Z tag pushed without a GitHub Release, e.g. the v15.12.5/v15.12.6 casualties of the pre-#2564 release-cancellation bug). The generator now walks (latest-published-release, target] — resolved via gh release list from the release_github CI 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, and OMP_RELEASE_NOTES_FLOOR=v15.12.4 overrides the lookup for manual rebuilds (#2596).
  • Fixed Test & smoke (TS) CI timeouts caused by parallel test files racing on the process-global Settings singleton. CustomEditor now accepts a magicKeywordsEnabledOverride injection point so the shimmer-gate test can assert behaviour without calling resetSettingsForTest() / 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/ssh box 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 with ctrl+o and 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. The provisionalPendingPreview flag 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: #checkTodoCompletion appended a <system-reminder> and then scheduled agent.continue(), so a text-only acknowledgement ("paused at your instruction") triggered another agent_end that re-ran the same check and fired the next reminder — no user input required. AgentSession now tracks #todoReminderAwaitingProgress: a reminder sets it, any toolResult (real progress) or a new user prompt clears it, and #checkTodoCompletion stays silent while it is set. Escalation through todo.reminders.max still works when the agent makes tool-level progress between stops (#2590).
  • Fixed profile bootstrap so an extension-shadowed --plan flag 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 unauth deleting another profile's MCP OAuth credential row under broker-backed auth storage: when a shared mcp.json pins an explicit auth.credentialId scoped 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 16px font-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: manipulation and 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, and insert after block operations 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 stored memory_embeddings rows differs from the active currentEmbeddingModel(), 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 the MNEMOPI_NO_EMBEDDINGS env, 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 found on 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; the linux-x64 (baseline + modern) and linux-arm64 addons are now built through cargo-zigbuild against a pinned glibc 2.17 floor, restoring portability to any glibc ≥ 2.17 (CentOS 7 / Ubuntu 14.04 era).
  • Fixed pi-natives deadlocking at addon load (dlopen hang) 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 __ompInstallTokioRuntime that the JS loader calls once, immediately after dlopen returns and before any async native runs; #[module_init] only installs the crash handler. napi-rs materializes its runtime lazily on first async use (RT is a LazyLock) and create_custom_tokio_runtime only 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's replace block / delete block / insert after block ops) returning no block for a construct whose opening line follows a blank line — most visibly in Swift, where replace block on a SwiftUI var 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, which ts_node_named_descendant_for_point_range absorbs 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 sequence for a multi-command line that contains a here-doc with a quoted or escaped delimiter (<<'TAG', <<"TAG", <<\TAG) followed by another command (e.g. a sqlite3 … <<'SQL' … SQL query followed by an echo/second command). The output minimizer's segmented-chain runner rebuilds each &&/;/newline segment from the brush-parser AST via pipeline.to_string(), and that Display impl re-emits a quoted/escaped here-doc's closing delimiter with its quotes intact ('SQL' instead of the required bare SQL) — 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-iso Windows 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=sccache points at an unavailable shared cache backend. The native build script now retries the napi build 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, so children() / live_descendants() returned empty and termination waves never reached the children. It now falls back to scanning /proc and grouping by parent pid (the primitive the macOS path already uses) when no children file 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) and 11on16-bw (8x13 glyphs on an 11px advance — extra letter spacing). Both pin the indexed stretch: false path, so the native renderer draws natural-size glyphs on the padded cell box (the Rust path already advances by cellWidth and the new variants validate horizontal padding)
  • Added openai-codex to 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 — real search/read/find output with structure-sensitive QA) showed the prose-era density erases the line numbers and indentation that code/search output depends on. Anthropic moves from 6x12-dim to 11on16-bw (opus-4.8 f1 .806 vs .755 for plain 8on16-bw and .351 for 6x12-dim, which fell below the OCR ~16px/char floor and abstained); OpenAI and Google move to 8on22-bw (gemini-3.5-flash f1 .934 vs .807 for 8on16-bw and .287 for doc-8on16-sent-dim; same leading win on gpt-5.5/gpt-5.4-mini). Kimi and GLM keep their measured 8on16-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 git from 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 Editor with setVolatileText(text), clearVolatileText(), and commitVolatileText(text) so hosts can replace, discard, or commit live dictated text at the cursor without appending
  • Added an always-on LoopWatchdog armed in TUI.start()/TUI.stop() that logs ui.loop-blocked (rising-edge deduped, with blockedMs and the phase active during the elapsed interval) when a self-scheduled probe tick runs late, plus a ui.select-filter breadcrumb around the SelectList fuzzy filter. The phase is read via takeRecentLoopPhase, 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 (via clearTimeout on the default handle) so repeated start/stop cycles leave no pending probe, with the generation guard as a fallback (#2485)
  • Added ctrl+j as a second default binding for the tui.input.newLine action alongside shift+enter, so terminals that cannot emit shift+enter still have a newline key. On terminals with Kitty-protocol / modifyOtherKeys disambiguation ctrl+j inserts a newline while Enter still submits; on legacy terminals where ctrl+j and Enter are both byte-identical LF it 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). Returning true lets 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). Added Editor.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 to count characters 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-Space push-to-talk gesture deleting the space-bar auto-repeat burst.
  • Added an optional getNativeScrollbackSnapshotSafeEnd() to the NativeScrollbackLiveRegion contract: a durable commit boundary (D ≥ the byte-stable commitSafeEnd) 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-stable auditRows prefix), 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 === byteStableBoundary and auditRows === committedRows, so the ledger math is byte-identical.

Fixed

  • Fixed overlays without an explicit maxHeight dropping their bottom rows off-screen when taller than the terminal: #resolveOverlayLayout now 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.#decorate rejecting keyword matches glued to the cursor: CURSOR_MARKER begins 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 the TMUX/STY/ZELLIJ env vars and missing the TERM=tmux-*/screen-* fallback every sibling detector uses. When the multiplexer env was stripped but TERM survived (sudo without -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 with shouldEnableSynchronizedOutputByDefault, detectRectangularSgrSupport, and getFallbackImageProtocol in terminal-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 dirs module — setProfile(), getActiveProfile(), getProfileRootDir(), and normalizeProfileName() — plus resolveProfileEnv(), which selects the active profile from OMP_PROFILE (canonical; takes precedence) then PI_PROFILE (legacy fallback, consulted only when OMP_PROFILE is unset).
  • Added support for a runtime overrides map in RuntimeInstallSpec, which is now written into generated runtime package.json manifests to force dependency pins (including transitive ones) across the runtime tree
  • Added a lightweight loop-phase breadcrumb stack (pushLoopPhase/popLoopPhase/currentLoopPhase, plus takeRecentLoopPhase which 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 underlying fetch call). false disables 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-host module (declareWorkerHostEntry() / workerHostEntry()), extracted from env (still re-exported there) so worker spawn sites can resolve the self-dispatching CLI host entry without importing env's side-effecting module graph.

Fixed

  • Fixed profile directory isolation when a profile's agent .env customizes directory roots: directory-affecting keys (XDG_DATA_HOME/XDG_STATE_HOME/XDG_CACHE_HOME, and a default-mode PI_CODING_AGENT_DIR) are now honored. The env loader rebuilds the dirs resolver after applying .env files (refreshDirsFromEnv()), so a profile .env that points XDG roots elsewhere no longer leaks state into the home-based config dir.
  • Made TempDir cleanup retry transient Windows EBUSY/EPERM/ENOTEMPTY removal 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

Full Changelog: v15.13.0...v15.13.1

Don't miss a new oh-my-pi release

NewReleases is sending notifications on new releases.