@intentsolutionsio/sprint 1.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.
- package/.claude-plugin/plugin.json +23 -0
- package/LICENSE +21 -0
- package/README.md +320 -0
- package/agents/allpurpose-agent.md +159 -0
- package/agents/cicd-agent.md +189 -0
- package/agents/nextjs-dev.md +204 -0
- package/agents/nextjs-diagnostics-agent.md +206 -0
- package/agents/project-architect.md +398 -0
- package/agents/python-dev.md +159 -0
- package/agents/qa-test-agent.md +192 -0
- package/agents/ui-test-agent.md +295 -0
- package/agents/website-designer.md +48 -0
- package/commands/clean.md +153 -0
- package/commands/generate-map.md +160 -0
- package/commands/new.md +173 -0
- package/commands/setup.md +239 -0
- package/commands/sprint.md +482 -0
- package/commands/test.md +183 -0
- package/package.json +44 -0
- package/skills/agent-patterns/SKILL.md +103 -0
- package/skills/agent-patterns/references/errors.md +8 -0
- package/skills/agent-patterns/references/examples.md +291 -0
- package/skills/agent-patterns/references/ui-test-report.md +35 -0
- package/skills/api-contract/SKILL.md +115 -0
- package/skills/api-contract/references/best-practices.md +47 -0
- package/skills/api-contract/references/errors.md +8 -0
- package/skills/api-contract/references/examples.md +448 -0
- package/skills/api-contract/references/pagination.md +46 -0
- package/skills/api-contract/references/typescript-interfaces.md +46 -0
- package/skills/api-contract/references/writing-endpoints.md +45 -0
- package/skills/spec-writing/SKILL.md +110 -0
- package/skills/spec-writing/references/errors.md +8 -0
- package/skills/spec-writing/references/examples.md +274 -0
- package/skills/spec-writing/references/testing-configuration.md +40 -0
- package/skills/sprint-workflow/SKILL.md +81 -0
- package/skills/sprint-workflow/references/errors.md +8 -0
- package/skills/sprint-workflow/references/examples.md +317 -0
- package/skills/sprint-workflow/references/sprint-phases.md +54 -0
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
# Examples
|
|
2
|
+
|
|
3
|
+
## Example 1: Complete CRUD Contract for a Resource
|
|
4
|
+
|
|
5
|
+
A full api-contract.md covering all standard CRUD operations for a single
|
|
6
|
+
resource with typed request/response schemas and error codes.
|
|
7
|
+
|
|
8
|
+
```markdown
|
|
9
|
+
# API Contract: Products
|
|
10
|
+
|
|
11
|
+
## Shared Types
|
|
12
|
+
|
|
13
|
+
### Product
|
|
14
|
+
| Field | Type | Description |
|
|
15
|
+
|-------------|-------------------|--------------------------------|
|
|
16
|
+
| id | uuid | Unique product identifier |
|
|
17
|
+
| name | string (required) | Product name, 1-200 chars |
|
|
18
|
+
| description | string (optional) | Product description, max 5000 |
|
|
19
|
+
| price | number (required) | Price in cents (integer) |
|
|
20
|
+
| category | string (required) | One of: electronics, clothing, food, other |
|
|
21
|
+
| inStock | boolean | Availability flag |
|
|
22
|
+
| createdAt | ISO 8601 datetime | Creation timestamp |
|
|
23
|
+
| updatedAt | ISO 8601 datetime | Last modification timestamp |
|
|
24
|
+
|
|
25
|
+
### ApiError
|
|
26
|
+
| Field | Type | Description |
|
|
27
|
+
|---------|----------------------------|--------------------------|
|
|
28
|
+
| code | string | Machine-readable error |
|
|
29
|
+
| message | string | Human-readable message |
|
|
30
|
+
| details | Record<string, string[]>? | Field-level errors |
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
#### POST /api/products
|
|
35
|
+
|
|
36
|
+
Create a new product.
|
|
37
|
+
|
|
38
|
+
**Request:**
|
|
39
|
+
| Field | Type | Required | Constraints |
|
|
40
|
+
|-------------|--------|----------|----------------------------|
|
|
41
|
+
| name | string | yes | 1-200 characters |
|
|
42
|
+
| description | string | no | Max 5000 characters |
|
|
43
|
+
| price | number | yes | Integer, >= 0 (cents) |
|
|
44
|
+
| category | string | yes | electronics, clothing, food, other |
|
|
45
|
+
|
|
46
|
+
**Response (201 Created):**
|
|
47
|
+
Returns the full Product object with generated id, createdAt, updatedAt.
|
|
48
|
+
|
|
49
|
+
**Errors:**
|
|
50
|
+
- 400: Missing required fields → `{ code: "VALIDATION_ERROR", details: { name: ["required"] } }`
|
|
51
|
+
- 422: Price is negative → `{ code: "INVALID_PRICE", message: "Price must be >= 0" }`
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
#### GET /api/products/:id
|
|
56
|
+
|
|
57
|
+
Retrieve a single product by ID.
|
|
58
|
+
|
|
59
|
+
**Path Parameters:**
|
|
60
|
+
| Param | Type | Description |
|
|
61
|
+
|-------|------|-----------------------|
|
|
62
|
+
| id | uuid | Product identifier |
|
|
63
|
+
|
|
64
|
+
**Response (200 OK):**
|
|
65
|
+
Returns the full Product object.
|
|
66
|
+
|
|
67
|
+
**Errors:**
|
|
68
|
+
- 404: Product not found → `{ code: "NOT_FOUND", message: "Product not found" }`
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
#### PATCH /api/products/:id
|
|
73
|
+
|
|
74
|
+
Update one or more product fields. Only provided fields are modified.
|
|
75
|
+
|
|
76
|
+
**Request:**
|
|
77
|
+
| Field | Type | Required | Constraints |
|
|
78
|
+
|-------------|--------|----------|-----------------------|
|
|
79
|
+
| name | string | no | 1-200 characters |
|
|
80
|
+
| description | string | no | Max 5000 characters |
|
|
81
|
+
| price | number | no | Integer, >= 0 (cents) |
|
|
82
|
+
| category | string | no | Valid category value |
|
|
83
|
+
|
|
84
|
+
**Response (200 OK):**
|
|
85
|
+
Returns the updated Product object with new updatedAt timestamp.
|
|
86
|
+
|
|
87
|
+
**Errors:**
|
|
88
|
+
- 400: Invalid field value → field-level details
|
|
89
|
+
- 404: Product not found
|
|
90
|
+
- 409: Concurrent modification → `{ code: "CONFLICT", message: "Product was modified" }`
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
#### DELETE /api/products/:id
|
|
95
|
+
|
|
96
|
+
Soft-delete a product (sets archived flag, does not remove from database).
|
|
97
|
+
|
|
98
|
+
**Response (204 No Content):**
|
|
99
|
+
Empty body on success.
|
|
100
|
+
|
|
101
|
+
**Errors:**
|
|
102
|
+
- 404: Product not found
|
|
103
|
+
- 409: Product already archived
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
#### GET /api/products
|
|
108
|
+
|
|
109
|
+
List products with pagination and filtering.
|
|
110
|
+
|
|
111
|
+
**Query Parameters:**
|
|
112
|
+
| Param | Type | Default | Description |
|
|
113
|
+
|----------|---------|-----------|-----------------------------------|
|
|
114
|
+
| page | integer | 1 | Page number (1-based) |
|
|
115
|
+
| limit | integer | 20 | Items per page (max 100) |
|
|
116
|
+
| sort | string | createdAt | Sort field (name, price, createdAt) |
|
|
117
|
+
| order | string | desc | Sort direction (asc, desc) |
|
|
118
|
+
| category | string | (all) | Filter by category |
|
|
119
|
+
| inStock | boolean | (all) | Filter by availability |
|
|
120
|
+
|
|
121
|
+
**Response (200 OK):**
|
|
122
|
+
```json
|
|
123
|
+
{
|
|
124
|
+
"data": [Product],
|
|
125
|
+
"pagination": {
|
|
126
|
+
"page": 1,
|
|
127
|
+
"limit": 20,
|
|
128
|
+
"total": 150,
|
|
129
|
+
"totalPages": 8
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**Errors:**
|
|
135
|
+
- 400: Invalid query parameter → `{ code: "INVALID_PARAM", details: { limit: ["max 100"] } }`
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Example 2: Authentication Contract with Token Flow
|
|
139
|
+
|
|
140
|
+
A contract covering registration, login, and token refresh with explicit
|
|
141
|
+
security considerations.
|
|
142
|
+
|
|
143
|
+
```markdown
|
|
144
|
+
# API Contract: Authentication
|
|
145
|
+
|
|
146
|
+
## Shared Types
|
|
147
|
+
|
|
148
|
+
### AuthTokens
|
|
149
|
+
| Field | Type | Description |
|
|
150
|
+
|--------------|--------|---------------------------------------|
|
|
151
|
+
| accessToken | string | JWT, 15-minute expiry, HS256 |
|
|
152
|
+
| refreshToken | string | Opaque token, 7-day expiry, stored DB |
|
|
153
|
+
| expiresIn | number | Access token TTL in seconds (900) |
|
|
154
|
+
|
|
155
|
+
### UserProfile
|
|
156
|
+
| Field | Type | Description |
|
|
157
|
+
|-------------|-------------------|--------------------------------|
|
|
158
|
+
| id | uuid | User identifier |
|
|
159
|
+
| email | string | Verified email address |
|
|
160
|
+
| name | string or null | Display name (optional) |
|
|
161
|
+
| role | string | One of: user, admin |
|
|
162
|
+
| createdAt | ISO 8601 datetime | Registration timestamp |
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
#### POST /auth/register
|
|
167
|
+
|
|
168
|
+
Create a new user account and return authentication tokens.
|
|
169
|
+
|
|
170
|
+
**Request:**
|
|
171
|
+
| Field | Type | Required | Constraints |
|
|
172
|
+
|----------|--------|----------|---------------------------------|
|
|
173
|
+
| email | string | yes | Valid email format, max 254 |
|
|
174
|
+
| password | string | yes | Min 8 chars, at least 1 number |
|
|
175
|
+
| name | string | no | 1-100 characters |
|
|
176
|
+
|
|
177
|
+
**Response (201 Created):**
|
|
178
|
+
```json
|
|
179
|
+
{
|
|
180
|
+
"user": UserProfile,
|
|
181
|
+
"tokens": AuthTokens
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**Errors:**
|
|
186
|
+
- 400: Invalid email format or weak password → field-level details
|
|
187
|
+
- 409: Email already registered → `{ code: "EMAIL_EXISTS" }`
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
#### POST /auth/login
|
|
192
|
+
|
|
193
|
+
Authenticate with email and password.
|
|
194
|
+
|
|
195
|
+
**Request:**
|
|
196
|
+
| Field | Type | Required |
|
|
197
|
+
|----------|--------|----------|
|
|
198
|
+
| email | string | yes |
|
|
199
|
+
| password | string | yes |
|
|
200
|
+
|
|
201
|
+
**Response (200 OK):**
|
|
202
|
+
```json
|
|
203
|
+
{
|
|
204
|
+
"user": UserProfile,
|
|
205
|
+
"tokens": AuthTokens
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
**Errors:**
|
|
210
|
+
- 401: Invalid credentials → `{ code: "INVALID_CREDENTIALS" }`
|
|
211
|
+
(same message for wrong email and wrong password to prevent enumeration)
|
|
212
|
+
- 429: Too many attempts → `{ code: "RATE_LIMITED", message: "Try again in 60s" }`
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
#### POST /auth/refresh
|
|
217
|
+
|
|
218
|
+
Exchange a valid refresh token for new tokens. The old refresh token is
|
|
219
|
+
invalidated (rotation).
|
|
220
|
+
|
|
221
|
+
**Request:**
|
|
222
|
+
| Field | Type | Required |
|
|
223
|
+
|--------------|--------|----------|
|
|
224
|
+
| refreshToken | string | yes |
|
|
225
|
+
|
|
226
|
+
**Response (200 OK):**
|
|
227
|
+
```json
|
|
228
|
+
{
|
|
229
|
+
"tokens": AuthTokens
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
**Errors:**
|
|
234
|
+
- 401: Invalid or expired refresh token → `{ code: "INVALID_REFRESH_TOKEN" }`
|
|
235
|
+
(also triggered if token was already rotated — potential theft detection)
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
#### POST /auth/logout
|
|
240
|
+
|
|
241
|
+
Invalidate the refresh token for the current session.
|
|
242
|
+
|
|
243
|
+
**Headers:**
|
|
244
|
+
| Header | Value |
|
|
245
|
+
|---------------|----------------------|
|
|
246
|
+
| Authorization | Bearer {accessToken} |
|
|
247
|
+
|
|
248
|
+
**Request:**
|
|
249
|
+
| Field | Type | Required |
|
|
250
|
+
|--------------|--------|----------|
|
|
251
|
+
| refreshToken | string | yes |
|
|
252
|
+
|
|
253
|
+
**Response (204 No Content):**
|
|
254
|
+
Empty body.
|
|
255
|
+
|
|
256
|
+
**Errors:**
|
|
257
|
+
- 401: Missing or invalid access token
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
## Example 3: TypeScript Interface Definitions
|
|
261
|
+
|
|
262
|
+
Canonical type definitions shared between backend and frontend agents.
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
// types/api.ts — Shared types for api-contract.md
|
|
266
|
+
|
|
267
|
+
/** Standard paginated response wrapper */
|
|
268
|
+
interface PaginatedResponse<T> {
|
|
269
|
+
data: T[];
|
|
270
|
+
pagination: {
|
|
271
|
+
page: number;
|
|
272
|
+
limit: number;
|
|
273
|
+
total: number;
|
|
274
|
+
totalPages: number;
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/** Standard API error response */
|
|
279
|
+
interface ApiError {
|
|
280
|
+
code: string;
|
|
281
|
+
message: string;
|
|
282
|
+
details?: Record<string, string[]>;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/** Product resource */
|
|
286
|
+
interface Product {
|
|
287
|
+
id: string;
|
|
288
|
+
name: string;
|
|
289
|
+
description: string | null;
|
|
290
|
+
price: number; // in cents
|
|
291
|
+
category: 'electronics' | 'clothing' | 'food' | 'other';
|
|
292
|
+
inStock: boolean;
|
|
293
|
+
createdAt: string; // ISO 8601
|
|
294
|
+
updatedAt: string; // ISO 8601
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/** Create product request body */
|
|
298
|
+
interface CreateProductRequest {
|
|
299
|
+
name: string;
|
|
300
|
+
description?: string;
|
|
301
|
+
price: number;
|
|
302
|
+
category: Product['category'];
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/** Update product request body (all fields optional) */
|
|
306
|
+
interface UpdateProductRequest {
|
|
307
|
+
name?: string;
|
|
308
|
+
description?: string;
|
|
309
|
+
price?: number;
|
|
310
|
+
category?: Product['category'];
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/** Search request with filters */
|
|
314
|
+
interface SearchRequest {
|
|
315
|
+
query: string;
|
|
316
|
+
filters?: {
|
|
317
|
+
category?: Product['category'];
|
|
318
|
+
priceMin?: number;
|
|
319
|
+
priceMax?: number;
|
|
320
|
+
inStock?: boolean;
|
|
321
|
+
};
|
|
322
|
+
page?: number;
|
|
323
|
+
limit?: number;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/** Search response with facets */
|
|
327
|
+
interface SearchResponse {
|
|
328
|
+
results: Product[];
|
|
329
|
+
total: number;
|
|
330
|
+
facets: FacetGroup[];
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/** Facet group for filtering */
|
|
334
|
+
interface FacetGroup {
|
|
335
|
+
name: string;
|
|
336
|
+
values: Array<{
|
|
337
|
+
value: string;
|
|
338
|
+
count: number;
|
|
339
|
+
}>;
|
|
340
|
+
}
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
## Example 4: Contract with Nested Resources
|
|
344
|
+
|
|
345
|
+
An API contract where one resource is nested under another, showing
|
|
346
|
+
the relationship between parent and child endpoints.
|
|
347
|
+
|
|
348
|
+
```markdown
|
|
349
|
+
# API Contract: Orders and Line Items
|
|
350
|
+
|
|
351
|
+
## Shared Types
|
|
352
|
+
|
|
353
|
+
### Order
|
|
354
|
+
| Field | Type | Description |
|
|
355
|
+
|-----------|-------------------|--------------------------------|
|
|
356
|
+
| id | uuid | Order identifier |
|
|
357
|
+
| userId | uuid | Customer identifier |
|
|
358
|
+
| status | string | pending, confirmed, shipped, delivered, cancelled |
|
|
359
|
+
| total | number | Total in cents |
|
|
360
|
+
| items | LineItem[] | Ordered products |
|
|
361
|
+
| createdAt | ISO 8601 datetime | Order creation time |
|
|
362
|
+
|
|
363
|
+
### LineItem
|
|
364
|
+
| Field | Type | Description |
|
|
365
|
+
|-----------|--------|--------------------------------|
|
|
366
|
+
| productId | uuid | Product reference |
|
|
367
|
+
| name | string | Product name at time of order |
|
|
368
|
+
| quantity | number | Integer, >= 1 |
|
|
369
|
+
| unitPrice | number | Price in cents at time of order |
|
|
370
|
+
| subtotal | number | quantity * unitPrice |
|
|
371
|
+
|
|
372
|
+
---
|
|
373
|
+
|
|
374
|
+
#### POST /api/orders
|
|
375
|
+
|
|
376
|
+
Create a new order from the user's cart.
|
|
377
|
+
|
|
378
|
+
**Headers:**
|
|
379
|
+
Authorization: Bearer {accessToken}
|
|
380
|
+
|
|
381
|
+
**Request:**
|
|
382
|
+
| Field | Type | Required |
|
|
383
|
+
|-------|---------------------------------------|----------|
|
|
384
|
+
| items | Array<{ productId: uuid, quantity: number }> | yes |
|
|
385
|
+
|
|
386
|
+
**Response (201 Created):**
|
|
387
|
+
Returns the full Order object with computed totals and line items.
|
|
388
|
+
|
|
389
|
+
**Errors:**
|
|
390
|
+
- 400: Empty items array → `{ code: "EMPTY_CART" }`
|
|
391
|
+
- 404: Product not found → `{ code: "PRODUCT_NOT_FOUND", details: { productId: ["..."] } }`
|
|
392
|
+
- 409: Product out of stock → `{ code: "OUT_OF_STOCK", details: { productId: ["..."] } }`
|
|
393
|
+
- 422: Quantity exceeds available stock
|
|
394
|
+
|
|
395
|
+
---
|
|
396
|
+
|
|
397
|
+
#### GET /api/orders/:orderId/items
|
|
398
|
+
|
|
399
|
+
List line items for a specific order.
|
|
400
|
+
|
|
401
|
+
**Response (200 OK):**
|
|
402
|
+
```json
|
|
403
|
+
{
|
|
404
|
+
"data": [LineItem],
|
|
405
|
+
"orderId": "uuid",
|
|
406
|
+
"itemCount": 3
|
|
407
|
+
}
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
**Errors:**
|
|
411
|
+
- 403: Order belongs to a different user
|
|
412
|
+
- 404: Order not found
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
## Example 5: Contract Section for Webhook Callbacks
|
|
416
|
+
|
|
417
|
+
When the API needs to send callbacks to external systems, the contract
|
|
418
|
+
documents the outbound payload format.
|
|
419
|
+
|
|
420
|
+
```markdown
|
|
421
|
+
# Webhook Events
|
|
422
|
+
|
|
423
|
+
## Order Status Changed
|
|
424
|
+
|
|
425
|
+
Sent when an order transitions between statuses.
|
|
426
|
+
|
|
427
|
+
**POST {webhookUrl}**
|
|
428
|
+
|
|
429
|
+
**Payload:**
|
|
430
|
+
| Field | Type | Description |
|
|
431
|
+
|------------|-------------------|--------------------------------|
|
|
432
|
+
| event | string | Always "order.status.changed" |
|
|
433
|
+
| orderId | uuid | Order identifier |
|
|
434
|
+
| oldStatus | string | Previous status value |
|
|
435
|
+
| newStatus | string | New status value |
|
|
436
|
+
| timestamp | ISO 8601 datetime | When the transition occurred |
|
|
437
|
+
| metadata | object (optional) | Additional context (tracking number, carrier) |
|
|
438
|
+
|
|
439
|
+
**Expected Response:**
|
|
440
|
+
- 200 OK: Webhook processed successfully
|
|
441
|
+
- 4xx/5xx: Retry with exponential backoff (3 attempts, 30s/120s/300s delays)
|
|
442
|
+
|
|
443
|
+
**Signature Header:**
|
|
444
|
+
X-Webhook-Signature: HMAC-SHA256 of the JSON body using the shared secret
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
---
|
|
448
|
+
*[Tons of Skills](https://tonsofskills.com) by [Intent Solutions](https://intentsolutions.io) | [jeremylongshore.com](https://jeremylongshore.com)*
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Pagination
|
|
2
|
+
|
|
3
|
+
## Pagination
|
|
4
|
+
|
|
5
|
+
For list endpoints:
|
|
6
|
+
|
|
7
|
+
```markdown
|
|
8
|
+
#### GET /products
|
|
9
|
+
|
|
10
|
+
List products with pagination.
|
|
11
|
+
|
|
12
|
+
**Query Parameters:**
|
|
13
|
+
| Param | Type | Default | Description |
|
|
14
|
+
|-------|------|---------|-------------|
|
|
15
|
+
| page | integer | 1 | Page number |
|
|
16
|
+
| limit | integer | 20 | Items per page (max 100) |
|
|
17
|
+
| sort | string | createdAt | Sort field |
|
|
18
|
+
| order | string | desc | Sort order (asc/desc) |
|
|
19
|
+
|
|
20
|
+
**Response (200):**
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"data": [Product],
|
|
24
|
+
"pagination": {
|
|
25
|
+
"page": 1,
|
|
26
|
+
"limit": 20,
|
|
27
|
+
"total": 150,
|
|
28
|
+
"totalPages": 8
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Pagination Interface
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
interface PaginatedResponse<T> {
|
|
38
|
+
data: T[];
|
|
39
|
+
pagination: {
|
|
40
|
+
page: number;
|
|
41
|
+
limit: number;
|
|
42
|
+
total: number;
|
|
43
|
+
totalPages: number;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
```
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Typescript Interfaces
|
|
2
|
+
|
|
3
|
+
## TypeScript Interfaces
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
// User types
|
|
7
|
+
interface User {
|
|
8
|
+
id: string;
|
|
9
|
+
email: string;
|
|
10
|
+
name: string | null;
|
|
11
|
+
createdAt: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface CreateUserRequest {
|
|
15
|
+
email: string;
|
|
16
|
+
password: string;
|
|
17
|
+
name?: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface LoginRequest {
|
|
21
|
+
email: string;
|
|
22
|
+
password: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface AuthResponse {
|
|
26
|
+
user: User;
|
|
27
|
+
token: string;
|
|
28
|
+
expiresAt: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Error response
|
|
32
|
+
interface ApiError {
|
|
33
|
+
code: string;
|
|
34
|
+
message: string;
|
|
35
|
+
details?: Record<string, string[]>;
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Type Guidelines
|
|
41
|
+
|
|
42
|
+
- Use explicit types, not `any`
|
|
43
|
+
- Mark optional fields with `?`
|
|
44
|
+
- Use union types for nullable: `string | null`
|
|
45
|
+
- Include all possible response shapes
|
|
46
|
+
- Match types to JSON serialization
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Writing Endpoints
|
|
2
|
+
|
|
3
|
+
## Writing Endpoints
|
|
4
|
+
|
|
5
|
+
### Endpoint Definition
|
|
6
|
+
|
|
7
|
+
```markdown
|
|
8
|
+
#### POST /auth/register
|
|
9
|
+
|
|
10
|
+
Create a new user account.
|
|
11
|
+
|
|
12
|
+
**Request:**
|
|
13
|
+
```json
|
|
14
|
+
{
|
|
15
|
+
"email": "string (required, valid email)",
|
|
16
|
+
"password": "string (required, min 8 chars)",
|
|
17
|
+
"name": "string (optional)"
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**Response (201):**
|
|
22
|
+
```json
|
|
23
|
+
{
|
|
24
|
+
"id": "uuid",
|
|
25
|
+
"email": "string",
|
|
26
|
+
"name": "string | null",
|
|
27
|
+
"createdAt": "ISO 8601 datetime"
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Errors:**
|
|
32
|
+
- 400: Invalid request body
|
|
33
|
+
- 409: Email already exists
|
|
34
|
+
- 422: Validation failed
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Key Elements
|
|
38
|
+
|
|
39
|
+
| Element | Purpose |
|
|
40
|
+
|---------|---------|
|
|
41
|
+
| Method + Route | HTTP verb and path |
|
|
42
|
+
| Description | What the endpoint does |
|
|
43
|
+
| Request | Input schema with types and constraints |
|
|
44
|
+
| Response | Output schema with status code |
|
|
45
|
+
| Errors | Possible error responses |
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: spec-writing
|
|
3
|
+
description: |
|
|
4
|
+
Execute this skill should be used when the user asks about "writing specs", "specs.md format", "how to write specifications", "sprint requirements", "testing configuration", "scope definition", or needs guidance on creating effective sprint specifications for agentic development. Use when appropriate context detected. Trigger with relevant phrases based on skill purpose.
|
|
5
|
+
allowed-tools: Read
|
|
6
|
+
version: 1.0.0
|
|
7
|
+
author: Damien Laine <damien.laine@gmail.com>
|
|
8
|
+
license: MIT
|
|
9
|
+
compatible-with: claude-code, codex, openclaw
|
|
10
|
+
tags: [community, spec-writing]
|
|
11
|
+
---
|
|
12
|
+
# Spec Writing
|
|
13
|
+
|
|
14
|
+
## Overview
|
|
15
|
+
|
|
16
|
+
Spec Writing provides guidance on authoring effective `specs.md` files that drive the Sprint plugin's autonomous development workflow. A well-written specification determines the quality of agent output by clearly defining goals, scope boundaries, and testing requirements.
|
|
17
|
+
|
|
18
|
+
## Prerequisites
|
|
19
|
+
|
|
20
|
+
- Sprint plugin installed (`/plugin install sprint`)
|
|
21
|
+
- Project onboarding completed via `/sprint:setup` (creates `project-goals.md` and `project-map.md`)
|
|
22
|
+
- Sprint directory created via `/sprint:new` (generates `.claude/sprint/[N]/specs.md`)
|
|
23
|
+
- Understanding of the sprint phase lifecycle (see the `sprint-workflow` skill)
|
|
24
|
+
|
|
25
|
+
## Instructions
|
|
26
|
+
|
|
27
|
+
1. Open the generated `specs.md` file at `.claude/sprint/[N]/specs.md` and define a concise goal statement at the top. State what the sprint delivers in one sentence (e.g., "Add user authentication with email/password login").
|
|
28
|
+
2. Define explicit scope boundaries using **In Scope** and **Out of Scope** sections. List specific features, endpoints, or components in each. Agents only implement what appears in scope; ambiguity leads to drift.
|
|
29
|
+
3. Add the **Testing** section to control which testing agents run and how. Configure three settings as documented in `${CLAUDE_SKILL_DIR}/references/testing-configuration.md`:
|
|
30
|
+
- `QA`: `required` | `optional` | `skip` -- Controls API and unit test execution
|
|
31
|
+
- `UI Testing`: `required` | `optional` | `skip` -- Controls browser-based E2E tests
|
|
32
|
+
- `UI Testing Mode`: `automated` | `manual` -- Auto-run or user-driven testing
|
|
33
|
+
4. Set QA to `required` for new API endpoints, business logic changes, and data validation rules. Set QA to `skip` for frontend-only changes, documentation updates, or configuration changes.
|
|
34
|
+
5. Set UI Testing to `required` for user-facing features, form submissions, and navigation flows. Choose `automated` mode for regression testing and standard CRUD flows; choose `manual` mode for complex interactions, visual verification, or exploratory testing.
|
|
35
|
+
6. Keep specifications minimal but precise. The architect expands high-level specs into detailed implementation files (`backend-specs.md`, `frontend-specs.md`, `api-contract.md`). Over-specifying implementation details in `specs.md` constrains the architect unnecessarily.
|
|
36
|
+
7. For iterative sprints, review `status.md` from the previous iteration. Remove completed items from specs and add any new requirements or bug fixes discovered during testing.
|
|
37
|
+
|
|
38
|
+
## Output
|
|
39
|
+
|
|
40
|
+
- A complete `specs.md` file with goal, scope (in/out), and testing configuration
|
|
41
|
+
- Clear scope boundaries that prevent agent drift during implementation
|
|
42
|
+
- Testing configuration that selects appropriate QA and UI testing agents
|
|
43
|
+
- Iteratively refined specs where completed work is removed and remaining work is focused
|
|
44
|
+
|
|
45
|
+
## Error Handling
|
|
46
|
+
|
|
47
|
+
| Error | Cause | Solution |
|
|
48
|
+
|-------|-------|----------|
|
|
49
|
+
| Agents implement unintended features | Missing "Out of Scope" section | Explicitly list features excluded from this sprint |
|
|
50
|
+
| Tests not running during sprint | Testing section omitted or set to `skip` | Add `QA: required` and `UI Testing: required` to the Testing section |
|
|
51
|
+
| Sprint iterates without converging | Specs too broad for a single sprint | Break into smaller sprints targeting one domain boundary each |
|
|
52
|
+
| Architect produces conflicting spec files | Ambiguous or contradictory requirements in `specs.md` | Review for conflicting statements; each requirement should have a single interpretation |
|
|
53
|
+
| Manual tests not triggered | `UI Testing Mode` set to `automated` | Change to `manual` for scenarios requiring visual verification or exploratory testing |
|
|
54
|
+
|
|
55
|
+
## Examples
|
|
56
|
+
|
|
57
|
+
**Minimal but effective spec:**
|
|
58
|
+
```markdown
|
|
59
|
+
# Sprint 1: User Authentication
|
|
60
|
+
|
|
61
|
+
## Goal
|
|
62
|
+
Add user authentication with email/password login
|
|
63
|
+
|
|
64
|
+
## Scope
|
|
65
|
+
### In Scope
|
|
66
|
+
- Registration endpoint (POST /auth/register)
|
|
67
|
+
- Login endpoint (POST /auth/login)
|
|
68
|
+
- JWT token generation and validation
|
|
69
|
+
- Password hashing with bcrypt
|
|
70
|
+
|
|
71
|
+
### Out of Scope
|
|
72
|
+
- OAuth providers (Google, GitHub)
|
|
73
|
+
- Password reset flow
|
|
74
|
+
- Email verification
|
|
75
|
+
|
|
76
|
+
## Testing
|
|
77
|
+
- QA: required
|
|
78
|
+
- UI Testing: required
|
|
79
|
+
- UI Testing Mode: automated
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Frontend-only sprint (no QA needed):**
|
|
83
|
+
```markdown
|
|
84
|
+
# Sprint 3: Dashboard Redesign
|
|
85
|
+
|
|
86
|
+
## Goal
|
|
87
|
+
Redesign the admin dashboard with responsive layout
|
|
88
|
+
|
|
89
|
+
## Scope
|
|
90
|
+
### In Scope
|
|
91
|
+
- Responsive grid layout for dashboard widgets
|
|
92
|
+
- Dark mode toggle
|
|
93
|
+
- Mobile navigation drawer
|
|
94
|
+
|
|
95
|
+
### Out of Scope
|
|
96
|
+
- New API endpoints
|
|
97
|
+
- Database changes
|
|
98
|
+
- Authentication changes
|
|
99
|
+
|
|
100
|
+
## Testing
|
|
101
|
+
- QA: skip
|
|
102
|
+
- UI Testing: required
|
|
103
|
+
- UI Testing Mode: manual
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Resources
|
|
107
|
+
|
|
108
|
+
- `${CLAUDE_SKILL_DIR}/references/testing-configuration.md` -- Testing section options with guidance on when to use each setting
|
|
109
|
+
- Sprint workflow skill for understanding how specs feed into the phase lifecycle
|
|
110
|
+
- API contract skill for designing endpoint contracts referenced by specs
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Error Handling Reference
|
|
2
|
+
|
|
3
|
+
- Invalid input: Prompts for correction
|
|
4
|
+
- Missing dependencies: Lists required components
|
|
5
|
+
- Permission errors: Suggests remediation steps
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
*[Tons of Skills](https://tonsofskills.com) by [Intent Solutions](https://intentsolutions.io) | [jeremylongshore.com](https://jeremylongshore.com)*
|