@martinffx/atelier 0.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.
- package/CHANGELOG.md +38 -0
- package/LICENSE +21 -0
- package/README.md +285 -0
- package/agents/architect.md +38 -0
- package/agents/oracle.md +40 -0
- package/agents/recon.md +39 -0
- package/dist/atelier.js +33082 -0
- package/package.json +44 -0
- package/skills/code-conventional-commit/SKILL.md +134 -0
- package/skills/code-conventional-commit/evals/evals.json +23 -0
- package/skills/code-conventional-commit/workspace/iteration-1/eval-0/with_skill/outputs/commit-message.txt +4 -0
- package/skills/code-conventional-commit/workspace/iteration-1/eval-0/with_skill/outputs/eval_metadata.json +6 -0
- package/skills/code-conventional-commit/workspace/iteration-1/eval-1/with_skill/outputs/eval_metadata.json +6 -0
- package/skills/code-conventional-commit/workspace/iteration-1/eval-1/with_skill/outputs/validation-result.txt +16 -0
- package/skills/code-conventional-commit/workspace/iteration-1/eval-2/with_skill/outputs/commit-message.txt +8 -0
- package/skills/code-conventional-commit/workspace/iteration-1/eval-2/with_skill/outputs/eval_metadata.json +6 -0
- package/skills/code-conventional-commit/workspace/iteration-1/report.html +1325 -0
- package/skills/code-debug/SKILL.md +271 -0
- package/skills/code-debug/references/language-tools.md +139 -0
- package/skills/code-debug/references/techniques.md +117 -0
- package/skills/code-docs/SKILL.md +171 -0
- package/skills/code-docs/references/api-docs.md +116 -0
- package/skills/code-docs/references/changelog.md +64 -0
- package/skills/code-docs/references/readme-structure.md +94 -0
- package/skills/code-git-worktrees/SKILL.md +218 -0
- package/skills/code-perf/SKILL.md +163 -0
- package/skills/code-perf/references/common-bottlenecks.md +124 -0
- package/skills/code-perf/references/optimization-patterns.md +167 -0
- package/skills/code-perf/references/profiling-tools.md +126 -0
- package/skills/code-review/SKILL.md +78 -0
- package/skills/code-review/references/output.md +200 -0
- package/skills/code-review/references/reviewers.md +719 -0
- package/skills/code-review/references/rq.md +357 -0
- package/skills/code-review/references/rs.md +30 -0
- package/skills/code-security/SKILL.md +183 -0
- package/skills/code-security/references/owasp-top-10.md +129 -0
- package/skills/code-security/references/security-tools.md +102 -0
- package/skills/code-security/references/vulnerability-patterns.md +129 -0
- package/skills/code-stacked-commit/SKILL.md +155 -0
- package/skills/code-subagents/SKILL.md +184 -0
- package/skills/code-subagents/references/code-quality-reviewer-prompt.md +48 -0
- package/skills/code-subagents/references/implementor-prompt.md +79 -0
- package/skills/code-subagents/references/spec-reviewer-prompt.md +62 -0
- package/skills/oracle-architect/SKILL.md +246 -0
- package/skills/oracle-architect/references/api-design.md +345 -0
- package/skills/oracle-architect/references/data-modeling.md +318 -0
- package/skills/oracle-architect/references/ddd-patterns.md +247 -0
- package/skills/oracle-challenge/SKILL.md +126 -0
- package/skills/oracle-testing/SKILL.md +237 -0
- package/skills/oracle-testing/references/anti-patterns.md +618 -0
- package/skills/oracle-testing/references/boundaries.md +579 -0
- package/skills/oracle-testing/references/core-testing.md +691 -0
- package/skills/oracle-testing/references/edge-testing.md +794 -0
- package/skills/oracle-testing/references/stub-driven-tdd.md +322 -0
- package/skills/oracle-thinkdeep/SKILL.md +164 -0
- package/skills/python-architecture/SKILL.md +148 -0
- package/skills/python-architecture/references/data-modeling.md +558 -0
- package/skills/python-architecture/references/ddd.md +569 -0
- package/skills/python-architecture/references/functional-core.md +337 -0
- package/skills/python-build-tools/SKILL.md +153 -0
- package/skills/python-build-tools/references/basedpyright.md +321 -0
- package/skills/python-build-tools/references/ruff.md +225 -0
- package/skills/python-build-tools/references/uv.md +257 -0
- package/skills/python-fastapi/SKILL.md +184 -0
- package/skills/python-fastapi/references/api-design.md +563 -0
- package/skills/python-fastapi/references/dependencies.md +479 -0
- package/skills/python-fastapi/references/middleware.md +475 -0
- package/skills/python-fastapi/references/validation.md +497 -0
- package/skills/python-modern-python/SKILL.md +201 -0
- package/skills/python-modern-python/references/async.md +76 -0
- package/skills/python-modern-python/references/pattern-matching.md +89 -0
- package/skills/python-modern-python/references/typing.md +96 -0
- package/skills/python-monorepo/SKILL.md +146 -0
- package/skills/python-monorepo/references/docker.md +515 -0
- package/skills/python-monorepo/references/namespace-packages.md +426 -0
- package/skills/python-monorepo/references/workspace-config.md +341 -0
- package/skills/python-sqlalchemy/SKILL.md +119 -0
- package/skills/python-sqlalchemy/references/async.md +51 -0
- package/skills/python-sqlalchemy/references/models.md +67 -0
- package/skills/python-sqlalchemy/references/queries.md +57 -0
- package/skills/python-temporal/SKILL.md +128 -0
- package/skills/python-temporal/references/patterns.md +87 -0
- package/skills/python-temporal/references/testing.md +54 -0
- package/skills/python-testing/SKILL.md +161 -0
- package/skills/python-testing/references/boundaries.md +449 -0
- package/skills/python-testing/references/mocking.md +449 -0
- package/skills/python-testing/references/pytest.md +524 -0
- package/skills/spec-brainstorm/SKILL.md +325 -0
- package/skills/spec-finish/SKILL.md +159 -0
- package/skills/spec-implement/SKILL.md +296 -0
- package/skills/spec-orchestrator/SKILL.md +156 -0
- package/skills/spec-plan/SKILL.md +248 -0
- package/skills/typescript-api-design/SKILL.md +396 -0
- package/skills/typescript-api-design/references/error-responses.md +469 -0
- package/skills/typescript-build-tools/SKILL.md +447 -0
- package/skills/typescript-build-tools/references/biome.md +436 -0
- package/skills/typescript-build-tools/references/bun.md +432 -0
- package/skills/typescript-build-tools/references/turborepo.md +426 -0
- package/skills/typescript-build-tools/references/vitest.md +518 -0
- package/skills/typescript-drizzle-orm/SKILL.md +398 -0
- package/skills/typescript-drizzle-orm/references/cloudflare.md +392 -0
- package/skills/typescript-drizzle-orm/references/entity-pattern.md +412 -0
- package/skills/typescript-drizzle-orm/references/postgresql.md +191 -0
- package/skills/typescript-drizzle-orm/references/repository-pattern.md +479 -0
- package/skills/typescript-drizzle-orm/references/sqlite.md +291 -0
- package/skills/typescript-dynamodb-toolbox/SKILL.md +370 -0
- package/skills/typescript-dynamodb-toolbox/references/entity-layer.md +574 -0
- package/skills/typescript-dynamodb-toolbox/references/error-handling.md +495 -0
- package/skills/typescript-dynamodb-toolbox/references/modeling.md +332 -0
- package/skills/typescript-dynamodb-toolbox/references/repository-layer.md +631 -0
- package/skills/typescript-dynamodb-toolbox/references/testing.md +718 -0
- package/skills/typescript-dynamodb-toolbox/references/transactions.md +423 -0
- package/skills/typescript-effect-ts/SKILL.md +341 -0
- package/skills/typescript-effect-ts/references/core.md +412 -0
- package/skills/typescript-effect-ts/references/error-handling.md +468 -0
- package/skills/typescript-effect-ts/references/resources.md +476 -0
- package/skills/typescript-effect-ts/references/schema.md +536 -0
- package/skills/typescript-effect-ts/references/services.md +461 -0
- package/skills/typescript-fastify/SKILL.md +405 -0
- package/skills/typescript-fastify/references/plugins.md +329 -0
- package/skills/typescript-fastify/references/typeid.md +315 -0
- package/skills/typescript-functional-patterns/SKILL.md +402 -0
- package/skills/typescript-functional-patterns/references/adts.md +497 -0
- package/skills/typescript-functional-patterns/references/branded-types.md +542 -0
- package/skills/typescript-functional-patterns/references/migration-guide.md +695 -0
- package/skills/typescript-functional-patterns/references/option-result.md +585 -0
- package/skills/typescript-testing/SKILL.md +353 -0
- package/skills/typescript-testing/references/mocking.md +675 -0
- package/skills/typescript-testing/references/msw.md +852 -0
- package/skills/typescript-testing/references/snapshot-testing.md +774 -0
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
# Stub-Driven TDD Workflow
|
|
2
|
+
|
|
3
|
+
Complete workflow examples showing the Stub → Test → Implement → Refactor pattern.
|
|
4
|
+
|
|
5
|
+
## The Four-Step Pattern
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
1. Stub → Create minimal interface/function signatures
|
|
9
|
+
2. Test → Write tests against stubs
|
|
10
|
+
3. Implement → Make tests pass with real implementation
|
|
11
|
+
4. Refactor → Improve code while keeping tests green
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Why Stub-Driven?
|
|
15
|
+
|
|
16
|
+
**Traditional TDD problem:** Can't write tests until implementation exists
|
|
17
|
+
|
|
18
|
+
**Stub-Driven solution:** Write interface/type signatures first, test against those, then implement
|
|
19
|
+
|
|
20
|
+
**Benefits:**
|
|
21
|
+
- Tests define behavior before implementation
|
|
22
|
+
- Interfaces emerge from use cases, not speculation
|
|
23
|
+
- Refactoring is safe (tests validate behavior)
|
|
24
|
+
- Fast feedback loop (stub → test → implement)
|
|
25
|
+
|
|
26
|
+
## Complete Order Service Example
|
|
27
|
+
|
|
28
|
+
### Step 1: Stub
|
|
29
|
+
|
|
30
|
+
Define the interface and service class with stub methods:
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
// Define repository interface from use case
|
|
34
|
+
interface OrderRepository {
|
|
35
|
+
save(order: OrderRecord): Promise<OrderRecord>;
|
|
36
|
+
findById(id: string): Promise<OrderRecord | null>;
|
|
37
|
+
delete(id: string): Promise<void>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Service uses stub - methods throw NotImplemented
|
|
41
|
+
class OrderService {
|
|
42
|
+
constructor(private repo: OrderRepository) {}
|
|
43
|
+
|
|
44
|
+
async createOrder(request: CreateOrderRequest): Promise<Result<Order>> {
|
|
45
|
+
throw new Error('Not implemented');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async cancelOrder(id: string): Promise<Result<void>> {
|
|
49
|
+
throw new Error('Not implemented');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async getOrder(id: string): Promise<Result<Order>> {
|
|
53
|
+
throw new Error('Not implemented');
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Export for testing
|
|
58
|
+
export { OrderService, OrderRepository };
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Step 2: Test
|
|
62
|
+
|
|
63
|
+
Write comprehensive tests against the stubs:
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
67
|
+
import { OrderService, OrderRepository } from './order-service';
|
|
68
|
+
import { CreateOrderRequest, OrderRecord, Order } from './order';
|
|
69
|
+
import { Ok, Err } from './result';
|
|
70
|
+
|
|
71
|
+
describe('OrderService', () => {
|
|
72
|
+
let service: OrderService;
|
|
73
|
+
let mockRepo: OrderRepository;
|
|
74
|
+
|
|
75
|
+
beforeEach(() => {
|
|
76
|
+
// Create stub implementation
|
|
77
|
+
mockRepo = {
|
|
78
|
+
save: vi.fn(),
|
|
79
|
+
findById: vi.fn(),
|
|
80
|
+
delete: vi.fn()
|
|
81
|
+
};
|
|
82
|
+
service = new OrderService(mockRepo);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
describe('createOrder', () => {
|
|
86
|
+
it('should save valid order', async () => {
|
|
87
|
+
mockRepo.save.mockResolvedValue({
|
|
88
|
+
id: '123',
|
|
89
|
+
customer_id: 'C1',
|
|
90
|
+
items: '[]',
|
|
91
|
+
status: 'pending',
|
|
92
|
+
total: 0
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
const result = await service.createOrder({
|
|
96
|
+
customerId: 'C1',
|
|
97
|
+
items: [{ productId: 'P1', quantity: 2, price: 10 }]
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
expect(result.ok).toBe(true);
|
|
101
|
+
expect(mockRepo.save).toHaveBeenCalledWith(
|
|
102
|
+
expect.objectContaining({
|
|
103
|
+
customer_id: 'C1',
|
|
104
|
+
status: 'pending'
|
|
105
|
+
})
|
|
106
|
+
);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('should validate order before saving', async () => {
|
|
110
|
+
const result = await service.createOrder({
|
|
111
|
+
customerId: 'C1',
|
|
112
|
+
items: [] // Invalid: empty items
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
expect(result.ok).toBe(false);
|
|
116
|
+
expect(mockRepo.save).not.toHaveBeenCalled();
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it('should calculate total correctly', async () => {
|
|
120
|
+
mockRepo.save.mockResolvedValue({
|
|
121
|
+
id: '123',
|
|
122
|
+
customer_id: 'C1',
|
|
123
|
+
items: '[]',
|
|
124
|
+
status: 'pending',
|
|
125
|
+
total: 0
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
await service.createOrder({
|
|
129
|
+
customerId: 'C1',
|
|
130
|
+
items: [
|
|
131
|
+
{ productId: 'P1', quantity: 2, price: 10 },
|
|
132
|
+
{ productId: 'P2', quantity: 1, price: 15 }
|
|
133
|
+
]
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
expect(mockRepo.save).toHaveBeenCalledWith(
|
|
137
|
+
expect.objectContaining({ total: 35 })
|
|
138
|
+
);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
describe('cancelOrder', () => {
|
|
143
|
+
it('should cancel pending order', async () => {
|
|
144
|
+
mockRepo.findById.mockResolvedValue({
|
|
145
|
+
id: '123',
|
|
146
|
+
customer_id: 'C1',
|
|
147
|
+
items: '[]',
|
|
148
|
+
status: 'pending',
|
|
149
|
+
total: 0
|
|
150
|
+
});
|
|
151
|
+
mockRepo.delete.mockResolvedValue(undefined);
|
|
152
|
+
|
|
153
|
+
const result = await service.cancelOrder('123');
|
|
154
|
+
|
|
155
|
+
expect(result.ok).toBe(true);
|
|
156
|
+
expect(mockRepo.delete).toHaveBeenCalledWith('123');
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it('should reject canceling shipped order', async () => {
|
|
160
|
+
mockRepo.findById.mockResolvedValue({
|
|
161
|
+
id: '123',
|
|
162
|
+
customer_id: 'C1',
|
|
163
|
+
items: '[]',
|
|
164
|
+
status: 'shipped',
|
|
165
|
+
total: 0
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
const result = await service.cancelOrder('123');
|
|
169
|
+
|
|
170
|
+
expect(result.ok).toBe(false);
|
|
171
|
+
expect(mockRepo.delete).not.toHaveBeenCalled();
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it('should reject canceling non-existent order', async () => {
|
|
175
|
+
mockRepo.findById.mockResolvedValue(null);
|
|
176
|
+
|
|
177
|
+
const result = await service.cancelOrder('999');
|
|
178
|
+
|
|
179
|
+
expect(result.ok).toBe(false);
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
describe('getOrder', () => {
|
|
184
|
+
it('should retrieve order by id', async () => {
|
|
185
|
+
mockRepo.findById.mockResolvedValue({
|
|
186
|
+
id: '123',
|
|
187
|
+
customer_id: 'C1',
|
|
188
|
+
items: '[]',
|
|
189
|
+
status: 'pending',
|
|
190
|
+
total: 0
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
const result = await service.getOrder('123');
|
|
194
|
+
|
|
195
|
+
expect(result.ok).toBe(true);
|
|
196
|
+
if (result.ok) {
|
|
197
|
+
expect(result.value.id).toBe('123');
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it('should return error for non-existent order', async () => {
|
|
202
|
+
mockRepo.findById.mockResolvedValue(null);
|
|
203
|
+
|
|
204
|
+
const result = await service.getOrder('999');
|
|
205
|
+
|
|
206
|
+
expect(result.ok).toBe(false);
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Step 3: Implement
|
|
213
|
+
|
|
214
|
+
Make tests pass with real implementation:
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
class OrderService {
|
|
218
|
+
constructor(private repo: OrderRepository) {}
|
|
219
|
+
|
|
220
|
+
async createOrder(request: CreateOrderRequest): Promise<Result<Order>> {
|
|
221
|
+
// Transform request to entity
|
|
222
|
+
const order = Order.fromRequest(request);
|
|
223
|
+
|
|
224
|
+
// Validate
|
|
225
|
+
const validation = order.validate();
|
|
226
|
+
if (!validation.ok) return validation;
|
|
227
|
+
|
|
228
|
+
// Save to repository
|
|
229
|
+
const record = order.toRecord();
|
|
230
|
+
const saved = await this.repo.save(record);
|
|
231
|
+
|
|
232
|
+
// Transform back to entity
|
|
233
|
+
return Ok(Order.fromRecord(saved));
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
async cancelOrder(id: string): Promise<Result<void>> {
|
|
237
|
+
// Find order
|
|
238
|
+
const record = await this.repo.findById(id);
|
|
239
|
+
if (!record) return Err('Order not found');
|
|
240
|
+
|
|
241
|
+
// Transform to entity
|
|
242
|
+
const order = Order.fromRecord(record);
|
|
243
|
+
|
|
244
|
+
// Check business rule
|
|
245
|
+
if (!order.canCancel()) {
|
|
246
|
+
return Err(`Cannot cancel ${order.status} order`);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Delete
|
|
250
|
+
await this.repo.delete(id);
|
|
251
|
+
return Ok(undefined);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
async getOrder(id: string): Promise<Result<Order>> {
|
|
255
|
+
// Find order
|
|
256
|
+
const record = await this.repo.findById(id);
|
|
257
|
+
if (!record) return Err('Order not found');
|
|
258
|
+
|
|
259
|
+
// Transform to entity
|
|
260
|
+
return Ok(Order.fromRecord(record));
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Step 4: Refactor
|
|
266
|
+
|
|
267
|
+
Improve code while keeping tests green:
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
class OrderService {
|
|
271
|
+
constructor(private repo: OrderRepository) {}
|
|
272
|
+
|
|
273
|
+
async createOrder(request: CreateOrderRequest): Promise<Result<Order>> {
|
|
274
|
+
const order = Order.fromRequest(request);
|
|
275
|
+
return await this.validateAndSave(order);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
async cancelOrder(id: string): Promise<Result<void>> {
|
|
279
|
+
const order = await this.findOrderOrError(id);
|
|
280
|
+
if (!order.ok) return order;
|
|
281
|
+
|
|
282
|
+
return await this.checkCancellableAndDelete(order.value);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
async getOrder(id: string): Promise<Result<Order>> {
|
|
286
|
+
return await this.findOrderOrError(id);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
private async validateAndSave(order: Order): Promise<Result<Order>> {
|
|
290
|
+
const validation = order.validate();
|
|
291
|
+
if (!validation.ok) return validation;
|
|
292
|
+
|
|
293
|
+
const record = order.toRecord();
|
|
294
|
+
const saved = await this.repo.save(record);
|
|
295
|
+
return Ok(Order.fromRecord(saved));
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
private async findOrderOrError(id: string): Promise<Result<Order>> {
|
|
299
|
+
const record = await this.repo.findById(id);
|
|
300
|
+
if (!record) return Err('Order not found');
|
|
301
|
+
return Ok(Order.fromRecord(record));
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
private async checkCancellableAndDelete(order: Order): Promise<Result<void>> {
|
|
305
|
+
if (!order.canCancel()) {
|
|
306
|
+
return Err(`Cannot cancel ${order.status} order`);
|
|
307
|
+
}
|
|
308
|
+
await this.repo.delete(order.id);
|
|
309
|
+
return Ok(undefined);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
All tests still pass after refactoring - behavior is unchanged, only implementation improved.
|
|
315
|
+
|
|
316
|
+
## Key Takeaways
|
|
317
|
+
|
|
318
|
+
1. **Start with stubs** - Define interfaces before implementation
|
|
319
|
+
2. **Test against contracts** - Test the interface, not the implementation
|
|
320
|
+
3. **Implement once tests are clear** - Make tests pass with real code
|
|
321
|
+
4. **Refactor with confidence** - Tests validate behavior doesn't change
|
|
322
|
+
5. **Keep feedback loop fast** - Each step is quick and focused
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: oracle-thinkdeep
|
|
3
|
+
description: Extended reasoning analysis using sequential thinking. Use for deep exploration, comprehensive analysis, complex decisions, or when you need fresh perspectives on difficult problems.
|
|
4
|
+
user-invocable: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# ThinkDeep: Extended Reasoning Analysis
|
|
8
|
+
|
|
9
|
+
## Step 1: Parse Request Parameters
|
|
10
|
+
|
|
11
|
+
<strategist>
|
|
12
|
+
@agent-oracle
|
|
13
|
+
|
|
14
|
+
Analyze the thinkdeep request: $ARGUMENTS
|
|
15
|
+
|
|
16
|
+
**Parameter Extraction:**
|
|
17
|
+
- **Main prompt**: [extract core thinking request]
|
|
18
|
+
- **Focus areas**: [extract "architecture, performance, security" etc]
|
|
19
|
+
- **File references**: [extract "reference to file.py" patterns]
|
|
20
|
+
- **Problem context**: [extract additional context provided]
|
|
21
|
+
|
|
22
|
+
**Parsed Configuration:**
|
|
23
|
+
- Prompt: [core request]
|
|
24
|
+
- Focus areas: [identified areas]
|
|
25
|
+
- File references: [any files mentioned]
|
|
26
|
+
- Problem context: [additional context]
|
|
27
|
+
</strategist>
|
|
28
|
+
|
|
29
|
+
## Step 2: Deep Sequential Analysis
|
|
30
|
+
|
|
31
|
+
<strategist>
|
|
32
|
+
@agent-oracle
|
|
33
|
+
|
|
34
|
+
Use sequential thinking (mcp__sequential-thinking__sequentialthinking) for extended reasoning:
|
|
35
|
+
|
|
36
|
+
### Thought 1: Context Understanding
|
|
37
|
+
Analyze the current session context to understand:
|
|
38
|
+
- What has been discussed so far
|
|
39
|
+
- Previous decisions and analyses made
|
|
40
|
+
- User's specific constraints and goals
|
|
41
|
+
- Existing solutions or approaches tried
|
|
42
|
+
|
|
43
|
+
### Thought 2: Problem Decomposition
|
|
44
|
+
Break down the core issue into:
|
|
45
|
+
- Primary problem statement
|
|
46
|
+
- Key sub-problems or components
|
|
47
|
+
- Underlying assumptions and constraints
|
|
48
|
+
- Success criteria and desired outcomes
|
|
49
|
+
|
|
50
|
+
### Thought 3: Assumption Challenge
|
|
51
|
+
Question the underlying assumptions:
|
|
52
|
+
- What assumptions are we making?
|
|
53
|
+
- Are these assumptions valid in this context?
|
|
54
|
+
- What if the opposite were true?
|
|
55
|
+
- Alternative perspectives to consider
|
|
56
|
+
|
|
57
|
+
### Thought 4: Alternative Approaches Exploration
|
|
58
|
+
Explore different solution paths:
|
|
59
|
+
- Conventional approaches and their pros/cons
|
|
60
|
+
- Unconventional or innovative solutions
|
|
61
|
+
- Trade-offs between different options
|
|
62
|
+
- Hybrid or combined approaches
|
|
63
|
+
|
|
64
|
+
### Thought 5: Context Integration
|
|
65
|
+
Incorporate relevant context:
|
|
66
|
+
- File references and code patterns
|
|
67
|
+
- Previous session insights
|
|
68
|
+
- User's specific technical stack
|
|
69
|
+
- Business or project constraints
|
|
70
|
+
|
|
71
|
+
### Thought 6: Edge Case Analysis
|
|
72
|
+
Identify potential issues:
|
|
73
|
+
- What could go wrong with each approach?
|
|
74
|
+
- Edge cases and failure modes
|
|
75
|
+
- Scalability and performance concerns
|
|
76
|
+
- Security and maintenance implications
|
|
77
|
+
|
|
78
|
+
### Thought 7: Risk Assessment
|
|
79
|
+
Evaluate risks for each option:
|
|
80
|
+
- Implementation complexity
|
|
81
|
+
- Technical debt potential
|
|
82
|
+
- Team skill requirements
|
|
83
|
+
- Timeline and resource impacts
|
|
84
|
+
|
|
85
|
+
### Thought 8: Solution Synthesis
|
|
86
|
+
Combine insights into recommendations:
|
|
87
|
+
- Primary recommended approach
|
|
88
|
+
- Backup or alternative options
|
|
89
|
+
- Implementation considerations
|
|
90
|
+
- Next steps and validation points
|
|
91
|
+
|
|
92
|
+
Continue sequential thinking until satisfaction, using:
|
|
93
|
+
- `isRevision: true` to refine previous thoughts
|
|
94
|
+
- `branchFromThought` to explore alternative reasoning paths
|
|
95
|
+
- `needsMoreThoughts: true` to extend analysis if needed
|
|
96
|
+
</strategist>
|
|
97
|
+
|
|
98
|
+
## Step 3: Critical Evaluation & Synthesis
|
|
99
|
+
|
|
100
|
+
**Self-Critique Questions:**
|
|
101
|
+
- Does the analysis address the user's specific context?
|
|
102
|
+
- Are the recommendations practical and implementable?
|
|
103
|
+
- Have we considered the most important constraints?
|
|
104
|
+
- Are there any blind spots or missing perspectives?
|
|
105
|
+
|
|
106
|
+
**Contextual Validation:**
|
|
107
|
+
- Fit with user's technical stack and preferences
|
|
108
|
+
- Alignment with previous decisions in session
|
|
109
|
+
- Practicality given team skills and resources
|
|
110
|
+
- Integration with existing systems or patterns
|
|
111
|
+
|
|
112
|
+
**Final Synthesis:**
|
|
113
|
+
- **Primary Recommendation**: [best approach with rationale]
|
|
114
|
+
- **Alternative Options**: [backup plans with trade-offs]
|
|
115
|
+
- **Implementation Guidance**: [key considerations and next steps]
|
|
116
|
+
- **Risk Mitigation**: [how to address identified concerns]
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Usage Examples
|
|
121
|
+
|
|
122
|
+
**Basic deep analysis:**
|
|
123
|
+
```
|
|
124
|
+
/atelier-thinkdeep "Analyze my authentication architecture"
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**With file references:**
|
|
128
|
+
```
|
|
129
|
+
/atelier-thinkdeep "Evaluate my database schema with reference to models/user.py"
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**With focus areas:**
|
|
133
|
+
```
|
|
134
|
+
/atelier-thinkdeep "Assess my microservices design focusing on performance and security"
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Complex architectural decisions:**
|
|
138
|
+
```
|
|
139
|
+
/atelier-thinkdeep "Should I use GraphQL or REST for my API considering team skills and scalability needs"
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## When to Use ThinkDeep
|
|
143
|
+
|
|
144
|
+
- **Architecture decisions**: When choosing between major design approaches
|
|
145
|
+
- **Complex problem solving**: Multi-faceted issues requiring deep analysis
|
|
146
|
+
- **Assumption validation**: Challenging conventional wisdom or previous decisions
|
|
147
|
+
- **Alternative exploration**: When stuck and need fresh perspectives
|
|
148
|
+
- **Risk assessment**: Before major implementation decisions
|
|
149
|
+
|
|
150
|
+
## ThinkDeep vs Challenge
|
|
151
|
+
|
|
152
|
+
**Use /atelier-thinkdeep**: Deep exploration, comprehensive analysis, alternative discovery, complex decisions
|
|
153
|
+
**Use /atelier-challenge**: Question assumptions, test validity, assess risks, prevent automatic agreement
|
|
154
|
+
|
|
155
|
+
**Key distinction**: ThinkDeep = deep exploration, Challenge = critical evaluation
|
|
156
|
+
|
|
157
|
+
## Expected Outcomes
|
|
158
|
+
|
|
159
|
+
After using this command:
|
|
160
|
+
- Comprehensive understanding of the problem space
|
|
161
|
+
- Multiple approaches evaluated with trade-offs
|
|
162
|
+
- Clear recommendation with solid reasoning
|
|
163
|
+
- Risk assessment and mitigation strategies
|
|
164
|
+
- Actionable next steps for implementation
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: python-architecture
|
|
3
|
+
description: Python application architecture with functional core, effectful shell, DDD, and data modeling. Use when designing application layers, separating pure business logic from IO, defining domain models, implementing validation, or structuring bounded contexts.
|
|
4
|
+
user-invocable: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Python Application Architecture
|
|
8
|
+
|
|
9
|
+
Modern Python application architecture following functional core / imperative shell pattern, Domain-Driven Design, and type-safe data modeling.
|
|
10
|
+
|
|
11
|
+
## Core Principle: Functional Core / Imperative Shell
|
|
12
|
+
|
|
13
|
+
Separate pure business logic from side effects:
|
|
14
|
+
|
|
15
|
+
- **Functional Core**: Pure functions, business logic, no IO
|
|
16
|
+
- **Imperative Shell**: Coordinates external dependencies, handles side effects
|
|
17
|
+
|
|
18
|
+
See [references/functional-core.md](references/functional-core.md) for detailed patterns and examples.
|
|
19
|
+
|
|
20
|
+
## Layered Architecture
|
|
21
|
+
|
|
22
|
+
Follow bottom-up dependency flow:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
Router/Handler → Service → Repository → Entity → Database
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Each layer depends only on layers below.
|
|
29
|
+
|
|
30
|
+
**Responsibilities:**
|
|
31
|
+
- **Entity**: Domain models, validation, business rules, data transformations (fromRequest, toRecord, toResponse)
|
|
32
|
+
- **Repository**: Abstract storage interface, returns domain entities
|
|
33
|
+
- **Service**: Business workflows, orchestrates entities and repositories
|
|
34
|
+
- **Router/Handler**: HTTP handling, delegates to services
|
|
35
|
+
|
|
36
|
+
## Domain Models
|
|
37
|
+
|
|
38
|
+
### Entity Example
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
from dataclasses import dataclass
|
|
42
|
+
from uuid import UUID
|
|
43
|
+
from decimal import Decimal
|
|
44
|
+
|
|
45
|
+
@dataclass
|
|
46
|
+
class Order:
|
|
47
|
+
"""Entity - has identity and encapsulated behavior"""
|
|
48
|
+
id: UUID
|
|
49
|
+
customer_id: UUID
|
|
50
|
+
total: Decimal
|
|
51
|
+
status: str
|
|
52
|
+
|
|
53
|
+
def apply_discount(self, rate: Decimal) -> None:
|
|
54
|
+
"""Business rule - encapsulated in entity"""
|
|
55
|
+
if self.status == "pending":
|
|
56
|
+
self.total = self.total * (1 - rate)
|
|
57
|
+
|
|
58
|
+
@classmethod
|
|
59
|
+
def from_request(cls, req, customer_id: UUID) -> "Order":
|
|
60
|
+
"""Transform API request → entity"""
|
|
61
|
+
return cls(id=uuid4(), customer_id=customer_id, total=Decimal("0"), status="pending")
|
|
62
|
+
|
|
63
|
+
def to_response(self):
|
|
64
|
+
"""Transform entity → API response"""
|
|
65
|
+
return {"id": self.id, "total": self.total, "status": self.status}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Value Object Example
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
from dataclasses import dataclass
|
|
72
|
+
|
|
73
|
+
@dataclass(frozen=True)
|
|
74
|
+
class Money:
|
|
75
|
+
"""Value object - immutable, no identity"""
|
|
76
|
+
amount: Decimal
|
|
77
|
+
currency: str
|
|
78
|
+
|
|
79
|
+
def add(self, other: "Money") -> "Money":
|
|
80
|
+
if self.currency != other.currency:
|
|
81
|
+
raise ValueError("Cannot add different currencies")
|
|
82
|
+
return Money(self.amount + other.amount, self.currency)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
See [references/ddd.md](references/ddd.md) for aggregates, bounded contexts, and domain services.
|
|
86
|
+
|
|
87
|
+
## Repository Pattern
|
|
88
|
+
|
|
89
|
+
Abstract storage behind interface:
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
from abc import ABC, abstractmethod
|
|
93
|
+
from typing import Optional
|
|
94
|
+
|
|
95
|
+
class OrderRepository(ABC):
|
|
96
|
+
"""Abstract repository - interface only"""
|
|
97
|
+
|
|
98
|
+
@abstractmethod
|
|
99
|
+
def get(self, order_id: UUID) -> Optional[Order]:
|
|
100
|
+
pass
|
|
101
|
+
|
|
102
|
+
@abstractmethod
|
|
103
|
+
def save(self, order: Order) -> None:
|
|
104
|
+
pass
|
|
105
|
+
|
|
106
|
+
class PostgresOrderRepository(OrderRepository):
|
|
107
|
+
"""Concrete implementation"""
|
|
108
|
+
|
|
109
|
+
def get(self, order_id: UUID) -> Optional[Order]:
|
|
110
|
+
record = self.session.get(OrderRecord, order_id)
|
|
111
|
+
return Order.from_record(record) if record else None
|
|
112
|
+
|
|
113
|
+
def save(self, order: Order) -> None:
|
|
114
|
+
record = order.to_record()
|
|
115
|
+
self.session.merge(record)
|
|
116
|
+
self.session.commit()
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Data Modeling
|
|
120
|
+
|
|
121
|
+
- **dataclasses**: Domain models and internal logic (lightweight, standard library)
|
|
122
|
+
- **Pydantic**: API boundaries (validation, JSON schema, OpenAPI)
|
|
123
|
+
- **Entity transformations**: `from_request()`, `to_response()`, `from_record()`, `to_record()`
|
|
124
|
+
|
|
125
|
+
See [references/data-modeling.md](references/data-modeling.md) for validation patterns, Pydantic features, and transformation examples.
|
|
126
|
+
|
|
127
|
+
## Best Practices
|
|
128
|
+
|
|
129
|
+
1. **Pure functions first** - Write business logic without IO dependencies
|
|
130
|
+
2. **Entity encapsulation** - Keep business rules inside entities
|
|
131
|
+
3. **Repository abstraction** - Hide storage details, work with domain entities
|
|
132
|
+
4. **Validate at boundaries** - Use Pydantic at API edges, simple validation in entities
|
|
133
|
+
5. **Immutable value objects** - Always use `frozen=True`
|
|
134
|
+
6. **Single Responsibility** - Each layer has one reason to change
|
|
135
|
+
7. **Dependency direction** - Always depend on abstractions, not implementations
|
|
136
|
+
|
|
137
|
+
## Anti-Patterns
|
|
138
|
+
|
|
139
|
+
❌ **Anemic Domain Model** - Entities with only getters/setters, all logic in services
|
|
140
|
+
❌ **Transaction Script** - All logic in service layer, entities just data
|
|
141
|
+
❌ **Leaky Abstraction** - Repository exposing database details
|
|
142
|
+
❌ **God Object** - Entity with too many responsibilities
|
|
143
|
+
❌ **Mixed Concerns** - Business logic calling IO directly
|
|
144
|
+
|
|
145
|
+
For detailed examples, patterns, and decision trees, see the reference materials:
|
|
146
|
+
- [references/functional-core.md](references/functional-core.md) - Core vs shell separation
|
|
147
|
+
- [references/ddd.md](references/ddd.md) - DDD patterns, aggregates, bounded contexts
|
|
148
|
+
- [references/data-modeling.md](references/data-modeling.md) - dataclasses, Pydantic, transformations
|