- New github_close_pr tool distinct from github_close_issue; proper PR wording
in tool output, audit records, and gh pr close (not issue close)
- handle_read detects art_/call_/SHA refs and points to retrieve_tool_result
with copy-pasteable hints; error messages show correct tool for each ref type
- Shell delta tool results include the command field so the UI can resolve
task_id-only exec cells when the completion metadata arrives
- Sidebar background shell tasks show the actual command on the primary row
instead of just the task ID; task ID stays available as dim detail
- Tool routing falls back to task_id when exec_shell_wait has no command,
then updates when the completion carries command metadata
- Plan mode prompt explains update_plan as the handoff signal; model waits
for user action instead of continuing to tool around
- Base prompt clarifies handle_read scope (var_handles only) vs
retrieve_tool_result (artifacts/tool-result refs)
- New tests: close_pr_schema, close distinction wording, handle_read artifact
detection, shell_wait task_id fallback, sidebar background task labels
Sweep brand mentions of `DeepSeek TUI` / `deepseek-tui` / bare
`deepseek` (the dispatcher binary) across all user-facing docs to
the new `codewhale` brand. The DeepSeek **provider** integration is
left untouched throughout: env vars (`DEEPSEEK_*`), model IDs
(`deepseek-v4-pro`, `deepseek-v4-flash`, `deepseek-chat`,
`deepseek-reasoner`), the `api.deepseek.com` host, the
`~/.deepseek/` config dir, and the `--provider deepseek` argument
value all keep the legacy spelling.
Anti-scope items deliberately left as the legacy `deepseek-tui`:
- Homebrew tap and formula (`Hmbown/homebrew-deepseek-tui`,
`brew install deepseek-tui`, `scoop install deepseek-tui`). The
tap rename ships separately.
- Docker image (`ghcr.io/hmbown/deepseek-tui`). Image-tag rename
ships separately.
- CNB mirror namespace (`cnb.cool/deepseek-tui.com/DeepSeek-TUI`).
Third-party hosted path.
- Security contact email (`security@deepseek-tui.com`).
- GitHub repo URL (`Hmbown/DeepSeek-TUI`).
New artifact:
- `docs/REBRAND.md` documents what changed, what didn't, the
deprecation window, and migration commands for npm / Cargo /
Homebrew / manual installs.
CHANGELOG entries:
- Root `CHANGELOG.md` and `crates/tui/CHANGELOG.md` both gain a
new `[Unreleased]` section describing the rename and the one-
release deprecation window. Historical entries are untouched.
Issue templates:
- `.github/ISSUE_TEMPLATE/bug_report.md` and `feature_request.md`
refer to "codewhale" / `codewhale --version` instead of the old
brand name in their environment fields.
The rebrand sweep was driven by a perl script with bulk patterns
(`deepseek-tui` -> `codewhale-tui`, `DeepSeek TUI` -> `codewhale`,
bare `deepseek` -> `codewhale` with provider/model/host/env-var/
config-path negative lookbehind/lookahead) followed by targeted
reverts for the anti-scope items above. Output was visually
reviewed file-by-file before committing.
Verified:
- `cargo check --workspace --all-targets --locked` — pass.
- `cargo test --workspace --all-features --locked` — pass (no
test source touched here; suite stayed green to confirm no
doc-from-string assertions broke).
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.
Closes#1359. On Windows 11 + VSCode integrated terminal +
PowerShell, pressing `Shift+Enter` in the composer submitted the
message instead of inserting a newline. `Alt+Enter` / `Ctrl+J`
were broken the same way. Root cause: crossterm's
`PushKeyboardEnhancementFlags` checks `is_ansi_code_supported()`
before emitting the escape, and on Windows that helper queries
the console mode rather than the VT capability and
unconditionally returns false — so the Kitty push `\x1b[>1u` was
never written. xterm.js then stayed in legacy mode where
`Shift+Enter` and `Enter` both encode as `\r`, indistinguishable.
The fix writes the push and pop escapes directly under
`#[cfg(windows)]`, bypassing the crossterm capability gate.
VSCode and Windows Terminal honour the Kitty keyboard protocol;
terminals that don't (older conhost without VT processing)
silently discard the unknown escapes. The same gate also meant
`PopKeyboardEnhancementFlags` was silently dropped on Windows in
the `main.rs` panic hook and in
`tui::external_editor::spawn_editor_for_input` — both call sites
now route through `pop_keyboard_enhancement_flags` so a crash or
`$EDITOR` invocation can't leave the parent shell with a
Kitty-enhanced keyboard state.
Two `#[cfg(windows)]` regression tests pin the direct-write path
so accidentally falling back to `execute!()` against
`crossterm::PushKeyboardEnhancementFlags` would now fail in CI:
- `push_keyboard_flags_writes_kitty_push_sequence_on_windows`
- `pop_keyboard_flags_writes_kitty_pop_sequence_on_windows`
Non-Windows behaviour is unchanged — the existing
`recover_terminal_modes_emits_expected_csi_sequences_with_gating`
test still passes on Linux and macOS.
Also adds a v0.8.29 audit note to `docs/KEYBINDINGS.md` and
documents a pre-existing FocusGained stack-depth bug for a
separate fix.
Harvested from PR #1483 by @CrepuscularIRIS
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>
Closes the persistent "fatal: could not read Username for 'https://cnb.cool'"
failure that bit about half of recent sync-cnb runs.
Root causes from the failure log of run 25705666413 (2026-05-12) and
25697452832 (2026-05-11):
1. The previous tencentcom/git-sync Docker action discovered every
local ref via fetch-depth: 0 and tried to push them all —
including dependabot/* branches that GitHub had locally. Those
follow-on pushes ran without the configured credential helper
in scope and failed with the basic-auth prompt error above.
2. No concurrency guard meant the back-to-back `main` push and
`v*` tag push that auto-tag.yml fires within ~15s of each other
raced. Two workflow runs would attempt to push to the same
CNB remote simultaneously; one would lose.
Rewrite:
* Hand-rolled `git push` with the CNB token URL-encoded inline so
the credential is always in scope. No Docker action dependency.
* `concurrency: group: cnb-sync, cancel-in-progress: false` so
queued runs serialize cleanly rather than racing or dropping.
* Only push the ref that triggered the run — `main` on branch
push (with --force-with-lease for safety), the specific tag on
tag push. Feature branches and dependabot refs no longer
mirror.
* 3-attempt retry with linear backoff (5s, 10s) for transient
failures (CNB rate-limit, DNS blips, etc.).
* `workflow_dispatch: {}` trigger so the maintainer can re-run
against a specific ref manually if the automated run fails.
Adds docs/CNB_MIRROR.md with: the verification steps after a
release, the manual fallback procedure (one-time `git remote add cnb`,
then `git push cnb vX.Y.Z`), the token-rotation procedure, and a
note on why binary release assets aren't on CNB today.
Cross-links from docs/RELEASE_RUNBOOK.md so the verify-after-release
step doesn't get forgotten.
Extend /note beyond append-only usage with list, show, edit, remove,
clear, path, and explicit add subcommands.
Keep existing /note <text> behavior compatible, preserve the existing
--- separated file format, and number notes only at display time so the
stored notes stay clean.
Update command help, localization, docs, and tests.
Replace the separate /agent, /plan, and /yolo commands with a single
/mode command that can either open a picker or switch directly by name
or number.
This keeps mode switching in one command surface and avoids duplicating
similar commands for each mode.
- Bump workspace version 0.8.22 → 0.8.23 across Cargo.toml, every per-crate
path-dependency pin, npm/deepseek-tui/package.json (both `version` and
`deepseekBinaryVersion`), and Cargo.lock.
- Add a 0.8.23 CHANGELOG entry covering the security hardening stack
(sanitized child env, plan-mode tool surface, sub-agent approvals,
symlink walks, runtime API auth, shell safety classification, MCP
config path traversal), the macOS Keychain prompt fix, the #1244 MCP
spawn error visibility + env passthrough work, the compact-thinking UX
change, and a Known issues callout for mid-run MCP stderr.
- Backfill missing CHANGELOG entries for v0.8.21 (community-heavy
release, contributors credited) and v0.8.22 (fetch_url redirect
validation). The gap was unintentional, so contributor work is being
reflected in-repo now.
- Add docs/RELEASE_CHECKLIST.md so future releases gate on the
CHANGELOG/version/preflight steps explicitly.
## Summary
- Prefer a writable named Docker volume for the container home data path.
- Document the non-root UID/GID ownership requirement for host bind mounts.
- Update README and Docker docs examples to avoid permission-denied first runs.
## Test plan
- git diff --check
- GitHub CI green: version drift, lint, ubuntu, macOS, Windows, npm wrapper smoke, GitGuardian
Update competitive analysis to reflect that LSP integration is now
implemented as automatic post-edit diagnostics injection, and adjust
the recommended implementation order accordingly.
Co-authored-by: Stephen Xu <wexu@expediagroup.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(config): keep DeepSeek beta endpoint for legacy cn alias
* fix(ci): filter download-artifact to deepseek* pattern
Prevents the release aggregation job from picking up non-binary
artifacts (e.g. Docker .dockerbuild cache layers) that cause the
checksum manifest to include spurious entries and the Release to
carry files it shouldn't.
* fix(tui): enable focus events to restore IME after app-switch
On macOS, switching away (Cmd+Tab) and back suspends the IME compositor.
Without focus-event handling, the TUI never signals readiness to the
terminal, so CJK input methods (Pinyin, Zhuyin, etc.) stop working.
- EnableFocusChange on startup so the terminal reports FocusGained/FocusLost
- Re-push KeyboardEnhancementFlags on FocusGained (some terminals reset
the enhanced keyboard mode on focus-loss)
- DisableFocusChange on shutdown for clean terminal handoff
* chore: cargo fmt
* docs: add DataWhale and DeepSeek to acknowledgments
* docs: fix DeepSeek name etymology in acknowledgments
* fix(tui): recapture viewport on focus restore
* docs: thank DeepSeek and DataWhale bilingually