@redpanda-data/docs-extensions-and-macros 4.12.5 → 4.13.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.adoc +33 -1064
- package/bin/doc-tools-mcp.js +720 -0
- package/bin/doc-tools.js +1050 -50
- package/bin/mcp-tools/antora.js +153 -0
- package/bin/mcp-tools/cache.js +89 -0
- package/bin/mcp-tools/cloud-regions.js +127 -0
- package/bin/mcp-tools/content-review.js +196 -0
- package/bin/mcp-tools/crd-docs.js +153 -0
- package/bin/mcp-tools/frontmatter.js +138 -0
- package/bin/mcp-tools/generated-docs-review.js +887 -0
- package/bin/mcp-tools/helm-docs.js +152 -0
- package/bin/mcp-tools/index.js +245 -0
- package/bin/mcp-tools/job-queue.js +468 -0
- package/bin/mcp-tools/mcp-validation.js +266 -0
- package/bin/mcp-tools/metrics-docs.js +146 -0
- package/bin/mcp-tools/openapi.js +174 -0
- package/bin/mcp-tools/prompt-discovery.js +283 -0
- package/bin/mcp-tools/property-docs.js +157 -0
- package/bin/mcp-tools/rpcn-docs.js +113 -0
- package/bin/mcp-tools/rpk-docs.js +141 -0
- package/bin/mcp-tools/telemetry.js +211 -0
- package/bin/mcp-tools/utils.js +131 -0
- package/bin/mcp-tools/versions.js +168 -0
- package/cli-utils/convert-doc-links.js +1 -1
- package/cli-utils/github-token.js +58 -0
- package/cli-utils/self-managed-docs-branch.js +2 -2
- package/cli-utils/setup-mcp.js +313 -0
- package/docker-compose/25.1/transactions.md +1 -1
- package/docker-compose/transactions.md +1 -1
- package/extensions/DEVELOPMENT.adoc +464 -0
- package/extensions/README.adoc +124 -0
- package/extensions/REFERENCE.adoc +768 -0
- package/extensions/USER_GUIDE.adoc +339 -0
- package/extensions/generate-rp-connect-info.js +3 -4
- package/extensions/version-fetcher/get-latest-console-version.js +38 -27
- package/extensions/version-fetcher/get-latest-redpanda-helm-version-from-operator.js +1 -1
- package/extensions/version-fetcher/get-latest-redpanda-version.js +65 -54
- package/extensions/version-fetcher/retry-util.js +88 -0
- package/extensions/version-fetcher/set-latest-version.js +6 -3
- package/macros/DEVELOPMENT.adoc +377 -0
- package/macros/README.adoc +105 -0
- package/macros/REFERENCE.adoc +222 -0
- package/macros/USER_GUIDE.adoc +220 -0
- package/macros/rp-connect-components.js +6 -6
- package/package.json +12 -3
- package/tools/bundle-openapi.js +20 -10
- package/tools/cloud-regions/generate-cloud-regions.js +1 -1
- package/tools/fetch-from-github.js +18 -4
- package/tools/gen-rpk-ascii.py +3 -1
- package/tools/generate-cli-docs.js +325 -0
- package/tools/get-console-version.js +4 -2
- package/tools/get-redpanda-version.js +4 -2
- package/tools/metrics/metrics.py +19 -7
- package/tools/property-extractor/Makefile +7 -1
- package/tools/property-extractor/cloud_config.py +4 -4
- package/tools/property-extractor/constant_resolver.py +11 -11
- package/tools/property-extractor/property_extractor.py +18 -16
- package/tools/property-extractor/topic_property_extractor.py +2 -2
- package/tools/property-extractor/transformers.py +7 -7
- package/tools/property-extractor/type_definition_extractor.py +4 -4
- package/tools/redpanda-connect/README.adoc +1 -1
- package/tools/redpanda-connect/generate-rpcn-connector-docs.js +5 -3
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Tools - Helm Chart Documentation Generation
|
|
3
|
+
*
|
|
4
|
+
* OPTIMIZATION: This tool calls CLI, doesn't use LLM directly.
|
|
5
|
+
* - No model recommendation (CLI tool)
|
|
6
|
+
* - Cost comes from doc-tools CLI execution
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const { spawnSync } = require('child_process');
|
|
10
|
+
const { findRepoRoot, getDocToolsCommand, MAX_EXEC_BUFFER_SIZE, DEFAULT_COMMAND_TIMEOUT } = require('./utils');
|
|
11
|
+
const { getAntoraStructure } = require('./antora');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Generate Helm chart documentation
|
|
15
|
+
*
|
|
16
|
+
* Use tags for released content (GA or beta), branches for in-progress content.
|
|
17
|
+
* When using GitHub URLs, requires either --tag or --branch to be specified.
|
|
18
|
+
* Auto-prepends "operator/" for tags when using redpanda-operator repository.
|
|
19
|
+
*
|
|
20
|
+
* @param {Object} args - Arguments
|
|
21
|
+
* @param {string} [args.chart_dir] - Chart directory, root, or GitHub URL
|
|
22
|
+
* @param {string} [args.tag] - Git tag for released content when using GitHub URL (auto-prepends "operator/" for redpanda-operator repository)
|
|
23
|
+
* @param {string} [args.branch] - Branch name for in-progress content when using GitHub URL
|
|
24
|
+
* @param {string} [args.readme] - Relative README.md path inside each chart dir
|
|
25
|
+
* @param {string} [args.output_dir] - Where to write generated AsciiDoc files
|
|
26
|
+
* @param {string} [args.output_suffix] - Suffix to append to each chart name
|
|
27
|
+
* @returns {Object} Generation results
|
|
28
|
+
*/
|
|
29
|
+
function generateHelmDocs(args = {}) {
|
|
30
|
+
const repoRoot = findRepoRoot();
|
|
31
|
+
const structure = getAntoraStructure(repoRoot);
|
|
32
|
+
|
|
33
|
+
if (!structure.hasDocTools) {
|
|
34
|
+
return {
|
|
35
|
+
success: false,
|
|
36
|
+
error: 'doc-tools not found in this repository',
|
|
37
|
+
suggestion: 'Navigate to the docs-extensions-and-macros repository'
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Validate that tag and branch are mutually exclusive
|
|
42
|
+
if (args.tag && args.branch) {
|
|
43
|
+
return {
|
|
44
|
+
success: false,
|
|
45
|
+
error: 'Cannot specify both tag and branch',
|
|
46
|
+
suggestion: 'Use either --tag or --branch, not both'
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
// Normalize tag: add 'v' prefix if not present
|
|
52
|
+
let normalizedTag = null;
|
|
53
|
+
if (args.tag) {
|
|
54
|
+
normalizedTag = args.tag;
|
|
55
|
+
if (!normalizedTag.startsWith('v')) {
|
|
56
|
+
normalizedTag = `v${normalizedTag}`;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Get doc-tools command (handles both local and installed)
|
|
61
|
+
const docTools = getDocToolsCommand(repoRoot);
|
|
62
|
+
|
|
63
|
+
// Build command arguments array
|
|
64
|
+
const baseArgs = ['generate', 'helm-spec'];
|
|
65
|
+
|
|
66
|
+
if (args.chart_dir) {
|
|
67
|
+
baseArgs.push('--chart-dir');
|
|
68
|
+
baseArgs.push(args.chart_dir);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (normalizedTag) {
|
|
72
|
+
baseArgs.push('--tag');
|
|
73
|
+
baseArgs.push(normalizedTag);
|
|
74
|
+
} else if (args.branch) {
|
|
75
|
+
baseArgs.push('--branch');
|
|
76
|
+
baseArgs.push(args.branch);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (args.readme) {
|
|
80
|
+
baseArgs.push('--readme');
|
|
81
|
+
baseArgs.push(args.readme);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (args.output_dir) {
|
|
85
|
+
baseArgs.push('--output-dir');
|
|
86
|
+
baseArgs.push(args.output_dir);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (args.output_suffix) {
|
|
90
|
+
baseArgs.push('--output-suffix');
|
|
91
|
+
baseArgs.push(args.output_suffix);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const result = spawnSync(docTools.program, docTools.getArgs(baseArgs), {
|
|
95
|
+
cwd: repoRoot.root,
|
|
96
|
+
encoding: 'utf8',
|
|
97
|
+
stdio: 'pipe',
|
|
98
|
+
maxBuffer: MAX_EXEC_BUFFER_SIZE,
|
|
99
|
+
timeout: DEFAULT_COMMAND_TIMEOUT
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Check for spawn errors
|
|
103
|
+
if (result.error) {
|
|
104
|
+
const err = new Error(`Failed to execute command: ${result.error.message}`);
|
|
105
|
+
err.stdout = result.stdout || '';
|
|
106
|
+
err.stderr = result.stderr || '';
|
|
107
|
+
err.status = result.status;
|
|
108
|
+
throw err;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Check for non-zero exit codes
|
|
112
|
+
if (result.status !== 0) {
|
|
113
|
+
const errorMsg = result.stderr || `Command failed with exit code ${result.status}`;
|
|
114
|
+
const err = new Error(errorMsg);
|
|
115
|
+
err.stdout = result.stdout || '';
|
|
116
|
+
err.stderr = result.stderr || '';
|
|
117
|
+
err.status = result.status;
|
|
118
|
+
throw err;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const output = result.stdout;
|
|
122
|
+
|
|
123
|
+
// Parse output to extract information
|
|
124
|
+
const chartCountMatch = output.match(/(\d+) charts?/i);
|
|
125
|
+
|
|
126
|
+
const refType = normalizedTag ? 'tag' : args.branch ? 'branch' : null;
|
|
127
|
+
const gitRef = normalizedTag || args.branch;
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
success: true,
|
|
131
|
+
...(refType && { [refType]: gitRef }),
|
|
132
|
+
chart_dir: args.chart_dir || 'default',
|
|
133
|
+
charts_documented: chartCountMatch ? parseInt(chartCountMatch[1]) : null,
|
|
134
|
+
files_generated: [args.output_dir || 'modules/reference/pages'],
|
|
135
|
+
output: output.trim(),
|
|
136
|
+
summary: `Generated Helm chart documentation${gitRef ? ` for ${refType} ${gitRef}` : ''}`
|
|
137
|
+
};
|
|
138
|
+
} catch (err) {
|
|
139
|
+
return {
|
|
140
|
+
success: false,
|
|
141
|
+
error: err.message,
|
|
142
|
+
stdout: err.stdout || '',
|
|
143
|
+
stderr: err.stderr || '',
|
|
144
|
+
exitCode: err.status,
|
|
145
|
+
suggestion: 'Check that the chart directory or GitHub URL is valid and accessible'
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
module.exports = {
|
|
151
|
+
generateHelmDocs
|
|
152
|
+
};
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Tools - Main Exports
|
|
3
|
+
*
|
|
4
|
+
* This module exports all MCP tools in a modular structure.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Utilities
|
|
8
|
+
const { findRepoRoot, executeCommand, normalizeVersion, formatDate } = require('./utils');
|
|
9
|
+
|
|
10
|
+
// Antora
|
|
11
|
+
const { getAntoraStructure } = require('./antora');
|
|
12
|
+
|
|
13
|
+
// Versions
|
|
14
|
+
const { getRedpandaVersion, getConsoleVersion } = require('./versions');
|
|
15
|
+
|
|
16
|
+
// Documentation generation tools
|
|
17
|
+
const { generatePropertyDocs } = require('./property-docs');
|
|
18
|
+
const { generateMetricsDocs } = require('./metrics-docs');
|
|
19
|
+
const { generateRpkDocs } = require('./rpk-docs');
|
|
20
|
+
const { generateRpConnectDocs } = require('./rpcn-docs');
|
|
21
|
+
const { generateHelmDocs } = require('./helm-docs');
|
|
22
|
+
const { generateCloudRegions } = require('./cloud-regions');
|
|
23
|
+
const { generateCrdDocs } = require('./crd-docs');
|
|
24
|
+
const { generateBundleOpenApi } = require('./openapi');
|
|
25
|
+
|
|
26
|
+
// Review tools
|
|
27
|
+
const { reviewGeneratedDocs, generateReviewReport } = require('./generated-docs-review');
|
|
28
|
+
const { reviewContent } = require('./content-review');
|
|
29
|
+
|
|
30
|
+
// Job queue
|
|
31
|
+
const { initializeJobQueue, createJob, getJob, listJobs, cleanupOldJobs } = require('./job-queue');
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Execute a tool and return results
|
|
35
|
+
* @param {string} toolName - Name of the tool to execute
|
|
36
|
+
* @param {Object} args - Arguments for the tool
|
|
37
|
+
* @returns {Object} Tool execution results
|
|
38
|
+
*/
|
|
39
|
+
function executeTool(toolName, args = {}) {
|
|
40
|
+
const repoRoot = findRepoRoot();
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
switch (toolName) {
|
|
44
|
+
case 'get_antora_structure':
|
|
45
|
+
return getAntoraStructure(repoRoot);
|
|
46
|
+
|
|
47
|
+
case 'get_redpanda_version':
|
|
48
|
+
return getRedpandaVersion(args);
|
|
49
|
+
|
|
50
|
+
case 'get_console_version':
|
|
51
|
+
return getConsoleVersion();
|
|
52
|
+
|
|
53
|
+
case 'generate_property_docs':
|
|
54
|
+
return generatePropertyDocs(args);
|
|
55
|
+
|
|
56
|
+
case 'generate_metrics_docs':
|
|
57
|
+
return generateMetricsDocs(args);
|
|
58
|
+
|
|
59
|
+
case 'generate_rpk_docs':
|
|
60
|
+
return generateRpkDocs(args);
|
|
61
|
+
|
|
62
|
+
case 'generate_rpcn_connector_docs':
|
|
63
|
+
return generateRpConnectDocs(args);
|
|
64
|
+
|
|
65
|
+
case 'generate_helm_docs':
|
|
66
|
+
return generateHelmDocs(args);
|
|
67
|
+
|
|
68
|
+
case 'generate_cloud_regions':
|
|
69
|
+
return generateCloudRegions(args);
|
|
70
|
+
|
|
71
|
+
case 'generate_crd_docs':
|
|
72
|
+
return generateCrdDocs(args);
|
|
73
|
+
|
|
74
|
+
case 'generate_bundle_openapi':
|
|
75
|
+
return generateBundleOpenApi(args);
|
|
76
|
+
|
|
77
|
+
case 'review_generated_docs':
|
|
78
|
+
return reviewGeneratedDocs(args);
|
|
79
|
+
|
|
80
|
+
case 'review_content':
|
|
81
|
+
return reviewContent(args, repoRoot.root);
|
|
82
|
+
|
|
83
|
+
case 'run_doc_tools_command': {
|
|
84
|
+
// Validate and execute raw doc-tools command
|
|
85
|
+
if (!args || typeof args !== 'object') {
|
|
86
|
+
return {
|
|
87
|
+
success: false,
|
|
88
|
+
error: 'Invalid arguments: expected an object'
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const validation = validateDocToolsCommand(args.command);
|
|
93
|
+
if (!validation.valid) {
|
|
94
|
+
return {
|
|
95
|
+
success: false,
|
|
96
|
+
error: validation.error
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
try {
|
|
101
|
+
// Get doc-tools command (handles both local and installed)
|
|
102
|
+
const { getDocToolsCommand } = require('./utils');
|
|
103
|
+
const docTools = getDocToolsCommand(repoRoot);
|
|
104
|
+
|
|
105
|
+
// Parse command into argument array (no shell interpolation)
|
|
106
|
+
// Since validation already rejects shell metacharacters, we can safely split by spaces
|
|
107
|
+
// Handle quoted strings for paths with spaces
|
|
108
|
+
const cmdArgs = parseCommandArgs(args.command);
|
|
109
|
+
|
|
110
|
+
// Build full args using the appropriate command
|
|
111
|
+
const fullArgs = docTools.getArgs(cmdArgs);
|
|
112
|
+
|
|
113
|
+
const output = executeCommand(docTools.program, fullArgs, {
|
|
114
|
+
cwd: repoRoot.root
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
return {
|
|
118
|
+
success: true,
|
|
119
|
+
output: output.trim(),
|
|
120
|
+
command: `${docTools.program} ${fullArgs.join(' ')}`
|
|
121
|
+
};
|
|
122
|
+
} catch (err) {
|
|
123
|
+
return {
|
|
124
|
+
success: false,
|
|
125
|
+
error: err.message,
|
|
126
|
+
stdout: err.stdout || '',
|
|
127
|
+
stderr: err.stderr || ''
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
default:
|
|
133
|
+
return {
|
|
134
|
+
success: false,
|
|
135
|
+
error: `Unknown tool: ${toolName}`,
|
|
136
|
+
suggestion: 'Check the tool name and try again'
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
} catch (err) {
|
|
140
|
+
return {
|
|
141
|
+
success: false,
|
|
142
|
+
error: err.message,
|
|
143
|
+
suggestion: 'An unexpected error occurred while executing the tool'
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Parse command string into array of arguments
|
|
150
|
+
* Handles quoted strings for paths with spaces
|
|
151
|
+
* @param {string} command - The command string to parse
|
|
152
|
+
* @returns {string[]} Array of arguments
|
|
153
|
+
*/
|
|
154
|
+
function parseCommandArgs(command) {
|
|
155
|
+
const args = [];
|
|
156
|
+
let current = '';
|
|
157
|
+
let inQuotes = false;
|
|
158
|
+
let quoteChar = '';
|
|
159
|
+
|
|
160
|
+
for (let i = 0; i < command.length; i++) {
|
|
161
|
+
const char = command[i];
|
|
162
|
+
|
|
163
|
+
if ((char === '"' || char === "'") && !inQuotes) {
|
|
164
|
+
// Start of quoted string
|
|
165
|
+
inQuotes = true;
|
|
166
|
+
quoteChar = char;
|
|
167
|
+
} else if (char === quoteChar && inQuotes) {
|
|
168
|
+
// End of quoted string
|
|
169
|
+
inQuotes = false;
|
|
170
|
+
quoteChar = '';
|
|
171
|
+
} else if (char === ' ' && !inQuotes) {
|
|
172
|
+
// Space outside quotes - end of argument
|
|
173
|
+
if (current) {
|
|
174
|
+
args.push(current);
|
|
175
|
+
current = '';
|
|
176
|
+
}
|
|
177
|
+
} else {
|
|
178
|
+
// Regular character
|
|
179
|
+
current += char;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Add final argument if present
|
|
184
|
+
if (current) {
|
|
185
|
+
args.push(current);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return args;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Validate doc-tools command to prevent command injection
|
|
193
|
+
* @param {string} command - The command string to validate
|
|
194
|
+
* @returns {{ valid: boolean, error?: string }} Validation result
|
|
195
|
+
*/
|
|
196
|
+
function validateDocToolsCommand(command) {
|
|
197
|
+
if (!command || typeof command !== 'string') {
|
|
198
|
+
return { valid: false, error: 'Command must be a non-empty string' };
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const dangerousChars = /[;|&$`<>(){}[\]!*?~]/;
|
|
202
|
+
if (dangerousChars.test(command)) {
|
|
203
|
+
return {
|
|
204
|
+
valid: false,
|
|
205
|
+
error: 'Invalid command: shell metacharacters not allowed. Use simple doc-tools commands only.'
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (command.includes('..') || command.includes('~')) {
|
|
210
|
+
return {
|
|
211
|
+
valid: false,
|
|
212
|
+
error: 'Invalid command: path traversal sequences not allowed'
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return { valid: true };
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
module.exports = {
|
|
220
|
+
// Core functions
|
|
221
|
+
findRepoRoot,
|
|
222
|
+
executeTool,
|
|
223
|
+
|
|
224
|
+
// Individual tool exports (for testing or direct use)
|
|
225
|
+
getAntoraStructure,
|
|
226
|
+
getRedpandaVersion,
|
|
227
|
+
getConsoleVersion,
|
|
228
|
+
generatePropertyDocs,
|
|
229
|
+
generateMetricsDocs,
|
|
230
|
+
generateRpkDocs,
|
|
231
|
+
generateRpConnectDocs,
|
|
232
|
+
generateHelmDocs,
|
|
233
|
+
generateCloudRegions,
|
|
234
|
+
generateCrdDocs,
|
|
235
|
+
generateBundleOpenApi,
|
|
236
|
+
reviewGeneratedDocs,
|
|
237
|
+
generateReviewReport,
|
|
238
|
+
|
|
239
|
+
// Job queue
|
|
240
|
+
initializeJobQueue,
|
|
241
|
+
createJob,
|
|
242
|
+
getJob,
|
|
243
|
+
listJobs,
|
|
244
|
+
cleanupOldJobs
|
|
245
|
+
};
|