adpa-enterprise-framework-automation
Version:
Modular, standards-compliant Node.js/TypeScript automation framework for enterprise requirements, project, and data management. Provides CLI and API for BABOK v3, PMBOK 7th Edition, and DMBOK 2.0 (in progress). Production-ready Express.js API with TypeSpe
587 lines • 25.8 kB
JavaScript
/**
* Command Integration Service
*
* Provides seamless integration between the interactive CLI menu system
* and existing yargs command handlers. This service maps menu actions
* to command handlers and executes them directly without spawning child processes.
*
* @version 1.0.0
* @author ADPA Team
*/
import { handleGenerateCommand, handleGenerateCategoryCommand, handleGenerateAllCommand, handleGenerateCoreAnalysisCommand, handleListTemplatesCommand } from '../../commands/generate.js';
import { handleStakeholderAnalysisCommand, handleStakeholderRegisterCommand, handleStakeholderEngagementPlanCommand, handleStakeholderAutomationCommand } from '../../commands/stakeholder.js';
import { handleStatusCommand, handleAnalyzeCommand, handleSetupCommand, handleValidateCommand } from '../../commands/index.js';
import { handleInterviewQuestionsCommand, handleWorkshopPlanCommand, handleRequirementsExtractionCommand, handleProcessModelCommand, handleUseCaseModelCommand, handleBusinessRulesCommand, handleImpactAnalysisCommand, handleQualityAssessmentCommand, handleConsistencyValidationCommand, handleQualityMetricsCommand, displayBusinessAnalysisHelp } from '../../commands/business-analysis.js';
import { handleConfluenceInitCommand, handleConfluenceTestCommand, handleConfluencePublishCommand, handleConfluenceStatusCommand } from '../../commands/confluence.js';
import { handleSharePointInitCommand, handleSharePointTestCommand, handleSharePointPublishCommand, handleSharePointStatusCommand } from '../../commands/sharepoint.js';
import { handleVcsInitCommand, handleVcsStatusCommand, handleVcsCommitCommand, handleVcsPushCommand } from '../../commands/vcs.js';
import { handleStrategicPlanningCommand, handleRequirementsGenerationCommand, handleTechnologyAnalysisCommand, handleRiskManagementCommand, handleComprehensiveAnalysisCommand } from '../../commands/user-stories.js';
import { DEFAULT_OUTPUT_DIR } from '../../constants.js';
/**
* Command Integration Service
* Maps interactive menu commands to actual command handlers
*/
export class CommandIntegrationService {
/**
* Execute a command with the given arguments
*/
async executeCommand(command, args = []) {
try {
console.log(`🔄 Executing: ${command} ${args.join(' ')}`);
// Parse arguments into options
const options = this.parseArguments(args);
// Route to appropriate command handler
switch (command) {
// Generate commands
case 'generate':
await this.handleGenerate(args, options);
break;
case 'generate-category':
await this.handleGenerateCategory(args, options);
break;
case 'generate-all':
await this.handleGenerateAll(options);
break;
case 'generate-core-analysis':
await this.handleGenerateCoreAnalysis(options);
break;
case 'list-templates':
await this.handleListTemplates();
break;
// Analysis commands
case 'analyze':
await this.handleAnalyze(args, options);
break;
case 'status':
await this.handleStatus(options);
break;
case 'validate':
await this.handleValidate(options);
break;
// Setup commands
case 'setup':
await this.handleSetup(options);
break;
// Stakeholder commands
case 'stakeholder':
await this.handleStakeholder(args, options);
break;
// Business analysis commands
case 'business-analysis':
await this.handleBusinessAnalysis(args, options);
break;
// Risk and compliance commands
case 'risk-compliance':
await this.handleRiskCompliance(args, options);
break;
// Feedback commands
case 'feedback':
await this.handleFeedback(args, options);
break;
// Integration commands
case 'confluence':
await this.handleConfluence(args, options);
break;
case 'sharepoint':
await this.handleSharePoint(args, options);
break;
case 'vcs':
await this.handleVcs(args, options);
break;
// User Stories commands
case 'strategic-planning':
await this.handleStrategicPlanning(args, options);
break;
case 'requirements-generation':
await this.handleRequirementsGeneration(args, options);
break;
case 'technology-analysis':
await this.handleTechnologyAnalysis(args, options);
break;
case 'risk-management':
await this.handleRiskManagement(args, options);
break;
case 'comprehensive-analysis':
await this.handleComprehensiveAnalysis(args, options);
break;
default:
throw new Error(`Unknown command: ${command}`);
}
return { success: true, message: `Command '${command}' executed successfully` };
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
console.error(`❌ Error executing command '${command}':`, errorMessage);
return {
success: false,
error: error instanceof Error ? error : new Error(errorMessage),
message: `Failed to execute '${command}': ${errorMessage}`
};
}
}
/**
* Parse command line arguments into options object
*/
parseArguments(args) {
const options = {};
for (let i = 0; i < args.length; i++) {
const arg = args[i];
if (arg.startsWith('--')) {
const key = arg.substring(2);
const nextArg = args[i + 1];
if (nextArg && !nextArg.startsWith('--')) {
// Option with value
options[key] = nextArg;
i++; // Skip next argument as it's the value
}
else {
// Boolean flag
options[key] = true;
}
}
else if (arg.startsWith('-')) {
const key = arg.substring(1);
const nextArg = args[i + 1];
if (nextArg && !nextArg.startsWith('-')) {
// Option with value
options[key] = nextArg;
i++; // Skip next argument as it's the value
}
else {
// Boolean flag
options[key] = true;
}
}
}
return options;
}
/**
* Handle generate command
*/
async handleGenerate(args, options) {
const key = args.find(arg => !arg.startsWith('-')) || '';
if (!key) {
throw new Error('Document key is required for generate command');
}
await handleGenerateCommand(key, {
output: options.output || options.o || DEFAULT_OUTPUT_DIR,
format: options.format || 'markdown',
quiet: options.quiet || options.q || false,
retries: parseInt(options.retries || '0'),
retryBackoff: parseInt(options['retry-backoff'] || '1000'),
retryMaxDelay: parseInt(options['retry-max-delay'] || '30000')
});
}
/**
* Handle generate-category command
*/
async handleGenerateCategory(args, options) {
const category = args.find(arg => !arg.startsWith('-')) || '';
if (!category) {
throw new Error('Category is required for generate-category command');
}
await handleGenerateCategoryCommand(category, {
output: options.output || options.o || DEFAULT_OUTPUT_DIR,
quiet: options.quiet || options.q || false,
retries: parseInt(options.retries || '0'),
retryBackoff: parseInt(options['retry-backoff'] || '1000'),
retryMaxDelay: parseInt(options['retry-max-delay'] || '30000')
});
}
/**
* Handle generate-all command
*/
async handleGenerateAll(options) {
await handleGenerateAllCommand({
output: options.output || options.o || DEFAULT_OUTPUT_DIR,
quiet: options.quiet || options.q || false,
retries: parseInt(options.retries || '0'),
retryBackoff: parseInt(options['retry-backoff'] || '1000'),
retryMaxDelay: parseInt(options['retry-max-delay'] || '30000')
});
}
/**
* Handle generate-core-analysis command
*/
async handleGenerateCoreAnalysis(options) {
await handleGenerateCoreAnalysisCommand({
output: options.output || options.o || DEFAULT_OUTPUT_DIR,
quiet: options.quiet || options.q || false,
retries: parseInt(options.retries || '0'),
retryBackoff: parseInt(options['retry-backoff'] || '1000'),
retryMaxDelay: parseInt(options['retry-max-delay'] || '30000')
});
}
/**
* Handle list-templates command
*/
async handleListTemplates() {
await handleListTemplatesCommand();
}
/**
* Handle analyze command
*/
async handleAnalyze(args, options) {
await handleAnalyzeCommand();
}
/**
* Handle status command
*/
async handleStatus(options) {
await handleStatusCommand();
}
/**
* Handle validate command
*/
async handleValidate(options) {
await handleValidateCommand({
outputDir: options.output || options['output-dir'] || DEFAULT_OUTPUT_DIR,
quiet: options.quiet || options.q || false
});
}
/**
* Handle setup command
*/
async handleSetup(options) {
await handleSetupCommand();
}
/**
* Handle stakeholder commands
*/
async handleStakeholder(args, options) {
const subcommand = args.find(arg => !arg.startsWith('-')) || 'analysis';
const stakeholderOptions = {
outputDir: options['output-dir'] || options.output || options.o || DEFAULT_OUTPUT_DIR,
format: options.format || 'markdown',
verbose: options.verbose || options.v || false,
includeRegister: options['include-register'] !== false,
includeEngagementPlan: options['include-engagement-plan'] || false,
analysisDepth: options['analysis-depth'] || 'comprehensive'
};
switch (subcommand) {
case 'analysis':
await handleStakeholderAnalysisCommand(stakeholderOptions);
break;
case 'register':
await handleStakeholderRegisterCommand(stakeholderOptions);
break;
case 'engagement-plan':
await handleStakeholderEngagementPlanCommand(stakeholderOptions);
break;
case 'automate':
await handleStakeholderAutomationCommand(stakeholderOptions);
break;
default:
throw new Error(`Unknown stakeholder subcommand: ${subcommand}`);
}
}
/**
* Handle business-analysis commands
*/
async handleBusinessAnalysis(args, options) {
const subcommand = args.find(arg => !arg.startsWith('-')) || 'help';
const businessAnalysisOptions = {
outputDir: options['output-dir'] || options.output || options.o || DEFAULT_OUTPUT_DIR,
format: options.format || 'markdown',
verbose: options.verbose || options.v || false,
stakeholderRole: options['stakeholder-role'],
workshopType: options['workshop-type'],
duration: parseInt(options.duration || '4'),
participants: options.participants ? options.participants.split(',') : undefined,
elicitationType: options['elicitation-type'],
targetAudience: options['target-audience'],
objectives: options.objectives ? options.objectives.split(',') : undefined,
analysisType: options['analysis-type'],
modelType: options['model-type'],
currentState: options['current-state'],
futureState: options['future-state'],
qualityType: options['quality-type'],
standards: options.standards,
template: options.template,
documents: options.documents ? options.documents.split(',') : undefined
};
// Get additional arguments (file paths, etc.)
const additionalArgs = args.filter(arg => !arg.startsWith('-')).slice(1);
switch (subcommand) {
case 'interview-questions':
const stakeholderRole = additionalArgs[0];
if (!stakeholderRole) {
throw new Error('Stakeholder role is required for interview-questions command');
}
await handleInterviewQuestionsCommand(stakeholderRole, businessAnalysisOptions);
break;
case 'workshop-plan':
const workshopType = additionalArgs[0];
if (!workshopType) {
throw new Error('Workshop type is required for workshop-plan command');
}
await handleWorkshopPlanCommand(workshopType, businessAnalysisOptions);
break;
case 'extract-requirements':
const notesFile = additionalArgs[0];
if (!notesFile) {
throw new Error('Notes file is required for extract-requirements command');
}
await handleRequirementsExtractionCommand(notesFile, businessAnalysisOptions);
break;
case 'process-model':
const requirementsFile = additionalArgs[0];
if (!requirementsFile) {
throw new Error('Requirements file is required for process-model command');
}
await handleProcessModelCommand(requirementsFile, businessAnalysisOptions);
break;
case 'use-case-model':
const useCaseFile = additionalArgs[0];
if (!useCaseFile) {
throw new Error('Requirements file is required for use-case-model command');
}
await handleUseCaseModelCommand(useCaseFile, businessAnalysisOptions);
break;
case 'business-rules':
const businessRulesFile = additionalArgs[0];
if (!businessRulesFile) {
throw new Error('Requirements file is required for business-rules command');
}
await handleBusinessRulesCommand(businessRulesFile, businessAnalysisOptions);
break;
case 'impact-analysis':
const requirement = additionalArgs[0];
if (!requirement) {
throw new Error('Requirement is required for impact-analysis command');
}
await handleImpactAnalysisCommand(requirement, businessAnalysisOptions);
break;
case 'quality-assessment':
const qualityFile = additionalArgs[0];
if (!qualityFile) {
throw new Error('Requirements file is required for quality-assessment command');
}
await handleQualityAssessmentCommand(qualityFile, businessAnalysisOptions);
break;
case 'consistency-check':
const documentFiles = additionalArgs;
if (documentFiles.length === 0) {
throw new Error('At least one document file is required for consistency-check command');
}
await handleConsistencyValidationCommand(documentFiles, businessAnalysisOptions);
break;
case 'quality-metrics':
await handleQualityMetricsCommand(businessAnalysisOptions);
break;
case 'help':
default:
displayBusinessAnalysisHelp();
break;
}
}
/**
* Handle risk-compliance command
*/
async handleRiskCompliance(args, options) {
const project = options.project || options.p;
if (!project) {
throw new Error('Project name is required for risk-compliance command');
}
// Create and execute the risk compliance command
const { createRiskComplianceCommand } = await import('../../commands/risk-compliance.js');
const command = createRiskComplianceCommand();
// Build command arguments
const commandArgs = [
'--project', project,
'--type', options.type || options.t || 'SOFTWARE_DEVELOPMENT',
'--output', options.output || options.o || 'generated-documents/risk-compliance',
'--format', options.format || 'markdown'
];
if (options.description || options.d) {
commandArgs.push('--description', options.description || options.d);
}
if (options.integrated) {
commandArgs.push('--integrated');
}
if (options['pmbok-only']) {
commandArgs.push('--pmbok-only');
}
// Execute the command by calling its action directly
const parsedOptions = command.parse(commandArgs, { from: 'user' });
}
/**
* Handle feedback command
*/
async handleFeedback(args, options) {
const subcommand = args.find(arg => !arg.startsWith('-')) || 'stats';
// Create and execute the feedback command
const { createFeedbackCommand } = await import('../../commands/feedback.js');
const command = createFeedbackCommand();
// Build command arguments for the subcommand
const commandArgs = [subcommand];
// Add options based on subcommand
if (options.project || options.p) {
commandArgs.push('--project', options.project || options.p);
}
if (options.days) {
commandArgs.push('--days', options.days);
}
if (options['document-type']) {
commandArgs.push('--document-type', options['document-type']);
}
if (options['dry-run']) {
commandArgs.push('--dry-run');
}
// Execute the command by parsing the arguments
await command.parseAsync(commandArgs, { from: 'user' });
}
/**
* Handle confluence commands
*/
async handleConfluence(args, options) {
const subcommand = args.find(arg => !arg.startsWith('-')) || 'status';
const confluenceOptions = { quiet: options.quiet || options.q || false };
switch (subcommand) {
case 'init':
await handleConfluenceInitCommand(confluenceOptions);
break;
case 'test':
await handleConfluenceTestCommand(confluenceOptions);
break;
case 'publish':
await handleConfluencePublishCommand({
...confluenceOptions,
documentsPath: options['documents-path'],
parentPageTitle: options['parent-page'],
labelPrefix: options['label-prefix'],
dryRun: options['dry-run'] || false,
force: options.force || false
});
break;
case 'status':
await handleConfluenceStatusCommand(confluenceOptions);
break;
default:
throw new Error(`Unknown confluence subcommand: ${subcommand}`);
}
}
/**
* Handle sharepoint commands
*/
async handleSharePoint(args, options) {
const subcommand = args.find(arg => !arg.startsWith('-')) || 'status';
const sharepointOptions = { quiet: options.quiet || options.q || false };
switch (subcommand) {
case 'init':
await handleSharePointInitCommand(sharepointOptions);
break;
case 'test':
await handleSharePointTestCommand(sharepointOptions);
break;
case 'publish':
await handleSharePointPublishCommand({
...sharepointOptions,
documentsPath: options['documents-path'],
folderPath: options['folder-path'],
labelPrefix: options['label-prefix'],
dryRun: options['dry-run'] || false,
force: options.force || false
});
break;
case 'status':
await handleSharePointStatusCommand(sharepointOptions);
break;
default:
throw new Error(`Unknown sharepoint subcommand: ${subcommand}`);
}
}
/**
* Handle vcs commands
*/
async handleVcs(args, options) {
const subcommand = args.find(arg => !arg.startsWith('-')) || 'status';
const vcsOptions = {
outputDir: options.output || DEFAULT_OUTPUT_DIR,
quiet: options.quiet || options.q || false
};
switch (subcommand) {
case 'init':
await handleVcsInitCommand(vcsOptions);
break;
case 'status':
await handleVcsStatusCommand(vcsOptions);
break;
case 'commit':
await handleVcsCommitCommand({
...vcsOptions,
message: options.message || 'Update generated documents'
});
break;
case 'push':
await handleVcsPushCommand({
...vcsOptions,
remote: options.remote || 'origin',
branch: options.branch || 'main'
});
break;
default:
throw new Error(`Unknown vcs subcommand: ${subcommand}`);
}
}
/**
* Handle user stories commands
*/
async handleStrategicPlanning(args, options) {
const userStoryOptions = {
businessProblem: options.businessProblem || options.problem,
technologyStack: options.technologyStack ? options.technologyStack.split(',') : [],
contextBundle: options.contextBundle || options.context || '',
output: options.output || DEFAULT_OUTPUT_DIR,
format: options.format || 'markdown',
quiet: options.quiet || false
};
await handleStrategicPlanningCommand(userStoryOptions);
}
async handleRequirementsGeneration(args, options) {
const userStoryOptions = {
businessProblem: options.businessProblem || options.problem,
technologyStack: options.technologyStack ? options.technologyStack.split(',') : [],
contextBundle: options.contextBundle || options.context || '',
output: options.output || DEFAULT_OUTPUT_DIR,
format: options.format || 'json',
quiet: options.quiet || false
};
await handleRequirementsGenerationCommand(userStoryOptions);
}
async handleTechnologyAnalysis(args, options) {
const userStoryOptions = {
businessProblem: options.businessProblem || options.problem,
technologyStack: options.technologyStack ? options.technologyStack.split(',') : [],
contextBundle: options.contextBundle || options.context || '',
output: options.output || DEFAULT_OUTPUT_DIR,
format: options.format || 'markdown',
quiet: options.quiet || false
};
await handleTechnologyAnalysisCommand(userStoryOptions);
}
async handleRiskManagement(args, options) {
const userStoryOptions = {
businessProblem: options.businessProblem || options.problem,
technologyStack: options.technologyStack ? options.technologyStack.split(',') : [],
contextBundle: options.contextBundle || options.context || '',
output: options.output || DEFAULT_OUTPUT_DIR,
format: options.format || 'markdown',
quiet: options.quiet || false
};
await handleRiskManagementCommand(userStoryOptions);
}
async handleComprehensiveAnalysis(args, options) {
const userStoryOptions = {
businessProblem: options.businessProblem || options.problem,
technologyStack: options.technologyStack ? options.technologyStack.split(',') : [],
contextBundle: options.contextBundle || options.context || '',
output: options.output || DEFAULT_OUTPUT_DIR,
format: options.format || 'markdown',
quiet: options.quiet || false
};
await handleComprehensiveAnalysisCommand(userStoryOptions);
}
}
export default CommandIntegrationService;
//# sourceMappingURL=CommandIntegration.js.map