chore: updated changelogs + remove summarization marker

This commit is contained in:
can1357
2026-07-22 23:59:32 +02:00
parent 242bcbef8c
commit 7d404686c2
12 changed files with 84 additions and 224 deletions
+1 -1
View File
@@ -4,7 +4,7 @@
### Fixed
- Recovered completed tool calls after transient stream JSON parse failures while keeping incomplete, unknown, refused, and sensitive calls non-executable.
- Improved resilience against transient stream JSON parse failures by recovering completed tool calls while safely preventing incomplete, unknown, refused, or sensitive calls from executing.
## [17.0.5] - 2026-07-18
+7 -7
View File
@@ -4,13 +4,13 @@
### Fixed
- Fixed Gemini Flash Cloud Code Assist responses containing only intercepted planning-leak JSON being counted as meaningful output, so fully discarded leaks now use the existing empty-response retry path while visible suffixes and native structured tool calls remain successful.
- Fixed Antigravity auto endpoint routing stopping after the daily endpoint exhausted its empty-stream retries, allowing retryable pre-content provider failures to fail over to the sandbox endpoint without replaying partial output or retrying content blocks.
- Fixed OpenAI-compatible providers configured with `auth: none` still sending `Authorization: Bearer N/A`, which broke custom endpoints that authenticate via their own headers (e.g. `headers.x-api-key`) and reject the bogus bearer. The keyless sentinel now suppresses the `Authorization` injection in `resolveOpenAIRequestSetup`, matching the existing guards on the `google-vertex` and `amazon-bedrock` transports ([#6188](https://github.com/can1357/oh-my-pi/issues/6188)).
- Fixed `auth-gateway` model listings exposing duplicate, ambiguous bare IDs by advertising one provider-qualified routing ID per upstream model ([#6170](https://github.com/can1357/oh-my-pi/issues/6170)).
- Classified the provider terminal message `Unable to connect. Is the computer able to access the url?` as a transient transport failure so exhausted fetch retries surface as retriable to the session layer, while explicit rejections like `Unable to connect: 401 Unauthorized` stay auth-failed and non-retryable ([#6139](https://github.com/can1357/oh-my-pi/pull/6139)).
- Fixed custom Anthropic base URLs losing native thinking signatures in the leaked-thinking recovery wrapper: the signature Anthropic delivers at `thinking_end` (after all `thinking_delta` events) was ignored, so continuations replayed the block with an empty signature and signing endpoints rejected it ([#6046](https://github.com/can1357/oh-my-pi/issues/6046)).
- Fixed Alibaba Coding Plan Custom login rejecting valid API keys when the endpoint does not serve the built-in validation model by validating against its model catalog instead. ([#6078](https://github.com/can1357/oh-my-pi/issues/6078))
- Fixed Gemini Flash Cloud Code Assist empty-response retries when responses contain only intercepted planning-leak JSON.
- Fixed Antigravity auto-routing to correctly fail over to the sandbox endpoint when the daily endpoint exhausts its retries.
- Fixed OpenAI-compatible providers configured with auth: none incorrectly sending an Authorization: Bearer N/A header, which broke custom endpoints using alternative authentication headers.
- Fixed auth-gateway model listings exposing duplicate or ambiguous model IDs by ensuring only provider-qualified routing IDs are advertised.
- Improved connection error handling by classifying generic connection failures as transient, allowing them to be retried, while keeping explicit authentication rejections non-retryable.
- Fixed custom Anthropic base URLs losing native thinking signatures during continuation requests.
- Fixed Alibaba Coding Plan Custom login rejecting valid API keys on endpoints that do not serve the default validation model by validating against the model catalog instead.
## [17.0.6] - 2026-07-20
+11 -32
View File
@@ -4,47 +4,26 @@
### Added
- Added MiniMax M3 model with reasoning and multi-modal support
- Added Gemini 3.5 Flash Lite model across multiple providers
- Added Gemini 3.6 Flash model across multiple providers with thinking support
- Added Hy3 model with reasoning and effort-based thinking
- Added Doubao-Seed-Character model with image input support
- Added LongCat 2.0 model across multiple providers
- Added Laguna S 2.1 model (free and paid tiers) across multiple providers
- Added Qwen 3.6 35B A3B model with thinking support
- Added SWE-1.6 Slow model to devin agent catalog
- Added XiaomiMiMo/MiMo-V2.5 model with reasoning support
- Added support for several new models across multiple providers, including MiniMax M3, Gemini 3.5 Flash Lite, Gemini 3.6 Flash (with thinking support), Hy3, Doubao-Seed-Character, LongCat 2.0, Laguna S 2.1 (free and paid tiers), Qwen 3.6 35B A3B, SWE-1.6 Slow (devin agent catalog), and XiaomiMiMo/MiMo-V2.5.
### Changed
- Changed Grok 4.5 API type from "openai-completions" to "openai-responses"
- Changed thinking format for "o3-mini" from "zai" to "kimi"
- Renamed "Auto Router (Beta)" to "OpenRouter Auto Router (Beta)"
- Renamed "Body Builder (beta)" to "OpenRouter Body Builder (beta)"
- Renamed "Pareto Code Router" to "OpenRouter Pareto Code Router"
- Updated numerous model context window sizes, costs, and token limits
- Updated "o3-mini" model to support thinking capabilities
- Updated Grok 4.5 API type to "openai-responses" and updated "o3-mini" to support thinking capabilities with the "kimi" thinking format.
- Renamed OpenRouter-specific models and routers to include "OpenRouter" in their names (e.g., "OpenRouter Auto Router (Beta)", "OpenRouter Body Builder (beta)", and "OpenRouter Pareto Code Router").
- Updated context window sizes, costs, and token limits for numerous models.
### Fixed
- Fixed GPT-5.6 Codex SKUs (`gpt-5.6-{sol,terra,luna}`) losing ~75K of usable context when the Codex discovery endpoint actively reports `context_window: 272000`: discovery now floors these SKUs at the 372K hard capacity instead of only substituting it when the field is absent, so the runtime dynamic value no longer overwrites the bundled pin ([#6259](https://github.com/can1357/oh-my-pi/issues/6259)).
- Fixed authenticated OpenAI Codex discovery dropping account-listed ChatGPT-only models such as GPT-5.3 Codex Spark when they are unavailable through the public API ([#6108](https://github.com/can1357/oh-my-pi/issues/6108)).
- Fixed Codex (`openai-codex`) catalog discovery hiding models available only through a second configured OAuth account: discovery fetched one account's `/models` catalog and, being authoritative, pruned every model the other accounts exposed. `openaiCodexModelManagerOptions` now takes a `resolveAccounts` callback, fetches each configured account's catalog independently, and unions them by id before the authoritative merge (bundled models are retained when every account fetch fails) ([#6265](https://github.com/can1357/oh-my-pi/issues/6265)).
- Fixed cached models that reuse a bundled request model — including GitHub Copilot `-1m` long-context variants — being flagged unrestorable and dropped after a restart. Header restoration now matches the `requestModelId` base and bypasses a stale `unrestorable` marker written by the old id-only cache writer. ([#6037](https://github.com/can1357/oh-my-pi/issues/6037), [#6284](https://github.com/can1357/oh-my-pi/issues/6284))
- Fixed LM Studio discovery reporting a model's architectural maximum (`max_context_length`) instead of the window the running instance actually serves. `getLmStudioNativeContextWindow` now prefers `loaded_context_length` when a model reports `state: "loaded"`, so context accounting and compaction schedule against the real window ([#6082](https://github.com/can1357/oh-my-pi/issues/6082)).
- Fixed an issue where GPT-5.6 Codex SKUs lost usable context window capacity due to dynamic discovery values overwriting bundled limits.
- Fixed OpenAI Codex discovery dropping account-listed ChatGPT-only models (such as GPT-5.3 Codex Spark) when they are unavailable through the public API.
- Fixed Codex catalog discovery hiding models when multiple OAuth accounts are configured by independently fetching and merging catalogs from all accounts.
- Fixed cached models reusing a bundled request model (such as GitHub Copilot long-context variants) being incorrectly flagged as unrestorable and dropped after a restart.
- Fixed LM Studio discovery reporting a model's theoretical maximum context length instead of the actual loaded context window size of the running instance.
### Removed
- Removed Claude Fable 5 family of models from devin catalog
- Removed Claude Opus 4.6 and 4.7 model families from devin catalog
- Removed Claude Sonnet 4.6 and 5 model families from devin catalog
- Removed DeepSeek V4 Pro from devin catalog
- Removed Gemini 3.1 Pro and Gemini 3.5 Flash families from devin catalog
- Removed GLM-5.2 and GLM-5.2 1M from devin catalog
- Removed GPT-5 through GPT-5.3 Codex variants from openai-codex catalog
- Removed GPT-5.4 nano from openai-codex catalog
- Removed SWE-1.6 family models from devin catalog
- Removed Nemotron 3 Ultra from devin catalog
- Removed several deprecated model families from the devin catalog, including Claude Fable 5, Claude Opus 4.6/4.7, Claude Sonnet 4.6/5, DeepSeek V4 Pro, Gemini 3.1 Pro, Gemini 3.5 Flash, GLM-5.2, SWE-1.6, and Nemotron 3 Ultra.
- Removed GPT-5 through GPT-5.3 Codex variants and GPT-5.4 nano from the openai-codex catalog.
## [17.0.6] - 2026-07-20
+45 -51
View File
@@ -4,63 +4,57 @@
### Added
- Added `/tree` re-answer for a past `ask` toolResult: selecting it now re-opens the picker with the original questions and branches the new answer as a sibling toolResult, leaving the original answer's branch reachable ([#5895](https://github.com/can1357/oh-my-pi/pull/5895) by [@Mathews-Tom](https://github.com/Mathews-Tom)).
- Added configurable Hindsight client request deadlines via `hindsight.requestTimeoutMs` / `reflectTimeoutMs` / `recallTimeoutMs` / `retainTimeoutMs` settings (and matching `HINDSIGHT_*_TIMEOUT_MS` env vars).
- Added a `/tree` re-answer option for past `ask` tool 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`, and `retainTimeoutMs` settings (and matching `HINDSIGHT_*_TIMEOUT_MS` environment variables).
- Added `omp-linux-musl-x64` and `omp-linux-musl-arm64` release binaries for Alpine and other musl-based Linux distributions, with automatic musl selection in the installer and self-updater.
### Changed
- Added `omp-linux-musl-x64` and `omp-linux-musl-arm64` release binaries for Alpine and other musl-based Linux distributions, with automatic musl selection in the binary installer. ([#3367](https://github.com/can1357/oh-my-pi/issues/3367))
- Edit-tool previews, diff components, and intra-line word highlighting now compute line and word diffs natively, cutting synchronous diff time 2-10x on large inputs (a 50k-line file at 20% edit density drops from ~26s to ~2.4s; see `packages/natives/bench/diff-results.md`) ([#6279](https://github.com/can1357/oh-my-pi/pull/6279) by [@wolfiesch](https://github.com/wolfiesch)).
- 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.
### Fixed
- Fixed `Ctrl+V` clipboard paste being dropped while API-key and other modal prompts own focus ([#6057](https://github.com/can1357/oh-my-pi/issues/6057)).
- Fixed `omp update` on musl-based Linux hosts downloading the glibc release binary over a musl install; self-update now detects a musl host (Alpine release file or musl loader) and fetches the matching `omp-linux-musl-*` asset.
- Fixed `scripts/install.sh` installing an x86_64 build on Apple Silicon when an x86_64 `bun` runs under Rosetta. The default path only checked whether `bun` existed; it now compares `bun`'s `process.arch` to the host (detected via `sysctl -in hw.optional.arm64` so Rosetta can't spoof it) and falls back to the prebuilt native binary on a mismatch, while `--source` errors with an actionable message. `install_binary` also derives the arch from the real host instead of the Rosetta-translated `uname -m` ([#6268](https://github.com/can1357/oh-my-pi/issues/6268)).
- Fixed the model picker hiding Codex models available only through a second configured ChatGPT/Codex OAuth account. Catalog discovery now resolves every stored `openai-codex` OAuth account and unions their `/models` catalogs instead of surfacing only the discovery preflight account's list ([#6265](https://github.com/can1357/oh-my-pi/issues/6265)).
- Fixed GitHub Copilot 1M-context models (e.g. `github-copilot/gpt-5.6-sol-1m`) disappearing from the model picker on restart, with a `Could not restore model` warning, until discovery was manually refreshed. The startup cache loader now restores their transport headers from the bundled base via `requestModelId`. ([#6037](https://github.com/can1357/oh-my-pi/issues/6037), [#6284](https://github.com/can1357/oh-my-pi/issues/6284))
- Fixed `--model <role>` skipping the role's ordered `retry.fallbackChains` when its configured primary is unavailable, so startup now selects the first available authenticated fallback instead of leaving the role unresolved ([#6283](https://github.com/can1357/oh-my-pi/issues/6283)).
- Fixed global `setModelRole` persisting the entire stale in-memory `modelRoles` record, which clobbered concurrent/external per-role edits to `config.yml` (roles reverted, added keys vanished) when a process with a stale global snapshot made one global model switch. Global saves now merge only the changed role into the re-read file, mirroring the project save path ([#6260](https://github.com/can1357/oh-my-pi/issues/6260)).
- Fixed a terminal provider error on the continuation turn after a failed tool result silently ending the run with no durable record of why. When retry, model fallback, and compaction all declined a `stopReason: "error"` turn with no substantive content, `#persistSessionMessageIfMissing` dropped it as an empty error turn, so the session JSONL stopped at the last tool result and the provider's `errorMessage` was lost. The non-retry terminal error tail now persists the empty error turn (mirroring the retry-lifecycle dead-ends), keeping it off the wire on reload while preserving the diagnostic ([#6249](https://github.com/can1357/oh-my-pi/issues/6249)).
- Fixed repeated OpenRouter Gemini reasoning-to-payload stream closures consuming the full ten-attempt retry budget; thinking-bearing `server_error: stream closed with reason: error` failures now get one recovery attempt before surfacing.
- Fixed Agent Hub freezing for tens of seconds when opening a large read-only Advisor transcript. On cold open the viewer laid out every synthetic `Session update` input as full Markdown before `ScrollView` clipped the viewport (a 6.5 MiB `__advisor.jsonl` blocked `render()` for ~27s in a repro). Synthetic (agent-attributed) inputs now collapse to a compact summary row (`<heading> · <size> · <n> lines · ctrl+o`) and build their Markdown body only when expanded, so blocks above the viewport never pay layout cost on first frame ([#6308](https://github.com/can1357/oh-my-pi/issues/6308)).
- Fixed `/agents` showing prewalk as off for the bundled `task` agent when `task.prewalk` enables its runtime default ([#6306](https://github.com/can1357/oh-my-pi/issues/6306)).
- Fixed `hub start`/`for:"ready"` waits blocking for the full readiness timeout when the launched process became ready and exited within one poll interval (or exited before ever becoming ready). The wait now wakes on the sticky `readyAt` marker or any terminal state instead of sampling the transient live state, and `start` reports `Process exited before readiness was observed.` for a pre-ready exit ([#6303](https://github.com/can1357/oh-my-pi/issues/6303)).
- Fixed `tools.maxTimeout` only clamping explicitly-passed tool timeouts: the per-tool default (e.g. `bash` 300s), used whenever the agent omits `timeout`, bypassed the ceiling entirely. `clampTimeout` now caps the resolved effective timeout — including the default-fallback path — against `tools.maxTimeout` at every call site (`bash`, `eval`, `browser`, `debug`, `lsp`, `fetch`, and the session-level bash executor) ([#6294](https://github.com/can1357/oh-my-pi/issues/6294)).
- Fixed MCP argument-shaping parity between direct and Task/subagent tool calls: `MCPTool`/`DeferredMCPTool` now declare `strict: false` so OpenAI-family serializers preserve the explicit non-strict flag (models no longer over-fill mutually exclusive optional fields), and Task proxies (`createMCPProxyTools`) now delegate to the current source MCP tool instead of rebuilding a raw `tools/call`, so harness-intent (`i`) stripping, optional-placeholder pruning, local-URL resolution, reconnect, abort, and result metadata match the direct path. Strict servers no longer reject proxied calls with `unrecognized_keys ["i"]` ([#6208](https://github.com/can1357/oh-my-pi/issues/6208)).
- Fixed the remapped TypeBox compatibility shim omitting `Type.Unsafe`, which crashed extensions such as `pi-mcp-adapter` when they registered tools from raw MCP input schemas ([#6221](https://github.com/can1357/oh-my-pi/issues/6221)).
- Fixed `omp models` hanging after output when loaded extensions kept background resources alive; the one-shot command now emits `session_shutdown` and clears managed extension timers before returning ([#6297](https://github.com/can1357/oh-my-pi/issues/6297)).
- Fixed HTML session exports overflowing the browser call stack when rendering valid deeply nested conversation trees.
- Fixed summarized changelog entries being reintroduced by stale pull-request merges and repeated in later patch release notes ([#6157](https://github.com/can1357/oh-my-pi/issues/6157)).
- Fixed AgentSession ending task agents on the provider terminal message `Unable to connect. Is the computer able to access the url?` instead of entering its bounded auto-retry path ([#6139](https://github.com/can1357/oh-my-pi/pull/6139)).
- Fixed a cache-cold startup race where `modelRoles.default` pointing at a `models.yml` discovery provider (e.g. a custom OpenAI-compatible endpoint with `discovery.type: openai-models-list`) was silently replaced by an unrelated authenticated provider's default. `createAgentSession` resolves the default role before background discovery populates the catalog, so on a cold `models.db` the configured provider had no models yet and the fallback went straight to `pickDefaultAvailableModel`. Startup now awaits one cache-aware discovery pass and re-resolves the configured default whenever it is still unresolved (not only when nothing resolved at all) before accepting a bundled-provider fallback ([#6162](https://github.com/can1357/oh-my-pi/issues/6162)).
- Fixed unqualified `--model` startup selection preferring an unauthenticated provider's catalog entry over the same model from a configured provider. ([#6150](https://github.com/can1357/oh-my-pi/issues/6150))
- Fixed provider stream failures being invisible in the main log: the `agent_end` handler recorded `stopReason`/`provider`/`model` at debug only and dropped `errorMessage`/`errorStatus`/`errorId`, so a session dying repeatedly on provider errors left no actionable trace outside the session transcript. A turn ending in `stopReason:"error"` now emits one warn-level `agent turn ended with provider error` log carrying `provider`, `model`, `errorMessage`, `errorStatus`, and `errorId` ([#6177](https://github.com/can1357/oh-my-pi/issues/6177)).
- Fixed parallel `todo done` calls losing completions when asynchronous session event handling replayed stale result snapshots over newer tool state ([#6148](https://github.com/can1357/oh-my-pi/issues/6148)).
- Fixed `omp` crashing with `[Unhandled Rejection] Error: ENOENT ... uv_spawn 'git'` when `git` is not installed/on `PATH` (e.g. Windows relying on WSL git). The read-only git helpers in `utils/git.ts` spawned `git` directly and only inspected the exit code, so `Bun.spawn`/`Bun.spawnSync` throwing `ENOENT` at launch escaped as an unhandled rejection; missing-binary launches now degrade to a non-zero result (async) or `null` (sync ref readers) instead of crashing, while mutating/checked commands keep surfacing the clean "git is not installed." error ([#6169](https://github.com/can1357/oh-my-pi/issues/6169)).
- Fixed `/changelog` and `/changelog full` reporting no entries in standalone binaries by embedding omp's release history as the safe fallback when no package asset directory exists ([#6172](https://github.com/can1357/oh-my-pi/issues/6172)).
- Fixed isolated branch merge-back rejecting committed agent edits when the parent had unrelated uncommitted changes in the same file; dirty-baseline blobs are now seeded into the parent object database and replayed with a 3-way synthetic-tree apply ([#6135](https://github.com/can1357/oh-my-pi/issues/6135)).
- Fixed the single 30s Hindsight client timeout aborting healthy `reflect` calls, which are agentic retrieve+synthesize ops that routinely exceed 30s; each op now has its own deadline (reflect defaults to 120s) and the timeout error reports the effective seconds ([#6125](https://github.com/can1357/oh-my-pi/issues/6125)).
- Fixed Mnemopi consolidation re-storing cumulative session transcripts after incremental auto-retain, including after resuming a session ([#6058](https://github.com/can1357/oh-my-pi/issues/6058)).
- Fixed turn-ending Codex rate-limit errors remaining hidden behind the fullscreen Plan Review overlay and leaving its approval promise pending ([#6086](https://github.com/can1357/oh-my-pi/issues/6086)).
- Fixed prewalked subagents continuing to display their starting model after switching to the target model. ([#6083](https://github.com/can1357/oh-my-pi/issues/6083))
- Fixed Esc aborting an ongoing agent turn instead of overlapping TTS playback, leaving speech uninterruptible ([#6118](https://github.com/can1357/oh-my-pi/issues/6118)).
- Fixed project system prompts shortening working directories beneath the user's home to `~`, which could cause models to invent an incorrect absolute path for tool calls ([#6100](https://github.com/can1357/oh-my-pi/issues/6100)).
- Fixed the TUI `/usage` matrix mis-aligning multi-account columns across quota windows: each window row was sorted independently by used fraction, so the positional `account N` labels denoted different credentials per row and an exhausted limit (e.g. a Kimi Code account's 5h window) could render under a sibling that still had quota. Account columns are now ordered once per provider (worst-first) and held stable across every window row ([#6067](https://github.com/can1357/oh-my-pi/issues/6067)).
- Fixed near-miss `xd://` write targets silently creating filesystem paths instead of surfacing a corrective URI error ([#6123](https://github.com/can1357/oh-my-pi/issues/6123)).
- Fixed the `task` tool rejecting a valid batch `{ context, tasks[] }` call with the misleading `task must be a string (was missing)` when `task.batch` was disabled. The flat single-spawn wire schema strips `tasks`/`context` (arktype `"+": "delete"`) and then fails on the now-missing `task` in the agent loop, preempting the tool's own actionable shape check. The tool now uses lenient argument validation so those raw args reach `execute()`, which explains the real cause (`task.batch is disabled…`) ([#6039](https://github.com/can1357/oh-my-pi/issues/6039)).
- Fixed JS/TS `debug` launches timing out on WSL2 with `networkingMode=mirrored` by waiting for the adapter's listening banner before connecting (avoiding the ghost-accept window on a just-released reservation port) and rejecting pending DAP requests and event waiters the moment the transport closes, so any transport failure surfaces as an immediate `DAP connection closed` error instead of a silent 30s timeout ([#6055](https://github.com/can1357/oh-my-pi/issues/6055)).
- Fixed the advisor docs (`docs/advisor-watchdog.md`) describing `/advisor`, `/advisor on`, and `/advisor off` as toggling the persisted `advisor.enabled` setting; the slash toggle is session-scoped and writes nothing to config ([#6128](https://github.com/can1357/oh-my-pi/issues/6128)).
- Fixed post-compaction transcript rebuilds blocking the main thread by reusing settled message components and their rendered layout caches ([#6033](https://github.com/can1357/oh-my-pi/issues/6033)).
- Fixed the fullscreen Plan Review overlay staying interactive with no feedback after a choice was picked: while the approval ran slow async work (e.g. context compaction) the overlay remained mounted, arrow keys still moved the cursor, and repeat Enter/Esc were silently swallowed, so users on Ghostty and macOS Terminal thought `/plan` was frozen. The overlay now locks input and shows a "submitting…" indicator the moment a choice commits ([#5926](https://github.com/can1357/oh-my-pi/issues/5926)).
### Removed
- Fixed dynamic model discovery refreshes dropping provider-level compatibility overrides from `models.yml` ([#6041](https://github.com/can1357/oh-my-pi/issues/6041)).
- Fixed a startup crash that locked users out of the app when `prewalk.enabled` was set but the prewalk hand-off target (default `@smol`) had no configured API key; prewalk now stays unarmed with a warning instead of aborting startup ([#6064](https://github.com/can1357/oh-my-pi/issues/6064)).
- Fixed in-progress aborts awaiting `session_stop` extension handlers whose results would be discarded ([#6134](https://github.com/can1357/oh-my-pi/issues/6134)).
- Fixed `/retry` reporting "Nothing to retry" after a stream stalled or aborted mid-tool-call, where a synthetic tool result appended for the un-run tool call shadowed the failed assistant turn ([#6056](https://github.com/can1357/oh-my-pi/issues/6056)).
- Fixed locally consumed extension commands triggering automatic title generation and exposing their command text to the title model ([#6061](https://github.com/can1357/oh-my-pi/issues/6061)).
- Fixed an issue where `Ctrl+V` clipboard paste was ignored while API-key and other modal prompts had focus.
- Fixed `scripts/install.sh` incorrectly 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.yml` by 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 `/agents` incorrectly showing prewalk as disabled for the bundled `task` agent when enabled by its runtime default.
- Fixed `hub start` waiting for the full timeout when a launched process exited or became ready quickly.
- Fixed `tools.maxTimeout` failing 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-adapter` caused by the TypeBox compatibility shim omitting `Type.Unsafe`.
- Fixed `omp models` hanging 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 `--model` startup 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 done` calls losing completions due to asynchronous session events overwriting newer tool states.
- Fixed `omp` crashing when `git` is not installed or missing from the system `PATH`.
- Fixed `/changelog` commands 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 `reflect` operations 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 `/usage` matrix 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 `task` tool rejecting valid batch calls with misleading validation errors when batching is disabled.
- Fixed JS/TS `debug` launches 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.enabled` was set but the prewalk hand-off target had no configured API key.
- Fixed in-progress aborts awaiting `session_stop` extension handlers whose results would be discarded.
- Fixed `/retry` reporting "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
+1 -1
View File
@@ -4,7 +4,7 @@
### Fixed
- Prevented IME composition (Korean/Japanese/Chinese) from duplicating the last character when pressing Enter to commit in the collab web composer. ([#6163](https://github.com/can1357/oh-my-pi/issues/6163))
- Fixed an issue where IME composition (Korean, Japanese, and Chinese) duplicated the last character when pressing Enter to commit in the composer.
## [17.0.1] - 2026-07-16
+1 -1
View File
@@ -4,7 +4,7 @@
### Changed
- Snapshot recovery line remapping now uses the native line diff ([#6279](https://github.com/can1357/oh-my-pi/pull/6279) by [@wolfiesch](https://github.com/wolfiesch)).
- Improved snapshot recovery line remapping by utilizing native line diffing.
## [17.0.4] - 2026-07-18
+1 -1
View File
@@ -4,7 +4,7 @@
### Changed
- Recall hot loops (exact vector-index search, SHMR similarity clustering, and default-similarity MMR rerank) now run on native batch kernels with one N-API crossing per operation. Wrapper-inclusive speedups at dim=384 on Apple M1 (see `bench/native-vectors.bench.json`): 1.6-1.8x top-K search, 2.4x pairwise clustering scans at the measured 100- and 1000-candidate points (0.86x at the measured 10-candidate point, where the whole scan costs ~20µs either way), and 22-36x MMR rerank. Binary vector search stays on the TypeScript loops (per-call packing measured as a wash), as do custom `similarityFn` MMR reranks and incremental per-row scoring ([#6280](https://github.com/can1357/oh-my-pi/pull/6280) by [@wolfiesch](https://github.com/wolfiesch)).
- Optimized vector operations (exact vector-index search, SHMR similarity clustering, and default-similarity MMR rerank) by migrating hot loops to native batch kernels, resulting in significant performance improvements (up to 1.8x faster top-K search, 2.4x faster pairwise clustering, and 22-36x faster MMR reranking).
## [17.0.4] - 2026-07-18
+3 -3
View File
@@ -4,12 +4,12 @@
### Added
- Added jsdiff-compatible native diff exports: `diffLines`, `diffWords`, `diffLineRuns`, and `structuredPatchHunks` ([#6279](https://github.com/can1357/oh-my-pi/pull/6279) by [@wolfiesch](https://github.com/wolfiesch)).
- Added batch vector kernels for mnemopi recall paths: `cosineSimilarityPairs`, `vectorIndexTopK`, and `mmrRerankIndices` ([#6280](https://github.com/can1357/oh-my-pi/pull/6280) by [@wolfiesch](https://github.com/wolfiesch)).
- Added jsdiff-compatible native diff exports: `diffLines`, `diffWords`, `diffLineRuns`, and `structuredPatchHunks`.
- Added batch vector kernels for mnemopi recall paths: `cosineSimilarityPairs`, `vectorIndexTopK`, and `mmrRerankIndices`.
### Fixed
- Fixed the in-process `rm` builtin treating an empty path operand as the shell working directory, so `rm -rf ""` recursively deleted the current directory instead of rejecting the operand. An empty operand reached `pi_uutils_ctx::resolve`, which joins `""` onto the cwd and yields the cwd itself; the builtin now rejects empty operands before resolution, matching GNU `rm` (ENOENT, silent under `-f`) and leaving the cwd untouched ([#6287](https://github.com/can1357/oh-my-pi/issues/6287)).
- Fixed a critical issue where the in-process `rm` builtin treated an empty path operand as the current working directory, causing `rm -rf ""` to recursively delete the current directory. Empty operands are now rejected, matching GNU `rm` behavior.
## [17.0.5] - 2026-07-18
+3 -3
View File
@@ -4,9 +4,9 @@
### Fixed
- Fixed ST-terminated OSC 8 hyperlinks corrupting Markdown table column widths when linked text started with inline markup.
- Prevented canonical slash commands and their matching aliases from appearing as duplicate autocomplete rows ([#6131](https://github.com/can1357/oh-my-pi/issues/6131)).
- Fixed Ctrl+L appearance refreshes inside tmux reading tmux's stale OSC 11 background cache instead of querying the outer terminal when passthrough is enabled ([#6066](https://github.com/can1357/oh-my-pi/issues/6066)).
- Fixed an issue where OSC 8 hyperlinks with inline markup corrupted Markdown table column widths.
- Prevented duplicate autocomplete suggestions for slash commands and their matching aliases.
- Fixed terminal background color detection during screen refreshes (Ctrl+L) inside tmux when passthrough is enabled.
## [17.0.6] - 2026-07-20
+1 -54
View File
@@ -3,15 +3,7 @@ import * as fs from "node:fs/promises";
import * as os from "node:os";
import * as path from "node:path";
import { $ } from "bun";
import {
collectPromotableAddedItemLines,
fixChangelogContent,
parseChangelog,
parseItems,
recordSummarizedItemFingerprints,
renderChangelog,
runChangelogFixer,
} from "./fix-changelogs";
import { collectPromotableAddedItemLines, fixChangelogContent, runChangelogFixer } from "./fix-changelogs";
describe("collectPromotableAddedItemLines", () => {
it("keeps new changelog item additions while ignoring moves and edits", () => {
@@ -163,51 +155,6 @@ describe("fixChangelogContent", () => {
);
});
it("drops stale source bullets after summarization changes their text", () => {
const sourceItem =
"- Fixed isolated `task` subagents mutating the parent checkout and stacking parallel task branches ([#6003](https://github.com/can1357/oh-my-pi/issues/6003)).";
const document = parseChangelog(
["# Changelog", "", "## [Unreleased]", "", "### Fixed", "", sourceItem, ""].join("\n"),
);
const unreleased = document.sections.find(section => section.title === "Unreleased");
if (!unreleased) throw new Error("fixture is missing Unreleased");
const sourceItems = unreleased.subsections.flatMap(sub => parseItems(sub.lines));
const summarizedItem =
"- Fixed isolated `task` subagents mutating the parent checkout by detaching the git directory.";
unreleased.subsections = [{ title: "Fixed", lines: [{ text: summarizedItem, lineNumber: 0 }] }];
recordSummarizedItemFingerprints(document, sourceItems, unreleased);
const staleMerge = renderChangelog(document).replace(summarizedItem, `${summarizedItem}\n${sourceItem}`);
const result = fixChangelogContent(staleMerge, new Set());
expect(result.droppedReleasedDuplicates).toBe(1);
expect(result.content).toContain(summarizedItem);
expect(result.content).not.toContain(sourceItem);
});
it("keeps bullets the rewrite preserved verbatim instead of dropping them as consumed", () => {
const keptItem =
"- Fixed crash when opening the empty settings panel ([#1234](https://github.com/can1357/oh-my-pi/issues/1234)).";
const document = parseChangelog(
["# Changelog", "", "## [Unreleased]", "", "### Fixed", "", keptItem, ""].join("\n"),
);
const unreleased = document.sections.find(section => section.title === "Unreleased");
if (!unreleased) throw new Error("fixture is missing Unreleased");
const sourceItems = unreleased.subsections.flatMap(sub => parseItems(sub.lines));
// The model returned this bullet unchanged; applyRewrite writes it back.
unreleased.subsections = [{ title: "Fixed", lines: [{ text: keptItem, lineNumber: 0 }] }];
recordSummarizedItemFingerprints(document, sourceItems, unreleased);
const afterRewrite = renderChangelog(document);
expect(afterRewrite).not.toContain("changelog-source-item");
const result = fixChangelogContent(afterRewrite, new Set());
expect(result.droppedReleasedDuplicates).toBe(0);
expect(result.content).toContain(keptItem);
});
it("can recover Unreleased by dropping bullets known to be historically released", () => {
const content = [
"# Changelog",
+10 -67
View File
@@ -7,7 +7,6 @@ const CHANGELOG_GLOB = "packages/*/CHANGELOG.md";
const ORDERED_SECTION_TITLES = ["Breaking Changes", "Added", "Changed", "Fixed", "Removed"] as const;
const CHANGELOG_BASELINE_REF = "refs/clog";
const CHANGELOG_BASELINE_NAME = "clog";
const SUMMARIZED_ITEM_MARKER = /^<!-- changelog-source-item sha256:([0-9a-f]{64}) -->$/;
export interface NumberedLine {
text: string;
@@ -278,58 +277,6 @@ function itemTextKey(itemLines: readonly string[]): string {
return trimBlankLines(itemLines).join("\n");
}
function itemFingerprint(itemLines: readonly string[]): string {
const text = itemTextKey(itemLines);
if (!text) return "";
return new Bun.CryptoHasher("sha256").update(text).digest("hex");
}
function collectRecordedItemFingerprints(lines: readonly NumberedLine[], keys: Set<string>): void {
for (const line of lines) {
const fingerprint = line.text.match(SUMMARIZED_ITEM_MARKER)?.[1];
if (fingerprint) keys.add(fingerprint);
}
}
function addItemKeys(keys: Set<string>, itemLines: readonly string[]): void {
const text = itemTextKey(itemLines);
if (text) keys.add(text);
const fingerprint = itemFingerprint(itemLines);
if (fingerprint) keys.add(fingerprint);
}
/**
* Records fingerprints for source items consumed by summarization. Called
* after the rewrite is applied: items whose exact text survives in the
* rewritten section are skipped — recording those would make the next fixer
* run treat the still-valid Unreleased bullet as already consumed and drop it.
*/
export function recordSummarizedItemFingerprints(
document: ChangelogDocument,
sourceItems: readonly ParsedItem[],
rewrittenSection: ReleaseSection,
): void {
const surviving = new Set<string>();
for (const subsection of rewrittenSection.subsections) {
for (const item of parseItems(subsection.lines)) {
const text = itemTextKey(item.lines);
if (text) surviving.add(text);
}
}
const recorded = new Set<string>();
collectRecordedItemFingerprints(document.prefixLines, recorded);
for (const item of sourceItems) {
if (surviving.has(itemTextKey(item.lines))) continue;
const fingerprint = itemFingerprint(item.lines);
if (!fingerprint || recorded.has(fingerprint)) continue;
document.prefixLines.push({
text: `<!-- changelog-source-item sha256:${fingerprint} -->`,
lineNumber: 0,
});
recorded.add(fingerprint);
}
}
function subsectionHasItem(subsection: Subsection, itemLines: readonly string[]): boolean {
const wanted = itemTextKey(itemLines);
if (!wanted) return true;
@@ -341,12 +288,12 @@ function subsectionHasItem(subsection: Subsection, itemLines: readonly string[])
function collectReleasedItemKeys(document: ChangelogDocument): Set<string> {
const keys = new Set<string>();
collectRecordedItemFingerprints(document.prefixLines, keys);
for (const section of document.sections) {
if (section.title === "Unreleased") continue;
for (const subsection of section.subsections) {
for (const item of parseItems(subsection.lines)) {
addItemKeys(keys, item.lines);
const key = itemTextKey(item.lines);
if (key) keys.add(key);
}
}
}
@@ -354,10 +301,11 @@ function collectReleasedItemKeys(document: ChangelogDocument): Set<string> {
}
/**
* Drops items from [Unreleased] that already appeared in a released section or
* were consumed by changelog summarization. Summarization records source
* fingerprints before replacing the text, so stale branches cannot reintroduce
* the original wording. Runs before promotion and only mutates Unreleased.
* Drop items from [Unreleased] that already appear verbatim in a released
* section — the residue of a release that copied [Unreleased] into the new
* version section without clearing it. The released copy is authoritative, so
* the Unreleased duplicate is removed. Runs before promotion (while parse line
* numbers are still real) and only ever mutates the Unreleased section.
*/
function dropUnreleasedDuplicatesOfReleased(
document: ChangelogDocument,
@@ -371,11 +319,7 @@ function dropUnreleasedDuplicatesOfReleased(
let dropped = 0;
for (const subsection of unreleased.subsections) {
const duplicates = parseItems(subsection.lines).filter(item => {
const text = itemTextKey(item.lines);
const fingerprint = itemFingerprint(item.lines);
return releasedKeys.has(text) || releasedKeys.has(fingerprint);
});
const duplicates = parseItems(subsection.lines).filter(item => releasedKeys.has(itemTextKey(item.lines)));
if (duplicates.length === 0) continue;
const linesToRemove = lineRangeSet(duplicates);
subsection.lines = subsection.lines.filter(line => !linesToRemove.has(line.lineNumber));
@@ -860,12 +804,11 @@ async function collectHistoricalReleaseRecovery(
if (recovery.sectionsByTitle.get(section.title) !== undefined) {
for (const subsection of section.subsections) {
for (const item of parseItems(subsection.lines)) {
addItemKeys(recovery.itemKeys, item.lines);
recovery.itemKeys.add(itemTextKey(item.lines));
}
}
}
}
if (recovery) collectRecordedItemFingerprints(document.prefixLines, recovery.itemKeys);
}
}
@@ -986,7 +929,7 @@ function usage(): string {
"Usage: bun scripts/fix-changelogs.ts [--dry-run|--check] [--since <tag>] [--recover] [--pin]",
"",
"Moves changelog items added since the baseline from released sections into [Unreleased],",
"drops [Unreleased] items already released or consumed by changelog summarization, removes",
"drops [Unreleased] items that already appear verbatim in a released section, removes",
"blank separators between adjacent bullet items, then removes duplicate or empty",
"### category headings.",
"",
-3
View File
@@ -51,7 +51,6 @@ import {
parseChangelog,
parseItems,
type ReleaseSection,
recordSummarizedItemFingerprints,
renderChangelog,
resolveRepoRoot,
} from "./fix-changelogs";
@@ -335,10 +334,8 @@ async function run(options: RunOptions): Promise<RunResult> {
.replace(/^## \[Unreleased\]\n?/, "")
.trim();
const sourceItems = section.subsections.flatMap(sub => parseItems(sub.lines));
const rewritten = await requestRewrite(model, changelogPath, unreleasedBody);
applyRewrite(section, rewritten);
recordSummarizedItemFingerprints(document, sourceItems, section);
const next = renderChangelog(document);
if (next === content) continue;