sno code
AI coding agent — works with any codebase, native intelligence for Synoema
What is sno code?
sno code is a terminal-based AI coding agent shipped as part of the Synoema toolchain. It operates in two distinct modes:
Synoema Mode →
Deep language integration — type-aware edits, contract verification, MCP tools, RAG retrieval from the Synoema knowledge base. Auto-activated when sno.toml or .sno files are detected.
Universal Mode →
Works with any codebase — Rust, Python, TypeScript, JavaScript, Go, and more. Same agent loop, same profile system, same observability. No Synoema knowledge required.
Command Reference →
All subcommands: profiles, sessions, config, pipeline, doctor, stats, observability. Detailed flags and usage examples.
Quick Start
Install
curl -fsSL https://synoema.tech/install.sh | sh
sno code version
The installer places sno-code at ~/.sno/bin/sno-code. The sno code command auto-delegates to this binary.
First run
# Interactive setup — choose provider, model, store API key
sno code init
# Ask a question about your codebase
sno code -p "explain the auth flow in this project"
# Start an interactive session
sno code
Batch mode
# Single-turn prompt, text output
sno code -p "add input validation to the signup handler"
# JSON output for scripts
sno code -p "list all TODO comments" --output-format json
# Pipe a prompt from stdin
echo "refactor the database module" | sno code
How It Works
Project type detection
sno code auto-detects your project type on startup and tailors its behavior accordingly:
| Mode | Detection rule | Effect |
|---|---|---|
| Synoema | sno.toml present, or ≥50% .sno files | Full language integration: typecheck, contracts, MCP, RAG |
| Mixed | .sno files + other languages | Synoema tools active alongside general tools |
| Rust | Cargo.toml, ≥70% .rs files | Cargo-aware context |
| Python | pyproject.toml, ≥70% .py files | Python-aware context |
| TypeScript | tsconfig.json, ≥70% .ts/.tsx files | TS-aware context |
| JavaScript | package.json, ≥70% .js/.jsx files | JS-aware context |
| Go | go.mod, ≥70% .go files | Go-aware context |
| Generic | No dominant language | General-purpose agent tools |
Override detection: sno code --project-type rust
Permission modes
Control what the agent can do without asking:
| Mode | File edits | Shell commands | Read-only tools |
|---|---|---|---|
ask (default) | Prompt | Prompt | Auto |
auto-edits | Auto | Prompt | Auto |
plan | Denied | Denied | Auto |
autonomous | Auto | Auto | Auto |
sno code --mode auto-edits -p "fix the failing test"
sno code --plan -p "how would you restructure the auth module?"
sno code --autonomous -p "update all dependencies and fix breakage"
Autonomous mode requires explicit TTY confirmation or SNO_AUTONOMOUS_CONFIRMED=1.
Worktree isolation
Run the agent in a dedicated git worktree so your working tree stays untouched:
sno code --worktree -p "refactor the payment module"
# Agent works in ~/.sno/worktrees/sno/refactor-payment-7n2qpm/
# Your working directory is unchanged
Auto-generated branch names follow the pattern sno/{type}-{slug}-{ulid} (e.g., sno/refactor-payment-7n2qpm). The branch type is inferred from the prompt.
Multi-Provider Profiles
sno code supports 30+ LLM providers through a unified profile system. Switch between providers without changing your workflow.
Configuration cascade
Settings are resolved in order (highest priority first):
- CLI flags (
--profile,--model,--base-url) - Environment variables (
SNO_PROFILE,SNO_MODEL) - Project config (
./.sno/config.toml) - User config (
~/.sno/config.toml)
Example config
# ~/.sno/config.toml
[providers.anthropic]
env_key = "ANTHROPIC_API_KEY"
[providers.deepseek]
base_url = "https://api.deepseek.com/v1"
env_key = "DEEPSEEK_API_KEY"
api_kind = "openai_compat"
[profiles.default]
provider = "anthropic"
model = "claude-sonnet-4-6"
[profiles.cheap]
provider = "deepseek"
model = "deepseek-coder"
[agent]
active = "default"
# Switch profiles
sno code use cheap
sno code current # → cheap
# Or override inline
sno code --profile default -p "complex refactor"
Role-based model routing
Assign different models to different tasks within a single profile:
| Role | Used for | Typical model |
|---|---|---|
| Default | Primary agent reasoning | claude-sonnet-4-6 |
| Weak | Loop detection, classification | claude-haiku-4-5 |
| Think | Extended reasoning, planning | claude-opus-4-7 |
| Embed | RAG retrieval, corpus search | bge-m3 (via Ollama) |
[profiles.advanced]
provider = "anthropic"
model = "claude-sonnet-4-6"
weak_model = "anthropic/claude-haiku-4-5"
think_model = "anthropic/claude-opus-4-7"
embed_model = "ollama/bge-m3"
Context System
The agent assembles context from multiple sources, merged into the system prompt in load order:
AGENTS.md hierarchy
Discovered bottom-up from the current directory to the repository root:
~/.sno/AGENTS.md # User-global defaults
repo/AGENTS.md # Repository-wide context
repo/src/AGENTS.md # Subsystem context
repo/src/auth/AGENTS.md # Module-specific context
Each file is injected with a # Context: <path> header. Total context above 50 KB triggers a warning.
SNO.md overlay
Synoema-specific context files that layer on top of AGENTS.md:
repo/SNO.md # Synoema-specific overlay
repo/src/SNO.md # Subsystem overlay
Skills
Reusable task templates stored as SKILL.md files:
# ~/.sno/skills/typecheck-then-test/SKILL.md
---
name: typecheck-then-test
description: After every typecheck, run cargo test
allowed_tools: [bash, file_read]
model: claude-haiku-4-5
---
After running sno check, always run cargo test...
Skills are discovered from ~/.sno/skills/ (user) and .sno/skills/ (project). Project skills take precedence on name collision.
Sessions & Observability
Session persistence
Every conversation is stored as append-only JSONL with event lineage (UUIDv7 parent chains):
~/.sno/projects/<project-hash>/<session-uuid>.jsonl
Events: user, assistant, tool_use, tool_result, summary, git_snapshot.
# List sessions
sno code sessions list
sno code sessions list --json
# Inspect a session
sno code sessions show 01J5...
Multi-session registry
Running sessions register in ~/.sno/sessions/ with heartbeat-based liveness detection (stale after 30 seconds).
Budget system
Multi-dimensional limits prevent runaway sessions:
| Dimension | Default |
|---|---|
| Max turns | 25 (CLI) / 50 (internal) |
| Max seconds | 600 (10 min) |
| Max tool calls | 200 |
| Max cost | $10.00 |
| Max input tokens | 1,000,000 |
| Max output tokens | 200,000 |
Warnings at 70%, 85%, and 90% of each dimension.
OpenTelemetry
Structured observability with GenAI semantic conventions. Three exporters: file (JSONL), stdout (pretty), OTLP.
sno code otel status # Current config
sno code otel test # Emit a test span
SNO_TRACE=1 sno code -p "..." # Enable tracing for one run
Privacy-first: prompt/response content is excluded by default (include_body = false). Counts, IDs, latency, and cost always pass through.
Pipeline Execution
Define multi-stage workflows in TOML and execute them as a single pipeline:
sno code pipeline --from ci-pipeline.toml
sno code pipeline --from ci-pipeline.toml --dry-run
sno code pipeline --from ci-pipeline.toml --json
Pipelines contain stages (sequential or parallel), each with multiple tasks. Dry-run validates the structure and prints stage/task counts without executing.
License
sno code is licensed under BUSL-1.1 with a broad Additional Use Grant. Free for personal, research, education, open-source, internal commercial, and CI/CD use. The restriction applies only to reselling as a hosted Commercial LLM Service. Each release converts to Apache-2.0 after 7 years.
Synoema Mode →
Type-aware edits, contract verification, MCP tools, RAG retrieval.
Universal Mode →
Rust, Python, TypeScript, Go — any language, same agent.
Command Reference →
All subcommands with flags, defaults, and examples.