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,207 @@
1
+ ---
2
+ name: code-coverage
3
+ description: Code coverage with V8 or Istanbul providers
4
+ ---
5
+
6
+ # Code Coverage
7
+
8
+ ## Setup
9
+
10
+ ```bash
11
+ # Run tests with coverage
12
+ vitest run --coverage
13
+ ```
14
+
15
+ ## Configuration
16
+
17
+ ```ts
18
+ // vitest.config.ts
19
+ defineConfig({
20
+ test: {
21
+ coverage: {
22
+ // Provider: 'v8' (default, faster) or 'istanbul' (more compatible)
23
+ provider: 'v8',
24
+
25
+ // Enable coverage
26
+ enabled: true,
27
+
28
+ // Reporters
29
+ reporter: ['text', 'json', 'html'],
30
+
31
+ // Files to include
32
+ include: ['src/**/*.{ts,tsx}'],
33
+
34
+ // Files to exclude
35
+ exclude: [
36
+ 'node_modules/',
37
+ 'tests/',
38
+ '**/*.d.ts',
39
+ '**/*.test.ts',
40
+ ],
41
+
42
+ // Report uncovered files
43
+ all: true,
44
+
45
+ // Thresholds
46
+ thresholds: {
47
+ lines: 80,
48
+ functions: 80,
49
+ branches: 80,
50
+ statements: 80,
51
+ },
52
+ },
53
+ },
54
+ })
55
+ ```
56
+
57
+ ## Providers
58
+
59
+ ### V8 (Default)
60
+
61
+ ```bash
62
+ npm i -D @vitest/coverage-v8
63
+ ```
64
+
65
+ - Faster, no pre-instrumentation
66
+ - Uses V8's native coverage
67
+ - Recommended for most projects
68
+
69
+ ### Istanbul
70
+
71
+ ```bash
72
+ npm i -D @vitest/coverage-istanbul
73
+ ```
74
+
75
+ - Pre-instruments code
76
+ - Works in any JS runtime
77
+ - More overhead but widely compatible
78
+
79
+ ## Reporters
80
+
81
+ ```ts
82
+ coverage: {
83
+ reporter: [
84
+ 'text', // Terminal output
85
+ 'text-summary', // Summary only
86
+ 'json', // JSON file
87
+ 'html', // HTML report
88
+ 'lcov', // For CI tools
89
+ 'cobertura', // XML format
90
+ ],
91
+ reportsDirectory: './coverage',
92
+ }
93
+ ```
94
+
95
+ ## Thresholds
96
+
97
+ Fail tests if coverage is below threshold:
98
+
99
+ ```ts
100
+ coverage: {
101
+ thresholds: {
102
+ // Global thresholds
103
+ lines: 80,
104
+ functions: 75,
105
+ branches: 70,
106
+ statements: 80,
107
+
108
+ // Per-file thresholds
109
+ perFile: true,
110
+
111
+ // Auto-update thresholds (for gradual improvement)
112
+ autoUpdate: true,
113
+ },
114
+ }
115
+ ```
116
+
117
+ ## Ignoring Code
118
+
119
+ ### V8
120
+
121
+ ```ts
122
+ /* v8 ignore next -- @preserve */
123
+ function ignored() {
124
+ return 'not covered'
125
+ }
126
+
127
+ /* v8 ignore start -- @preserve */
128
+ // All code here ignored
129
+ /* v8 ignore stop -- @preserve */
130
+ ```
131
+
132
+ ### Istanbul
133
+
134
+ ```ts
135
+ /* istanbul ignore next -- @preserve */
136
+ function ignored() {}
137
+
138
+ /* istanbul ignore if -- @preserve */
139
+ if (condition) {
140
+ // ignored
141
+ }
142
+ ```
143
+
144
+ Note: `@preserve` keeps comments through esbuild.
145
+
146
+ ## Package.json Scripts
147
+
148
+ ```json
149
+ {
150
+ "scripts": {
151
+ "test": "vitest",
152
+ "test:coverage": "vitest run --coverage",
153
+ "test:coverage:watch": "vitest --coverage"
154
+ }
155
+ }
156
+ ```
157
+
158
+ ## Vitest UI Coverage
159
+
160
+ Enable HTML coverage in Vitest UI:
161
+
162
+ ```ts
163
+ coverage: {
164
+ enabled: true,
165
+ reporter: ['text', 'html'],
166
+ }
167
+ ```
168
+
169
+ Run with `vitest --ui` to view coverage visually.
170
+
171
+ ## CI Integration
172
+
173
+ ```yaml
174
+ # GitHub Actions
175
+ - name: Run tests with coverage
176
+ run: npm run test:coverage
177
+
178
+ - name: Upload coverage to Codecov
179
+ uses: codecov/codecov-action@v3
180
+ with:
181
+ files: ./coverage/lcov.info
182
+ ```
183
+
184
+ ## Coverage with Sharding
185
+
186
+ Merge coverage from sharded runs:
187
+
188
+ ```bash
189
+ vitest run --shard=1/3 --coverage --reporter=blob
190
+ vitest run --shard=2/3 --coverage --reporter=blob
191
+ vitest run --shard=3/3 --coverage --reporter=blob
192
+
193
+ vitest --merge-reports --coverage --reporter=json
194
+ ```
195
+
196
+ ## Key Points
197
+
198
+ - V8 is faster, Istanbul is more compatible
199
+ - Use `--coverage` flag or `coverage.enabled: true`
200
+ - Include `all: true` to see uncovered files
201
+ - Set thresholds to enforce minimum coverage
202
+ - Use `@preserve` comment to keep ignore hints
203
+
204
+ <!--
205
+ Source references:
206
+ - https://vitest.dev/guide/coverage.html
207
+ -->
@@ -0,0 +1,211 @@
1
+ ---
2
+ name: test-filtering
3
+ description: Filter tests by name, file patterns, and tags
4
+ ---
5
+
6
+ # Test Filtering
7
+
8
+ ## CLI Filtering
9
+
10
+ ### By File Path
11
+
12
+ ```bash
13
+ # Run files containing "user"
14
+ vitest user
15
+
16
+ # Multiple patterns
17
+ vitest user auth
18
+
19
+ # Specific file
20
+ vitest src/user.test.ts
21
+
22
+ # By line number
23
+ vitest src/user.test.ts:25
24
+ ```
25
+
26
+ ### By Test Name
27
+
28
+ ```bash
29
+ # Tests matching pattern
30
+ vitest -t "login"
31
+ vitest --testNamePattern "should.*work"
32
+
33
+ # Regex patterns
34
+ vitest -t "/user|auth/"
35
+ ```
36
+
37
+ ## Changed Files
38
+
39
+ ```bash
40
+ # Uncommitted changes
41
+ vitest --changed
42
+
43
+ # Since specific commit
44
+ vitest --changed HEAD~1
45
+ vitest --changed abc123
46
+
47
+ # Since branch
48
+ vitest --changed origin/main
49
+ ```
50
+
51
+ ## Related Files
52
+
53
+ Run tests that import specific files:
54
+
55
+ ```bash
56
+ vitest related src/utils.ts src/api.ts --run
57
+ ```
58
+
59
+ Useful with lint-staged:
60
+
61
+ ```js
62
+ // .lintstagedrc.js
63
+ export default {
64
+ '*.{ts,tsx}': 'vitest related --run',
65
+ }
66
+ ```
67
+
68
+ ## Focus Tests (.only)
69
+
70
+ ```ts
71
+ test.only('only this runs', () => {})
72
+
73
+ describe.only('only this suite', () => {
74
+ test('runs', () => {})
75
+ })
76
+ ```
77
+
78
+ In CI, `.only` throws error unless configured:
79
+
80
+ ```ts
81
+ defineConfig({
82
+ test: {
83
+ allowOnly: true, // Allow .only in CI
84
+ },
85
+ })
86
+ ```
87
+
88
+ ## Skip Tests
89
+
90
+ ```ts
91
+ test.skip('skipped', () => {})
92
+
93
+ // Conditional
94
+ test.skipIf(process.env.CI)('not in CI', () => {})
95
+ test.runIf(!process.env.CI)('local only', () => {})
96
+
97
+ // Dynamic skip
98
+ test('dynamic', ({ skip }) => {
99
+ skip(someCondition, 'reason')
100
+ })
101
+ ```
102
+
103
+ ## Tags
104
+
105
+ Filter by custom tags:
106
+
107
+ ```ts
108
+ test('database test', { tags: ['db'] }, () => {})
109
+ test('slow test', { tags: ['slow', 'integration'] }, () => {})
110
+ ```
111
+
112
+ Run tagged tests:
113
+
114
+ ```bash
115
+ vitest --tags db
116
+ vitest --tags "db,slow" # OR
117
+ vitest --tags db --tags slow # OR
118
+ ```
119
+
120
+ Configure allowed tags:
121
+
122
+ ```ts
123
+ defineConfig({
124
+ test: {
125
+ tags: ['db', 'slow', 'integration'],
126
+ strictTags: true, // Fail on unknown tags
127
+ },
128
+ })
129
+ ```
130
+
131
+ ## Include/Exclude Patterns
132
+
133
+ ```ts
134
+ defineConfig({
135
+ test: {
136
+ // Test file patterns
137
+ include: ['**/*.{test,spec}.{ts,tsx}'],
138
+
139
+ // Exclude patterns
140
+ exclude: [
141
+ '**/node_modules/**',
142
+ '**/e2e/**',
143
+ '**/*.skip.test.ts',
144
+ ],
145
+
146
+ // Include source for in-source testing
147
+ includeSource: ['src/**/*.ts'],
148
+ },
149
+ })
150
+ ```
151
+
152
+ ## Watch Mode Filtering
153
+
154
+ In watch mode, press:
155
+ - `p` - Filter by filename pattern
156
+ - `t` - Filter by test name pattern
157
+ - `a` - Run all tests
158
+ - `f` - Run only failed tests
159
+
160
+ ## Projects Filtering
161
+
162
+ Run specific project:
163
+
164
+ ```bash
165
+ vitest --project unit
166
+ vitest --project integration --project e2e
167
+ ```
168
+
169
+ ## Environment-based Filtering
170
+
171
+ ```ts
172
+ const isDev = process.env.NODE_ENV === 'development'
173
+ const isCI = process.env.CI
174
+
175
+ describe.skipIf(isCI)('local only tests', () => {})
176
+ describe.runIf(isDev)('dev tests', () => {})
177
+ ```
178
+
179
+ ## Combining Filters
180
+
181
+ ```bash
182
+ # File pattern + test name + changed
183
+ vitest user -t "login" --changed
184
+
185
+ # Related files + run mode
186
+ vitest related src/auth.ts --run
187
+ ```
188
+
189
+ ## List Tests Without Running
190
+
191
+ ```bash
192
+ vitest list # Show all test names
193
+ vitest list -t "user" # Filter by name
194
+ vitest list --filesOnly # Show only file paths
195
+ vitest list --json # JSON output
196
+ ```
197
+
198
+ ## Key Points
199
+
200
+ - Use `-t` for test name pattern filtering
201
+ - `--changed` runs only tests affected by changes
202
+ - `--related` runs tests importing specific files
203
+ - Tags provide semantic test grouping
204
+ - Use `.only` for debugging, but configure CI to reject it
205
+ - Watch mode has interactive filtering
206
+
207
+ <!--
208
+ Source references:
209
+ - https://vitest.dev/guide/filtering.html
210
+ - https://vitest.dev/guide/cli.html
211
+ -->
@@ -0,0 +1,265 @@
1
+ ---
2
+ name: mocking
3
+ description: Mock functions, modules, timers, and dates with vi utilities
4
+ ---
5
+
6
+ # Mocking
7
+
8
+ ## Mock Functions
9
+
10
+ ```ts
11
+ import { expect, vi } from 'vitest'
12
+
13
+ // Create mock function
14
+ const fn = vi.fn()
15
+ fn('hello')
16
+
17
+ expect(fn).toHaveBeenCalled()
18
+ expect(fn).toHaveBeenCalledWith('hello')
19
+
20
+ // With implementation
21
+ const add = vi.fn((a, b) => a + b)
22
+ expect(add(1, 2)).toBe(3)
23
+
24
+ // Mock return values
25
+ fn.mockReturnValue(42)
26
+ fn.mockReturnValueOnce(1).mockReturnValueOnce(2)
27
+ fn.mockResolvedValue({ data: true })
28
+ fn.mockRejectedValue(new Error('fail'))
29
+
30
+ // Mock implementation
31
+ fn.mockImplementation((x) => x * 2)
32
+ fn.mockImplementationOnce(() => 'first call')
33
+ ```
34
+
35
+ ## Spying on Objects
36
+
37
+ ```ts
38
+ const cart = {
39
+ getTotal: () => 100,
40
+ }
41
+
42
+ const spy = vi.spyOn(cart, 'getTotal')
43
+ cart.getTotal()
44
+
45
+ expect(spy).toHaveBeenCalled()
46
+
47
+ // Mock implementation
48
+ spy.mockReturnValue(200)
49
+ expect(cart.getTotal()).toBe(200)
50
+
51
+ // Restore original
52
+ spy.mockRestore()
53
+ ```
54
+
55
+ ## Module Mocking
56
+
57
+ ```ts
58
+ // vi.mock is hoisted to top of file
59
+ vi.mock('./api', () => ({
60
+ fetchUser: vi.fn(() => ({ id: 1, name: 'Mock' })),
61
+ }))
62
+
63
+ import { fetchUser } from './api'
64
+
65
+ test('mocked module', () => {
66
+ expect(fetchUser()).toEqual({ id: 1, name: 'Mock' })
67
+ })
68
+ ```
69
+
70
+ ### Partial Mock
71
+
72
+ ```ts
73
+ vi.mock('./utils', async (importOriginal) => {
74
+ const actual = await importOriginal()
75
+ return {
76
+ ...actual,
77
+ specificFunction: vi.fn(),
78
+ }
79
+ })
80
+ ```
81
+
82
+ ### Auto-mock with Spy
83
+
84
+ ```ts
85
+ // Keep implementation but spy on calls
86
+ vi.mock('./calculator', { spy: true })
87
+
88
+ import { add } from './calculator'
89
+
90
+ test('spy on module', () => {
91
+ const result = add(1, 2) // Real implementation
92
+ expect(result).toBe(3)
93
+ expect(add).toHaveBeenCalledWith(1, 2)
94
+ })
95
+ ```
96
+
97
+ ### Manual Mocks (__mocks__)
98
+
99
+ ```
100
+ src/
101
+ __mocks__/
102
+ axios.ts # Mocks 'axios'
103
+ api/
104
+ __mocks__/
105
+ client.ts # Mocks './client'
106
+ client.ts
107
+ ```
108
+
109
+ ```ts
110
+ // Just call vi.mock with no factory
111
+ vi.mock('axios')
112
+ vi.mock('./api/client')
113
+ ```
114
+
115
+ ## Dynamic Mocking (vi.doMock)
116
+
117
+ Not hoisted - use for dynamic imports:
118
+
119
+ ```ts
120
+ test('dynamic mock', async () => {
121
+ vi.doMock('./config', () => ({
122
+ apiUrl: 'http://test.local',
123
+ }))
124
+
125
+ const { apiUrl } = await import('./config')
126
+ expect(apiUrl).toBe('http://test.local')
127
+
128
+ vi.doUnmock('./config')
129
+ })
130
+ ```
131
+
132
+ ## Mock Timers
133
+
134
+ ```ts
135
+ import { afterEach, beforeEach, vi } from 'vitest'
136
+
137
+ beforeEach(() => {
138
+ vi.useFakeTimers()
139
+ })
140
+
141
+ afterEach(() => {
142
+ vi.useRealTimers()
143
+ })
144
+
145
+ test('timers', () => {
146
+ const fn = vi.fn()
147
+ setTimeout(fn, 1000)
148
+
149
+ expect(fn).not.toHaveBeenCalled()
150
+
151
+ vi.advanceTimersByTime(1000)
152
+ expect(fn).toHaveBeenCalled()
153
+ })
154
+
155
+ // Other timer methods
156
+ vi.runAllTimers() // Run all pending timers
157
+ vi.runOnlyPendingTimers() // Run only currently pending
158
+ vi.advanceTimersToNextTimer() // Advance to next timer
159
+ ```
160
+
161
+ ### Async Timer Methods
162
+
163
+ ```ts
164
+ test('async timers', async () => {
165
+ vi.useFakeTimers()
166
+
167
+ let resolved = false
168
+ setTimeout(() => Promise.resolve().then(() => { resolved = true }), 100)
169
+
170
+ await vi.advanceTimersByTimeAsync(100)
171
+ expect(resolved).toBe(true)
172
+ })
173
+ ```
174
+
175
+ ## Mock Dates
176
+
177
+ ```ts
178
+ vi.setSystemTime(new Date('2024-01-01'))
179
+ expect(new Date().getFullYear()).toBe(2024)
180
+
181
+ vi.useRealTimers() // Restore
182
+ ```
183
+
184
+ ## Mock Globals
185
+
186
+ ```ts
187
+ vi.stubGlobal('fetch', vi.fn(() =>
188
+ Promise.resolve({ json: () => ({ data: 'mock' }) })
189
+ ))
190
+
191
+ // Restore
192
+ vi.unstubAllGlobals()
193
+ ```
194
+
195
+ ## Mock Environment Variables
196
+
197
+ ```ts
198
+ vi.stubEnv('API_KEY', 'test-key')
199
+ expect(import.meta.env.API_KEY).toBe('test-key')
200
+
201
+ // Restore
202
+ vi.unstubAllEnvs()
203
+ ```
204
+
205
+ ## Clearing Mocks
206
+
207
+ ```ts
208
+ const fn = vi.fn()
209
+ fn()
210
+
211
+ fn.mockClear() // Clear call history
212
+ fn.mockReset() // Clear history + implementation
213
+ fn.mockRestore() // Restore original (for spies)
214
+
215
+ // Global
216
+ vi.clearAllMocks()
217
+ vi.resetAllMocks()
218
+ vi.restoreAllMocks()
219
+ ```
220
+
221
+ ## Config Auto-Reset
222
+
223
+ ```ts
224
+ // vitest.config.ts
225
+ defineConfig({
226
+ test: {
227
+ clearMocks: true, // Clear before each test
228
+ mockReset: true, // Reset before each test
229
+ restoreMocks: true, // Restore after each test
230
+ unstubEnvs: true, // Restore env vars
231
+ unstubGlobals: true, // Restore globals
232
+ },
233
+ })
234
+ ```
235
+
236
+ ## Hoisted Variables for Mocks
237
+
238
+ ```ts
239
+ const mockFn = vi.hoisted(() => vi.fn())
240
+
241
+ vi.mock('./module', () => ({
242
+ getData: mockFn,
243
+ }))
244
+
245
+ import { getData } from './module'
246
+
247
+ test('hoisted mock', () => {
248
+ mockFn.mockReturnValue('test')
249
+ expect(getData()).toBe('test')
250
+ })
251
+ ```
252
+
253
+ ## Key Points
254
+
255
+ - `vi.mock` is hoisted - called before imports
256
+ - Use `vi.doMock` for dynamic, non-hoisted mocking
257
+ - Always restore mocks to avoid test pollution
258
+ - Use `{ spy: true }` to keep implementation but track calls
259
+ - `vi.hoisted` lets you reference variables in mock factories
260
+
261
+ <!--
262
+ Source references:
263
+ - https://vitest.dev/guide/mocking.html
264
+ - https://vitest.dev/api/vi.html
265
+ -->