From 4c32a316bea28bd5b63f39b0b0e8d7040af92ac5 Mon Sep 17 00:00:00 2001 From: Hunter Bown Date: Thu, 14 May 2026 14:37:14 -0500 Subject: [PATCH] chore(release): prepare v0.8.37 --- CHANGELOG.md | 52 ++- Cargo.lock | 28 +- Cargo.toml | 2 +- README.md | 15 +- 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 | 52 ++- crates/tui/Cargo.toml | 4 +- crates/tui/src/config.rs | 10 +- crates/tui/src/tui/footer_ui.rs | 6 +- crates/tui/src/tui/format_helpers.rs | 6 +- crates/tui/src/tui/ui/tests.rs | 23 +- npm/deepseek-tui/package.json | 4 +- web/app/[locale]/install/page.tsx | 634 +++++++++++++++----------- web/app/[locale]/page.tsx | 2 +- web/components/footer.tsx | 1 + web/components/install-binary.tsx | 107 +++++ web/components/install-code-block.tsx | 34 ++ web/components/install-tabs.tsx | 331 -------------- web/lib/facts.generated.ts | 4 +- web/lib/github.ts | 2 +- 27 files changed, 694 insertions(+), 681 deletions(-) create mode 100644 web/components/install-binary.tsx create mode 100644 web/components/install-code-block.tsx delete mode 100644 web/components/install-tabs.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index d2a5c0ec..e2338fe3 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.37] - 2026-05-14 + ### Added - **Tencent Lighthouse + Feishu/Lark bridge setup.** Added a `/opt/whalebro` @@ -17,9 +19,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 Feishu/Lark + optional EdgeOne teaching path and added non-active CNB deploy templates for a future Lighthouse deploy button. Feishu/Lighthouse branches are now mirrored to CNB for Tencent-first bootstrap. +- **Homebrew tap automation is release-gated.** The release workflow can update + `Hmbown/homebrew-deepseek-tui` from the checksum manifest when a tap token is + configured, and skips cleanly before downloading release assets when no tap + token exists. + +### Changed + +- **Bing is the default `web_search` backend.** DuckDuckGo remains selectable + with `[search] provider = "duckduckgo"` and keeps its Bing fallback path. ### Fixed +- **First-run onboarding stays usable without an API key.** Missing-key startup + no longer aborts the TUI before onboarding can collect provider settings. +- **Streamable HTTP MCP sessions keep their server-issued session ID.** Custom + headers also apply to GET preflight requests, fixing authenticated MCP + servers that require both. +- **DeepSeek model completions use canonical IDs.** Alias completions now + resolve to stable DeepSeek model names before being written to config. +- **Terminal and child-process reliability is tighter.** Signal shutdown now + restores the terminal, child tasks preserve proxy environment variables, and + Windows Enter / CSI-u input handling avoids the prior event mismatch. +- **Long terminal text wraps instead of overflowing.** Streaming output, diff + rendering, and the pager now hard-wrap overlong no-whitespace and CJK runs. +- **Release and platform edges are safer.** The TUI no longer trips the Windows + Instant-underflow test path, unsupported desktop targets compile the external + URL opener, and legacy DeepSeek CN provider aliases deserialize to the + canonical DeepSeek provider. +- **Footer diagnostics are less cryptic.** Prefix-cache stability is no longer + shown in the default footer, and the opt-in `/statusline` chip now says + `cache prefix 100%` instead of the ambiguous `P 100%`. - **Feishu/Lark bridge dependency installs are locked and audited.** The bridge now ships a package lock, installs with `npm ci` on Lighthouse when available, and overrides the Lark SDK's transitive `axios` dependency to a @@ -33,10 +63,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 workflow now mirrors Feishu/Lighthouse release branches, so Tencent Lighthouse bootstrap can use CNB before the release branch merges. -### Changed +### Thanks -- **Bing is the default `web_search` backend.** DuckDuckGo remains selectable - with `[search] provider = "duckduckgo"` and keeps its Bing fallback path. +Thanks to **ZzzPL ([@Oliver-ZPLiu](https://github.com/Oliver-ZPLiu))** for +the MCP Streamable HTTP and Homebrew automation fixes (#1643, #1631), +**Reid ([@reidliu41](https://github.com/reidliu41))** for CI, streaming wrap, +and model-completion fixes (#1603, #1628, #1601), **MidoriKurage +([@mdrkrg](https://github.com/mdrkrg))** for the onboarding crash fix (#1598), +**Gordon ([@gordonlu](https://github.com/gordonlu))** for the Windows Enter / +CSI-u fix (#1612), **Aitensa ([@Aitensa](https://github.com/Aitensa))** for +the CJK diff/pager wrap fix (#1622), **qiyan233 +([@qiyan233](https://github.com/qiyan233))** for legacy DeepSeek CN provider +aliases (#1645), **jieshu666 ([@jieshu666](https://github.com/jieshu666))** +for the repaint-flicker reduction (#1563), **Vishnu +([@Vishnu1837](https://github.com/Vishnu1837))** for terminal restoration on +signals (#1586), and **axobase001 +([@axobase001](https://github.com/axobase001))** for proxy environment +preservation in child tasks (#1608). ## [0.8.36] - 2026-05-14 @@ -4161,7 +4204,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.36...HEAD +[Unreleased]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.8.37...HEAD +[0.8.37]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.8.36...v0.8.37 [0.8.36]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.8.35...v0.8.36 [0.8.35]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.8.34...v0.8.35 [0.8.34]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.8.33...v0.8.34 diff --git a/Cargo.lock b/Cargo.lock index c55a62b8..8621c8a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1160,7 +1160,7 @@ dependencies = [ [[package]] name = "deepseek-agent" -version = "0.8.36" +version = "0.8.37" dependencies = [ "deepseek-config", "serde", @@ -1168,7 +1168,7 @@ dependencies = [ [[package]] name = "deepseek-app-server" -version = "0.8.36" +version = "0.8.37" dependencies = [ "anyhow", "axum", @@ -1190,7 +1190,7 @@ dependencies = [ [[package]] name = "deepseek-config" -version = "0.8.36" +version = "0.8.37" dependencies = [ "anyhow", "deepseek-secrets", @@ -1202,7 +1202,7 @@ dependencies = [ [[package]] name = "deepseek-core" -version = "0.8.36" +version = "0.8.37" dependencies = [ "anyhow", "chrono", @@ -1220,7 +1220,7 @@ dependencies = [ [[package]] name = "deepseek-execpolicy" -version = "0.8.36" +version = "0.8.37" dependencies = [ "anyhow", "deepseek-protocol", @@ -1229,7 +1229,7 @@ dependencies = [ [[package]] name = "deepseek-hooks" -version = "0.8.36" +version = "0.8.37" dependencies = [ "anyhow", "async-trait", @@ -1243,7 +1243,7 @@ dependencies = [ [[package]] name = "deepseek-mcp" -version = "0.8.36" +version = "0.8.37" dependencies = [ "anyhow", "serde", @@ -1252,7 +1252,7 @@ dependencies = [ [[package]] name = "deepseek-protocol" -version = "0.8.36" +version = "0.8.37" dependencies = [ "serde", "serde_json", @@ -1260,7 +1260,7 @@ dependencies = [ [[package]] name = "deepseek-secrets" -version = "0.8.36" +version = "0.8.37" dependencies = [ "dirs", "keyring", @@ -1273,7 +1273,7 @@ dependencies = [ [[package]] name = "deepseek-state" -version = "0.8.36" +version = "0.8.37" dependencies = [ "anyhow", "chrono", @@ -1285,7 +1285,7 @@ dependencies = [ [[package]] name = "deepseek-tools" -version = "0.8.36" +version = "0.8.37" dependencies = [ "anyhow", "async-trait", @@ -1298,7 +1298,7 @@ dependencies = [ [[package]] name = "deepseek-tui" -version = "0.8.36" +version = "0.8.37" dependencies = [ "anyhow", "arboard", @@ -1361,7 +1361,7 @@ dependencies = [ [[package]] name = "deepseek-tui-cli" -version = "0.8.36" +version = "0.8.37" dependencies = [ "anyhow", "chrono", @@ -1386,7 +1386,7 @@ dependencies = [ [[package]] name = "deepseek-tui-core" -version = "0.8.36" +version = "0.8.37" [[package]] name = "deltae" diff --git a/Cargo.toml b/Cargo.toml index d941949d..fd2e4aee 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.36" +version = "0.8.37" 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/README.md b/README.md index 26670df1..300dd585 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ It is built around DeepSeek V4 (`deepseek-v4-pro` / `deepseek-v4-flash`), includ - **Thinking-mode streaming** — see DeepSeek reasoning blocks as the model works - **Full tool suite** — file ops, shell execution, git, web search/browse, apply-patch, sub-agents, MCP servers - **1M-token context** — context tracking, manual or configured compaction, and prefix-cache telemetry -- **Prefix-cache stability tracking** — a footer chip surfaces how stable the cached prefix has been across recent turns so cost-busting edits are visible before they land +- **Prefix-cache stability tracking** — an optional `/statusline` footer chip surfaces how stable the cached prefix has been across recent turns so cost-busting edits are visible before they land - **Three modes** — Plan (read-only explore), Agent (interactive with approval), YOLO (auto-approved) - **Reasoning-effort tiers** — cycle through `off → high → max` with `Shift + Tab` - **Session save/resume** — checkpoint and resume long-running sessions @@ -491,7 +491,7 @@ This project ships with help from a growing community of contributors: - **[loongmiaow-pixel](https://github.com/loongmiaow-pixel)** — Windows + China install documentation (#578) - **[20bytes](https://github.com/20bytes)** — User memory docs and help polish (#569) - **[staryxchen](https://github.com/staryxchen)** — glibc compatibility preflight (#556) -- **[Vishnu1837](https://github.com/Vishnu1837)** — glibc compatibility improvements (#565) +- **[Vishnu1837](https://github.com/Vishnu1837)** — glibc compatibility improvements and terminal restoration on SIGINT/SIGTERM (#565, #1586) - **[shentoumengxin](https://github.com/shentoumengxin)** — Shell `cwd` boundary validation (#524) - **[toi500](https://github.com/toi500)** — Windows paste fix report - **[xsstomy](https://github.com/xsstomy)** — Terminal startup repaint report @@ -502,8 +502,8 @@ This project ships with help from a growing community of contributors: - **[wangfeng](mailto:wangfengcsu@qq.com)** — Pricing/discount info update (#692) - **[zichen0116](https://github.com/zichen0116)** — CODE_OF_CONDUCT.md (#686) - **[dfwqdyl-ui](https://github.com/dfwqdyl-ui)** — model ID case-sensitivity compatibility report (#729) -- **[Oliver-ZPLiu](https://github.com/Oliver-ZPLiu)** — stale `working...` state bug report and Windows clipboard fallback (#738, #850) -- **[reidliu41](https://github.com/reidliu41)** — resume hint, workspace trust persistence, Ollama provider support, and thinking-block stream finalization (#863, #870, #921, #1078) +- **[Oliver-ZPLiu](https://github.com/Oliver-ZPLiu)** — stale `working...` state bug report, Windows clipboard fallback, MCP Streamable HTTP session fixes, and Homebrew tap automation (#738, #850, #1643, #1631) +- **[reidliu41](https://github.com/reidliu41)** — resume hint, workspace trust persistence, Ollama provider support, thinking-block stream finalization, CI cache hardening, streaming wrap, and DeepSeek model completions (#863, #870, #921, #1078, #1603, #1628, #1601) - **[xieshutao](https://github.com/xieshutao)** — plain Markdown skill fallback (#869) - **[GK012](https://github.com/GK012)** — npm wrapper `--version` fallback (#885) - **[y0sif](https://github.com/y0sif)** — parent turn-loop wakeup after direct child sub-agent completion (#901) @@ -520,7 +520,7 @@ This project ships with help from a growing community of contributors: - **Hafeez Pizofreude** — SSRF protection in `fetch_url` and Star History chart - **Unic (YuniqueUnic)** — Schema-driven config UI (TUI + web) - **Jason** — SSRF security hardening -- **[axobase001](https://github.com/axobase001)** — snapshot orphan cleanup, npm install guards, session telemetry fixes, model-scope cache clear, symlinked skill support, and npm mirror-escape-hatch guidance (#975, #1032, #1047, #1049, #1052, #1019, #1051, #1056) +- **[axobase001](https://github.com/axobase001)** — snapshot orphan cleanup, npm install guards, session telemetry fixes, model-scope cache clear, symlinked skill support, npm mirror-escape-hatch guidance, and proxy preservation for child tasks (#975, #1032, #1047, #1049, #1052, #1019, #1051, #1056, #1608) - **[MengZ-super](https://github.com/MengZ-super)** — `/theme` command foundation and SSE gzip/brotli decompression (#1057, #1061) - **[DI-HUO-MING-YI](https://github.com/DI-HUO-MING-YI)** — Plan-mode read-only sandbox safety fix (#1077) - **[bevis-wong](https://github.com/bevis-wong)** — precise paste-Enter auto-submit reproducer (#1073) @@ -530,6 +530,11 @@ This project ships with help from a growing community of contributors: - **[Jefsky](https://github.com/Jefsky)** — DeepSeek endpoint correction report (#1079, #1084) - **[wlon](https://github.com/wlon)** — NVIDIA NIM provider API-key preference diagnosis (#1081) - **[Horace Liu](https://github.com/liuhq)** — Nix package support and install documentation (#1173) +- **[jieshu666](https://github.com/jieshu666)** — terminal repaint flicker reduction (#1563) +- **[gordonlu](https://github.com/gordonlu)** — Windows Enter / CSI-u input fix (#1612) +- **[mdrkrg](https://github.com/mdrkrg)** — first-run onboarding crash fix when the API key is missing (#1598) +- **[Aitensa](https://github.com/Aitensa)** — CJK wrapping propagation for diff and pager output (#1622) +- **[qiyan233](https://github.com/qiyan233)** — legacy DeepSeek CN provider alias compatibility (#1645) --- diff --git a/crates/agent/Cargo.toml b/crates/agent/Cargo.toml index e15650e6..e118e5ea 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] -deepseek-config = { path = "../config", version = "0.8.36" } +deepseek-config = { path = "../config", version = "0.8.37" } serde.workspace = true diff --git a/crates/app-server/Cargo.toml b/crates/app-server/Cargo.toml index 8d1c0e60..8cef20c1 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 -deepseek-agent = { path = "../agent", version = "0.8.36" } -deepseek-config = { path = "../config", version = "0.8.36" } -deepseek-core = { path = "../core", version = "0.8.36" } -deepseek-execpolicy = { path = "../execpolicy", version = "0.8.36" } -deepseek-hooks = { path = "../hooks", version = "0.8.36" } -deepseek-mcp = { path = "../mcp", version = "0.8.36" } -deepseek-protocol = { path = "../protocol", version = "0.8.36" } -deepseek-state = { path = "../state", version = "0.8.36" } -deepseek-tools = { path = "../tools", version = "0.8.36" } +deepseek-agent = { path = "../agent", version = "0.8.37" } +deepseek-config = { path = "../config", version = "0.8.37" } +deepseek-core = { path = "../core", version = "0.8.37" } +deepseek-execpolicy = { path = "../execpolicy", version = "0.8.37" } +deepseek-hooks = { path = "../hooks", version = "0.8.37" } +deepseek-mcp = { path = "../mcp", version = "0.8.37" } +deepseek-protocol = { path = "../protocol", version = "0.8.37" } +deepseek-state = { path = "../state", version = "0.8.37" } +deepseek-tools = { path = "../tools", version = "0.8.37" } serde.workspace = true serde_json.workspace = true tokio.workspace = true diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 75c34c49..d9098ea7 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -14,13 +14,13 @@ path = "src/main.rs" anyhow.workspace = true clap.workspace = true clap_complete.workspace = true -deepseek-agent = { path = "../agent", version = "0.8.36" } -deepseek-app-server = { path = "../app-server", version = "0.8.36" } -deepseek-config = { path = "../config", version = "0.8.36" } -deepseek-execpolicy = { path = "../execpolicy", version = "0.8.36" } -deepseek-mcp = { path = "../mcp", version = "0.8.36" } -deepseek-secrets = { path = "../secrets", version = "0.8.36" } -deepseek-state = { path = "../state", version = "0.8.36" } +deepseek-agent = { path = "../agent", version = "0.8.37" } +deepseek-app-server = { path = "../app-server", version = "0.8.37" } +deepseek-config = { path = "../config", version = "0.8.37" } +deepseek-execpolicy = { path = "../execpolicy", version = "0.8.37" } +deepseek-mcp = { path = "../mcp", version = "0.8.37" } +deepseek-secrets = { path = "../secrets", version = "0.8.37" } +deepseek-state = { path = "../state", version = "0.8.37" } chrono.workspace = true dirs.workspace = true serde.workspace = true diff --git a/crates/config/Cargo.toml b/crates/config/Cargo.toml index db91205a..15fd19a9 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 -deepseek-secrets = { path = "../secrets", version = "0.8.36" } +deepseek-secrets = { path = "../secrets", version = "0.8.37" } dirs.workspace = true serde.workspace = true toml.workspace = true diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index 81456cb7..bbd5240d 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 -deepseek-agent = { path = "../agent", version = "0.8.36" } -deepseek-config = { path = "../config", version = "0.8.36" } -deepseek-execpolicy = { path = "../execpolicy", version = "0.8.36" } -deepseek-hooks = { path = "../hooks", version = "0.8.36" } -deepseek-mcp = { path = "../mcp", version = "0.8.36" } -deepseek-protocol = { path = "../protocol", version = "0.8.36" } -deepseek-state = { path = "../state", version = "0.8.36" } -deepseek-tools = { path = "../tools", version = "0.8.36" } +deepseek-agent = { path = "../agent", version = "0.8.37" } +deepseek-config = { path = "../config", version = "0.8.37" } +deepseek-execpolicy = { path = "../execpolicy", version = "0.8.37" } +deepseek-hooks = { path = "../hooks", version = "0.8.37" } +deepseek-mcp = { path = "../mcp", version = "0.8.37" } +deepseek-protocol = { path = "../protocol", version = "0.8.37" } +deepseek-state = { path = "../state", version = "0.8.37" } +deepseek-tools = { path = "../tools", version = "0.8.37" } serde_json.workspace = true uuid.workspace = true diff --git a/crates/execpolicy/Cargo.toml b/crates/execpolicy/Cargo.toml index 7affb7a7..8726a31e 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 -deepseek-protocol = { path = "../protocol", version = "0.8.36" } +deepseek-protocol = { path = "../protocol", version = "0.8.37" } serde.workspace = true diff --git a/crates/hooks/Cargo.toml b/crates/hooks/Cargo.toml index 4e60418f..ba7ab4fa 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 -deepseek-protocol = { path = "../protocol", version = "0.8.36" } +deepseek-protocol = { path = "../protocol", version = "0.8.37" } reqwest.workspace = true serde.workspace = true serde_json.workspace = true diff --git a/crates/tools/Cargo.toml b/crates/tools/Cargo.toml index e245b556..5551bf98 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 -deepseek-protocol = { path = "../protocol", version = "0.8.36" } +deepseek-protocol = { path = "../protocol", version = "0.8.37" } serde.workspace = true serde_json.workspace = true tokio.workspace = true diff --git a/crates/tui/CHANGELOG.md b/crates/tui/CHANGELOG.md index d2a5c0ec..e2338fe3 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.37] - 2026-05-14 + ### Added - **Tencent Lighthouse + Feishu/Lark bridge setup.** Added a `/opt/whalebro` @@ -17,9 +19,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 Feishu/Lark + optional EdgeOne teaching path and added non-active CNB deploy templates for a future Lighthouse deploy button. Feishu/Lighthouse branches are now mirrored to CNB for Tencent-first bootstrap. +- **Homebrew tap automation is release-gated.** The release workflow can update + `Hmbown/homebrew-deepseek-tui` from the checksum manifest when a tap token is + configured, and skips cleanly before downloading release assets when no tap + token exists. + +### Changed + +- **Bing is the default `web_search` backend.** DuckDuckGo remains selectable + with `[search] provider = "duckduckgo"` and keeps its Bing fallback path. ### Fixed +- **First-run onboarding stays usable without an API key.** Missing-key startup + no longer aborts the TUI before onboarding can collect provider settings. +- **Streamable HTTP MCP sessions keep their server-issued session ID.** Custom + headers also apply to GET preflight requests, fixing authenticated MCP + servers that require both. +- **DeepSeek model completions use canonical IDs.** Alias completions now + resolve to stable DeepSeek model names before being written to config. +- **Terminal and child-process reliability is tighter.** Signal shutdown now + restores the terminal, child tasks preserve proxy environment variables, and + Windows Enter / CSI-u input handling avoids the prior event mismatch. +- **Long terminal text wraps instead of overflowing.** Streaming output, diff + rendering, and the pager now hard-wrap overlong no-whitespace and CJK runs. +- **Release and platform edges are safer.** The TUI no longer trips the Windows + Instant-underflow test path, unsupported desktop targets compile the external + URL opener, and legacy DeepSeek CN provider aliases deserialize to the + canonical DeepSeek provider. +- **Footer diagnostics are less cryptic.** Prefix-cache stability is no longer + shown in the default footer, and the opt-in `/statusline` chip now says + `cache prefix 100%` instead of the ambiguous `P 100%`. - **Feishu/Lark bridge dependency installs are locked and audited.** The bridge now ships a package lock, installs with `npm ci` on Lighthouse when available, and overrides the Lark SDK's transitive `axios` dependency to a @@ -33,10 +63,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 workflow now mirrors Feishu/Lighthouse release branches, so Tencent Lighthouse bootstrap can use CNB before the release branch merges. -### Changed +### Thanks -- **Bing is the default `web_search` backend.** DuckDuckGo remains selectable - with `[search] provider = "duckduckgo"` and keeps its Bing fallback path. +Thanks to **ZzzPL ([@Oliver-ZPLiu](https://github.com/Oliver-ZPLiu))** for +the MCP Streamable HTTP and Homebrew automation fixes (#1643, #1631), +**Reid ([@reidliu41](https://github.com/reidliu41))** for CI, streaming wrap, +and model-completion fixes (#1603, #1628, #1601), **MidoriKurage +([@mdrkrg](https://github.com/mdrkrg))** for the onboarding crash fix (#1598), +**Gordon ([@gordonlu](https://github.com/gordonlu))** for the Windows Enter / +CSI-u fix (#1612), **Aitensa ([@Aitensa](https://github.com/Aitensa))** for +the CJK diff/pager wrap fix (#1622), **qiyan233 +([@qiyan233](https://github.com/qiyan233))** for legacy DeepSeek CN provider +aliases (#1645), **jieshu666 ([@jieshu666](https://github.com/jieshu666))** +for the repaint-flicker reduction (#1563), **Vishnu +([@Vishnu1837](https://github.com/Vishnu1837))** for terminal restoration on +signals (#1586), and **axobase001 +([@axobase001](https://github.com/axobase001))** for proxy environment +preservation in child tasks (#1608). ## [0.8.36] - 2026-05-14 @@ -4161,7 +4204,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.36...HEAD +[Unreleased]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.8.37...HEAD +[0.8.37]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.8.36...v0.8.37 [0.8.36]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.8.35...v0.8.36 [0.8.35]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.8.34...v0.8.35 [0.8.34]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.8.33...v0.8.34 diff --git a/crates/tui/Cargo.toml b/crates/tui/Cargo.toml index e9ebb170..5579d6db 100644 --- a/crates/tui/Cargo.toml +++ b/crates/tui/Cargo.toml @@ -21,8 +21,8 @@ path = "src/main.rs" [dependencies] anyhow = "1.0.100" arboard = "3.4" -deepseek-secrets = { path = "../secrets", version = "0.8.36" } -deepseek-tools = { path = "../tools", version = "0.8.36" } +deepseek-secrets = { path = "../secrets", version = "0.8.37" } +deepseek-tools = { path = "../tools", version = "0.8.37" } schemaui = { version = "0.12.0", default-features = false, optional = true } async-stream = "0.3.6" async-trait = "0.1" diff --git a/crates/tui/src/config.rs b/crates/tui/src/config.rs index 672a4f62..077bdd17 100644 --- a/crates/tui/src/config.rs +++ b/crates/tui/src/config.rs @@ -648,7 +648,7 @@ pub enum StatusItem { Agents, /// Reasoning-replay token count ("rsn 12.3k"). ReasoningReplay, - /// Prefix stability ("P 100%"). + /// Prefix stability ("cache prefix 100%"). PrefixStability, /// Cache hit rate ("cache 73%"). Cache, @@ -663,9 +663,10 @@ pub enum StatusItem { } impl StatusItem { - /// Default footer composition matching v0.6.6 behaviour exactly. Used when - /// `tui.status_items` is missing from `config.toml` so upgraders see the - /// same footer they had before. + /// Default footer composition for the always-on status line. Used when + /// `tui.status_items` is missing from `config.toml` so upgraders see a + /// concise footer by default; diagnostic chips remain available via + /// `/statusline` without crowding the main UI. #[must_use] pub fn default_footer() -> Vec { vec![ @@ -676,7 +677,6 @@ impl StatusItem { StatusItem::Coherence, StatusItem::Agents, StatusItem::ReasoningReplay, - StatusItem::PrefixStability, StatusItem::Cache, ] } diff --git a/crates/tui/src/tui/footer_ui.rs b/crates/tui/src/tui/footer_ui.rs index c3f86f7a..958e965d 100644 --- a/crates/tui/src/tui/footer_ui.rs +++ b/crates/tui/src/tui/footer_ui.rs @@ -510,8 +510,10 @@ pub(crate) fn footer_auxiliary_spans(app: &App, max_width: usize) -> Vec String { ) } -/// Format prefix stability info for the TUI footer chip. +/// Format prefix stability info for the opt-in TUI footer chip. pub(super) fn prefix_stability_chip(app: &App) -> Option<(String, ratatui::style::Color)> { let pct = app.prefix_stability_pct?; let changes = app.prefix_change_count; @@ -49,10 +49,10 @@ pub(super) fn prefix_stability_chip(app: &App) -> Option<(String, ratatui::style }; let label = if changes == 0 { - format!("P {pct}%") + format!("cache prefix {pct}%") } else { format!( - "P {pct}% ({changes} change{})", + "cache prefix {pct}% ({changes} change{})", if changes == 1 { "" } else { "s" } ) }; diff --git a/crates/tui/src/tui/ui/tests.rs b/crates/tui/src/tui/ui/tests.rs index aa5186a6..5978750e 100644 --- a/crates/tui/src/tui/ui/tests.rs +++ b/crates/tui/src/tui/ui/tests.rs @@ -4980,18 +4980,17 @@ fn render_footer_from_with_default_items_renders_mode_and_model() { } #[test] -fn default_footer_includes_prefix_stability_before_cache() { +fn default_footer_keeps_prefix_stability_opt_in() { let items = crate::config::StatusItem::default_footer(); - let prefix = items - .iter() - .position(|item| *item == crate::config::StatusItem::PrefixStability) - .expect("default footer includes prefix stability"); - let cache = items - .iter() - .position(|item| *item == crate::config::StatusItem::Cache) - .expect("default footer includes cache"); - assert!(prefix < cache); + assert!( + !items.contains(&crate::config::StatusItem::PrefixStability), + "prefix stability is a diagnostic chip and should not crowd the default footer" + ); + assert!( + items.contains(&crate::config::StatusItem::Cache), + "default footer should still include provider-reported cache hit rate" + ); } #[test] @@ -5002,7 +5001,7 @@ fn render_footer_from_prefix_stability_item_renders_cache_slot_chip() { let props = render_footer_from(&app, &[crate::config::StatusItem::PrefixStability], None); - assert_eq!(spans_text(&props.cache), "P 100%"); + assert_eq!(spans_text(&props.cache), "cache prefix 100%"); } #[test] @@ -5023,7 +5022,7 @@ fn render_footer_from_preserves_prefix_then_cache_order() { None, ); - assert!(spans_text(&props.cache).starts_with("P 100% Cache: 90.0% hit")); + assert!(spans_text(&props.cache).starts_with("cache prefix 100% Cache: 90.0% hit")); } #[test] diff --git a/npm/deepseek-tui/package.json b/npm/deepseek-tui/package.json index 5295ad1b..a2e689c4 100644 --- a/npm/deepseek-tui/package.json +++ b/npm/deepseek-tui/package.json @@ -1,7 +1,7 @@ { "name": "deepseek-tui", - "version": "0.8.36", - "deepseekBinaryVersion": "0.8.36", + "version": "0.8.37", + "deepseekBinaryVersion": "0.8.37", "description": "Install and run deepseek and deepseek-tui binaries from GitHub release artifacts.", "author": "Hmbown", "license": "MIT", diff --git a/web/app/[locale]/install/page.tsx b/web/app/[locale]/install/page.tsx index bb66d230..5ca2a8b4 100644 --- a/web/app/[locale]/install/page.tsx +++ b/web/app/[locale]/install/page.tsx @@ -1,7 +1,7 @@ import Link from "next/link"; -import { GITEE_ENABLED } from "@/lib/i18n/config"; import { Seal } from "@/components/seal"; -import { InstallTabs } from "@/components/install-tabs"; +import { InstallCodeBlock } from "@/components/install-code-block"; +import { InstallBinary } from "@/components/install-binary"; export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }) { const { locale } = await params; @@ -9,288 +9,396 @@ export async function generateMetadata({ params }: { params: Promise<{ locale: s return { title: isZh ? "安装 · DeepSeek TUI" : "Install · DeepSeek TUI", description: isZh - ? "在 macOS、Linux 或 Windows 上通过 Cargo、npm、Homebrew tap 或预编译二进制安装 deepseek-tui。" - : "Install deepseek-tui on macOS, Linux, or Windows via Cargo, npm, the Homebrew tap, or pre-built binaries.", + ? "通过 Cargo 安装 deepseek-tui。其他方式:npm、Homebrew、预编译二进制、Docker、国内镜像。" + : "Install deepseek-tui via Cargo. Other ways: npm, Homebrew, prebuilt binary, Docker, source.", }; } +const CARGO_INSTALL = `cargo install deepseek-tui-cli --locked`; +const FIRST_RUN = `deepseek`; +const VERIFY = `deepseek --version +deepseek doctor`; + +const SET_KEY_BASH = `export DEEPSEEK_API_KEY=sk-...`; +const SET_KEY_AUTH = `deepseek auth set --provider deepseek --api-key sk-...`; + +const NPM_INSTALL = `npm install -g deepseek-tui`; + +const TUNA_CONFIG = `# ~/.cargo/config.toml +[source.crates-io] +replace-with = "tuna" + +[source.tuna] +registry = "sparse+https://mirrors.tuna.tsinghua.edu.cn/crates.io-index/"`; +const TUNA_INSTALL = `cargo install deepseek-tui-cli --locked`; +const NPMMIRROR = `npm config set registry https://registry.npmmirror.com +npm install -g deepseek-tui`; + +const BREW = `brew tap Hmbown/deepseek-tui +brew install deepseek-tui`; + +const DOCKER = `git clone https://github.com/Hmbown/deepseek-tui +cd deepseek-tui +docker build -t deepseek-tui . + +docker run --rm -it \\ + -e DEEPSEEK_API_KEY=$DEEPSEEK_API_KEY \\ + -v ~/.deepseek:/home/deepseek/.deepseek \\ + -v "$PWD:/work" -w /work \\ + deepseek-tui`; + +const FROM_SOURCE = `git clone https://github.com/Hmbown/deepseek-tui +cd deepseek-tui +cargo build --release --locked + +# Install both binaries from the local checkout +cargo install --path crates/cli --locked # deepseek +cargo install --path crates/tui --locked # deepseek-tui`; + +const CONFIG_TREE = `~/.deepseek/ +├── config.toml api keys, model, hooks, profiles +├── mcp.json MCP server definitions +├── skills/ user skills (each with SKILL.md) +├── sessions/ checkpoints + offline queue +├── tasks/ background task store +└── audit.log credential / approval / elevation audit trail + +./.deepseek/ project-scoped config (optional, per-repo)`; + +const CONFIG_TREE_ZH = `~/.deepseek/ +├── config.toml API 密钥、模型、钩子、配置集 +├── mcp.json MCP 服务器定义 +├── skills/ 用户技能(每个含 SKILL.md) +├── sessions/ 检查点 + 离线队列 +├── tasks/ 后台任务存储 +└── audit.log 凭证 / 审批 / 提权审计日志 + +./.deepseek/ 项目级配置(可选,每个仓库)`; + export default async function InstallPage({ params }: { params: Promise<{ locale: string }> }) { const { locale } = await params; const isZh = locale === "zh"; + const copyLabel = isZh ? "复制" : "Copy"; + const copiedLabel = isZh ? "已复制 ✓" : "Copied ✓"; + return ( <> - {isZh ? ( - <> -
-
- -
Section 01 · 安装
+ {/* ① INSTALL */} +
+
+ +
{isZh ? "01 · 安装" : "01 · Install"}
+
+

