4e285595b0
Two pieces: **#1073 fix.** When a paste burst is currently being assembled, or when the burst's Enter-suppression window is still open after a flush, the trailing newline of the paste was firing `submit_input()` and the in-flight burst buffer was getting destroyed by `clear_after_explicit_paste()`. The PasteBurst module already exposed `newline_should_insert_instead_of_submit` and `append_newline_if_active` for exactly this case, but no caller had been wired up. Added `App::handle_composer_enter`, which checks the suppression state and either appends `\n` to the burst buffer or inserts it directly into the composer text — no submit. The `KeyCode::Enter` arm in the composer event loop now dispatches through that helper. Reproduces the Windows/PowerShell symptom from the report: multi-line paste ending with `\n` no longer auto-submits AND the text no longer leaks into the now-empty composer. Four unit tests cover: active-burst Enter, post-flush window Enter, normal Enter outside the window, and Enter with paste-burst detection disabled (suppression must be off). **PTY QA harness.** New `crates/tui/tests/support/qa_harness/` wraps `portable-pty` (already a runtime dep) and `vt100` (new dev-dep) into a small surface for scenarios that need a real PTY: spawn a binary, send keys/paste/resize, parse the ANSI stream into a frame, assert on visible text + filesystem state. The harness seals `$HOME` so scenarios cannot read the developer's real `~/.deepseek/` and points the base URL at 127.0.0.1:1 so no live request escapes. README under `support/qa_harness/README.md` documents how to add a scenario. Initial scenarios in `crates/tui/tests/qa_pty.rs`: smoke boot, keystroke round-trip, and bracketed/unbracketed paste-with-trailing- newline regression guards for #1073. The unbracketed scenario does not deterministically reproduce the bug on macOS (single-syscall PTY writes keep the burst continuously active), but the unit tests above cover the path conclusively; the PTY test stands as a regression guard for the visible-text invariant. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
86 lines
2.4 KiB
TOML
86 lines
2.4 KiB
TOML
[package]
|
|
name = "deepseek-tui"
|
|
version.workspace = true
|
|
edition.workspace = true
|
|
license.workspace = true
|
|
repository.workspace = true
|
|
description = "Terminal UI for DeepSeek"
|
|
default-run = "deepseek-tui"
|
|
|
|
[features]
|
|
default = ["tui", "json", "toml"]
|
|
tui = ["dep:schemaui", "schemaui/tui", "json", "toml"]
|
|
web = ["dep:schemaui", "schemaui/web", "json", "toml"]
|
|
json = ["schemaui/json"]
|
|
toml = ["schemaui/toml"]
|
|
|
|
[[bin]]
|
|
name = "deepseek-tui"
|
|
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" }
|
|
schemaui = { version = "0.12.0", default-features = false, optional = true }
|
|
async-stream = "0.3.6"
|
|
async-trait = "0.1"
|
|
base64 = "0.22.1"
|
|
axum = { version = "0.8.4", features = ["json"] }
|
|
clap = { version = "4.5.54", features = ["derive"] }
|
|
clap_complete = "4.5"
|
|
colored = "3.0.0"
|
|
crossterm = "0.28"
|
|
dotenvy = "0.15.7"
|
|
dirs = "6.0.0"
|
|
fd-lock = "4.0.4"
|
|
futures-util = "0.3.31"
|
|
ratatui = "0.29"
|
|
regex = "1.11"
|
|
reqwest = { version = "0.13.1", default-features = false, features = ["blocking", "json", "stream", "multipart", "rustls", "http2"] }
|
|
similar = "2"
|
|
rustyline = "15.0.0"
|
|
serde = { version = "1.0.228", features = ["derive"] }
|
|
serde_json = { version = "1.0.149", features = ["preserve_order"] }
|
|
schemars = { version = "1.2.1", features = ["derive", "preserve_order"] }
|
|
shellexpand = "3"
|
|
toml = "0.9.7"
|
|
tokio = { version = "1.49.0", features = ["full"] }
|
|
tokio-util = { version = "0.7.16", features = ["io"] }
|
|
unicode-width = "0.2"
|
|
unicode-segmentation = "1.12"
|
|
uuid = { version = "1.11", features = ["v4"] }
|
|
chrono = { version = "0.4", features = ["serde"] }
|
|
tempfile = "3.16"
|
|
thiserror = "2.0"
|
|
tracing = "0.1"
|
|
tower-http = { version = "0.6", features = ["cors"] }
|
|
wait-timeout = "0.2"
|
|
multimap = "0.10.0"
|
|
shlex = "1.3.0"
|
|
starlark = "0.13.0"
|
|
tiny_http = "0.12"
|
|
portable-pty = "0.8"
|
|
zeroize = "1.8.2"
|
|
ignore = "0.4"
|
|
image = { version = "0.25", default-features = false, features = ["png"] }
|
|
pdf-extract = "0.7"
|
|
tar = "0.4"
|
|
flate2 = "1.1"
|
|
sha2 = "0.10"
|
|
|
|
[dev-dependencies]
|
|
wiremock = "0.6"
|
|
pretty_assertions = "1.4"
|
|
vt100 = "0.15"
|
|
|
|
[target.'cfg(target_os = "macos")'.dependencies]
|
|
libc = "0.2"
|
|
|
|
[target.'cfg(target_os = "linux")'.dependencies]
|
|
libc = "0.2"
|
|
|
|
[target.'cfg(target_os = "windows")'.dependencies]
|
|
windows = { version = "0.60", features = ["Win32_Foundation", "Win32_System_Console", "Win32_UI_WindowsAndMessaging", "Win32_System_Diagnostics_Debug"] }
|