strray-ai 1.7.2 → 1.7.3
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/.opencode/hooks/post-commit +152 -55
- package/.opencode/hooks/post-commit.backup +110 -174
- package/.opencode/hooks/post-push +47 -64
- package/.opencode/hooks/post-push.backup +34 -38
- package/.opencode/strray/features.json +3 -3
- package/.opencode/strray/routing-mappings.json +90 -34
- package/AGENTS.md +7 -2
- package/dist/analytics/anonymization-engine.d.ts +108 -0
- package/dist/analytics/anonymization-engine.d.ts.map +1 -0
- package/dist/analytics/anonymization-engine.js +352 -0
- package/dist/analytics/anonymization-engine.js.map +1 -0
- package/dist/analytics/consent-manager.d.ts +94 -0
- package/dist/analytics/consent-manager.d.ts.map +1 -0
- package/dist/analytics/consent-manager.js +257 -0
- package/dist/analytics/consent-manager.js.map +1 -0
- package/dist/analytics/emerging-pattern-detector.d.ts +68 -0
- package/dist/analytics/emerging-pattern-detector.d.ts.map +1 -0
- package/dist/analytics/emerging-pattern-detector.js +250 -0
- package/dist/analytics/emerging-pattern-detector.js.map +1 -0
- package/dist/analytics/pattern-learning-engine.d.ts +81 -0
- package/dist/analytics/pattern-learning-engine.d.ts.map +1 -0
- package/dist/analytics/pattern-learning-engine.js +262 -0
- package/dist/analytics/pattern-learning-engine.js.map +1 -0
- package/dist/analytics/pattern-performance-tracker.d.ts +89 -0
- package/dist/analytics/pattern-performance-tracker.d.ts.map +1 -0
- package/dist/analytics/pattern-performance-tracker.js +289 -0
- package/dist/analytics/pattern-performance-tracker.js.map +1 -0
- package/dist/analytics/prompt-pattern-analyzer.d.ts +100 -0
- package/dist/analytics/prompt-pattern-analyzer.d.ts.map +1 -0
- package/dist/analytics/prompt-pattern-analyzer.js +372 -0
- package/dist/analytics/prompt-pattern-analyzer.js.map +1 -0
- package/dist/analytics/routing-performance-analyzer.d.ts +102 -0
- package/dist/analytics/routing-performance-analyzer.d.ts.map +1 -0
- package/dist/analytics/routing-performance-analyzer.js +342 -0
- package/dist/analytics/routing-performance-analyzer.js.map +1 -0
- package/dist/analytics/routing-refiner.d.ts +105 -0
- package/dist/analytics/routing-refiner.d.ts.map +1 -0
- package/dist/analytics/routing-refiner.js +381 -0
- package/dist/analytics/routing-refiner.js.map +1 -0
- package/dist/cli/commands/analytics-disable.d.ts +10 -0
- package/dist/cli/commands/analytics-disable.d.ts.map +1 -0
- package/dist/cli/commands/analytics-disable.js +73 -0
- package/dist/cli/commands/analytics-disable.js.map +1 -0
- package/dist/cli/commands/analytics-enable-action.d.ts +9 -0
- package/dist/cli/commands/analytics-enable-action.d.ts.map +1 -0
- package/dist/cli/commands/analytics-enable-action.js +83 -0
- package/dist/cli/commands/analytics-enable-action.js.map +1 -0
- package/dist/cli/commands/analytics-preview.d.ts +10 -0
- package/dist/cli/commands/analytics-preview.d.ts.map +1 -0
- package/dist/cli/commands/analytics-preview.js +107 -0
- package/dist/cli/commands/analytics-preview.js.map +1 -0
- package/dist/cli/commands/analytics-status.d.ts +10 -0
- package/dist/cli/commands/analytics-status.d.ts.map +1 -0
- package/dist/cli/commands/analytics-status.js +68 -0
- package/dist/cli/commands/analytics-status.js.map +1 -0
- package/dist/cli/index.js +6 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/core/adaptive-kernel.d.ts +110 -0
- package/dist/core/adaptive-kernel.d.ts.map +1 -0
- package/dist/core/adaptive-kernel.js +193 -0
- package/dist/core/adaptive-kernel.js.map +1 -0
- package/dist/core/kernel-patterns.d.ts +105 -0
- package/dist/core/kernel-patterns.d.ts.map +1 -0
- package/dist/core/kernel-patterns.js +328 -0
- package/dist/core/kernel-patterns.js.map +1 -0
- package/dist/core/orchestrator.d.ts +1 -0
- package/dist/core/orchestrator.d.ts.map +1 -1
- package/dist/core/orchestrator.js +40 -11
- package/dist/core/orchestrator.js.map +1 -1
- package/dist/delegation/agent-delegator.d.ts +1 -0
- package/dist/delegation/agent-delegator.d.ts.map +1 -1
- package/dist/delegation/agent-delegator.js +24 -2
- package/dist/delegation/agent-delegator.js.map +1 -1
- package/dist/delegation/task-skill-router.d.ts +269 -5
- package/dist/delegation/task-skill-router.d.ts.map +1 -1
- package/dist/delegation/task-skill-router.js +810 -23
- package/dist/delegation/task-skill-router.js.map +1 -1
- package/dist/postprocessor/PostProcessor.d.ts +10 -0
- package/dist/postprocessor/PostProcessor.d.ts.map +1 -1
- package/dist/postprocessor/PostProcessor.js +87 -17
- package/dist/postprocessor/PostProcessor.js.map +1 -1
- package/dist/processors/agents-md-validation-processor.d.ts +1 -0
- package/dist/processors/agents-md-validation-processor.d.ts.map +1 -1
- package/dist/processors/agents-md-validation-processor.js +34 -12
- package/dist/processors/agents-md-validation-processor.js.map +1 -1
- package/dist/processors/processor-manager.d.ts +7 -0
- package/dist/processors/processor-manager.d.ts.map +1 -1
- package/dist/processors/processor-manager.js +93 -0
- package/dist/processors/processor-manager.js.map +1 -1
- package/dist/processors/test-auto-creation-processor.d.ts.map +1 -1
- package/dist/processors/test-auto-creation-processor.js +52 -38
- package/dist/processors/test-auto-creation-processor.js.map +1 -1
- package/dist/scripts/analytics/daily-routing-analysis.d.ts +18 -0
- package/dist/scripts/analytics/daily-routing-analysis.d.ts.map +1 -0
- package/dist/scripts/analytics/daily-routing-analysis.js +268 -0
- package/dist/scripts/analytics/daily-routing-analysis.js.map +1 -0
- package/dist/scripts/analytics/index.d.ts +15 -0
- package/dist/scripts/analytics/index.d.ts.map +1 -0
- package/dist/scripts/analytics/index.js +17 -0
- package/dist/scripts/analytics/index.js.map +1 -0
- package/dist/scripts/test-p9.d.ts +15 -0
- package/dist/scripts/test-p9.d.ts.map +1 -0
- package/dist/scripts/test-p9.js +220 -0
- package/dist/scripts/test-p9.js.map +1 -0
- package/package.json +6 -2
- package/scripts/node/kernel-e2e-test.mjs +168 -0
- package/scripts/node/kernel-framework-test.mjs +127 -0
- package/scripts/node/kernel-live-test.mjs +147 -0
- package/scripts/node/kernel-real-framework-test.mjs +103 -0
- package/scripts/node/kernel-update.cjs +379 -0
- package/scripts/node/reflection-check.sh +245 -27
- package/scripts/node/test-simple-names-comprehensive.mjs +221 -0
- package/scripts/node/test-simple-names.mjs +39 -0
- package/dist/agents/documentation-writer.d.ts +0 -9
- package/dist/agents/documentation-writer.d.ts.map +0 -1
- package/dist/agents/documentation-writer.js +0 -85
- package/dist/agents/documentation-writer.js.map +0 -1
- package/dist/agents/explore.d.ts +0 -8
- package/dist/agents/explore.d.ts.map +0 -1
- package/dist/agents/explore.js +0 -55
- package/dist/agents/explore.js.map +0 -1
- package/dist/agents/librarian.d.ts +0 -3
- package/dist/agents/librarian.d.ts.map +0 -1
- package/dist/agents/librarian.js +0 -84
- package/dist/agents/librarian.js.map +0 -1
- package/dist/agents/marketing-expert.d.ts +0 -9
- package/dist/agents/marketing-expert.d.ts.map +0 -1
- package/dist/agents/marketing-expert.js +0 -112
- package/dist/agents/marketing-expert.js.map +0 -1
- package/dist/agents/oracle.d.ts +0 -8
- package/dist/agents/oracle.d.ts.map +0 -1
- package/dist/agents/oracle.js +0 -51
- package/dist/agents/oracle.js.map +0 -1
- package/dist/agents/seo-copywriter.d.ts +0 -10
- package/dist/agents/seo-copywriter.d.ts.map +0 -1
- package/dist/agents/seo-copywriter.js +0 -73
- package/dist/agents/seo-copywriter.js.map +0 -1
- package/dist/agents/seo-specialist.d.ts +0 -9
- package/dist/agents/seo-specialist.d.ts.map +0 -1
- package/dist/agents/seo-specialist.js +0 -54
- package/dist/agents/seo-specialist.js.map +0 -1
- package/dist/agents/test-architect.d.ts +0 -3
- package/dist/agents/test-architect.d.ts.map +0 -1
- package/dist/agents/test-architect.js +0 -96
- package/dist/agents/test-architect.js.map +0 -1
- package/dist/mcps/enhanced-orchestrator.server.d.ts +0 -14
- package/dist/mcps/enhanced-orchestrator.server.d.ts.map +0 -1
- package/dist/mcps/enhanced-orchestrator.server.js +0 -266
- package/dist/mcps/enhanced-orchestrator.server.js.map +0 -1
- package/dist/mcps/knowledge-skills/analyzer.server.d.ts +0 -7
- package/dist/mcps/knowledge-skills/analyzer.server.d.ts.map +0 -1
- package/dist/mcps/knowledge-skills/analyzer.server.js +0 -282
- package/dist/mcps/knowledge-skills/analyzer.server.js.map +0 -1
- package/dist/mcps/knowledge-skills/documentation-generation.server.d.ts +0 -48
- package/dist/mcps/knowledge-skills/documentation-generation.server.d.ts.map +0 -1
- package/dist/mcps/knowledge-skills/documentation-generation.server.js +0 -1238
- package/dist/mcps/knowledge-skills/documentation-generation.server.js.map +0 -1
- package/dist/mcps/knowledge-skills/explore.server.d.ts +0 -21
- package/dist/mcps/knowledge-skills/explore.server.d.ts.map +0 -1
- package/dist/mcps/knowledge-skills/explore.server.js +0 -582
- package/dist/mcps/knowledge-skills/explore.server.js.map +0 -1
- package/dist/mcps/knowledge-skills/marketing-expert.server.d.ts +0 -8
- package/dist/mcps/knowledge-skills/marketing-expert.server.d.ts.map +0 -1
- package/dist/mcps/knowledge-skills/marketing-expert.server.js +0 -356
- package/dist/mcps/knowledge-skills/marketing-expert.server.js.map +0 -1
- package/dist/mcps/knowledge-skills/oracle.server.d.ts +0 -25
- package/dist/mcps/knowledge-skills/oracle.server.d.ts.map +0 -1
- package/dist/mcps/knowledge-skills/oracle.server.js +0 -569
- package/dist/mcps/knowledge-skills/oracle.server.js.map +0 -1
- package/dist/mcps/knowledge-skills/seo-copywriter.server.d.ts +0 -8
- package/dist/mcps/knowledge-skills/seo-copywriter.server.d.ts.map +0 -1
- package/dist/mcps/knowledge-skills/seo-copywriter.server.js +0 -251
- package/dist/mcps/knowledge-skills/seo-copywriter.server.js.map +0 -1
- package/dist/mcps/knowledge-skills/seo-specialist.server.d.ts +0 -8
- package/dist/mcps/knowledge-skills/seo-specialist.server.d.ts.map +0 -1
- package/dist/mcps/knowledge-skills/seo-specialist.server.js +0 -211
- package/dist/mcps/knowledge-skills/seo-specialist.server.js.map +0 -1
- package/dist/mcps/librarian.server.d.ts +0 -17
- package/dist/mcps/librarian.server.d.ts.map +0 -1
- package/dist/mcps/librarian.server.js +0 -382
- package/dist/mcps/librarian.server.js.map +0 -1
- package/dist/optimization/performance-optimizer.d.ts +0 -179
- package/dist/optimization/performance-optimizer.d.ts.map +0 -1
- package/dist/optimization/performance-optimizer.js +0 -556
- package/dist/optimization/performance-optimizer.js.map +0 -1
- package/dist/utils/memory-pool.d.ts +0 -90
- package/dist/utils/memory-pool.d.ts.map +0 -1
- package/dist/utils/memory-pool.js +0 -245
- package/dist/utils/memory-pool.js.map +0 -1
|
@@ -1,1238 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* StrRay Documentation Generation MCP Server
|
|
3
|
-
*
|
|
4
|
-
* Knowledge skill for automated documentation creation, API docs generation,
|
|
5
|
-
* code documentation maintenance, and technical writing assistance
|
|
6
|
-
*/
|
|
7
|
-
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
8
|
-
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
9
|
-
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
10
|
-
import * as fs from "fs";
|
|
11
|
-
import * as path from "path";
|
|
12
|
-
class StrRayDocumentationGenerationServer {
|
|
13
|
-
server;
|
|
14
|
-
constructor() {
|
|
15
|
-
this.server = new Server({
|
|
16
|
-
name: "documentation-generation",
|
|
17
|
-
version: "1.6.0",
|
|
18
|
-
}, {
|
|
19
|
-
capabilities: {
|
|
20
|
-
tools: {},
|
|
21
|
-
},
|
|
22
|
-
});
|
|
23
|
-
this.setupToolHandlers();
|
|
24
|
-
// Server initialization - removed unnecessary startup logging
|
|
25
|
-
}
|
|
26
|
-
setupToolHandlers() {
|
|
27
|
-
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
28
|
-
return {
|
|
29
|
-
tools: [
|
|
30
|
-
{
|
|
31
|
-
name: "analyze_documentation",
|
|
32
|
-
description: "Analyze existing documentation for completeness, quality, and gaps",
|
|
33
|
-
inputSchema: {
|
|
34
|
-
type: "object",
|
|
35
|
-
properties: {
|
|
36
|
-
docsPath: {
|
|
37
|
-
type: "string",
|
|
38
|
-
description: "Path to documentation directory or files",
|
|
39
|
-
},
|
|
40
|
-
codePath: {
|
|
41
|
-
type: "string",
|
|
42
|
-
description: "Path to corresponding code for comparison",
|
|
43
|
-
},
|
|
44
|
-
docTypes: {
|
|
45
|
-
type: "array",
|
|
46
|
-
items: {
|
|
47
|
-
type: "string",
|
|
48
|
-
enum: [
|
|
49
|
-
"readme",
|
|
50
|
-
"api",
|
|
51
|
-
"code",
|
|
52
|
-
"architecture",
|
|
53
|
-
"deployment",
|
|
54
|
-
"user-guide",
|
|
55
|
-
],
|
|
56
|
-
},
|
|
57
|
-
description: "Types of documentation to analyze",
|
|
58
|
-
},
|
|
59
|
-
},
|
|
60
|
-
required: ["docsPath"],
|
|
61
|
-
},
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
name: "generate_api_docs",
|
|
65
|
-
description: "Generate comprehensive API documentation from code analysis",
|
|
66
|
-
inputSchema: {
|
|
67
|
-
type: "object",
|
|
68
|
-
properties: {
|
|
69
|
-
codePath: {
|
|
70
|
-
type: "string",
|
|
71
|
-
description: "Path to API code files",
|
|
72
|
-
},
|
|
73
|
-
framework: {
|
|
74
|
-
type: "string",
|
|
75
|
-
enum: [
|
|
76
|
-
"express",
|
|
77
|
-
"fastify",
|
|
78
|
-
"koa",
|
|
79
|
-
"nestjs",
|
|
80
|
-
"spring",
|
|
81
|
-
"django",
|
|
82
|
-
"flask",
|
|
83
|
-
"fastapi",
|
|
84
|
-
],
|
|
85
|
-
description: "API framework being used",
|
|
86
|
-
},
|
|
87
|
-
format: {
|
|
88
|
-
type: "string",
|
|
89
|
-
enum: ["openapi", "markdown", "html", "postman"],
|
|
90
|
-
description: "Output documentation format",
|
|
91
|
-
default: "openapi",
|
|
92
|
-
},
|
|
93
|
-
includeExamples: {
|
|
94
|
-
type: "boolean",
|
|
95
|
-
description: "Include request/response examples",
|
|
96
|
-
default: true,
|
|
97
|
-
},
|
|
98
|
-
},
|
|
99
|
-
required: ["codePath", "framework"],
|
|
100
|
-
},
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
name: "generate_code_documentation",
|
|
104
|
-
description: "Generate inline code documentation and improve existing docs",
|
|
105
|
-
inputSchema: {
|
|
106
|
-
type: "object",
|
|
107
|
-
properties: {
|
|
108
|
-
codePath: {
|
|
109
|
-
type: "string",
|
|
110
|
-
description: "Path to code files to document",
|
|
111
|
-
},
|
|
112
|
-
language: {
|
|
113
|
-
type: "string",
|
|
114
|
-
enum: [
|
|
115
|
-
"typescript",
|
|
116
|
-
"javascript",
|
|
117
|
-
"python",
|
|
118
|
-
"java",
|
|
119
|
-
"csharp",
|
|
120
|
-
"go",
|
|
121
|
-
"rust",
|
|
122
|
-
],
|
|
123
|
-
description: "Programming language",
|
|
124
|
-
},
|
|
125
|
-
style: {
|
|
126
|
-
type: "string",
|
|
127
|
-
enum: ["jsdoc", "docstring", "xml", "markdown"],
|
|
128
|
-
description: "Documentation comment style",
|
|
129
|
-
default: "jsdoc",
|
|
130
|
-
},
|
|
131
|
-
includePrivate: {
|
|
132
|
-
type: "boolean",
|
|
133
|
-
description: "Include documentation for private members",
|
|
134
|
-
default: false,
|
|
135
|
-
},
|
|
136
|
-
},
|
|
137
|
-
required: ["codePath", "language"],
|
|
138
|
-
},
|
|
139
|
-
},
|
|
140
|
-
{
|
|
141
|
-
name: "generate_readme",
|
|
142
|
-
description: "Generate or improve project README documentation",
|
|
143
|
-
inputSchema: {
|
|
144
|
-
type: "object",
|
|
145
|
-
properties: {
|
|
146
|
-
projectPath: {
|
|
147
|
-
type: "string",
|
|
148
|
-
description: "Path to project root directory",
|
|
149
|
-
},
|
|
150
|
-
projectType: {
|
|
151
|
-
type: "string",
|
|
152
|
-
enum: ["library", "application", "api", "cli", "framework"],
|
|
153
|
-
description: "Type of project",
|
|
154
|
-
},
|
|
155
|
-
includeSections: {
|
|
156
|
-
type: "array",
|
|
157
|
-
items: { type: "string" },
|
|
158
|
-
description: "Specific sections to include",
|
|
159
|
-
default: [
|
|
160
|
-
"installation",
|
|
161
|
-
"usage",
|
|
162
|
-
"api",
|
|
163
|
-
"contributing",
|
|
164
|
-
"license",
|
|
165
|
-
],
|
|
166
|
-
},
|
|
167
|
-
existingReadme: {
|
|
168
|
-
type: "string",
|
|
169
|
-
description: "Path to existing README to improve",
|
|
170
|
-
},
|
|
171
|
-
},
|
|
172
|
-
required: ["projectPath", "projectType"],
|
|
173
|
-
},
|
|
174
|
-
},
|
|
175
|
-
],
|
|
176
|
-
};
|
|
177
|
-
});
|
|
178
|
-
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
179
|
-
const { name, arguments: args } = request.params;
|
|
180
|
-
switch (name) {
|
|
181
|
-
case "analyze_documentation":
|
|
182
|
-
return await this.analyzeDocumentation(args);
|
|
183
|
-
case "generate_api_docs":
|
|
184
|
-
return await this.generateAPIDocs(args);
|
|
185
|
-
case "generate_code_documentation":
|
|
186
|
-
return await this.generateCodeDocumentation(args);
|
|
187
|
-
case "generate_readme":
|
|
188
|
-
return await this.generateReadme(args);
|
|
189
|
-
default:
|
|
190
|
-
throw new Error(`Unknown tool: ${name}`);
|
|
191
|
-
}
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
async analyzeDocumentation(args) {
|
|
195
|
-
const { docsPath, codePath, docTypes = ["readme", "api", "code"] } = args;
|
|
196
|
-
try {
|
|
197
|
-
const analysis = await this.performDocumentationAnalysis(docsPath, codePath, docTypes);
|
|
198
|
-
return {
|
|
199
|
-
content: [
|
|
200
|
-
{
|
|
201
|
-
type: "text",
|
|
202
|
-
text: `Documentation Analysis Report:\n\n` +
|
|
203
|
-
`📊 OVERALL SCORES\n` +
|
|
204
|
-
`Completeness: ${analysis.completeness}/100\n` +
|
|
205
|
-
`Quality: ${analysis.quality}/100\n\n` +
|
|
206
|
-
`📈 COVERAGE BY TYPE\n${Object.entries(analysis.coverage)
|
|
207
|
-
.map(([type, score]) => `${type}: ${score}%`)
|
|
208
|
-
.join("\n")}\n\n` +
|
|
209
|
-
`🚨 ISSUES FOUND: ${analysis.issues.length}\n${analysis.issues
|
|
210
|
-
.slice(0, 5)
|
|
211
|
-
.map((issue) => `${this.getSeverityIcon(issue.severity)} ${issue.type.toUpperCase()}: ${issue.description}`)
|
|
212
|
-
.join("\n")}\n\n` +
|
|
213
|
-
`💡 RECOMMENDATIONS\n${analysis.recommendations.map((rec, i) => `${i + 1}. ${rec}`).join("\n")}`,
|
|
214
|
-
},
|
|
215
|
-
],
|
|
216
|
-
data: analysis,
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
catch (error) {
|
|
220
|
-
return {
|
|
221
|
-
content: [
|
|
222
|
-
{
|
|
223
|
-
type: "text",
|
|
224
|
-
text: `Error analyzing documentation: ${error instanceof Error ? error.message : String(error)}`,
|
|
225
|
-
},
|
|
226
|
-
],
|
|
227
|
-
};
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
async generateAPIDocs(args) {
|
|
231
|
-
const { codePath, framework, format = "openapi", includeExamples = true, } = args;
|
|
232
|
-
try {
|
|
233
|
-
const apiDocs = await this.analyzeAPICode(codePath, framework);
|
|
234
|
-
let output = "";
|
|
235
|
-
switch (format) {
|
|
236
|
-
case "openapi":
|
|
237
|
-
output = this.generateOpenAPISpec(apiDocs, includeExamples);
|
|
238
|
-
break;
|
|
239
|
-
case "markdown":
|
|
240
|
-
output = this.generateMarkdownAPIDocs(apiDocs, includeExamples);
|
|
241
|
-
break;
|
|
242
|
-
case "html":
|
|
243
|
-
output = this.generateHTMLAPIDocs(apiDocs, includeExamples);
|
|
244
|
-
break;
|
|
245
|
-
case "postman":
|
|
246
|
-
output = this.generatePostmanCollection(apiDocs, includeExamples);
|
|
247
|
-
break;
|
|
248
|
-
default:
|
|
249
|
-
output = this.generateOpenAPISpec(apiDocs, includeExamples);
|
|
250
|
-
}
|
|
251
|
-
return {
|
|
252
|
-
content: [
|
|
253
|
-
{
|
|
254
|
-
type: "text",
|
|
255
|
-
text: `API Documentation Generated (${format.toUpperCase()}):\n\n` +
|
|
256
|
-
`📊 API ANALYSIS\n` +
|
|
257
|
-
`Endpoints: ${apiDocs.endpoints.length}\n` +
|
|
258
|
-
`Schemas: ${apiDocs.schemas.length}\n` +
|
|
259
|
-
`Examples: ${apiDocs.examples.length}\n` +
|
|
260
|
-
`Error Codes: ${apiDocs.errorCodes.length}\n\n` +
|
|
261
|
-
`🔐 AUTHENTICATION: ${apiDocs.authentication.type.toUpperCase()}\n` +
|
|
262
|
-
`${apiDocs.authentication.description}\n\n` +
|
|
263
|
-
`${format === "markdown" ? output.substring(0, 2000) + (output.length > 2000 ? "\n\n... (truncated)" : "") : "Full documentation generated successfully."}`,
|
|
264
|
-
},
|
|
265
|
-
],
|
|
266
|
-
fullDocumentation: output,
|
|
267
|
-
data: apiDocs,
|
|
268
|
-
};
|
|
269
|
-
}
|
|
270
|
-
catch (error) {
|
|
271
|
-
return {
|
|
272
|
-
content: [
|
|
273
|
-
{
|
|
274
|
-
type: "text",
|
|
275
|
-
text: `Error generating API documentation: ${error instanceof Error ? error.message : String(error)}`,
|
|
276
|
-
},
|
|
277
|
-
],
|
|
278
|
-
};
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
async generateCodeDocumentation(args) {
|
|
282
|
-
const { codePath, language, style = "jsdoc", includePrivate = false, } = args;
|
|
283
|
-
try {
|
|
284
|
-
const documentation = await this.analyzeCodeForDocumentation(codePath, language, includePrivate);
|
|
285
|
-
const generatedDocs = this.generateDocumentationComments(documentation, style);
|
|
286
|
-
return {
|
|
287
|
-
content: [
|
|
288
|
-
{
|
|
289
|
-
type: "text",
|
|
290
|
-
text: `Code Documentation Analysis:\n\n` +
|
|
291
|
-
`📊 ANALYSIS RESULTS\n` +
|
|
292
|
-
`Files Processed: ${documentation.filesProcessed}\n` +
|
|
293
|
-
`Functions Documented: ${documentation.functionsDocumented}/${documentation.totalFunctions}\n` +
|
|
294
|
-
`Classes Documented: ${documentation.classesDocumented}/${documentation.totalClasses}\n` +
|
|
295
|
-
`Coverage: ${documentation.coverage}%\n\n` +
|
|
296
|
-
`📝 GENERATED DOCUMENTATION\n` +
|
|
297
|
-
`Style: ${style.toUpperCase()}\n` +
|
|
298
|
-
`Comments Added: ${generatedDocs.length}\n\n` +
|
|
299
|
-
`💡 SAMPLE GENERATED DOCS\n${generatedDocs
|
|
300
|
-
.slice(0, 3)
|
|
301
|
-
.map((doc) => `\`\`\`${language}\n${doc}\n\`\`\``)
|
|
302
|
-
.join("\n\n")}`,
|
|
303
|
-
},
|
|
304
|
-
],
|
|
305
|
-
documentationUpdates: generatedDocs,
|
|
306
|
-
data: documentation,
|
|
307
|
-
};
|
|
308
|
-
}
|
|
309
|
-
catch (error) {
|
|
310
|
-
return {
|
|
311
|
-
content: [
|
|
312
|
-
{
|
|
313
|
-
type: "text",
|
|
314
|
-
text: `Error generating code documentation: ${error instanceof Error ? error.message : String(error)}`,
|
|
315
|
-
},
|
|
316
|
-
],
|
|
317
|
-
};
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
async generateReadme(args) {
|
|
321
|
-
const { projectPath, projectType, includeSections = [
|
|
322
|
-
"installation",
|
|
323
|
-
"usage",
|
|
324
|
-
"api",
|
|
325
|
-
"contributing",
|
|
326
|
-
"license",
|
|
327
|
-
], existingReadme, } = args;
|
|
328
|
-
try {
|
|
329
|
-
const projectAnalysis = await this.analyzeProjectStructure(projectPath, projectType);
|
|
330
|
-
const readmeContent = this.generateReadmeContent(projectAnalysis, includeSections, existingReadme);
|
|
331
|
-
return {
|
|
332
|
-
content: [
|
|
333
|
-
{
|
|
334
|
-
type: "text",
|
|
335
|
-
text: `README Generation Complete:\n\n` +
|
|
336
|
-
`📋 PROJECT ANALYSIS\n` +
|
|
337
|
-
`Type: ${projectType.toUpperCase()}\n` +
|
|
338
|
-
`Languages: ${projectAnalysis.languages.join(", ")}\n` +
|
|
339
|
-
`Dependencies: ${projectAnalysis.dependencies.length}\n` +
|
|
340
|
-
`Entry Points: ${projectAnalysis.entryPoints.length}\n\n` +
|
|
341
|
-
`📝 README STRUCTURE\n` +
|
|
342
|
-
`Sections: ${includeSections.join(", ")}\n` +
|
|
343
|
-
`Length: ${readmeContent.length} characters\n\n` +
|
|
344
|
-
`📖 GENERATED README\n${readmeContent.substring(0, 1000)}${readmeContent.length > 1000 ? "\n\n... (truncated - see full content)" : ""}`,
|
|
345
|
-
},
|
|
346
|
-
],
|
|
347
|
-
fullReadme: readmeContent,
|
|
348
|
-
data: projectAnalysis,
|
|
349
|
-
};
|
|
350
|
-
}
|
|
351
|
-
catch (error) {
|
|
352
|
-
return {
|
|
353
|
-
content: [
|
|
354
|
-
{
|
|
355
|
-
type: "text",
|
|
356
|
-
text: `Error generating README: ${error instanceof Error ? error.message : String(error)}`,
|
|
357
|
-
},
|
|
358
|
-
],
|
|
359
|
-
};
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
async performDocumentationAnalysis(docsPath, codePath, docTypes) {
|
|
363
|
-
const analysis = {
|
|
364
|
-
completeness: 0,
|
|
365
|
-
quality: 0,
|
|
366
|
-
coverage: {},
|
|
367
|
-
issues: [],
|
|
368
|
-
recommendations: [],
|
|
369
|
-
};
|
|
370
|
-
// Analyze existing documentation
|
|
371
|
-
for (const docType of docTypes) {
|
|
372
|
-
analysis.coverage[docType] = await this.analyzeDocTypeCoverage(docsPath, docType);
|
|
373
|
-
}
|
|
374
|
-
// Compare with code if provided
|
|
375
|
-
if (codePath) {
|
|
376
|
-
analysis.issues = await this.compareDocsWithCode(docsPath, codePath, docTypes);
|
|
377
|
-
}
|
|
378
|
-
// Check documentation quality
|
|
379
|
-
analysis.issues.push(...(await this.analyzeDocumentationQuality(docsPath)));
|
|
380
|
-
// Calculate scores
|
|
381
|
-
analysis.completeness = this.calculateCompletenessScore(analysis.coverage);
|
|
382
|
-
analysis.quality = this.calculateQualityScore(analysis.issues);
|
|
383
|
-
// Generate recommendations
|
|
384
|
-
analysis.recommendations =
|
|
385
|
-
this.generateDocumentationRecommendations(analysis);
|
|
386
|
-
return analysis;
|
|
387
|
-
}
|
|
388
|
-
async analyzeDocTypeCoverage(docsPath, docType) {
|
|
389
|
-
let coverage = 0;
|
|
390
|
-
try {
|
|
391
|
-
const files = fs.readdirSync(docsPath, { recursive: true });
|
|
392
|
-
switch (docType) {
|
|
393
|
-
case "readme":
|
|
394
|
-
coverage = files.some((f) => typeof f === "string" && f.toLowerCase().includes("readme"))
|
|
395
|
-
? 100
|
|
396
|
-
: 0;
|
|
397
|
-
break;
|
|
398
|
-
case "api":
|
|
399
|
-
coverage = files.some((f) => typeof f === "string" &&
|
|
400
|
-
(f.includes("api") ||
|
|
401
|
-
f.includes("swagger") ||
|
|
402
|
-
f.includes("openapi")))
|
|
403
|
-
? 100
|
|
404
|
-
: 0;
|
|
405
|
-
break;
|
|
406
|
-
case "code":
|
|
407
|
-
coverage = files.some((f) => typeof f === "string" && f.includes("code"))
|
|
408
|
-
? 100
|
|
409
|
-
: 0;
|
|
410
|
-
break;
|
|
411
|
-
case "architecture":
|
|
412
|
-
coverage = files.some((f) => typeof f === "string" &&
|
|
413
|
-
(f.includes("arch") || f.includes("design")))
|
|
414
|
-
? 100
|
|
415
|
-
: 0;
|
|
416
|
-
break;
|
|
417
|
-
case "deployment":
|
|
418
|
-
coverage = files.some((f) => typeof f === "string" && f.includes("deploy"))
|
|
419
|
-
? 100
|
|
420
|
-
: 0;
|
|
421
|
-
break;
|
|
422
|
-
case "user-guide":
|
|
423
|
-
coverage = files.some((f) => typeof f === "string" &&
|
|
424
|
-
(f.includes("guide") || f.includes("tutorial")))
|
|
425
|
-
? 100
|
|
426
|
-
: 0;
|
|
427
|
-
break;
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
catch {
|
|
431
|
-
coverage = 0;
|
|
432
|
-
}
|
|
433
|
-
return coverage;
|
|
434
|
-
}
|
|
435
|
-
async compareDocsWithCode(docsPath, codePath, docTypes) {
|
|
436
|
-
const issues = [];
|
|
437
|
-
// Check for missing API documentation
|
|
438
|
-
if (docTypes.includes("api")) {
|
|
439
|
-
// This would analyze code for exported functions/classes and check if they're documented
|
|
440
|
-
issues.push({
|
|
441
|
-
type: "missing",
|
|
442
|
-
severity: "medium",
|
|
443
|
-
description: "API documentation not found for exported functions",
|
|
444
|
-
suggestion: "Generate API documentation for all public exports",
|
|
445
|
-
});
|
|
446
|
-
}
|
|
447
|
-
// Check for README completeness
|
|
448
|
-
if (docTypes.includes("readme")) {
|
|
449
|
-
issues.push({
|
|
450
|
-
type: "incomplete",
|
|
451
|
-
severity: "low",
|
|
452
|
-
description: "README missing usage examples",
|
|
453
|
-
suggestion: "Add practical usage examples to README",
|
|
454
|
-
});
|
|
455
|
-
}
|
|
456
|
-
return issues;
|
|
457
|
-
}
|
|
458
|
-
async analyzeDocumentationQuality(docsPath) {
|
|
459
|
-
const issues = [];
|
|
460
|
-
try {
|
|
461
|
-
const files = fs.readdirSync(docsPath, { recursive: true });
|
|
462
|
-
for (const file of files) {
|
|
463
|
-
if (typeof file === "string" &&
|
|
464
|
-
(file.endsWith(".md") || file.endsWith(".txt"))) {
|
|
465
|
-
try {
|
|
466
|
-
const content = fs.readFileSync(path.join(docsPath, file), "utf-8");
|
|
467
|
-
// Check for outdated information
|
|
468
|
-
if (content.includes("TODO") || content.includes("FIXME")) {
|
|
469
|
-
issues.push({
|
|
470
|
-
type: "incomplete",
|
|
471
|
-
severity: "low",
|
|
472
|
-
file,
|
|
473
|
-
description: "Documentation contains TODO/FIXME comments",
|
|
474
|
-
suggestion: "Address pending documentation tasks",
|
|
475
|
-
});
|
|
476
|
-
}
|
|
477
|
-
// Check for broken links (simplified)
|
|
478
|
-
const links = content.match(/\[([^\]]+)\]\(([^)]+)\)/g);
|
|
479
|
-
if (links && links.some((link) => link.includes("http"))) {
|
|
480
|
-
issues.push({
|
|
481
|
-
type: "inconsistent",
|
|
482
|
-
severity: "low",
|
|
483
|
-
file,
|
|
484
|
-
description: "External links should be validated",
|
|
485
|
-
suggestion: "Verify all external links are accessible",
|
|
486
|
-
});
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
catch {
|
|
490
|
-
// Skip files that can't be read
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
catch {
|
|
496
|
-
// Skip directories that can't be read
|
|
497
|
-
}
|
|
498
|
-
return issues;
|
|
499
|
-
}
|
|
500
|
-
calculateCompletenessScore(coverage) {
|
|
501
|
-
const values = Object.values(coverage);
|
|
502
|
-
return values.length > 0
|
|
503
|
-
? Math.round(values.reduce((sum, val) => sum + val, 0) / values.length)
|
|
504
|
-
: 0;
|
|
505
|
-
}
|
|
506
|
-
calculateQualityScore(issues) {
|
|
507
|
-
let score = 100;
|
|
508
|
-
issues.forEach((issue) => {
|
|
509
|
-
switch (issue.severity) {
|
|
510
|
-
case "critical":
|
|
511
|
-
score -= 15;
|
|
512
|
-
break;
|
|
513
|
-
case "high":
|
|
514
|
-
score -= 10;
|
|
515
|
-
break;
|
|
516
|
-
case "medium":
|
|
517
|
-
score -= 5;
|
|
518
|
-
break;
|
|
519
|
-
case "low":
|
|
520
|
-
score -= 2;
|
|
521
|
-
break;
|
|
522
|
-
}
|
|
523
|
-
});
|
|
524
|
-
return Math.max(0, score);
|
|
525
|
-
}
|
|
526
|
-
generateDocumentationRecommendations(analysis) {
|
|
527
|
-
const recommendations = [];
|
|
528
|
-
if (analysis.completeness < 70) {
|
|
529
|
-
recommendations.push("Improve documentation completeness - cover all major functionality");
|
|
530
|
-
}
|
|
531
|
-
if (analysis.quality < 80) {
|
|
532
|
-
recommendations.push("Enhance documentation quality - ensure clarity and accuracy");
|
|
533
|
-
}
|
|
534
|
-
const lowCoverage = Object.entries(analysis.coverage).filter(([_, score]) => score < 50);
|
|
535
|
-
if (lowCoverage.length > 0) {
|
|
536
|
-
recommendations.push(`Add documentation for: ${lowCoverage.map(([type]) => type).join(", ")}`);
|
|
537
|
-
}
|
|
538
|
-
recommendations.push("Set up automated documentation validation in CI/CD pipeline");
|
|
539
|
-
recommendations.push("Establish documentation review process for all changes");
|
|
540
|
-
return recommendations;
|
|
541
|
-
}
|
|
542
|
-
async analyzeAPICode(codePath, framework) {
|
|
543
|
-
const apiDocs = {
|
|
544
|
-
endpoints: [],
|
|
545
|
-
schemas: [],
|
|
546
|
-
examples: [],
|
|
547
|
-
authentication: {
|
|
548
|
-
type: "bearer",
|
|
549
|
-
description: "Bearer token authentication",
|
|
550
|
-
parameters: [],
|
|
551
|
-
examples: [],
|
|
552
|
-
},
|
|
553
|
-
errorCodes: [],
|
|
554
|
-
};
|
|
555
|
-
// Simplified API analysis - in production would be more sophisticated
|
|
556
|
-
try {
|
|
557
|
-
const files = fs.readdirSync(codePath, { recursive: true });
|
|
558
|
-
for (const file of files) {
|
|
559
|
-
if (typeof file === "string" &&
|
|
560
|
-
(file.endsWith(".ts") || file.endsWith(".js"))) {
|
|
561
|
-
try {
|
|
562
|
-
const content = fs.readFileSync(path.join(codePath, file), "utf-8");
|
|
563
|
-
// Extract route definitions based on framework
|
|
564
|
-
const routes = this.extractRoutes(content, framework);
|
|
565
|
-
apiDocs.endpoints.push(...routes);
|
|
566
|
-
// Extract schemas/types
|
|
567
|
-
const schemas = this.extractSchemas(content, framework);
|
|
568
|
-
apiDocs.schemas.push(...schemas);
|
|
569
|
-
}
|
|
570
|
-
catch {
|
|
571
|
-
// Skip files that can't be read
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
catch {
|
|
577
|
-
// Skip directories that can't be read
|
|
578
|
-
}
|
|
579
|
-
// Generate examples
|
|
580
|
-
apiDocs.examples = this.generateAPIExamples(apiDocs.endpoints);
|
|
581
|
-
// Generate error codes
|
|
582
|
-
apiDocs.errorCodes = this.generateErrorCodes();
|
|
583
|
-
return apiDocs;
|
|
584
|
-
}
|
|
585
|
-
extractRoutes(content, framework) {
|
|
586
|
-
const endpoints = [];
|
|
587
|
-
// Simplified route extraction - would be framework-specific in production
|
|
588
|
-
const routePatterns = {
|
|
589
|
-
express: /(?:app|router)\.(get|post|put|delete|patch)\s*\(\s*['"]([^'"]+)['"]/g,
|
|
590
|
-
fastify: /(?:fastify|app)\.(get|post|put|delete|patch)\s*\(\s*['"]([^'"]+)['"]/g,
|
|
591
|
-
nestjs: /@(Get|Post|Put|Delete|Patch)\s*\(\s*['"]([^'"]+)['"]\s*\)/g,
|
|
592
|
-
};
|
|
593
|
-
const pattern = routePatterns[framework];
|
|
594
|
-
if (pattern) {
|
|
595
|
-
let match;
|
|
596
|
-
while ((match = pattern.exec(content)) !== null) {
|
|
597
|
-
const [, method, path] = match;
|
|
598
|
-
if (method && path) {
|
|
599
|
-
endpoints.push({
|
|
600
|
-
path,
|
|
601
|
-
method: method.toUpperCase(),
|
|
602
|
-
summary: `API endpoint`,
|
|
603
|
-
description: `API endpoint for ${path}`,
|
|
604
|
-
parameters: [],
|
|
605
|
-
responses: [
|
|
606
|
-
{
|
|
607
|
-
statusCode: 200,
|
|
608
|
-
description: "Success response",
|
|
609
|
-
},
|
|
610
|
-
{
|
|
611
|
-
statusCode: 400,
|
|
612
|
-
description: "Bad request",
|
|
613
|
-
},
|
|
614
|
-
{
|
|
615
|
-
statusCode: 500,
|
|
616
|
-
description: "Internal server error",
|
|
617
|
-
},
|
|
618
|
-
],
|
|
619
|
-
tags: ["API"],
|
|
620
|
-
});
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
return endpoints;
|
|
625
|
-
}
|
|
626
|
-
extractSchemas(content, framework) {
|
|
627
|
-
const schemas = [];
|
|
628
|
-
// Extract TypeScript interfaces/classes
|
|
629
|
-
const interfaceMatches = content.match(/interface\s+(\w+)\s*{([^}]*)}/g);
|
|
630
|
-
if (interfaceMatches) {
|
|
631
|
-
interfaceMatches.forEach((match) => {
|
|
632
|
-
const [, name, properties] = match.match(/interface\s+(\w+)\s*{([^}]*)}/) || [];
|
|
633
|
-
if (name && properties) {
|
|
634
|
-
const schema = {
|
|
635
|
-
name,
|
|
636
|
-
type: "object",
|
|
637
|
-
properties: {},
|
|
638
|
-
};
|
|
639
|
-
// Parse properties (simplified)
|
|
640
|
-
const propMatches = properties.match(/(\w+):\s*([^;]+)/g);
|
|
641
|
-
if (propMatches) {
|
|
642
|
-
propMatches.forEach((prop) => {
|
|
643
|
-
const [, propName, propType] = prop.match(/(\w+):\s*([^;]+)/) || [];
|
|
644
|
-
if (propName && propType) {
|
|
645
|
-
schema.properties[propName] = {
|
|
646
|
-
type: this.mapTypeScriptType(propType.trim()),
|
|
647
|
-
description: `${propName} field`,
|
|
648
|
-
};
|
|
649
|
-
}
|
|
650
|
-
});
|
|
651
|
-
}
|
|
652
|
-
schemas.push(schema);
|
|
653
|
-
}
|
|
654
|
-
});
|
|
655
|
-
}
|
|
656
|
-
return schemas;
|
|
657
|
-
}
|
|
658
|
-
mapTypeScriptType(tsType) {
|
|
659
|
-
const typeMap = {
|
|
660
|
-
string: "string",
|
|
661
|
-
number: "number",
|
|
662
|
-
boolean: "boolean",
|
|
663
|
-
"string[]": "array",
|
|
664
|
-
"number[]": "array",
|
|
665
|
-
"boolean[]": "array",
|
|
666
|
-
Date: "string",
|
|
667
|
-
any: "object",
|
|
668
|
-
};
|
|
669
|
-
return typeMap[tsType] || "string";
|
|
670
|
-
}
|
|
671
|
-
generateAPIExamples(endpoints) {
|
|
672
|
-
return endpoints.slice(0, 3).map((endpoint) => ({
|
|
673
|
-
title: `${endpoint.method} ${endpoint.path}`,
|
|
674
|
-
request: {
|
|
675
|
-
method: endpoint.method,
|
|
676
|
-
path: endpoint.path,
|
|
677
|
-
headers: {
|
|
678
|
-
"Content-Type": "application/json",
|
|
679
|
-
Authorization: "Bearer <token>",
|
|
680
|
-
},
|
|
681
|
-
},
|
|
682
|
-
response: {
|
|
683
|
-
statusCode: 200,
|
|
684
|
-
headers: {
|
|
685
|
-
"Content-Type": "application/json",
|
|
686
|
-
},
|
|
687
|
-
body: { success: true, data: {} },
|
|
688
|
-
},
|
|
689
|
-
}));
|
|
690
|
-
}
|
|
691
|
-
generateErrorCodes() {
|
|
692
|
-
return [
|
|
693
|
-
{
|
|
694
|
-
code: "VALIDATION_ERROR",
|
|
695
|
-
message: "Input validation failed",
|
|
696
|
-
description: "The provided input does not meet the required validation criteria",
|
|
697
|
-
resolution: "Check the input parameters and ensure they match the expected format",
|
|
698
|
-
},
|
|
699
|
-
{
|
|
700
|
-
code: "UNAUTHORIZED",
|
|
701
|
-
message: "Authentication required",
|
|
702
|
-
description: "Access to this resource requires authentication",
|
|
703
|
-
resolution: "Provide valid authentication credentials",
|
|
704
|
-
},
|
|
705
|
-
{
|
|
706
|
-
code: "FORBIDDEN",
|
|
707
|
-
message: "Access denied",
|
|
708
|
-
description: "You do not have permission to access this resource",
|
|
709
|
-
resolution: "Contact administrator for access permissions",
|
|
710
|
-
},
|
|
711
|
-
{
|
|
712
|
-
code: "NOT_FOUND",
|
|
713
|
-
message: "Resource not found",
|
|
714
|
-
description: "The requested resource could not be found",
|
|
715
|
-
resolution: "Verify the resource identifier and try again",
|
|
716
|
-
},
|
|
717
|
-
{
|
|
718
|
-
code: "INTERNAL_ERROR",
|
|
719
|
-
message: "Internal server error",
|
|
720
|
-
description: "An unexpected error occurred on the server",
|
|
721
|
-
resolution: "Try again later or contact support if the problem persists",
|
|
722
|
-
},
|
|
723
|
-
];
|
|
724
|
-
}
|
|
725
|
-
generateOpenAPISpec(apiDocs, includeExamples) {
|
|
726
|
-
const spec = {
|
|
727
|
-
openapi: "3.0.0",
|
|
728
|
-
info: {
|
|
729
|
-
title: "API Documentation",
|
|
730
|
-
version: "1.6.0",
|
|
731
|
-
description: "Generated API documentation",
|
|
732
|
-
},
|
|
733
|
-
servers: [
|
|
734
|
-
{
|
|
735
|
-
url: "https://api.example.com/v1",
|
|
736
|
-
},
|
|
737
|
-
],
|
|
738
|
-
security: [
|
|
739
|
-
{
|
|
740
|
-
bearerAuth: [],
|
|
741
|
-
},
|
|
742
|
-
],
|
|
743
|
-
components: {
|
|
744
|
-
securitySchemes: {
|
|
745
|
-
bearerAuth: {
|
|
746
|
-
type: "http",
|
|
747
|
-
scheme: "bearer",
|
|
748
|
-
},
|
|
749
|
-
},
|
|
750
|
-
schemas: apiDocs.schemas.reduce((acc, schema) => {
|
|
751
|
-
acc[schema.name] = {
|
|
752
|
-
type: schema.type,
|
|
753
|
-
properties: schema.properties,
|
|
754
|
-
required: schema.required,
|
|
755
|
-
};
|
|
756
|
-
return acc;
|
|
757
|
-
}, {}),
|
|
758
|
-
},
|
|
759
|
-
paths: apiDocs.endpoints.reduce((acc, endpoint) => {
|
|
760
|
-
const pathKey = endpoint.path.replace(/:(\w+)/g, "{$1}");
|
|
761
|
-
if (!acc[pathKey])
|
|
762
|
-
acc[pathKey] = {};
|
|
763
|
-
acc[pathKey][endpoint.method.toLowerCase()] = {
|
|
764
|
-
summary: endpoint.summary,
|
|
765
|
-
description: endpoint.description,
|
|
766
|
-
parameters: endpoint.parameters.map((param) => ({
|
|
767
|
-
name: param.name,
|
|
768
|
-
in: "path",
|
|
769
|
-
required: param.required,
|
|
770
|
-
schema: { type: param.type },
|
|
771
|
-
description: param.description,
|
|
772
|
-
})),
|
|
773
|
-
responses: endpoint.responses.reduce((resAcc, response) => {
|
|
774
|
-
resAcc[response.statusCode] = {
|
|
775
|
-
description: response.description,
|
|
776
|
-
content: {
|
|
777
|
-
"application/json": {
|
|
778
|
-
schema: response.schema
|
|
779
|
-
? {
|
|
780
|
-
$ref: `#/components/schemas/${response.schema.name}`,
|
|
781
|
-
}
|
|
782
|
-
: {},
|
|
783
|
-
},
|
|
784
|
-
},
|
|
785
|
-
};
|
|
786
|
-
return resAcc;
|
|
787
|
-
}, {}),
|
|
788
|
-
tags: endpoint.tags,
|
|
789
|
-
};
|
|
790
|
-
return acc;
|
|
791
|
-
}, {}),
|
|
792
|
-
};
|
|
793
|
-
return JSON.stringify(spec, null, 2);
|
|
794
|
-
}
|
|
795
|
-
generateMarkdownAPIDocs(apiDocs, includeExamples) {
|
|
796
|
-
let markdown = `# API Documentation\n\n`;
|
|
797
|
-
markdown += `## Authentication\n\n`;
|
|
798
|
-
markdown += `${apiDocs.authentication.description}\n\n`;
|
|
799
|
-
if (includeExamples && apiDocs.authentication.examples.length > 0) {
|
|
800
|
-
markdown += `### Authentication Examples\n\n`;
|
|
801
|
-
apiDocs.authentication.examples.forEach((example) => {
|
|
802
|
-
markdown += `#### ${example.title}\n\n`;
|
|
803
|
-
markdown += `\`\`\`\n`;
|
|
804
|
-
Object.entries(example.headers).forEach(([key, value]) => {
|
|
805
|
-
markdown += `${key}: ${value}\n`;
|
|
806
|
-
});
|
|
807
|
-
markdown += `\`\`\`\n\n`;
|
|
808
|
-
markdown += `${example.description}\n\n`;
|
|
809
|
-
});
|
|
810
|
-
}
|
|
811
|
-
markdown += `## Endpoints\n\n`;
|
|
812
|
-
apiDocs.endpoints.forEach((endpoint) => {
|
|
813
|
-
markdown += `### ${endpoint.method} ${endpoint.path}\n\n`;
|
|
814
|
-
markdown += `${endpoint.description}\n\n`;
|
|
815
|
-
if (endpoint.parameters.length > 0) {
|
|
816
|
-
markdown += `**Parameters:**\n\n`;
|
|
817
|
-
endpoint.parameters.forEach((param) => {
|
|
818
|
-
markdown += `- \`${param.name}\` (${param.type})`;
|
|
819
|
-
if (param.required)
|
|
820
|
-
markdown += " **required**";
|
|
821
|
-
markdown += ` - ${param.description}\n`;
|
|
822
|
-
});
|
|
823
|
-
markdown += `\n`;
|
|
824
|
-
}
|
|
825
|
-
markdown += `**Responses:**\n\n`;
|
|
826
|
-
endpoint.responses.forEach((response) => {
|
|
827
|
-
markdown += `- \`${response.statusCode}\`: ${response.description}\n`;
|
|
828
|
-
});
|
|
829
|
-
markdown += `\n`;
|
|
830
|
-
});
|
|
831
|
-
if (apiDocs.errorCodes.length > 0) {
|
|
832
|
-
markdown += `## Error Codes\n\n`;
|
|
833
|
-
apiDocs.errorCodes.forEach((error) => {
|
|
834
|
-
markdown += `### ${error.code}\n\n`;
|
|
835
|
-
markdown += `**Message:** ${error.message}\n\n`;
|
|
836
|
-
markdown += `**Description:** ${error.description}\n\n`;
|
|
837
|
-
markdown += `**Resolution:** ${error.resolution}\n\n`;
|
|
838
|
-
});
|
|
839
|
-
}
|
|
840
|
-
return markdown;
|
|
841
|
-
}
|
|
842
|
-
generateHTMLAPIDocs(apiDocs, includeExamples) {
|
|
843
|
-
return `<html><body><h1>API Documentation</h1><p>Generated documentation</p></body></html>`;
|
|
844
|
-
}
|
|
845
|
-
generatePostmanCollection(apiDocs, includeExamples) {
|
|
846
|
-
const collection = {
|
|
847
|
-
info: {
|
|
848
|
-
name: "API Collection",
|
|
849
|
-
schema: "https://schema.getpostman.com/json/collection/v1.1.1/collection.json",
|
|
850
|
-
},
|
|
851
|
-
item: apiDocs.endpoints.map((endpoint) => ({
|
|
852
|
-
name: `${endpoint.method} ${endpoint.path}`,
|
|
853
|
-
request: {
|
|
854
|
-
method: endpoint.method,
|
|
855
|
-
header: [
|
|
856
|
-
{
|
|
857
|
-
key: "Content-Type",
|
|
858
|
-
value: "application/json",
|
|
859
|
-
},
|
|
860
|
-
],
|
|
861
|
-
url: {
|
|
862
|
-
raw: `{{baseUrl}}${endpoint.path}`,
|
|
863
|
-
host: ["{{baseUrl}}"],
|
|
864
|
-
path: endpoint.path.split("/").filter((p) => p),
|
|
865
|
-
},
|
|
866
|
-
},
|
|
867
|
-
})),
|
|
868
|
-
};
|
|
869
|
-
return JSON.stringify(collection, null, 2);
|
|
870
|
-
}
|
|
871
|
-
async analyzeCodeForDocumentation(codePath, language, includePrivate) {
|
|
872
|
-
const analysis = {
|
|
873
|
-
filesProcessed: 0,
|
|
874
|
-
totalFunctions: 0,
|
|
875
|
-
functionsDocumented: 0,
|
|
876
|
-
totalClasses: 0,
|
|
877
|
-
classesDocumented: 0,
|
|
878
|
-
coverage: 0,
|
|
879
|
-
};
|
|
880
|
-
try {
|
|
881
|
-
const files = fs.readdirSync(codePath, { recursive: true });
|
|
882
|
-
for (const file of files) {
|
|
883
|
-
if (typeof file === "string" &&
|
|
884
|
-
((language === "typescript" && file.endsWith(".ts")) ||
|
|
885
|
-
(language === "javascript" && file.endsWith(".js")) ||
|
|
886
|
-
(language === "python" && file.endsWith(".py")))) {
|
|
887
|
-
try {
|
|
888
|
-
const content = fs.readFileSync(path.join(codePath, file), "utf-8");
|
|
889
|
-
analysis.filesProcessed++;
|
|
890
|
-
// Analyze functions
|
|
891
|
-
const functions = this.extractFunctions(content, language);
|
|
892
|
-
analysis.totalFunctions += functions.length;
|
|
893
|
-
analysis.functionsDocumented += functions.filter((f) => this.hasDocumentation(f, content, language)).length;
|
|
894
|
-
// Analyze classes
|
|
895
|
-
const classes = this.extractClasses(content, language);
|
|
896
|
-
analysis.totalClasses += classes.length;
|
|
897
|
-
analysis.classesDocumented += classes.filter((c) => this.hasDocumentation(c, content, language)).length;
|
|
898
|
-
}
|
|
899
|
-
catch {
|
|
900
|
-
// Skip files that can't be read
|
|
901
|
-
}
|
|
902
|
-
}
|
|
903
|
-
}
|
|
904
|
-
}
|
|
905
|
-
catch {
|
|
906
|
-
// Skip directories that can't be read
|
|
907
|
-
}
|
|
908
|
-
// Calculate coverage
|
|
909
|
-
const totalDocumentable = analysis.totalFunctions + analysis.totalClasses;
|
|
910
|
-
const documented = analysis.functionsDocumented + analysis.classesDocumented;
|
|
911
|
-
analysis.coverage =
|
|
912
|
-
totalDocumentable > 0
|
|
913
|
-
? Math.round((documented / totalDocumentable) * 100)
|
|
914
|
-
: 0;
|
|
915
|
-
return analysis;
|
|
916
|
-
}
|
|
917
|
-
extractFunctions(content, language) {
|
|
918
|
-
const functions = [];
|
|
919
|
-
switch (language) {
|
|
920
|
-
case "typescript":
|
|
921
|
-
case "javascript":
|
|
922
|
-
// Match function declarations and arrow functions
|
|
923
|
-
const jsFunctions = content.match(/(?:function\s+(\w+)|const\s+(\w+)\s*=\s*(?:\([^)]*\)\s*=>|function\s*\([^)]*\)))/g);
|
|
924
|
-
if (jsFunctions) {
|
|
925
|
-
functions.push(...jsFunctions.map((f) => f
|
|
926
|
-
.replace(/^(?:function\s+|const\s+|=\s*)/, "")
|
|
927
|
-
.replace(/\s*=.*$/, "")));
|
|
928
|
-
}
|
|
929
|
-
break;
|
|
930
|
-
case "python":
|
|
931
|
-
// Match function definitions
|
|
932
|
-
const pyFunctions = content.match(/def\s+(\w+)/g);
|
|
933
|
-
if (pyFunctions) {
|
|
934
|
-
functions.push(...pyFunctions.map((f) => f.replace("def ", "")));
|
|
935
|
-
}
|
|
936
|
-
break;
|
|
937
|
-
}
|
|
938
|
-
return functions;
|
|
939
|
-
}
|
|
940
|
-
extractClasses(content, language) {
|
|
941
|
-
const classes = [];
|
|
942
|
-
switch (language) {
|
|
943
|
-
case "typescript":
|
|
944
|
-
case "javascript":
|
|
945
|
-
const jsClasses = content.match(/class\s+(\w+)/g);
|
|
946
|
-
if (jsClasses) {
|
|
947
|
-
classes.push(...jsClasses.map((c) => c.replace("class ", "")));
|
|
948
|
-
}
|
|
949
|
-
break;
|
|
950
|
-
case "python":
|
|
951
|
-
const pyClasses = content.match(/class\s+(\w+)/g);
|
|
952
|
-
if (pyClasses) {
|
|
953
|
-
classes.push(...pyClasses.map((c) => c.replace("class ", "")));
|
|
954
|
-
}
|
|
955
|
-
break;
|
|
956
|
-
}
|
|
957
|
-
return classes;
|
|
958
|
-
}
|
|
959
|
-
hasDocumentation(element, content, language) {
|
|
960
|
-
// Check if there's documentation before the element
|
|
961
|
-
const elementIndex = content.indexOf(element);
|
|
962
|
-
if (elementIndex === -1)
|
|
963
|
-
return false;
|
|
964
|
-
// Look for documentation comments before the element
|
|
965
|
-
const beforeElement = content.substring(0, elementIndex);
|
|
966
|
-
const lines = beforeElement.split("\n");
|
|
967
|
-
let consecutiveCommentLines = 0;
|
|
968
|
-
for (let i = lines.length - 1; i >= 0; i--) {
|
|
969
|
-
const line = lines[i];
|
|
970
|
-
if (!line)
|
|
971
|
-
continue;
|
|
972
|
-
const trimmedLine = line.trim();
|
|
973
|
-
if (language === "python" && trimmedLine.startsWith('"""')) {
|
|
974
|
-
return true;
|
|
975
|
-
}
|
|
976
|
-
if ((language === "typescript" || language === "javascript") &&
|
|
977
|
-
(trimmedLine.startsWith("/**") ||
|
|
978
|
-
trimmedLine.startsWith("*") ||
|
|
979
|
-
trimmedLine.startsWith("*/") ||
|
|
980
|
-
trimmedLine.startsWith("//") ||
|
|
981
|
-
trimmedLine.match(/\/\*\*/))) {
|
|
982
|
-
consecutiveCommentLines++;
|
|
983
|
-
if (consecutiveCommentLines >= 2)
|
|
984
|
-
return true;
|
|
985
|
-
}
|
|
986
|
-
else if (trimmedLine === "") {
|
|
987
|
-
continue; // Skip empty lines
|
|
988
|
-
}
|
|
989
|
-
else {
|
|
990
|
-
break; // Stop if we hit non-comment, non-empty line
|
|
991
|
-
}
|
|
992
|
-
}
|
|
993
|
-
return false;
|
|
994
|
-
}
|
|
995
|
-
generateDocumentationComments(documentation, style) {
|
|
996
|
-
const comments = [];
|
|
997
|
-
// This would generate actual documentation comments based on code analysis
|
|
998
|
-
// For now, return sample comments
|
|
999
|
-
comments.push(`/**
|
|
1000
|
-
* Sample function documentation
|
|
1001
|
-
* @param {string} param1 - First parameter
|
|
1002
|
-
* @param {number} param2 - Second parameter
|
|
1003
|
-
* @returns {boolean} Result of operation
|
|
1004
|
-
*/`);
|
|
1005
|
-
comments.push(`/**
|
|
1006
|
-
* Sample class documentation
|
|
1007
|
-
* @class
|
|
1008
|
-
* @description Represents a sample class
|
|
1009
|
-
*/`);
|
|
1010
|
-
return comments;
|
|
1011
|
-
}
|
|
1012
|
-
async analyzeProjectStructure(projectPath, projectType) {
|
|
1013
|
-
const analysis = {
|
|
1014
|
-
languages: [],
|
|
1015
|
-
dependencies: [],
|
|
1016
|
-
entryPoints: [],
|
|
1017
|
-
structure: {},
|
|
1018
|
-
};
|
|
1019
|
-
try {
|
|
1020
|
-
// Analyze package.json if it exists
|
|
1021
|
-
const packagePath = path.join(projectPath, "package.json");
|
|
1022
|
-
if (fs.existsSync(packagePath)) {
|
|
1023
|
-
const packageJson = JSON.parse(fs.readFileSync(packagePath, "utf-8"));
|
|
1024
|
-
analysis.dependencies = Object.keys(packageJson.dependencies || {});
|
|
1025
|
-
analysis.entryPoints = [packageJson.main || "index.js"];
|
|
1026
|
-
}
|
|
1027
|
-
// Analyze languages used
|
|
1028
|
-
const files = fs.readdirSync(projectPath, { recursive: true });
|
|
1029
|
-
const extensions = new Set();
|
|
1030
|
-
files.forEach((file) => {
|
|
1031
|
-
if (typeof file === "string") {
|
|
1032
|
-
const ext = path.extname(file);
|
|
1033
|
-
if (ext)
|
|
1034
|
-
extensions.add(ext);
|
|
1035
|
-
}
|
|
1036
|
-
});
|
|
1037
|
-
const langMap = {
|
|
1038
|
-
".ts": "TypeScript",
|
|
1039
|
-
".tsx": "TypeScript",
|
|
1040
|
-
".js": "JavaScript",
|
|
1041
|
-
".jsx": "JavaScript",
|
|
1042
|
-
".py": "Python",
|
|
1043
|
-
".java": "Java",
|
|
1044
|
-
".go": "Go",
|
|
1045
|
-
".rs": "Rust",
|
|
1046
|
-
};
|
|
1047
|
-
analysis.languages = Array.from(extensions).map((ext) => langMap[ext] || ext.substring(1));
|
|
1048
|
-
}
|
|
1049
|
-
catch {
|
|
1050
|
-
// Use defaults if analysis fails
|
|
1051
|
-
}
|
|
1052
|
-
return analysis;
|
|
1053
|
-
}
|
|
1054
|
-
generateReadmeContent(projectAnalysis, includeSections, existingReadme) {
|
|
1055
|
-
let content = "";
|
|
1056
|
-
// Title
|
|
1057
|
-
content += `# ${projectAnalysis.name || "Project Name"}\n\n`;
|
|
1058
|
-
// Description
|
|
1059
|
-
content += `${projectAnalysis.description || "A software project."}\n\n`;
|
|
1060
|
-
// Badges (if applicable)
|
|
1061
|
-
if (projectAnalysis.languages.includes("TypeScript")) {
|
|
1062
|
-
content += `[](https://www.typescriptlang.org/)\n`;
|
|
1063
|
-
}
|
|
1064
|
-
content += "\n";
|
|
1065
|
-
// Table of Contents
|
|
1066
|
-
if (includeSections.length > 3) {
|
|
1067
|
-
content += "## Table of Contents\n\n";
|
|
1068
|
-
includeSections.forEach((section) => {
|
|
1069
|
-
content += `- [${section.charAt(0).toUpperCase() + section.slice(1)}](#${section})\n`;
|
|
1070
|
-
});
|
|
1071
|
-
content += "\n";
|
|
1072
|
-
}
|
|
1073
|
-
// Generate each requested section
|
|
1074
|
-
includeSections.forEach((section) => {
|
|
1075
|
-
switch (section) {
|
|
1076
|
-
case "installation":
|
|
1077
|
-
content += this.generateInstallationSection(projectAnalysis);
|
|
1078
|
-
break;
|
|
1079
|
-
case "usage":
|
|
1080
|
-
content += this.generateUsageSection(projectAnalysis);
|
|
1081
|
-
break;
|
|
1082
|
-
case "api":
|
|
1083
|
-
content += this.generateAPISection(projectAnalysis);
|
|
1084
|
-
break;
|
|
1085
|
-
case "contributing":
|
|
1086
|
-
content += this.generateContributingSection();
|
|
1087
|
-
break;
|
|
1088
|
-
case "license":
|
|
1089
|
-
content += this.generateLicenseSection();
|
|
1090
|
-
break;
|
|
1091
|
-
}
|
|
1092
|
-
});
|
|
1093
|
-
return content;
|
|
1094
|
-
}
|
|
1095
|
-
generateInstallationSection(projectAnalysis) {
|
|
1096
|
-
let content = "## Installation\n\n";
|
|
1097
|
-
if (projectAnalysis.languages.includes("JavaScript") ||
|
|
1098
|
-
projectAnalysis.languages.includes("TypeScript")) {
|
|
1099
|
-
content += "```bash\n";
|
|
1100
|
-
content += "# Clone the repository\n";
|
|
1101
|
-
content += "git clone <repository-url>\n";
|
|
1102
|
-
content += "cd <project-directory>\n\n";
|
|
1103
|
-
content += "# Install dependencies\n";
|
|
1104
|
-
content += "npm install\n";
|
|
1105
|
-
content += "# or\n";
|
|
1106
|
-
content += "yarn install\n";
|
|
1107
|
-
content += "```\n\n";
|
|
1108
|
-
}
|
|
1109
|
-
if (projectAnalysis.languages.includes("Python")) {
|
|
1110
|
-
content += "```bash\n";
|
|
1111
|
-
content += "# Install with pip\n";
|
|
1112
|
-
content += "pip install <package-name>\n\n";
|
|
1113
|
-
content += "# Or install from source\n";
|
|
1114
|
-
content += "git clone <repository-url>\n";
|
|
1115
|
-
content += "cd <project-directory>\n";
|
|
1116
|
-
content += "pip install -e .\n";
|
|
1117
|
-
content += "```\n\n";
|
|
1118
|
-
}
|
|
1119
|
-
return content;
|
|
1120
|
-
}
|
|
1121
|
-
generateUsageSection(projectAnalysis) {
|
|
1122
|
-
let content = "## Usage\n\n";
|
|
1123
|
-
content += "```javascript\n";
|
|
1124
|
-
content += "// Basic usage example\n";
|
|
1125
|
-
content += "const result = await performOperation();\n";
|
|
1126
|
-
content += "console.log(result);\n";
|
|
1127
|
-
content += "```\n\n";
|
|
1128
|
-
content += "### Advanced Usage\n\n";
|
|
1129
|
-
content +=
|
|
1130
|
-
"For more advanced features, see the [API documentation](./docs/api.md).\n\n";
|
|
1131
|
-
return content;
|
|
1132
|
-
}
|
|
1133
|
-
generateAPISection(projectAnalysis) {
|
|
1134
|
-
let content = "## API\n\n";
|
|
1135
|
-
content += "### Core Functions\n\n";
|
|
1136
|
-
content += "- `performOperation()` - Performs the main operation\n";
|
|
1137
|
-
content += "- `configure(options)` - Configures the library\n";
|
|
1138
|
-
content += "- `validateInput(input)` - Validates input data\n\n";
|
|
1139
|
-
content +=
|
|
1140
|
-
"For detailed API documentation, see [API Reference](./docs/api.md).\n\n";
|
|
1141
|
-
return content;
|
|
1142
|
-
}
|
|
1143
|
-
generateContributingSection() {
|
|
1144
|
-
let content = "## Contributing\n\n";
|
|
1145
|
-
content +=
|
|
1146
|
-
"We welcome contributions! Please see our [Contributing Guide](./CONTRIBUTING.md) for details.\n\n";
|
|
1147
|
-
content += "### Development Setup\n\n";
|
|
1148
|
-
content += "```bash\n";
|
|
1149
|
-
content += "git clone <repository-url>\n";
|
|
1150
|
-
content += "cd <project-directory>\n";
|
|
1151
|
-
content += "npm install\n";
|
|
1152
|
-
content += "npm run dev\n";
|
|
1153
|
-
content += "```\n\n";
|
|
1154
|
-
content += "### Testing\n\n";
|
|
1155
|
-
content += "```bash\n";
|
|
1156
|
-
content += "npm test\n";
|
|
1157
|
-
content += "npm run test:coverage\n";
|
|
1158
|
-
content += "```\n\n";
|
|
1159
|
-
return content;
|
|
1160
|
-
}
|
|
1161
|
-
generateLicenseSection() {
|
|
1162
|
-
let content = "## License\n\n";
|
|
1163
|
-
content +=
|
|
1164
|
-
"This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n";
|
|
1165
|
-
return content;
|
|
1166
|
-
}
|
|
1167
|
-
getSeverityIcon(severity) {
|
|
1168
|
-
const icons = {
|
|
1169
|
-
critical: "🚨",
|
|
1170
|
-
high: "🔴",
|
|
1171
|
-
medium: "🟡",
|
|
1172
|
-
low: "🟢",
|
|
1173
|
-
};
|
|
1174
|
-
return icons[severity] || "❓";
|
|
1175
|
-
}
|
|
1176
|
-
async run() {
|
|
1177
|
-
const transport = new StdioServerTransport();
|
|
1178
|
-
await this.server.connect(transport);
|
|
1179
|
-
console.log("StrRay Documentation Generation MCP Server running...");
|
|
1180
|
-
const cleanup = async (signal) => {
|
|
1181
|
-
console.log(`Received ${signal}, shutting down gracefully...`);
|
|
1182
|
-
// Set a timeout to force exit if graceful shutdown fails
|
|
1183
|
-
const timeout = setTimeout(() => {
|
|
1184
|
-
console.error("Graceful shutdown timeout, forcing exit...");
|
|
1185
|
-
process.exit(1);
|
|
1186
|
-
}, 5000); // 5 second timeout
|
|
1187
|
-
try {
|
|
1188
|
-
if (this.server && typeof this.server.close === "function") {
|
|
1189
|
-
await this.server.close();
|
|
1190
|
-
}
|
|
1191
|
-
clearTimeout(timeout);
|
|
1192
|
-
console.log("StrRay MCP Server shut down gracefully");
|
|
1193
|
-
process.exit(0);
|
|
1194
|
-
}
|
|
1195
|
-
catch (error) {
|
|
1196
|
-
clearTimeout(timeout);
|
|
1197
|
-
console.error("Error during server shutdown:", error);
|
|
1198
|
-
process.exit(1);
|
|
1199
|
-
}
|
|
1200
|
-
};
|
|
1201
|
-
// Handle multiple shutdown signals
|
|
1202
|
-
process.on("SIGINT", () => cleanup("SIGINT"));
|
|
1203
|
-
process.on("SIGTERM", () => cleanup("SIGTERM"));
|
|
1204
|
-
process.on("SIGHUP", () => cleanup("SIGHUP"));
|
|
1205
|
-
// Monitor parent process (opencode) and shutdown if it dies
|
|
1206
|
-
const checkParent = () => {
|
|
1207
|
-
try {
|
|
1208
|
-
process.kill(process.ppid, 0); // Check if parent is alive
|
|
1209
|
-
setTimeout(checkParent, 1000); // Check again in 1 second
|
|
1210
|
-
}
|
|
1211
|
-
catch (error) {
|
|
1212
|
-
// Parent process died, shut down gracefully
|
|
1213
|
-
console.log("Parent process (opencode) died, shutting down MCP server...");
|
|
1214
|
-
cleanup("parent-process-death");
|
|
1215
|
-
}
|
|
1216
|
-
};
|
|
1217
|
-
// Start monitoring parent process
|
|
1218
|
-
setTimeout(checkParent, 2000); // Start checking after 2 seconds
|
|
1219
|
-
// Handle uncaught exceptions and unhandled rejections
|
|
1220
|
-
process.on("uncaughtException", (error) => {
|
|
1221
|
-
console.error("Uncaught Exception:", error);
|
|
1222
|
-
cleanup("uncaughtException");
|
|
1223
|
-
});
|
|
1224
|
-
process.on("unhandledRejection", (reason, promise) => {
|
|
1225
|
-
console.error("Unhandled Rejection at:", promise, "reason:", reason);
|
|
1226
|
-
cleanup("unhandledRejection");
|
|
1227
|
-
});
|
|
1228
|
-
process.on("SIGINT", cleanup);
|
|
1229
|
-
process.on("SIGTERM", cleanup);
|
|
1230
|
-
}
|
|
1231
|
-
}
|
|
1232
|
-
// Run the server if this file is executed directly
|
|
1233
|
-
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
1234
|
-
const server = new StrRayDocumentationGenerationServer();
|
|
1235
|
-
server.run().catch(console.error);
|
|
1236
|
-
}
|
|
1237
|
-
export { StrRayDocumentationGenerationServer };
|
|
1238
|
-
//# sourceMappingURL=documentation-generation.server.js.map
|