- Line-wrap long function signatures and format arguments
- Fix bracket placement for early returns (consistent style)
- Use [!] instead of [✓] for network-denied skill sync
- Fix copy-selection ordering: clear after success, not always
- Add CODEWHALE_RELEASE_BASE_URL as canonical env override for release
asset base URL (DEEPSEEK_TUI_RELEASE_BASE_URL and DEEPSEEK_RELEASE_BASE_URL
remain as legacy fallbacks).
- Add CODEWHALE_USE_CNB_MIRROR env var to auto-select the CNB (cnb.cool)
mirror for binary downloads, avoiding GitHub Releases timeouts in China.
- Update npm install scripts (artifacts.js) with the same env checks.
- Update Rust self-updater (update.rs) with new constants and env cascade.
Fixes#2222.
- config/src/lib.rs: remove undefined has_api_key variable (#2062 conflict)
- ui.rs: clone receipt before move into set_receipt_text
- footer_ui.rs: convert &str to String for if/else type consistency
- rlm.rs: use ref bindings to avoid partial moves of stdout/stderr_preview
- file.rs: prefix unused fuzz variable
- update.rs: remove redundant borrows
- tests.rs: allow print_stderr on catalog metrics test function
All clippy warnings resolved. CI should go green.
Issue 1600 asks for full rename UX: set a custom title, remove it back
to `(unnamed)`. The set side already shipped as `deepseek thread
set-name <id> <name>`, but there was no inverse — users who wanted to
drop a no-longer-relevant title had to either edit the SQLite store by
hand or set a placeholder string.
Add `deepseek thread clear-name <id>`, mirroring the existing
`SetName` arm in `run_thread_command`: look up the thread, set
`name = None`, refresh `updated_at`, upsert. Printed confirmation is
`cleared name for <id>` so it stays distinguishable from the
`renamed` line emitted by `set-name`.
Snapshot help test and the parser-matrix test both gain the new
subcommand. No state-store changes: `upsert_thread` already accepts
`name: None` and `thread list` already prints `(unnamed)` when the
field is empty, so the round-trip is complete with this CLI-only
change.
Co-authored-by: Claude <noreply@anthropic.com>
Covers Openrouter, Novita, NvidiaNim, Fireworks, Sglang, Vllm, Ollama,
Atlascloud, and WanjieArk — the providers that were silently expanded
by the generic provider_env_vars loop but had no test coverage beyond
the existing Moonshot and OpenAI cases.
Co-Authored-By: bot_apk <apk@cognition.ai>
Harvested from PR #2118 by @Hmbown.
Includes Kimi/Moonshot OAuth, v0.8.45 release prep, the Codex/ChatGPT OAuth removal, open-source-first model defaults, and the safe green PR batch merged into main before the release branch refresh.
Adds Moonshot/Kimi provider support with Kimi CLI OAuth reuse and review fixes for secure refresh writes, model completion, CLI auth, and secret-store behavior.
Permanent short-form shim — forwards silently to codewhale.
Six fewer keystrokes, no deprecation warning. Ships alongside
codewhale and the legacy deepseek alias.
Rename the canonical binaries:
- `deepseek` → `codewhale` (CLI dispatcher)
- `deepseek-tui` → `codewhale-tui` (TUI runtime)
Both legacy names continue to ship as tiny deprecation shims that print
a one-line warning to stderr and forward argv to the new binary. The
shims are produced by two new `[[bin]]` entries in `crates/cli/Cargo.toml`
and `crates/tui/Cargo.toml` pointing at small source files under
`src/bin/`. They will be removed in v0.9.0.
Touchpoints:
- Cargo bin entries + new shim source files.
- clap `name`/`bin_name`/usage strings flip to `codewhale`.
- Dispatcher's sibling-binary discovery looks for `codewhale-tui` and
reports `codewhale` in its error/help prose. `DEEPSEEK_TUI_BIN` env
var stays — env vars are explicitly anti-scope.
- `update.rs` now downloads `codewhale-*` assets and verifies them
against `codewhale-artifacts-sha256.txt`. Legacy `deepseek-*` assets
and `deepseek-artifacts-sha256.txt` are still produced by the release
matrix so v0.8.40's `deepseek update` keeps working through one
transition release.
- `ci.yml`, `nightly.yml`, `release.yml` updated to build/upload the new
canonical binaries; `release.yml`'s matrix doubles to also ship the
legacy shim binaries so v0.8.40 update clients land on the shim.
- `scripts/release/crates.sh` and `check-versions.sh` updated for the
renamed crate names from R1.
Local gates green: `cargo check --workspace --all-targets --locked`,
`cargo fmt --all -- --check`, `cargo clippy --workspace --all-targets
--all-features --locked -- -D warnings`, `cargo test --workspace
--all-features --locked` (3226+ pass, 0 fail), and `cargo build
--release` produces all four binaries:
- target/release/codewhale (canonical dispatcher)
- target/release/codewhale-tui (canonical TUI)
- target/release/deepseek (legacy shim, forwards to codewhale)
- target/release/deepseek-tui (legacy shim, forwards to codewhale-tui)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Rename the 14 workspace member crates from `deepseek-*` (and
`deepseek-tui-*`) to `codewhale-*`. Internal-only — binary names
(`deepseek` and `deepseek-tui`) are intentionally untouched in this
phase; they move in the next phase along with the deprecation shims.
Affects:
- 14 `[package] name = "..."` declarations.
- All inter-crate `[dependencies]` entries that referenced the old
package names.
- All `use deepseek_*::...` statements rewritten to `use codewhale_*`.
- Cargo.lock regenerated.
CI workflows and release scripts that pass `-p deepseek-*` still
reference the old names; those move with the binary rename phase so
that pair lands together.
Local gates green: `cargo check --workspace --all-targets --locked`,
`cargo fmt --all -- --check`, `cargo clippy --workspace --all-targets
--all-features --locked -- -D warnings`, `cargo test --workspace
--all-features --locked` (3226+ pass, 0 fail).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add the Feishu/Lark long-connection bridge, Tencent Lighthouse runbooks, CNB mirror guidance, CNB tag release pipeline, and China-friendly update fallback documentation for the v0.8.37 line.
Workspace, all 9 path-pinned crate deps, and the npm wrapper's
package.json all advance from 0.8.31 → 0.8.32. `scripts/release/
check-versions.sh` passes (workspace ↔ npm ↔ Cargo.lock all in
sync).
Auto-tag only fires on push-to-main, so this bump on `work/v0.8.32`
doesn't accidentally cut a release; it just makes the
in-development binary identify itself correctly. When this branch
merges to main, the existing release pipeline takes over from
here.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
AtlasCloud (https://atlascloud.ai) hosts the V4 family on its own
DeepSeek-compatible endpoint at `https://api.atlascloud.ai/v1`, and
several contributors had been running it through the
OpenAI-compatible passthrough with manual `base_url` / model
overrides. Selecting `provider = "atlascloud"` in
`~/.deepseek/config.toml` (or via `DEEPSEEK_PROVIDER=atlascloud`)
now wires up:
- documented `DEFAULT_ATLASCLOUD_BASE_URL` /
`DEFAULT_ATLASCLOUD_MODEL` defaults so a fresh install needs
only the api_key
- a `[providers.atlascloud]` config block with the same fields
every other named provider exposes (api_key / base_url / model
/ http_headers)
- `ATLASCLOUD_API_KEY` env var path, including the secrets test
cleanup loop so per-test env hygiene continues to work
- the provider-picker / `/provider` slash command entries so the
provider is reachable from the runtime UI, not just config
- the env-driven `*_BASE_URL` override branch so users who pin a
proxy can still flip it without editing config.toml
Trust-boundary pins held: AtlasCloud is opt-in (default remains
DeepSeek), no API keys are hardcoded, the api_key resolution flows
through the same `secrets` crate path every other provider uses,
and the provider-config base_url stays settable per environment.
Resolved 3-way merge conflicts in `crates/secrets/src/lib.rs` (env
cleanup loop) and `crates/tui/src/config.rs` (per-provider
base_url match arm + `provider_passes_model_through` predicate)
so the contributor's AtlasCloud branch coexists with the v0.8.x
provider expansion already on `main`. Added the missing match arm
in `validate_provider_base_url` so the non-exhaustive-pattern
check passes after the new variant lands.
Harvested from PR #1436 by @lucaszhu-hue
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Before this change, `deepseek update` would replace the running
dispatcher binary at `~/.cargo/bin/deepseek` but leave the sibling
`~/.cargo/bin/deepseek-tui` at whatever version was installed last.
The dispatcher then reported the new release while the TUI binary it
shells out to for every interactive turn stayed pinned to the old
build — most visible on Volta-managed npm installs and on any flow
that uses `deepseek update` instead of re-running both
`cargo install --path crates/{cli,tui}`.
The updater now enumerates the running binary plus an existing
colocated sibling up front, fetches and SHA256-verifies every needed
release asset before replacing anything on disk, then swaps the
sibling first and the running dispatcher last so a partial network
failure can't leave the launcher updated while the TUI remains stale.
The success message lists every refreshed binary by full path.
Tests cover sibling target detection (dispatcher present + sibling TUI
present → both targeted) and the no-sibling fallback (dispatcher only
→ single target).
Harvested from PR #1492 by @NorethSea
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- workspace.package.version: 0.8.29 → 0.8.30
- per-crate path-dependency version pins: 0.8.29 → 0.8.30
- npm/deepseek-tui: version + deepseekBinaryVersion → 0.8.30
- Cargo.lock refreshed via `cargo update --workspace --offline`
- CHANGELOG: `[Unreleased]` → `[0.8.30] - 2026-05-11` with the full
release-theme paragraph and the new "Changed" section for the
Alt+<key> unification
Verified with `./scripts/release/check-versions.sh`:
Version state OK: workspace=0.8.30, npm=0.8.30, lockfile in sync.
Workspace + per-crate path-dep version pins, npm wrapper, and
deepseekBinaryVersion all advance 0.8.28 -> 0.8.29.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Workspace + per-crate path-dep version pins, npm wrapper, and
`deepseekBinaryVersion` all advance from 0.8.27 → 0.8.28. Lockfile
refreshed via `cargo update --workspace --offline`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two small workspace-clippy gaps that snuck through the per-crate
sweeps in this branch:
* `crates/cli/src/lib.rs` — the OpenAI-provider passthrough test was
building a `ResolvedRuntimeOptions` literal directly and missed the
`yolo: Option<bool>` field that landed earlier on this branch in
665801bb8 (`fix(cli): forward --yolo to TUI binary`). Set to `None`
to match the test's non-yolo intent.
* `crates/tui/src/mcp.rs` — the new `reload_if_config_changed` swap
test was using `iter().any(|n| *n == "new")`, which is rust-1.94
clippy's `manual_contains` lint. Switched to `names.contains(&"new")`.
`cargo clippy --workspace --all-targets --all-features --locked --
-D warnings` is now green.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The CLI dispatcher accepted --yolo but only passed it to Exec(TuiPassthroughArgs),
not to the plain Run(RunArgs) path used for interactive sessions.
Fix: pass DEEPSEEK_YOLO=true env var to the TUI binary. The TUI already
reads this env var (matching DEEPSEEK_SANDBOX_MODE pattern) and sets
allow_shell + start_in_agent_mode + yolo.
Also adds yolo field to CliRuntimeOverrides and ResolvedRuntimeOptions
so the flag propagates through the full resolve chain.
The earlier build-script fix only watched .git/HEAD, which catches
branch switches and detached-HEAD moves but NOT git commit on the
current branch — the commit updates the underlying ref file
(refs/heads/<name> or packed-refs after pack-refs), and HEAD itself
stays unchanged. So the embedded short-SHA in deepseek --version went
stale on the same-branch-commit case the fix was supposed to cover.
Resolve the symbolic ref at build time and watch:
- the loose ref file (refs/heads/<branch>)
- packed-refs (Cargo treats a non-existent rerun-if-changed path as
always-changed, which covers the loose to packed transition after
git pack-refs)
Detached HEAD is unchanged: HEAD itself contains a SHA, no symbolic
deref happens, and HEAD-as-watched still triggers on every move.
Adds parse_symbolic_ref + 4 unit tests covering: stripped prefix,
no trailing newline, detached SHA, empty input.
Smoke verified: with the previous fix, an empty commit on the same
branch did not bust the cache. With this commit, it does.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`build.rs` only declared `rerun-if-env-changed` for `DEEPSEEK_BUILD_SHA`
and `GITHUB_SHA`. With no `rerun-if-changed` directives, Cargo cached
the build-script output across commits and the embedded short-SHA in
`DEEPSEEK_BUILD_VERSION` (visible in `--version`) went stale until the
next `cargo clean`.
Add a `cargo:rerun-if-changed=<workspace>/.git/HEAD` directive in both
the `cli` and `tui` build scripts. Handle both layouts: a regular
checkout (`.git` is a directory) and a worktree (`.git` is a pointer
file containing `gitdir: <path>`), so the SHA stays current in either
case.
Verified: touching `.git/HEAD` now triggers a recompile of the affected
crate; `--version` reflects the current commit on the next build.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two responsibly-disclosed security fixes:
- GHSA-88gh-2526-gfrr (@JafarAkhondali)
- GHSA-72w5-pf8h-xfp4 (@47Cid)
Plus version bump, CHANGELOG, regression tests for both.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>