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.
brew install SmooAI/tools/th
# verify
th --versionThat 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 -fsSL https://raw.githubusercontent.com/SmooAI/smooth/main/install.sh | shgit clone https://github.com/SmooAI/smooth.git
cd smooth
cargo install --path crates/smooth-cli# 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 codeOr bring your own provider — see Authentication below for the full list.
No Docker. No Node.js. No runtime dependencies. One 10MB binary.
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.
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.
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.
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).
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
th up # Start everything
th down # Stop
th status # System health
th code # Interactive coding assistant (ratatui)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-defaultNote 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.
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 attentionth 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# 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 --projectGlobal config lives at ~/.smooth/; project config at
<repo>/.smooth/. Project entries shadow global on name collision.
See docs/extending.md for the full guide.
Dispatch a pearl (or ad-hoc prompt) to a Smooth operative. Big Smooth
(th up) execs the operative as a host subprocess 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 (and thesmooai/smooth-operativemicroVM image) went away with the microVM stack, 2026-07 (pearlth-f4a801). The operative now runs directly on the host and uses your real toolchain — no per-VM image or cache mount.
Build locally:
scripts/build-smooth-operative-image.shOverride via --image or SMOOTH_OPERATIVE_IMAGE env if you want a
custom variant (e.g. a version pinned for CI reproducibility).
Microsandbox image resolution. Locally-built images live in
your Docker Desktop image store; microsandbox pulls from registries
by default, so if its pull can't see your local build, push it
first (docker push smooai/smooth-operative:0.2.0) or set
SMOOTH_OPERATIVE_IMAGE to something microsandbox can reach.
Project cache. Each workspace path hashes to its own cache,
mounted at /opt/smooth/cache inside the VM. Subsequent runs on the
same repo share mise installs + language stores (pnpm-store, cargo
registry, uv cache, etc.). Backed by a first-class microsandbox
Volume by default (~/.microsandbox/volumes/smooth-cache-<key>/);
set SMOOTH_USE_VOLUMES=0 to fall back to the legacy bind-mount
(~/.smooth/project-cache/<key>/). Manage with:
th cache list # shows entries from both backends, tagged
th cache prune --older-than 30 # evict caches idle > N days
th cache clear /path/to/project # remove entry for a specific workspaceKeep 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 instructionsth 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 worktreesTwo 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.
| 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) |
smooth/
├── crates/
│ ├── smooth-cli/ # Binary — clap CLI, the `th` entry point
│ ├── smooth-bigsmooth/ # Library — orchestrator, policy gen, session mgmt, in-process dispatch
│ ├── smooth-operator/ # Library — Rust-native AI agent framework
│ ├── smooth-operative/ # Binary — agent loop for a dispatched pearl (host subprocess)
│ ├── smooth-policy/ # Library — shared policy types, TOML parsing
│ ├── smooth-narc/ # Library — tool surveillance + secret detection
│ ├── smooth-scribe/ # Library — structured logging
│ # (removed 2026-07, pearl th-f4a801: smooth-bootstrap-bill, smooth-wonk,
│ # smooth-goalie, smooth-host-stub, smooth-credential-helper — see git history)
│ ├── smooth-archivist/ # Library — central log aggregator
│ ├── smooth-pearls/ # Library — Dolt-backed pearl tracker
│ ├── smooth-plugin/ # Library — CLI-wrapper plugin manifests
│ ├── smooth-diver/ # Library — pearl lifecycle manager + Jira sync
│ ├── smooth-tunnel/ # Library — th.smoo.ai reverse-tunnel client
│ ├── smooth-bench/ # Binary — coding-benchmark harness (aider-polyglot, SWE-bench, …)
│ ├── smooth-code/ # Library — ratatui terminal dashboard
│ └── smooth-web/ # Library — embedded Vite SPA
│ └── web/ # React + Vite source
├── Cargo.toml # Workspace root
├── rustfmt.toml # Format config
└── install.sh # Curl installer
# 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/thSmooth 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
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.
Built by Smoo AI — AI built into every product.
