@re-shell/cli
Version:
Full-stack development platform uniting microservices and microfrontends. Build complete applications with .NET (ASP.NET Core Web API, Minimal API), Java (Spring Boot, Quarkus, Micronaut, Vert.x), Rust (Actix-Web, Warp, Rocket, Axum), Python (FastAPI, Dja
431 lines (430 loc) ⢠22.2 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.generatePluginDocumentation = generatePluginDocumentation;
exports.showCommandHelp = showCommandHelp;
exports.listDocumentedCommands = listDocumentedCommands;
exports.searchDocumentation = searchDocumentation;
exports.showDocumentationStats = showDocumentationStats;
exports.configureHelpSystem = configureHelpSystem;
exports.showDocumentationTemplates = showDocumentationTemplates;
const fs = __importStar(require("fs-extra"));
const path = __importStar(require("path"));
const chalk_1 = __importDefault(require("chalk"));
const spinner_1 = require("../utils/spinner");
const error_handler_1 = require("../utils/error-handler");
const plugin_command_docs_1 = require("../utils/plugin-command-docs");
const plugin_command_registry_1 = require("../utils/plugin-command-registry");
// Generate documentation for plugin commands
async function generatePluginDocumentation(commands = [], options = {}) {
const { verbose = false, json = false, format = plugin_command_docs_1.DocumentationFormat.MARKDOWN, output, template = 'markdown', includePrivate = false, includeDeprecated = false, includeExamples = true, generateIndex = true } = options;
try {
const { Command } = require('commander');
const tempProgram = new Command();
const commandRegistry = (0, plugin_command_registry_1.createPluginCommandRegistry)(tempProgram);
await commandRegistry.initialize();
const documentationGenerator = (0, plugin_command_docs_1.createDocumentationGenerator)();
const registeredCommands = commandRegistry.getCommands();
documentationGenerator.registerCommands(registeredCommands);
const generationOptions = {
format,
template,
outputDir: output,
includePrivate,
includeDeprecated,
includeExamples,
generateIndex
};
const commandIds = commands.length > 0
? commands.map(cmd => registeredCommands.find(c => c.definition.name === cmd)?.id).filter(id => id !== undefined)
: [];
const spinner = (0, spinner_1.createSpinner)('Generating documentation...');
spinner.start();
const docs = await documentationGenerator.generateDocumentation(commandIds, generationOptions);
spinner.stop();
if (json) {
console.log(JSON.stringify(docs, null, 2));
return;
}
console.log(chalk_1.default.green(`ā Generated documentation for ${docs.length} command(s)`));
if (verbose) {
console.log(chalk_1.default.yellow('\nDocumentation Details:'));
console.log(` Format: ${format}`);
console.log(` Template: ${template}`);
console.log(` Total size: ${(0, plugin_command_docs_1.formatDocumentationSize)(docs)}`);
console.log(` Average reading time: ${Math.round(docs.reduce((sum, doc) => sum + doc.metadata.estimatedReadingTime, 0) / docs.length || 0)} minutes`);
if (output) {
console.log(` Output directory: ${output}`);
}
}
// Display sample documentation if no output directory specified
if (!output && docs.length > 0) {
console.log(chalk_1.default.cyan('\nSample Documentation:'));
console.log(chalk_1.default.gray('ā'.repeat(80)));
console.log(docs[0].content.split('\n').slice(0, 20).join('\n'));
if (docs[0].content.split('\n').length > 20) {
console.log(chalk_1.default.gray('... (truncated)'));
}
console.log(chalk_1.default.gray('ā'.repeat(80)));
if (docs.length > 1) {
console.log(chalk_1.default.blue(`\nš” Use --output <dir> to save all ${docs.length} documentation files`));
}
}
// Save documentation files if output directory specified
if (output) {
await fs.ensureDir(output);
for (const doc of docs) {
const extension = format === plugin_command_docs_1.DocumentationFormat.MARKDOWN ? '.md' :
format === plugin_command_docs_1.DocumentationFormat.HTML ? '.html' :
format === plugin_command_docs_1.DocumentationFormat.JSON ? '.json' : '.txt';
const filename = `${doc.command}${extension}`;
const filepath = path.join(output, filename);
await fs.writeFile(filepath, doc.content);
}
console.log(chalk_1.default.blue(`\nš Documentation saved to: ${output}`));
}
}
catch (error) {
throw new error_handler_1.ValidationError(`Failed to generate documentation: ${error instanceof Error ? error.message : String(error)}`);
}
}
// Show help for a specific command
async function showCommandHelp(commandName, options = {}) {
const { verbose = false, json = false, mode = plugin_command_docs_1.HelpDisplayMode.DETAILED } = options;
try {
const { Command } = require('commander');
const tempProgram = new Command();
const commandRegistry = (0, plugin_command_registry_1.createPluginCommandRegistry)(tempProgram);
await commandRegistry.initialize();
const documentationGenerator = (0, plugin_command_docs_1.createDocumentationGenerator)({ displayMode: mode });
const registeredCommands = commandRegistry.getCommands();
documentationGenerator.registerCommands(registeredCommands);
const command = registeredCommands.find(cmd => cmd.definition.name === commandName ||
(cmd.definition.aliases && cmd.definition.aliases.includes(commandName)));
if (!command) {
throw new error_handler_1.ValidationError(`Command '${commandName}' not found`);
}
const helpText = documentationGenerator.generateHelpText(command.id, { verbosityLevel: verbose ? 'verbose' : 'normal' });
if (json) {
const helpData = {
command: command.definition.name,
description: command.definition.description,
arguments: command.definition.arguments,
options: command.definition.options,
examples: command.definition.examples,
aliases: command.definition.aliases,
plugin: command.pluginName,
category: command.definition.category,
deprecated: command.definition.deprecated,
hidden: command.definition.hidden
};
console.log(JSON.stringify(helpData, null, 2));
return;
}
console.log(helpText);
}
catch (error) {
throw new error_handler_1.ValidationError(`Failed to show command help: ${error instanceof Error ? error.message : String(error)}`);
}
}
// List all documented commands
async function listDocumentedCommands(options = {}) {
const { verbose = false, json = false, plugin, category, complexity } = options;
try {
const { Command } = require('commander');
const tempProgram = new Command();
const commandRegistry = (0, plugin_command_registry_1.createPluginCommandRegistry)(tempProgram);
await commandRegistry.initialize();
const documentationGenerator = (0, plugin_command_docs_1.createDocumentationGenerator)();
const registeredCommands = commandRegistry.getCommands();
documentationGenerator.registerCommands(registeredCommands);
let commands = registeredCommands;
// Apply filters
if (plugin) {
commands = commands.filter(cmd => cmd.pluginName === plugin);
}
if (category) {
commands = commands.filter(cmd => cmd.definition.category === category);
}
if (json) {
const commandData = commands.map(cmd => ({
name: cmd.definition.name,
description: cmd.definition.description,
plugin: cmd.pluginName,
category: cmd.definition.category,
complexity: complexity, // Would be calculated
aliases: cmd.definition.aliases,
deprecated: cmd.definition.deprecated,
hidden: cmd.definition.hidden,
registeredAt: cmd.registeredAt,
usageCount: cmd.usageCount
}));
console.log(JSON.stringify(commandData, null, 2));
return;
}
console.log(chalk_1.default.cyan('š Available Documented Commands\n'));
if (commands.length === 0) {
console.log(chalk_1.default.yellow('No commands found matching criteria.'));
return;
}
// Group by plugin
const commandsByPlugin = commands.reduce((acc, cmd) => {
if (!acc[cmd.pluginName]) {
acc[cmd.pluginName] = [];
}
acc[cmd.pluginName].push(cmd);
return acc;
}, {});
Object.entries(commandsByPlugin).forEach(([pluginName, pluginCommands]) => {
console.log(chalk_1.default.yellow(`${pluginName} (${pluginCommands.length} commands):`));
pluginCommands.forEach(cmd => {
const name = cmd.definition.name;
const description = cmd.definition.description || 'No description';
const aliasText = cmd.definition.aliases && cmd.definition.aliases.length > 0
? chalk_1.default.gray(` (${cmd.definition.aliases.join(', ')})`)
: '';
const deprecatedText = cmd.definition.deprecated ? chalk_1.default.red(' [DEPRECATED]') : '';
const hiddenText = cmd.definition.hidden ? chalk_1.default.gray(' [HIDDEN]') : '';
console.log(` ${chalk_1.default.cyan(name)}${aliasText}${deprecatedText}${hiddenText}`);
console.log(` ${chalk_1.default.gray(description)}`);
if (verbose) {
console.log(` ${chalk_1.default.gray('Category:')} ${cmd.definition.category || 'general'}`);
console.log(` ${chalk_1.default.gray('Usage:')} ${cmd.usageCount}`);
console.log(` ${chalk_1.default.gray('Registered:')} ${new Date(cmd.registeredAt).toLocaleDateString()}`);
}
console.log('');
});
});
console.log(chalk_1.default.yellow(`Total: ${commands.length} command(s)`));
}
catch (error) {
throw new error_handler_1.ValidationError(`Failed to list documented commands: ${error instanceof Error ? error.message : String(error)}`);
}
}
// Search documentation
async function searchDocumentation(query, options = {}) {
const { verbose = false, json = false, plugin, category, complexity } = options;
try {
const { Command } = require('commander');
const tempProgram = new Command();
const commandRegistry = (0, plugin_command_registry_1.createPluginCommandRegistry)(tempProgram);
await commandRegistry.initialize();
const documentationGenerator = (0, plugin_command_docs_1.createDocumentationGenerator)();
const registeredCommands = commandRegistry.getCommands();
documentationGenerator.registerCommands(registeredCommands);
const filters = { plugin, category, complexity };
const results = documentationGenerator.searchDocumentation(query, filters);
if (json) {
console.log(JSON.stringify(results, null, 2));
return;
}
console.log(chalk_1.default.cyan(`š Search Results for "${query}"\n`));
if (results.length === 0) {
console.log(chalk_1.default.yellow('No matching documentation found.'));
// Suggest similar commands
const allCommands = registeredCommands.map(cmd => cmd.definition.name);
const suggestions = allCommands.filter(name => name.toLowerCase().includes(query.toLowerCase()) ||
query.toLowerCase().includes(name.toLowerCase())).slice(0, 3);
if (suggestions.length > 0) {
console.log(chalk_1.default.blue('\nš” Did you mean:'));
suggestions.forEach(suggestion => {
console.log(` ${chalk_1.default.cyan(suggestion)}`);
});
}
return;
}
results.forEach((result, index) => {
console.log(`${index + 1}. ${chalk_1.default.cyan(result.command)}`);
console.log(` ${chalk_1.default.gray(result.description)}`);
console.log(` ${chalk_1.default.yellow('Plugin:')} ${result.plugin}`);
console.log(` ${chalk_1.default.yellow('Category:')} ${result.category}`);
console.log(` ${chalk_1.default.yellow('Complexity:')} ${result.complexity}`);
if (verbose) {
console.log(` ${chalk_1.default.yellow('Tags:')} ${result.tags.join(', ')}`);
console.log(` ${chalk_1.default.yellow('Last modified:')} ${new Date(result.lastModified).toLocaleDateString()}`);
}
console.log('');
});
console.log(chalk_1.default.yellow(`Found ${results.length} result(s)`));
}
catch (error) {
throw new error_handler_1.ValidationError(`Failed to search documentation: ${error instanceof Error ? error.message : String(error)}`);
}
}
// Show documentation statistics
async function showDocumentationStats(options = {}) {
const { verbose = false, json = false } = options;
try {
const { Command } = require('commander');
const tempProgram = new Command();
const commandRegistry = (0, plugin_command_registry_1.createPluginCommandRegistry)(tempProgram);
await commandRegistry.initialize();
const documentationGenerator = (0, plugin_command_docs_1.createDocumentationGenerator)();
const registeredCommands = commandRegistry.getCommands();
documentationGenerator.registerCommands(registeredCommands);
const stats = documentationGenerator.getDocumentationStats();
if (json) {
console.log(JSON.stringify(stats, null, 2));
return;
}
console.log(chalk_1.default.cyan('š Documentation Statistics\n'));
// Overview
console.log(chalk_1.default.yellow('Overview:'));
console.log(` Total commands: ${stats.totalCommands}`);
console.log(` Documented commands: ${stats.documentedCommands}`);
console.log(` Coverage: ${Math.round(stats.documentationCoverage * 100)}%`);
console.log(` Average word count: ${Math.round(stats.averageWordCount)}`);
console.log(` Average reading time: ${Math.round(stats.averageReadingTime)} minutes`);
// Format distribution
console.log(chalk_1.default.yellow('\nFormat Distribution:'));
Object.entries(stats.formatDistribution).forEach(([format, count]) => {
console.log(` ${format}: ${count}`);
});
// Complexity distribution
console.log(chalk_1.default.yellow('\nComplexity Distribution:'));
Object.entries(stats.complexityDistribution).forEach(([complexity, count]) => {
const color = complexity === 'basic' ? 'green' :
complexity === 'intermediate' ? 'yellow' : 'red';
const colorFn = chalk_1.default[color];
console.log(` ${colorFn(complexity)}: ${count}`);
});
// Plugin distribution
console.log(chalk_1.default.yellow('\nPlugin Distribution:'));
Object.entries(stats.pluginDistribution).forEach(([plugin, count]) => {
console.log(` ${plugin}: ${count}`);
});
if (verbose) {
console.log(chalk_1.default.yellow('\nRecommendations:'));
if (stats.documentationCoverage < 0.8) {
console.log(chalk_1.default.red(' ⢠Improve documentation coverage (currently < 80%)'));
}
if (stats.averageWordCount < 50) {
console.log(chalk_1.default.yellow(' ⢠Consider adding more detailed descriptions'));
}
if (Object.keys(stats.formatDistribution).length === 1) {
console.log(chalk_1.default.blue(' ⢠Consider generating documentation in multiple formats'));
}
}
}
catch (error) {
throw new error_handler_1.ValidationError(`Failed to show documentation statistics: ${error instanceof Error ? error.message : String(error)}`);
}
}
// Configure help system
async function configureHelpSystem(setting, value, options = {}) {
const { verbose = false } = options;
try {
const documentationGenerator = (0, plugin_command_docs_1.createDocumentationGenerator)();
const currentConfig = documentationGenerator.getHelpConfiguration();
// Validate setting
const validSettings = [
'displayMode', 'maxWidth', 'showExamples', 'showRelatedCommands',
'enableSearch', 'enableFiltering', 'sortBy', 'groupBy',
'includeHidden', 'verbosityLevel'
];
if (!validSettings.includes(setting)) {
throw new error_handler_1.ValidationError(`Invalid setting '${setting}'. Valid options: ${validSettings.join(', ')}`);
}
// Parse value based on setting type
let parsedValue = value;
if (setting === 'maxWidth') {
parsedValue = parseInt(value, 10);
if (isNaN(parsedValue) || parsedValue < 40 || parsedValue > 200) {
throw new error_handler_1.ValidationError('maxWidth must be a number between 40 and 200');
}
}
else if (['showExamples', 'showRelatedCommands', 'enableSearch', 'enableFiltering', 'includeHidden'].includes(setting)) {
parsedValue = value.toLowerCase() === 'true';
}
else if (setting === 'displayMode') {
if (!Object.values(plugin_command_docs_1.HelpDisplayMode).includes(value)) {
throw new error_handler_1.ValidationError(`Invalid display mode. Valid options: ${Object.values(plugin_command_docs_1.HelpDisplayMode).join(', ')}`);
}
parsedValue = value;
}
// Update configuration
const updates = { [setting]: parsedValue };
documentationGenerator.updateHelpConfiguration(updates);
console.log(chalk_1.default.green(`ā Updated help configuration: ${setting} = ${parsedValue}`));
if (verbose) {
console.log(chalk_1.default.yellow('\nCurrent Configuration:'));
const newConfig = documentationGenerator.getHelpConfiguration();
Object.entries(newConfig).forEach(([key, val]) => {
const isChanged = key === setting;
const color = isChanged ? 'cyan' : 'gray';
const colorFn = chalk_1.default[color];
console.log(` ${colorFn(key)}: ${val}`);
});
}
}
catch (error) {
throw new error_handler_1.ValidationError(`Failed to configure help system: ${error instanceof Error ? error.message : String(error)}`);
}
}
// Show available documentation templates
async function showDocumentationTemplates(options = {}) {
const { verbose = false, json = false } = options;
try {
const documentationGenerator = (0, plugin_command_docs_1.createDocumentationGenerator)();
const templates = documentationGenerator.getAvailableTemplates();
if (json) {
console.log(JSON.stringify(templates, null, 2));
return;
}
console.log(chalk_1.default.cyan('š Available Documentation Templates\n'));
templates.forEach(template => {
console.log(chalk_1.default.yellow(template.name));
console.log(` Format: ${template.format}`);
console.log(` Sections: ${template.sections.length}`);
if (verbose) {
console.log(` Section types: ${template.sections.join(', ')}`);
if (template.styles) {
console.log(` Styled: Yes`);
}
if (template.metadata) {
console.log(` Metadata fields: ${Object.keys(template.metadata).length}`);
}
}
console.log('');
});
console.log(chalk_1.default.gray(`Total: ${templates.length} template(s)`));
}
catch (error) {
throw new error_handler_1.ValidationError(`Failed to show documentation templates: ${error instanceof Error ? error.message : String(error)}`);
}
}