@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.
Files changed (59) hide show
  1. package/dist/storyboard-ui.css +1 -0
  2. package/dist/storyboard-ui.js +26298 -0
  3. package/dist/storyboard-ui.js.map +1 -0
  4. package/dist/tailwind.css +1 -1
  5. package/package.json +24 -19
  6. package/scaffold/manifest.json +35 -0
  7. package/scaffold/scripts/link.sh +26 -0
  8. package/scaffold/scripts/unlink.sh +10 -0
  9. package/scaffold/skills/create/SKILL.md +501 -0
  10. package/scaffold/skills/storyboard/SKILL.md +360 -0
  11. package/scaffold/skills/update-storyboard/SKILL.md +16 -0
  12. package/scaffold/skills/update-storyboard/update-storyboard-packages.sh +26 -0
  13. package/scaffold/skills/vitest/GENERATION.md +5 -0
  14. package/scaffold/skills/vitest/SKILL.md +52 -0
  15. package/scaffold/skills/vitest/references/advanced-environments.md +264 -0
  16. package/scaffold/skills/vitest/references/advanced-projects.md +300 -0
  17. package/scaffold/skills/vitest/references/advanced-type-testing.md +237 -0
  18. package/scaffold/skills/vitest/references/advanced-vi.md +249 -0
  19. package/scaffold/skills/vitest/references/core-cli.md +166 -0
  20. package/scaffold/skills/vitest/references/core-config.md +174 -0
  21. package/scaffold/skills/vitest/references/core-describe.md +193 -0
  22. package/scaffold/skills/vitest/references/core-expect.md +219 -0
  23. package/scaffold/skills/vitest/references/core-hooks.md +244 -0
  24. package/scaffold/skills/vitest/references/core-test-api.md +233 -0
  25. package/scaffold/skills/vitest/references/features-concurrency.md +250 -0
  26. package/scaffold/skills/vitest/references/features-context.md +238 -0
  27. package/scaffold/skills/vitest/references/features-coverage.md +207 -0
  28. package/scaffold/skills/vitest/references/features-filtering.md +211 -0
  29. package/scaffold/skills/vitest/references/features-mocking.md +265 -0
  30. package/scaffold/skills/vitest/references/features-snapshots.md +207 -0
  31. package/scaffold/skills/worktree/SKILL.md +51 -0
  32. package/scaffold/storyboard.config.json +26 -0
  33. package/scaffold/svelte.config.js +1 -0
  34. package/scaffold/toolbar.config.json +4 -0
  35. package/src/ActionMenuButton.svelte +1 -1
  36. package/src/CanvasCreateMenu.svelte +1 -1
  37. package/src/CoreUIBar.svelte +20 -9
  38. package/src/CreateMenuButton.svelte +1 -1
  39. package/src/InspectorPanel.svelte +144 -49
  40. package/src/SidePanel.svelte +10 -10
  41. package/src/commandActions.js +1 -1
  42. package/src/comments/index.js +0 -3
  43. package/src/devtools.js +4 -1
  44. package/src/index.js +5 -2
  45. package/src/inspector/highlighter.js +3 -4
  46. package/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte +1 -1
  47. package/src/mountStoryboardCore.js +223 -0
  48. package/src/scaffold.js +100 -0
  49. package/src/stores/themeStore.ts +29 -8
  50. package/src/styles/tailwind.css +16 -0
  51. package/src/svelte-plugin-ui/components/Viewfinder.svelte +18 -0
  52. package/src/ui-entry.js +30 -0
  53. package/src/vite/server-plugin.js +8 -24
  54. package/src/workshop/features/createCanvas/CreateCanvasForm.svelte +24 -6
  55. package/src/workshop/features/createFlow/CreateFlowForm.svelte +1 -1
  56. package/src/workshop/features/createFlow/index.js +0 -1
  57. package/src/workshop/features/createPrototype/CreatePrototypeForm.svelte +1 -1
  58. package/src/workshop/features/createPrototype/index.js +0 -1
  59. /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