Zum Hauptinhalt springen
Sichere ProgrammierungI'm an AI agent. I read the agent-economy job boards' own numbers.(05.10.2026 um 03:41 Uhr)
••••
Sichere ProgrammierungYour ops dashboard does not need a frontend framework(05.10.2026 um 03:47 Uhr)
•
Sichere ProgrammierungThree pieces, zero readers: what I got wrong about publishing(05.10.2026 um 03:47 Uhr)
•
Sichere ProgrammierungProofDesk: A contact review is only as current as its evidence(05.10.2026 um 03:49 Uhr)
•
AI & KI NachrichtenAI Agents - Tool Calling And Its Types(05.10.2026 um 03:49 Uhr)
•
Sichere ProgrammierungSTAGE LADDER - A Private, Offline Speaking Coach Built for a Friend(05.10.2026 um 03:51 Uhr)
••
Sichere ProgrammierungI'm an AI agent. I read the agent-economy job boards' own numbers.(05.10.2026 um 03:41 Uhr)
••••
Sichere ProgrammierungYour ops dashboard does not need a frontend framework(05.10.2026 um 03:47 Uhr)
•
Sichere ProgrammierungThree pieces, zero readers: what I got wrong about publishing(05.10.2026 um 03:47 Uhr)
•
Sichere ProgrammierungProofDesk: A contact review is only as current as its evidence(05.10.2026 um 03:49 Uhr)
•
AI & KI NachrichtenAI Agents - Tool Calling And Its Types(05.10.2026 um 03:49 Uhr)
•
Sichere ProgrammierungSTAGE LADDER - A Private, Offline Speaking Coach Built for a Friend(05.10.2026 um 03:51 Uhr)
••
Intelligence View
⚡ tsecurity.de Intelligence

GitHub Release: codewhale-hq/Codewhale v0.10.0 (22.09.2026)

Release v0.10.0 von codewhale-hq/Codewhale auf GitHub: Codewhale is the public product from Shannon Labs. The codewhale command, npm package, and release-asset…

Beitrag
0
Seite
0
↗ Quelle (GitHub · codewhale-hq/Codewhale)
Social ReaktionenReagiere als Erste:r — dein Feedback zählt!
codewhale-hq/Codewhalev0.10.022.09.2026@github-actions[bot]

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



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


curl -fsSL https://codewhale.net/install.sh | CODEWHALE_VERSION="v0.10.0" 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


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


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

The image exposes the same runtime as both codewhale and codew. The

latest tag is also updated on release.


Cargo (Linux / macOS)


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.



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):


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.



Download the checksum manifests from this Release and verify:


# 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.10.0


Codewhale v0.10.0 brings a redesigned terminal workbench, clearer settings, and

more reliable session and runtime behavior. It supersedes the unpublished

v0.9.14 candidate.


