- Anchors the incomplete-todo reminder block inside the scrollback transcript instead of a floating live container.
- Eliminates duplicate reminder copies piling up in terminal scrollback during terminal reflows.
- Removes the dedicated `todoReminderContainer` and simplifies state synchronization on todo reload.
- Updates tests to verify sequential reminders commit as separate blocks and are left intact when tools succeed.
Added setup.cfg and pyrightconfig.json to PYTHON_ROOT_MARKERS so pyright, basedpyright, and pylsp project shapes also probe Windows .venv/Scripts before PATH fallback.
Fixes#3916
Added Windows virtualenv Scripts directories to local LSP command resolution so project-local Ruff launchers are discovered before PATH fallback.
Fixes#3916
- Introduced a model canonicalization helper to strip redundant model compatibility fields that match defaults.
- Regenerated the models catalog JSON to eliminate over eight hundred lines of redundant compatibility specifications.
- Updated the variant collapse logic to rebuild models using the projected compatibility configurations.
- Added a missing type annotation to a test environment variable to resolve a compilation warning.
- Added configurations for `anthropic/claude-sonnet-5` under openrouter, vercel-ai-gateway, and zenmux providers.
- Reduced model pricing and cost structure rates for `anthropic/claude-sonnet-5`.
- Removed `trustExplicitThinkingOnly` compatibility flag from several Claude and Gemini model entries.
- Removed legacy `disableStrictTools` property from model definitions and updated tests.
- Fixed model builder variant collapse logic to properly map `compatConfig` to `compat`.
- Sanitized environment variables in git-clone test helpers to avoid host-leakage in test runs.
Extended the mid-prompt /skill:<name> parser exclusions to also defer
to the bash tool (!cmd / !!cmd) and the python tool ($ cmd / $$ cmd
followed by ASCII whitespace), so drafts like '!echo /skill:reviewer'
are no longer consumed as skill invocations before the local-execution
branches of the interactive submit path get to dispatch them.
${HOME}-style shell expansions and prose-leading $ characters (which
pythonCommandPrefixLength already declines) keep matching mid-prompt
skills as before.
Fixes#3913
Restricted mid-prompt /skill:<name> parsing to non-slash drafts so
builtin/custom slash-command arguments such as /compact /skill:foo are
not intercepted before the command dispatcher runs.
Added parser and RPC dispatch regression coverage for the precedence
case while keeping leading /skill:<name> (including leading whitespace)
working.
Fixes#3913
The mid-prompt slash skill autocomplete added in #3654 replaced the
entire editor draft with /skill:<name> on accept so the dispatcher
(which only matched leading /skill:) would still fire. That wiped
every keystroke the user had typed before reaching for the skill.
Insert the /skill:<name> token at the cursor in the TUI editor —
replacing only the partial /sk slash token, leaving prose before and
after intact — and extend the skill-command parser so a /skill:<name>
token surrounded by whitespace is recognized as an invocation too,
with the surrounding prose threaded through to the skill as args.
The parser change is shared across all three dispatch sites
(interactive TUI, ACP, RPC) via a new parseSkillInvocation helper
in extensibility/skills, so the three Map<string,string> /
session.skills lookups stay aligned on the same parse.
Fixes#3913
- Added the `llama3.2:3b` model configuration pointing to the quantized `onnx-community/Llama-3.2-3B-Instruct-ONNX` repository.
- Registered the model in both the available local models registry and list of valid memory model values.
- Documented the new option as a shipped local model choice in the documentation and changelog.
- Replaced the map-based persisted message index with a Set of key identities.
- Removed the message content equality check during branch verification to avoid false out-of-order skips when display-side content variants are present.
- Added an `isAnthropicAdaptiveGenAtLeast` utility to classify adaptive-thinking Claude generations at or above a given version threshold.
- Enabled adaptive thinking display, sampling restrictions, and mid-conversation system message flags for Claude Sonnet 5+ models.
- Updated Bedrock and OpenRouter adaptive reasoning effort maps to support five-tier scales on Sonnet 5+ models.
- Added a hidden system notice prompt to instruct the model to break repetitive behaviors when a thinking or response loop is detected.
- Injected the redirect notice into the retried turn's context when resetting the active context after a loop retry.
- Added unit tests to verify the custom redirect message is appended, configured as non-displaying, and visible in subsequent LLM contexts.
Captured the configured thinking selector when entering plan mode so approving a plan restores auto instead of the provisional concrete effort. Reloaded DEFAULT(auto) badges from defaultThinkingLevel and covered the plan-approval handoff plus /model display.
Fixes#3901
- Added comprehensive integration tests verifying Speech-to-Text submit triggers in STTController under different configuration settings.
- Cleaned up unused imports and types from the stt-controller source file.
- Documented Speech-to-Text submit trigger updates and programmatic editor submission changes in package changelogs.
- Added `stt.submitTrigger` setting to control automatic dictation submission.
- Introduced `evaluateSubmitTrigger` to process sentence punctuation and spoken cues.
- Integrated trigger evaluation into batch and streaming `STTController` pipelines.
- Implemented trailing word trimming to strip trigger words like "submit" before sending.
- Added comprehensive unit tests for all trigger evaluation behaviors.
- Renamed references to the `quick_task` subagent to `sonic` across docs, agent definitions, prompts, and test files.
- Updated the parallel file analysis tool to spawn `sonic` subagents instead of `quick_task`.
- Documented the breaking change in the changelog along with additions and removals of other built-in subagents.
The CPU profiler called node:v8 setFlagsFromString("--allow-natives-syntax")
unconditionally and crashed on Bun (oven-sh/bun#1702), surfacing as
"Failed to start profiler: node:v8 setFlagsFromString is not yet
implemented in Bun". The flag is only needed for ad-hoc V8 natives such
as %GetOptimizationStatus, not for the CDP Profiler session that actually
collects samples — so swallow the error and let the inspector path run.
Added a Bun-runtime regression test that would have caught the crash:
without the guard, startCpuProfile() throws before returning a session.
Fixes#3897
Esc and wizard abort signals now race the MCP OAuth login promise directly, so cancellation wins even before OAuthCallbackFlow reaches its callback wait and registers an abort listener. OAuthCallbackFlow also checks pre-aborted signals before opening/waiting on the callback server and its wait path handles already-aborted signals.
Threaded the abort signal into MCP OAuth fetches so dynamic client registration, metadata discovery, authorization probes, and token exchange unblock promptly when the user cancels.
Added a regression test where MCPOAuthFlow.login never observes ctrl.signal, matching the pre-wait race called out in review.
Fixes#3888
PR review pointed out that the unconditional opt-out blocks the safe case: when no static `client_id` is set, `MCPOAuthFlow.#tryRegisterClient` does DCR with whichever loopback URI we actually bound, so the provider issues a `client_id` tied to the fallback port and the authorize request is accepted. First-install users whose default port 3000 is busy could no longer authenticate.
Gate `allowPortFallback` on `staticClientIdFromConfig(config) === undefined`: pinned client ids (config-supplied or embedded in the authorization URL) keep the strict-port behavior that fixes#3887; unresolved client ids fall back as before. Factored the static client-id resolution into a module-level helper so `MCPOAuthFlow.#resolveClientId` and `resolveCallbackOptions` share the same logic.
Added an oauth-flow.test.ts case that wires a mock registration endpoint + occupies the preferred port and asserts the fallback URI is what DCR registers and what the authorize request advertises. Tightened the existing strict-port test's title to call out the static-clientId trigger.
#handleOAuthFlow now installs an editor.onEscape hook that aborts its
AbortController, and accepts an external abortSignal so the add-wizard
can thread its own controller through (the wizard owns focus and absorbs
Esc itself). Cancellation surfaces as MCPOAuthCancelledError, which the
reauth and add catches translate into a neutral status line instead of
the generic OAuth failure banner. Disambiguated from the existing 5-min
timeout via a userCancelled flag so timeouts still read as errors.
The wizard intercepts Esc/Ctrl+C while #oauthAbort is set so its own
"Press Esc to cancel" advertisement now matches the behaviour, and
renames its error heading + tip when the failure is a user cancel. Also
fixed the misleading "(Press Ctrl+C to cancel)" message in the chat
transcript onAuth block to say "Press Esc" — Ctrl+C is bound to the
editor clear action, not interrupt.
Fixes#3888
When the MCP OAuth callback server's preferred port (default 3000) was unavailable, `OAuthCallbackFlow.#startCallbackServer` silently bound a random port and forwarded the mismatched `redirect_uri` to the authorization server. Providers that validate redirect URIs against a registered callback (e.g. Atlassian) returned an opaque HTTP 500, leaving the local flow waiting for a callback that never arrived until the 5-minute timeout fired.
Added `OAuthCallbackFlowOptions.allowPortFallback` (default `true`, preserving every existing AI-provider flow) and threaded `allowPortFallback: false` through `MCPOAuthFlow`'s `resolveCallbackOptions`. With fallback disabled, login now throws a `ConfigurationError` that names the busy port and the remediation (free the port, or set `oauth.callbackPort`/`oauth.redirectUri` in `mcp.json`) before opening the browser. The existing `oauth.redirectUri`-strict path is reworded along the same lines so callers see one consistent message family.
Fixes#3887
- Added a last-resort recovery step to run `shake("elide")` on oversized message tails when auto-compaction cannot otherwise free enough context.
- Re-tests the context headroom and auto-continue predicates after a successful rescue before falling back to pausing maintenance.
- Updated the dead-end warning message to suggest running `/shake images` for irreducible, image-only tails.
ToolArgsRevealController.setTarget initialized new entries with revealed=0, so the first message_update returned { __partialJson: "" } even when the provider had already parsed a complete chunk. For renderers without exposeRawPartialJson (e.g. write), the throttled re-parse + cached displayArgs short-circuited every subsequent setTarget, leaving the preview body blank until tool_execution_end.
Seed revealed with the full incoming partialJson length on entry creation (clamped to a surrogate-safe boundary). The first frame now carries the parsed path/content immediately; subsequent message_updates extend target and the reveal ticks pace only the newly arrived bytes — no field is ever truncated because the seeded prefix is the longest the entry has seen so far.
Fixes#3881
fix(compaction): cap snapcompact frame payloads (#3866)
Bound rebuilt snapcompact image payloads by a per-request base64 byte
budget so long sessions stop re-sending multi-megabyte standing image
archives on every provider request; auto-compaction falls back to
context-full summaries when snapcompact output is too large.
Resolved snapcompact.ts conflict against the main font-rendering refactor
by keeping both renderabilityProbeText and the frame-budget helpers.
Fixed historyBlocks to emit the omitted-frame notice before the kept
(newer) images, since the byte budget drops the oldest frames — keeping
reconstructed blocks oldest-to-newest (addresses Codex P2 review).
Fixes#3792
- Added eight new Go-specific rules to the discovery package.
- Registered the new Go rules in the default rule source index.
- Covered the new Go AST matching conditions with test cases in `builtin-defaults.test.ts`.
Forwarded persisted provider stream timeout settings into model requests so slow local LLM streams can widen or disable first-event and idle watchdogs without environment variables.
Fixes#3878
Normalized string-encoded JSON arrays in grep/search path handling so direct execute paths match validated tool-call behavior.
Added regression coverage for direct GrepTool.execute paths supplied as a JSON-array-shaped string.
Fixes#3873
The yield tool's per-call schema validator was skipped entirely for incremental
yields (`type: ["<label>"]`), so when a subagent emitted a non-conforming value
for a known section (e.g. DeepSeek-v4-pro returning "Correct"/"correct."/"approved"
for the reviewer's `overall_correctness` enum), the call succeeded locally and
the model got no retry feedback. The mismatch only surfaced post-mortem in
`finalizeSubprocessOutput` as a fatal `schema_violation` — the parent agent
lost the entire result, with no recourse for the subagent to fix it.
Build a per-label sub-validator map alongside the full-schema validator: each
entry validates one section's `data` against its top-level property's sub-schema
(items schema for array-typed labels like `findings`). The yield tool runs this
map for incremental yields and routes failures through the same MAX_SCHEMA_RETRIES
budget the terminal path uses, so the model sees up to three corrective retries
and the existing schema-override safety net accepts the value with
SUBAGENT_WARNING_SCHEMA_OVERRIDDEN after exhaustion. Unknown labels remain
unconstrained so scratchpad/streaming sections still pass.
Fixes#3870