UNPKG

@redpanda-data/docs-extensions-and-macros

Version:

Antora extensions and macros developed for Redpanda documentation.

142 lines (124 loc) 4.35 kB
/** * MCP Tools - RPK Documentation Generation * * OPTIMIZATION: This tool calls CLI, doesn't use LLM directly. * - No model recommendation (CLI tool) * - Cost comes from doc-tools CLI execution */ const { spawnSync } = require('child_process'); const { findRepoRoot, getDocToolsCommand, MAX_EXEC_BUFFER_SIZE, DEFAULT_COMMAND_TIMEOUT } = require('./utils'); const { getAntoraStructure } = require('./antora'); const { createJob } = require('./job-queue'); /** * Generate RPK command documentation * * Use tags for released content (GA or beta), branches for in-progress content. * Defaults to branch "dev" if neither tag nor branch is provided. * * @param {Object} args - Arguments * @param {string} [args.tag] - Git tag for released content (for example, "v25.3.1") * @param {string} [args.branch] - Branch name for in-progress content (for example, "dev", "main") * @param {boolean} [args.background] - Run as background job * @returns {Object} Generation results */ function generateRpkDocs(args) { const repoRoot = findRepoRoot(); const structure = getAntoraStructure(repoRoot); if (!structure.hasDocTools) { return { success: false, error: 'doc-tools not found in this repository', suggestion: 'Navigate to the docs-extensions-and-macros repository' }; } // Validate that tag and branch are mutually exclusive if (args.tag && args.branch) { return { success: false, error: 'Cannot specify both tag and branch', suggestion: 'Use either --tag or --branch, not both' }; } // Default to 'dev' branch if neither provided const gitRef = args.tag || args.branch || 'dev'; const refType = args.tag ? 'tag' : 'branch'; // Normalize version (add 'v' prefix if not present and not a branch name like 'dev' or 'main') let version = gitRef; if (args.tag && !version.startsWith('v')) { version = `v${version}`; } // Get doc-tools command (handles both local and installed) const docTools = getDocToolsCommand(repoRoot); // Build command arguments array const baseArgs = ['generate', 'rpk-docs']; if (args.tag) { baseArgs.push('--tag'); baseArgs.push(version); } else { baseArgs.push('--branch'); baseArgs.push(version); } // If background mode, create job and return immediately if (args.background) { const cmdArgs = [docTools.program, ...docTools.getArgs(baseArgs)]; const jobId = createJob('generate_rpk_docs', cmdArgs, { cwd: repoRoot.root }); return { success: true, background: true, job_id: jobId, message: `RPK docs generation started in background. Use get_job_status with job_id: ${jobId} to check progress.`, [refType]: version }; } // Otherwise run synchronously try { const result = spawnSync(docTools.program, docTools.getArgs(baseArgs), { cwd: repoRoot.root, encoding: 'utf8', stdio: 'pipe', maxBuffer: MAX_EXEC_BUFFER_SIZE, timeout: DEFAULT_COMMAND_TIMEOUT }); // Check for spawn errors if (result.error) { const err = new Error(`Failed to execute command: ${result.error.message}`); err.stdout = result.stdout || ''; err.stderr = result.stderr || ''; err.status = result.status; throw err; } // Check for non-zero exit codes if (result.status !== 0) { const errorMsg = result.stderr || `Command failed with exit code ${result.status}`; const err = new Error(errorMsg); err.stdout = result.stdout || ''; err.stderr = result.stderr || ''; err.status = result.status; throw err; } const output = result.stdout; const commandCountMatch = output.match(/(\d+) commands/i); return { success: true, [refType]: version, files_generated: [`autogenerated/${version}/rpk/*.adoc`], commands_documented: commandCountMatch ? parseInt(commandCountMatch[1]) : null, output: output.trim(), summary: `Generated RPK documentation for Redpanda ${refType} ${version}` }; } catch (err) { return { success: false, error: err.message, stdout: err.stdout || '', stderr: err.stderr || '', exitCode: err.status, suggestion: 'Check that the version exists in the Redpanda repository' }; } } module.exports = { generateRpkDocs };