vstack 0.0.0__py3-none-any.whl
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.
- vstack/__init__.py +5 -0
- vstack/__main__.py +5 -0
- vstack/_templates/agents/_partials/agent-skill-boundary.md +5 -0
- vstack/_templates/agents/architect/config.yaml +38 -0
- vstack/_templates/agents/architect/template.md +84 -0
- vstack/_templates/agents/designer/config.yaml +36 -0
- vstack/_templates/agents/designer/template.md +99 -0
- vstack/_templates/agents/engineer/config.yaml +36 -0
- vstack/_templates/agents/engineer/template.md +88 -0
- vstack/_templates/agents/product/config.yaml +37 -0
- vstack/_templates/agents/product/template.md +87 -0
- vstack/_templates/agents/release/config.yaml +35 -0
- vstack/_templates/agents/release/template.md +86 -0
- vstack/_templates/agents/tester/config.yaml +41 -0
- vstack/_templates/agents/tester/template.md +90 -0
- vstack/_templates/instructions/git/config.yaml +4 -0
- vstack/_templates/instructions/git/template.md +36 -0
- vstack/_templates/instructions/python/config.yaml +4 -0
- vstack/_templates/instructions/python/template.md +37 -0
- vstack/_templates/prompts/code-review/config.yaml +10 -0
- vstack/_templates/prompts/code-review/template.md +39 -0
- vstack/_templates/skills/_partials/base-branch.md +8 -0
- vstack/_templates/skills/_partials/observability-checklist.md +36 -0
- vstack/_templates/skills/_partials/run-tests.md +22 -0
- vstack/_templates/skills/_partials/skill-context.md +21 -0
- vstack/_templates/skills/adr/config.yaml +17 -0
- vstack/_templates/skills/adr/template.md +167 -0
- vstack/_templates/skills/analyse/config.yaml +16 -0
- vstack/_templates/skills/analyse/template.md +188 -0
- vstack/_templates/skills/architecture/config.yaml +18 -0
- vstack/_templates/skills/architecture/template.md +213 -0
- vstack/_templates/skills/cicd/config.yaml +16 -0
- vstack/_templates/skills/cicd/template.md +169 -0
- vstack/_templates/skills/code-review/config.yaml +16 -0
- vstack/_templates/skills/code-review/template.md +180 -0
- vstack/_templates/skills/concise/config.yaml +16 -0
- vstack/_templates/skills/concise/template.md +128 -0
- vstack/_templates/skills/consult/config.yaml +18 -0
- vstack/_templates/skills/consult/template.md +195 -0
- vstack/_templates/skills/container/config.yaml +17 -0
- vstack/_templates/skills/container/template.md +122 -0
- vstack/_templates/skills/debug/config.yaml +16 -0
- vstack/_templates/skills/debug/template.md +247 -0
- vstack/_templates/skills/dependency/config.yaml +18 -0
- vstack/_templates/skills/dependency/template.md +293 -0
- vstack/_templates/skills/design/config.yaml +16 -0
- vstack/_templates/skills/design/template.md +231 -0
- vstack/_templates/skills/docs/config.yaml +17 -0
- vstack/_templates/skills/docs/template.md +128 -0
- vstack/_templates/skills/explore/config.yaml +17 -0
- vstack/_templates/skills/explore/template.md +188 -0
- vstack/_templates/skills/guardrails/config.yaml +16 -0
- vstack/_templates/skills/guardrails/template.md +45 -0
- vstack/_templates/skills/incident/config.yaml +17 -0
- vstack/_templates/skills/incident/template.md +293 -0
- vstack/_templates/skills/inspect/config.yaml +16 -0
- vstack/_templates/skills/inspect/template.md +105 -0
- vstack/_templates/skills/migrate/config.yaml +17 -0
- vstack/_templates/skills/migrate/template.md +298 -0
- vstack/_templates/skills/onboard/config.yaml +18 -0
- vstack/_templates/skills/onboard/template.md +289 -0
- vstack/_templates/skills/openapi/config.yaml +17 -0
- vstack/_templates/skills/openapi/template.md +382 -0
- vstack/_templates/skills/performance/config.yaml +15 -0
- vstack/_templates/skills/performance/template.md +198 -0
- vstack/_templates/skills/pr/config.yaml +15 -0
- vstack/_templates/skills/pr/template.md +108 -0
- vstack/_templates/skills/refactor/config.yaml +18 -0
- vstack/_templates/skills/refactor/template.md +283 -0
- vstack/_templates/skills/release-notes/config.yaml +16 -0
- vstack/_templates/skills/release-notes/template.md +127 -0
- vstack/_templates/skills/requirements/config.yaml +17 -0
- vstack/_templates/skills/requirements/template.md +187 -0
- vstack/_templates/skills/security/config.yaml +17 -0
- vstack/_templates/skills/security/template.md +256 -0
- vstack/_templates/skills/verify/config.yaml +17 -0
- vstack/_templates/skills/verify/template.md +201 -0
- vstack/_templates/skills/vision/config.yaml +19 -0
- vstack/_templates/skills/vision/template.md +169 -0
- vstack/agents/__init__.py +5 -0
- vstack/agents/config.py +67 -0
- vstack/agents/constants.py +14 -0
- vstack/agents/generator.py +20 -0
- vstack/artifacts/__init__.py +17 -0
- vstack/artifacts/config.py +111 -0
- vstack/artifacts/constants.py +6 -0
- vstack/artifacts/generator.py +406 -0
- vstack/artifacts/models.py +55 -0
- vstack/artifacts/protocol.py +50 -0
- vstack/cli/__init__.py +3 -0
- vstack/cli/commands.py +596 -0
- vstack/cli/constants.py +33 -0
- vstack/cli/manifest.py +166 -0
- vstack/cli/parser.py +156 -0
- vstack/constants.py +84 -0
- vstack/frontmatter/__init__.py +8 -0
- vstack/frontmatter/parser.py +272 -0
- vstack/frontmatter/schema.py +142 -0
- vstack/frontmatter/serializer.py +208 -0
- vstack/instructions/__init__.py +5 -0
- vstack/instructions/config.py +21 -0
- vstack/instructions/constants.py +9 -0
- vstack/instructions/generator.py +13 -0
- vstack/main.py +71 -0
- vstack/models.py +35 -0
- vstack/prompts/__init__.py +5 -0
- vstack/prompts/config.py +21 -0
- vstack/prompts/constants.py +9 -0
- vstack/prompts/generator.py +13 -0
- vstack/skills/__init__.py +5 -0
- vstack/skills/config.py +58 -0
- vstack/skills/constants.py +17 -0
- vstack/skills/generator.py +20 -0
- vstack/skills/models.py +15 -0
- vstack-0.0.0.dist-info/METADATA +725 -0
- vstack-0.0.0.dist-info/RECORD +119 -0
- vstack-0.0.0.dist-info/WHEEL +4 -0
- vstack-0.0.0.dist-info/entry_points.txt +3 -0
- vstack-0.0.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
{{SKILL_CONTEXT}}
|
|
2
|
+
|
|
3
|
+
# openapi — OpenAPI 3.1 Specification
|
|
4
|
+
|
|
5
|
+
Write or review OpenAPI 3.1 specifications. The spec is the contract — it must
|
|
6
|
+
be precise, complete, and implementable without ambiguity.
|
|
7
|
+
|
|
8
|
+
## Out of scope
|
|
9
|
+
|
|
10
|
+
- Service architecture decisions (use `architecture`)
|
|
11
|
+
- Full API design from scratch (use `design`)
|
|
12
|
+
- Security audit of the implementation (use `security`)
|
|
13
|
+
- Contract compliance of the implementation (use `verify`)
|
|
14
|
+
|
|
15
|
+
**Golden rule: The spec is the source of truth. Code must conform to the spec,
|
|
16
|
+
not the other way around.**
|
|
17
|
+
|
|
18
|
+
______________________________________________________________________
|
|
19
|
+
|
|
20
|
+
## Step 0: Understand the Task
|
|
21
|
+
|
|
22
|
+
> **Question:** What needs to be done?
|
|
23
|
+
>
|
|
24
|
+
> **Options:**
|
|
25
|
+
> A) Write a new OpenAPI spec from scratch
|
|
26
|
+
> B) Review and improve an existing spec
|
|
27
|
+
> C) Add endpoints to an existing spec
|
|
28
|
+
> D) Validate spec for correctness and completeness
|
|
29
|
+
> **Default:** B — review existing spec
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# Locate existing spec files
|
|
33
|
+
find . -name 'openapi*.yaml' -o -name 'openapi*.json' \
|
|
34
|
+
-o -name 'swagger*.yaml' -o -name 'swagger*.json' \
|
|
35
|
+
2>/dev/null | grep -v node_modules | grep -v .venv | head -10
|
|
36
|
+
|
|
37
|
+
# Validate spec if tooling is available
|
|
38
|
+
[ -f openapi.yaml ] && npx @redocly/cli lint openapi.yaml 2>/dev/null || true
|
|
39
|
+
[ -f openapi.yaml ] && npx swagger-cli validate openapi.yaml 2>/dev/null || true
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
______________________________________________________________________
|
|
43
|
+
|
|
44
|
+
## Part 1: Spec Structure
|
|
45
|
+
|
|
46
|
+
Every OpenAPI 3.1 spec must have:
|
|
47
|
+
|
|
48
|
+
```yaml
|
|
49
|
+
openapi: "3.1.0"
|
|
50
|
+
|
|
51
|
+
info:
|
|
52
|
+
title: Service Name API
|
|
53
|
+
version: "1.0.0"
|
|
54
|
+
description: |
|
|
55
|
+
One paragraph describing the service purpose.
|
|
56
|
+
contact:
|
|
57
|
+
name: Team Name
|
|
58
|
+
email: team@example.com
|
|
59
|
+
|
|
60
|
+
servers:
|
|
61
|
+
- url: https://api.example.com/v1
|
|
62
|
+
description: Production
|
|
63
|
+
- url: https://api.staging.example.com/v1
|
|
64
|
+
description: Staging
|
|
65
|
+
|
|
66
|
+
tags:
|
|
67
|
+
- name: users
|
|
68
|
+
description: User management
|
|
69
|
+
|
|
70
|
+
paths: {}
|
|
71
|
+
|
|
72
|
+
components:
|
|
73
|
+
schemas: {}
|
|
74
|
+
securitySchemes: {}
|
|
75
|
+
|
|
76
|
+
security: []
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Check:
|
|
80
|
+
|
|
81
|
+
- [ ] `openapi` field is `"3.1.0"` (not 3.0.x or 2.x)
|
|
82
|
+
- [ ] `info.version` follows semver
|
|
83
|
+
- [ ] At least one server defined
|
|
84
|
+
- [ ] Tags defined at root level and used consistently on operations
|
|
85
|
+
- [ ] `components` section exists for reusable schemas
|
|
86
|
+
|
|
87
|
+
______________________________________________________________________
|
|
88
|
+
|
|
89
|
+
## Part 2: Resource & Path Design
|
|
90
|
+
|
|
91
|
+
### Naming conventions
|
|
92
|
+
|
|
93
|
+
| Correct | Incorrect | Rule |
|
|
94
|
+
| -------------------------- | -------------------- | --------------------------- |
|
|
95
|
+
| `/users` | `/getUsers`, `/user` | Plural nouns, no verbs |
|
|
96
|
+
| `/users/{userId}` | `/users/{id}` | Descriptive path parameters |
|
|
97
|
+
| `/users/{userId}/orders` | `/userOrders` | Nested for ownership |
|
|
98
|
+
| `/orders/{orderId}/cancel` | `/cancelOrder/{id}` | Sub-resource for actions |
|
|
99
|
+
|
|
100
|
+
### HTTP method semantics
|
|
101
|
+
|
|
102
|
+
| Method | Semantics | Idempotent | Body |
|
|
103
|
+
| -------- | ------------------------------- | ---------- | ---- |
|
|
104
|
+
| `GET` | Read, no side effects | Yes | No |
|
|
105
|
+
| `POST` | Create or non-idempotent action | No | Yes |
|
|
106
|
+
| `PUT` | Full replace | Yes | Yes |
|
|
107
|
+
| `PATCH` | Partial update | No | Yes |
|
|
108
|
+
| `DELETE` | Remove | Yes | No |
|
|
109
|
+
|
|
110
|
+
Check each path:
|
|
111
|
+
|
|
112
|
+
- [ ] Path uses plural noun, no verbs
|
|
113
|
+
- [ ] Path parameters are descriptive (`userId` not `id`)
|
|
114
|
+
- [ ] HTTP method matches semantics above
|
|
115
|
+
- [ ] `GET` operations have no request body
|
|
116
|
+
- [ ] `DELETE` operations return `204 No Content` or `200` with body, never `201`
|
|
117
|
+
- [ ] Every operation has a unique `operationId` (camelCase, e.g. `listUsers`, `createOrder`)
|
|
118
|
+
- [ ] Every operation has a `summary` (short title, ≤ 80 chars) and `tags`
|
|
119
|
+
|
|
120
|
+
______________________________________________________________________
|
|
121
|
+
|
|
122
|
+
## Part 3: Status Codes
|
|
123
|
+
|
|
124
|
+
Use exactly these status codes — no others unless justified:
|
|
125
|
+
|
|
126
|
+
| Code | Meaning | When to use |
|
|
127
|
+
| --------------------------- | ----------------------------- | ------------------------------------- |
|
|
128
|
+
| `200 OK` | Success with body | `GET`, `PUT`, `PATCH` success |
|
|
129
|
+
| `201 Created` | Resource created | `POST` creating a resource |
|
|
130
|
+
| `202 Accepted` | Accepted for async processing | Background jobs |
|
|
131
|
+
| `204 No Content` | Success, no body | `DELETE`, `POST` with no return |
|
|
132
|
+
| `400 Bad Request` | Validation error | Invalid input |
|
|
133
|
+
| `401 Unauthorized` | Not authenticated | Missing/invalid token |
|
|
134
|
+
| `403 Forbidden` | Not authorized | Valid token, insufficient permissions |
|
|
135
|
+
| `404 Not Found` | Resource missing | ID doesn't exist |
|
|
136
|
+
| `409 Conflict` | State conflict | Duplicate create, optimistic lock |
|
|
137
|
+
| `422 Unprocessable Entity` | Semantic validation | Business rule violation |
|
|
138
|
+
| `429 Too Many Requests` | Rate limited | Include `Retry-After` header |
|
|
139
|
+
| `500 Internal Server Error` | Unexpected error | Never expose internals |
|
|
140
|
+
|
|
141
|
+
Check:
|
|
142
|
+
|
|
143
|
+
- [ ] Every operation documents all realistic status codes
|
|
144
|
+
- [ ] `200` vs `201` vs `204` used correctly
|
|
145
|
+
- [ ] `401` and `403` are distinct and documented
|
|
146
|
+
- [ ] `500` is documented but never includes stack traces
|
|
147
|
+
|
|
148
|
+
______________________________________________________________________
|
|
149
|
+
|
|
150
|
+
## Part 4: Error Response Schema
|
|
151
|
+
|
|
152
|
+
Every error response must use a consistent schema:
|
|
153
|
+
|
|
154
|
+
```yaml
|
|
155
|
+
components:
|
|
156
|
+
schemas:
|
|
157
|
+
Error:
|
|
158
|
+
type: object
|
|
159
|
+
required: [code, message]
|
|
160
|
+
properties:
|
|
161
|
+
code:
|
|
162
|
+
type: string
|
|
163
|
+
description: Machine-readable error code
|
|
164
|
+
example: "VALIDATION_ERROR"
|
|
165
|
+
message:
|
|
166
|
+
type: string
|
|
167
|
+
description: Human-readable description
|
|
168
|
+
example: "email must be a valid email address"
|
|
169
|
+
details:
|
|
170
|
+
type: array
|
|
171
|
+
description: Field-level validation errors
|
|
172
|
+
items:
|
|
173
|
+
type: object
|
|
174
|
+
required: [field, message]
|
|
175
|
+
properties:
|
|
176
|
+
field:
|
|
177
|
+
type: string
|
|
178
|
+
example: "email"
|
|
179
|
+
message:
|
|
180
|
+
type: string
|
|
181
|
+
example: "must be a valid email address"
|
|
182
|
+
request_id:
|
|
183
|
+
type: string
|
|
184
|
+
description: Correlation ID for tracing
|
|
185
|
+
example: "req_01HZ..."
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Check:
|
|
189
|
+
|
|
190
|
+
- [ ] All `4xx` and `5xx` responses reference `$ref: '#/components/schemas/Error'`
|
|
191
|
+
- [ ] Error schema has a machine-readable `code` field
|
|
192
|
+
- [ ] `request_id` for correlation is present
|
|
193
|
+
- [ ] Field-level errors included for `400`/`422`
|
|
194
|
+
|
|
195
|
+
______________________________________________________________________
|
|
196
|
+
|
|
197
|
+
## Part 5: Pagination
|
|
198
|
+
|
|
199
|
+
Standard cursor-based pagination (preferred for large datasets):
|
|
200
|
+
|
|
201
|
+
```yaml
|
|
202
|
+
# Query parameters
|
|
203
|
+
parameters:
|
|
204
|
+
- name: cursor
|
|
205
|
+
in: query
|
|
206
|
+
schema:
|
|
207
|
+
type: string
|
|
208
|
+
description: Opaque cursor from previous response
|
|
209
|
+
- name: limit
|
|
210
|
+
in: query
|
|
211
|
+
schema:
|
|
212
|
+
type: integer
|
|
213
|
+
minimum: 1
|
|
214
|
+
maximum: 100
|
|
215
|
+
default: 20
|
|
216
|
+
|
|
217
|
+
# Response envelope
|
|
218
|
+
components:
|
|
219
|
+
schemas:
|
|
220
|
+
PaginatedUsers:
|
|
221
|
+
type: object
|
|
222
|
+
required: [data, pagination]
|
|
223
|
+
properties:
|
|
224
|
+
data:
|
|
225
|
+
type: array
|
|
226
|
+
items:
|
|
227
|
+
$ref: '#/components/schemas/User'
|
|
228
|
+
pagination:
|
|
229
|
+
type: object
|
|
230
|
+
required: [has_more]
|
|
231
|
+
properties:
|
|
232
|
+
has_more:
|
|
233
|
+
type: boolean
|
|
234
|
+
next_cursor:
|
|
235
|
+
type: string
|
|
236
|
+
nullable: true
|
|
237
|
+
total:
|
|
238
|
+
type: integer
|
|
239
|
+
description: Total count (expensive — omit if not needed)
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
Check:
|
|
243
|
+
|
|
244
|
+
- [ ] Pagination is cursor-based (not offset for large collections)
|
|
245
|
+
- [ ] `limit` has a maximum and default
|
|
246
|
+
- [ ] Response includes `has_more` and `next_cursor`
|
|
247
|
+
- [ ] `total` is optional (expensive query — only include if needed)
|
|
248
|
+
|
|
249
|
+
______________________________________________________________________
|
|
250
|
+
|
|
251
|
+
## Part 6: Schema Quality
|
|
252
|
+
|
|
253
|
+
For each schema in `components/schemas`:
|
|
254
|
+
|
|
255
|
+
```yaml
|
|
256
|
+
components:
|
|
257
|
+
schemas:
|
|
258
|
+
User:
|
|
259
|
+
type: object
|
|
260
|
+
required: [id, email, created_at] # ← explicit required list
|
|
261
|
+
properties:
|
|
262
|
+
id:
|
|
263
|
+
type: string
|
|
264
|
+
format: uuid
|
|
265
|
+
readOnly: true # ← readOnly for server-generated fields
|
|
266
|
+
example: "01HZ..."
|
|
267
|
+
email:
|
|
268
|
+
type: string
|
|
269
|
+
format: email
|
|
270
|
+
example: "user@example.com"
|
|
271
|
+
name:
|
|
272
|
+
type: string
|
|
273
|
+
minLength: 1
|
|
274
|
+
maxLength: 255
|
|
275
|
+
example: "Alice"
|
|
276
|
+
created_at:
|
|
277
|
+
type: string
|
|
278
|
+
format: date-time
|
|
279
|
+
readOnly: true
|
|
280
|
+
example: "2026-01-01T00:00:00Z"
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
Check:
|
|
284
|
+
|
|
285
|
+
- [ ] All schemas have a `required` list (no implicit optionals)
|
|
286
|
+
- [ ] `id`, `created_at`, `updated_at` are `readOnly: true`
|
|
287
|
+
- [ ] All string fields have `minLength`/`maxLength` where appropriate
|
|
288
|
+
- [ ] All fields have an `example`
|
|
289
|
+
- [ ] `format` used for `uuid`, `email`, `date-time`, `uri`
|
|
290
|
+
- [ ] No `type: object` without properties (use `additionalProperties` explicitly)
|
|
291
|
+
- [ ] No circular `$ref` without a nullable break
|
|
292
|
+
|
|
293
|
+
______________________________________________________________________
|
|
294
|
+
|
|
295
|
+
## Part 7: Security Schemes
|
|
296
|
+
|
|
297
|
+
```yaml
|
|
298
|
+
components:
|
|
299
|
+
securitySchemes:
|
|
300
|
+
bearerAuth:
|
|
301
|
+
type: http
|
|
302
|
+
scheme: bearer
|
|
303
|
+
bearerFormat: JWT
|
|
304
|
+
apiKey:
|
|
305
|
+
type: apiKey
|
|
306
|
+
in: header
|
|
307
|
+
name: X-API-Key
|
|
308
|
+
|
|
309
|
+
security:
|
|
310
|
+
- bearerAuth: [] # Global default
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
Override at operation level where needed:
|
|
314
|
+
|
|
315
|
+
```yaml
|
|
316
|
+
paths:
|
|
317
|
+
/health:
|
|
318
|
+
get:
|
|
319
|
+
security: [] # Public endpoint — no auth required
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
Check:
|
|
323
|
+
|
|
324
|
+
- [ ] Security scheme is defined in `components.securitySchemes`
|
|
325
|
+
- [ ] Global `security` set at root level
|
|
326
|
+
- [ ] Public endpoints explicitly override with `security: []`
|
|
327
|
+
- [ ] OAuth2 scopes are defined if using OAuth
|
|
328
|
+
- [ ] No API keys in query parameters (use headers)
|
|
329
|
+
|
|
330
|
+
______________________________________________________________________
|
|
331
|
+
|
|
332
|
+
## Part 8: Versioning
|
|
333
|
+
|
|
334
|
+
URI versioning is the recommended approach:
|
|
335
|
+
|
|
336
|
+
```yaml
|
|
337
|
+
servers:
|
|
338
|
+
- url: https://api.example.com/v1
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
Check:
|
|
342
|
+
|
|
343
|
+
- [ ] Version in server URL (`/v1`, `/v2`)
|
|
344
|
+
- [ ] No minor versions in URL (`/v1.1` is wrong — use headers for minor)
|
|
345
|
+
- [ ] Deprecated operations tagged with `deprecated: true`
|
|
346
|
+
- [ ] Deprecated operations have a `x-sunset` date
|
|
347
|
+
|
|
348
|
+
```yaml
|
|
349
|
+
/users/{userId}:
|
|
350
|
+
get:
|
|
351
|
+
deprecated: true
|
|
352
|
+
x-sunset: "2027-01-01"
|
|
353
|
+
description: "Deprecated. Use /v2/users/{userId} instead."
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
______________________________________________________________________
|
|
357
|
+
|
|
358
|
+
## Output
|
|
359
|
+
|
|
360
|
+
Produce a review report or the corrected spec:
|
|
361
|
+
|
|
362
|
+
**Review report format:**
|
|
363
|
+
|
|
364
|
+
```text
|
|
365
|
+
OpenAPI Spec Review
|
|
366
|
+
═══════════════════
|
|
367
|
+
|
|
368
|
+
Spec: [filename]
|
|
369
|
+
Version: [openapi version]
|
|
370
|
+
Paths: [count]
|
|
371
|
+
Schemas: [count]
|
|
372
|
+
|
|
373
|
+
Issues:
|
|
374
|
+
🔴 CRITICAL: [issue] — [path/operation]
|
|
375
|
+
🟡 WARNING: [issue] — [path/operation]
|
|
376
|
+
🟢 INFO: [suggestion]
|
|
377
|
+
|
|
378
|
+
Summary: [N critical, N warnings, N info]
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
**If writing or correcting the spec:** produce the complete corrected YAML, using
|
|
382
|
+
`$ref` for all reusable schemas, and validate it passes linting.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
name: performance
|
|
2
|
+
version: 1.0.2
|
|
3
|
+
description: |
|
|
4
|
+
Performance profiling and regression detection. Establishes baselines, detects
|
|
5
|
+
regressions, profiles bottlenecks, and recommends optimizations. Use when asked
|
|
6
|
+
to "profile", "benchmark", "performance test", or "is this faster?".
|
|
7
|
+
argument-hint: '[endpoint or function to profile]'
|
|
8
|
+
|
|
9
|
+
license: MIT
|
|
10
|
+
compatibility: Requires a skills-compatible agent with repository file access and terminal command execution when needed.
|
|
11
|
+
metadata:
|
|
12
|
+
owner: vstack
|
|
13
|
+
maturity: stable
|
|
14
|
+
user-invocable: true
|
|
15
|
+
disable-model-invocation: false
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
{{SKILL_CONTEXT}}
|
|
2
|
+
|
|
3
|
+
{{BASE_BRANCH}}
|
|
4
|
+
|
|
5
|
+
# performance — Profile, Benchmark & Regression Detection
|
|
6
|
+
|
|
7
|
+
Profile backend services, detect performance regressions, and recommend
|
|
8
|
+
optimizations. Measure first; never optimize without evidence.
|
|
9
|
+
|
|
10
|
+
## Out of scope
|
|
11
|
+
|
|
12
|
+
- Full code review (use `code-review`)
|
|
13
|
+
- Security analysis (use `security`)
|
|
14
|
+
- Architecture design (use `architecture`)
|
|
15
|
+
- Non-performance bug fixing (use `debug`)
|
|
16
|
+
|
|
17
|
+
## Deliverable and artifact policy
|
|
18
|
+
|
|
19
|
+
- Primary deliverable: `docs/performance-baseline.md`
|
|
20
|
+
- Baseline-first default: write benchmark outcomes and regression verdicts directly to `docs/performance-baseline.md` on the feature branch.
|
|
21
|
+
- Optional WIP area for complex/uncertain efforts: `docs/delta/{id}/PERFORMANCE_DELTA.md`
|
|
22
|
+
- Before merge: consolidate thresholds, measurements, and recommendations into the baseline performance report.
|
|
23
|
+
|
|
24
|
+
______________________________________________________________________
|
|
25
|
+
|
|
26
|
+
## Setup
|
|
27
|
+
|
|
28
|
+
**Parse the user's request:**
|
|
29
|
+
|
|
30
|
+
| Parameter | Default | Override |
|
|
31
|
+
| --------- | --------------------------- | ---------------------------------------- |
|
|
32
|
+
| Target | Whole service / entry point | `Focus on the /search endpoint` |
|
|
33
|
+
| Mode | Comparison (vs base branch) | `--baseline`, `--profile`, `--load-test` |
|
|
34
|
+
| Threshold | 5% regression | `--threshold 0.10` (10%) |
|
|
35
|
+
|
|
36
|
+
______________________________________________________________________
|
|
37
|
+
|
|
38
|
+
## Phase 1: Establish Baseline
|
|
39
|
+
|
|
40
|
+
If on a feature branch, record performance metrics before and after the change:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# Record current branch metrics
|
|
44
|
+
CURRENT=$(git branch --show-current)
|
|
45
|
+
|
|
46
|
+
# Run benchmarks
|
|
47
|
+
echo "=== Benchmarks on $CURRENT ==="
|
|
48
|
+
{{RUN_TESTS}}
|
|
49
|
+
|
|
50
|
+
# Language-specific benchmark runners:
|
|
51
|
+
# Node/Bun
|
|
52
|
+
[ -f package.json ] && npm run bench 2>/dev/null \
|
|
53
|
+
|| npx vitest bench 2>/dev/null \
|
|
54
|
+
|| npx jest --config jest.bench.config.js 2>/dev/null || true
|
|
55
|
+
|
|
56
|
+
# Python
|
|
57
|
+
[ -f pyproject.toml ] && python -m pytest --benchmark-only -v 2>/dev/null || true
|
|
58
|
+
|
|
59
|
+
# Go
|
|
60
|
+
[ -f go.mod ] && go test -bench=. -benchmem ./... 2>/dev/null || true
|
|
61
|
+
|
|
62
|
+
# Rust
|
|
63
|
+
[ -f Cargo.toml ] && cargo bench 2>/dev/null || true
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
______________________________________________________________________
|
|
67
|
+
|
|
68
|
+
## Phase 2: Comparison vs Base Branch
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# Stash current changes and benchmark base
|
|
72
|
+
git stash
|
|
73
|
+
git checkout <base>
|
|
74
|
+
|
|
75
|
+
echo "=== Benchmarks on <base> ==="
|
|
76
|
+
# [run same benchmark commands as Phase 1]
|
|
77
|
+
|
|
78
|
+
# Restore feature branch
|
|
79
|
+
git checkout "$CURRENT"
|
|
80
|
+
git stash pop
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Compare results:
|
|
84
|
+
|
|
85
|
+
- p50 latency change
|
|
86
|
+
- p95/p99 latency change
|
|
87
|
+
- Throughput (ops/second) change
|
|
88
|
+
- Memory allocation change
|
|
89
|
+
- CPU usage change
|
|
90
|
+
|
|
91
|
+
**Regression threshold:** Flag if any metric degrades by more than 5% (or configured threshold).
|
|
92
|
+
|
|
93
|
+
______________________________________________________________________
|
|
94
|
+
|
|
95
|
+
## Phase 3: Load Testing (if applicable)
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# Check for load test tools
|
|
99
|
+
which k6 2>/dev/null && echo "k6 available"
|
|
100
|
+
which hey 2>/dev/null && echo "hey available"
|
|
101
|
+
which wrk 2>/dev/null && echo "wrk available"
|
|
102
|
+
which ab 2>/dev/null && echo "ab available"
|
|
103
|
+
|
|
104
|
+
# Example k6 run (adapt to your endpoint)
|
|
105
|
+
# k6 run --vus 50 --duration 30s script.js
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
For API endpoints, run a basic load test:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
# Using hey (install: go install github.com/rakyll/hey@latest)
|
|
112
|
+
hey -n 1000 -c 50 "${SERVICE_URL}/health" 2>/dev/null || true
|
|
113
|
+
|
|
114
|
+
# Using wrk (if available)
|
|
115
|
+
wrk -t4 -c100 -d30s "${SERVICE_URL}/health" 2>/dev/null || true
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
______________________________________________________________________
|
|
119
|
+
|
|
120
|
+
## Phase 4: Profiling (if regression found)
|
|
121
|
+
|
|
122
|
+
If a regression is detected, profile to identify the bottleneck:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
# Node.js profiling
|
|
126
|
+
node --prof app.js &
|
|
127
|
+
# ...run workload...
|
|
128
|
+
node --prof-process isolate-*.log > profile.txt
|
|
129
|
+
|
|
130
|
+
# Python profiling
|
|
131
|
+
python -m cProfile -o profile.prof app.py
|
|
132
|
+
python -m pstats profile.prof
|
|
133
|
+
|
|
134
|
+
# Go pprof
|
|
135
|
+
go tool pprof cpu.prof
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Common bottleneck categories:
|
|
139
|
+
|
|
140
|
+
- **N+1 queries:** Multiple DB calls where one would suffice
|
|
141
|
+
- **Serialization:** JSON marshal/unmarshal overhead
|
|
142
|
+
- **Lock contention:** Mutex/lock held too long
|
|
143
|
+
- **Memory allocation:** GC pressure from excessive allocations
|
|
144
|
+
- **Missing cache:** Repeated computation of the same result
|
|
145
|
+
- **Sync where async:** Blocking I/O on hot path
|
|
146
|
+
- **Regex compilation:** Regex compiled inside hot loop
|
|
147
|
+
|
|
148
|
+
______________________________________________________________________
|
|
149
|
+
|
|
150
|
+
## Phase 5: Optimization Loop
|
|
151
|
+
|
|
152
|
+
For each bottleneck identified:
|
|
153
|
+
|
|
154
|
+
1. Propose the optimization with rationale
|
|
155
|
+
1. Implement
|
|
156
|
+
1. Re-benchmark
|
|
157
|
+
1. Confirm improvement
|
|
158
|
+
|
|
159
|
+
**Optimization principles:**
|
|
160
|
+
|
|
161
|
+
- Measure first, optimize second. Never guess what's slow.
|
|
162
|
+
- Profile the real workload, not synthetic microbenchmarks.
|
|
163
|
+
- Big-O matters more than constant factors.
|
|
164
|
+
- Cache invalidation is a correctness problem, not just a performance trick.
|
|
165
|
+
- Async I/O > sync I/O for I/O-bound work.
|
|
166
|
+
- Batch > N individual calls.
|
|
167
|
+
|
|
168
|
+
______________________________________________________________________
|
|
169
|
+
|
|
170
|
+
## Performance Report
|
|
171
|
+
|
|
172
|
+
```text
|
|
173
|
+
## Performance Report — [service/endpoint] — [date]
|
|
174
|
+
|
|
175
|
+
### Benchmark Results
|
|
176
|
+
|
|
177
|
+
| Metric | Base | Current | Change | Status |
|
|
178
|
+
|--------|------|---------|--------|--------|
|
|
179
|
+
| p50 latency | Xms | Xms | +N% | ✓/✗ |
|
|
180
|
+
| p95 latency | Xms | Xms | +N% | ✓/✗ |
|
|
181
|
+
| p99 latency | Xms | Xms | +N% | ✓/✗ |
|
|
182
|
+
| Throughput (rps) | X | X | +N% | ✓/✗ |
|
|
183
|
+
| Memory (MB) | X | X | +N% | ✓/✗ |
|
|
184
|
+
|
|
185
|
+
### Regressions Found
|
|
186
|
+
[NONE / List regressions]
|
|
187
|
+
|
|
188
|
+
### Bottlenecks Identified
|
|
189
|
+
1. [Bottleneck] — [Evidence] — [Recommended fix]
|
|
190
|
+
|
|
191
|
+
### Optimizations Applied
|
|
192
|
+
1. [Change] — [Before: Xms → After: Xms] — [Commit SHA]
|
|
193
|
+
|
|
194
|
+
### Verdict
|
|
195
|
+
[NO REGRESSION / REGRESSION FIXED / REGRESSION NEEDS ATTENTION]
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
______________________________________________________________________
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
name: pr
|
|
2
|
+
version: 1.0.2
|
|
3
|
+
description: |
|
|
4
|
+
Commit, push, and open a pull request from the current branch to main.
|
|
5
|
+
Uses the release notes from docs/releases/{date}.md as the PR body.
|
|
6
|
+
Use when asked to "open a PR", "push and create PR", or "submit for review".
|
|
7
|
+
|
|
8
|
+
license: MIT
|
|
9
|
+
compatibility: Requires a skills-compatible agent with repository file access and terminal command execution when needed.
|
|
10
|
+
metadata:
|
|
11
|
+
owner: vstack
|
|
12
|
+
maturity: stable
|
|
13
|
+
argument-hint: '[task]'
|
|
14
|
+
user-invocable: true
|
|
15
|
+
disable-model-invocation: false
|