The user's ~/Library/Application Support/deepseek/settings.toml had
default_mode = "yolo", which caused test_mode_yolo_sets_all_flags,
test_trust_on_enables_flag, and
footer_status_line_spans_show_mode_and_model_idle_and_active to fail
because they implicitly depended on the host's global mode setting.
Pin each test to Agent mode explicitly so they pass regardless of the
developer's personal settings.
Add clearer prompts to bug reports and feature requests so users provide
reproduction details, impact, environment context, use cases, and supporting
materials up front.
`resolve_cli_auto_route` was hard-coding `reasoning_effort: None` when
`--model` is not `auto`, which silently dropped the value the user had
set in `~/.deepseek/config.toml` on every non-auto-route exec/one-shot
call.
For vllm + Qwen3 users with `reasoning_effort = "off"`, thinking was
therefore never disabled. The model emitted a long reasoning trace for
every prompt and SSE idle timeouts (`did not receive response headers
after 45s`) fired on any non-trivial prompt. After this fix, the same
prompts return in ~1.5s.
Route the configured value through `ReasoningEffort::from_setting`, the
same parser the TUI uses elsewhere for this field. Auto-route behaviour
(`--model auto`) is unchanged.
Verified by capturing the outgoing request body with `nc` before and
after; chat_template_kwargs.enable_thinking=false now appears in the
body on vllm exec runs.
Co-authored-by: hexin <he.xin@h3c.com>
Validate binary pandoc target formats before checking whether pandoc is
installed. This keeps invalid input errors stable on systems without pandoc
and fixes the CI test that expects missing output_path to be reported first.
- overwrite existing AGENTS.md on /init rather than blocking with an "already exists" message
- report "Updated" vs "Created" depending on prior file state
- replace noop test with one verifying stale content is regenerated
Show the current session's persisted metadata.title in the composer
border's top-right corner alongside the existing vim mode indicator.
- app.rs: add `session_title: Option<String>` field to App
- ui.rs: populate it from metadata.title in apply_loaded_session and
SessionUpdated handler; add derive_session_title() fallback helper
- widgets/mod.rs: render title (muted) + vim label in a single
right-aligned title_top span to avoid overlap
The version-consistency test `prompts::tests::changelog_entry_
exists_for_current_package_version` requires a `## [0.8.32]`
section once the workspace `Cargo.toml` has advanced to that
version — release hygiene from the v0.8.x sequence. Promote
the existing `[Unreleased]` content to `## [0.8.32] - 2026-05-12`
and leave a fresh empty `[Unreleased]` placeholder above it so
future post-tag commits have somewhere to land.
Also tighten the opening paragraph: the v0.8.31 throat-clear
("release in progress") becomes a release-shape summary that
calls out the five new tools, six PR harvests, and the snapshot
2 GB cap that closes the multi-hundred-GB-workspace "scroll
demon".
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Users reported a "scroll demon" — visible thrash where the
display would flicker / scroll / redraw spuriously while moving
the mouse. Root cause: the #376 native-selection escape hatch
watched every mouse event for `KeyModifiers::SHIFT`, and on each
transition (Shift pressed → released, or vice versa) it:
1. Toggled the alt-screen mouse-capture mode via crossterm
execute!(DisableMouseCapture / EnableMouseCapture).
2. Pushed a status toast ("Native selection — release Shift to
return" / "Mouse capture restored").
On terminals that report mouse-event modifier state aggressively
(notably the modern xterm-modifyOtherKeys / Kitty keyboard
protocol family the v0.8.32 Windows fix in PR #1483 just turned
on more broadly), the bypass would flip on stray Shift state
changes during ordinary scrolling — producing a tight cycle of
mouse-capture toggles and toast renders that the user perceived
as the display going haywire.
The feature was never load-bearing for native text selection on
modern terminals: macOS Terminal and iTerm honor Option-drag
(macOS convention), most Linux terminals honor Shift-drag at the
terminal layer regardless of what the TUI does with mouse
events, and Windows Terminal exposes its own copy mode. The
in-TUI bypass was a workaround for a narrower set of terminals
that bowed out of relevance once we got mouse capture cleaner
elsewhere.
Removed:
- `let mut shift_bypass_active = false;` state on `ui::run_app`
- The mouse-event Shift-modifier branch that flipped capture
modes and emitted toasts
- The 5-second redraw nudge that the toast cycle implied
Net delta: 23 lines deleted, 0 added. Mouse capture stays
on for the whole session (or off when `--no-mouse-capture` is
set at launch), and stray Shift events on mouse move are now
ordinary mouse events.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Workspace, all 9 path-pinned crate deps, and the npm wrapper's
package.json all advance from 0.8.31 → 0.8.32. `scripts/release/
check-versions.sh` passes (workspace ↔ npm ↔ Cargo.lock all in
sync).
Auto-tag only fires on push-to-main, so this bump on `work/v0.8.32`
doesn't accidentally cut a release; it just makes the
in-development binary identify itself correctly. When this branch
merges to main, the existing release pipeline takes over from
here.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Users reported running `deepseek-tui` inside project directories
with hundreds of GB of content — ML datasets, model weights
(`.safetensors`, `.gguf`, `.pt`, `.onnx`), Docker image dumps,
parquet / arrow caches, anything that falls outside the snapshot
built-in excludes. The pre/post-turn snapshot path called
`SnapshotRepo::open_or_init` which initialized the side git repo
and then ran `git add -A` — which walked the entire workspace
indexing every file. On a 100-300 GB directory this hung the TUI
for minutes-to-hours while git churned through the index.
The pre-existing v0.8.27 fixes (#1112: retention cap, mid-session
prune, expanded built-in excludes) addressed the orthogonal
"snapshots grow unbounded over many turns" angle but did nothing
to prevent the first snapshot from being impossible to take.
This change adds `estimate_workspace_size_bounded()` — a bounded
`ignore::WalkBuilder` walk that respects `.gitignore` and the
snapshot module's existing skip list (`node_modules/`, `target/`,
`.next/`, `.venv/`, `__pycache__/`, etc.). The walk early-exits
at either the byte cap or 200,000 file entries, returning `None`
to signal "too big to snapshot."
`SnapshotRepo::open_or_init_with_cap(workspace, cap_bytes)` calls
the estimator *before* the side `git init`, and returns
`Err(InvalidInput)` with a "workspace too large" reason — which
`turn::snapshot_with_label` already logs at WARN and continues
past, so a too-large workspace silently disables snapshots
without blocking any turn. The check is paid only on first init;
subsequent snapshots through the existing side repo skip it.
Plumbing:
- `SnapshotsConfig.max_workspace_gb` (default 2, `0` disables)
- `EngineConfig.snapshots_max_workspace_bytes` resolved at engine
construction from `config.snapshots_config().max_workspace_gb`
- `pre_turn_snapshot` / `post_turn_snapshot` / `pre_tool_snapshot`
take a `cap_bytes: u64` argument threaded from the engine
- `SnapshotRepo::open_or_init` retains its v0.8.31 signature as a
thin wrapper over `open_or_init_with_cap` using the default cap
- `config.example.toml` documents the new `max_workspace_gb` knob
with the "set to 0 to disable" escape hatch for users with
legitimate large monorepos
Six new tests pin both the estimator (under-cap returns Some,
over-cap returns None, builtin-excluded dirs skipped, cap=0
disables the bound) and the `open_or_init_with_cap` integration
(oversized workspace fails with the right error and references
the config knob; cap=0 succeeds even on oversized content).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Node's `os.platform()` returns `openharmony` on HarmonyPC and on
OpenHarmony's Linux ABI-compatible userspace. The npm wrapper's
platform-asset matrix only covered `linux` / `darwin` / `win32`,
so `npm i -g deepseek-tui` aborted on those hosts with
Unsupported platform: openharmony. Supported platforms: …
even though the existing Linux x64 / arm64 binaries run unchanged
on that environment (OpenHarmony is Linux-ABI-compatible at the
ELF level).
Added a `PLATFORM_ALIASES = { openharmony: "linux" }` indirection
that resolves the raw platform name through the alias map before
the `ASSET_MATRIX` lookup. Genuinely unsupported platforms still
report the raw `os.platform()` value in the error so OS-mismatch
bug reports stay diagnostic.
Four pure-JS regression tests pin the behaviour:
- openharmony x64 → linux x64 binaries
- openharmony arm64 → linux arm64 binaries
- known platforms unchanged by the alias map
- freebsd still reports `Unsupported platform: freebsd`
Harvested from PR #1499 by @CrepuscularIRIS
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The center of the startup welcome view used to repeat
information already shown in the header and footer
(active model and mode names). It now shows three pieces of
context that first-time users don't otherwise see at a glance:
- the build version (so users on stale installs notice it
before reaching `deepseek doctor`)
- the active model with a `/model` hint so the picker is
discoverable from the empty state
- the current working directory so users can confirm the
workspace deepseek-tui anchored at
The header and footer continue to show the running model and
mode for the active session; this change is only about the
center "empty transcript" panel that sits in the gap before the
first user message lands.
Harvested from PR #1444 by @reidliu41
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
A single 50-line `SKILL.md` encoding three V4-specific workflow
rules for multi-step thinking-mode tasks. Each rule maps to a
concrete observable failure class the maintainer or contributors
have hit when running V4-flash / V4-pro on long agent loops; the
text is opinionated but discovered through the existing skill
mechanism rather than baked into the always-on system prompt.
Follows the existing bundled-skill convention
(`crates/tui/assets/skills/skill-creator/`) so the discovery
walker picks it up alongside the workspace's own skills. Not
enabled by default — users see it in `/skills` and opt in
explicitly, keeping the always-on prompt-prefix footprint
unchanged for everyone who doesn't want the directive.
Single new file; zero Rust changes, zero new dependencies, zero
config schema changes. Fully reversible by deleting the directory.
Harvested from PR #1448 by @SamhandsomeLee
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`instructions = [...]` (the per-workspace config-driven block),
the user memory file (`/memory`), and the current session goal
(`/goal`) were being rendered at position 2.5 in the system
prompt — inside the static prefix layer that DeepSeek's KV
prefix cache hits.
Any edit to those files invalidated every cached byte from that
position onward. A `# foo` memory quick-add (or a `/goal` update)
on turn 5 meant the engine had to re-tokenize and re-charge the
full static suffix — skills block, context management, compact
template, environment, ~thousands of tokens — on turn 6.
Relocate the three blocks to position 6, immediately above the
previous-session handoff block, where the volatile-content
boundary already lives. The static prefix above the boundary
(mode, project context, env, skills, context management, compact
template) now stays cached across turns regardless of how often
the user edits their memory file or shifts session goals.
Resolved a 3-way merge against the v0.8.32 `translation_enabled`
addition (PR #1462). The new translation-output instruction stays
at position 2.3a (inside the static prefix layer) because it's a
per-session flag — `/translate` is a session toggle, not a
turn-by-turn knob, so the prompt-prefix bytes don't drift
mid-session.
Harvested from PR #1345 by @Duducoco
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>