chore(release): prepare codewhale v0.8.41 test build

This commit is contained in:
Hunter Bown
2026-05-23 13:09:30 -05:00
parent f10e8de45d
commit 6de8ba363f
22 changed files with 346 additions and 216 deletions
+123 -71
View File
@@ -1,78 +1,112 @@
# CNB is a one-way mirror from GitHub. Keep this file source-controlled here;
# CNB-side edits will be overwritten by the GitHub -> CNB sync workflow.
.feishu_bridge_tests: &feishu_bridge_tests
name: feishu bridge tests
runner:
tags: cnb:arch:amd64
cpus: 8
docker:
image: node:22-bookworm
stages:
- name: feishu bridge tests
script: |
set -euo pipefail
cd integrations/feishu-bridge
npm ci
npm run check
npm test
.linux_rust_gates: &linux_rust_gates
name: linux rust gates
runner:
tags: cnb:arch:amd64
cpus: 16
docker:
image: rust:1.88-bookworm
stages:
- name: install linux dependencies
script: |
set -euo pipefail
apt-get update
apt-get install -y git libdbus-1-dev nodejs npm pkg-config
if command -v rustup >/dev/null 2>&1; then
rustup component add rustfmt clippy
fi
- name: rust workspace gates
script: |
set -euo pipefail
./scripts/release/check-versions.sh
cargo fmt --all -- --check
cargo check --workspace --all-targets --locked
cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
cargo test --workspace --all-features --locked
- name: linux npm wrapper smoke
script: |
set -euo pipefail
cargo build --release --locked -p codewhale-cli -p codewhale-tui
node scripts/release/npm-wrapper-smoke.js
./target/release/codewhale --version
./target/release/codewhale-tui --version
./target/release/deepseek --version
./target/release/deepseek-tui --version
.linux_release_preflight: &linux_release_preflight
name: linux release preflight
runner:
tags: cnb:arch:amd64
cpus: 16
docker:
image: rust:1.88-bookworm
stages:
- name: install release dependencies
script: |
set -euo pipefail
apt-get update
apt-get install -y curl git libdbus-1-dev nodejs npm pkg-config
if command -v rustup >/dev/null 2>&1; then
rustup component add rustfmt clippy
fi
- name: rust workspace gates
script: |
set -euo pipefail
./scripts/release/check-versions.sh
cargo fmt --all -- --check
cargo check --workspace --all-targets --locked
cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
cargo test --workspace --all-features --locked
- name: crate publish dry-run
script: |
set -euo pipefail
./scripts/release/publish-crates.sh dry-run
- name: release binary smoke
script: |
set -euo pipefail
cargo build --release --locked -p codewhale-cli -p codewhale-tui
node scripts/release/npm-wrapper-smoke.js
./target/release/codewhale --version
./target/release/codewhale-tui --version
./target/release/deepseek --version
./target/release/deepseek-tui --version
main:
push:
- docker:
image: node:22-bookworm
stages:
- name: feishu bridge tests
script: |
set -euo pipefail
cd integrations/feishu-bridge
npm ci
npm run check
npm test
- *feishu_bridge_tests
- *linux_rust_gates
- docker:
image: rust:1.88-bookworm
stages:
- name: release version check
script: |
set -euo pipefail
apt-get update
apt-get install -y git libdbus-1-dev nodejs pkg-config
./scripts/release/check-versions.sh
"work/v*-stability":
"(fix/*|rebrand/*)":
push:
- name: feishu bridge release preflight
runner:
tags: cnb:arch:amd64
cpus: 8
docker:
image: node:22-bookworm
stages:
- name: feishu bridge tests
script: |
set -euo pipefail
cd integrations/feishu-bridge
npm ci
npm run check
npm test
- *linux_rust_gates
- name: linux release preflight
runner:
tags: cnb:arch:amd64
cpus: 16
docker:
image: rust:1.88-bookworm
stages:
- name: install release dependencies
script: |
set -euo pipefail
apt-get update
apt-get install -y git libdbus-1-dev nodejs npm pkg-config
if command -v rustup >/dev/null 2>&1; then
rustup component add rustfmt clippy
fi
- name: rust workspace gates
script: |
set -euo pipefail
./scripts/release/check-versions.sh
cargo fmt --all -- --check
cargo check --workspace --all-targets --locked
cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
cargo test --workspace --all-features --locked
- name: release binary smoke
script: |
set -euo pipefail
cargo build --release --locked -p deepseek-tui-cli -p deepseek-tui
node scripts/release/npm-wrapper-smoke.js
./target/release/deepseek --version
./target/release/deepseek-tui --version
"work/v*":
push:
- *feishu_bridge_tests
- *linux_release_preflight
$:
tag_push:
@@ -87,17 +121,29 @@ $:
apt-get install -y git libdbus-1-dev nodejs pkg-config
./scripts/release/check-versions.sh
cargo build --release --locked -p deepseek-tui-cli -p deepseek-tui
cargo build --release --locked -p codewhale-cli -p codewhale-tui
mkdir -p target/cnb-release
cp target/release/codewhale target/cnb-release/codewhale-linux-x64
cp target/release/codewhale-tui target/cnb-release/codewhale-tui-linux-x64
cp target/release/deepseek target/cnb-release/deepseek-linux-x64
cp target/release/deepseek-tui target/cnb-release/deepseek-tui-linux-x64
strip target/cnb-release/deepseek-linux-x64 target/cnb-release/deepseek-tui-linux-x64 || true
strip \
target/cnb-release/codewhale-linux-x64 \
target/cnb-release/codewhale-tui-linux-x64 \
target/cnb-release/deepseek-linux-x64 \
target/cnb-release/deepseek-tui-linux-x64 \
|| true
(
cd target/cnb-release
sha256sum deepseek-linux-x64 deepseek-tui-linux-x64 \
> deepseek-artifacts-sha256.txt
sha256sum \
codewhale-linux-x64 \
codewhale-tui-linux-x64 \
deepseek-linux-x64 \
deepseek-tui-linux-x64 \
> codewhale-artifacts-sha256.txt
cp codewhale-artifacts-sha256.txt deepseek-artifacts-sha256.txt
)
tag_name="${CNB_BRANCH:-}"
@@ -118,6 +164,9 @@ $:
echo "Built by CNB from ${commit_sha}."
echo
echo "Assets:"
echo "- codewhale-linux-x64"
echo "- codewhale-tui-linux-x64"
echo "- codewhale-artifacts-sha256.txt"
echo "- deepseek-linux-x64"
echo "- deepseek-tui-linux-x64"
echo "- deepseek-artifacts-sha256.txt"
@@ -133,6 +182,9 @@ $:
image: cnbcool/attachments:latest
settings:
attachments:
- target/cnb-release/codewhale-linux-x64
- target/cnb-release/codewhale-tui-linux-x64
- target/cnb-release/codewhale-artifacts-sha256.txt
- target/cnb-release/deepseek-linux-x64
- target/cnb-release/deepseek-tui-linux-x64
- target/cnb-release/deepseek-artifacts-sha256.txt
+23 -46
View File
@@ -22,15 +22,6 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: Install Linux system dependencies
if: runner.os == 'Linux'
run: |
for i in 1 2 3 4 5; do
sudo apt-get update && break
echo "apt-get update failed (attempt $i); retrying in 15s"
sleep 15
done
sudo apt-get install -y libdbus-1-dev pkg-config
- uses: actions/setup-node@v4
with:
node-version: 20
@@ -44,55 +35,41 @@ jobs:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy, rustfmt
- name: Install Linux system dependencies
if: runner.os == 'Linux'
run: |
for i in 1 2 3 4 5; do
sudo apt-get update && break
echo "apt-get update failed (attempt $i); retrying in 15s"
sleep 15
done
sudo apt-get install -y libdbus-1-dev pkg-config
- uses: Swatinem/rust-cache@v2
with:
cache-bin: false
components: rustfmt
- name: Check formatting
run: cargo fmt --all -- --check
# Mirror the release-workflow `parity` gate exactly. Anything that
# would fail there must fail here so we never push a `v*` tag that
# the npm publish pipeline can't ship. The Release job runs with
# `--locked` + `-D warnings`; we do the same.
- name: Clippy (release-strict)
run: cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
- name: Linux clippy location
run: echo "Linux clippy/test gates run on CNB for mirrored fix/*, rebrand/*, work/v*, and main branches."
test:
name: Test
runs-on: ${{ matrix.os }}
strategy:
matrix:
# Linux workspace tests moved to CNB; GitHub keeps the platform
# coverage CNB cannot provide.
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v4
if: runner.os != 'Linux'
- uses: dtolnay/rust-toolchain@stable
- name: Install Linux system dependencies
if: runner.os == 'Linux'
run: |
for i in 1 2 3 4 5; do
sudo apt-get update && break
echo "apt-get update failed (attempt $i); retrying in 15s"
sleep 15
done
sudo apt-get install -y libdbus-1-dev pkg-config
if: runner.os != 'Linux'
- uses: Swatinem/rust-cache@v2
if: runner.os != 'Linux'
with:
cache-bin: false
- name: Run tests
if: runner.os != 'Linux'
run: cargo test --workspace --all-features --locked
- name: Lockfile drift guard
if: runner.os != 'Linux'
run: git diff --exit-code -- Cargo.lock
- name: Run Offline Eval Harness
if: runner.os != 'Linux'
run: cargo run -p codewhale-tui --all-features -- eval
- name: Linux test location
if: runner.os == 'Linux'
run: echo "Linux workspace tests run on CNB for mirrored first-party branches."
npm-wrapper-smoke:
name: npm wrapper smoke
@@ -103,26 +80,26 @@ jobs:
os: ${{ fromJSON(github.event_name == 'pull_request' && '["ubuntu-latest"]' || '["ubuntu-latest","macos-latest","windows-latest"]') }}
steps:
- uses: actions/checkout@v4
if: runner.os != 'Linux'
- uses: dtolnay/rust-toolchain@stable
- name: Install Linux system dependencies
if: runner.os == 'Linux'
run: |
for i in 1 2 3 4 5; do
sudo apt-get update && break
echo "apt-get update failed (attempt $i); retrying in 15s"
sleep 15
done
sudo apt-get install -y libdbus-1-dev pkg-config
if: runner.os != 'Linux'
- uses: actions/setup-node@v4
if: runner.os != 'Linux'
with:
node-version: 20
- uses: Swatinem/rust-cache@v2
if: runner.os != 'Linux'
with:
cache-bin: false
- name: Build wrapper binaries
if: runner.os != 'Linux'
run: cargo build --release --locked -p codewhale-cli -p codewhale-tui
- name: Smoke wrapper install and delegated entrypoints
if: runner.os != 'Linux'
run: node scripts/release/npm-wrapper-smoke.js
- name: Linux smoke location
if: runner.os == 'Linux'
run: echo "Linux npm wrapper smoke runs on CNB for mirrored first-party branches."
# Check documentation builds without warnings
docs:
+8 -4
View File
@@ -7,7 +7,8 @@ name: Sync to CNB
# Triggers:
# * push to main → mirrors that commit to CNB main
# * tag matching v* → mirrors that tag to CNB
# * release stability branches→ mirrors release-candidate refs for CNB preflight
# * release work branches → mirrors release-candidate refs for CNB preflight
# * fix/rebrand branches → mirrors first-party heavy Linux CI refs
# * Tencent release branches → mirrors Feishu/Lighthouse setup branches
# * workflow_dispatch → manual fallback if any of the above fails
#
@@ -26,7 +27,9 @@ on:
push:
branches:
- main
- 'work/v*-stability'
- 'work/v*'
- 'fix/*'
- 'rebrand/*'
- 'work/v*-feishu-*'
- 'work/v*-lighthouse*'
tags: ['v*']
@@ -111,8 +114,9 @@ jobs:
# was actually behind GitHub.
push_with_retry "main" HEAD:refs/heads/main --force
else
# Tencent release-candidate branches are first-class CNB
# sources for release preflight and Lighthouse/Feishu bootstrap.
# First-party fix/rebrand/release branches are first-class CNB
# sources for heavy Linux CI, release preflight, and
# Lighthouse/Feishu bootstrap.
# Mirror the triggering branch exactly so the CNB clone path stays
# useful before the branch has merged to main or become a release
# tag.
+41 -1
View File
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [0.8.41] - 2026-05-23
### Changed
- **Project renamed to codewhale.** The canonical CLI dispatcher is now
@@ -30,6 +32,43 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
cycle as a no-`bin` deprecation shim whose postinstall directs users
to `npm install -g codewhale`. It will be removed in v0.9.0.
### Fixed
- **Windows CI spillover tests are isolated.** Tool-result deduplication
tests now use a temporary spillover root guarded by the existing global
spillover mutex, removing the shared-state race that made Windows CI fail
unrelated PRs (#1943).
- **Terminated sub-agents keep `agent_eval` recoverable.** Evaluating a
completed child session now returns the available transcript result instead
of losing the final output (#1738, #1928).
- **Bare `@/` completions no longer freeze the TUI.** File-mention
completion skips bare separator and dot tokens so Windows/WSL2 workspaces
do not trigger an eager 4096-entry filesystem walk on the UI thread
(#1921, #1929).
- **Enter paths avoid synchronous UI-thread waits.** Composer history writes,
offline queue persistence, feedback URL launching, and clipboard fallback
helpers now run off the hot Enter path where appropriate (#1927, #1931,
#1940, #1941, #1944).
- **tmux and screen sessions stop idling as terminal activity.** Terminal
multiplexers now force low-motion behavior and pin the fallback footer label
so passive animations do not trip activity monitors (#1925, #1942).
- **Composer sanitization catches OSC 8 and Kitty fragments.** The input
sanitizer now strips common hyperlink and keyboard-protocol fragments that
leaked into drafts while preserving ordinary prose (#1915, #1933).
- **The Work sidebar hides stale completed tasks.** Terminal task records older
than the current session and outside the recent-completion window no longer
crowd active Work sidebar rows (#1913, #1930).
- **V4 Pro pricing docs reflect permanent rates.** The English, Simplified
Chinese, and Japanese READMEs now describe the V4 Pro pricing change as
permanent instead of temporary (#1923, #1932).
### Thanks
Thanks to **OpenWarp ([@zerx-lab](https://github.com/zerx-lab))** for
prioritizing codewhale support and collaborating on terminal-agent UX.
Thanks to **[@leo119](https://github.com/leo119)** for the update-command
documentation lineage now preserved through the rename.
## [0.8.40] - 2026-05-21
### Added
@@ -4556,7 +4595,8 @@ Welcome — and thank you.
- Hooks system and config profiles
- Example skills and launch assets
[Unreleased]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.8.40...HEAD
[Unreleased]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.8.41...HEAD
[0.8.41]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.8.40...v0.8.41
[0.8.40]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.8.39...v0.8.40
[0.8.39]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.8.38...v0.8.39
[0.8.38]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.8.37...v0.8.38
Generated
+14 -14
View File
@@ -803,7 +803,7 @@ checksum = "e9b18233253483ce2f65329a24072ec414db782531bdbb7d0bbc4bd2ce6b7e21"
[[package]]
name = "codewhale-agent"
version = "0.8.40"
version = "0.8.41"
dependencies = [
"codewhale-config",
"serde",
@@ -811,7 +811,7 @@ dependencies = [
[[package]]
name = "codewhale-app-server"
version = "0.8.40"
version = "0.8.41"
dependencies = [
"anyhow",
"axum",
@@ -833,7 +833,7 @@ dependencies = [
[[package]]
name = "codewhale-cli"
version = "0.8.40"
version = "0.8.41"
dependencies = [
"anyhow",
"chrono",
@@ -858,7 +858,7 @@ dependencies = [
[[package]]
name = "codewhale-config"
version = "0.8.40"
version = "0.8.41"
dependencies = [
"anyhow",
"codewhale-secrets",
@@ -870,7 +870,7 @@ dependencies = [
[[package]]
name = "codewhale-core"
version = "0.8.40"
version = "0.8.41"
dependencies = [
"anyhow",
"chrono",
@@ -888,7 +888,7 @@ dependencies = [
[[package]]
name = "codewhale-execpolicy"
version = "0.8.40"
version = "0.8.41"
dependencies = [
"anyhow",
"codewhale-protocol",
@@ -897,7 +897,7 @@ dependencies = [
[[package]]
name = "codewhale-hooks"
version = "0.8.40"
version = "0.8.41"
dependencies = [
"anyhow",
"async-trait",
@@ -911,7 +911,7 @@ dependencies = [
[[package]]
name = "codewhale-mcp"
version = "0.8.40"
version = "0.8.41"
dependencies = [
"anyhow",
"serde",
@@ -920,7 +920,7 @@ dependencies = [
[[package]]
name = "codewhale-protocol"
version = "0.8.40"
version = "0.8.41"
dependencies = [
"serde",
"serde_json",
@@ -928,7 +928,7 @@ dependencies = [
[[package]]
name = "codewhale-secrets"
version = "0.8.40"
version = "0.8.41"
dependencies = [
"dirs",
"keyring",
@@ -941,7 +941,7 @@ dependencies = [
[[package]]
name = "codewhale-state"
version = "0.8.40"
version = "0.8.41"
dependencies = [
"anyhow",
"chrono",
@@ -953,7 +953,7 @@ dependencies = [
[[package]]
name = "codewhale-tools"
version = "0.8.40"
version = "0.8.41"
dependencies = [
"anyhow",
"async-trait",
@@ -966,7 +966,7 @@ dependencies = [
[[package]]
name = "codewhale-tui"
version = "0.8.40"
version = "0.8.41"
dependencies = [
"anyhow",
"arboard",
@@ -1031,7 +1031,7 @@ dependencies = [
[[package]]
name = "codewhale-tui-core"
version = "0.8.40"
version = "0.8.41"
[[package]]
name = "colorchoice"
+1 -1
View File
@@ -19,7 +19,7 @@ default-members = ["crates/cli", "crates/app-server", "crates/tui"]
resolver = "2"
[workspace.package]
version = "0.8.40"
version = "0.8.41"
edition = "2024"
# Rust 1.88 stabilized `let_chains` in `if`/`while` conditions, which the
# codebase relies on extensively. Cargo enforces this so users on older
+1 -1
View File
@@ -7,5 +7,5 @@ repository.workspace = true
description = "Model/provider registry and fallback strategy for DeepSeek workspace architecture"
[dependencies]
codewhale-config = { path = "../config", version = "0.8.40" }
codewhale-config = { path = "../config", version = "0.8.41" }
serde.workspace = true
+9 -9
View File
@@ -10,15 +10,15 @@ description = "Codex-style app-server transport for DeepSeek workspace architect
anyhow.workspace = true
axum.workspace = true
clap.workspace = true
codewhale-agent = { path = "../agent", version = "0.8.40" }
codewhale-config = { path = "../config", version = "0.8.40" }
codewhale-core = { path = "../core", version = "0.8.40" }
codewhale-execpolicy = { path = "../execpolicy", version = "0.8.40" }
codewhale-hooks = { path = "../hooks", version = "0.8.40" }
codewhale-mcp = { path = "../mcp", version = "0.8.40" }
codewhale-protocol = { path = "../protocol", version = "0.8.40" }
codewhale-state = { path = "../state", version = "0.8.40" }
codewhale-tools = { path = "../tools", version = "0.8.40" }
codewhale-agent = { path = "../agent", version = "0.8.41" }
codewhale-config = { path = "../config", version = "0.8.41" }
codewhale-core = { path = "../core", version = "0.8.41" }
codewhale-execpolicy = { path = "../execpolicy", version = "0.8.41" }
codewhale-hooks = { path = "../hooks", version = "0.8.41" }
codewhale-mcp = { path = "../mcp", version = "0.8.41" }
codewhale-protocol = { path = "../protocol", version = "0.8.41" }
codewhale-state = { path = "../state", version = "0.8.41" }
codewhale-tools = { path = "../tools", version = "0.8.41" }
serde.workspace = true
serde_json.workspace = true
tokio.workspace = true
+7 -7
View File
@@ -20,13 +20,13 @@ path = "src/bin/deepseek_legacy_shim.rs"
anyhow.workspace = true
clap.workspace = true
clap_complete.workspace = true
codewhale-agent = { path = "../agent", version = "0.8.40" }
codewhale-app-server = { path = "../app-server", version = "0.8.40" }
codewhale-config = { path = "../config", version = "0.8.40" }
codewhale-execpolicy = { path = "../execpolicy", version = "0.8.40" }
codewhale-mcp = { path = "../mcp", version = "0.8.40" }
codewhale-secrets = { path = "../secrets", version = "0.8.40" }
codewhale-state = { path = "../state", version = "0.8.40" }
codewhale-agent = { path = "../agent", version = "0.8.41" }
codewhale-app-server = { path = "../app-server", version = "0.8.41" }
codewhale-config = { path = "../config", version = "0.8.41" }
codewhale-execpolicy = { path = "../execpolicy", version = "0.8.41" }
codewhale-mcp = { path = "../mcp", version = "0.8.41" }
codewhale-secrets = { path = "../secrets", version = "0.8.41" }
codewhale-state = { path = "../state", version = "0.8.41" }
chrono.workspace = true
dirs.workspace = true
serde.workspace = true
+1 -1
View File
@@ -8,7 +8,7 @@ description = "Config schema and precedence model for DeepSeek workspace archite
[dependencies]
anyhow.workspace = true
codewhale-secrets = { path = "../secrets", version = "0.8.40" }
codewhale-secrets = { path = "../secrets", version = "0.8.41" }
dirs.workspace = true
serde.workspace = true
toml.workspace = true
+8 -8
View File
@@ -9,13 +9,13 @@ description = "Core runtime boundaries for DeepSeek workspace architecture"
[dependencies]
anyhow.workspace = true
chrono.workspace = true
codewhale-agent = { path = "../agent", version = "0.8.40" }
codewhale-config = { path = "../config", version = "0.8.40" }
codewhale-execpolicy = { path = "../execpolicy", version = "0.8.40" }
codewhale-hooks = { path = "../hooks", version = "0.8.40" }
codewhale-mcp = { path = "../mcp", version = "0.8.40" }
codewhale-protocol = { path = "../protocol", version = "0.8.40" }
codewhale-state = { path = "../state", version = "0.8.40" }
codewhale-tools = { path = "../tools", version = "0.8.40" }
codewhale-agent = { path = "../agent", version = "0.8.41" }
codewhale-config = { path = "../config", version = "0.8.41" }
codewhale-execpolicy = { path = "../execpolicy", version = "0.8.41" }
codewhale-hooks = { path = "../hooks", version = "0.8.41" }
codewhale-mcp = { path = "../mcp", version = "0.8.41" }
codewhale-protocol = { path = "../protocol", version = "0.8.41" }
codewhale-state = { path = "../state", version = "0.8.41" }
codewhale-tools = { path = "../tools", version = "0.8.41" }
serde_json.workspace = true
uuid.workspace = true
+1 -1
View File
@@ -8,5 +8,5 @@ description = "Execution policy and approval model parity for DeepSeek workspace
[dependencies]
anyhow.workspace = true
codewhale-protocol = { path = "../protocol", version = "0.8.40" }
codewhale-protocol = { path = "../protocol", version = "0.8.41" }
serde.workspace = true
+1 -1
View File
@@ -10,7 +10,7 @@ description = "Hook dispatch and notifications parity for DeepSeek workspace arc
anyhow.workspace = true
async-trait.workspace = true
chrono.workspace = true
codewhale-protocol = { path = "../protocol", version = "0.8.40" }
codewhale-protocol = { path = "../protocol", version = "0.8.41" }
reqwest.workspace = true
serde.workspace = true
serde_json.workspace = true
+1 -1
View File
@@ -9,7 +9,7 @@ description = "Tool invocation lifecycle, schema validation, and scheduler paral
[dependencies]
anyhow.workspace = true
async-trait.workspace = true
codewhale-protocol = { path = "../protocol", version = "0.8.40" }
codewhale-protocol = { path = "../protocol", version = "0.8.41" }
serde.workspace = true
serde_json.workspace = true
tokio.workspace = true
+42 -3
View File
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [0.8.41] - 2026-05-23
### Changed
- **Project renamed to codewhale.** The canonical CLI dispatcher is now
@@ -14,8 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
(was `deepseek-tui`). The 14 workspace crates are renamed from
`deepseek-*` / `deepseek-tui-*` to `codewhale-*` / `codewhale-tui-*`.
The npm wrapper package is now `codewhale` (was `deepseek-tui`). See
[docs/REBRAND.md](https://github.com/Hmbown/DeepSeek-TUI/blob/main/docs/REBRAND.md)
for migration notes.
[docs/REBRAND.md](docs/REBRAND.md) for migration notes.
- **DeepSeek provider integration is unchanged.** `DEEPSEEK_*` env vars,
model IDs (`deepseek-v4-pro`, `deepseek-v4-flash`, the legacy
`deepseek-chat` / `deepseek-reasoner` aliases), the
@@ -31,6 +32,43 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
cycle as a no-`bin` deprecation shim whose postinstall directs users
to `npm install -g codewhale`. It will be removed in v0.9.0.
### Fixed
- **Windows CI spillover tests are isolated.** Tool-result deduplication
tests now use a temporary spillover root guarded by the existing global
spillover mutex, removing the shared-state race that made Windows CI fail
unrelated PRs (#1943).
- **Terminated sub-agents keep `agent_eval` recoverable.** Evaluating a
completed child session now returns the available transcript result instead
of losing the final output (#1738, #1928).
- **Bare `@/` completions no longer freeze the TUI.** File-mention
completion skips bare separator and dot tokens so Windows/WSL2 workspaces
do not trigger an eager 4096-entry filesystem walk on the UI thread
(#1921, #1929).
- **Enter paths avoid synchronous UI-thread waits.** Composer history writes,
offline queue persistence, feedback URL launching, and clipboard fallback
helpers now run off the hot Enter path where appropriate (#1927, #1931,
#1940, #1941, #1944).
- **tmux and screen sessions stop idling as terminal activity.** Terminal
multiplexers now force low-motion behavior and pin the fallback footer label
so passive animations do not trip activity monitors (#1925, #1942).
- **Composer sanitization catches OSC 8 and Kitty fragments.** The input
sanitizer now strips common hyperlink and keyboard-protocol fragments that
leaked into drafts while preserving ordinary prose (#1915, #1933).
- **The Work sidebar hides stale completed tasks.** Terminal task records older
than the current session and outside the recent-completion window no longer
crowd active Work sidebar rows (#1913, #1930).
- **V4 Pro pricing docs reflect permanent rates.** The English, Simplified
Chinese, and Japanese READMEs now describe the V4 Pro pricing change as
permanent instead of temporary (#1923, #1932).
### Thanks
Thanks to **OpenWarp ([@zerx-lab](https://github.com/zerx-lab))** for
prioritizing codewhale support and collaborating on terminal-agent UX.
Thanks to **[@leo119](https://github.com/leo119)** for the update-command
documentation lineage now preserved through the rename.
## [0.8.40] - 2026-05-21
### Added
@@ -4557,7 +4595,8 @@ Welcome — and thank you.
- Hooks system and config profiles
- Example skills and launch assets
[Unreleased]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.8.40...HEAD
[Unreleased]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.8.41...HEAD
[0.8.41]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.8.40...v0.8.41
[0.8.40]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.8.39...v0.8.40
[0.8.39]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.8.38...v0.8.39
[0.8.38]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.8.37...v0.8.38
+2 -2
View File
@@ -27,8 +27,8 @@ path = "src/bin/deepseek_tui_legacy_shim.rs"
[dependencies]
anyhow = "1.0.100"
arboard = "3.4"
codewhale-secrets = { path = "../secrets", version = "0.8.40" }
codewhale-tools = { path = "../tools", version = "0.8.40" }
codewhale-secrets = { path = "../secrets", version = "0.8.41" }
codewhale-tools = { path = "../tools", version = "0.8.41" }
schemaui = { version = "0.12.0", default-features = false, optional = true }
async-stream = "0.3.6"
async-trait = "0.1"
+26 -14
View File
@@ -3,7 +3,8 @@
`cnb.cool/deepseek-tui.com/DeepSeek-TUI` is a one-way mirror of this
GitHub repository for users on networks where GitHub is slow or blocked
(primarily mainland China). The mirror receives every push to `main`, every
`v*` release tag, and Tencent release-candidate branches used by the
`fix/*`, `rebrand/*`, and `work/v*` branch used for first-party release work,
every `v*` release tag, and Tencent release-candidate branches used by the
Lighthouse/Feishu setup.
## How it works
@@ -12,15 +13,17 @@ The mirror is maintained by the [`Sync to CNB`](../.github/workflows/sync-cnb.ym
GitHub Actions workflow:
- **Trigger:** `push` to `main`, `push` of any `v*` tag,
release stability branches matching `work/v*-stability`,
release work branches matching `work/v*`, first-party fix and rebrand
branches matching `fix/*` and `rebrand/*`,
Tencent setup branches matching `work/v*-feishu-*` or
`work/v*-lighthouse*`, or `workflow_dispatch` for manual recovery.
- **Auth:** HTTPS basic auth as user `cnb` with the `CNB_GIT_TOKEN`
repository secret as the password.
- **Scope:** only the ref that triggered the run is pushed. Tag pushes
push exactly that tag. Branch pushes mirror `main` or an explicitly
matched release/Tencent setup branch. Other feature branches and dependabot
refs are intentionally *not* mirrored.
push exactly that tag. Branch pushes mirror `main`, first-party
`fix/*`/`rebrand/*` branches, or explicitly matched release/Tencent setup
branches. Other feature branches and dependabot refs are intentionally
*not* mirrored.
- **Concurrency:** runs are serialized via a `cnb-sync` concurrency
group so the back-to-back `main` push and tag push from
`auto-tag.yml` cannot race each other.
@@ -43,16 +46,25 @@ release assets from source and publishes a CNB release with:
- `codewhale-artifacts-sha256.txt`
This gives users who can reach CNB but not GitHub a CNB-native release path.
GitHub remains the canonical full release matrix; the CNB tag pipeline is the
China-friendly Linux x64 fallback.
GitHub remains the canonical macOS/Windows release matrix; the CNB tag pipeline
is the China-friendly Linux x64 fallback.
## Release branch preflight
## CNB Linux CI and release preflight
Release stability branches matching `work/v*-stability` are mirrored to CNB so
CNB can run Linux/container release preflight before the branch merges. This is
useful for offloading Linux Rust, npm wrapper, and Feishu bridge checks, but it
does not replace platform-specific GitHub Actions jobs such as Windows and
macOS.
First-party `fix/*` and `rebrand/*` branches are mirrored to CNB so the heavy
Linux Rust gates run on Tencent-hosted runners instead of GitHub Actions:
- `./scripts/release/check-versions.sh`
- `cargo fmt --all -- --check`
- `cargo check --workspace --all-targets --locked`
- `cargo clippy --workspace --all-targets --all-features --locked -- -D warnings`
- `cargo test --workspace --all-features --locked`
- `cargo build --release --locked -p codewhale-cli -p codewhale-tui`
- `node scripts/release/npm-wrapper-smoke.js`
Release branches matching `work/v*` also run the Feishu bridge checks and
`./scripts/release/publish-crates.sh dry-run`. GitHub Actions keeps the cheap
drift/fmt statuses plus the macOS and Windows jobs that CNB cannot replace.
## Verifying the mirror after a release
@@ -147,7 +159,7 @@ expired:
## Binary release assets and `codewhale update`
CNB now builds Linux x64 assets for `v*` tags from the source-controlled
`.cnb.yml` pipeline. GitHub remains the canonical full release matrix. Users
`.cnb.yml` pipeline. GitHub remains the canonical macOS/Windows release matrix. Users
behind GitHub-blocking networks should use one of these paths:
- **`cargo install`** from the CNB mirror:
+4 -2
View File
@@ -29,8 +29,10 @@ publish-crates), see [`RELEASE_RUNBOOK.md`](RELEASE_RUNBOOK.md).
- [ ] `Cargo.toml` workspace `version` is bumped.
- [ ] All per-crate `crates/*/Cargo.toml` path-dependency `version = "..."`
pins match the new workspace version.
- [ ] `npm/codewhale-tui/package.json` `version` AND `deepseekBinaryVersion`
- [ ] `npm/codewhale/package.json` `version` AND `codewhaleBinaryVersion`
are both bumped.
- [ ] `npm/deepseek-tui/package.json` `version` is bumped for the one-release
deprecation shim.
- [ ] `Cargo.lock` is refreshed (`cargo update --workspace --offline`).
- [ ] `./scripts/release/check-versions.sh` reports
`Version state OK: workspace=X.Y.Z, npm=X.Y.Z, lockfile in sync.`
@@ -82,7 +84,7 @@ Run, in order, from the repo root:
- [ ] `git push origin vX.Y.Z`
- [ ] The `release.yml` workflow has built and uploaded artifacts to the
GitHub release for this tag.
- [ ] `npm view codewhale-tui@X.Y.Z version deepseekBinaryVersion --json`
- [ ] `npm view codewhale@X.Y.Z version codewhaleBinaryVersion --json`
reports the new version on the npm registry.
- [ ] `crates.io` has the new version (or the `publish-crates.sh` job has
pushed it).
+23 -19
View File
@@ -1,10 +1,10 @@
# codewhale Release Runbook
This runbook is the source of truth for shipping Rust crates, GitHub release assets,
and the `codewhale-tui` npm wrapper.
and the `codewhale` npm wrapper.
Current packaging note:
- `codewhale-tui` is the live runtime and TUI package shipped to users today.
- `codewhale-tui` is the live runtime crate shipped to users today.
- `codewhale-tui-core` is a supporting workspace crate for the extraction/parity effort, not a replacement for the shipping runtime.
## Canonical Publish Targets
@@ -25,17 +25,16 @@ Current packaging note:
- `codewhale-core`
- `codewhale-app-server`
- `codewhale-tui-core`
- `codewhale-cli` on crates.io is an unrelated crate and is not part of this release flow.
## Version Coordination
- Rust crates inherit the shared workspace version from [Cargo.toml](../Cargo.toml).
- Internal path dependency versions should match the shared workspace version; stale older pins are release blockers once the workspace version moves.
- The npm wrapper version lives in [npm/codewhale-tui/package.json](../npm/codewhale-tui/package.json).
- `deepseekBinaryVersion` controls which GitHub release binaries the npm wrapper downloads.
- The npm wrapper version lives in [npm/codewhale/package.json](../npm/codewhale/package.json).
- `codewhaleBinaryVersion` controls which GitHub release binaries the npm wrapper downloads.
- Packaging-only npm releases are allowed:
- bump the npm package version
- leave `deepseekBinaryVersion` pinned to the previously released Rust binaries
- leave `codewhaleBinaryVersion` pinned to the previously released Rust binaries
- rerun `npm pack` smoke checks before `npm publish`
## Preflight
@@ -54,9 +53,14 @@ cargo publish --dry-run --locked --allow-dirty -p codewhale-tui
`check-versions.sh` also runs in CI on every push/PR (the `versions` job in
`.github/workflows/ci.yml`), so drift between `Cargo.toml`, the per-crate
manifests, `npm/codewhale-tui/package.json`, and `Cargo.lock` is caught before
manifests, `npm/codewhale/package.json`, and `Cargo.lock` is caught before
release time rather than at it.
The source-controlled CNB pipeline mirrors the heavy Linux version/fmt/check/
clippy/test/npm-smoke gates for `fix/*`, `rebrand/*`, `work/v*`, and `main`.
GitHub Actions keeps the cheap drift/fmt statuses plus macOS and Windows
coverage, while CNB carries the Linux work.
`publish-crates.sh dry-run` performs a full `cargo publish --dry-run` for crates
without unpublished workspace dependencies and a packaging preflight for dependent
workspace crates. That avoids false negatives from crates.io not yet containing the
@@ -81,14 +85,14 @@ directory with a full asset matrix fixture before starting the server:
```bash
DEEPSEEK_TUI_PREPARE_ALL_ASSETS=1 node scripts/release/prepare-local-release-assets.js
cd npm/codewhale-tui
cd npm/codewhale
DEEPSEEK_TUI_VERSION=X.Y.Z DEEPSEEK_TUI_RELEASE_BASE_URL=http://127.0.0.1:8123/ npm run release:check
```
Set `DEEPSEEK_TUI_VERSION` to the npm package version you are verifying for that local run.
The CI workflow runs the same tarball install + delegated-entrypoint smoke test
on Linux, macOS, and Windows.
The CNB workflow runs the Linux tarball install + delegated-entrypoint smoke
test; GitHub Actions keeps macOS and Windows smoke coverage.
After publishing, prove the release is visible in both registries:
@@ -96,7 +100,7 @@ After publishing, prove the release is visible in both registries:
./scripts/release/check-published.sh X.Y.Z
```
Do not mark a Rust release complete until that command sees `codewhale-tui@X.Y.Z`
Do not mark a Rust release complete until that command sees `codewhale@X.Y.Z`
on npm and every `codewhale-*` crate at `X.Y.Z` on crates.io. For a rare
npm packaging-only release, run with `--allow-npm-binary-mismatch` and keep the
release notes explicit that no new Rust binary version shipped.
@@ -159,14 +163,14 @@ on a workstation with `npm login` and an authenticator app.
### Steps
1. Set the npm package version in [npm/codewhale-tui/package.json](../npm/codewhale-tui/package.json) to match the workspace `Cargo.toml`. CI's version-drift guard will catch mismatches before tag.
2. Set `deepseekBinaryVersion` to the GitHub release tag that should supply binaries.
1. Set the npm package version in [npm/codewhale/package.json](../npm/codewhale/package.json) to match the workspace `Cargo.toml`. CI's version-drift guard will catch mismatches before tag.
2. Set `codewhaleBinaryVersion` to the GitHub release tag that should supply binaries.
3. Push the version bump to `main`. `auto-tag.yml` creates the matching `vX.Y.Z` tag, and `release.yml` builds the binary matrix and drafts the GitHub Release.
4. **Wait for the GitHub Release to finalize** with all eight signed binaries plus `codewhale-artifacts-sha256.txt`. The npm `prepublishOnly` hook (`scripts/verify-release-assets.js`) requires every asset to be present.
5. From a developer machine, publish the npm wrapper manually:
```bash
cd npm/codewhale-tui
cd npm/codewhale
npm publish --access public
# (you will be prompted for the npm OTP from your authenticator)
```
@@ -182,11 +186,11 @@ To re-enable automated publish: provision an npm automation token with "Bypass 2
## CNB Cool mirror
Every push to `main` and every `v*` tag is mirrored to
Every push to `main`, `fix/*`, `rebrand/*`, `work/v*`, and every `v*` tag is mirrored to
`cnb.cool/deepseek-tui.com/DeepSeek-TUI` via the `Sync to CNB` workflow
so users behind GitHub-blocking networks can fetch the source. After a
release tag, **verify the mirror caught it** before declaring the
release shipped:
so users behind GitHub-blocking networks can fetch the source and so CNB can
run the heavy Linux CI lane. After a release tag, **verify the mirror caught
it** before declaring the release shipped:
```bash
git ls-remote https://cnb.cool/deepseek-tui.com/DeepSeek-TUI.git refs/tags/vX.Y.Z
@@ -206,7 +210,7 @@ remote add cnb …`, then `git push cnb vX.Y.Z`).
- retag or upload corrected assets before `npm publish`
- npm packaging-only problem:
- bump only the npm package version
- keep `deepseekBinaryVersion` on the last known-good Rust release
- keep `codewhaleBinaryVersion` on the last known-good Rust release
- repack and republish the wrapper
- A bad npm publish cannot be overwritten:
- publish a new npm version with corrected metadata or install logic
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "codewhale",
"version": "0.8.40",
"codewhaleBinaryVersion": "0.8.40",
"version": "0.8.41",
"codewhaleBinaryVersion": "0.8.41",
"description": "Install and run the codewhale CLI dispatcher and codewhale-tui terminal UI from GitHub release artifacts.",
"author": "Hmbown",
"license": "MIT",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "deepseek-tui",
"version": "0.8.40",
"version": "0.8.41",
"description": "Deprecated. Renamed to `codewhale`. Run `npm install -g codewhale` instead.",
"author": "Hmbown",
"license": "MIT",
+7 -7
View File
@@ -17,7 +17,7 @@ esac
packages=("${release_crates[@]}")
workspace_version=""
workspace_deepseek_packages=()
workspace_codewhale_packages=()
workspace_package_dep_flags=()
while IFS=$'\t' read -r kind name value; do
@@ -26,7 +26,7 @@ while IFS=$'\t' read -r kind name value; do
workspace_version="${name}"
;;
crate)
workspace_deepseek_packages+=("${name}")
workspace_codewhale_packages+=("${name}")
workspace_package_dep_flags+=("${value}")
;;
esac
@@ -52,7 +52,7 @@ if len(versions) != 1:
print(f"version\t{versions[0]}\t")
for pkg in sorted(workspace_packages, key=lambda item: item["name"]):
if not pkg["name"].startswith("deepseek-"):
if not pkg["name"].startswith("codewhale-"):
continue
has_workspace_dep = any(
dep.get("path") and dep["name"] in workspace_by_name
@@ -68,7 +68,7 @@ if [[ -z "${workspace_version}" ]]; then
fi
missing_packages=()
for workspace_package in "${workspace_deepseek_packages[@]}"; do
for workspace_package in "${workspace_codewhale_packages[@]}"; do
found=0
for package in "${packages[@]}"; do
if [[ "${package}" == "${workspace_package}" ]]; then
@@ -84,7 +84,7 @@ done
extra_packages=()
for package in "${packages[@]}"; do
found=0
for workspace_package in "${workspace_deepseek_packages[@]}"; do
for workspace_package in "${workspace_codewhale_packages[@]}"; do
if [[ "${package}" == "${workspace_package}" ]]; then
found=1
break
@@ -108,8 +108,8 @@ fi
package_has_workspace_deps() {
local package_name="$1"
local index
for ((index = 0; index < ${#workspace_deepseek_packages[@]}; index += 1)); do
if [[ "${workspace_deepseek_packages[$index]}" == "${package_name}" ]]; then
for ((index = 0; index < ${#workspace_codewhale_packages[@]}; index += 1)); do
if [[ "${workspace_codewhale_packages[$index]}" == "${package_name}" ]]; then
[[ "${workspace_package_dep_flags[$index]}" == "1" ]]
return
fi