specweave 1.0.261 → 1.0.262
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/README.md +0 -2
- package/CLAUDE.md +27 -27
- package/bin/specweave.js +14 -85
- package/dist/dashboard/assets/index-Cv1XUAKk.css +1 -0
- package/dist/dashboard/assets/index-DHOztQSu.js +11 -0
- package/dist/dashboard/index.html +2 -2
- package/dist/src/adapters/README.md +1 -1
- package/dist/src/adapters/agents-md-generator.js +1 -1
- package/dist/src/adapters/agents-md-generator.js.map +1 -1
- package/dist/src/adapters/claude/README.md +8 -8
- package/dist/src/adapters/claude/adapter.js +2 -2
- package/dist/src/adapters/claude-md-generator.js +2 -2
- package/dist/src/adapters/claude-md-generator.js.map +1 -1
- package/dist/src/adapters/cursor/README.md +7 -7
- package/dist/src/adapters/generic/README.md +2 -2
- package/dist/src/cli/commands/create-increment.d.ts +1 -1
- package/dist/src/cli/commands/create-increment.js +1 -1
- package/dist/src/cli/commands/update.d.ts.map +1 -1
- package/dist/src/cli/commands/update.js +64 -1
- package/dist/src/cli/commands/update.js.map +1 -1
- package/dist/src/cli/helpers/init/api-docs-config.js +7 -7
- package/dist/src/cli/helpers/init/api-docs-config.js.map +1 -1
- package/dist/src/core/config/types.d.ts +18 -0
- package/dist/src/core/config/types.d.ts.map +1 -1
- package/dist/src/core/config/types.js +4 -0
- package/dist/src/core/config/types.js.map +1 -1
- package/dist/src/core/external-tools/external-items-display.d.ts.map +1 -1
- package/dist/src/core/external-tools/external-items-display.js +1 -11
- package/dist/src/core/external-tools/external-items-display.js.map +1 -1
- package/dist/src/core/increment/increment-archiver.js +1 -1
- package/dist/src/core/increment/increment-archiver.js.map +1 -1
- package/dist/src/core/increment/metadata-manager.js +2 -2
- package/dist/src/core/increment/metadata-manager.js.map +1 -1
- package/dist/src/core/increment/template-creator.d.ts +1 -1
- package/dist/src/core/increment/template-creator.js +4 -4
- package/dist/src/core/lazy-loading/llm-plugin-detector.d.ts +2 -2
- package/dist/src/core/lazy-loading/llm-plugin-detector.d.ts.map +1 -1
- package/dist/src/core/lazy-loading/llm-plugin-detector.js +15 -5
- package/dist/src/core/lazy-loading/llm-plugin-detector.js.map +1 -1
- package/dist/src/core/living-docs/feature-consistency-validator.js +1 -1
- package/dist/src/core/living-docs/feature-consistency-validator.js.map +1 -1
- package/dist/src/core/living-docs/scaffolding/scaffold.js +3 -3
- package/dist/src/core/notifications/command-integration.d.ts.map +1 -1
- package/dist/src/core/notifications/command-integration.js +0 -1
- package/dist/src/core/notifications/command-integration.js.map +1 -1
- package/dist/src/core/reflection/reflect-handler.js +2 -2
- package/dist/src/core/reflection/reflect-handler.js.map +1 -1
- package/dist/src/core/validators/ac-presence-validator.d.ts +1 -1
- package/dist/src/core/validators/ac-presence-validator.js +3 -3
- package/dist/src/core/validators/ac-presence-validator.js.map +1 -1
- package/dist/src/dashboard/server/command-runner.d.ts.map +1 -1
- package/dist/src/dashboard/server/command-runner.js +2 -2
- package/dist/src/dashboard/server/command-runner.js.map +1 -1
- package/dist/src/dashboard/server/dashboard-server.d.ts.map +1 -1
- package/dist/src/dashboard/server/dashboard-server.js +20 -9
- package/dist/src/dashboard/server/dashboard-server.js.map +1 -1
- package/dist/src/utils/agents-md-compiler.js +1 -1
- package/dist/src/utils/agents-md-compiler.js.map +1 -1
- package/dist/src/utils/find-project-root.d.ts +5 -4
- package/dist/src/utils/find-project-root.d.ts.map +1 -1
- package/dist/src/utils/find-project-root.js +8 -10
- package/dist/src/utils/find-project-root.js.map +1 -1
- package/dist/src/utils/generate-skills-index.js +3 -3
- package/dist/src/utils/notification-constants.js +1 -1
- package/dist/src/utils/notification-constants.js.map +1 -1
- package/package.json +1 -1
- package/plugins/FINAL-AUDIT-RECOMMENDATIONS.md +3 -3
- package/plugins/specweave/PLUGIN.md +0 -22
- package/plugins/specweave/commands/analytics.md +1 -1
- package/plugins/specweave/commands/discrepancies.md +0 -1
- package/plugins/specweave/commands/living-docs.md +0 -1
- package/plugins/specweave/commands/reconcile.md +1 -1
- package/plugins/specweave/hooks/hooks.json +10 -0
- package/plugins/specweave/hooks/pre-compact.sh +39 -0
- package/plugins/specweave/hooks/stop-sync.sh +23 -1
- package/plugins/specweave/hooks/universal/fail-fast-wrapper.sh +4 -0
- package/plugins/specweave/hooks/user-prompt-submit.sh +193 -59
- package/plugins/specweave/hooks/v2/dispatchers/session-start.sh +7 -0
- package/plugins/specweave/hooks/v2/guards/spec-template-enforcement-guard.sh +1 -1
- package/plugins/specweave/hooks/v2/handlers/ac-sync-dispatcher.sh +25 -6
- package/plugins/specweave/hooks/v2/handlers/universal-auto-create-dispatcher.sh +21 -3
- package/plugins/specweave/hooks/v2/lib/check-provider-enabled.sh +52 -0
- package/plugins/specweave/lib/vendor/core/increment/metadata-manager.js +2 -2
- package/plugins/specweave/lib/vendor/core/increment/metadata-manager.js.map +1 -1
- package/plugins/specweave/skills/do/SKILL.md +1 -1
- package/plugins/specweave/skills/done/SKILL.md +1 -1
- package/plugins/specweave/skills/framework/SKILL.md +4 -4
- package/plugins/specweave/skills/increment/SKILL.md +192 -25
- package/plugins/specweave/skills/next/SKILL.md +36 -630
- package/plugins/specweave/skills/pm/phases/00-deep-interview.md +2 -2
- package/plugins/specweave/skills/progress-sync/SKILL.md +7 -25
- package/plugins/specweave/skills/spec-generator/SKILL.md +44 -626
- package/plugins/specweave/skills/tdd-green/SKILL.md +10 -798
- package/plugins/specweave/skills/tdd-red/SKILL.md +8 -136
- package/plugins/specweave/skills/tdd-refactor/SKILL.md +15 -147
- package/plugins/specweave-github/hooks/github-auto-create-handler.sh +23 -5
- package/src/templates/AGENTS.md.template +11 -11
- package/src/templates/CLAUDE.md.template +1 -1
- package/dist/dashboard/assets/index-CDl14O5G.css +0 -1
- package/dist/dashboard/assets/index-CmqBqnWd.js +0 -11
- package/plugins/specweave/commands/api-docs.md +0 -672
- package/plugins/specweave/commands/check-hooks.md +0 -241
- package/plugins/specweave/commands/embed-acs.md +0 -445
- package/plugins/specweave/commands/external.md +0 -145
- package/plugins/specweave/commands/import-docs.md +0 -212
- package/plugins/specweave/commands/migrate-config.md +0 -104
- package/plugins/specweave/commands/notifications.md +0 -94
- package/plugins/specweave/commands/plugin-validator.md +0 -429
- package/plugins/specweave/commands/revert-wip-limit.md +0 -82
- package/plugins/specweave/commands/sync-acs.md +0 -342
- package/plugins/specweave/commands/sync-specs.md +0 -339
- package/plugins/specweave/commands/sync-tasks.md +0 -255
- package/plugins/specweave/commands/update-scope.md +0 -351
- package/plugins/specweave/commands/validate-features.md +0 -207
- package/plugins/specweave/skills/archive-increments/SKILL.md +0 -209
- package/plugins/specweave/skills/code-review/SKILL.md +0 -598
- package/plugins/specweave/skills/increment-planner/SKILL.md +0 -238
- package/plugins/specweave/skills/increment-work-router/SKILL.md +0 -562
- package/plugins/specweave/skills/multi-project-spec-mapper/SKILL.md +0 -423
- package/plugins/specweave/skills/pm-closure-validation/SKILL.md +0 -542
- package/plugins/specweave/skills/smart-reopen-detector/SKILL.md +0 -245
- package/plugins/specweave/skills/tdd-orchestrator/SKILL.md +0 -228
- package/plugins/specweave/skills/umbrella-repo-detector/SKILL.md +0 -301
|
@@ -1,672 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Generate and synchronize API documentation - OpenAPI spec, Postman collection with environments, and API client SDKs. Framework-aware with auto-detection. For API projects only.
|
|
3
|
-
argument-hint: [--openapi] [--postman] [--all] [--validate]
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# API Documentation Generator
|
|
7
|
-
|
|
8
|
-
**Usage**: `/sw:api-docs [options]`
|
|
9
|
-
|
|
10
|
-
**For REST API projects only.** Skip if your project has no REST endpoints.
|
|
11
|
-
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
## Limitations
|
|
15
|
-
|
|
16
|
-
This command is designed for **REST APIs with OpenAPI specification**. The following API types are NOT supported:
|
|
17
|
-
|
|
18
|
-
| API Type | Why Not Supported | Alternative |
|
|
19
|
-
|----------|-------------------|-------------|
|
|
20
|
-
| **GraphQL** | Uses SDL schema, not OpenAPI | Export schema via `apollo schema:download` or GraphQL introspection |
|
|
21
|
-
| **gRPC** | Uses Protocol Buffers (.proto), not OpenAPI | Use `protoc` with documentation plugins |
|
|
22
|
-
| **WebSocket** | No standard specification format | Document in README or use AsyncAPI |
|
|
23
|
-
| **tRPC** | TypeScript-first, schema inferred | Types are the documentation |
|
|
24
|
-
|
|
25
|
-
For these API types, use their native specification formats instead of OpenAPI.
|
|
26
|
-
|
|
27
|
-
---
|
|
28
|
-
|
|
29
|
-
## Purpose
|
|
30
|
-
|
|
31
|
-
Generate and maintain API documentation artifacts:
|
|
32
|
-
- **OpenAPI specification** (source of truth)
|
|
33
|
-
- **Postman collection** (derived from OpenAPI)
|
|
34
|
-
- **Postman environment file** (derived from .env)
|
|
35
|
-
- **API client SDKs** (optional, TypeScript/Python)
|
|
36
|
-
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
## Command Options
|
|
40
|
-
|
|
41
|
-
| Option | Description |
|
|
42
|
-
|--------|-------------|
|
|
43
|
-
| (none) | Interactive mode - auto-detects framework and prompts |
|
|
44
|
-
| `--openapi` | Generate/update OpenAPI spec only |
|
|
45
|
-
| `--postman` | Generate Postman collection from OpenAPI |
|
|
46
|
-
| `--env` | Generate Postman environment from .env |
|
|
47
|
-
| `--all` | Generate all artifacts (OpenAPI + Postman + env) |
|
|
48
|
-
| `--watch` | Watch for API changes and regenerate |
|
|
49
|
-
| `--validate` | Validate existing OpenAPI spec |
|
|
50
|
-
| `--framework <name>` | Override framework detection (nest, express, fastapi, etc.) |
|
|
51
|
-
| `--base-url <url>` | Override base URL for generated collection |
|
|
52
|
-
| `--output <dir>` | Output directory (default: project root) |
|
|
53
|
-
|
|
54
|
-
---
|
|
55
|
-
|
|
56
|
-
## Quick Start
|
|
57
|
-
|
|
58
|
-
### Generate Everything (Recommended)
|
|
59
|
-
|
|
60
|
-
```bash
|
|
61
|
-
/sw:api-docs --all
|
|
62
|
-
|
|
63
|
-
# Output:
|
|
64
|
-
# ✅ Generated: openapi.yaml (127 endpoints)
|
|
65
|
-
# ✅ Generated: postman-collection.json (imported openapi.yaml)
|
|
66
|
-
# ✅ Generated: postman-environment.json (12 variables from .env)
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
### Interactive Mode
|
|
70
|
-
|
|
71
|
-
```bash
|
|
72
|
-
/sw:api-docs
|
|
73
|
-
|
|
74
|
-
# Prompts:
|
|
75
|
-
# 1. Detected framework: NestJS (src/main.ts)
|
|
76
|
-
# 2. Generate OpenAPI from decorators? [Y/n]
|
|
77
|
-
# 3. Generate Postman collection? [Y/n]
|
|
78
|
-
# 4. Generate environment file? [Y/n]
|
|
79
|
-
# 5. Watch for changes? [y/N]
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
---
|
|
83
|
-
|
|
84
|
-
## Framework Detection & Generation
|
|
85
|
-
|
|
86
|
-
### Supported Frameworks
|
|
87
|
-
|
|
88
|
-
| Framework | Detection | OpenAPI Generation Method |
|
|
89
|
-
|-----------|-----------|---------------------------|
|
|
90
|
-
| **NestJS** | `@nestjs/swagger` in package.json | Extract from decorators via `SwaggerModule.createDocument()` |
|
|
91
|
-
| **Express + swagger-jsdoc** | `swagger-jsdoc` in package.json | Generate from JSDoc comments |
|
|
92
|
-
| **Fastify** | `@fastify/swagger` in package.json | Extract from route schemas |
|
|
93
|
-
| **Hono** | `@hono/swagger-ui` in package.json | Generate from Zod schemas |
|
|
94
|
-
| **Next.js API Routes** | `pages/api/` or `app/api/` folders | Parse route handlers, infer from types |
|
|
95
|
-
| **FastAPI** | `fastapi` in requirements.txt | Export from `/openapi.json` endpoint |
|
|
96
|
-
| **Django REST** | `djangorestframework` in requirements.txt | Use `generateschema` management command |
|
|
97
|
-
| **Flask** | `flask-restx` or `apispec` in requirements.txt | Extract from decorators or specs |
|
|
98
|
-
| **Spring Boot** | `springdoc-openapi` in pom.xml/build.gradle | Export from `/v3/api-docs` endpoint |
|
|
99
|
-
| **Go/Gin** | `swaggo/swag` in go.mod | Run `swag init` |
|
|
100
|
-
| **Go/Echo** | `swaggo/echo-swagger` in go.mod | Run `swag init` |
|
|
101
|
-
|
|
102
|
-
---
|
|
103
|
-
|
|
104
|
-
## Implementation Steps
|
|
105
|
-
|
|
106
|
-
### Step 1: Detect Framework and Config
|
|
107
|
-
|
|
108
|
-
```typescript
|
|
109
|
-
import { detectApiFramework, loadApiDocsConfig } from '../../../src/cli/helpers/init/api-docs-config.js';
|
|
110
|
-
|
|
111
|
-
// Check if API docs enabled in config
|
|
112
|
-
const config = loadConfig(projectPath);
|
|
113
|
-
if (!config.apiDocs?.enabled) {
|
|
114
|
-
console.log(`
|
|
115
|
-
ℹ️ API documentation not enabled for this project.
|
|
116
|
-
|
|
117
|
-
To enable:
|
|
118
|
-
1. Run: specweave init (and answer yes to API docs)
|
|
119
|
-
2. Or add to .specweave/config.json:
|
|
120
|
-
"apiDocs": { "enabled": true }
|
|
121
|
-
|
|
122
|
-
This feature is for API projects only.
|
|
123
|
-
`);
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// Detect framework
|
|
128
|
-
const framework = await detectApiFramework(projectPath);
|
|
129
|
-
console.log(`🔍 Detected framework: ${framework.name} (${framework.confidence}% confidence)`);
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
### Step 2: Generate OpenAPI Specification
|
|
133
|
-
|
|
134
|
-
Based on detected framework:
|
|
135
|
-
|
|
136
|
-
#### NestJS (Decorators)
|
|
137
|
-
|
|
138
|
-
```typescript
|
|
139
|
-
// Option 1: Run application and extract OpenAPI
|
|
140
|
-
const openApiSpec = await generateNestJsOpenApi(projectPath);
|
|
141
|
-
|
|
142
|
-
// Option 2: Start dev server temporarily
|
|
143
|
-
// npm run start:dev & sleep 5 && curl localhost:3000/api-json > openapi.json
|
|
144
|
-
|
|
145
|
-
// Typical NestJS OpenAPI generation:
|
|
146
|
-
async function generateNestJsOpenApi(projectPath: string): Promise<OpenAPIObject> {
|
|
147
|
-
// Check if swagger module installed
|
|
148
|
-
const hasSwagger = await checkDependency(projectPath, '@nestjs/swagger');
|
|
149
|
-
if (!hasSwagger) {
|
|
150
|
-
throw new Error('Install @nestjs/swagger: npm install @nestjs/swagger swagger-ui-express');
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// Look for existing swagger setup
|
|
154
|
-
const mainTs = await findFile(projectPath, 'src/main.ts');
|
|
155
|
-
const hasSwaggerSetup = /SwaggerModule\.setup/.test(mainTs);
|
|
156
|
-
|
|
157
|
-
if (hasSwaggerSetup) {
|
|
158
|
-
// Start server and fetch OpenAPI
|
|
159
|
-
const result = await runCommand('npm run start:dev &');
|
|
160
|
-
await sleep(5000);
|
|
161
|
-
const openapi = await fetch('http://localhost:3000/api-json');
|
|
162
|
-
await runCommand('pkill -f "nest start"');
|
|
163
|
-
return openapi.json();
|
|
164
|
-
} else {
|
|
165
|
-
// Suggest adding swagger setup
|
|
166
|
-
console.log(`
|
|
167
|
-
⚠️ Swagger not configured in main.ts
|
|
168
|
-
|
|
169
|
-
Add this to src/main.ts:
|
|
170
|
-
|
|
171
|
-
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
|
|
172
|
-
|
|
173
|
-
const config = new DocumentBuilder()
|
|
174
|
-
.setTitle('Your API')
|
|
175
|
-
.setVersion('1.0')
|
|
176
|
-
.build();
|
|
177
|
-
const document = SwaggerModule.createDocument(app, config);
|
|
178
|
-
SwaggerModule.setup('api', app, document);
|
|
179
|
-
`);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
#### Express + swagger-jsdoc
|
|
185
|
-
|
|
186
|
-
```typescript
|
|
187
|
-
async function generateExpressOpenApi(projectPath: string): Promise<OpenAPIObject> {
|
|
188
|
-
// Look for swagger-jsdoc config
|
|
189
|
-
const swaggerConfig = await findSwaggerJsdocConfig(projectPath);
|
|
190
|
-
|
|
191
|
-
if (swaggerConfig) {
|
|
192
|
-
// Run swagger-jsdoc CLI
|
|
193
|
-
const result = await runCommand(`npx swagger-jsdoc -d ${swaggerConfig} -o openapi.json`);
|
|
194
|
-
return JSON.parse(await readFile('openapi.json'));
|
|
195
|
-
} else {
|
|
196
|
-
// Suggest adding JSDoc comments
|
|
197
|
-
console.log(`
|
|
198
|
-
⚠️ No swagger-jsdoc configuration found
|
|
199
|
-
|
|
200
|
-
Create swagger-config.js:
|
|
201
|
-
|
|
202
|
-
module.exports = {
|
|
203
|
-
definition: {
|
|
204
|
-
openapi: '3.0.0',
|
|
205
|
-
info: { title: 'Your API', version: '1.0.0' },
|
|
206
|
-
servers: [{ url: 'http://localhost:3000' }]
|
|
207
|
-
},
|
|
208
|
-
apis: ['./src/routes/*.js']
|
|
209
|
-
};
|
|
210
|
-
|
|
211
|
-
Then add JSDoc comments to routes:
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* @openapi
|
|
215
|
-
* /users:
|
|
216
|
-
* get:
|
|
217
|
-
* summary: Get all users
|
|
218
|
-
* responses:
|
|
219
|
-
* 200:
|
|
220
|
-
* description: List of users
|
|
221
|
-
*/
|
|
222
|
-
`);
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
#### FastAPI (Python)
|
|
228
|
-
|
|
229
|
-
```typescript
|
|
230
|
-
async function generateFastApiOpenApi(projectPath: string): Promise<OpenAPIObject> {
|
|
231
|
-
// FastAPI auto-generates OpenAPI at /openapi.json
|
|
232
|
-
// Start server and fetch
|
|
233
|
-
await runCommand('uvicorn main:app &');
|
|
234
|
-
await sleep(3000);
|
|
235
|
-
const openapi = await fetch('http://localhost:8000/openapi.json');
|
|
236
|
-
await runCommand('pkill -f uvicorn');
|
|
237
|
-
return openapi.json();
|
|
238
|
-
}
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
### Step 3: Generate Postman Collection from OpenAPI
|
|
242
|
-
|
|
243
|
-
```typescript
|
|
244
|
-
import { convert as openApiToPostman } from 'openapi-to-postmanv2';
|
|
245
|
-
|
|
246
|
-
async function generatePostmanCollection(
|
|
247
|
-
openApiPath: string,
|
|
248
|
-
outputPath: string,
|
|
249
|
-
baseUrl: string
|
|
250
|
-
): Promise<void> {
|
|
251
|
-
const openApiContent = await readFile(openApiPath, 'utf-8');
|
|
252
|
-
|
|
253
|
-
const options = {
|
|
254
|
-
type: 'string',
|
|
255
|
-
data: openApiContent
|
|
256
|
-
};
|
|
257
|
-
|
|
258
|
-
return new Promise((resolve, reject) => {
|
|
259
|
-
openApiToPostman.convert(options, {}, (err, conversionResult) => {
|
|
260
|
-
if (!conversionResult.result) {
|
|
261
|
-
reject(new Error(`Conversion failed: ${conversionResult.reason}`));
|
|
262
|
-
return;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
const collection = conversionResult.output[0].data;
|
|
266
|
-
|
|
267
|
-
// Enhance collection with baseUrl variable
|
|
268
|
-
collection.variable = collection.variable || [];
|
|
269
|
-
collection.variable.push({
|
|
270
|
-
key: 'baseUrl',
|
|
271
|
-
value: baseUrl,
|
|
272
|
-
type: 'string'
|
|
273
|
-
});
|
|
274
|
-
|
|
275
|
-
// Replace hardcoded URLs with {{baseUrl}}
|
|
276
|
-
const collectionStr = JSON.stringify(collection, null, 2)
|
|
277
|
-
.replace(new RegExp(escapeRegex(baseUrl), 'g'), '{{baseUrl}}');
|
|
278
|
-
|
|
279
|
-
await writeFile(outputPath, collectionStr);
|
|
280
|
-
resolve();
|
|
281
|
-
});
|
|
282
|
-
});
|
|
283
|
-
}
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
### Step 4: Generate Postman Environment from .env
|
|
287
|
-
|
|
288
|
-
```typescript
|
|
289
|
-
async function generatePostmanEnvironment(
|
|
290
|
-
projectPath: string,
|
|
291
|
-
outputPath: string
|
|
292
|
-
): Promise<void> {
|
|
293
|
-
const envPath = path.join(projectPath, '.env');
|
|
294
|
-
const envContent = await readFile(envPath, 'utf-8');
|
|
295
|
-
|
|
296
|
-
// Parse .env file
|
|
297
|
-
const envVars = envContent
|
|
298
|
-
.split('\n')
|
|
299
|
-
.filter(line => line && !line.startsWith('#'))
|
|
300
|
-
.map(line => {
|
|
301
|
-
const [key, ...valueParts] = line.split('=');
|
|
302
|
-
const value = valueParts.join('=').replace(/^["']|["']$/g, '');
|
|
303
|
-
return { key: key.trim(), value };
|
|
304
|
-
});
|
|
305
|
-
|
|
306
|
-
// Create Postman environment
|
|
307
|
-
const environment = {
|
|
308
|
-
id: uuidv4(),
|
|
309
|
-
name: `${path.basename(projectPath)} - Local`,
|
|
310
|
-
values: [
|
|
311
|
-
// Always include baseUrl
|
|
312
|
-
{
|
|
313
|
-
key: 'baseUrl',
|
|
314
|
-
value: process.env.API_BASE_URL || 'http://localhost:3000',
|
|
315
|
-
enabled: true,
|
|
316
|
-
type: 'default'
|
|
317
|
-
},
|
|
318
|
-
// API-relevant env vars only (filter sensitive ones)
|
|
319
|
-
...envVars
|
|
320
|
-
.filter(({ key }) => isApiRelevant(key))
|
|
321
|
-
.map(({ key, value }) => ({
|
|
322
|
-
key: toPostmanVarName(key),
|
|
323
|
-
value: isSensitive(key) ? '' : value, // Don't include secrets
|
|
324
|
-
enabled: true,
|
|
325
|
-
type: isSensitive(key) ? 'secret' : 'default'
|
|
326
|
-
}))
|
|
327
|
-
],
|
|
328
|
-
_postman_variable_scope: 'environment'
|
|
329
|
-
};
|
|
330
|
-
|
|
331
|
-
await writeFile(outputPath, JSON.stringify(environment, null, 2));
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
function isApiRelevant(key: string): boolean {
|
|
335
|
-
const relevantPatterns = [
|
|
336
|
-
/^API_/i,
|
|
337
|
-
/^BASE_URL/i,
|
|
338
|
-
/^PORT$/i,
|
|
339
|
-
/^HOST$/i,
|
|
340
|
-
/TOKEN/i,
|
|
341
|
-
/KEY$/i,
|
|
342
|
-
/SECRET$/i,
|
|
343
|
-
/^AUTH/i,
|
|
344
|
-
/^JWT/i
|
|
345
|
-
];
|
|
346
|
-
return relevantPatterns.some(pattern => pattern.test(key));
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
function isSensitive(key: string): boolean {
|
|
350
|
-
const sensitivePatterns = [
|
|
351
|
-
/SECRET/i,
|
|
352
|
-
/PASSWORD/i,
|
|
353
|
-
/KEY$/i,
|
|
354
|
-
/TOKEN/i,
|
|
355
|
-
/CREDENTIALS/i
|
|
356
|
-
];
|
|
357
|
-
return sensitivePatterns.some(pattern => pattern.test(key));
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
function toPostmanVarName(envKey: string): string {
|
|
361
|
-
// Convert ENV_VAR_NAME to envVarName for Postman
|
|
362
|
-
return envKey
|
|
363
|
-
.toLowerCase()
|
|
364
|
-
.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
|
|
365
|
-
}
|
|
366
|
-
```
|
|
367
|
-
|
|
368
|
-
### Step 5: Display Results
|
|
369
|
-
|
|
370
|
-
```markdown
|
|
371
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
372
|
-
API DOCUMENTATION GENERATED
|
|
373
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
374
|
-
|
|
375
|
-
Framework: NestJS (detected from @nestjs/swagger)
|
|
376
|
-
Base URL: http://localhost:3000
|
|
377
|
-
|
|
378
|
-
📄 OpenAPI Specification
|
|
379
|
-
File: openapi.yaml
|
|
380
|
-
Endpoints: 47
|
|
381
|
-
Schemas: 23
|
|
382
|
-
Tags: 8 (users, auth, products, orders, payments, admin, webhooks, health)
|
|
383
|
-
|
|
384
|
-
📦 Postman Collection
|
|
385
|
-
File: postman-collection.json
|
|
386
|
-
Requests: 47
|
|
387
|
-
Folders: 8
|
|
388
|
-
Variables: 3 (baseUrl, apiVersion, authToken)
|
|
389
|
-
|
|
390
|
-
Import: Postman → Import → Upload postman-collection.json
|
|
391
|
-
|
|
392
|
-
🔐 Postman Environment
|
|
393
|
-
File: postman-environment.json
|
|
394
|
-
Variables: 12
|
|
395
|
-
Secrets: 3 (marked as secret type, values empty)
|
|
396
|
-
|
|
397
|
-
Import: Postman → Environments → Import → Upload postman-environment.json
|
|
398
|
-
|
|
399
|
-
⚠️ Fill in secret values after import:
|
|
400
|
-
• apiKey (from API_KEY in .env)
|
|
401
|
-
• authToken (from AUTH_TOKEN in .env)
|
|
402
|
-
• jwtSecret (from JWT_SECRET in .env)
|
|
403
|
-
|
|
404
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
405
|
-
NEXT STEPS
|
|
406
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
407
|
-
|
|
408
|
-
1. Import to Postman:
|
|
409
|
-
- Open Postman
|
|
410
|
-
- Click "Import" → Select postman-collection.json
|
|
411
|
-
- Click "Environments" → "Import" → Select postman-environment.json
|
|
412
|
-
- Select the environment from dropdown
|
|
413
|
-
|
|
414
|
-
2. Configure secrets:
|
|
415
|
-
- Click the environment → Edit
|
|
416
|
-
- Fill in secret values (apiKey, authToken, etc.)
|
|
417
|
-
|
|
418
|
-
3. Test an endpoint:
|
|
419
|
-
- Expand a folder
|
|
420
|
-
- Click a request
|
|
421
|
-
- Click "Send"
|
|
422
|
-
|
|
423
|
-
4. Keep in sync:
|
|
424
|
-
- Run /sw:api-docs --all after API changes
|
|
425
|
-
- Or enable watch mode: /sw:api-docs --watch
|
|
426
|
-
|
|
427
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
428
|
-
```
|
|
429
|
-
|
|
430
|
-
---
|
|
431
|
-
|
|
432
|
-
## Watch Mode
|
|
433
|
-
|
|
434
|
-
Enable continuous synchronization during development:
|
|
435
|
-
|
|
436
|
-
```bash
|
|
437
|
-
/sw:api-docs --watch
|
|
438
|
-
|
|
439
|
-
# Output:
|
|
440
|
-
# 👀 Watching for API changes...
|
|
441
|
-
#
|
|
442
|
-
# Patterns:
|
|
443
|
-
# • src/routes/**/*.ts
|
|
444
|
-
# • src/controllers/**/*.ts
|
|
445
|
-
# • src/api/**/*.ts
|
|
446
|
-
# • **/*.dto.ts
|
|
447
|
-
# • **/*.schema.ts
|
|
448
|
-
#
|
|
449
|
-
# Press Ctrl+C to stop
|
|
450
|
-
```
|
|
451
|
-
|
|
452
|
-
When changes detected:
|
|
453
|
-
|
|
454
|
-
```
|
|
455
|
-
[14:32:15] Change detected: src/controllers/users.controller.ts
|
|
456
|
-
[14:32:16] Regenerating OpenAPI spec...
|
|
457
|
-
[14:32:17] ✅ openapi.yaml updated (48 endpoints, +1)
|
|
458
|
-
[14:32:17] Regenerating Postman collection...
|
|
459
|
-
[14:32:18] ✅ postman-collection.json updated
|
|
460
|
-
```
|
|
461
|
-
|
|
462
|
-
---
|
|
463
|
-
|
|
464
|
-
## Integration with /sw:done
|
|
465
|
-
|
|
466
|
-
When closing an increment, if `apiDocs.generateOn: 'on-increment-done'`:
|
|
467
|
-
|
|
468
|
-
```typescript
|
|
469
|
-
// In close-increment.ts
|
|
470
|
-
if (config.apiDocs?.enabled && config.apiDocs.generateOn === 'on-increment-done') {
|
|
471
|
-
const hasApiChanges = await detectApiChanges(incrementPath);
|
|
472
|
-
|
|
473
|
-
if (hasApiChanges) {
|
|
474
|
-
console.log('🔄 API changes detected, regenerating documentation...');
|
|
475
|
-
await runCommand('/sw:api-docs --all');
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
```
|
|
479
|
-
|
|
480
|
-
---
|
|
481
|
-
|
|
482
|
-
## Validation
|
|
483
|
-
|
|
484
|
-
Validate existing OpenAPI spec:
|
|
485
|
-
|
|
486
|
-
```bash
|
|
487
|
-
/sw:api-docs --validate
|
|
488
|
-
|
|
489
|
-
# Output:
|
|
490
|
-
# 🔍 Validating openapi.yaml...
|
|
491
|
-
#
|
|
492
|
-
# ✅ Valid OpenAPI 3.0.3 specification
|
|
493
|
-
#
|
|
494
|
-
# Statistics:
|
|
495
|
-
# • Paths: 47
|
|
496
|
-
# • Operations: 127
|
|
497
|
-
# • Schemas: 23
|
|
498
|
-
# • Security schemes: 2
|
|
499
|
-
#
|
|
500
|
-
# Warnings:
|
|
501
|
-
# ⚠️ Missing description: GET /users/{id}
|
|
502
|
-
# ⚠️ Missing example: POST /orders request body
|
|
503
|
-
# ⚠️ Deprecated endpoint still documented: DELETE /v1/legacy-users
|
|
504
|
-
#
|
|
505
|
-
# Score: 94/100 (EXCELLENT)
|
|
506
|
-
```
|
|
507
|
-
|
|
508
|
-
---
|
|
509
|
-
|
|
510
|
-
## Configuration
|
|
511
|
-
|
|
512
|
-
Add to `.specweave/config.json`:
|
|
513
|
-
|
|
514
|
-
```json
|
|
515
|
-
{
|
|
516
|
-
"apiDocs": {
|
|
517
|
-
"enabled": true,
|
|
518
|
-
"openApiPath": "openapi.yaml",
|
|
519
|
-
"autoGenerateOpenApi": true,
|
|
520
|
-
"generatePostman": true,
|
|
521
|
-
"postmanPath": "postman-collection.json",
|
|
522
|
-
"postmanEnvPath": "postman-environment.json",
|
|
523
|
-
"generateOn": "on-increment-done",
|
|
524
|
-
"watchPatterns": [
|
|
525
|
-
"**/routes/**",
|
|
526
|
-
"**/controllers/**",
|
|
527
|
-
"**/api/**",
|
|
528
|
-
"**/endpoints/**",
|
|
529
|
-
"**/*.dto.ts",
|
|
530
|
-
"**/*.schema.ts"
|
|
531
|
-
],
|
|
532
|
-
"baseUrl": "http://localhost:3000",
|
|
533
|
-
"framework": "auto"
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
```
|
|
537
|
-
|
|
538
|
-
---
|
|
539
|
-
|
|
540
|
-
## Examples
|
|
541
|
-
|
|
542
|
-
### Example 1: First-Time Setup
|
|
543
|
-
|
|
544
|
-
```bash
|
|
545
|
-
# During init
|
|
546
|
-
specweave init
|
|
547
|
-
# → API framework detected: NestJS
|
|
548
|
-
# → Enable API documentation? [Y/n]: Y
|
|
549
|
-
# → Generate Postman collection? [Y/n]: Y
|
|
550
|
-
# → Generate Postman environment? [Y/n]: Y
|
|
551
|
-
|
|
552
|
-
# Generate docs
|
|
553
|
-
/sw:api-docs --all
|
|
554
|
-
```
|
|
555
|
-
|
|
556
|
-
### Example 2: After Adding New Endpoints
|
|
557
|
-
|
|
558
|
-
```bash
|
|
559
|
-
# Made changes to API
|
|
560
|
-
vim src/controllers/products.controller.ts
|
|
561
|
-
|
|
562
|
-
# Regenerate
|
|
563
|
-
/sw:api-docs --all
|
|
564
|
-
# → ✅ Added 3 new endpoints to openapi.yaml
|
|
565
|
-
# → ✅ Updated postman-collection.json
|
|
566
|
-
```
|
|
567
|
-
|
|
568
|
-
### Example 3: CI/CD Integration
|
|
569
|
-
|
|
570
|
-
```yaml
|
|
571
|
-
# .github/workflows/api-docs.yml
|
|
572
|
-
name: Update API Docs
|
|
573
|
-
|
|
574
|
-
on:
|
|
575
|
-
push:
|
|
576
|
-
paths:
|
|
577
|
-
- 'src/controllers/**'
|
|
578
|
-
- 'src/routes/**'
|
|
579
|
-
- 'src/**/*.dto.ts'
|
|
580
|
-
|
|
581
|
-
jobs:
|
|
582
|
-
update-docs:
|
|
583
|
-
runs-on: ubuntu-latest
|
|
584
|
-
steps:
|
|
585
|
-
- uses: actions/checkout@v4
|
|
586
|
-
- run: npm install
|
|
587
|
-
- run: npx specweave api-docs --all
|
|
588
|
-
- run: |
|
|
589
|
-
git config user.name "GitHub Actions"
|
|
590
|
-
git config user.email "actions@github.com"
|
|
591
|
-
git add openapi.yaml postman-*.json
|
|
592
|
-
git diff --staged --quiet || git commit -m "docs: update API documentation"
|
|
593
|
-
git push
|
|
594
|
-
```
|
|
595
|
-
|
|
596
|
-
### Example 4: Multi-Environment Setup
|
|
597
|
-
|
|
598
|
-
```bash
|
|
599
|
-
# Generate environment files for different stages
|
|
600
|
-
/sw:api-docs --env --output postman-env-local.json --base-url http://localhost:3000
|
|
601
|
-
/sw:api-docs --env --output postman-env-staging.json --base-url https://staging-api.example.com
|
|
602
|
-
/sw:api-docs --env --output postman-env-prod.json --base-url https://api.example.com
|
|
603
|
-
```
|
|
604
|
-
|
|
605
|
-
---
|
|
606
|
-
|
|
607
|
-
## Error Handling
|
|
608
|
-
|
|
609
|
-
### Framework Not Detected
|
|
610
|
-
|
|
611
|
-
```
|
|
612
|
-
❌ Could not detect API framework
|
|
613
|
-
|
|
614
|
-
Supported frameworks:
|
|
615
|
-
• NestJS (@nestjs/swagger)
|
|
616
|
-
• Express (swagger-jsdoc)
|
|
617
|
-
• FastAPI (fastapi)
|
|
618
|
-
• Django REST (djangorestframework)
|
|
619
|
-
• Spring Boot (springdoc-openapi)
|
|
620
|
-
• Go/Gin (swaggo/swag)
|
|
621
|
-
|
|
622
|
-
To specify manually:
|
|
623
|
-
/sw:api-docs --framework nest
|
|
624
|
-
```
|
|
625
|
-
|
|
626
|
-
### OpenAPI Generation Failed
|
|
627
|
-
|
|
628
|
-
```
|
|
629
|
-
❌ Failed to generate OpenAPI specification
|
|
630
|
-
|
|
631
|
-
Error: Server not responding at http://localhost:3000/api-json
|
|
632
|
-
|
|
633
|
-
Troubleshooting:
|
|
634
|
-
1. Is your dev server running? (npm run start:dev)
|
|
635
|
-
2. Is Swagger configured in main.ts?
|
|
636
|
-
3. Check the server logs for errors
|
|
637
|
-
|
|
638
|
-
For NestJS, ensure you have:
|
|
639
|
-
SwaggerModule.setup('api', app, document);
|
|
640
|
-
```
|
|
641
|
-
|
|
642
|
-
### .env File Not Found
|
|
643
|
-
|
|
644
|
-
```
|
|
645
|
-
⚠️ No .env file found
|
|
646
|
-
|
|
647
|
-
Postman environment will include only:
|
|
648
|
-
• baseUrl: http://localhost:3000
|
|
649
|
-
|
|
650
|
-
To generate full environment:
|
|
651
|
-
1. Create .env file with your API configuration
|
|
652
|
-
2. Run: /sw:api-docs --env
|
|
653
|
-
```
|
|
654
|
-
|
|
655
|
-
---
|
|
656
|
-
|
|
657
|
-
## Related Commands
|
|
658
|
-
|
|
659
|
-
- `/sw:increment` - API changes trigger docs update on close
|
|
660
|
-
- `/sw:done` - Auto-generates API docs if enabled
|
|
661
|
-
- `/sw:validate` - Validates API documentation as part of increment validation
|
|
662
|
-
- `/sw:living-docs` - API docs become part of living documentation
|
|
663
|
-
|
|
664
|
-
---
|
|
665
|
-
|
|
666
|
-
## Related Skills
|
|
667
|
-
|
|
668
|
-
- `increment-planner` - Plans API endpoints as part of increment
|
|
669
|
-
|
|
670
|
-
---
|
|
671
|
-
|
|
672
|
-
**Important**: This feature is for API projects only. Projects without REST/GraphQL endpoints should not enable this feature.
|