grimoire-wizard 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +176 -1461
- package/dist/cli.js +29 -6
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +29 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,1550 +17,265 @@
|
|
|
17
17
|
|
|
18
18
|
---
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
## Features
|
|
23
|
-
|
|
24
|
-
- **10 input types** — text, select, multiselect, confirm, password, number, search, editor, path, toggle
|
|
25
|
-
- **Conditional branching** — show or skip steps based on previous answers using `when` conditions
|
|
26
|
-
- **Route-based navigation** — select steps can branch to different step sequences
|
|
27
|
-
- **Back-navigation** — built-in history stack lets users go back through steps
|
|
28
|
-
- **Step groups** — organize steps into named sections with visual headers
|
|
29
|
-
- **Visual progress bar** — step counter shown at each prompt
|
|
30
|
-
- **Theming** — 7 semantic color tokens and 4 icon overrides for full visual control
|
|
31
|
-
- **Structured output** — export answers as JSON, YAML, or `.env` format
|
|
32
|
-
- **Config inheritance** — `extends` keyword merges a base config into your wizard
|
|
33
|
-
- **Pre-flight checks** — run shell commands before the wizard starts; abort on failure
|
|
34
|
-
- **Plugin system** — register custom step types with their own render and validate logic
|
|
35
|
-
- **`$ENV_VAR` resolution** — use environment variables as default values in any step
|
|
36
|
-
- **Async validation** — hook into step completion to run async checks (API calls, file system, etc.)
|
|
37
|
-
- **`--dry-run` preview** — print the full step plan without running any prompts
|
|
38
|
-
- **`--mock` non-interactive mode** — supply preset answers as JSON for CI/CD pipelines
|
|
39
|
-
- **`--json` structured output** — emit a machine-readable JSON result envelope for AI agents and scripts
|
|
40
|
-
- **JSON Schema** — `grimoire.schema.json` for IDE autocomplete in VS Code and any JSON Schema-aware editor
|
|
41
|
-
- **Shell completions** — bash, zsh, and fish completion scripts via `grimoire completion`
|
|
42
|
-
- **`grimoire create` scaffolder** — interactively generate a new wizard config file
|
|
43
|
-
- **`grimoire demo` showcase** — run a built-in demo that exercises all 10 step types
|
|
44
|
-
- **Answer caching** — previous answers become defaults on the next run; password steps are never cached
|
|
45
|
-
- **Templates** — save and load named answer presets per wizard
|
|
46
|
-
- **MRU ordering** — frequently selected options float to the top of select/multiselect/search lists
|
|
47
|
-
- **`optionsFrom`** — load select/multiselect/search options from an external JSON or YAML file
|
|
48
|
-
- **Lifecycle hooks** — `onBeforeStep` and `onAfterStep` callbacks in the programmatic API
|
|
49
|
-
- **Ink renderer** — alternative renderer with box-drawing characters and progress percentages
|
|
50
|
-
- **Clack-style renderer** — connected `│` guide lines, `◇` collapsed steps, `┌`/`└` session framing, bordered note boxes
|
|
51
|
-
- **6 theme presets** — catppuccin, dracula, nord, tokyonight, monokai; set `preset` in your theme config
|
|
52
|
-
- **Note step type** — display bordered info boxes inline in the wizard flow
|
|
53
|
-
- **Progress persistence** — auto-resume from where you left off after Ctrl+C; `--no-resume` to disable
|
|
54
|
-
- **Step review screen** — review all answers before final submission; set `review: true` in meta
|
|
55
|
-
- **Wizard pipelines** — chain multiple wizard configs, forwarding answers between them
|
|
56
|
-
- **ASCII art banner** — figlet + gradient banner shown at startup; suppressed with `--plain`
|
|
57
|
-
- **`--plain` / `--no-color` flags** — disable colors and banner for plain-text environments
|
|
58
|
-
|
|
59
|
-
## Quick Start
|
|
20
|
+
## Install
|
|
60
21
|
|
|
61
22
|
```bash
|
|
62
23
|
npm install -g grimoire-wizard
|
|
63
24
|
```
|
|
64
25
|
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Quick Start
|
|
29
|
+
|
|
65
30
|
Create `setup.yaml`:
|
|
66
31
|
|
|
67
32
|
```yaml
|
|
68
33
|
meta:
|
|
69
34
|
name: Project Setup
|
|
35
|
+
review: true
|
|
70
36
|
|
|
71
37
|
steps:
|
|
72
38
|
- id: project-name
|
|
73
39
|
type: text
|
|
74
|
-
message:
|
|
40
|
+
message: Project name?
|
|
75
41
|
validate:
|
|
76
42
|
- rule: required
|
|
77
|
-
- rule:
|
|
78
|
-
value:
|
|
43
|
+
- rule: pattern
|
|
44
|
+
value: "^[a-z0-9-]+$"
|
|
79
45
|
|
|
80
|
-
- id:
|
|
46
|
+
- id: project-type
|
|
81
47
|
type: select
|
|
82
|
-
message:
|
|
48
|
+
message: What kind of project?
|
|
83
49
|
options:
|
|
84
|
-
- { value:
|
|
85
|
-
- { value:
|
|
50
|
+
- { value: web, label: "Web App" }
|
|
51
|
+
- { value: api, label: "REST API" }
|
|
52
|
+
- { value: cli, label: "CLI Tool" }
|
|
53
|
+
routes:
|
|
54
|
+
web: framework
|
|
55
|
+
api: framework
|
|
56
|
+
cli: features
|
|
86
57
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
58
|
+
- id: framework
|
|
59
|
+
type: search
|
|
60
|
+
message: Pick a framework
|
|
61
|
+
options:
|
|
62
|
+
- { value: nextjs, label: "Next.js" }
|
|
63
|
+
- { value: remix, label: Remix }
|
|
64
|
+
- { value: fastify, label: Fastify }
|
|
65
|
+
- { value: express, label: Express }
|
|
66
|
+
|
|
67
|
+
- id: features
|
|
68
|
+
type: multiselect
|
|
69
|
+
message: Features to include
|
|
70
|
+
min: 1
|
|
71
|
+
options:
|
|
72
|
+
- { value: eslint, label: ESLint }
|
|
73
|
+
- { value: prettier, label: Prettier }
|
|
74
|
+
- { value: vitest, label: Vitest }
|
|
75
|
+
- { value: husky, label: Husky }
|
|
76
|
+
|
|
77
|
+
- id: port
|
|
78
|
+
type: number
|
|
79
|
+
message: Dev server port
|
|
80
|
+
default: 3000
|
|
81
|
+
min: 1024
|
|
82
|
+
max: 65535
|
|
83
|
+
|
|
84
|
+
- id: output-dir
|
|
85
|
+
type: path
|
|
86
|
+
message: Output directory
|
|
87
|
+
default: ./my-project
|
|
88
|
+
|
|
89
|
+
- id: theme
|
|
90
|
+
type: toggle
|
|
91
|
+
message: Color scheme
|
|
92
|
+
active: Dark
|
|
93
|
+
inactive: Light
|
|
94
|
+
default: true
|
|
95
|
+
|
|
96
|
+
- id: ts-strict
|
|
97
|
+
type: confirm
|
|
98
|
+
message: Enable strict TypeScript?
|
|
99
|
+
default: true
|
|
100
|
+
when:
|
|
101
|
+
field: project-type
|
|
102
|
+
notEquals: cli
|
|
90
103
|
|
|
91
|
-
|
|
104
|
+
- id: notes
|
|
105
|
+
type: editor
|
|
106
|
+
message: Any notes for the README?
|
|
92
107
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
108
|
+
- id: api-key
|
|
109
|
+
type: password
|
|
110
|
+
message: API key (optional)
|
|
96
111
|
|
|
97
|
-
|
|
112
|
+
- id: info
|
|
113
|
+
type: note
|
|
114
|
+
message: "Almost done"
|
|
115
|
+
description: "Review your answers on the next screen."
|
|
98
116
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
117
|
+
- id: confirm
|
|
118
|
+
type: confirm
|
|
119
|
+
message: Create project?
|
|
120
|
+
default: true
|
|
102
121
|
|
|
103
|
-
|
|
122
|
+
output:
|
|
123
|
+
format: json
|
|
124
|
+
path: answers.json
|
|
104
125
|
|
|
105
|
-
|
|
106
|
-
|
|
126
|
+
theme:
|
|
127
|
+
preset: catppuccin
|
|
107
128
|
```
|
|
108
129
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
## CLI Commands
|
|
112
|
-
|
|
113
|
-
### `grimoire run <config>`
|
|
114
|
-
|
|
115
|
-
Run a wizard from a config file. Accepts `.yaml`, `.json`, `.js`, or `.ts` files.
|
|
130
|
+
Run it:
|
|
116
131
|
|
|
117
132
|
```bash
|
|
118
133
|
grimoire run setup.yaml
|
|
119
|
-
grimoire run setup.yaml -o answers.json
|
|
120
|
-
grimoire run setup.yaml --dry-run
|
|
121
|
-
grimoire run setup.yaml --mock '{"project-name":"my-app","language":"typescript"}'
|
|
122
|
-
grimoire run setup.yaml --json
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
| Flag | Description |
|
|
126
|
-
|------|-------------|
|
|
127
|
-
| `-o, --output <path>` | Write answers to a file |
|
|
128
|
-
| `-f, --format <format>` | Output format: `json`, `yaml`, or `env` (default: `json`) |
|
|
129
|
-
| `-q, --quiet` | Suppress header and summary output |
|
|
130
|
-
| `--dry-run` | Print the step plan without running any prompts |
|
|
131
|
-
| `--mock <json>` | Run non-interactively with preset answers (JSON object string) |
|
|
132
|
-
| `--json` | Emit a structured JSON result envelope to stdout |
|
|
133
|
-
| `--no-cache` | Disable answer caching for this run |
|
|
134
|
-
| `--no-resume` | Disable progress resume for this run |
|
|
135
|
-
| `--template <name>` | Load a saved template as default answers |
|
|
136
|
-
| `--renderer <type>` | Renderer to use: `inquirer` (default), `ink`, or `clack` |
|
|
137
|
-
| `--plain` | Plain output mode (no colors, no banner) |
|
|
138
|
-
| `--no-color` | Disable colored output |
|
|
139
|
-
|
|
140
|
-
#### `--dry-run`
|
|
141
|
-
|
|
142
|
-
Prints every step with its type, ID, prompt message, visibility status, and any conditions or routes. Useful for reviewing a config before running it.
|
|
143
|
-
|
|
144
|
-
```
|
|
145
|
-
Dry Run: "Project Setup"
|
|
146
|
-
|
|
147
|
-
Step 1 text project-name "What is your project name?"
|
|
148
|
-
Step 2 select language "Pick a language"
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
#### `--mock`
|
|
152
|
-
|
|
153
|
-
Runs the wizard without any interactive prompts. Pass a JSON object where keys are step IDs and values are the answers. Steps with defaults will use their defaults if not provided in the mock object.
|
|
154
|
-
|
|
155
|
-
```bash
|
|
156
|
-
grimoire run setup.yaml --mock '{"project-name":"my-app","language":"typescript"}'
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
#### `--json`
|
|
160
|
-
|
|
161
|
-
Suppresses all interactive output and emits a single JSON object to stdout:
|
|
162
|
-
|
|
163
|
-
```json
|
|
164
|
-
{
|
|
165
|
-
"ok": true,
|
|
166
|
-
"wizard": "Project Setup",
|
|
167
|
-
"answers": {
|
|
168
|
-
"project-name": "my-app",
|
|
169
|
-
"language": "typescript"
|
|
170
|
-
},
|
|
171
|
-
"stepsCompleted": 2,
|
|
172
|
-
"format": "json"
|
|
173
|
-
}
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
On error, emits `{ "ok": false, "error": "..." }` and exits with code 1.
|
|
177
|
-
|
|
178
|
-
---
|
|
179
|
-
|
|
180
|
-
### `grimoire validate <config>`
|
|
181
|
-
|
|
182
|
-
Parse and validate a config file without running any prompts. Exits with a non-zero code if the config is invalid.
|
|
183
|
-
|
|
184
|
-
```bash
|
|
185
|
-
grimoire validate setup.yaml
|
|
186
|
-
# Valid wizard config: "Project Setup"
|
|
187
|
-
# 2 steps defined
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
---
|
|
191
|
-
|
|
192
|
-
### `grimoire create [output]`
|
|
193
|
-
|
|
194
|
-
Interactively scaffold a new wizard config file. Asks for a wizard name, description, number of steps, step types, output format, and optional theme. Writes a ready-to-run YAML file.
|
|
195
|
-
|
|
196
|
-
```bash
|
|
197
|
-
grimoire create # writes to wizard.yaml
|
|
198
|
-
grimoire create my-wizard.yaml # writes to my-wizard.yaml
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
---
|
|
202
|
-
|
|
203
|
-
### `grimoire demo`
|
|
204
|
-
|
|
205
|
-
Run the built-in demo wizard that exercises all 10 step types, step groups, and theming.
|
|
206
|
-
|
|
207
|
-
```bash
|
|
208
|
-
grimoire demo
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
---
|
|
212
|
-
|
|
213
|
-
### `grimoire completion <shell>`
|
|
214
|
-
|
|
215
|
-
Print a shell completion script to stdout. Pipe it into your shell's completion directory.
|
|
216
|
-
|
|
217
|
-
```bash
|
|
218
|
-
grimoire completion bash
|
|
219
|
-
grimoire completion zsh
|
|
220
|
-
grimoire completion fish
|
|
221
134
|
```
|
|
222
135
|
|
|
223
|
-
See [Shell Completions](#shell-completions) for installation instructions.
|
|
224
|
-
|
|
225
136
|
---
|
|
226
137
|
|
|
227
|
-
|
|
138
|
+
## Why grimoire?
|
|
228
139
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
grimoire cache clear "Project Setup" # clears cache for one wizard
|
|
234
|
-
```
|
|
140
|
+
- **No code required** for simple wizards. Write YAML, get a polished interactive CLI.
|
|
141
|
+
- **CI-friendly** — `--mock '{"step-id":"value"}'` runs non-interactively; `--json` emits structured output.
|
|
142
|
+
- **TypeScript API** when you need lifecycle hooks, async validation, plugins, or pipelines.
|
|
143
|
+
- **Post-wizard actions** — shell commands with `{{step-id}}` interpolation run after completion.
|
|
235
144
|
|
|
236
145
|
---
|
|
237
146
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
List all saved templates for a wizard.
|
|
147
|
+
## Step Types
|
|
241
148
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
149
|
+
| type | returns | use case |
|
|
150
|
+
|------|---------|----------|
|
|
151
|
+
| `text` | `string` | Free-form input with validation |
|
|
152
|
+
| `select` | `string` | Single choice from a list; supports `routes` |
|
|
153
|
+
| `multiselect` | `string[]` | Multiple choices; `min`/`max` constraints |
|
|
154
|
+
| `confirm` | `boolean` | Yes/no prompt |
|
|
155
|
+
| `password` | `string` | Masked input, never cached |
|
|
156
|
+
| `number` | `number` | Numeric input with `min`/`max`/`step` |
|
|
157
|
+
| `search` | `string` | Fuzzy-searchable single choice |
|
|
158
|
+
| `editor` | `string` | Opens terminal editor, returns full text |
|
|
159
|
+
| `path` | `string` | Path input with tab-completion |
|
|
160
|
+
| `toggle` | `boolean` | Binary toggle with custom labels |
|
|
161
|
+
| `note` | — | Inline info box, no input collected |
|
|
248
162
|
|
|
249
163
|
---
|
|
250
164
|
|
|
251
|
-
|
|
165
|
+
## CLI
|
|
252
166
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
grimoire
|
|
257
|
-
|
|
167
|
+
| command | description |
|
|
168
|
+
|---------|-------------|
|
|
169
|
+
| `grimoire run <config>` | Run a wizard. Flags: `--mock`, `--json`, `--dry-run`, `--template`, `--renderer` |
|
|
170
|
+
| `grimoire validate <config>` | Parse and validate without running |
|
|
171
|
+
| `grimoire create [output]` | Scaffold a new wizard config interactively |
|
|
172
|
+
| `grimoire demo` | Run the built-in demo (all 11 step types) |
|
|
173
|
+
| `grimoire completion <shell>` | Print bash/zsh/fish completion script |
|
|
174
|
+
| `grimoire cache clear [name]` | Clear cached answers |
|
|
175
|
+
| `grimoire template list/delete` | Manage named answer presets |
|
|
258
176
|
|
|
259
177
|
---
|
|
260
178
|
|
|
261
|
-
## Config
|
|
262
|
-
|
|
263
|
-
A grimoire config has these top-level sections:
|
|
264
|
-
|
|
265
|
-
| Section | Required | Description |
|
|
266
|
-
|---------|----------|-------------|
|
|
267
|
-
| `meta` | yes | Wizard name, version, description |
|
|
268
|
-
| `steps` | yes | Array of step definitions |
|
|
269
|
-
| `output` | no | Output format and file path |
|
|
270
|
-
| `theme` | no | Color tokens and icon overrides |
|
|
271
|
-
| `checks` | no | Pre-flight shell commands |
|
|
272
|
-
| `extends` | no | Path to a base config to inherit from |
|
|
179
|
+
## Config Shape
|
|
273
180
|
|
|
274
181
|
```yaml
|
|
182
|
+
# meta (required)
|
|
275
183
|
meta:
|
|
276
|
-
name:
|
|
277
|
-
version:
|
|
278
|
-
description:
|
|
184
|
+
name: string # wizard title
|
|
185
|
+
version: string # optional semver
|
|
186
|
+
description: string # shown at startup
|
|
187
|
+
review: boolean # show review screen before submit
|
|
279
188
|
|
|
189
|
+
# extends (optional) — inherit from a base config
|
|
280
190
|
extends: ./base.yaml
|
|
281
191
|
|
|
282
|
-
|
|
283
|
-
tokens:
|
|
284
|
-
primary: "#cba6f7"
|
|
285
|
-
icons:
|
|
286
|
-
pointer: ">"
|
|
287
|
-
|
|
192
|
+
# checks (optional) — pre-flight shell commands, abort on failure
|
|
288
193
|
checks:
|
|
289
|
-
- name:
|
|
290
|
-
run:
|
|
291
|
-
message:
|
|
194
|
+
- name: string
|
|
195
|
+
run: string # shell command
|
|
196
|
+
message: string # error if non-zero exit
|
|
292
197
|
|
|
198
|
+
# steps (required) — array of step definitions
|
|
293
199
|
steps:
|
|
294
|
-
- id:
|
|
295
|
-
type:
|
|
296
|
-
message:
|
|
297
|
-
|
|
200
|
+
- id: string # unique key in answers output
|
|
201
|
+
type: string # see step types table
|
|
202
|
+
message: string # prompt text
|
|
203
|
+
group: string # section header (shown once per group)
|
|
204
|
+
when: Condition # show only if condition passes
|
|
205
|
+
next: string # override sequential flow; "__done__" to end
|
|
206
|
+
default: any # initial value; "$ENV_VAR" reads from env
|
|
207
|
+
validate: Rule[] # required, minLength, maxLength, pattern, min, max
|
|
208
|
+
|
|
209
|
+
# output (optional)
|
|
298
210
|
output:
|
|
299
|
-
format: json
|
|
300
|
-
path: answers
|
|
301
|
-
```
|
|
302
|
-
|
|
303
|
-
### `meta`
|
|
304
|
-
|
|
305
|
-
| Field | Required | Description |
|
|
306
|
-
|-------|----------|-------------|
|
|
307
|
-
| `name` | yes | Wizard name, shown in the header |
|
|
308
|
-
| `version` | no | Config version string |
|
|
309
|
-
| `description` | no | Short description shown below the name |
|
|
310
|
-
|
|
311
|
-
---
|
|
312
|
-
|
|
313
|
-
## Step Types Reference
|
|
314
|
-
|
|
315
|
-
Every step requires `id`, `type`, and `message`. All other fields are optional unless noted.
|
|
316
|
-
|
|
317
|
-
### `text`
|
|
318
|
-
|
|
319
|
-
Free-form text input with optional placeholder, default, and validation.
|
|
320
|
-
|
|
321
|
-
```yaml
|
|
322
|
-
- id: project-name
|
|
323
|
-
type: text
|
|
324
|
-
message: What is your project name?
|
|
325
|
-
placeholder: my-awesome-project
|
|
326
|
-
default: my-app
|
|
327
|
-
validate:
|
|
328
|
-
- rule: required
|
|
329
|
-
- rule: minLength
|
|
330
|
-
value: 2
|
|
331
|
-
- rule: maxLength
|
|
332
|
-
value: 64
|
|
333
|
-
- rule: pattern
|
|
334
|
-
value: "^[a-z0-9-]+$"
|
|
335
|
-
message: Only lowercase letters, numbers, and hyphens
|
|
336
|
-
```
|
|
337
|
-
|
|
338
|
-
### `select`
|
|
339
|
-
|
|
340
|
-
Single-choice list. Returns the selected `value` string. Options can have a `hint` and can be `disabled`.
|
|
341
|
-
|
|
342
|
-
```yaml
|
|
343
|
-
- id: language
|
|
344
|
-
type: select
|
|
345
|
-
message: Pick a language
|
|
346
|
-
default: typescript
|
|
347
|
-
options:
|
|
348
|
-
- { value: typescript, label: TypeScript }
|
|
349
|
-
- { value: javascript, label: JavaScript }
|
|
350
|
-
- { value: python, label: Python }
|
|
351
|
-
- { value: go, label: Go, hint: "Fast and simple" }
|
|
352
|
-
- { value: rust, label: Rust, disabled: true }
|
|
353
|
-
routes:
|
|
354
|
-
typescript: ts-config
|
|
355
|
-
python: python-version
|
|
356
|
-
```
|
|
357
|
-
|
|
358
|
-
Instead of inline `options`, use `optionsFrom` to load options from an external file. See [Dynamic Options (`optionsFrom`)](#dynamic-options-optionsfrom).
|
|
359
|
-
|
|
360
|
-
### `multiselect`
|
|
361
|
-
|
|
362
|
-
Multi-choice list. Returns an array of selected `value` strings. Use `min` and `max` to constrain selection count.
|
|
363
|
-
|
|
364
|
-
```yaml
|
|
365
|
-
- id: features
|
|
366
|
-
type: multiselect
|
|
367
|
-
message: Select features to include
|
|
368
|
-
min: 1
|
|
369
|
-
max: 4
|
|
370
|
-
options:
|
|
371
|
-
- { value: eslint, label: ESLint, hint: Linting }
|
|
372
|
-
- { value: prettier, label: Prettier, hint: Formatting }
|
|
373
|
-
- { value: vitest, label: Vitest, hint: Testing }
|
|
374
|
-
- { value: husky, label: Husky, hint: "Git hooks" }
|
|
375
|
-
```
|
|
376
|
-
|
|
377
|
-
Supports `optionsFrom` as an alternative to inline `options`. See [Dynamic Options (`optionsFrom`)](#dynamic-options-optionsfrom).
|
|
211
|
+
format: json | yaml | env
|
|
212
|
+
path: string # write answers to file
|
|
378
213
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
message: Use TypeScript?
|
|
387
|
-
default: true
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
### `password`
|
|
391
|
-
|
|
392
|
-
Masked text input. The value is included in output but never echoed to the terminal.
|
|
393
|
-
|
|
394
|
-
```yaml
|
|
395
|
-
- id: api-key
|
|
396
|
-
type: password
|
|
397
|
-
message: Enter your API key
|
|
398
|
-
validate:
|
|
399
|
-
- rule: required
|
|
400
|
-
- rule: minLength
|
|
401
|
-
value: 32
|
|
402
|
-
message: API keys must be at least 32 characters
|
|
403
|
-
```
|
|
404
|
-
|
|
405
|
-
### `number`
|
|
406
|
-
|
|
407
|
-
Numeric input. Supports `min`, `max`, and `step` constraints.
|
|
408
|
-
|
|
409
|
-
```yaml
|
|
410
|
-
- id: port
|
|
411
|
-
type: number
|
|
412
|
-
message: Dev server port
|
|
413
|
-
default: 3000
|
|
414
|
-
min: 1024
|
|
415
|
-
max: 65535
|
|
416
|
-
step: 1
|
|
417
|
-
```
|
|
418
|
-
|
|
419
|
-
### `search`
|
|
420
|
-
|
|
421
|
-
Searchable single-choice list with fuzzy filtering. Useful for long option lists.
|
|
422
|
-
|
|
423
|
-
```yaml
|
|
424
|
-
- id: framework
|
|
425
|
-
type: search
|
|
426
|
-
message: Search for a framework
|
|
427
|
-
placeholder: Type to filter...
|
|
428
|
-
options:
|
|
429
|
-
- { value: nextjs, label: "Next.js" }
|
|
430
|
-
- { value: remix, label: Remix }
|
|
431
|
-
- { value: astro, label: Astro }
|
|
432
|
-
- { value: sveltekit, label: SvelteKit }
|
|
433
|
-
- { value: nuxt, label: Nuxt }
|
|
434
|
-
- { value: gatsby, label: Gatsby }
|
|
435
|
-
```
|
|
436
|
-
|
|
437
|
-
Supports `optionsFrom` as an alternative to inline `options`. See [Dynamic Options (`optionsFrom`)](#dynamic-options-optionsfrom).
|
|
438
|
-
|
|
439
|
-
### `editor`
|
|
440
|
-
|
|
441
|
-
Opens a multi-line text editor in the terminal. Returns the full text content when the user saves and exits.
|
|
442
|
-
|
|
443
|
-
```yaml
|
|
444
|
-
- id: readme-content
|
|
445
|
-
type: editor
|
|
446
|
-
message: Write your README content
|
|
447
|
-
default: "# My Project\n\nA short description."
|
|
448
|
-
required: false
|
|
449
|
-
```
|
|
450
|
-
|
|
451
|
-
### `path`
|
|
452
|
-
|
|
453
|
-
File system path input with tab-completion for existing paths.
|
|
454
|
-
|
|
455
|
-
```yaml
|
|
456
|
-
- id: project-dir
|
|
457
|
-
type: path
|
|
458
|
-
message: Where should we create the project?
|
|
459
|
-
placeholder: ./my-project
|
|
460
|
-
default: .
|
|
461
|
-
validate:
|
|
462
|
-
- rule: required
|
|
463
|
-
```
|
|
464
|
-
|
|
465
|
-
### `toggle`
|
|
466
|
-
|
|
467
|
-
A binary toggle with custom labels for each state. Returns a boolean.
|
|
468
|
-
|
|
469
|
-
```yaml
|
|
470
|
-
- id: dark-mode
|
|
471
|
-
type: toggle
|
|
472
|
-
message: Color scheme
|
|
473
|
-
active: Dark
|
|
474
|
-
inactive: Light
|
|
475
|
-
default: true
|
|
476
|
-
```
|
|
477
|
-
|
|
478
|
-
### `note`
|
|
479
|
-
|
|
480
|
-
Displays a bordered info box inline in the wizard flow. No input is collected. Useful for showing instructions, warnings, or section headers between prompts.
|
|
481
|
-
|
|
482
|
-
```yaml
|
|
483
|
-
- id: info
|
|
484
|
-
type: note
|
|
485
|
-
message: Setup Complete
|
|
486
|
-
description: "Run npm install to get started"
|
|
214
|
+
# theme (optional)
|
|
215
|
+
theme:
|
|
216
|
+
preset: catppuccin | dracula | nord | tokyonight | monokai
|
|
217
|
+
tokens: # override individual color tokens
|
|
218
|
+
primary: "#hex"
|
|
219
|
+
icons:
|
|
220
|
+
pointer: ">"
|
|
487
221
|
```
|
|
488
222
|
|
|
489
|
-
The `message` becomes the box title and `description` is the body text. Note steps are skipped in `--mock` mode and excluded from the answers output.
|
|
490
|
-
|
|
491
223
|
---
|
|
492
224
|
|
|
493
|
-
##
|
|
494
|
-
|
|
495
|
-
`select`, `multiselect`, and `search` steps can load their options from an external JSON or YAML file instead of defining them inline. This is useful when the option list is large, shared across multiple wizards, or generated by another tool.
|
|
496
|
-
|
|
497
|
-
```yaml
|
|
498
|
-
- id: framework
|
|
499
|
-
type: select
|
|
500
|
-
message: Pick a framework
|
|
501
|
-
optionsFrom: ./frameworks.json
|
|
502
|
-
```
|
|
503
|
-
|
|
504
|
-
`frameworks.json`:
|
|
505
|
-
|
|
506
|
-
```json
|
|
507
|
-
[
|
|
508
|
-
{ "value": "nextjs", "label": "Next.js" },
|
|
509
|
-
{ "value": "remix", "label": "Remix" },
|
|
510
|
-
{ "value": "astro", "label": "Astro" }
|
|
511
|
-
]
|
|
512
|
-
```
|
|
225
|
+
## Programmatic API
|
|
513
226
|
|
|
514
|
-
|
|
227
|
+
```typescript
|
|
228
|
+
import { defineWizard, runWizard, runPipeline } from 'grimoire-wizard'
|
|
515
229
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
230
|
+
const config = defineWizard({
|
|
231
|
+
meta: { name: 'Deploy' },
|
|
232
|
+
steps: [
|
|
233
|
+
{ id: 'env', type: 'select', message: 'Target?',
|
|
234
|
+
options: [{ value: 'prod', label: 'Production' }, { value: 'staging', label: 'Staging' }] },
|
|
235
|
+
{ id: 'confirm', type: 'confirm', message: 'Deploy now?', default: false },
|
|
236
|
+
],
|
|
237
|
+
output: { format: 'json' },
|
|
238
|
+
})
|
|
525
239
|
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
240
|
+
const answers = await runWizard(config, {
|
|
241
|
+
mockAnswers: { env: 'staging', confirm: true }, // CI mode
|
|
242
|
+
onStepComplete: (stepId, value) => console.log(stepId, value),
|
|
243
|
+
onCancel: () => process.exit(1),
|
|
244
|
+
asyncValidate: async (stepId, value) => {
|
|
245
|
+
if (stepId === 'env' && value === 'prod') return 'Use staging first'
|
|
246
|
+
return null
|
|
247
|
+
},
|
|
248
|
+
plugins: [], // GrimoirePlugin[] for custom step types
|
|
249
|
+
cache: true, // persist answers as defaults on next run
|
|
250
|
+
})
|
|
531
251
|
```
|
|
532
252
|
|
|
533
|
-
|
|
253
|
+
Key `RunWizardOptions`: `mockAnswers`, `templateAnswers`, `onBeforeStep`, `onAfterStep`, `onStepComplete`, `onCancel`, `asyncValidate`, `plugins`, `cache`, `mru`, `renderer`, `quiet`, `plain`.
|
|
534
254
|
|
|
535
255
|
---
|
|
536
256
|
|
|
537
|
-
##
|
|
538
|
-
|
|
539
|
-
Add a `group` field to any step to display a section header when that group starts. The header is shown once, the first time a step in that group is reached.
|
|
540
|
-
|
|
541
|
-
```yaml
|
|
542
|
-
steps:
|
|
543
|
-
- id: name
|
|
544
|
-
type: text
|
|
545
|
-
group: "Project Info"
|
|
546
|
-
message: Project name?
|
|
547
|
-
|
|
548
|
-
- id: description
|
|
549
|
-
type: text
|
|
550
|
-
group: "Project Info"
|
|
551
|
-
message: Short description?
|
|
552
|
-
|
|
553
|
-
- id: framework
|
|
554
|
-
type: select
|
|
555
|
-
group: "Tech Stack"
|
|
556
|
-
message: Pick a framework
|
|
557
|
-
options:
|
|
558
|
-
- { value: react, label: React }
|
|
559
|
-
- { value: vue, label: Vue }
|
|
560
|
-
```
|
|
561
|
-
|
|
562
|
-
---
|
|
563
|
-
|
|
564
|
-
## Conditions
|
|
565
|
-
|
|
566
|
-
Use the `when` field on any step to show it only when a condition is met. Steps that don't pass their condition are skipped and excluded from the output.
|
|
567
|
-
|
|
568
|
-
```yaml
|
|
569
|
-
- id: ts-config
|
|
570
|
-
type: select
|
|
571
|
-
message: Which tsconfig preset?
|
|
572
|
-
when:
|
|
573
|
-
field: language
|
|
574
|
-
equals: typescript
|
|
575
|
-
options:
|
|
576
|
-
- { value: strict, label: Strict }
|
|
577
|
-
- { value: base, label: Base }
|
|
578
|
-
```
|
|
579
|
-
|
|
580
|
-
### Condition operators
|
|
581
|
-
|
|
582
|
-
| Operator | Shape | Description |
|
|
583
|
-
|----------|-------|-------------|
|
|
584
|
-
| `equals` | `{ field, equals }` | Field value equals the given value |
|
|
585
|
-
| `notEquals` | `{ field, notEquals }` | Field value does not equal the given value |
|
|
586
|
-
| `includes` | `{ field, includes }` | Array field includes the given value |
|
|
587
|
-
| `notIncludes` | `{ field, notIncludes }` | Array field does not include the given value |
|
|
588
|
-
| `greaterThan` | `{ field, greaterThan }` | Numeric field is greater than the given value |
|
|
589
|
-
| `lessThan` | `{ field, lessThan }` | Numeric field is less than the given value |
|
|
590
|
-
| `isEmpty` | `{ field, isEmpty: true }` | Field is empty, null, or an empty array |
|
|
591
|
-
| `isNotEmpty` | `{ field, isNotEmpty: true }` | Field is not empty |
|
|
592
|
-
|
|
593
|
-
### Compound conditions
|
|
594
|
-
|
|
595
|
-
Combine conditions with `all`, `any`, or `not`:
|
|
596
|
-
|
|
597
|
-
```yaml
|
|
598
|
-
# All conditions must be true
|
|
599
|
-
when:
|
|
600
|
-
all:
|
|
601
|
-
- field: language
|
|
602
|
-
equals: typescript
|
|
603
|
-
- field: features
|
|
604
|
-
includes: eslint
|
|
257
|
+
## AI Agent Integration
|
|
605
258
|
|
|
606
|
-
|
|
607
|
-
when:
|
|
608
|
-
any:
|
|
609
|
-
- field: project-type
|
|
610
|
-
equals: web
|
|
611
|
-
- field: project-type
|
|
612
|
-
equals: api
|
|
259
|
+
Paste this URL into Claude, ChatGPT, or any LLM to generate correct wizard configs instantly:
|
|
613
260
|
|
|
614
|
-
# Negate a condition
|
|
615
|
-
when:
|
|
616
|
-
not:
|
|
617
|
-
field: skip-tests
|
|
618
|
-
equals: true
|
|
619
261
|
```
|
|
620
|
-
|
|
621
|
-
---
|
|
622
|
-
|
|
623
|
-
## Routes
|
|
624
|
-
|
|
625
|
-
A `select` step can branch to different step sequences based on the chosen value. Set `routes` to a map of option values to step IDs. Grimoire jumps to the mapped step instead of the next step in the list.
|
|
626
|
-
|
|
627
|
-
```yaml
|
|
628
|
-
- id: project-type
|
|
629
|
-
type: select
|
|
630
|
-
message: What kind of project?
|
|
631
|
-
options:
|
|
632
|
-
- { value: web, label: "Web App" }
|
|
633
|
-
- { value: api, label: "REST API" }
|
|
634
|
-
- { value: cli, label: "CLI Tool" }
|
|
635
|
-
routes:
|
|
636
|
-
web: web-framework
|
|
637
|
-
api: api-framework
|
|
638
|
-
cli: cli-features
|
|
639
|
-
|
|
640
|
-
- id: web-framework
|
|
641
|
-
type: select
|
|
642
|
-
message: Which web framework?
|
|
643
|
-
options:
|
|
644
|
-
- { value: nextjs, label: "Next.js" }
|
|
645
|
-
- { value: remix, label: Remix }
|
|
646
|
-
next: deploy
|
|
647
|
-
|
|
648
|
-
- id: api-framework
|
|
649
|
-
type: select
|
|
650
|
-
message: Which API framework?
|
|
651
|
-
options:
|
|
652
|
-
- { value: express, label: Express }
|
|
653
|
-
- { value: fastify, label: Fastify }
|
|
654
|
-
next: deploy
|
|
655
|
-
|
|
656
|
-
- id: cli-features
|
|
657
|
-
type: multiselect
|
|
658
|
-
message: CLI features to include
|
|
659
|
-
options:
|
|
660
|
-
- { value: args, label: "Argument parsing" }
|
|
661
|
-
- { value: colors, label: "Colored output" }
|
|
662
|
-
next: deploy
|
|
663
|
-
|
|
664
|
-
- id: deploy
|
|
665
|
-
type: select
|
|
666
|
-
message: Deployment target?
|
|
667
|
-
options:
|
|
668
|
-
- { value: vercel, label: Vercel }
|
|
669
|
-
- { value: docker, label: Docker }
|
|
262
|
+
https://raw.githubusercontent.com/YosefHayim/grimoire/main/docs/GRIMOIRE_REFERENCE.md
|
|
670
263
|
```
|
|
671
264
|
|
|
672
|
-
|
|
265
|
+
The reference doc covers the full schema, all step types, conditions, routes, actions, and annotated examples.
|
|
673
266
|
|
|
674
267
|
---
|
|
675
268
|
|
|
676
|
-
##
|
|
677
|
-
|
|
678
|
-
Add a `validate` array to any step that supports it (`text`, `password`, `editor`, `path`). Rules are checked in order and the first failure stops validation.
|
|
269
|
+
## Contributing
|
|
679
270
|
|
|
680
|
-
|
|
681
|
-
validate:
|
|
682
|
-
- rule: required
|
|
683
|
-
- rule: minLength
|
|
684
|
-
value: 2
|
|
685
|
-
- rule: maxLength
|
|
686
|
-
value: 128
|
|
687
|
-
- rule: pattern
|
|
688
|
-
value: "^[a-zA-Z0-9_-]+$"
|
|
689
|
-
message: Only letters, numbers, underscores, and hyphens allowed
|
|
690
|
-
- rule: min
|
|
691
|
-
value: 0
|
|
692
|
-
- rule: max
|
|
693
|
-
value: 100
|
|
694
|
-
```
|
|
695
|
-
|
|
696
|
-
| Rule | Applies to | Description |
|
|
697
|
-
|------|-----------|-------------|
|
|
698
|
-
| `required` | all | Value must not be empty |
|
|
699
|
-
| `minLength` | text, password, editor, path | Minimum character count |
|
|
700
|
-
| `maxLength` | text, password, editor, path | Maximum character count |
|
|
701
|
-
| `pattern` | text, password, editor, path | Must match the given regex string |
|
|
702
|
-
| `min` | number | Minimum numeric value |
|
|
703
|
-
| `max` | number | Maximum numeric value |
|
|
704
|
-
|
|
705
|
-
All rules accept an optional `message` field to override the default error text.
|
|
271
|
+
Open to contributors. Check the [issues](https://github.com/YosefHayim/grimoire/issues) for good first tasks, or open one if you have an idea.
|
|
706
272
|
|
|
707
273
|
---
|
|
708
274
|
|
|
709
|
-
##
|
|
710
|
-
|
|
711
|
-
Define a `theme` block in your config to customize colors and icons. Colors accept any 6-digit hex string. All tokens are optional and fall back to grimoire's defaults.
|
|
712
|
-
|
|
713
|
-
```yaml
|
|
714
|
-
theme:
|
|
715
|
-
tokens:
|
|
716
|
-
primary: "#89b4fa"
|
|
717
|
-
success: "#a6e3a1"
|
|
718
|
-
error: "#f38ba8"
|
|
719
|
-
warning: "#fab387"
|
|
720
|
-
info: "#74c7ec"
|
|
721
|
-
muted: "#6c7086"
|
|
722
|
-
accent: "#cba6f7"
|
|
723
|
-
icons:
|
|
724
|
-
step: "●"
|
|
725
|
-
stepDone: "✔"
|
|
726
|
-
stepPending: "○"
|
|
727
|
-
pointer: "❯"
|
|
728
|
-
```
|
|
729
|
-
|
|
730
|
-
### Color tokens
|
|
731
|
-
|
|
732
|
-
| Token | Used for |
|
|
733
|
-
|-------|---------|
|
|
734
|
-
| `primary` | Step headers, active selections |
|
|
735
|
-
| `success` | Completion messages, check marks |
|
|
736
|
-
| `error` | Validation errors, failed checks |
|
|
737
|
-
| `warning` | Cancellation messages |
|
|
738
|
-
| `info` | Informational text |
|
|
739
|
-
| `muted` | Descriptions, secondary text |
|
|
740
|
-
| `accent` | Highlights, group headers |
|
|
741
|
-
|
|
742
|
-
### Icons
|
|
743
|
-
|
|
744
|
-
| Icon | Used for |
|
|
745
|
-
|------|---------|
|
|
746
|
-
| `step` | Current step indicator |
|
|
747
|
-
| `stepDone` | Completed step indicator |
|
|
748
|
-
| `stepPending` | Upcoming step indicator |
|
|
749
|
-
| `pointer` | Selection cursor in lists |
|
|
750
|
-
|
|
751
|
-
### Theme presets
|
|
752
|
-
|
|
753
|
-
Instead of specifying individual tokens, pick a built-in preset with a single line:
|
|
275
|
+
## Requirements
|
|
754
276
|
|
|
755
|
-
|
|
756
|
-
theme:
|
|
757
|
-
preset: catppuccin
|
|
758
|
-
```
|
|
759
|
-
|
|
760
|
-
| Preset | Primary color | Style |
|
|
761
|
-
|--------|--------------|-------|
|
|
762
|
-
| `default` | `#7C3AED` | Purple |
|
|
763
|
-
| `catppuccin` | `#cba6f7` | Soft lavender (Mocha) |
|
|
764
|
-
| `dracula` | `#bd93f9` | Purple on dark |
|
|
765
|
-
| `nord` | `#88c0d0` | Arctic blue |
|
|
766
|
-
| `tokyonight` | `#7aa2f7` | Night blue |
|
|
767
|
-
| `monokai` | `#a6e22e` | Vibrant green |
|
|
768
|
-
|
|
769
|
-
Any `tokens` or `icons` you set alongside `preset` override the preset's values.
|
|
770
|
-
|
|
771
|
-
---
|
|
772
|
-
|
|
773
|
-
## Environment Variables
|
|
774
|
-
|
|
775
|
-
Any `default` field that starts with `$` is treated as an environment variable reference. Grimoire resolves it at runtime from `process.env`. If the variable is not set, the literal string (e.g., `$MY_VAR`) is used as the default.
|
|
776
|
-
|
|
777
|
-
```yaml
|
|
778
|
-
- id: api-url
|
|
779
|
-
type: text
|
|
780
|
-
message: API base URL
|
|
781
|
-
default: $API_BASE_URL
|
|
782
|
-
|
|
783
|
-
- id: port
|
|
784
|
-
type: number
|
|
785
|
-
message: Port number
|
|
786
|
-
default: $PORT
|
|
787
|
-
|
|
788
|
-
- id: debug
|
|
789
|
-
type: confirm
|
|
790
|
-
message: Enable debug mode?
|
|
791
|
-
default: $DEBUG_MODE
|
|
792
|
-
```
|
|
793
|
-
|
|
794
|
-
Supported on: `text`, `select`, `search`, `editor`, `path`, `number`, `confirm`, `toggle`.
|
|
795
|
-
|
|
796
|
-
---
|
|
797
|
-
|
|
798
|
-
## Config Inheritance
|
|
799
|
-
|
|
800
|
-
Use `extends` to inherit from a base config. The child config's `steps`, `theme`, `output`, and `checks` replace the base config's values entirely. The `meta` from the child takes precedence.
|
|
801
|
-
|
|
802
|
-
```yaml
|
|
803
|
-
# base.yaml
|
|
804
|
-
meta:
|
|
805
|
-
name: Base Wizard
|
|
806
|
-
theme:
|
|
807
|
-
tokens:
|
|
808
|
-
primary: "#7C3AED"
|
|
809
|
-
steps:
|
|
810
|
-
- id: name
|
|
811
|
-
type: text
|
|
812
|
-
message: Project name?
|
|
813
|
-
validate:
|
|
814
|
-
- rule: required
|
|
815
|
-
output:
|
|
816
|
-
format: json
|
|
817
|
-
```
|
|
818
|
-
|
|
819
|
-
```yaml
|
|
820
|
-
# extended.yaml
|
|
821
|
-
extends: ./base.yaml
|
|
822
|
-
|
|
823
|
-
meta:
|
|
824
|
-
name: Extended Wizard
|
|
825
|
-
description: Extends base config with additional steps
|
|
826
|
-
|
|
827
|
-
steps:
|
|
828
|
-
- id: name
|
|
829
|
-
type: text
|
|
830
|
-
message: Project name?
|
|
831
|
-
validate:
|
|
832
|
-
- rule: required
|
|
833
|
-
|
|
834
|
-
- id: language
|
|
835
|
-
type: select
|
|
836
|
-
message: Language?
|
|
837
|
-
options:
|
|
838
|
-
- { value: typescript, label: TypeScript }
|
|
839
|
-
- { value: javascript, label: JavaScript }
|
|
840
|
-
|
|
841
|
-
- id: confirm
|
|
842
|
-
type: confirm
|
|
843
|
-
message: Create project?
|
|
844
|
-
next: __done__
|
|
845
|
-
|
|
846
|
-
output:
|
|
847
|
-
format: yaml
|
|
848
|
-
path: project-config.yaml
|
|
849
|
-
```
|
|
850
|
-
|
|
851
|
-
The `extends` path is resolved relative to the child config file.
|
|
852
|
-
|
|
853
|
-
---
|
|
854
|
-
|
|
855
|
-
## Pre-flight Checks
|
|
856
|
-
|
|
857
|
-
The `checks` block runs shell commands before the wizard starts. If any command exits with a non-zero code, grimoire prints the associated `message` and aborts. Pre-flight checks are skipped in `--mock` mode.
|
|
858
|
-
|
|
859
|
-
```yaml
|
|
860
|
-
checks:
|
|
861
|
-
- name: Node.js installed
|
|
862
|
-
run: node --version
|
|
863
|
-
message: "Node.js is required. Install from https://nodejs.org"
|
|
864
|
-
|
|
865
|
-
- name: Git available
|
|
866
|
-
run: git --version
|
|
867
|
-
message: "Git is required. Install from https://git-scm.com"
|
|
868
|
-
|
|
869
|
-
- name: Docker running
|
|
870
|
-
run: docker info
|
|
871
|
-
message: "Docker must be running before deployment."
|
|
872
|
-
```
|
|
873
|
-
|
|
874
|
-
| Field | Required | Description |
|
|
875
|
-
|-------|----------|-------------|
|
|
876
|
-
| `name` | yes | Display name shown in the pre-flight output |
|
|
877
|
-
| `run` | yes | Shell command to execute |
|
|
878
|
-
| `message` | yes | Error message shown if the command fails |
|
|
879
|
-
|
|
880
|
-
---
|
|
881
|
-
|
|
882
|
-
## Plugin System
|
|
883
|
-
|
|
884
|
-
Plugins let you register custom step types with their own render and validate logic. A plugin is a plain object with a `name` and a `steps` map.
|
|
885
|
-
|
|
886
|
-
```typescript
|
|
887
|
-
import { runWizard, defineWizard } from 'grimoire-wizard'
|
|
888
|
-
import type { GrimoirePlugin } from 'grimoire-wizard'
|
|
889
|
-
|
|
890
|
-
const myPlugin: GrimoirePlugin = {
|
|
891
|
-
name: 'my-plugin',
|
|
892
|
-
steps: {
|
|
893
|
-
'date-picker': {
|
|
894
|
-
async render(config, state, theme) {
|
|
895
|
-
// config is the raw step config object
|
|
896
|
-
// state is the current WizardState
|
|
897
|
-
// theme is the ResolvedTheme
|
|
898
|
-
const answer = await myDatePickerPrompt(config.message as string)
|
|
899
|
-
return answer
|
|
900
|
-
},
|
|
901
|
-
validate(value, config) {
|
|
902
|
-
if (!value) return 'A date is required'
|
|
903
|
-
return null // null means valid
|
|
904
|
-
},
|
|
905
|
-
},
|
|
906
|
-
},
|
|
907
|
-
}
|
|
908
|
-
|
|
909
|
-
const config = defineWizard({
|
|
910
|
-
meta: { name: 'My Wizard' },
|
|
911
|
-
steps: [
|
|
912
|
-
{
|
|
913
|
-
id: 'launch-date',
|
|
914
|
-
type: 'date-picker',
|
|
915
|
-
message: 'Pick a launch date',
|
|
916
|
-
} as any,
|
|
917
|
-
],
|
|
918
|
-
output: { format: 'json' },
|
|
919
|
-
})
|
|
920
|
-
|
|
921
|
-
const answers = await runWizard(config, {
|
|
922
|
-
plugins: [myPlugin],
|
|
923
|
-
})
|
|
924
|
-
```
|
|
925
|
-
|
|
926
|
-
Built-in step types (`text`, `select`, `multiselect`, `confirm`, `password`, `number`, `search`, `editor`, `path`, `toggle`) cannot be overridden by plugins.
|
|
927
|
-
|
|
928
|
-
### Plugin interfaces
|
|
929
|
-
|
|
930
|
-
```typescript
|
|
931
|
-
interface GrimoirePlugin {
|
|
932
|
-
name: string;
|
|
933
|
-
steps: Record<string, StepPlugin>;
|
|
934
|
-
}
|
|
935
|
-
|
|
936
|
-
interface StepPlugin {
|
|
937
|
-
render(
|
|
938
|
-
config: Record<string, unknown>,
|
|
939
|
-
state: WizardState,
|
|
940
|
-
theme: ResolvedTheme
|
|
941
|
-
): Promise<unknown>;
|
|
942
|
-
validate?(value: unknown, config: Record<string, unknown>): string | null;
|
|
943
|
-
}
|
|
944
|
-
```
|
|
945
|
-
|
|
946
|
-
---
|
|
947
|
-
|
|
948
|
-
## Programmatic API
|
|
949
|
-
|
|
950
|
-
### Core functions
|
|
951
|
-
|
|
952
|
-
```typescript
|
|
953
|
-
import { loadWizardConfig, runWizard, defineWizard } from 'grimoire-wizard'
|
|
954
|
-
|
|
955
|
-
// Load from a file (YAML, JSON, JS, or TS)
|
|
956
|
-
const config = await loadWizardConfig('./setup.yaml')
|
|
957
|
-
const answers = await runWizard(config)
|
|
958
|
-
console.log(answers)
|
|
959
|
-
```
|
|
960
|
-
|
|
961
|
-
### `defineWizard(config)`
|
|
962
|
-
|
|
963
|
-
Identity function that returns the config unchanged. Its value is type inference: TypeScript will check your config object against `WizardConfig` at compile time.
|
|
964
|
-
|
|
965
|
-
```typescript
|
|
966
|
-
import { defineWizard, runWizard } from 'grimoire-wizard'
|
|
967
|
-
|
|
968
|
-
const config = defineWizard({
|
|
969
|
-
meta: {
|
|
970
|
-
name: 'Deploy Config',
|
|
971
|
-
description: 'Configure your deployment target.',
|
|
972
|
-
},
|
|
973
|
-
steps: [
|
|
974
|
-
{
|
|
975
|
-
id: 'environment',
|
|
976
|
-
type: 'select',
|
|
977
|
-
message: 'Target environment?',
|
|
978
|
-
options: [
|
|
979
|
-
{ label: 'Production', value: 'prod' },
|
|
980
|
-
{ label: 'Staging', value: 'staging' },
|
|
981
|
-
],
|
|
982
|
-
},
|
|
983
|
-
{
|
|
984
|
-
id: 'confirm',
|
|
985
|
-
type: 'confirm',
|
|
986
|
-
message: 'Ready to deploy?',
|
|
987
|
-
default: false,
|
|
988
|
-
},
|
|
989
|
-
],
|
|
990
|
-
output: { format: 'json' },
|
|
991
|
-
})
|
|
992
|
-
|
|
993
|
-
const answers = await runWizard(config, {
|
|
994
|
-
onStepComplete: (stepId, value, state) => {
|
|
995
|
-
console.log(`${stepId} answered: ${String(value)}`)
|
|
996
|
-
},
|
|
997
|
-
onCancel: (state) => {
|
|
998
|
-
console.log('Wizard cancelled')
|
|
999
|
-
process.exit(1)
|
|
1000
|
-
},
|
|
1001
|
-
})
|
|
1002
|
-
```
|
|
1003
|
-
|
|
1004
|
-
### `RunWizardOptions`
|
|
1005
|
-
|
|
1006
|
-
| Option | Type | Description |
|
|
1007
|
-
|--------|------|-------------|
|
|
1008
|
-
| `renderer` | `WizardRenderer` | Custom renderer (defaults to `InquirerRenderer`) |
|
|
1009
|
-
| `quiet` | `boolean` | Suppress title, description, and summary output |
|
|
1010
|
-
| `plain` | `boolean` | Disable colors and banner (plain-text mode) |
|
|
1011
|
-
| `mockAnswers` | `Record<string, unknown>` | Preset answers for non-interactive mode |
|
|
1012
|
-
| `templateAnswers` | `Record<string, unknown>` | Pre-loaded template answers used as defaults |
|
|
1013
|
-
| `onBeforeStep` | `(stepId, step, state) => void \| Promise<void>` | Called before each step is rendered |
|
|
1014
|
-
| `onAfterStep` | `(stepId, value, state) => void \| Promise<void>` | Called after each step completes, before moving on |
|
|
1015
|
-
| `onStepComplete` | `(stepId, value, state) => void` | Called after each step completes |
|
|
1016
|
-
| `onCancel` | `(state) => void` | Called when the user cancels with Ctrl+C |
|
|
1017
|
-
| `plugins` | `GrimoirePlugin[]` | Custom step type plugins |
|
|
1018
|
-
| `asyncValidate` | `(stepId, value, answers) => Promise<string \| null>` | Async validation hook called after each step |
|
|
1019
|
-
| `cache` | `boolean \| { dir?: string }` | Enable/disable answer caching, or set a custom cache directory (default: `true`) |
|
|
1020
|
-
| `mru` | `boolean` | Enable/disable MRU ordering for select/multiselect/search steps (default: `true`) |
|
|
1021
|
-
|
|
1022
|
-
### Async validation
|
|
1023
|
-
|
|
1024
|
-
The `asyncValidate` hook runs after each step's synchronous validation passes. Return a string to show as an error and re-prompt the step, or return `null` to accept the value.
|
|
1025
|
-
|
|
1026
|
-
```typescript
|
|
1027
|
-
const answers = await runWizard(config, {
|
|
1028
|
-
asyncValidate: async (stepId, value, answers) => {
|
|
1029
|
-
if (stepId === 'username') {
|
|
1030
|
-
const taken = await checkUsernameAvailability(value as string)
|
|
1031
|
-
if (taken) return 'That username is already taken'
|
|
1032
|
-
}
|
|
1033
|
-
return null
|
|
1034
|
-
},
|
|
1035
|
-
})
|
|
1036
|
-
```
|
|
1037
|
-
|
|
1038
|
-
### Lifecycle hooks
|
|
1039
|
-
|
|
1040
|
-
`onBeforeStep` fires just before a step is rendered. `onAfterStep` fires after the user answers but before the wizard advances. Both can be async.
|
|
1041
|
-
|
|
1042
|
-
```typescript
|
|
1043
|
-
const answers = await runWizard(config, {
|
|
1044
|
-
onBeforeStep: async (stepId, step, state) => {
|
|
1045
|
-
console.log(`About to render: ${stepId}`)
|
|
1046
|
-
},
|
|
1047
|
-
onAfterStep: async (stepId, value, state) => {
|
|
1048
|
-
await logAnswer(stepId, value)
|
|
1049
|
-
},
|
|
1050
|
-
})
|
|
1051
|
-
```
|
|
1052
|
-
|
|
1053
|
-
### Ink renderer
|
|
1054
|
-
|
|
1055
|
-
The `InkRenderer` is an alternative to the default `InquirerRenderer`. It uses box-drawing characters, a filled progress bar with percentage, and formatted step headers.
|
|
1056
|
-
|
|
1057
|
-
```typescript
|
|
1058
|
-
import { runWizard } from 'grimoire-wizard'
|
|
1059
|
-
import { InkRenderer } from 'grimoire-wizard/renderers/ink'
|
|
1060
|
-
|
|
1061
|
-
const answers = await runWizard(config, {
|
|
1062
|
-
renderer: new InkRenderer(),
|
|
1063
|
-
})
|
|
1064
|
-
```
|
|
1065
|
-
|
|
1066
|
-
Or from the CLI:
|
|
1067
|
-
|
|
1068
|
-
```bash
|
|
1069
|
-
grimoire run setup.yaml --renderer ink
|
|
1070
|
-
```
|
|
1071
|
-
|
|
1072
|
-
### Clack renderer
|
|
1073
|
-
|
|
1074
|
-
The `ClackRenderer` gives your wizard a clack-style visual flow: a continuous `│` guide line connects all prompts, answered steps collapse to a single `◇ Question · answer` line, and the session opens with a `┌` header and closes with a `└` outro. Note steps render as bordered boxes. Spinners animate during async operations.
|
|
1075
|
-
|
|
1076
|
-
```bash
|
|
1077
|
-
grimoire run setup.yaml --renderer clack
|
|
1078
|
-
```
|
|
1079
|
-
|
|
1080
|
-
Or programmatically:
|
|
1081
|
-
|
|
1082
|
-
```typescript
|
|
1083
|
-
import { runWizard } from 'grimoire-wizard'
|
|
1084
|
-
import { ClackRenderer } from 'grimoire-wizard'
|
|
1085
|
-
|
|
1086
|
-
const answers = await runWizard(config, {
|
|
1087
|
-
renderer: new ClackRenderer(),
|
|
1088
|
-
})
|
|
1089
|
-
```
|
|
1090
|
-
|
|
1091
|
-
### Exported types
|
|
1092
|
-
|
|
1093
|
-
```typescript
|
|
1094
|
-
import type {
|
|
1095
|
-
WizardConfig,
|
|
1096
|
-
StepConfig,
|
|
1097
|
-
TextStepConfig,
|
|
1098
|
-
SelectStepConfig,
|
|
1099
|
-
MultiSelectStepConfig,
|
|
1100
|
-
ConfirmStepConfig,
|
|
1101
|
-
PasswordStepConfig,
|
|
1102
|
-
NumberStepConfig,
|
|
1103
|
-
SearchStepConfig,
|
|
1104
|
-
EditorStepConfig,
|
|
1105
|
-
PathStepConfig,
|
|
1106
|
-
ToggleStepConfig,
|
|
1107
|
-
NoteStepConfig,
|
|
1108
|
-
SelectOption,
|
|
1109
|
-
ValidationRule,
|
|
1110
|
-
Condition,
|
|
1111
|
-
ThemeConfig,
|
|
1112
|
-
ResolvedTheme,
|
|
1113
|
-
WizardState,
|
|
1114
|
-
WizardTransition,
|
|
1115
|
-
WizardRenderer,
|
|
1116
|
-
WizardEvent,
|
|
1117
|
-
PreFlightCheck,
|
|
1118
|
-
RunWizardOptions,
|
|
1119
|
-
GrimoirePlugin,
|
|
1120
|
-
StepPlugin,
|
|
1121
|
-
} from 'grimoire-wizard'
|
|
1122
|
-
```
|
|
1123
|
-
|
|
1124
|
-
### Utility functions
|
|
1125
|
-
|
|
1126
|
-
```typescript
|
|
1127
|
-
import {
|
|
1128
|
-
parseWizardConfig, // Parse and validate a raw config object against the schema
|
|
1129
|
-
parseWizardYAML, // Parse a YAML string into a WizardConfig
|
|
1130
|
-
evaluateCondition, // Evaluate a Condition against an answers map
|
|
1131
|
-
isStepVisible, // Check if a step should be shown given current answers
|
|
1132
|
-
createWizardState, // Create an initial WizardState from a config
|
|
1133
|
-
wizardReducer, // Pure reducer for wizard state transitions
|
|
1134
|
-
getVisibleSteps, // Get all currently visible steps given current answers
|
|
1135
|
-
resolveNextStep, // Resolve the next step ID (respects routes and next fields)
|
|
1136
|
-
validateStepAnswer, // Run validation rules against a value
|
|
1137
|
-
resolveTheme, // Merge a ThemeConfig with defaults into a ResolvedTheme
|
|
1138
|
-
resolveEnvDefault, // Resolve a $ENV_VAR string from process.env
|
|
1139
|
-
runPreFlightChecks, // Run a checks array and throw on first failure
|
|
1140
|
-
registerPlugin, // Register a GrimoirePlugin into the global registry
|
|
1141
|
-
getPluginStep, // Look up a registered StepPlugin by type name
|
|
1142
|
-
clearPlugins, // Clear all registered plugins
|
|
1143
|
-
// Cache
|
|
1144
|
-
loadCachedAnswers, // Load cached answers for a wizard by name
|
|
1145
|
-
saveCachedAnswers, // Save answers to the cache for a wizard
|
|
1146
|
-
clearCache, // Delete cached answers (one wizard or all)
|
|
1147
|
-
// MRU
|
|
1148
|
-
recordSelection, // Record a user's selection for MRU tracking
|
|
1149
|
-
getOrderedOptions, // Return options sorted by selection frequency
|
|
1150
|
-
// Templates
|
|
1151
|
-
saveTemplate, // Save a named answer preset for a wizard
|
|
1152
|
-
loadTemplate, // Load a named answer preset
|
|
1153
|
-
listTemplates, // List all saved template names for a wizard
|
|
1154
|
-
deleteTemplate, // Delete a named template
|
|
1155
|
-
// Banner
|
|
1156
|
-
renderBanner, // Render the ASCII art banner for a wizard name
|
|
1157
|
-
// Renderers
|
|
1158
|
-
ClackRenderer, // Clack-style renderer with guide lines and collapsed steps
|
|
1159
|
-
// Pipelines
|
|
1160
|
-
runPipeline, // Chain multiple wizard configs in sequence
|
|
1161
|
-
// Progress persistence
|
|
1162
|
-
saveProgress, // Save wizard progress to disk
|
|
1163
|
-
loadProgress, // Load saved wizard progress
|
|
1164
|
-
clearProgress, // Delete saved wizard progress
|
|
1165
|
-
} from 'grimoire-wizard'
|
|
1166
|
-
```
|
|
1167
|
-
|
|
1168
|
-
---
|
|
1169
|
-
|
|
1170
|
-
## Answer Caching
|
|
1171
|
-
|
|
1172
|
-
Grimoire remembers your answers between runs. The next time you run the same wizard, cached answers become the default values for each step, so you only need to change what's different.
|
|
1173
|
-
|
|
1174
|
-
Password steps are never cached.
|
|
1175
|
-
|
|
1176
|
-
Cache files are stored in `~/.config/grimoire/cache/` as JSON, one file per wizard (named by slugifying the wizard's `meta.name`).
|
|
1177
|
-
|
|
1178
|
-
Caching is enabled by default. Disable it for a single run with `--no-cache`:
|
|
1179
|
-
|
|
1180
|
-
```bash
|
|
1181
|
-
grimoire run setup.yaml --no-cache
|
|
1182
|
-
```
|
|
1183
|
-
|
|
1184
|
-
Clear the cache from the CLI:
|
|
1185
|
-
|
|
1186
|
-
```bash
|
|
1187
|
-
grimoire cache clear # clears all wizards
|
|
1188
|
-
grimoire cache clear "Project Setup" # clears one wizard
|
|
1189
|
-
```
|
|
1190
|
-
|
|
1191
|
-
Control caching in the programmatic API via the `cache` option:
|
|
1192
|
-
|
|
1193
|
-
```typescript
|
|
1194
|
-
// Disable caching entirely
|
|
1195
|
-
const answers = await runWizard(config, { cache: false })
|
|
1196
|
-
|
|
1197
|
-
// Use a custom cache directory
|
|
1198
|
-
const answers = await runWizard(config, { cache: { dir: '/tmp/my-cache' } })
|
|
1199
|
-
```
|
|
1200
|
-
|
|
1201
|
-
---
|
|
1202
|
-
|
|
1203
|
-
## Progress Persistence
|
|
1204
|
-
|
|
1205
|
-
If you press Ctrl+C mid-wizard, grimoire saves your progress automatically. The next time you run the same wizard, it resumes from where you left off, with all previous answers pre-filled.
|
|
1206
|
-
|
|
1207
|
-
Progress files are stored in `~/.config/grimoire/progress/` as JSON, one file per wizard.
|
|
1208
|
-
|
|
1209
|
-
Disable resume for a single run:
|
|
1210
|
-
|
|
1211
|
-
```bash
|
|
1212
|
-
grimoire run setup.yaml --no-resume
|
|
1213
|
-
```
|
|
1214
|
-
|
|
1215
|
-
Or programmatically:
|
|
1216
|
-
|
|
1217
|
-
```typescript
|
|
1218
|
-
const answers = await runWizard(config, { resume: false })
|
|
1219
|
-
```
|
|
1220
|
-
|
|
1221
|
-
Manage progress files directly:
|
|
1222
|
-
|
|
1223
|
-
```typescript
|
|
1224
|
-
import { saveProgress, loadProgress, clearProgress } from 'grimoire-wizard'
|
|
1225
|
-
|
|
1226
|
-
const saved = loadProgress('Project Setup')
|
|
1227
|
-
clearProgress('Project Setup')
|
|
1228
|
-
```
|
|
1229
|
-
|
|
1230
|
-
---
|
|
1231
|
-
|
|
1232
|
-
## Review Screen
|
|
1233
|
-
|
|
1234
|
-
Set `review: true` in your wizard's `meta` block to show a summary of all answers before the wizard completes. The user can confirm or go back to change any answer.
|
|
1235
|
-
|
|
1236
|
-
```yaml
|
|
1237
|
-
meta:
|
|
1238
|
-
name: Deploy Wizard
|
|
1239
|
-
review: true
|
|
1240
|
-
```
|
|
1241
|
-
|
|
1242
|
-
The review screen lists every answered step with its question and value. Selecting an answer jumps back to that step. Confirming submits the wizard.
|
|
1243
|
-
|
|
1244
|
-
---
|
|
1245
|
-
|
|
1246
|
-
## Wizard Pipelines
|
|
1247
|
-
|
|
1248
|
-
Pipelines let you chain multiple wizard configs in sequence. Each wizard's answers are forwarded to the next, so later wizards can reference earlier answers in their `when` conditions and `default` values.
|
|
1249
|
-
|
|
1250
|
-
```typescript
|
|
1251
|
-
import { runPipeline } from 'grimoire-wizard'
|
|
1252
|
-
|
|
1253
|
-
const results = await runPipeline([
|
|
1254
|
-
{ config: setupConfig },
|
|
1255
|
-
{ config: deployConfig, when: { field: 'name', equals: 'my-app' } },
|
|
1256
|
-
])
|
|
1257
|
-
```
|
|
1258
|
-
|
|
1259
|
-
Each entry in the array accepts:
|
|
1260
|
-
|
|
1261
|
-
| Field | Type | Description |
|
|
1262
|
-
|-------|------|-------------|
|
|
1263
|
-
| `config` | `WizardConfig` | The wizard config to run |
|
|
1264
|
-
| `mockAnswers` | `Record<string, unknown>` | Preset answers for this stage |
|
|
1265
|
-
| `when` | `Condition` | Skip this stage if the condition is not met |
|
|
1266
|
-
|
|
1267
|
-
`runPipeline` returns an array of answer objects, one per stage that ran. Stages that are skipped via `when` return `null`.
|
|
1268
|
-
|
|
1269
|
-
---
|
|
1270
|
-
|
|
1271
|
-
## Templates
|
|
1272
|
-
|
|
1273
|
-
Templates are named answer presets. Save a set of answers under a name, then load them as defaults on future runs. Useful for environments like staging vs. production that share the same wizard but need different values.
|
|
1274
|
-
|
|
1275
|
-
Templates are stored in `~/.config/grimoire/templates/<wizard-slug>/`.
|
|
1276
|
-
|
|
1277
|
-
### Saving a template
|
|
1278
|
-
|
|
1279
|
-
Templates are saved programmatically after a run:
|
|
1280
|
-
|
|
1281
|
-
```typescript
|
|
1282
|
-
import { runWizard, saveTemplate } from 'grimoire-wizard'
|
|
1283
|
-
|
|
1284
|
-
const answers = await runWizard(config)
|
|
1285
|
-
saveTemplate('Project Setup', 'production', answers)
|
|
1286
|
-
```
|
|
1287
|
-
|
|
1288
|
-
### Loading a template via CLI
|
|
1289
|
-
|
|
1290
|
-
```bash
|
|
1291
|
-
grimoire run setup.yaml --template production
|
|
1292
|
-
```
|
|
1293
|
-
|
|
1294
|
-
Template answers become the defaults for each step. The user can still change any value.
|
|
1295
|
-
|
|
1296
|
-
### Managing templates
|
|
1297
|
-
|
|
1298
|
-
```bash
|
|
1299
|
-
grimoire template list "Project Setup"
|
|
1300
|
-
grimoire template delete "Project Setup" production
|
|
1301
|
-
```
|
|
1302
|
-
|
|
1303
|
-
### Programmatic API
|
|
1304
|
-
|
|
1305
|
-
```typescript
|
|
1306
|
-
import { saveTemplate, loadTemplate, listTemplates, deleteTemplate } from 'grimoire-wizard'
|
|
1307
|
-
|
|
1308
|
-
saveTemplate('Project Setup', 'staging', answers)
|
|
1309
|
-
|
|
1310
|
-
const staging = loadTemplate('Project Setup', 'staging')
|
|
1311
|
-
|
|
1312
|
-
const names = listTemplates('Project Setup')
|
|
1313
|
-
// ['production', 'staging']
|
|
1314
|
-
|
|
1315
|
-
deleteTemplate('Project Setup', 'staging')
|
|
1316
|
-
```
|
|
1317
|
-
|
|
1318
|
-
---
|
|
1319
|
-
|
|
1320
|
-
## MRU (Most Recently Used) Ordering
|
|
1321
|
-
|
|
1322
|
-
For `select`, `multiselect`, and `search` steps, grimoire tracks which options you pick and floats the most frequently chosen ones to the top of the list on subsequent runs. Options you've never picked stay in their original order below.
|
|
1323
|
-
|
|
1324
|
-
MRU data is stored in `~/.config/grimoire/mru/` and is per-wizard, per-step.
|
|
1325
|
-
|
|
1326
|
-
MRU ordering is enabled by default. Disable it programmatically:
|
|
1327
|
-
|
|
1328
|
-
```typescript
|
|
1329
|
-
const answers = await runWizard(config, { mru: false })
|
|
1330
|
-
```
|
|
1331
|
-
|
|
1332
|
-
There's no CLI flag for this. It's a programmatic-only option.
|
|
1333
|
-
|
|
1334
|
-
---
|
|
1335
|
-
|
|
1336
|
-
## Banner
|
|
1337
|
-
|
|
1338
|
-
When grimoire starts a wizard in interactive mode, it renders the wizard name as ASCII art using figlet with a purple-to-blue-to-green gradient. If figlet rendering fails for any reason, it falls back to plain bold text.
|
|
1339
|
-
|
|
1340
|
-
The banner is suppressed in `--quiet` mode and in `--plain` mode. Use `--plain` to get clean, color-free output suitable for terminals that don't support ANSI codes or for piping:
|
|
1341
|
-
|
|
1342
|
-
```bash
|
|
1343
|
-
grimoire run setup.yaml --plain
|
|
1344
|
-
```
|
|
1345
|
-
|
|
1346
|
-
The `NO_COLOR` environment variable also disables colors and the banner:
|
|
1347
|
-
|
|
1348
|
-
```bash
|
|
1349
|
-
NO_COLOR=1 grimoire run setup.yaml
|
|
1350
|
-
```
|
|
1351
|
-
|
|
1352
|
-
---
|
|
1353
|
-
|
|
1354
|
-
## CI/CD Integration
|
|
1355
|
-
|
|
1356
|
-
Combine `--mock` and `--json` to run wizards non-interactively in pipelines and capture structured output.
|
|
1357
|
-
|
|
1358
|
-
```bash
|
|
1359
|
-
# Run with preset answers, capture JSON output
|
|
1360
|
-
grimoire run deploy.yaml \
|
|
1361
|
-
--mock '{"environment":"staging","version":"1.2.3","confirm":true}' \
|
|
1362
|
-
--json > deploy-answers.json
|
|
1363
|
-
|
|
1364
|
-
# Use the output in subsequent steps
|
|
1365
|
-
cat deploy-answers.json | jq '.answers.environment'
|
|
1366
|
-
```
|
|
1367
|
-
|
|
1368
|
-
The `--json` flag always emits to stdout. On success:
|
|
1369
|
-
|
|
1370
|
-
```json
|
|
1371
|
-
{
|
|
1372
|
-
"ok": true,
|
|
1373
|
-
"wizard": "Deployment Wizard",
|
|
1374
|
-
"answers": { "environment": "staging", "version": "1.2.3" },
|
|
1375
|
-
"stepsCompleted": 3,
|
|
1376
|
-
"format": "json"
|
|
1377
|
-
}
|
|
1378
|
-
```
|
|
1379
|
-
|
|
1380
|
-
On failure:
|
|
1381
|
-
|
|
1382
|
-
```json
|
|
1383
|
-
{
|
|
1384
|
-
"ok": false,
|
|
1385
|
-
"error": "Mock mode: no answer provided for step \"confirm\" and no default available"
|
|
1386
|
-
}
|
|
1387
|
-
```
|
|
1388
|
-
|
|
1389
|
-
Exit code is `0` on success and `1` on failure, so pipelines can branch on the result.
|
|
1390
|
-
|
|
1391
|
-
---
|
|
1392
|
-
|
|
1393
|
-
## JSON Schema
|
|
1394
|
-
|
|
1395
|
-
Grimoire ships a JSON Schema at `schema/grimoire.schema.json`. Add it to your editor for autocomplete and inline validation of config files.
|
|
1396
|
-
|
|
1397
|
-
### VS Code
|
|
1398
|
-
|
|
1399
|
-
Add this to your workspace `.vscode/settings.json`:
|
|
1400
|
-
|
|
1401
|
-
```json
|
|
1402
|
-
{
|
|
1403
|
-
"yaml.schemas": {
|
|
1404
|
-
"./node_modules/grimoire-wizard/schema/grimoire.schema.json": "*.wizard.yaml"
|
|
1405
|
-
}
|
|
1406
|
-
}
|
|
1407
|
-
```
|
|
1408
|
-
|
|
1409
|
-
Or add a `$schema` comment at the top of any config file:
|
|
1410
|
-
|
|
1411
|
-
```yaml
|
|
1412
|
-
# yaml-language-server: $schema=./node_modules/grimoire-wizard/schema/grimoire.schema.json
|
|
1413
|
-
meta:
|
|
1414
|
-
name: My Wizard
|
|
1415
|
-
```
|
|
1416
|
-
|
|
1417
|
-
### Other editors
|
|
1418
|
-
|
|
1419
|
-
Point your editor's JSON Schema support at:
|
|
1420
|
-
|
|
1421
|
-
```
|
|
1422
|
-
./node_modules/grimoire-wizard/schema/grimoire.schema.json
|
|
1423
|
-
```
|
|
1424
|
-
|
|
1425
|
-
---
|
|
1426
|
-
|
|
1427
|
-
## Shell Completions
|
|
1428
|
-
|
|
1429
|
-
### Bash
|
|
1430
|
-
|
|
1431
|
-
```bash
|
|
1432
|
-
grimoire completion bash > ~/.bash_completion.d/grimoire
|
|
1433
|
-
source ~/.bash_completion.d/grimoire
|
|
1434
|
-
```
|
|
1435
|
-
|
|
1436
|
-
Or add to your `.bashrc`:
|
|
1437
|
-
|
|
1438
|
-
```bash
|
|
1439
|
-
eval "$(grimoire completion bash)"
|
|
1440
|
-
```
|
|
1441
|
-
|
|
1442
|
-
### Zsh
|
|
1443
|
-
|
|
1444
|
-
```bash
|
|
1445
|
-
grimoire completion zsh > ~/.zsh/completions/_grimoire
|
|
1446
|
-
```
|
|
1447
|
-
|
|
1448
|
-
Make sure `~/.zsh/completions` is in your `$fpath`. Then reload:
|
|
1449
|
-
|
|
1450
|
-
```bash
|
|
1451
|
-
autoload -Uz compinit && compinit
|
|
1452
|
-
```
|
|
1453
|
-
|
|
1454
|
-
### Fish
|
|
1455
|
-
|
|
1456
|
-
```bash
|
|
1457
|
-
grimoire completion fish > ~/.config/fish/completions/grimoire.fish
|
|
1458
|
-
```
|
|
1459
|
-
|
|
1460
|
-
---
|
|
1461
|
-
|
|
1462
|
-
## Examples
|
|
1463
|
-
|
|
1464
|
-
The `examples/` directory contains ready-to-run configs in both YAML (`examples/yaml/`) and JSON (`examples/json/`) formats. Every YAML example (except `base.yaml` and `extended.yaml`, which use `extends:`) has a JSON equivalent.
|
|
1465
|
-
|
|
1466
|
-
### `examples/yaml/basic.yaml`
|
|
1467
|
-
|
|
1468
|
-
A 6-step project setup wizard covering the core input types: project name (text with validation and pattern), description (optional text), language (select with default), features (multiselect with min), license (select), and confirm. Good starting point for your own configs.
|
|
1469
|
-
|
|
1470
|
-
```bash
|
|
1471
|
-
grimoire run examples/yaml/basic.yaml
|
|
1472
|
-
grimoire run examples/json/basic.json # JSON equivalent
|
|
1473
|
-
```
|
|
1474
|
-
|
|
1475
|
-
### `examples/yaml/conditional.yaml`
|
|
1476
|
-
|
|
1477
|
-
An 11-step wizard that branches based on project type. A `select` step with `routes` sends users down one of four paths (web, api, cli, lib), each with its own framework or feature selection step. Additional steps use `when` conditions to show or hide options based on earlier answers.
|
|
1478
|
-
|
|
1479
|
-
```bash
|
|
1480
|
-
grimoire run examples/yaml/conditional.yaml
|
|
1481
|
-
```
|
|
1482
|
-
|
|
1483
|
-
### `examples/yaml/themed.yaml`
|
|
1484
|
-
|
|
1485
|
-
An 8-step account setup wizard styled with the Catppuccin Mocha color palette. Demonstrates all 7 color tokens and custom icon overrides. Steps cover username, email, role, experience, interests, newsletter, password, and confirm.
|
|
1486
|
-
|
|
1487
|
-
```bash
|
|
1488
|
-
grimoire run examples/yaml/themed.yaml
|
|
1489
|
-
```
|
|
1490
|
-
|
|
1491
|
-
### `examples/yaml/demo.yaml`
|
|
1492
|
-
|
|
1493
|
-
The built-in demo config used by `grimoire demo`. Exercises all 10 step types across 4 named groups: Text Inputs (text, editor, path, password), Selections (select, multiselect, search), Toggles and Numbers (toggle, number), and Confirmation (confirm).
|
|
1494
|
-
|
|
1495
|
-
```bash
|
|
1496
|
-
grimoire run examples/yaml/demo.yaml
|
|
1497
|
-
# or
|
|
1498
|
-
grimoire demo
|
|
1499
|
-
```
|
|
1500
|
-
|
|
1501
|
-
### `examples/yaml/all-features.yaml`
|
|
1502
|
-
|
|
1503
|
-
A focused showcase of the newer step types: search, path, toggle, editor, and number, organized into two groups (Project Setup and Configuration).
|
|
1504
|
-
|
|
1505
|
-
```bash
|
|
1506
|
-
grimoire run examples/yaml/all-features.yaml
|
|
1507
|
-
```
|
|
1508
|
-
|
|
1509
|
-
### `examples/yaml/base.yaml`
|
|
1510
|
-
|
|
1511
|
-
A minimal base config with a name step, optional description, and confirm. Intended to be inherited via `extends`.
|
|
1512
|
-
|
|
1513
|
-
```bash
|
|
1514
|
-
grimoire run examples/yaml/base.yaml
|
|
1515
|
-
```
|
|
1516
|
-
|
|
1517
|
-
### `examples/yaml/extended.yaml`
|
|
1518
|
-
|
|
1519
|
-
Extends `base.yaml` and adds a language select step. Demonstrates how `extends` merges configs and how the child's `output` and `meta` override the base.
|
|
1520
|
-
|
|
1521
|
-
```bash
|
|
1522
|
-
grimoire run examples/yaml/extended.yaml
|
|
1523
|
-
```
|
|
1524
|
-
|
|
1525
|
-
### `examples/yaml/with-checks.yaml`
|
|
1526
|
-
|
|
1527
|
-
A deployment wizard with two pre-flight checks (Node.js and Git). Shows how `checks` abort the wizard before any prompts if the environment isn't ready.
|
|
1528
|
-
|
|
1529
|
-
```bash
|
|
1530
|
-
grimoire run examples/yaml/with-checks.yaml
|
|
1531
|
-
```
|
|
1532
|
-
|
|
1533
|
-
### `examples/yaml/themed-catppuccin.yaml`
|
|
1534
|
-
|
|
1535
|
-
A 3-step project setup wizard using the `catppuccin` theme preset. Shows how a single `preset` line replaces manual token configuration.
|
|
1536
|
-
|
|
1537
|
-
```bash
|
|
1538
|
-
grimoire run examples/yaml/themed-catppuccin.yaml
|
|
1539
|
-
grimoire run examples/json/themed-catppuccin.json # JSON equivalent
|
|
1540
|
-
```
|
|
1541
|
-
|
|
1542
|
-
### `examples/yaml/pipeline.yaml`
|
|
1543
|
-
|
|
1544
|
-
A multi-stage wizard demonstrating the pipeline concept using `note` steps as stage dividers. Shows how to structure a wizard that covers multiple logical phases in a single config.
|
|
1545
|
-
|
|
1546
|
-
```bash
|
|
1547
|
-
grimoire run examples/yaml/pipeline.yaml
|
|
1548
|
-
```
|
|
1549
|
-
|
|
1550
|
-
---
|
|
1551
|
-
|
|
1552
|
-
## AI Agent Integration
|
|
1553
|
-
|
|
1554
|
-
Building wizard configs with an AI assistant? Give it this reference:
|
|
1555
|
-
|
|
1556
|
-
```
|
|
1557
|
-
https://raw.githubusercontent.com/YosefHayim/grimoire/main/docs/GRIMOIRE_REFERENCE.md
|
|
1558
|
-
```
|
|
1559
|
-
|
|
1560
|
-
This single file contains the complete grimoire-wizard schema, all step types, conditions, actions, handler contracts, and annotated examples — everything an AI agent needs to generate correct configs in one shot.
|
|
1561
|
-
|
|
1562
|
-
---
|
|
277
|
+
Node.js >= 18. ESM only (`"type": "module"` or `.mjs`).
|
|
1563
278
|
|
|
1564
279
|
## License
|
|
1565
280
|
|
|
1566
|
-
MIT
|
|
281
|
+
MIT
|