An idle ACP session sets `deferAgentInitiatedTurns`, so a steered terminal
blocker routed through `sendCustomMessage({ triggerTurn: true })` was buried
in `#pendingNextTurnMessages` instead of starting a turn — invisible and
deferred to the next user prompt, the exact regression #5628 avoids.
`#routeAdvice` now preserves the blocker as a visible card when a turn cannot
auto-trigger (idle + ACP defer without an explicit allow), folding the
existing plan-mode preserve branch into the same guard.
Fixes#5628
- Updated schema and runtime paths to use `dev.autoqaConsent` and `todo.remindersMax`, including auto-QA consent reads/persistence and todo reminder limit checks.
- Adjusted settings expectations so obsolete BM25-discovery keys were dropped on load and `tools.xdev` now kept its default unless explicitly set.
- Added/updated tests for the setting key migration and refreshed issue-consent flows, plus a new `refreshMCPTools` test for steered `xdev-mount-notice` updates without prompt rebuilds.
Instead of including the xd:// device inventory in the system-prompt signature, mount/unmount events now inject a steered `xdev-mount-notice` message so the system prompt (and its provider cache prefix) stays byte-stable across MCP connects and disconnects. Full device docs are picked up opportunistically on the next unrelated rebuild.
Also caps external (dynamic-mount) device descriptions to 200 chars in `docsAll` to prevent server-controlled prose from consuming prompt budget; built-ins keep their full curated docs, and `read xd://` always returns the untruncated text.
Legacy `discoveryMode: "off"` → `tools.xdev: false` migration is removed; the setting keeps its own default without inference from the deprecated key.
- Added the `xd://` virtual device protocol (`internal-urls/xd-protocol.ts`, `tools/xdev.ts`): tools declaring `loadMode: "discoverable"` are unmounted from the request tools array and driven via `read xd://` (list/docs+schema) and `write xd://<tool>` (execute), gated by the `tools.xdev` setting (default on) and inlined into the system prompt.
- Merged the `irc`, `job`, and `launch` tools into a single `hub` tool (`tools/hub/`, `async/job-manager.ts`): messaging keeps `send`/`inbox`/`list`, job control maps to `wait`/`cancel`/`jobs`, process supervision keeps `start`/`logs`/`stop`/`restart`/`describe` with `ps`, and the unified `wait` races background jobs against peer messages; SDK `IrcTool`/`JobTool`/`LaunchTool` are replaced by `HubTool`.
- Removed the hidden `resolve` tool in favor of the `xd://resolve`/`xd://reject`/`xd://propose` resolution devices, auto-including `write` whenever a deferrable tool or plan mode is present.
- Removed the BM25 tool-discovery system: the `search_tool_bm25` tool, the `tool-discovery` module, the `tools.discoveryMode`/`mcp.discoveryMode`/`mcp.discoveryDefaultServers`/`tools.essentialOverride` settings, per-tool MCP selection, and the `mcp_tool_selection` message type.
- Unified tool presentation on `ToolLoadMode` (`essential`|`discoverable`), replacing the custom-tool `xdev?: boolean` opt-out; custom, extension, MCP, RPC host, image-generation, and TTS tools now default to `discoverable`, and added a `satisfies` predicate to `SoftToolRequirement`.
- Removed the standalone `ssh` command tool and `ssh/ssh-executor` (the `ssh://` read/write/search protocol stays), and made `--tools` address hidden built-ins.
- Updated collab-web to render `xd://` dispatches and `hub` op families, dropped the `search_tool_bm25`/`ssh`/`report-finding` renderers, refreshed tool docs and prompts, and migrated the affected tests and changelogs.
- Renamed the system prompt's project-context section wrapper from `<context>` to `<repo-rules>` in `project-prompt.md`, so it no longer collides with the `task` tool's `context` parameter under in-band XML tool dialects.
- Updated `snapcompact-inline`'s context-section strip pattern to match `<repo-rules>`.
- Updated the `snapcompact-inline` test fixture to the new wrapper.
- Changelog entry for this rename rides with the fused device-migration commit (adjacent changelog lines).
Each tool-result turn now re-arms one text-only continuation while prewalk is pending. Consecutive prose replies without intervening tool progress terminate naturally, preserving multi-step plan detours without restoring the completion loop.
Fixes#5551
A prose plan and a bash-only completion are structurally identical after any pre-implementation tool detour, so the net now stays armed across every such turn and fires exactly once on the first text-only reply. This bridges read/record/bash detours before the plan while bounding a genuine no-edit completion to a single continuation instead of looping.
Fixes#5551
The continuation net now stays armed across a todo-only turn and disarms only when a non-planning tool runs without a prose plan, so the normal plan-nudge to todo to prose to edit flow still reaches implementation while a bash-only completion no longer loops.
Fixes#5551
Limited the hidden continuation safety net to the assistant turn immediately following the plan nudge, so later bash-only completion ends normally.
Added regression coverage for commit-style flows that never call edit or write.
Fixes#5551
- Updated prewalk gating in `AgentSession` to key the todo gate on active tools instead of registry presence, so deactivated todo tools no longer block prewalk handoff.
- Changed subprocess tool filtering so `todo` is stripped for normal subagents but retained when prewalk is armed, and propagated the prewalk state through tool-session setup.
- Added regression tests for restricted active-tool slates and prewalk/non-prewalk subagent tool propagation to verify todo is handled correctly in each case.
wantsSnapcompact is true for both the default strategy and an explicit
/compact snapcompact mode override. The prior fix downgraded both to LLM
compaction, which silently shipped the transcript to a provider for users
who deliberately requested the local-only no-LLM archive path. Only the
default-configured strategy now falls back; explicit snapcompact keeps
failing locally. Added a regression test for the explicit path.
Fixes#5064
Switching from a vision model to a text-only model kept replaying
historical image content blocks to the new provider, which rejected them
with invalid_argument. The convertToLlm wrapper in sdk.ts only filtered
images when images.blockImages was set, never by model capability, so
the outbound request carried image blocks the active model could not
accept.
Add replaceLlmImagesWithText() to scrub image blocks out of the
already-converted LLM message view, and call it from the sdk wrapper
when the active model's input lacks "image". History on disk keeps its
images; only the provider request is scrubbed, and the check reads the
active model dynamically so a /model switch takes effect next turn.
Fixes#5400
A stalled or dropped provider stream that surfaces as stopReason:"error"
carrying the bare "Request was aborted" sentinel fell through both retry
gates: #isRetryableReasonlessAbort required stopReason:"aborted", and
#isRetryableError's classifier returns no retriable kinds for the generic
sentinel. The turn died immediately despite retry.enabled.
- Relaxed #isRetryableReasonlessAbort to accept an empty generic-abort
sentinel turn under stopReason "aborted" or "error", tagging it Abort so
#handleRetryableError retries it without model fallback.
- Kept the deliberate-abort guards intact: user interrupts and silent aborts
carry their own markers (not the generic sentinel), and #abortInProgress /
#isDisposed / #streamingEditAbortTriggered still settle without retry.
- Rewrote the stale fallback test that froze the buggy no-retry behavior to
assert retry-and-recover for the error-stop sentinel.
Fixes#5375
navigateTree() treated every custom_message entry as a re-editable user
turn, setting the leaf to the injection's parent and dumping the expanded
skill body into the editor. A /skill:<name> invocation is persisted as a
skill-prompt custom_message, so selecting it in /tree dropped the skill off
the active branch. Skip the parent-leaf/editor-prefill path for
skill-prompt entries so the leaf lands on the injection node itself.
Fixes#5374
- Added a Codex rate-limit parser for `x-codex-*` headers and registered it with the Codex usage provider.
- Updated auth-storage to require parsed usage headers before ingesting usage data, treated exhaustion as non-throttled, and renamed ranked candidate drain fields.
- Reworked key ranking math to use `headroom / remainingHours` with a 1-minute minimum, then applied measured-usage precedence with hot-window demotion behavior.
- Updated session handling and tests to support provider-aware header ingestion with deterministic, exhaustion-aware account selection.
Manual /compact with the snapcompact strategy hard-threw when the active
model lacked image input, unlike the auto-compaction path which downgrades
to LLM-backed compaction. Clear snapcompactReady instead of throwing so the
flow falls through to #compactWithFallbackModel (active text-only model
tried first for text->text summarization).
Fixes#5064
- Added `tui.scrollbackRebuild` configuration with interactive startup/controller wiring to apply `setScrollbackRebuild`.
- Exposed prewalk session state in `SegmentContext` and rendered a dedicated prewalk segment/icon in the status line.
- Added divergence-aware TUI full-paint logic that enables scrollback erase-and-replay rebuilds for non-multiplexer divergence cases.
- Updated rendering and streaming tests to verify rebuild behavior (`3J`) and eliminate stale marker expectations under drift scenarios.
- Replaced legacy `pi/` role alias prefix with canonical `@` syntax across model resolution, documentation, and tests.
- Added support for bare `*` default alias and multiple alias prefix detection with custom role resolution in `resolveConfiguredRolePattern()`.
- Enhanced thinking suffix parsing to accept unambiguous abbreviations (minimum 2 characters) for effort and level selectors.
- Extended `resolveCliModel()` and `filterAvailableModelsByEnabledPatterns()` to accept settings parameter for role alias resolution from `--model` flag.
- Removed the Google Interactions transport and deleted interaction-specific request options from the shared AI stream typing/API surface.
- Simplified Google provider routing to eliminate interactions auto-selection logic and keep `streamGoogle` on the `:streamGenerateContent` path.
- Updated Vertex request handling to use resolved stream hosts without `/interactions`/`Api-Revision` and removed related interaction constants.
- Deleted obsolete Interactions tests and updated remaining Google stream tests to no longer reference `useInteractionsApi`/`storeInteraction`/`previousInteractionId`.
- Removed the `downshift.boomerang` feature, including CLI flags, configuration schema settings, and internal session state logic.
- Deleted the associated prompt definition file and all unit tests related to the boomerang validation flow.
- Cleaned up frontend forms and server request handling in the harbor-manager package to reflect the feature removal.
- Updated the downshift planning prompt instructions to maintain continuity in task creation.
- Modify downshift logic to ignore `todo` tool calls as triggers, requiring them instead to open a "gate" that permits switching only on subsequent `edit`/`write` actions.
- Ensure the starting model consistently handles implementation until the todo list is established, preventing premature hand-off to the fast/cheap model.
- Update system prompts to emphasize strict validation and multi-test execution requirements for the boomerang model upon returning to the primary context.
- Introduced `--downshift-boomerang` CLI flag and `downshift.boomerang` configuration setting.
- Integrated boomerang validation hand-back logic and context cutting within the agent session.
- Added system prompt templates and runtime checks to facilitate message handling for boomerang transitions.
- Included unit tests to verify context management and validation pass requirements during the boomerang process.
- Included the todo tool in downshift action triggers, gated on the plan nudge being in context — a post-nudge todo init is the planning-complete signal, while a turn-one todo remains bookkeeping.
- Updated flag help, settings schema, SDK docs, slash-command text, and plan-nudge instructions.
- Added a regression test covering the nudge-gated todo trigger.
- Replaced legacy reasoning-slide functionality with new downshift and plan-yolo capabilities.
- Updated CLI arguments, slash commands, and configuration schemas to support the new model-switching and execution behaviors.
- Refactored agent session logic to handle downshift arming, plan-yolo headless execution, and context scrubbing.
- Renamed and added system prompts to align with the updated downshift and plan-yolo workflows.
- Clear inherited todo list state and persist empty edit at fork creation to prevent parent task reminders from affecting the tangential session.
- Re-inject the fork notice after each auto-compaction event to ensure the boundary between the parent and child session survives history summarization.
- Align the provider cache key with the parent's actual pinned key to correctly mirror cached session context.
- Update `AgentSession` to perform a full entry rewrite during tool result pruning to ensure session files match pruned state for reliable resuming and branching.
- Added test coverage for auto-compaction entry warning attribution during dead-end scenarios.
- Verified automatic continuation and warning suppression when image-drop recovery successfully clears context pressure.
- Mocked session context usage and image-drop functionality to simulate high-usage state recovery.
- Added `StrippedToolCallsMarker` to identify assistant messages with dangling tool calls that were removed during context building.
- Updated `buildSessionContext` to preserve turn entries in transcripts even when all content is stripped, marking them with the count of elided calls.
- Updated `UiHelpers` to render a dim, italicized placeholder in the TUI when an assistant message has elided tool calls, preventing silent activity gaps.
- Added `warning` field to `CompactionEntry` and `CompactionSummaryMessage` to persist dead-end status in session history.
- Introduced a multi-tier rescue mechanism in `AgentSession` that automatically performs `elide` and `dropImages` passes when maintenance fails to recover sufficient headroom.
- Integrated visual indicators for dead-ends into the `CompactionSummaryMessageComponent`, surfacing warnings directly on the compaction divider and detail block.
- Updated `AgentSession` logic to re-evaluate progress after each rescue tier and emit recovery notices, ensuring transparent reporting of automated history rewrites.
- Update in-flight context snapshots after historical messages are modified by compaction or elision.
- Prevent stale run-start token counts from triggering false-positive dead-end "no progress" warnings during auto-continuation.
- Add regression test to verify that prompt headroom measurements correctly account for post-compaction context sizes.