发布说明

Codewhale 0.10.3

发布于 2026年11月6日。以下是该版本的全部条目,取自仓库中的 CHANGELOG.md,条目原文为英文。

Work in progress and known limits8

  • Codex App Server compatibility: Codewhale is working toward full Codex wire parity on the existing Engine. The current HTTP/SSE Runtime remains available; full-tool turns, subscriptions, bidirectional interactions, durable settlements, TCP WebSocket and the complete SDK remain unfinished.
  • DSH plugins and MCP lifecycle: compatibility with unmodified DeepSeek Harness plugins remains in progress. Automatic restoration of a missing runtime snapshot is unfinished and may only use canonical source bytes that still match its receipt. Existing mismatched or tampered snapshots refuse and require review. Authenticated DSH UI asset transport and revocation, and an end-to-end published-plugin journey remain unfinished. Downgrading a newly saved plugin marketplace catalog remains unqualified.
  • ChatGPT sign-in on Windows: the reported 0.10.2 post-browser identity verification failure has not been confirmed resolved in the reporter's environment. More specific errors and clock-skew handling are not a successful Windows sign-in receipt. (#7203)
  • Conversation recovery on Deepin: scoped interrupted-reply recovery and persistence checks do not establish a fix for the original whole-history disappearance on Deepin 25.2.2. (#7095)
  • Windows ACP and undo: the original Paseo approval/sandbox journey and ordinary multi-turn /undo through Windows ConPTY remain unqualified on the final candidate. macOS and simulated checks do not establish those Windows results. (#6992, #6970)
  • Install and update routes: final-candidate Windows and Linux package, install, update, rollback and uninstall coverage is incomplete. Earlier scoped platform receipts do not qualify the final package matrix or ordinary Windows user journeys. (#7091)
  • Workspace downgrade and rollback: compatibility with older binaries after a 0.10.3 workspace migration remains unqualified. The CLI self-updater guard refuses recorded targets below 0.10.3 in codewhale update --rollback when running 0.10.3 or newer, before replacing the executable. Five isolated macOS development-candidate refusal/control cases passed with fixture trees unchanged. This does not provide backward-compatible rollback or qualify actual workspace migration or an allowed rollback. Manual or package-manager downgrades and older builds reporting the same version remain outside the guard.
  • Long-running ZAI sessions: scoped watchdog and recovery checks do not establish a fix for the original hours-long, tool-heavy silent stall. (#6184)

Added51

  • Refresh model catalogs during use: Runtime provider refresh now checks public Models.dev metadata alongside the exact provider's model list; force_catalog=true bypasses the public cache TTL and retry backoff. GET /v1/providers exposes catalog revision and freshness so clients can pick up new models without repeatedly loading an unchanged catalog. The runtime rechecks in the background, retains the last good snapshot on failure, and preserves explicit model selections and account/route scope.
  • Tinker beta route: configure Thinking Machines Tinker's OpenAI-compatible endpoint and a serverless model or sampler checkpoint ID. Model-list discovery, key verification through that list, and cost estimates remain unavailable; live conversations, tools and image input have not been qualified in Codewhale. See provider setup.
  • Worktrees for parallel workspaces: GET /v1/worktrees lists a repository's worktrees, POST /v1/worktrees creates a branch and its own checkout under <repository>/.codewhale/worktrees/ through the existing lane provisioning, and POST /v1/worktrees/remove archives a clean managed one without --force, keeping the branch. A client starts a thread in the new folder, so several agents can work on one project without sharing files. (codewhale-hq/codewhale-app#3500)
  • Thread-scoped snapshots: GET /v1/snapshots and POST /v1/snapshots/{id}/restore accept ?thread_id= and act on that thread's workspace under the same restore admission rule. (codewhale-hq/codewhale-app#3500)
  • DSH plugins can carry their own client UI: a reviewed DSH plugin closure may now ship its own Node/Bun dependency tree, CommonJS/CTS entries and UI-only source bundles. The Engine exposes a trusted and enabled plugin's client entry and assets through two loopback-only, read-only routes with bounded sizes, confined paths and safe MIME/no-store responses; no other plugin route gains an unauthenticated path. (#2, #3)
  • Present final files: the read-only present tool takes 1–32 existing workspace files, streams their SHA-256 and byte counts, and returns an auditable handoff receipt without copying, moving or uploading them. It is eager in Act/Operate and Plan; the present-handoff feature is experimental, and there is no dedicated app card yet.
  • Truthful background jobs: shell job snapshots and completion events now carry the exact start time, a typed termination cause (producer, killed, timed_out, unknown) and whether the producer reported it. A killed job is no longer indistinguishable from a failed one, and the bash guidance tells the model to collect or cancel live jobs before a final answer.
  • /export writes HTML and JSON: /export file report.html saves a self-contained page (light and dark, no scripts, a strict content-security policy, tool calls collapsed) and report.json a versioned, typed-block envelope. --format md|html|json overrides the extension, and --no-tools drops tool calls and results from the conversation. /export file with no path now writes an auto-named codewhale-<title>-<timestamp> file under <codewhale home>/exports and reports the format, line count and redactions; ~ expands and quotes keep a path with spaces together. --force, --no-tools and --format are accepted in any position. HTML and JSON are file-only; the clipboard and /export turn remain Markdown.
  • Tencent HY4: the stable tencent/hy4 model is available through OpenRouter with its published multimodal, tool, reasoning and context metadata. /provider tencent adds the direct TokenHub route with hy4 and TENCENT_API_KEY; direct availability and prices remain separate from OpenRouter, and preview/HY3 selections are preserved.
  • WeCom steers a running turn (#7211): a WeCom message sent while a turn is running is forwarded to the Runtime's steer endpoint instead of being dropped with the busy notice, which remains the fallback when the steer is rejected. Thanks @gaord.
  • WeCom accepts media and voice (#7212): the WeCom bridge downloads image, video and file messages into WECOM_MEDIA_DIR (default <workspace>/media) under a sanitized name and replies with the saved name, size and path; a failed download tells the sender the link expires after about five minutes. Voice messages use WeCom's transcription as the prompt, and other message types get an explicit answer instead of a blanket refusal. Thanks @gaord.
  • Pinned local thread controls (preview): initialized App Server clients can list retained loaded Engines with cursor paging and rename the canonical thread through thread/loaded/list and thread/name/set. Saved but unloaded threads stay out of the loaded list; existing aliases remain available. Full-tool turns and subscription parity remain unfinished.
  • Local whale voice (preview): the host can edit its private, revision-checked SOUL.md through the Runtime API. The Engine captures it for the next turn within the existing instruction budget and records its source; invalid private files refuse the turn with a terminal failure.
  • MCP tool approval rules (preview): exact tool names in the global server configuration can use Always, Ask or Off across workspaces. Off wins, server edits invalidate the prior grant, and required Computer Use consent and nested-program approval remain in place.
  • Attested watch-turn ingress (preview): a configured Runtime master bearer can admit typed schedule or pull-request receipts through the existing thread and turn owner, with exact operation replay and read-only recovery lookup. This supplies the Native ingress prerequisite; it does not qualify the complete continuous-operation workflow.
  • Goal continuations send the objective once per live conversation window. Later passes show the current goal state, estimated conversation input and the applicable compaction setting. Full notes stay available through get_goal. Thanks @7jrxt42BxFZo4iAnN4CX for measuring the repeated text and identifying the misleading token figure (#7172).
  • Composition on the first request: execute_tools accepts a bounded named batch from the current MCP catalog, with argument names from its allowed members and the same nested gate as a JavaScript program. Exact tool-name searches work with regex anchors. Stream receipts hash the executable in the background; CODEWHALE_TIMING=1 reports phase durations. (CW-7649)
  • The model can read what compaction replaced (#7173): two read-only tools, context_archive_search and context_archive_get, search the session's saved pre-compaction snapshots and read one archived message by id, with bounded results (12,000 characters per read, 20 hits and a 200-character query per search). Each message is masked whole for credential shapes and currently configured secrets before it is searched or paged, and codewhale sessions scrub-secrets now also rewrites those snapshots. A /fork cannot read the archive its handoff note refers to, and a bare secret absent from current configuration is not masked. Thanks @SparkofSpike.
  • Opper as a bundled provider (#7131): /provider offers Opper, an EU-hosted OpenAI-compatible gateway, with OPPER_API_KEY, https://api.opper.ai/v3/compat and the claude-sonnet-4-6 pool name as the bootstrap model; provider/model ids pin one route. Live /v3/compat/models is the model authority and billing stays Unknown. No live Opper call was made here. Thanks @Felixkw12.
  • Runcrate is a bundled provider: runcrate reaches the OpenAI-compatible host at https://api.runcrate.ai/v1 with RUNCRATE_API_KEY, and codewhale models --update --provider runcrate refreshes its public model IDs before a key is configured. Inference requires the route key. Thanks @heydryft for the request and the vendor details. (#7085)
  • MCP connection status reaches the model: one existing history snapshot now records permitted configured, connecting, failed, authorization-required, unknown and connected servers, with bounded inert names and no raw errors. Stale status and server guidance are withdrawn on contention, configuration/scope changes and restore; observation does not connect servers or promise callable tools. (#6866)
  • Bundled-skill policy: [skills.bundled] separates automatic, authoritative and disabled installation from discovery, with per-name selection, disable and explicit-only controls. Aliases share policy; disabled shipped copies reveal user alternatives. Modified and managed files remain intact, and doctor plus /skills inspect show the effective policy. (#7066)
  • Configurable skill routing index: [skills] listing_max_description_chars and listing_budget_fraction control the shared parent/child catalogue. Defaults use 120 characters and 0.2% of the route window, within the existing total bounds. Load warnings, localized inspect notes and /context explain shortening; full skill loading stays available. (#7073)
  • Compact approvals keep their authority visible: cards show three choices and default to Deny. An exact saved rule requires its scope preview on screen. Shortcuts for additional actions require opening Details; a hidden saved-rule choice never falls back to granting the session.
  • Quicker everyday navigation: top-level help separates everyday and advanced commands, doctor --all expands path/backend details, and the launch screen labels how to resume recent work. Up selects the newest recent session. Whale cameos stay out of transcript text.
  • Session-window diagnostics: the audit log records when a saved window starts a new journal root while retaining the previous branch, helping distinguish window replacement from lost durable history. session.window.rerooted now names a cause (engine_projection, session_restore or unattributed) and also fires when a journal with entries has no active path. (#7142)
  • Usage reporting counts models, tokens and tools: when usage reporting is on, each session now also reports, per provider and model, its turns by outcome, input, output and prompt-cache tokens, and turn-time buckets, plus how many times each built-in tool ran and failed. A model is named only when it is in Codewhale's bundled public model catalog; custom, local and fine-tuned names are sent as other, and MCP and plugin tools as mcp or other. No prompts, outputs, tool arguments or paths are sent. Runs under CI or the GitHub Action report the ci session source. The first-run notice is shown once more to describe this. DO_NOT_TRACK=1 now turns usage reporting off for that run, like CODEWHALE_TELEMETRY=0; codewhale config set telemetry false still turns it off for good. See docs/TELEMETRY.md.
  • exec and doctor follow the TUI onto local Ollama: with no cloud key and no explicit route, codewhale exec uses a running local Ollama chat model and says so, and codewhale doctor --probe-local checks that route. Nothing is saved. (#7115)
  • Thinking starts at auto: new configurations and the built-in default use reasoning_effort = "auto" instead of max; an effort you set is never changed.
  • DSH Git review scopes: the extension host brokers bounded, read-only Git metadata to reviewed DSH plugins through a new git_review_scope action (extension-host policy v8).
  • Safer, more complete uninstall: for a receipted release copy, codewhale uninstall --yes now also removes this install's exact three-line # >>> codewhale PATH >>> block from your shell profiles and the Codewhale-generated completion files at their documented paths (bash, zsh and fish, honouring XDG_DATA_HOME and XDG_CONFIG_HOME). It touches nothing else in a profile, leaves a symlinked or unreadable profile for you to edit, keeps the completion files while another Codewhale copy remains on PATH, and exits non-zero if that cleanup fails after the program is already gone. The codewhale.net/install.sh hint and the install guide now print the PATH line as that marked block, so there is something provably yours to remove; a bare export PATH=… line you added earlier is never touched. Data purge requires a receipted removal in the same confirmed run. Both Unix installers reject unsafe or managed destinations before creating them and still never edit shell profiles themselves. Uninstall instructions match the explicit-home purge scope in English and Chinese. Not yet observed on a real Windows host or an installed release artifact. (Refs #7091)
  • Nested and deletable threads (Runtime API): a fork (including a backtrack fork) records parent_thread_id, POST /v1/threads accepts one naming an existing thread, and GET /v1/threads/summary returns it so clients can nest child conversations. DELETE /v1/threads/{id} removes an idle thread with its turns, items, events and goal, and its saved session unless another thread shares it or a terminal holds it open; a running thread answers 409.
  • Hunk actions in Review (Runtime API): POST /v1/git/stage, /v1/git/unstage and /v1/git/discard take a patch holding hunks of the one path in paths and apply only those hunks through git apply, under the same expect preconditions as whole-path writes. A patch that no longer applies fails with git's message and writes nothing; renames, mode changes and binary patches are refused. The tasks tool can also suggest a task, shown as a Start/Hide card, without starting anything.
  • Live /models ceilings reach the route: a provider that states per-model context and output limits in its own /models body now keeps them instead of falling back to the legacy 128K window. OpenAI limit blocks, flat context_length / context_window / max_model_len / max_context_length fields, max_output_tokens / max_completion_tokens, and a relay metadata block (context_limit, context_budget, output_budget) are read; metadata.context_limit outranks context_budget because the first is the model capability and the second the share one deployment accepts. Each field is parsed on its own, so an unreadable one costs only its own candidate instead of hiding the readable fields below it.
  • Change mode and permissions while the agent works: Tab, Shift+Tab, /mode, the hotbar and /config mode no longer refuse while a turn is running. A response that is already streaming is not restarted; the change applies at the agent's next step in the same turn (before its next tool batch, at every approval gate, and before its next model request, which carries the new mode notice). The status line says so until it applies. A call still waiting for approval goes back to the model under the new posture, and a call you already approved runs only if the new posture is equal or broader. Model, thinking level and provider stay locked until the turn ends.
  • Steering interrupts thinking: a steer (Ctrl+Enter, or Enter twice after queueing) now closes the in-flight model request at once, whether the model is waiting on headers, reasoning, writing text or emitting a tool call, and continues the same turn with your message. Text already shown is kept as interrupted output; unfinished reasoning and partial tool calls are discarded, never run.
  • Modern MCP client: MCP servers now connect through the official MCP SDK (2.4) behind Codewhale's Rust broker by default (mcp_backend = "host"; "rust" stays available for one release). Servers that speak the 2026-07-28 revision are discovered with server/discover; other stdio and HTTP servers fall back to the legacy initialize handshake, and configured SSE servers keep theirs. Rust keeps process, network, credential, catalog, approval and cancellation authority.
  • DeepSeek Harness plugins: reviewed DSH plugins (definition API pinned to DSH 0.2.1-rc.5 in a shared compatibility table) run in the Native extension host. Tool output is validated against its declared schema, unsupported options are refused instead of ignored, and plugin commands can submit a prompt with visible plugin attribution. Terminal command receipts are kept in thread snapshots without entering model history. Changing the compatibility table invalidates earlier trust. A newly enabled plugin's tools are offered on the first turn: the turn waits up to 10 seconds for the plugin host to finish loading instead of adding them only from the next turn. The importer reports that it does not convert dsh.client UI; Engine routes and a desktop slot exist, but isolated end-to-end plugin UI remains unqualified, including network containment. A plugin tool can call ctx.sessions.flush(exec.agent.session) to have the Engine save the conversation so far before it continues (Runtime, terminal and exec sessions); it reports failure instead of claiming a save. Installing a plugin whose bytes changed after review now returns a 409 conflict instead of a server error. A plugin tool can ask you a question with ctx.userQuestions.ask and gets back the options you picked, your own text, or a skip; the question shows like any other Codewhale question in the terminal and through the Runtime API. A plugin tool can start a child agent with ctx.subagents.startActivation (the spawn provider): the child runs through Codewhale's own sub-agent manager, needs the same approval as the model's agent tool, can carry an extra persona section and a narrower tool list set in its agent/created handler, and returns its result to the plugin.
  • MCP catalogs stay fresh: a server's tools, resources, prompts and skills are rediscovered on their own connection when an advertised ttlMs expires or the server sends a list-changed notice. A tool resolved against the old catalog is refused with "retry the call", a removed tool cannot run, and a failed refresh reconnects instead of serving stale entries. Catalogs are never shared across servers, credentials or reconnects.
  • MCP Skills extension: servers that advertise the published Skills extension have their skills listed in list_mcp_resources. Listing never activates a skill, and reading a skill file is refused unless its size and sha256 digest match the listing. MCP skills do not yet join /skills.
  • Updates install themselves: release-binary installs check for a new release every 6 hours (was 1), download and checksum-verify it in the background, and apply it the next time codewhale starts, never during a session. One line says Updated to v… · What's new: … · Undo: codewhale update --rollback. Until releases are signed, the download waits for your OK (one [y/N] question at the next start, or /update install); a release with a valid Ed25519 manifest signature applies on its own. codewhale update --rollback puts back the version the last update replaced and keeps the rolled-back version from returning automatically. Turn it down with codewhale config set update.mode notify (or off, or CODEWHALE_UPDATE_MODE); an organization's root-owned policy.toml overrides both. Offline and rate-limited checks retry about an hour later instead of on every launch. Package-manager and desktop-app copies only get their manager's command. Builds with the release key refuse a missing or invalid signature, and re-check the staged binary against the signed manifest at start. The checksum manifest now always comes from GitHub Releases; on Linux x64 the CNB mirror can still serve the binary, but only bytes that GitHub's manifest lists.
  • One view of every Codewhale on the machine: codewhale doctor has an Installations section and codewhale doctor --installs (--json, --brief) lists every codewhale, codew, codewhale-tui, deepseek and deepseek-tui with its owner: install receipt, package manager (with its exact removal command), the desktop app, a backup, or not ours. Nothing found is ever run. codewhale doctor --fix adds one plan to tidy them: old backups move to ~/.codewhale/recovery/<stamp>/ (kept 30 days, then deleted by a later --fix), an unreceipted codew is brought in line with codewhale, and the directory gets an install receipt; each move prints its undo and codewhale doctor --restore <stamp> reverses the lot. Package-managed, desktop-app, symlinked and foreign files are never touched, and neither is user data. codewhale uninstall now lists other copies with the same classification.
  • Uninstall guidance on every install route: codewhale uninstall previews receipt-owned release files and --yes removes only checked files, with the running command last. Both Unix installers and the Windows archive installer record command ownership; self-update renews existing receipts on both. On Windows the running codewhale.exe is renamed, then a hidden PowerShell process deletes it after the command exits. Package-managed copies are left alone, and the command prints their exact removal command: npm with its prefix, Cargo with its root, the Homebrew formula, scoop uninstall codewhale, winget uninstall --id HunterBown.CodeWhale, or the Windows setup's Uninstall.exe. Every other codewhale/codew still on PATH is listed. User data is kept unless you add --purge-data. With --yes it runs only after a receipted installation was removed in that same run, and then deletes only ~/.codewhale (or a CODEWHALE_HOME named .codewhale) and ~/.deepseek/snapshots, refusing symlinks, home ancestors and directories owned by another user. A copy from an older curl | sh installer that wrote no receipt is adopted on --yes when it sits in a known older curl-installer directory: the commands byte-identical to the running program get a receipt and are removed, anything else is preserved, and a symlink or hard link among them stops adoption before any receipt is written. (Refs #7091)
  • GitHub Action reviews: analysis can export a structured Engine review for a separate trusted publisher job. The publisher checks the current PR revision and line anchors, deduplicates its findings, and keeps uncertain or preexisting claims out of inline comments.
  • DingTalk bridge: an optional internal-app Stream adapter reuses the same Engine, shared admission and approval helpers. Tenant/staff allowlists, durable acceptance before acknowledgement and retained uncertain deliveries protect recovery. Managed account linking is separate from this advanced self-hosted bridge.
  • Answerless output-limit recovery: opt into [reasoning_only] on_output_limit = true to request an answer again after a length stop with no answer or tool call, including hidden reasoning and ordinary Fleet workers. Retries share max_reprompts, retain existing output and control limits, and record request-scoped nudge receipts without adding them to resumed conversation context. RLM keeps its existing stop protocol. Thanks @M-Maciej for the long-proof Fleet report. (#6990)
  • OrcaRouter recommendation: /provider and /model offer a shared partner recommendation with the DeepSeek V4.1 Flash 30% top-up-match link, public referral disclosure and localized offer details. F7 or a click opens the existing pager while retaining the current route.
  • Per-scope instruction budgets: global and project standing instructions now have separate token budgets (100,000 estimated tokens each, capped at 25% of the usable context window), every trim, skip or refusal reaches the model and /context report, and [instruction_budget] policy = "refuse" stops a request before dispatch. Other tools' instruction files stay opt-in through project_instruction_imports or claude_fallback, and the table is user config only. Thanks @7jrxt42BxFZo4iAnN4CX for the design and implementation. (#6526, #7086)
  • The TUI Terminal dock now also shows the model's shell commands for the session: each running or recent command is a read-only tab with its live output, beside the interactive shells. "No live terminals" appears only when there are neither.
  • Preview: dispatch --computer starts an account cloud conversation that can also be opened in desktop. --thread continues or inspects it; --stop, --approve and --deny control its current task. Explicit --key-stdin installs provider access in the running computer's memory. Retries retain one operation key and the account/VM binding. Existing Agent Work dispatch remains available when no computer conversation is selected.
  • A long draft or paste now grows the composer past its density row limit, up to half the screen (never less than that limit) while leaving room for the transcript, so the text can be read and edited before sending. While a slash, mention or history-search menu is open the composer keeps its usual height (#7049).

Changed28

  • Managed ACP requirements outrank Full Access: when organization requirements manage approval policy, ACP no longer lets --full-access override them. The TUI already locked YOLO this way; ACP now matches.
  • Cleaner, safer Markdown export: headings no longer carry Content N: numbering, a text block that opens a message is bare, tool results show their tool name and appear under a tool role instead of user, and Error: appears only on an error. Tool output is now fenced, so a tool result can no longer forge a heading or a message in the transcript. A trailing --force is a flag rather than part of the path. /share now publishes the same HTML page as /export file x.html, still as a redacted secret gist after confirmation.
  • Internal coarse split: Runtime owns bounded owner work, Paths owns the protected socket layout, and Protocol owns shared avatar data. App Server now owns the Runtime host and control transports previously embedded in the TUI. Engine and Sandbox do not depend on App Server; the remaining Stage B boundaries stay open (#5586).
  • Newer DeepSeek Harness plugin compatibility: the Native host targets DSH 0.2.1-rc.5 with Cordis 4.0.5 and refreshed reviewed composition packages. Boolean deferLoading hints are accepted while the Engine keeps tool-loading policy; when remains refused. Service metadata distinguishes DSH, Cordis and Codewhale services. The changed compatibility digest requires fresh plugin review and trust. The legacy preset adapter keeps its recorded source pin; this is local compatibility evidence, not release qualification.
  • Goal tool guidance while awaiting an answer (#7177): the tool schema now tells the model to yield when it needs the user’s answer and reserves blocked for stalled progress. Existing runtime semantics are unchanged; no live-model qualification is claimed. Thanks @SparkofSpike.
  • A goal pauses to ask instead of inventing the answer (#7175): the goal continuation prompts now tell the model to call update_goal with status: "yield" when the next pass needs an answer only the user can give, and that asking in prose does not pause the goal. This is prompt steering, not enforcement: a model that ignores it still keeps the goal active. Thanks @SparkofSpike.
  • Newer model rows in the offline catalog: the bundled seed now carries kimi-k3.1-pro and kimi-k3.1-pro-highspeed (Moonshot), MiniMax-M3.1-Flash (MiniMax and its Anthropic-compatible endpoint) and gpt-6.1-terra (OpenAI), which Models.dev already listed and Codewhale did not pin. Live refreshes from Models.dev were already showing these online; the seed is what a first run, an offline start and a deep-offline install read, so it is now re-locked at 2026-10-30 and rendered. seed render --check matches and defaults audit reports no stale default.
  • Skills ownership (internal): skill discovery, provenance, mutation and bundled skill content move into codewhale-skills. Native roots still use the existing host manager's selection and lifetime checks. (S20, #5316)
  • Model pricing ownership (internal): hand-sourced price metadata and recorded-time rules move into codewhale-models; cost auditing and live catalog callers use the same owner. (S24p1, #5316)
  • codewhale-error-taxonomy crate (internal): error_taxonomy moves out of codewhale-tui into a new crate; the LlmError envelope conversion stays in the TUI crate until the model-wire split. No behavior change. (N13, #5316)
  • codewhale-tui-kit crate (internal): terminal rendering helpers (markdown, diff, text width, paste burst, OSC-8, streaming) move out of codewhale-tui into a new crate, and syntect is no longer a direct codewhale-tui dependency. No behavior change. (S52, #5316)
  • Terminal kit on design tokens 2.3.0: the vendored codewhale-ratatui now follows design tokens 2.3.0: an Accent role carries the one blue for links, focus and selection, and Primary is the ink of filled actions (upstream codewhale-hq/codewhale-ratatui 528a9c4). The built-in TUI themes keep their colours; only surfaces drawn in the kit's own roles take the 2.3.0 values.
  • Fleet workers run the same Codewhale: codewhale fleet run and Runtime API Fleet runs (POST /v1/fleet/runs) now start workers from the running codewhale binary instead of whichever codewhale is first on PATH, so they work with a minimal PATH and never pick up a stale copy. CODEWHALE_FLEET_CODEWHALE_BINARY still overrides it. (#7119)
  • Switching provider lands on its current model: /provider stepfun now selects Step 5 Preview instead of the older Step 3.7 Flash; a model you saved for a provider is still kept. /model now lists the current provider's own models (bundled and live, newest first, up to 20) instead of only the selected one. Search also matches ids typed without separators (step5). While you search, Shift+P and Shift+F type their letters rather than pinning or adding to Fleet, so Step-5-Preview can be typed in full; Ctrl+P and Ctrl+F pin or add the highlighted row at any time.
  • First run without a key: /provider now opens on the full provider list (DeepSeek and the other cloud providers) when only a keyless local runtime is set up, no longer shows a disabled Antigravity row that was never configured, and Shift+A toggles the view like a. A local Ollama model that is not loaded yet is loaded before the first turn, so the route uses its real context window (for example 32K for qwen3:4b) instead of an 8K fallback that refused the second message with "~5120 tokens usable"; the footer's context reading follows the same window. The TUI resolves an unknown Ollama default to an installed chat model on startup. If the daemon or chat model appears later, selecting /provider ollama retries discovery. Embedding-only tags keep the model unresolved. An installed Ollama model is listed in /model and GET /v1/providers/ollama/models once its own catalog has answered, even when another provider is active. (#7113, #7114, #7116)
  • Computer Use delivery: the standalone Engine uses the separately released Computer Use plugin; desktop packaging owns its embedded background helper. The marketplace pins plugin 0.16.0 and its archive checksum. Consent tools load on first use, and decisions still require a human approval card.
  • First-party marketplace receipt: the shipped catalog is pinned to marketplace revision 6096906d57a5a27460ec46eb916460c611aa32c8.
  • Upgrading over older installs: codewhale update writes an install receipt for a copy installed before receipts, and moves a mismatched codew to the recovery folder and replaces it instead of refusing the update. The curl | sh and archive installers upgrade an earlier Codewhale in the install directory instead of refusing, keep the old files in the recovery folder rather than as .bak files beside the commands, and finish with codewhale doctor --installs --brief; a symlink or a non-Codewhale file at the destination is still refused. The Windows archive installer keeps the replaced files in the recovery folder too.
  • The desktop app's Engine is never self-updated: codewhale update refuses to write inside *.app/Contents/MacOS/ or the app's pinned Engine store, and the update notice for that copy says to use Codewhale > Check for Updates.
  • GitHub Action needs an explicit provider: the Action's provider input no longer defaults to the codewhale account relay. Name your BYOK provider (or codewhale for a separately verified account machine key); a missing provider stops with configuration_missing before any download or model call. The repository's own (disabled) review workflow now pins CLI v0.10.2 by default instead of v0.10.0.
  • Local Ollama defaults now come from chat-capable tags, and /provider ollama refreshes the live catalog before switching. Exec and Runtime API defaults use the same discovery path. Fresh context observations come from loaded models' served windows; unloaded models retain an explicitly unverified fallback (#5848).
  • The Runtime API's turn.usage receipts now carry each model call's priced cost on the route that served it and the prompt size the provider billed, so a client can follow a long turn while it runs. The mobile control page shows live token usage and a partial cost estimate in its header, keeps the estimate after the turn settles, starts fresh for the next turn, and counts a replayed receipt once (#7074). Thanks @gaord.
  • --full-access is now the documented flag for Full Access (--yolo stays an alias), and serve accepts it after the subcommand: codewhale serve --acp --yolo used to fail with "unexpected argument". serve --acp also writes one stderr line naming the permission and sandbox it runs with, and the ACP permission option's Full Access hint names the working command. A configured sandbox_mode = "danger-full-access" still never widens Ask or Auto-Review (#6992, #4955). Thanks @eugenicum for the request.
  • Ctrl+C on an idle composer that holds a draft now clears the draft instead of arming exit, and Ctrl+Z restores it. The "press Ctrl+C again" exit prompt arms only once the composer is empty, and Ctrl+C during a running turn still cancels the turn first. Clearing a draft with Ctrl+C or Esc also resets a pending exit prompt (#6237, #7084).
  • While a background job runs, the git status probe now backs off after 30 seconds without input or engine events, as it already did in an idle session, instead of starting about a dozen git processes every 2 seconds for as long as the job lives (#6728).
  • An idle session wakes less often. While an approval, elevation or question prompt waits on you, while a background job runs, or while only a once-a-second label ticks, the event loop now relaxes to its 250 ms quiet poll instead of polling every 24 to 48 ms; animations and the prompt's timeout still wake it on their own deadlines. The terminal input thread polls every 200 ms instead of 50 ms after 5 seconds without input. Measured on macOS with release builds: an approval wait went from 29 to 12 timer wakeups per second, a background job from 32 to 16 and an idle composer from 25 to 11 (#6728).
  • Saving a session no longer copies every message body: journal entries share their content, so the snapshot taken on each update copies ids and pointers. Resuming a session compares a leftover crash checkpoint against the saved document's metadata instead of parsing the whole document first, so --resume and attach read the document once (#6842).
  • Multiline mode now has a send key on every terminal: with composer_multiline_mode = true, Enter inserts a newline and Alt-Enter sends. Shift-Enter also sends where the terminal reports it distinctly; on Linux terminals that report it as plain Enter, multiline mode previously had no way to send. Ctrl-J always inserts a newline. Thanks @luestr for the report. (#7093)

Fixed134

  • Plugin enablement revalidates its review: enabling rechecks the staged snapshot and, under the existing state lock, refuses a changed review generation or trust receipt. The macOS stale-enable check passed (1/1); a separate Linux run reported 202 passed and one ignored on an earlier base with matching plugin files and lockfile. Snapshot checking is point-in-time; automatic restoration is unfinished and filesystem races remain open. A stage-disappearance regression and the final candidate remain unqualified.
  • Plugin status and UI admission: an enabled, trusted plugin whose reviewed runtime snapshot is missing or invalid now reports runtime-snapshot-unavailable. Both plugin UI metadata and assets require a declared DSH client; ordinary plugins cannot expose staged files through the client UI route. Automatic restoration of missing snapshots from receipt-matching canonical source and authenticated DSH asset transport remain work in progress; existing modified snapshots require review.
  • A local proxy that stops mid-session no longer strands the session (#7231): the model, catalog, search, vision, finance, MCP-registry, profile and remote-control clients watch a loopback proxy port and go direct while it refuses connections, then resume proxying when it returns. Only a definite refusal from every resolved address changes the route; remote proxies, NO_PROXY matches, credentials and the existing precedence are unchanged. Set CODEWHALE_LOCAL_PROXY_FALLBACK=0 to keep the old build-time snapshot.
  • Proxy diagnostic privacy (#7233): malformed MCP proxy warnings omit configured values; local-proxy log labels mask userinfo and omit URL paths, queries and fragments. Routing is unchanged. All 23 existing proxy tests passed on macOS; runtime log capture and other platforms remain unqualified. Thanks @SparkofSpike for the report.
  • Fork, undo and retry work after a workspace drift notice (#7234): the history-boundary walks now treat a whole <context_update> envelope as engine-owned, so a session that received one can be cut at every saved turn. A person quoting a notice or a truncated envelope still counts as their own prompt.
  • Git writes land in the right workspace: stage, unstage, discard, commit, push and branch take ?thread_id= and run in that thread's recorded workspace, matching the read routes. Before, they always ran in the server's own folder, so a commit asked for a thread in another folder could land in the wrong tree.
  • ChatGPT sign-in tolerates a small device clock skew: identity-token expiry and not-before checks allow the same 60-second tolerance already used for ordinary network time drift, while signature, issuer, audience, subject and nonce checks remain exact. The diagnostic text still names the exact failed check when a token is genuinely invalid.
  • Remaining long-blocking work moved off async callers (#6553): route credential and certificate preflight, worktree creation, Runtime Chat relay and remote-control journal transactions, and the remaining session, branch, tree, skill, plugin and memory command I/O now run on the supervised blocking owner. Results are still awaited before state publication; sync APIs remain where sync callers still use them.
  • Frozen prices on DeepSeek endpoints: published rates are captured for DeepSeek's root, /v1, /beta and Anthropic endpoint variants, and remain bound to the exact endpoint on replay. Other providers keep their existing pricing scopes; official credential aliases alone do not establish equivalent regional or plan prices. Request outcomes, missing provider usage, legacy usage and unverified corrections now have distinct cost explanations; saved receipts without a frozen quote remain unpriced.
  • Clipboard image persistence: the existing confined writer handles relocated user state directly, without a second filesystem fallback that bypassed its protections and exceeded the blocking-call budget.
  • Case-sensitive model selection (#7214): the provider picker restores the exact configured or wire model ID before trying case-insensitive compatibility matches. Thanks @liuyy2 for the diagnosis and @SparkofSpike for the compatibility-preserving fix.
  • WeCom replies carry the API's error (#7208): a rejected WeCom call now shows its errcode and message in the bridge reply instead of [object Object]. Thanks @gaord.
  • WeCom streams survive the ten-minute expiry (#7210): the bridge finalizes the current stream and opens a fresh one before WeCom stops accepting updates, and reopens once on a rejected update. Thanks @gaord.
  • Non-English packs lose stale mode-jump and rail copy (#7225): the sweep covers every non-English locale and a test pins it. Thanks @asto18089.
  • image_analyze accepts absolute paths inside the workspace (#7226): POSIX and Windows spellings that resolve under the workspace are read instead of refused. Thanks @asto18089.
  • Sub-agent follow-ups report what happened (#7228): a message to an existing successor says whether it was delivered without a resume, the focus view follows the actual recipient, and an undelivered follow-up keeps focus and shows the failure. Thanks @asto18089.
  • A long turn no longer ends at 64 model requests: a turn that had recorded 64 provider usage receipts failed on the next one with "captured usage sink did not acknowledge its source", discarding the person's answer. The per-turn receipt cap is removed. Receipts keep recording exactly once; a sink refusal now retains the exact receipt for a later admitted flush and continues the turn, while owner-lock loss or thread mismatch still fails closed.
  • The verify tool names a callable surface (#7223): its description taught the model to use the retired, hidden run_verifiers name; it now says to use the Run tool with action="verifiers", and the retired-name guard test now covers verify's description. Thanks @asto18089.
  • A home-directory workspace no longer refuses its own state (#7207): a session started in the home directory treated it as a confined workspace, which broke the supported layout where ~/.codewhale is a directory junction onto another volume (Windows mklink /J); only the home state directory is now exempt, and confinement for links elsewhere is unchanged. Thanks @SparkofSpike.
  • The command palette keeps your draft (#7205): picking a command that takes an argument, such as /rename, no longer discards what was in the composer; the draft is stashed so history search can recover it. Thanks @Lstarsky0.
  • Old sessions restore with the topology checkpoint in place (#7229): sessions saved by v0.9.10 to v0.9.12 that compacted with live sub-agents placed the agent-topology checkpoint at the end of the history, which left a tool-then-user message pair that strict Chat Completions templates reject with HTTP 400. Restore now moves the checkpoint to where current saves place it, deletes nothing, and a restore followed by a re-compaction no longer keeps a superseded duplicate. Thanks @asto18089.
  • /patch-undo undoes the turn you chose (#7216): POST /v1/threads/{id}/patch-undo ignored turn_id and undid the latest turn instead, so a caller got a different turn than /undo removes for the same request. It now removes the named turn and every turn after it. GET previews the exact turns and the files that would be restored; sending them back as expected_turn_ids and expected_paths makes a changed selection answer 409 undo_selection_changed before any file is touched. Clients should require the thread_patch_undo_turn_id capability before sending a selected turn, because older Engines ignore the field. Thanks @soarkit for the report.
  • grep_files matches brace and nested-directory globs (#7215): include patterns such as *.{txt,md} and **/*.{txt,md} no longer return an empty result with no error; they match the same files the equivalent separate globs do, at the root and in nested directories. Thanks @Lstarsky0.
  • Sub-agent write claims accept absolute in-workspace paths (#7227): a write-capable sub-agent that spelled an in-workspace target as an absolute path was refused while the relative spelling succeeded. Absolute paths that resolve inside the claimed workspace are accepted; paths outside it, .. traversal and symlinked ancestors that escape are refused exactly as before. Thanks @asto18089.
  • WeCom replies are split by UTF-8 bytes (#7209): the WeCom bridge now caps each reply chunk at 3,800 bytes (WECOM_MAX_REPLY_BYTES) on code-point boundaries, so a long Chinese reply is no longer delivered silently truncated at WeCom's 4,096-byte limit. Callers that do not pass a byte cap keep their behavior. Thanks @gaord.
  • file_search reports workspace-root paths (#7213): a search scoped with path now returns matches the way read and grep_files resolve them, so reading a result opens the file that matched. A path naming one file and glob searches under a subdirectory are fixed too. Thanks @Lstarsky0.
  • Sub-agent worktree isolation no longer adopts unrelated checkouts (#7224): only the session anchor itself may adopt nested repositories; ancestors are probed for containment only, so a workspace a few levels below the home directory no longer fails with "Multiple git repositories found" over unrelated projects. Thanks @asto18089.
  • fetch_url no longer claims to be sandboxed (#7222): its description now says it is an in-process HTTP client guarded by the network policy and the SSRF/DNS checks, and attributes the sandbox contrast to exec_shell. Thanks @asto18089.
  • Usage on long tool turns: physical model-call receipts remain available after the 64th response without dropping earlier sources. A completed tool-only provider response uses its terminal stream event for accounting, while incomplete streams retain unknown coverage.
  • Retained browser connections follow their desktop owner: authenticated runtime registration binds the browser endpoint and credential to its workspace; existing Core catalogs and connections retire a replaced registration before reuse.
  • /new waits for the Engine: the terminal keeps the current session, transcript and draft until the exact session switch is acknowledged. A refused closure preserves them; a late acknowledgement can finish once while retaining input edited during the wait. Pending or uncertain switches pause new work and retain the existing scoped Stop controls.
  • Interactive command confirmations keep their stack headroom: the existing interactive startup chain heap-pins its large futures instead of embedding their debug state machines in each caller.
  • Live MCP status includes runtime servers: the existing pool snapshot now includes workspace-scoped dynamic servers, retaining static-name precedence and the same permission and connection checks.
  • Plugin reload confirms its workspace: the status translation receives the required workspace value instead of producing an empty acknowledgement.
  • MCP credentials fail clearly: missing or invalid required credential configuration stops before connection, stored OAuth discovery failures retain their cause, and reviewed-plugin errors redact credential details. Explicit reconnect still reloads saved credentials.
  • Desktop browser MCP stays with its workspace: the paired desktop host registers its authenticated loopback server at runtime, late registrations refresh the tool catalog, and another workspace cannot inherit the connection. Recognizable obsolete global browser entries are ignored without rewriting user configuration.
  • Closing an empty delegated fleet avoids an unnecessary writer lock: a session with no locally owned agent or worker records can close while another Codewhale process coordinates the workspace. Read-only or failed-admission state and sessions with owned records retain the existing coordination checks.
  • Child, review and Auto usage keeps its captured session and route through late completion and persistence retries. Unreported usage stays unknown, cache writes and reasoning remain distinct, and cost calculations use the quote captured for the request.
  • Interrupted children persist their continuation checkpoint and complete their workflow task instead of leaving it waiting on a worker whose execution already ended. Live approval waits retain their existing behavior.
  • Session publication compares the document and crash checkpoint captured before work was queued. A delayed save refuses changed records without replacing newer history or clearing its checkpoint. Ordered completion retains real checkpoint acknowledgments, and native turn/control identity follows restores, undo and terminal saves. Legacy checkpoints require explicit recovery; canonical history recovery retains its original source and exact prepared generation.
  • Damaged usage sidecars keep valid recovery data readable with incomplete coverage and no publication receipt. Known retirement, changed raw records and unsafe writes still refuse.
  • Local control and ACP output serialize within the existing 8 MiB frame limit and stop a damaged or stalled output stream. Compatibility replies, events and relay stdout now share the 30-second write deadline; owner forwarding keeps its tighter 5 seconds. Standalone and attached ACP recover after complete invalid UTF-8 or oversized input frames, discard oversized tails through the real newline, and preserve cancellation, permissions and actual Core receipts.
  • MCP composition records actual schema or description changes before the next request, so a conservative batch withdrawal re-pins the declared tool surface instead of failing the C5 prefix guard. Semantically unchanged runtime refreshes preserve the original serialized catalog and schema key order. The execute_tools description also explains that visual input needs a direct capture call because nested results do not deliver inline images to the model.
  • Runtime SDK declarations for event, image and dynamic-tool messages are generated from the same Rust wire contracts. Output schemas retain required nullable fields while request defaults remain optional.
  • Inference requests stop after uncertain delivery or an interrupted stream instead of silently sending another request. Automatic retries require an ordinary rate limit or a transient connection failure before dispatch. Redirects and HTTP protocol retries cannot bypass this policy; retained output and missing usage coverage remain visible. Terminal exec failures return exit 1; error categories no longer imply that repeating a saved command is safe.
  • MCP calls inside execute_tools expose a single bare JSON result directly through content. Rich or annotated results retain their envelopes, and oversized results keep the original raw size and spill receipt.
  • Session metadata reads stop at a bounded scan and report unreadable records without hiding healthy picker rows. Queued saves preserve durable renames, archive state and Runtime ownership under the session write lock; uncertain metadata refuses writes and cleanup. Persistence batches run off the async executor, and explicit placeholder-title renames retain their intent.
  • Worker coordination serializes durable admissions across processes, preserves foreign workers and winning completion receipts, and fences stale checkpoints. Fleet restart reservations retain uncertain prior processes until exact teardown is confirmed; final output, usage and the receipt publish together without duplicate accounting on retry. Retained transcripts follow committed ownership.
  • JSONPath projections bound path length, traversal steps and intermediate matches before cloning results. Direct fetches share the same parser and enforce one aggregate serialized-field budget; oversized selections refuse with narrower-selection guidance.
  • Long tool output and diffs use bounded display windows and a byte-limited row cache. Retained details load verified byte ranges and label what search and copy include; explicit source copy keeps stored text with control-sequence cleanup. Oversized Unicode is shown safely without changing question answers; long answers retain their exact bytes in the existing owned output artifact before bounded model-context projection. New pager notices are translated across all 15 complete language packs.
  • Markdown character references: ordinary prose renders valid references once, while inline code, plugin approval text and argv retain their literal values. Long URL punctuation stays linear to scan. Thanks @Lstarsky0 for the report and original fix (#7192).
  • Managed Fleet validates overlapping write roots with a component-sorted scan and deduplicates roots once. Large valid request bodies no longer spend quadratic CPU before admission; existing write-scope refusals and execution limits remain in force (#6554).
  • MCP transports, connection pools and child Engines retain the owning host credential context for placeholders, headers, bearer tokens and OAuth setup. Missing injected values never fall back to process secrets. Reviewed plugins keep their captured environment authority, whose Debug output now masks values. Durable OAuth token custody and full subprocess isolation remain separate work (#5637).
  • Python REPL drains stderr while code runs, retains at most 64 KiB of diagnostics and reports omitted bytes, so noisy code cannot block request completion (#6554).
  • Saved tool results use bounded streaming inspection while preserving session ownership, digest and generation checks. Text refuses oversized lines or selections with byte-recovery guidance; verification also has explicit scan and cancellation limits (#6554).
  • Telemetry bounds its pending event queue and disk-tail reads, keeps final flush admission available, and skips invalid UTF-8 records without discarding intact neighboring records. Existing opt-out and privacy ordering remain in force (#6554).
  • Workflow history summaries retain large child totals without allocating one row per claimed child. Missing outcomes, usage and elapsed time remain unknown, including in the workbar (#6554). The independent terminal kit advances to unpublished 0.2.0 for its u64 total API; registry-based TUI packaging waits for separately approved kit publication.
  • Web build dependencies cap glob preprocessing and stop cancelled directory traversals through compatible, verified upstream backports. Raw dependency findings remain visible. Thanks @isaacs for the minimatch and glob fixes (#6560).
  • Repeated requests no longer make /undo restore files from an older invocation. /undo select chooses a request range and shows checking, restoring and saving progress. Missing, ambiguous or stale restore points refuse before changing files. Esc–Esc continues to rewind only the conversation. Thanks @luestr for reporting #6970.
  • web.run refuses more than 64 operations across its command arrays before starting network work or changing its session cache (#6554).
  • Skill discovery and audit marker reads stop at 512 KiB. Approved linked global skills still load; oversized, invalid and non-regular files produce visible refusals instead of unbounded reads (#6554).
  • OpenSandbox caps successful responses at 8 MiB before parsing and limits remote error details to 4 KiB with terminal controls removed. Oversized responses fail explicitly. Remote execution cancellation remains a separate requirement (#6554).
  • The WinGet manifest generator now selects the published x64 portable executable by exact name and records its checksum and Visual C++ dependency.
  • The Windows setup uninstaller preserves a trailing separator in the current-user PATH and retains other settings stored in the CodeWhale registry key.
  • Inline code in terminal replies preserves embedded backticks. Text after an unmatched delimiter keeps its normal styling. Thanks @Lstarsky0. #7185
  • Windows Ctrl+Break and terminal-close events now request the same bounded session checkpoint and persistence flush as Ctrl+C (CW-7553).
  • When a keyless local Ollama route has no resolved chat model, retrying /provider ollama refreshes the catalog in the background. You can keep typing while the daemon responds. #5848
  • Auto checks the served context window on an active keyless Ollama route when its default model still has an unverified limit. A later turn can use the running model’s window once Ollama has loaded it. #5848
  • The bundled catalog recognizes the bare deepseek-v4.1-flash model ID. It reports a 1,000,000-token context window and a 384,000-token output ceiling. #7183
  • After /undo restores files, Codewhale saves the conversation rewind before reporting completion. Pressing Esc twice and choosing an earlier request also saves that exact conversation boundary, even when two requests have identical text. The picker keeps workspace files as they are. Thanks @luestr for reporting #6970.
  • Feishu and Weixin persist each incoming message ID before handling it. Concurrent deliveries share one result. After a restart, a message with an uncertain outcome stays pending until the bridge can tell the user to check its status. Thanks @7jrxt42BxFZo4iAnN4CX for the durability audit (#6555).
  • Custom OpenAI-compatible routes now honor explicit output requests within the configured window and serving limits. A hosted model with the same name could previously truncate reasoning at 32,768 tokens. Thanks @Gabriel-Degret for reporting #7179.
  • Saving a user turn when the Engine adds its metadata preserves the journal entry and its place in history. Sessions with a fork keep the earlier branch intact. Thanks @SparkofSpike. (#7180)
  • Star keycaps stay intact in Markdown (#7176): plain and escaped text preserve the full grapheme, and a keycap cannot open emphasis. The separate Windows Terminal font-fallback issue remains unqualified. Thanks @SparkofSpike.
  • Codewhale runs from a HarmonyOS user directory (#7168): on HarmonyOS hmdfs (the 2in1 /storage/Users/currentUser mount), which reports its own owner and a group-writable mode for every object and refuses chmod and advisory locks, a GUI start failed one feature at a time — the workspace lease, the owner control socket, then the OAuth credential directory. Private directories, the secret store and credential files now probe the mount once, keep the strict ownership check everywhere it can be expressed, and on a mount that cannot express ownership still enforce no-follow, single-link and atomic publication, with one warning naming what the mount reported. A filesystem without advisory locks serialises secret-store writes within the process instead of refusing; a held lock is still contention. Not observed here on a real HarmonyOS device. Thanks @gaord.
  • Notes stop swallowing a backslash: a transcript note is machine-generated and names paths, but it went through the markdown renderer, where CommonMark §2.4 reads a backslash before ASCII punctuation as an escape. A note naming C:\Users\asus\.codewhale\setup_state.json therefore printed as C:\Users\asus.codewhale\setup_state.json — a directory that does not exist, in the one line a user would copy to find the real one. Notes are now escaped where they are rendered. Fenced blocks, and lines carrying inline code or a table row, are passed through untouched, because the renderer already copies those verbatim and doubling a backslash inside one would print it doubled.
  • Setup state survives a second instance: two running Codewhale windows share one home, and both rewrite setup_state.json when the provider or model changes. The replacing rename is now retried briefly when the destination is held open for a read — Windows refuses it outright while that handle lives — instead of surfacing a write the caller could have made. The failure message also carries the underlying I/O error instead of only the outer context, so the next occurrence is diagnosable.
  • doctor stops flagging a user's own temp-named logs: the stale_setup_temp_files check matched any file whose name starts with .tmp, so scratch files such as .tmp-build-release.log made a clean home report as half-applied. It now matches the shape a staged write leaves when it never lands (.tmpXXXXXX, no extension).
  • Approval cards are translated in every locale (#7071): the "Do you want to proceed?" question, the Why and Stop explanations on destructive actions, the Approve, Edit plan and Cancel choices on workflow plans, the Save row, the details pager's title and the card's impact lines (one sentence per tool category plus the Reads, Writes, Target, Connected app, Agent type and Primary input rows) came from English literals, or from Simplified Chinese only. They now use the shared message catalogs, so all 15 packs carry them. The 14 non-English translations were written without native-speaker review. Still English outside Simplified Chinese: a workflow plan's own impact lines and detail labels, and the delegated-authority rows.
  • Local vLLM models keep their own reasoning ladder (#7124): a vLLM or SGLang route treated every model as low/medium/high and folded low and medium onto high. Reviewed model-template facts (crates/config/src/local_reasoning.json) now give Qwen3.8, Qwen3.6-35B-A3B, Ornith, GLM-5.3-Flash and DeepSeek-V4-Flash-Vision-Exp the controls their template accepts, and the effort picker offers exactly those tiers, so low stays low and medium stays medium where the model has them. Unreviewed models are unchanged. Not yet observed against a real vLLM or SGLang server. Thanks @gannp.
  • /undo, retry and fork-at-turn work on large and attachment-heavy conversations again (#7147): a fork was measured by the shape it is stored in (a saved session repeats its conversation while it carries a journal, so the file can be twice the history) against the 8 MiB bound the reader judges by what the conversation carries, so a conversation the runtime kept opening and extending could still refuse /undo with "full history exceeds byte transport bound". The saved-history boundary also counted MCP-server notices, shell-completion handoffs, the deferred-toolbox snapshot and <image> attachment tags as prompts you typed, so a conversation that had received one refused with "Cannot identify an exact saved-history boundary". Both now use what the conversation carries. Thanks @gaord.
  • Table cells retain code, bold text and clickable links when they wrap. Inline code that fits its cell keeps its indentation and any space-only content. Thanks @Lstarsky0. #7181 · #7184
  • Markdown shows what was written: a paragraph nested under a list item keeps its indent (#7146), ~~~ fences render as code blocks and keep backtick lines inside them as code (#7156), asterisks that do not open emphasis (5 * 60 * 60, *args) stay literal (#7157), a bare URL ends at full-width punctuation such as 。 and ) instead of swallowing it (#7158), a link whose target has its own parentheses (…/wiki/Rust_(programming_language)) keeps its closing ) (#7170), and inline code and links inside bold, italic or strikethrough render as code and links instead of their raw backticks and brackets (#7171). Thanks @Lstarsky0.
  • Fleet changes no longer put a stray English status in the footer (#7152): the engine's "Fleet roster refreshed for subsequent turns" arrived after the change's own receipt, stayed for seconds, took over the footer, pushed the Shift+Tab hint off the row and stayed English in every locale. /config stream_chunk_timeout_secs no longer leaves the engine's "Stream chunk timeout set to …" status in the footer after its own note either (#7169). Thanks @Lstarsky0.
  • Simplified Chinese uses one form per term (#7150): the pack addresses you as 你 throughout (the telemetry notice mixed 你 and 您), says 提供商 for provider and token for usage, and drops two stray spaces after full-width punctuation. Thanks @luochen211.
  • A turn can no longer wedge forever after a tool returns (#6184): the heartbeat's tool phase carried no bound, on the assumption that per-tool timeouts covered it. They cover a *running* tool, not the engine's own work after a result comes back, so that window had no owner: the in-app watchdog deferred to the engine because the engine still looked like the owner, and the engine watchdog only reported. A real turn sat there for 56 minutes, produced no stall record and never cancelled. The tool phase now has a ceiling, and a watchdog report cancels the turn so it ends with a stated reason instead of hanging.
  • A restored conversation can be undone again: a saved document keeps each turn's <turn_meta> envelope before the prompt while a thread rebuilt from its turn records keeps it after, and only the leading shape was stripped before comparing the two. Every record-side prompt was therefore longer than its transcript twin, so the exact-boundary search never matched and /undo on a resumed thread refused with "Cannot identify an exact saved-history boundary" instead of answering. Both shapes are now stripped, so the comparison sees the prompt text alone.
  • MCP servers that reject the modern probe now fall back to the legacy handshake: a server answering server/discover with HTTP 400 and a JSON-RPC error (for example -32600 Unsupported protocol version) was treated as a hard failure instead of evidence that it speaks the older handshake, so such a server could not connect at all. Codewhale now reads a parsed JSON-RPC error on the probe as a transport refusal and negotiates the legacy initialize handshake, which is what a server that clearly answered in JSON-RPC means. Reproduced against mcp.deepwiki.com (three tools after the fix); Linear is unaffected.
  • MCP servers reject requests that carried two framing headers: Codewhale sent every Streamable HTTP request with a duplicated Accept and Content-Type, because the extension host forwarded the SDK's headers and the Rust send path added them again. A server that validates those headers answered 415, which Codewhale read as "this endpoint is not Streamable HTTP" and answered by switching to the deprecated SSE transport; servers that refuse GET then returned 405 and the connection failed with only SSE error: Non-200 status code (405). Linear was unreachable this way. The send path now collapses the framing headers to one value each. Verified against Linear: discovery, tool listing (77 tools) and connection succeed.
  • One context window from planning to compaction (#7133): the window a route resolves (from provider facts, your configuration or a fallback) and where it came from now travel together. Turn planning, automatic compaction, tool-output sizing, output caps, child agents, the context inspector and the model picker all use the same window. Previously a custom model with no context metadata was sent with a 128K fallback while compaction planned against 1M. A model switch or re-sync that keeps the same model and limits keeps that window. On resume, /context shows the last Auto route’s saved window and its source. Each new turn resolves its own window from current settings and provider facts. After a model switch, the /preview-request body hash includes the compaction setting the new route will send. The /context report command identifies the Engine as the source of both its bundled constitution and the session relay template. The original Windows report has not been reproduced.
  • Session saves no longer fail silently (#7095): if the session store has stopped, a checkpoint or reset save now reports the failure in the status line instead of being dropped with only a log line.
  • Saves keep your recovery checkpoint (#7095): a finished turn is saved even when a newer in-progress checkpoint arrives at the same time, and a /clear or /new reset no longer drops its own snapshot when saves queue up. If the reset snapshot cannot be built or written, the previous recovery checkpoint is kept and the save failure is shown in the transcript and status line instead. Retrying an interrupted session deletion finishes it without removing the shared checkpoint an older Codewhale may still be writing. These fixes do not yet reproduce the original report.
  • Context inspector shows the real compaction trigger (#7133): /context uses the current route's effective threshold, including when it is zero. When automatic compaction is off, it says so, and the Work rail points to manual /compact.
  • doctor --probe-local changes nothing (#7115): when a configured route rules out local Ollama, the check skips credential inspection. Otherwise it reads credentials without migrating the legacy secret store; exec keeps its normal resolver.
  • Blockquotes keep their rail when wrapped (#7144): every wrapped row of a blockquote keeps the quote rail, and copying a selection still leaves the rail out. Thanks @Lstarsky0.
  • Localized activity and file receipts: grouped tool activity, file counts, patch outcomes and tool status use the shared 15-language catalog. Language changes refresh cached summaries; filenames, diffs and execution receipts keep their original data.
  • Automatic compaction stays off when disabled: preflight and provider context-overflow recovery preserve the conversation and report the setting instead of forcing a summary. Manual compaction remains available, and a rejected recovery request retains its actual cause in both paths. (#7142)
  • VS Code packaging security: use patched MSAL Node in the extension packager, addressing GHSA-xcx6-jx8p-x3h5.
  • Compaction preserves task state: a summary that is empty, a placeholder or only leaked reasoning tags (as local models sometimes return) no longer replaces your history. The recent tail is chosen by token budget on whole tool exchanges, the older span and any earlier checkpoint are summarized, and the original history is saved before the swap. Context budgeting learns from provider-reported usage within a turn and reports repeated rapid refills instead of looping. (#7133)
  • Vim Normal mode works on every terminal: with composer_vim_mode = "vim", Normal-mode keys no longer land in the draft as text on Windows terminals or on any terminal that does not report bracketed paste (everything except ghostty, iTerm, WezTerm and Apple Terminal, tmux and VS Code's terminal included). A held key now reaches Normal mode, shifted keys such as G move instead of typing, and k history recall repaints at once. Keys that arrive in one burst are still taken as a paste. (#7126, #7130) Thanks @Lstarsky0.
  • Remote-control start failures stay visible: a refused or failed /rc start now leaves the controller in the Failed state with its reason, logs a redacted line, and keeps /rc status in the footer after the toast expires instead of reporting "off". (#7127, #7120) Thanks @laozidabo.
  • /undo follows your language: what /undo reports (the request it undid, each file it restored, what it left in place) now comes from the locale catalog in all 15 complete packs instead of English text in the code; English output is unchanged. If a localized report cannot be built, the restore still syncs with the Engine and an English report is shown. (#7121, part of #7071) Thanks @Aboysky.
  • TSX files get TSX diagnostics: the language server now opens .tsx documents as typescriptreact, so valid JSX is no longer reported as a TypeScript syntax error. (#7140) Thanks @Ricardo-M-L.
  • Work stays with the session that was saved (#7118): saving, forking, renaming and rewinding a conversation now publish only the Work (To-do) state that belongs to the session just saved, and a newer update stays pending instead of being overwritten. A rewind that applied but could not be saved says so and puts the retry or replacement prompt where you can copy it. Tasks missing from /task list while the tracker shows them are not explained by this change.
  • Interrupted session hint stays visible (#7095): when a plain codewhale launch finds a session whose turn never finished, the "Run codewhale --continue to resume it" hint now appears in the TUI's status line instead of being printed to the terminal just before the TUI covered it.
  • Interrupted sessions are kept and listed (#7095): crash checkpoints are no longer deleted after 24 hours. The resume picker shows a session that exists only as a checkpoint, labelled Interrupted, --resume <id-prefix> finds it, and codewhale sessions lists it with an interrupted mark. A newer checkpoint is promoted into its saved session only under the session lease, and only for the same workspace. Retained checkpoints are not yet capped in number.
  • Resume an interrupted reply (#7095). Escape preserves the visible partial reply. On SIGINT, SIGTERM or SIGHUP the terminal has up to two seconds to save the active turn and flush pending writes. A second signal exits immediately. On Ubuntu, killing the process after its regular checkpoint preserved the visible text through that checkpoint. On resume, the transcript marks the partial reply interrupted, and /copy returns the last completed answer. Thanks @laozidabo for the signal handling in #7122.
  • Remote control works again: codewhale rc (/rc) can attach to the hosted control plane for web Chat again. The control plane had only accepted the retired 0.9.13 runtime identity, so every 0.10.x Engine was refused with runner_runtime_identity_unavailable; it now accepts the exact released runtime identity (commit, image and digest) and fails closed when they are not configured.
  • MCP compatibility fixes: older servers that answer the discovery probe with an error or an unrelated result now connect through the legacy handshake instead of being refused after the probe. A server that rejects sign-in reports its real 401 and the /mcp login hint rather than the probe's "method not found". A stale OAuth token is refreshed once when the probe itself is rejected. A server whose command cannot start now says why (for example, command not found) instead of a generic broker refusal.
  • Image-heavy session recovery: ordinary image reads use a 256 KiB delivery budget. Requests measure serialized bytes; over the local budget, older images are omitted from the outbound copy first, with receipts. An initial HTTP 413 is retried exactly once without image attachments, each replaced by an omission note. Saved images and executed tool actions remain intact.
  • Composer history honors CODEWHALE_HOME: with CODEWHALE_HOME set, prompt history reads and writes $CODEWHALE_HOME/composer_history.jsonl instead of sharing ~/.codewhale across isolated homes; an invalid CODEWHALE_HOME keeps no history rather than falling back to your real home. (#7069)
  • Slow tools are not reported missing: a tool whose --version probe is still running at its 3-second deadline (for example the cargo rustup shim on a busy machine) now counts as installed instead of being cached as missing for the rest of the session.
  • Telegram recovery: prompts and their initiating identity are durable before the polling cursor advances. Restart recovery reuses the original Engine operation, questions preserve human ownership, and uncertain final replies remain available through /status without an automatic resend.
  • Long drafts now show a localized external-editor hint when the actual composer viewport clips their text. The hint uses the shared F4 binding and preserves queue, running-turn, history, and menu hints (#7049). Thanks @Lstarsky0.
  • Archived context markdown now uses the active theme's palette when rendered in the transcript, preventing unreadable dark text on dark backgrounds (#7043). Thanks @Statter.
  • Plan-to-Work handoff now names the seeded To-do item in a localized reminder to keep it on the list and complete it after the plan (#7068).
  • Localized question footers, approval and plan-handoff chrome, tool waiting status, and /color receipts use the shared locale packs (#7071).
  • Clearing a conversation with no goal no longer shows a misleading "Goal cleared." receipt. Clearing an existing or configured goal still reports it (#7089). Thanks @Lstarsky0.
  • A fatal engine error no longer turns on offline queueing by itself. When the error came from a step that never starts a turn (a finished background shell, a goal continuation or a child completion that cannot resolve its route), every later message used to be queued behind it; it is now sent normally. An environment-only authentication failure still reopens provider setup and queues until you fix it (#6561).
  • codewhale --provider <name> resume <id> now moves the saved session to the named provider, as exec --resume already did, so a session whose provider table was deleted can be reopened on a provider you still have. It takes that provider's default model unless --model is also given. Without --provider the resume still refuses rather than fall back, and the refusal, now also on the codewhale resume and fork mount path, names this command beside codewhale sessions export <id> (#6996). Thanks @luestr.
  • The model's skills index now says when it shortens skill descriptions. When a description hits the 400-char row cap, or rows are cut to fit the context budget, the index ends with "descriptions shortened for N of M skills" and points to load_skill with name="list" for the full text; /context report and /context json show the same count on the skills entry. /skills inspect now flags a description by the same rule the index uses (#7073).
  • A shell command that spans several lines (a heredoc, a loop, an && chain split across lines) now shows those lines on its Live card while it runs and after it succeeds, within the card's usual line limit, instead of only the first line. Transcript shows the whole command. Single-line cards are unchanged (#6436, #7082).
  • codewhale review no longer accepts leaked tool-call markup as a review: a pass whose reply is a DeepSeek DSML (or other) tool-call wrapper outside code now fails as incomplete, with no tally and nothing posted (#7072). Reviews no longer have fixed per-risk output caps (a Low-risk review used to get 4,000 tokens, which a reasoning pass could spend entirely on thinking): every pass may use the route's own output limit, and the step, tool and money budgets still stop a review early as a named partial review rather than truncating it. The review tool bounds its reasoning level to leave room for the review, and an exhausted pass reports the allowance and reserve actually sent and says "cut off" when visible text came back (#7067).
  • A delegated agent still marked running that has reported no progress for 10 minutes no longer holds its parent turn open: the turn's stall watchdogs can recover again, and the stall record names the agent. A child's running time stays unlimited; only silence counts (#6184).
  • Code blocks inside reasoning cells now take their syntax colours from the active theme instead of the terminal's detected light or dark mode, so a dark theme such as Shoreline in a light-profile terminal no longer paints near-black code on its dark reasoning surface. The pager and clipboard copies still follow terminal detection (#7043).
  • /balance and the balance status chip work on the default DeepSeek route again. The balance request now goes to the DeepSeek API root instead of the /beta inference path, which failed with "Could not fetch DeepSeek account balance". A failed balance request now names its reason, such as HTTP 401 Unauthorized (#7055).
  • An AGENTS.md or global instruction file over 100 KiB is no longer skipped (which could let a sibling file load in its place): Codewhale loads its first 100 KiB, ends it with a marker giving the bytes omitted, and names the file in /context report. The shared 48 KiB instruction budget still applies after that, and the marker it leaves when it drops broader scopes now gives the bytes dropped and the total (#6526).
  • write over an existing file now says when it kept that file's CRLF or LF line endings, so the agent no longer reports a line-ending conversion that did not happen (#7070).
  • The To-do that a Plan-to-Work handoff seeds is now titled with the plan's first non-heading line outside code fences, without list or emphasis markdown, instead of the whole plan run together (#7068).
  • Right-click "Open in editor" on a transcript cell now also offers a bare workspace file path with no line number, opening it at line 1 (#2342).
  • Composer history is no longer rewritten from a partial read: when the history file cannot be read, new entries are not saved over it and a warning is logged. An empty declarative workflow is refused ("workflow must contain at least one node") instead of succeeding with no work (#6559).
  • A SKILL.md that is not a regular file is reported as a skill load warning instead of being read, so a FIFO in a skills directory can no longer stall discovery (#6554).
  • app-server: a turn whose response_start could not be written to stdio is now interrupted instead of running on with nothing able to stop it (#6558).
  • Session saves no longer fail with "Fleet artifact path must stay within the workspace" when the Codewhale state root is a symlink or Windows junction to another volume: the state root is resolved before session-side state is opened. Thanks @SparkofSpike. (#7097)

Security4

  • Saved tool-result reads refuse links in the selected session, including a linked session directory, while preserving deliberately relocated application storage. Owned files and digest-checked legacy results keep their existing access paths.
  • Pinned marketplace archives: a Codewhale or Claude marketplace entry whose tarball source carries a sha256 now installs only when the downloaded bytes match it; a mismatch, a malformed pin or a pin on a non-archive source refuses the install with nothing written. The pin also applies to direct installs as https://…/x.tar.gz#sha256=<hex>.
  • Sandboxed commands cannot plant git hooks or edit git config: in workspace-write mode, .git/hooks and .git/config (and a linked worktree's shared hooks and config) are read-only to sandboxed commands, so a command cannot leave a hook or core.hooksPath that later runs outside the sandbox. The workspace's .codewhale/ is protected even before it exists (on Linux it is created first, because bubblewrap can only protect existing paths). git commit and ordinary file writes are unaffected; git config writes and hook edits need an approved unsandboxed command.
  • Tool image validation: an image returned by a tool must decode before it is sent, so truncated or corrupt files are omitted with a receipt even when they are already within the delivery budget.

Maintenance19

  • MCP regression fixtures retain private extension-host roots and wait for their own workers to finish, preventing parallel checks from borrowing a deleted fixture home. Production connection and credential policy is unchanged.
  • Independent terminal kit candidate 0.2.0: its workflow totals use u64, and its existing avatar API reexports the shared Protocol contract. All local consumers pin 0.2.0. Protocol 0.10.3 must be published and verified before the kit, followed by the dependent Engine packages; each publication retains its separate approval.
  • codewhale-plugins crate: plugin discovery, review, install and marketplace parsing move out of codewhale-tui into a new crate; MCP server config types move to codewhale-mcp, and the skill parse core and recommendations to codewhale-skill-install. Review and trust behavior is unchanged. (S19, #5316)
  • codewhale-config modules (internal): the 8,100-line lib.rs is split into 23 modules (provider TOML, permissions, fleet, config resolution, env overrides, state dirs, config store and backup, and others); codewhale_config:: paths are unchanged. No behavior change. (S57, #5316)
  • codewhale-app-server modules (internal): lib.rs is carved into http, stdio, turns, bridge and config_rpc modules; BoundedLines and runtime_compatibility_router now live at codewhale_app_server::stdio and ::http. No behavior change. (S49, #5316)
  • codewhale-account-cli crate (internal): the cloud account, cloud computer and dispatch CLI commands move out of codewhale-cli into a new crate. No behavior change. (S50, #5316)
  • runtime_threads store and manager (internal): runtime_threads is split into the durable store (runtime_threads.rs) and the thread manager (runtime_threads/manager.rs); callers import from runtime_threads::manager. No behavior change. (S35, #5316)
  • Crate split S24a (internal): the workshop byte-budget slot moves to codewhale-runtime, AutoRouteDecisionEvidence to codewhale-models, and cost-status session persistence to a tui usage_persistence module, so billing no longer reaches the session manager or model routing. No behavior change. (#5316)
  • Provider pre-cuts B (internal): client wire helpers, reasoning-effort mapping and the Ollama catalog parsers move into their own client modules, and test-only provider gates use the shared test-isolation predicate. No behavior change. (#5316)
  • codewhale-dependencies, codewhale-snapshot, codewhale-lsp, codewhale-repl crates: external-tool resolution, workspace snapshots, the language-server client and the Python REPL runtime moved out of codewhale-tui into their own crates; write_context_file now lives in codewhale-repl. No behavior change. (#5316)
  • codewhale-skill-install crate: the community-skill installer, package content digest and SKILL.md frontmatter reader move out of codewhale-tui into a new crate; the install SSRF guard and timeouts are unchanged in production builds. (#5316)
  • codewhale-util crate: shared utilities, confined workspace file access, link and file-identity checks, bundle file readers, the .git name rule and the owner file lock move out of codewhale-tui into a new crate; no behavior change. (#5316)
  • Crate-split contract hygiene: the canonical_action policy table now lives in codewhale-execpolicy, required_action, the file path-alias folding and the apply_patch preflight parser in codewhale-tools, and DEFAULT_SPAWN_DEPTH, PermissionCeiling and ShellCeiling in codewhale_protocol::fleet, so codewhale-agent-contract no longer depends on codewhale-config or codewhale-workflow. Approval and authority behavior is unchanged. (#5316)
  • Provider pre-cuts (internal): schema sanitizing, prompt-turn classification, image-window capping, tool-projection warning names and the reasoning-effort tier moved into codewhale-models; stall records and route-label sanitizing moved into codewhale-runtime. No behavior change. (#5316)
  • Linux hardening tests: the NoNewPrivs child matrices now respect a parent that already holds the irreversible flag, keeping the full assertions on unpinned hosts and checking the kernel ratchet on pinned hosts. Thanks @asto18089 for diagnosing the hardened-container failure. (#7021)
  • Removed the internal config re-export facade and its model-constant wrapper; provider types, shared constants, credential helpers, and notification types now come directly from their shared owners. Configuration and saved settings keep their existing behavior.
  • Removed superseded home-directory and Fleet-role re-export shims, unused tool-context sandbox/MCP fields, and the redundant core tool-parser facade. Consumers now call their existing owners directly; tool denial rules, approval posture, strict tool schemas, home resolution, and legacy saved-role migration retain their behavior. The cleanup removes three dead-code suppressions and keeps the engine as the sole owner of human approval attestations.
  • Removed unused plan/journal accessors, an unused plan-status glyph helper, and a cancellation case that no execution path issued. Active mailbox and cancellation wiring stays in place; its stale unused-code suppressions are removed. No supported command or feature is retired by this cleanup.
  • README translations carry refreshed source stamps after the 0.10.3 batch. Thanks @Aboysky. (#7104)

Contributors22

  • @zhuowp (git author z27014) — added bounded HTTP rate-limit recovery and corrected retry deadlines, quota guidance and recovery receipts (#7220).
  • @printf033 — enabled exclusive rename on Android so Fleet publication does not fall back to SELinux-denied hard links (fbe9f24ee).
  • @liuyy2 — diagnosed case-sensitive model selection collisions in the provider picker (#7214).
  • @isaacs — upstream minimatch preprocessing and glob cancellation fixes reused in compatible web build dependency backports.
  • @Gabriel-Degret — reported that a hosted output limit truncated reasoning on a custom endpoint (#7179).
  • @soarkit — reported that /patch-undo ignored turn_id and undid the latest turn (#7216).
  • @Felixkw12 — added Opper as a bundled provider (#7131).
  • @7jrxt42BxFZo4iAnN4CX — per-scope instruction budgets with visible truncation (#7086, #6526).
  • @Lstarsky0 — kept the /diff pager's place across a resize (#7087), said "Goal cleared." only when there was a goal (#7089), and stopped printing an unpriced session cost as $0.0000 in /status (#7090), kept Normal-mode keys out of the draft on terminals without bracketed paste (#7126) and let shifted keys such as G reach Normal mode (#7130), kept the quote rail on every wrapped row of a blockquote (#7144), kept a nested list paragraph's indent (#7146), rendered ~~~ fences as code (#7156), left asterisks that do not open emphasis literal (#7157), ended bare URLs at full-width punctuation (#7158), kept a link target's own parentheses (#7170), rendered code and links inside emphasis (#7171) and stopped the engine's fleet-roster and stream-timeout statuses from taking over the footer (#7152, #7169). Preserved indentation and space-only inline code in table cells (#7184). Reported file_search matches relative to the workspace (#7213). Matched brace and nested-directory globs in grep_files (#7215). Kept the draft when the command palette inserts a command (#7205).
  • @gaord — a running turn's cost and context in the Runtime (#7074) forks that measure the history they carry (#7147), and private state on a HarmonyOS mount that cannot express ownership (#7168). Capped WeCom reply chunks by UTF-8 bytes (#7209). Accepted media and voice messages on the WeCom bridge (#7212). Steered a running turn from the WeCom bridge (#7211). Surfaced WeCom API error details in bridge replies (#7208) and rotated WeCom stream replies before the ten-minute expiry (#7210); both were harvested with the original commits kept.
  • @luochen211 — one form per term in the Simplified Chinese pack (#7150) and dropped blanket dead-code allows in fleet alerts and the pet worker (#7149).
  • @gannp — reported vLLM effort values that ignored the local model template and fixed it with a reviewed template registry (#7124, #7125).
  • Sh1Zuku / @SparkofSpike — resolved a relocated state root before session-side state opens (#7097) and made a goal pause to ask instead of inventing the answer (#7175), and gave the model a way back into the transcript compaction replaced (#7173). Also preserved journal history when a provisional input receives its Engine metadata (#7180). Added the bare DeepSeek V4.1 Flash catalog entry (#7183). Stopped a home-directory workspace from refusing its own state (#7207).
  • @ddlw — repaired main for the 0.10.3 batch: clippy -D warnings across protocol, runtime, util and tui (boxed review and MCP-add payloads, scoped dead-code expectations, cfg-gated platform test helpers), rustfmt, split extension-host imports, the provider-registry identity check, Windows-stable DSH receipt bytes, and the first-party marketplace receipt (#7108, #7109).
  • @laozidabo — localized /diff feedback (#7101), flushed queued saves before signal exit (#7122) and kept /rc start failures visible (#7127).
  • Boyce / @Aboysky — refreshed the README translation source stamps (#7104) and localized /undo feedback (#7121).
  • @Ricardo-M-L — opened .tsx documents with the typescriptreact language ID (#7140).
  • @M-Maciej — reported answerless output-limit stops in long Fleet proofs (#6990).
  • @asto18089 — diagnosed the NoNewPrivs child-matrix failure on hardened containers (#7021). Dropped the false sandbox claim from the fetch_url description (#7222) and limited nested-repository discovery to the sub-agent worktree anchor (#7224). Accepted absolute in-workspace paths in sub-agent write claims (#7227). Repaired pre-0.10.0 topology checkpoint placement on session restore (#7229). Pointed the verify description at the Run tool instead of a retired name (#7223). Swept stale mode-jump and rail copy from the non-English packs (#7225), accepted absolute image paths that resolve inside the workspace (#7226) and reported follow-up delivery truthfully (#7228); all three were harvested with the original commits kept.
  • @Statter — reported black-on-black text on terminals that do not report their background (#7043).
  • @eugenicum — asked for a visible Full Access flag for serve --acp (#6992).
  • @luestr — reported file and conversation rollback diverging (#6970), the Linux multiline send key (#7093) and session export guidance (#6996).