seed-cli logo

seed-cli

Spec-driven filesystem orchestration, scaffolding, and maintenance

seed-cli

Terraform for your filesystem

Define, version, and replicate directory structures declaratively

Browse Recipes →

Immutable Plans

Export plans to JSON, review them, then apply the exact plan later.

Scaffolding

Use reusable templates, content sources, and Copier-style template config.

Maintenance

Plan or execute repository, service, and system upkeep from manifests.

History & Locks

Snapshots, spec history, structure locking, and state locks keep changes auditable.


Quick Start

1. Install

pip install seed-cli
pip install "seed-cli[image]"   # OCR/image parsing
pip install "seed-cli[ui]"      # rich terminal output

2. Capture and plan

seed capture --out project.tree
seed plan project.tree --out plan.json

3. Apply the saved plan

seed apply plan.json

4. Maintain repositories or services

seed maintain maintenance.yml
seed maintain maintenance.yml --execute

Highlights

Global Options

Available on all commands:

seed [command] --verbose          # enable verbose logging
seed [command] --debug            # enable debug logging
seed [command] --ignore PATTERN   # extra ignore patterns
seed [command] --targets PATTERN  # extra target globs
seed [command] --target-mode {prefix,exact}  # target matching mode

Commands & Workflow

seed plan <spec>

Parse a spec and build a deterministic execution plan without modifying the filesystem.

--base BASE base directory (default: current directory)
--vars VARS template variables (key=value)
--out OUT write the plan as JSON
--dot export the plan as Graphviz DOT
--no-skip hide SKIP lines in console output
seed plan project.tree
seed plan project.tree --vars environment=prod
seed plan project.tree --out plan.json
seed plan project.tree --dot > plan.dot

seed apply <spec-or-plan>

Apply a spec directly or execute a previously saved plan. When applying a spec, seed also registers project-local templates and removes stale literal placeholder paths from older runs.

--base BASE base directory (default: current directory)
--dangerous allow dangerous plan steps when needed
--dry-run preview execution without writes
--yes, -y create all optional items
--skip-optional skip all optional items
seed apply project.tree
seed apply plan.json
seed apply project.tree --base ./myproject
seed apply project.tree --dry-run

seed register <spec>

Register any .tree spec into project .seed support files. If the spec contains template placeholders, seed also extracts project templates and removes stale literal placeholder paths such as <name>/.

--base BASE base directory (default: current directory)
--vars VARS template variables (key=value)
seed register project.tree
seed register project.tree --base ./myproject

seed diff <spec>

Compare a spec with the current filesystem and show missing, extra, or drifted paths.

--base BASE base directory (default: current directory)
--ignore PATTERN ignore matching paths (repeatable)
--no-sublevels hide extras inside directories already defined in the spec
seed diff project.tree
seed diff project.tree --ignore "*.pyc" --ignore "__pycache__"
seed diff project.tree --no-sublevels

seed maintain <manifest-or-dir>

Build or execute repository, project, service, and system maintenance plans from YAML or JSON manifests.

--execute run the generated commands instead of only printing the plan
seed maintain maintenance.yml
seed maintain ./workspace
seed maintain ./workspace --execute

seed capture

Capture the current filesystem state as a spec, JSON document, or DOT graph.

--base BASE base directory (default: current directory)
--json output JSON instead of tree text
--dot output Graphviz DOT
--out OUT write to a file instead of stdout
seed capture --out project.tree
seed capture --json --out project.json
seed capture --dot --out project.dot

seed create

Create a new instance from a spec with template directories, a mirrored project template path, or a registered project template name.

--template TEMPLATE use a project template path under .seed/templates/
--project PROJECT use a registered project template name
--base BASE base directory (default: current directory)
--dry-run preview what would be created
seed create releases.tree version_id=v3
seed create --template .seed/templates/releases.tree version_id=v3
seed create --project version_id version_id=v3
seed create releases.tree version_id=v3 --dry-run

Sync & Match

These commands modify the filesystem to match your spec exactly, including deleting extra files. Use with caution.

seed sync <spec> dangerous

Same as apply, but also deletes extraneous files. Plugins may veto deletions. Requires --dangerous flag.

--base BASE Base directory (default: current directory)
--dangerous Required flag to enable sync (not required with --dry-run)
--dry-run Show what would be executed without making changes
--yes, -y Create all optional items (marked with ?) without prompting
--skip-optional Skip all optional items (marked with ?) without prompting
# Preview what would be synced
seed sync project.tree --dry-run

# Actually sync (deletes extra files!)
seed sync project.tree --dangerous

# Sync with auto-create optionals
seed sync project.tree --dangerous --yes

seed match <spec> dangerous

Modify filesystem to match the spec. Creates missing items and deletes extras. Use ... in spec to mark directories where extra files are allowed.

--base BASE Base directory (default: current directory)
--dangerous Required flag (will create/delete files). Not required with --dry-run
--dry-run Preview changes without modifying filesystem
--yes, -y Create all optional items (marked with ?) without prompting
--skip-optional Skip all optional items (marked with ?) without prompting
# Preview what would change
seed match project.tree --dry-run

