natoora-cli
natoora-cli
A developer CLI that wraps Docker Compose and a handful of project workflows used at Natoora — bringing services up/down, tailing logs, opening shells, running migrations, swapping between dev modes, managing git worktrees, hot-reloading local libraries via yalc, and backing up / restoring the database.
Internal tool. It assumes the conventions of the Natoora monorepo (compose file layout, service names like
pro-backend,pro-frontend, etc., and@natoora-libs/*packages).
Install
npm install -g natoora-cli
# or
pnpm add -g natoora-cli
This exposes the natoora binary on your PATH.
Requirements:
- Node.js 18+
- Docker + Docker Compose
git(for worktree commands)pnpm(for frontend / bump-libs / upgrade flows)
Usage
Run from inside a Natoora repo. The CLI auto-detects the repo root, compose file, and project name.
natoora --help
natoora <command> --help
Most service-targeted commands accept either explicit service names or a --group. Groups are organised into per-domain stacks (pro, ws, customers, …), role-based sets (all-backends, celery, workers, …), and infrastructure (infra, messaging, …) — run natoora groups to see them all. With no arguments these commands open an interactive picker.
natoora up # interactive picker
natoora up pro-backend pro-frontend # explicit services
natoora up --group ws # group shortcut
natoora groups # list every group and its services
Commands
Stack lifecycle
| Command | Description |
|---|---|
up [services...] |
Start services (or whole stack); --wait blocks until healthy |
down |
Stop and remove the stack |
reload [services...] |
Restart all or selected services |
recreate [services...] |
Force-recreate containers |
reset [services...] |
Stop, remove, and rebuild from scratch |
clean [services...] |
Remove containers, volumes, and orphan resources |
ps |
List running containers |
info [services...] |
Show service info (ports, image, status) |
Inspect & exec
| Command | Description |
|---|---|
logs [services...] |
Tail container output |
enter <service> |
Open an interactive shell inside a container |
shell <service> |
Open a Django/Node REPL appropriate to the service |
exec <service> [args...] |
Run a one-off command in a container (shell if no args) |
manage <backend> [args...] |
Run a manage.py command in a backend |
test <backend> [args...] |
Run the backend's tests (pytest; --django for manage.py test) |
Database
| Command | Description |
|---|---|
resetdb |
Reset the database to a known baseline |
backup [name] |
Create a named database backup |
backup-delete |
Delete a saved backup (interactive picker) |
migrations <backend> |
Run Django migrations against a backend service |
generate |
Generate fake data using a backend's factories (interactive) |
resetdb can restore from any named backup created with backup. It also fixes root-owned volume files (via an interactive sudo chown) on a fresh worktree and reloads the backends afterward so they reconnect to the new DB (--no-reload skips the restart when nothing is running against the volumes yet).
generate seeds fake data by calling a backend's factory_boy factories directly. Run it interactively to pick a backend, an entity (bands, customers, orders, addresses, …), and a count, or script it:
natoora generate --backend ws-backend --entity bands --count 25 -y
natoora generate --backend pro-backend --populate-everything -y
natoora generate --list --backend ws-backend # list entities
natoora generate --list-scenarios # list multi-step recipes
natoora generate --scenario qa-baseline -y # run a recipe
natoora generate --backend ws-backend --discover # list ALL factories (max coverage)
Scenarios are named recipes (a sequence of {backend, entity, count} steps). Built-ins ship with the CLI; override or add your own at <repo>/.natoora/scenarios.json.
Dev modes & libraries
| Command | Description |
|---|---|
switch [services...] |
Switch a service between dev / prod-like modes |
hot-reload |
Live-reload a local @natoora-libs/* package into selected frontends |
hot-reload-clean |
Remove yalc links and restore registry versions |
bump-libs |
Bump shared @natoora-libs/* versions across frontends (stable or dev channel) |
upgrade |
Reinstall dependencies and audit vulnerabilities across frontends |
hot-reload watches the selected library and, for each chosen frontend, picks the right strategy automatically:
- Running in Docker — rebuilds the library on the host and syncs the fresh
distinto the container's installed copy, then nudges Vite to re-read it. The container keeps its own dependency tree, so the library's runtime deps stay resolvable. Nothing in the host repo is mutated. - Running on the host — falls back to yalc (
yalc publish+yalc add --link), linking the library'snode_modulesinto the.yalccopy so externalized deps resolve.
bump-libs splits registry versions into stable (x.y.z) and dev / prerelease (suffixed) channels and shows the latest 10 of whichever you pick, sorted by version.
Worktrees & sandboxes
| Command | Description |
|---|---|
worktree |
Pick a git worktree, then open it in VS Code, open a shell in it, or both |
worktree-create [name] |
Create a new worktree (Claude Code-style), then cd in + open Claude, a shell, VS Code, or all |
worktree-delete |
Remove worktrees via a picker (--older-than [days] filters + pre-selects old ones) |
worktree-purge |
Bulk-remove worktrees |
sandbox <branch> |
Spin up an isolated sandbox stack for a branch |
worktree-create is like claude -w <name>: it adds a worktree under ~/.claude/worktrees/<name>/<repo> by default (the same location Claude Code uses). The worktree always branches off $NATOORA_MAIN_FOLDER (the main checkout), regardless of where you run the command. By default it's a detached checkout at the base ref (origin/HEAD, falling back to HEAD) — a clean starting point you git switch -c feat/… from, with no throwaway branch to clean up. Pass --branch <name> to create/check out a branch up front instead. Override the base dir with --dir (or the NATOORA_WORKTREE_DIR env var — e.g. .codex/worktrees) and the base ref with --base. After creating it, you pick what to do: cd in + open Claude, a shell only, VS Code, or all of them.
New worktrees are made stack-ready automatically: fresh database volumes are seeded via resetdb --clean --no-reload (skip with --no-resetdb), missing bind-mount dirs and *.template.*-generated files are pre-created as your user (so docker/containers don't create them as root), and node_modules/.pnpm-store are pre-owned for the apps you pick — interactively, or with --apps <csv|all|none>.
natoora worktree-create my-feature # interactive action picker
natoora worktree-create my-feature --dir .codex/worktrees
natoora worktree-create hotfix --branch fix/login --base origin/staging --action all
natoora worktree-create my-feature --apps ws-react-frontend --no-resetdb
natoora worktree-delete --older-than 15 # pre-selects worktrees >15d old
Diagnostics & maintenance
| Command | Description |
|---|---|
doctor [--fix] |
Diagnose the dev environment and suggest fixes |
open [service] |
Show browser URL(s) for running services (--launch to open) |
self-update |
Pull, rebuild, and reinstall the CLI globally |
completion [bash|zsh] |
Print a shell completion script |
doctor checks the Docker daemon, a nested-docker/virtiofs storage heuristic (the OrbStack layer-extraction error), repo context, root-owned volumes, disk space, service health, and CLI version drift — each with a fix hint. --fix applies the safe ones (volume ownership).
self-update resolves the CLI source from $NATOORA_CLI_DIR (default ~/natoora-cli).
Misc
| Command | Description |
|---|---|
groups |
List service groups (and a group's services) |
credits |
Show credits |
Global flags
--dry-run prints the underlying docker compose … command(s) instead of executing the mutating ones (read-only previews still run). Works on any command:
natoora up --group ws --dry-run
Non-interactive use (scripts & LLMs)
The interactive commands all accept flags so they can run without a TTY (they still prompt when run bare):
natoora resetdb --clean # or --backup <name>
natoora backup-delete --name old-snapshot -y # or --all -y
natoora worktree --branch feat/x --action both
cd "$(natoora worktree --print-path --branch feat/x)" # shell wrapper for a real cd
natoora worktree-create my-feature --action all # claude | shell | vscode | all
cd "$(natoora worktree-create my-feature --action shell --print-path)" # create + cd in
natoora hot-reload --lib core --services pro-app,ws-react-frontend
natoora hot-reload-clean --all
natoora bump-libs --lib core --channel stable --version 1.2.3
natoora generate --backend ws-backend --entity orders --count 50 -y
License
ISC