diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e78012a..59ea53f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,64 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.8.18] - 2026-05-07 + +This is the v0.8.17 follow-up release: a tighter TUI/runtime/install pass with +safer session startup semantics, Docker images promoted to a supported install +path, and several community PRs harvested into the release branch. VS Code and +Feishu/Lark/mobile companion work remain out of scope for this release. + +### Added +- **Prebuilt Docker images on GHCR** - release builds now publish + `ghcr.io/hmbown/deepseek-tui` with `latest`, semver, and `vX.Y.Z` tags, and + the GitHub release notes include a Docker install snippet. Docker publishing + is now a release gate rather than a best-effort check. +- **Draggable transcript scrollbar** (#1075, #1076) - when mouse capture is + enabled, drag the transcript scrollbar thumb to move through long sessions. + The implementation also clears stale drag state on resize and new left-clicks. + Thanks @Oliver-ZPLiu. +- **PTY regression for viewport drift** (#1085) - the QA harness now covers the + blank-top-rows failure after a failed/long turn so future layout changes catch + terminal viewport drift. + +### Changed +- **Plain `deepseek` starts a fresh session** - opening a second `deepseek` in + the same folder no longer silently attaches to the same in-flight checkpoint. + Crash/interrupted checkpoints are preserved as saved sessions and recovered + explicitly through `deepseek --continue`. +- **npm postinstall is recoverable for transient download failures** (#1059) - + install-time GitHub download/extract failures are non-blocking and documented, + while unsupported platforms, checksum mismatches, glibc preflight failures, + and runtime wrapper failures remain fatal. Thanks @Fire-dtx. +- **Docker Buildx cargo caches are platform-isolated and locked** - registry, + git, and target caches now use platform-specific cache IDs plus locked + sharing to avoid the `.cargo-ok File exists` unpack race in release checks. +- **Long-session palette is easier to read** (#1070, #936 partial) - default + body text is slightly softer, reasoning/thinking text uses a warmer accent, + and the light-theme adaptation keeps those contrasts coherent. Thanks + @bevis-wong and @oooyuy92 for the readability reports. +- **Install docs add a second rustup mirror fallback** (#1011) - `rsproxy.cn` + is documented as an alternate rustup mirror, and old Debian/Ubuntu Cargo + `edition2024` failures now point users to rustup stable. Thanks @wuwuzhijing. + +### Fixed +- **Chinese destructive approval dialogs keep explicit risk wording** (#1087, + #1091) - zh-Hans destructive approval copy now localizes the operation label, + title, prompt, and destructive-risk warning without changing English default + behavior. Thanks @qinxianyuzou and @axobase001. +- **Terminal viewport is reset before repaint** (#1085) - the TUI now clears + scroll margins/origin mode before key repaints after resume, resize, and turn + completion, preventing alt-screen content from drifting downward and leaving + blank rows at the top. +- **FreeBSD can compile the secrets crate** (#1089) - platforms without a native + `keyring` dependency now fail the OS-keyring probe cleanly and fall back to + the file-backed secret store instead of referencing a missing crate. Thanks + @avysk for the FreeBSD report. +- **Windows sandbox docs no longer overstate guarantees** (#1015, #1058) - the + docs and code comments now describe the future Windows helper as + process-tree containment only until filesystem, network, registry, or + AppContainer isolation is actually implemented. Thanks @axobase001. + ## [0.8.17] - 2026-05-07 A focused reliability release built almost entirely from community contributions. diff --git a/Cargo.lock b/Cargo.lock index 55c5866d..c6c615f5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1152,7 +1152,7 @@ dependencies = [ [[package]] name = "deepseek-agent" -version = "0.8.17" +version = "0.8.18" dependencies = [ "deepseek-config", "serde", @@ -1160,7 +1160,7 @@ dependencies = [ [[package]] name = "deepseek-app-server" -version = "0.8.17" +version = "0.8.18" dependencies = [ "anyhow", "axum", @@ -1182,7 +1182,7 @@ dependencies = [ [[package]] name = "deepseek-config" -version = "0.8.17" +version = "0.8.18" dependencies = [ "anyhow", "deepseek-secrets", @@ -1194,7 +1194,7 @@ dependencies = [ [[package]] name = "deepseek-core" -version = "0.8.17" +version = "0.8.18" dependencies = [ "anyhow", "chrono", @@ -1212,7 +1212,7 @@ dependencies = [ [[package]] name = "deepseek-execpolicy" -version = "0.8.17" +version = "0.8.18" dependencies = [ "anyhow", "deepseek-protocol", @@ -1221,7 +1221,7 @@ dependencies = [ [[package]] name = "deepseek-hooks" -version = "0.8.17" +version = "0.8.18" dependencies = [ "anyhow", "async-trait", @@ -1235,7 +1235,7 @@ dependencies = [ [[package]] name = "deepseek-mcp" -version = "0.8.17" +version = "0.8.18" dependencies = [ "anyhow", "serde", @@ -1244,7 +1244,7 @@ dependencies = [ [[package]] name = "deepseek-protocol" -version = "0.8.17" +version = "0.8.18" dependencies = [ "serde", "serde_json", @@ -1252,7 +1252,7 @@ dependencies = [ [[package]] name = "deepseek-secrets" -version = "0.8.17" +version = "0.8.18" dependencies = [ "dirs", "keyring", @@ -1265,7 +1265,7 @@ dependencies = [ [[package]] name = "deepseek-state" -version = "0.8.17" +version = "0.8.18" dependencies = [ "anyhow", "chrono", @@ -1277,7 +1277,7 @@ dependencies = [ [[package]] name = "deepseek-tools" -version = "0.8.17" +version = "0.8.18" dependencies = [ "anyhow", "async-trait", @@ -1290,7 +1290,7 @@ dependencies = [ [[package]] name = "deepseek-tui" -version = "0.8.17" +version = "0.8.18" dependencies = [ "anyhow", "arboard", @@ -1351,7 +1351,7 @@ dependencies = [ [[package]] name = "deepseek-tui-cli" -version = "0.8.17" +version = "0.8.18" dependencies = [ "anyhow", "chrono", @@ -1375,7 +1375,7 @@ dependencies = [ [[package]] name = "deepseek-tui-core" -version = "0.8.17" +version = "0.8.18" [[package]] name = "deranged" diff --git a/Cargo.toml b/Cargo.toml index 2d602ddc..17ffd3a6 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.17" +version = "0.8.18" 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 9201fb4c..0374e0bc 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,12 @@ brew install deepseek-tui # 4. Direct download — no package manager or toolchain. # https://github.com/Hmbown/DeepSeek-TUI/releases # Prebuilt for Linux x64/ARM64, macOS x64/ARM64, Windows x64. + +# 5. Docker — prebuilt release image. +docker run --rm -it \ + -e DEEPSEEK_API_KEY \ + -v "$PWD:/workspace" \ + ghcr.io/hmbown/deepseek-tui:latest ``` > In mainland China, speed up the npm path with @@ -219,31 +225,30 @@ deepseek --provider ollama --model deepseek-coder:1.3b --- -## What's New In v0.8.17 +## What's New In v0.8.18 -A focused reliability release built almost entirely from community contributions. +A focused follow-up release for TUI/runtime/install polish. [Full changelog](CHANGELOG.md). -- **Plan-mode sandbox is now read-only** — shell commands in Plan mode can no - longer write to the workspace, closing a safety gap where `python -c - "open('f','w')"` could mutate files during investigation. -- **Paste-Enter no longer auto-submits** — pasting multi-line text with a - trailing newline stays in the composer instead of firing immediately. -- **Slash menu covers all skills** — `/skills`, `/skill`, and the slash - autocomplete now show both project-local and global skills in sync with the - system-prompt block. -- **`deepseek-cn` preset uses the official host** — defaults to - `https://api.deepseek.com` while still recognising legacy configs with the - old typo host. -- **Streaming thinking blocks finalize cleanly** — stream errors and restarts - no longer leave partial reasoning orphaned in the transcript. -- **NVIDIA NIM provider prefers its own API key** — even when a legacy root - DeepSeek key is present, avoiding 401s. -- **Plus**: `/theme` command for dark/light toggle, Windows UTF-8 shell output, - ~30 GB snapshot-orphan cleanup, OpenRouter model-ID preservation, KV - prefix-cache stabilisation, SSE decompression behind compressing gateways, - npm mirror-escape-hatch guidance, and a PTY-driven TUI QA harness for - regression testing. +- **Plain `deepseek` starts fresh** - opening a second terminal in the same + folder now creates a new session instead of silently re-entering the same + interrupted checkpoint. Use `deepseek --continue` when you want recovery. +- **Docker is a supported install path** - release builds publish + `ghcr.io/hmbown/deepseek-tui` images with `latest`, semver, and `vX.Y.Z` + tags; Docker publishing is part of the release gate. +- **Chinese destructive approval dialogs are localized** - zh-Hans approval + copy keeps explicit destructive-risk wording while English defaults stay + unchanged. +- **Transcript scrollbar dragging** - with mouse capture enabled, drag the + transcript scrollbar thumb to move through long sessions. +- **Viewport drift fix** - terminal scroll margins and origin mode are reset + before key repaints, with a PTY regression for the blank-top-rows bug. +- **npm installs are more resilient** - transient release-download failures + are recoverable at postinstall time, while checksum, platform, glibc, and + runtime failures remain fatal. +- **Plus**: FreeBSD secrets-crate compile fallback, Docker Buildx cache-race + fix, softer long-session text colors, Windows sandbox guarantee cleanup, and + rustup mirror/install troubleshooting updates. --- diff --git a/README.zh-CN.md b/README.zh-CN.md index ed017510..57a22350 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -26,6 +26,12 @@ brew install deepseek-tui # 4. 直接下载 —— 无需任何工具链。 # https://github.com/Hmbown/DeepSeek-TUI/releases # 覆盖 Linux x64/ARM64、macOS x64/ARM64、Windows x64 + +# 5. Docker —— 预构建发布镜像。 +docker run --rm -it \ + -e DEEPSEEK_API_KEY \ + -v "$PWD:/workspace" \ + ghcr.io/hmbown/deepseek-tui:latest ``` > 中国大陆访问较慢时,npm 可加 `--registry=https://registry.npmmirror.com`, @@ -186,24 +192,23 @@ deepseek --provider ollama --model deepseek-coder:1.3b --- -## v0.8.17 新功能 +## v0.8.18 新功能 -几乎全部由社区贡献构成的可靠性版本。[完整更新日志](CHANGELOG.md)。 +面向 TUI、运行时和安装体验的跟进版本。[完整更新日志](CHANGELOG.md)。 -- **Plan 模式沙箱改为只读** —— Plan 模式下的 shell 命令不再能写入工作区, - 关闭了 `python -c "open('f','w')"` 可在探索阶段篡改文件的安全缺口。 -- **粘贴不再自动提交** —— 粘贴带末尾换行的多行文本会留在输入框,不再立即发送。 -- **斜杠菜单覆盖所有技能** —— `/skills`、`/skill` 和斜杠自动补全现在同时显示 - 项目本地和全局技能,与系统提示块保持同步。 -- **`deepseek-cn` 预设使用官方域名** —— 默认指向 `https://api.deepseek.com`, - 同时仍兼容旧配置中的拼写错误域名。 -- **流式思考块正确终结** —— 流错误和重启不再导致部分推理内容丢失在对话记录中。 -- **NVIDIA NIM provider 优先使用自己的 API key** —— 即使存在旧的根 DeepSeek - key,也能避免 401 错误。 -- **此外**:`/theme` 命令支持深色/浅色主题切换、Windows UTF-8 shell 输出、 - ~30 GB 快照孤儿文件清理、OpenRouter 模型 ID 保留、KV 前缀缓存稳定化、 - 压缩网关后的 SSE 解压、npm 镜像逃生路径指引,以及用于回归测试的 PTY - TUI QA 框架。 +- **直接运行 `deepseek` 会启动新会话** —— 同一目录开第二个终端时,不再静默进入 + 同一个中断检查点;需要恢复时请显式使用 `deepseek --continue`。 +- **Docker 成为受支持安装方式** —— 发布流程会推送 + `ghcr.io/hmbown/deepseek-tui`,包含 `latest`、语义版本和 `vX.Y.Z` 标签。 +- **中文危险审批弹窗本地化** —— zh-Hans 文案会明确保留破坏性风险提示, + 英文默认行为不变。 +- **对话滚动条支持拖拽** —— 开启鼠标捕获后,可直接拖拽 transcript 滚动条。 +- **修复终端视口漂移** —— 关键重绘前会重置滚动边界和 origin mode,并加入 PTY + 回归测试覆盖顶部空行问题。 +- **npm 安装更稳健** —— postinstall 阶段的临时下载失败可恢复;校验和、平台、 + glibc 和运行时错误仍然保持失败。 +- **此外**:FreeBSD secrets crate 编译回退、Docker Buildx cache 竞争修复、 + 长会话文本配色微调、Windows 沙箱保证说明收紧,以及 rustup 镜像安装排障更新。 --- diff --git a/crates/agent/Cargo.toml b/crates/agent/Cargo.toml index 0197da8c..af8b9a5b 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.17" } +deepseek-config = { path = "../config", version = "0.8.18" } serde.workspace = true diff --git a/crates/app-server/Cargo.toml b/crates/app-server/Cargo.toml index 5ef4752f..865204e3 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.17" } -deepseek-config = { path = "../config", version = "0.8.17" } -deepseek-core = { path = "../core", version = "0.8.17" } -deepseek-execpolicy = { path = "../execpolicy", version = "0.8.17" } -deepseek-hooks = { path = "../hooks", version = "0.8.17" } -deepseek-mcp = { path = "../mcp", version = "0.8.17" } -deepseek-protocol = { path = "../protocol", version = "0.8.17" } -deepseek-state = { path = "../state", version = "0.8.17" } -deepseek-tools = { path = "../tools", version = "0.8.17" } +deepseek-agent = { path = "../agent", version = "0.8.18" } +deepseek-config = { path = "../config", version = "0.8.18" } +deepseek-core = { path = "../core", version = "0.8.18" } +deepseek-execpolicy = { path = "../execpolicy", version = "0.8.18" } +deepseek-hooks = { path = "../hooks", version = "0.8.18" } +deepseek-mcp = { path = "../mcp", version = "0.8.18" } +deepseek-protocol = { path = "../protocol", version = "0.8.18" } +deepseek-state = { path = "../state", version = "0.8.18" } +deepseek-tools = { path = "../tools", version = "0.8.18" } serde.workspace = true serde_json.workspace = true tokio.workspace = true diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index d9c1ff86..2cc4a88b 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.17" } -deepseek-app-server = { path = "../app-server", version = "0.8.17" } -deepseek-config = { path = "../config", version = "0.8.17" } -deepseek-execpolicy = { path = "../execpolicy", version = "0.8.17" } -deepseek-mcp = { path = "../mcp", version = "0.8.17" } -deepseek-secrets = { path = "../secrets", version = "0.8.17" } -deepseek-state = { path = "../state", version = "0.8.17" } +deepseek-agent = { path = "../agent", version = "0.8.18" } +deepseek-app-server = { path = "../app-server", version = "0.8.18" } +deepseek-config = { path = "../config", version = "0.8.18" } +deepseek-execpolicy = { path = "../execpolicy", version = "0.8.18" } +deepseek-mcp = { path = "../mcp", version = "0.8.18" } +deepseek-secrets = { path = "../secrets", version = "0.8.18" } +deepseek-state = { path = "../state", version = "0.8.18" } chrono.workspace = true dirs.workspace = true serde.workspace = true diff --git a/crates/config/Cargo.toml b/crates/config/Cargo.toml index 996cd183..d72ff34e 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.17" } +deepseek-secrets = { path = "../secrets", version = "0.8.18" } dirs.workspace = true serde.workspace = true toml.workspace = true diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index e490e7b4..6c365c23 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.17" } -deepseek-config = { path = "../config", version = "0.8.17" } -deepseek-execpolicy = { path = "../execpolicy", version = "0.8.17" } -deepseek-hooks = { path = "../hooks", version = "0.8.17" } -deepseek-mcp = { path = "../mcp", version = "0.8.17" } -deepseek-protocol = { path = "../protocol", version = "0.8.17" } -deepseek-state = { path = "../state", version = "0.8.17" } -deepseek-tools = { path = "../tools", version = "0.8.17" } +deepseek-agent = { path = "../agent", version = "0.8.18" } +deepseek-config = { path = "../config", version = "0.8.18" } +deepseek-execpolicy = { path = "../execpolicy", version = "0.8.18" } +deepseek-hooks = { path = "../hooks", version = "0.8.18" } +deepseek-mcp = { path = "../mcp", version = "0.8.18" } +deepseek-protocol = { path = "../protocol", version = "0.8.18" } +deepseek-state = { path = "../state", version = "0.8.18" } +deepseek-tools = { path = "../tools", version = "0.8.18" } serde_json.workspace = true uuid.workspace = true diff --git a/crates/execpolicy/Cargo.toml b/crates/execpolicy/Cargo.toml index 90c2fc90..1e8846ce 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.17" } +deepseek-protocol = { path = "../protocol", version = "0.8.18" } serde.workspace = true diff --git a/crates/hooks/Cargo.toml b/crates/hooks/Cargo.toml index 89a75432..12a8d0c7 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.17" } +deepseek-protocol = { path = "../protocol", version = "0.8.18" } reqwest.workspace = true serde.workspace = true serde_json.workspace = true diff --git a/crates/tools/Cargo.toml b/crates/tools/Cargo.toml index 7c0c0690..eb8b7727 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.17" } +deepseek-protocol = { path = "../protocol", version = "0.8.18" } serde.workspace = true serde_json.workspace = true tokio.workspace = true diff --git a/crates/tui/Cargo.toml b/crates/tui/Cargo.toml index 48ef2a65..b123b09a 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.17" } -deepseek-tools = { path = "../tools", version = "0.8.17" } +deepseek-secrets = { path = "../secrets", version = "0.8.18" } +deepseek-tools = { path = "../tools", version = "0.8.18" } 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/prompts.rs b/crates/tui/src/prompts.rs index bb67c35c..cbffb765 100644 --- a/crates/tui/src/prompts.rs +++ b/crates/tui/src/prompts.rs @@ -618,8 +618,8 @@ mod tests { fn package_version_is_current_hotfix_release() { assert_eq!( env!("CARGO_PKG_VERSION"), - "0.8.17", - "0.8.17 hotfix branch must report the release version before publishing" + "0.8.18", + "0.8.18 release branch must report the release version before publishing" ); } diff --git a/npm/deepseek-tui/package.json b/npm/deepseek-tui/package.json index c2891002..843abd19 100644 --- a/npm/deepseek-tui/package.json +++ b/npm/deepseek-tui/package.json @@ -1,7 +1,7 @@ { "name": "deepseek-tui", - "version": "0.8.17", - "deepseekBinaryVersion": "0.8.17", + "version": "0.8.18", + "deepseekBinaryVersion": "0.8.18", "description": "Install and run deepseek and deepseek-tui binaries from GitHub release artifacts.", "author": "Hmbown", "license": "MIT", diff --git a/npm/deepseek-tui/test/install.test.js b/npm/deepseek-tui/test/install.test.js index fb340f0d..4cc87d36 100644 --- a/npm/deepseek-tui/test/install.test.js +++ b/npm/deepseek-tui/test/install.test.js @@ -29,7 +29,7 @@ test("install failure hint explains release base override for blocked GitHub dow try { const error = Object.assign( new Error( - "fetch https://github.com/Hmbown/DeepSeek-TUI/releases/download/v0.8.17/deepseek-artifacts-sha256.txt failed after 5 attempts:\ngetaddrinfo ENOTFOUND github.com", + "fetch https://github.com/Hmbown/DeepSeek-TUI/releases/download/v0.8.18/deepseek-artifacts-sha256.txt failed after 5 attempts:\ngetaddrinfo ENOTFOUND github.com", ), { code: "ENOTFOUND" }, );