+ {isZh ? ( + <>安装 Install + ) : ( + <>Install 安装 + )} +

+ +
+ + +
+ +

+ {isZh ? ( + <> + 编译并安装 deepseek~/.cargo/bin。 + 需要 Rust 1.88+——如未安装可访问{" "} + rustup.rs。 + 下方「其他安装方式」列出了不用 Rust 工具链、国内镜像、Homebrew、预编译二进制等替代选项。 + + ) : ( + <> + Compiles and installs deepseek to{" "} + ~/.cargo/bin. Requires Rust 1.88+ — install via{" "} + rustup.rs if you don't have it. + See Other ways to install below for + npm, Homebrew, prebuilt binaries, or mainland China mirrors. + + )} +

+
+ + {/* ② VERIFY */} +
+
+ +
{isZh ? "02 · 验证" : "02 · Verify"}
+
+ + + +

+ {isZh ? ( + <> + deepseek doctor 检查 API 密钥、网络、沙箱可用性、 + MCP 服务器,并将完整报告写入{" "} + ~/.deepseek/doctor.log。 + + ) : ( + <> + deepseek doctor checks your API key, network, + sandbox availability, and MCP servers. Full report is written to{" "} + ~/.deepseek/doctor.log. + + )} +

+
+ + {/* ③ FIRST RUN */} +
+
+ +
{isZh ? "03 · 首次运行" : "03 · First run"}
+
+ +
    +
  1. +
    + {isZh ? "① 获取 API 密钥" : "① Get an API key"}
    -

    - 安装 Install -

    -

    - 选择下方适合你平台的安装方式——首次加载时会自动检测。所有方式安装的都是同一个二进制文件: - 一个静态链接的 deepseek 可执行文件,交互使用时调用 TUI,同时暴露 - doctormcp、 - serveeval 等子命令。 +

    + {isZh ? ( + <> + 在{" "} + + platform.deepseek.com + {" "} + 注册并创建密钥,格式为 sk-...。 + + ) : ( + <> + Sign up at{" "} + + platform.deepseek.com + {" "} + and create a key (format: sk-...). + + )}

    -
+ - +
  • +
    + {isZh ? "② 设置密钥" : "② Set the key"} +
    +
    + +

    + {isZh ? "或保存到 ~/.deepseek/config.toml:" : "Or persist it to ~/.deepseek/config.toml:"} +

    + +
    +
  • - {/* 国内镜像安装 */} -
    -
    - -

    - 国内镜像安装 中国大陆专用 -

    +
  • +
    + {isZh ? "③ 在项目目录中运行" : "③ Run it in a project"} +
    + +

    + {isZh ? ( + <> + 默认 Plan 模式(只读调查)。按{" "} + Tab{" "} + 切换到 Agent 模式(执行工具,按需审批)。再按一次进入 YOLO 模式(自动批准)。 + + ) : ( + <> + Plan mode (read-only) is the default. Press{" "} + Tab{" "} + to switch to Agent mode (tool execution, per-action approval). Press again for + YOLO (auto-approve). + + )} +

    +
  • + +
    + + {/* ④ OTHER WAYS TO INSTALL */} +
    +
    +
    + +
    {isZh ? "04 · 其他安装方式" : "04 · Other ways to install"}
    +
    +

    + {isZh ? "其他安装方式" : "Other ways to install"} +

    +

    + {isZh + ? "如果上面的 Cargo 路径不适合你,从下面找到匹配你情况的一条。每条都安装同一个 deepseek 二进制。" + : "If the Cargo path above doesn't fit your setup, pick the row that matches your situation. Every path installs the same deepseek binary."} +

    + +
    + {/* No Rust toolchain */} +
    +
    + {isZh ? "没有 Rust 工具链" : "No Rust toolchain"} +
    + +

    + {isZh ? ( + <> + npm 包装器会从 GitHub Releases 下载对应平台的预编译二进制。需要 Node 18+。 + 安装后会同时提供 deepseek 和{" "} + deepseek-tui 两个命令。 + + ) : ( + <> + The npm wrapper downloads the prebuilt binary from GitHub Releases for your + platform. Requires Node 18+. Installs both deepseek{" "} + and deepseek-tui on PATH. + + )} +

    -
    - {/* npmmirror */} -
    -

    npmmirror 镜像

    -

    - 将 npm 注册表切换至国内镜像,然后全局安装: -

    -
    -{`npm config set registry https://registry.npmmirror.com
    -npm install -g deepseek-tui`}
    -                
    + {/* Mainland China network */} +
    +
    + {isZh ? "中国大陆网络" : "Mainland China network"} +
    +

    + {isZh ? ( + <> + Cargo 经清华 Tuna 镜像——添加到 ~/.cargo/config.toml: + + ) : ( + <> + Cargo via Tsinghua Tuna mirror — add to{" "} + ~/.cargo/config.toml: + + )} +

    + +
    +
    - {/* Tuna Cargo */} -
    -

    Tuna Cargo 镜像

    -

    - 在 ~/.cargo/config.toml 中添加以下配置,即可使用清华 Tuna 源: -

    -
    -{`[source.crates-io]
    -replace-with = "tuna"
    +              

    + {isZh ? "npm 经 npmmirror 镜像:" : "npm via npmmirror:"} +

    + -[source.tuna] -registry = "sparse+https://mirrors.tuna.tsinghua.edu.cn/crates.io-index/"`} -
    -

    - 配置完成后运行 cargo install deepseek-tui-cli --locked 即可(提供 deepseek 命令)。 -

    -
    - - {/* Gitee 二进制 */} - {GITEE_ENABLED &&
    -

    Gitee 预编译二进制

    -

    - 从 Gitee 发布页直接下载对应平台的预编译二进制文件,解压后即可使用: -

    - - gitee.com/Hmbown/deepseek-tui/releases → - -
    } - - {/* API 端点 */} -
    -

    国内 API 访问

    -

    - DeepSeek 服务器位于中国境内, - https://api.deepseek.com{" "} - 是 - 官方唯一域名, - 国内可直连——无需替代节点。设置 API key: -

    -
    -{`# 推荐:环境变量
    -export DEEPSEEK_API_KEY=sk-...
    -
    -# 或保存到配置文件
    -deepseek auth set --provider deepseek --api-key sk-...`}
    -                
    -

    - 如有自建反向代理或私有镜像,可通过{" "} - DEEPSEEK_BASE_URL 覆盖默认地址。 -

    -
    +

    + {isZh ? ( + <> + npm 包装器仍会从{" "} + github.com/Hmbown/deepseek-tui/releases{" "} + 下载二进制,国内可能较慢。Cargo + Tuna 完全绕开 GitHub。 + DeepSeek API(api.deepseek.com)在国内直连,无需代理。 + + ) : ( + <> + The npm wrapper still downloads the binary from{" "} + github.com/Hmbown/deepseek-tui/releases, which can + be slow over GFW. Cargo + Tuna routes around GitHub entirely. The DeepSeek API + at api.deepseek.com is reachable from mainland + China without a proxy. + + )} +

    - {GITEE_ENABLED &&
    - - Gitee 仓库镜像 → + {/* Homebrew */} +
    +
    + Homebrew{" "} + + · macOS / Linux + +
    + +
    + + {/* Prebuilt binary */} +
    +
    + {isZh ? "预编译二进制" : "Prebuilt binary"}{" "} + + {isZh ? "· 已自动检测" : "· auto-detected"} + +
    + +
    + + {/* Docker */} +
    +
    Docker
    + +

    + {isZh + ? "支持 multi-arch buildx。目前没有发布到镜像仓库,需要本地构建。" + : "Multi-arch buildx is supported. No image is published to a registry yet, so you build locally."} +

    +
    + + {/* From source */} +
    +
    + {isZh ? "从源码编译" : "From source"} +
    + +

    + {isZh + ? "适合本地修改 workspace 或贡献补丁。" + : "Useful for hacking on the workspace itself or contributing patches."} +

    +
    +
    +
    +
    + + {/* ⑤ WHERE CONFIG LIVES */} +
    +
    + +
    + {isZh ? "05 · 配置文件位置" : "05 · Where config lives"} +
    +
    +

    + {isZh ? "配置文件位置" : "Where config lives"} +

    + + + +

    + {isZh ? ( + <> + 所有用户配置存放在 ~/.deepseek/。仓库根目录下的{" "} + .deepseek/ 用于项目级覆盖。 + 完整字段参考{" "} + + {isZh ? "文档" : "the docs"} -

    } -
    - - {/* 安装后 */} -
    -
    - -

    - 安装之后 下一步 -

    -
    - -
      -
    1. -
      -
      获取密钥
      -

      在 platform.deepseek.com 注册

      -

      - 注册后会获得一个 sk-... 格式的 API 密钥。粘贴一次后, - deepseek auth 会将其存储在 - ~/.deepseek/config.toml。 -

      -
    2. -
    3. -
      -
      运行诊断
      -

      验证环境

      -

      - deepseek doctor 会检查密钥、网络连通性、沙箱可用性、 - MCP 服务器,并将报告写入 ~/.deepseek/doctor.log。 -

      -
    4. -
    5. -
      -
      试一试
      -

      第一个提示

      -

      - cd 到某个项目目录,运行 deepseek, - 然后提问:"这个代码库是做什么的?" Plan 模式默认只读——按 - Tab 切换到 Agent 模式。 -

      -
    6. -
    -
    - - {/* 配置 */} -
    -
    -
    -
    配置文件 · Config
    -

    文件存放位置

    -

    - 所有配置存放在 ~/.deepseek/ 目录下。项目级别的覆盖通过仓库根目录的 - .deepseek/ 等项目级配置实现。 -

    -
    - 完整配置参考 → -
    -
    -
    -
    -{`~/.deepseek/
    -├── config.toml          # API 密钥、模型、钩子、配置集
    -├── mcp.json             # MCP 服务器定义
    -├── skills/              # 用户技能(每个含 SKILL.md)
    -├── sessions/            # 检查点 + 离线队列
    -├── tasks/               # 后台任务存储
    -└── audit.log            # 凭证 / 审批 / 提权审计日志
    -
    -# 项目级别
    -./.deepseek/             # 项目级配置(可选)`}
    -                
    -
    -
    -
    - - ) : ( - <> -
    -
    - -
    Section 01 · 安装
    -
    -

    - Install 安装 -

    -

    - Pick your platform below — we auto-detect on first load. Every method gives you the same - binary: a single static deepseek executable that - dispatches to the TUI for interactive use and exposes subcommands like - doctor, mcp, - serve, eval. -

    -
    - - - - {/* AFTER INSTALL */} -
    -
    - -

    - After install 下一步 -

    -
    - -
      -
    1. -
      -
      Get a key
      -

      Sign up at platform.deepseek.com

      -

      - You'll get an sk-... API key. Paste it once and - deepseek auth will store it in - ~/.deepseek/config.toml. -

      -
    2. -
    3. -
      -
      Run doctor
      -

      Verify your setup

      -

      - deepseek doctor checks your key, network, - sandbox availability, MCP servers, and writes a report to{" "} - ~/.deepseek/doctor.log. -

      -
    4. -
    5. -
      -
      Try it out
      -

      First prompt

      -

      - cd into a project, run deepseek, - and ask: "What does this codebase do?" Plan mode is read-only by default — - press Tab to switch to Agent mode. -

      -
    6. -
    -
    - - {/* CONFIG */} -
    -
    -
    -
    Config files · 配置
    -

    Where things live

    -

    - All configuration goes under ~/.deepseek/. Per-project - overrides via project-scoped .deepseek/ config at the repo root. -

    -
    - Full configuration reference → -
    -
    -
    -
    -{`~/.deepseek/
    -├── config.toml          # api keys, model, hooks, profiles
    -├── mcp.json             # MCP server definitions
    -├── skills/              # user skills (each with SKILL.md)
    -├── sessions/            # checkpoints + offline queue
    -├── tasks/               # background task store
    -└── audit.log            # credential / approval / elevation audit trail
    -
    -# project-local
    -./.deepseek/             # project-scoped config (optional)`}
    -                
    -
    -
    -
    - - )} + 。 + + ) : ( + <> + All user-level configuration goes under ~/.deepseek/. + Per-project overrides live in .deepseek/ at the repo + root. Full field reference in{" "} + the docs. + + )} +

    + ); } diff --git a/web/app/[locale]/page.tsx b/web/app/[locale]/page.tsx index 0ab032ef..b1928828 100644 --- a/web/app/[locale]/page.tsx +++ b/web/app/[locale]/page.tsx @@ -17,7 +17,7 @@ const FALLBACK_STATS: RepoStats = { forks: 0, openIssues: 0, openPulls: 0, - contributors: 69, + contributors: 91, fetchedAt: new Date().toISOString(), }; diff --git a/web/components/footer.tsx b/web/components/footer.tsx index 858b6b13..42140185 100644 --- a/web/components/footer.tsx +++ b/web/components/footer.tsx @@ -98,6 +98,7 @@ export function Footer({ locale = "en" }: { locale?: Locale }) {
    镜像源 / Mirror
    {GITEE_ENABLED && Gitee 镜像} + CNB 镜像 npmmirror Tuna crates.io
    diff --git a/web/components/install-binary.tsx b/web/components/install-binary.tsx new file mode 100644 index 00000000..014965a8 --- /dev/null +++ b/web/components/install-binary.tsx @@ -0,0 +1,107 @@ +"use client"; + +import { useEffect, useState } from "react"; +import { InstallCodeBlock } from "./install-code-block"; + +type Arch = "macos-arm64" | "macos-x64" | "linux-x64" | "linux-arm64" | "windows-x64"; + +const SNIPPETS: Record = { + "macos-arm64": `curl -fsSL -o deepseek \\ + https://github.com/Hmbown/deepseek-tui/releases/latest/download/deepseek-macos-arm64 +chmod +x deepseek +xattr -d com.apple.quarantine deepseek 2>/dev/null || true +sudo mv deepseek /usr/local/bin/`, + "macos-x64": `curl -fsSL -o deepseek \\ + https://github.com/Hmbown/deepseek-tui/releases/latest/download/deepseek-macos-x64 +chmod +x deepseek +xattr -d com.apple.quarantine deepseek 2>/dev/null || true +sudo mv deepseek /usr/local/bin/`, + "linux-x64": `curl -fsSL -o deepseek \\ + https://github.com/Hmbown/deepseek-tui/releases/latest/download/deepseek-linux-x64 +chmod +x deepseek +sudo mv deepseek /usr/local/bin/`, + "linux-arm64": `curl -fsSL -o deepseek \\ + https://github.com/Hmbown/deepseek-tui/releases/latest/download/deepseek-linux-arm64 +chmod +x deepseek +sudo mv deepseek /usr/local/bin/`, + "windows-x64": `# PowerShell +$ErrorActionPreference = "Stop" +$dest = "$Env:USERPROFILE\\bin" +New-Item -ItemType Directory -Force $dest | Out-Null + +Invoke-WebRequest \` + -Uri https://github.com/Hmbown/deepseek-tui/releases/latest/download/deepseek-windows-x64.exe \` + -OutFile "$dest\\deepseek.exe" + +$Env:Path = "$dest;$Env:Path"`, +}; + +const VERIFY: Record = { + "macos-arm64": `curl -fsSL -O https://github.com/Hmbown/deepseek-tui/releases/latest/download/deepseek-artifacts-sha256.txt +shasum -a 256 -c deepseek-artifacts-sha256.txt --ignore-missing`, + "macos-x64": `curl -fsSL -O https://github.com/Hmbown/deepseek-tui/releases/latest/download/deepseek-artifacts-sha256.txt +shasum -a 256 -c deepseek-artifacts-sha256.txt --ignore-missing`, + "linux-x64": `curl -fsSL -O https://github.com/Hmbown/deepseek-tui/releases/latest/download/deepseek-artifacts-sha256.txt +sha256sum -c deepseek-artifacts-sha256.txt --ignore-missing`, + "linux-arm64": `curl -fsSL -O https://github.com/Hmbown/deepseek-tui/releases/latest/download/deepseek-artifacts-sha256.txt +sha256sum -c deepseek-artifacts-sha256.txt --ignore-missing`, + "windows-x64": `# PowerShell +Get-FileHash "$Env:USERPROFILE\\bin\\deepseek.exe" -Algorithm SHA256`, +}; + +const LABELS: Record = { + "macos-arm64": "macOS · Apple Silicon", + "macos-x64": "macOS · Intel", + "linux-x64": "Linux · x64", + "linux-arm64": "Linux · arm64", + "windows-x64": "Windows · x64", +}; + +function detect(): Arch { + if (typeof navigator === "undefined") return "macos-arm64"; + const ua = navigator.userAgent.toLowerCase(); + if (ua.includes("win")) return "windows-x64"; + if (ua.includes("linux")) { + if (ua.includes("aarch64") || ua.includes("arm64")) return "linux-arm64"; + return "linux-x64"; + } + // mac: most modern macs are arm64; Intel users can switch tab + return "macos-arm64"; +} + +interface Props { + copyLabel?: string; + copiedLabel?: string; + verifyHeading?: string; +} + +export function InstallBinary({ copyLabel, copiedLabel, verifyHeading = "Verify checksum" }: Props) { + const [arch, setArch] = useState("macos-arm64"); + + useEffect(() => { setArch(detect()); }, []); + + return ( +
    +
    + {(Object.keys(SNIPPETS) as Arch[]).map((a, i) => ( + + ))} +
    + + + +
    +
    {verifyHeading}
    + +
    +
    + ); +} diff --git a/web/components/install-code-block.tsx b/web/components/install-code-block.tsx new file mode 100644 index 00000000..5dfe2db8 --- /dev/null +++ b/web/components/install-code-block.tsx @@ -0,0 +1,34 @@ +"use client"; + +import { useState } from "react"; + +interface Props { + cmd: string; + copyLabel?: string; + copiedLabel?: string; +} + +export function InstallCodeBlock({ cmd, copyLabel = "Copy", copiedLabel = "Copied ✓" }: Props) { + const [copied, setCopied] = useState(false); + + const copy = () => { + if (typeof navigator !== "undefined" && navigator.clipboard) { + navigator.clipboard.writeText(cmd); + setCopied(true); + setTimeout(() => setCopied(false), 1400); + } + }; + + return ( +
    + +
    {cmd}
    +
    + ); +} diff --git a/web/components/install-tabs.tsx b/web/components/install-tabs.tsx deleted file mode 100644 index 399216c1..00000000 --- a/web/components/install-tabs.tsx +++ /dev/null @@ -1,331 +0,0 @@ -"use client"; - -import { useEffect, useState } from "react"; - -type OS = "macos" | "linux" | "windows" | "any"; - -interface Method { - id: string; - os: OS; - label: string; - cn: string; - recommended?: boolean; - comingSoon?: boolean; - prereq: string; - cmd: string; -} - -const METHODS: Method[] = [ - // ─── macOS ──────────────────────────────────────────────── - { - id: "cargo-mac", - os: "macos", - label: "Cargo (recommended)", - cn: "Cargo · 推荐", - recommended: true, - prereq: "Rust 1.88+ — install via rustup.rs if needed", - cmd: `# Install the dispatcher (provides \`deepseek\`) -cargo install deepseek-tui-cli --locked - -# Optional: also install the raw TUI binary (\`deepseek-tui\`) -cargo install deepseek-tui --locked - -# Set your API key (one-time) -export DEEPSEEK_API_KEY=sk-... -echo 'export DEEPSEEK_API_KEY=sk-...' >> ~/.zshrc - -# Run it -deepseek`, - }, - { - id: "npm-mac", - os: "macos", - label: "npm wrapper", - cn: "npm 包", - prereq: "Node.js 18+", - cmd: `npm install -g deepseek-tui - -# Provides both binaries on PATH: -deepseek # canonical dispatcher -deepseek-tui # raw TUI binary`, - }, - { - id: "binary-mac", - os: "macos", - label: "Pre-built binary", - cn: "二进制", - prereq: "Apple Silicon (arm64) or Intel (x64). Releases ship raw binaries — no archive to extract.", - cmd: `# Apple Silicon -curl -fsSL -o deepseek \\ - https://github.com/Hmbown/deepseek-tui/releases/latest/download/deepseek-macos-arm64 -chmod +x deepseek -xattr -d com.apple.quarantine deepseek 2>/dev/null || true -sudo mv deepseek /usr/local/bin/ - -# Intel -curl -fsSL -o deepseek \\ - https://github.com/Hmbown/deepseek-tui/releases/latest/download/deepseek-macos-x64 -chmod +x deepseek -xattr -d com.apple.quarantine deepseek 2>/dev/null || true -sudo mv deepseek /usr/local/bin/ - -# Verify checksum (optional but recommended) -curl -fsSL -O https://github.com/Hmbown/deepseek-tui/releases/latest/download/deepseek-artifacts-sha256.txt -shasum -a 256 -c deepseek-artifacts-sha256.txt --ignore-missing - -deepseek`, - }, - { - id: "brew", - os: "macos", - label: "Homebrew", - cn: "Homebrew", - prereq: "Homebrew on macOS or Linux; installs the dispatcher and companion TUI from the official Hmbown tap.", - cmd: `brew tap Hmbown/deepseek-tui -brew install deepseek-tui - -deepseek --version -deepseek`, - }, - - // ─── Linux ──────────────────────────────────────────────── - { - id: "cargo-linux", - os: "linux", - label: "Cargo (recommended)", - cn: "Cargo · 推荐", - recommended: true, - prereq: "Rust 1.88+; on Debian/Ubuntu: apt install build-essential pkg-config libssl-dev", - cmd: `cargo install deepseek-tui-cli --locked -export DEEPSEEK_API_KEY=sk-... -deepseek`, - }, - { - id: "npm-linux", - os: "linux", - label: "npm wrapper", - cn: "npm 包", - prereq: "Node.js 18+", - cmd: `npm install -g deepseek-tui -deepseek`, - }, - { - id: "binary-linux", - os: "linux", - label: "Pre-built binary", - cn: "二进制", - prereq: "x86_64 or aarch64 glibc. Releases ship raw binaries — no archive to extract.", - cmd: `# x86_64 -curl -fsSL -o deepseek \\ - https://github.com/Hmbown/deepseek-tui/releases/latest/download/deepseek-linux-x64 -chmod +x deepseek -sudo mv deepseek /usr/local/bin/ - -# arm64 -curl -fsSL -o deepseek \\ - https://github.com/Hmbown/deepseek-tui/releases/latest/download/deepseek-linux-arm64 -chmod +x deepseek -sudo mv deepseek /usr/local/bin/ - -# Verify checksum (optional but recommended) -curl -fsSL -O https://github.com/Hmbown/deepseek-tui/releases/latest/download/deepseek-artifacts-sha256.txt -sha256sum -c deepseek-artifacts-sha256.txt --ignore-missing - -deepseek`, - }, - - // ─── Windows ────────────────────────────────────────────── - { - id: "cargo-win", - os: "windows", - label: "Cargo (recommended)", - cn: "Cargo · 推荐", - recommended: true, - prereq: "Rust 1.88+ via rustup-init.exe", - cmd: `cargo install deepseek-tui-cli --locked -$env:DEEPSEEK_API_KEY = "sk-..." -deepseek`, - }, - { - id: "npm-win", - os: "windows", - label: "npm wrapper", - cn: "npm 包", - prereq: "Node.js 18+", - cmd: `npm install -g deepseek-tui -deepseek`, - }, - { - id: "binary-win", - os: "windows", - label: "Pre-built binary", - cn: "二进制", - prereq: "Windows 10+ x64. Releases ship a raw .exe — no archive to extract.", - cmd: `# PowerShell -$ErrorActionPreference = "Stop" -$dest = "$Env:USERPROFILE\\bin" -New-Item -ItemType Directory -Force $dest | Out-Null - -Invoke-WebRequest \` - -Uri https://github.com/Hmbown/deepseek-tui/releases/latest/download/deepseek-windows-x64.exe \` - -OutFile "$dest\\deepseek.exe" - -# Add to PATH for this session (persist via System Properties → Environment Variables) -$Env:Path = "$dest;$Env:Path" - -$Env:DEEPSEEK_API_KEY = "sk-..." -deepseek`, - }, - { - id: "scoop", - os: "windows", - label: "Scoop", - cn: "Scoop", - comingSoon: true, - prereq: "Scoop manifest not yet published — use Cargo or the pre-built .exe above.", - cmd: `# Coming soon — no Scoop manifest yet. -# Working alternatives on Windows: -# - Cargo (recommended above) -# - Pre-built deepseek-windows-x64.exe (above) -# -# Track progress: -# https://github.com/Hmbown/deepseek-tui/issues`, - }, - - // ─── Any (cross-platform) ──────────────────────────────── - { - id: "docker", - os: "any", - label: "Docker", - cn: "Docker", - prereq: "Dockerfile ships with the repo (multi-arch buildx). No prebuilt image is published to a registry yet.", - cmd: `git clone https://github.com/Hmbown/deepseek-tui -cd deepseek-tui - -# Build for your local arch -docker build -t deepseek-tui . - -# Or multi-arch via buildx -docker buildx build --platform linux/amd64,linux/arm64 -t deepseek-tui . - -# Run interactively, mounting your config + a project -docker run --rm -it \\ - -e DEEPSEEK_API_KEY=$DEEPSEEK_API_KEY \\ - -v ~/.deepseek:/home/deepseek/.deepseek \\ - -v "$PWD:/work" -w /work \\ - deepseek-tui`, - }, - { - id: "from-source", - os: "any", - label: "Build from source", - cn: "源码编译", - prereq: "Rust 1.88+ and a git checkout — useful for hacking on the workspace itself.", - cmd: `git clone https://github.com/Hmbown/deepseek-tui -cd deepseek-tui - -# Builds both \`deepseek\` and \`deepseek-tui\` into ./target/release/ -cargo build --release --locked - -# Run without installing -./target/release/deepseek - -# Or install both binaries from your local checkout -cargo install --path crates/cli --locked # provides \`deepseek\` -cargo install --path crates/tui --locked # provides \`deepseek-tui\``, - }, -]; - -const OS_LABEL: Record = { - macos: { en: "macOS", cn: "苹果" }, - linux: { en: "Linux", cn: "Linux" }, - windows: { en: "Windows", cn: "视窗" }, - any: { en: "Any platform", cn: "通用" }, -}; - -function detectOS(): OS { - if (typeof navigator === "undefined") return "macos"; - const ua = navigator.userAgent.toLowerCase(); - if (ua.includes("mac")) return "macos"; - if (ua.includes("win")) return "windows"; - if (ua.includes("linux")) return "linux"; - return "macos"; -} - -export function InstallTabs() { - const [os, setOS] = useState("macos"); - const [copied, setCopied] = useState(null); - - useEffect(() => { setOS(detectOS()); }, []); - - // Show OS-specific methods + universal ones (Docker status / source build). - // On the "Any" tab, only show universal ones. - const methods = METHODS.filter((m) => (os === "any" ? m.os === "any" : m.os === os || m.os === "any")); - - const copy = (id: string, text: string) => { - navigator.clipboard?.writeText(text); - setCopied(id); - setTimeout(() => setCopied(null), 1400); - }; - - return ( -
    - {/* OS selector */} -
    - {(["macos", "linux", "windows", "any"] as OS[]).map((o) => { - const active = os === o; - return ( - - ); - })} -
    - - {/* methods */} -
    - {methods.map((m, i) => ( -
    0 ? "hairline-t" : ""}> -
    -
    -
    - {m.recommended && Recommended} - {m.comingSoon && Coming soon} - Method 0{i + 1} -
    -

    {m.label}

    -
    {m.cn}
    -
    - Prereq: {m.prereq} -
    -
    -
    - {!m.comingSoon && ( - - )} -
    {m.cmd}
    -
    -
    -
    - ))} -
    -
    - ); -} diff --git a/web/lib/facts.generated.ts b/web/lib/facts.generated.ts index 7533be5f..2f0bd80e 100644 --- a/web/lib/facts.generated.ts +++ b/web/lib/facts.generated.ts @@ -18,8 +18,8 @@ export interface RepoFacts { } export const FACTS: RepoFacts = { - "generatedAt": "2026-05-13T06:15:45.167Z", - "version": "0.8.35", + "generatedAt": "2026-05-14T19:34:46.542Z", + "version": "0.8.37", "crates": [ "agent", "app-server", diff --git a/web/lib/github.ts b/web/lib/github.ts index 928b8a4c..82e8f507 100644 --- a/web/lib/github.ts +++ b/web/lib/github.ts @@ -2,7 +2,7 @@ import type { FeedItem, RepoStats } from "./types"; const REPO = process.env.GITHUB_REPO ?? "Hmbown/deepseek-tui"; const GH = "https://api.github.com"; -const MIN_KNOWN_CONTRIBUTORS = 69; +const MIN_KNOWN_CONTRIBUTORS = 91; function headers(token?: string): HeadersInit { const h: Record = {