From 8c690cb7bf10f8a8e2b82644699a962663c70f08 Mon Sep 17 00:00:00 2001 From: Hunter B Date: Fri, 12 Jun 2026 02:22:10 -0700 Subject: [PATCH] fix(update): guide legacy deepseek users to codewhale Harvests PR #3013 by @cyq1017 and PR #3053 by @angus-guo. Legacy deepseek/deepseek-tui binaries now return migration steps instead of trying to self-update through a missing codewhale binary, and the README/rebrand docs carry the same upgrade path. Co-authored-by: cyq1017 <61975706+cyq1017@users.noreply.github.com> Co-authored-by: gus <217034332+angus-guo@users.noreply.github.com> --- .github/AUTHOR_MAP | 2 + CHANGELOG.md | 7 +++ README.md | 35 ++++++++++++++ crates/cli/src/update.rs | 99 +++++++++++++++++++++++++++++++++++++++- crates/tui/CHANGELOG.md | 7 +++ docs/REBRAND.md | 17 +++++-- 6 files changed, 160 insertions(+), 7 deletions(-) diff --git a/.github/AUTHOR_MAP b/.github/AUTHOR_MAP index 0ee92f40..9dd66405 100644 --- a/.github/AUTHOR_MAP +++ b/.github/AUTHOR_MAP @@ -55,6 +55,8 @@ JasonOA888 = JasonOA888 <101583541+JasonOA888@users.noreply.github.com> Inference1 = Inference1 <68734681+Inference1@users.noreply.github.com> hongqitai = hongqitai <188678175+hongqitai@users.noreply.github.com> gordonlu = gordonlu <3125629+gordonlu@users.noreply.github.com> +angus-guo = gus <217034332+angus-guo@users.noreply.github.com> +gus.guo@tec-do.com = gus <217034332+angus-guo@users.noreply.github.com> gaord = gaord <9567937+gaord@users.noreply.github.com> Ben Gao = gaord <9567937+gaord@users.noreply.github.com> bengao168@msn.com = gaord <9567937+gaord@users.noreply.github.com> diff --git a/CHANGELOG.md b/CHANGELOG.md index cee8a633..849ab494 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -57,6 +57,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **Self-update download timeout (#3006).** `codewhale update` now applies a five-minute HTTP client timeout so blocked or very slow GitHub release downloads fail instead of hanging indefinitely. Thanks @New2Niu for the PR. +- **Legacy `deepseek` update migration (#2960/#3013/#3053).** Running + `deepseek update` or `deepseek-tui update` from a pre-rebrand install now + returns copy-pasteable npm, Cargo, Homebrew, and manual-binary migration + steps instead of trying to spawn a missing `codewhale` binary. README and + rebrand docs now cover the same upgrade path. Thanks @jazzi and + @tiangangQiu for the reports, @cyq1017 for the update-path PR, and + @angus-guo for the README PR. - **Constitution trust wording (#2950/#3008).** The base prompt now explains that "begins with an A" means a baseline of trust, not a literal output formatting rule. Thanks @cyq1017 for the PR. diff --git a/README.md b/README.md index 11672616..db2c3e0a 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,39 @@ For Docker, direct downloads, China mirrors, Windows/Scoop, Nix, checksums, and troubleshooting, use [docs/INSTALL.md](docs/INSTALL.md) or the website install page. +## Upgrading from deepseek-tui + +If you installed the legacy `deepseek-tui` package, run the commands for your +install method below. Your existing config, sessions, skills, and MCP settings +are preserved, and DeepSeek provider support is unchanged. See +[docs/REBRAND.md](docs/REBRAND.md) for the full migration guide. + +**npm** + +```bash +npm uninstall -g deepseek-tui +npm install -g codewhale +``` + +**Cargo** + +```bash +cargo uninstall deepseek-tui-cli 2>/dev/null || true +cargo uninstall deepseek-tui 2>/dev/null || true +cargo install codewhale-cli --locked +cargo install codewhale-tui --locked +``` + +**Homebrew** - keep using `brew upgrade deepseek-tui` for now; the formula +rename is in progress. + +**GitHub Releases** - download the matched `codewhale-*` and +`codewhale-tui-*` archives for your platform from the +[Releases page](https://github.com/Hmbown/CodeWhale/releases), then replace the +old binaries on your `PATH`. + +After upgrading, run `codewhale doctor` to confirm the migration succeeded. + ## First Run ```bash @@ -117,6 +150,8 @@ The README carries the idea and the first path. The details live in docs and on - [User guide](docs/GUIDE.md) — first hour with CodeWhale. - [Install guide](docs/INSTALL.md) — every package path and troubleshooting. +- [Rebrand migration guide](docs/REBRAND.md) — upgrading from the legacy + `deepseek-tui` package. - [Configuration](docs/CONFIGURATION.md) — config files, repo constitution, and provider settings. - [Provider registry](docs/PROVIDERS.md) — model routes, credentials, base URLs, diff --git a/crates/cli/src/update.rs b/crates/cli/src/update.rs index abce2e06..0850be1f 100644 --- a/crates/cli/src/update.rs +++ b/crates/cli/src/update.rs @@ -29,6 +29,10 @@ pub fn run_update(beta: bool, check_only: bool, proxy_arg: Option) -> Re let current_exe = std::env::current_exe().context("failed to determine current executable path")?; + if is_legacy_binary(¤t_exe) { + bail!("{}", legacy_binary_message(¤t_exe)); + } + let targets = update_targets_for_exe(¤t_exe); let channel = ReleaseChannel::from_beta_flag(beta); let current_version = env!("CARGO_PKG_VERSION"); @@ -188,12 +192,55 @@ pub(crate) fn release_arch_for_rust_arch(arch: &str) -> &str { } } +/// Returns true when the binary name belongs to the pre-rebrand `deepseek-tui` era. +pub(crate) fn is_legacy_binary(current_exe: &Path) -> bool { + let exe_name = current_exe + .file_name() + .and_then(|name| name.to_str()) + .unwrap_or("") + .to_ascii_lowercase(); + exe_name.starts_with("deepseek") +} + +fn legacy_binary_message(current_exe: &Path) -> String { + format!( + "\ +this binary ({exe}) is using the legacy deepseek/deepseek-tui command name. + +The package has been renamed to `codewhale`. Self-update cannot continue from +the old binary name, but DeepSeek provider support is unchanged. + +Reinstall using your original install method: + + npm: + npm uninstall -g deepseek-tui + npm install -g codewhale + + Cargo: + cargo uninstall deepseek-tui-cli 2>/dev/null || true + cargo uninstall deepseek-tui 2>/dev/null || true + cargo install codewhale-cli --locked + cargo install codewhale-tui --locked + + Homebrew: + brew upgrade deepseek-tui + + Manual binary: + download the matched codewhale and codewhale-tui assets from + https://github.com/Hmbown/CodeWhale/releases/latest + +Once `codewhale` is on your PATH, run `codewhale update` for future updates.", + exe = current_exe.display(), + ) +} + pub(crate) fn binary_prefix_for_exe(current_exe: &Path) -> &'static str { let exe_name = current_exe .file_name() .and_then(|name| name.to_str()) - .unwrap_or("codewhale"); - if exe_name.contains("codewhale-tui") { + .unwrap_or("codewhale") + .to_ascii_lowercase(); + if exe_name.contains("codewhale-tui") || exe_name.contains("deepseek-tui") { "codewhale-tui" } else { "codewhale" @@ -621,6 +668,10 @@ mod tests { binary_prefix_for_exe(Path::new("codewhale-tui.exe")), "codewhale-tui" ); + assert_eq!( + binary_prefix_for_exe(Path::new("CodeWhale-TUI.exe")), + "codewhale-tui" + ); assert_eq!( binary_prefix_for_exe(Path::new("/usr/local/bin/codewhale-tui")), "codewhale-tui" @@ -642,6 +693,50 @@ mod tests { binary_prefix_for_exe(Path::new("other-binary")), "codewhale" ); + + // Legacy names still map to the canonical update asset prefixes. + assert_eq!( + binary_prefix_for_exe(Path::new("deepseek-tui")), + "codewhale-tui" + ); + assert_eq!( + binary_prefix_for_exe(Path::new("/usr/local/bin/deepseek-tui")), + "codewhale-tui" + ); + assert_eq!( + binary_prefix_for_exe(Path::new("DeepSeek-TUI.exe")), + "codewhale-tui" + ); + assert_eq!(binary_prefix_for_exe(Path::new("deepseek")), "codewhale"); + } + + #[test] + fn test_is_legacy_binary_detection() { + assert!(is_legacy_binary(Path::new("deepseek"))); + assert!(is_legacy_binary(Path::new("deepseek-tui"))); + assert!(is_legacy_binary(Path::new("/usr/local/bin/deepseek"))); + assert!(is_legacy_binary(Path::new("/usr/local/bin/deepseek-tui"))); + assert!(is_legacy_binary(Path::new("DeepSeek.exe"))); + assert!(is_legacy_binary(Path::new("DeepSeek-TUI.exe"))); + assert!(!is_legacy_binary(Path::new("codewhale"))); + assert!(!is_legacy_binary(Path::new("codewhale-tui"))); + assert!(!is_legacy_binary(Path::new("codew"))); + } + + #[test] + fn legacy_binary_message_gives_copy_pasteable_migration_steps() { + let message = legacy_binary_message(Path::new("/usr/local/bin/deepseek-tui")); + + assert!(message.contains("legacy deepseek/deepseek-tui command name")); + assert!(message.contains("DeepSeek provider support is unchanged")); + assert!(message.contains("npm uninstall -g deepseek-tui")); + assert!(message.contains("npm install -g codewhale")); + assert!(message.contains("cargo uninstall deepseek-tui-cli 2>/dev/null || true")); + assert!(message.contains("cargo uninstall deepseek-tui 2>/dev/null || true")); + assert!(message.contains("cargo install codewhale-cli --locked")); + assert!(message.contains("cargo install codewhale-tui --locked")); + assert!(message.contains("brew upgrade deepseek-tui")); + assert!(message.contains("https://github.com/Hmbown/CodeWhale/releases/latest")); } #[test] diff --git a/crates/tui/CHANGELOG.md b/crates/tui/CHANGELOG.md index caf0e766..70b793fc 100644 --- a/crates/tui/CHANGELOG.md +++ b/crates/tui/CHANGELOG.md @@ -57,6 +57,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **Self-update download timeout (#3006).** `codewhale update` now applies a five-minute HTTP client timeout so blocked or very slow GitHub release downloads fail instead of hanging indefinitely. Thanks @New2Niu for the PR. +- **Legacy `deepseek` update migration (#2960/#3013/#3053).** Running + `deepseek update` or `deepseek-tui update` from a pre-rebrand install now + returns copy-pasteable npm, Cargo, Homebrew, and manual-binary migration + steps instead of trying to spawn a missing `codewhale` binary. README and + rebrand docs now cover the same upgrade path. Thanks @jazzi and + @tiangangQiu for the reports, @cyq1017 for the update-path PR, and + @angus-guo for the README PR. - **Constitution trust wording (#2950/#3008).** The base prompt now explains that "begins with an A" means a baseline of trust, not a literal output formatting rule. Thanks @cyq1017 for the PR. diff --git a/docs/REBRAND.md b/docs/REBRAND.md index 71360955..15c0210b 100644 --- a/docs/REBRAND.md +++ b/docs/REBRAND.md @@ -9,11 +9,16 @@ DeepSeek provider integration changed — only the local CLI / TUI brand. ```bash # 1. Uninstall the old wrapper or binaries. -npm uninstall -g deepseek-tui # or cargo uninstall deepseek-tui-cli deepseek-tui - # or brew uninstall deepseek-tui +npm uninstall -g deepseek-tui # or: +cargo uninstall deepseek-tui-cli 2>/dev/null || true +cargo uninstall deepseek-tui 2>/dev/null || true + # legacy Homebrew installs may use: + # brew upgrade deepseek-tui # 2. Install under the new name. -npm install -g codewhale # or cargo install codewhale-cli codewhale-tui --locked +npm install -g codewhale # or: +cargo install codewhale-cli --locked +cargo install codewhale-tui --locked # legacy Homebrew installs may still use # brew install deepseek-tui until the tap # formula is renamed. @@ -96,8 +101,10 @@ npm install -g codewhale ### Cargo ```bash -cargo uninstall deepseek-tui-cli deepseek-tui 2>/dev/null || true -cargo install codewhale-cli codewhale-tui --locked +cargo uninstall deepseek-tui-cli 2>/dev/null || true +cargo uninstall deepseek-tui 2>/dev/null || true +cargo install codewhale-cli --locked +cargo install codewhale-tui --locked ``` Or in a checkout: