| name | ddd-cli |
| description | Use when scaffolding, extending, validating, serving, watching, or publishing ddd_cqrs_es applications through the `ddd` CLI; especially for agent/MCP workflows that need dry-run JSON, `ddd.toml` manifests, fine-grained `ddd add ...` commands, capability enablement, Spin runtime presets, fullstack SaaS scaffolding, or same-version library/CLI release handling. |
ddd CLI Skill
Core Rule
Prefer the ddd CLI over hand-written scaffolding when the target is a generated ddd_cqrs_es app or a new app created from this repository's templates.
In this repository, run the development binary as:
cargo run -p ddd-cqrs-es-cli -- <args>
After publishing or installing from crates.io, the user-facing command is:
ddd <args>
Current library/CLI version pair: read version from root Cargo.toml (e.g. 0.3.0-rc.6). Always keep library and CLI at the same version.
First Moves
Before generating or mutating code:
- Discover the live command surface:
cargo run -p ddd-cqrs-es-cli -- capabilities --json
- For runtime/backend combinations, inspect:
cargo run -p ddd-cqrs-es-cli -- matrix
- For any mutating command, preview first with dry-run JSON:
cargo run -p ddd-cqrs-es-cli -- --dry-run --format json <command>
- Inspect the planned
operations before running the same command without --dry-run.
The JSON report is the agent/MCP contract. Expect fields like status, message, operations, command, and data.
Presets
Supported presets (from capabilities --json): basic, leptos-wasi, fullstack, native-api, worker, custom.
| Preset | Use for | Domain codegen (ddd add) | Runtime after init |
|---|
basic | Pure domain + fixture tests | Yes (src/domain markers) | N/A (library-shaped) |
leptos-wasi | Thin Spin Leptos CQRS shell (counter-style) | Yes | make spin … via ddd serve |
fullstack | Production SaaS (auth/org/settings, wasi-auth) | Yes for aggregate/event/command (optional src/domain); stubs refused | make dev transport=both via ddd serve |
native-api / worker / custom | API/worker/minimal bases | Partial / stub-oriented | Make targets as generated |
The CLI is Spin-focused. Do not use --runtime wasmtime for CLI-generated projects unless capabilities --json lists it.
Fullstack shape (locked)
preset=fullstack requires:
db=postgres
transport=both
ui=leptos
Defaults already set those. Generated tree is dual-synced with examples/fullstack-app (no src/domain/; empty [domains] in ddd.toml).
Quick scaffold: fullstack SaaS
Preferred product path:
ddd init my-saas --preset fullstack
make scaffold-fullstack DIR=my-saas
cargo run -p ddd-cqrs-es-cli -- init my-saas --preset fullstack
cd my-saas
cp .env.example .env
make db-up
make dev transport=both
Init JSON includes data.next_steps for fullstack. make dev starts Spin + wasi-auth-outbox-worker (required for verification mail). make spin alone does not deliver mail.
Fullstack command matrix
| Command | Supported? |
|---|
ddd check | Yes |
ddd serve / ddd watch | Yes → make dev transport=… |
ddd fresh | Yes → make db=postgres fresh (Postgres up) |
ddd enable auth / authorization / passkeys / oauth-provider * | Manifest only; set secrets in .env/Spin |
ddd enable grpc / rest / leptos | Manifest bookkeeping; no Cargo.toml feature surgery |
ddd enable db * (non-postgres) | Fails validation |
ddd add aggregate | Yes — src/domain + domain_app + domain_rest (/api/domain/...) + lib/rest hooks |
ddd add event / command | Yes — patches marker regions on the aggregate module |
ddd add projection|route|server-fn|grpc-method|… | No — unwired product stubs refused |
Example after fullstack init:
cd my-saas
ddd add aggregate Invoice
ddd add event Invoice InvoicePaid --field amount:i64
ddd add command Invoice PayInvoice --field amount:i64
src/domain, src/domain_app, and src/domain_rest.rs are app-specific and excluded from dual-sync.
Project Creation (other presets)
cargo run -p ddd-cqrs-es-cli -- init my-app --preset basic --domain Invoice
cargo run -p ddd-cqrs-es-cli -- init my-app --preset leptos-wasi --domain Counter --db sqlite --runtime spin --realtime off --transport http --ui leptos
cargo run -p ddd-cqrs-es-cli -- init my-saas --preset fullstack
Keep Redis modes distinct:
--db redis means Redis is the durable event/checkpoint/read-model store.
--realtime redis means Redis is the wake/notification transport and can pair with another durable DB.
Extending Generated Projects (basic / leptos-wasi)
Run fine-grained generators from the generated project root, or pass --cwd <project>:
cargo run -p ddd-cqrs-es-cli -- --cwd my-app add aggregate BillingAccount
cargo run -p ddd-cqrs-es-cli -- --cwd my-app add event Invoice InvoicePaid --field amount:i64 --field paid_at:String
cargo run -p ddd-cqrs-es-cli -- --cwd my-app add command Invoice PayInvoice --field amount:i64
cargo run -p ddd-cqrs-es-cli -- --cwd my-app add projection InvoiceLedger
cargo run -p ddd-cqrs-es-cli -- --cwd my-app add route invoice-summary --method GET --path /api/invoices/summary
These require src/domain/{module}.rs with // ddd:… markers. On fullstack,
prefer add aggregate|event|command (also wires domain_app + REST); refuse
orphan projection/route stubs.
Use ddd enable ... for capability wiring on non-fullstack apps:
cargo run -p ddd-cqrs-es-cli -- --cwd my-app enable db postgres
cargo run -p ddd-cqrs-es-cli -- --cwd my-app enable realtime redis
cargo run -p ddd-cqrs-es-cli -- --cwd my-app enable grpc
cargo run -p ddd-cqrs-es-cli -- --cwd my-app enable idempotency
cargo run -p ddd-cqrs-es-cli -- --cwd my-app enable snapshots
cargo run -p ddd-cqrs-es-cli -- --cwd my-app enable tracing
Generated projects are tracked by ddd.toml. If ddd.toml is missing, treat the app as outside the supported patching path unless the user explicitly asks to adopt it.
File and Symbol Targeting
Do not invent unsupported target syntax. As of this skill, ddd add event and ddd add command target aggregates by manifest/domain name, not arbitrary /path/to/file.rs:Symbol selectors.
Runtime Commands
cargo run -p ddd-cqrs-es-cli -- --cwd my-app --dry-run --format json serve
cargo run -p ddd-cqrs-es-cli -- --cwd my-app --dry-run --format json watch
cargo run -p ddd-cqrs-es-cli -- --cwd my-app --dry-run --format json fresh --db sqlite
fresh is reset-only. It must not be described as starting the server.
Use ddd check after mutations:
cargo run -p ddd-cqrs-es-cli -- --cwd my-app check
Monorepo: dual-sync and drift (template editors)
When editing examples/fullstack-app product files that belong in the CLI template:
bash examples/fullstack-app/scripts/sync_fullstack_template.sh
bash examples/fullstack-app/scripts/sync_fullstack_template.sh check
bash scripts/regenerate-fullstack-example.sh --check
Cargo for the template is shipped as Cargo.toml.template (not nested Cargo.toml) so cargo package includes the tree.
UI chrome / soft-nav / skeleton patterns: docs/tutorial/leptos-islands-persistent-chrome.md and examples/fullstack-app (not domain codegen).
Safety Rules
- Dry-run before writing unless the user explicitly asks for immediate writes.
- Avoid
--force until inspecting the collision and confirming overwrite is intended.
- Prefer generated marker regions and
ddd.toml updates over ad hoc string edits (non-fullstack).
- Keep the root framework transport-agnostic; HTTP, REST, SSE, gRPC, Spin, and app wiring belong in generated apps and CLI templates.
- When changing CLI behavior, update tests and this skill if agent-facing commands change.
- On fullstack, prefer
ddd add aggregate|event|command for product domain; refuse unwired stubs.
Release Workflow
The library crate and CLI crate are released as a same-version pair:
make version 0.3.0-rc.6
make publish dry-run
make publish
Full chain (leptos-wasi-runtime → wasi-auth → ddd → CLI):
make publish-fullstack dry-run
make publish-fullstack
make registry-check
Run cargo login first, or provide CARGO_REGISTRY_TOKEN in the environment.
The publish script validates matching versions and publishes ddd_cqrs_es before ddd-cqrs-es-cli.
Verification
After editing the CLI or this skill, run the focused checks that match the change:
cargo fmt --all -- --check
cargo test -p ddd-cqrs-es-cli --all-targets
bash scripts/verify-docs.sh
bash scripts/regenerate-fullstack-example.sh --check
For release-flow changes, run:
bash scripts/release-crates-io.sh dry-run
Roadmap
Fullstack product domain includes demo app + REST. Still manual for production:
durable event store (replace InMemory), Cedar auth on /api/domain/*, Leptos UI,
gRPC, and projections.