diff --git a/CHANGELOG.md b/CHANGELOG.md index 8feb62a3..8ca961d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.4.5] - 2026-04-24 + +### Fixed +- Alternate-screen TUI sessions now capture mouse input by default so wheel scrolling moves the transcript instead of exposing terminal scrollback from before the TUI started. Use `--no-mouse-capture` or `tui.mouse_capture = false` when terminal-native drag selection is preferred. + ## [0.4.2] - 2026-04-24 ### Fixed diff --git a/Cargo.lock b/Cargo.lock index 17174d67..ef06610f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -806,7 +806,7 @@ dependencies = [ [[package]] name = "deepseek-agent" -version = "0.4.4" +version = "0.4.5" dependencies = [ "deepseek-config", "serde", @@ -814,7 +814,7 @@ dependencies = [ [[package]] name = "deepseek-app-server" -version = "0.4.4" +version = "0.4.5" dependencies = [ "anyhow", "axum", @@ -837,7 +837,7 @@ dependencies = [ [[package]] name = "deepseek-config" -version = "0.4.4" +version = "0.4.5" dependencies = [ "anyhow", "dirs", @@ -848,7 +848,7 @@ dependencies = [ [[package]] name = "deepseek-core" -version = "0.4.4" +version = "0.4.5" dependencies = [ "anyhow", "chrono", @@ -867,7 +867,7 @@ dependencies = [ [[package]] name = "deepseek-execpolicy" -version = "0.4.4" +version = "0.4.5" dependencies = [ "anyhow", "deepseek-protocol", @@ -876,7 +876,7 @@ dependencies = [ [[package]] name = "deepseek-hooks" -version = "0.4.4" +version = "0.4.5" dependencies = [ "anyhow", "async-trait", @@ -890,7 +890,7 @@ dependencies = [ [[package]] name = "deepseek-mcp" -version = "0.4.4" +version = "0.4.5" dependencies = [ "anyhow", "deepseek-protocol", @@ -900,7 +900,7 @@ dependencies = [ [[package]] name = "deepseek-protocol" -version = "0.4.4" +version = "0.4.5" dependencies = [ "serde", "serde_json", @@ -908,7 +908,7 @@ dependencies = [ [[package]] name = "deepseek-state" -version = "0.4.4" +version = "0.4.5" dependencies = [ "anyhow", "chrono", @@ -920,7 +920,7 @@ dependencies = [ [[package]] name = "deepseek-tools" -version = "0.4.4" +version = "0.4.5" dependencies = [ "anyhow", "async-trait", @@ -933,7 +933,7 @@ dependencies = [ [[package]] name = "deepseek-tui" -version = "0.4.4" +version = "0.4.5" dependencies = [ "anyhow", "arboard", @@ -987,7 +987,7 @@ dependencies = [ [[package]] name = "deepseek-tui-cli" -version = "0.4.4" +version = "0.4.5" dependencies = [ "anyhow", "chrono", @@ -1005,7 +1005,7 @@ dependencies = [ [[package]] name = "deepseek-tui-core" -version = "0.4.4" +version = "0.4.5" [[package]] name = "deranged" diff --git a/Cargo.toml b/Cargo.toml index 147c7c1f..5ad9a02c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ default-members = ["crates/cli", "crates/app-server", "crates/tui"] resolver = "2" [workspace.package] -version = "0.4.4" +version = "0.4.5" edition = "2024" license = "MIT" repository = "https://github.com/Hmbown/DeepSeek-TUI" diff --git a/config.example.toml b/config.example.toml index aac381e3..ea6bdda5 100644 --- a/config.example.toml +++ b/config.example.toml @@ -68,7 +68,7 @@ max_subagents = 5 # optional (1-20) # ───────────────────────────────────────────────────────────────────────────────── [tui] alternate_screen = "auto" # auto | always | never -mouse_capture = false # false keeps terminal-native drag selection/copy; true enables internal mouse scrolling/selection +mouse_capture = true # true keeps wheel scrolling inside the TUI; false allows terminal-native drag selection/copy # ───────────────────────────────────────────────────────────────────────────────── # Feature Flags diff --git a/crates/agent/Cargo.toml b/crates/agent/Cargo.toml index f031378a..d101732a 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.4.4" } +deepseek-config = { path = "../config", version = "0.4.5" } serde.workspace = true diff --git a/crates/app-server/Cargo.toml b/crates/app-server/Cargo.toml index 22ea742d..1b45a3cd 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.4.4" } -deepseek-config = { path = "../config", version = "0.4.4" } -deepseek-core = { path = "../core", version = "0.4.4" } -deepseek-execpolicy = { path = "../execpolicy", version = "0.4.4" } -deepseek-hooks = { path = "../hooks", version = "0.4.4" } -deepseek-mcp = { path = "../mcp", version = "0.4.4" } -deepseek-protocol = { path = "../protocol", version = "0.4.4" } -deepseek-state = { path = "../state", version = "0.4.4" } -deepseek-tools = { path = "../tools", version = "0.4.4" } +deepseek-agent = { path = "../agent", version = "0.4.5" } +deepseek-config = { path = "../config", version = "0.4.5" } +deepseek-core = { path = "../core", version = "0.4.5" } +deepseek-execpolicy = { path = "../execpolicy", version = "0.4.5" } +deepseek-hooks = { path = "../hooks", version = "0.4.5" } +deepseek-mcp = { path = "../mcp", version = "0.4.5" } +deepseek-protocol = { path = "../protocol", version = "0.4.5" } +deepseek-state = { path = "../state", version = "0.4.5" } +deepseek-tools = { path = "../tools", version = "0.4.5" } serde.workspace = true serde_json.workspace = true tokio.workspace = true diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 60952495..f0d79e33 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -14,12 +14,12 @@ path = "src/main.rs" anyhow.workspace = true clap.workspace = true clap_complete.workspace = true -deepseek-agent = { path = "../agent", version = "0.4.4" } -deepseek-app-server = { path = "../app-server", version = "0.4.4" } -deepseek-config = { path = "../config", version = "0.4.4" } -deepseek-execpolicy = { path = "../execpolicy", version = "0.4.4" } -deepseek-mcp = { path = "../mcp", version = "0.4.4" } -deepseek-state = { path = "../state", version = "0.4.4" } +deepseek-agent = { path = "../agent", version = "0.4.5" } +deepseek-app-server = { path = "../app-server", version = "0.4.5" } +deepseek-config = { path = "../config", version = "0.4.5" } +deepseek-execpolicy = { path = "../execpolicy", version = "0.4.5" } +deepseek-mcp = { path = "../mcp", version = "0.4.5" } +deepseek-state = { path = "../state", version = "0.4.5" } chrono.workspace = true serde_json.workspace = true tokio.workspace = true diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index 760d564b..8487fd5e 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -9,14 +9,14 @@ description = "Core runtime boundaries for DeepSeek workspace architecture" [dependencies] anyhow.workspace = true chrono.workspace = true -deepseek-agent = { path = "../agent", version = "0.4.4" } -deepseek-config = { path = "../config", version = "0.4.4" } -deepseek-execpolicy = { path = "../execpolicy", version = "0.4.4" } -deepseek-hooks = { path = "../hooks", version = "0.4.4" } -deepseek-mcp = { path = "../mcp", version = "0.4.4" } -deepseek-protocol = { path = "../protocol", version = "0.4.4" } -deepseek-state = { path = "../state", version = "0.4.4" } -deepseek-tools = { path = "../tools", version = "0.4.4" } +deepseek-agent = { path = "../agent", version = "0.4.5" } +deepseek-config = { path = "../config", version = "0.4.5" } +deepseek-execpolicy = { path = "../execpolicy", version = "0.4.5" } +deepseek-hooks = { path = "../hooks", version = "0.4.5" } +deepseek-mcp = { path = "../mcp", version = "0.4.5" } +deepseek-protocol = { path = "../protocol", version = "0.4.5" } +deepseek-state = { path = "../state", version = "0.4.5" } +deepseek-tools = { path = "../tools", version = "0.4.5" } serde_json.workspace = true tokio.workspace = true uuid.workspace = true diff --git a/crates/execpolicy/Cargo.toml b/crates/execpolicy/Cargo.toml index ef0b1360..e53032ed 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.4.4" } +deepseek-protocol = { path = "../protocol", version = "0.4.5" } serde.workspace = true diff --git a/crates/hooks/Cargo.toml b/crates/hooks/Cargo.toml index 5bb9bd42..b319d863 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.4.4" } +deepseek-protocol = { path = "../protocol", version = "0.4.5" } reqwest.workspace = true serde.workspace = true serde_json.workspace = true diff --git a/crates/mcp/Cargo.toml b/crates/mcp/Cargo.toml index cbb0ee27..1fff24b8 100644 --- a/crates/mcp/Cargo.toml +++ b/crates/mcp/Cargo.toml @@ -8,6 +8,6 @@ description = "MCP server lifecycle and tool proxy compatibility for DeepSeek wo [dependencies] anyhow.workspace = true -deepseek-protocol = { path = "../protocol", version = "0.4.4" } +deepseek-protocol = { path = "../protocol", version = "0.4.5" } serde.workspace = true serde_json.workspace = true diff --git a/crates/tools/Cargo.toml b/crates/tools/Cargo.toml index b0eae43b..8b2648bf 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.4.4" } +deepseek-protocol = { path = "../protocol", version = "0.4.5" } serde.workspace = true serde_json.workspace = true tokio.workspace = true diff --git a/crates/tui/src/main.rs b/crates/tui/src/main.rs index b8fc891b..0ab8542c 100644 --- a/crates/tui/src/main.rs +++ b/crates/tui/src/main.rs @@ -2130,7 +2130,7 @@ fn should_use_mouse_capture(cli: &Cli, config: &Config, use_alt_screen: bool) -> .tui .as_ref() .and_then(|tui| tui.mouse_capture) - .unwrap_or(false) + .unwrap_or(true) } fn is_zellij() -> bool { @@ -2479,6 +2479,54 @@ async fn run_exec_agent( Ok(()) } +#[cfg(test)] +mod terminal_mode_tests { + use super::*; + use clap::Parser; + + fn parse_cli(args: &[&str]) -> Cli { + Cli::try_parse_from(args).expect("CLI args should parse") + } + + #[test] + fn mouse_capture_defaults_on_when_alternate_screen_is_active() { + let cli = parse_cli(&["deepseek"]); + let config = Config::default(); + + assert!(should_use_mouse_capture(&cli, &config, true)); + } + + #[test] + fn no_mouse_capture_flag_disables_mouse_capture() { + let cli = parse_cli(&["deepseek", "--no-mouse-capture"]); + let config = Config::default(); + + assert!(!should_use_mouse_capture(&cli, &config, true)); + } + + #[test] + fn config_can_disable_default_mouse_capture() { + let cli = parse_cli(&["deepseek"]); + let config = Config { + tui: Some(crate::config::TuiConfig { + alternate_screen: None, + mouse_capture: Some(false), + }), + ..Config::default() + }; + + assert!(!should_use_mouse_capture(&cli, &config, true)); + } + + #[test] + fn mouse_capture_is_off_without_alternate_screen() { + let cli = parse_cli(&["deepseek", "--mouse-capture"]); + let config = Config::default(); + + assert!(!should_use_mouse_capture(&cli, &config, false)); + } +} + #[cfg(test)] mod doctor_mcp_tests { use super::*; diff --git a/docs/CONFIGURATION.md b/docs/CONFIGURATION.md index 42d0669b..1e0c7f95 100644 --- a/docs/CONFIGURATION.md +++ b/docs/CONFIGURATION.md @@ -163,7 +163,7 @@ If you are upgrading from older releases: - `[capacity].deepseek_v3_2_reasoner_prior` (float, default `4.1`) - `[capacity].fallback_default_prior` (float, default `3.8`) - `tui.alternate_screen` (string, optional): `auto`, `always`, or `never`. `auto` disables the alternate screen in Zellij; `--no-alt-screen` forces inline mode. Set `never` or run with `--no-alt-screen` when you want real terminal scrollback. -- `tui.mouse_capture` (bool, optional, default `false`): enable internal mouse scrolling/transcript selection. Leave this off for terminal-native drag selection and highlight-to-copy; `--mouse-capture` enables it for one run, and `--no-mouse-capture` forces it off. +- `tui.mouse_capture` (bool, optional, default `true` when the alternate screen is active): enable internal mouse scrolling/transcript selection. Set this to `false` or run with `--no-mouse-capture` for terminal-native drag selection and highlight-to-copy. - `hooks` (optional): lifecycle hooks configuration (see `config.example.toml`). - `features.*` (optional): feature flag overrides (see below). diff --git a/docs/MODES.md b/docs/MODES.md index 9bd51a65..c69433c5 100644 --- a/docs/MODES.md +++ b/docs/MODES.md @@ -79,8 +79,8 @@ Run `deepseek --help` for the canonical list. Common flags: - `-r, --resume `: resume a saved session - `-c, --continue`: resume the most recent session - `--max-subagents `: clamp to `1..=20` -- `--no-alt-screen`: run inline so native terminal scrollback works -- `--mouse-capture` / `--no-mouse-capture`: opt in or out of internal mouse scrolling/selection +- `--no-alt-screen`: run inline without the alternate screen buffer +- `--mouse-capture` / `--no-mouse-capture`: opt in or out of internal mouse scrolling/selection. Mouse capture is enabled by default when the alternate screen is active; use `--no-mouse-capture` when you need terminal-native drag selection. - `--profile `: select config profile - `--config `: config file path - `-v, --verbose`: verbose logging diff --git a/npm/deepseek-tui/package.json b/npm/deepseek-tui/package.json index 6cfafb72..aab7bf40 100644 --- a/npm/deepseek-tui/package.json +++ b/npm/deepseek-tui/package.json @@ -1,7 +1,7 @@ { "name": "deepseek-tui", - "version": "0.4.4", - "deepseekBinaryVersion": "0.4.4", + "version": "0.4.5", + "deepseekBinaryVersion": "0.4.5", "description": "Install and run deepseek and deepseek-tui binaries from GitHub release artifacts.", "author": "Hmbown", "license": "MIT",