Smith is a task-tree runner where the LLM is the runtime. You write markdown files, organize them into folders, and Smith executes them as programs.
go build -o smith ./cmd/smithLaunch the interactive TUI:
smithOr use the command-line config:
smith configOr set the environment variable:
export SMITH_ANTHROPIC_API_KEY="sk-ant-..."smith initThis extracts the built-in planner and shipped lib tools to ~/.smith/lib/.
If you are working on Smith itself and changing files under internal/lib/builtin/ or the shipped native tool catalog, rebuild and refresh the extracted lib before testing smith plan or any lib-backed app:
go build -o smith ./cmd/smith
./smith initsmith init preserves user-modified files in ~/.smith/lib/. If you need the embedded copies to win, run smith lib update --force, or test in a clean temporary home directory.
A task tree is a directory. The minimum is a task.md and an agent.md:
my-project/
task.md # what to do (the prompt)
agent.md # which model to use
task.md — the instruction:
Summarize the key arguments in the provided text.
Keep it under 200 words.agent.md — the model config:
model: anthropic/claude-sonnet-4-6
temperature: 0.2smith validate my-project # check the tree is valid
smith run my-project # execute itOutput lands in my-project/output/result.md.
Subtasks go in a subtasks/ directory. Numeric prefixes control execution order:
my-project/
task.md
agent.md
subtasks/
01-gather/
task.md
02-analyze/
task.md
03-write/
task.md
Tasks with numeric prefixes run sequentially (01 before 02 before 03). Each subtask's output is available to the next via depends_on.
If a subtask needs another subtask's output, declare it in frontmatter:
---
depends_on:
- 01-gather
---
Analyze the information gathered in the previous step.The dependency's output is injected into the prompt automatically.
Tasks can produce JSON instead of markdown. Add output.type: json to frontmatter and provide a schema.md:
task.md:
---
output:
type: json
---
Extract the top 5 key points from the provided text.schema.md:
{
"type": "object",
"required": ["points"],
"properties": {
"points": {
"type": "array",
"items": { "type": "string" }
}
}
}The output goes to output/result.json and is validated against the schema.
| File | Purpose |
|---|---|
agent.md |
Model, persona, temperature, max_tokens |
tools.md |
Tool access (one per line: - project.read) |
schema.md |
JSON Schema for output.type: json tasks |
context/static/ |
Reference files injected into the prompt |
Agent config inherits from parent to child — subtasks without their own agent.md use the parent's.
Add behavioral guardrails in frontmatter:
---
constraints:
- Keep responses under 500 words
- Use only peer-reviewed sources
- Write in British English
---Tasks can run shell scripts instead of LLM prompts. Set model: shell in agent.md:
agent.md:
model: shelltask.md:
curl -s https://api.example.com/data | jq '.results'Shell tasks receive sibling outputs via $SMITH_DEP_* environment variables and run input via $SMITH_INPUT_*.
Put reference documents in context/static/:
my-project/
task.md
agent.md
context/
static/
company-style-guide.md
product-requirements.md
These files are injected into the task's prompt as labeled sections.
Instead of writing task trees by hand, let Smith design them for you:
smith plan ./my-project "research climate change impacts and write a summary report"This runs the built-in planner, which:
- Examines the target directory
- Designs a task tree to achieve your goal
- Creates a proposal in
.smith/proposals/
cat my-project/.smith/proposals/<id>/summary.mdBrowse the staged files in my-project/.smith/proposals/<id>/files/ to see exactly what will be created.
smith apply my-project/.smith/proposals/<id>This materializes the task tree and runs validation.
smith run my-projectsmith plan ./demo "create a research pipeline about renewable energy"
smith apply ./demo/.smith/proposals/<id>
smith validate ./demo
smith run ./demosmith plan ./demo "goal" --model anthropic/claude-sonnet-4-6 # override planner model
smith plan ./demo "goal" --max-cost-usd 1.00 # set cost ceilingThe shipped web.* tools are especially useful for research and briefing apps. A good pattern is to describe the exact web behavior you want and use explicit dates instead of relative phrases like "yesterday".
Example:
./smith plan ./demo-news "Create a web-backed news briefing app that accepts user inputs for a target location and briefing goal. Use explicit dates rather than relative phrases like 'yesterday'. Prefer the shipped web.lookup and web.fetch_markdown tools instead of creating new web tools. The output should be a concise markdown briefing with sections for world news, sports, finance, and local or regional updates." --max-cost-usd 0.75Suggested follow-through:
cat ./demo-news/.smith/proposals/<id>/summary.md
./smith apply ./demo-news/.smith/proposals/<id>
./smith validate ./demo-newsIf you are testing planner or lib changes from source, rebuild and run ./smith init first so the planner and shipped web tools in ~/.smith/lib/ match your current checkout.
See examples for checked-in example apps and repo hygiene notes for .smith/ runtime data.
Smith caches task outputs. If inputs haven't changed, re-running skips cached tasks:
smith run my-project # runs everything
smith run my-project # skips cached tasks
smith run my-project --no-cache # force re-run everythingTo mark a task as never cacheable:
---
cache: never
---Smith works as a Unix filter:
cat document.txt | smith run ./summarizer > summary.md- Piped stdin becomes a run input entry
- Stdout receives the root task's canonical output
- Status messages go to stderr
Pass data to a task tree at invocation time:
smith run ./analyzer --input topic="quantum computing" --input format="bullet points"Run input appears in the root task's prompt as labeled sections.
Reuse task trees from ~/.smith/lib/ via module.yaml:
# module.yaml
source: summarizeThis imports the summarize library module. Override its config with local sidecar files alongside module.yaml.
Run smith with no arguments to launch the interactive terminal dashboard:
smithThe TUI has four tabs (navigate with Tab/Shift+Tab):
- Config — set API keys, Ollama endpoint, probe providers for live model discovery, and configure default planner/task models
- Projects — browse known projects, view run history, remove stale entries
- Packages — browse installed lib modules and tool definitions with provenance indicators (embedded, user-modified, user-added)
- Search — search file names and content across all known projects (press Enter to focus the search input, Esc to unfocus)
Press q to quit. Ctrl+C always quits, even during editing.
| Command | Description |
|---|---|
smith |
Launch TUI (TTY) or print help (non-TTY) |
smith tui |
Launch TUI explicitly |
smith run <path> |
Execute a task tree |
smith plan <path> <goal> |
Generate a proposal from a goal |
smith apply <proposal-path> |
Materialize a proposal |
smith validate <path> |
Check a task tree is valid |
smith status <path> |
Report per-task execution status |
smith init |
Extract built-in libraries |
smith lib update |
Update libraries from binary |
smith config |
Configure API credentials |
| Flag | Description |
|---|---|
--dry |
Show execution plan without running |
--no-cache |
Force all tasks to execute |
--input key=value |
Pass run input (repeatable) |
--scope key=value |
Set tool scope (repeatable) |
| Flag | Description |
|---|---|
--model <model> |
Override planner model |
--max-cost-usd <amount> |
Cost ceiling for planning |
| Flag | Description |
|---|---|
--dry |
Show what would be applied |
--force |
Skip conflict detection |