v0.9.12

sundowndev/phoneinfogav0.9.12Sep 5, 2026by github-actions[bot]

AI Summary

This release integrates a computer-use plugin into the binary, adds Alibaba Model Studio and Concentrate as new gateway options, introduces cloud dispatch for coding agents, and implements a per-session control socket. It also includes significant UI updates to the shell.

Key Highlights

  • Embedded Computer use plugin with 38 tools across macOS, Windows, Linux, and HarmonyOS.
  • Integration of Alibaba Model Studio (Qwen models) and Concentrate (BYOK gateway).
  • New cloud dispatch feature for offloading coding agent tasks to isolated sandboxes.
  • New per-session control socket for JSON-RPC management and session control.
  • Rebranding from `deepseek` to `codewhale` with deprecated legacy packages.

Breaking Changes

  • Legacy npm package `deepseek-tui` is deprecated.
  • Legacy binary names (`deepseek`, `deepseek-tui`) are replaced by `codewhale`.
  • The stdlib-Python computer-use server has been removed.

New Features

  • Computer use plugin with accessibility-first observation, screenshots, and screen recording.
  • Alibaba Model Studio support via data-driven provider table with live model discovery.
  • Concentrate opt-in BYOK Responses gateway with SSE streaming.
  • Cloud dispatch for remote runner with machine token auth.
  • Per-session control socket binding to `<sessions-dir>/<session-id>/control.sock`.
  • New shell UI components: launch card, work surface, focus owner, and stateful tool cells.

Full Release Notes

> **Codewhale** is the public product from Shannon Labs. The `codewhale`
> command, npm package, and release-asset names remain lowercase technical
> identifiers. The legacy npm package `deepseek-tui` is deprecated and
> receives no further releases. Users coming from v0.8.x legacy `deepseek` /
> `deepseek-tui` names should migrate with `docs/REBRAND.md`.

## Install

### Recommended — official GitHub release

New macOS/Linux install (checksummed binaries from this release):

```bash
curl -fsSL https://codewhale.net/install.sh | CODEWHALE_VERSION="v0.9.12" sh
"$HOME/.local/bin/codewhale" --version
```

