Commit Graph

843 Commits

Author SHA1 Message Date
Zhuoran Deng 451d66ab0a docs(sandbox): define windows helper contract 2026-05-07 15:28:10 -05:00
Hunter Bown e814a203cb fix(secrets): fall back without native keyring 2026-05-07 15:27:14 -05:00
Hunter Bown 7cc8c53d79 fix(tui): soften long-session transcript palette 2026-05-07 15:22:02 -05:00
Hunter Bown b80d522f0e fix(tui): clear stale scrollbar drag state 2026-05-07 15:17:08 -05:00
Hunter Bown 245e409a20 fix(tui): reset terminal viewport before repaint 2026-05-07 15:17:03 -05:00
Hunter Bown 8f181c80f8 feat(release): publish supported Docker image 2026-05-07 15:16:23 -05:00
Hunter Bown 3f3395e00e fix(npm): make postinstall download failures recoverable 2026-05-07 15:16:17 -05:00
Hunter Bown 74b2f2f911 fix(session): start fresh on plain launch 2026-05-07 15:16:12 -05:00
Zhiping 9805c1b45e fix(tui): satisfy scrollbar drag clippy lint 2026-05-07 14:54:00 -05:00
Zhiping 0044361bc5 feat(tui): support transcript scrollbar dragging 2026-05-07 14:54:00 -05:00
Zhuoran Deng 96e58d23fd fix(i18n): localize approval dialog safety copy 2026-05-07 14:52:53 -05:00
Hunter Bown 200b4f4d15 docs(readme): refresh v0.8.17 highlights 2026-05-07 14:20:16 -05:00
Hunter Bown 5ce1314684 feat(runtime): bridge desktop approvals and skills 2026-05-07 13:53:01 -05:00
Hunter Bown 77e0810940 fix(npm): explain release mirror on download failures 2026-05-07 13:37:20 -05:00
Hunter Bown a0ef4017b4 fix(config): prefer provider API keys over root key 2026-05-07 13:34:38 -05:00
Hunter Bown 0f46acdd76 fix(release): close v0.8.17 gate gaps 2026-05-07 13:27:31 -05:00
Hunter Bown ee0ce460ee 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) <noreply@anthropic.com>
2026-05-07 12:52:53 -05:00
Hunter Bown 52d1959937 chore: rustfmt + rustdoc fixes after v0.8.17 sweep
Five rustdoc warnings (all pre-existing or surfaced by recent merges)
that the CI \`RUSTDOCFLAGS=-Dwarnings cargo doc\` gate would have
caught:

- \`backend.rs\`: intra-doc link to \`OpenSandboxBackend\` couldn't
  resolve without a use; qualify with the module path.
- \`markdown_render.rs\`: backtick-quote the literal \`[text](url)\`
  example so rustdoc doesn't try to follow it as an actual link.
- \`anchor.rs\`: rewrite the \`<text>\` / \`<n>\` placeholder syntax in
  doc comments so they aren't parsed as malformed HTML tags.
- \`config.rs\`: wrap the bare api-docs URL in \`<>\` so rustdoc treats
  it as a hyperlink instead of warning.

Plus rustfmt cleanup of two recently-merged files (\`commands/config.rs\`,
\`localization.rs\`) where the inserted lines weren't yet through
\`cargo fmt\`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 12:49:32 -05:00
THINKER_ONLY 4aee8a15c6 fix(config): preserve OpenRouter custom endpoint models
When OpenRouter is pointed at a custom base_url, keep explicit model values verbatim instead of remapping DeepSeek aliases to OpenRouter catalog IDs.

Add config coverage for both the dispatcher config crate and the TUI config loader, while preserving existing provider alias behavior such as NVIDIA NIM.

Closes #857
2026-05-07 12:45:37 -05:00
kurise 9d86ddb480 fix(tui): enable reqwest gzip/brotli decompression for SSE responses
DeepSeek API returns gzip/brotli compressed SSE responses. Without
auto-decompression enabled, reqwest's rustls backend passed compressed
bytes directly to UTF-8 parsing, causing garbled output () for Chinese
thinking content.

Add "gzip" and "brotli" features to reqwest to enable automatic content
encoding decompression (Accept-Encoding: gzip, br).

Fixes #954
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-07 12:45:03 -05:00
Reid 3433145487 fix(thinking): finalize streaming thinking block on stream errors and restarts (#1078)
Refactors the thinking-block lifecycle in `run_event_loop` into three named helpers — `start_streaming_thinking_block`, `finalize_current_streaming_thinking`, `stash_reasoning_buffer_into_last_reasoning` — and calls `finalize_current_streaming_thinking` from the engine-error handler so a thinking block that's still active when the stream errors gets drained into the transcript instead of being discarded.

This addresses one of the failure modes in #861 ("thinking collapse — thinking blocks freeze, truncate silently, or drop reasoning_content"): the case where a transient stream error mid-thinking left the partial reasoning orphaned in `StreamingState`.

Thanks to @reidliu41 — extracting the named helpers is the kind of refactor that pays off the next time we have to touch this lifecycle.
2026-05-07 12:44:39 -05:00
Lloyd Zhou 6d3e67e9ce fix(cache): auto-generate .deepseek/instructions.md to stabilize KV prefix cache (#1080)
When a workspace has no context file anywhere up the parent chain, `load_project_context_with_parents` now writes a short `.deepseek/instructions.md` (project tree + summary) on first launch. This replaces the previous per-turn filesystem-scan fallback in `prompts.rs`, whose output varied turn-to-turn and broke KV prefix-cache stability for the system prompt.

The auto-generated file is plainly labelled and the user can edit or delete it freely; it's only created when there is no existing context file to respect.

Thanks to @lloydzhou — making the cache surface stable through a real on-disk artifact is exactly the right move for prefix-cache hit rate.
2026-05-07 12:44:18 -05:00
Arron 81fe6de57a fix(ui): force resize-event size during post-resize draw (macOS Terminal.app, ConHost) (#993)
Some terminal emulators (macOS Terminal.app, Windows ConHost) briefly report stale dimensions via `crossterm::terminal::size()` after a resize. ratatui's `draw()` calls `autoresize()` internally, queries the backend, and shrinks the viewport back to the stale dimension — leaving the newly-expanded area filled with stale content from the previous frame (the duplicate-panel symptom users have reported).

The fix adds `force_size` / `clear_forced_size` to `ColorCompatBackend` and forces the resize-event size for the post-resize draw, then clears the forcing for subsequent frames. Same class of fix as #582 but covers an additional emulator family.

Thanks to @ArronAI007 for tracking down the autoresize→stale-size→short-buffer interaction.
2026-05-07 12:44:12 -05:00
吴梦知 379186d911 feat(tui): add /theme command to toggle dark/light theme (#1057)
Slash command toggles between the dark and light `UiTheme` presets without round-tripping through `/config`. Useful for quickly matching the editor or terminal theme.

Thanks to @MengZ-super — small, scoped, exactly the right surface for a quick toggle.
2026-05-07 12:43:56 -05:00
axobase001 34357560c8 fix(snapshot): clean stale git pack temps + prune unreachable objects (#1055)
Two snapshot-store improvements that together address #975 (≈30 GB+ disk consumed by stale snapshot temp files):

1. **Startup cleanup** of `tmp_pack_*` files left by interrupted git pack operations — a side-repo crash or sigkill mid-snapshot can leave hundreds of these orphaned in `.deepseek/snapshots/objects/pack/`.
2. **Prune unreachable objects** during the regular snapshot prune cycle so loose objects from rolled-back snapshots don't accumulate.

Closes #975. Thanks to @axobase001 — the 60-minute staleness threshold is the right balance between cleanup eagerness and not interfering with an actively-running git pack.
2026-05-07 12:43:53 -05:00
John Doe 493dc0d6e8 fix(shell): force UTF-8 output on Windows via chcp 65001 (#1018)
Prefixes Windows shell commands with `chcp 65001 >/dev/null & ` so subprocess output is UTF-8 instead of the system ANSI code page (e.g. GBK on Chinese-locale machines). The `display_command` helper strips the prefix so transcripts and approval prompts show the original command.

Closes #982. Thanks to @chnjames for the fix and the test update — the prefix-strip in `display_command` is exactly the right symmetric move.
2026-05-07 12:43:48 -05:00
Hunter Bown c64eef7939 fix(engine): Plan mode uses ReadOnly sandbox so shell can't mutate workspace (#1077)
Plan mode's tool context elevated the shell sandbox to `WorkspaceWrite`
with the workspace itself as a writable root. Reads were correct, but a
shell call like `python -c "open('foo','w').write('x')"` succeeded
because the sandbox literally permitted writes inside the workspace —
which is exactly what the user reported in #1077: "Plan mode … uses
shell to run python to change files."

Plan mode is investigation, not modification. Switch to
`SandboxPolicy::ReadOnly`: no writes anywhere on the filesystem, no
network. The model-facing tool surface still includes shell so
read-only commands (`ls`, `git log`, `grep`, `cat`, `cargo metadata`,
…) keep working; the per-platform sandbox (seatbelt on macOS, landlock
on Linux) blocks the rest.

Refactored the per-mode policy decision into
`tool_setup::sandbox_policy_for_mode(mode, workspace)` so it has one
unit-testable home. Updated the network-denied hint to surface the
actual contract ("read-only sandbox — no writes, no network") instead
of the previous wording that only mentioned network.

Tests:
- New `sandbox_policy_for_mode_returns_correct_policy_per_mode` asserts
  the helper returns `ReadOnly` / `WorkspaceWrite{network: true}` /
  `DangerFullAccess` for Plan / Agent / YOLO respectively.
- Existing `engine_elevates_sandbox_policy_for_mode` test extended to
  confirm Plan mode is `ReadOnly` (not just network-denied),
  `has_full_disk_write_access()` is false, and `get_writable_roots`
  enumerates zero entries.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 12:24:13 -05:00
Hunter Bown 4e285595b0 fix(tui): paste-Enter must not auto-submit (#1073) + PTY QA harness
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>
2026-05-07 12:23:57 -05:00
Hunter Bown 22442d58b1 docs(contrib): rewrite contributor philosophy — gumbo not steak
Replace the close-by-default admission rules with a find-value-first
posture. The new section in AGENTS.md says: every contribution has
value somewhere; harvest commits/files/ideas yourself rather than
asking contributors to split or resubmit; always credit; keep the
trust boundary on sandbox/providers/publishing/global-prompts but
own the work of getting there.

Bad-faith / prompt-injection contributions: close and block.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 12:01:16 -05:00
Jefsky Wong 5c112b40bf fix(config): default deepseek-cn to official api.deepseek.com (#1084)
Sets the `deepseek-cn` provider preset's default `base_url` to the official host (`https://api.deepseek.com`) per [api-docs.deepseek.com](https://api-docs.deepseek.com/). Keeps recognizing `api.deepseeki.com` in URL heuristics and chat-client normalization so existing configs continue to work, and updates the `doctor` strict-tool-mode endpoint hint, docs, and examples accordingly.

