- 33d66643d removed the process-local URL response cache (#5803) but left
two fetch-kagi-toggle tests asserting the old reuse contract.
- Deleted the obsolete repeated-read reuse test (refetch behavior is
covered by fetch-raw-mode and search-url-paths regressions) and kept
the offset/limit selector contract without the no-network assertion.
- `DEL N:` previously consumed the colon and body rows then failed with the
wrong guidance; it now falls through to contamination detection which
emits the corrective "has no colon" message, matching `DEL.BLK N`.
- Aligns tokenizer with the leniency removal in 766790cba.
The Kimi branch in streamSimple forwarded raw options to streamKimi,
bypassing normalizeMandatoryReasoningOptions. With supports_thinking_type
'only' now surfaced as thinking.requiresEffort, disabled/omitted requests
(e.g. title generation) serialized thinking:{type:disabled}, which the
mandatory K3 endpoint rejects. Clamp to the lowest supported effort in the
Kimi path, mirroring the mapOptionsForApi contract every other provider
uses, and add a regression test.
Kept top-level custom tool descriptors when a retained xd device uses the same name. Added compact and inline inventory coverage for mounted-only and dual-presentation tools.
Subprocess.kill("SIGTERM") terminates a Windows child immediately
regardless of any handler, so the child in
"is idempotent even when close() had to escalate to SIGKILL" can never
trap SIGTERM to exercise the escalation path — the >=900ms grace-window
assertion would fail spuriously on win32 even though close() behaves
correctly there. Guards it the same way stdio.test.ts's
terminateStdioProcess describe block already skips its POSIX-only
real-signal tests.
- Fixed xd:// mount notices forcing their own model turn by deferring them until the next user prompt instead.
- Added `#pendingXdevMountDelta` field and `#takePendingXdevMountNotice()` to coalesce mount/unmount events and ride along with prompts.
- Mount and unmount events that cancel each other out before the next prompt are now dropped from the coalesced delta.
- Notices remain buffered during quiet startup mode (`startup.quiet`) and are delivered on the subsequent user prompt.
terminateStdioProcess() treated a detached leader's cooperative SIGTERM
exit as proof the whole process group was gone, so close() skipped the
group SIGKILL and left a SIGTERM-trapping/ignoring grandchild running as
an orphan — exactly the process tree this change set out to reap. A
detached transport now always sweeps the group SIGKILL after SIGTERM,
even when the leader itself already exited.
waitForProcessExit() also left its losing Bun.sleep() timer running
after Promise.race settled from the other side, holding the event loop
open for up to the full grace window on every close(). It now uses a
cancellable setTimeout cleared in a finally block.
Adds a regression test spawning a non-trapping leader with a
SIGTERM-trapping grandchild to cover the gap the first fix closes.
- Parsed live named efforts, mandatory-thinking state, and model protocol metadata.
- Sent native Kimi named efforts and adaptive Anthropic override efforts without generic token budgets.
Fixes#5893
selectCollapsedTodos took the active-overflow branch at active.length >= cap, so exactly cap actives plus trailing pending returned the cap rows with an empty summary — the pending work vanished with no '… N more' indicator.
Use a strict '> cap' guard so equality falls through to the normal branch, which counts every hidden row.
Fixes#5873
The first pass anchored a slice on the active task, which still showed completed rows, kept the active item mid-window, and gave the two views divergent selection logic. Per reviewer, replace it with one shared policy both collapsed views run.
selectCollapsedTodos (todo.ts) omits completed/abandoned, pulls every active task (in_progress or subagent-matched pending) to the head in todo order, fills remaining rows with following pending tasks, and emits '… N more active todos' when active work alone exceeds the cap; it falls back to closed tasks for a settled phase so HUD persistence still renders. renderTreeList gains a trailingSummary primitive so item selection lives in the todo domain. The transient tool result reaches live subagent matches via setActiveTodoDescriptionsProvider, wired from interactive mode's observer registry, so both views share the active set.
Fixes#5873
Before: StdioTransport.close() did a bare `this.#process.kill()` — a single
direct SIGTERM to the immediate child, with no wait and no escalation. On
Linux (and other non-Windows/non-macOS POSIX hosts), the MCP server is
spawned detached (setsid, its own session leader) so terminal job-control
signals can't stop it. A detached server that traps/ignores SIGTERM — or a
grandchild it spawns inside that session — survived omp process exit and
was orphaned, re-parented to PID 1.
After: close() runs a bounded, idempotent teardown:
1. End stdin first (cooperative EOF) so a well-behaved server can exit on
its own before any signal is sent.
2. Send SIGTERM: to the whole process group (negative-pid `process.kill`)
when this transport actually spawned detached on a POSIX host, else to
the direct child only. A negative-pid signal is never attempted for a
non-detached transport, since it could hit an unrelated group. ESRCH
from the group signal means the group is already gone (treated as
success); any other group-signal failure falls back to a direct-child
signal.
3. Wait up to ~1s for the direct child to exit; if it hasn't, escalate to
SIGKILL (group-or-direct, same rule as step 2) and wait a further
bounded ~0.5s before returning. Total worst case (~1.5s) stays well
inside the ~3s MCP disconnect-all budget in agent-session.ts dispose().
`#process` is captured into a local and nulled before the first `await`, so
repeat/concurrent close() calls see it already cleared and skip re-signaling
— idempotent per the existing contract documented above close().
Extracted the signal/escalate logic into an exported `terminateStdioProcess`
(plus a `KillableSubprocess` structural type, decoupled from the stdio pipe
generics) so tests can drive group-signal escalation with an explicit
`detached` flag — `StdioTransport.connect()` ties `detached` to the host's
real `process.platform` via `resolveStdioSpawnCommand()`, so a POSIX
detached session can't be reproduced end-to-end through `connect()` on a
non-Linux dev/CI host, but a real detached process group can still be
spawned directly on any POSIX host to exercise it.
Tests added to stdio.test.ts: detached child trapping SIGTERM escalates to
SIGKILL; a detached parent's SIGTERM-trapping grandchild is only reached by
the group SIGKILL (proves group, not direct-child-only, signaling); a
well-behaved child closes promptly without escalating; a non-detached
transport never attempts a group signal. Extended
test/mcp-stdio-transport.test.ts's existing close() idempotency coverage
with a case where the first close() had to run the full escalation path.
Fixes#5578.
Closed active OSC 8 state on wrap_single_line's short-line fast path and wrapped whole table cells in one call so hyperlinks stay balanced across <br>-derived newlines.
Fixes#5885
Closed and restored OSC 8 hyperlinks at native wrap boundaries so composed table cells cannot inherit active link state.
Moved explicit-link spacing outside the clickable URL span and added wrapped table regression coverage.
Fixes#5885
- route direct task and eval agent() launches through one structured-subagent policy, artifact, isolation, and execution primitive
- add invocation-specific outputSchema/schemaMode support to flat and heterogeneous task batches with ordered all-settled fan-out
- allow eval agents in plan mode through a persisted host-enforced capability clamp
- preserve eval handles/runtime helpers, task background lifecycle/progress, isolation recovery, schema precedence, and user tool-approval policy
Fixes#5279
Create the resolved agent database parent before the synchronous compatibility store opens SQLite, and cover a fresh nested agent directory.
Fixes#5879