Skip to content

Commit dfdcfb7

Browse files
committed
puzzletide CLI: word search, crossword, and sudoku generator with printables, evals, and agent skills
Local-first puzzle toolkit from the PuzzleTide team: - Word search, crossword, and sudoku engines (seeded, deterministic, property-tested; sudoku puzzles verified to have a unique solution) - 30 generic starter word bank themes (contributions welcome) - Terminal, JSON, SVG, and printable PDF output (puzzle + solution pages) - Textavia-style command model: ptide <ns> <op>, ptide run <tool-id>, tools list/search/info/docs, agent manifest - Verifiable eval tasks for benchmarking agents (by-construction grading) - Hangman and daily sudoku in the terminal - Five SKILL.md agent skills, loadable via: pi install npm:puzzletide
0 parents  commit dfdcfb7

50 files changed

Lines changed: 8142 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
8+
jobs:
9+
test:
10+
runs-on: ubuntu-latest
11+
strategy:
12+
matrix:
13+
node-version: [20, 22]
14+
steps:
15+
- uses: actions/checkout@v4
16+
- uses: actions/setup-node@v4
17+
with:
18+
node-version: ${{ matrix.node-version }}
19+
cache: npm
20+
- run: npm ci
21+
- run: npm run build
22+
- run: npm test

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules/
2+
dist/
3+
*.tsbuildinfo
4+
.DS_Store

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 Caravaca Labs
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
<!--
2+
Keyword rationale (d4s / DataForSEO, 2026-07-16, google en):
3+
word search generator 33,100/mo KD37 · word search maker 33,100 KD40 · sudoku solver 40,500 KD41
4+
sudoku generator 1,000 KD9 · sudoku puzzle generator 170 KD10 · crossword generator 12,100 KD51
5+
printable word search 18,100 KD5 · printable sudoku puzzles 4,400 KD15 · expert sudoku 2,400 KD0
6+
daily sudoku 27,100 KD37 · hangman game 40,500 KD35 · llm evals 480 KD28
7+
Dev modifiers (cli/npm/javascript/github variants) are all ≤10/mo — the surfaces that matter are
8+
GitHub search, npm search, and Google snippets of the repo page, all of which read the repo
9+
description, package.json description/keywords, and README H1/H2s.
10+
Contiguous phrases to keep intact: "word search generator", "crossword generator",
11+
"sudoku generator", "sudoku solver", "printable word search", "printable sudoku",
12+
"expert sudoku", "daily sudoku", "LLM evals", "puzzle generator CLI".
13+
Banned claims (not shipped): word search solver, crossword solver, anagram solver (word tools
14+
search only the 30 starter banks), MCP server, PNG output, AI clue generation,
15+
nonograms/cryptograms, speed guarantees for expert sudoku, "full English dictionary".
16+
IP rule: the package ships only the 30 generic starter themes in scripts/wordbanks-source.json —
17+
NEVER include or reference-compile the proprietary puzzletide.com word bank dataset here.
18+
-->
19+
20+
# PuzzleTide CLI — word search, crossword & sudoku generator
21+
22+
[![npm package](https://img.shields.io/npm/v/puzzletide?label=npm)](https://www.npmjs.com/package/puzzletide)
23+
[![Docs](https://img.shields.io/badge/docs-GitHub-24292F)](https://github.com/Caravaca-Labs/puzzletide-cli/tree/main/docs)
24+
[![Agent skills](https://img.shields.io/badge/agent_skills-SKILL.md-0F766E)](https://github.com/Caravaca-Labs/puzzletide-cli/blob/main/docs/agent-skills.md)
25+
[![License: MIT](https://img.shields.io/badge/license-MIT-green)](./LICENSE)
26+
27+
Word search generator, crossword generator, and sudoku generator + solver in
28+
one local-first puzzle generator CLI — with printable PDF worksheets, starter
29+
word banks, verifiable LLM evals, and bundled agent skills. From the makers
30+
of [puzzletide.com](https://puzzletide.com).
31+
32+
## Install
33+
34+
```sh
35+
npm install -g puzzletide
36+
ptide --version
37+
```
38+
39+
The package installs both binaries:
40+
41+
- `ptide`
42+
- `puzzletide`
43+
44+
## Why generate puzzles with a CLI
45+
46+
Ask a language model to write a word search and you get a grid where half the
47+
words are broken; ask it for a sudoku and you usually get one with several
48+
solutions, or none. Grids are exactly the kind of output LLMs are bad at and
49+
deterministic code is good at.
50+
51+
PuzzleTide CLI is that deterministic code:
52+
53+
- Every word search word is placed and verifiable — placement coordinates are
54+
part of the output, and the generators are property-tested.
55+
- Every generated sudoku is checked to have exactly one solution.
56+
- Every crossword is validated against its own clues before it's returned.
57+
- Same `--seed` in, same puzzle out, on any machine.
58+
59+
The package also ships `SKILL.md` agent skills, so coding agents (Pi, Hermes,
60+
OpenClaw, and other SKILL.md-based systems) reach for the CLI instead of
61+
hand-writing grids.
62+
63+
## Command model
64+
65+
```sh
66+
ptide <namespace> <operation> [input] [options] # for humans
67+
ptide run <tool-id> [input] [options] --json # canonical, for scripts/agents
68+
ptide tools list | search <q> | info <id> | docs <id>
69+
ptide agent manifest
70+
```
71+
72+
Use short commands interactively and canonical tool ids in automation:
73+
74+
```sh
75+
ptide sudoku generate --difficulty hard
76+
ptide run puzzle.sudoku.generate --difficulty hard --json
77+
```
78+
79+
## Word search generator
80+
81+
Eight placement directions with easy/medium/hard presets, auto-sized grids
82+
(6–30), accent/space/hyphen normalization. Words come from flags, files, or
83+
bundled themes:
84+
85+
```sh
86+
# Word search from your own words, printed in the terminal
87+
ptide wordsearch generate --words "coral,shark,kelp,wave,tide"
88+
89+
# Themed printable word search (puzzle page + solution page)
90+
ptide wordsearch generate --theme animals/ocean-animals --pdf ocean.pdf
91+
92+
# Kids mode: easy = forward-only words
93+
ptide wordsearch generate --theme seasonal/halloween --difficulty easy
94+
```
95+
96+
## Crossword generator
97+
98+
Interlocking placement with standard crossword numbering, clue-grid
99+
validation, and deterministic fallback clues for theme words. Words that
100+
cannot interlock are reported instead of silently dropped:
101+
102+
```sh
103+
# Crossword with your clues
104+
ptide crossword generate --words "PARIS: Capital of France; TOKYO: Capital of Japan"
105+
106+
# From a JSON file, as a printable PDF
107+
ptide crossword generate --file words.json --pdf review.pdf --title "Unit 4 Review"
108+
```
109+
110+
## Sudoku generator and solver
111+
112+
Easy, medium, hard, and expert sudoku (17–21 givens) with a uniqueness
113+
guarantee, an instant solver, and a validator that reports conflicts,
114+
solvability, and solution uniqueness:
115+
116+
```sh
117+
ptide sudoku generate --difficulty expert --seed 42
118+
ptide sudoku solve "53..7....6..195....98....6.8...6...34..8.3..17...2...6.6....28....419..5....8..79"
119+
ptide sudoku validate --file puzzle.txt
120+
ptide daily # today's daily sudoku, same for everyone on a given UTC day
121+
```
122+
123+
## Printable puzzles: PDF worksheets and SVG
124+
125+
Every generator takes `--pdf <file>` for a print-ready worksheet — puzzle
126+
page(s) plus a solution page (`--paper letter|a4`, omit the answer key with
127+
`--no-solution-page`) — and `--svg <file>` for vector images. Printable word
128+
search and printable sudoku sheets for a classroom packet are one loop away:
129+
130+
```sh
131+
for i in 1 2 3 4 5; do
132+
ptide sudoku generate --difficulty medium --seed "$i" --pdf "sudoku-$i.pdf" --title "Sudoku #$i"
133+
done
134+
```
135+
136+
## Word banks and word tools
137+
138+
30 starter themes (ocean animals, fruits, space, halloween, ...) — browse,
139+
search, pattern-match, anagrams, random picks. Bring your own lists via
140+
`--words`/`--file`, or play the full curated collection at
141+
[puzzletide.com](https://puzzletide.com):
142+
143+
```sh
144+
ptide words themes --search dinosaur
145+
ptide words match "c_r_l" # crossword-style pattern matching
146+
ptide words anagram coral
147+
```
148+
149+
There's a hangman game in the terminal too: `ptide play hangman`.
150+
151+
## Agent skills
152+
153+
Pi can load the bundled skills directly from this npm package:
154+
155+
```sh
156+
pi install npm:puzzletide
157+
```
158+
159+
The package manifest declares:
160+
161+
```json
162+
{
163+
"pi": {
164+
"skills": ["./skills"]
165+
}
166+
}
167+
```
168+
169+
Five skills are included: word search, crossword, sudoku, printable puzzles,
170+
and agent evals. Each prefers the local CLI and checks `ptide`, `puzzletide`,
171+
then `npx puzzletide`. Skills never auto-install anything; agents should ask
172+
the user before installing.
173+
174+
## Verifiable LLM evals
175+
176+
Puzzle answers are checkable without an answer key: a sudoku answer either
177+
satisfies the rules and preserves the givens or it doesn't; a word search
178+
answer either spells the word along a straight line in the grid or it
179+
doesn't. That makes puzzles clean benchmark tasks for LLM evals — no LLM
180+
judge needed:
181+
182+
```sh
183+
ptide eval generate --type sudoku --n 20 --difficulty hard --seed 1 --out tasks.json
184+
# ...run your model on tasks.json, collect [{id, answer}] ...
185+
ptide eval check --tasks tasks.json --answers answers.json --json
186+
```
187+
188+
The (type, difficulty, n, seed) tuple fully determines the task set, so it
189+
names a reproducible benchmark.
190+
191+
## Library usage
192+
193+
The engines are importable TypeScript with no CLI involved:
194+
195+
```ts
196+
import { generateSudoku, generateWordSearch, wordSearchPdf } from 'puzzletide';
197+
198+
const sudoku = generateSudoku({ difficulty: 'hard', seed: 42 });
199+
const search = generateWordSearch({
200+
words: ['coral', 'shark', 'kelp'],
201+
directions: ['E', 'S', 'SE'],
202+
seed: 7,
203+
});
204+
const pdfBytes = await wordSearchPdf(search, { title: 'Ocean Animals' });
205+
```
206+
207+
More docs:
208+
209+
- [CLI commands](./docs/cli.md)
210+
- [Tool registry](./docs/registry.md)
211+
- [Agent skills](./docs/agent-skills.md)
212+
213+
## Online versions
214+
215+
Prefer a browser?
216+
217+
- [PuzzleTide word search](https://puzzletide.com/word-search)
218+
- [PuzzleTide crossword](https://puzzletide.com/crossword)
219+
- [PuzzleTide sudoku](https://puzzletide.com/sudoku)
220+
- [PuzzleTide hangman](https://puzzletide.com/hangman)
221+
- [Printable puzzles](https://puzzletide.com/printable)
222+
- [Make your own puzzle](https://puzzletide.com/maker)
223+
224+
## Privacy
225+
226+
Everything runs locally. No account, no API key, no telemetry, no network
227+
access.
228+
229+
## Development
230+
231+
```sh
232+
npm install
233+
npm run build # tsc → dist/
234+
npm test # vitest + fast-check property tests (build first: CLI tests run dist/)
235+
```
236+
237+
The starter word banks are generic, original lists written for this package
238+
(`scripts/wordbanks-source.json`, compiled with `npm run build:wordbanks`).
239+
Theme contributions are welcome — add an entry to the source file and run the
240+
build. The full curated PuzzleTide word bank collection is proprietary to
241+
puzzletide.com and is not part of this repository.
242+
243+
## License
244+
245+
MIT © Caravaca Labs

data/wordbanks.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"source":"puzzletide-cli starter word banks","categories":[{"slug":"animals","title":"Animals","themes":7},{"slug":"food","title":"Food & Drink","themes":4},{"slug":"nature","title":"Nature & Science","themes":5},{"slug":"everyday","title":"Everyday Life","themes":7},{"slug":"places","title":"Places","themes":3},{"slug":"seasonal","title":"Seasonal","themes":4}],"themes":[{"id":"animals/ocean-animals","category":"animals","title":"Ocean Animals","difficulty":"easy","description":"Creatures of the sea, from sharks to seahorses.","words":["Shark","Whale","Dolphin","Octopus","Coral","Crab","Lobster","Seahorse","Jellyfish","Starfish","Seal","Walrus","Stingray","Turtle","Squid","Clam"]},{"id":"animals/farm-animals","category":"animals","title":"Farm Animals","difficulty":"easy","description":"Animals you would meet in the barnyard.","words":["Cow","Horse","Sheep","Goat","Pig","Chicken","Rooster","Duck","Turkey","Donkey","Rabbit","Goose","Llama","Mule","Calf","Lamb"]},{"id":"animals/zoo-animals","category":"animals","title":"Zoo Animals","difficulty":"easy","description":"Favorites from a day at the zoo.","words":["Lion","Tiger","Elephant","Giraffe","Zebra","Monkey","Gorilla","Panda","Kangaroo","Penguin","Hippo","Rhino","Flamingo","Camel","Otter","Koala"]},{"id":"animals/birds","category":"animals","title":"Birds","difficulty":"medium","description":"Birds of backyards, forests, and coasts.","words":["Eagle","Owl","Robin","Sparrow","Hawk","Falcon","Parrot","Crow","Raven","Hummingbird","Woodpecker","Cardinal","Pelican","Swan","Pigeon","Heron"]},{"id":"animals/insects","category":"animals","title":"Insects & Bugs","difficulty":"medium","description":"Six-legged friends and garden crawlers.","words":["Butterfly","Bee","Ant","Beetle","Dragonfly","Ladybug","Grasshopper","Cricket","Moth","Firefly","Caterpillar","Wasp","Mosquito","Mantis","Cicada"]},{"id":"animals/dinosaurs","category":"animals","title":"Dinosaurs","difficulty":"hard","description":"Giants of the prehistoric world.","words":["Tyrannosaurus","Triceratops","Stegosaurus","Velociraptor","Brachiosaurus","Pterodactyl","Fossil","Jurassic","Raptor","Herbivore","Carnivore","Extinct","Allosaurus","Diplodocus"]},{"id":"animals/pets","category":"animals","title":"Pets","difficulty":"easy","description":"Companions at home, furry and finned.","words":["Puppy","Kitten","Hamster","Goldfish","Parakeet","Rabbit","Turtle","Gerbil","Ferret","Leash","Collar","Aquarium","Kennel","Whiskers"]},{"id":"food/fruits","category":"food","title":"Fruits","difficulty":"easy","description":"Sweet picks from the orchard and market.","words":["Apple","Banana","Orange","Grape","Strawberry","Watermelon","Peach","Pear","Cherry","Mango","Pineapple","Kiwi","Lemon","Blueberry","Raspberry","Plum"]},{"id":"food/vegetables","category":"food","title":"Vegetables","difficulty":"easy","description":"Garden staples from carrots to corn.","words":["Carrot","Potato","Broccoli","Spinach","Tomato","Cucumber","Pepper","Onion","Lettuce","Celery","Pumpkin","Zucchini","Cabbage","Radish","Corn","Peas"]},{"id":"food/desserts","category":"food","title":"Desserts","difficulty":"easy","description":"Treats from the bakery and the sweet shop.","words":["Cake","Cookie","Brownie","Pudding","Cupcake","Donut","Sundae","Fudge","Caramel","Gelato","Sorbet","Muffin","Tart","Waffle","Toffee"]},{"id":"food/breakfast","category":"food","title":"Breakfast","difficulty":"easy","description":"Morning plates and what goes on them.","words":["Pancake","Waffle","Cereal","Oatmeal","Bacon","Sausage","Toast","Bagel","Omelet","Yogurt","Granola","Juice","Butter","Honey","Syrup"]},{"id":"nature/weather","category":"nature","title":"Weather","difficulty":"medium","description":"From gentle drizzle to roaring storms.","words":["Sunshine","Rainbow","Thunder","Lightning","Tornado","Hurricane","Blizzard","Drizzle","Breeze","Hail","Frost","Forecast","Cloud","Fog","Humidity"]},{"id":"nature/space","category":"nature","title":"Space","difficulty":"medium","description":"Planets, rockets, and the night sky.","words":["Planet","Galaxy","Asteroid","Comet","Meteor","Nebula","Orbit","Rocket","Astronaut","Telescope","Satellite","Eclipse","Gravity","Jupiter","Saturn","Mars"]},{"id":"nature/flowers","category":"nature","title":"Flowers","difficulty":"medium","description":"Blooms from the garden and the florist.","words":["Rose","Tulip","Daisy","Sunflower","Orchid","Lily","Violet","Daffodil","Marigold","Peony","Lavender","Petal","Blossom","Bouquet"]},{"id":"nature/trees","category":"nature","title":"Trees & Forest","difficulty":"medium","description":"From acorns to towering redwoods.","words":["Oak","Maple","Pine","Birch","Willow","Cedar","Redwood","Spruce","Acorn","Branch","Trunk","Leaves","Roots","Forest","Bark"]},{"id":"nature/human-body","category":"nature","title":"Human Body","difficulty":"medium","description":"Anatomy from head to toe.","words":["Skeleton","Muscle","Heart","Lungs","Brain","Stomach","Kidney","Liver","Nerve","Artery","Spine","Elbow","Ankle","Shoulder","Knuckle"]},{"id":"everyday/colors","category":"everyday","title":"Colors","difficulty":"easy","description":"Shades and hues across the palette.","words":["Red","Blue","Green","Yellow","Purple","Orange","Turquoise","Magenta","Crimson","Violet","Indigo","Scarlet","Emerald","Amber","Ivory","Maroon"]},{"id":"everyday/clothing","category":"everyday","title":"Clothing","difficulty":"easy","description":"What hangs in the closet, season to season.","words":["Jacket","Sweater","Trousers","Scarf","Mittens","Sneakers","Sandals","Pajamas","Hoodie","Blouse","Vest","Beanie","Overalls","Raincoat"]},{"id":"everyday/school","category":"everyday","title":"School Days","difficulty":"easy","description":"Around the classroom and the schoolyard.","words":["Pencil","Notebook","Teacher","Classroom","Homework","Recess","Library","Backpack","Eraser","Crayon","Ruler","Scissors","Locker","Quiz","Desk"]},{"id":"everyday/jobs","category":"everyday","title":"Jobs & Careers","difficulty":"medium","description":"People who keep the world running.","words":["Doctor","Teacher","Firefighter","Chef","Farmer","Pilot","Nurse","Dentist","Plumber","Electrician","Carpenter","Artist","Lawyer","Engineer","Barber"]},{"id":"everyday/sports","category":"everyday","title":"Sports","difficulty":"easy","description":"Games played on fields, courts, and slopes.","words":["Soccer","Basketball","Baseball","Tennis","Hockey","Swimming","Volleyball","Golf","Rugby","Cricket","Boxing","Cycling","Skiing","Surfing","Marathon"]},{"id":"everyday/music","category":"everyday","title":"Music","difficulty":"medium","description":"Instruments and the sounds they make.","words":["Guitar","Piano","Violin","Drums","Trumpet","Flute","Saxophone","Cello","Harp","Clarinet","Banjo","Melody","Rhythm","Chorus","Orchestra"]},{"id":"everyday/transportation","category":"everyday","title":"Transportation","difficulty":"easy","description":"Ways to get from here to there.","words":["Airplane","Bicycle","Subway","Ferry","Helicopter","Scooter","Train","Truck","Motorcycle","Sailboat","Taxi","Tram","Canoe","Bus"]},{"id":"places/countries","category":"places","title":"Countries","difficulty":"medium","description":"Nations around the globe.","words":["Canada","Brazil","France","Japan","Egypt","India","Australia","Mexico","Italy","Spain","Germany","Kenya","Norway","Greece","Portugal","Thailand"]},{"id":"places/cities","category":"places","title":"World Cities","difficulty":"medium","description":"Capitals and famous cities worldwide.","words":["Paris","Tokyo","London","Sydney","Cairo","Toronto","Madrid","Berlin","Athens","Dublin","Vienna","Prague","Lisbon","Oslo","Amsterdam"]},{"id":"places/around-town","category":"places","title":"Around Town","difficulty":"easy","description":"Stops on an errand-filled afternoon.","words":["Bakery","Library","Museum","Hospital","Pharmacy","Grocery","Park","Cinema","Stadium","Airport","Harbor","Market","Fountain","Bridge"]},{"id":"seasonal/winter-holidays","category":"seasonal","title":"Winter Holidays","difficulty":"easy","description":"Cozy December traditions and trimmings.","words":["Snowflake","Reindeer","Sleigh","Ornament","Garland","Mistletoe","Carol","Stocking","Gingerbread","Candle","Wreath","Ribbon","Fireplace","Cocoa","Present"]},{"id":"seasonal/halloween","category":"seasonal","title":"Halloween","difficulty":"easy","description":"Spooky night of costumes and candy.","words":["Pumpkin","Ghost","Witch","Spider","Skeleton","Vampire","Costume","Candy","Haunted","Cauldron","Broomstick","Zombie","Lantern","Spooky"]},{"id":"seasonal/summer","category":"seasonal","title":"Summer","difficulty":"easy","description":"Long days at the beach and the backyard.","words":["Beach","Sunscreen","Popsicle","Swimsuit","Sandcastle","Lemonade","Vacation","Campfire","Fireworks","Seashell","Sunglasses","Picnic","Hammock","Surfboard"]},{"id":"seasonal/spring","category":"seasonal","title":"Spring","difficulty":"easy","description":"The season of blossoms and rain showers.","words":["Blossom","Rainfall","Tulip","Butterfly","Nest","Puddle","Umbrella","Garden","Seedling","Robin","Meadow","Sprout","Breeze","Hatch"]}]}

0 commit comments

Comments
 (0)