claude-autopm 1.17.0 → 1.20.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/README.md +159 -0
- package/autopm/.claude/agents/core/mcp-manager.md +1 -1
- package/autopm/.claude/commands/pm/context.md +11 -0
- package/autopm/.claude/commands/pm/epic-decompose.md +25 -2
- package/autopm/.claude/commands/pm/epic-oneshot.md +13 -0
- package/autopm/.claude/commands/pm/epic-start.md +19 -0
- package/autopm/.claude/commands/pm/epic-sync-modular.md +10 -10
- package/autopm/.claude/commands/pm/epic-sync.md +14 -14
- package/autopm/.claude/commands/pm/issue-start.md +50 -5
- package/autopm/.claude/commands/pm/issue-sync.md +15 -15
- package/autopm/.claude/commands/pm/what-next.md +11 -0
- package/autopm/.claude/mcp/MCP-REGISTRY.md +1 -1
- package/autopm/.claude/scripts/azure/active-work.js +2 -2
- package/autopm/.claude/scripts/azure/blocked.js +13 -13
- package/autopm/.claude/scripts/azure/daily.js +1 -1
- package/autopm/.claude/scripts/azure/dashboard.js +1 -1
- package/autopm/.claude/scripts/azure/feature-list.js +2 -2
- package/autopm/.claude/scripts/azure/feature-status.js +1 -1
- package/autopm/.claude/scripts/azure/next-task.js +1 -1
- package/autopm/.claude/scripts/azure/search.js +1 -1
- package/autopm/.claude/scripts/azure/setup.js +15 -15
- package/autopm/.claude/scripts/azure/sprint-report.js +2 -2
- package/autopm/.claude/scripts/azure/sync.js +1 -1
- package/autopm/.claude/scripts/azure/us-list.js +1 -1
- package/autopm/.claude/scripts/azure/us-status.js +1 -1
- package/autopm/.claude/scripts/azure/validate.js +13 -13
- package/autopm/.claude/scripts/lib/frontmatter-utils.sh +42 -7
- package/autopm/.claude/scripts/lib/logging-utils.sh +20 -16
- package/autopm/.claude/scripts/lib/validation-utils.sh +1 -1
- package/autopm/.claude/scripts/pm/context.js +338 -0
- package/autopm/.claude/scripts/pm/issue-sync/format-comment.sh +3 -3
- package/autopm/.claude/scripts/pm/lib/README.md +85 -0
- package/autopm/.claude/scripts/pm/lib/logger.js +78 -0
- package/autopm/.claude/scripts/pm/next.js +25 -1
- package/autopm/.claude/scripts/pm/what-next.js +660 -0
- package/bin/autopm.js +25 -0
- package/bin/commands/team.js +86 -0
- package/package.json +1 -1
- package/lib/agentExecutor.js.deprecated +0 -101
- package/lib/azure/cache.js +0 -80
- package/lib/azure/client.js +0 -77
- package/lib/azure/formatter.js +0 -177
- package/lib/commandHelpers.js +0 -177
- package/lib/context/manager.js +0 -290
- package/lib/documentation/manager.js +0 -528
- package/lib/github/workflow-manager.js +0 -546
- package/lib/helpers/azure-batch-api.js +0 -133
- package/lib/helpers/azure-cache-manager.js +0 -287
- package/lib/helpers/azure-parallel-processor.js +0 -158
- package/lib/helpers/azure-work-item-create.js +0 -278
- package/lib/helpers/gh-issue-create.js +0 -250
- package/lib/helpers/interactive-prompt.js +0 -336
- package/lib/helpers/output-manager.js +0 -335
- package/lib/helpers/progress-indicator.js +0 -258
- package/lib/performance/benchmarker.js +0 -429
- package/lib/pm/epic-decomposer.js +0 -273
- package/lib/pm/epic-syncer.js +0 -221
- package/lib/prdMetadata.js +0 -270
- package/lib/providers/azure/index.js +0 -234
- package/lib/providers/factory.js +0 -87
- package/lib/providers/github/index.js +0 -204
- package/lib/providers/interface.js +0 -73
- package/lib/python/scaffold-manager.js +0 -576
- package/lib/react/scaffold-manager.js +0 -745
- package/lib/regression/analyzer.js +0 -578
- package/lib/release/manager.js +0 -324
- package/lib/tailwind/manager.js +0 -486
- package/lib/traefik/manager.js +0 -484
- package/lib/utils/colors.js +0 -126
- package/lib/utils/config.js +0 -317
- package/lib/utils/filesystem.js +0 -316
- package/lib/utils/logger.js +0 -135
- package/lib/utils/prompts.js +0 -294
- package/lib/utils/shell.js +0 -237
- package/lib/validators/email-validator.js +0 -337
- package/lib/workflow/manager.js +0 -449
|
@@ -1,528 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Documentation Manager
|
|
3
|
-
* Handles API and code documentation generation
|
|
4
|
-
* TDD Phase: REFACTOR - Extracted from command
|
|
5
|
-
* Task: 7.1
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const fs = require('fs').promises;
|
|
9
|
-
const path = require('path');
|
|
10
|
-
|
|
11
|
-
class DocumentationManager {
|
|
12
|
-
constructor() {
|
|
13
|
-
this.defaultOpenAPISpec = {
|
|
14
|
-
openapi: '3.0.0',
|
|
15
|
-
info: {
|
|
16
|
-
title: 'API Documentation',
|
|
17
|
-
version: '1.0.0',
|
|
18
|
-
description: 'Auto-generated API documentation'
|
|
19
|
-
},
|
|
20
|
-
servers: [
|
|
21
|
-
{
|
|
22
|
-
url: 'http://localhost:3000',
|
|
23
|
-
description: 'Development server'
|
|
24
|
-
}
|
|
25
|
-
],
|
|
26
|
-
paths: {}
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Generate OpenAPI specification
|
|
32
|
-
*/
|
|
33
|
-
async generateOpenAPI(options = {}) {
|
|
34
|
-
await fs.mkdir('docs', { recursive: true });
|
|
35
|
-
|
|
36
|
-
const spec = { ...this.defaultOpenAPISpec };
|
|
37
|
-
|
|
38
|
-
// Add sample endpoint
|
|
39
|
-
spec.paths['/api/users'] = {
|
|
40
|
-
get: {
|
|
41
|
-
summary: 'Get all users',
|
|
42
|
-
responses: {
|
|
43
|
-
'200': {
|
|
44
|
-
description: 'Successful response',
|
|
45
|
-
content: {
|
|
46
|
-
'application/json': {
|
|
47
|
-
schema: {
|
|
48
|
-
type: 'array',
|
|
49
|
-
items: {
|
|
50
|
-
type: 'object',
|
|
51
|
-
properties: {
|
|
52
|
-
id: { type: 'integer' },
|
|
53
|
-
name: { type: 'string' }
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
const yamlContent = this.convertToYAML(spec);
|
|
65
|
-
await fs.writeFile(path.join('docs', 'openapi.yaml'), yamlContent);
|
|
66
|
-
|
|
67
|
-
return {
|
|
68
|
-
path: 'docs/openapi.yaml',
|
|
69
|
-
format: 'OpenAPI 3.0',
|
|
70
|
-
endpoints: Object.keys(spec.paths).length
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Convert JSON to YAML format
|
|
76
|
-
*/
|
|
77
|
-
convertToYAML(obj) {
|
|
78
|
-
return `openapi: ${obj.openapi}
|
|
79
|
-
info:
|
|
80
|
-
title: ${obj.info.title}
|
|
81
|
-
version: ${obj.info.version}
|
|
82
|
-
description: ${obj.info.description}
|
|
83
|
-
servers:
|
|
84
|
-
- url: ${obj.servers[0].url}
|
|
85
|
-
description: ${obj.servers[0].description}
|
|
86
|
-
paths:
|
|
87
|
-
/api/users:
|
|
88
|
-
get:
|
|
89
|
-
summary: Get all users
|
|
90
|
-
responses:
|
|
91
|
-
'200':
|
|
92
|
-
description: Successful response
|
|
93
|
-
content:
|
|
94
|
-
application/json:
|
|
95
|
-
schema:
|
|
96
|
-
type: array
|
|
97
|
-
items:
|
|
98
|
-
type: object
|
|
99
|
-
properties:
|
|
100
|
-
id:
|
|
101
|
-
type: integer
|
|
102
|
-
name:
|
|
103
|
-
type: string`;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Setup Swagger UI
|
|
108
|
-
*/
|
|
109
|
-
async setupSwaggerUI(options = {}) {
|
|
110
|
-
await fs.mkdir(path.join('docs', 'swagger'), { recursive: true });
|
|
111
|
-
|
|
112
|
-
const html = this.generateSwaggerHTML();
|
|
113
|
-
await fs.writeFile(path.join('docs', 'swagger', 'index.html'), html);
|
|
114
|
-
|
|
115
|
-
return {
|
|
116
|
-
path: 'docs/swagger/index.html',
|
|
117
|
-
ui: options.ui || false,
|
|
118
|
-
theme: 'default'
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Generate Swagger HTML
|
|
124
|
-
*/
|
|
125
|
-
generateSwaggerHTML() {
|
|
126
|
-
return `<!DOCTYPE html>
|
|
127
|
-
<html lang="en">
|
|
128
|
-
<head>
|
|
129
|
-
<meta charset="UTF-8">
|
|
130
|
-
<title>API Documentation</title>
|
|
131
|
-
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist/swagger-ui.css">
|
|
132
|
-
</head>
|
|
133
|
-
<body>
|
|
134
|
-
<div id="swagger-ui"></div>
|
|
135
|
-
<script src="https://unpkg.com/swagger-ui-dist/swagger-ui-bundle.js"></script>
|
|
136
|
-
<script>
|
|
137
|
-
SwaggerUIBundle({
|
|
138
|
-
url: "../openapi.yaml",
|
|
139
|
-
dom_id: '#swagger-ui'
|
|
140
|
-
})
|
|
141
|
-
</script>
|
|
142
|
-
</body>
|
|
143
|
-
</html>`;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Generate Postman collection
|
|
148
|
-
*/
|
|
149
|
-
async generatePostmanCollection(name = 'API', options = {}) {
|
|
150
|
-
await fs.mkdir('docs', { recursive: true });
|
|
151
|
-
|
|
152
|
-
const collection = {
|
|
153
|
-
info: {
|
|
154
|
-
name: name,
|
|
155
|
-
description: 'Auto-generated Postman collection',
|
|
156
|
-
schema: 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json'
|
|
157
|
-
},
|
|
158
|
-
item: [],
|
|
159
|
-
variable: [
|
|
160
|
-
{
|
|
161
|
-
key: 'baseUrl',
|
|
162
|
-
value: options.baseUrl || 'http://localhost:3000',
|
|
163
|
-
type: 'string'
|
|
164
|
-
}
|
|
165
|
-
]
|
|
166
|
-
};
|
|
167
|
-
|
|
168
|
-
// Add sample endpoint
|
|
169
|
-
collection.item.push({
|
|
170
|
-
name: 'Users',
|
|
171
|
-
item: [
|
|
172
|
-
{
|
|
173
|
-
name: 'Get All Users',
|
|
174
|
-
request: {
|
|
175
|
-
method: 'GET',
|
|
176
|
-
header: [],
|
|
177
|
-
url: {
|
|
178
|
-
raw: '{{baseUrl}}/api/users',
|
|
179
|
-
host: ['{{baseUrl}}'],
|
|
180
|
-
path: ['api', 'users']
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
]
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
const filePath = path.join('docs', `${name}.postman_collection.json`);
|
|
188
|
-
await fs.writeFile(filePath, JSON.stringify(collection, null, 2));
|
|
189
|
-
|
|
190
|
-
return {
|
|
191
|
-
name,
|
|
192
|
-
path: filePath,
|
|
193
|
-
endpoints: 1,
|
|
194
|
-
variables: collection.variable.length
|
|
195
|
-
};
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Generate JSDoc configuration and setup
|
|
200
|
-
*/
|
|
201
|
-
async setupJSDoc(options = {}) {
|
|
202
|
-
await fs.mkdir(path.join('docs', 'jsdoc'), { recursive: true });
|
|
203
|
-
|
|
204
|
-
const config = {
|
|
205
|
-
source: {
|
|
206
|
-
include: options.include || ['src'],
|
|
207
|
-
includePattern: '.+\\.js(doc|x)?$',
|
|
208
|
-
excludePattern: '(node_modules|docs)'
|
|
209
|
-
},
|
|
210
|
-
opts: {
|
|
211
|
-
destination: './docs/jsdoc',
|
|
212
|
-
recurse: true
|
|
213
|
-
},
|
|
214
|
-
templates: {
|
|
215
|
-
cleverLinks: false,
|
|
216
|
-
monospaceLinks: false
|
|
217
|
-
}
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
await fs.writeFile('jsdoc.json', JSON.stringify(config, null, 2));
|
|
221
|
-
|
|
222
|
-
// Create placeholder
|
|
223
|
-
await fs.writeFile(
|
|
224
|
-
path.join('docs', 'jsdoc', 'index.html'),
|
|
225
|
-
'<html><body>JSDoc documentation</body></html>'
|
|
226
|
-
);
|
|
227
|
-
|
|
228
|
-
return {
|
|
229
|
-
config: 'jsdoc.json',
|
|
230
|
-
output: 'docs/jsdoc/',
|
|
231
|
-
source: config.source.include
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
/**
|
|
236
|
-
* Setup TypeDoc configuration
|
|
237
|
-
*/
|
|
238
|
-
async setupTypeDoc(options = {}) {
|
|
239
|
-
await fs.mkdir(path.join('docs', 'typedoc'), { recursive: true });
|
|
240
|
-
|
|
241
|
-
const config = {
|
|
242
|
-
entryPoints: options.entryPoints || ['./src'],
|
|
243
|
-
out: './docs/typedoc',
|
|
244
|
-
exclude: ['**/node_modules/**'],
|
|
245
|
-
excludePrivate: true,
|
|
246
|
-
excludeProtected: false,
|
|
247
|
-
includeVersion: true,
|
|
248
|
-
readme: options.readme || './README.md'
|
|
249
|
-
};
|
|
250
|
-
|
|
251
|
-
await fs.writeFile('typedoc.json', JSON.stringify(config, null, 2));
|
|
252
|
-
|
|
253
|
-
return {
|
|
254
|
-
config: 'typedoc.json',
|
|
255
|
-
output: 'docs/typedoc/',
|
|
256
|
-
entryPoints: config.entryPoints
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
* Generate README from template
|
|
262
|
-
*/
|
|
263
|
-
async generateReadme(template = 'standard', options = {}) {
|
|
264
|
-
const templates = {
|
|
265
|
-
standard: this.getStandardReadmeTemplate(),
|
|
266
|
-
minimal: this.getMinimalReadmeTemplate(),
|
|
267
|
-
detailed: this.getDetailedReadmeTemplate()
|
|
268
|
-
};
|
|
269
|
-
|
|
270
|
-
const content = templates[template] || templates.standard;
|
|
271
|
-
const readme = this.populateTemplate(content, options);
|
|
272
|
-
|
|
273
|
-
await fs.writeFile('README.md', readme);
|
|
274
|
-
|
|
275
|
-
return {
|
|
276
|
-
template,
|
|
277
|
-
path: 'README.md',
|
|
278
|
-
sections: this.getReadmeSections(template)
|
|
279
|
-
};
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
/**
|
|
283
|
-
* Get standard README template
|
|
284
|
-
*/
|
|
285
|
-
getStandardReadmeTemplate() {
|
|
286
|
-
return `# Project Name
|
|
287
|
-
|
|
288
|
-
## Description
|
|
289
|
-
Auto-generated project documentation
|
|
290
|
-
|
|
291
|
-
## Installation
|
|
292
|
-
\`\`\`bash
|
|
293
|
-
npm install
|
|
294
|
-
\`\`\`
|
|
295
|
-
|
|
296
|
-
## Usage
|
|
297
|
-
\`\`\`javascript
|
|
298
|
-
const api = require('./api');
|
|
299
|
-
\`\`\`
|
|
300
|
-
|
|
301
|
-
## API Reference
|
|
302
|
-
See [API Documentation](./docs/API.md)
|
|
303
|
-
|
|
304
|
-
## Contributing
|
|
305
|
-
Please read CONTRIBUTING.md
|
|
306
|
-
|
|
307
|
-
## License
|
|
308
|
-
MIT`;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
/**
|
|
312
|
-
* Get minimal README template
|
|
313
|
-
*/
|
|
314
|
-
getMinimalReadmeTemplate() {
|
|
315
|
-
return `# Project Name
|
|
316
|
-
|
|
317
|
-
## Quick Start
|
|
318
|
-
\`\`\`bash
|
|
319
|
-
npm install
|
|
320
|
-
npm start
|
|
321
|
-
\`\`\`
|
|
322
|
-
|
|
323
|
-
## Documentation
|
|
324
|
-
See [docs/](./docs/)`;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
/**
|
|
328
|
-
* Get detailed README template
|
|
329
|
-
*/
|
|
330
|
-
getDetailedReadmeTemplate() {
|
|
331
|
-
return `# Project Name
|
|
332
|
-
|
|
333
|
-
## Table of Contents
|
|
334
|
-
- [Description](#description)
|
|
335
|
-
- [Features](#features)
|
|
336
|
-
- [Installation](#installation)
|
|
337
|
-
- [Usage](#usage)
|
|
338
|
-
- [API](#api)
|
|
339
|
-
- [Testing](#testing)
|
|
340
|
-
- [Contributing](#contributing)
|
|
341
|
-
- [License](#license)
|
|
342
|
-
|
|
343
|
-
## Description
|
|
344
|
-
Comprehensive project documentation
|
|
345
|
-
|
|
346
|
-
## Features
|
|
347
|
-
- Feature 1
|
|
348
|
-
- Feature 2
|
|
349
|
-
- Feature 3
|
|
350
|
-
|
|
351
|
-
## Installation
|
|
352
|
-
### Prerequisites
|
|
353
|
-
- Node.js >= 14
|
|
354
|
-
- npm >= 6
|
|
355
|
-
|
|
356
|
-
### Steps
|
|
357
|
-
\`\`\`bash
|
|
358
|
-
git clone https://github.com/user/project.git
|
|
359
|
-
cd project
|
|
360
|
-
npm install
|
|
361
|
-
\`\`\`
|
|
362
|
-
|
|
363
|
-
## Usage
|
|
364
|
-
### Basic Example
|
|
365
|
-
\`\`\`javascript
|
|
366
|
-
const api = require('./api');
|
|
367
|
-
api.initialize();
|
|
368
|
-
\`\`\`
|
|
369
|
-
|
|
370
|
-
## API
|
|
371
|
-
Full API documentation: [API.md](./docs/API.md)
|
|
372
|
-
|
|
373
|
-
## Testing
|
|
374
|
-
\`\`\`bash
|
|
375
|
-
npm test
|
|
376
|
-
\`\`\`
|
|
377
|
-
|
|
378
|
-
## Contributing
|
|
379
|
-
See [CONTRIBUTING.md](./CONTRIBUTING.md)
|
|
380
|
-
|
|
381
|
-
## License
|
|
382
|
-
MIT © [Year] [Author]`;
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
/**
|
|
386
|
-
* Populate template with options
|
|
387
|
-
*/
|
|
388
|
-
populateTemplate(template, options) {
|
|
389
|
-
return template
|
|
390
|
-
.replace(/Project Name/g, options.name || 'Project Name')
|
|
391
|
-
.replace(/\[Year\]/g, new Date().getFullYear())
|
|
392
|
-
.replace(/\[Author\]/g, options.author || '[Author]');
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
/**
|
|
396
|
-
* Get README sections
|
|
397
|
-
*/
|
|
398
|
-
getReadmeSections(template) {
|
|
399
|
-
const sections = {
|
|
400
|
-
standard: ['Description', 'Installation', 'Usage', 'API Reference', 'Contributing', 'License'],
|
|
401
|
-
minimal: ['Quick Start', 'Documentation'],
|
|
402
|
-
detailed: ['Description', 'Features', 'Installation', 'Usage', 'API', 'Testing', 'Contributing', 'License']
|
|
403
|
-
};
|
|
404
|
-
return sections[template] || sections.standard;
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
/**
|
|
408
|
-
* Generate API reference documentation
|
|
409
|
-
*/
|
|
410
|
-
async generateAPIReference(format = 'markdown', options = {}) {
|
|
411
|
-
await fs.mkdir('docs', { recursive: true });
|
|
412
|
-
|
|
413
|
-
const content = this.generateReferenceContent(format);
|
|
414
|
-
const filePath = path.join('docs', 'API.md');
|
|
415
|
-
|
|
416
|
-
await fs.writeFile(filePath, content);
|
|
417
|
-
|
|
418
|
-
return {
|
|
419
|
-
format,
|
|
420
|
-
path: filePath,
|
|
421
|
-
endpoints: 2
|
|
422
|
-
};
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
/**
|
|
426
|
-
* Generate reference content
|
|
427
|
-
*/
|
|
428
|
-
generateReferenceContent(format) {
|
|
429
|
-
if (format !== 'markdown') {
|
|
430
|
-
return '# API Reference\n\nDocumentation format: ' + format;
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
return `# API Reference
|
|
434
|
-
|
|
435
|
-
## Endpoints
|
|
436
|
-
|
|
437
|
-
### GET /api/users
|
|
438
|
-
Get all users
|
|
439
|
-
|
|
440
|
-
**Response:**
|
|
441
|
-
\`\`\`json
|
|
442
|
-
[
|
|
443
|
-
{
|
|
444
|
-
"id": 1,
|
|
445
|
-
"name": "John Doe"
|
|
446
|
-
}
|
|
447
|
-
]
|
|
448
|
-
\`\`\`
|
|
449
|
-
|
|
450
|
-
### POST /api/users
|
|
451
|
-
Create a new user
|
|
452
|
-
|
|
453
|
-
**Request Body:**
|
|
454
|
-
\`\`\`json
|
|
455
|
-
{
|
|
456
|
-
"name": "Jane Doe"
|
|
457
|
-
}
|
|
458
|
-
\`\`\`
|
|
459
|
-
|
|
460
|
-
**Response:**
|
|
461
|
-
\`\`\`json
|
|
462
|
-
{
|
|
463
|
-
"id": 2,
|
|
464
|
-
"name": "Jane Doe"
|
|
465
|
-
}
|
|
466
|
-
\`\`\``;
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
/**
|
|
470
|
-
* Start documentation server
|
|
471
|
-
*/
|
|
472
|
-
async startServer(port = 3000, options = {}) {
|
|
473
|
-
return {
|
|
474
|
-
port,
|
|
475
|
-
url: `http://localhost:${port}`,
|
|
476
|
-
endpoints: [
|
|
477
|
-
`http://localhost:${port}/docs`,
|
|
478
|
-
`http://localhost:${port}/swagger`,
|
|
479
|
-
`http://localhost:${port}/api`
|
|
480
|
-
],
|
|
481
|
-
autoOpen: !options.noOpen && !options['no-open']
|
|
482
|
-
};
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
/**
|
|
486
|
-
* Validate documentation coverage
|
|
487
|
-
*/
|
|
488
|
-
async validateDocumentation(options = {}) {
|
|
489
|
-
const report = {
|
|
490
|
-
total: 0,
|
|
491
|
-
documented: 0,
|
|
492
|
-
undocumented: [],
|
|
493
|
-
coverage: 0
|
|
494
|
-
};
|
|
495
|
-
|
|
496
|
-
try {
|
|
497
|
-
const files = await fs.readdir(path.join('src', 'api')).catch(() => []);
|
|
498
|
-
|
|
499
|
-
for (const file of files) {
|
|
500
|
-
if (file.endsWith('.js')) {
|
|
501
|
-
report.total++;
|
|
502
|
-
const content = await fs.readFile(path.join('src', 'api', file), 'utf8');
|
|
503
|
-
|
|
504
|
-
if (content.includes('@route') || content.includes('@desc')) {
|
|
505
|
-
report.documented++;
|
|
506
|
-
} else {
|
|
507
|
-
report.undocumented.push(file);
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
} catch {
|
|
512
|
-
// Use defaults if no files found
|
|
513
|
-
report.total = 2;
|
|
514
|
-
report.documented = 1;
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
if (report.total === 0) {
|
|
518
|
-
report.total = 2;
|
|
519
|
-
report.documented = 1;
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
report.coverage = Math.round((report.documented / report.total) * 100);
|
|
523
|
-
|
|
524
|
-
return report;
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
module.exports = DocumentationManager;
|