Closes #1079. Thanks to @Jefsky for the fix.
2026-05-07 12:01:07 -05:00
Duducoco 5d3a51e29e fix(skills): show all skills in slash menu (#1083)
Aligns the slash-menu cache with `discover_in_workspace`, so global `~/.deepseek/skills` and `~/.claude/skills` skills appear alongside project-local `.agents/skills` in the slash menu, `/skills` listing, and `/skill <name>` lookups. Also strips surrounding YAML quotes from `SKILL.md` frontmatter values, so a skill declared as `name: "hud"` registers as `hud` and matches prefix lookup.

Closes #1068. Thanks to @AlphaGogoo / @Duducoco for the fix and the test.
2026-05-07 12:00:55 -05:00
Hunter Bown 39b2d528cd feat(tools): retrieve spilled tool outputs (#1054) 2026-05-07 06:56:20 -05:00
axobase001 9fc0c416e4 fix(cache): clear history on model scope changes (#1052) 2026-05-07 06:51:13 -05:00
axobase001 4642ff9a6d fix(load): reset unpersisted session telemetry (#1049) 2026-05-07 06:49:29 -05:00
Hunter Bown 8c36c1c6be feat(subagents): fork parent context on demand (#1048) 2026-05-07 06:33:04 -05:00
axobase001 b476703a8d fix(npm): guard unsupported node during install (#1032) 2026-05-07 06:27:38 -05:00
axobase001 2644be9b52 fix(clear): reset session telemetry (#1047) 2026-05-07 06:26:43 -05:00
Hunter Bown 628fb3c4a8 feat(tui): support custom background color (#1034) 2026-05-07 06:15:58 -05:00
axobase001 dc3fef1346 fix(skills): follow symlinked skill directories (#1019) 2026-05-07 05:52:10 -05:00
axobase001 9327167e1d fix(engine): align stream idle timeout guard (#1012) 2026-05-07 05:42:24 -05:00
Hunter Bown f97604c3f0 fix(provider): enable OpenAI-compatible TUI runtime (#1017) 2026-05-07 05:32:15 -05:00
Hunter Bown f8d5fd84d7 ci: add nightly build artifacts (#1013) 2026-05-07 05:01:06 -05:00
Hunter Bown 3e2c832933 fix(api): narrow reasoning replay policy (#1009) 2026-05-07 04:45:55 -05:00
Hunter Bown 17a010aecc fix(doctor): explain strict tool mode endpoints (#1008) 2026-05-07 04:26:38 -05:00
Hunter Bown 323598e764 fix(api): harden strict tool schemas (#1005) 2026-05-07 04:12:22 -05:00
Hunter Bown c270ef81ef fix(tui): harden terminal resume and runtime context
Summary:
- Keep default auto alternate-screen mode inside the TUI so transcript scrolling stays app-owned unless users explicitly opt out.
- Queue terminal resume events when the engine channel is full, avoiding stranded paused terminal state after interactive tool cancellation or bursts.
- Scope crash-checkpoint recovery to the resolved launch workspace instead of the shell cwd.
- Add runtime deepseek_version to the prompt environment block so agents can distinguish installed runtime identity from a stale checkout.

Test plan:
- cargo test -p deepseek-tui --locked on a simulated merge with current main
- cargo fmt --all -- --check
- git diff --check
- Existing PR CI was green for lint, version drift, Linux/macOS/Windows tests, npm wrapper smoke, and GitGuardian.
2026-05-07 03:48:09 -05:00
Hunter Bown d2e9f58756 fix(config): persist cost currency from /config
Summary:
- Let /config cost_currency cny --save persist the setting.
- Show the live cost currency via /config cost_currency.
- Add cost currency to the interactive config document and apply path.
- Add regression tests for command persistence and config UI currency round-tripping.

Test plan:
- cargo test -p deepseek-tui config_command_cost_currency_save_persists_value --locked
- cargo test -p deepseek-tui build_document_reflects_cost_currency_from_settings --locked
- cargo test -p deepseek-tui session_only_apply_keeps_runtime_overrides_and_skips_reload --locked
- cargo fmt --all -- --check
- git diff --check

Supersedes #956. Fixes #932.
2026-05-07 03:46:02 -05:00
Hunter Bown 063d5d7d99 fix: prevent panic-prone edge cases
Summary:
- Use Reverse for job timestamp sorting to avoid negation overflow edge cases.
- Make secret redaction UTF-8 safe while preserving the previous short-secret threshold.
- Update remaining setup and doctor guidance to use the supported deepseek dispatcher name.

Test plan:
- cargo test -p deepseek-config list_values_redacts --locked
- cargo test -p deepseek-core --locked
- cargo test -p deepseek-tui doctor_endpoint_tests --locked
- cargo fmt --all -- --check
- git diff --check

Supersedes #957.
2026-05-07 03:37:50 -05:00
Hunter Bown 593ed2f900 fix(npm): preserve -v passthrough
Summary:
- Stop treating -v as an npm wrapper version fallback.
- Keep wrapper fallback for --version and -V.
- Add a Node regression test for wrapper version flag detection.

Test plan:
- npm test from npm/deepseek-tui
- git diff --check origin/main...HEAD

Supersedes #959.
2026-05-07 03:37:22 -05:00
Turisla dd822edcfc feat(tui): add jump-to-latest transcript button
Summary:
- Add a mouse-only jump-to-latest affordance when the transcript is scrolled away from the live tail.
- Hide the control at the tail or when mouse capture is disabled.
- Add tests for visibility and click behavior.

Maintainer verification on current origin/main:
- cargo test -p deepseek-tui jump_to_latest --locked
- cargo fmt --all -- --check
- git diff --check origin/main...HEAD

Closes #971
2026-05-07 03:23:53 -05:00