Codewhale v0.9.13 (Formerly DeepSeek TUI) 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.13" 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.
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.13
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:
- 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-.tar.gz
cd codewhale-
./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- and
codew- assets. The seven codewhale-tui- 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.13
Codewhale v0.9.13 addresses integrity issues in 0.9.12:
multiline paste is one paste again, truncated tool arguments can no longer execute, strict
ACP clients connect again, concurrent instances stop destroying each
other's queued text, and the Computer Use bundle includes plugin 0.3.1
with an accessibility-first pointer that no longer steals focus. DeepSeek V4.1 Flash
(deepseek-flash) is the default DeepSeek model, reasoning-capable routes
keep reasoning out of the answer even when a model id carries no version
number, and /mcp reload no longer freezes the interface while servers
reconnect. The Codewhale pet arrives with /pet: a full-screen habitat that
shows what the Engine is doing and reveals the answer when it is done.
Added
/pet turns the terminal over to the Codewhale pet. /pet on (or bare
/pet) gives the habitat the whole content viewport now and on every
accepted turn, reveals the actual answer or error when the turn completes,
and Escape returns to the composer without cancelling anything. /pet off
closes the view and stops automatic entry while the durable companion keeps
the pet alive; /pet appearance|window|source|sound|export|status address
the shared companion. The pet no longer lives in the workbar: the Watch
panel and /workbar watch … are gone (#6109, #6110).
- Codewhale Computer Use 0.3.1 ships as its own notarized Mac app. Download
the disk image from codewhale.net/computer-use
or the v0.3.1 release
(Codewhale-Computer-Use-0.3.1-macos-universal.dmg, drag into
Applications; the ZIP stays for the in-app updater). The bundled plugin and
the first-party marketplace pin the same 0.3.1 sources, so the app, the
computer-use plugin and /mcp see one implementation.
Fixed
- The website's Computer Use download page resolves its state without the
GitHub API (using GITHUB_TOKEN only when bound), and every page regenerates
on the Worker again: the Open Graph image route read brand SVGs at import
time, which the Workers runtime cannot do, so codewhale.net had been serving
its build-time snapshot.
- Operate can run structured workflows directly, with named phases, model
assignments from Fleet, prerequisite results and shared budgets. Independent
steps run together; dependent work waits for its required results and gates.
Detached runs return their outcome to the owning conversation, and headless
sessions stay alive between phases until the final handback is consumed.
- Computer Use 0.3.1: mouse actions no longer steal focus or reclaim the
foreground when the user switches apps mid-action; background typing,
scrolling and selection use semantic input, and screenshots stay scoped to
the targeted app. The bundled plugin and the first-party marketplace pin
carry the same 0.3.1 sources. A registered macOS helper stays in charge of
input through its Pause and Stop controls; an unavailable registered helper
produces an error instead of silently bypassing those controls.
- The Fleet editor uses the standard model picker to manage sub-agent model
and thinking assignments. Enter edits the selected row without changing the
running session's model. Unconfigured providers are refused, failed saves
retain the previous assignment, and a changed or removed team file must be
reopened before a pick can overwrite it.
- The provider catalog includes Baseten and the other compatible-provider
templates as selectable rows, opening their existing prefilled setup forms.
DeepSeek routes with clock-based pricing show the current peak or off-peak
tier beside session cost, with translated labels.
- Extensions, teams, workflows and automations support mouse-wheel scrolling.
Plugin and MCP rows have keyboard enable/disable controls and two-step
removal; MCP OAuth can retry with narrower scopes after a scope rejection.
- Healthy sub-agents continue after an ordinary parent reply. Headless runs
keep the existing Engine alive for child results within the run deadline.
Explicit cancellation remains authoritative when result queues are full or
a completion starts a followup turn.
- Sub-agent followup supports multiple targets and all parked children, keeps
old IDs connected to their current continuation, and saves continuation
identity before starting work. Repeated followup does not fork duplicates.
- Sub-agents validate declared output files and distinguish real edit claims
from file citations and unrelated workspace changes. Disjoint file claims
can run together; overlapping writers receive the actual conflict and remedies.
Explicit read-only shell analysis requires an enforcing native sandbox and
refuses execution when that protection is unavailable.
- Delegation depth stays absolute through saved profiles, nested workers and
continuations. Per-call token, step and time limits narrow inherited limits;
continuation retains ancestor usage and deadlines. Workers reserve room for
one tools-disabled partial report inside those limits, then run the declared-
output checks. Missing usage or unavailable reporting room produces an
explicit fallback; partial work is never marked complete.
- Agent rosters and detail pages have bounded output, visible continuation and
descendant relationships, and usable handles for full diagnostic evidence.
Completion receipts include measured worker and descendant token usage,
count each continuation once, and distinguish unreported usage from zero.
- Localization and native helper builds resolve the active checkout when the
build script runs, so a shared Cargo target keeps working after a worktree
moves or is removed.
- Selecting a saved agent profile that is malformed, unreadable or duplicated
now fails before any child request, including when its name matches a
built-in role; the parent's default route is never substituted silently.
agent(action: "roster") lists affected profile identities and paths, Fleet
run creation performs the same check, and docs/SUBAGENTS.md documents the
valid personal profile format with [permissions] (#6117, thanks
@Gabriel-Degret).
- Interactive startup no longer mistakes worker scheduling delays for an
unresponsive terminal. Terminal ownership checks and shutdown cleanup remain
enforced (#5929).
- Interrupted conversations whose saved runtime store is missing recover into a
fresh scope without restoring old tasks or approvals. Stale session saves
cannot resurrect the broken binding (#6102).
- Permission checks distinguish literal heredoc data from executable commands,
including substitutions and shell stdin (#6098).
- Automatic compaction runs quietly from live context pressure, preserving the
current task and recent tool exchanges while keeping the system/tool prefix
stable. Original history and the handoff are saved before context replacement;
failed or canceled compaction retains the conversation (#5620, #6047).
- Custom and gateway providers can override context limits for each exact model,
so switching models also switches the meter and compaction budget (#6108).
- Plugin suggestions explain their matching term and remember explicit dismissals
across restarts. Generic words and repository-host domains no longer trigger
unrelated installation prompts (#6031).
- Plugin trust and automation deletion have keyboard and mouse confirmation
controls bound to the exact reviewed content; users can still copy the command
and changed content requires a fresh review (#6039).
- The model-facing MCP start tool can reconnect an existing configured name after
login without changing its credential key or restarting healthy siblings (#6030).
A decreasing token-expiry countdown no longer makes a revoked credential look
like a new login from another session.
- Gemini setup uses the official endpoint's supported reasoning-effort field,
avoiding the rejected top-level Google thinking object. Gemini 2.5 and 3 keep
their supported effort ranges; signed tool history still survives reasoning
changes and restart (#6018, thanks @vmakarov-uk).
- Missed automation occurrences coalesce without overlapping a running job;
restart reconciles durable receipts without replaying accepted work. Damaged
neighboring records are isolated while preserving their original bytes.
- The bundled first-party marketplace lists the actual plugin bundles and uses
the existing install, review, trust and update paths. A read-only connection
check verifies catalog and skill mirrors on changes and weekly. Already present
bundles lead to their local review and management controls; catalog installs
refuse name collisions before downloading, without overwriting or granting trust.
- Windows deny checks preserve native path separators while retaining the
conservative POSIX scan for shell wrappers and substitutions.
- The config example agrees with the telemetry disclosure: usage analytics are
optional and enabled by default; local diagnostics do not require telemetry (#6011).
- Sub-agents enforce the session's typed shell and file deny rules, including
Full Access, delegated edits, and policy updates after a child starts (#6097).
- Live permission edits reach running engine clones atomically. Deny rules
support token wildcards and Windows command spellings while keeping POSIX
arguments literal (#6054, thanks @h3c-hexin and @asto18089).
- Tool-result images use the existing typed inline path and are fully decoded
under size and allocation limits before admission or provider projection.
Invalid images keep a visible omission receipt alongside the text result
(adapted from #6053, thanks @h3c-hexin and @asto18089).
- A lone
y, Y, or r remains composer input after selecting transcript
text. Clicking the composer releases transcript and dock focus.
- The Agents register updates from live worker events while the parent is
busy, including when the register opened before the workers spawned.
- Ghostty no longer shows a second graphical whale over the launch mark.
The selected model stays visible before the first message; unused session
metrics stay quiet. Scheduled counts open /automation directly.
- Marketplace installation accepts compatible Claude plugin bundles and roots
their relative sources outside .claude-plugin; unsupported components fail
explicitly. Native trust and enablement review still applies.
- Config table and nested reads work consistently and redact credentials.
Unsupported dotted writes fail without changing the file, and config doctor
no longer labels runtime settings as never applied (#6083).
- Esc during a worker fanout keeps the parent stopped when cancelled workers
finish. Their receipts remain available for the next explicit user turn.
- Undo preserves messages even when older state lacks a timestamp. Session
journal entries retain their append-time stamps when saved again.
- Extension actions refresh in place, and inspection output uses the text
pager. The empty launch shell hides unused metrics and keeps recovery hints
readable when several MCP servers need attention.
- The large-output router defaults to bounded spillover; adaptive routing
remains opt-in through CODEWHALE_ADAPTIVE_OUTPUT_ROUTING=1.
- Direct composer paste (
Ctrl-V) preserves rich clipboard headings, lists,
links, tables and code as Markdown, with plain-text fallback. Whole-answer
copy preserves authored Markdown without terminal wrapping; settings fields
still paste literal text.
- The embedded Computer Use bundle includes the marketplace's JPEG capture
and bounded-payload fixes, so new built-in installations receive them too.
- A provider's missing-
thought_signature HTTP 400 now explains how to recover:
use the built-in Google provider and start a new session, or verify the
gateway's signature handling. Working gateways are not blocked by a broader
preflight check (#6048, #6081, thanks @nightt5879).
- Chinese documentation links resolve to the contributor guide and Windows
screenshots from their translated paths (#6080, thanks @c020627).
- GLM-5.3 reasoning controls follow the forced-thinking contract on Z.ai and
BigModel routes, including low effort when a prior configuration requested
thinking off (#6051, thanks @h3c-hexin and @asto18089).
- Finance calls respect the session network policy, and model-facing shell,
verifier, notification and Fleet guidance matches executable contracts
(#6052, thanks @h3c-hexin and @asto18089).
- The sandbox-elevation prompt shows every option,
Abort included. The card
was a fixed 22 rows centred on the frame; inside its border and padding that
left at most 18 usable rows against 20 to 23 rows of content, with no scroll
rail and no truncation hint. The safe exit — the one choice that grants
nothing — was painted past the bottom edge at every terminal size. The card
is measured from its content now and reserves the option rows before the
denial detail, which is what shortens; below roughly 60x24 the per-option
descriptions shed and every choice keeps its row. Option hitboxes were also
counted in unwrapped source lines, so a description that wrapped put every
hitbox below it out of step and a click committed a different choice than the
one under the pointer.
d in the Hotbar setup modal asks before it clears every slot. It persisted
hotbar = [] on the first keystroke, in a view that takes bare letters as its
filter — the destructive key and the search key were the same press. It arms a
confirmation that owns every key until answered, and the prompt takes the
intro's place in the header so it cannot be the line that falls off a
five-row budget.
- Failure red means failure again. The metrics line painted the context reading
in the error colour from 80 %, while the posture bar one row above called the
identical threshold Attention; the workflow panel painted a Waiting row like
a crashed one, though its own is_running counts Waiting as healthy; and the
work surface spent error_fg on to-dos that were merely waiting, blocked or
stale, and on the routine approach to auto-compaction. WorkTone has a real
Failure variant now, and a guard test holds the reservation across every
selectable theme rather than the default alone.
- The command palette runs the row you highlighted.
refilter clamped the
selection index but never re-anchored it, and every keystroke re-sorts the
list, so refining a query could move the highlight to an unrelated entry that
Enter then ran. Long labels also overran their column and pushed the
description off the card, because the padding never truncated and the capacity
was measured against the popup rather than the content area.
- The work surface's first
Down reaches the first row. Nothing is selected
when the dock opens, and that resolved to "row 0 is selected", so the first
press moved to row 1 and row 0 could not be reached by pressing Down at all.
- Auto-compact could not fire mid-turn. The gate read `max(last billed
prompt, /4 estimate of the whole list)`, so as soon as the estimator
undercounted the full list below the last bill, every tool result appended
after that prompt was invisible to it, and a long turn could exhaust the
context window with nothing compacted. It now reads live tokens — the
billed prompt plus the growth since it, watermarked when the parent usage
is recorded — and is still evaluated at the pre-request boundary after
tools complete, never mid-tool-call.
- Esc or Ctrl+C during a compaction that is serving an in-flight turn now
stops the turn. It previously cancelled only the compaction pass, so the
turn resumed against the context that had just failed to shrink. A manual
/compact with no request in flight still cancels only the pass.
- The
request_user_input dialog is a bottom-anchored sheet instead of a
centered 22-row overlay. It leaves the transcript visible above it, grows
with its content, and scrolls internally so the highlighted option and the
custom response being typed stay on screen at 141x38 and 80x24. Left arrow
or h goes back to the previous question; Esc still cancels the whole
request. PageUp/PageDown, Home/End and modified arrows now review the
transcript while the sheet stays open; the mouse wheel scrolls the surface
under the pointer. Wheel browsing preserves the answer, and option navigation
or typing restores the focused content to view. The transcript viewport ends
above question and approval prompts, so End keeps the newest rows visible.
Documented in GUIDE.md and KEYBINDINGS.md (#6045).
/mcp reload no longer freezes the interface. The reload was awaiting the
whole reconnect batch on the TUI event loop; it now joins the same
supervised background pass the session boot uses, the status chip counts
the batch down live, and the finished receipt arrives as an event. With
23 configured servers (11 live, 10 awaiting auth, 2 failing) the first
echoed keystroke after a reload lands in ~5 s instead of ~42 s (#5974).
- The posture bar no longer states the same duration twice on a first turn
(#6041).
- Reasoning-capable models whose id carries no version substring
(deepseek-flash) keep reasoning_content in the thinking block instead
of the answer text. The gate only ever matched the literal deepseek-v4
version string, so it now consults the model catalog as well; the older
literal arms remain for the V4 aliases they were written for (#6044).
codewhale model resolve accepts a provider's declared default even when
its registry row is missing — deepseek-flash failed resolution against
the provider that declares it as default — and a test now resolves every
provider's DEFAULT_*_MODEL for its own provider (#6043).
- A configured
default_text_model is honored when a new thread's route is
resolved. That path consulted only the provider's catalog default, so a
config naming one model silently created threads on another, and the
unset default disagreed with the shipped one; the active provider's
configured default now wins, matching provider_default_model, and both
unset defaults name deepseek-flash (#6043).
- Markdown
_italic_ requires both delimiters to be flanking per CommonMark,
so math subscripts no longer italicize the prose between them
([t_, b_p]. Actually — hold on, do we even tile all the way from t_?
rendered 60 characters italic) (#6042).
- An MCP server configured for OAuth that answers 401 before its first login
now points at /mcp login in the failure hint instead of a bearer
token that does not exist (#6030).
- Cancelling a foreground shell wait stops its owned process group even when
the tool future is dropped. Explicitly backgrounded jobs retain their
ownership. Interrupted tool receipts distinguish work that started from
calls skipped before execution, and returned tool failures remain errors in
the next model request.
- Saved Fleet model identifiers retain exact spelling through selection,
role pins, and roster changes, so changing one saved model does not modify
another identifier that differs only in letter case.
- Chat wrapping reserves its scrollbar gutter consistently, keeping long
identifiers readable when the viewport changes.
- The Engine keeps large send-message futures off the event loop's stack,
preventing stack exhaustion when a restored session starts a provider turn.
- New, imported, and live session titles skip runtime handoffs and use the
first real user prompt. Explicitly renamed titles retain priority
(#6012, thanks @SparkofSpike).
- UI dispatch acceptance now precedes Engine execution, so a delayed acceptance
callback cannot overwrite a turn that has already started or completed.
Cancelling before acceptance preserves the prompt and leaves the next
dispatch usable.
- Bottom-chrome effort is omitted when the route cannot prove an effective
tier; /status retains the full explanation. Cost remains visible when
known, and cost: unknown remains on metered routes lacking a reading (#5950).
- Pasting multiline text is one paste again. 0.9.12 gated the
paste-burst heuristic off whenever bracketed paste was requested, but
a terminal can accept EnableBracketedPaste and still deliver a paste
as individual keystrokes — on those terminals (observed on Windows 11)
every pasted line was submitted as its own message. The heuristic is
again armed whenever tui.paste_burst_detection is on, and the
existing bracketed_paste_seen guard still disarms it for the rest of
the session once a real Event::Paste arrives, so fast typing on
terminals with working bracketed paste is unaffected (#5981, thanks
@nsfoxer).
serve --acp no longer breaks strict JetBrains clients: the
initialize response advertised sessionCapabilities.list as a
boolean and carried an undefined nested load capability; it now
sends {"list": {}} with no load key, per the ACP schema (#5969,
reported by @Lujc0523).
- Concurrent Codewhale instances no longer destroy each other's queued,
unsent text. The offline input queue was one global file that boot
cleared on session-id mismatch, so a second instance deleted the
first's parked messages. Queues are now keyed per session (mirroring
per-session checkpoints), an existing global file is adopted by its
owning session rather than discarded, and the adoption race between
two instances of the same session tolerates the loser's cleanup.
- A tool call truncated at the provider's output limit can no longer be
repaired into valid JSON and executed: repairs that had to synthesize
structure (append or discard closers) are routed to the existing
malformed-arguments path so the model is asked to re-issue — including
when the stream is cut before the closing content-block event (#5986).
codewhale metrics reads Codewhale's own receipts again: the
deepseek-home fallback resolved $HOME/.deepseek unconditionally, so
the rollup reported all zeros from a directory nothing has written
since 2024. The Codewhale audit log is primary, with a checked legacy
fallback.
- The goal-continuation loop's promised stall bound actually bounds
stalls now, and undeclared fleet role names fail closed to read-only
explore in both fleet drivers instead of resolving to write-capable
customs in one and not the other.
allow_insecure_http = true under a [providers.] table works
again. 0.9.12 tightened plain-HTTP base URL handling in a way that
silently dropped the per-provider key, leaving the process-wide env
var as the only opt-in — LAN llama.cpp and internal-gateway users
had to export CODEWHALE_ALLOW_INSECURE_HTTP=1 to connect at all.
The key is honored again (parsed, settable and unsettable through
codewhale config set providers..allow_insecure_http, and
listed in the custom-provider field hint), it stays distinct from
insecure_skip_tls_verify, and the refusal message now leads with
the config key. Loopback hosts remain auto-allowed and telemetry
endpoint validation deliberately still consults neither switch
(#5991, thanks @Gabriel-Degret).
- A Fleet task that selects a roster member with
worker.agent_profile now
runs with that member's posture. The launch-time resolver only consulted the
resolved member when the legacy worker.role label was absent, so a task
labelled manager that selected member:reviewer ran as a write-capable
manager instead of a reviewer and was never leased. The member's canonical
slot now wins whenever one resolved; the label remains the posture only when
no member resolved at all. To keep the fix from widening authority in the
mirror case (a read-only label on a write-capable member), a spec whose
worker.role names a different posture than the selected member's role is
rejected at run creation with a message naming both postures; casing and
legacy aliases of the member's own role are still accepted (#5945, thanks
@gaord).
- A queued message keeps one transcript entry from queue through steer to
dispatch. It no longer reads as delivered while it is still pending, and the
second Enter the strip prompts for no longer paints a duplicate bubble.
- The Tasks rail panel no longer swallows the first keystroke of typed input:
bare y/Y yank only when the work surface holds keyboard focus, so a
message that starts with "yes" stays intact (#2000).
wait results reach the parent intact. The parent-context summarizer
projected every agent tool result through the sub-agent snapshot renderer,
which replaced a wait envelope's settled, still_running, timed_out,
waited_ms, and note with unknown (agent) status=unknown. Only
snapshot-shaped results are summarized now.
- A sub-agent's final summary uses the same adaptive tool-result budget as
every other tool result (tool_result_max_bytes, 12k floor, 2 MiB ceiling)
instead of a hardcoded 12k/4k/4k copy that cut a 12,001-character report to
8,000.
- The metrics line no longer carries a permanent
/help hint. The route still
appears until its binding has been used and then retires with the other
footer hints, so the row stays quiet once help is learned.
request_user_input's description names when asking is the right move
(ambiguous scope, an irreversible or expensive choice, a missing preference)
and when it is not, so the model stops guessing at discoverable facts.
config.example.toml states the real search default (keyless Firecrawl, not
DuckDuckGo) and the preferred CODEWHALE_SEARCH_* environment names.
- Startup type-ahead is preserved whole, and a slash command interrupted by
startup keystrokes is no longer re-read as prose and sent to the model
(#5925).
- The model picker renders a large catalog without lag and supports per-column
sort and mouse selection (#5975).
- Session metrics report effective request throughput from provider receipts
instead of a live estimate divided by the whole turn, and cost stays honest
when a route has no price reading (#5976, #5977).
- An offline-queue submit delivered as late raw keystrokes no longer wedges the
composer behind stacked session notices (#5999).
- Fleet setup with a model filter that matches nothing renders a hint instead
of panicking (#5953), and shortlist enrollment plus authoritative role pins
are honored on dispatch (#5915).
- A mid-turn MCP catalog refresh keeps the tool pool deferred and the active
set narrow (#5939).
- Computer Use on macOS verifies application activation before sending
keystrokes and guards input by the frontmost app (#5927).
- Onboarding tests isolate
CODEWHALE_HOME, so a fixture provider can no
longer leak into the real setup state (#5932).
- Snapshot availability is retained with one warning per session, and a
diverged engine session id is a visible notice rather than a log line
(#5930).
Changed
- How long Codewhale waits for a human is configurable. `[tools]
user_input_timeout_seconds` governs the wait for an approval decision or a
request_user_input answer; it was a hardcoded 300 seconds, which silently
cancelled the work of anyone who stepped away mid-task. An explicit 0
waits indefinitely, the value is clamped to 24 hours, and omitting the key
keeps the previous 300-second default. Documented in
docs/CONFIGURATION.md (#6003).
docs/PROVIDERS.md lists every beginner setup template, not the four it
happened to mention when the page was written. Baseten, Groq, Cerebras and
Command Code have shipped as supported OpenAI-compatible hosts for a while
and appeared nowhere in the provider documentation, which reads from outside
exactly like not supporting them. The page now carries the full table —
host, default model and key env for each — and states the rule it follows:
a plain Chat Completions backend is a template row, while ProviderKind is
reserved for distinct wires. A test now fails if a shipped template is
missing from that page.
- Reasoning capability for the Kimi coding routes and the qwen3.x Model Studio
deep-thinking ids is catalog data now rather than hardcoded match arms, and
model_reasoning_capability reports a model nothing knows about as unknown
instead of silently not reasoning-capable. model_supports_reasoning keeps
its bool shape for existing callers, where unknown still reads as false.
The ids that have no cited source yet keep their literal arms (#6032).
- The website uses Shannon Sans with versioned local font assets and retained
serif, monospace, and language fallbacks. Terminal fonts are unchanged.
codewhale metrics reports recorded model requests and stream recovery
separately from provider-reported token usage, with coverage for missing
and duplicate receipts. Status messages and cumulative snapshots do not
add requests or count tokens again.
- Runtime turn receipts retain the Engine's terminal model-request, stream-retry,
and resume counters separately from displayed status and provider-reported
usage. These counters do not count HTTP retries inside a provider client or
establish provider billing.
- Initial tool definitions no longer repeat shell interpreter guidance and
agent lifecycle/scope instructions in multiple description fields. Parameter
schemas, approval rules and dispatch behavior are preserved. This reduces
prompt schema size; it does not establish a provider billing regression.
- The built-in Computer Use plugin bundle is refreshed to the standalone
plugin's 0.2.1 runtime (vendored from Hmbown/codewhale-cu-plugin
at 724ad258): the native macOS accessibility backend with an
a11y-first pointer strategy (covered points are refused, previews are
drawn), the permission-owning desktop-app socket transport, remote
computers over ssh and HarmonyOS HDC with contained temp handling,
truthful win32 PowerShell failure reporting, and the shared
allow-listed request handler for the app socket and ssh agent.
The bundle retains the hardening port from
standalone plugin PR #12.
Single left clicks on macOS element targets now revalidate and press
the observed element directly, without substituting a point hit-test
or raw-pointer fallback. Explicit event clicks retain the app-ownership
guard; a sent press still requires visual verification. Background mode
permits application-bound keys and accessibility actions while refusing
shared-pointer gestures; it does not provide an isolated desktop. The
embed list gained the five new runtime files, and a consistency test
now pins the embed list to the vendored tree so the bundle cannot rot
silently again. Because the bundle's content hash changes, Computer
Use deactivates and asks for a fresh review after upgrading — that is
the designed fail-closed path for a desktop-driving plugin. The
current macOS source candidate also embeds the compiled native helper,
so its bundled server can run directly without a separate Computer Use
app or a compiler on the user's machine. Accessibility and Screen
Recording permissions belong to the hosting app or terminal and remain
user-controlled. The CLI's Computer Use server requires Node.js 20 or newer. These are source
candidate changes; they do not establish published-package or platform
qualification. See the included plugin guide
for platform requirements and limitations.
/statusline drives the bottom chrome again. Since the 0.9.12 shell
redesign the posture bar and the metrics line were built independently of
tui.status_items, so every toggle in the picker except the balance fetch
was decoration. Each remaining item now shows or hides exactly one thing:
model, context_percent, cost, balance, cache, tokens and
session_metrics are metrics-line segments, and mode is the posture
bar's plan/act/operate chip. The status, agents, reasoning_replay,
prefix_stability, git_branch, last_tool_elapsed and rate_limit
items drove nothing and are retired; an existing config.toml still loads
and those keys are ignored (#5950, #5962).
- The context reading is back on screen at every fullness. 0.9.12 painted
ctx NN% only from 50% up, which left most of a session with no context
signal at all; it now paints from 0% and keeps its warning colour from 80%
up (#5950).
- A child agent parked because its parent's turn ended is shown as
parked
in the Agents panel, the sidebar and Agent Details, with resume_from /
cancel as the recovery, instead of wearing the same "waiting for input"
label as a child that asked a question. Parked work sorts below live and
answerable work and no longer inflates the blocked chip; the receipts
roster and the wire state gain parked (#5906, #5921).
codewhale account keys set|remove|list no longer carry a hardcoded
eight-provider list. Provider ids come from the control plane's public
catalog (GET /api/model-providers), are validated locally against
^[a-z0-9][a-z0-9-]{0,63}$ before they reach a URL path, and list shows
every catalog provider with its label and stored-key state. --from-local
maps a catalog row onto the local runtime provider through the catalog's own
runtimeProvider field, so a newly supported provider needs no CLI release.
/mcp lists the servers that need a login first, as their own
Needs login group above Needs attention, and opens with the cursor
already on the first such row so the Enter the screen advertises runs
/mcp login straight away; translated in all 15 packs. A
snapshot test pins the footer shape the chip landed with (`MCP · N
connected · N ◆ auth required · N failed`) so an expired login never
regresses into the failed count (#5926).
Fixed
- Five of the load-flaky tests tracked in #5929 no longer depend on shared
state or live local daemons. Background-hook capture tests wait for the
capture file to hold bytes instead of merely existing (the shell's >
redirection creates the file empty before cat writes, which read as
valid JSON: EOF under load); the session-picker acceptance test drives
the real picker over a private store instead of a process-global
CODEWHALE_HOME redirect that concurrent tests could observe mid-flight;
the DeepSeek-Anthropic translate test holds the test env barrier so its
request-time and assertion-time max_tokens reads cannot straddle another
test's CODEWHALE_MAX_OUTPUT_TOKENS override; the unit-test binary no
longer probes a real local Ollama daemon (127.0.0.1:11434) from the
fire-and-forget provider catalog refresh, whose merged tags could flip
another test's live-snapshot assertions; and the tmux clipboard test's
attach/OSC 52 wait bounds tolerate a fully loaded machine (3s -> 30s)
without changing what they verify (#5929).
- The posture bar states how long the session has been working and how long
the current turn has run, distinguishing actively working from waiting on
a tool, a sub-agent or the operator; the 0.9.12 shell had dropped the overall
working-time indicator from the place a glancing user checks (#5914).
- A background runtime turn whose own store record could not be read, parsed
or written (Failed to read turn …, Failed to read item …) was only a log
line. The runtime now publishes a runtime.store_failure event naming the
file, the root cause and the next action (move the file aside, or check free
space and permissions); the TUI shows it as a warning toast and a transcript
line, the task timeline records it, and the runtime API streams it. A turn
whose own record is unreadable or unwritable is reported as terminal, so its
task fails at once instead of idling out (#5931).
- An MCP token refresh that fails to parse the provider's answer keeps the
endpoint's receipt — status line, content type, and a 200-byte excerpt
with every credential-shaped value (access_token, refresh_token,
client_secret, id_token, bearer schemes) masked before the cut —
instead of rmcp's bare Failed to parse server response, so a provider
outage answering an HTML 502 reads differently from a parser defect, and
the login remedy stays named (#5926; remedy wording landed in #5959).
Added
POST /v1/threads/{id}/file-revert restores exactly one file from the
exact tool:/pre-turn: snapshot the client selected, checking the
reviewed file hash before and after the mandatory safety snapshot. Literal
file names, regular files only, thread trust and active-turn admission are
enforced, and patch-undo no longer forks a conversation whose file
rollback failed (#6111, thanks @gaord; engine half of
HengQuWorld/CodeWhale-VSCode#3).
- Authenticated Runtime API workspace file suggestions reuse TUI
@file
matching and discovery, with bounded queries/results and workspace-contained
relative paths only (GET /v1/workspace/files/search, #6095, #6120, thanks @wuisabel-gif; reported by @LmeSzinc). Shared discovery
now honors disabled symlink following for AI-tool directory scan roots too.
- Serply is available as an opt-in
[search] provider for the Web tool
(provider = "serply", key from [search] api_key or SERPLY_API_KEY).
Preflight fails closed without a key; Firecrawl remains the default and
existing configurations are unchanged (#6100, thanks @googio).
- Linux terminals: finishing a transcript or composer mouse selection copies
the text to the PRIMARY selection without touching the regular clipboard, and
middle-click inside the composer pastes PRIMARY at the pointer without
submitting. Native X11 and Wayland data control are used through one bounded
background worker; SSH sessions without a forwarded display keep their
terminal's own selection behavior (#6116, thanks @dmt4).
codewhale sessions export saves a .tar.xz archive
with the durable record, portable session container, manifest and artifacts.
Prefix exports preserve unfinished tool calls; confined reads reject linked
artifact roots, and existing outputs require --force. Archives retain
unredacted content; /load opens the extracted record without installing
extracted artifacts (#6056, thanks @h3c-hexin and @asto18089).
deepseek-flash (DeepSeek V4.1 Flash: 1M-token context,
reasoning and tool calls) joins the catalog as DeepSeek's declared default,
and the offline catalog seed matches it; the DeepSeek Pro listing no longer
overstates the published price (#6025).
- DeepSeek's September 11 reversal is reflected in provider notices and cost
estimates: V4 Pro remains available after September 14 at Pro rates. Explicit
Pro selections remain unchanged; Flash remains the default (#6025, thanks @ronohara).
- Native plugin authoring guides now cover English and Chinese. The explicit
offline converter supports selected portable Skills and static Streamable
HTTP MCP declarations from OpenCode and DSH. Unsupported executable hooks,
automatic OAuth and policy-bearing configurations are refused; generated
bundles still require native installation, review and trust. Legacy SSE
fallback is not reproduced (#5827, requested by @giancarlocp).
- Signed cloud model facts can refresh provider capabilities and prices while
preserving verified cached data when a refresh fails. A dispatched request
keeps its selected price snapshot so later catalog updates cannot change its
recorded cost (#5752).
- Saved sessions preserve exact provider routes. Auxiliary model calls settle
their usage once against the route and price snapshot that executed them,
including recovery, rather than resolving a new price at completion
(#5726, #5848).
[tui].posture_bar and [tui].metrics_line accept full, compact, or
hidden, also available through /config. Compact preserves the existing
rows' essential fields; hidden returns their space to the transcript (#5973).
- Optional model-bound tool-output redaction opt-out, with two explicit startup
confirmations and a receipt bound to the readable config contents and
modification time. Unconfirmed requests keep masking enabled; routing and
stored goal summaries remain redacted (#5982, thanks @SparkofSpike).
- The
rusty-alloc cargo feature on codewhale-tui and codewhale-cli
opts the binaries into the rusty_alloc global allocator (the mimalloc
v2.4.5 architecture remade in pure Rust — no C compiler or build script
on that path) instead of the default mimalloc. It is off by default and
the default build is unchanged; build with
cargo build -p codewhale-tui --features rusty-alloc (#5872).
- The
/theme picker now discovers valid user-authored custom:
overlays, previews their colors, highlights the active overlay, and preserves
it when the picker is opened and committed without navigation (#5901).
- Compaction has two standing knobs next to
[context] in config.toml:
[compaction] summary_instructions (appended to the summarizer prompt on
every manual and automatic pass; /compact still composes after
it) and [compaction] retained_user_message_tokens (default 20 000,
clamped 2 000..=200 000) for the verbatim user-message budget. Both are
absent by default and absent means the pre-existing behavior. The
/compact receipt names the effective budget and whether operator
instructions applied (#5956).
[tools] user_input_max_questions (default 6, 1..=10) and
[tools] user_input_max_options (default 4, 2..=10) replace the hard-coded
request_user_input limits; the validator, the tool schema and its
description read one value, spawned children inherit the parent's ceilings,
and a rejected payload names the ceiling it hit and the key to raise (#5949).
- The slash menu shows a command's usage line and its subcommands as soon as
a space is typed after the verb, filtered by what follows, so Tab completes
/workspace wor to /workspace worktrees; /help states the focused
command's usage in its detail slot (#5952).
- The three
/fleet views (roster, live workers, saved teams) are one
back-navigable stack: Esc in workers or saved teams returns to the roster
with its cursor intact and still closes the window at the root or on direct
entry; the Esc footer hint says back or close accordingly (#5954).
/fleet presents its prioritized core (members, setup, teams,
workers, help); every other verb stays dispatchable and is documented
under explicit groups in /fleet help. The roster no longer shows the
untouched built-in general alias next to worker (#5888).
codewhale provider: account-backed model access over the provider keys a
customer connected to their Codewhale account. One base URL
(https://api.codewhale.net/v1, overridable with CODEWHALE_API_BASE;
HTTPS required except on loopback), one cwc_key_… account API key with the
models:infer scope (CODEWHALE_API_KEY), and a per-model wire chosen from
the account's authenticated GET /v1/models: ids are provider/model and
each row states chat-completions (/v1/chat/completions) or
anthropic-messages (/v1/messages). Both protocols authenticate with
Authorization: Bearer, never x-api-key. The key is read from
CODEWHALE_API_KEY, the codewhale secret-store slot, or
[providers.codewhale] api_key / api_key_env, and a missing key fails
before any request instead of dispatching unauthenticated. If the catalog
cannot be fetched the route falls back to three bootstrap ids and says so.
codewhale account api-keys create --scope now accepts models:infer
alongside account:read and agent:run, and an omitted --scope sends all
three explicitly. --use saves the new secret as this machine's local
codewhale provider credential in the same secret store codewhale auth
uses; nothing is uploaded.
Git grows a commit_plan action: a propose-only planner that splits the
working tree into ordered atomic commits (#3999). It groups whole files —
lock files ride with their manifest, tests ride with the source they name —
orders the groups so a commit that defines a symbol lands before the commit
that uses it, and refuses the whole plan when that dependency graph has a
cycle. It reads git diff HEAD plus the untracked-file list and writes
nothing: no git add -N, no git apply --cached, no git commit, so
staging and committing stay with the ordinary git add / git commit shell
path where the approval gate already applies. Thanks
@goransh-walia for the original
implementation (PR #5870, fixes #3999).
Notes
- DeepSeek V4 Pro continues after September 14. The vendor reversed its
earlier retirement notice. Codewhale preserves Pro selections and Pro pricing;
deepseek-flash remains the default for new direct DeepSeek configurations.
- Upgrading from 0.9.12 with Computer Use trusted and enabled: the
bundle's content hash changes with the 0.2.1 refresh, so the plugin
deactivates and asks for a fresh review — that is the designed
fail-closed path for a desktop-driving plugin. Re-trust it from the
Plugins page.
- The multiline-paste fix restores v9.11 behavior on terminals that
accept EnableBracketedPaste but deliver pastes as keystrokes
(reported on Windows 11 / PowerShell). Verified at the input-contract
level and in CI; a manual paste check on a real Windows terminal is
still welcome — please comment on #5981 with your terminal if anything
still misbehaves.
Contributors
- @LmeSzinc — requested Runtime API access to the TUI's fuzzy file search (#6095).
- @dmt4 — requested Linux copy-on-select and middle-click paste (#6116).
- @Gabriel-Degret — reported that saved agent profiles were silently ignored when spawning sub-agents (#6117).
- @nightt5879 — Gemini signature recovery guidance and transport regressions (#6081).
- @c020627 — Chinese documentation link repairs (#6080).
- @h3c-hexin and @asto18089 — GLM-5.3 reasoning controls and tool-gating/documentation fixes (#6051, #6052).
- @Hmbown — dependency updates (#6057) and the Gemini signature recovery report (#6048).
- @gaord — contributed the file-scoped restore endpoint and the trust-gated whole-tree rollback (#6111), Fleet schema inspection, role precedence and worker deliverable receipts, and linked the community VS Code frontend (#5944, #5945, #5946, #5992).
- @7jrxt42BxFZo4iAnN4CX — documented turn budgets and goal configuration, and reported gaps in command discovery, Fleet navigation, human waits, state hooks, history and provider routing (#5996, #5952, #5954, #6003, #6004, #6006, #6007).
- @SparkofSpike — contributed two-stage consent for opting out of model-bound credential redaction (#5982).
- @aboimpinto — moved session lifecycle and session-control commands onto shared command contracts (#5902, #5951).
- @wuisabel-gif — exposed workspace file suggestions through the Runtime API (#6120) and added custom-theme discovery, preview and selection in the theme picker (#5907).
- @zhuowp — matched model-visible shell guidance to the interpreter selected for execution (#5900).
- @nsfoxer — reported the multiline-paste regression and incomplete provider model lists (#5981, #6009).
- @Lujc0523 — reported the ACP initialize schema violation affecting strict IDE clients (#5969).
- @mo-vic — proposed storing evicted context on disk so it can be retrieved later (#6008).
- @giancarlocp — requested a plugin authoring guide and OpenCode plugin conversion (#5827).
- @hxfhd — supplied a Windows reproduction of a turn stopping before its stated next tool action (#6010).
See CHANGELOG.md for full notes and docs/CHANGELOG_ARCHIVE.md for older releases.
|
Post a Comment/Report Broken Link: