@martinffx/atelier 1.4.0 → 3.0.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 (93) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +95 -220
  3. package/agents/architect.md +6 -6
  4. package/agents/oracle.md +1 -1
  5. package/agents/{recon.md → sentinel.md} +3 -3
  6. package/dist/atelier.js +167 -26
  7. package/package.json +2 -1
  8. package/skills/atelier-orchestrator/SKILL.md +180 -0
  9. package/skills/atelier-setup/SKILL.md +80 -0
  10. package/skills/code-review/SKILL.md +2 -2
  11. package/skills/code-review/references/reviewers.md +3 -3
  12. package/skills/code-review/references/rq.md +9 -9
  13. package/skills/code-subagents/SKILL.md +44 -75
  14. package/skills/code-subagents/references/batch-reviewer-prompt.md +44 -0
  15. package/skills/code-subagents/references/implementor-prompt.md +10 -11
  16. package/skills/spec-brainstorm/SKILL.md +21 -16
  17. package/skills/spec-finish/SKILL.md +14 -14
  18. package/skills/spec-implement/SKILL.md +42 -42
  19. package/skills/spec-plan/SKILL.md +72 -26
  20. package/skills/spec-plan/references/plan_template.md +77 -0
  21. package/skills/code-subagents/references/code-quality-reviewer-prompt.md +0 -48
  22. package/skills/code-subagents/references/spec-reviewer-prompt.md +0 -62
  23. package/skills/python-architecture/SKILL.md +0 -148
  24. package/skills/python-architecture/references/data-modeling.md +0 -558
  25. package/skills/python-architecture/references/ddd.md +0 -569
  26. package/skills/python-architecture/references/functional-core.md +0 -337
  27. package/skills/python-build-tools/SKILL.md +0 -153
  28. package/skills/python-build-tools/references/basedpyright.md +0 -321
  29. package/skills/python-build-tools/references/ruff.md +0 -225
  30. package/skills/python-build-tools/references/uv.md +0 -257
  31. package/skills/python-fastapi/SKILL.md +0 -184
  32. package/skills/python-fastapi/references/api-design.md +0 -563
  33. package/skills/python-fastapi/references/dependencies.md +0 -479
  34. package/skills/python-fastapi/references/middleware.md +0 -475
  35. package/skills/python-fastapi/references/validation.md +0 -497
  36. package/skills/python-modern-python/SKILL.md +0 -201
  37. package/skills/python-modern-python/references/async.md +0 -76
  38. package/skills/python-modern-python/references/pattern-matching.md +0 -89
  39. package/skills/python-modern-python/references/typing.md +0 -96
  40. package/skills/python-monorepo/SKILL.md +0 -146
  41. package/skills/python-monorepo/references/docker.md +0 -515
  42. package/skills/python-monorepo/references/namespace-packages.md +0 -426
  43. package/skills/python-monorepo/references/workspace-config.md +0 -341
  44. package/skills/python-sqlalchemy/SKILL.md +0 -119
  45. package/skills/python-sqlalchemy/references/async.md +0 -51
  46. package/skills/python-sqlalchemy/references/models.md +0 -67
  47. package/skills/python-sqlalchemy/references/queries.md +0 -57
  48. package/skills/python-temporal/SKILL.md +0 -128
  49. package/skills/python-temporal/references/patterns.md +0 -87
  50. package/skills/python-temporal/references/testing.md +0 -54
  51. package/skills/python-testing/SKILL.md +0 -161
  52. package/skills/python-testing/references/boundaries.md +0 -449
  53. package/skills/python-testing/references/mocking.md +0 -449
  54. package/skills/python-testing/references/pytest.md +0 -524
  55. package/skills/spec-orchestrator/SKILL.md +0 -145
  56. package/skills/typescript-api-design/SKILL.md +0 -396
  57. package/skills/typescript-api-design/references/error-responses.md +0 -469
  58. package/skills/typescript-build-tools/SKILL.md +0 -447
  59. package/skills/typescript-build-tools/references/biome.md +0 -436
  60. package/skills/typescript-build-tools/references/bun.md +0 -432
  61. package/skills/typescript-build-tools/references/turborepo.md +0 -426
  62. package/skills/typescript-build-tools/references/vitest.md +0 -518
  63. package/skills/typescript-drizzle-orm/SKILL.md +0 -398
  64. package/skills/typescript-drizzle-orm/references/cloudflare.md +0 -392
  65. package/skills/typescript-drizzle-orm/references/entity-pattern.md +0 -412
  66. package/skills/typescript-drizzle-orm/references/postgresql.md +0 -191
  67. package/skills/typescript-drizzle-orm/references/repository-pattern.md +0 -479
  68. package/skills/typescript-drizzle-orm/references/sqlite.md +0 -291
  69. package/skills/typescript-dynamodb-toolbox/SKILL.md +0 -370
  70. package/skills/typescript-dynamodb-toolbox/references/entity-layer.md +0 -574
  71. package/skills/typescript-dynamodb-toolbox/references/error-handling.md +0 -495
  72. package/skills/typescript-dynamodb-toolbox/references/modeling.md +0 -332
  73. package/skills/typescript-dynamodb-toolbox/references/repository-layer.md +0 -631
  74. package/skills/typescript-dynamodb-toolbox/references/testing.md +0 -718
  75. package/skills/typescript-dynamodb-toolbox/references/transactions.md +0 -423
  76. package/skills/typescript-effect-ts/SKILL.md +0 -341
  77. package/skills/typescript-effect-ts/references/core.md +0 -412
  78. package/skills/typescript-effect-ts/references/error-handling.md +0 -468
  79. package/skills/typescript-effect-ts/references/resources.md +0 -476
  80. package/skills/typescript-effect-ts/references/schema.md +0 -536
  81. package/skills/typescript-effect-ts/references/services.md +0 -461
  82. package/skills/typescript-fastify/SKILL.md +0 -405
  83. package/skills/typescript-fastify/references/plugins.md +0 -329
  84. package/skills/typescript-fastify/references/typeid.md +0 -315
  85. package/skills/typescript-functional-patterns/SKILL.md +0 -402
  86. package/skills/typescript-functional-patterns/references/adts.md +0 -497
  87. package/skills/typescript-functional-patterns/references/branded-types.md +0 -542
  88. package/skills/typescript-functional-patterns/references/migration-guide.md +0 -695
  89. package/skills/typescript-functional-patterns/references/option-result.md +0 -585
  90. package/skills/typescript-testing/SKILL.md +0 -353
  91. package/skills/typescript-testing/references/mocking.md +0 -675
  92. package/skills/typescript-testing/references/msw.md +0 -852
  93. package/skills/typescript-testing/references/snapshot-testing.md +0 -774
@@ -1,353 +0,0 @@
1
- ---
2
- name: typescript-testing
3
- description: TypeScript testing patterns with Vitest and MSW. Use when writing unit tests, mocking APIs, creating typed mocks for dependency injection, or using snapshot testing.
4
- user-invocable: false
5
- ---
6
-
7
- # TypeScript Testing Patterns
8
-
9
- Comprehensive testing patterns using Vitest for unit testing, MSW for API mocking, and snapshot testing for complex object validation.
10
-
11
- ## Quick Start
12
-
13
- ### Installation
14
-
15
- ```bash
16
- # Core testing dependencies
17
- bun add -d vitest @vitest/ui
18
-
19
- # MSW for API mocking
20
- bun add -d msw
21
-
22
- # Optional: coverage reporting
23
- bun add -d @vitest/coverage-v8
24
- ```
25
-
26
- ### Basic Test Structure
27
-
28
- ```typescript
29
- import { describe, it, expect, vi, beforeEach } from 'vitest'
30
-
31
- describe('UserService', () => {
32
- beforeEach(() => {
33
- vi.clearAllMocks()
34
- })
35
-
36
- it('creates user with valid data', async () => {
37
- const result = await userService.create({ name: 'Alice' })
38
- expect(result).toMatchObject({ name: 'Alice' })
39
- })
40
- })
41
- ```
42
-
43
- ## Typed Mock Objects
44
-
45
- Create type-safe mocks for dependency injection using `vi.mocked()`:
46
-
47
- ```typescript
48
- import { vi } from 'vitest'
49
- import type { UserRepository } from './user-repository'
50
-
51
- // Mock the entire module
52
- vi.mock('./user-repository')
53
-
54
- // Get typed mock instance
55
- const mockUserRepo = vi.mocked<UserRepository>({
56
- findById: vi.fn(),
57
- save: vi.fn(),
58
- delete: vi.fn(),
59
- })
60
-
61
- // Type-safe mock return values
62
- mockUserRepo.findById.mockResolvedValue({
63
- id: '123',
64
- name: 'Alice',
65
- email: 'alice@example.com',
66
- })
67
-
68
- // Assertions with full type safety
69
- expect(mockUserRepo.findById).toHaveBeenCalledWith('123')
70
- ```
71
-
72
- ### Mock Return Values
73
-
74
- ```typescript
75
- // Single return value
76
- mockRepo.findById.mockResolvedValue(user)
77
-
78
- // Multiple calls, different returns
79
- mockRepo.findById
80
- .mockResolvedValueOnce(null)
81
- .mockResolvedValueOnce(user)
82
-
83
- // Conditional logic
84
- mockRepo.findById.mockImplementation(async (id) => {
85
- if (id === '123') return user
86
- return null
87
- })
88
-
89
- // Throw errors
90
- mockRepo.save.mockRejectedValue(new Error('Database error'))
91
- ```
92
-
93
- ### Spy on Real Implementations
94
-
95
- ```typescript
96
- import { vi } from 'vitest'
97
- import { emailService } from './email-service'
98
-
99
- // Spy on method without replacing it
100
- vi.spyOn(emailService, 'send')
101
-
102
- // Call real implementation
103
- await emailService.send({ to: 'alice@example.com', subject: 'Test' })
104
-
105
- // Assert it was called
106
- expect(emailService.send).toHaveBeenCalledOnce()
107
-
108
- // Temporarily override return value
109
- emailService.send.mockResolvedValueOnce({ messageId: 'test-123' })
110
- ```
111
-
112
- See [references/mocking.md](./references/mocking.md) for comprehensive mocking patterns including module mocks, class mocks, stateful handlers, and dependency injection.
113
-
114
- ## API Mocking with MSW
115
-
116
- Mock HTTP requests at the network level for integration tests:
117
-
118
- ```typescript
119
- import { http, HttpResponse } from 'msw'
120
- import { setupServer } from 'msw/node'
121
- import { afterAll, afterEach, beforeAll } from 'vitest'
122
-
123
- // Define handlers
124
- const handlers = [
125
- http.get('/api/users/:id', ({ params }) => {
126
- return HttpResponse.json({
127
- id: params.id,
128
- name: 'Alice',
129
- email: 'alice@example.com',
130
- })
131
- }),
132
-
133
- http.post('/api/users', async ({ request }) => {
134
- const body = await request.json()
135
- return HttpResponse.json({ id: '123', ...body }, { status: 201 })
136
- }),
137
- ]
138
-
139
- // Setup server
140
- const server = setupServer(...handlers)
141
-
142
- beforeAll(() => server.listen())
143
- afterEach(() => server.resetHandlers())
144
- afterAll(() => server.close())
145
- ```
146
-
147
- See [references/msw.md](./references/msw.md) for advanced MSW patterns including error simulation, delays, and per-test overrides.
148
-
149
- ## Snapshot Testing
150
-
151
- Validate complex objects and output without manual assertions:
152
-
153
- ```typescript
154
- import { it, expect } from 'vitest'
155
-
156
- it('generates correct user profile', () => {
157
- const profile = generateUserProfile(user)
158
-
159
- // Snapshot entire object
160
- expect(profile).toMatchSnapshot()
161
- })
162
-
163
- // Handle dynamic values (dates, IDs)
164
- it('creates order with timestamp', () => {
165
- const order = createOrder(items)
166
-
167
- expect(order).toMatchSnapshot({
168
- id: expect.any(String),
169
- createdAt: expect.any(Date),
170
- })
171
- })
172
-
173
- // Inline snapshots for small objects
174
- it('formats error message', () => {
175
- const error = formatError(new Error('Failed'))
176
- expect(error).toMatchInlineSnapshot(`
177
- {
178
- "message": "Failed",
179
- "code": "UNKNOWN_ERROR",
180
- }
181
- `)
182
- })
183
- ```
184
-
185
- See [references/snapshot-testing.md](./references/snapshot-testing.md) for snapshot maintenance, custom serializers, and best practices.
186
-
187
- ## Testing Async Code
188
-
189
- ```typescript
190
- // Promises
191
- it('loads user data', async () => {
192
- const user = await userService.findById('123')
193
- expect(user).toBeDefined()
194
- })
195
-
196
- // Callbacks
197
- it('calls callback on completion', () => {
198
- return new Promise<void>((resolve) => {
199
- processData(data, (result) => {
200
- expect(result).toBe(expected)
201
- resolve()
202
- })
203
- })
204
- })
205
-
206
- // Timers
207
- it('retries after delay', async () => {
208
- vi.useFakeTimers()
209
-
210
- const promise = retryOperation()
211
- vi.advanceTimersByTime(1000)
212
-
213
- const result = await promise
214
- expect(result).toBe('success')
215
-
216
- vi.useRealTimers()
217
- })
218
- ```
219
-
220
- ## Test Organization
221
-
222
- ```typescript
223
- // Group related tests
224
- describe('UserService', () => {
225
- describe('create', () => {
226
- it('succeeds with valid data', () => {})
227
- it('throws on duplicate email', () => {})
228
- })
229
-
230
- describe('update', () => {
231
- it('updates existing user', () => {})
232
- it('throws on not found', () => {})
233
- })
234
- })
235
-
236
- // Shared setup
237
- describe('authenticated requests', () => {
238
- beforeEach(() => {
239
- mockAuth.isAuthenticated.mockReturnValue(true)
240
- })
241
-
242
- it('allows user creation', () => {})
243
- it('allows user deletion', () => {})
244
- })
245
- ```
246
-
247
- ## Guidelines
248
-
249
- 1. **Test behavior, not implementation** - Focus on what the code does, not how it does it
250
- 2. **One assertion per test when possible** - Makes failures clearer and tests more focused
251
- 3. **Use typed mocks** - `vi.mocked<T>()` provides type safety for mock setup and assertions
252
- 4. **Mock at boundaries** - Mock external dependencies (APIs, databases), not internal functions
253
- 5. **Use MSW for API tests** - Mock at the network level for realistic integration tests
254
- 6. **Snapshots for complex output** - Use snapshots for large objects, explicit assertions for critical values
255
- 7. **Property matchers for dynamic values** - Handle dates, IDs, timestamps with `expect.any()`
256
- 8. **Clear test names** - Describe the scenario and expected outcome: "creates user with valid data"
257
- 9. **Setup/teardown for state** - Use `beforeEach`/`afterEach` to ensure test isolation
258
- 10. **Async/await over callbacks** - Prefer `async`/`await` for cleaner async test code
259
- 11. **Fake timers for time-based code** - Use `vi.useFakeTimers()` to control time in tests
260
- 12. **Test error cases** - Verify error handling with `expect().rejects.toThrow()`
261
-
262
- ## Related Skills
263
-
264
- - **build-tools** - Vitest configuration, test scripts, coverage setup
265
- - **api-design** - Testing REST API contracts and error responses
266
- - **fastify** - Testing Fastify routes and plugins
267
- - **drizzle-orm** - Testing database queries (use MSW or in-memory DB)
268
- - **dynamodb-toolbox** - Testing DynamoDB entities and queries
269
-
270
- ## Common Patterns
271
-
272
- ### Testing with Dependency Injection
273
-
274
- ```typescript
275
- class UserService {
276
- constructor(
277
- private repo: UserRepository,
278
- private email: EmailService,
279
- ) {}
280
-
281
- async create(data: CreateUserInput) {
282
- const user = await this.repo.save(data)
283
- await this.email.sendWelcome(user.email)
284
- return user
285
- }
286
- }
287
-
288
- // Test with mocks
289
- it('sends welcome email on create', async () => {
290
- const mockRepo = vi.mocked<UserRepository>({
291
- save: vi.fn().mockResolvedValue(savedUser),
292
- })
293
- const mockEmail = vi.mocked<EmailService>({
294
- sendWelcome: vi.fn().mockResolvedValue(undefined),
295
- })
296
-
297
- const service = new UserService(mockRepo, mockEmail)
298
- await service.create(userData)
299
-
300
- expect(mockEmail.sendWelcome).toHaveBeenCalledWith('alice@example.com')
301
- })
302
- ```
303
-
304
- ### Testing Error Boundaries
305
-
306
- ```typescript
307
- it('handles repository errors gracefully', async () => {
308
- mockRepo.save.mockRejectedValue(new Error('Database error'))
309
-
310
- await expect(
311
- service.create(userData)
312
- ).rejects.toThrow('Failed to create user')
313
-
314
- // Verify cleanup or rollback occurred
315
- expect(mockEmail.sendWelcome).not.toHaveBeenCalled()
316
- })
317
- ```
318
-
319
- ### Testing Race Conditions
320
-
321
- ```typescript
322
- it('handles concurrent requests correctly', async () => {
323
- const promises = [
324
- service.processOrder(order1),
325
- service.processOrder(order2),
326
- service.processOrder(order3),
327
- ]
328
-
329
- const results = await Promise.all(promises)
330
-
331
- expect(results).toHaveLength(3)
332
- expect(new Set(results.map(r => r.id)).size).toBe(3)
333
- })
334
- ```
335
-
336
- ## Debugging Tests
337
-
338
- ```bash
339
- # Run single test file
340
- vitest run path/to/test.spec.ts
341
-
342
- # Run tests matching pattern
343
- vitest run -t "creates user"
344
-
345
- # Watch mode for TDD
346
- vitest watch
347
-
348
- # UI mode for debugging
349
- vitest --ui
350
-
351
- # Coverage report
352
- vitest run --coverage
353
- ```