@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,237 @@
1
+ ---
2
+ name: type-testing
3
+ description: Test TypeScript types with expectTypeOf and assertType
4
+ ---
5
+
6
+ # Type Testing
7
+
8
+ Test TypeScript types without runtime execution.
9
+
10
+ ## Setup
11
+
12
+ Type tests use `.test-d.ts` extension:
13
+
14
+ ```ts
15
+ // math.test-d.ts
16
+ import { expectTypeOf } from 'vitest'
17
+ import { add } from './math'
18
+
19
+ test('add returns number', () => {
20
+ expectTypeOf(add).returns.toBeNumber()
21
+ })
22
+ ```
23
+
24
+ ## Configuration
25
+
26
+ ```ts
27
+ defineConfig({
28
+ test: {
29
+ typecheck: {
30
+ enabled: true,
31
+
32
+ // Only type check
33
+ only: false,
34
+
35
+ // Checker: 'tsc' or 'vue-tsc'
36
+ checker: 'tsc',
37
+
38
+ // Include patterns
39
+ include: ['**/*.test-d.ts'],
40
+
41
+ // tsconfig to use
42
+ tsconfig: './tsconfig.json',
43
+ },
44
+ },
45
+ })
46
+ ```
47
+
48
+ ## expectTypeOf API
49
+
50
+ ```ts
51
+ import { expectTypeOf } from 'vitest'
52
+
53
+ // Basic type checks
54
+ expectTypeOf<string>().toBeString()
55
+ expectTypeOf<number>().toBeNumber()
56
+ expectTypeOf<boolean>().toBeBoolean()
57
+ expectTypeOf<null>().toBeNull()
58
+ expectTypeOf<undefined>().toBeUndefined()
59
+ expectTypeOf<void>().toBeVoid()
60
+ expectTypeOf<never>().toBeNever()
61
+ expectTypeOf<any>().toBeAny()
62
+ expectTypeOf<unknown>().toBeUnknown()
63
+ expectTypeOf<object>().toBeObject()
64
+ expectTypeOf<Function>().toBeFunction()
65
+ expectTypeOf<[]>().toBeArray()
66
+ expectTypeOf<symbol>().toBeSymbol()
67
+ ```
68
+
69
+ ## Value Type Checking
70
+
71
+ ```ts
72
+ const value = 'hello'
73
+ expectTypeOf(value).toBeString()
74
+
75
+ const obj = { name: 'test', count: 42 }
76
+ expectTypeOf(obj).toMatchTypeOf<{ name: string }>()
77
+ expectTypeOf(obj).toHaveProperty('name')
78
+ ```
79
+
80
+ ## Function Types
81
+
82
+ ```ts
83
+ function greet(name: string): string {
84
+ return `Hello, ${name}`
85
+ }
86
+
87
+ expectTypeOf(greet).toBeFunction()
88
+ expectTypeOf(greet).parameters.toEqualTypeOf<[string]>()
89
+ expectTypeOf(greet).returns.toBeString()
90
+
91
+ // Parameter checking
92
+ expectTypeOf(greet).parameter(0).toBeString()
93
+ ```
94
+
95
+ ## Object Types
96
+
97
+ ```ts
98
+ interface User {
99
+ id: number
100
+ name: string
101
+ email?: string
102
+ }
103
+
104
+ expectTypeOf<User>().toHaveProperty('id')
105
+ expectTypeOf<User>().toHaveProperty('name').toBeString()
106
+
107
+ // Check shape
108
+ expectTypeOf({ id: 1, name: 'test' }).toMatchTypeOf<User>()
109
+ ```
110
+
111
+ ## Equality vs Matching
112
+
113
+ ```ts
114
+ interface A { x: number }
115
+ interface B { x: number; y: string }
116
+
117
+ // toMatchTypeOf - subset matching
118
+ expectTypeOf<B>().toMatchTypeOf<A>() // B extends A
119
+
120
+ // toEqualTypeOf - exact match
121
+ expectTypeOf<A>().not.toEqualTypeOf<B>() // Not exact match
122
+ expectTypeOf<A>().toEqualTypeOf<{ x: number }>() // Exact match
123
+ ```
124
+
125
+ ## Branded Types
126
+
127
+ ```ts
128
+ type UserId = number & { __brand: 'UserId' }
129
+ type PostId = number & { __brand: 'PostId' }
130
+
131
+ expectTypeOf<UserId>().not.toEqualTypeOf<PostId>()
132
+ expectTypeOf<UserId>().not.toEqualTypeOf<number>()
133
+ ```
134
+
135
+ ## Generic Types
136
+
137
+ ```ts
138
+ function identity<T>(value: T): T {
139
+ return value
140
+ }
141
+
142
+ expectTypeOf(identity<string>).returns.toBeString()
143
+ expectTypeOf(identity<number>).returns.toBeNumber()
144
+ ```
145
+
146
+ ## Nullable Types
147
+
148
+ ```ts
149
+ type MaybeString = string | null | undefined
150
+
151
+ expectTypeOf<MaybeString>().toBeNullable()
152
+ expectTypeOf<string>().not.toBeNullable()
153
+ ```
154
+
155
+ ## assertType
156
+
157
+ Assert a value matches a type (no assertion at runtime):
158
+
159
+ ```ts
160
+ import { assertType } from 'vitest'
161
+
162
+ function getUser(): User | null {
163
+ return { id: 1, name: 'test' }
164
+ }
165
+
166
+ test('returns user', () => {
167
+ const result = getUser()
168
+
169
+ // @ts-expect-error - should fail type check
170
+ assertType<string>(result)
171
+
172
+ // Correct type
173
+ assertType<User | null>(result)
174
+ })
175
+ ```
176
+
177
+ ## Using @ts-expect-error
178
+
179
+ Test that code produces type error:
180
+
181
+ ```ts
182
+ test('rejects wrong types', () => {
183
+ function requireString(s: string) {}
184
+
185
+ // @ts-expect-error - number not assignable to string
186
+ requireString(123)
187
+ })
188
+ ```
189
+
190
+ ## Running Type Tests
191
+
192
+ ```bash
193
+ # Run type tests
194
+ vitest typecheck
195
+
196
+ # Run alongside unit tests
197
+ vitest --typecheck
198
+
199
+ # Type tests only
200
+ vitest --typecheck.only
201
+ ```
202
+
203
+ ## Mixed Test Files
204
+
205
+ Combine runtime and type tests:
206
+
207
+ ```ts
208
+ // user.test.ts
209
+ import { describe, expect, expectTypeOf, test } from 'vitest'
210
+ import { createUser } from './user'
211
+
212
+ describe('createUser', () => {
213
+ test('runtime: creates user', () => {
214
+ const user = createUser('John')
215
+ expect(user.name).toBe('John')
216
+ })
217
+
218
+ test('types: returns User type', () => {
219
+ expectTypeOf(createUser).returns.toMatchTypeOf<{ name: string }>()
220
+ })
221
+ })
222
+ ```
223
+
224
+ ## Key Points
225
+
226
+ - Use `.test-d.ts` for type-only tests
227
+ - `expectTypeOf` for type assertions
228
+ - `toMatchTypeOf` for subset matching
229
+ - `toEqualTypeOf` for exact type matching
230
+ - Use `@ts-expect-error` to test type errors
231
+ - Run with `vitest typecheck` or `--typecheck`
232
+
233
+ <!--
234
+ Source references:
235
+ - https://vitest.dev/guide/testing-types.html
236
+ - https://vitest.dev/api/expect-typeof.html
237
+ -->
@@ -0,0 +1,249 @@
1
+ ---
2
+ name: vi-utilities
3
+ description: vi helper for mocking, timers, utilities
4
+ ---
5
+
6
+ # Vi Utilities
7
+
8
+ The `vi` helper provides mocking and utility functions.
9
+
10
+ ```ts
11
+ import { vi } from 'vitest'
12
+ ```
13
+
14
+ ## Mock Functions
15
+
16
+ ```ts
17
+ // Create mock
18
+ const fn = vi.fn()
19
+ const fnWithImpl = vi.fn((x) => x * 2)
20
+
21
+ // Check if mock
22
+ vi.isMockFunction(fn) // true
23
+
24
+ // Mock methods
25
+ fn.mockReturnValue(42)
26
+ fn.mockReturnValueOnce(1)
27
+ fn.mockResolvedValue(data)
28
+ fn.mockRejectedValue(error)
29
+ fn.mockImplementation(() => 'result')
30
+ fn.mockImplementationOnce(() => 'once')
31
+
32
+ // Clear/reset
33
+ fn.mockClear() // Clear call history
34
+ fn.mockReset() // Clear history + implementation
35
+ fn.mockRestore() // Restore original (for spies)
36
+ ```
37
+
38
+ ## Spying
39
+
40
+ ```ts
41
+ const obj = { method: () => 'original' }
42
+
43
+ const spy = vi.spyOn(obj, 'method')
44
+ obj.method()
45
+
46
+ expect(spy).toHaveBeenCalled()
47
+
48
+ // Mock implementation
49
+ spy.mockReturnValue('mocked')
50
+
51
+ // Spy on getter/setter
52
+ vi.spyOn(obj, 'prop', 'get').mockReturnValue('value')
53
+ ```
54
+
55
+ ## Module Mocking
56
+
57
+ ```ts
58
+ // Hoisted to top of file
59
+ vi.mock('./module', () => ({
60
+ fn: vi.fn(),
61
+ }))
62
+
63
+ // Partial mock
64
+ vi.mock('./module', async (importOriginal) => ({
65
+ ...(await importOriginal()),
66
+ specificFn: vi.fn(),
67
+ }))
68
+
69
+ // Spy mode - keep implementation
70
+ vi.mock('./module', { spy: true })
71
+
72
+ // Import actual module inside mock
73
+ const actual = await vi.importActual('./module')
74
+
75
+ // Import as mock
76
+ const mocked = await vi.importMock('./module')
77
+ ```
78
+
79
+ ## Dynamic Mocking
80
+
81
+ ```ts
82
+ // Not hoisted - use with dynamic imports
83
+ vi.doMock('./config', () => ({ key: 'value' }))
84
+ const config = await import('./config')
85
+
86
+ // Unmock
87
+ vi.doUnmock('./config')
88
+ vi.unmock('./module') // Hoisted
89
+ ```
90
+
91
+ ## Reset Modules
92
+
93
+ ```ts
94
+ // Clear module cache
95
+ vi.resetModules()
96
+
97
+ // Wait for dynamic imports
98
+ await vi.dynamicImportSettled()
99
+ ```
100
+
101
+ ## Fake Timers
102
+
103
+ ```ts
104
+ vi.useFakeTimers()
105
+
106
+ setTimeout(() => console.log('done'), 1000)
107
+
108
+ // Advance time
109
+ vi.advanceTimersByTime(1000)
110
+ vi.advanceTimersByTimeAsync(1000) // For async callbacks
111
+ vi.advanceTimersToNextTimer()
112
+ vi.advanceTimersToNextFrame() // requestAnimationFrame
113
+
114
+ // Run all timers
115
+ vi.runAllTimers()
116
+ vi.runAllTimersAsync()
117
+ vi.runOnlyPendingTimers()
118
+
119
+ // Clear timers
120
+ vi.clearAllTimers()
121
+
122
+ // Check state
123
+ vi.getTimerCount()
124
+ vi.isFakeTimers()
125
+
126
+ // Restore
127
+ vi.useRealTimers()
128
+ ```
129
+
130
+ ## Mock Date/Time
131
+
132
+ ```ts
133
+ vi.setSystemTime(new Date('2024-01-01'))
134
+ expect(new Date().getFullYear()).toBe(2024)
135
+
136
+ vi.getMockedSystemTime() // Get mocked date
137
+ vi.getRealSystemTime() // Get real time (ms)
138
+ ```
139
+
140
+ ## Global/Env Mocking
141
+
142
+ ```ts
143
+ // Stub global
144
+ vi.stubGlobal('fetch', vi.fn())
145
+ vi.unstubAllGlobals()
146
+
147
+ // Stub environment
148
+ vi.stubEnv('API_KEY', 'test')
149
+ vi.stubEnv('NODE_ENV', 'test')
150
+ vi.unstubAllEnvs()
151
+ ```
152
+
153
+ ## Hoisted Code
154
+
155
+ Run code before imports:
156
+
157
+ ```ts
158
+ const mock = vi.hoisted(() => vi.fn())
159
+
160
+ vi.mock('./module', () => ({
161
+ fn: mock, // Can reference hoisted variable
162
+ }))
163
+ ```
164
+
165
+ ## Waiting Utilities
166
+
167
+ ```ts
168
+ // Wait for callback to succeed
169
+ await vi.waitFor(async () => {
170
+ const el = document.querySelector('.loaded')
171
+ expect(el).toBeTruthy()
172
+ }, { timeout: 5000, interval: 100 })
173
+
174
+ // Wait for truthy value
175
+ const element = await vi.waitUntil(
176
+ () => document.querySelector('.loaded'),
177
+ { timeout: 5000 }
178
+ )
179
+ ```
180
+
181
+ ## Mock Object
182
+
183
+ Mock all methods of an object:
184
+
185
+ ```ts
186
+ const original = {
187
+ method: () => 'real',
188
+ nested: { fn: () => 'nested' },
189
+ }
190
+
191
+ const mocked = vi.mockObject(original)
192
+ mocked.method() // undefined (mocked)
193
+ mocked.method.mockReturnValue('mocked')
194
+
195
+ // Spy mode
196
+ const spied = vi.mockObject(original, { spy: true })
197
+ spied.method() // 'real'
198
+ expect(spied.method).toHaveBeenCalled()
199
+ ```
200
+
201
+ ## Test Configuration
202
+
203
+ ```ts
204
+ vi.setConfig({
205
+ testTimeout: 10_000,
206
+ hookTimeout: 10_000,
207
+ })
208
+
209
+ vi.resetConfig()
210
+ ```
211
+
212
+ ## Global Mock Management
213
+
214
+ ```ts
215
+ vi.clearAllMocks() // Clear all mock call history
216
+ vi.resetAllMocks() // Reset + clear implementation
217
+ vi.restoreAllMocks() // Restore originals (spies)
218
+ ```
219
+
220
+ ## vi.mocked Type Helper
221
+
222
+ TypeScript helper for mocked values:
223
+
224
+ ```ts
225
+ import { myFn } from './module'
226
+ vi.mock('./module')
227
+
228
+ // Type as mock
229
+ vi.mocked(myFn).mockReturnValue('typed')
230
+
231
+ // Deep mocking
232
+ vi.mocked(myModule, { deep: true })
233
+
234
+ // Partial mock typing
235
+ vi.mocked(fn, { partial: true }).mockResolvedValue({ ok: true })
236
+ ```
237
+
238
+ ## Key Points
239
+
240
+ - `vi.mock` is hoisted - use `vi.doMock` for dynamic mocking
241
+ - `vi.hoisted` lets you reference variables in mock factories
242
+ - Use `vi.spyOn` to spy on existing methods
243
+ - Fake timers require explicit setup and teardown
244
+ - `vi.waitFor` retries until assertion passes
245
+
246
+ <!--
247
+ Source references:
248
+ - https://vitest.dev/api/vi.html
249
+ -->
@@ -0,0 +1,166 @@
1
+ ---
2
+ name: vitest-cli
3
+ description: Command line interface commands and options
4
+ ---
5
+
6
+ # Command Line Interface
7
+
8
+ ## Commands
9
+
10
+ ### `vitest`
11
+
12
+ Start Vitest in watch mode (dev) or run mode (CI):
13
+
14
+ ```bash
15
+ vitest # Watch mode in dev, run mode in CI
16
+ vitest foobar # Run tests containing "foobar" in path
17
+ vitest basic/foo.test.ts:10 # Run specific test by file and line number
18
+ ```
19
+
20
+ ### `vitest run`
21
+
22
+ Run tests once without watch mode:
23
+
24
+ ```bash
25
+ vitest run
26
+ vitest run --coverage
27
+ ```
28
+
29
+ ### `vitest watch`
30
+
31
+ Explicitly start watch mode:
32
+
33
+ ```bash
34
+ vitest watch
35
+ ```
36
+
37
+ ### `vitest related`
38
+
39
+ Run tests that import specific files (useful with lint-staged):
40
+
41
+ ```bash
42
+ vitest related src/index.ts src/utils.ts --run
43
+ ```
44
+
45
+ ### `vitest bench`
46
+
47
+ Run only benchmark tests:
48
+
49
+ ```bash
50
+ vitest bench
51
+ ```
52
+
53
+ ### `vitest list`
54
+
55
+ List all matching tests without running them:
56
+
57
+ ```bash
58
+ vitest list # List test names
59
+ vitest list --json # Output as JSON
60
+ vitest list --filesOnly # List only test files
61
+ ```
62
+
63
+ ### `vitest init`
64
+
65
+ Initialize project setup:
66
+
67
+ ```bash
68
+ vitest init browser # Set up browser testing
69
+ ```
70
+
71
+ ## Common Options
72
+
73
+ ```bash
74
+ # Configuration
75
+ --config <path> # Path to config file
76
+ --project <name> # Run specific project
77
+
78
+ # Filtering
79
+ --testNamePattern, -t # Run tests matching pattern
80
+ --changed # Run tests for changed files
81
+ --changed HEAD~1 # Tests for last commit changes
82
+
83
+ # Reporters
84
+ --reporter <name> # default, verbose, dot, json, html
85
+ --reporter=html --outputFile=report.html
86
+
87
+ # Coverage
88
+ --coverage # Enable coverage
89
+ --coverage.provider v8 # Use v8 provider
90
+ --coverage.reporter text,html
91
+
92
+ # Execution
93
+ --shard <index>/<count> # Split tests across machines
94
+ --bail <n> # Stop after n failures
95
+ --retry <n> # Retry failed tests n times
96
+ --sequence.shuffle # Randomize test order
97
+
98
+ # Watch mode
99
+ --no-watch # Disable watch mode
100
+ --standalone # Start without running tests
101
+
102
+ # Environment
103
+ --environment <env> # jsdom, happy-dom, node
104
+ --globals # Enable global APIs
105
+
106
+ # Debugging
107
+ --inspect # Enable Node inspector
108
+ --inspect-brk # Break on start
109
+
110
+ # Output
111
+ --silent # Suppress console output
112
+ --no-color # Disable colors
113
+ ```
114
+
115
+ ## Package.json Scripts
116
+
117
+ ```json
118
+ {
119
+ "scripts": {
120
+ "test": "vitest",
121
+ "test:run": "vitest run",
122
+ "test:ui": "vitest --ui",
123
+ "coverage": "vitest run --coverage"
124
+ }
125
+ }
126
+ ```
127
+
128
+ ## Sharding for CI
129
+
130
+ Split tests across multiple machines:
131
+
132
+ ```bash
133
+ # Machine 1
134
+ vitest run --shard=1/3 --reporter=blob
135
+
136
+ # Machine 2
137
+ vitest run --shard=2/3 --reporter=blob
138
+
139
+ # Machine 3
140
+ vitest run --shard=3/3 --reporter=blob
141
+
142
+ # Merge reports
143
+ vitest --merge-reports --reporter=junit
144
+ ```
145
+
146
+ ## Watch Mode Keyboard Shortcuts
147
+
148
+ In watch mode, press:
149
+ - `a` - Run all tests
150
+ - `f` - Run only failed tests
151
+ - `u` - Update snapshots
152
+ - `p` - Filter by filename pattern
153
+ - `t` - Filter by test name pattern
154
+ - `q` - Quit
155
+
156
+ ## Key Points
157
+
158
+ - Watch mode is default in dev, run mode in CI (when `process.env.CI` is set)
159
+ - Use `--run` flag to ensure single run (important for lint-staged)
160
+ - Both camelCase (`--testTimeout`) and kebab-case (`--test-timeout`) work
161
+ - Boolean options can be negated with `--no-` prefix
162
+
163
+ <!--
164
+ Source references:
165
+ - https://vitest.dev/guide/cli.html
166
+ -->