CLI Reference
Run commands from the repository root unless --global is specified.
New to Tuff? Start with the Getting Started guide, then return here for the complete command and flag reference.
Command Groups
Section titled “Command Groups”| Group | Commands |
|---|---|
| Start | tuff init |
| Create or add capabilities | tuff create, tuff add |
| Inspect and generate | tuff list, tuff status, tuff generate, tuff outdated |
| Diff and update | tuff diff, tuff update |
| Validate in CI | tuff check |
| Clean up | tuff delete, tuff untrack, tuff cache clear |
| Configure agents and scope | tuff agent, scope behavior |
Show the ASCII banner and quick-start menu:
tufftuff init
Section titled “tuff init”Initialize Tuff state in the current directory:
tuff initInitialize global scope (for primitives shared across all projects):
tuff init --globalCreates tuff.lock (and a user-state lockfile for global scope),
scaffolds .agents/, and configures open-agents as the default agent.
Create or Add Capabilities
Section titled “Create or Add Capabilities”tuff create
Section titled “tuff create”Create and track a new agent-local capability:
tuff create skill my-skilltuff create tool my-tool -a claudetuff create hook review-hook -a open-agents -a claudetuff create workflow release-flow -a claudeThe capability type and id are positional. -a, --agent is optional and
repeatable. When omitted, Tuff uses the configured default agent. Creation
initializes Tuff state, registers the selected agents, writes adapter-valid
files, and records the baseline. Use -a <agent> when creating for a
different agent.
tuff add
Section titled “tuff add”Install a capability from a local capability directory or Git URL. The command supports two forms:
- Let Tuff infer the capability type from a local path.
- Use an explicit capability-type subcommand when the type is known or when installing from a Git repository.
The available capability types are skill, tool, hook, and workflow.
In the examples below, <capability-type> means “replace this placeholder
with one of those four types.”
Local sources
Section titled “Local sources”For a local capability directory, Tuff can infer the type from its location or from its manifest:
# Auto-detect the typetuff add ./my-skill
# Explicit typetuff add <capability-type> ./path/to/capability
# Explicit type with a selected agenttuff add <capability-type> ./path/to/capability --agent claude
# Multiple agentstuff add <capability-type> ./path/to/capability --agent claude --agent open-agents
# Global scopetuff add <capability-type> ./path/to/capability --globalFor typed capability commands, --agent and --global come after the source
and remain scoped to the selected capability type. For example:
tuff add tool ./my-tool --agent claudeFor typed capability commands, options come after the capability source:
# Agent and scope options stay with the typed commandtuff add tool ./my-tool --agent claude --globalAdd existing agent files in place without copying their content:
tuff add --agent open-agents .agents/skills/my-skilltuff add --agent claude .agents/skills/my-skillInstall from a git repository:
tuff add <capability-type> https://github.com/owner/repo <name> --agent open-agentstuff add <capability-type> https://github.com/owner/repo <name> --agent claudeFor Git sources, <name> is the capability directory name inside the
repository. For example:
tuff add skill https://github.com/owner/repo rust-implement --agent open-agentsUse the same structure for a tool, hook, or workflow by replacing skill with
the corresponding capability type.
For harness-native hooks, pass the hook fragment explicitly:
tuff add hook ./claude-session-start --agent claude --hook-file settings.jsonTuff-standard manifest hooks are validated against adapter compatibility and rendered to the target harness’s native settings. To inspect hook support or check a tracked hook before switching adapters:
tuff hooks matrixtuff hooks check-portability pre-commit-lint --target claude| Flag | Description |
|---|---|
-a, --agent <id> | Agent harness (optional, repeatable; defaults to configured agent) |
-g, --global | Install to global user scope |
--hook-file <path> | Hook-only native settings fragment, relative to the hook source directory |
The capability type is specified as a subcommand (skill, tool, hook, or
workflow) rather than a --type flag. For a typed local source, the name is
optional and is normally inferred from the source. For a Git source, the name
is required so Tuff knows which capability directory to discover.
Adding Existing Agent Files
Section titled “Adding Existing Agent Files”Bring existing agent assets under Tuff management without rewriting content:
tuff add --agent open-agents .agents/skills/python-uvBefore/after
Section titled “Before/after”Before add:.agents/skills/python-uv/ └── SKILL.md ← existing, unmanaged
After tuff add --agent open-agents .agents/skills/python-uv:.agents/skills/python-uv/ └── SKILL.md ← untouchedtuff.config.json ├── tuff.lock ← entry added └── objects/ └── sha256/ └── a1/ └── b2c3... ← immutable baseline objectAfter add, the directory participates in the full lifecycle. tuff list,
tuff diff, tuff check, and tuff update all work without modifying
your existing agent files. Use tuff update <id> to accept intentional local
edits as the new baseline.
Inspect and Generate
Section titled “Inspect and Generate”tuff list
Section titled “tuff list”Show installed capabilities with scope, drift status, and path:
tuff listFilters
Section titled “Filters”# By scopetuff list --scope projecttuff list --scope global
# By capability typetuff list --type skilltuff list --type tool
# Combine filterstuff list --scope global --type toolStatus values
Section titled “Status values”| Status | Meaning |
|---|---|
clean | Installed content matches recorded hash |
modified | Installed content has local changes |
missing | Installed file no longer exists |
tuff list uses terminal colors when supported: clean is green, modified is amber, and missing is red.
tuff status
Section titled “tuff status”Show per-primitive detail including scope, drift, and override warnings:
tuff statusExample output:
python-uv-default project clean [overrides global: won't receive global updates]commit-hygiene global cleanscan-tool project cleantuff generate
Section titled “tuff generate”Generate derived Tuff artifacts from tracked project state:
# Agent-facing capability indextuff generate index -a open-agentstuff generate index -a claude
# Custom index pathtuff generate index -a open-agents --output docs/CAPABILITIES.md
# Human-readable project reporttuff generate reporttuff generate report --output docs/tuff-report.mdtuff generate index writes the default index for the selected agent:
| Agent | Default output |
|---|---|
open-agents | .agents/CAPABILITIES.md |
claude | .claude/CAPABILITIES.md |
The generated index is intended for agent context. Point AGENTS.md,
CLAUDE.md, or equivalent agent instructions at the generated
CAPABILITIES.md file when you want the agent to see a compact inventory of
tracked capabilities.
tuff generate report writes tuff-report.md by default.
The report includes installed capabilities, agents, source type, emitted paths,
and clean/modified/missing status summaries.
Generated files are derived output. The source of truth is
tuff.lock tracking state.
tuff outdated
Section titled “tuff outdated”Show all installed capabilities and whether upstream updates are available. Read-only; never modifies files.
tuff outdatedExample output:
find-skills skill open-agents 2adcfe5 def5678 outdatedpre-commit-lint hook open-agents 1.0.0 none up to datesecurity-review tool claude abc1234 2adcfe5 outdatedFor git-sourced primitives, CURRENT and LATEST show the 7-character commit SHA.
For local primitives, LATEST shows none and status is always up to date or modified source.
Diff and Update
Section titled “Diff and Update”tuff diff
Section titled “tuff diff”Show unified diff between baseline and installed files, or compare against latest upstream:
# Local changes against baselinetuff diff <id>
# Upstream changes since last install (git-sourced only)tuff diff <id> --upstream
# Diff a specific agenttuff diff <id> -a claudeWhen color is enabled, diff headers are cyan, additions are green, and deletions are red,
matching the usual Git diff convention. Set NO_COLOR=1 for plain output.
tuff update
Section titled “tuff update”Update a capability according to its recorded source. In-place local capabilities accept
current edits as the new baseline; external local sources reload from sourcePath;
Git-sourced capabilities perform a three-way merge between baseline, local, and upstream.
See the lifecycle docs for the merge behavior table.
# Update the configured default agenttuff update <id>
# Dry run: show what would happen without applyingtuff update <id> --check
# Update a specific agent insteadtuff update <id> -a <agent>
# Force overwrite local changes with recorded source outputtuff update <id> --force
# Explicit scopetuff update <id> --scope globalValidate in CI
Section titled “Validate in CI”tuff check
Section titled “tuff check”Validate installed capabilities for CI. Exits 1 on any failure.
tuff check # check all capabilitiestuff check --json # machine-readable JSON outputtuff check --ignore-failures # report failures but exit 0Example output:
✓ python-uv-default skill open-agents ok✗ dirty-skill skill open-agents modified (.agents/skills/dirty-skill/SKILL.md)CI with GitHub Actions
Section titled “CI with GitHub Actions”Add this to your project’s .github/workflows/tuff-check.yml:
name: Tuff Checkon: [push, pull_request]
jobs: check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- name: Install Rust uses: actions-rs/toolchain@v1 with: toolchain: stable
- name: Build and install tuff run: cargo install tuffcli
- name: Validate capabilities run: tuff check --jsonCommit tuff.lock to your repo so
tuff check runs against the committed state. See the lockfile reference
for what to commit.
Clean Up
Section titled “Clean Up”tuff delete
Section titled “tuff delete”Delete Tuff-generated capability files for explicitly selected agents:
# Delete generated files for one agenttuff delete <id> -a open-agents
# Delete generated files for multiple agentstuff delete <id> -a open-agents -a claude
# Delete from global scopetuff delete <id> -a open-agents --scope global
# Delete files with local modificationstuff delete <id> -a open-agents --forceWhen -a/--agent is omitted, delete uses the configured agent. It removes emitted files, their baselines,
and generated tool MCP entries. It never deletes the original capability source
directory. Modified generated files require --force. In-place added capabilities
cannot be deleted; use tuff untrack instead.
tuff untrack
Section titled “tuff untrack”Stop tracking a capability for explicitly selected agents while preserving its agent files and manifest:
# Stop tracking an in-place added skill for the default agenttuff untrack my-skill
# Stop tracking several agentstuff untrack my-skill -a open-agents -a claude
# Stop tracking a global capabilitytuff untrack my-skill -a open-agents --scope globaluntrack removes the selected lockfile entry and baseline. It preserves the
capability files, source directories, and MCP configuration.
The lockfile itself remains in place, even when it contains no capabilities.
tuff cache clear
Section titled “tuff cache clear”Delete Tuff’s disposable machine-local cache of materialized trees and source clones. This does not remove project capability files or lockfile entries:
tuff cache clearConfigure Agents and Scope
Section titled “Configure Agents and Scope”tuff agent
Section titled “tuff agent”Configure the default agent
Section titled “Configure the default agent”# Project defaulttuff agent set-default open-agents
# Global defaulttuff agent set-default claude --globalCommands that accept -a/--agent use this value when the flag is omitted.
An explicit agent flag always overrides the default, and repeated flags still
apply an operation to multiple agents.
List available and registered agents
Section titled “List available and registered agents”tuff agent list
# Show the global defaulttuff agent list --globalRegister an agent
Section titled “Register an agent”tuff agent add open-agentstuff agent add claudetuff agent add codextuff agent add cursorRegistering an agent also creates its project directory (.agents/ or
.claude/) if it does not already exist.
claude-code remains an alias for claude. codex and cursor are dedicated adapter IDs.
The REGISTERED column shows which agents are available for Tuff operations in
the selected config. The DEFAULT column shows which registered agent is used
when -a/--agent is omitted.
Remove an agent
Section titled “Remove an agent”tuff agent remove open-agentsUnregisters the agent from the project configuration. It does not delete
capabilities, emitted files, baselines, MCP registrations, or lockfile entries.
Use tuff delete <id> or tuff untrack <id> for the configured default
agent. Pass -a <agent> when selecting a different agent.
Tuff supports two scopes:
| Scope | Location | Use |
|---|---|---|
project | tuff.lock in repo root | Shared with team via version control |
global | Tuff user state directory | Available across all projects |
Resolution order: project always wins. If the same primitive exists at both scopes,
the project copy shadows the global one. tuff status flags shadowed primitives.