Installation

The CLI ships with the repository rather than as a published package. Clone it, install with pnpm, and compile:

git clone https://github.com/aedeny/the-cook-book.git
cd the-cook-book
pnpm install
pnpm build

That puts the compiled CLI at dist/cli/index.js. Run it with node dist/cli/index.js <command>, or pnpm link --global once to get a ckl command on your path. The examples below use ckl.

Commands at a glance

CommandWhat it does
ckl check [path…]Parse and validate recipes. Fails on errors.
ckl lint <path…>Print every diagnostic the linter finds. Fails if there are any.
ckl build [path…]Compile recipes into build/.
ckl ast <file>Print a recipe's syntax tree as JSON.
ckl siteGenerate this website into site/.
ckl docsGenerate the older markdown-only docs site.

A path can be a single .ckl.md file or a directory. Directories are searched recursively for .ckl.md files, skipping any folder named invalid — that is where the repository keeps recipes that are meant to fail.

Checking recipes

check

The command to run before committing a recipe, and the one CI runs. It parses every ckl block, then runs the full rule set: undeclared ingredients and equipment, food safety, closed vocabularies, and the best-practice warnings.

ckl check                              # everything under recipes/
ckl check recipes/carbonara.ckl.md     # one file

Each finding is printed as file:line:column: severity[code]: message, with the line number counted from the top of the .ckl.md file, not the ckl block:

recipes/invalid/unsafe-chicken.ckl.md:27:1: error[E101]: Poultry internal temperature 60°C is below safe minimum of 74°C

Warnings and info notes are printed but do not fail the command. Add --strict to fail on warnings too, or --json for output a program can read (see JSON output).

lint

Runs the linter alone and prints what it finds. Unlike check, it exits with 1 if it prints anything at all — including warnings and info notes — so it is a review tool rather than a gate.

ckl lint recipes/

lint needs an explicit path. What each rule means, and the cooking reason behind it, is in Lint Rules.

Building

build

With no path, compiles every recipe in recipes/ and writes the results to build/:

  • build/ast/<recipe>.json — the syntax tree of each recipe
  • build/index.json — every recipe, ingredient and technique, and the graph that connects them
ckl build

Given a path, it compiles just those files, prints ✓ or ✗ for each, and writes nothing.

ckl build recipes/pasta-aglio-olio.ckl.md

site

Generates this website — every recipe, technique, ingredient and equipment page — into site/. It runs build first if build/index.json does not exist yet.

ckl site
ckl site --base /the-cook-book/

--base sets the path the site is served from; it defaults to /. The CKL_BASE_PATH environment variable does the same and takes precedence.

To build and preview the site locally, use the package scripts instead: pnpm site rebuilds everything, and pnpm start also serves site/ at http://localhost:3000.

docs

Generates the original documentation site, which renders the markdown in docs/ and recipes/ without the interactive pages. It is kept for compatibility; ckl site is what produces this website.

Inspecting

ast

Prints the parsed syntax tree of one recipe as JSON. A file with several ckl blocks prints an array, one tree per block.

ckl ast recipes/carbonara.ckl.md

It stops at parse errors and does not run the linter, so it is the quickest way to see how CKL reads a line you are unsure about.

Options

OptionApplies toEffect
--strictcheck, lintTreat warnings as failures.
--jsoncheckPrint results as JSON instead of text.
--base <path>siteBase path the site is served from. Default /.
-h, --help—Print usage.
-v, --version—Print the version.

Exit codes

CodeMeaning
0Success.
1The command failed: an error in a recipe (or, with --strict, a warning), a file that does not exist, or an unknown command.

JSON output

ckl check --json prints one entry per file, each with its list of diagnostics. A clean file has an empty list.

[
  {
    "file": "recipes/invalid/unsafe-chicken.ckl.md",
    "diagnostics": [
      {
        "message": "Recipe uses poultry but does not verify internal temperature reaches 74°C",
        "severity": "warning",
        "line": 18,
        "column": 1,
        "code": "W101"
      },
      {
        "message": "Poultry internal temperature 60°C is below safe minimum of 74°C",
        "severity": "error",
        "line": 27,
        "column": 1,
        "code": "E101"
      }
    ]
  }
]

severity is one of error, warning or info.