# Match filesystem to spec (creates and deletes!)
seed match project.tree --dangerous

# Match specific directory
seed match project.tree --base ./target --dangerous

Protecting Directories from Deletion

Use ... to mark directories where extra files should be preserved:

project/
├── src/
│   └── main.py
├── data/       ...   # Extra files here won't be deleted
└── config.yaml

Spec Syntax

Spec files use an intuitive tree-like syntax. Supports .tree, .seed, .yaml, .json, .dot, and even images.

Basic Structure

project/
├── src/
│   ├── main.py
│   └── utils/
│       └── helpers.py
├── tests/
│   └── test_main.py
├── config.yaml
└── README.md

Annotations

scripts/
├── build.py      @generated
├── config.json   @manual
├── cache/        ...
└── docs/?

.seed Metadata

Use .seed when tree nodes need inline metadata for semantic kind, tags, or content/source URLs. Directory URLs can hydrate template content from remote sources.

vendor/
└── api/ !service +remote -> https://github.com/acme/api-client.git

Structured YAML and JSON specs can carry the same data with a metadata object or top-level kind, tags, and url fields.

Template Variables

Create reusable specs with dynamic values:

<project_name>/
├── src/
│   └── <module_name>/
│       └── __init__.py
├── <environment>/
│   └── config.yaml
└── README.md

Using Variables

# With seed plan/apply
seed apply spec.tree --vars project_name=myapp module_name=core

# With seed create
seed create spec.tree project_name=myapp environment=prod

Includes

Import other spec files to compose larger structures:

@include base.tree
@include ./shared/common.tree

project/
├── custom/
└── specific.py

Templates & Scaffolding

Use the registry for reusable templates, or create directly from project-local templates under .seed/templates/.

seed templates add <source>

Add a template from GitHub or a local .tree/.seed spec. Directory sources can contain spec.seed or spec.tree. Templates can also fetch real file contents from a content source.

--name, -n NAME template name (default: derived from source)
--version, -v VERSION version name (default: auto-increment)
--content-url URL local path, GitHub tree URL, or git repository URL for file contents
seed templates add ./template.tree --name my-template
seed templates add ./template.seed --name service-template
seed templates add ./fastapi --name fastapi \
  --content-url https://github.com/tiangolo/full-stack-fastapi-template/tree/master/backend/app
seed templates add ./service.seed --name service \
  --content-url https://github.com/acme/service-skeleton.git

seed templates use <name>

Apply a stored template with direct vars, data files, answers files, overwrite rules, and gated template tasks.

--version, -v VERSION version to use (default: current)
--base BASE base directory (default: current directory)
--vars VARS template variables (key=value)
--data-file FILE load variables from JSON or YAML
--defaults use template defaults for unanswered questions
--non-interactive fail instead of prompting for missing required answers
--answers-file FILE write resolved answers inside the target base directory
--unsafe allow execution of template-defined _tasks
--overwrite overwrite existing files when rendering content
--yes, -y apply without prompting
--dry-run preview the plan without applying it
seed templates use python-package --base ./myapp
seed templates use python-package --data-file answers.yml --defaults
seed templates use python-package --answers-file .seed/answers.yml
seed templates use python-package --unsafe --overwrite

seed templates list | show | versions | lock | update | remove

Inspect templates, manage versions, lock a template to a specific version, refresh content sources, or remove a template from the registry.

seed templates list
seed templates show python-package --version v1
seed templates versions python-package --add ./updated.tree --name v2
seed templates lock python-package --version v2
seed templates update --all
seed templates remove python-package

Project-Local Templates

Run seed register to mirror any .tree or .seed spec into .seed/templates/. If the spec contains template subtrees, seed also extracts nested project templates into .seed/templates/project/. seed apply <spec> runs the same registration step automatically.

seed register releases.tree
seed create --template .seed/templates/releases.tree version_id=v3
seed create --project version_id version_id=v3

Content Sources

Templates can include a source.json file so seed fetches actual file contents from a local directory, a GitHub tree URL, or a git repository URL. .seed directory nodes can also declare nested content sources inline with -> URL.

{
  "content_url": "https://github.com/owner/repo/tree/main/src"
}
vendor/
└── api/ !service +remote -> https://github.com/acme/api-client.git

The built-in fastapi, python-package, and node-typescript templates use this pattern. Template storage defaults to ~/.seed/templates/ and can be moved with SEED_HOME.

Copier-Style Config

Template configs are discovered from copier.yml, copier.yaml, .seed-template.yml, or .seed-template.yaml. seed understands question defaults, choices, _exclude, _skip_if_exists, _answers_file, and _tasks.

Versioning & Locking

Lock filesystem structures to a spec. Supports versioning and watch mode to prevent drift.

seed lock set <spec>

Set the active structure spec. Creates a version if needed.

