A concise, high-performance terminal AI coding agent written in safe Rust, powered by the DeepSeek API.
zero-code-cli brings an agentic coding workflow to your terminal: it can explore your codebase, plan a design, and write code on your behalf — all through a streaming TUI. It uses a Plan → Build dual-mode workflow so you can separate thinking from implementation, and ships with filesystem + shell tools the agent can call autonomously via a ReAct loop.
- ~4300 lines of Rust, zero
unsafecode (#![forbid(unsafe_code)]) - Single-threaded async runtime (tokio current-thread)
- Real-time token streaming rendered with Ratatui
- Works with any DeepSeek-compatible OpenAI-style chat API
- Small and readable. The entire agent fits in ~4300 lines across 9 files — easy to audit, learn from, and hack on. No framework lock-in.
- Plan / Build separation. Research and design happen in Plan mode; switching to Build captures the plan as context so the coding agent inherits the full design.
- Safe Rust.
#![forbid(unsafe_code)]means no unsafe blocks, anywhere. - Local-first sessions & memory. Conversations are saved per-project on your own machine under
~/.zero-code-cli/, and past sessions are distilled into a topic-based long-term memory that is recalled on demand.
- Dual-mode workflow — Plan mode for research and design thinking, Build mode for writing code. Switch with
Tab. - Plan artifact handoff — When you switch from Plan to Build, the plan conversation is captured and injected as context so the Build agent inherits the full design.
- Session persistence — Conversations are automatically saved per-project under
~/.zero-code-cli/memory/. List and switch sessions with/sessions. - Long-term memory —
/summarycondenses all past sessions for a project into a topic-basedmemory.mdvia the API; relevant topic blocks are keyword-scored and injected as context on each new message. Sessions older than 7 days are auto-summarized. - ReAct agent loop — The agent reasons, calls tools, and iterates up to
max_iterationsturns (default 50) per message. - API retry with exponential backoff — Failed API calls are retried up to
retry_counttimes with configurable delay. - Built-in tools —
read_file,write_file(both with partial read/write via line ranges),bash(with timeout enforcement),grep,ls— all defined with JSON Schema and accessible to the model. - Streaming TUI — Real-time token streaming with blinking cursor indicator, rendered with Ratatui.
- DeepSeek reasoning support — Handles
reasoning_contenttokens from DeepSeek reasoning models (e.g.deepseek-reasoner). - Configurable — API endpoint, model, temperature, max tokens, retry settings, max iterations, and custom system prompt all set via
~/.zero-code-cli/config.toml. - Debug logging — Set
DEBUG=truefor detailed logs to~/.zero-code-cli/debug.log. - Cross-platform — Runs on Windows, macOS, and Linux via crossterm.
- Rust toolchain (edition 2024)
- A DeepSeek API key
- Windows only: ripgrep (
rg) must be installed and on yourPATH. Thegreptool usesrgon Windows (Unix uses the systemgrep).- Install via
winget install BurntSushi.ripgrep.MSVC,scoop install ripgrep, orchoco install ripgrep - Verify with
rg --version
- Install via
git clone https://github.com/gaoze1998/zero-code-cli.git
cd zero-code-cli
cargo build --releaseThe binary will be at target/release/zero-code-cli (or target\release\zero-code-cli.exe on Windows).
# 1. Configure your API key
mkdir -p ~/.zero-code-cli
cat > ~/.zero-code-cli/config.toml <<'EOF'
api_url = "https://api.deepseek.com"
api_key = "sk-your-key-here"
model = "deepseek-v4-flash"
max_tokens = 4096
temperature = 0.7
max_iterations = 50
EOF
# 2. Run it from any project directory
cd your-project
zero-code-cliOn Windows PowerShell:
New-Item -ItemType Directory -Force "$env:USERPROFILE\.zero-code-cli"
@'
api_url = "https://api.deepseek.com"
api_key = "sk-your-key-here"
model = "deepseek-v4-flash"
max_tokens = 4096
temperature = 0.7
max_iterations = 50
'@ | Set-Content "$env:USERPROFILE\.zero-code-cli\config.toml"Create ~/.zero-code-cli/config.toml:
api_url = "https://api.deepseek.com"
api_key = "sk-your-key-here"
model = "deepseek-v4-flash"
max_tokens = 4096
temperature = 0.7
retry_count = 2
retry_delay_secs = 2
max_iterations = 50
system_prompt = "You are a helpful coding assistant."Environment variable overrides:
| Variable | Config key |
|---|---|
DEEPSEEK_API_KEY |
api_key |
DEEPSEEK_API_URL |
api_url |
DEEPSEEK_MODEL |
model |
Tip: Because the client speaks the OpenAI-compatible chat completions format, you can point
api_urlat any compatible endpoint (e.g. a local proxy or other DeepSeek-compatible provider).
cargo run
# or with debug logging
DEBUG=true cargo run| Key | Action |
|---|---|
Enter |
Send message (or handle slash command) |
Tab |
Switch Plan ↔ Build mode |
Ctrl+C / Ctrl+D |
Quit |
Ctrl+W |
Delete previous word |
Home / End |
Move to line start/end |
Up / Down |
Scroll conversation (1 line) |
PageUp / PageDown |
Scroll conversation (5 lines) |
| Command | Action |
|---|---|
/new |
Reset both Plan and Build conversations (auto-saves current session) |
/summary |
Summarize all sessions into long-term memory (memory.md), then delete session files |
/plan |
Switch to Plan mode |
/build |
Switch to Build mode (captures plan artifact) |
/sessions |
List all saved sessions for the current project |
/sessions <n> |
Switch to session number n (auto-saves current session first) |
Sessions are automatically saved per-project to ~/.zero-code-cli/memory/<project>/sessions/. Each session file stores both Plan and Build conversation histories, the plan artifact, and the current mode.
- Auto-save — The current session is saved on quit (
Ctrl+C/Ctrl+D), on/new, and before switching to another session. - Auto-name — Session names are derived from the first user message in the conversation.
- List & switch — Use
/sessionsto see all saved sessions (most recent first), then/sessions 1to load session #1.
Past sessions are distilled into a topic-based knowledge file at ~/.zero-code-cli/memory/<project>/memory.md:
- Manual summary —
/summarysends all session transcripts to the API, which produces structured## Topic:blocks and writes them tomemory.md, then deletes the raw session files. - Auto-summarization — When a session file is older than 7 days, summarization is triggered automatically (on save or quit).
- Recall — On each user message, topic blocks are keyword-scored against your message; the top relevant blocks (above a 0.10 relevance threshold) are injected as system context so the agent remembers past decisions.
- Size guard —
memory.mdis capped at 10 MB; when exceeded, the oldest topic blocks are pruned automatically.
- Plan mode (
/plan) — Ask the agent to research, explore, and design a solution. The system prompt guides it toward analysis and design, not code writing. - Switch (
Tab) — All agent messages from Plan are captured into a plan artifact. - Build mode (
/build) — On your first message, the plan artifact is injected as context. The Build system prompt focuses the agent on implementation. - Iterate — Switch back to Plan anytime to refine the design, then back to Build to continue coding.
The agent can call these tools on your filesystem:
read_file— Read file contents, supports partial reads viastart_line/end_line(1 MB limit)write_file— Write or overwrite a file, supports targeted edits viastart_line/end_line(path traversal guarded)bash— Execute shell commands with configurable timeout (default 30s, max 120s)grep— Search files by regex (output truncated to 100 KB)ls— List directory contents
See the examples/ directory for projects built with zero-code-cli:
- tetris — Classic Tetris game (vanilla JS + HTML5 Canvas, SRS rotation, 7-bag randomizer, ghost piece), generated entirely by the agent.
src/
├── main.rs Entry point, terminal setup, event loop, agent_loop(), key handling
├── app.rs App state, dual message histories, plan artifact, slash commands
├── api.rs DeepSeek API client, SSE streaming, tool-call parsing
├── ui.rs Ratatui rendering: tabs, conversation, input, status bar
├── tools.rs 5 built-in tools with JSON Schema definitions
├── config.rs Config loading from TOML + env var overrides
├── session.rs Session persistence: save, load, list (JSON files per project)
├── memory.rs Long-term memory: topic-block search, summarization, expiry, size limits
└── logger.rs Debug logging to file
Data flow: user types → Enter spawns agent_loop() as a tokio task → api::stream_chat() POSTs to the API → SSE tokens stream through an mpsc channel → main event loop drains them into App → ui::draw() re-renders at ~60fps. When the model responds with tool calls, agent_loop() executes them, feeds results back, and loops (max max_iterations iterations, default 50). On every user message, memory::search_memory() keyword-scores topic blocks from memory.md and injects the relevant ones as system context; /summary (or sessions older than 7 days) triggers memory::run_summarization(), consolidating all sessions into memory.md and deleting the originals.
┌─────────────┐ Enter ┌──────────────┐ SSE stream ┌─────────────┐
│ Input box │ ─────────► │ agent_loop │ ◄────────────► │ DeepSeek API│
└─────────────┘ └──────┬───────┘ └─────────────┘
▲ │ tool calls
│ render ▼
┌───────┴───────┐ ┌──────────────┐
│ ui::draw() │ ◄───────── │ tools.rs │ read/write/bash/grep/ls
└───────────────┘ events └──────────────┘
Contributions are welcome! This project is intentionally small — please keep new code unsafe-free and within the existing module layout. Open an issue first to discuss larger changes.
MIT — see LICENSE.
