On macOS the shared headless browser daemon launched from the system Google Chrome app bundle, running as a com.google.Chrome instance. macOS LaunchServices could then deliver the user's open-URL Apple Events to the daemon instead of their own Chrome, silently swallowing link clicks.
ensureChromiumExecutable now prefers the isolated Chrome for Testing binary (com.google.chrome.for.testing) on macOS, falling back to system Chrome only when Chrome for Testing cannot be obtained. Other platforms keep the download-avoiding system Chrome preference.
Fixes#8673
Mirrored registry status from pre-wire session run-state transitions and required live session corroboration before a peer can sustain bare hub waits.
Fixes#8634
Added Chromium no-startup-window to the broker-owned browser launch so no unowned foreground page survives session tab cleanup.
Covered the resolved Chromium argv and documented the Windows regression.
Fixes#8615
reloadServer() sent the rust-analyzer-specific rust-analyzer/reloadWorkspace
request to every server before falling back to workspace/didChangeConfiguration.
Servers that crash on an unknown method instead of replying -32601 (Roslyn,
dotnet/roslyn#84890) were killed by `lsp reload` rather than reloaded.
Gate the request on isRustAnalyzerClient (exported from client.ts) or a
"rust-analyzer" server name; every other server reloads via
workspace/didChangeConfiguration directly. Consolidate tool.ts's inline
rust-analyzer detection onto the same helper.
Fixes#8571
The shared-browser CDP liveness probes (probeEndpoint, waitForCdp, probeCdpAt) used a bare fetch() against the loopback DevTools endpoint. Bun's fetch honors HTTP_PROXY/HTTPS_PROXY and forwards even 127.0.0.1 requests to the proxy unless NO_PROXY covers them, so a local proxy (e.g. Clash) that 502s internal addresses made a healthy daemon look dead and ensureSharedBrowser tore it down.
Replace the three probes with probeCdpStatus(), a raw-TCP HTTP/1.1 GET that never routes through a proxy and resolves to the response status (or null on unreachable/aborted/timeout).
Fixes#8567
- 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.
- 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.
- 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.
- Replaced time-based sleeps and polling loops with event-driven promise resolvers and fake timers across agent and tool tests.
- Migrated test suites to share in-memory auth storage and fixtures using lifecycle hooks.
- Updated catalog model definitions, metadata, and configurations.
The executable version probe added in ecb22957 ("validate Linux browser
executables") replaced the file-only check in resolveSystemChromium with
isChromiumExecutable, which spawns the candidate `--version` for every
platform. On Windows chrome.exe is a GUI-subsystem binary: `--version`
does not print to a detached stdout and can hand off to a running
instance, opening/activating the user's normal browser window, after
which the probe rejects the candidate and falls back to cached Chrome
for Testing.
Gate the spawn probe on process.platform === "linux" (its intended
platform, where non-Chromium PATH wrappers are the real risk) and trust
the executable-file check on Windows and macOS.
Fixes#8445
- Remove redundant definedness, null, and type checks across test suites in multiple packages.
- Clean up unused assertions, metadata tests, and obsolete test cases.
- Add good versus bad test filter guidelines and requirements to project documentation.
Updates test assertions and fixtures to reflect that V4 Pro now exposes the full [low, high, max] effort ladder, switches the incompatible-fallback test to the openrouter deepseek-v4-pro entry, and adds a shared browser lease in the evaluation suite to avoid relaunching Chromium per test under load.
- Displace overwritten destination into a temporary sibling directory during workspace renames.
- Restore the displaced file and clean up the temp directory if the main rename operation fails.
- applyWorkspaceEdit takes an onExecuted callback fired after each
filesystem mutation, so callers hold the executed prefix even when a
later op throws.
- applyWorkspaceEditWithLsp reconciles overlays/watchers for that prefix
best-effort before rethrowing the original apply error.
- applyWorkspaceEdit now returns { applied, executed }; ops skipped via
ignoreIfExists/ignoreIfNotExists are excluded from executed.
- applyWorkspaceEditWithLsp derives didClose/refresh/watched-file
notifications from executed ops, so a skipped rename no longer closes
the old URI overlay or emits phantom Deleted/Created events.
Skipped destination removal when an overwrite rename resolves both paths to the same inode (case-only rename on case-insensitive filesystems), so the source is no longer deleted before fs.rename runs.
Fixes#8373
Reject snippet-formatted or overlapping rename edits across all accepted URIs before applying any, so a later snippet edit cannot leave earlier files half-applied.
Fixes#8376
The willRenameFiles loop caught every non-abort, non-method-not-found
error into serverNotes and fell through to fs.rename, so a genuine
failure from a server that supports the request moved the path without
its semantic edits, leaving references dangling. Split client acquisition
from the request, track hard failures, and abort before any mutation when
a supporting server errors. Servers replying method-not-found are still
skipped without blocking.
Fixes#8380
The direct diagnostics loop caught non-abort server errors without recording them, so a file whose every applicable server failed produced an empty aggregate rendered as OK with success: true — a false-negative hiding a total diagnostics failure.
Track per-file and global success/failure counts: zero successful server responses now yields success: false with an explicit failure line, while partial success still surfaces diagnostics and names the servers that failed.
Fixes#8377
Propagated CreateFile, RenameFile, and DeleteFile options through workspace edit planning and enforced their overwrite, ignore, and recursive semantics during execution.
Fixes#8373
Advertised abort semantics because multi-file text edits are applied sequentially and cannot satisfy textOnlyTransactional.
Added initialization capability coverage and documented the fix.
Fixes#8375
- Multi-question dialogs now advance on Enter in multi-select mode
instead of submitting every question at once (roboomp blocking)
- Ask tool accepts an empty multi-select submission as a "select none"
answer instead of aborting as a cancellation (codex P2)
- Footer hint reflects advance vs submit for multi-question dialogs
- Move the #8252 changelog entry to Unreleased (codex P2)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Added the `--external-thinking` CLI flag alongside model capability checks to gate external thinking tool availability.
- Updated Anthropic and Google transports to honor `forceReasoningOff` for native thinking-off controls.
- Renamed the `thoughts` property and parameter to `notes` across think fixtures, tools, and tests.
- Updated system prompt instructions and test suites to verify transport-specific thinking and tool activation.