@dfosco/storyboard-core 3.1.2 → 3.3.0
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/dist/storyboard-ui.css +1 -0
- package/dist/storyboard-ui.js +26298 -0
- package/dist/storyboard-ui.js.map +1 -0
- package/dist/tailwind.css +1 -1
- package/package.json +24 -19
- package/scaffold/manifest.json +35 -0
- package/scaffold/scripts/link.sh +26 -0
- package/scaffold/scripts/unlink.sh +10 -0
- package/scaffold/skills/create/SKILL.md +501 -0
- package/scaffold/skills/storyboard/SKILL.md +360 -0
- package/scaffold/skills/update-storyboard/SKILL.md +16 -0
- package/scaffold/skills/update-storyboard/update-storyboard-packages.sh +26 -0
- package/scaffold/skills/vitest/GENERATION.md +5 -0
- package/scaffold/skills/vitest/SKILL.md +52 -0
- package/scaffold/skills/vitest/references/advanced-environments.md +264 -0
- package/scaffold/skills/vitest/references/advanced-projects.md +300 -0
- package/scaffold/skills/vitest/references/advanced-type-testing.md +237 -0
- package/scaffold/skills/vitest/references/advanced-vi.md +249 -0
- package/scaffold/skills/vitest/references/core-cli.md +166 -0
- package/scaffold/skills/vitest/references/core-config.md +174 -0
- package/scaffold/skills/vitest/references/core-describe.md +193 -0
- package/scaffold/skills/vitest/references/core-expect.md +219 -0
- package/scaffold/skills/vitest/references/core-hooks.md +244 -0
- package/scaffold/skills/vitest/references/core-test-api.md +233 -0
- package/scaffold/skills/vitest/references/features-concurrency.md +250 -0
- package/scaffold/skills/vitest/references/features-context.md +238 -0
- package/scaffold/skills/vitest/references/features-coverage.md +207 -0
- package/scaffold/skills/vitest/references/features-filtering.md +211 -0
- package/scaffold/skills/vitest/references/features-mocking.md +265 -0
- package/scaffold/skills/vitest/references/features-snapshots.md +207 -0
- package/scaffold/skills/worktree/SKILL.md +51 -0
- package/scaffold/storyboard.config.json +26 -0
- package/scaffold/svelte.config.js +1 -0
- package/scaffold/toolbar.config.json +4 -0
- package/src/ActionMenuButton.svelte +1 -1
- package/src/CanvasCreateMenu.svelte +1 -1
- package/src/CoreUIBar.svelte +20 -9
- package/src/CreateMenuButton.svelte +1 -1
- package/src/InspectorPanel.svelte +144 -49
- package/src/SidePanel.svelte +10 -10
- package/src/commandActions.js +1 -1
- package/src/comments/index.js +0 -3
- package/src/devtools.js +4 -1
- package/src/index.js +5 -2
- package/src/inspector/highlighter.js +3 -4
- package/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte +1 -1
- package/src/mountStoryboardCore.js +223 -0
- package/src/scaffold.js +100 -0
- package/src/stores/themeStore.ts +29 -8
- package/src/styles/tailwind.css +16 -0
- package/src/svelte-plugin-ui/components/Viewfinder.svelte +18 -0
- package/src/ui-entry.js +30 -0
- package/src/vite/server-plugin.js +8 -24
- package/src/workshop/features/createCanvas/CreateCanvasForm.svelte +24 -6
- package/src/workshop/features/createFlow/CreateFlowForm.svelte +1 -1
- package/src/workshop/features/createFlow/index.js +0 -1
- package/src/workshop/features/createPrototype/CreatePrototypeForm.svelte +1 -1
- package/src/workshop/features/createPrototype/index.js +0 -1
- /package/{core-ui.config.json → toolbar.config.json} +0 -0
|
@@ -0,0 +1,501 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: create
|
|
3
|
+
description: Walks users through creating any Storyboard asset — prototype, external prototype, flow, canvas, object, or record. Use when asked to "create", "new", or "scaffold" anything in storyboard.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Create
|
|
7
|
+
|
|
8
|
+
> Triggered by: "create a new prototype", "scaffold a prototype", "new prototype", "create prototype", "new flow", "create flow", "new canvas", "create canvas", "new object", "create object", "new record", "create record", "create new", "scaffold", "add external prototype", "link external prototype"
|
|
9
|
+
|
|
10
|
+
## What This Does
|
|
11
|
+
|
|
12
|
+
Guides the user through creating a new Storyboard **prototype**, **external prototype**, **flow**, **canvas**, **object**, or **record** by collecting inputs interactively, then writing the files directly or calling the scaffolding API.
|
|
13
|
+
|
|
14
|
+
## Procedure
|
|
15
|
+
|
|
16
|
+
### Step 1: Ask what to create
|
|
17
|
+
|
|
18
|
+
Use `ask_user` to ask:
|
|
19
|
+
|
|
20
|
+
> What would you like to create?
|
|
21
|
+
|
|
22
|
+
Provide choices:
|
|
23
|
+
- "Prototype" — A new page with routing and metadata
|
|
24
|
+
- "External Prototype" — A link to a prototype hosted elsewhere (opens in new tab)
|
|
25
|
+
- "Flow" — A new flow data file (.flow.json)
|
|
26
|
+
- "Canvas" — A new freeform canvas (.canvas.jsonl)
|
|
27
|
+
- "Object" — A reusable data fragment (.object.json)
|
|
28
|
+
- "Record" — A parameterized collection (.record.json)
|
|
29
|
+
|
|
30
|
+
If the user's original request already specifies the type (e.g., "create a new canvas", "add an external prototype"), skip this step and proceed directly.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Prototype Path
|
|
35
|
+
|
|
36
|
+
### Step P1: Ask for the prototype name
|
|
37
|
+
|
|
38
|
+
Use `ask_user` to ask:
|
|
39
|
+
|
|
40
|
+
> What should the prototype be called? Use kebab-case (e.g., `my-new-prototype`, `dashboard-v2`).
|
|
41
|
+
|
|
42
|
+
Validate the name is kebab-case (lowercase letters, numbers, hyphens only).
|
|
43
|
+
|
|
44
|
+
### Step P2: Ask for the title
|
|
45
|
+
|
|
46
|
+
Use `ask_user` to ask with a suggested default based on the name (humanized):
|
|
47
|
+
|
|
48
|
+
> What's the human-readable title for this prototype?
|
|
49
|
+
|
|
50
|
+
Provide the humanized name as the first choice (e.g., for `my-prototype` suggest "My Prototype"), with a freeform option.
|
|
51
|
+
|
|
52
|
+
### Step P3: Ask about folder placement
|
|
53
|
+
|
|
54
|
+
First, check which `.folder` directories exist by running:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
ls -d src/prototypes/*.folder 2>/dev/null | sed 's|src/prototypes/||;s|\.folder||'
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Then use `ask_user` to ask:
|
|
61
|
+
|
|
62
|
+
> Should this prototype go inside an existing folder group?
|
|
63
|
+
|
|
64
|
+
Provide choices:
|
|
65
|
+
- Each existing folder (e.g., "security-offsite", "code-quality")
|
|
66
|
+
- "Standalone (no folder group)"
|
|
67
|
+
- "Create a new folder group"
|
|
68
|
+
|
|
69
|
+
If "Create a new folder group" is chosen, ask for the folder name in a follow-up question.
|
|
70
|
+
|
|
71
|
+
### Step P4: Ask for the recipe
|
|
72
|
+
|
|
73
|
+
Use `ask_user` to ask:
|
|
74
|
+
|
|
75
|
+
> Which template should I use?
|
|
76
|
+
|
|
77
|
+
Provide choices:
|
|
78
|
+
- `bare` — Minimal page with Application template (Recommended)
|
|
79
|
+
- `security` — Security recipe with repo-level navigation
|
|
80
|
+
- `security-org` — Security Org recipe with org-level navigation
|
|
81
|
+
|
|
82
|
+
### Step P5: Ask for author
|
|
83
|
+
|
|
84
|
+
Use `ask_user` to ask:
|
|
85
|
+
|
|
86
|
+
> What's your GitHub username? (for the author field — comma-separate multiple authors)
|
|
87
|
+
|
|
88
|
+
### Step P6: Ask about flow file
|
|
89
|
+
|
|
90
|
+
Use `ask_user` to ask:
|
|
91
|
+
|
|
92
|
+
> Should I create a starter flow.json file for this prototype?
|
|
93
|
+
|
|
94
|
+
Choices: "Yes", "No"
|
|
95
|
+
|
|
96
|
+
A flow file is useful if the prototype will use flow data (navigation, user profiles, entity lists). It can always be added later.
|
|
97
|
+
|
|
98
|
+
### Step P7: Run the script
|
|
99
|
+
|
|
100
|
+
Build and execute the command with the gathered values:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
npm run create -- --name <name> --title "<title>" [--folder <folder>] [--recipe <recipe>] [--author <author>] [--flow]
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Only include optional flags when the user provided values:
|
|
107
|
+
- Omit `--folder` if standalone was chosen
|
|
108
|
+
- Omit `--flow` if the user said no
|
|
109
|
+
- Always include `--recipe` (default is `bare`)
|
|
110
|
+
|
|
111
|
+
### Step P8: Confirm and suggest next steps
|
|
112
|
+
|
|
113
|
+
After the script runs successfully:
|
|
114
|
+
|
|
115
|
+
1. Show the user what was created (the script prints a summary)
|
|
116
|
+
2. Suggest next steps:
|
|
117
|
+
- Run `npm run dev` to preview the prototype
|
|
118
|
+
- Use the **storyboard** skill to add data objects and flows
|
|
119
|
+
- Use the **primer-screenshot-builder** skill to build pages from screenshots
|
|
120
|
+
- Edit `index.jsx` directly to start building
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## External Prototype Path
|
|
125
|
+
|
|
126
|
+
An external prototype is a reference to a prototype hosted at an external URL. It shows up in the viewfinder with an "external" badge and opens in a new tab. No `index.jsx` or flow files are created — only a folder with a `.prototype.json` containing a `url` field.
|
|
127
|
+
|
|
128
|
+
### Step E1: Ask for the prototype name
|
|
129
|
+
|
|
130
|
+
Use `ask_user` to ask:
|
|
131
|
+
|
|
132
|
+
> What should the external prototype be called? Use kebab-case (e.g., `figma-design`, `staging-app`).
|
|
133
|
+
|
|
134
|
+
Validate the name is kebab-case (lowercase letters, numbers, hyphens only).
|
|
135
|
+
|
|
136
|
+
### Step E2: Ask for the URL
|
|
137
|
+
|
|
138
|
+
Use `ask_user` to ask:
|
|
139
|
+
|
|
140
|
+
> What's the URL of the external prototype?
|
|
141
|
+
|
|
142
|
+
Validate it's a valid absolute URL (must start with `http://` or `https://`).
|
|
143
|
+
|
|
144
|
+
### Step E3: Ask for the title
|
|
145
|
+
|
|
146
|
+
Use `ask_user` to ask with a suggested default based on the name (humanized):
|
|
147
|
+
|
|
148
|
+
> What's the human-readable title for this prototype?
|
|
149
|
+
|
|
150
|
+
Provide the humanized name as the first choice, with a freeform option.
|
|
151
|
+
|
|
152
|
+
### Step E4: Ask about folder placement
|
|
153
|
+
|
|
154
|
+
First, check which `.folder` directories exist by running:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
ls -d src/prototypes/*.folder 2>/dev/null | sed 's|src/prototypes/||;s|\.folder||'
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Then use `ask_user` to ask:
|
|
161
|
+
|
|
162
|
+
> Should this prototype go inside an existing folder group?
|
|
163
|
+
|
|
164
|
+
Provide choices:
|
|
165
|
+
- Each existing folder (e.g., "main", "security-offsite")
|
|
166
|
+
- "Standalone (no folder group)"
|
|
167
|
+
|
|
168
|
+
### Step E5: Ask for author (optional)
|
|
169
|
+
|
|
170
|
+
Use `ask_user` to ask:
|
|
171
|
+
|
|
172
|
+
> What's your GitHub username? (for the author field — comma-separate multiple authors, or leave blank)
|
|
173
|
+
|
|
174
|
+
### Step E6: Create the external prototype
|
|
175
|
+
|
|
176
|
+
Determine the target directory:
|
|
177
|
+
- If in a folder: `src/prototypes/<folder>.folder/<name>/`
|
|
178
|
+
- If standalone: `src/prototypes/<name>/`
|
|
179
|
+
|
|
180
|
+
Create the directory and write the `.prototype.json` file:
|
|
181
|
+
|
|
182
|
+
```json
|
|
183
|
+
{
|
|
184
|
+
"meta": {
|
|
185
|
+
"title": "<Title>",
|
|
186
|
+
"author": ["<author>"],
|
|
187
|
+
"description": "<description if provided>"
|
|
188
|
+
},
|
|
189
|
+
"url": "<url>"
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Only include `author` and `description` if provided. The `url` field is required.
|
|
194
|
+
|
|
195
|
+
### Step E7: Confirm and suggest next steps
|
|
196
|
+
|
|
197
|
+
1. Show the created file path
|
|
198
|
+
2. Explain it will appear in the viewfinder with an "external" badge
|
|
199
|
+
3. Suggest:
|
|
200
|
+
- Run `npm run dev` and check the viewfinder to see the entry
|
|
201
|
+
- Click the entry to open the external URL in a new tab
|
|
202
|
+
- Edit the `.prototype.json` to update the URL or metadata anytime
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Flow Path
|
|
207
|
+
|
|
208
|
+
### Step F1: Ask for the flow name
|
|
209
|
+
|
|
210
|
+
Use `ask_user` to ask:
|
|
211
|
+
|
|
212
|
+
> What should the flow be called? Use kebab-case (e.g., `empty-state`, `admin-view`).
|
|
213
|
+
|
|
214
|
+
Validate the name is kebab-case.
|
|
215
|
+
|
|
216
|
+
### Step F2: Ask for the title
|
|
217
|
+
|
|
218
|
+
Use `ask_user` with a humanized default:
|
|
219
|
+
|
|
220
|
+
> What's the human-readable title for this flow?
|
|
221
|
+
|
|
222
|
+
### Step F3: Ask about prototype scope
|
|
223
|
+
|
|
224
|
+
First, list available prototypes:
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
find src/prototypes -name "*.prototype.json" -not -path "*/node_modules/*" 2>/dev/null | sed 's|src/prototypes/||;s|/[^/]*\.prototype\.json||' | sort -u
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Use `ask_user` to ask:
|
|
231
|
+
|
|
232
|
+
> Should this flow belong to a specific prototype, or be global?
|
|
233
|
+
|
|
234
|
+
Provide choices:
|
|
235
|
+
- "Global (available to all prototypes)"
|
|
236
|
+
- Each existing prototype name
|
|
237
|
+
|
|
238
|
+
### Step F4: Ask about copying from existing flow
|
|
239
|
+
|
|
240
|
+
List existing flows:
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
find src -name "*.flow.json" -not -path "*/node_modules/*" 2>/dev/null | head -20
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
If flows exist, use `ask_user`:
|
|
247
|
+
|
|
248
|
+
> Would you like to copy data from an existing flow?
|
|
249
|
+
|
|
250
|
+
Choices: "No, start empty", then list existing flow names.
|
|
251
|
+
|
|
252
|
+
### Step F5: Create the flow file
|
|
253
|
+
|
|
254
|
+
Determine the target directory:
|
|
255
|
+
- If global: `src/data/`
|
|
256
|
+
- If prototype-scoped: `src/prototypes/<name>/`
|
|
257
|
+
|
|
258
|
+
Create the file `<name>.flow.json` with:
|
|
259
|
+
|
|
260
|
+
```json
|
|
261
|
+
{
|
|
262
|
+
"meta": {
|
|
263
|
+
"title": "<title>"
|
|
264
|
+
},
|
|
265
|
+
"$global": []
|
|
266
|
+
}
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
If copying from another flow, read and adapt the source data.
|
|
270
|
+
|
|
271
|
+
### Step F6: Confirm and suggest next steps
|
|
272
|
+
|
|
273
|
+
1. Show the created file path
|
|
274
|
+
2. Suggest next steps:
|
|
275
|
+
- Use the **storyboard** skill to add data objects and `$ref` references
|
|
276
|
+
- Add `$global` entries for shared objects (e.g., navigation, user)
|
|
277
|
+
- Switch to the flow with the Flows menu or `?flow=<name>`
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## Canvas Path
|
|
282
|
+
|
|
283
|
+
### Step C1: Ask for the canvas name
|
|
284
|
+
|
|
285
|
+
Use `ask_user` to ask:
|
|
286
|
+
|
|
287
|
+
> What should the canvas be called? Use kebab-case (e.g., `design-overview`, `button-patterns`).
|
|
288
|
+
|
|
289
|
+
Validate the name is kebab-case.
|
|
290
|
+
|
|
291
|
+
### Step C2: Ask for the title
|
|
292
|
+
|
|
293
|
+
Use `ask_user` with a humanized default:
|
|
294
|
+
|
|
295
|
+
> What's the human-readable title for this canvas?
|
|
296
|
+
|
|
297
|
+
### Step C3: Ask about folder placement
|
|
298
|
+
|
|
299
|
+
Check existing canvas folders:
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
ls -d src/canvas/*.folder 2>/dev/null | sed 's|src/canvas/||;s|\.folder||'
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
Use `ask_user`:
|
|
306
|
+
|
|
307
|
+
> Should this canvas go inside an existing folder group?
|
|
308
|
+
|
|
309
|
+
Provide choices:
|
|
310
|
+
- Each existing folder
|
|
311
|
+
- "Standalone (no folder group)"
|
|
312
|
+
|
|
313
|
+
### Step C4: Ask about options
|
|
314
|
+
|
|
315
|
+
Use `ask_user`:
|
|
316
|
+
|
|
317
|
+
> Should the canvas include a JSX companion file? (for code-defined widgets)
|
|
318
|
+
|
|
319
|
+
Choices: "No (Recommended)", "Yes"
|
|
320
|
+
|
|
321
|
+
### Step C5: Create the canvas
|
|
322
|
+
|
|
323
|
+
Use the canvas creation API via curl:
|
|
324
|
+
|
|
325
|
+
```bash
|
|
326
|
+
curl -s -X POST "http://localhost:$(cat .port 2>/dev/null || echo 1234)/_storyboard/canvas/create" \
|
|
327
|
+
-H "Content-Type: application/json" \
|
|
328
|
+
-d '{"name":"<name>","title":"<title>","folder":"<folder>","grid":true,"includeJsx":<bool>}'
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
Or if the dev server isn't running, create the file directly at `src/canvas/<name>.canvas.jsonl`:
|
|
332
|
+
|
|
333
|
+
```jsonl
|
|
334
|
+
{"event":"canvas_created","timestamp":"<ISO date>","title":"<Title>","grid":true,"gridSize":24,"colorMode":"auto","widgets":[]}
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Step C6: Confirm and suggest next steps
|
|
338
|
+
|
|
339
|
+
1. Show the created file path and route (`/canvas/<name>`)
|
|
340
|
+
2. Suggest next steps:
|
|
341
|
+
- Run `npm run dev` and navigate to the canvas
|
|
342
|
+
- Add widgets via the toolbar (sticky notes, markdown, prototypes)
|
|
343
|
+
- Paste URLs to embed prototypes or link previews
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
## Object Path
|
|
348
|
+
|
|
349
|
+
Objects are reusable JSON data fragments (users, navigation, settings, etc.). They are referenced in flows via `$ref` or `$global`.
|
|
350
|
+
|
|
351
|
+
### Step O1: Ask for the object name
|
|
352
|
+
|
|
353
|
+
Use `ask_user` to ask:
|
|
354
|
+
|
|
355
|
+
> What should the object be called? Use kebab-case (e.g., `jane-doe`, `navigation`, `settings`).
|
|
356
|
+
|
|
357
|
+
Validate the name is kebab-case.
|
|
358
|
+
|
|
359
|
+
### Step O2: Ask about prototype scope
|
|
360
|
+
|
|
361
|
+
First, list available prototypes:
|
|
362
|
+
|
|
363
|
+
```bash
|
|
364
|
+
find src/prototypes -name "*.prototype.json" -not -path "*/node_modules/*" 2>/dev/null | sed 's|src/prototypes/||;s|/[^/]*\.prototype\.json||' | sort -u
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
Use `ask_user` to ask:
|
|
368
|
+
|
|
369
|
+
> Should this object belong to a specific prototype, or be global?
|
|
370
|
+
|
|
371
|
+
Provide choices:
|
|
372
|
+
- "Global (available to all prototypes)"
|
|
373
|
+
- Each existing prototype name
|
|
374
|
+
|
|
375
|
+
### Step O3: Ask for initial shape
|
|
376
|
+
|
|
377
|
+
Use `ask_user` to ask:
|
|
378
|
+
|
|
379
|
+
> What kind of data does this object represent? Describe briefly so I can generate the initial structure (e.g., "a user with name, avatar, role", "sidebar navigation links").
|
|
380
|
+
|
|
381
|
+
Alternatively, the user can say "start empty".
|
|
382
|
+
|
|
383
|
+
### Step O4: Create the object file
|
|
384
|
+
|
|
385
|
+
Determine the target directory:
|
|
386
|
+
- If global: `src/data/` (create if needed)
|
|
387
|
+
- If prototype-scoped: `src/prototypes/<proto-name>/` (inside `.folder/` if applicable)
|
|
388
|
+
|
|
389
|
+
Create `<name>.object.json` with the generated structure, or an empty object if "start empty":
|
|
390
|
+
|
|
391
|
+
```json
|
|
392
|
+
{}
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
Example generated structure for "a user with name, avatar, role":
|
|
396
|
+
|
|
397
|
+
```json
|
|
398
|
+
{
|
|
399
|
+
"name": "Jane Doe",
|
|
400
|
+
"username": "janedoe",
|
|
401
|
+
"avatar": "https://avatars.githubusercontent.com/u/1?v=4",
|
|
402
|
+
"role": "admin"
|
|
403
|
+
}
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
### Step O5: Confirm and suggest next steps
|
|
407
|
+
|
|
408
|
+
1. Show the created file path
|
|
409
|
+
2. Suggest next steps:
|
|
410
|
+
- Reference it in a flow with `{ "$ref": "<name>" }` or add to `$global`
|
|
411
|
+
- Access it directly with `useObject('<name>')` in a component
|
|
412
|
+
- Edit the JSON to add or modify fields
|
|
413
|
+
|
|
414
|
+
---
|
|
415
|
+
|
|
416
|
+
## Record Path
|
|
417
|
+
|
|
418
|
+
Records are collections — arrays of entries, each with a unique identifier. They power dynamic routes (e.g., a list page + detail pages).
|
|
419
|
+
|
|
420
|
+
### Step R1: Ask for the record name
|
|
421
|
+
|
|
422
|
+
Use `ask_user` to ask:
|
|
423
|
+
|
|
424
|
+
> What should the record collection be called? Use kebab-case, plural form (e.g., `posts`, `team-members`, `repositories`).
|
|
425
|
+
|
|
426
|
+
Validate the name is kebab-case.
|
|
427
|
+
|
|
428
|
+
### Step R2: Ask about prototype scope
|
|
429
|
+
|
|
430
|
+
First, list available prototypes:
|
|
431
|
+
|
|
432
|
+
```bash
|
|
433
|
+
find src/prototypes -name "*.prototype.json" -not -path "*/node_modules/*" 2>/dev/null | sed 's|src/prototypes/||;s|/[^/]*\.prototype\.json||' | sort -u
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
Use `ask_user` to ask:
|
|
437
|
+
|
|
438
|
+
> Should this record belong to a specific prototype, or be global?
|
|
439
|
+
|
|
440
|
+
Provide choices:
|
|
441
|
+
- "Global (available to all prototypes)"
|
|
442
|
+
- Each existing prototype name
|
|
443
|
+
|
|
444
|
+
### Step R3: Ask for ID field
|
|
445
|
+
|
|
446
|
+
Use `ask_user` to ask:
|
|
447
|
+
|
|
448
|
+
> What field should be the unique identifier for each entry? This maps to the `[param]` in dynamic route filenames.
|
|
449
|
+
|
|
450
|
+
Provide choices:
|
|
451
|
+
- "id (Recommended)"
|
|
452
|
+
- "slug"
|
|
453
|
+
- "permalink"
|
|
454
|
+
|
|
455
|
+
### Step R4: Ask for entry fields
|
|
456
|
+
|
|
457
|
+
Use `ask_user` to ask:
|
|
458
|
+
|
|
459
|
+
> Describe the entries in this collection (e.g., "blog posts with title, author, date, excerpt" or "repos with name, stars, language"). I'll generate sample data.
|
|
460
|
+
|
|
461
|
+
Alternatively, the user can say "start with a minimal example".
|
|
462
|
+
|
|
463
|
+
### Step R5: Create the record file
|
|
464
|
+
|
|
465
|
+
Determine the target directory:
|
|
466
|
+
- If global: `src/data/` (create if needed)
|
|
467
|
+
- If prototype-scoped: `src/prototypes/<proto-name>/` (inside `.folder/` if applicable)
|
|
468
|
+
|
|
469
|
+
Create `<name>.record.json` with the generated entries. Always include at least 2–3 sample entries:
|
|
470
|
+
|
|
471
|
+
```json
|
|
472
|
+
[
|
|
473
|
+
{ "id": "first-entry", "title": "First Entry" },
|
|
474
|
+
{ "id": "second-entry", "title": "Second Entry" },
|
|
475
|
+
{ "id": "third-entry", "title": "Third Entry" }
|
|
476
|
+
]
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
### Step R6: Confirm and suggest next steps
|
|
480
|
+
|
|
481
|
+
1. Show the created file path
|
|
482
|
+
2. Suggest next steps:
|
|
483
|
+
- Create a dynamic route page `[id].jsx` (or `[slug].jsx` etc.) to render individual entries
|
|
484
|
+
- Use `useRecord('<name>')` in the detail page to get the matched entry
|
|
485
|
+
- Use `useRecords('<name>')` in a list page to get all entries
|
|
486
|
+
- Add more entries to the JSON file anytime
|
|
487
|
+
|
|
488
|
+
---
|
|
489
|
+
|
|
490
|
+
## Rules
|
|
491
|
+
|
|
492
|
+
- **Context inference:** If the user's prompt already contains answers to any question (type, name, template, folder, URL, author, description, etc.), **skip that question** and use the provided value directly. Only ask about missing information. For example, "create a prototype called dashboard with Application template" should skip the name and template questions.
|
|
493
|
+
- **Always use `ask_user`** for each remaining question — never assume values that weren't provided
|
|
494
|
+
- **One question at a time** — don't bundle questions
|
|
495
|
+
- Names must be kebab-case: `/^[a-z0-9]+(?:-[a-z0-9]+)*$/`
|
|
496
|
+
- Titles default to a humanized version of the name if the user accepts the suggestion
|
|
497
|
+
- Description is optional — skip it unless the user volunteers one
|
|
498
|
+
- Available prototype recipes: `bare` (default), `security`, `security-org`
|
|
499
|
+
- **Data files must live inside the prototype folder.** Every prototype must contain its own copies of any `.record.json`, `.object.json`, or `.flow.json` files it needs — never reference or import data files from other prototypes. Each prototype is an independent sandbox.
|
|
500
|
+
- **Records must be arrays** with each entry having a unique identifier field (default: `id`)
|
|
501
|
+
- **Objects are plain JSON** — no special keys required, any shape works
|