Files

3.8 KiB

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:

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.

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:

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:

{
  "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:

{"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.

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

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

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.