Smith is a terminal-first coding agent: a TUI and a non-interactive -p mode
over a shared, provider-neutral agent runtime.
Smith consumes ../agent-runtime, which owns reusable
mechanism — provider adapters, the direct provider/tool loop, versioned
events, disjoint usage accounting, cancellation, and deterministic testing.
The dependency is one-way: the runtime never depends on Smith.
This repository owns Smith's policy — the parts a product must decide for itself, which the runtime deliberately ships as traits only:
| Crate | Owns |
|---|---|
smith-config |
Layered configuration, provenance, credential references, and project trust |
smith-host |
Prepared approval/question brokers and the project workspace boundary |
smith-runtime |
The single runtime factory, harness policy, checkpoints, artifacts, snapshots, and event journal |
smith-module |
Value-returning compiled module contracts and mount planning |
smith-plugin |
Claude Code bundle inspection, sources, digest verification, and user storage |
crates/modules/* |
Optional image-generation and budget-notice modules |
smith-tools |
The coding tools: read, list, search, edit, shell |
smith-tui |
Transcript, status, composer, theme, key map, and rendering |
smith-cli |
The smith binary, terminal host loop, and headless output contracts |
The runtime composition boundary is documented in
docs/architecture.md; extension trust tiers and the
future Forge adapter are in docs/extensions.md and
docs/forge-integration.md.
Every built-in filesystem-tool path resolves through the session's workspace,
so its project boundary is enforced in one place rather than re-implemented per
tool. Each invocation is prepared
before approval: argument validation and canonical resource resolution produce
the exact permissions, target, deadline, display, and fingerprint that are
authorized and then executed. edit requests authority for its canonical file,
narrowed to the operation it was given — create asks to create, delete asks
only to read and delete, and neither asks for process or network authority the
way routing a removal through shell rm would. shell is deliberately not a
workspace-contained filesystem tool: it prepares an unsandboxed host-shell
resource covering same-user host files, inherited environment and credentials,
child processes, network access, and data egress. Its project cwd is only the
initial working directory, not a sandbox boundary.
The read-only three run without asking. Reads, listings, searches, and command
output are bounded. Oversized output is stored in the session-private artifact
store and represented to the model by a bounded preview plus a retrievable
reference.
edit carries four operations: replace (an exact string that must appear
once, and the default), create, overwrite, and delete. The two that
destroy content the call does not itself carry are refused unless the session
has already read the target in full and its modification time is unchanged —
so an overwrite cannot silently discard work done in the user's own editor
between the agent's read and its write. An exact replace needs no such
precondition: a stale old_string simply fails to match.
shell puts each command in its own process group and signals the group, so a
build script's background watcher does not outlive the invocation. Unless the
whole run explicitly uses allow-all, every host-shell call reaches the
approval policy under its exact prepared command digest.
Smith's root surface also composes ask_user, write_todos, and depth-one
delegation through Agent Runtime's ability registry — each registered only
where it applies, and each described in the prompt only where it is registered,
so a child agent is never instructed to use a tool it does not have. Initial
activation is intent-scoped: a read-only request does not advertise mutation
merely because edit and shell are registered. Trusted skills, bounded memory, todo state,
artifact offloading, and semantic summarization contribute through the same
session-scoped harness pipeline.
Optional compiled modules provide image generation and context-pressure
notices. /modules lists their state, deciding configuration key and layer,
and first-party or named third-party origin. /modules <id> on|off reviews a
user-config switch and applies it at a safe boundary; smith config modules
prints the same listing without a session. Default builds include both
first-party modules, and --no-default-features builds retain the core tools.
See docs/modules.md for the contract and contributor steps.
Installable plugins bundle namespaced skills, prompt commands, and MCP servers
and sandboxed WASM components
in the Claude Code layout. smith plugin add reviews every component and a digest
of every plugin file before installation and trust; /plugins lists admission
states and previews user-config enablement changes. Hooks are listed and do not
run. Local directories, git sources, and marketplaces are supported. See
docs/plugins.md for installation and authoring.
WASM modules have no ambient authority and use confirmed capability grants;
see docs/wasm-modules.md and the SDK example.
The default wasm-modules feature can be omitted without removing content plugins.
When ordinary session persistence and protected checkpoints are both
available, delegated children are durable addressable sessions. @child-1 continue … starts a confirmed follow-up on that same child's canonical
history; /agent resume child-1 separately confirms continuation of one safe
interrupted checkpoint. Startup, /agent, /timeline, and headless status
only inspect retained metadata and never spend provider tokens. Smith never
turns a missing or incompatible child ID into an implicit new spawn.
Persisted root sessions may also own one explicit multi-turn goal. /goal <objective> creates it locally; bare /goal shows canonical status, reported
token evidence, budget, and active elapsed time. Smith continues an active goal
only while this process is running and the session is idle. Real user input
wins admission, child and ephemeral sessions never receive goal abilities, and
no daemon or restart-time scheduler is created.
During eligible provider-backed work, ordinary composer input has two explicit
intents: Enter steers the serving turn at its next safe boundary, while
Tab stores a process-local future whole turn. Pending text is not added to
canonical transcript history until Agent Runtime emits its committed steering
disposition. Alt+Up restores the newest Smith-owned queued turn for editing;
Esc interrupts and resends only steers the runtime actually discarded. File
identities remain exact and their bytes are read when the queued turn starts.
Slash commands, shell shortcuts, child operations, approvals, and
questionnaires are never queued implicitly.
Use PageUp / PageDown or the mouse wheel to scroll through a session.
Press Ctrl+L or Ctrl+End to jump to the bottom and follow new output
without changing your draft. The footer shows Ctrl+L bottom while scrolled
back; /help and ? on an empty draft list the shortcuts.
Detected skills appear directly in slash completion as /<skill-name>.
Invoke one alone to activate it for your next prompt, or add a task to activate
and run it immediately. /skills use <name> handles command-name collisions;
/skills lists availability and project trust. These shortcuts use
provider-backed turns; installed CLI agents use the skill MCP bridge.
See Skills.
Save a Markdown prompt template at ~/.smith/commands/<name>.md or
<project>/.smith/commands/<name>.md, then invoke /<name> args in the TUI or
with smith -p "/<name> args". Project commands need /commands trust <name>
before they can run. See File commands for a
complete example, argument substitution, trust, and the // literal escape.
# Run instantly through npm, without installing anything (macOS / Linux)
npx @forgeailab/smith
# Install the binary onto your PATH at ~/.local/bin — no sudo, no npm at runtime
npx @forgeailab/smith --install
# Or install via the curl installer, which also defaults to ~/.local/bin
curl -fsSL https://raw.githubusercontent.com/ForgeAILab/smith/main/install.sh | bashBoth installers write to your own ~/.local prefix, so neither needs root.
After either one, smith is a normal command; npx is no longer involved.
Pick a different location, or install machine-wide, with:
npx @forgeailab/smith --install --install-dir ~/bin
npx @forgeailab/smith --uninstall # removes ~/.local/bin/smith
curl -fsSL .../install.sh | bash -s -- --dir ~/bin
curl -fsSL .../install.sh | bash -s -- --system # /usr/local/bin, uses sudo
curl -fsSL .../install.sh | bash -s -- --release v0.2.9 # pin a release tagIf the install directory is not already on your PATH, both installers print
the export PATH=... line to add to your shell profile.
Prefer to build from source? Smith requires Rust 1.88 or newer.
cargo install --path crates/smith-cli # or: cargo run -p smith-cliThe canonical Linux archives are fully static musl binaries for x86_64 and
ARM64, so the npm and curl installers use the same download on Debian, Ubuntu,
Alpine, and other Linux distributions. Native GNU alternatives built on
Ubuntu 22.04 are also attached as smith-<arch>-linux-gnu.tar.gz.
Every release includes SHA256SUMS. For a manually downloaded archive:
sha256sum --check --ignore-missing SHA256SUMSPortable Linux builds retain Secret Service/keyring support. On a headless
server without a credential service, guided setup can instead record an
environment reference or explicitly store the API key in owner-only
~/.smith/config.toml.
cargo run -p smith-cli -- # interactive TUI
cargo run -p smith-cli -- setup # guided provider/model setup
cargo run -p smith-cli -- -p "explain this repo" # one headless turn
cargo run -p smith-cli -- sessions list
cargo run -p smith-cli -- config explain model
cargo test --workspace
cargo clippy --workspace --all-targetsSmith discovers the nearest .smith/config.toml, then layers user,
project-local, profile, SMITH_*, and CLI settings.
A plain interactive smith inspects configuration before entering raw terminal
mode. A genuinely empty install opens guided setup; a partial or malformed
configuration is reported as invalid and is never overwritten. Headless,
piped, machine-output, session-list, and config-explain commands remain
non-interactive and non-mutating.
The first-run GLM path configures Z.AI's Coding Plan endpoint and glm-5.2,
including the verified 1M context/input limits, 131,072 model-output ceiling,
Smith's 32,768 per-request output budget, and compatibility policy for
providers that deliver a successful final answer only as reasoning content.
Ongoing changes use the same reusable surface:
smith setup
smith setup add-provider
smith setup add-model
smith setup add-model --provider openrouter
smith setup credential --provider openrouter
smith setup checkpoint-keyThe generic provider path asks for a stable provider name, OpenAI-compatible
base URL, credential reference, exact model ID, explicit model limits, response
behavior, and whether the new pair becomes the default. add-model adds a
model beneath an existing provider without redeclaring that provider.
API-key input is masked. Authentication offers three explicit storage models:
- Keychain / Secret Service is the default and gives the strongest at-rest protection, but the operating system may ask for access again—especially for a locally rebuilt binary.
- An environment reference such as
env:OPENROUTER_API_KEYleaves storage to the shell or an external secret manager. Smith stores only the variable name. - “Store in config (no prompts)” writes
api_key = "…"only to the owner-only user file~/.smith/config.toml. This is self-contained and avoids credential-service prompts, but it is plaintext: other processes running as the same OS user and backups can read it.
The local-config choice is never an automatic fallback. Setup warns before
accepting it, masks the input, renders api_key = [redacted] during review,
and publishes the config through a mode-0600 atomic replace. Project and
project-local files cannot contain api_key; ordinary startup also refuses an
inline-key user config that is a symlink, non-regular, owned by another user,
or group/world accessible.
Trusted local model bridges can also use the command-jsonl provider kind.
They run through the same TUI/headless runtime and Smith-owned MCP/tool loop as
native providers, with a strict revisioned stdin/JSONL protocol and bounded
process supervision. This is not direct support for autonomous coding CLIs
such as Codex app-server. See Local command model providers
for configuration, protocol, and trust requirements.
Before committing, setup shows the secret-free change and exact destination,
then performs a local factory preflight. A failed preflight restores the exact
prior config bytes and any Keychain value it replaced. Runtime credential
reads have a 30-second startup boundary, so a hidden or unanswered platform
unlock prompt fails with an env:<VAR> recovery hint instead of hanging.
smith setup credential --provider <name> changes only that existing
provider's credential source; it does not rewrite its endpoint, models,
limits, profiles, or default.
The same credential funnel is available at an idle TUI boundary with
/connect [PROVIDER]; omitting the name opens a searchable provider picker.
/disconnect [PROVIDER] removes only that authentication source, and
/status reports the connection method/readiness without showing a key,
account ID, or credential locator. OpenRouter is built in: /connect openrouter fixes https://openrouter.ai/api/v1, offers the normal protected
credential choices, and hands off to a reviewed catalog-model picker with
enforceable limits. Existing OpenRouter connections change only authentication.
Google Gemini is also built in. Create an API key in Google AI Studio,
then run /connect google, choose protected API-key storage (or an environment
reference), and select a catalog-backed Gemini model. Smith uses Google's native
Gemini Interactions API with a fixed endpoint; it does not ask for an endpoint,
limits, headers, or hosted-tool settings, and it writes no explicit model record.
ChatGPT subscription login is deliberately different and explicitly
experimental. /connect chatgpt offers Smith-owned browser PKCE or device-code
login in a bounded popup, stores one renewable token bundle in the chatgpt
entry of the fixed owner-only plaintext file ~/.smith/auth.json, and adds a
trusted chatgpt/gpt-5.6-terra model. Smith creates ~/.smith as mode 0700
and auth.json as mode 0600; same-user processes and backups can still read
or retain these tokens, so treat the file like a password. ChatGPT connect,
startup, refresh, reconnect, and disconnect never query Keychain or Secret
Service.
Smith then calls the fixed ChatGPT Codex Responses endpoint directly through
its normal runtime, so Smith tools, approvals, attachments, steering, goals,
checkpoints, persistence, cancellation, recovery, events, and usage remain in
force. No Codex executable or another client's auth cache is used.
This subscription-token endpoint is not a supported public OpenAI Platform API
contract and may change without compatibility notice. Use an OpenAI Platform
API-key provider when a supported integration is required. /disconnect chatgpt removes Smith's protected bundle while preserving the endpoint and
model declaration.
If an earlier Smith build stored ChatGPT at keychain:smith/chatgpt, that
legacy entry is intentionally neither read nor deleted. Start Smith with
another configured provider, run /connect chatgpt, and complete a fresh login
to publish authfile:chatgpt. Remove the old Keychain item manually only if you
want to clean it up without involving Smith.
Checkpoint protection is configured separately. smith setup checkpoint-key
offers owner-only inline storage, an environment-variable reference, or OS
protected storage. Inline/environment choices never initialize Keychain or
Secret Service, remain redacted in config explanation and journals, and keep
the exact checkpoint authenticated-encrypted. Source changes refuse without
modification while encrypted checkpoints exist, so old resumable state is
never silently abandoned.
Encrypted file: references are reserved for a future externally unlocked
encrypted-store backend; Smith does not silently treat a plaintext file as
encrypted storage. When rotating a key, revoke the old key at the provider,
rerun credential setup (or carefully replace the user-only api_key), verify
chmod 600 ~/.smith/config.toml, and account for retained backup copies.
For local development, a minimal offline smoke configuration is:
default_profile = "dev"
profile_order = ["dev", "review"]
[profiles.dev]
provider = "local"
model = "example-model"
description = "local implementation"
posture = "build"
use = ["main", "child"]
instructions = "Implement the request and verify the result."
[profiles.review]
extends = "dev"
description = "read-only independent review"
posture = "review"
use = ["main", "child"]
instructions = "Report prioritized evidence-backed findings."
[providers.local]
kind = "fake"
[models."local/example-model"]
context_tokens = 128000
max_input_tokens = 124000
max_output_tokens = 4096Inside the empty idle TUI, the footer identifies the active agent profile
beside provider/model and context confidence. Tab cycles the main-enabled
profiles in profile_order only at that safe empty/idle boundary. If the order
is omitted, Smith derives it deterministically from real main-enabled profiles;
guided setup creates build, plan, and review variants explicitly. @
completes canonical workspace files and child-enabled profiles, plus retained
child IDs available for follow-up; leading ! runs the canonical
prepared local-shell path without a provider request. @@ and !! are the
literal escapes. /details, /timeline, and /redo expose bounded live work,
canonical session evidence, and exact recovery locally.
Ctrl+P opens the command palette. /model, /provider, /connect,
/disconnect, /profile, and /resume need no argument: each opens a
searchable local list with current and unavailable states. Explicit values
remain validated shortcuts. Model rows are always provider-qualified, so
selecting a model applies its provider/model pair atomically; selecting a
provider with several models cascades into that provider's model list.
/think [on|off|default] and /effort [LEVEL|default] use the same local
picker grammar and require an idle turn. Model metadata supplies picker choices
and provider-specific request formats. OpenAI-compatible endpoints receive
explicit reasoning selections even when the model is missing from the catalog
or its advertised effort list is incomplete; unsupported values are reported
by the endpoint. The effective state, effort, and source are visible in
/status and /context, and a non-default override is shown in the wide
footer. These choices can affect latency, token use, and cost.
For a private OpenAI-compatible endpoint, an explicit effort is sent as
top-level reasoning_effort unless a different reasoning format is configured.
Thinking off sends none; thinking on uses the configured default effort or
medium when no effort was selected. Omitting a selection preserves the
provider's defaults. Optional model metadata supplies picker choices and
request-format overrides:
[models."my-provider/my-model".reasoning]
dialect = "openai-effort"
efforts = ["low", "medium", "high"]Set the desired effort = "high" in [profiles.<name>.reasoning] or use
--effort high. A missing control declaration does not block the request, and
Smith does not issue extra completion requests to probe support. Other native
adapters still require reasoning controls their request format can represent.
smith --resume likewise opens a project-session picker before any host is
constructed. smith --resume <session-id> remains the explicit form, while
headless use without an ID is refused with a smith sessions list hint.
Session rows include the full ID, updated time, turn count, provider/model, and
a bounded preview when known.
/agent lists retained child sessions with durability, child-session ID,
state, cumulative turns/tokens, and bounded incompatibility. /agent resume <child-id> is intentionally explicit and has no Enter-default confirmation;
it resumes the exact interrupted turn rather than consuming a new child task
slot.
For runtime changes Smith restores the normal terminal, saves the current
session, re-runs complete preflight through smith-runtime, and resumes the
same identity. It never swaps an immutable runtime during a turn and the local
pickers never contact a provider.
/model is not limited to model IDs copied into TOML. Smith ships a reviewed,
generated Models.dev snapshot and augments configured providers only when an
available OpenAI-compatible adapter has one of these exact normalized
endpoints:
| Configured endpoint | Catalog |
|---|---|
https://api.openai.com/v1 |
Models.dev openai |
https://openrouter.ai/api/v1 |
Models.dev openrouter |
https://api.z.ai/api/coding/paas/v4 |
Models.dev zai-coding-plan |
native gemini-interactions provider |
Models.dev google |
The configured provider name remains authoritative. A provider named router
at the OpenRouter endpoint therefore exposes choices such as
router/openai/gpt-5.2; a provider merely named openrouter at another
endpoint inherits nothing. Catalog data never creates a provider or imports
Models.dev endpoint, package, environment, header, or credential settings.
Startup uses a schema-validated last-good cache at
~/.smith/cache/models-dev-v1.json, falling back to the embedded seed when the
cache is absent, corrupt, truncated, oversized, or from the wrong origin. A
stale snapshot schedules a bounded credential-free refresh from exactly
https://models.dev/api.json; redirects, timeouts, bad status, responses over
8 MiB, and invalid metadata leave the current snapshot untouched. Publication
is atomic, and a successful refresh is visible only to a later host rebuild.
Deleting the cache safely restores the embedded seed.
Custom OpenAI-compatible providers also discover models through their own
authenticated GET <base_url>/models listing. Smith caches validated IDs,
limits, modalities, capabilities, and any published prices under
~/.smith/cache/provider-models-v1/. Metadata stays scoped to the provider,
endpoint, and account; an alias such as selected-large never inherits another
vendor's price. Missing prices remain unknown.
Smith refreshes enabled sources every 24 hours while running and catches up on startup. Offline or failed refreshes retain the last-good cache. Updates join the model picker at an idle rebuild without changing the selected model, an active request, or historical usage prices. No system scheduler is installed. An immediate refresh is also available:
smith models sync
smith models sync --provider xiaoge --forceTo disable automatic refresh or change its interval, use owner-controlled
~/.smith/config.toml:
[model_sync]
enabled = true
interval_hours = 24 # 1 through 168smith setup add-model --provider xiaoge offers discovered models before manual
entry, prefills their published limits, and asks only for missing context.
Explicit model overrides keep precedence; a derived request output budget
does not replace a published or explicit output ceiling.
Catalog rows show display name, provider-qualified ID, enforceable limits,
capabilities, revision/age, and advertised provenance. Deprecated rows are
omitted; entries without text output, tool calling, valid limits, or a usable
input budget remain searchable but disabled with a reason. Advertisement is
not entitlement—the provider can still reject a model for account, plan,
region, or rollout reasons.
Explicit [models."<provider>/<model>"] fields override catalog fields
independently. Smith's embedded trusted GLM metadata remains above the cached
catalog, and picker selection plus runtime preflight use the same frozen
snapshot so a background refresh cannot change an active session underneath
it.
For a real endpoint, set the provider kind to openai-compatible, add its
base_url, and choose exactly one credential source. A reference keeps the
key outside the config:
[providers.remote]
kind = "openai-compatible"
base_url = "https://provider.example/v1"
credential = "env:PROVIDER_API_KEY"
[providers.remote.response]
reasoning_only = "text" # only when this provider needs the compatibility policyThe explicit no-prompt user-config form is:
# ~/.smith/config.toml only; never a project .smith/config*.toml
[providers.remote]
kind = "openai-compatible"
base_url = "https://provider.example/v1"
api_key = "replace-with-the-provider-key"The selected model must also resolve accurate context_tokens,
max_input_tokens, and max_output_tokens from explicit
[models."<provider>/<model>"] fields, trusted embedded metadata, or a
validated bound catalog. Smith refuses to guess missing limits.
The ignored smith-cli live test exercises the installed process, production
HTTP transport, streaming adapter, real read tool, continuation request,
provider-reported usage, clean shutdown, and credential redaction. It disables
persistence, allows no retries, explicitly auto-approves the isolated temporary
workspace, permits two tool rounds, caps each provider response at 2,048 tokens,
and has a 150-second outer deadline.
For a Z.AI Coding Plan account, export the API key as
SMITH_LIVE_API_KEY through a secret-safe shell or credential tool, then run:
SMITH_LIVE_BASE_URL=https://api.z.ai/api/coding/paas/v4 \
SMITH_LIVE_MODEL=glm-5.2 \
SMITH_LIVE_CONTEXT_TOKENS=1000000 \
SMITH_LIVE_MAX_INPUT_TOKENS=1000000 \
SMITH_LIVE_MAX_OUTPUT_TOKENS=131072 \
cargo test --all-features -p smith-cli --test live_provider -- --ignored --nocaptureThe key is never written to project configuration. Unset
SMITH_LIVE_API_KEY after the run. Other OpenAI-compatible endpoints can use
the same test with their documented model limits.
live_conformance is an ignored, quota-spending suite for the routes in your
real ~/.smith/config.toml. It runs sequentially through two-read tool turns,
session continuation, SIGKILL after a successful tool result and resume, every
ordered pair of distinct routes, and optional hosted-search-plus-tool turns.
Routes split at the first / into --provider and --model; model names may
contain further slashes. For example:
mkdir -p /private/tmp/smith-fixture-tmp
CARGO_TARGET_DIR=/private/tmp/smith-conformance-target \
TMPDIR=/private/tmp/smith-fixture-tmp \
SMITH_LIVE_CONFORMANCE_MODELS=google/gemini-4-argon,chatgpt/gpt-5.6-luna \
SMITH_LIVE_CONFORMANCE_SEARCH=google/gemini-4-argon \
cargo test -p smith-cli --test live_conformance -- --ignored --nocaptureSMITH_LIVE_CONFORMANCE_MODELS is required even with --ignored; an unset or
empty value does no work. SMITH_LIVE_CONFORMANCE_SEARCH is an optional subset
of those routes with hosted search. SMITH_LIVE_CONFORMANCE_BINARY optionally
selects a binary instead of Cargo's built smith.
SMITH_LIVE_CONFORMANCE_REPORT_DIR defaults to target/live-conformance at the
workspace root; relative overrides also resolve from that root.
The suite keeps your HOME, credentials, and profiles, creates fixtures beneath
the system temporary directory, uses headless --approval deny (read-only
workspace tools work; authority-bearing tools are denied), and bounds each
process to 180 seconds. Child-process automatic approval rules are cleared so
they cannot override deny. Project persistence overrides are rejected by the host,
so it queries the binary's configured session store and removes only files for
session IDs reported by its own runs. Persistence and mid-turn durability must
be available in your real configuration for resume scenarios to pass.
report.json preserves per-turn answers, token usage and provenance, optional
cache-read percentages, session IDs, timings, and failure diagnostics.
report.md contains a table and full errors with the last 20 stderr lines
(lines containing api_key are dropped), and is printed with --nocapture.
Multiple turns appear in execution order; interrupted turns have no final
envelope, so their usage is unavailable. Cache percentages are never asserted.
Failures are collected before the test fails; unselected search routes and
cross-provider checks with fewer than two routes are reported as skips.
The live direct ChatGPT Responses smoke test is ignored by default because it
requires explicitly injected test credentials and may spend provider quota. It
never reads Smith's Keychain entry. Have a secret-safe test runner inject
SMITH_CHATGPT_TEST_ACCESS_TOKEN and SMITH_CHATGPT_TEST_ACCOUNT_ID, then run:
cargo test -p smith-runtime live_chatgpt_responses -- --ignored --nocaptureHeadless mode accepts a direct prompt or stdin and keeps machine stdout clean:
smith -p "review this change"
printf '%s' "run the checks" | smith -p -
smith -p "summarize" --output-format json
smith -p "inspect" --output-format stream-json
smith -p "continue" --resume session-...json emits one schema-v3 result. stream-json emits versioned Smith-client events
followed by that result. Results project attempt commits/discards, the frozen
activation epoch, todo counts/items when public, artifact references, recovery
metadata, optional final goal state and continuation count, prepared approval
authority, and interaction-required state. A
forced live questionnaire—or a protected pending question on resume—returns
interaction_required with exit status 5 and never reads prompt stdin; resume
the same session interactively to answer the exact request. With the default
approval.mode = "ask", an unattended mutation is denied and exits with status
4; explicitly choose --approval allow-all only in an already trusted
automation boundary. See docs/headless-protocol.md
for the complete stdout, schema, redaction, and exit contract.
--yolo is the explicit shorthand for --approval allow-all; it never adds
tools removed by a read-only profile, so smith --profile plan --yolo remains
read-only.
Filesystem tools can also access paths outside the project after permission.
--yolo grants that permission automatically. Relative paths still start at
the project, and reading an image returns image content to a model that accepts it.
Repository-controlled config cannot set allow-all or add [[approval.auto]]
grants merely by being opened; those authority-bearing choices must come from
user config or an explicit command-line policy. Legacy non-empty
approval.auto_approve tool-name lists are rejected. It likewise cannot redirect or disable
user-scoped snapshots and journals.
Snapshots and redacted canonical event journals live under
~/.smith/sessions/<project-id>/. Exact in-flight state uses a separately
encrypted, authenticated checkpoint; artifacts are owner-only and
session-authorized. Completed turns save immediately. On restart, unresolved
children and process-owned monitor markers are reported interrupted and are
never silently restarted. Both the TUI and smith -p use the same factory and
session lifecycle. See
docs/persistence-recovery.md.
DESIGN.md is the visual and interaction contract for the TUI —
layout, glyphs, color, focus, motion, and the rules that keep an estimated
number from looking like a reported one. Code comments reference its sections.
docs/GOAL.md defines the first release outcome, evidence
gates, runtime co-development boundary, and deliberately deferred work.
docs/ci.md documents the fail-closed local and hosted release
gates and the exact Agent Runtime source they require.
docs/configuration.md is the typed configuration
reference, and docs/security.md records Smith's threat
model and trust boundaries.
The current behavioral contracts live under docs/spec/specs/.
Completed proposals and their implementation evidence live under
docs/spec/changes/archive/.
Smith is licensed under either the MIT License or Apache License 2.0, at your
option. See LICENSE-MIT and
LICENSE-APACHE.