# Formulation CLI The Formulation CLI is the supported local automation interface for recipes, ingredients, purchases, prices, units, equipment, prep actions, inventory, recipe books, archives, and database backups. It calls the same domain layer as the web application instead of editing SQLite or generated files directly. ## Running it From the repository: ```bash npm run cli -- help npm run cli -- recipe list --query chicken --limit 10 ``` After `npm link`, the same commands can be invoked as `formulation ...`. `formulation help recipe save` shows command-specific arguments. For agents and other programs, `formulation cli commands --compact` returns the complete command registry as JSON. The default database is `var/recipe-book.sqlite`. Select another database with `--database path/to/file.sqlite` or the `FORMULATION_DATABASE` environment variable. An explicitly selected database takes precedence. ## Input and output Simple fields can be options. Hyphens in option names map to underscores in the domain payload and numbers, booleans, `null`, arrays, and objects are coerced from JSON-compatible values. ```bash formulation unit convert 2 kilogram gram formulation recipe get RECIPE_ID --target-yield 4 --target-yield-unit kilogram ``` Nested writes should use a JSON object from a file or standard input: ```bash formulation ingredient save --input ingredient.json formulation recipe save RECIPE_ID --input recipe.json Get-Content recipe.json | formulation recipe save --input - ``` Command-line values override fields supplied by `--input`. Successful commands emit this stable envelope: ```json { "success": true, "command": "recipe get", "dry_run": false, "data": {} } ``` Use `--compact` for one-line JSON. `--output file.json` writes the result to a file and prints a small confirmation envelope. Database exports are written as raw backup bundles so they can be passed directly to validate, diff, or import. Errors are emitted to standard error: ```json {"success":false,"error":{"code":"USAGE_ERROR","message":"..."}} ``` Exit codes are `0` for success, `2` for invalid commands or input, `3` for a domain or validation rejection, and `4` for filesystem, database, or other system failures. ## Safety Add `--dry-run` to any mutation. The CLI copies the selected database, performs the complete operation on the copy, returns the result, and deletes the copy. The original database and generated site projection remain unchanged. ```bash formulation recipe save RECIPE_ID --input recipe.json --dry-run ``` Include `expected_save_version` when updating a recipe. A stale version is rejected, preventing an automation run from silently overwriting a newer edit. Permanent archive deletion and database import require `--yes`. They can be tested without confirmation using `--dry-run`. ## Command families ```text recipe list, get, save, archive, quality, cost, nutrition ingredient list, get, save, archive purchase list, get, save, price unit list, convert equipment list prep-action list inventory list, get, create, update book list, get, save archive list, restore, purge db stats, export, validate, import, diff cli commands ``` IDs are positional where practical. Save commands accept the complete domain object through `--input`; their required top-level fields are listed by command-specific help. ## Backup workflow ```bash formulation db export --output data/backup.json formulation db validate --input data/backup.json formulation db diff --input data/backup.json formulation db import --input data/backup.json --dry-run formulation db import --input data/backup.json --yes ``` Import defaults to transactional replacement. Pass `--mode merge` to merge the bundle. A missing database selected with `--database` is created and migrated before import. Invalid bundles are rejected before their contents are applied.