Simplify UI and improve footer display (v0.3.14) (#2)

* Polish UI, fix bugs, and rewrite README for clarity

- Fix welcome banner generating a fake session ID (random UUID that
  didn't match the actual session); now shows tips and omits the
  misleading session line
- Fix footer redundancy: mode and model were shown in both the header
  and footer; footer now shows session ID, token count, and help hint
- Fix STATUS_SUCCESS and STATUS_WARNING being the same color
  (both DEEPSEEK_SKY), making success/warning states indistinguishable;
  success is now green, warning is amber
- Remove unprofessional thinking tagline ("You're absolutely right!
  ... maybe."); replaced with professional labels
- Fix README mode cycle documentation (said Normal->Plan->Agent->YOLO
  but code actually cycles Plan->Agent->YOLO->Plan)
- Fix README tool miscategorization: web.run, web_search,
  request_user_input, and multi_tool_use.parallel were listed under
  "File Operations" instead of their own categories
- Rewrite README with numbered getting-started steps, keyboard
  shortcuts table, cleaner tool categories, environment variable table,
  and compact troubleshooting table
- Remove unused imports (chrono::Local, uuid::Uuid, Color, Modifier)
  and dead code (mode_color, mode_badge_style)

https://claude.ai/code/session_011XiGZRhainhyvZ8BKKrfzj

* Update src/tui/app.rs
* Update README.md
This commit is contained in:
Hunter Bown
2026-02-05 13:29:38 -06:00
parent 702f9c353c
commit 4e516a7c1f
5 changed files with 188 additions and 279 deletions
Generated
+1 -1
View File
@@ -674,7 +674,7 @@ dependencies = [
[[package]]
name = "deepseek-tui"
version = "0.3.13"
version = "0.3.14"
dependencies = [
"anyhow",
"arboard",
+145 -205
View File
@@ -1,274 +1,214 @@
# DeepSeek CLI 🤖
# DeepSeek CLI
Your AI-powered terminal companion for DeepSeek models
An unofficial terminal UI and CLI for the [DeepSeek platform](https://platform.deepseek.com).
[![CI](https://github.com/Hmbown/DeepSeek-TUI/actions/workflows/ci.yml/badge.svg)](https://github.com/Hmbown/DeepSeek-TUI/actions/workflows/ci.yml)
[![crates.io](https://img.shields.io/crates/v/deepseek-tui)](https://crates.io/crates/deepseek-tui)
Unofficial terminal UI (TUI) + CLI for the [DeepSeek platform](https://platform.deepseek.com) — chat with DeepSeek models and collaborate with AI assistants that can read, write, execute, and plan with approval-gated tool access.
Chat with DeepSeek models directly from your terminal. The assistant can read and write files, run shell commands, search the web, manage tasks, and coordinate sub-agents — all with configurable approval gating.
**Not affiliated with DeepSeek Inc.**
## ✨ Features
## Getting Started
- **Interactive TUI** with multiple modes (Normal, Plan, Agent, YOLO)
- **Comprehensive tool access** File operations, shell execution, task management, and sub-agent systems
- **File operations**: List directories, read/write/edit files, apply patches, search files with regex
- **Shell execution**: Run commands with timeout support, background execution with task management
- **Task management**: Todo lists, implementation plans, persistent notes
- **Sub-agent system**: Spawn, coordinate, and cancel background agents (including swarms)
- **User input prompts**: Ask structured, multiple-choice questions during tool flows
- **Web browsing**: `web.run` search/open/click/find/screenshot/image_query with citation-ready sources
- **Structured data tools**: weather, finance, sports, time, calculator
- **Multimodel support** DeepSeekReasoner, DeepSeekChat, and other DeepSeek models
- **Contextaware** loads projectspecific instructions from `AGENTS.md`
- **Session management** resume, fork, and search past conversations
- **Skills system** reusable workflows stored as `SKILL.md` directories
- **Model Context Protocol (MCP)** integrate external tool servers
- **Sandboxed execution** (macOS) for safe shell commands
- **Git integration** code review, patch application, diff analysis
- **Crossplatform** works on macOS, Linux, and Windows
### 1. Install
## 🚀 Quick Start
1. **Get an API key** from [https://platform.deepseek.com](https://platform.deepseek.com)
2. **Install and run**:
Choose one of:
```bash
# Install via Cargo
# From crates.io (requires Rust 1.85+)
cargo install deepseek-tui --locked
# Set your API key
export DEEPSEEK_API_KEY="YOUR_DEEPSEEK_API_KEY"
# Bootstrap MCP + skills templates (recommended)
deepseek setup
# Start chatting
deepseek
```
3. Press `F1` or type `/help` for the inapp command list.
If anything looks off, run `deepseek doctor` to diagnose configuration issues.
## 📦 Installation
### From crates.io
```bash
cargo install deepseek-tui --locked
```
### Build from source
```bash
# Or build from source
git clone https://github.com/Hmbown/DeepSeek-TUI.git
cd DeepSeek-TUI
cargo build --release
./target/release/deepseek --help
# binary is at ./target/release/deepseek
```
### Direct download
Prebuilt binaries are also available on [GitHub Releases](https://github.com/Hmbown/DeepSeek-TUI/releases).
Download a prebuilt binary from [GitHub Releases](https://github.com/Hmbown/DeepSeek-TUI/releases) and put it on your `PATH` as `deepseek`.
### 2. Set your API key
## ⚙️ Configuration
Get a key from [platform.deepseek.com](https://platform.deepseek.com), then:
On first run, the TUI can prompt for your API key and save it to `~/.deepseek/config.toml`. You can also create the file manually:
```toml
# ~/.deepseek/config.toml
api_key = "YOUR_DEEPSEEK_API_KEY" # must be nonempty
default_text_model = "deepseek-reasoner" # optional
allow_shell = false # optional
max_subagents = 3 # optional (120)
```bash
export DEEPSEEK_API_KEY="sk-..."
```
Useful environment variables:
Alternatively, run `deepseek` and the onboarding wizard will prompt you to enter and save the key.
- `DEEPSEEK_API_KEY` (overrides `api_key`)
- `DEEPSEEK_BASE_URL` (default: `https://api.deepseek.com`; China users may use `https://api.deepseeki.com`)
- `DEEPSEEK_PROFILE` (selects `[profiles.<name>]` from the config; errors if missing)
- `DEEPSEEK_CONFIG_PATH` (override config path)
- `DEEPSEEK_MCP_CONFIG`, `DEEPSEEK_SKILLS_DIR`, `DEEPSEEK_NOTES_PATH`, `DEEPSEEK_MEMORY_PATH`, `DEEPSEEK_ALLOW_SHELL`, `DEEPSEEK_MAX_SUBAGENTS`
To bootstrap MCP and skills at their resolved locations, run `deepseek setup`. To
only create an MCP template, run `deepseek mcp init`.
See `config.example.toml` and `docs/CONFIGURATION.md` for a full reference.
## 🎮 Modes
In the TUI, press `Tab` to cycle modes: **Normal → Plan → Agent → YOLO → Normal**.
| Mode | Description | Approval Behavior |
|------|-------------|-------------------|
| **Normal** | Chat; asks before file writes or shell | Manual approval for writes & shell |
| **Plan** | Designfirst prompting; same approvals as Normal | Manual approval for writes & shell |
| **Agent** | Multistep tool use; asks before shell | Manual approval for shell, autoapprove file writes |
| **YOLO** | Enables shell + trust + autoapproves all tools (dangerous) | Autoapprove all tools |
Approval behavior is modedependent, but you can also override it at runtime with `/set approval_mode auto|suggest|never`.
## 🛠️ Tools
DeepSeek CLI exposes a comprehensive set of tools to the model across 5 categories, with 16+ individual tools available, all with approval gating based on the current mode.
### Tool Categories
#### File Operations
- **`list_dir`** List directory contents with file/directory metadata
- **`read_file`** Read UTF8 files from the workspace
- **`write_file`** Create or overwrite files
- **`edit_file`** Search and replace text in files
- **`apply_patch`** Apply unified diff patches with fuzzy matching
- **`grep_files`** Search files by regex pattern with context lines
- **`web.run`** Browse the web (search/open/click/find/screenshot/image_query) with ref_ids for citations
- **`web_search`** Quick web search (fallback when citations are not needed)
- **`request_user_input`** Ask the user short multiple-choice questions
- **`multi_tool_use.parallel`** Execute multiple read-only tools in parallel
#### Structured Data
- **`weather`** Daily weather forecast for a location
- **`finance`** Latest price for a stock, fund, index, or cryptocurrency
- **`sports`** Schedules or standings for a league
- **`time`** Current time for a UTC offset
- **`calculator`** Evaluate arithmetic expressions
#### Shell Execution
- **`exec_shell`** Run shell commands with timeout support
- **Background execution** Run commands in background with task ID return
#### Task Management
- **`todo_write`** Create and update todo lists with status tracking
- **`update_plan`** Manage structured implementation plans
- **`note`** Append persistent notes across sessions
#### SubAgents
- **`agent_spawn`** Create background subagents for focused tasks
- **`agent_swarm`** Launch a dependencyaware swarm of subagents
- **`agent_result`** Retrieve results from subagents
- **`agent_list`** List all active and completed agents
- **`agent_cancel`** Cancel running subagents
### System Behavior
- **Workspace boundary**: File tools are restricted to `--workspace` unless you enable `/trust` (YOLO enables trust automatically).
- **Approvals**: The TUI requests approval depending on mode and tool category (file writes, shell).
- **Web browsing**: `web.run` uses DuckDuckGo HTML results and is autoapproved.
- **Web search**: `web_search` is a quick fallback when citations are not needed.
- **Skills**: Reusable workflows stored as `SKILL.md` directories. The resolved skills dir prefers workspace-local `.agents/skills`, then `./skills`, then `~/.deepseek/skills`. Use `/skills` and `/skill <name>`. Bootstrap with `deepseek setup --skills` (add `--local` for `./skills`).
- **MCP**: Load external tool servers via `~/.deepseek/mcp.json` (supports `servers` and `mcpServers`). MCP tools currently execute without TUI approval prompts, so only enable servers you trust. See `docs/MCP.md`.
## 📚 Examples
### Interactive chat
### 3. Run
```bash
deepseek
```
### Oneshot prompt (noninteractive)
On first launch the TUI opens in **Agent** mode. Press **Tab** to switch modes, **F1** or type `/help` to see all commands, and **Esc** to cancel a running request.
### 4. Optional setup
```bash
deepseek -p "Write a haiku about Rust"
# Bootstrap MCP server config and skills templates
deepseek setup
# Verify your environment
deepseek doctor
```
### Agentic execution with tool access
## Keyboard Shortcuts
```bash
deepseek exec --auto "Fix lint errors in the current directory"
| Key | Action |
|-----|--------|
| `Enter` | Send message |
| `Alt+Enter` / `Ctrl+J` | Insert newline |
| `Tab` | Cycle modes (Plan / Agent / YOLO) |
| `Esc` | Cancel request / clear input |
| `Ctrl+C` | Cancel request or exit |
| `Ctrl+R` | Search past sessions |
| `F1` or `Ctrl+/` | Toggle help overlay |
| `PageUp` / `PageDown` | Scroll transcript |
| `Alt+Up` / `Alt+Down` | Scroll transcript (small) |
| `l` (empty input) | Open last message in pager |
## Modes
Press `Tab` to cycle modes: **Plan -> Agent -> YOLO -> Plan**.
| Mode | Description | Approvals |
|------|-------------|-----------|
| **Plan** | Design-first prompting; produces a plan before implementing | Manual for writes and shell |
| **Agent** | Multi-step autonomous tool use | Auto-approve file writes, manual for shell |
| **YOLO** | Full auto-approve (use with caution) | All tools auto-approved |
Normal mode is also available (chat-only with manual approval for everything) and can be selected via `Esc` from Agent mode or `/set mode normal`.
Override approval behavior at runtime: `/set approval_mode auto|suggest|never`.
## Tools
The model has access to 25+ tools across these categories:
### File Operations
- `list_dir` / `read_file` / `write_file` / `edit_file` — basic file I/O within the workspace
- `apply_patch` — apply unified diffs with fuzzy matching
- `grep_files` / `file_search` — search files by regex or name
### Shell Execution
- `exec_shell` — run commands with timeout support and background execution
- `exec_shell_wait` / `exec_shell_interact` — wait on or send input to running commands
### Web
- `web.run` — multi-command browser (search / open / click / find / screenshot / image_query) with citation support
- `web_search` — quick DuckDuckGo search when citations are not needed
### Task Management
- `todo_write` — create and track task lists with status
- `update_plan` — structured implementation plans
- `note` — persistent cross-session notes
### Sub-Agents
- `agent_spawn` / `agent_swarm` — launch background agents or dependency-aware swarms
- `agent_result` / `agent_list` / `agent_cancel` — manage running agents
### Structured Data
- `weather` / `finance` / `sports` / `time` / `calculator`
### Interaction
- `request_user_input` — ask the user structured or multiple-choice questions
- `multi_tool_use.parallel` — execute multiple read-only tools in parallel
All file tools respect the `--workspace` boundary unless `/trust` is enabled (YOLO enables trust automatically). MCP tools execute without TUI approval prompts, so only enable servers you trust.
## Configuration
The TUI stores its config at `~/.deepseek/config.toml`:
```toml
api_key = "sk-..."
default_text_model = "deepseek-reasoner" # optional
allow_shell = false # optional
max_subagents = 3 # optional (1-20)
```
### Resume latest session
### Environment Variables
| Variable | Purpose |
|----------|---------|
| `DEEPSEEK_API_KEY` | API key (overrides config file) |
| `DEEPSEEK_BASE_URL` | API endpoint (default: `https://api.deepseek.com`) |
| `DEEPSEEK_PROFILE` | Select a `[profiles.<name>]` section from config |
| `DEEPSEEK_CONFIG_PATH` | Override config file location |
Additional overrides: `DEEPSEEK_MCP_CONFIG`, `DEEPSEEK_SKILLS_DIR`, `DEEPSEEK_NOTES_PATH`, `DEEPSEEK_MEMORY_PATH`, `DEEPSEEK_ALLOW_SHELL`, `DEEPSEEK_MAX_SUBAGENTS`.
See `config.example.toml` and `docs/CONFIGURATION.md` for the full reference.
## Examples
```bash
# Interactive chat (default)
deepseek
# One-shot prompt (non-interactive, prints and exits)
deepseek -p "Explain the borrow checker in two sentences"
# Agentic execution with auto-approve
deepseek exec --auto "Fix all clippy warnings in this project"
# Resume latest session
deepseek --continue
```
### Work on a specific project
```bash
# Work on a specific project directory
deepseek --workspace /path/to/project
```
### Review staged git changes
```bash
# Review staged git changes
deepseek review --staged
```
### Apply a patch file
```bash
deepseek apply patch.diff
```
### List saved sessions
```bash
# List saved sessions
deepseek sessions --limit 50
```
### Generate shell completions
```bash
# Shell completions
deepseek completions zsh > _deepseek
deepseek completions bash > deepseek.bash
deepseek completions fish > deepseek.fish
```
## 🔧 Troubleshooting
## Troubleshooting
### No API key
Set `DEEPSEEK_API_KEY` environment variable or run `deepseek` and complete onboarding.
| Problem | Fix |
|---------|-----|
| No API key | Set `DEEPSEEK_API_KEY` or run `deepseek` to complete onboarding |
| Config not found | Check `~/.deepseek/config.toml` (or `DEEPSEEK_CONFIG_PATH`) |
| Wrong region | Set `DEEPSEEK_BASE_URL` to `https://api.deepseeki.com` (China) |
| Session issues | Run `deepseek sessions` then `deepseek --resume latest` |
| Skills missing | Run `deepseek setup --skills` (add `--local` for workspace-local) |
| MCP tools missing | Run `deepseek mcp init`, then restart |
| Sandbox errors (macOS) | Run `deepseek doctor` to confirm sandbox availability |
### Config not found
Check `~/.deepseek/config.toml` (or `DEEPSEEK_CONFIG_PATH`).
## Documentation
### Wrong region / base URL
Set `DEEPSEEK_BASE_URL` to `https://api.deepseeki.com` (China).
- [Configuration Reference](docs/CONFIGURATION.md)
- [Architecture](docs/ARCHITECTURE.md)
- [Mode Comparison](docs/MODES.md)
- [MCP Integration](docs/MCP.md)
- [Contributing](CONTRIBUTING.md)
### Session issues
Run `deepseek sessions` and try `deepseek --resume latest`.
### Skills missing
Run `deepseek setup --skills` to create a global skills directory, or add `--local`
to create `./skills` for the current workspace. If you want the preferred
workspace-local path, create `.agents/skills` manually. Then run `deepseek doctor`
to see which skills directory is selected.
### MCP tools missing
Run `deepseek mcp init` (or `deepseek setup --mcp`), then restart. `deepseek doctor`
now checks the MCP path resolved from your config/env overrides.
### Sandbox errors (macOS)
Run `deepseek doctor` to confirm sandbox availability. On macOS, ensure
`/usr/bin/sandbox-exec` exists. For other platforms, sandboxing is limited.
## 📖 Documentation
- `docs/CONFIGURATION.md` Complete configuration reference
- `docs/MCP.md` Model Context Protocol guide
- `docs/ARCHITECTURE.md` Project architecture
- `docs/MODES.md` Mode comparison and usage
- `CONTRIBUTING.md` How to contribute to the project
## 🧪 Development
## Development
```bash
cargo build
cargo test
cargo fmt
cargo clippy
cargo fmt
```
See `CONTRIBUTING.md` for detailed guidelines.
See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines.
## 📄 License
## License
MIT
---
DeepSeek is a trademark of DeepSeek Inc. This is an unofficial project.
DeepSeek is a trademark of DeepSeek Inc. This is an unofficial, community-driven project.
+2 -2
View File
@@ -45,8 +45,8 @@ pub const TEXT_PRIMARY: Color = Color::White;
pub const TEXT_MUTED: Color = Color::DarkGray;
pub const TEXT_DIM: Color = Color::Gray;
pub const STATUS_SUCCESS: Color = DEEPSEEK_SKY;
pub const STATUS_WARNING: Color = DEEPSEEK_SKY;
pub const STATUS_SUCCESS: Color = Color::Rgb(80, 200, 120); // Green
pub const STATUS_WARNING: Color = Color::Rgb(255, 170, 60); // Amber
pub const STATUS_ERROR: Color = DEEPSEEK_RED;
#[allow(dead_code)]
pub const STATUS_INFO: Color = DEEPSEEK_BLUE;
+11 -18
View File
@@ -25,25 +25,22 @@ use crate::tui::scrolling::{MouseScrollState, TranscriptScroll};
use crate::tui::selection::TranscriptSelection;
use crate::tui::transcript::TranscriptViewCache;
use crate::tui::views::ViewStack;
use uuid::Uuid;
/// Format a nice welcome banner similar to Kimi CLI.
fn format_welcome_banner(model: &str, workspace: &PathBuf, session_id: &str, yolo: bool) -> String {
/// Format a nice welcome banner.
fn format_welcome_banner(model: &str, workspace: &PathBuf, yolo: bool) -> String {
let mode_line = if yolo {
"\n\n🚀 YOLO mode — shell + trust + auto-approve enabled"
"\nYOLO mode — shell + trust + auto-approve enabled\n"
} else {
""
};
format!(
r#"Welcome to DeepSeek TUI!
Send /help for help information.{mode_line}
Directory: {}
Session: {}
Model: {}"#,
"Tips: Tab to switch modes, F1 or /help for commands, Esc to cancel\n\
{mode_line}\
Directory: {}\n\
Model: {}",
workspace.display(),
&session_id[..8],
model
)
}
@@ -364,10 +361,8 @@ impl App {
let history = if needs_onboarding {
Vec::new() // No welcome message during onboarding
} else {
// Generate a session ID for welcome display
let session_id = Uuid::new_v4().to_string();
vec![HistoryCell::System {
content: format_welcome_banner(&model, &workspace, &session_id, yolo),
content: format_welcome_banner(&model, &workspace, yolo),
}]
};
@@ -500,10 +495,8 @@ impl App {
if let Err(err) = crate::tui::onboarding::mark_onboarded() {
self.status_message = Some(format!("Failed to mark onboarding: {err}"));
}
// Generate a session ID for welcome display
let session_id = Uuid::new_v4().to_string();
self.add_message(HistoryCell::System {
content: format_welcome_banner(&self.model, &self.workspace, &session_id, self.yolo),
content: format_welcome_banner(&self.model, &self.workspace, self.yolo),
});
}
@@ -533,7 +526,7 @@ impl App {
let _ = self.hooks.execute(HookEvent::ModeChange, &context);
}
/// Cycle through modes: Plan Agent YOLO Plan
/// Cycle through modes: Plan -> Agent -> YOLO -> Plan
pub fn cycle_mode(&mut self) {
let next = match self.mode {
AppMode::Plan => AppMode::Agent,
+29 -53
View File
@@ -6,7 +6,6 @@ use std::path::PathBuf;
use std::time::Instant;
use anyhow::Result;
use chrono::Local;
use crossterm::{
event::{
self, DisableBracketedPaste, DisableMouseCapture, EnableBracketedPaste, EnableMouseCapture,
@@ -20,7 +19,7 @@ use ratatui::{
Frame, Terminal,
backend::CrosstermBackend,
layout::{Constraint, Direction, Layout, Rect},
style::{Color, Modifier, Style, Stylize},
style::{Style, Stylize},
text::{Line, Span},
widgets::{Block, Paragraph, Wrap},
};
@@ -1645,25 +1644,30 @@ fn render_footer(f: &mut Frame, area: Rect, app: &App) {
Style::default().fg(palette::DEEPSEEK_SKY),
)]
} else {
// Time (Left)
let time_str = Local::now().format("%H:%M").to_string();
let time_span = Span::styled(
format!("{} ", time_str),
// Compact footer: session + token cost + help hint
let mut spans = Vec::new();
if let Some(ref sid) = app.current_session_id {
spans.push(Span::styled(
format!("session:{} ", &sid[..8.min(sid.len())]),
Style::default().fg(palette::TEXT_DIM),
));
}
if app.total_conversation_tokens > 0 {
let tokens_k = app.total_conversation_tokens as f64 / 1000.0;
spans.push(Span::styled(
format!("{tokens_k:.1}k tokens "),
Style::default().fg(palette::TEXT_DIM),
));
}
spans.push(Span::styled(
"F1 help",
Style::default().fg(palette::TEXT_DIM),
);
));
// Mode (Left) - Lowercase, colored
let mode_str = app.mode.label().to_lowercase();
let mode_style = mode_badge_style(app.mode);
let mode_span = Span::styled(format!("{} ", mode_str), mode_style);
// Agent Info (Left)
let model = &app.model;
let status_suffix = if app.is_loading { ", thinking" } else { "" };
let agent_text = format!("agent ({}{})", model, status_suffix);
let agent_span = Span::styled(agent_text, Style::default().fg(palette::TEXT_DIM));
vec![time_span, mode_span, agent_span]
spans
};
// Calculate Widths
@@ -1677,7 +1681,7 @@ fn render_footer(f: &mut Frame, area: Rect, app: &App) {
all_spans.push(Span::raw(" ".repeat(spacer_width)));
all_spans.extend(right_spans);
} else {
// Fallback for narrow screens: Drop agent info
// Fallback for narrow screens
let simple_left = if let Some(msg) = app.status_message.as_ref() {
let max_left = available_width.saturating_sub(10).saturating_sub(1).max(1);
let truncated = truncate_line_to_width(msg, max_left);
@@ -1686,16 +1690,10 @@ fn render_footer(f: &mut Frame, area: Rect, app: &App) {
Style::default().fg(palette::DEEPSEEK_SKY),
)]
} else {
let time_str = Local::now().format("%H:%M").to_string();
let mode_str = app.mode.label().to_lowercase();
let mode_style = mode_badge_style(app.mode);
vec![
Span::styled(
format!("{} ", time_str),
Style::default().fg(palette::TEXT_DIM),
),
Span::styled(format!("{} ", mode_str), mode_style),
]
vec![Span::styled(
"F1 help",
Style::default().fg(palette::TEXT_DIM),
)]
};
let bar_filled_narrow = "".repeat(filled.min(5));
let bar_empty_narrow = "".repeat(5 - filled.min(5));
@@ -1741,22 +1739,6 @@ fn get_context_percent_decimal(app: &App) -> f32 {
}
}
fn mode_color(mode: AppMode) -> Color {
match mode {
AppMode::Normal => palette::MODE_NORMAL,
AppMode::Agent => palette::MODE_AGENT,
AppMode::Yolo => palette::MODE_YOLO,
AppMode::Plan => palette::MODE_PLAN,
}
}
fn mode_badge_style(mode: AppMode) -> Style {
Style::default()
.fg(palette::TEXT_PRIMARY)
.bg(mode_color(mode))
.add_modifier(Modifier::BOLD)
}
fn prompt_for_mode(mode: AppMode) -> &'static str {
match mode {
AppMode::Normal => "> ",
@@ -1812,13 +1794,7 @@ fn typing_indicator(start: Option<Instant>) -> &'static str {
}
fn deepseek_thinking_label(start: Option<Instant>) -> &'static str {
const TAGLINES: [&str; 5] = [
"Thinking",
"Plotting",
"Drafting",
"You're absolutely right! ... maybe.",
"Working",
];
const TAGLINES: [&str; 4] = ["Thinking", "Reasoning", "Drafting", "Working"];
const INITIAL_MS: u128 = 2400;
let elapsed_ms = start.map_or(0, |t| t.elapsed().as_millis());
if elapsed_ms < INITIAL_MS {