skillshop 2.0.0 → 2.1.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 (62) hide show
  1. package/README.md +217 -104
  2. package/agents-content/000_communication-writing.block.md +11 -0
  3. package/agents-content/001_external-actions.block.md +9 -0
  4. package/agents-content/AGENTS.md +11 -0
  5. package/package.json +6 -3
  6. package/skills-content/architecture-scanner/SKILL.md +274 -0
  7. package/skills-content/architecture-scanner/files.json +10 -0
  8. package/skills-content/architecture-scanner/scan.sh +823 -0
  9. package/skills-content/change-review/SKILL.md +76 -0
  10. package/skills-content/change-review/agents/openai.yaml +4 -0
  11. package/skills-content/changelog/SKILL.md +99 -0
  12. package/skills-content/changeset/changeset.md +80 -0
  13. package/skills-content/code-buddy/SKILL.md +136 -0
  14. package/skills-content/design-system-catalog/SKILL.md +106 -0
  15. package/skills-content/design-system-catalog/extract-components.mjs +441 -0
  16. package/skills-content/design-system-catalog/generate-catalog.sh +255 -0
  17. package/skills-content/flare/SKILL.md +96 -0
  18. package/skills-content/grilling/SKILL.md +31 -0
  19. package/skills-content/install-sigmap/SKILL.md +97 -0
  20. package/skills-content/one-shot/SKILL.md +51 -0
  21. package/skills-content/release/SKILL.md +128 -0
  22. package/skills-content/shadow-clone/SKILL.md +228 -0
  23. package/skills-content/shadow-clone/extract-signatures.mjs +202 -0
  24. package/skills-content/shadow-clone/scan-repo.mjs +343 -0
  25. package/skills-content/ship/SKILL.md +95 -0
  26. package/skills-content/shots/SKILL.md +89 -0
  27. package/skills-content/shots/agents/openai.yaml +4 -0
  28. package/skills-content/skillshop/SKILL.md +104 -0
  29. package/skills-content/skillz/SKILL.md +15 -0
  30. package/skills-content/transcript-clean/SKILL.md +55 -0
  31. package/skills-content/transcript-edit/SKILL.md +80 -0
  32. package/skills-content/vitest/GENERATION.md +5 -0
  33. package/skills-content/vitest/SKILL.md +52 -0
  34. package/skills-content/vitest/references/advanced-environments.md +264 -0
  35. package/skills-content/vitest/references/advanced-projects.md +300 -0
  36. package/skills-content/vitest/references/advanced-type-testing.md +237 -0
  37. package/skills-content/vitest/references/advanced-vi.md +249 -0
  38. package/skills-content/vitest/references/core-cli.md +166 -0
  39. package/skills-content/vitest/references/core-config.md +174 -0
  40. package/skills-content/vitest/references/core-describe.md +193 -0
  41. package/skills-content/vitest/references/core-expect.md +219 -0
  42. package/skills-content/vitest/references/core-hooks.md +244 -0
  43. package/skills-content/vitest/references/core-test-api.md +233 -0
  44. package/skills-content/vitest/references/features-concurrency.md +250 -0
  45. package/skills-content/vitest/references/features-context.md +238 -0
  46. package/skills-content/vitest/references/features-coverage.md +207 -0
  47. package/skills-content/vitest/references/features-filtering.md +211 -0
  48. package/skills-content/vitest/references/features-mocking.md +265 -0
  49. package/skills-content/vitest/references/features-snapshots.md +207 -0
  50. package/skills-content/workleaf/SKILL.md +77 -0
  51. package/skills-content/worklog/SKILL.md +145 -0
  52. package/skills-content/worklog/references/summary-format.md +114 -0
  53. package/skills-content/worktree/SKILL.md +71 -0
  54. package/src/agents-instructions.js +219 -0
  55. package/src/cli.js +87 -23
  56. package/src/import.js +12 -7
  57. package/src/index.js +1 -0
  58. package/src/legacy-agents-content.js +36 -0
  59. package/src/legacy-cli.js +1234 -0
  60. package/src/library.js +9 -0
  61. package/src/specifier.js +11 -0
  62. package/src/user-install.js +48 -0
