cookcli 0.38.1

A command-line interface for managing and working with Cooklang recipes
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
# CookCLI

[![Test](https://github.com/cooklang/cookcli/actions/workflows/test.yml/badge.svg)](https://github.com/cooklang/cookcli/actions/workflows/test.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/cooklang/CookCLI)](https://github.com/cooklang/CookCLI/releases)
[![GitHub Stars](https://img.shields.io/github/stars/cooklang/CookCLI?style=social)](https://github.com/cooklang/CookCLI)

**Command line tools for working with [Cooklang](https://cooklang.org) recipes.** Full reference: [CookCLI documentation](https://cooklang.org/cli/).

### 🎯 Quick Install

```bash
# macOS/Linux (Homebrew)
brew install cookcli

# Download binary (all platforms)
# Visit: https://github.com/cooklang/CookCLI/releases
```

## 📋 Table of Contents

- [What is CookCLI?]#-what-is-cookcli
- [Getting Started]#-getting-started
- [Installation]#-installation
- [Commands]#-commands
- [Documentation]#-documentation
- [Configuration]#️-configuration
- [Tips]#-tips
- [Contributing]#-contributing
- [Contributors]#-contributors
- [License]#-license
- [Support]#-support

## 📖 What is CookCLI?

CookCLI provides a suite of commands to create shopping lists,
reports and maintain recipes. We've built it to be simple and useful
for automating your cooking and shopping routine with existing
UNIX command line and scripting tools. It can also function
as a webserver for your recipes, making them browsable on
any device with a web browser.

**Try the web interface live at [demo.cooklang.org](https://demo.cooklang.org)**

### ✨ Features

* 🔧 **UNIX Philosophy** - Integrate your Cooklang recipes with other tools
* 📝 **Meal Planning** - Script meal planning and shopping
* 📊 **Reports** - Evaluate your recipes or menus with custom reports
* 🌐 **Web Interface** - Browse recipes from any device
* 🛒 **Smart Shopping** - Generate organized shopping lists
* 🔍 **Recipe Search** - Find recipes quickly
* 📦 **Pantry Tracking** - Manage inventory and expiration dates
* ☁️ **Sync** - after `cook login`, `cook server` keeps your recipe folder in step with your phone and desktop through [Cook Cloud sync]https://cook.md/ (Cook Basic)

## 🚀 Getting Started

First, install CookCLI using one of the methods below. CookCLI comes with a few sample recipes to play with. `cook seed` populates its target directory with recipe files and folders, so create a dedicated directory for them first:

```bash
$ mkdir my-recipes && cd my-recipes
$ cook seed ./
$ cook recipe "Neapolitan Pizza.cook"
```

This displays the recipe in a human-readable format:

```
Neapolitan Pizza

source: https://www.stadlermade.com/how-to-pizza-dough/neapolitan/
servings: 6

Ingredients:
  semolina
  Pizza Dough              (recipe: Shared/Pizza Dough)     6 balls
  flour
  semolina
  San Marzano tomato sauce                                  5 tbsp
  basil leaves
  mozzarella cheese                                         100 grams

Cookware:
  outdoor oven
  spatula

Steps:
 1. Preheat your outdoor oven so it’s around 450/500°C (842/932°F).
     [-]
 2. Prepare your pizza toppings because from now on you wanna work fast.
    Sprinkle some semolina on your work surface.
     [semolina]
 ...
```

Create a shopping list from multiple recipes:

```bash
$ cook -v shopping-list "Neapolitan Pizza.cook" "./Breakfast/Easy Pancakes.cook""
```

Plan your meals with a menu file (`Weekly Plan.menu`):

```
---
servings: 2
---

==Saturday==

Breakfast: \
- @oats{1%cup} with @milk{1/2%cup} and @honey{1%tbsp}

Lunch: \
- @./lamb-chops{}

Dinner: \
- @./Neapolitan Pizza{}

==Sunday==

Breakfast: \
- @./Breakfast/Easy Pancakes{} with @maple syrup{2%tbsp}

Lunch: \
- @./Salads/Caprese{}

Dinner: \
- @./Risotto{}
```

Menu files let you reference recipes and inline ingredients, plan by day and meal, and generate a combined shopping list for the whole plan.

Or start the web server to browse your recipes:

```bash
$ cook server --open
Listening on http://127.0.0.1:9080
Serving Web UI on http://localhost:9080
Serving recipe files from: "/Users/chefalexey/recipes"
```

<img width="600" alt="recipes" src="docs/screenshots/recipe-list.png?v=3" />
<img width="600" alt="recipe" src="docs/screenshots/recipe-detail.png?v=3" />
<img width="600" alt="menu" src="docs/screenshots/menu.png?v=3" />
<img width="600" alt="shopping list" src="docs/screenshots/shopping-list.png?v=3" />
<img width="600" alt="pantry" src="docs/screenshots/pantry.png?v=3" />


## 📦 Installation

### Download Binary

Download the latest release for your platform from the [releases page](https://github.com/cooklang/CookCLI/releases) and add it to your PATH.

### macOS/Linux

Using Homebrew:

```bash
brew install cookcli
```

### Fedora / RPM-based Linux

Every [release](https://github.com/cooklang/CookCLI/releases) ships RPMs built
in Fedora containers (x86_64 and aarch64). Download the one for your Fedora
version and install it:

```bash
sudo dnf install ./cookcli-<version>-1.fcXX.x86_64.rpm
```

The package installs the `cook` binary and shell completions. To build the RPM
yourself (or to set up a COPR repository), see [packaging/fedora](packaging/fedora).

### Debian / Ubuntu

Every [release](https://github.com/cooklang/CookCLI/releases) ships `.deb`
packages for amd64 and arm64. They install on Debian 12+ and Ubuntu 22.04+:

```bash
sudo apt install ./cookcli_<version>-1_amd64.deb
```

The package installs the `cook` binary and shell completions. To build it
yourself, see [packaging/debian](packaging/debian).

### Install with Cargo

If you have Rust installed:

```bash
cargo install cookcli --locked
```

`--locked` builds against the dependency versions we tested and released with, rather than re-resolving to the newest compatible ones.

Note that this compiles CookCLI and all its dependencies from source, which needs a few GB of RAM and disk. If you are on a Raspberry Pi, an Armbian board, or anything else memory-constrained, prefer the [prebuilt binaries](https://github.com/cooklang/CookCLI/releases) — we publish `aarch64` and `armv7` Linux builds.

<details>
<summary>Building on a low-memory single-board computer</summary>

`cargo install` places its build directory under `$TMPDIR`. On Armbian, `/tmp` is mounted on zram — a RAM-backed device sized to half your RAM — so a multi-gigabyte build will exhaust memory and fail, sometimes with a confusing `failed to load bitcode of module ...` error.

Point the build somewhere on real storage:

```bash
CARGO_TARGET_DIR=~/.cache/cookcli-build cargo install cookcli --locked
```

If memory is still tight, disable link-time optimisation for the build:

```bash
CARGO_PROFILE_RELEASE_LTO=false \
CARGO_TARGET_DIR=~/.cache/cookcli-build \
  cargo install cookcli --locked
```

</details>

### Build from Source

You'll need Rust and Node.js installed. Then:

```bash
# Clone the repository
git clone https://github.com/cooklang/CookCLI.git
cd CookCLI

# Install frontend dependencies
npm install

# Build CSS and JS (required for web UI; the build fails without them)
npm run build-css
npm run build-js

# Build the CLI with web UI
cargo build --release

# Binary will be at target/release/cook
```

#### Building without Node.js

`static/css/output.css` and `static/js/editor.bundle.js` are generated by Tailwind and esbuild and are not checked into git, so they are missing from clones and from GitHub's auto-generated tag archives — and `cargo build` refuses to start without them.

If Node.js is unavailable or its native toolchain has no build for your platform, use a source drop that ships those two files prebuilt:

```bash
# cook-<version>-source.tar.gz is attached to each GitHub release.
# Set VERSION to the one you want: https://github.com/cooklang/CookCLI/releases
VERSION=0.34.0

curl -LO "https://github.com/cooklang/CookCLI/releases/download/v$VERSION/cook-$VERSION-source.tar.gz"
tar xzf "cook-$VERSION-source.tar.gz"
cd "cookcli-$VERSION"
cargo build --release --locked
```

The crates.io package (`cargo install cookcli --locked`) includes them too.

#### Cargo features

The optional commands are behind Cargo features, all enabled by default. Turning them off cuts the dependency graph roughly in half (412 crates → 225) and the binary from ~23 MB to ~9 MB — useful for CI/CD, package managers, or small machines where you only want the core recipe tooling.

| Feature | Command | Notes |
|---|---|---|
| `server` | `cook server` | Web UI (axum + tower). `cook build` still works without it. |
| `import` | `cook import` | Scrape a recipe from a website. |
| `lsp` | `cook lsp` | Language server for editor integrations. |
| `sync` | `cook login` / `cook logout` | Recipe sync. Implies `server` — the sync loop runs inside it. |
| `self-update` | `cook update` | In-place binary upgrade. |

```bash
# Core CLI only: recipe, shopping-list, search, doctor, pantry, report, build, seed
cargo build --release --no-default-features

# Core plus the web server
cargo build --release --no-default-features --features server
```

Everything not listed above — parsing, scaling, shopping lists, search, pantry, reports and the static site builder — is always compiled in.

### Development Setup

For development with hot-reload of CSS changes:

```bash
# Install dependencies
npm install

# In one terminal, watch CSS changes
npm run watch-css

# In another terminal, run the development server
cargo run -- server ./seed

# Or use the Makefile
make dev_server  # Builds CSS and starts server
```

## 🛠 Commands

CookCLI follows the UNIX philosophy: each command does one thing well.

### `cook recipe`

Parse and display recipe files. You can view them in different formats and scale quantities.

```bash
# View a recipe
cook recipe "Pasta Carbonara.cook"

# Scale a recipe to 2x
cook recipe "Pizza.cook:2"

# Output as JSON
cook recipe "Soup.cook" -f json

# Save as Markdown
cook recipe "Cake.cook" -f markdown > cake.md
```

### `cook shopping-list`

Generate shopping lists from one or more recipes. Ingredients are automatically combined and organized by store section.

```bash
# Single recipe
cook shopping-list "Dinner.cook"

# Multiple recipes with scaling
cook shopping-list "Pasta.cook:3" "Salad.cook"

# All recipes in a directory
cook shopping-list *.cook
```

### `cook server`

Run a web server to browse your recipes from any device.

```bash
# Start on localhost
cook server

# Allow access from other devices on your network
cook server --host

# Only if you open it by host name instead of IP address: name that origin,
# or the server refuses to answer it
cook server --host --cors-origin http://raspberrypi.local:9080

# Use a different port
cook server --port 8080

# Open browser immideately
cook server --open

# Require sign-in before anyone can change recipes (asks for a password)
cook server user add alice
```

Without users, anyone who can reach the server can change your recipes. Once
you add one, visitors can still browse, but creating, editing or deleting
recipes and changing the pantry or the shopping list need a signed-in user.
Manage users with `cook server user add|passwd|remove|list`; a running server
picks up the changes on its own. See [Signing in to make
changes](docs/server.md#signing-in-to-make-changes).

#### Sign-in in a container

The container image runs `cook server /recipes --host`, so the server is open
to everyone who can reach the container. To require sign-in:

1. **Give the container a configuration directory.** The image's user has no
   home directory, so without one there is nowhere to keep the users file or
   the key that signs session cookies. In `docker-compose.yml`:

   ```yaml
   services:
     cookcli:
       image: ghcr.io/cooklang/cookcli:latest
       environment:
         COOK_CONFIG_DIR: /config
       ports:
         - "9080:9080"
       volumes:
         - ./recipes:/recipes
         - ./config:/config
   ```

   Create the folder yourself before the first start (`mkdir config`): a
   folder Docker creates belongs to root, and the container runs as UID 1000,
   which cannot write to it. If your own UID is not 1000, set `user:` as the
   comment in `docker-compose.yml` explains.

2. **Add the first user.** Before starting the container:

   ```bash
   docker compose run --rm cookcli cook server user add alice
   docker compose up -d
   ```

   If it is already running, add the user inside it and restart it once.
   Sign-in turns on when the server starts with a users file, so only this
   first user needs a restart:

   ```bash
   docker compose exec cookcli cook server user add alice
   docker compose restart cookcli
   ```

3. **Manage users in the running container.** No restart needed: the server
   reloads the users file when it changes. Removing a user or changing their
   password signs them out everywhere.

   ```bash
   docker compose exec cookcli cook server user add bob
   docker compose exec cookcli cook server user passwd bob
   docker compose exec cookcli cook server user remove bob
   docker compose exec cookcli cook server user list
   ```

The password prompt does not echo what you type. `docker compose exec` and
`run` give the command a terminal; with plain `docker`, pass `-it`
(`docker exec -it <container> cook server user add bob`). From a script, with
no terminal, pipe the password in and pass `-T`:

```bash
printf '%s\n' "$PASSWORD" | docker compose exec -T cookcli cook server user add bob
```

### `cook build web`

Generate a self-contained static website from your recipes. Hostable anywhere or browsable via `file://`.

```bash
# Build into ./_site from the current directory
cook build web

# Build a specific collection into a custom output
cook build web dist --base-path ~/my-recipes

# Build for hosting under a subpath
cook build web --base-url /recipes/

# Link back to the recipe repository from the footer
cook build web --repo-url https://github.com/user/my-recipes
```

### `cook search`

Find recipes by searching through ingredients, instructions, and metadata.

```bash
# Search for recipes with chicken
cook search chicken

# Find quick recipes
cook search "30 minutes"

# Search in specific directory
cook search -b ~/recipes pasta
```

### `cook import`

Import recipes from websites and convert them to Cooklang format. Requires
`OPENAI_API_KEY` environment variable set. Or
[convert a recipe to Cooklang](https://cook.md/cookifies/new) on cook.md (Cook Basic).

```bash
# Import a recipe
cook import https://www.example.com/recipe > recipe.cook

# Import without conversion
cook import https://www.example.com/recipe --skip-conversion
```

### `cook doctor`

Check your recipe collection for issues and maintain consistency.

```bash
# Validate all recipes and display parsing errors
cook doctor validate

# Check aisle configuration for shopping lists
cook doctor aisle

# Check pantry configuration
cook doctor pantry

# Run all checks
cook doctor
```

### `cook seed`

Add sample recipes to explore Cooklang features. This populates the target directory with recipe files and folders, so point it at an empty or dedicated directory.

```bash
# Add to current directory
cook seed ./

# Add to specific directory
cook seed ~/my-recipes
```

### `cook report`

Generate custom outputs using templates (experimental feature).

```bash
# Generate a recipe card
cook report -t recipe-card.md.jinja recipe.cook

# Create nutrition label
cook report -t nutrition.html.jinja recipe.cook
```

### `cook pantry`

Manage your pantry inventory, track low stock items, expiring ingredients, and find recipes you can make.

```bash
# Show items that are low or out of stock
cook pantry depleted

# Check expiring items in the next 7 days
cook pantry expiring

# Find recipes you can make with available ingredients
cook pantry recipes

# Include partial matches (recipes where most ingredients are available)
cook pantry recipes --partial --threshold 60

# Output in machine-readable formats
cook pantry -f json depleted
cook pantry -f yaml expiring --days 14
```

## 📚 Documentation

Detailed documentation for each command is available in the [docs/](docs/) directory:

* [Recipe command]docs/recipe.md - viewing and converting recipes
* [Shopping lists]docs/shopping-list.md - creating shopping lists
* [Server]docs/server.md - web interface
* [Build]docs/build.md - generate a static website
* [Search]docs/search.md - finding recipes
* [Import]docs/import.md - importing from websites
* [Doctor]docs/doctor.md - validation and maintenance
* [Seed]docs/seed.md - example recipes
* [Report]docs/report.md - custom outputs
* [Pantry]docs/pantry.md - inventory management and tracking
* [Completions]docs/completions.md - shell completion scripts

## ⚙️ Configuration

CookCLI looks for configuration files in:

* `./config/` - in your recipe directory (highest priority)
* the global configuration directory (fallback):
  * `~/.config/cook/` - on Linux
  * `~/Library/Application Support/cook/` - on macOS
  * `%APPDATA%\cook\config\` - on Windows

Configuration files:
* `aisle.conf` - Organizes ingredients by store section
* `pantry.conf` - Tracks your ingredient inventory with quantities

### `COOK_CONFIG_DIR`

Set `COOK_CONFIG_DIR` to use a different global configuration directory. It
replaces the platform default above for *everything* CookCLI keeps there —
`aisle.conf`, `pantry.conf`, your CookCloud session, the sync database, and
`cook server`'s users file, session key and signed-out sessions — so it gives
you a self-contained CookCLI:

```bash
COOK_CONFIG_DIR=~/kitchen/cook-config cook shopping-list dinner.cook
```

A local `./config/` still takes priority. An empty value means "unset", and the
platform default applies.

This is also how the test suite keeps itself away from your real session:
`HOME` and `XDG_CONFIG_HOME` cannot do the job, because the Windows
configuration directory is resolved through the Known Folder API and ignores
both.

### `COOK_CORS_ORIGIN`

Set `COOK_CORS_ORIGIN` to name the origins `cook server` accepts browser
requests from, and so the host names it answers at, separated by commas — the
same values as `--cors-origin`, which overrides the variable:

```bash
COOK_CORS_ORIGIN=https://cook.example.com cook server --host
```

It exists for containers, where passing a flag means restating the image's
whole command. An empty value means "unset". `--no-csrf-check` has no
equivalent variable and has to be passed on the command line.

### `COOK_USERS_FILE`

Names the users file `cook server` reads to require sign-in, in place of
`users.toml` in the configuration directory. `cook server user` edits the same
file. `--users-file` overrides it, and an empty value means "unset". See
[Signing in to make changes](docs/server.md#signing-in-to-make-changes).

```bash
COOK_USERS_FILE=/etc/cook/users.toml cook server --host
```

### Aisle Configuration (`aisle.conf`)

Organizes ingredients by store section for shopping lists. Items not in any category will appear under "Other".

```
[produce]
tomatoes|tomato
basil|basil leaves
garlic
onions

[dairy]
milk
cheese
yogurt
butter

[pantry]
flour
sugar
pasta
rice
olive oil

[meat]
chicken
beef
pork

[bakery]
bread
rolls
```

### Pantry Configuration (`pantry.conf`)

Tracks your ingredient inventory with quantities, expiration dates, and low stock thresholds. Items in your pantry are excluded from shopping lists automatically.

```toml
[freezer]
ice_cream = "1%L"
frozen_peas = "500%g"
spinach = { bought = "05.05.2024", expire = "05.06.2024", quantity = "1%kg" }

[fridge]
milk = { expire = "10.05.2024", quantity = "2%L", low = "500%ml" }
cheese = { expire = "15.05.2024" }
butter = "250%g"

[pantry]
rice = { quantity = "5%kg", low = "1%kg" }
pasta = { quantity = "1%kg", low = "200%g" }
flour = { quantity = "5%kg", low = "1%kg" }
olive_oil = { quantity = "1%L", low = "250%ml" }
salt = "1%kg"
```

Pantry items can be specified in two formats:
- Simple: `item = "quantity"`
- Detailed: `item = { quantity = "amount", expire = "date", bought = "date", low = "threshold" }`

Attributes:
- `quantity` - Current amount in stock
- `low` - Threshold for low stock warnings (same units as quantity)
- `expire` - Expiration date
- `bought` - Purchase date

Items listed in your pantry will be automatically excluded from shopping lists, helping you track what you already have at home. Use `cook pantry depleted` to see low stock items and `cook pantry expiring` to check expiration dates.

### Using Configuration Files

```bash
# Shopping list will organize by aisle and exclude pantry items
cook shopping-list "Pasta.cook"

# Check which ingredients aren't categorized
cook doctor aisle

# Use specific config directory
cook shopping-list "Recipe.cook" --aisle ./my-config/aisle.conf

# Example: Recipe calls for salt, pepper, chicken, tomatoes
# With pantry.conf containing salt and rice in your inventory:
# Shopping list will only show: pepper, chicken, tomatoes
```

## 💡 Tips

### Logging

CookCLI has different level of logging. You can pass `-v` to show info messages, `-vv` for debug and `-vvv` for trace. Use it if you want to submit bug report because it will help us to better understand what's going on.

### Scaling Recipes

Use the `:` notation to scale any recipe:

```bash
cook recipe "Pizza.cook:2"              # Double
cook shopping-list "Pasta.cook:0.5"     # Half
```

### Combining with UNIX Tools

CookCLI works great with pipes and standard tools:

```bash
# Find all recipes with chicken and create a shopping list
cook search chicken | xargs cook shopping-list

# Convert all recipes to Markdown
for r in *.cook; do
  cook recipe "$r" -f markdown > "docs/${r%.cook}.md"
done
```

## ⭐ Give us a star

Why not? It will help more people discover this tool and Cooklang.

## 🤝 Contributing

We welcome contributions! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.

Areas where we'd love help:

* Bug fixes and testing
* Documentation improvements
* New features
* Recipe collections
* Translations
* UI/UX improvements

## 👥 Contributors

Thanks to all the people who have contributed to CookCLI!

<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<a href="https://github.com/cooklang/CookCLI/graphs/contributors">
  <img src="https://contrib.rocks/image?repo=cooklang/CookCLI" />
</a>
<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->
<!-- ALL-CONTRIBUTORS-LIST:END -->

## 📄 License

MIT License. See [LICENSE](LICENSE) for details.

Some source files include code from [cooklang-chef](https://github.com/Zheoni/cooklang-chef), also under MIT license.

## 🔗 Links

* [CookCLI documentation]https://cooklang.org/cli/ - every command, the server, and guides
* [Cooklang Specification]https://cooklang.org/docs/spec - the recipe markup language
* [Cooklang Apps]https://cooklang.org/app/ - iOS and Android apps

## 💬 Support

* [Issue Tracker]https://github.com/cooklang/CookCLI/issues - report bugs
* [Twitter]https://twitter.com/cooklang_org - updates and news
* [Playground]https://cooklang.github.io/cooklang-rs/
* [Discord server]https://discord.gg/fUVVvUzEEK, ask for help or say hello fellow cooks
* [Spec discussions]https://github.com/cooklang/spec/discussions, suggest a new idea or give your opinion on future development
* [Awesome Cooklang Recipes]https://github.com/cooklang/awesome-cooklang-recipes, find inspiration or share your recipes with the community.