- Retained tool-search server calls and opaque results in signed assistant history across direct streams, gateways, and custom-endpoint projection.
- Added replay regressions for interleaved thinking and client tool continuations.
Fixes#8559
- Add `renderPdfPageScreenshot` to render PDF pages via headless Chromium.
- Update `ReadTool` to intercept legacy PDF image paths and return page screenshots.
- Ensure daemon clients are closed on read command exit.
- RpcClient: when stdout closes before ready, race child.exited (which settles only after ptree drains the stderr tail for nonzero exits) for 250ms before rejecting, so the earlier-registered exit watcher rejects with the real stderr text instead of an empty 'Stderr:'.
- mock-rpc-agent fixture: await the stderr pipe write callback before process.exit so failure text cannot be dropped unflushed.
- sdk-tool-activation: restore the default extension-handler budget once the intentionally stalled activation times out, so full-suite machine load cannot also time out the genuine recovery registration.
Both tests flaked only under concurrent full-suite chunk load; 10 concurrent stress runs pass post-fix.
- Replaced Reflect.deleteProperty teardown with the descriptor-preserving restoreProperty pattern used by the other ProcessTerminal suites, so real isTTY/setRawMode/columns/rows own-properties survive on TTY hosts and later test files are not poisoned.
- Replaced the custom MuPDF-WASM PDF extraction and rendering pipeline with the new `pdfToMarkdown` native function from `@oh-my-pi/pi-natives`.
- Removed legacy MuPDF extraction modules, WASM embedding scripts, and PDF image extraction tools.
- Added OCR warnings and browser/text redirection for unsupported PDF image reads.
- Updated native package definitions, documentation, and test suites for the new PDF inspection capability.
Passed the cmd.exe /s /c command line through Bun verbatim so configured editors and temporary paths retain their quotes.
Added command-line regression coverage and documented the fix.
Fixes#8544
The private-CSI reassembly gate and the DA1 swallow were both guarded by
`#da1SentinelOwners.length > 0`, so a Device-Attributes reply that arrived
after the startup capability-probe sentinel FIFO drained fell through to the
input handler and leaked into the composer as literal text (e.g.
`1;22;...;52c`). The extra latency of an SSH/zmx PTY chain makes the race
observable.
`CSI ? ... c` and split private-CSI responses are terminal->host reports,
never keystrokes, so they are now consumed regardless of whether a sentinel
is still outstanding.
Fixes#8542
-[DCDevice isSupported] synchronously opens an XPC connection to the per-user DeviceCheck metadata daemon, which exists only in an interactive GUI login session. From a session without graphic access (SSH, launchd LaunchDaemon, CI runner, service account, sandbox) the connection setup hits _xpc_api_misuse and aborts the process with SIGTRAP before any completion handler runs, so the promise never rejects and every openai-codex/* OAuth model becomes unusable.
Check the caller's security session for the sessionHasGraphicAccess attribute via SessionGetInfo before touching DeviceCheck; resolve { supported: false, error } when it is absent, mirroring the non-macOS stub and letting the caller send an error-coded attestation instead of dying.
Fixes#8353
The /hotkeys table described app.exit (Ctrl+D) as "Exit (when editor is
empty)", implying readline/EOF-style conditional exit. The handler exits
unconditionally and snapshots the current prompt as a resumable draft
regardless of editor content (custom-editor.ts fires onExit for app.exit
with no empty check; input-controller.ts handleCtrlD calls shutdown()
unconditionally, which persists the draft). Corrected the line to
"Exit (saves current prompt as draft)".
Fixes#8530
buildWhere() appended a redundant hard `channel_id = ?` clause on top of
the `(session_id = ? OR scope = 'global' OR channel_id = ?)` visibility
clause. The hard AND nullified the `scope='global'` branch, so any global
row whose channel_id differed from the recall channelId — including rows
imported via importFromDict() with channel_id NULL — was silently dropped.
Channel isolation is fully preserved by the visibility OR-clause alone
(other-channel, non-global, cross-session rows still fail all three
disjuncts), so removing the hard clause restores global visibility without
leaking other channels.
Fixes#8525
The OpenRouter non-Flash DeepSeek V4 effort override forced HIGH_ONLY for every id, so getModelDefinedEfforts clamped deepseek-v4-pro-0813 to high even though OpenRouter's /models advertises reasoning.supported_efforts [low,high,max] and the route accepts them. Carve out the dated SKU to the wire-exact low/high/max ladder while keeping the undated deepseek-v4-pro route high-only.
Fixes#8517
Moved the optional Streamable HTTP GET listener after the initialized notification so stateful servers do not terminate the session during setup.
Added regression coverage for a server that rejects pre-initialization GET traffic.
Fixes#8514
- Updated `RemoteAuthCredentialStore` to track broker usage accounts across snapshots and streams before account-pool filtering.
- Replaced `#countUsageAccounts` with dynamic tracking methods `#replaceBrokerUsageAccounts`, `#upsertBrokerUsageAccount`, and `#removeBrokerUsageAccount`.
- Refactored `AuthStorage.#fetchUsageCached` to accept an options object for `timeoutMs` and `forceRefresh`.
- Updated dockerignore patterns to exclude `**/.venv/` and ensure depth-agnostic `.env` secret exclusion.
- Scale usage fetch timeout dynamically in AuthBrokerClient based on the maximum account count per provider.
- Track maximum usage accounts per provider in RemoteAuthCredentialStore snapshot applications.
- Add comprehensive wire and store tests covering serialized account batch timeouts and account pool sizing.
Copilot discovery writes an authoritative cache, so online-if-uncached served the prior endpoint for the full TTL after COPILOT_GITHUB_TOKEN switched accounts. Keying the cache namespace on the credential forces fresh discovery for a new token instead of reusing a stale personal-endpoint cache.
Fixes#8507
- Switched Docker images to build native addons via cargo/napi-rs (`OMP_NATIVE_BUILD_BACKEND=cargo`) instead of Bazel.
- Updated Cargo.toml workspace members explicitly to prevent loading errors from stale directories under crates/.
- Added depth-agnostic patterns to .dockerignore files to exclude nested build outputs from Docker build contexts.
- Added OMP_NATIVE_CARGO_PROFILE environment variable to support configuring cargo profiles for addon builds.
- Added force-refresh tracking to serialize provider usage probes and prevent stale fallback re-plays after manual invalidation.
- Updated usage request handling to incorporate cache epochs and prevent stale in-flight results from overwriting new data.
- Added integration test verifying that broker invalidations correctly drop server-side last-good usage reports.
Threaded the shared 10s discovery AbortSignal into the copilot_internal/user probe so a stalled endpoint falls back to the personal host instead of hanging startup or refresh.
Fixes#8507
Shared the plan-endpoint probe between OAuth login and raw token model discovery so Business credentials route to their advertised API host.
Added regression coverage for the raw environment-token path.
Fixes#8507
- Recover dangling range separators in hunk headers as single-line ranges instead of rejecting them.
- Ensure strict rejection is maintained when a dangling separator is followed by invalid tokens.
Detected npm and Bun ownership from the bin link immediate target within each precise global node_modules root. Foreign aliases now update their resolved standalone binary without replacing the alias.
Fixes#8468
- Replaced child_process spawn with Bun.spawn in packages/coding-agent/src/utils/external-editor.ts.
- Removed the browser tab evaluation test suite from packages/coding-agent/test/tools/browser-tab-evaluate.test.ts.
formatReadHashlineHeader collapsed every relative in-workspace path to its
basename, so reading a nested file (e.g. src/settings.json) emitted
[settings.json#tag]. When a same-basename file existed at the session cwd,
a verbatim follow-up edit resolved against the cwd file; Patcher.prepare only
runs snapshot-tag path recovery when the authored path is missing, so the
valid edit was deterministically rejected with "hash is not from this
session". Keep the workspace-relative path, which names the file uniquely and
stays directly resolvable against cwd. Out-of-workspace absolute paths remain
shortened; root-level files are unchanged.
Fixes#8482
- Removed markit-converters.test.ts from packages/coding-agent.
- Updated google-gemini-cli provider to ensure antigravity version during stream execution.
- Updated antigravity discovery options to use fetcher fallback.
Resolved npm and bun bin-entry symlinks before selecting the update method, and preserved foreign aliases by replacing their standalone target.
Fixes#8468