Adds first-class keyring management on the dispatcher CLI and wires
the TUI to read its DeepSeek key through the same Secrets façade.
Subcommands:
* `auth set --provider <name>` writes to the OS keyring; prompts
on stdin without echo, never prints the key, never touches
`config.toml`. Supports `--api-key` and `--api-key-stdin`.
* `auth get --provider <name>` reports `set` / `not set` plus the
resolving layer (keyring / env / config-file). Never prints the
value.
* `auth clear --provider <name>` deletes from keyring and from any
legacy plaintext slot in `config.toml` for parity.
* `auth list` table of all known providers and
whether each layer holds a key. Non-revealing.
* `auth migrate [--dry-run]` reads `api_key` (root + per-provider
blocks) from `config.toml`, writes them to the keyring, then
strips the entries from disk. Idempotent.
* `auth status` expanded to also report the active
keyring backend and per-provider keyring state.
`doctor` now prints `keyring backend: ...` plus per-provider
`keyring=yes/no, env=yes/no` lines and points users at
`deepseek auth set` when no key resolves.
`Config::deepseek_api_key()` in the TUI is rewritten to consult
`Secrets::auto_detect()` first (keyring -> env), then fall back to
the existing TOML slots with a deprecation warning. Error messages
now lead with `deepseek auth set --provider <name>`.
5 new unit tests cover argument parsing for the new subcommands and
end-to-end auth set/clear/migrate behaviour against an
`InMemoryKeyringStore`, verifying that no plaintext key ever lands
in `config.toml`.
Verified manually on macOS:
$ deepseek auth set --provider deepseek --api-key-stdin
$ security find-generic-password -s deepseek -a deepseek
# entry present
$ deepseek auth migrate
# api_key lines stripped from ~/.deepseek/config.toml
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Implement `deepseek metrics` as a dispatcher-handled subcommand (no TUI
binary roundtrip) that reads ~/.deepseek/audit.log, session JSON files,
and tasks runtime JSONL event streams, then prints a human-readable
usage rollup aggregated by tool name, compaction events, sub-agent
spawns, and capacity-controller interventions.
Flags: --json (machine-readable) and --since DURATION (e.g. 7d, 24h,
30m, now-2h, 2h30m). Empty/missing audit log exits 0 with an empty
rollup; malformed lines are skipped silently via tracing::trace!.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a structured rlm_query tool for parallel/batched LLM fan-out.
The model calls it with one prompt or up to 16 concurrent prompts;
children dispatch via tokio::join_all against the existing DeepSeek
client. Default child model is deepseek-v4-flash; override per-call
via the model field. Available in Plan / Agent / YOLO. Cost folds
into the session's running total automatically.
Fixes scroll-stuck regression (#56): TranscriptScroll::resolve_top
and scrolled_by now use a three-level fallback chain (same line →
same cell line 0 → nearest cell at-or-before) instead of teleporting
to ToBottom when an anchor cell vanishes.
Loosens command-safety chains (#57): cargo build && cargo test and
similar chains of known-safe commands now escalate to RequiresApproval
instead of being hard-blocked as Dangerous. Chains containing unknown
commands still block.
Suppresses the GettingCrowded footer chip — context-percent header
already covers conversation pressure.
Refactors:
- Extracts file_mention parsing/completion/expansion (~450 LOC) from
the 5,500-line ui.rs into crates/tui/src/tui/file_mention.rs.
- Deletes truly unused helpers (write_bytes, timestamped_filename,
extension_from_url, output_path, has_project_doc, primary_doc_path).
Tests: 853 pass. cargo clippy --workspace -D warnings clean.
cargo fmt --all -- --check clean.
Closes#46#47#48#49#50#53#54#55#56#57#58.
### Fixed
- DeepSeek thinking-mode tool-call rounds now always replay reasoning_content
in all subsequent requests (including across new user turns), matching the
documented API contract that assistant tool-call messages must retain their
reasoning content forever. Previously, reasoning_content was cleared after
the current user turn completed, which could cause HTTP 400 errors.
- 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 rejections.
- Session checkpoint now persists a Thinking-block placeholder for tool-call
turns that produced no streamed reasoning text, keeping on-disk sessions
structurally correct for subsequent requests.
- 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.
### Changed
- Internal crate dependency pins bumped 0.4.5 → 0.4.9 to match workspace.
- npm wrapper version and deepseekBinaryVersion bumped to 0.4.9.
- README fully rewritten: clearer feature highlights, V4 model focus,
keyboard shortcut table, improved docs index, and more engaging layout.
- CHANGELOG entry for 0.4.9 with comparison URLs.
Adds first-class DeepSeek V4 Pro and Flash support, updates the default model to deepseek-v4-pro, aligns legacy aliases with the current V4 1M context behavior, and fixes thinking-mode request handling.
Key fixes:
- Send DeepSeek's raw Chat Completions `thinking` parameter at the top level instead of SDK-only `extra_body`.
- Preserve assistant `reasoning_content` for all prior thinking-mode tool-call turns so subsequent requests satisfy DeepSeek V4's replay requirement.
- Fix npm wrapper concurrent first-run downloads by using per-process temporary download paths.
- Add `.mailmap` so historical bot-attributed commits aggregate under Hunter Bown where mailmap is honored.
Verified with the full local Rust gate, live DeepSeek V4 smoke, npm wrapper temp-install smoke, and green PR CI across Linux, macOS, and Windows.
- Move src/* into crates/tui/src/ to create a proper workspace structure
- Add .claude/ and .trimtab/ directories for Trimtab closed-loop workflow
- Add DEPENDENCY_GRAPH.md and update documentation
- Update Cargo.toml files to reflect new crate dependencies
- Update CI workflows and npm package scripts
- All tests pass, release build works
- Convert root to Cargo workspace with crates/ layout
- Add deepseek-* crates mirroring Codex architecture
- Add parity CI workflow with snapshot/protocol/state tests
- Update release workflow to build both deepseek and deepseek-tui binaries
- Bump version to 0.3.28