Commit Graph

864 Commits

Author SHA1 Message Date
Aqil Aziz de4ecee41c docs: fix memory skill link (#1096) 2026-05-08 02:21:11 -05:00
Friende 8f39aadf0b docs: fix help keybinding reference (#1095) 2026-05-08 02:20:40 -05:00
jiaren wang 0d7cbe37a8 fix(undo): sync session context after snapshot restore (#1139) (#1150) 2026-05-08 02:14:04 -05:00
Friende f969de91aa fix(memory): report omitted bytes in truncation marker 2026-05-08 01:55:30 -05:00
Reid 71c5dfbfc6 fix(tui): make composer arrows navigate input history (#1117)
Make plain Up/Down navigate composer input history instead of scrolling
  the transcript from an empty composer.

  Keep menu overlays in control of arrow keys, preserve existing transcript
  scroll shortcuts, and support word-wise cursor movement with Ctrl or
  Alt/Option Left/Right.
2026-05-08 01:52:00 -05:00
Sun 2904d817fa fix(rlm): preserve prompt cache usage (#1127)
* fix(rlm): preserve prompt cache usage

* refactor(rlm): share prompt cache usage helper
2026-05-08 01:51:24 -05:00
jiaren wang fa32e7ac53 fix(plan): enforce read-only tool boundaries in Plan mode (#1114) 2026-05-08 01:49:31 -05:00
Hunter Bown f283e56bd1 fix(prompts): prioritize user language for reasoning (#1137) 2026-05-07 23:53:15 -05:00
Hunter Bown b31b93aaae v0.8.19: endpoint, release workflow, IME + viewport fixes (#1128)
* fix(config): keep DeepSeek beta endpoint for legacy cn alias

* fix(ci): filter download-artifact to deepseek* pattern

Prevents the release aggregation job from picking up non-binary
artifacts (e.g. Docker .dockerbuild cache layers) that cause the
checksum manifest to include spurious entries and the Release to
carry files it shouldn't.

* fix(tui): enable focus events to restore IME after app-switch

On macOS, switching away (Cmd+Tab) and back suspends the IME compositor.
Without focus-event handling, the TUI never signals readiness to the
terminal, so CJK input methods (Pinyin, Zhuyin, etc.) stop working.

- EnableFocusChange on startup so the terminal reports FocusGained/FocusLost
- Re-push KeyboardEnhancementFlags on FocusGained (some terminals reset
  the enhanced keyboard mode on focus-loss)
- DisableFocusChange on shutdown for clean terminal handoff

* chore: cargo fmt

* docs: add DataWhale and DeepSeek to acknowledgments

* docs: fix DeepSeek name etymology in acknowledgments

* fix(tui): recapture viewport on focus restore

* docs: thank DeepSeek and DataWhale bilingually
2026-05-07 23:05:39 -05:00
Hunter Bown 3521f1af91 fix(web): drop deepseek-cn from facts-drift cron labelMap (#1125)
Sister fix to #1108 / #1121. The 6-hour facts-drift cron has its own
provider labelMap (lib/facts-drift.ts) that re-derives ApiProvider
from the live source on GitHub and writes to CURATED_KV under
"facts:current". Without this fix, every cron tick repopulates the
KV cache with deepseek-cn even though the published binary's
ProviderArg rejects it — undoing the static facts.generated.ts fix.

Mirror the labelMap that derive-facts.mjs uses (no DeepseekCN entry).

Stale "facts:current" KV entry was deleted manually so this takes
effect immediately rather than after the next 6h cron tick.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 22:04:18 -05:00
Hunter Bown 4eccb1b5cd fix(web): correct China-network install snippet (#1104 follow-up) (#1121)
DeepSeek's official API has a single endpoint, https://api.deepseek.com,
with servers physically in China. There is no separate mainland endpoint,
and api.deepseeki.com is a typo grandfathered into the source.

The /zh/install "国内 API 访问" panel previously suggested users set a
custom base_url to a China endpoint, which doesn't exist. Replace with
the truth: the default works for mainland users; only override
DEEPSEEK_BASE_URL if you have a private mirror.

Also re-runs derive-facts to keep facts.generated.ts at 9 providers.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 21:53:40 -05:00
Hunter Bown b417fc9efa chore(ci): remove deploy-web workflow until Cloudflare token is sorted (#1115)
The current CLOUDFLARE_API_TOKEN secret authenticates but lacks
User -> User Details -> Read, which OpenNext needs to call the
/memberships endpoint during the KV populate step. Until that
permission is added (or the token is regenerated from Cloudflare's
"Edit Cloudflare Workers" template), every push to web/** fails CI.

Removing the workflow file until the token is ready. Re-add when
the secret has the right scopes; the workflow's previous content
is preserved in git history at 6483997480.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 21:17:05 -05:00
Hunter Bown 6483997480 ci(deploy-web): bump Node to 22 for wrangler@4 (#1111)
wrangler 4 requires Node.js >=22; the deploy job was pinned to 20
and failed at `npx wrangler deploy` with "Wrangler requires at
least Node.js v22.0.0".

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 21:03:42 -05:00
Hunter Bown 9e45780ba0 feat(web): community site for deepseek-tui.com (mobile + color refresh) (#1108)
First commit of the Next.js community site that powers
deepseek-tui.com, deployed via Cloudflare Workers / OpenNext.

This commit lands the scaffold and applies the visual + correctness
pass requested by community feedback:

- Palette: drop the cream/Anthropic-feel paper (#F4F1E8) for a
  DeepSeek-aligned cool white + soft gray (#FFFFFF / #F4F6FB), with
  indigo accents kept. Soften default hairlines so a pure-white
  background reads clean instead of harsh.
- Mobile: add a hamburger menu (mobile-menu.tsx) so phones can reach
  Install / Docs / Activity / Roadmap / Contribute — previously the
  link list was hidden on phones with no replacement. Tighter hero,
  flexible button row, viewport-safe code blocks, columnar grids
  collapse cleanly under 768px, and the printed-almanac center rule
  is desktop-only now (it sliced through narrow viewports).
- "How it works" diagram: replace the hand-rolled ASCII art (which
  misaligned under CJK monospace because Han characters take 2
  columns vs Latin's 1, per dhh's note in WeChat) with a real
  mermaid diagram rendered client-side via dynamic import. Uses the
  mermaid.live standard syntax 庄表伟 recommended.
- Issue #1104: the docs listed a `deepseek-cn` provider that the
  v0.8.16 binary doesn't accept (`ProviderArg` in crates/cli only
  has 9 variants; the 10th lives only in the legacy tui/config.rs).
  derive-facts.mjs now omits `deepseek-cn` until that variant is
  wired through the shared ProviderKind, and the install page's
  China-network recipe uses `base_url` / `DEEPSEEK_BASE_URL` (which
  actually works on v0.8.16) instead of the unsupported provider.

Auto-deploys via .github/workflows/deploy-web.yml on push to main.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 21:00:06 -05:00
Hunter Bown b3329f69f1 fix(release): unblock arm64 docker image build
Merge release infrastructure fix for v0.8.18 Docker/GHCR publish.
2026-05-07 20:56:47 -05:00
Hunter B 10c6901b64 fix(release): unblock arm64 docker image build 2026-05-07 20:48:40 -05:00
Hunter Bown 5c573b958b merge: v0.8.18 follow-up
Merge v0.8.18 release branch after local release gates and green CI.
2026-05-07 20:21:39 -05:00
Hunter Bown 35ee329b13 fix(tui): wait for terminal pause before interactive tools 2026-05-07 16:30:00 -05:00
Hunter Bown 2eddff473e fix(tui): keep light theme readable after toggle 2026-05-07 16:29:42 -05:00
Hunter Bown aa9e32bf0e chore(release): prepare v0.8.18 2026-05-07 15:36:30 -05:00
Hunter Bown ef808d893b docs(install): document rustup mirror fallback
Co-authored-by: nsight <wuyefeima@163.com>
2026-05-07 15:29:05 -05:00
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