For Windows, use the matching installer or archive below. For an existing
direct install, run `codewhale update`; it prints the executable path and
keeps newer builds. If the install directory is occupied by a different build,
use the fresh-directory migration in [the installation guide](https://github.com/Hmbown/CodeWhale/blob/main/docs/INSTALL.md).

### Secondary packaging — npm and Cargo

```bash
npm install -g codewhale
# or build from source
cargo install codewhale-cli --locked
```

The wrapper downloads the matched `codewhale` and `codew` command assets
from this Release. Both contain the same compiled runtime.

### Docker / GHCR

```bash
docker run --rm -it \
  -e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
  -v codewhale-home:/home/codewhale/.codewhale \
  ghcr.io/hmbown/codewhale:v0.9.12
```

The image exposes the same runtime as both `codewhale` and `codew`. The
`latest` tag is also updated on release.

### Cargo (Linux / macOS)

```bash
cargo install codewhale-cli --locked
```

The Cargo package installs `codewhale`. Cargo cannot create a second command
alias from one binary target; users who want the shorter spelling can add a
`codew` symlink to that installed executable. The npm, Homebrew, archive,
shell-installer, and container channels install both command names directly.

### Manual download — platform archives (recommended)

Each archive below contains the same runtime under the `codewhale` and
`codew` command names, plus an install script:

| Platform | Archive | Install script |
|---|---|---|
| Linux x64 | `codewhale-linux-x64.tar.gz` | `install.sh` |
| Linux ARM64 | `codewhale-linux-arm64.tar.gz` | `install.sh` |
| Android ARM64 (Termux) | `codewhale-android-arm64.tar.gz` | `install.sh` |
| macOS x64 | `codewhale-macos-x64.tar.gz` | `install.sh` |
| macOS ARM | `codewhale-macos-arm64.tar.gz` | `install.sh` |
| Windows x64 (installer) | `CodeWhaleSetup.exe` | NSIS setup |
| Windows x64 | `codewhale-windows-x64.zip` | `install.bat` |
| Windows x64 (portable) | `codewhale-windows-x64-portable.zip` | — |
| Windows ARM64 | `codewhale-windows-arm64.zip` | `install.bat` |
| Windows ARM64 (portable) | `codewhale-windows-arm64-portable.zip` | — |

**Unix (Linux / macOS):**
```bash
tar xzf codewhale-<platform>.tar.gz
cd codewhale-<platform>
./install.sh
```

**Windows:**
- For the installer path, run `CodeWhaleSetup.exe`; it installs
  `codewhale.exe`, `codew.exe`, and `codewhale.bat` under
  `%LOCALAPPDATA%\Programs\CodeWhale\bin`, adds that directory to the
  current-user PATH, and creates a Start Menu shortcut that prefers
  Windows Terminal (`wt.exe`) when it is installed.
- Extract the archive for your machine: `codewhale-windows-x64.zip` or
  `codewhale-windows-arm64.zip`
- Double-click `codewhale.bat` (not the raw `.exe`) to launch
- Run `install.bat` to copy the binaries and launcher to `%USERPROFILE%\bin`
- Add `%USERPROFILE%\bin` to your PATH

The **portable** Windows archive skips the install script — extract and run `codewhale.bat` from any directory. The NSIS installer is currently unsigned and may trigger Windows SmartScreen until a signing certificate is wired into the release pipeline.

Each platform also has **bare, unarchived** `codewhale-<platform>` and
`codew-<platform>` assets. The seven `codewhale-tui-<platform>` filenames
attached to v0.9.5 are byte-identical compatibility copies used only to let
already-installed v0.9.4 clients discover and cross this single-binary
transition; current installers do not expose a third runtime. The legacy npm
package `deepseek-tui` is deprecated and is not republished. For migration
from v0.8.x legacy binary names, see `docs/REBRAND.md`.

### Verify (recommended)

Download the checksum manifests from this Release and verify:

```bash
# Linux — archive bundles
sha256sum -c codewhale-bundles-sha256.txt --ignore-missing

# Linux — individual binaries
sha256sum -c codewhale-artifacts-sha256.txt --ignore-missing

# macOS
shasum -a 256 -c codewhale-bundles-sha256.txt --ignore-missing
shasum -a 256 -c codewhale-artifacts-sha256.txt --ignore-missing
```

## What's in v0.9.12

Codewhale v0.9.12 puts computer use in the binary, opens two new routes —
Alibaba Model Studio through the data-driven provider table and Concentrate
as an opt-in BYOK Responses gateway — and adds cloud dispatch plus a
config-gated per-session control socket. The shell is the other half of the
release: a new launch card, the work surface docked under the composer, one
focus owner for Tab, tool cells that carry their own state, and `fleet` as
the public word for the live collective. The complete item-level change
record is retained below the categorized release highlights.

### Added

- Computer use ships with the binary. The `computer-use` plugin — 38 tools
  across macOS, Windows, Linux and HarmonyOS, accessibility-first observation
  with pixel fallback, screenshots, zoom, screen recording, and registered
  remote computers over ssh and hdc — is embedded in Codewhale and written to
  `$CODEWHALE_HOME/builtin-plugins` on first run, so every install channel
  carries it. It lists as `builtin · not-reviewed` and stays disabled until
  you review and enable it: shipping it is not consenting to it. The
  stdlib-Python computer-use server it replaces is gone.
- Alibaba Model Studio joins the data-driven provider table as an
  `openai-compatible` descriptor: international compatible-mode endpoint,
  `DASHSCOPE_API_KEY` credential, live `/v1/models` discovery. Qwen 3.8
  Flash and Qwen 3.8 Max arrive through the catalog authority — never a
  hard-coded id.
- Concentrate: first-class opt-in BYOK Responses gateway with live models
  discovery and typed SSE streaming (#5725).
- Cloud dispatch: remote runner offloads coding agent tasks to isolated
  cloud sandboxes with machine token auth and structured job tracking
  (#5701, #5712).
- Per-session control socket: config-gated `[control_socket]` table binds
  `<sessions-dir>/<session-id>/control.sock` per running session, exposing
  message, interrupt, relaunch, and status JSON-RPC verbs (#5533, #5831).

### Changed

- **Anonymous usage counting is on by default.** The 0.9.11 release asked
  first; 0.9.12 counts the same aggregate version/platform, session, feature
  and error totals unless you turn it off, and says so once at first launch
  (policy notice version 5, schema 3, `notice_version` replacing
  `consent_version`). Every recorded opt-out stays off: a durable
  `telemetry = false`, a decline recorded under the old opt-in notice,
  unreadable privacy state, and the `CODEWHALE_TELEMETRY=0` / `--telemetry
  false` kill switches. Showing the disclosure records only that it was
  shown, never an acceptance. `codewhale config set telemetry false` turns
  it off and wipes queued counts; `codewhale config set telemetry true`
  deliberately re-enables it. Nothing new is collected: no conversations,
  code, prompts, files, names, model content, credentials, or IP.

- The launch screen is our own card take: a thin top line
  `⑂ branch  path`; a centred bordered card with the whale mark,
  `Codewhale` + version, one announcement line only when it is true (the
  no-model warning, or MCP news), and the menu New worktree / Resume
  session / Changelog / Quit with their real chords right-aligned. Enter
  runs the highlighted entry, Up/Down move it, and typing goes straight to
  the composer. The card dissolves on the first keystroke or command
  (≤240 ms, instant under reduced motion) (#5826, #5801, #5815, #5286).
- The work surface sits under the composer by default, keeping history
  readable and leaving the stage unencumbered (#5809).
- Skills command shapes: FEAT-022 command shapes and retained-host
  validation (#5825, #5829).
- After the card dissolves, the working screen shows `⑂ branch  path` with
  `⋮ MCP n/m` on the right, the transcript starts with the
  `◆ session_start` receipt (naming the configured session-start hooks),
  and the composer's bottom rule carries `model (effort) · permission` —
  the route's one launch reading. The posture bar and metrics line appear
  only once a session exists.
- Vocabulary: `fleet` is the public term and `Pod` is retired from copy —
  roster, setup, detail, worker-runtime and managed-API messages now say
  Fleet (`/fleet` canonical, `/pod` alias). The workflow wire accepts the
  canonical role spellings (general/explore/planner/reviewer/implement/
  test/advisor) with the pre-rename ones kept as load-time aliases, and
  serializes canonical names.
- The Operate mode-picker hint is shortened to fit 80 columns.

- The footer always shows the permission posture; when only one chip
  fits, the permission chip outranks the mode word (#5796).
- Local Ollama: the header names a model only when the local catalog can
  serve it, and says `unknown` until it knows. The startup mark, web and
  app icon carry the new side-view prompt-eye whale (#5795).
- One focus owner: Tab and Shift+Tab work regardless of what is in the
  composer; Alt shortcuts survive mid-draft; Ctrl+Tab no longer cycles the
  mode by accident (#5798).
- Tool cells carry their own state: a running, failed or warned tool
  reads as such in the transcript itself, with per-entry rail dots and
  family-coloured glyphs (#5799).
- Web: docs hub with task search, shared empty/loading/error states, an
  offline-to-back-online banner, `/changelog` in every locale, and real
  404s with correct metadata (#5743).
- Web: the app's colours come from one file generated from the TUI whale
  palette; re-typing a colour by hand fails web CI (#5797).
- Web: a one-way ceiling on `isZh` branching outside the i18n spine —
  the count may only go down (#5805).
- An internal agent handoff doc was removed from the public tree and
  `.playwright-mcp/` is now ignored (#5800).
- First run paints the composer immediately: the Welcome/language/provider/
  trust gates no longer precede the first keystroke. Missing-key and
  workspace-trust recovery stay for returning users; language and provider
  remain in `/setup`.
- The canonical whale-tile mark propagates beyond web to the exact-raster
  surfaces that can carry it (#5738).
- Dead-code sweep: delete proven-unreferenced helpers (unused builders,
  wrappers, and leftover identifiers) and drop stale `#[allow(dead_code)]`
  where the item is production-called or test-exercised. No runtime behavior
  change (#5791, #5587).
- Remote-control recovery gives every fresh pre-dispatch attempt a new lease
  generation while preserving that generation across its typed start (#5605).

- Public roster language is Pod. `/pod` is the customer surface; fleet remains
  the internal wire, storage, and migration name (#5776).

- Compaction replacement history keeps a bounded last user round (assistant +
  tool results) instead of dropping them behind a summary. `/context` names
  the compaction path and `/anchor` survival. Failed compact still does not
  replace live history (#4394).
- Provider catalogs: compatible hosts (Baseten, Groq, Cerebras, SenseNova,
  Command Code) no longer compile a frozen model roster. Descriptors name the
  wire, URL, and env; live `GET /v1/models` and a Codewhale-owned catalog
  layer are the offering list. Command Code is a catalog/descriptor row, not
  a `ProviderKind`. Catalog presence is not an availability, entitlement, or
  provider-acceptance claim (#5783).

- Provider selection no longer probes or adopts an external CLI credential on
  ordinary picker use. Reuse requires an explicit "Use external CLI credentials"
  choice, exact-path confirmation, and Codewhale-owned revoke (#5772).

- TUI: startup no longer presents an approximate ASCII or block-glyph whale as
  the product mark. It keeps the direct Tideline prompt while exact-raster
  surfaces remain responsible for the canonical asset.

- TUI: the active-session composer paints the same three-cell `[↑]` send
  target as Startup and clicks it through the existing Enter submit
  dispatcher (#5771). Compact/quiet composers still omit the control.

- TUI/CLI: Pod is the public roster surface. User-facing Fleet wording
  moves to Pod; durable receipt keys stay compatible (#5776).

### Added

- Native ChatGPT sign-in for the `openai-codex` route: `codewhale auth
  chatgpt` opens a browser PKCE flow and stores refreshable tokens in
  Codewhale-owned credentials — no Codex CLI install required.
  `/auth chatgpt-revoke` clears them off the event loop (#5784, #5778).
- MCP servers and plugins can be connected self-serve from the session: a
  unified auth flow with rotation-safe token handling, a spoken authorization
  URL, and catalog refresh when stored credentials stop working (#5747).
- `/operate` reads match the landed CWC `OperateRecord` contract: fetching an
  absent record returns a truthful not-found view instead of a fabricated
  operation, and an empty evidence path is rejected rather than resolving to
  the workspace directory (#5703).
- TUI: scheduled automations project into the top strip
  (`⏱ N scheduled · M running`, compact `⏱ N·M`) with typed
  `HistoryCell::Automation` receipts when a run this session watched settle.
  `/automation` acknowledges failures. The merged footer does not carry the
  work fact (#5748).
- The app-server can listen on a unix domain socket and advertise a
  `daemon/attach` handshake, so a local client can attach to an already-running
  engine instead of spawning its own. The socket is created with
  owner-only permissions and stale sockets are reclaimed on start. Non-unix
  hosts return a typed unsupported-platform refusal; the Windows named-pipe
  endpoint is named but not yet implemented (#5749).
- The engine's internal `Op`/`Event` types and the wire protocol's `Op`/
  `EventMsg` now carry a compile-enforced twin for every variant: adding an
  engine variant without a protocol counterpart fails the build instead of
  drifting silently. Internal durability work — no user-visible surface
  change yet (#5751).
- Machine tokens: with `CODEWHALE_API_KEY` set, the CLI authenticates as the
  Codewhale account with no local session file and no browser — the CI
  authentication path, with a typed token shape and redaction (#5721).
- Compaction publishes a structured survival contract for session-tree
  journal entry types (`crates/tui/src/compaction/SURVIVAL_CONTRACT.md`) and
  fails closed when the last user round, tool results, `/anchor` text, or
  checkpoint receipt would vanish (#4394, #5782).
- Internal: `codewhale-config` gains `RouteAuthoritySnapshot`, one immutable
  authority that owns a compiled provider catalog together with the route
  resolver projected from it, so a picker, a readiness view, and an execution
  path can no longer resolve against different catalog snapshots without a
  type-level signal. Resolution still goes through the sole resolver; the
  returned receipt distinguishes an exact catalog row, a custom-endpoint route
  whose provider facts are deliberately not reused, and an allowed
  pass-through route with no catalog row. All state is secret-free. No call
  site changed and no user-visible behaviour changed yet (#5766).

- Computer session records now count only time a provider actually accepted the
  session as active, at per-second granularity. Idle, queued, stopped, and
  teardown time are excluded, and a session whose allocation does not match a
  standard profile is refused rather than recorded approximately. Covered by
  hermetic fixtures; no live provider call and no deploy (#5781).

- Website: the public site moves to the Tideline deep-ocean design language
  (dark by default with an opt-in light documentation sheet, palette grounded
  in the TUI's WHALE_* tokens) and the new whale brand mark across the favicon,
  app icons, web manifest, nav wordmark, and social card (#5573).

- Add `codewhale dispatch` / `/dispatch` so a local session can propose a
  Codewhale cloud agent against an explicit `github`, `cnb`, or `gitee` remote.
  Confirmation is required; missing credentials fail closed; cloud jobs share
  the existing `/jobs` surface as `kind=cloud`. See
  [DAYTONA_CLOUD_DISPATCH.md](docs/DAYTONA_CLOUD_DISPATCH.md).
- `/login` reports the Codewhale account session and provider-key next
  steps. The internal cloud-agent credential is not user surface: there is
  no `auth set-slot`/`auth clear-slot` command, no hint, and no completion
  entry for it — signing in with `codewhale login` is the only door.
- Add the Tideline component family from the ratatui translation spec
  (#5698's screens, riding the #5699 work-strip layout): hero startup
  surface with quick actions and option strip, notifications inbox, merged
  footer band, pod ledger, receipt
  stream, theme list with motion toggles, live preview, settings rail,
  and the left rail — each a standalone render module pinned by 28 new
  byte-exact golden buffers. Frame wiring follows the Tideline acceptance
  gate; `NO_COLOR` is now honored by palette depth detection.
- Route Contract Phase 1: `RouteResolver` is the runtime path for
  `resolve_runtime_options`; `codewhale providers export --json` ships the
  owned descriptor catalog; CLI `--provider` accepts any catalog route id
  (the closed `ProviderArg` enum is deleted). Catalog layers are
  bundled → models.dev → provider `/v1/models` → config.toml → user, with
  policy DENY last and never overridden.
- Add provider-native web search for documented Xiaomi MiMo 2.5 Pro and 2.5
  chat routes while keeping neighboring models and custom gateways fail-closed.
- Add structured provider-native web search for exact Z.AI global and Zhipu
  China general API routes, using each site's documented search engine value.
  Existing `open.bigmodel.cn` configurations now share Z.AI's official model
  namespace and credential scope; unknown model IDs still pass through.
- Add provider-native web search for documented Qwen models on ModelStudio
  Token Plan's Responses Harness, without enabling Coding Plan or Anthropic
  routes.
- Added `/copy` to place the latest completed assistant response on the
  clipboard without copying tools, system messages, hidden reasoning, or
  active partial output (#5668).
- Add provider-native web search for documented DeepSeek V4 routes through the
  Responses API, with fail-closed capability gating for compatible custom
  endpoints.
- Add provider-native search for exact Moonshot K3 Formula, legacy K2.6
  built-in search, and Kimi Code membership `/search` routes. Treat the exact
  Moonshot China endpoint as a first-party direct route.
- Z.ai `GLM-5.3-Flash` and OpenRouter `z-ai/glm-5.3-flash` are first-class
  picker rows (`/model GLM-5.3-Flash`). Flash is the faster/explore sibling
  of `GLM-5.3`; the Z.ai default stays `GLM-5.3`. List price is $0.15/$0.50
  per 1M (durable; the 50% promo through 2026-09-09 is not the catalog row).
- Baseten, Groq, and Cerebras are bundled OpenAI-compatible setup templates
  (`[providers.<id>] kind = "openai-compatible"`), not new `ProviderKind`
  variants. `/provider` fills URL, model, and env from one catalog row.
- MCP manager copy now names the server, the failure, and one recovery
  command (`The X MCP server requires OAuth reauthentication. Run /mcp login X`).
- Settings Advanced exposes clickable MCP Connect, Reconnect, and Diagnose
  actions, while Extensions and Problems route recovery through the existing
  `/mcp login`, `/mcp reload`, `/mcp validate`, and `/plugin validate` commands
  (#5643, #5655).
- Plugin prompt matching (#5579): sending a task can toast the next review
  step when the prompt strongly matches an installed-but-idle plugin or a
  marketplace catalog you added (for example a Supabase prompt suggesting
  `/plugin trust supabase`). A live composer CTA offers the same review
  command while you type, matching turns append a bounded
  `<recommended_plugins>` user block, and `request_plugin_install` surfaces
  review without installing. `/plugin suggest` now ranks manifest keywords and
  catalog candidates, never auto-installs, and on-disk plugin changes also
  nudge `/plugin reload` between turns.


- Added `/import-claude` (#5557): reads `~/.claude.json` and
  `~/.claude/settings.json` read-only and renders an explicit, reviewable
  migration plan plus a written report. MCP servers route through the
  existing `/mcp import <name> --approve` consent flow, allowlisted env keys
  become an unapplied portable bundle for `codewhale config import`, and
  permissions/hooks map to manual follow-ups; secret-shaped values are named
  but never echoed or imported.
- Added the managed Chat relay: account-owned Chat commands now execute on the
  native runtime thread engine through a new `runtime_chat_relay` module
  instead of a second execution path. Each Chat thread is a dedicated,
  isolated runtime thread with an empty model-visible tool allowlist, a
  chat-only system prompt, and no workspace, memory, skill, credential, or
  local-path context; the active interactive TUI thread is never reused. The
  relay keeps one durable state file per scope behind a session-wide owner
  lock, binds a saved session permanently to its first remote target, replays
  exact duplicate commands from retained results instead of starting a second
  inference turn, terminalizes orphaned reservations on restart, and rejects
  (never queues into) a busy local Work turn with an immediate retryable
  result. Stop commands require the exact run and turn identity, and a worker
  aborts on any account or target mismatch during token refresh.

- Added a verified Omarchy/AUR packaging path: `packaging/aur` now carries a
  `PKGBUILD` template, `.SRCINFO` renderer and tests, release-candidate
  render step, and docs; the live AUR compatibility alias `codewhale-tui ->
  codewhale` is preserved, AUR dependencies match the live package, and the
  self-updater refuses to fight an Omarchy/package-manager installation.
- Added a Fleet run-wide cost/token usage ceiling (R6, #5567): an accumulator
  plus admission gate and alert bound a whole run's spend across workers.
- Added the real provider cache hit rate to `/context` (C3, DSH #3): the
  token-weighted provider-reported rate from the same telemetry `/cache`
  aggregates, plus an honest "no cache telemetry yet" state when nothing is
  recorded.
- Added per-step cost movement: `TurnUsage` receipts are priced as they land
  so the live cost surface moves during long agentic turns instead of only at
  `TurnComplete` (#5578), and the footer now honestly shows `cost: unknown`
  when nothing can be priced instead of hiding the line.
- Added the underwater session surface: the ambient water reads session state
  from across the room, its animation shape follows live agent activity, and
  attention tints are steady (no breathing) with a distinct reading treatment
  and no mid-water seam on tall windows.
- Added `@path:START-END` ranged line mentions (#5550, picker half to follow),
  a predictable last-copy backup file for clipboard exports with the path
  named when the clipboard fails (#5555), `wait` on multiple background shell
  tasks with `until=any|all` (#5549, named-kill half to follow), and composer
  double-click word / triple-click line selection.
- Added workflow parallel-`schema` slot partial success (#5583): a slot that
  produces a schema-valid partial result no longer fails the whole parallel
  branch.
- Added plugin load-failure startup hints (#5579) and OpenRouter app
  attribution headers on outbound requests.
- Added `codewhale doctor --fix` (with `--yes` for non-interactive consent):
  the doctor now computes a concrete repair plan — delete stale `.tmp*`
  leftovers from interrupted atomic writes, tighten secret-store file
  permissions to `0600`, disable structurally broken (Error-status) MCP
  entries through the atomic MCP save path, and scaffold missing user-global
  `skills`/`tools`/`plugins` directories — shows it, and applies it only after
  explicit consent. Every action is narrowly scoped and idempotent; JSON and
  context-JSON modes stay read-only and conflict with `--fix` (#5552, v1).
- Added `/context` reporting of the real provider prompt-cache hit rate (C3)
  alongside token pressure.

### Changed

- Provider-native web search now applies domain constraints before accepting an
  attempt, discards generated answers when returned citations violate those
  constraints, and preserves the caller's configured/local timeout as an
  independent fallback budget (#5681).
- Idle session metrics omit zero facts (`0 turns`, `LLM 0s`) until the
  runtime has evidence. Working chrome says `in the current` instead of a
  generic `working`.
- Deleted nine uncompiled `runtime_contract/` staging files. Live contracts
  remain `model.rs` and `termination.rs`.

- The first #5587 dead-code sweep converts audited test-only helpers to
  `#[cfg(test)]`, keeping production builds free of test-only APIs without
  changing runtime behavior.
- `/plugin reload` is now discoverable when on-disk plugin bundles change: the
  next send and `/plugin list` nudge once with `Run /plugin reload to apply`
  instead of silently keeping the stale catalog (#5579). Trust is unchanged;
  this does not auto-reload.
- Context-pressure warnings and critical alerts now remain visible in sticky UI
  status until compaction or explicit dismissal, instead of disappearing into
  scrolling turn metadata (#5620).
- The Runtime thread store defaults to a per-session root
  (`$CODEWHALE_HOME/sessions/<id>/runtime`) so multiple Codewhale processes on
  one machine no longer share one owner lock (#5630). The exclusive lock is
  unchanged; `CODEWHALE_RUNTIME_DIR` still selects a shared root when that is
  intended.
- Session token totals now include display-only per-model-call deltas while a
  turn is running, including input/output and cache-class counters; the
  authoritative `TurnComplete` totals still reconcile exactly once (#5581).
- Transcript focus now exposes per-block actions: `y` copies content, `Y`
  copies the rendered metadata view, Enter opens a fullscreen block pager, and
  `r` opens raw detail; the existing Tasks rail shortcuts remain unchanged
  (#5551).
- Provider neutrality (#5588): model resolution of omitted/aliased models is
  now provider-relative, OpenAI-native defaults no longer route through
  another provider's table, CLI credentials stay provider-scoped, and NVIDIA
  credentials no longer leak into the DeepSeek keychain. Neutrality test
  matrices exercise several providers instead of standing in with one.
- The workflow engine module was decomposed out of its 3k-line mega-file into
  `journal`, `usage`, and `report` modules plus a module directory (#5586
  slices 1a/B/C/D), a semantic-free move verified by normalized-content hash.
- Compaction refusals are now always named (#5577): silent holds under context
  pressure are gone, the context meter honors the same provider-billed prompt
  the trigger uses (T1), and prune outcomes are projected without cloning the
  transcript.
- Step budgets now end honestly: an ~80% soft landing nudges the model to
  write its final report, and exhaustion grants exactly one bounded
  report-on-exhaustion turn instead of dying silently (A1/A2).
- Contributor credit: recognized agent contributors (e.g. `Codewhale Agent`)
  may now carry `Co-authored-by` trailers; unknown bot/tool trailers are
  still rejected by the credit gate.

### Fixed

- Fast typing no longer corrupts the composer. The paste-burst heuristic ran
  on every session until a real bracketed paste arrived, holding, buffering,
  retro-grabbing, and absorbing Enter on timing guesses; it is now
  fallback-only (gated off when the terminal provides bracketed paste), the
  retro-grab is deleted, and Enter on held command text flushes and submits.
- Ctrl+C works on the pre-session launch menu and speaks everywhere: the
  first press arms the two-second exit window with a visible localized
  "Press Ctrl+C again to quit" hint (previously silent), the second exits.
  The worktree name input keeps Ctrl+C as cancel-input.
- Fresh interactive sessions no longer leave a phantom one-message duplicate
  behind. The TUI claimed one session id (Runtime store lock, turn-start crash
  checkpoint) while the engine minted a second one; the first `SessionUpdated`
  re-keyed the App, the completion commit cleared only the engine id's
  checkpoint, and `codewhale --continue` later "recovered" the orphaned
  checkpoint as a duplicate session instead of the real one. The engine now
  adopts the host-owned id at spawn (`EngineConfig::session_id`) and `/clear`
  mints the next id in the App like `/new`. A non-TTY `--continue` no longer
  promotes and consumes the crash checkpoint before failing the terminal
  check, and the root `codewhale --resume <id>` / `--session-id <id>` flags
  documented in the operations runbook now parse instead of being swallowed
  as a prompt.
- Website: `/signin`, `/signup`, and `/auth/callback` are locale-aware public
  routes instead of localized 404s. Sign-in and create-account send the person
  to the CWC app; OAuth callbacks hop to `app.codewhale.net` with the query
  intact; `/login` and `/register` are aliases. Local CLI use is not presented
  as requiring an account (#5767).
- The sandbox read deny-list matches a rule's resolved path as well as its
  literal spelling. On macOS `/etc` and `/var` are symlinks into `/private`,
  so a read of `/private/etc/sudoers` walked around the `/etc/sudoers` rule,
  and a rule written against a symlinked directory never fired for the real
  path that `canonicalize` and the process cwd hand back.
- Background shells are first-class work-strip rows (`▾ Shells N`) you can
  open, watch, and cancel by the `shell_*` id on the row. `/jobs cancel all`
  cancels running shells; it no longer looks up a task named `all`. The
  composer hourglass crumb no longer stands in for a shell surface.
- `codewhale logout` and `/logout` now clear the Codewhale account session
  and the Daytona secret slot, not only provider API keys. The TUI crate's
  leftover `login --api-key` path no longer claims to save a key.
- Account sessions no longer read the macOS Keychain. Unsigned or rebuilt
  `codewhale` binaries were a new Keychain ACL principal every time, so
  `codewhale web` and the TUI popped a password dialog on start. Sessions
  now use `~/.codewhale/secrets/secrets.json` (mode 0600), the same store
  as provider keys. Extracted from the Keychain-retirement half of #5632.
- Hardened the dispatcher-side config parse the same way: `ConfigStore`
  loads and project-config parsing now deserialize `ConfigToml` on a
  dedicated 16 MiB-stack thread (the guided-setup save path could overflow
  a 2 MiB worker stack the same way the TUI's `ConfigFile` parse did), and
  the #5585 setup-confirm toast test runs its runtime on an equally sized
  thread instead of overflowing the default libtest stack.
- Fixed detached interactive agents reporting worker usage after the parent
  turn ends with the usage missing from the session/live `/cost` total
  (#5597): interactive turns acquire an owner-scoped runtime usage lease,
  late usage enters the session cost pool without reopening the sealed
  mailbox, and worker/session/reload accounting share one hashed response
  identity so retried deliveries stay exactly-once.
- Fixed the sub-agent fiasco class: in-workspace absolute `git -C` no longer
  trips the read-only child shell gate with a coherent bounded gate (#5595),
  turn end parks turn-owned children resumably instead of silently cancelling
  them (#5596), stale write-claims are released by liveness with coordinate
  release (#5562), and the verifier role description matches its real
  surface (#5562).
- Fixed workflow responseSchema failure handling (#5583): bounded repair with
  typed receipts (kind + attempt), raw-output receipts persisted as artifacts
  that survive reload, and failures surfaced instead of null success (#5528).
  Degraded owner snapshots no longer project as ordinary Completed runs
  (#5582), typed task error kinds enable fail-fast parallel/pipeline (R9), and
  `/workflow confirm` finds the draft despite interleaved messages.
- Fixed the DeepSeek session that never auto-compacted at 842k/1M (#5577): the
  exact `billed_842k_on_a_1m_window_compacts_despite_a_small_estimate`
  regression pins the trigger.
- Fixed sandbox escapes and authority gaps: workspace-write tools resolve
  hard-linked files before writing (S2, #5569), an opt-in read deny-list
  bounds full-disk reads in any posture (S1, #5568), and session grants match
  the command family instead of widening the whole tool (R2).
- Fixed provider-transport robustness: non-streaming HTTP requests are bounded
  by a read timeout (R4), and Chat-Completions mid-stream error frames surface
  instead of hanging (R3). MCP OAuth expiry now reacts to 401/403 with a named
  recovery path and login hint instead of looking like a broken server (T4,
  #5572).
- Fixed Fleet lifecycle gaps: detached workers are reaped when their manager
  dies (R7) and the per-task wall-clock timeout is enforced (R5); the local
  Fleet host compiles on non-Unix targets; detached schema repair stays within
  the runtime budget.
- Fixed prompt-cache correctness: the tool catalog is fingerprinted in
  provider wire order (C1), prefix changes between requests are always
  declared (C5) — including the newly named mid-turn `change:tool_surface`
  reasons for deferred-tool admission, tool-search activation, and runtime MCP
  tool arrival — and a reasoning-only response stopped at the output limit now
  fails the turn honestly instead of re-issuing a request that can only
  reproduce the stop.
- Fixed docs/public-surface drift: REBRAND.md no longer presents
  `api.deepseeki.com` as a China fallback (#5564), and the web facts/tool
  counts match the repository.

- Heavy pull requests now run the real Linux workspace nextest, doctest, and
  lockfile lanes directly on GitHub Actions instead of reporting a green
  placeholder while waiting for a branch-specific CNB mirror (#5547).
- Fleet roster members in a selected Fleet now expose a visible edit affordance
  and a direct `m` model-picker shortcut, while the coordinator row remains
  read-only (#5604, covers #5589).
- The context inspector now attributes bounded tool-schema cost to the built-in
  catalog and each discovered MCP server without changing prompt assembly or
  cache behavior (#5553).
- The goal-continuation quiet period (`[goal] continuation_delay_seconds`,
  added in #5508) now applies on every dispatch path. Previously the
  within-turn dispatch hook fired the next continuation prompt immediately
  whenever a model step ended with the goal still active, so CLI-resumed and
  host-managed sessions never observed the configured delay (measured
  end-to-start gaps of ~9 s with a 300 s delay configured). The wait now
  runs unconditionally inside `goal_continuation_message_if_needed`,
  remains cancellable, and pause/clear/terminal `update_goal` calls still
  cancel a pending pass (#5534).
- Two unit tests no longer depend on process-global environment state that
  sibling tests mutate concurrently.
  `route_budget::tests::v4_trigger_uses_window_percent_when_it_fits_spendable_input`
  asserted no-override output-budget values while reading
  `CODEWHALE_MAX_OUTPUT_TOKENS` / `DEEPSEEK_MAX_OUTPUT_TOKENS` without
  holding `lock_test_env()`, so a concurrent writer could flip the value
  mid-assertion (the order-dependent full-suite flake).
  `prompts::tests::system_prompt_prefix_never_leaks_private_content` read the
  real home via `HOME`/`USERPROFILE`, so a machine with
  `~/.codewhale/instructions.md` leaked its absolute path into the prompt and
  failed the no-private-paths assertion unless a sibling's temporary `HOME`
  guard happened to be live. Both tests now hold the env barrier and pin the
  variables (the route-budget test removes the overrides; the prompts test
  points `HOME`/`USERPROFILE` at a scratch dir). Assertions unchanged.

- TUI sessions now apply a subtle OSC 12 cursor accent only on explicitly
  supported terminals and restore the terminal default through normal, panic,
  and signal cleanup paths (#5554).

## Contributors

- **hexin ([@h3c-hexin](https://github.com/h3c-hexin))** — provider-native web
  search across four routes (#5682, #5683, #5685, #5687), authoritative
  edit-last-turn boundaries (#5621), Kimi Code k3-256k (#5622),
  post-compaction input-token reporting (#5623), and preserving the scheduled
  model selection in automations (#5650).
- **秋月凉梦 ([@qiuYliangM](https://github.com/qiuYliangM))** — co-authored the
  edit-last-turn boundary fix (#5621), Kimi Code k3-256k support (#5622), and
  post-compaction input-token reporting (#5623).
- **Isabel Wu ([@wuisabel-gif](https://github.com/wuisabel-gif))** — live
  session token totals (#5624), persisted context-pressure warnings (#5629),
  discoverable Fleet roster editing (#5604), the capability-gated cursor
  accent (#5599), and `/copy` for the latest completed response (#5692).
- **Paulo Aboim Pinto ([@aboimpinto](https://github.com/aboimpinto))** —
  Windows verbatim-path operands preserved through POSIX word splitting
  (#5610), the plugins group moved onto the command shapes (#5657), FEAT-022
  skills command shapes with retained-host validation (#5825), and FEAT-020
  plugin command shapes re-landed on main (#5865).
- **Alex Musichen ([@musichen](https://github.com/musichen))** — a stable
  DeepSeek heading in the configured-view model picker, keeping every official
  catalog model for the active provider visible (#5689).
- **[@gaord](https://github.com/gaord)** — the `GET /v1/fleet/profiles`
  runtime API endpoint, reusing the FleetManager validation path (#5688).
- **Sh1Zuku ([@SparkofSpike](https://github.com/SparkofSpike))** — corrected
  English documentation inaccuracies and the first zh_hans translations for
  the Tier-2 docs (#5613).
- **[@M-Maciej](https://github.com/M-Maciej)** — goal continuation cadence
  (#5591) and the per-session control socket (#5533, #5831).
- **Serephus ([@serephus](https://github.com/serephus))** — nixpkgs update
  (#5669).
- **[@whp233](https://github.com/whp233)** — `wire = responses|anthropic` for
  openai-compatible custom routes and opencode-zen muse-spark (#5716, landed
  as #5719).
- **Gabriel Degret ([@Gabriel-Degret](https://github.com/Gabriel-Degret))** —
  found the reasoning-only retry gap and built the first fix; landed as the
  `[reasoning_only]` retry ceiling with a request-scoped nudge (#5867).
- **[@huangxianzhan](https://github.com/huangxianzhan)** — the
  `x-opencode-session` header for OpenCode Go and Zen gateways (#5868).
- **[@zhuowp](https://github.com/zhuowp)** — task origin preserved in job
  snapshots (#5869).
- **AdityaG ([@AdityaVG13](https://github.com/AdityaVG13))** — a ten-commit
  performance pass: a zero-copy LaTeX fast path for streaming render,
  single-pass token accounting on the per-turn pressure paths, memoized
  provider resolution in the catalog cutline, parsing the bundled and
  on-disk models.dev catalogs once per process (interactive boot -70%),
  adaptive poll cadence for foreground shell completion, and worker caps
  across the read-only diagnostic family.
- **Nightt ([@nightt5879](https://github.com/nightt5879))** — isolated remote
  recovery lease generations (#5790).
- **[@yiheng-kkk](https://github.com/yiheng-kkk)** — replaced stale todo
  transcript snapshots so a rewritten todo list renders its current tasks
  (#5871, #5873).
- **[@Lfanxing](https://github.com/Lfanxing)** — Moonshot routes now degrade
  incompatible tool definitions per request instead of failing the turn.
- **WissssleyL ([@Lstarsky0](https://github.com/Lstarsky0))** — moved
  `docs/subagents` and `docs/mcp` onto the dictionary spine (#5337), with the
  metaTitle probe that keeps them there.

Reports and reproductions that shaped this release:

- **[@slowly247](https://github.com/slowly247)** — reported the Ollama input
  budget collapsing to 1,024 tokens on 32K local models (#5820).
- **[@ronohara](https://github.com/ronohara)** — reported the engine stopping
  after recoverable network errors, with the reproduction that pinned the
  discarded approval (#5769).
- **[@Lujc0523](https://github.com/Lujc0523)** — asked for ACP session
  configuration of mode and model (#5863).
- **[@senka9h](https://github.com/senka9h)** — reported that `serve --acp`
  lacked `session/list` and `session/load` (#5864).

See [CHANGELOG.md](https://github.com/Hmbown/CodeWhale/blob/main/CHANGELOG.md) for full notes and [docs/CHANGELOG_ARCHIVE.md](https://github.com/Hmbown/CodeWhale/blob/main/docs/CHANGELOG_ARCHIVE.md) for older releases.