@@ -0,0 +1,233 @@
1
+ ---
2
+ name: test-api
3
+ description: test/it function for defining tests with modifiers
4
+ ---
5
+
6
+ # Test API
7
+
8
+ ## Basic Test
9
+
10
+ ```ts
11
+ import { expect, test } from 'vitest'
12
+
13
+ test('adds numbers', () => {
14
+ expect(1 + 1).toBe(2)
15
+ })
16
+
17
+ // Alias: it
18
+ import { it } from 'vitest'
19
+
20
+ it('works the same', () => {
21
+ expect(true).toBe(true)
22
+ })
23
+ ```
24
+
25
+ ## Async Tests
26
+
27
+ ```ts
28
+ test('async test', async () => {
29
+ const result = await fetchData()
30
+ expect(result).toBeDefined()
31
+ })
32
+
33
+ // Promises are automatically awaited
34
+ test('returns promise', () => {
35
+ return fetchData().then(result => {
36
+ expect(result).toBeDefined()
37
+ })
38
+ })
39
+ ```
40
+
41
+ ## Test Options
42
+
43
+ ```ts
44
+ // Timeout (default: 5000ms)
45
+ test('slow test', async () => {
46
+ // ...
47
+ }, 10_000)
48
+
49
+ // Or with options object
50
+ test('with options', { timeout: 10_000, retry: 2 }, async () => {
51
+ // ...
52
+ })
53
+ ```
54
+
55
+ ## Test Modifiers
56
+
57
+ ### Skip Tests
58
+
59
+ ```ts
60
+ test.skip('skipped test', () => {
61
+ // Won't run
62
+ })
63
+
64
+ // Conditional skip
65
+ test.skipIf(process.env.CI)('not in CI', () => {})
66
+ test.runIf(process.env.CI)('only in CI', () => {})
67
+
68
+ // Dynamic skip via context
69
+ test('dynamic skip', ({ skip }) => {
70
+ skip(someCondition, 'reason')
71
+ // ...
72
+ })
73
+ ```
74
+
75
+ ### Focus Tests
76
+
77
+ ```ts
78
+ test.only('only this runs', () => {
79
+ // Other tests in file are skipped
80
+ })
81
+ ```
82
+
83
+ ### Todo Tests
84
+
85
+ ```ts
86
+ test.todo('implement later')
87
+
88
+ test.todo('with body', () => {
89
+ // Not run, shows in report
90
+ })
91
+ ```
92
+
93
+ ### Failing Tests
94
+
95
+ ```ts
96
+ test.fails('expected to fail', () => {
97
+ expect(1).toBe(2) // Test passes because assertion fails
98
+ })
99
+ ```
100
+
101
+ ### Concurrent Tests
102
+
103
+ ```ts
104
+ // Run tests in parallel
105
+ test.concurrent('test 1', async ({ expect }) => {
106
+ // Use context.expect for concurrent tests
107
+ expect(await fetch1()).toBe('result')
108
+ })
109
+
110
+ test.concurrent('test 2', async ({ expect }) => {
111
+ expect(await fetch2()).toBe('result')
112
+ })
113
+ ```
114
+
115
+ ### Sequential Tests
116
+
117
+ ```ts
118
+ // Force sequential in concurrent context
119
+ test.sequential('must run alone', async () => {})
120
+ ```
121
+
122
+ ## Parameterized Tests
123
+
124
+ ### test.each
125
+
126
+ ```ts
127
+ test.each([
128
+ [1, 1, 2],
129
+ [1, 2, 3],
130
+ [2, 1, 3],
131
+ ])('add(%i, %i) = %i', (a, b, expected) => {
132
+ expect(a + b).toBe(expected)
133
+ })
134
+
135
+ // With objects
136
+ test.each([
137
+ { a: 1, b: 1, expected: 2 },
138
+ { a: 1, b: 2, expected: 3 },
139
+ ])('add($a, $b) = $expected', ({ a, b, expected }) => {
140
+ expect(a + b).toBe(expected)
141
+ })
142
+
143
+ // Template literal
144
+ test.each`
145
+ a | b | expected
146
+ ${1} | ${1} | ${2}
147
+ ${1} | ${2} | ${3}
148
+ `('add($a, $b) = $expected', ({ a, b, expected }) => {
149
+ expect(a + b).toBe(expected)
150
+ })
151
+ ```
152
+
153
+ ### test.for
154
+
155
+ Preferred over `.each` - doesn't spread arrays:
156
+
157
+ ```ts
158
+ test.for([
159
+ [1, 1, 2],
160
+ [1, 2, 3],
161
+ ])('add(%i, %i) = %i', ([a, b, expected], { expect }) => {
162
+ // Second arg is TestContext
163
+ expect(a + b).toBe(expected)
164
+ })
165
+ ```
166
+
167
+ ## Test Context
168
+
169
+ First argument provides context utilities:
170
+
171
+ ```ts
172
+ test('with context', ({ expect, skip, task }) => {
173
+ console.log(task.name) // Test name
174
+ skip(someCondition) // Skip dynamically
175
+ expect(1).toBe(1) // Context-bound expect
176
+ })
177
+ ```
178
+
179
+ ## Custom Test with Fixtures
180
+
181
+ ```ts
182
+ import { test as base } from 'vitest'
183
+
184
+ const test = base.extend({
185
+ db: async ({}, use) => {
186
+ const db = await createDb()
187
+ await use(db)
188
+ await db.close()
189
+ },
190
+ })
191
+
192
+ test('query', async ({ db }) => {
193
+ const users = await db.query('SELECT * FROM users')
194
+ expect(users).toBeDefined()
195
+ })
196
+ ```
197
+
198
+ ## Retry Configuration
199
+
200
+ ```ts
201
+ test('flaky test', { retry: 3 }, async () => {
202
+ // Retries up to 3 times on failure
203
+ })
204
+
205
+ // Advanced retry options
206
+ test('with delay', {
207
+ retry: {
208
+ count: 3,
209
+ delay: 1000,
210
+ condition: /timeout/i, // Only retry on timeout errors
211
+ },
212
+ }, async () => {})
213
+ ```
214
+
215
+ ## Tags
216
+
217
+ ```ts
218
+ test('database test', { tags: ['db', 'slow'] }, async () => {})
219
+
220
+ // Run with: vitest --tags db
221
+ ```
222
+
223
+ ## Key Points
224
+
225
+ - Tests with no body are marked as `todo`
226
+ - `test.only` throws in CI unless `allowOnly: true`
227
+ - Use context's `expect` for concurrent tests and snapshots
228
+ - Function name is used as test name if passed as first arg
229
+
230
+ <!--
231
+ Source references:
232
+ - https://vitest.dev/api/test.html
233
+ -->
@@ -0,0 +1,250 @@
1
+ ---
2
+ name: concurrency-parallelism
3
+ description: Concurrent tests, parallel execution, and sharding
4
+ ---
5
+
6
+ # Concurrency & Parallelism
7
+
8
+ ## File Parallelism
9
+
10
+ By default, Vitest runs test files in parallel across workers:
11
+
12
+ ```ts
13
+ defineConfig({
14
+ test: {
15
+ // Run files in parallel (default: true)
16
+ fileParallelism: true,
17
+
18
+ // Number of worker threads
19
+ maxWorkers: 4,
20
+ minWorkers: 1,
21
+
22
+ // Pool type: 'threads', 'forks', 'vmThreads'
23
+ pool: 'threads',
24
+ },
25
+ })
26
+ ```
27
+
28
+ ## Concurrent Tests
29
+
30
+ Run tests within a file in parallel:
31
+
32
+ ```ts
33
+ // Individual concurrent tests
34
+ test.concurrent('test 1', async ({ expect }) => {
35
+ expect(await fetch1()).toBe('result')
36
+ })
37
+
38
+ test.concurrent('test 2', async ({ expect }) => {
39
+ expect(await fetch2()).toBe('result')
40
+ })
41
+
42
+ // All tests in suite concurrent
43
+ describe.concurrent('parallel suite', () => {
44
+ test('test 1', async ({ expect }) => {})
45
+ test('test 2', async ({ expect }) => {})
46
+ })
47
+ ```
48
+
49
+ **Important:** Use `{ expect }` from context for concurrent tests.
50
+
51
+ ## Sequential in Concurrent Context
52
+
53
+ Force sequential execution:
54
+
55
+ ```ts
56
+ describe.concurrent('mostly parallel', () => {
57
+ test('parallel 1', async () => {})
58
+ test('parallel 2', async () => {})
59
+
60
+ test.sequential('must run alone 1', async () => {})
61
+ test.sequential('must run alone 2', async () => {})
62
+ })
63
+
64
+ // Or entire suite
65
+ describe.sequential('sequential suite', () => {
66
+ test('first', () => {})
67
+ test('second', () => {})
68
+ })
69
+ ```
70
+
71
+ ## Max Concurrency
72
+
73
+ Limit concurrent tests:
74
+
75
+ ```ts
76
+ defineConfig({
77
+ test: {
78
+ maxConcurrency: 5, // Max concurrent tests per file
79
+ },
80
+ })
81
+ ```
82
+
83
+ ## Isolation
84
+
85
+ Each file runs in isolated environment by default:
86
+
87
+ ```ts
88
+ defineConfig({
89
+ test: {
90
+ // Disable isolation for faster runs (less safe)
91
+ isolate: false,
92
+ },
93
+ })
94
+ ```
95
+
96
+ ## Sharding
97
+
98
+ Split tests across machines:
99
+
100
+ ```bash
101
+ # Machine 1
102
+ vitest run --shard=1/3
103
+
104
+ # Machine 2
105
+ vitest run --shard=2/3
106
+
107
+ # Machine 3
108
+ vitest run --shard=3/3
109
+ ```
110
+
111
+ ### CI Example (GitHub Actions)
112
+
113
+ ```yaml
114
+ jobs:
115
+ test:
116
+ strategy:
117
+ matrix:
118
+ shard: [1, 2, 3]
119
+ steps:
120
+ - run: vitest run --shard=${{ matrix.shard }}/3 --reporter=blob
121
+
122
+ merge:
123
+ needs: test
124
+ steps:
125
+ - run: vitest --merge-reports --reporter=junit
126
+ ```
127
+
128
+ ### Merge Reports
129
+
130
+ ```bash
131
+ # Each shard outputs blob
132
+ vitest run --shard=1/3 --reporter=blob --coverage
133
+ vitest run --shard=2/3 --reporter=blob --coverage
134
+
135
+ # Merge all blobs
136
+ vitest --merge-reports --reporter=json --coverage
137
+ ```
138
+
139
+ ## Test Sequence
140
+
141
+ Control test order:
142
+
143
+ ```ts
144
+ defineConfig({
145
+ test: {
146
+ sequence: {
147
+ // Run tests in random order
148
+ shuffle: true,
149
+
150
+ // Seed for reproducible shuffle
151
+ seed: 12345,
152
+
153
+ // Hook execution order
154
+ hooks: 'stack', // 'stack', 'list', 'parallel'
155
+
156
+ // All tests concurrent by default
157
+ concurrent: true,
158
+ },
159
+ },
160
+ })
161
+ ```
162
+
163
+ ## Shuffle Tests
164
+
165
+ Randomize to catch hidden dependencies:
166
+
167
+ ```ts
168
+ // Via CLI
169
+ vitest --sequence.shuffle
170
+
171
+ // Per suite
172
+ describe.shuffle('random order', () => {
173
+ test('test 1', () => {})
174
+ test('test 2', () => {})
175
+ test('test 3', () => {})
176
+ })
177
+ ```
178
+
179
+ ## Pool Options
180
+
181
+ ### Threads (Default)
182
+
183
+ ```ts
184
+ defineConfig({
185
+ test: {
186
+ pool: 'threads',
187
+ poolOptions: {
188
+ threads: {
189
+ maxThreads: 8,
190
+ minThreads: 2,
191
+ isolate: true,
192
+ },
193
+ },
194
+ },
195
+ })
196
+ ```
197
+
198
+ ### Forks
199
+
200
+ Better isolation, slower:
201
+
202
+ ```ts
203
+ defineConfig({
204
+ test: {
205
+ pool: 'forks',
206
+ poolOptions: {
207
+ forks: {
208
+ maxForks: 4,
209
+ isolate: true,
210
+ },
211
+ },
212
+ },
213
+ })
214
+ ```
215
+
216
+ ### VM Threads
217
+
218
+ Full VM isolation per file:
219
+
220
+ ```ts
221
+ defineConfig({
222
+ test: {
223
+ pool: 'vmThreads',
224
+ },
225
+ })
226
+ ```
227
+
228
+ ## Bail on Failure
229
+
230
+ Stop after first failure:
231
+
232
+ ```bash
233
+ vitest --bail 1 # Stop after 1 failure
234
+ vitest --bail # Stop on first failure (same as --bail 1)
235
+ ```
236
+
237
+ ## Key Points
238
+
239
+ - Files run in parallel by default
240
+ - Use `.concurrent` for parallel tests within file
241
+ - Always use context's `expect` in concurrent tests
242
+ - Sharding splits tests across CI machines
243
+ - Use `--merge-reports` to combine sharded results
244
+ - Shuffle tests to find hidden dependencies
245
+
246
+ <!--
247
+ Source references:
248
+ - https://vitest.dev/guide/features.html#running-tests-concurrently
249
+ - https://vitest.dev/guide/improving-performance.html
250
+ -->
@@ -0,0 +1,238 @@
1
+ ---
2
+ name: test-context-fixtures
3
+ description: Test context, custom fixtures with test.extend
4
+ ---
5
+
6
+ # Test Context & Fixtures
7
+
8
+ ## Built-in Context
9
+
10
+ Every test receives context as first argument:
11
+
12
+ ```ts
13
+ test('context', ({ task, expect, skip }) => {
14
+ console.log(task.name) // Test name
15
+ expect(1).toBe(1) // Context-bound expect
16
+ skip() // Skip test dynamically
17
+ })
18
+ ```
19
+
20
+ ### Context Properties
21
+
22
+ - `task` - Test metadata (name, file, etc.)
23
+ - `expect` - Expect bound to this test (important for concurrent tests)
24
+ - `skip(condition?, message?)` - Skip the test
25
+ - `onTestFinished(fn)` - Cleanup after test
26
+ - `onTestFailed(fn)` - Run on failure only
27
+
28
+ ## Custom Fixtures with test.extend
29
+
30
+ Create reusable test utilities:
31
+
32
+ ```ts
33
+ import { test as base } from 'vitest'
34
+
35
+ // Define fixture types
36
+ interface Fixtures {
37
+ db: Database
38
+ user: User
39
+ }
40
+
41
+ // Create extended test
42
+ export const test = base.extend<Fixtures>({
43
+ // Fixture with setup/teardown
44
+ db: async ({}, use) => {
45
+ const db = await createDatabase()
46
+ await use(db) // Provide to test
47
+ await db.close() // Cleanup
48
+ },
49
+
50
+ // Fixture depending on another fixture
51
+ user: async ({ db }, use) => {
52
+ const user = await db.createUser({ name: 'Test' })
53
+ await use(user)
54
+ await db.deleteUser(user.id)
55
+ },
56
+ })
57
+ ```
58
+
59
+ Using fixtures:
60
+
61
+ ```ts
62
+ test('query user', async ({ db, user }) => {
63
+ const found = await db.findUser(user.id)
64
+ expect(found).toEqual(user)
65
+ })
66
+ ```
67
+
68
+ ## Fixture Initialization
69
+
70
+ Fixtures only initialize when accessed:
71
+
72
+ ```ts
73
+ const test = base.extend({
74
+ expensive: async ({}, use) => {
75
+ console.log('initializing') // Only runs if test uses it
76
+ await use('value')
77
+ },
78
+ })
79
+
80
+ test('no fixture', () => {}) // expensive not called
81
+ test('uses fixture', ({ expensive }) => {}) // expensive called
82
+ ```
83
+
84
+ ## Auto Fixtures
85
+
86
+ Run fixture for every test:
87
+
88
+ ```ts
89
+ const test = base.extend({
90
+ setup: [
91
+ async ({}, use) => {
92
+ await globalSetup()
93
+ await use()
94
+ await globalTeardown()
95
+ },
96
+ { auto: true } // Always run
97
+ ],
98
+ })
99
+ ```
100
+
101
+ ## Scoped Fixtures
102
+
103
+ ### File Scope
104
+
105
+ Initialize once per file:
106
+
107
+ ```ts
108
+ const test = base.extend({
109
+ connection: [
110
+ async ({}, use) => {
111
+ const conn = await connect()
112
+ await use(conn)
113
+ await conn.close()
114
+ },
115
+ { scope: 'file' }
116
+ ],
117
+ })
118
+ ```
119
+
120
+ ### Worker Scope
121
+
122
+ Initialize once per worker:
123
+
124
+ ```ts
125
+ const test = base.extend({
126
+ sharedResource: [
127
+ async ({}, use) => {
128
+ await use(globalResource)
129
+ },
130
+ { scope: 'worker' }
131
+ ],
132
+ })
133
+ ```
134
+
135
+ ## Injected Fixtures (from Config)
136
+
137
+ Override fixtures per project:
138
+
139
+ ```ts
140
+ // test file
141
+ const test = base.extend({
142
+ apiUrl: ['/default', { injected: true }],
143
+ })
144
+
145
+ // vitest.config.ts
146
+ defineConfig({
147
+ test: {
148
+ projects: [
149
+ {
150
+ test: {
151
+ name: 'prod',
152
+ provide: { apiUrl: 'https://api.prod.com' },
153
+ },
154
+ },
155
+ ],
156
+ },
157
+ })
158
+ ```
159
+
160
+ ## Scoped Values per Suite
161
+
162
+ Override fixture for specific suite:
163
+
164
+ ```ts
165
+ const test = base.extend({
166
+ environment: 'development',
167
+ })
168
+
169
+ describe('production tests', () => {
170
+ test.scoped({ environment: 'production' })
171
+
172
+ test('uses production', ({ environment }) => {
173
+ expect(environment).toBe('production')
174
+ })
175
+ })
176
+
177
+ test('uses default', ({ environment }) => {
178
+ expect(environment).toBe('development')
179
+ })
180
+ ```
181
+
182
+ ## Extended Test Hooks
183
+
184
+ Type-aware hooks with fixtures:
185
+
186
+ ```ts
187
+ const test = base.extend<{ db: Database }>({
188
+ db: async ({}, use) => {
189
+ const db = await createDb()
190
+ await use(db)
191
+ await db.close()
192
+ },
193
+ })
194
+
195
+ // Hooks know about fixtures
196
+ test.beforeEach(({ db }) => {
197
+ db.seed()
198
+ })
199
+
200
+ test.afterEach(({ db }) => {
201
+ db.clear()
202
+ })
203
+ ```
204
+
205
+ ## Composing Fixtures
206
+
207
+ Extend from another extended test:
208
+
209
+ ```ts
210
+ // base-test.ts
211
+ export const test = base.extend<{ db: Database }>({
212
+ db: async ({}, use) => { /* ... */ },
213
+ })
214
+
215
+ // admin-test.ts
216
+ import { test as dbTest } from './base-test'
217
+
218
+ export const test = dbTest.extend<{ admin: User }>({
219
+ admin: async ({ db }, use) => {
220
+ const admin = await db.createAdmin()
221
+ await use(admin)
222
+ },
223
+ })
224
+ ```
225
+
226
+ ## Key Points
227
+
228
+ - Use `{ }` destructuring to access fixtures
229
+ - Fixtures are lazy - only initialize when accessed
230
+ - Return cleanup function from fixtures
231
+ - Use `{ auto: true }` for setup fixtures
232
+ - Use `{ scope: 'file' }` for expensive shared resources
233
+ - Fixtures compose - extend from extended tests
234
+
235
+ <!--
236
+ Source references:
237
+ - https://vitest.dev/guide/test-context.html
238
+ -->