Removed the bash tool execution-path rewrite that stripped trailing head/tail pipeline stages before running commands.
Added regression coverage for short-reading final pipeline stages.
Fixes#4562
Tightened xAI web_search's xai-oauth preference so lower-priority xai-oauth api_key or fallback credentials do not get shadowed by the shared XAI_API_KEY fallback.
Added regression coverage for the stored xai-oauth API-key plus shared XAI_API_KEY case, preserving explicit xai runtime credential routing.
Refs #4536
Restricted the xai-oauth preference in web_search to dedicated credentials (hasNonEnvCredential("xai-oauth") or XAI_OAUTH_TOKEN) so an XAI_API_KEY-only environment no longer routes an explicit xai runtime/config credential through the xai-oauth resolver.
Added regression tests covering the shared-env case and the xai-only availability check.
Refs #4536
- Stopped adding Responses Agent Tools-incompatible search_parameters to xAI web_search requests.
- Kept limit and numSearchResults enforcement as a local cap over parsed sources and citations.
- Added regression coverage for limit, numSearchResults, recency, and local cap request shapes.
Fixes#4537
Validated path-like renderer inputs before calling path helpers so provider-supplied arrays or objects cannot crash TUI rendering before schema validation reports the bad tool call.
Added renderer regression coverage for read, write, and edit call/result components with array and object path arguments.
Fixes#4525
- Replaced commit-based stability checks with a unified `isTranscriptBlockFinalized` tracking mechanism.
- Removed deprecated provisional rendering configuration and flags across tool and renderer interfaces.
- Standardized native scrollback boundary logic to pin at the first unfinalized block using settled row verification.
- Updated and refactored test suites to validate block finalization and settled row boundaries instead of deprecated commit stability methods.
The cmux release regression tests install spies on CmuxSocketClient.prototype. Bun keeps those spies active across later browser-* files unless the file restores them explicitly, so browser-cmux-socket.test could stop exercising the real socket client depending on order.
Restore all Bun test mocks in afterEach after draining any test tabs, preserving mocked cleanup while preventing cross-file pollution.
Fixes#4499
Codex review of #4502 flagged that a bare `.catch(() => undefined)`
neutralizes the unhandledRejection but leaves the affected `runInTab`
call blocked inside `runCmuxCode` until timeout when the in-flight
code does not make another cmux socket request (e.g. `await
wait(60_000)`). `releaseTab` was signaling the run only by rejecting
an orphaned promise.
Wire the tab-close event all the way into the cmux run body:
- `PendingRun` gains a `closeAc: AbortController` that `releaseTab`
aborts BEFORE calling `pending.reject`. `wait(...)` (via
`waitForBrowserRun` -> `untilAborted`), in-flight cmux socket calls
(via CmuxTab's `#request` -> `untilAborted`), and facade proxies
(via `bindBrowserRunFacade`) all consume the composed signal, so
the run body unwinds within a microtask instead of blocking to its
own timeout.
- `runInTabWithSnapshot`'s cmux branch composes `closeAc.signal` into
the run's signal (`AbortSignal.any([opts.signal, closeAc.signal])`)
and now publishes `runCmuxCode(...)`'s outcome to the shared
`promise` via `.then(resolve, reject)` and returns `await promise`.
Both branches thus await the same promise, so `pending.reject`
always has an attached handler (removing the original crash) AND
the caller sees `Tab "..." was closed` immediately instead of
waiting on the run's timeout.
- Drop the defensive `promise.catch(() => undefined)` — the promise
is now actively consumed on both backends.
The new regression test adds a second case that exercises the
reviewer's exact scenario (`await wait(60_000);`) and asserts:
1. `pending.closeAc.signal.aborted` flips from `false` to `true`
across `releaseTab`, with the tab-close error as its reason.
2. The awaited `runInTab(...)` rejects with `Tab "..." was closed`.
3. No `unhandledRejection` fires.
Verified locally by temporarily removing `closeAc.abort(...)` in
`releaseTab` — the new assertions fail; restoring it makes them pass.
Fixes#4499
The cmux branch of `runInTabWithSnapshot` awaits `runCmuxCode(...)`
directly and never awaits/`.catch`es the `Promise.withResolvers()`
promise it stashes on `tab.pending`. When `releaseTab` walks pending
runs and calls `pending.reject(new ToolError("Tab ... was closed"))`
(a sibling subagent's `browser close --all`, session-scoped reap, etc.),
that orphaned promise had zero handlers and Bun surfaced the rejection
as `unhandledRejection`, which the CLI's top-level handler treats as
fatal — killing every other tab and subagent sharing the process, not
just the affected run.
Attach a no-op `.catch(() => undefined)` to the promise immediately
after creation. Inert for the worker branch (which still awaits the
same promise via `raceWithTimeout`, and attaching a second handler is
safe) and neutralizes the orphan on the cmux branch.
Adds a regression test that drives real `acquireBrowser` /
`acquireTab` / `runInTab` / `releaseTab` against a mocked
`CmuxSocketClient`, races `releaseTab` against an in-flight cmux run,
and asserts no `unhandledRejection` fires.
Fixes#4499
Skipped the workflow notice on raw selectors so bounded raw reads stay byte-for-byte, and taught resolveToolSearchScope to request pathOnly resolution so ast_grep/ast_edit scope-only calls no longer trip the inline-content cap on large artifacts.
Fixes#4482
Watched-file notifications sent from the LSP writethrough now use the same bounded operation signal as sync/save notifications, so a stalled server cannot hang the write after disk commit.
Extended the freshness regression to assert a bounded signal reaches watched-file notification sends.
Refs #4459
shortenPath() the artifact.path leaked into the read-tool 'Artifact storage' and 'Unbounded raw read blocked' notices so $HOME never appears verbatim; details.resolvedPath keeps the absolute path for tooling.
Fixes#4482
Resolved artifact:// reads to backing files before selector handling, streamed bounded reads, and blocked unbounded raw reads for large artifacts with recovery guidance.
Fixes#4482
Announced harness-authored create, change, and delete operations to active LSP clients with workspace/didChangeWatchedFiles before edit-time diagnostics are read.
Added regression coverage for non-LSP sibling files in a batched write so diagnostics see the workspace state the harness just produced.
Fixes#4459
Collapsed duplicate byte-identical non-empty LSP text edits before overlap validation so rename_file accepts idempotent server output while still rejecting real conflicts.
Fixes#4458
Documented the 1-3600 second bash timeout clamp in the schema, model-facing prompt, and tool docs, including the async timeout behavior.
Added coverage that the shipped schema and rendered prompt expose the contract.
Fixes#4408
Filtered TypeScript project-resolution diagnostics for files with no root marker ancestor while preserving syntax diagnostics. Added regression coverage for Bun scratch files outside project roots.\n\nFixes #4401
- Changed the `path` property from an array of strings to a single semicolon-delimited string across tool definitions and tests.
- Updated validation error messages to reflect the new `path` input format.
- Adjusted all relevant test cases to provide path targets as semicolon-separated strings.
Upstream's grep/glob/ast_grep breaking change (replaced the paths array
input with a single semicolon-delimited path string) missed two test
files: multi-path-missing.test.ts and search-url-paths.test.ts. Both
still called tool.execute() with the removed paths array, which the
new schema silently ignores, so the tools fell back to scanning the
workspace root instead of the intended (and in several cases
external-URL) targets.
Migrate every call site to path, and adjust the one assertion whose
prior guarantee is no longer reachable: when every semicolon-joined
glob pattern is missing, the delimiter splitter cannot tell a literal
path from several missing globs (it requires at least one segment to
resolve before it will split), so the error now names only the first
pattern instead of all of them.
- Added renderer hooks for first-result placeholder replacement and partial-result settle repaints.\n- Enabled the hooks for SSH and covered the streamed-placeholder and settle seams.\n\nFixes #4314
Added providers.webSearchGeminiModel and GEMINI_SEARCH_MODEL so Gemini web_search requests use a selected grounding model while keeping gemini-2.5-flash as the fallback.
Covered OAuth, Developer API, and missing modelVersion fallback paths in Gemini web search tests.
Fixes#4312
- Replaced `grep`, `glob`, and `ast_grep` `paths` inputs with optional single `path` strings while preserving default workspace-root behavior.
- Added shared `toPathList` normalization for legacy arrays and JSON-encoded arrays across tool execution and TUI renderers.
- Updated prompts, fixtures, shims, transcript summaries, and tests to send and display the new `path` argument.
- Updated collab-web search tool cards to read `path` while falling back to legacy `paths` for historical transcripts.
- Recorded the contiguous coding-agent changelog run for the tool-path breaking change and adjacent TTS entries.
- Consolidated duplicated inline thinking level comparisons into a unified `concreteThinkingLevel` helper.
- Enhanced legacy tool shims to respect isolated session settings and support legacy options.
- Cleaned up redundant UI render requests and extra status-line updates.
- Refactored `grep` tool shim to configure context dynamically via isolated settings.
- Disabled platform-incompatible shell shim tests on Windows environments.
- Fixed grep and ast-grep tools rejecting fuzzy url-shaped paths like schemeless www. or collapsed-scheme spellings.
- Applied the extra-CA wrapper to the model registry default fetch to respect the NODE_EXTRA_CA_CERTS environment variable.
- Moved isReadableUrlPath utility to path-utils to share recognition logic between reading and searching pipelines.
- Implemented a fallback that checks if a directory matching a fuzzy URL path exists locally before resolving it as an external URL.
- Added explicit errors for unsupported URL schemes to replace misleading local-path errors.
- Extends output schema validation to support `oneOf` and `anyOf` closed union schemas.
- Prevents unknown section label submissions when all union variants constraint allowed properties.
- Permits arbitrary yield labels when at least one union variant remains open.
- Supports JTD discriminator output schemas by treating union constraints disjunctively.
- Restored CustomInputRow.priority field dropped in 3b80dc01d ask row budgeting.
- Narrowed dereferenced schema properties via isRecord in yield-assembly and output-schema-validator instead of untyped object access.
- Renamed stale advisorReadOnlyTools to advisorTools in advisor parity test.
- Narrowed AgentMessage content access in session-loader-stream test.
- Reformatted browser-schema test to satisfy biome.
- Consolidated `browserOpenSchema`, `browserCloseSchema`, and `browserRunSchema` into a single `browserSchema`.
- Simplified the `action` type definition to accept `'open' | 'close' | 'run'`.
- Updated schema validation tests to reflect the unified schema definition.