- Added the `ps` shell builtin with BSD and procps selection forms, custom formatting, and sorting capabilities.
- Implemented the `sanitize_process_command` helper to clean process command names and arguments.
- Updated the bash prompt template and package changelogs to document the new builtin.
- Added an optional `timeoutMs` property to the provider discovery configuration schema with validation.
- Passed custom discovery timeout values through model discovery and metadata probing functions.
Fixes#6952
- Refused background keyboard delivery for multi-window macOS applications to prevent ambiguous keystroke routing.
- Set `AXMain` and `AXFocused` attributes during foreground macOS input delivery to ensure proper window activation.
- Activated Chromium renderer accessibility trees lazily during window snapshots to avoid capturing only browser chrome.
- Used `AXDescription` as a fallback title for unnamed macOS accessibility controls in snapshots and queries.
- Update tool usage, exploration, delegation, and execution workflow guidelines in the system prompt.
- Tighten constraints on completion, completeness, evidence output, and yielding behaviors.
- Replaced monolithic desktop native bindings and action batching with a modular cross-platform backend structure supporting Wayland, X11, macOS, and Win32.
- Updated the computer tool schema and supervisor to execute persistent JavaScript script runs with timeout clamping and asynchronous tool calling.
- Integrated accessibility (AX) tree snapshotting, node querying, and bounds-based hit testing across platform desktop layers.
- Added native clipboard bindings and updated coding-agent prompts, renderers, and tests to validate script-based computer workflows.
The postmortem module bound the native hard-exit once at module init
(process.reallyExit.bind(process)). The shipped bundle defers this
module's evaluation until first access, which can land inside a
withHostGuard window where process.reallyExit is the ExtensionExitError-
throwing stub; .bind() then froze that stub permanently, so every later
host-owned exit (SIGHUP 129, SIGINT 130, fatal 1) threw and re-entered
the unhandled-rejection fatal path in a loop (exit 129 storm).
Resolve the native exit on every call instead of binding at init, and
have withHostGuard stamp its throwing replacement with the native
primitive it shadows so a signal arriving mid-guard still exits (#6488)
without the guard poisoning later exits (#7393).
Fixes#7393
- Added an LSP multiplexer server, protocol definitions, and daemon lifecycle management to route traffic across sessions.
- Introduced `lsp.shared` settings configuration and SDK session creation support for shared language servers.
- Migrated shared daemon ensure helpers into a central launch module with updated import references.
- Added comprehensive unit tests and fake LSP server fixtures covering muxing, sharing, caching, and restarts.
- Serialized group and ungroup operations to prevent duplicate tab group creation races.
- Queued and serially drained tab grouping requests in the relay bridge to prevent overlapping RPCs.
- Mirrored tab group titles to session storage and healed duplicate groups during background service worker recovery.
- Renamed run-cancellation utility to run-scope and updated corresponding module and test references.
- Added window discovery, targeting, and frame validation for macOS, Windows, and Linux platforms.
- Updated computer tool and protocol definitions to support listing and targeting specific application windows.
- Refactored native computer tool exposure to function-only representation across models.
- Updated documentation and test suites to reflect window-scoped computer control capabilities.
The isTerminal:false early-return skipped #finishAgentEnd, the only site
that flushes a deferred plan-mode model switch, so an automatic continuation
(async wake) ran on the old model/thinking level until the terminal settle.
Flush the pending switch on the non-terminal branch before returning; the
title/loader teardown stays deferred to the terminal agent_end.
EventController.#handleAgentEnd guarded only on session.isStreaming, so a
non-terminal agent_end (isTerminal:false, emitted while an async job will
re-wake the loop) flipped the terminal title to idle and tore down the
working loader while a /vibe worker or async bash job was still running.
Early-return on event.isTerminal === false, matching the guard every other
agent_end consumer already applies; the later terminal agent_end performs
the normal teardown.
Fixes#7386
The OpenAI service tier could only be chosen through the `tier.openai`
setting, or for a resumed session through whatever tier that session
recorded. Wanting flex or priority for a single run meant editing
settings and putting them back afterwards, while `bench` already took a
`--service-tier` flag that the session CLI did not offer.
Add `--service-tier` to the root command. The flag wins over the
configured setting and over a resumed session's recorded tier, leaves
the Anthropic and Google entries untouched, and records the resulting
map so a later resume keeps it. `none` removes the OpenAI entry, which
omits `service_tier` from the request.
Signed-off-by: Christian Stewart <christian@aperture.us>
Dropped the single-active-run fallback that claimed unrelated stackless rejections in the shared main-process realm, matching the eval inline-mode invariant. Only guest-file stack frames attribute a rejection now; stackless reasons keep the fatal path. Restored the probe to an Error rejection carrying a guest stack.
Fixes#7365
Attributed unmatched rejection reasons when exactly one cmux guest run is active, covering primitive and library-created failures without guessing between concurrent runs. Updated the process probe to reject with a primitive value.
Fixes#7365
Captured browser-run-attributable promise rejections before the global fatal handler and surfaced active failures as tool errors. Retained finished run filenames so late rejections remain isolated without consuming unrelated process failures.
Fixes#7365
- Caught all-target recall failures inside the fire-and-forget auto-recall path.
- Kept first-turn recall eligible for retry after an engine failure.
- Added regression coverage for the background failure contract.
- Warned when a scoped recall target fails while preserving partial results from healthy targets.
- Re-threw the underlying failure when every target fails so recall cannot masquerade as an empty search.
- Added tool-level regression coverage for total and partial scoped failures.
Fixes#7364
On Windows process.env/Bun.env lookups are case-insensitive, so the
"env var name, else literal" resolvers turned a literal /login key like
`public` (OpenCode Zen's free key) into the built-in PUBLIC=C:\Users\Public,
sending `Authorization: Bearer C:\Users\Public` and 401ing every request.
Added `$envExact` in pi-utils, which trusts an env lookup only when an
exact-case key is enumerated (the only case-preserving signal on Windows;
the getter and hasOwnProperty/getOwnPropertyDescriptor traps are all
case-insensitive there). Wired it into all three resolvers:
resolve-config-value.ts, model-registry.ts, and auth-storage.ts.
Fixes#7361
Kept the hard timeout and worker reap for steady-state embed requests while allowing first-use runtime installation and model bootstrap to finish without SIGKILL stranding the install lock.
Added deterministic coverage for initialization outliving the embed timeout budget and corrected the changelog contract.
Fixes#7352
Extended the shutdown busy-timeout clamp from the retain bank to all owned banks so a locked shared bank (per-project-tagged) cannot stall teardown for the default 5s SQLite timeout.
Fixes#7351
Embed-worker init/embed requests awaited the reply with no timeout, so a
wedged fastembed/onnxruntime runtime blocked the turn memory recall or the
shutdown consolidation forever, hanging headless -p/--mode json runs and
leaving __omp_worker_mnemopi_embed unreaped. The #5753 fix only bounded the
dispose-time consolidate await, not the embed IPC beneath it.
Bound every request with an unref-ed timeout; on expiry fail the request
and SIGKILL-reap the worker so the next call respawns a fresh child.
Fixes#7352
Capped synchronous SQLite busy waits before starting bounded final consolidation, then spent only the remaining shutdown deadline on asynchronous drains.
Added regression coverage for a locked Mnemopi writer in the headless teardown path.
Fixes#7351
Combined native HWND and stdio TTY evidence so compiled Windows Terminal launches no longer set CREATE_NO_WINDOW for the Python eval kernel.
Fixes#7343
Address review feedback on #7344:
- grep/glob/ast_grep descriptions now render via a getter instead of a
construction-time field, so a live task.disabledAgents change (e.g. via
/agents) is picked up on the next prompt rebuild instead of leaving
stale 'Task + scout' guidance cached.
- The workflowz notice now also gates the 'Scout inline FIRST' verb on
line 5, matching the already-gated line 14.
Hard-coded 'scout' references reached the model even when the scout
agent was disabled via task.disabledAgents or absent from the session
spawn list. Gate every such reference on scout actually being spawnable:
the task tool description, the delegation gates, the plan-mode and
workflowz notices, the glob/grep/ast-grep guidance, and the task
specialization advisory. Prompt shape is otherwise unchanged; only
erroneous references to the unavailable subagent are dropped.
Closes#7313