The perfect pair for the `tree` program. Seed creates, updates and deletes file and folder structures in your codebase.
Project description
seed-cli
seed is a Terraform-inspired, spec-driven filesystem orchestration tool.
It captures directory trees, plans changes, applies them safely, syncs drift, scaffolds projects from reusable templates, and can also execute manifest-driven repository or service maintenance.
Think Terraform for directory trees, plus template scaffolding and workspace maintenance.
Highlights
- Multiple spec inputs:
.tree,.seed, YAML, JSON, DOT, image OCR, and stdin - Deterministic planning with exportable plans:
seed plan spec.seed --out plan.json - Safe execution of immutable plans:
seed apply plan.json - Drift workflows:
diff,sync,match, snapshots, and spec history - Template variables in paths and content:
<varname>/and{{var}} - Project-local template registration under
.seed/templates/ - Reusable template registry with versions, locking, content sources, and built-in templates
- Copier-style template config support: questions, defaults, answers files, excludes, skip-if-exists, and gated tasks
- Manifest-driven repository/service/system maintenance with
seed maintain - Structure locking, watch mode, state locks, hooks, Graphviz export, and shell completion
Install
pip install seed-cli
pip install "seed-cli[image]" # OCR/image parsing
pip install "seed-cli[ui]" # rich terminal output
Python >=3.10 is required.
Quick Start
Capture an existing directory, preview a plan, then apply it:
seed capture --out project.tree
seed plan project.tree --out plan.json
seed apply plan.json
For direct spec execution:
seed register project.tree
seed apply project.tree
seed diff project.tree
For repository or service automation:
seed maintain maintenance.yml
seed maintain maintenance.yml --execute
Commands
| Command | Description |
|---|---|
plan |
Parse a spec and generate an execution plan |
apply |
Apply a spec or a saved plan |
register |
Register .tree or .seed specs into project .seed/ files |
sync |
Apply a spec and delete extras |
diff |
Compare a spec with the filesystem |
match |
Modify the filesystem to match a spec, respecting ... |
maintain |
Build or execute repository/service/system maintenance plans |
create |
Instantiate template directory structures |
revert |
Revert to a previous snapshot |
doctor |
Lint a spec and optionally auto-fix issues |
capture |
Capture filesystem state as a spec |
export |
Export a tree, JSON spec, plan, or DOT graph |
lock |
Manage structure locks, versions, and watch mode |
hooks |
Install git hooks |
specs |
View captured spec history and watch for changes |
templates |
Manage reusable templates |
utils |
extract-tree and state-lock helpers |
Core Workflow
Immutable Plans
seed plan dir_structure.tree --out plan.json
seed apply plan.json
seed apply also accepts a spec directly:
seed apply dir_structure.tree
When you apply a spec with template placeholders such as <name>/, seed apply
first runs seed register semantics: it writes the supporting files under
.seed/templates/ and .seed/templates/project/, then removes any stale
literal placeholder paths like features/<name>/ left behind by older runs.
Drift Detection
seed diff dir_structure.tree
seed sync dir_structure.tree --dangerous
seed match dir_structure.tree --dangerous
sync deletes extras not in the spec. match also creates missing paths while
respecting directories marked with ....
Partial Plans
seed plan dir_structure.tree --target scripts/
seed plan dir_structure.tree --targets "services/*"
seed plan dir_structure.tree --target-mode exact
Spec Syntax
Use .tree for simple filesystem specs, or .seed when you want the same tree-shaped format plus richer inline metadata such as kinds, tags, and URLs.
Basic Example
@include base.tree
scripts/
├── build.py @generated
├── notes.txt @manual
├── cache/ ...
└── docs/ ?
Markers
@include file.tree: include another spec@generated: generated file@manual: manually maintained file?: optional file or directory...: allow extras inside a directory<varname>/: template directory placeholder{{var}}: variable interpolation in file contents
.seed also supports inline metadata markers:
!kind: semantic kind marker such as!service,!doc, or!template+tag: repeatable tags such as+remote +shared-> URL: attach a metadata URL to a node; on directory nodes this can be used as a template content source
Example:
vendor/
└── api/ !service +remote -> https://github.com/acme/repo.git
Structured YAML and JSON specs can also carry metadata with either a
metadata object or top-level kind, tags, and url fields.
Variable Usage
seed plan spec.tree --vars project_name=myapp
seed apply spec.tree --vars project_name=myapp
seed create spec.tree project_name=myapp
Templates
Template Directories
Define repeating structures with template variables:
files/
├── <version_id>/
│ ├── data.json
│ └── meta/
└── ...
Create instances:
seed create releases.tree version_id=v3
seed create releases.tree version_id=v3 --dry-run
Project-Local Templates
Use seed register to mirror any .tree or .seed spec into the project-level
.seed/templates/ directory. When the spec contains nested template subtrees,
it also extracts them into .seed/templates/project/. seed apply <spec> runs
the same registration step automatically before execution.
seed register releases.tree
seed apply releases.tree
That lets you create from either a path-based project template:
seed create --template .seed/templates/releases.tree version_id=v3
or a registered project template name:
seed create --project version_id version_id=v3
Template Registry
Manage reusable templates stored under ~/.seed/templates/ by default, or
under $SEED_HOME/templates/ when SEED_HOME is set.
seed templates list
seed templates add ./template.tree --name my-template
seed templates add ./template.seed --name service-template
seed templates show my-template
seed templates use my-template
seed templates versions my-template --add ./updated.tree --name v2
seed templates lock my-template
seed templates update my-template
seed templates remove my-template
Built-in templates include fastapi, python-package, and node-typescript.
Template Content Sources
Templates can point at a local directory, a GitHub tree URL, or a git
repository URL so seed can fetch real file contents alongside the structure
spec. Repository sources are cloned without their .git metadata.
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 update fastapi
seed templates update --all
seed templates update fastapi --content-url /path/to/local/files
Templates that include a source.json file with {"content_url": "..."} are
fetched automatically when installed. .seed directory nodes can also declare
their own content sources inline:
vendor/
└── api/ !service +remote -> https://github.com/acme/api-client.git
Copier-Style Scaffolding
seed templates use supports template config files named copier.yml,
copier.yaml, .seed-template.yml, or .seed-template.yaml.
Supported workflow features include:
- promptable questions and defaults
--data-filefor JSON/YAML answers--defaultsand--non-interactive--answers-fileor_answers_file_excludeand_skip_if_exists_tasks, which only execute with--unsafe--overwritefor existing files
Example:
seed templates use python-package \
--base ./myapp \
--data-file answers.yml \
--defaults \
--answers-file .seed/answers.yml \
--overwrite
If a template defines _tasks, they are shown but skipped unless you opt into
execution:
seed templates use python-package --unsafe
Repository & System Maintenance
seed maintain orchestrates repository, service, system, and project upkeep
from YAML or JSON manifests.
Built-in maintenance goals include:
- repositories:
ensure_path,git_fetch,git_status,git_pull_ff_only - services:
ensure_paths,compose_pull,compose_up,launchctl_restart - custom actions with
tool,args,cwd,env, or shell commands
You can point seed maintain at a manifest file or a directory containing
maintenance.yml, project.yml, or service.yml.
Workspace Manifest
targets:
- name: seed-cli
kind: repository
path: ./repos/seed-cli
goals:
- ensure_path
- git_fetch
- git_status
- name: notes-api
kind: service
path: ./systems/services/notes-api
config_dir: ./systems/services/notes-api/config
data_dir: ./local/services/notes-api
compose_file: compose.yml
deploy_engine: docker-compose
launch_agent: user/com.example.notes-api
goals:
- ensure_paths
- compose_pull
- compose_up
- launchctl_restart
project.yml
name: product-x
type: project
path: ~/work/projects/active/product-x
maintenance:
goals:
- git_fetch
- git_status
repos:
- name: web-app
path: repos/web-app
- name: api
path: repos/api
service.yml
name: notes-api
type: service
path: ~/systems/services/notes-api
config_dir: ~/systems/services/notes-api/config
data_dir: ~/local/services/notes-api
compose_file: compose.yml
deploy_engine: docker-compose
launch_agent: user/com.example.notes-api
maintenance:
goals:
- ensure_paths
- compose_pull
- compose_up
- launchctl_restart
actions:
- tool: python
args: ["scripts/rebuild_index.py"]
cwd: "{{path}}"
Run the planner first, then execute:
seed maintain ./workspace
seed maintain ./workspace --execute
Snapshots, Spec History, and Locks
Snapshots are created automatically before apply, sync, and match:
seed revert --list
seed revert
seed revert abc123 --dry-run
Applied structures are also captured as versioned specs:
seed specs list
seed specs show
seed specs diff v1 v3
seed specs watch
seed specs watch polls the workspace and writes a new .seed/specs/vN.tree
whenever the filesystem structure changes, so manual file creation after an
initial apply advances the internal reference automatically.
Lock a filesystem structure and watch it for drift:
seed lock set spec.tree
seed lock list
seed lock status
seed lock watch
seed lock upgrade v2 --dry-run
seed lock downgrade v1 --dangerous
Export, Hooks, and Utilities
Export current state or a plan:
seed export tree --out structure.tree
seed export json --out structure.json
seed export dot --out structure.dot
seed plan spec.tree --dot > plan.dot
Install git hooks:
seed hooks install
seed hooks install --hook pre-push
Utilities:
seed utils extract-tree screenshot.png --out spec.tree
seed utils state-lock
seed utils state-lock --force-unlock
Shell Autocomplete
Enable completion with argcomplete:
# zsh / bash
eval "$(register-python-argcomplete seed)"
# fish
register-python-argcomplete --shell fish seed | source
Then reload your shell and use tab completion:
seed <TAB>
seed templates <TAB>
seed lock <TAB>
Safety Model
seed is designed to be safe by default:
- destructive workflows require explicit dangerous flags
- execution state is lock-protected with heartbeat renewal
- plans are validated before writes and deletes
- template tasks require explicit
--unsafe - answers files and execution targets are constrained to the base directory
- git maintenance refuses
git pull --ff-onlyon dirty worktrees
Philosophy
seed-cli is:
- Declarative
- Deterministic
- Auditable
- Safe by default
License
Modified MIT. See LICENSE.md.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file seed_cli-1.0.9.tar.gz.
File metadata
- Download URL: seed_cli-1.0.9.tar.gz
- Upload date:
- Size: 7.8 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d43d3c91d9c918674ea9fa14614cf0d43be93c71f9846600b041f6c9096b848e
|
|
| MD5 |
6c07b8e3780fa4f23d45a011005905a4
|
|
| BLAKE2b-256 |
441128abf5621041c8949d58cebbcf24edf2b40007d65498558218dc2ad919d1
|
File details
Details for the file seed_cli-1.0.9-py3-none-any.whl.
File metadata
- Download URL: seed_cli-1.0.9-py3-none-any.whl
- Upload date:
- Size: 104.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
73ab71fa9968016ffcf22e65240e60a2643e0c1991ae5d2f0a406a6a75263424
|
|
| MD5 |
843569cdea50672f6a9e54785404fa88
|
|
| BLAKE2b-256 |
208cc11f249d6d6fe7abd7b9f8f8fbd8399022f80c5dbfdb622767fb0e06adeb
|