From 6de8ba363f3bd92513a0881b1f9ad9f38ca6a9b5 Mon Sep 17 00:00:00 2001 From: Hunter Bown Date: Sat, 23 May 2026 13:09:30 -0500 Subject: [PATCH] chore(release): prepare codewhale v0.8.41 test build --- .cnb.yml | 194 +++++++++++++++++++----------- .github/workflows/ci.yml | 69 ++++------- .github/workflows/sync-cnb.yml | 12 +- CHANGELOG.md | 42 ++++++- Cargo.lock | 28 ++--- Cargo.toml | 2 +- crates/agent/Cargo.toml | 2 +- crates/app-server/Cargo.toml | 18 +-- crates/cli/Cargo.toml | 14 +-- crates/config/Cargo.toml | 2 +- crates/core/Cargo.toml | 16 +-- crates/execpolicy/Cargo.toml | 2 +- crates/hooks/Cargo.toml | 2 +- crates/tools/Cargo.toml | 2 +- crates/tui/CHANGELOG.md | 45 ++++++- crates/tui/Cargo.toml | 4 +- docs/CNB_MIRROR.md | 40 +++--- docs/RELEASE_CHECKLIST.md | 6 +- docs/RELEASE_RUNBOOK.md | 42 ++++--- npm/codewhale/package.json | 4 +- npm/deepseek-tui/package.json | 2 +- scripts/release/publish-crates.sh | 14 +-- 22 files changed, 346 insertions(+), 216 deletions(-) diff --git a/.cnb.yml b/.cnb.yml index c60eb913..8c86c883 100644 --- a/.cnb.yml +++ b/.cnb.yml @@ -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 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e3f3033c..4203a17c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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: diff --git a/.github/workflows/sync-cnb.yml b/.github/workflows/sync-cnb.yml index 82747826..15a221c8 100644 --- a/.github/workflows/sync-cnb.yml +++ b/.github/workflows/sync-cnb.yml @@ -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. diff --git a/CHANGELOG.md b/CHANGELOG.md index dc35c502..41c027a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/Cargo.lock b/Cargo.lock index 3fe5dab2..f7ce059b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/Cargo.toml b/Cargo.toml index 7b085757..0a0b76de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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 diff --git a/crates/agent/Cargo.toml b/crates/agent/Cargo.toml index 8e0a0601..36733251 100644 --- a/crates/agent/Cargo.toml +++ b/crates/agent/Cargo.toml @@ -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 diff --git a/crates/app-server/Cargo.toml b/crates/app-server/Cargo.toml index fc118c4b..06e7e504 100644 --- a/crates/app-server/Cargo.toml +++ b/crates/app-server/Cargo.toml @@ -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 diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 613b6d88..305d78c9 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -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 diff --git a/crates/config/Cargo.toml b/crates/config/Cargo.toml index 8d10efdb..c8cee6ec 100644 --- a/crates/config/Cargo.toml +++ b/crates/config/Cargo.toml @@ -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 diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index 75096dab..b98c2987 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -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 diff --git a/crates/execpolicy/Cargo.toml b/crates/execpolicy/Cargo.toml index 021be64c..45e179e3 100644 --- a/crates/execpolicy/Cargo.toml +++ b/crates/execpolicy/Cargo.toml @@ -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 diff --git a/crates/hooks/Cargo.toml b/crates/hooks/Cargo.toml index 4ce20bf4..7e79f98f 100644 --- a/crates/hooks/Cargo.toml +++ b/crates/hooks/Cargo.toml @@ -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 diff --git a/crates/tools/Cargo.toml b/crates/tools/Cargo.toml index e652ec5c..65f83103 100644 --- a/crates/tools/Cargo.toml +++ b/crates/tools/Cargo.toml @@ -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 diff --git a/crates/tui/CHANGELOG.md b/crates/tui/CHANGELOG.md index 683c7651..41c027a7 100644 --- a/crates/tui/CHANGELOG.md +++ b/crates/tui/CHANGELOG.md @@ -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 diff --git a/crates/tui/Cargo.toml b/crates/tui/Cargo.toml index 50126759..96789578 100644 --- a/crates/tui/Cargo.toml +++ b/crates/tui/Cargo.toml @@ -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" diff --git a/docs/CNB_MIRROR.md b/docs/CNB_MIRROR.md index c4c5a71d..9b69a28e 100644 --- a/docs/CNB_MIRROR.md +++ b/docs/CNB_MIRROR.md @@ -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: diff --git a/docs/RELEASE_CHECKLIST.md b/docs/RELEASE_CHECKLIST.md index 90e31009..1f4b9ce2 100644 --- a/docs/RELEASE_CHECKLIST.md +++ b/docs/RELEASE_CHECKLIST.md @@ -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). diff --git a/docs/RELEASE_RUNBOOK.md b/docs/RELEASE_RUNBOOK.md index 1b1dcb3b..df4877b9 100644 --- a/docs/RELEASE_RUNBOOK.md +++ b/docs/RELEASE_RUNBOOK.md @@ -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 diff --git a/npm/codewhale/package.json b/npm/codewhale/package.json index 38ca98e7..20de37f8 100644 --- a/npm/codewhale/package.json +++ b/npm/codewhale/package.json @@ -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", diff --git a/npm/deepseek-tui/package.json b/npm/deepseek-tui/package.json index ef8d30ec..4f4da995 100644 --- a/npm/deepseek-tui/package.json +++ b/npm/deepseek-tui/package.json @@ -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", diff --git a/scripts/release/publish-crates.sh b/scripts/release/publish-crates.sh index 2c52b800..bad30760 100755 --- a/scripts/release/publish-crates.sh +++ b/scripts/release/publish-crates.sh @@ -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