Files
codewhale/CHANGELOG.md
T
Hunter Bown bf6d82e4ba chore: release v0.8.2 — Windows build fix, npm offline, model-visible skills, zh-CN README
Bumps workspace, all internal path-deps, and npm wrapper (version +
deepseekBinaryVersion) from 0.8.1 → 0.8.2. Lockfile re-locked offline
to keep the registry index untouched.

Triggers auto-tag.yml on push, which creates v0.8.2 and fires
release.yml to build cross-platform binaries and draft the GitHub
Release. npm publish remains manual per CLAUDE.md release runbook.

Note: npm registry already has 0.8.2 published (with binaryVersion
0.8.1 from an earlier checkpoint). That release keeps working unchanged
because v0.8.1 binaries stay on GitHub. Repo state aligns to 0.8.2 so
the version-drift gate passes; next npm publish (which will need to be
0.8.3 since 0.8.2 is taken) will pick up binaryVersion=0.8.2 and pull
the new binaries.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 01:41:47 -05:00

838 lines
65 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [0.8.2] - 2026-05-01
### Fixed
- **Windows release build (LNK1104)** — drop the `deepseek` shim binary in
`crates/tui` that 0.8.1 introduced for the bundled `cargo install`. It
produced a second `target/release/deepseek.exe` that collided with the
`deepseek-tui-cli` artifact during workspace builds; the second linker
invocation hit `LNK1104: cannot open file deepseek.exe` on Windows. The
cli crate is now the single source of `deepseek`; workspace default
members still produce both binaries (one per crate).
- **npm wrapper offline robustness** — `bin/deepseek(-tui).js` no longer
re-fetches the GitHub-hosted SHA-256 checksum manifest on every invocation.
When the binary is already installed and its `.version` marker matches the
package version, the wrapper trusts the local file. The manifest is fetched
lazily on actual download (first install or `DEEPSEEK_TUI_FORCE_DOWNLOAD=1`),
so GitHub flakes, captive portals, corporate proxies, and offline state no
longer break every command.
### Added
- **Model-visible skills block** — installed skills (name, description, file
path) are now exposed in the agent's system prompt under a `## Skills`
section, with progressive disclosure: bodies stay on disk, the model opens a
specific `SKILL.md` only when it decides to use that skill. Capped at a 12k
prompt budget with 512-char per-description truncation. Threaded through
`EngineConfig.skills_dir` so the TUI app, exec agent, and runtime thread
manager all populate it from `Config::skills_dir()`.
- **Simplified Chinese README** (`README.zh-CN.md`) with cross-link from the
English README.
### Changed
- **`cargo install` UX** — to install the canonical `deepseek` command,
`cargo install deepseek-tui-cli` (the historical path). The 0.8.1
one-command flow (`cargo install deepseek-tui` providing both binaries) is
reverted because it broke Windows release builds; install both packages
separately if you want the TUI binary too.
## [0.8.1] - 2026-05-01
### Fixed
- **One-command Cargo install** — `cargo install deepseek-tui --locked` now
provides both the canonical `deepseek` dispatcher and the `deepseek-tui`
companion binary from the main `deepseek-tui` package, so dispatcher
subcommands such as `deepseek doctor --json` work without installing
`deepseek-tui-cli` separately.
## [0.8.0] - 2026-05-01
### Fixed
- **Shell FD leak / post-send lag** — completed background shell jobs now release
their process, stdin, stdout, and stderr handles as soon as completion is
observed, while keeping the job record inspectable. This prevents long-running
TUI sessions from hitting `Too many open files (os error 24)`, which could
make checkpoint saves fail and cause shell spawning, message send, close, and
Esc/cancel paths to lag or fail.
- **Windows REPL runtime CI startup** — Windows gets a longer Python bootstrap
readiness timeout for the REPL runtime tests, matching GitHub runner startup
contention without weakening bootstrap failures on other platforms.
### Added
- **China / mirror-friendly Cargo install docs** — README now documents
installing through the TUNA Cargo mirror and direct release assets for users
with slow GitHub/npm access.
### Tests
- Added a regression test proving completed background shell jobs drop their
live process handles after `exec_shell_wait`.
- Re-ran the focused shell cancellation and Python REPL runtime slices.
## [0.7.9] - 2026-05-02
### Fixed
- **Post-turn freeze** — the checkpoint-restart cycle boundary (`maybe_advance_cycle`) now runs *before* `TurnComplete` emission instead of after, so the terminal is immediately responsive when the UI receives the completion event. The status chip ("↻ context refreshing…") remains visible during the cycle wait. (#234)
- **Enter during streaming no longer corrupts the turn** — a new `QueueFollowUp` submit disposition parks the draft on `queued_messages` when the model is actively streaming text. Previously, pressing Enter during streaming would forward the message as a mid-turn steer, which could interfere with the in-flight response. The message now dispatches as a normal user message after `TurnComplete`. (#234)
- **Idempotent Esc during fanout** — `finalize_active_cell_as_interrupted` and `finalize_streaming_assistant_as_interrupted` are now guarded by `Option::take()`. When Esc cancels a turn and the engine later delivers `TurnComplete(Interrupted)`, the second call is a no-op — no double `[interrupted]` prefix, no corrupted cell state. Regression test locks in the contract. (#243)
### Tests
- 2 new tests: `submit_disposition_queue_follow_up_when_streaming` (Enter/steering fix), `turn_complete_after_esc_is_idempotent` (Esc fanout double-call hardening)
- 1 expanded test: `submit_disposition_queue_when_offline_and_busy` now covers streaming state
## [0.7.8] - 2026-05-01
### Added
- **`exec_shell_cancel` tool** — cancel a running background shell task by id, or cancel all running tasks with `all: true`. Requires approval. (#248)
- **Foreground-to-background shell detach** — press `Ctrl+B` while a foreground command is running to open shell controls and either detach the command to the background (where it can be polled via `exec_shell_wait`) or cancel the current turn. (#248)
- **`exec_shell_wait` turn-cancellation awareness** — canceling a turn while `exec_shell_wait` is blocking now stops the wait but leaves the background task running, with `wait_canceled: true` in metadata. (#248)
- **`ShellControlView` modal** (Ctrl+B) — two-option dialog (Background / Cancel) rendered as a popup over the transcript. (#248)
### Changed
- **`exec_shell` foreground path** now spawns all foreground commands through the background job table, enabling the detach-to-background flow. Metadata now includes `backgrounded: true/false`. (#248)
- **`exec_shell_interact`** poll loop now observes the turn cancel token so stalled interactive sessions don't block turn cancellation. (#248)
- **Transcript running-tool hint** — executing shell cells now show "Ctrl+B opens shell controls" while running. (#248)
- **Keybinding registry** now includes `Ctrl+B` (opens shell controls) next to `Ctrl+C` (cancel/exits). (#248)
- **Deferred swarm card creation** — `agent_swarm` no longer pre-seeds an all-pending FanoutCard from `ToolCallStarted`; the card is created only when the first `SwarmProgress` event carries real worker state. Until then the sidebar uses the declared task count as a pending dispatch placeholder. (#236, #238)
- **Swarm wording normalized** — fanout-family fallback labels now render as `swarm`, matching the canonical `agent_swarm` / `rlm` model and avoiding mixed `fanout` / `swarm` terminology in the transcript. (#236, #238)
- **OPERATIONS_RUNBOOK** and **TOOL_SURFACE** updated with new shell control paths and `exec_shell_cancel` documentation.
### Fixed
- **Nonblocking swarm state drift** — the sidebar no longer falls back to `0` or a contradictory seeded placeholder before the first progress event arrives, which removes the visible `pending` vs `running/done` mismatch during early `agent_swarm` dispatch. (#236, #238)
- **Unicode-safe search globbing** — search wildcard matching now iterates on UTF-8 char boundaries instead of raw byte offsets, preventing panics on filenames like `dialogue_line__冰糖.mp3`. (#249)
### Tests
- 7 new integration tests: foreground-to-background detach, wait-cancel-leaves-process, single-task cancel, bulk cancel (kill-all), foreground-cancel-kills, ShellControlView default/select states
- Expanded swarm/sidebar regression coverage for deferred card creation and pending-count fallback before first `SwarmProgress`. (#236, #238)
- Added a Unicode filename regression test for wildcard search matching. (#249)
## [0.7.7] - 2026-04-30
### Added
- **Checklist card rendering** — `checklist_write` / `todo_*` results now render as a purpose-built card with completed/total + percent header, per-item status markers (✅ / `●` / `○`), and a collapsing affordance for long lists. Plumbed through `GenericToolCell` so no new variant threading is needed. (#241)
- **Context menu for transcript operations** — right-click or `Ctrl+M` opens a context-sensitive menu with Copy, Copy All, and selection-aware actions. (`crates/tui/src/tui/context_menu.rs`)
- **Windows .exe sibling lookup** — `locate_sibling_tui_binary` in the CLI dispatcher finds `deepseek-tui.exe` on Windows, honours `DEEPSEEK_TUI_BIN` override, and falls back to suffix-less lookup. Tests lock in platform-correct name resolution and env override. (#247)
### Changed
- **Swarm/sub-agent canonical data model** — `SwarmTaskOutcome` and `SwarmOutcome` are now the single source of truth. Every UI surface (sidebar, transcript FanoutCard, footer) reads from `swarm_jobs` rather than maintaining parallel projections. (#236, #238)
- **`swarm_card_index`** binds each swarm to its own FanoutCard by `swarm_id`, so overlapping fanouts no longer have one swarm's late progress clobber another's card. (#236, #238)
- **Fanout-class tools suppressed from footer** — `agent_swarm`, `spawn_agents_on_csv`, `rlm`, and `agent_spawn` no longer appear as active tools in the status strip; sidebar and FanoutCard show the actual worker counts. (#236, #238)
- **Esc clears active tool entries optimistically** — the active cell is finalized immediately on cancel rather than waiting for the engine's `TurnComplete` echo. Background `block:false` swarms remain durable and tracked through `swarm_jobs`. (#243)
- **Post-turn workspace snapshot detached** — the snapshot still runs on `spawn_blocking` but the engine no longer awaits its `JoinHandle`, so the UI accepts input immediately after `TurnComplete`. (#234)
- **Shell output preserves Cargo/test summaries under truncation** — high-signal tail lines (`test result:`, `failures:`, `error[E…]`, `Finished`, `Compiling`, panic markers) survive truncation so the agent doesn't re-run gates. (#242)
- **Monotonic spend display** — `displayed_session_cost` + `displayed_cost_high_water` ensure the visible session+sub-agent total never decreases across reconciliation events (cache discounts, provisional → final). (#244)
- Clipboard module expanded with additional platform-aware copy/paste paths. (`crates/tui/src/tui/clipboard.rs`)
- Context inspector enriched with additional metadata columns and session-scoped agent state. (`crates/tui/src/tui/context_inspector.rs`)
- Configuration documentation updated for v0.7.7 settings. (`docs/CONFIGURATION.md`, `docs/MODES.md`)
### Fixed
- **Windows npm install path** — the npm-distributed `deepseek` dispatcher now locates the platform-correct `deepseek-tui` binary (`.exe` suffix on Windows), fixing runtime failures for Windows users. (#247)
- **Sidebar/transcript/footer agreement** — all three surfaces now agree on agent counts and status because they share the canonical `swarm_jobs` store. (#236, #238)
- **Fanout card clobbering** — overlapping swarms no longer overwrite each other's progress cards. (#238)
- **Cost display regression** — negative reconciliation events (cache-hit discount applied after provisional count) no longer briefly drop the displayed cost. (#244)
### Tests
- 65+ new/expanded tests: checklist card rendering, swarm card index binding, fanout tool suppression, Esc cancel contract, monotonic spend under reconciliation, shell summary preservation, Windows sibling binary lookup, clipboard platform paths, context menu state transitions
### Added
- **UI Localization registry** — `locale` setting in `settings.toml` (`auto`, `en`, `ja`, `zh-Hans`, `pt-BR`) with `LC_ALL`/`LC_MESSAGES`/`LANG` auto-detection. Core packs shipped for English, Japanese, Chinese Simplified, and Brazilian Portuguese covering composer placeholder, history search, `/config` chrome, and help overlay. Missing/unsupported locales fall back to English. (`crates/tui/src/localization.rs`, `docs/CONFIGURATION.md`)
- **Grouped, searchable `/config` editor** — settings organized by section (Model, Permissions, Display, Composer, Sidebar, History, MCP) with live substring filter. Typing `j`/`k` navigates when the filter is empty; otherwise they enter the filter. (`crates/tui/src/tui/views/mod.rs`)
- **Pending input preview widget** — while a turn is running, queued messages, pending steers, rejected steers, and context chips render above the composer. Three-row-per-message truncation with ellipsis overflow. (`crates/tui/src/tui/widgets/pending_input_preview.rs`)
- **Alt+↑ edit-last-queued** — pops the most recently queued message back into the composer for editing. No-op when the composer is dirty. (`crates/tui/src/tui/app.rs`)
- **Composer history search and draft recovery** — `Alt+R` opens a live substring search across `input_history` and `draft_history` (max 50 entries). `Enter` accepts, `Esc` restores the pre-search draft. Unicode case-insensitive matching. (`crates/tui/src/tui/app.rs`)
- **Paste-burst detection** — fallback rapid-key paste detection independent of terminal bracketed-paste mode. Configurable via `paste_burst_detection` setting (default on). CRLF normalization (`\r\n``\n`, `\r``\n`). (`crates/tui/src/tui/paste_burst.rs`)
- **Composer attachment management** — `↑` at the composer start selects the attachment row; `Backspace`/`Delete` removes it without editing placeholder text. (`crates/tui/src/tui/app.rs`)
- **Searchable help overlay** — live substring filter across slash commands and keybindings, multi-term AND matching, localized chrome. (`crates/tui/src/tui/views/help.rs`)
- **Keyboard-binding documentation catalog** — single source of truth for help overlay rendering. Documents 38+ keyboard chords across Navigation, Editing, Submission, Modes, Sessions, Clipboard, and Help sections. (`crates/tui/src/tui/keybindings.rs`)
- **Legacy Rust deprecation audit** — non-destructive compatibility audit covering legacy MCP sync API, prompt constants, `/compact`, `todo_*` aliases, sub-agent aliases, provider `api_key` compatibility, model alias canonicalization, and palette aliases. Tracked by #218#221. (`docs/LEGACY_RUST_AUDIT_0_7_6.md`)
### Changed
- **Shift+Tab cycles reasoning-effort** through Off → High → Max (three behaviorally distinct tiers). Previously Tab cycled modes; Shift+Tab is now the reasoning-effort shortcut. (`crates/tui/src/tui/app.rs:1119`)
- **Reasoning-effort `Off` now sends `"off"`** to the API (was `None`). Allows explicit thinking disable. (`crates/tui/src/tui/app.rs`)
- **Media `@`-mentions now emit `<media-file>` hints** directing users to `/attach` instead of inlining binary bytes. Tests lock in the contract. (`crates/tui/src/tui/file_mention.rs`)
- **`/attach` rejects non-media files** with a descriptive error pointing to `@path` for text. (`crates/tui/src/commands/attachment.rs`)
- **Configuration reference updated** to cover all v0.7.6 settings: `locale`, `paste_burst_detection`, `reasoning_effort`, `composer_density`, `sidebar_focus`, and more. (`docs/CONFIGURATION.md`)
### Fixed
- **Unicode-safe truncation** in pending-input preview and view text — no more mid-character breaks on multi-byte UTF-8. (`crates/tui/src/tui/widgets/pending_input_preview.rs`, `crates/tui/src/tui/views/mod.rs`)
- **CJK/emoji display-width handling** in locale tests and config view rendering. (`crates/tui/src/localization.rs`)
- **Context preview distinguishes `@media`, `/attach`, missing, and included files** with separate kind labels and inclusion status. (`crates/tui/src/tui/file_mention.rs`)
- **Config view filter accept `j`/`k` only when filter is empty** — typing `j` or `k` into the filter field no longer navigates away. (`crates/tui/src/tui/views/mod.rs`)
### Tests
- 7 localization tests (tag normalization, env resolution, shipped pack completeness, missing-key fallback, Unicode width truncation)
- 11 pending-input preview tests (context buckets, truncation, URL overflow, narrow-width)
- 13 paste tests (burst detection, CRLF normalization, clipboard images, Unicode)
- 9 draft/history search tests (match filter, unicode, accept/cancel, recovery)
- 93 config tests (grouping, filter, edit, j/k, localization, escape/cancel)
- 24 workspace tests (context refresh, scroll, mention completion)
- 7 file-mention tests (context references, media/attach distinction, removability)
## [0.7.1] - 2026-04-28
### Added
- Grouped active tool-call cards with compact rails and a live working-status row while tools run. (#142, #149)
- Selected-card-aware Alt+V details so the visible or selected tool card opens the matching detail payload. (#143)
- Compact terminal-native session context inspector with persisted `@path` and `/attach` reference metadata for resumed transcripts. (#146, #150)
### Changed
- Polished tool cards, diff summaries, and pending context previews for denser terminal-native scanning. (#141, #144, #145, #148)
- Ranked Ctrl+P file-picker results with working-set relevance from modified files, recent `@file` mentions, and recent tool paths while keeping fuzzy filtering in memory. (#147)
## [0.7.0] - 2026-04-28
### Added
- OS keyring-backed auth storage with `deepseek auth` subcommands, migration from plaintext config, provider-aware key resolution, and doctor visibility. (#134)
- Egress network policy with allow/deny/prompt decisions, deny-wins matching, audit logging, and enforcement hooks for network-capable tools. (#135)
- LSP diagnostics auto-injection after edits so compile feedback can be reinjected into the next agent turn. (#136)
- Side-git workspace snapshots, `/restore`, and `revert_turn` so agent edits can be rolled back without moving the user's repository HEAD. (#137)
- Esc-Esc backtrack over prior user turns, desktop turn-complete notifications, Alt+V tool-details access, safer command-prefix auto-allow matching, bundled `skill-creator`, and `/skill install` management for community skills. (#131, #132, #133, #138, #139, #140)
### Changed
- Split more engine/tool primitives into focused modules and workspace crates, including shared tool result primitives and extracted turn/capacity flow. (#67, #74)
### Tests
- Added mock LLM and skill-install integration coverage for streaming turns, reasoning replay, tool-call loops, network policy, and skill validation. (#69, #140)
## [0.6.5] - 2026-04-27
### Added
- **`rlm_process` tool — recursive language model as a tool call.** The previous `/rlm` slash command had a UI rendering gap (the answer never made it back to the model's view) and required the user to remember to invoke it manually. `rlm_process` exposes the full RLM loop as a structured tool the model itself can choose, the same way it reaches for `agent_spawn` or `rlm_query`. Inputs: `task` (small instruction, shown to the root LLM each iteration) plus exactly one of `file_path` (workspace-relative, preferred — keeps the long input out of the model's context entirely) or `content` (inline, capped at 200k chars). Optional `child_model` (default `deepseek-v4-flash`) and `max_depth` (default 1, paper experiments). Returns the synthesized answer with metadata (iterations, duration, tokens, termination reason). Loaded across Plan / Agent / YOLO; never deferred via ToolSearch. (`crates/tui/src/tools/rlm_process.rs`)
- **Reference-aligned REPL surface.** Aligned the in-REPL Python helpers with the canonical reference RLM (alexzhang13/rlm). The sub-agent now sees `context` (the full input, not `PROMPT`), `llm_query`, `llm_query_batched`, `rlm_query` (was `sub_rlm`), `rlm_query_batched`, `SHOW_VARS()`, `FINAL(...)`, `FINAL_VAR(...)`, plus `repl_get`/`repl_set`. Same prompt patterns and decomposition strategies from the paper now apply verbatim. (`crates/tui/src/repl/runtime.rs`)
- **Concurrent fanout from inside the REPL.** `llm_query_batched(prompts, model=None)` runs up to 16 child completions in parallel via a new `POST /llm_batch` sidecar endpoint — much faster than serial `[llm_query(p) for p in prompts]`. `rlm_query_batched(prompts)` does the same for recursive RLM sub-calls via `POST /rlm_batch`. (`crates/tui/src/rlm/sidecar.rs`)
- **`SHOW_VARS()`** — returns `{name: type-name}` for every user variable in the REPL. Lets the model inspect what it has accumulated across rounds before deciding whether to call `FINAL_VAR(name)`.
- **Auto-persistence of REPL variables across rounds.** Any top-level JSON-serializable variable the sub-agent creates in a `repl` block now persists to the next round automatically — no `repl_set` ceremony needed unless you want explicit control. Matches the in-process reference REPL semantics.
### Changed
- **Code fence is `repl`, not `python`.** Matches the reference RLM language identifier so the same prompts and few-shot examples work here. Backward-compat fallback to `python` / `py` retained for older model behaviors.
- **`FINAL` / `FINAL_VAR` parseable from raw response text.** The reference RLM lets the model write `FINAL(value)` on its own line outside any code block to terminate the loop. Added `parse_text_final()` so that path works alongside the existing in-REPL Python sentinel mechanism. Code-fenced occurrences of `FINAL(...)` are correctly ignored to avoid false positives.
- **Strict termination loop.** The sub-agent must emit a ```repl block (or text-level FINAL) to make progress. One fence-less round triggers a reminder; two consecutive trigger a `RlmTermination::DirectAnswer` exit so we don't loop forever.
- **`rlm_process` separates `task` (root_prompt) from `file_path`/`content` (context).** The `task` rides along as `root_prompt` and is shown to the root LLM each iteration; the big input lives only in the REPL as `context`. Mirrors the reference's `completion(prompt, root_prompt=...)` API.
- **System prompt rewritten** with the reference's strategy patterns (PREVIEW → CHUNK + map-reduce via `llm_query_batched` → RECURSIVE decomposition via `rlm_query` → programmatic computation + LLM interpretation).
- The `/rlm` slash command stays for manual experimentation but is no longer the recommended path; the description in `commands/mod.rs` now points the model toward `rlm_process` for the in-agent flow.
### Reference
- Zhang, Kraska, Khattab. "Recursive Language Models." arXiv:2512.24601.
- alexzhang13/rlm — reference implementation by the paper authors. Variable names, helper surface, and code-fence convention align with that repo so prompts and patterns transfer.
### Fixed
- **`/rlm` actually recurses now (Algorithm 1 substrate, paper-faithful).** The v0.6.3 RLM loop had the right *shape* but its recursive substrate was non-functional: `llm_query()` was a Python stub that returned a hardcoded string, and `child_model` was bound with an underscore prefix and silently dropped. The loop ran but the sub-LLM never fired. v0.6.4 fixes this end-to-end:
- **HTTP sidecar.** Each RLM turn spins up a localhost-only axum server on a kernel-assigned port for the duration of the turn. Python's `llm_query()` and `sub_rlm()` are real `urllib.request.urlopen` POSTs; Rust services them via the existing DeepSeek client and returns the completion text. No long-lived python process, no FIFOs, no two-pass replay — Python blocks on HTTP, Rust answers it. (`crates/tui/src/rlm/sidecar.rs`)
- **`child_model` is plumbed through.** `Op::RlmQuery` and `AppAction::RlmQuery` carry the configured child model (default `deepseek-v4-flash`) all the way to the sidecar, where every `llm_query()` call uses it. Token usage is folded into `RlmTurnResult.usage` so cost tracking works.
- **`sub_rlm()` is exposed as a paper-faithful recursive RLM call.** The Python REPL gets a real `sub_rlm(prompt)` function that runs another full Algorithm-1 turn at depth-1 inside the same process (different sidecar route, decremented recursion budget). Default `max_depth = 2` from the `/rlm` command — the model can recurse twice before the budget hits zero. The recursive opaque-future cycle (`run_rlm_turn_inner``start_sidecar``sub_rlm_handler``run_rlm_turn_inner`) is broken by returning a concrete `Pin<Box<dyn Future + Send>>` from `run_rlm_turn_inner`.
- **Strict termination.** The loop only ends via `FINAL(value)` (or the iteration cap). The previous "no fence = direct answer, end loop" early-exit deviated from the paper and could short-circuit on iteration 1 with a chatty model that never saw `PROMPT`. The new behavior tolerates one fence-less round (with a reminder appended), then falls back to a `RlmTermination::DirectAnswer` exit. `RlmTurnResult` now carries a `termination: RlmTermination` enum (`Final | DirectAnswer | Exhausted | Error`) so callers can tell what happened.
- **Richer `Metadata(state)`.** The metadata message the root LLM sees now includes paper-required *access patterns* (`repl_get`, slicing, `splitlines`, `repl_set`, `llm_query`, `sub_rlm`, `FINAL`) and a live list of variable keys currently in the REPL state file — so the model can see what it's accumulated across rounds without us shipping the values themselves.
- **Unicode-safe truncation.** `truncate_text` now counts Unicode codepoints (was mixing `text.len()` bytes with `chars().take(n)`), so multi-byte previews can no longer mis-count. Per-turn temp state files are cleaned up on completion. `ROOM_TEMPERATURE` typo → `ROOT_TEMPERATURE`.
- **End-to-end smoke test.** `rlm::turn::tests::sidecar_url_is_exported_to_python_env` stands up a stand-in axum server that always replies `{"text":"pong-from-sidecar"}`, runs `print(llm_query('hello'))` in the real `PythonRuntime`, and asserts the reply round-trips. This catches future regressions in the sidecar URL passthrough.
### Reference
- Zhang, Kraska, Khattab. "Recursive Language Models." arXiv:2512.24601 (Algorithm 1).
### Added
- **Sub-agents surface in the footer status strip.** When N > 0 sub-agents are in flight, the footer grows a "1 agent" / "N agents" chip in DeepSeek-sky color matching the model badge. Hides entirely at zero. (`footer_agents_chip` in `widgets/footer.rs`)
- **`@`-mention popup is fully wired in the composer.** Previously only the App state fields existed (`mention_menu_selected`, `mention_menu_hidden`). The popup now renders below the input mirror-style with the slash menu, with `@`-prefixed entries; Up/Down navigates, Enter / Tab apply the selection, Esc hides until the next input edit. Mention takes precedence over slash because the positional check is stricter. (`visible_mention_menu_entries` + `apply_mention_menu_selection` in `file_mention.rs`)
### Fixed
- **Tool-call cells no longer flash `<command>` / `<file>` placeholders.** The engine used to emit `ToolCallStarted` from `ContentBlockStart` with `input: {}` — before any `InputJsonDelta` had streamed in — which baked the placeholder into the cell at creation time. The emission is now deferred to `ContentBlockStop` and routed through `final_tool_input`, so the cell is created with the parsed args already in hand. (engine.rs `final_tool_input`; engine/tests.rs `final_tool_input_*`)
- **`parse_invocation_count` flake.** Two `markdown_render` tests both read the global PARSE_INVOCATIONS atomic and raced when other tests called `parse()` in parallel. Switched the counter to `thread_local!<Cell<u64>>`, so each test thread sees only its own invocations. Tested 8 sequential full-suite runs: 8/8 green (was ~40% green).
### Changed
- **System prompts redesigned with decomposition-first philosophy.** All four prompt tiers (base, agent, plan, yolo) now teach the model to decompose tasks before acting — `todo_write` first for granular task tracking, `update_plan` for high-level strategy, and sub-agents for parallelizable work. Inspired by the "mismanaged geniuses hypothesis" (Zhang et al., 2026): frontier LMs are already capable enough; the bottleneck is how we scaffold their self-management. The prompts now make work visible through the sidebar (Plan / Todos / Tasks / Agents) instead of letting the model work invisibly.
- **Tool labels use progressive verbs.** "Read foo.rs" → "Reading foo.rs", "List X" → "Listing X", "Search pattern" → "Searching for `pattern`", "List files" → "Listing files". Past-tense labels read wrong while a tool is still in flight; the new forms match what the user actually sees.
- **Long-running tools grow an elapsed badge.** From 3 s onward the `running` status segment becomes `running (3s)`, `running (4s)`, … so the user can tell a tool isn't stuck. The status-animation tick (360 ms) drives the redraw; below 3 s the badge stays hidden so quick reads/greps don't churn. (history.rs `running_status_label_with_elapsed`)
- **Spinner pulse is twice as fast** — `TOOL_STATUS_SYMBOL_MS` 1800 ms → 720 ms per glyph (full 4-glyph heartbeat in ~2.88 s instead of ~7.2 s).
- **`tools/subagent.rs` is now a folder module.** Tests live in `tools/subagent/tests.rs`; runtime + manager + tool implementations stay in `tools/subagent/mod.rs`. Public API unchanged. The runtime / tool-impl split was deferred — `SubAgentTask`, `run_subagent_task`, `build_allowed_tools`, the agent prompt constants, and `normalize_role_alias` are referenced from both layers and need a small API design pass before they cleanly separate.
### Test hygiene
- **5 regression tests pin auto-scroll churn contract.** `mark_history_updated` does not scroll; tool-cell handlers only `mark_history_updated`; `add_message` and `flush_active_cell` gate on `user_scrolled_during_stream`; the per-stream lock clears at TurnComplete and when the user returns to the live tail. (P2.4)
## [0.6.1] - 2026-04-26
### Changed
- **V4 cache-hit input prices cut to 1/10th per DeepSeek's pricing update.** Pro promo 0.03625→0.003625, Pro base 0.145→0.0145, Flash 0.028→0.0028 per 1M tokens. Cache-miss and output rates unchanged.
- **Removed the "light" theme option.** It was never tested, looked bad, and the dark/whale palettes are the supported targets. Theme validation now accepts only `default`, `dark`, and `whale`.
- **System prompts redesigned with decomposition-first philosophy.** All five prompt tiers teach the model to `todo_write` before acting, `update_plan` for strategy, and sub-agents for parallel work. Inspired by the mismanaged-geniuses hypothesis (Zhang et al., 2026).
## [0.6.0] - 2026-04-25
### Added
- **`rlm_query` tool — recursive language models as a first-class structured tool.** Inspired by [Alex Zhang's RLM work](https://github.com/alexzhang13/rlm) and Sakana AI's published novelty-search research, but trimmed to what an agent loop actually needs. The model calls `rlm_query` with one prompt or up to 16 concurrent prompts; children run on `deepseek-v4-flash` by default and can be promoted to Pro per-call. Children dispatch concurrently via `tokio::join_all` against the existing DeepSeek client — no external runtime, no fenced-block DSL, no Python sandbox. Returns plain text for one prompt, indexed `[0] ...\n\n---\n\n[1] ...` blocks for many. Available in Plan / Agent / YOLO. Cost is folded into the session's running total automatically.
### Changed
- **Scroll position survives content rewrites (#56).** `TranscriptScroll::resolve_top` and `scrolled_by` no longer teleport to bottom when the anchor cell vanishes. Three-level fallback chain: same line → same cell, line 0 → nearest surviving cell at-or-before. Previously, any rewrite of the assistant message (e.g. tool-result replacement) silently dropped the user back to the live tail mid-scroll.
- **Looser command-safety chains (#57).** `cargo build && cargo test`, `git fetch && git rebase`, and similar chains of known-safe commands now escalate to `RequiresApproval` instead of being hard-blocked as `Dangerous`. Chains containing unknown commands still block.
- **`GettingCrowded` no longer surfaces a footer chip.** The context-percent header already covers conversation pressure; the chip now only fires for active engine interventions (`refreshing context`, `verifying`, `resetting plan`).
## [0.5.2] - 2026-04-25
### Added
- **`/model` opens a Pro/Flash + thinking-effort picker (#39).** Typing `/model` with no argument now pops a two-pane modal: model on the left (`deepseek-v4-pro` flagship, `deepseek-v4-flash` fast/cheap, plus a "current (custom)" row when the active id isn't one of the listed defaults), and thinking effort on the right. Tab/←/→ swaps panes, ↑/↓ moves within the focused pane, Enter applies both selections, Esc cancels. The effort pane intentionally exposes only **Off / High / Max** because [DeepSeek's Thinking Mode docs](https://api-docs.deepseek.com/guides/reasoning_model) state `low`/`medium` are mapped to `high` server-side and `xhigh` is mapped to `max` — the legacy variants stay valid in `~/.deepseek/settings.toml` for back-compat, the picker just doesn't surface them. Apply path persists `default_model` and `reasoning_effort` to settings, forwards `Op::SetModel` + `Op::SetCompaction` to the running engine so the next turn picks up the change without a restart, and resets the per-turn token gauges (cache, replay) so the footer numbers reflect the new model. `/model <id>` keeps working unchanged for power users.
## [0.5.1] - 2026-04-25
### Added
- **`fetch_url` tool** for direct HTTP GET on a known URL — complements `web_search` for cases where the link is already known. Supports `format` (`markdown` / `text` / `raw`), `max_bytes` (default 1 MB, hard cap 10 MB), `timeout_ms` (default 15 s, max 60 s), redirect following, and structured `{url, status, content_type, content, truncated}` responses. 4xx/5xx bodies are returned (with `success: false`) so the caller can read JSON error envelopes. (#33)
- **PDF support in `read_file`.** PDFs are auto-detected by extension or `%PDF-` magic bytes and extracted via `pdftotext -layout` (poppler) when available. New optional `pages` arg (`"5"` or `"1-10"`) reads page slices. Without `pdftotext`, returns a structured `{type: "binary_unavailable", kind: "pdf", reason, hint}` with install commands for macOS/Debian. (#34)
- **Reasoning-content replay telemetry, end-to-end (#30).** The chat-completions sanitizer now estimates replayed `reasoning_content` tokens (~4 chars/token), threads the value through the streaming `Usage` payload, stores it on the App, and renders an `rsn N.Nk` chip in the footer next to the cache hit-rate. The chip turns warning-coloured when replay tokens exceed 50% of the input budget, so users on long thinking-mode loops can see at a glance how much of their context window is going to V4's "Interleaved Thinking" replay (paper §5.1.1). Logged at `RUST_LOG=deepseek_tui=info` for tail-friendly diagnosis.
- **`@file` Tab-completion (#28).** Typing `@<partial>` and pressing Tab now resolves the mention against the workspace using the existing `ignore::WalkBuilder`. A unique match is spliced into the input; multiple matches with a longer common prefix extend the partial; remaining ambiguity is surfaced via the status line. The mention-expansion path that ships file contents to the model is unchanged — this is purely a discovery aid for typing the path. Inline-contents and a fuzzy popup picker are queued for v0.5.2.
- **Per-workspace external trust list (#29).** `~/.deepseek/workspace-trust.json` now records, for each workspace, the absolute paths the user has opted into reading/writing from outside that workspace. The new `/trust` slash command supports `add <path>`, `remove <path>`, `list`, `on`, `off`, and a status read with no args; the engine consults the list when constructing every `ToolContext` so changes apply on the next tool call without restart. `/diagnostics` surfaces the list. The interactive "Allow once / Always allow / Deny" approval prompt is deferred — for now grant access ahead of the turn with `/trust add <path>`.
### Fixed
- **TUI sidebar gutter bleed regression test (#36).** Snapshot tests now lock in that long single-line tool results — including a `todo_write` echo of a multi-kilobyte JSON payload — never write any cells outside `chat_area` at the widths reported in the bug (80, 120, 165, 200 cols). A second test verifies the scrollbar coexists with content along the right edge instead of overdrawing the penultimate column.
- **Version drift caught in CI.** New `versions` job in `.github/workflows/ci.yml` runs `scripts/release/check-versions.sh` on every push/PR, verifying every per-crate `Cargo.toml` inherits the workspace version, the npm wrapper matches the workspace version, and `Cargo.lock` is in sync. The release runbook now lists `check-versions.sh` as the first preflight step. (#31)
- **Per-mode soft context budget for V4 compaction trigger** (#27).
- **Phantom `web.run` references stripped** from prompts and the `web_search` tool surface (#25).
- **Unused import + `cargo fmt` drift** that landed with `feat(#27)` and broke Build / Test / npm wrapper smoke under `-Dwarnings`.
## [0.5.0] - 2026-04-25
### Fixed
- Multi-turn tool calls on thinking-mode models no longer return HTTP 400. Every assistant message in the conversation now carries `reasoning_content` when thinking is enabled — not just tool-call rounds — matching DeepSeek's actual API validation, which rejects any assistant message missing the field even though the docs describe non-tool-call reasoning as "ignored".
- Added a final-pass wire-payload sanitizer in the chat-completions client that forces a non-empty `reasoning_content` placeholder onto any assistant message still missing one at request time. This is the last line of defense after engine-side and build-side substitution, so sessions restored from older checkpoints, sub-agents that append messages directly, and cached prefix mismatches all produce a valid request.
- On a `reasoning_content`-related 400, the client now logs the offending message indices to make future regressions diagnosable.
- Stripped phantom `web.run` references from prompts and the `web_search` tool surface ([#25](https://github.com/Hmbown/DeepSeek-TUI/issues/25)).
### Changed
- Header/UI widget refactor in the TUI (`crates/tui/src/tui/ui.rs`, `widgets/header.rs`) — internal cleanup, no user-visible behavior change.
## [0.4.9] - 2026-04-27
### Fixed
- DeepSeek thinking-mode tool-call rounds now always replay `reasoning_content` in all subsequent requests (including across new user turns), matching DeepSeek's documented API contract that assistant messages with tool calls must retain their reasoning content forever.
- Missing `reasoning_content` on a tool-call assistant message now substitutes a safe placeholder (`"(reasoning omitted)"`) instead of dropping the tool calls and their matching tool results, preventing orphaned conversation chains and API 400 errors.
- Session checkpoint now persists a Thinking-block placeholder for tool-call turns that produced no streamed reasoning text, keeping on-disk sessions structurally correct so subsequent requests avoid HTTP 400 rejections.
- Token estimation for compaction now counts thinking tokens across all tool-call rounds (not just the current user turn), aligning with the updated reasoning_content replay rule.
## [0.4.8] - 2026-04-25
### Fixed
- DeepSeek V4 Pro cost estimates now use DeepSeek's current limited-time 75% discount until 2026-05-05 15:59 UTC, then automatically fall back to the base Pro rates.
## [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
- DeepSeek V4 thinking-mode tool turns now checkpoint the engine's authoritative API transcript, including assistant `reasoning_content` on reasoning-to-tool-call turns with no visible assistant text.
- Chat Completions request building now drops stale V4 tool-call rounds that are missing required `reasoning_content`, preventing old corrupted checkpoints from triggering DeepSeek HTTP 400 replay errors.
- Web search now falls back to Bing HTML results when DuckDuckGo returns a bot challenge or otherwise yields no parseable results.
## [0.4.1] - 2026-04-24
### Fixed
- DeepSeek V4 tool-result context now preserves large file reads and command outputs instead of compacting noisy tools to a 900-character snippet after 2k characters.
- Capacity guardrail refresh no longer performs destructive summary compaction unless the normal model-aware compaction thresholds are actually crossed.
- V4 compaction summaries retain larger tool-result excerpts and summary input when compaction is genuinely needed.
- The transcript now follows the bottom again when sending a new message, shows an in-app scrollbar when internally scrolled, and leaves mouse capture off in `--no-alt-screen` mode so terminal-native scrolling can work.
## [0.4.0] - 2026-04-23
### Added
- **DeepSeek V4 support**: `deepseek-v4-pro` (flagship) and `deepseek-v4-flash` (fast/cheap) are now first-class model IDs with 1M context windows.
- **Reasoning-effort tier**: new `reasoning_effort` config field (`off | low | medium | high | max`) mapped to DeepSeek's `reasoning_effort` + `thinking` request fields. Defaults to `max`.
- **Shift+Tab cycles reasoning-effort** through the three behaviorally distinct tiers (`off → high → max`). The current tier is shown as a ⚡ chip in the header.
- Per-model pricing table: `deepseek-v4-pro` priced at $0.145/$1.74/$3.48 per 1M tokens (cache-hit/miss/output); `deepseek-v4-flash` and legacy aliases at $0.028/$0.14/$0.28.
### Changed
- **Default model flipped to `deepseek-v4-pro`** (from `deepseek-reasoner`).
- `deepseek-chat` / `deepseek-reasoner` remain as silent aliases of `deepseek-v4-flash` for API compatibility; priced identically.
- **Context compaction**: 1M-context V4 models now compact at 800k input tokens or 2,000 messages, so short/tool-heavy sessions do not compact as if they were 128k-context runs.
- Cycling modes is now Tab-only; Shift+Tab is repurposed for reasoning-effort (reverse-mode cycle was low-value with only three modes).
- Updated help/hint strings, validator error messages, and the model picker to reference V4 IDs.
### Fixed
- `requires_reasoning_content` now recognizes `deepseek-v4*` so thinking streams render correctly on V4 models.
- DeepSeek V4 thinking-mode tool calls now preserve prior assistant `reasoning_content` whenever a tool call is replayed, matching DeepSeek's multi-turn contract and avoiding HTTP 400 rejections on later turns.
- Raw Chat Completions requests now send DeepSeek's top-level `thinking` parameter instead of the OpenAI SDK-only `extra_body` wrapper.
- Config, env, and UI model selection now normalize legacy DeepSeek aliases to `deepseek-v4-flash` instead of preserving old model labels.
- npm wrapper first-run downloads now use process-unique temp files so concurrent `deepseek` / `deepseek-tui` invocations do not race on `*.download` files.
## [0.3.33] - 2026-04-11
### Changed
- Footer polish: simplified footer rendering, removed footer clock label, updated status line layout
- Palette cleanup: removed `FOOTER_HINT` color constant
### Removed
- `FOOTER_HINT` color constant from palette (use `TEXT_MUTED` or `TEXT_HINT` instead)
### Fixed
- Test updates to align with simplified footer logic
- Empty state placeholder text removed for cleaner UI
## [0.3.32] - 2026-04-11
### Added
- Finance tool: Yahoo Finance v8 quote endpoint with chart fallback, supporting stocks, ETFs, indices, forex, and crypto lookups.
- Header widget redesign: proportional truncation, context-usage bar with gradient fill, streaming indicator, and graceful narrow-terminal degradation.
- Expanded test coverage: 680+ tests including footer state, context spans, plan prompt lifecycle, workspace context refresh, header rendering, and finance tool integration tests with wiremock.
- Workspace context refresh with configurable TTL and deferred initial fetch.
- Config command additions for runtime settings management.
### Changed
- Redesigned footer status strip with mode/model/status layout, context bar, and narrow-terminal fallback.
- Plan prompt now uses numeric selection (1-4) instead of keyword input; old aliases are sent as regular messages.
- Archived outdated docs (`workspace_migration_status.md` -> `docs/archive/`).
- Trimmed AGENTS.md boilerplate and updated task counts.
- Clarified release-surface documentation: crates.io publication may lag the workspace/npm wrapper.
### Fixed
- Header `metadata_spans` now uses `saturating_sub` to prevent underflow on narrow terminals.
- Finance tool reuses a single HTTP client instead of rebuilding per request.
- Finance tool tests no longer leak temp directories.
## [0.3.31] - 2026-03-08
### Added
- Replaced the finance tool backend with Yahoo Finance v8 + CoinGecko fallback for reliable real-time market data (stocks, ETFs, indices, forex, crypto).
- Added compaction UX: status strip shows animated COMPACTING indicator during context summarization, footer reflects compaction state, and CompactionCompleted events now include message count statistics.
- Added send flash: brief tinted background highlight on the last user message after sending.
- Added braille typing indicator with smooth 10-frame animation cycle.
### Changed
- Redesigned the footer status strip with mode/model/token/cost layout, quadrant separators, and a context-usage bar.
- Added Unicode prefix indicators (▸ You, ◆ Answer, ● System) to chat history cells for visual distinction.
- Improved thinking token delineation with labeled delimiters in transcript rendering.
- Refactored source code into workspace crates for better modularity and dependency management.
### Fixed
- Fixed Plan mode ESC key dismissing the prompt without clearing `plan_prompt_pending`, which prevented the prompt from reappearing on subsequent plan completions.
- Fixed clippy lint (collapsible_if) in web browsing session management.
## [0.3.30] - 2026-03-06
### Added
- Added a release-ready local npm smoke path that builds binaries, serves release assets locally, packs the wrapper, installs the tarball, and checks both entrypoints before publish.
- Added an opt-in full-matrix local release-asset fixture so `npm run release:check` can be exercised before GitHub release assets exist.
### Changed
- Bumped the Rust workspace crates and npm wrapper to `0.3.30`.
- Pointed the npm wrapper's default `deepseekBinaryVersion` at `0.3.30` for the next coordinated Rust + npm release.
- Updated the crates dry-run helper to work from a dirty workspace and to preflight dependent workspace crates without requiring unpublished versions to already exist on crates.io.
## [0.3.29] - 2026-03-03
### Added
- Added npm publish-time release asset verification for the `deepseek-tui` package to fail fast when expected GitHub binaries are missing.
- Added checksum manifests to GitHub release assets and checksum verification in the npm installer.
- Added `npm pack` install-and-smoke CI coverage for the `deepseek-tui` wrapper package.
- Added an end-to-end release runbook covering crates.io, GitHub Releases, and npm publication.
### Changed
- Updated npm package documentation for clearer install modes, environment overrides, and release integrity behavior.
- Improved installer support-matrix error messaging for unsupported platform/architecture combinations.
- Decoupled npm package version from default binary artifact version via `deepseekBinaryVersion`, enabling packaging-only npm releases.
- Moved the `deepseek-tui` binary target inside `crates/tui` so `cargo publish --dry-run -p deepseek-tui` works from the workspace package layout.
- Replaced the root-level crates publish workflow with an ordered workspace publish flow.
- Reworked first-run onboarding and README copy around primary workflows instead of shortcut memorization.
- Relaxed onboarding API-key format heuristics so unusual keys warn instead of blocking setup.
## [0.3.28] - 2026-03-02
### Added
- Converted the project to a modular Cargo workspace using a `crates/` layout.
- Added new crate boundaries mirroring a deepseek architecture (`agent`, `config`, `core`, `execpolicy`, `hooks`, `mcp`, `protocol`, `state`, `tools`, `tui-core`, `tui`, and `app-server`).
### Changed
- Added parity CI coverage with protocol/state/snapshot checks.
- Updated release workflow to build both `deepseek` and `deepseek-tui` binaries.
## [0.3.26] - 2026-03-02
### Fixed
- Resolved SSE stream corruption caused by byte/string position mismatch in streaming parse flow.
- Hardened base URL validation to reject non-HTTP/HTTPS schemes.
- Prevented multi-byte UTF-8 truncation panics in common-prefix and runtime thread summary paths.
- Corrected context usage alert thresholds by separating warning and critical trigger levels.
### Changed
- Removed non-code utility tools from the runtime tool registry (`calculator`, `weather`, `sports`, `finance`, `time`) and related wiring.
- Consolidated duplicate URL encoding helpers by delegating to shared `crate::utils::url_encode`.
- Replaced broad crate-level lint suppressions with targeted `#[allow(...)]` annotations where justified.
- Cleaned up dead APIs, unused struct fields, unused builder helpers, and non-integrated modules.
- Addressed clippy findings across the codebase (collapsible conditionals, defaults, indexing helpers, and API signature cleanup).
## [0.3.24] - 2026-02-25
### Fixed
- Preserve reasoning-only assistant turns for DeepSeek reasoning models (`deepseek-reasoner`, R-series markers) when rebuilding chat history.
- Align SSE tool streaming indices so each tool block start/delta/stop uses the same block index.
- Prevent transcript auto-scroll-to-bottom when a non-empty transcript selection is active.
- Allow session picker search mode to accept the current selection with a single `Enter` press.
- Preserve tool output whitespace/indentation while still wrapping long unbroken tokens.
- Make transcript selection copy/highlighting display-width aware (wide chars and tabs).
- Gate execpolicy behavior on the `exec_policy` feature flag across CLI/tool execution paths.
- Run doctor API connectivity checks using the effective loaded config/profile (instead of reloading defaults).
- Parse DeepSeek model context-window suffix hints such as `-32k` and `-256k`.
- Update README config docs with key environment overrides and a direct link to full configuration docs.
## [0.3.23] - 2026-02-24
### Changed
- Updated project copy to describe the app as a terminal-native TUI/CLI for DeepSeek models (not pinned to a specific model generation).
### Fixed
- Model selection and config validation now accept any valid `deepseek-*` model ID (including future releases), while still normalizing common aliases like `deepseek-v3.2` and `deepseek-r1`.
- Tool-call recovery now auto-loads deferred tools when the model requests them directly, instead of failing with manual `tool_search_*` instructions.
- YOLO mode now preloads tools by default (including deferred MCP tools), so model tool calls can run immediately without discovery indirection.
- Unknown tool-call failures now include discovery guidance and nearest tool-name suggestions instead of generic availability errors.
- Slash-command errors now suggest the closest known command (for example `/modle` -> `/model`) instead of only returning a generic unknown-command message.
## [0.3.22] - 2026-02-19
### Added
- Interactive `/config` editing modal for runtime settings updates.
### Changed
- Retired user-facing `/set` command path (no longer reachable/discoverable).
- Replaced `/deepseek` command behavior with `/links` (aliases: `dashboard`, `api`).
### Fixed
- Legacy `/set` and `/deepseek` inputs now return migration guidance instead of generic unknown-command errors.
## [0.3.21] - 2026-02-19
### Added
- Parallel tool execution in `multi_tool_use.parallel` for independent task workflows.
- Session resume-thread coverage in tests.
### Changed
- Desktop and web parity polish across the TUI and runtime surfaces.
- Onboarding and approval UX refinement from prior phase 3 iteration.
### Fixed
- Runtime pre-release startup issues and config-path edge cases.
- Clippy lint regressions introduced by the last parity pass.
### Security/Hardening
- General pre-release hardening for runtime app behavior.
## [0.3.17] - 2026-02-16
### Fixed
- Config loading now expands `~` in `DEEPSEEK_CONFIG_PATH` and `--config` paths.
- When `DEEPSEEK_CONFIG_PATH` points to a missing file, config loading now falls back to `~/.deepseek/config.toml` if it exists.
### Changed
- Removed committed transient runtime artifacts (`session_*.json`, `.deepseek/trusted`) and added ignore rules to prevent re-commit.
## [0.3.16] - 2026-02-15
### Added
- `deepseek models` CLI command to fetch and list models from the configured `/v1/models` endpoint (with `--json` output mode).
- `/models` slash command to fetch and display live model IDs in the TUI.
- Slash-command autocomplete hints in the composer plus `Tab` completion for `/` commands.
- Command palette modal (`Ctrl+K`) for quick insertion of slash commands and skills.
- Persistent right sidebar in wide terminals showing live plan/todo/sub-agent state.
- Expandable tool payload views (`v` in transcript, `v` in approval modal) for full params/output inspection.
- Runtime HTTP/SSE API (`deepseek serve --http`) with durable thread/turn/item lifecycle, interrupt/steer, and replayable event timeline.
- Background task queue (`/task add|list|show|cancel` and `POST /v1/tasks`) with persistent storage, bounded worker pool, and timeline/artifact tracking.
### Changed
- Centralized the default text model (`DEFAULT_TEXT_MODEL`) and shared common model list to reduce drift across runtime/config paths.
- `/model` now clarifies that any valid DeepSeek model ID is accepted (including future releases), while still showing common model IDs.
### Fixed
- Expanded reasoning-model detection for chat history reconstruction (supports R-series and reasoner-style naming without hardcoding single versions).
- Aligned docs/config examples with the then-current runtime default model.
## [0.3.14] - 2026-02-05
### Added
- `web.run` now supports `image_query` (DuckDuckGo image search)
- `multi_tool_use.parallel` now supports safe MCP meta tools (`list_mcp_resources`, `mcp_read_resource`, etc.)
### Fixed
- Encode tool-call function names when rebuilding Chat Completions history (keeps dotted tool names API-safe)
### Changed
- Prompts: stronger `web.run` citation placement and quote-limit guidance
## [0.3.13] - 2026-02-04
### Fixed
- Restore an in-app scrollbar for the transcript view
## [0.3.12] - 2026-02-04
### Fixed
- Map dotted tool names to API-safe identifiers for DeepSeek tool calls
- Encode any invalid tool names for API tool lists while preserving internal names
## [0.3.11] - 2026-02-04
### Fixed
- Fix tool name mapping for DeepSeek API
## [0.3.10] - 2026-02-04
### Fixed
- Always enable mouse wheel scrolling in the TUI (even without alt screen)
## [0.3.9] - 2026-02-04
### Removed
- RLM mode, tools, and documentation pending a faithful implementation of the MIT RLM design
- Duo mode tools and prompts pending a citable research spec
### Fixed
- Footer context usage bar remains visible while status toasts are shown
### Changed
- Updated prompts and docs to reflect the simplified mode/tool surface
## [0.3.8] - 2026-02-03
### Fixed
- Resolve clippy warnings (CI `-D warnings`) in new tool implementations
## [0.3.7] - 2026-02-03
### Added
- Tooling parity updates: `weather`, `finance`, `sports`, `time`, `calculator`, `request_user_input`, `multi_tool_use.parallel`, `web.run`
- Shell streaming helpers: `exec_shell_wait` and `exec_shell_interact`
- Sub-agent controls: `send_input` and `wait` (with aliases)
- MCP resource helpers: `list_mcp_resources`, `list_mcp_resource_templates`, and `read_mcp_resource` alias
### Changed
- Skills directory selection now prefers workspace `.agents/skills`, then `./skills`, then global
- Docs and prompts updated to reflect new tool surface and parity notes
## [0.3.6] - 2026-02-02
### Added
- New welcome banner on startup showing "Welcome to DeepSeek TUI!" with directory, session ID, and model info
- Visual context progress bar in footer showing usage with block characters [████░░░░░░] and percentage
### Changed
- Removed custom block-character scrollbar from chat area - now uses terminal's native scroll
- Simplified header bar: removed context percentage indicator (moved to footer as progress bar)
## [0.3.5] - 2026-01-30
### Added
- Intelligent context offloading: large tool results (>15k chars) are automatically moved to RLM memory to preserve the context window
- Persistent history context: compacted messages are offloaded to RLM `history` variable for recall
- Full MCP protocol support: SSE transport, Resources (`resources/list`, `resources/read`), and Prompts (`prompts/list`, `prompts/get`)
- `mcp_read_resource` and `mcp_get_prompt` virtual tools exposed to the model
- Dialectical Duo mode with specialized TUI rendering (`Player` / `Coach` history cells)
- Dynamic system prompt refreshing at each turn for up-to-date RLM/Duo/working-set context
- `project_map` tool for automatic codebase structure discovery
- `delegate_to_agent` alias for streamlined sub-agent delegation
### Changed
- Default theme changed to 'Whale' with updated color palette
- `with_agent_tools` now includes `project_map`, `test_runner`, and conditionally RLM tools for all agent modes
- MCP `McpServerConfig.command` is now `Option<String>` to support URL-only (SSE) servers
### Fixed
- MCP test compilation errors for updated `McpServerConfig` struct shape
## [0.3.4] - 2026-01-29
### Changed
- Updated Cargo.lock dependencies
### Fixed
- Compaction tool-call pairing: enforce bidirectional tool-call/tool-result integrity with fixpoint convergence
- Safety net scanning to drop orphan tool results in the request builder
- Double-dispatch race in parallel tool execution
## [0.3.3] - 2026-01-28
### Added
- TUI polish: Kimi-style footer with mode/model/token display
- Streaming thinking blocks with dedicated rendering
- Loading animation improvements
## [0.3.2] - 2026-01-28
### Fixed
- Preserve tool-call + tool-result pairing during compaction to avoid invalid tool message sequences
- Drop orphan tool results in request builder as a safety net to prevent API 400s
## [0.3.1] - 2026-01-27
### Added
- `deepseek setup` to bootstrap MCP config and skills directories
- `deepseek mcp init` to generate a template `mcp.json` at the configured path
### Changed
- `deepseek doctor` now follows the resolved config path and config-derived MCP/skills locations
### Fixed
- Doctor no longer reports missing MCP/skills when paths are overridden via config or env
## [0.3.0] - 2026-01-27
### Added
- Repo-aware working set tracking with prompt injection for active paths
- Working set signals now pin relevant messages during auto-compaction
- Offline eval harness (`deepseek eval`) with CI coverage in the test job
- Shell tool now emits stdout/stderr summaries and truncation metadata
- Dependency-aware `agent_swarm` tool for orchestrating multiple sub-agents
- Expanded sub-agent tool access (apply_patch, web_search, file_search)
### Changed
- Auto-compaction now accounts for pinned budget and preserves working-set context
- Apply patch tool validates patch shape, reports per-file summaries, and improves hunk mismatch diagnostics
- Eval harness shell step now uses a Windows-safe default command
- Increased `max_subagents` clamp to `1..=20`
## [0.2.2] - 2026-01-22
### Fixed
- Session save no longer panics on serialization errors
- Web search regex patterns are now cached for better performance
- Improved panic messages for regex compilation failures
## [0.2.1] - 2026-01-22
### Fixed
- Resolve clippy warnings for Rust 1.92
## [0.2.0] - 2026-01-20
### Changed
- Removed npm package distribution; now Cargo-only
- Clean up for public release
### Fixed
- Disabled automatic RLM mode switching; use /rlm or /aleph to enter RLM mode
- Fixed cargo fmt formatting issues
## [0.0.2] - 2026-01-20
### Fixed
- Disabled automatic RLM mode switching; use /rlm or /aleph to enter RLM mode.
## [0.0.1] - 2026-01-19
### Added
- DeepSeek Responses API client with chat-completions fallback
- CLI parity commands: login/logout, exec, review, apply, mcp, sandbox
- Resume/fork session workflows with picker fallback
- DeepSeek blue branding refresh + whale indicator
- Responses API proxy subcommand for key-isolated forwarding
- Execpolicy check tooling and feature flag CLI
- Agentic exec mode (`deepseek exec --auto`) with auto-approvals
### Changed
- Removed multimedia tooling and aligned prompts/docs for text-only DeepSeek API
## [0.1.9] - 2026-01-17
### Added
- API connectivity test in `deepseek doctor` command
- Helpful error diagnostics for common API failures (invalid key, timeout, network issues)
## [0.1.8] - 2026-01-16
### Added
- Renderable widget abstraction and modal view stack for TUI composition
- Parallel tool execution with lock-aware scheduling
- Interactive shell mode with terminal pause/resume handling
### Changed
- Tool approval requirements moved into tool specs
- Tool results are recorded in original request order
## [0.1.7] - 2026-01-15
### Added
- Duo mode (player-coach autocoding workflow)
- Character-level transcript selection
### Fixed
- Approval flow tool use ID routing
- Cursor position sync for transcript selection
## [0.1.6] - 2026-01-14
### Added
- Auto-RLM for large pasted blocks with context auto-load
- `chunk_auto` and `rlm_query` `auto_chunks` for quick document sweeps
- RLM usage badge with budget warnings in the footer
### Changed
- Auto-RLM now honors explicit RLM file requests even for smaller files
## [0.1.5] - 2026-01-14
### Added
- RLM prompt with external-context guidance and REPL tooling
- RLM tools for context loading, execution, status, and sub-queries (rlm_load, rlm_exec, rlm_status, rlm_query)
- RLM query usage tracking and variable buffers
- Workspace-relative `@path` support for RLM loads
- Auto-switch to RLM when users request large file analysis (or the largest file)
### Changed
- Removed Edit mode; RLM chat is default with /repl toggle
## [0.1.0] - 2026-01-12
### Added
- Initial alpha release of DeepSeek TUI
- Interactive TUI chat interface
- DeepSeek API integration (OpenAI-compatible Responses API)
- Tool execution (shell, file ops)
- MCP (Model Context Protocol) support
- Session management with history
- Skills/plugin system
- Cost tracking and estimation
- Hooks system and config profiles
- Example skills and launch assets
[Unreleased]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.8.0...HEAD
[0.8.0]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.7.9...v0.8.0
[0.7.9]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.7.8...v0.7.9
[0.7.8]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.7.7...v0.7.8
[0.7.7]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.7.6...v0.7.7
[0.7.6]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.7.5...v0.7.6
[0.6.1]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.6.0...v0.6.1
[0.6.0]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.4.9...v0.6.0
[0.4.9]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.4.8...v0.4.9
[0.4.8]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.3.33...v0.4.8
[0.3.33]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.3.32...v0.3.33
[0.3.32]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.3.31...v0.3.32
[0.3.31]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.3.28...v0.3.31
[0.3.28]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.3.27...v0.3.28
[0.3.23]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.3.22...v0.3.23
[0.3.22]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.3.21...v0.3.22
[0.3.21]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.3.17...v0.3.21
[0.3.17]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.3.16...v0.3.17
[0.3.16]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.3.14...v0.3.16
[0.3.14]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.3.13...v0.3.14
[0.3.13]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.3.12...v0.3.13
[0.3.12]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.3.11...v0.3.12
[0.3.11]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.3.10...v0.3.11
[0.3.10]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.3.6...v0.3.10
[0.3.6]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.3.5...v0.3.6
[0.3.5]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.3.4...v0.3.5
[0.3.4]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.3.3...v0.3.4
[0.3.3]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.3.2...v0.3.3
[0.3.2]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.3.1...v0.3.2
[0.3.1]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.3.0...v0.3.1
[0.3.0]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.2.2...v0.3.0
[0.2.2]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.2.0...v0.2.2
[0.2.0]: https://github.com/Hmbown/DeepSeek-TUI/releases/tag/v0.2.0
[0.0.2]: https://github.com/Hmbown/DeepSeek-TUI/releases/tag/v0.0.2
[0.0.1]: https://github.com/Hmbown/DeepSeek-TUI/releases/tag/v0.0.1
[0.1.9]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.1.8...v0.1.9
[0.1.8]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.1.7...v0.1.8
[0.1.7]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.1.6...v0.1.7
[0.1.6]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.1.5...v0.1.6
[0.1.5]: https://github.com/Hmbown/DeepSeek-TUI/compare/v0.1.0...v0.1.5
[0.1.0]: https://github.com/Hmbown/DeepSeek-TUI/releases/tag/v0.1.0