Skip to content

Commit b6a0d1a

Browse files
author
Anton Stefer
committed
docs: prepare logic-grid-ai for npm publish
- Add LICENSE (MIT) - Add README with API docs, usage examples, and custom client guide - Add keywords, homepage, bugs to package.json - Add prepublishOnly script (check + build) - Expand JSDoc on all exported functions
1 parent 795736d commit b6a0d1a

7 files changed

Lines changed: 184 additions & 5 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Monorepo for logic grid puzzle generation and solving.
55
## Packages
66

77
- [`logic-grid`](packages/logic-grid/) — Core library ([README](packages/logic-grid/README.md))
8+
- [`logic-grid-ai`](packages/logic-grid-ai/) — AI-powered themed category generation ([README](packages/logic-grid-ai/README.md))
89
- `logic-grid-demo` — Browser demo (SvelteKit)
910

1011
## Development

packages/logic-grid-ai/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 Anton Stefer
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.

packages/logic-grid-ai/README.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# logic-grid-ai
2+
3+
AI-powered themed category generation for [logic-grid](https://www.npmjs.com/package/logic-grid) puzzles. Uses the Anthropic API to turn a theme description into fully structured puzzle categories.
4+
5+
## Install
6+
7+
```bash
8+
npm install logic-grid-ai logic-grid
9+
```
10+
11+
Requires `logic-grid` as a peer dependency and an [Anthropic API key](https://console.anthropic.com/settings/keys).
12+
13+
## Quick Start
14+
15+
```typescript
16+
import { generateTheme } from "logic-grid-ai";
17+
import { generate } from "logic-grid";
18+
19+
const theme = await generateTheme({
20+
theme: "pirate adventure",
21+
size: 4,
22+
categories: 4,
23+
});
24+
// {
25+
// categories: [
26+
// { name: "Pirate", values: ["Blackbeard", "Redbeard", ...], noun: "" },
27+
// { name: "Ship", values: ["Revenge", "Kraken", ...], noun: "captain", verb: ["commands the", ...] },
28+
// ...
29+
// ],
30+
// positionNoun: ["cove", "coves"],
31+
// positionPreposition: "at"
32+
// }
33+
34+
const puzzle = generate({
35+
size: 4,
36+
categories: 4,
37+
categoryNames: theme.categories,
38+
positionNoun: theme.positionNoun,
39+
positionPreposition: theme.positionPreposition,
40+
});
41+
// Clues like: "Blackbeard commands the Revenge."
42+
// "The gold seeker is at the first cove."
43+
```
44+
45+
## API
46+
47+
### `generateTheme(options)`
48+
49+
Generate themed categories for a logic grid puzzle.
50+
51+
```typescript
52+
const result = await generateTheme({
53+
theme: "space exploration", // theme description (required)
54+
size: 5, // values per category, 3-8 (required)
55+
categories: 4, // number of categories, 3-8 (required)
56+
constraints: ["kid-friendly"], // optional hints for the AI
57+
client: myClient, // optional custom AIClient
58+
});
59+
```
60+
61+
Returns a `ThemeResult`:
62+
63+
```typescript
64+
interface ThemeResult {
65+
categories: Category[]; // from logic-grid
66+
positionNoun: [string, string]; // [singular, plural], e.g. ["planet", "planets"]
67+
positionPreposition: string; // e.g. "on" -> "lives on the first planet"
68+
}
69+
```
70+
71+
The result is validated against structural and semantic rules (value uniqueness, noun consistency, category count, etc.). If validation fails, the AI is retried with error feedback up to 3 times.
72+
73+
### `createAnthropicClient(apiKey?)`
74+
75+
Create the default AI client backed by the Anthropic SDK. If no key is provided, reads from `ANTHROPIC_API_KEY`.
76+
77+
```typescript
78+
import { createAnthropicClient } from "logic-grid-ai";
79+
80+
const client = createAnthropicClient("sk-ant-...");
81+
```
82+
83+
### Custom AI Client
84+
85+
Implement the `AIClient` interface to use a different provider:
86+
87+
```typescript
88+
import type { AIClient } from "logic-grid-ai";
89+
90+
const myClient: AIClient = {
91+
async completeJSON(prompt, schema) {
92+
// Call your preferred API, return JSON matching the schema
93+
},
94+
};
95+
96+
const theme = await generateTheme({
97+
theme: "cooking competition",
98+
size: 4,
99+
categories: 4,
100+
client: myClient,
101+
});
102+
```
103+
104+
### `validateThemeResult(result, size, categories)`
105+
106+
Validate AI output against structural and semantic rules. Returns an array of error messages (empty = valid). Used internally by `generateTheme`, but exported for custom pipelines.
107+
108+
```typescript
109+
import { validateThemeResult } from "logic-grid-ai";
110+
111+
const errors = validateThemeResult(result, 4, 4);
112+
if (errors.length > 0) {
113+
console.error("Invalid theme:", errors);
114+
}
115+
```
116+
117+
## How It Works
118+
119+
1. A detailed prompt describes the puzzle structure, category contract, and position noun semantics
120+
2. The AI responds via tool_use with structured JSON matching a strict schema
121+
3. The response is validated (category count, value uniqueness, noun consistency, etc.)
122+
4. If validation fails, errors are fed back to the AI for up to 3 retries
123+
124+
## License
125+
126+
MIT

packages/logic-grid-ai/package.json

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
11
{
22
"name": "logic-grid-ai",
33
"version": "1.0.0",
4-
"description": "AI-powered extensions for logic-grid puzzles",
4+
"description": "AI-powered themed category generation for logic-grid puzzles",
5+
"keywords": [
6+
"logic-grid",
7+
"puzzle",
8+
"ai",
9+
"theme-generation",
10+
"anthropic",
11+
"zebra-puzzle",
12+
"einstein-riddle"
13+
],
14+
"homepage": "https://github.com/antonstefer/logic-grid/tree/main/packages/logic-grid-ai#readme",
15+
"bugs": "https://github.com/antonstefer/logic-grid/issues",
516
"main": "./dist/index.js",
617
"module": "./dist/index.mjs",
718
"types": "./dist/index.d.ts",
@@ -28,7 +39,8 @@
2839
"lint": "eslint src/",
2940
"format": "prettier --write src/",
3041
"format:check": "prettier --check src/",
31-
"check": "npm run typecheck && npm run lint && npm run format:check && npm run test"
42+
"check": "npm run typecheck && npm run lint && npm run format:check && npm run test",
43+
"prepublishOnly": "npm run check && npm run build"
3244
},
3345
"engines": {
3446
"node": ">=20"

packages/logic-grid-ai/src/client.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
import Anthropic from "@anthropic-ai/sdk";
22
import type { AIClient, JSONSchema } from "./types";
33

4-
/** Default AIClient implementation using the Anthropic SDK. */
4+
/**
5+
* Create an AIClient backed by the Anthropic SDK.
6+
*
7+
* Uses Claude's tool_use feature for structured JSON output.
8+
* If no apiKey is provided, the SDK reads from ANTHROPIC_API_KEY.
9+
*/
510
export function createAnthropicClient(apiKey?: string): AIClient {
611
const client = new Anthropic({ apiKey });
712

packages/logic-grid-ai/src/theme.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,16 @@ Generate themed categories for: "${theme}"
124124
return prompt;
125125
}
126126

127-
/** Generate themed categories for a logic grid puzzle. */
127+
/**
128+
* Generate themed categories for a logic grid puzzle using AI.
129+
*
130+
* Calls the AI client to produce categories, position noun, and preposition
131+
* that fit the given theme. Validates the result and retries up to 3 times
132+
* if the AI output fails validation, feeding errors back into the prompt.
133+
*
134+
* @throws {RangeError} If size or categories is outside 3-8.
135+
* @throws {Error} If generation fails after all retry attempts.
136+
*/
128137
export async function generateTheme(
129138
options: ThemeOptions,
130139
): Promise<ThemeResult> {

packages/logic-grid-ai/src/validation.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,12 @@ const POSITIONAL_WORDS = new Set([
1111
"eighth",
1212
]);
1313

14-
/** Validate a ThemeResult and return an array of error messages. Empty = valid. */
14+
/**
15+
* Validate AI-generated theme output against structural and semantic rules.
16+
*
17+
* Returns an array of error messages. Empty array means the result is valid.
18+
* Used internally by generateTheme to decide whether to retry.
19+
*/
1520
export function validateThemeResult(
1621
result: ThemeResult,
1722
expectedSize: number,

0 commit comments

Comments
 (0)