From ee0ce460ee27fc29020b5ebd422129d3cc760bd0 Mon Sep 17 00:00:00 2001 From: Hunter Bown Date: Thu, 7 May 2026 12:52:53 -0500 Subject: [PATCH] chore(release): v0.8.17 A community-driven reliability release. Plan-mode safety, paste-Enter auto-submit, slash-menu skills coverage, the deepseek-cn endpoint preset, and a handful of platform / streaming / gateway-compat fixes, plus a small PTY-driven QA harness. See CHANGELOG.md for the full annotated change list with credits. Co-Authored-By: Claude Opus 4.7 (1M context) --- CHANGELOG.md | 100 ++++++++++++++++++++++++++++++++++ Cargo.lock | 28 +++++----- Cargo.toml | 2 +- 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/Cargo.toml | 4 +- npm/deepseek-tui/package.json | 4 +- 13 files changed, 148 insertions(+), 48 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c80ef8f..c62a1578 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,106 @@ 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.17] - 2026-05-07 + +A focused reliability release built almost entirely from community contributions. +Fixes Plan-mode safety, paste-Enter auto-submit, slash-menu skills coverage, the +`deepseek-cn` endpoint preset, and a handful of platform / streaming / +gateway-compatibility issues. Also lands a small PTY-driven QA harness so the +next round of TUI fixes can be verified against real terminal behaviour. + +### Added +- **`/theme` command** (#1057) — toggle between dark and light themes inline, + without round-tripping through `/config`. Thanks @MengZ-super. +- **PTY/frame-capture TUI QA harness** — new + `crates/tui/tests/support/qa_harness/` lets integration tests spawn + `deepseek-tui` in a real pseudo-terminal, send scripted keys / paste / + resize, and assert on the parsed terminal frame plus the workspace + filesystem. Initial scenarios cover boot smoke and the #1073 paste regression. + Adding-a-scenario walkthrough lives in `crates/tui/tests/support/qa_harness/README.md`. + +### Changed +- **`deepseek-cn` provider preset now defaults to the official + `https://api.deepseek.com` host** (#1079, #1084) — matches + [api-docs.deepseek.com](https://api-docs.deepseek.com/). The legacy typo + host `api.deepseeki.com` is still recognized in URL heuristics and chat-client + normalization so existing user configs keep working. Thanks @Jefsky. +- **Plan mode runs shell commands in a read-only sandbox** (#1077) — was + `WorkspaceWrite` with the workspace as a writable root, which let + `python -c "open('f','w').write('x')"` mutate files inside the workspace. + Now `SandboxPolicy::ReadOnly`: no writes anywhere on the filesystem, no + network. Read-only inspection commands (`ls`, `git log`, `grep`, + `cargo metadata`, …) keep working through the per-platform sandbox; for + anything that creates or modifies files, switch to Agent mode (`/agent`). + Thanks @DI-HUO-MING-YI. + +### Fixed +- **Pasting multi-line text with a trailing newline no longer auto-submits** + (#1073) — the composer's Enter handler now consults the paste-burst + suppression state and either appends `\n` to the in-flight burst buffer or + inserts it into the composer text directly, instead of falling through to + `submit_input()`. Reproduced from the original Windows / PowerShell + symptom; fix covers both the bracketed-paste and rapid-keystroke detection + paths. Thanks @bevis-wong for the precise reproducer. +- **Slash menu, `/skills`, and `/skill ` show project-local AND global + skills** (#1068, #1083) — switched the cache to `discover_in_workspace`, so + the UI surfaces stay in sync with the system-prompt skills block. Bonus + fix: `SKILL.md` frontmatter values are now stripped of surrounding YAML + quotes, so `name: "hud"` registers as `hud` and matches prefix lookup. + Thanks @AlphaGogoo / @Duducoco. +- **Windows shell output is decoded as UTF-8 even on non-UTF-8 system code + pages** (#982, #1018) — Windows shell commands are now wrapped with + `chcp 65001 >NUL & ` so subprocesses output UTF-8 instead of GBK / other + ANSI code pages. `display_command` strips the prefix so transcripts and + approval prompts stay clean. Thanks @chnjames. +- **Stale snapshot `tmp_pack_*` files are cleaned up on startup** (#975, + #1055) — interrupted side-repo git pack operations no longer leak orphaned + temp files; `prune_unreachable_objects` runs during the regular prune + cycle to drop loose objects from rolled-back snapshots. Closes the + ~30 GB+ disk-usage report. Thanks @axobase001. +- **Window-resize artifacts on macOS Terminal.app and Windows ConHost are + gone** (#993) — forces the resize-event size during the post-resize draw + so ratatui's internal `autoresize()` cannot shrink the viewport back to a + stale dimension and leave the newly-expanded area filled with stale + content. Same class as #582 for additional emulator families. Thanks + @ArronAI007. +- **Streaming thinking blocks finalize cleanly on stream errors and + restarts** (#861 partial, #1078) — the engine-error handler now drains + the in-flight thinking block into the transcript instead of leaving the + partial reasoning orphaned in `StreamingState`. Refactor extracts the + thinking lifecycle into named helpers (`start_streaming_thinking_block`, + `finalize_current_streaming_thinking`, `stash_reasoning_buffer_into_last_reasoning`). + Thanks @reidliu41. +- **OpenRouter and other custom-endpoint providers preserve explicit model + IDs** (#1066) — when a provider has an explicit model AND a custom + `base_url` (different from the provider default), the model name is no + longer rewritten by provider-specific normalization. Lets OpenAI-compatible + gateways accept bare IDs like `deepseek/deepseek-v4-pro`, + `accounts/fireworks/models/...`, or `glm-5`. Thanks @THINKER-ONLY. +- **Auto-generated `.deepseek/instructions.md` stabilizes the KV prefix + cache** (#1080) — replaces the per-turn filesystem-scan fallback in + `prompts.rs` with a real on-disk artifact when no context file exists, so + the system prompt's prefix stays byte-stable across turns and prefix-cache + hit-rate improves. The auto-generated file is plainly labelled and the + user can edit or delete it freely. Thanks @lloydzhou. +- **SSE responses behind compressing gateways decode correctly** (#1061) — + enables reqwest's `gzip` and `brotli` features so streams through proxies + that compress the response come through clean instead of as protocol + corruption. Quiets one of the failure modes behind some "stuck working" + reports. Thanks @MengZ-super. + +### Notes for contributors + +This release shifts the project's PR-handling philosophy: every contribution +has value somewhere; the maintainer's job is to find it, use it, and credit +the contributor — never to close a PR with nothing taken. If a PR is too +large or scope-mixed to merge whole, useful commits / files / ideas are +harvested directly rather than asking the contributor to split it. Trust +boundary on credentials, sandbox, providers, publishing, telemetry, +sponsorship, branding, and global prompts still requires explicit +maintainer sign-off, but the burden of getting there is on us. See +`AGENTS.md` for the full text. + ## [0.8.16] - 2026-05-07 A focused hotfix for v0.8.15 regressions in RLM, sub-agent visibility, and diff --git a/Cargo.lock b/Cargo.lock index b0917252..55c5866d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1152,7 +1152,7 @@ dependencies = [ [[package]] name = "deepseek-agent" -version = "0.8.16" +version = "0.8.17" dependencies = [ "deepseek-config", "serde", @@ -1160,7 +1160,7 @@ dependencies = [ [[package]] name = "deepseek-app-server" -version = "0.8.16" +version = "0.8.17" dependencies = [ "anyhow", "axum", @@ -1182,7 +1182,7 @@ dependencies = [ [[package]] name = "deepseek-config" -version = "0.8.16" +version = "0.8.17" dependencies = [ "anyhow", "deepseek-secrets", @@ -1194,7 +1194,7 @@ dependencies = [ [[package]] name = "deepseek-core" -version = "0.8.16" +version = "0.8.17" dependencies = [ "anyhow", "chrono", @@ -1212,7 +1212,7 @@ dependencies = [ [[package]] name = "deepseek-execpolicy" -version = "0.8.16" +version = "0.8.17" dependencies = [ "anyhow", "deepseek-protocol", @@ -1221,7 +1221,7 @@ dependencies = [ [[package]] name = "deepseek-hooks" -version = "0.8.16" +version = "0.8.17" dependencies = [ "anyhow", "async-trait", @@ -1235,7 +1235,7 @@ dependencies = [ [[package]] name = "deepseek-mcp" -version = "0.8.16" +version = "0.8.17" dependencies = [ "anyhow", "serde", @@ -1244,7 +1244,7 @@ dependencies = [ [[package]] name = "deepseek-protocol" -version = "0.8.16" +version = "0.8.17" dependencies = [ "serde", "serde_json", @@ -1252,7 +1252,7 @@ dependencies = [ [[package]] name = "deepseek-secrets" -version = "0.8.16" +version = "0.8.17" dependencies = [ "dirs", "keyring", @@ -1265,7 +1265,7 @@ dependencies = [ [[package]] name = "deepseek-state" -version = "0.8.16" +version = "0.8.17" dependencies = [ "anyhow", "chrono", @@ -1277,7 +1277,7 @@ dependencies = [ [[package]] name = "deepseek-tools" -version = "0.8.16" +version = "0.8.17" dependencies = [ "anyhow", "async-trait", @@ -1290,7 +1290,7 @@ dependencies = [ [[package]] name = "deepseek-tui" -version = "0.8.16" +version = "0.8.17" dependencies = [ "anyhow", "arboard", @@ -1351,7 +1351,7 @@ dependencies = [ [[package]] name = "deepseek-tui-cli" -version = "0.8.16" +version = "0.8.17" dependencies = [ "anyhow", "chrono", @@ -1375,7 +1375,7 @@ dependencies = [ [[package]] name = "deepseek-tui-core" -version = "0.8.16" +version = "0.8.17" [[package]] name = "deranged" diff --git a/Cargo.toml b/Cargo.toml index 8dd07166..2d602ddc 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.16" +version = "0.8.17" 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/crates/agent/Cargo.toml b/crates/agent/Cargo.toml index e66af62c..0197da8c 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.16" } +deepseek-config = { path = "../config", version = "0.8.17" } serde.workspace = true diff --git a/crates/app-server/Cargo.toml b/crates/app-server/Cargo.toml index 54b69329..5ef4752f 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.16" } -deepseek-config = { path = "../config", version = "0.8.16" } -deepseek-core = { path = "../core", version = "0.8.16" } -deepseek-execpolicy = { path = "../execpolicy", version = "0.8.16" } -deepseek-hooks = { path = "../hooks", version = "0.8.16" } -deepseek-mcp = { path = "../mcp", version = "0.8.16" } -deepseek-protocol = { path = "../protocol", version = "0.8.16" } -deepseek-state = { path = "../state", version = "0.8.16" } -deepseek-tools = { path = "../tools", version = "0.8.16" } +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" } serde.workspace = true serde_json.workspace = true tokio.workspace = true diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 1f049c0c..d9c1ff86 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.16" } -deepseek-app-server = { path = "../app-server", version = "0.8.16" } -deepseek-config = { path = "../config", version = "0.8.16" } -deepseek-execpolicy = { path = "../execpolicy", version = "0.8.16" } -deepseek-mcp = { path = "../mcp", version = "0.8.16" } -deepseek-secrets = { path = "../secrets", version = "0.8.16" } -deepseek-state = { path = "../state", version = "0.8.16" } +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" } chrono.workspace = true dirs.workspace = true serde.workspace = true diff --git a/crates/config/Cargo.toml b/crates/config/Cargo.toml index 8d59c75e..996cd183 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.16" } +deepseek-secrets = { path = "../secrets", version = "0.8.17" } dirs.workspace = true serde.workspace = true toml.workspace = true diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index 6f6c437d..e490e7b4 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.16" } -deepseek-config = { path = "../config", version = "0.8.16" } -deepseek-execpolicy = { path = "../execpolicy", version = "0.8.16" } -deepseek-hooks = { path = "../hooks", version = "0.8.16" } -deepseek-mcp = { path = "../mcp", version = "0.8.16" } -deepseek-protocol = { path = "../protocol", version = "0.8.16" } -deepseek-state = { path = "../state", version = "0.8.16" } -deepseek-tools = { path = "../tools", version = "0.8.16" } +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" } serde_json.workspace = true uuid.workspace = true diff --git a/crates/execpolicy/Cargo.toml b/crates/execpolicy/Cargo.toml index d7517dab..90c2fc90 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.16" } +deepseek-protocol = { path = "../protocol", version = "0.8.17" } serde.workspace = true diff --git a/crates/hooks/Cargo.toml b/crates/hooks/Cargo.toml index a59432cb..89a75432 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.16" } +deepseek-protocol = { path = "../protocol", version = "0.8.17" } reqwest.workspace = true serde.workspace = true serde_json.workspace = true diff --git a/crates/tools/Cargo.toml b/crates/tools/Cargo.toml index 347f8450..7c0c0690 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.16" } +deepseek-protocol = { path = "../protocol", version = "0.8.17" } serde.workspace = true serde_json.workspace = true tokio.workspace = true diff --git a/crates/tui/Cargo.toml b/crates/tui/Cargo.toml index f1127d29..48ef2a65 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.16" } -deepseek-tools = { path = "../tools", version = "0.8.16" } +deepseek-secrets = { path = "../secrets", version = "0.8.17" } +deepseek-tools = { path = "../tools", version = "0.8.17" } schemaui = { version = "0.12.0", default-features = false, optional = true } async-stream = "0.3.6" async-trait = "0.1" diff --git a/npm/deepseek-tui/package.json b/npm/deepseek-tui/package.json index 7539c178..5759a8f7 100644 --- a/npm/deepseek-tui/package.json +++ b/npm/deepseek-tui/package.json @@ -1,7 +1,7 @@ { "name": "deepseek-tui", - "version": "0.8.16", - "deepseekBinaryVersion": "0.8.16", + "version": "0.8.17", + "deepseekBinaryVersion": "0.8.17", "description": "Install and run deepseek and deepseek-tui binaries from GitHub release artifacts.", "author": "Hmbown", "license": "MIT",