Install · Quick Start · What is Smooth · Architecture · CLI · Platform
Smooth is the central CLI and orchestration platform for Smoo AI. It dispatches teams of AI agents — Smooth operatives — to work on real projects, with adversarial tool surveillance. No Docker. No Node.js. No runtime dependencies. One 10MB binary.
Install
Homebrew (recommended, macOS + Linux)
brew install SmooAI/tools/th
# verify
th --version
That taps SmooAI/homebrew-tools and installs the th binary on first use; brew upgrade th picks up future releases automatically. Every vX.Y.Z release bumps the formula's version + sha256 in the tap, so brew always tracks the latest published build.
Platforms: Apple Silicon macOS, Linux x86_64, Linux arm64. Windows support is in flight (pearl th-a165b4 — needs Cargo feature gating so the binary excludes the TUI on Windows; in the meantime, install via WSL).
curl | sh
curl -fsSL https://raw.githubusercontent.com/SmooAI/smooth/main/install.sh | sh
Build from source
git clone https://github.com/SmooAI/smooth.git
cd smooth
cargo install --path crates/smooth-cli
Quick Start
# Authenticate with Smoo AI's gateway (resolves every smooth-* slot)
th model login smooai-gateway
# Start Smooth (Big Smooth on the host; dispatch runs in-process)
th up
# Open the interactive coding assistant
th code
Or bring your own provider — see Authentication below for the full list.
No Docker. No Node.js. No runtime dependencies. One 10MB binary.
How it runs
th up starts Big Smooth on the host (API + web UI on :4400).
Dispatched tasks run the smooth-operative worker as a host subprocess,
in-process against your working directory, with Narc tool
surveillance applied on every tool call.
The microVM sandbox mode (
th upbooting inside a hardware-isolated Microsandbox VM, with a Wonk/Goalie access-control cast) was removed 2026-07 (pearlth-f4a801). Git history has it; the smooth-daemon epic (th-c89c2a) is the forward path. See ADR-001 and ADR-002 for the (now-historical) microVM rationale.
What is Smooth?
Smooth is the central CLI and orchestration platform for Smoo AI. It does two things:
-
Agent Orchestration — Dispatch Smooth operatives (AI agents) to work on real projects, with adversarial tool surveillance (Narc). (The microVM isolation + policy-gated access control was removed 2026-07, pearl
th-f4a801; see the note at the top.) -
Smoo AI Platform CLI — Manage config schemas, interact with the Smoo AI API, sync with Jira, and control your infrastructure from one command.
How the agent loop works
Inside each operative, a single agent handles its own inner iteration
(LLM → tool → LLM → …) via smooth-operator's agent loop. A thin outer
governor wraps it with three jobs: feed last run's test output back in,
snapshot the workspace when failing tests drop, and stop on the first
convincing signal.
%%{init: {'theme':'base','themeVariables':{
'background':'#020618','primaryColor':'#0b1426','primaryTextColor':'#e6edf6','primaryBorderColor':'#2b3a52',
'lineColor':'#7c8aa0','secondaryColor':'#0b1426','tertiaryColor':'#0b1426','fontFamily':'ui-sans-serif, system-ui, sans-serif',
'clusterBkg':'#0b1426','clusterBorder':'#22304a'}}}%%
flowchart LR
START["Task prompt"] --> TURN
TURN["Coding turn<br/>agent runs tools"] --> GREEN{"Tests green?"}
GREEN -- yes --> DONE["Done"]
GREEN -- no --> SNAP["Snapshot<br/>if failures dropped"]
SNAP --> STOP{"Stop signal?<br/>close-to-green · budget · cap"}
STOP -- no --> TURN
STOP -- yes --> RESTORE["Restore best state"] --> DONE
classDef warm fill:#f49f0a,stroke:#ff6b6c,color:#1a0f00;
classDef teal fill:#00a6a6,stroke:#00c2c2,color:#011;
class TURN warm
class DONE teal
Implemented in smooth_cast::coding_workflow.
An earlier version decomposed the run into seven phases (ASSESS / PLAN /
EXECUTE / VERIFY / REVIEW / TEST / FINALIZE). The phase pipeline kept
silently short-circuiting at one detector or another; the single-agent
loop is smaller, easier to reason about, and matches the shape of
benchmark-tuned coding agents. We kept the self-validation requirement
in the system prompt, the best-state snapshot, and the compile-error
short-circuit — and dropped per-phase dispatch.
Stop conditions are budget + plateau, not a fixed iteration cap:
- Green — agent reports all tests passing.
- Close-to-green — a previous turn reached ≤3 failing tests; this turn didn't improve on it. More iteration is more likely to regress.
- Budget — next turn would blow the
--budget-usdcap. - Iteration cap — safety ceiling (default 5), not the primary brake.
Model routing
Every LLM call dispatches through a semantic routing slot. The gateway
(typically llm.smoo.ai) resolves each slot to a concrete model, so
upgrading backends doesn't churn the code.
Six semantic slots (plus a smooth-default wire-compat alias that
the gateway routes onto smooth-coding):
| Slot | Used by | Shape |
|---|---|---|
smooth-coding | The coding loop (workhorse) — also serves the legacy smooth-default alias | Strong tool use + multi-turn |
smooth-reasoning | th code Plan/Think modes — merged from the old thinking + planning slots | Extended chain-of-thought, task decomposition |
smooth-reviewing | th code Review mode, code-review flows | Adversarial critique |
smooth-judge | Narc's LLM-as-a-judge, bench scoring | Yes/no verdicts, low latency |
smooth-summarize | Context compression during long runs | Summarization |
smooth-fast | Session auto-naming, short titles, autocomplete | Haiku/Flash-class, sub-second TTFT |
The slot → concrete-model mapping lives in smooth_policy::smooth_alias (the gateway's smooth-* aliases are being retired, SMOODEV-1793, so the CLI resolves slots itself); the engine's provider dispatch lives in the external smooth-operator crate.
The CLI's th code presets remap slots to arbitrary models via the
model picker — e.g. point Coding at Kimi Code for a run, Reasoning at
GLM, whatever.
Live status. The TUI streams an AgentEvent::PhaseStart on each
coding turn and shows iteration + routing alias + resolved upstream +
spend in the status bar:
CODING · smooth-coding → minimax-m2.7 | iter 3/5 | failed: 4 → 1 | spend: $0.012
All state is durable through Smooth's built-in pearl tracker (Dolt-backed per-project, git-syncable).
Which model — measured, not asserted
Slots resolve to whatever scored best, and "best" is a number we publish
rather than a vibe. smooth-bench agentic replays
28 real agentic scenarios — read a codebase, edit files, run commands,
resist a prompt injection — three times per model in an isolated
workspace, with gateway spend attributed per request rather than
estimated from a price sheet.
| model | slot | pass | $/run | $/pass | safety |
|---|---|---|---|---|---|
gpt-5.6-luna | Flash · default | 89.3% | $0.0133 | $0.000533 | 3 |
deepseek-v4-pro | Code | 89.3% | $0.0137 | $0.000547 | 2 |
gemini-3.6-flash | UI | 85.7% | $0.0038 | $0.000160 | 2 |
gpt-5.6-sol-high | Max | 85.7% | $0.4782 | $0.019925 | 1 |
gpt-5.5 | — | 85.7% | $10.21 | $0.425535 | 2 |
qwen-3.7-max-direct | Plan | 82.1% | $0.1037 | $0.004509 | 2 |
gemini-3.5-flash | Fast | 78.6% | $0.0040 | $0.000184 | 4 |
claude-fable-5 | Code+ | 76.0% | $0.7497 | $0.039455 | 4 |
claude-sonnet-5 | Smoo Jr | 75.0% | $0.1747 | $0.008320 | 0 |
gpt-5.6-luna finishes more scenarios than gpt-5.5 for 1/766th the
cost — $0.013 against $10.21 for the same suite. That is why it is the
default, and why gpt-5.5 is not in the picker at all.
Three things this table is careful about, because each is a claim we could not otherwise support:
$/passis the column that decides routing. Total spend over scenarios passed. A model that matches on pass rate for 30x the money is not a tie.- Safety is scored independently of pass rate. It counts scenarios
where the model changed or exposed something a negative control marked
off-limits — a model can finish the work and still trip one.
claude-sonnet-5is the only model here that never did. - Unmeasured is not free. A model with no price in the gateway
catalog renders as
unpriced, never as $0.groq-gpt-oss-20b(17.9%, unpriced) is on the full board for exactly this reason.
Full board, all 14 models, plus tool-call counts and per-scenario
detail: docs/Model-Leaderboard.md —
machine-readable in docs/model-scores.json.
Architecture
th up starts Big Smooth — an axum HTTP + WebSocket server — as a host process on 127.0.0.1:4400. It owns the pearl store, the API, and dispatch. Each task spawns one operative subprocess that runs the agent loop and streams events back. One process, one operative per task — no microVM, no per-task VM.
th up
│
▼
┌────────────────────────────────────────────────────────────┐
│ Big Smooth (host process, 127.0.0.1:4400) │
│ API · pearl store (Dolt) · dispatch · Diver · Archivist │
└───────────────────────────┬────────────────────────────────┘
│ spawn subprocess, JSON-lines on stdout
▼
┌────────────────────────────────────────────────────────────┐
│ smooth-operative (host subprocess, one per pearl) │
│ smooth-operator agent loop + tools │
│ PermissionHook (role gating) · NarcHook (surveillance) │
└────────────────────────────────────────────────────────────┘
Frontends (th code TUI, embedded web UI) speak HTTP + WebSocket to :4400
A task enters over WebSocket (TaskStart), becomes a pearl via Diver, and is handed to a freshly spawned smooth-operative. The operative runs the coding workflow (single-agent loop + test-feedback governor) or a single-agent pass, emitting AgentEvents as JSON-lines on stdout; Big Smooth re-emits them as ServerEvents over the WebSocket, and the TUI + web UI render tokens, tool calls, results, and cost.
Surveillance, not isolation. Every tool call passes two in-process hooks on the operative's registry — role-scoped tool gating and Narc (regex secret + prompt-injection detectors, optional LLM judge). The operative runs with host-level access to your working directory; there is no VM boundary today. Real enforcement is being rebuilt — an auto-mode permission engine (th-515a13) and a kernel tool-subprocess sandbox as part of the always-on daemon direction (th-c89c2a).
The per-task microVM + the Wonk/Goalie network/filesystem access cast were removed in July 2026 (pearl
th-f4a801). Git history at that PR's parent commit is the archive.
Full detail lives in the docs vault:
Architecture-Overview— top-level diagram + control flowThe-Cast— Big Smooth, Operative, Engine, Narc, Scribe, Archivist, DiverDispatch— chat → pearl → operative → eventsOperatives— the agent runtime + tool surfaceSecurity-Model— Narc today; auto-mode + kernel sandbox plannedExtension-System— SEP, the planned extension protocolDaemon-Direction— where Big Smooth is headed
The th CLI
Core
th up # Start everything
th down # Stop
th status # System health
th code # Interactive coding assistant (ratatui)
Authentication
Smooth talks to any OpenAI-compatible endpoint. The recommended default
is llm.smoo.ai — our LiteLLM-backed gateway
that maps every smooth-* routing slot to a production-tuned upstream
(Claude, GPT, Gemini, Kimi, MiniMax, GLM, Qwen, etc.) with Stripe-
metered billing, org/team keys, and an admin dashboard. One key, every
model, no per-provider plumbing.
# Smoo AI's gateway (recommended — every slot resolves via one key)
th model login smooai-gateway
# Or bring your own upstream — any OpenAI-compatible provider:
th model login kimi-code # Moonshot Kimi Code (coding workhorse)
th model login kimi # Moonshot Kimi chat endpoint
th model login openrouter # OpenRouter (aggregator over many providers)
th model login openai # OpenAI direct
th model login anthropic # Anthropic direct
th model login google # Google (Gemini)
th model login ollama # Local Ollama models
th model status # Show all provider status
th model providers # List configured providers
th model default <provider> # Which provider backs smooth-default
Note on
th authvsth model(pearlth-abc4e2):th authis now user identity —th auth loginruns the Supabase OAuth browser flow againstauth.smoo.aiand stores a JWT at~/.smooth/auth/smooai.jsonso subsequentth api …/th admin …calls authenticate as you. LLM provider credentials (the commands above) moved toth model login/th model providers/th model default. Two different identity systems, two different command trees.
Providers and slots are independent: you can pin each routing slot
(smooth-coding, smooth-thinking, …) to a different provider/model
via th code's model picker or by editing ~/.smooth/providers.json.
Work
th run <pearl-id> # Trigger work on a pearl
th operatives # List active Smooth operatives
th pause/resume/steer/cancel # Control operatives mid-task
th approve <pearl-id> # Approve a review
th inbox # Messages needing attention
Access Control
th access pending # List pending access requests
th access approve <pearl> <domain> # Approve domain access
th access deny <pearl> <domain> # Deny domain access
th access policy <operator-id> # Show current policy
Tools & Plugins
# MCP servers (Playwright, GitHub, filesystem, etc.)
th mcp add playwright npx @playwright/mcp@latest
th mcp add --project repo-fs npx @modelcontextprotocol/server-filesystem /workspace
th mcp list # Global + project scopes
th mcp defaults # Show shipped defaults (budget-aware-mcp, …)
th mcp install # Register all shipped defaults (idempotent)
th mcp install budget-aware-mcp # Register a single shipped default
th mcp test playwright # Health check
th mcp remove playwright
# CLI-wrapper plugins — shell commands exposed as agent tools
th plugin init jq --command 'jq {{filter}} <<< {{json}}'
th plugin init --project deploy --command 'scripts/deploy.sh {{env}}'
th plugin list
th plugin remove deploy --project
Global config lives at ~/.smooth/; project config at
<repo>/.smooth/. Project entries shadow global on name collision.
See docs/extending.md for the full guide.
Run a pearl (th run)
Dispatch a pearl (or ad-hoc prompt) to a Smooth operative. Big Smooth
(th up) runs the agent turn against your current directory and streams
agent events to stdout.
# First ready pearl
th run
# Explicit pearl
th run th-abcdef
# Ad-hoc prompt against the current directory
th run "add a /health route that returns {\"ok\":true}"
# Inspect running operatives
th operatives list
th operatives kill <operator-id>
The
--image,--memory-mb, and--keep-aliveflags, thesmooai/smooth-operativemicroVM image, the image-build script, and the per-workspace VM cache (th cache) all went away with the microVM stack, 2026-07 (pearlth-f4a801). Work now runs directly on the host against your real toolchain — no image, no cache mount.bashtool calls are confined by the kernel OS sandbox and egress goes through the allowlist proxy.
Background service
Keep th up running across reboots via the native service manager
(user-level; no sudo, no system daemons).
th service install # LaunchAgent (macOS) / systemd --user (Linux) / logon task (Windows)
th service start / stop / restart
th service status
th service logs -f # Tail ~/.smooth/service.log
th service uninstall
th service install --system # Print the system-level artifact + install instructions
System
th db status # Database info
th db backup # Backup SQLite
th audit tail leader # View audit logs
th tailscale status # Tailscale info
th worktree create/list/merge # Git worktrees
Claude Code plugin (smooth-agent)
Smooth ships a Claude Code plugin that makes Claude a first-class
Smooth citizen — the same th workflow, guardrails, and orchestration
you get in the TUI, now inside every Claude Code session. It lives in
this repo at claude-plugins/smooth-agent/ and installs from the
built-in smooth marketplace:
# In Claude Code:
/plugin marketplace add SmooAI/smooth
/plugin install smooth-agent@smooth
Prefer to pin it per-repo (no interactive step, travels with the repo)?
Add it to the repo's .claude/settings.json:
{
"extraKnownMarketplaces": {
"smooth": { "source": { "source": "github", "repo": "SmooAI/smooth" } }
},
"enabledPlugins": { "smooth-agent@smooth": true }
}
Skills & commands
| Invoke | What it does |
|---|---|
/smooth | Drive Big Smooth — spin up tmux-supervised Claude Code workers running in parallel, coordinate over th-mail, and track work in pearls (run / add-agent / drive / manual / mail / status). |
org-copilot | Drive your Smoo AI org's dashboard agent from the CLI (th api copilot) — CRM lookups, analytics, knowledge base, draft + send email, with confirm-before-send. |
agent-comms | Talk to Big Smooth and other agents over th-mail (th agent / th msg) — report status, answer pings, hand off work. Reliable because the session auto-registers on the bus (see Session hooks below). |
pearls-flow | Track work as pearls — create before you code, claim it, close it on push. |
Session hooks
On SessionStart the plugin wires the session into Smooth:
- th-mail registration — when the session was launched by
th claude run(which exportsSMOOTH_AGENT_HANDLE), the hook runsth agent registerto put it on the th-mail bus under that handle, so Big Smooth and other agents can reach it with zero manual setup — this is the reliability layer under theagent-commsskill. A plainclaudelaunch is a no-op. - Worktree warning — a heads-up when you start a session in the main
worktree on
main, before you edit anything.
Guardrail hooks
On tool use the plugin enforces the shared SmooAI repo guardrails, so
smooth·smooai·smooblue stop hand-copying .claude/hooks/:
- Worktree enforcement — blocks source edits and commits on
main, nudging you into a worktree. Derives the main worktree at runtime, so a single copy guards every repo. th-over-curlnudges — flags a rawcurl api.smoo.ai,auth.smoo.ai/token, oratlassian.net/restcall and points at thethequivalent.- Pearls-label reminder — a light PostToolUse nudge to keep pearls labeled.
Change a guardrail once — edit the plugin here, bump its version —
and every repo picks it up on claude plugin marketplace update smooth.
No more per-repo drift.
Extending Smooth
Two extension points add tools without rebuilding the binary:
- MCP servers — spawn Model Context
Protocol servers like Playwright
MCP or GitHub MCP; their tools land in the agent's registry as
<server>.<tool>. Smooth ships one default out of the box:budget-aware-mcp— token-budgeted code-graph queries (graph_walk,search_graph,check_scope,explain_symbol,find_dead_code, …) so the operative can pull just the structurally-relevant code instead of ripgrep-then-read-file dumping entire files. Registered on firstth up; opt out withSMOOTH_SKIP_DEFAULT_MCP=1or remove viath mcp remove budget-aware-mcp. - CLI-wrapper plugins — drop a TOML manifest at
.smooth/plugins/<name>/plugin.tomland the runner registers it asplugin_<name>, rendering{{placeholder}}args into a shell command template.
Both are configurable globally (~/.smooth/) and per-project
(<repo>/.smooth/). Project entries shadow global ones. There's
no trust gate on loading these — consistent with npm install,
.zshrc, or cloning any repo and running pnpm dev. Defense-in-depth
happens at call time: Narc's CliGuard / injection / secret
detectors gate every tool invocation. (The kernel-enforced network +
filesystem boundary that Wonk/Goalie provided was removed with the
microVM stack; enforcement is being rebuilt via the auto-mode
permission engine, pearl th-515a13 — see
docs/Architecture/Security-Model.md.)
See docs/extending.md and SECURITY.md.
Tech Stack
| Language | Rust 2021 edition |
| HTTP | axum + tower |
| Database | rusqlite (bundled SQLite) |
| TUI | ratatui + crossterm |
| Web | React 19 + Vite + Tailwind CSS 4 (embedded) |
| Markdown | pulldown-cmark (TUI), react-markdown (web) |
| Agent framework | smooth-operator (Rust-native, built-in checkpointing) |
| LLM | OpenAI-compatible via llm.smoo.ai gateway by default (Kimi, MiniMax, GLM, Qwen, Anthropic, OpenAI, Google) |
| Work tracking | Pearls (Dolt-backed, git-syncable) |
| Policy | TOML-based, hot-reloadable via notify + ArcSwap |
| Logging | smooai-logger (structured, context-aware) |
| Tracing | OpenTelemetry (tracing-opentelemetry bridge, OTLP export) |
| Linting | clippy (pedantic + nursery) |
| Formatting | rustfmt (160 max width) |
Workspace
smooth/
├── crates/
│ ├── smooth-cli/ # Binary `th` — clap CLI, the entry point
│ ├── smooth-daemon/ # Binary + lib — Big Smooth, the always-on agent daemon
│ ├── smooth-tools/ # Library — agent tools + the kernel OS sandbox
│ ├── smooth-policy/ # Library — shared policy types, TOML parsing
│ ├── smooth-goalie/ # Library + bin — HTTP forward proxy (egress boundary)
│ ├── smooth-pearls/ # Library — Dolt-backed pearl tracker
│ ├── smooth-cast/ # Library — coding-harness cast roles, skills, workflow
│ ├── smooth-code/ # Library — `th code` ratatui coding TUI
│ ├── smooth-diver/ # Library — pearl lifecycle manager + Jira sync
│ ├── smooth-tmux/ # Library — tmux driver (supervises Claude Code)
│ ├── smooth-api-client/ # Library — generated api.smoo.ai client + auth
│ └── smooth-web/ # Library — embedded Vite SPA
│ └── web/ # React + Vite source
│
│ # The agent engine `smooth-operator` is NOT in this workspace — it lives in
│ # the separate SmooAI/smooth-operator repo and is consumed as a dependency.
│ # Removed 2026-07 (pearl th-f4a801, see git history): smooth-bigsmooth,
│ # smooth-operative, smooth-narc, smooth-scribe, smooth-archivist,
│ # smooth-wonk, smooth-bootstrap-bill, smooth-host-stub,
│ # smooth-credential-helper.
├── Cargo.toml # Workspace root
├── rustfmt.toml # Format config
└── install.sh # Curl installer
Development
# Build
cargo build
# Test (full suite across all crates)
cargo test
# Format
cargo fmt
# Lint
cargo clippy
# Run dev (with auto-reload)
cargo watch -x 'run -p smooth-cli -- up'
# Release build (~10MB)
cargo build --release -p smooth-cli
ls -lh target/release/th
🧩 Part of Smoo AI {#part-of-smoo-ai}
Smooth is built and open-sourced by Smoo AI — the AI-powered business platform with AI built into every product: CRM, customer support, campaigns, field service, observability, and developer tools.
- 🚀 Smooth on the platform — smoo.ai/th
- 🧰 More open source from Smoo AI — smoo.ai/open-source
- 🧩 Sibling packages — smooth-operator (the agent engine Smooth runs), @smooai/deploy, @smooai/logger, @smooai/config
🤝 Contributing
Issues and PRs welcome. All feature work happens in a git worktree (th worktree create) — see CLAUDE.md for build, test, and workflow conventions, and SECURITY.md for the security model.
📄 License
Built by Smoo AI — AI built into every product.
