- Added `listDisabledCredentials` and `refreshSnapshot` methods to credential stores along with API endpoints and wire schemas.
- Added `authorizedAt` timestamps and Anthropic OAuth grant TTL constants to track credential lifecycles.
- Updated the usage CLI to render auto-disabled credential tombstones and grant expiration warnings.
- Added comprehensive unit and broker integration tests covering the new credential management features.
Passed session-scoped settings through Edit and Write generated-file checks and fell back to schema defaults when no global singleton exists.
Guarded inline image sizing against an uninitialized global settings proxy and added isolated-session regression coverage.
Fixes#6549
- Remove uniform language inference requirement, allowing mixed-language paths to rewrite each file in its own language.
- Update `ast_edit_blocking` in `crates/pi-natives/src/ast.rs` to compile rewrite rules per language and skip unsupported languages gracefully.
- Update `ast-edit.md` prompt documentation to reflect mixed-language path support.
- Add test coverage verifying mixed-language tree rewrites.
- Treated transient non-array retain items as absent during TUI streaming.
- Added regression coverage for malformed partial renderer arguments.
- Documented the fix in the coding-agent changelog.
Fixes#6528
- Added language-specific code formatters for JavaScript, Julia, Python, and Ruby to improve display rendering.
- Integrated display formatting into browser run and eval render tools while preserving verbatim execution.
- Added comprehensive test suites verifying formatting stability, lexical safety, and streaming behavior.
- Implemented a structured web-search query parsing module supporting directives, tokenization, date parsing, and syntax serialization.
- Updated search providers to map query directives and date bounds to native provider parameters and filters.
- Added lenient result constraint post-filtering and configuration settings for enhanced engine routing.
- Added comprehensive unit and integration tests covering query parsing, constraint filtering, and provider-specific request mapping.
The rebuild dedup dropped any preserved pendingTools component whose toolCallId
had a persisted toolResult. A background task's initial async.state=="running"
result is persisted while EventController#handleToolExecutionEnd deliberately
keeps its component in pendingTools so a later tool_execution_update/_end can
settle it. Dropping that still-live handle stranded those updates on the running
snapshot. Only terminal results are now owned by the replay; running async
handles stay preserved. Added a regression covering the running-task case.
rebuildChatFromMessages preserves the live pendingTools components across its
clear+replay so streaming keeps routing into them. That preservation assumed
every pending-tool component was still dangling (its result outside
state.messages). Once a tool's result had landed in the session entries while
its component still lingered in pendingTools (a rebuild racing the
tool-completion event, or a background/displaceable snapshot), the replay
reconstructed the completed block from the persisted toolResult AND the
preserved live component was re-appended, so the same tool block rendered twice.
Resolved tool calls are now dropped from the preserved live set and owned by the
replay; only genuinely in-flight (dangling, replay-stripped) calls are preserved.
Fixes#6516
- Added tool schema and description compaction for oversized data payloads in `packages/coding-agent/src/debug/raw-sse-buffer.ts`.
- Implemented head-tail trimming to preserve leading and trailing event fields when events exceed character budgets.
- Added test coverage verifying SSE debug event truncation, elision markers, and JSON-safe tool compaction behavior.
- Removes `model` field from task item/schema, TaskParams, and TaskItem types.
- Removes model selector validation, formatting, and approval display logic.
- Updates task tool priority docs to reflect that model is no longer per-call overridable.
- Updates eval agent() helper docs and prompt templates to remove model parameter.
- Updates tests to reflect removal of model override capability.
Required CLI model registries to expose getAvailable() and used that authenticated
set whenever callers omit availableModels. Deferred SDK and bench/dry-balance
resolution now lets configured roles beat unauthenticated catalog id collisions.
Updated resolver test registries and made the #6508 regression omit the explicit
availableModels option, covering the deferred-caller path from the review.
Fixes#6508
`resolveCliModel` ran findExactCliModel's unauthenticated catalog fallback
before configured-role resolution, so the bundled `cursor/default` model (bare
id `default`) shadowed a configured `modelRoles.default`. On machines without
Cursor credentials `--model default` failed with `No API key found for cursor`
instead of resolving the configured, authenticated default role.
Defer the catalog fallback: explicit provider/id references and authenticated
bare ids still win over roles, a configured role now beats an unauthenticated
catalog-only id, and the catalog id is still recovered via the trailing fuzzy
fallback when no role matches.
Fixes#6508
- Large-paste menu now saves pastes as local://paste-N.md instead of
local://attachment-N, giving the artifact a markdown extension and a
clearer name.
- Kept op required in the todo schema; lenientArgValidation now routes raw args to execute(), where resolveTodoParams re-validates and repairs an omitted op (list -> init, phase+items -> append, bare items on empty list -> init).
- Ambiguous op-less calls surface the schema error as a retryable tool error instead of a hard validation failure.
Redacted assistant anthropicServerTool blocks alongside redactedThinking and providerPayload so /share never uploads raw server_tool_use input or web_search_tool_result encrypted_content.
- Switched from `miniaudio` to `maudio` Rust crate and added `AudioCapture` and `AudioPlayback` native classes.
- Removed browser-side audio infrastructure including Web Audio API, audio worklet processor, and WebRTC runtime.
- Migrated STT recorder and transcriber modules to use native `AudioCapture` with callback-based streaming.
- Replaced streaming audio player with native `AudioPlayback` that writes PCM directly without TypeScript intermediaries.
- Removed ffmpeg, wav, and platform-specific playback commands from the audio toolchain.
- Extracted #formatToolExecution into a standalone formatDefaultToolExecution module.
- Updated xdev renderXdevCall and renderXdevResult to use the default card when no mounted renderer exists.
- Added fallback rendering that shows tool label, args, and output with appropriate theming.
- Added integration test verifying generic card renders for mounted tools without bespoke renderers.
- Catch execution errors in XdevRegistry and render them using the mounted tool's error handling.
- Preserve xdev dispatch context when device execution fails.
- Add `pinSessionOAuthAccount` storage method and active account flag to the auth storage API.
- Introduce session account selector component, controller logic, and interactive mode delegation.
- Implement the `/session pin` builtin slash command with text listing and account pinning capabilities.
- Add unit tests covering session account selection, component navigation, and command handling.
- Added the upstream keyText helper to the legacy package-root shim.
- Covered active keybinding formatting and documented the compatibility fix.
Fixes#6470
#finalizeFile marked the sink finalized then ran the capped-artifact tail
replay before closing. A write error during that replay threw before
sink.end(), and because #finalized was already set the executor finally
paths calling dispose() could not retry the close, leaking the descriptor
and masking the original tool error.
Moved sink.end() into a finally around the tail replay and swallowed both
the replay and close errors so the descriptor is always released and
dispose() never throws.
The first interactive submit fired session.generateTitle() before
startPendingSubmission() painted the optimistic user row, and
tinyTitleClient.generate() spawned the local tiny-title subprocess
synchronously in #ensureWorker() before its first await. With a local
providers.tinyModel configured, subprocess-spawn latency therefore landed
ahead of the first frame, stalling the first prompt.
Paint the pending row before starting titling, and prewarm an idle,
unref'd worker at TUI startup via a no-op ping (no model load) so the
first submit reuses a live subprocess.
Fixes#6462
OutputSink.dump() was the only path that closed the spill Bun.FileSink.
The bash and Python executors re-throw on failure and their finally
blocks never closed the sink, so any large-output command that errored
leaked the artifact descriptor until an unrelated read (e.g. a SKILL.md
load) hit EMFILE.
Added an idempotent OutputSink.dispose() that closes the sink exactly
once (awaiting any in-flight sink creation, guarding post-finalize
resurrection) and wired it into every executor's finally block.
Fixes#6463
- Replaced the separate GUI-linked pi_natives.desktop.linux-x64 addon with
a pure-Rust X11 backend (x11rb RustConnection capture via RandR/GetImage,
XTest input with keysym mapping) compiled into the core addon on every
published target; Linux arm64 and musl are now supported and headless
hosts load the addon unaffected.
- Removed the native-desktop-linux cargo feature, desktop_unsupported.rs,
lazy desktop loader, second napi build, desktop packaging/CI steps, GUI
build dependencies, and the now-unreferenced vendored libspa crate;
reverted setup-system-deps to main.
- Preserved the desktop input hardening semantics on the unified backend:
XTest layouts reject negative origins and coordinates beyond 0..=32767,
batch coordinates stay bound to the frame last returned to JS with
intermediate screenshots deferred, coordinate input requires a
previously returned frame, and failed chord releases still release
every held key.
- Enforced a 60s worker-side execute deadline (DESKTOP_DEADLINE_EXCEEDED):
no input is emitted after expiry and wait-heavy batches are rejected
upfront.
- Added int32 fail-closed validation for coordinates, drag points, and
scroll deltas at the JS ingress and gateway schema.
- Exposed computer to models without native OpenAI computer-use support as
a regular function tool with a typed GA action schema across OpenAI,
Azure, and Codex Responses providers, including named forced choice.
- Added the /computer slash command (on/off/status/toggle) for
session-only enablement via runtime tool registration in SessionTools.
- Updated docs, changelogs, and contract tests accordingly.
- Shimmed writable select.value in export-html harness; linkedom's getter-only HTMLSelectElement.value made template.js theme assignment throw under strict mode.
- Bound the oauth-flow port blocker to 127.0.0.1 explicitly; macOS lets a specific-address bind coexist with a wildcard one, so the flow bound the blocked port and never fell back.
- Re-anchored atomic-rewrite race tests on rewriteEntries() after the compaction-supersede rewrite trigger was removed in cb63ebd.
- Superseded compaction summaries render as elided placeholders in the forward transcript since cb63ebd; only the active compaction keeps its text and frames.