--base BASE Base directory
--version, -v VERSION Version name (default: auto-increment)
# Set lock with auto-versioning
seed lock set project.tree

# Set lock with specific version name
seed lock set project.tree --version v1.0

# Set lock for specific directory
seed lock set project.tree --base ./myproject

seed lock watch

Watch filesystem and enforce structure continuously. Runs as a daemon to detect and report drift.

--base BASE Base directory
--interval INTERVAL Check interval in seconds
# Start watching with default interval
seed lock watch

# Watch with custom interval (every 5 seconds)
seed lock watch --interval 5

# Watch specific directory
seed lock watch --base ./myproject

seed lock list

List available structure versions.

--base BASE Base directory
seed lock list

seed lock status

Show current structure lock status including active version and any drift.

--base BASE Base directory
seed lock status

seed lock upgrade <version> dangerous

Upgrade to a newer structure version. Applies changes to bring filesystem to the new version.

--base BASE Base directory
--dangerous Apply changes (required)
--dry-run Preview changes
# Preview upgrade
seed lock upgrade v2 --dry-run

# Apply upgrade
seed lock upgrade v2 --dangerous

seed lock downgrade <version> dangerous

Downgrade to an older structure version.

--base BASE Base directory
--dangerous Apply changes (required)
--dry-run Preview changes
# Preview downgrade
seed lock downgrade v1 --dry-run

# Apply downgrade
seed lock downgrade v1 --dangerous

Snapshots & Specs History

Snapshots are created automatically before apply/match/sync operations. Use them to undo changes.

Revert Command

seed revert [snapshot_id]

Revert filesystem to a previous snapshot. Snapshots are created automatically before apply/match/sync operations.

--base BASE Base directory (default: current directory)
--list List available snapshots
--dry-run Preview what would be reverted
--delete ID Delete a specific snapshot
# List all snapshots
seed revert --list

# Revert to latest snapshot
seed revert

# Revert to specific snapshot
seed revert abc123

# Preview revert
seed revert abc123 --dry-run

# Delete a snapshot
seed revert --delete abc123

Specs History

View and manage automatically captured spec versions.

seed specs list

List all captured spec versions with timestamps and metadata.

--base BASE Base directory
seed specs list

seed specs show [version]

Show content of a spec version.

--base BASE Base directory
version Version to show (e.g., 1 or v1). Default: latest
# Show latest spec
seed specs show

# Show specific version
seed specs show v1
seed specs show 2

seed specs diff <v1> <v2>

Compare two spec versions to see what changed.

--base BASE Base directory
# Compare two versions
seed specs diff v1 v2
seed specs diff 1 3

seed specs watch

Poll the workspace and capture a new .seed/specs/vN.tree whenever the filesystem structure changes.

--base BASE Base directory
--interval INTERVAL Check interval in seconds
seed specs watch
seed specs watch --interval 2

Utilities

Doctor

seed doctor <spec>

Lint spec file and optionally auto-fix issues. Checks for syntax errors, invalid paths, and common mistakes.

--base BASE Base directory (default: current directory)
--fix Automatically fix issues when possible
# Check spec for issues
seed doctor project.tree

# Auto-fix issues
seed doctor project.tree --fix

Export

seed export <format>

Export filesystem state or plan in various formats: tree, json, plan, or dot.

--input INPUT Input spec or plan file (default: capture from filesystem)
--out OUT Output file path (required)
--base BASE Base directory (default: current directory)
# Export current filesystem as tree
seed export tree --out structure.tree

# Export as JSON
seed export json --out structure.json

# Export as Graphviz DOT
seed export dot --out structure.dot

# Export existing spec to different format
seed export json --input project.tree --out project.json

Hooks

seed hooks install

Install lightweight git hooks from seed. Use this when you want repository-local automation around your structure workflow.

--hook HOOK Hook name to install (default: pre-commit)
# Install default pre-commit hook
seed hooks install

# Install specific hook
seed hooks install --hook pre-push

Utils

seed utils extract-tree <image>

Extract tree structure from an image using OCR. Useful for converting screenshots of directory structures into spec files.

--out OUT Output .tree file path (default: image path with .tree extension)
--vars VARS Template variables (key=value)
--raw Output raw OCR text without cleaning (for debugging)
# Extract from screenshot
seed utils extract-tree screenshot.png

# Specify output path
seed utils extract-tree screenshot.png --out project.tree

# Debug OCR output
seed utils extract-tree screenshot.png --raw

seed utils state-lock

Manage execution state locks for concurrent access control. Use if a process crashed and left a stale lock.

--base BASE Base directory
--renew Renew existing lock
--force-unlock Force unlock (use if process crashed)
# Check lock status
seed utils state-lock

# Force unlock after crash
seed utils state-lock --force-unlock

# Renew existing lock
seed utils state-lock --renew

Shell Completion

seed integrates with argcomplete for shell tab completion.

eval "$(register-python-argcomplete seed)"
register-python-argcomplete --shell fish seed | source