diff --git a/CHANGELOG.md b/CHANGELOG.md index d607d621..40ee250c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,17 @@ 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). -## [Unreleased] +## [0.8.30] - 2026-05-11 + +A "tighten what we shipped" release. Bare single-letter keystrokes +(`g`, `G`, `[`, `]`, `?`, `l`, `v`) no longer get eaten as transcript- +nav shortcuts when the composer is empty — every one of them is now +freely usable as the first character of a message. The water-spout +animation in the footer is decoupled from `low_motion` so typewriter +mode no longer hides the wave, and the v0.3.5-era 🐳→🐋 cycling +indicator is back next to the effort chip after a long detour through +geometric dots. Plus a handful of provider, shell, and config fixes +that surfaced during v0.8.29 testing. ### Added @@ -27,14 +37,33 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `off` — hide the chip entirely. Set via `/config status_indicator ` or in - `settings.toml`. Regression-guarded by - `whale_indicator_idle_frame_is_first_whale_glyph`, - `whale_indicator_advances_through_frames_then_breaches`, - `dots_indicator_uses_geometric_frames`, - `off_indicator_returns_none_so_chip_is_hidden`, - `unknown_indicator_mode_defaults_to_whale`, - `header_renders_whale_chip_next_to_effort_label`, - `header_hides_whale_chip_when_status_indicator_off`. + `settings.toml`. + +### Changed + +- **Transcript-nav single-letter shortcuts now require `Alt`.** Before + v0.8.30, pressing a bare `g`, `G`, `[`, `]`, `?`, `l`, or `v` with an + empty composer hijacked the keystroke for transcript navigation — so + typing "good morning" produced "ood morning" with no warning, and the + v0.8.29 spot-fix at `c13ddb04d` (gg double-tap) only suppressed the + scroll, not the lost character. The bindings are now uniformly + `Alt+`, mirroring `Alt+R` (history search) and `Alt+V` (tool + details) which already followed this pattern: + + | Old (bare) | New (`Alt+…`) | What it does | + |---|---|---| + | `gg` (double-tap) | `Alt+G` | scroll transcript to top | + | `G` or `Shift+G` | `Alt+Shift+G` | scroll transcript to bottom | + | `[` | `Alt+[` | jump to previous tool output | + | `]` | `Alt+]` | jump to next tool output | + | `?` | `Alt+?` | open the searchable help overlay (F1 / `Ctrl+/` also bound) | + | `l` | `Alt+L` | open pager for last message | + | `v` / `V` | `Alt+V` | open tool-details pager | + + Plain letters are now always inserted into the composer as text. The + `App::transcript_pending_g` field from the v0.8.29 half-fix is removed; + the unified `alt_nav_modifiers` predicate replaces the per-key + `is_empty()` checks. ### Fixed @@ -46,12 +75,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 upstream cadence), and `fancy_animations` alone decides whether the water-spout strip renders. The wave itself is unchanged from prior releases (wall-clock-driven sine, same cadence as v0.8.29). - -- **`g` no longer hijacks the first character of a message** — pressing a - single `g` with an empty composer used to silently arm a vim-style - jump-to-top binding, eating the keystroke; a second `g` would then jump - the transcript. The handler now requires a true double-tap `gg` and - the pending flag resets on any other key, Enter, or Escape. - **Custom-base-URL providers preserve the user's model name** (#857 class). Only OpenRouter was previously whitelisted; Sglang, Novita, Fireworks, Vllm, Ollama, and NvidiaNim users hitting custom gateways diff --git a/Cargo.lock b/Cargo.lock index 5982a370..79f9859f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1160,7 +1160,7 @@ dependencies = [ [[package]] name = "deepseek-agent" -version = "0.8.29" +version = "0.8.30" dependencies = [ "deepseek-config", "serde", @@ -1168,7 +1168,7 @@ dependencies = [ [[package]] name = "deepseek-app-server" -version = "0.8.29" +version = "0.8.30" dependencies = [ "anyhow", "axum", @@ -1190,7 +1190,7 @@ dependencies = [ [[package]] name = "deepseek-config" -version = "0.8.29" +version = "0.8.30" dependencies = [ "anyhow", "deepseek-secrets", @@ -1202,7 +1202,7 @@ dependencies = [ [[package]] name = "deepseek-core" -version = "0.8.29" +version = "0.8.30" dependencies = [ "anyhow", "chrono", @@ -1220,7 +1220,7 @@ dependencies = [ [[package]] name = "deepseek-execpolicy" -version = "0.8.29" +version = "0.8.30" dependencies = [ "anyhow", "deepseek-protocol", @@ -1229,7 +1229,7 @@ dependencies = [ [[package]] name = "deepseek-hooks" -version = "0.8.29" +version = "0.8.30" dependencies = [ "anyhow", "async-trait", @@ -1243,7 +1243,7 @@ dependencies = [ [[package]] name = "deepseek-mcp" -version = "0.8.29" +version = "0.8.30" dependencies = [ "anyhow", "serde", @@ -1252,7 +1252,7 @@ dependencies = [ [[package]] name = "deepseek-protocol" -version = "0.8.29" +version = "0.8.30" dependencies = [ "serde", "serde_json", @@ -1260,7 +1260,7 @@ dependencies = [ [[package]] name = "deepseek-secrets" -version = "0.8.29" +version = "0.8.30" dependencies = [ "dirs", "keyring", @@ -1273,7 +1273,7 @@ dependencies = [ [[package]] name = "deepseek-state" -version = "0.8.29" +version = "0.8.30" dependencies = [ "anyhow", "chrono", @@ -1285,7 +1285,7 @@ dependencies = [ [[package]] name = "deepseek-tools" -version = "0.8.29" +version = "0.8.30" dependencies = [ "anyhow", "async-trait", @@ -1298,7 +1298,7 @@ dependencies = [ [[package]] name = "deepseek-tui" -version = "0.8.29" +version = "0.8.30" dependencies = [ "anyhow", "arboard", @@ -1361,7 +1361,7 @@ dependencies = [ [[package]] name = "deepseek-tui-cli" -version = "0.8.29" +version = "0.8.30" dependencies = [ "anyhow", "chrono", @@ -1386,7 +1386,7 @@ dependencies = [ [[package]] name = "deepseek-tui-core" -version = "0.8.29" +version = "0.8.30" [[package]] name = "deltae" diff --git a/Cargo.toml b/Cargo.toml index 30cb09ff..2d08c227 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.29" +version = "0.8.30" 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 ac70ae9c..3daa9fe8 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.29" } +deepseek-config = { path = "../config", version = "0.8.30" } serde.workspace = true diff --git a/crates/app-server/Cargo.toml b/crates/app-server/Cargo.toml index 1326488b..57a5ae61 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.29" } -deepseek-config = { path = "../config", version = "0.8.29" } -deepseek-core = { path = "../core", version = "0.8.29" } -deepseek-execpolicy = { path = "../execpolicy", version = "0.8.29" } -deepseek-hooks = { path = "../hooks", version = "0.8.29" } -deepseek-mcp = { path = "../mcp", version = "0.8.29" } -deepseek-protocol = { path = "../protocol", version = "0.8.29" } -deepseek-state = { path = "../state", version = "0.8.29" } -deepseek-tools = { path = "../tools", version = "0.8.29" } +deepseek-agent = { path = "../agent", version = "0.8.30" } +deepseek-config = { path = "../config", version = "0.8.30" } +deepseek-core = { path = "../core", version = "0.8.30" } +deepseek-execpolicy = { path = "../execpolicy", version = "0.8.30" } +deepseek-hooks = { path = "../hooks", version = "0.8.30" } +deepseek-mcp = { path = "../mcp", version = "0.8.30" } +deepseek-protocol = { path = "../protocol", version = "0.8.30" } +deepseek-state = { path = "../state", version = "0.8.30" } +deepseek-tools = { path = "../tools", version = "0.8.30" } serde.workspace = true serde_json.workspace = true tokio.workspace = true diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 80db62a2..d158a746 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.29" } -deepseek-app-server = { path = "../app-server", version = "0.8.29" } -deepseek-config = { path = "../config", version = "0.8.29" } -deepseek-execpolicy = { path = "../execpolicy", version = "0.8.29" } -deepseek-mcp = { path = "../mcp", version = "0.8.29" } -deepseek-secrets = { path = "../secrets", version = "0.8.29" } -deepseek-state = { path = "../state", version = "0.8.29" } +deepseek-agent = { path = "../agent", version = "0.8.30" } +deepseek-app-server = { path = "../app-server", version = "0.8.30" } +deepseek-config = { path = "../config", version = "0.8.30" } +deepseek-execpolicy = { path = "../execpolicy", version = "0.8.30" } +deepseek-mcp = { path = "../mcp", version = "0.8.30" } +deepseek-secrets = { path = "../secrets", version = "0.8.30" } +deepseek-state = { path = "../state", version = "0.8.30" } chrono.workspace = true dirs.workspace = true serde.workspace = true diff --git a/crates/config/Cargo.toml b/crates/config/Cargo.toml index d0c3d0a8..b21daca1 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.29" } +deepseek-secrets = { path = "../secrets", version = "0.8.30" } dirs.workspace = true serde.workspace = true toml.workspace = true diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index 24fe36b4..318bf944 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.29" } -deepseek-config = { path = "../config", version = "0.8.29" } -deepseek-execpolicy = { path = "../execpolicy", version = "0.8.29" } -deepseek-hooks = { path = "../hooks", version = "0.8.29" } -deepseek-mcp = { path = "../mcp", version = "0.8.29" } -deepseek-protocol = { path = "../protocol", version = "0.8.29" } -deepseek-state = { path = "../state", version = "0.8.29" } -deepseek-tools = { path = "../tools", version = "0.8.29" } +deepseek-agent = { path = "../agent", version = "0.8.30" } +deepseek-config = { path = "../config", version = "0.8.30" } +deepseek-execpolicy = { path = "../execpolicy", version = "0.8.30" } +deepseek-hooks = { path = "../hooks", version = "0.8.30" } +deepseek-mcp = { path = "../mcp", version = "0.8.30" } +deepseek-protocol = { path = "../protocol", version = "0.8.30" } +deepseek-state = { path = "../state", version = "0.8.30" } +deepseek-tools = { path = "../tools", version = "0.8.30" } serde_json.workspace = true uuid.workspace = true diff --git a/crates/execpolicy/Cargo.toml b/crates/execpolicy/Cargo.toml index 63f0c053..b9292dcf 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.29" } +deepseek-protocol = { path = "../protocol", version = "0.8.30" } serde.workspace = true diff --git a/crates/hooks/Cargo.toml b/crates/hooks/Cargo.toml index a428bdf3..48ad8a1a 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.29" } +deepseek-protocol = { path = "../protocol", version = "0.8.30" } reqwest.workspace = true serde.workspace = true serde_json.workspace = true diff --git a/crates/tools/Cargo.toml b/crates/tools/Cargo.toml index f2ef0c56..4e984339 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.29" } +deepseek-protocol = { path = "../protocol", version = "0.8.30" } serde.workspace = true serde_json.workspace = true tokio.workspace = true diff --git a/crates/tui/Cargo.toml b/crates/tui/Cargo.toml index 1ec7ef8e..a4bf08cd 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.29" } -deepseek-tools = { path = "../tools", version = "0.8.29" } +deepseek-secrets = { path = "../secrets", version = "0.8.30" } +deepseek-tools = { path = "../tools", version = "0.8.30" } 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 bf5a8b79..a915bc1c 100644 --- a/npm/deepseek-tui/package.json +++ b/npm/deepseek-tui/package.json @@ -1,7 +1,7 @@ { "name": "deepseek-tui", - "version": "0.8.29", - "deepseekBinaryVersion": "0.8.29", + "version": "0.8.30", + "deepseekBinaryVersion": "0.8.30", "description": "Install and run deepseek and deepseek-tui binaries from GitHub release artifacts.", "author": "Hmbown", "license": "MIT",