Security




  • Children never inherit desktop or computer-control tools. Desktop control is

    the most machine-wide capability in the catalog, and a verifier child

    inherited it by default: on 2026-09-17 one opened the host Terminal and typed

    a blocked shell command into the user's live session. A family classifier now

    removes those tools when a child's registry is built, so they are neither

    eager nor searchable, and execute_full refuses the family at dispatch for

    every child role — visibility is a grant, and hiding is not the only defense

    (#6296).




  • Runtimes can be held to an organization's plugin allowlist. A managed policy

    document (managed-policy.json beside state.json, or

    CODEWHALE_MANAGED_POLICY_PATH) lists the plugin ids a Runtime may run,

    with an allow_unlisted flag and a schema version checked exactly like

    PluginStateFile. Enforcement sits inside apply_state, so a plugin

    enabled before the policy arrived — or hand-edited to enabled: true —

    never comes back enabled, and enable() re-reads the document so a policy

    landing after discovery refuses with a reason that names it. A malformed

    document fails closed rather than degrading to unenforced. With no policy

    present, behaviour is bit-for-bit what it was. This is the enforcement

    primitive only; the authority that decides the allowlist is still local,

    so it binds a cooperating Runtime, not a hostile one.




  • Approving an apply_patch "for the session" is now scoped to the file you

    approved. The grouping key that scopes a session grant was built by a second,

    weaker patch parser that read only +++ b/ headers and the replace array:

    it saw no target at all for the documented apply_patch{path, patch}

    override, for --no-prefix diffs, or for delete-only diffs, and collapsed

    every one of them to a single shared key. One approval therefore pre-approved

    every later patch of that shape, to any file, with no card and no notice. The

    key now comes from the same resolver the executor and the permission path

    already use, and an input that cannot be resolved gets its own key rather

    than a shared one (#6247).




Added




  • The statusline's performance readings survive compact mode and are separately

    configurable. Measured TTFT and average output rate are kept when space

    allows, shedding help text and secondary counts first; the existing metrics

    and statusline settings gain individual toggles with a migration that

    preserves a legacy single setting, and the picker takes mouse selection and

    scrolling.




  • Tasks can be given their own run name. NewTaskRequest, TaskRecord and

    TaskSummary carry an optional name, stored as given and omitted when

    absent, so queues still fall back to prompt-derived titles; a run started by

    an automation inherits the automation's name. The tasks tool's schema

    extends backward-compatibly and legacy records decode through serde defaults

    (APPS-153).




  • The offline catalog seeds Xiaomi's MiMo 2.6 family — xiaomi/mimo-v2.6-pro

    and xiaomi/mimo-v2.6-flash — so a first boot without network no longer shows

    the 2.5 generation. DEFAULT_XIAOMI_MIMO_MODEL stays on mimo-v2.5-pro, and

    the rows carry no price because the published rates cover only sk- keys.




  • Native memory is a reviewed store, not a model-writable file. codewhale-memory

    backs the TUI with SQLite as the authority instead of Markdown, and the

    remember tool now only proposes candidates — a model can no longer write

    an active memory. /memory and the Runtime API commit through

    remember_reviewed, and a Context Lens surface (/v1/memory/lens,

    /lens/actions, /events) shows what was kept and why.




  • Code mode (Experimental, default off): execute_tools runs a JavaScript

    program against a QuickJS host surface so a model can express several tool

    calls as one program. Nested calls must be read-only and auto-approved; the

    tool is hidden in Plan and refused under worker authority. Enable with

    [features] code_mode.




  • Two new built-in providers: ZenMux (ZENMUX_API_KEY) and CSDN 星图

    (CSDN_API_KEY, Coding Plan quota billing), each with its own key slot,

    bootstrap model and catalog rows.




  • The Runtime API gained the surface a native client actually needs: jobs with

    stdin, kill and cursor reads; context, secrets, git, diagnostics, targets,

    LSP and voice routes; GET /v1/commands for the slash-command catalog;

    GET /v1/workspace/instructions; account-wide GET /v1/approvals; plan and

    to-do inventory; /v1/settings/schema, with POST /v1/config now persisting

    every declared settings.toml key rather than a curated allowlist; PTY byte

    replay, resize and exit; and tool images as session artifacts.




  • Codewhale holds the host's idle-sleep assertion while a turn is in flight

    (caffeinate -i on macOS, systemd-inhibit on Linux), so an unattended

    machine no longer sleeps mid-run. You will see one child process per turn.




  • Skills are reachable in one call. The pinned ## Skills index told the model

    to call load_skill, but the tool was deferred behind tool_search, so it

    was never in the tool array that instruction was printed beside: using a

    skill cost a discovery hop, a name="list" round trip, and a

    change:tool_surface re-pin of the whole cached prefix. load_skill is now

    eager for the parent and for children — +244B of pinned catalog, measured,

    against a re-prefill avoided every time a skill is used — and it takes a

    query that searches names and descriptions, so a truncated index no longer

    forces pulling the whole catalogue to find one skill. The usage line now says

    to load the matching skill by name before starting the work.




  • A fast lane the router cannot serve now says so. provider_router_candidates

    answers cheap: None for any pair its tables do not know, and a

    Faster/Auto child on such a pair used to run at the parent's model and

    price with no receipt and no way to tell "single tier by design" from

    misconfiguration. The fallback stays — the router must not invent a model —

    but the spawn receipt now carries a fallback_note naming the unserved lane,

    the same field the pinned-provider fallback already uses. Inherit and

    served lanes stay quiet: this reports a fallback, it does not nag.




  • The runtime API tells a replayed submission apart from a new admission:

    POST /v1/threads/{id}/turns answers 200 with idempotent_replay: true

    when the operation key was already used, and 201 for a fresh admission, so a

    client that retries after a dropped response can no longer create a second

    turn. The flag is absent on a fresh admission, so responses existing clients

    already parse are unchanged (#76).




  • Event streams resume where they left off: journal frames carry their durable

    seq as the SSE event id:, Last-Event-ID is honoured as the cursor when

    no explicit since_seq is asked for, and RuntimeCapabilities advertises

    event_stream_resume so a client can gate its reconnect controls on the

    capability instead of discovering it from a missing id (#76).




  • TTFT and average output rate stay visible in the compact working footer when

    space allows. /statusline now controls them separately; existing

    session_metrics settings still work.




  • StepFun’s current coding catalog includes Step 5 Preview, Step 3.7 Flash,

    Step 3.5 Flash and its 2603 version, with published reasoning controls and

    PAYG rates. Existing Step Plan routing remains subscription-based.




  • read responses now always report the file's byte size, line count, and

    whether output was truncated, and truncation footers name the total size

    alongside the continuation offset — so paging through a large file is

    deliberate instead of a surprise (#6283).




  • File edits are parse-gated before the write lands: Rust goes through

    syn::parse_file for a grammar-exact line:column, and .toml / .json

    through the parsers already vendored. An edit is refused only when the file

    parsed before and would not parse after — repairing an already-broken

    file is the commonest reason to edit source at all, so pre-existing breakage

    and new files fail open. The check precedes the write, so a rejection leaves

    the file untouched and apply_patch cannot half-apply (#6204, #6206, #6151).




  • Rust files that were already rustfmt-clean are re-normalized after an edit,

    so the next patch's anchors still match. Hand-formatted files are never

    rewritten, and every failure path skips and lets the edit land (#6205, #6151).




  • Native clients can finish provider setup without dropping to the CLI:

    DELETE /v1/providers/{id}/key clears a Codewhale-owned credential through

    the same shared owner as codewhale auth clear, and GET /v1/providers

    now carries credentialSource / credentialWritable (plus a reason) so a

    client disables its control with a truthful explanation instead of letting

    a write fail late. A credential Codewhale does not own — a literal key in a

    config file, or an active external consent — refuses both verbs with 409

    rather than appearing to succeed against a source that still wins at

    request time (#6179).




  • The interactive approval card can be bounded: [approval] timeout_seconds

    resolves an unanswered card to deny when the window elapses — the same

    fail-closed decision the external approval path takes — and the transcript

    says the bound denied the call, not the operator. Omitted or 0 keeps

    today's unbounded wait, so nothing changes unless you opt in (#6101).




  • Transcript drag selection copies Markdown source by default: every cell the

    selection touches serializes through the same canonical path Ctrl-Y and

    /copy use, joined with blank lines, and the toast names the copied cell

    count. A selection that does not cover every touched cell end to end copies

    the exact rendered fragment instead: rounding a pinpoint selection out to

    whole cells meant copying an entire model message (#6228).

    tui.selection_copy_markdown = false keeps the rendered-text payload

    (#6156).




  • The Runtime API serves the workspace files a native client browses and edits:

    GET /v1/workspace/files lists one directory, GET /v1/workspace/files/read

    returns a bounded byte window with a whole-file SHA-256 revision, and

    PUT /v1/workspace/files writes atomically through the confined opener with

    revision-checked overwrites (409 on drift). .git is never served and

    symlinks are never followed. A saved session's oversized tool outputs are

    served as artifacts at GET /v1/sessions/{id}/artifacts and

    GET /v1/sessions/{id}/artifacts/{artifact_id}. (#6163)




  • A session that ended mid-turn is no longer invisible to the model. The newest

    workspace-scoped session still holding a crash-recovery checkpoint is

    surfaced as a one-line ## Prior Session notice in the session-pinned prompt

    prefix — metadata reads only, excluding the live session and any session this

    process instance created. Clean sessions get no block, so their prefix bytes

    are unchanged. Two bounded read-only tools, session_search and

    session_get, give the model workspace-scoped recall over the same store

    (one-line summaries and an 8-message tail, labeled untrusted user data, read

    on the blocking pool). Resuming stays the user's decision: the hint tells the

    model to offer a continuation, never to silently take one (#5715).




  • codewhale exec --hooks opts a headless run into the same HookExecutor the

    TUI builds — global config, reviewed plugin snapshots, and trusted project

    hooks.toml. Headless runs previously fired no hooks at all. tool_call_before

    can still deny and shell_env still applies; a hook ask resolves

    fail-closed without a terminal. Fleet worker subprocesses never opt in, and

    permissions.toml typed rules are unchanged (#6099).




  • codewhale doctor flags fleet and profile model pins that the provider's own

    roster no longer offers. A pin is reported only when a fresh cached live

    roster for that exact route exists and omits it — stale, failed, or absent

    rosters prove nothing and are counted as unverifiable rather than raising a

    false warning. Each row names the route and every owner of the pin; the pin

    is surfaced, never rewritten (#6035).




  • Background-capable clients can enumerate owned work and watch TUI-visible

    conditions: GET /v1/threads/running lists threads with queued or

    in-progress turns in one call (one turns scan grouped by thread), and

    GET /v1/threads/{id}/notices serves active subagent-terminal,

    elevation-needed, and model-notify notices with thread/turn identity,

    cleared by ack or — for elevation — when the tool call completes (#6180,

    #3757).




  • Sub-agent launches adapt to provider throttling: a DynamicGate replaces

    the fixed semaphore so launch capacity adjusts at runtime, and a

    RateLimitGovernor halves capacity on 429 pressure, pauses admissions

    past the threshold, and recovers additively; 429 retries honor

    Retry-After with jittered backoff, and quota exhaustion keeps the

    failure path (#6055).




  • Turns record the mode they ran in, so mixed-mode sessions stay legible

    after the fact (#6321).




  • Shell spawning refuses NUL bytes in command and cwd before spawn, and

    sub-agent runs fall back loudly past credentialless profile provider

    pins instead of misrouting silently (#5529, #6318, #6320).




  • Children land past a per-step context bound instead of burning

    quadratically, and status rows surface live declared-vs-observed writes

    (#6189, #6194).




  • Queued Agent Mail can be cancelled before delivery, and the TUI

    suspend/resume handshake restores on stop and rebuilds on continue

    (#6176, #6169).




  • MCP connections are supervised: dead servers are probed and reconnected

    with transitions reported, and a failed reconnect keeps the last-good

    catalog instead of dropping tools (#6187, #6142).




  • Web search autodetects Tavily from TAVILY_API_KEY (Firecrawl stays the

    default), fleet refusals name the alternative, and verification runs on

    a bounded Git fetch plus a merge_tree verify surface (#6298, #6296).




  • Fleet authority projects through one ChildGrant, and ModelScope joins

    the built-in providers (#5633, #6299).




  • Child tool results are capped at capture time, and run

    tests/verifiers accept a bounded cwd (#6282, #6294, #6296).




Changed




  • SearXNG results rank by the score the instance returns rather than by arrival

    order. Integers, floats and numeric strings are accepted; anything else,

    including NaN and infinity, becomes 0.0, and rows are stable-sorted descending

    before the result cap, so equal scores keep instance order. The docs now spell

    out the self-hosting requirement: the separate process must expose

    search.formats: [json] — an HTML-only instance answers 403 — and bind to

    loopback or a policy-allowed host, with no default instance discovered.




  • The bundled skills move to a new generation. social-media and health leave the

    shipped pack (phone-export workflows rather than everyday skills), feedback

    moves to docs/skills/ beside contributor onboarding, and the exact earlier

    body is retained so only unmodified shipped skills upgrade — a skill you have

    edited is left in place. Google OAuth scopes and client setup, Photos exports,

    forgetting limits, Spotify playback and plugin reload guidance were corrected

    in the same pass.




  • auto is a declared default, not a guess about your wording. Reasoning

    effort no longer maps request vocabulary to tiers (debug/error to Max, search

    to Low) and Auto routing no longer infers cheap-versus-big from phrasing:

    both resolve the configured default, with [auto] cost_saving as the

    explicit opt-in. The same prompt now costs the same thing twice.




  • A workflow's shared token budget is opt-in. [workflow] default_token_budget

    applied a silent 120,000-token cap across a run and all of its children, and

    a fan-out died at the limit with no hand-back; the default is now 0, meaning

    no shared cap.




  • The shipped deepseek-flash route speaks the Responses endpoint, and xhigh

    effort maps to high per the vendor's own table.




  • Streamed text is paced at a steady rate rather than inheriting the provider's

    SSE chunking, so output reveals at a readable beat instead of in bursts.




  • Broadening shell access for a conversation now requires an idle conversation

    and rejects a stale-workspace check before it commits. Engines advertise a

    thread_shell_consent capability, so an older Engine reads as unsupported to

    a native consent client instead of silently accepting.




  • One base prompt now serves every host. HEADLESS_BASE_PROMPT was a second

    hand-maintained rendering of the same constitution — the drift pattern this

    repo forbids by convention — so headless runs compose the same BASE_PROMPT

    plus language and output layers that interactive runs do, skipping only host

    chrome (execution profile, authority recap). Headless and interactive can no

    longer disagree about what the agent is.




  • BASE_PROMPT gains a Bearing article, which changes how the agent talks

    to you: the user is a peer who gets honesty rather than deference, a blocking

    gate is named plainly instead of dressed up as refusal, bad code is called

    bad, a crude request is carried out without a lecture, and an apology appears

    only when there is something to apologize for — not as punctuation. It also

    states that the request is the whole mandate, so the scope law opens with

    what is yours to do before it reaches the edge. Every pinned kernel invariant

    survives verbatim.




  • The ocean reads as animals rather than a mechanism. The school used to

    translate as one rigid body — bob phase and tail pose were staggered per

    fish, but horizontal position was locked to an exact wedge offset — so each

    fish now eases a dot fore and aft of its slot on its own slow period, and the

    formation breathes while it travels. Bubble emission and the per-animal

    periods are hash-jittered instead of sharing one clock. Amplitude stays an

    order of magnitude under the crossing speed, so no fish travels against the

    school and facing == velocity still holds by construction. The species list

    is unchanged.




  • Extensions keeps the exact-content plugin review on the panel: confirming

    a bundle's digest re-reads the inventory, so the row you just reviewed

    reports its new trust state and offers Enable instead of leaving you in

    the transcript with a stale "not reviewed" row.




  • Underwater motion ticks at the cadence the frame limiter actually draws

    (the atmosphere interval while only the water moves, the authored 80 ms

    ocean cadence inside the interactive cap while a turn streams), and the

    event loop wakes exactly for the next tick instead of on the next idle

    poll. Idle water no longer requests frames it cannot draw or quantizes its

    cadence to the poll interval; reduced motion, Ghostty, tmux and the

    six-second idle settle are unchanged.




  • The launcher keeps the Codewhale mark while balancing its layout above the

    composer. A single cursor identifies the selected action; MCP faults retain

    their warning color even in compact terminals. Recent-session counts now

    read correctly for a single message.




  • Model and provider settings use quieter selection surfaces, one focused

    cursor, clearer missing-key warnings, compact output limits, and less

    repetitive credential detail. Plugin actions use plain labels.




  • The terminal opens on Shoreline, the same palette the GPUI client already

    uses: warm charcoal field #211F23, a raised plate for panels and the

    composer, one blue for action and selection #90B9FF, and the whale's ivory

    #F2ECE5 for body text, with 4.5:1 floors on every muted step. The old

    saturated navy gradient is not gone — it is a named underwater theme, and

    after review it is once again what a fresh 0.10.0 install opens on

    (DEFAULT_TUI_THEME); Shoreline is one /theme away. Existing installs keep

    whatever theme they have saved (#6222).




  • Menu navigation is starting to mean the same thing everywhere. menu_style

    already single-sourced how a selected row looks; what a key does was still

    reinvented per surface — h/l in the provider picker against Left/Right

    in the model picker one screen later, Home/End in one of seven pickers, and

    no paging at all in Fleet's detail view. list_nav, which already owned the

    wrap arithmetic, now owns the vocabulary too: one vertical axis, one

    horizontal axis, and two entry points so a picker with a live filter never has

    a letter stolen out of its query. Fleet's detail view adopts it first and

    gains PageUp/PageDown and Home/End in both its lists (#6290).




  • Reviewed plugin bundles are no longer re-hashed four times per MCP dispatch.

    verify_plugin_authority walks and hashes both the reviewed source and the

    runtime snapshot, and four separate authority checks ran per tools/call —

    eight tree walks. Three of them sat one statement after a

    validate_before_use on the same source, so is_ready re-verified what had

    just been verified; readiness and authority are now separate, and only the

    callers with no preceding check still pay for both. The tool catalog is built

    once per turn instead of twice, which also removes a case where the two

    assemblies could disagree if authority drifted between them. The digest is

    deliberately not cached on (path, mtime, len): the reviewed tree is

    user-writable and utimensat(2) lets a same-uid process restore an mtime

    after an equal-length rewrite, so a stat-keyed cache would serve a pre-tamper

    digest (#6209).




  • A sub-agent's completion is read from the manager once instead of polled. The

    workflow pump re-read it up to fifty times, sleeping 20ms between attempts,

    waiting for a terminal status that was already committed — every publisher

    commits the status inside the same &mut self call that wakes the pump, so

    the write guard spans both and the first read always sees it. A child the

    manager had no record of cost a full second of head-of-line blocking before

    failing; it now fails immediately, and says what actually happened instead of

    claiming the child "did not report a terminal status within 1s" (#6211).




  • MCP protocol negotiation: every surface advertised the original 2024-11-05

    revision and the stdio client required an exact match, so newer servers

    could not connect. The server and both clients now advertise 2025-06-18

    and negotiate over the supported set (2025-06-18, 2025-03-26, 2024-11-05)

    — the server echoes the client's revision when it is supported and answers

    with the latest otherwise, the stdio client accepts any supported revision,

    and streamable HTTP sends the required MCP-Protocol-Version header on

    every post-initialize request (#6280, first half).




  • Configured MCP servers now connect lazily instead of all at session boot. The

    pool owns a connecting set marked at spawn and cleared on resolution or

    abort, so "connecting" is no longer inferred as enabled-minus-connected. The

    boot pass scopes to the eager set — required servers plus those covered by

    tools.always_load / allowed_tools — and a turn naming an unstarted server

    spawns its connects alongside, under the existing five-second deadline. A

    configured-but-unstarted server now reads as configured on every surface

    (session-boot rows, Extensions tab, launch card), never as connecting.

    docs/MCP.md documents the lifecycle (#6033).




  • The launch card's MCP problems row runs its own remedy. It already printed

    /mcp login <name> or /mcp; it now joins the shared paint/click/keyboard

    ordering, so Up/Down lands on it and Enter or a click types the printed

    command into the composer for you to send. Typing beats copying: no clipboard

    dependency over SSH, and you see the command before a second Enter runs it

    (#6085).




  • Computer Use is the only computer-use product in Extensions and

    /mcp recommendations. Cua is no longer suggested as a parallel

    desktop-control MCP; enable the first-party computer-use plugin

    instead. The bundled plugin is 0.11.2 — macOS beta, with the Windows and

    Linux backends experimental and source-only. It carries the per-app consent

    ledger, background-by-default control, and a focus lease that refuses rather

    than stealing the foreground, alongside get_app_state, focus/get_value

    and stop_computer_control. Shared-desktop pointer gestures stay gated, and

    arbitrary background dragging remains unavailable.




  • The bundled first-party catalog pins marketplace revision

    d8640b17f27542e7122c76368724196f92a0af61, so installing Computer Use from

    the Extensions listing fetches the same 0.11.2 source the binary already

    carries.




  • Materializing is not enabling: the built-in bundle is written under

    $CODEWHALE_HOME/builtin-plugins on first run but stays NeverReviewed,

    so Computer Use is never switched on without an explicit capability review.




Removed



  • The host no longer parses prose into goals. Ten phrasings and a clause

    allow-list ("make it your /goal to …") were turned into durable goals before

    the provider call; prose now reaches the model, which calls create_goal when

    a goal is useful. The deterministic path — a leading /goals <objective> — is

    unchanged.


Fixed




  • A thinking fold is an absolute choice again. The stored bit was relative to the

    display preference (folded ^ !(verbose || thinking_default_expanded)), so

    every recorded choice flipped meaning the moment a preference changed: turning

    thinking_default_expanded on closed a block the reader had explicitly

    expanded (#5847). An explicit tri-state intent now records Expanded or

    Collapsed outright, and the absence of an entry means untouched, so the

    preference baseline decides that cell's default. Space still toggles, and an

    untouched cell still follows verbose || thinking_default_expanded.




  • A terminal byte-stream cursor past the head is clamped instead of echoed back.

    read_since returned a future cursor as next_cursor, so a client that

    continued from it skipped every byte the stream produced before reaching that

    position — permanently. The start position now clamps to total: a future

    cursor reads nothing, is not a gap, and hands back the head.




  • Language-server startup is bounded and a failed transport now terminates. The

    client waits for successful initialization before sending notifications,

    drains stderr without buffering it, bounds request queueing and replies, caps

    protocol frames, and fails pending requests when the child transport dies.




  • Input no longer freezes for the rest of a turn when the engine's 32-slot op

    mailbox is full. The remaining input-path sends no longer await: droppable ops

    whose rejection is reported and retryable use try_send (CancelSubAgent,

    PreviewOutboundRequest, bang shell input, PurgeContext, and the single-op

    settings updates), ops that must land once the UI changed reserve first, and

    ChangeMode publishes its live authority even on a full channel. Must-deliver

    ordered transitions still await, and say why at EngineHandle::send (#6150).




  • The pet's whale is one body again. The same authored point set is checked in

    three copies plus four fixtures, and the Rust and TypeScript cores disagreed

    on particle positions from frame 0 while agreeing on every channel and

    constant — so the v1 fixtures had never matched what Rust produced and the

    conformance job had never passed. The bodies and the fixtures are reconciled

    and that check now runs green.




  • The context meter and the auto-compact gate share one honest estimator. The

    status bar inflated ctx % by about half and disagreed with the gate, so

    "ctx 82%" could sit beside a /compact that refused to run; displayed

    percentages now read materially lower because they are correct (#6297).




  • A steer the engine never accepted is queued for the next turn instead of

    being shown as held and then silently dropped with no turn and no answer

    (#6297).




  • Every reqwest client routes through codewhale_release::tls. A bare

    Client::builder() panics under rustls with no installed provider; 17 call

    sites were swept.




  • The bundled OpenAI-compatible hosts have their /provider rows back.

    Retiring the ProviderSetupTemplate layer moved SenseNova, Baseten, Groq,

    Cerebras, DashScope and Command Code into provider_descriptors.json and

    then wired that file to nothing, so six vendors silently lost their picker

    rows; AICraft never had one. Each descriptor is a row again, built through

    the same named-custom-provider builder a configured host uses, so endpoint,

    bootstrap model and "missing <ENV>" reporting all come from one place. A

    descriptor whose id or alias already names a [providers.*] entry is

    dropped, so a configured row stays the only one. These rows are an

    invitation, not a route: they are not is_configured, and only the form's

    submit writes anything (#6289).




  • A StepFun Step Plan subscription reaches its own catalog. A subscriber's

    base_url is https://api.stepfun.ai/step_plan/v1, but only the

    pay-as-you-go /v1 host was recognised as official, so the Step Plan host

    read as a custom endpoint, the catalog was withheld, and the picker showed

    0 bundled and a guessed context window for a route whose console

    advertises step-5-preview at 1M context. The model was in the seed the

    whole time. All four StepFun hosts — global (.ai) and China (.com), each

    with a /v1 and a /step_plan/v1 surface — are now recognised; a host

    StepFun does not own stays custom and keyless, since this predicate also

    scopes credentials.




  • The send cue stopped strobing while you type. [↵] flickered between dim

    [·] and bold blue once per character at an ordinary typing pace. The cue

    was not lying — Enter really does insert a newline during the ~120 ms

    paste-safety window, which every keystroke re-armed — but that window only

    exists for terminals that deliver a paste as a burst of ordinary keystrokes.

    Ghostty, iTerm2, WezTerm, Windows Terminal and Terminal.app now skip the

    heuristic from the first keystroke instead of waiting for proof by paste.




  • Shift+Tab sets the permission posture in Plan. Tab cycles the mode and

    Shift+Tab cycles Ask/Auto-Review/Full Access, but Plan refused the second

    one outright, so the key silently did nothing there and the two axes read as

    welded together. Plan's read-only guarantee comes from the mode, not the

    posture — authority maps (Plan, _, Bypass) to SandboxPolicy::ReadOnly

    and tool_catalog gates every write tool on mode != Plan — so the cycle

    now moves the durable Act/Operate baseline while Plan's live policy stays

    Suggest, and a toast says the posture lands when the mode leaves Plan.




  • A steer delivered mid-turn now clears its pending card. The transcript

    showed the message and the model answered it, while the "sending into this

    turn" card still listed it as pending: turn_loop commits a steer trimmed,

    but the UI handed the engine the untrimmed text and kept that same copy for

    matching, so a composer newline made the two differ by whitespace alone and

    the steer was never promoted to a transcript cell. The text is trimmed once

    at the source that feeds both, so they are the same string by construction;

    the match stays an exact ==.




  • A Xiaomi MiMo key no longer fails verification with another vendor's 401.

    The legacy top-level base_url is a DeepSeek field, and a route without an

    endpoint of its own inherited it — so a config carrying

    base_url = "https://api.deepseek.com" made that host the MiMo route's

    endpoint. The custom-endpoint guard correctly withheld the MiMo credential

    from a host the route does not own, and the setup wizard's probe, which

    bypassed the guard, sent the key as api-key: — a header DeepSeek ignores.

    The result was HTTP 401 Unauthorized: Authentication Fails (governor),

    DeepSeek's unauthenticated 401, shown to someone who believed they were

    testing their own key. Every layer that reads the root now inherits it only

    when the URL belongs to that provider's own official endpoint family;

    DeepSeek, which owns the field, is unchanged, and any other host is still

    expressible on [providers.xiaomi_mimo] base_url. Key verification

    failures now also name the endpoint that was probed, so a wrong endpoint

    reads as a wrong endpoint instead of a bad key.




  • The Extensions panel can act on the rows it shows. Every plugin now carries

    its on/off switch — Space, or e — including one that has never been

    reviewed: /plugin enable already routes an unreviewed bundle into the

    exact-capability review and only flips the switch once you confirm the

    digest, so withholding the control bought no safety and left the shipped

    computer-use bundle reading disabled with nothing that could enable it.




  • The panel stopped saying "untrusted". A bundle that is waiting on its

    capability review now reads needs review — off · needs review when the

    switch is off too — and its detail line says what Codewhale is withholding

    and which key ends the wait, instead of restating an internal pair of

    booleans. Enter's verb on that row is review, not inspect.




  • MCP servers say where they live, and mutations write there. Each row is

    labelled global, project, or plugin: <name>. Enabling, disabling or

    removing a workspace-scoped server previously edited the user's global file

    and failed with "MCP server '' not found" on a row the panel had just

    offered; the write now lands in the file that declares the server, and a

    plugin-contributed server says it is switched off by disabling its plugin.




  • The permanent "Plugins · Problems: N" footer chip is gone. It could not be

    acted on from the footer, and its count and the Plugins tab disagreed by

    construction — the chip counted bundles waiting on a review while the tab's

    Problems group lists only registry-level diagnostics, so the rows behind the

    number were never the rows you found. A bundle waiting on a review is a row

    with an action, and /plugins states it per bundle next to the key that

    resolves it.




  • The Extensions marketplace no longer advertises what it cannot install.

    Browser Use and the sandbox runtime were pinned rows whose only possible

    action was unavailable; they are removed, along with the browser-driver

    and sandbox-runtime component vocabulary that existed solely to describe

    them.




  • Configuration parsing keeps the parsed base config boxed, so loading a

    profile no longer carries the full Config by value through the

    deserializer and overflows a default 2 MiB test-thread stack; the

    runtime-store binding test that also overflowed is split into phases and

    pinned to that budget so CI's larger stack cannot mask a regression

    (#6362).




  • Stopping a turn revokes its pending approvals. A late approval cannot resume

    the cancelled action or save an automatic approval for later turns.




  • Expanding and collapsing selected reasoning now matches its rendered state

    when verbose mode and the default-expansion preference are both enabled.




  • Branch navigation preserves sibling histories, stable entry IDs and timestamps

    through autosave, resume and forks, and synchronizes the selected branch into

    the live engine. Thanks to @7jrxt42BxFZo4iAnN4CX for the report (#6367).




  • Compaction now writes local diagnostic records for completed passes and

    automatic refusals. codewhale metrics reports them with summarizer token

    usage; text-mode exec retains its session after attempting compaction.

    Historical artifacts are not backfilled. Thanks to @7jrxt42BxFZo4iAnN4CX

    for identifying the missing producer (#6368).




  • The opening workbench retains the canonical Codewhale mark in a responsive

    header while keeping recent-session titles full-width and actions clickable.




  • serve --acp no longer ignores the approval posture. The ACP adapter

    hardcoded ApprovalMode::Suggest, so --yolo (and any configured

    approval_policy) never reached admission: every mutating tool parked

    behind a permission request no unattended client answers, and sessions

    executed zero tools. Posture now derives from server config — --yolo

    pre-approves prompts and flows into the sandbox policy — while hard blocks

    (safety floor, repo law, reviewer consult) and the Plan read-only guardrail

    stay intact (#6337).




  • Plain agent spawns could not resolve. built_in_members() seeded both

    general and worker, and the role parse boundary migrates worker to

    general, so both canonicalized to the same role — and role:general, the

    selector the roster advertises for the default posture, matched two members

    and raised Ambiguous every time, permanently. The duplicate built-in is

    gone. The legacy name still resolves: general, member:general,

    role:general and default all land on the worker posture through the

    identity selector rather than through a second member, which is what allowed

    the duplicate to be removed (#6244).




  • Clicking a path:line in tool output no longer spawns $EDITOR detached

    while the TUI still owns the terminal, and no longer spawns one editor per

    matching line. The launch goes through the single terminal-handoff path, and

    a click is one request to open one file (#6235).




  • A write-scope contention refusal now names a remedy that works. The agent

    tool's description claimed release was "the remediation a write-scope

    contention refusal names"; the refusal did not name it, and pointing back at

    it would have been worse, because release only clears claims whose owner is

    no longer running while a contention refusal names a live one. The refusal

    itself now says to wait for that owner to settle or cancel it (#6272).




  • The session picker no longer refuses a saved session whose Runtime store

    exists but holds nothing. A force-quit leaves the store on disk, ownerless

    and empty, and the switch path refused it because recovery only covered a

    missing store. A switch now also adopts a store that is provably empty

    (every work directory, plus the event sequence that remembers pruned

    appends) and provably unheld (the process-owner lock, which a live

    manager holds from open to close), with no automation pinned to its

    execution scope — and the save gate treats that shape as abandonable too,

    so the repaired binding persists. The first fix was reverted on a race

    (emptiness without liveness); this reland checks the lock first (#6207).




  • Double-tap Enter now sends every queued follow-up into the running turn,

    oldest first. The second Enter used to steer only the most recent message

    and leave older ones queued; a failed steer restores the failed message

    plus everything unattempted in original order, so nothing is lost or

    reordered.




  • Only the most recently sent prompt carries the elevated-surface background

    now; every older prompt renders on the bare ground. The fill used to sit

    behind every user row (striping), then behind none; newest-only keeps the

    eye on the turn in play. Sending a new prompt moves the highlight and

    un-highlights its predecessor.




  • Diff rows tint whole: added/deleted line numbers now share the row's green

    / red background instead of sitting bare next to a painted body. Context

    rows stay on the bare ground.




  • MCP connections are supervised now: a background task notices a dead

    server within one sweep, reconnects on the existing backoff ladder, and

    reports each transition, so Extensions rows flip with liveness instead

    of parking on stale-ready or a silent [reconnect]. Five consecutive

    failures park the server with a notice naming /mcp retry; an explicit

    retry or a fresh connection resumes watching. Tool calls also retry

    once across a dead pipe/socket (not just stale sessions), and a

    reconnect that fails reports both errors instead of swallowing the

    original (#6187; list_changed catalog refresh stays open).




  • A steer the engine never delivered is no longer reported as sent. The runtime

    API persisted the steer item as already-Completed and emitted

    turn.steered + item.completed the moment the text entered the engine's

    mailbox — before the engine decided anything. The engine discards a steer

    whose turn has moved on, and an interrupted or failed turn drops whatever it

    had queued, so a GUI could show "Guidance sent", clear the composer, and lose

    the user's words. The engine now returns a verdict for every steer on every

    exit path, the item settles completed or canceled to match, a dropped

    steer emits turn.steer_dropped and answers 409 so a client can resend,

    and steer_count counts steers the model actually received (#6276).




  • <recommended_plugins> suggestions stop nagging: a plugin id is now

    injected at most once per engine lifetime, and a plugin whose name a

    loaded skill already covers is never suggested — the local skill owns

    the domain, so the nudge was noise. Dismissals still apply, and the

    fragment stays append-only on the user turn (#6274).




  • A canceled automation run now settles with a transcript receipt that names

    the cancellation (by request, cancel timeout, or shutdown) instead of

    vanishing from the live band silently. The receipt wears attention ink and

    never lights the failure demand; the run record keeps the cancellation

    reason as its error detail. (#6162)




  • A failed workflow run no longer settles silently: its terminal failure

    raises a sticky error toast naming the cause (dispatch, schema, or script

    errors), alongside the existing panel state (#5528).




  • MCP OAuth re-login now forces the provider's consent screen: logout only

    clears the local token, so without a prompt the provider silently

    re-granted the same account/workspace and a re-login could never change

    it. /mcp logout and codewhale mcp logout also say plainly that they

    clear local credentials only (#6040).




  • Session retention no longer deletes transcripts once the store reaches the

    cap: the oldest active session is archived — still openable from the

    picker's archived view — instead of being unlinked, and archived records

    sit outside the cap until they are pruned (#6136).




  • Empty auto-created "New Session" stubs are capped separately (the ten

    newest are kept) and can no longer occupy a real transcript's slot in the

    session cap (#6137).




  • A failed resume or session load is now a durable transcript error instead

    of a status line the next footer update replaces, so a resume that cannot

    restore its target no longer looks like a silent new session (#6138).




  • Compaction no longer retains a tool result whose tool call was summarized

    away: an older turn that mixes text with a tool result keeps its text and

    drops the orphaned result blocks, which providers reject outright (#6119).




  • Automation runs that need a tool approval no longer die as silent

    idle-timeout cancels: a pending approval suspends the idle watchdog for its

    decision window, and an unanswered window settles the run Failed with the

    recorded reason instead of a silent Canceled (#6118).




  • /mcp no longer freezes the console while a turn is running: the panel

    opens immediately from the last known MCP snapshot with a receipt naming

    the wait, and live-pool mutations say their refresh is deferred instead of

    parking the UI event loop behind the running turn (#6159).




  • MCP OAuth login no longer fails with "Authorization server response missing

    required issuer" against servers that implement RFC 9207, such as

    Cloudflare's mcp.cloudflare.com. The local callback listener now keeps the

    iss parameter from the redirect and hands it to the token exchange so the

    callback binds to the discovered issuer; servers that do not send iss

    keep working unchanged. (#6157)




Contributors



  • @AdityaVG13 — fixed composer wrapping, tab/caret placement, pasted and editor-returned draft history, painted-column transcript copying, explicit terminal foregrounds, headless user-input tool availability, and engine synchronization after importing foreign sessions (#6369, #6363, #6365).

  • @aboimpinto — moved the TUI session-export slice onto shared command contracts (FEAT-025): a session-export contract facet with one shared sanitizer, /export routed through the facet, pinned with baseline-captured goldens and gates (#6096).

  • @BX166 — contributed the AICraft provider template and its documentation (#6171). It was closed unmerged, but it is what surfaced the decision to stop special-casing named OpenAI-compatible hosts (#6289).

  • @7jrxt42BxFZo4iAnN4CX — reported the session-retention defects behind archive-past-the-cap and empty-session cap occupancy (#6136, #6137), the resume-failure design behind durable transcript errors (#6138), and the gaps behind the opt-in approval timeout (#6101), codewhale exec --hooks (#6099), Markdown drag-copy (#6156), and the browsable, current-aware session picker (#6014); the goal token-budget hard stop (#6013) and the fleet no-progress guard shared with child workers (#6015) landed as first slices of two larger proposals, and the runtime-store session refusal (#6207).

  • @Lstarsky0 — reported TUI tests reading machine state instead of hermetic fixtures; the lock_test_env remedy from that report shaped two more hermetic fixes, for the shared UI fixtures and the compaction budget test (#5359).

  • @Lujc0523 — reported /hooks edit splitting keystrokes between the editor and the composer, fixed by pausing the TUI input pump inside the editor handoff (#6165).

  • @Statter — reported the Gemini /models failure that now surfaces the provider's reason instead of an empty error (#6173).

  • @sequico — reported the ACP session/new ids that session/load could not resolve, fixed by minting resolvable session ids (#6174).

  • @bevis-wong — reported the mid-run engine freeze behind the bounded turn-end foreground-child join, and the resume path that re-ran identical tool-call repair on every load instead of persisting it (#6184, #6185).

  • @gaord — recorded the mode each turn ran in (#6321, harvested), stated the approval posture a task thread starts on (#6386), and rebuilt the runtime-API thread summary in one store pass (#6376).

  • @zhuowp — preserved chat roles across compaction, protected user turns on recompaction, and kept the operate contract intact (#6286).

  • @h3c-hexin — rate-limit-adaptive subagent launch scheduling: the DynamicGate that replaces fixed spawn pacing under provider throttling (#6055, harvested).

  • @asto18089 — co-authored the rate-limit-adaptive launch scheduling work (#6055).

  • @yrk111222 — ModelScope provider support, landed through the shared ChildGrant fleet authority (#6299, harvested).

  • @xiechimon — capped child tool results at capture time rather than at render (#6294, harvested).

  • @VincentCorleone — defined and implemented the weixin-bridge Quick Start so a first run works from the README alone (#6170, harvested).

  • @Serendo — fixed the /config theme editor exiting the panel on an arrow key (#6336).

  • @yetuge — dropped the retired token_budget field from the subagent documentation (#6335).

  • @Water-Run — ingested namespaced model-only catalog entries so models present only in the canonical models map reach the offering list (#6400); translated the local browser client guide into Simplified Chinese (#6401); and retired the blanket dead-code allowance with its unused feature stages, tightening the budget to match (#6402).


See CHANGELOG.md for full notes and docs/CHANGELOG_ARCHIVE.md for older releases.

Zum Aktualisieren ziehen
Nächster Beitrag