sf-agent-framework
Version:
AI Agent Orchestration Framework for Salesforce Development - Two-phase architecture with 70% context reduction
540 lines (484 loc) โข 17.2 kB
JavaScript
/**
* Workflow Initializer
*
* Purpose: Intelligent workflow selection based on project complexity analysis
* Implements scale-adaptive logic to recommend appropriate workflow tracks
*
* @module WorkflowInitializer
* @version 1.0.0
* @date 2025-11-25
*/
const inquirer = require('inquirer');
const chalk = require('chalk');
const ora = require('ora');
const fs = require('fs-extra');
const path = require('path');
class WorkflowInitializer {
constructor(rootDir = process.cwd()) {
this.rootDir = rootDir;
this.configPath = path.join(rootDir, 'sf-core', 'config', 'workflow-tracks.yaml');
}
/**
* Initialize workflow with intelligent selection
*/
async initialize() {
console.log(chalk.cyan.bold('\n๐ SF-Agent Workflow Initialization\n'));
console.log(chalk.gray("Let's analyze your project to recommend the best workflow...\n"));
try {
// Step 1: Gather project information
const projectInfo = await this.gatherProjectInfo();
// Step 2: Analyze complexity
const complexity = await this.analyzeComplexity(projectInfo);
// Step 3: Recommend workflow track
const recommendation = this.recommendTrack(complexity);
// Step 4: Present recommendation and get confirmation
const selectedTrack = await this.presentRecommendation(recommendation, complexity);
// Step 5: Initialize selected workflow
const initialized = await this.initializeWorkflow(selectedTrack, projectInfo);
if (initialized) {
this.displaySuccessMessage(selectedTrack);
}
return initialized;
} catch (error) {
console.error(chalk.red('\nโ Workflow initialization failed:'), error.message);
return false;
}
}
/**
* Gather project information from user
*/
async gatherProjectInfo() {
console.log(chalk.yellow('๐ Step 1: Project Information\n'));
const answers = await inquirer.prompt([
{
type: 'list',
name: 'projectType',
message: 'What type of project are you working on?',
choices: [
{ name: '๐ Bug fix / Hot fix', value: 'bug-fix' },
{ name: 'โจ Small enhancement', value: 'small-enhancement' },
{ name: '๐ฏ New feature', value: 'new-feature' },
{ name: '๐๏ธ New application/component', value: 'new-application' },
{ name: '๐ Org migration/upgrade', value: 'org-migration' },
{ name: '๐ Integration project', value: 'integration' },
{ name: '๐ข Enterprise-wide initiative', value: 'enterprise-initiative' },
],
},
{
type: 'list',
name: 'orgComplexity',
message: 'How would you describe your Salesforce org complexity?',
choices: [
{ name: '๐ข Simple (< 50 custom objects)', value: 'simple' },
{ name: '๐ก Medium (50-200 custom objects)', value: 'medium' },
{ name: '๐ Complex (200-500 custom objects)', value: 'complex' },
{ name: '๐ด Enterprise (500+ custom objects)', value: 'enterprise' },
],
},
{
type: 'list',
name: 'teamSize',
message: 'What is your team size?',
choices: [
{ name: '๐ค Solo (just me)', value: 'solo' },
{ name: '๐ฅ Small (2-5 people)', value: 'small' },
{ name: '๐จโ๐ฉโ๐งโ๐ฆ Medium (6-15 people)', value: 'medium' },
{ name: '๐ข Large (15+ people)', value: 'large' },
],
},
{
type: 'checkbox',
name: 'requirements',
message: 'Select any special requirements (space to select, enter to continue):',
choices: [
{ name: '๐ Compliance (HIPAA, GDPR, SOX, etc.)', value: 'compliance' },
{ name: '๐ก๏ธ High security requirements', value: 'security' },
{ name: '๐ Complex integrations (3+ systems)', value: 'complex-integrations' },
{ name: '๐ Data migration', value: 'data-migration' },
{ name: 'โก Performance critical', value: 'performance' },
{ name: '๐ Multi-org deployment', value: 'multi-org' },
{ name: '๐ฆ Package development', value: 'package-dev' },
],
},
{
type: 'list',
name: 'timeline',
message: 'What is your timeline?',
choices: [
{ name: 'โฑ๏ธ Urgent (< 1 day)', value: 'urgent' },
{ name: '๐
Standard (1-7 days)', value: 'standard' },
{ name: '๐ Extended (1-4 weeks)', value: 'extended' },
{ name: '๐๏ธ Long-term (1+ months)', value: 'long-term' },
],
},
{
type: 'confirm',
name: 'hasExistingDocs',
message: 'Do you have existing documentation or requirements?',
default: false,
},
]);
return answers;
}
/**
* Analyze project complexity and assign score
*/
async analyzeComplexity(projectInfo) {
const spinner = ora('Analyzing project complexity...').start();
// Simulate analysis delay
await new Promise((resolve) => setTimeout(resolve, 1000));
let score = 0;
const factors = [];
// Project type scoring (0-40 points)
const typeScores = {
'bug-fix': 10,
'small-enhancement': 20,
'new-feature': 40,
'new-application': 60,
'org-migration': 80,
integration: 70,
'enterprise-initiative': 90,
};
const typeScore = typeScores[projectInfo.projectType] || 40;
score += typeScore;
factors.push({
category: 'Project Type',
value: projectInfo.projectType,
score: typeScore,
weight: 'High',
});
// Org complexity scoring (0-25 points)
const orgScores = {
simple: 0,
medium: 10,
complex: 20,
enterprise: 25,
};
const orgScore = orgScores[projectInfo.orgComplexity] || 10;
score += orgScore;
factors.push({
category: 'Org Complexity',
value: projectInfo.orgComplexity,
score: orgScore,
weight: 'Medium',
});
// Team size scoring (0-15 points)
const teamScores = {
solo: 0,
small: 5,
medium: 10,
large: 15,
};
const teamScore = teamScores[projectInfo.teamSize] || 5;
score += teamScore;
factors.push({
category: 'Team Size',
value: projectInfo.teamSize,
score: teamScore,
weight: 'Low',
});
// Special requirements scoring (0-20 points)
const reqScore = Math.min(projectInfo.requirements.length * 4, 20);
score += reqScore;
if (projectInfo.requirements.length > 0) {
factors.push({
category: 'Special Requirements',
value: projectInfo.requirements.join(', '),
score: reqScore,
weight: 'Medium',
});
}
// Timeline scoring (0-10 points)
const timelineScores = {
urgent: 0, // Need quick workflow
standard: 3,
extended: 6,
'long-term': 10,
};
const timelineScore = timelineScores[projectInfo.timeline] || 3;
score += timelineScore;
factors.push({
category: 'Timeline',
value: projectInfo.timeline,
score: timelineScore,
weight: 'Low',
});
// Normalize score to 0-100
const normalizedScore = Math.min(score, 100);
spinner.succeed(chalk.green('Complexity analysis complete'));
return {
score: normalizedScore,
category: this.getComplexityCategory(normalizedScore),
factors: factors,
projectInfo: projectInfo,
};
}
/**
* Get complexity category based on score
*/
getComplexityCategory(score) {
if (score < 30) return 'Low';
if (score < 60) return 'Medium';
if (score < 80) return 'High';
return 'Very High';
}
/**
* Recommend workflow track based on complexity
*/
recommendTrack(complexity) {
const score = complexity.score;
const projectInfo = complexity.projectInfo;
// Quick track: Score < 30
if (score < 30) {
return {
track: 'quick',
name: 'โก Quick Flow',
reason: 'Low complexity - optimized for speed',
estimatedTime: '5-10 minutes',
phases: ['implementation'],
agents: ['sf-developer-lean', 'sf-qa-lean'],
description: 'Streamlined workflow for bug fixes and small changes',
benefits: ['Minimal overhead', 'Fast execution', 'Focus on implementation'],
bestFor: ['Bug fixes', 'Small enhancements', 'Quick configuration changes'],
};
}
// Balanced track: Score 30-70
if (score < 70) {
return {
track: 'balanced',
name: '๐ Balanced Flow',
reason: 'Medium complexity - comprehensive yet efficient',
estimatedTime: '15-30 minutes',
phases: ['planning', 'implementation', 'validation'],
agents: [
'sf-business-analyst',
'sf-architect',
'sf-developer-lean',
'sf-qa-lean',
'sf-devops-lead-lean',
],
description: 'Full-featured workflow with architecture and planning',
benefits: [
'Comprehensive planning',
'Architecture design',
'Quality validation',
'Deployment ready',
],
bestFor: ['New features', 'Standard projects', 'Most common scenarios'],
};
}
// Enterprise track: Score >= 70
return {
track: 'enterprise',
name: '๐ข Enterprise Flow',
reason: 'High complexity - full governance and compliance',
estimatedTime: '30-60 minutes',
phases: ['analysis', 'planning', 'solutioning', 'implementation', 'deployment'],
agents: [
'sf-product-manager',
'sf-business-analyst',
'sf-architect',
'sf-technical-architect',
'sf-data-architect',
'sf-security-architect',
'sf-developer-lean',
'sf-qa-lean',
'sf-devops-lead-lean',
'sf-release-manager',
],
description: 'Comprehensive workflow with full analysis and governance',
benefits: [
'Complete analysis phase',
'Full architecture review',
'Security and compliance',
'Data architecture',
'Comprehensive testing',
'Release management',
],
bestFor: [
'Enterprise initiatives',
'Complex integrations',
'Compliance-driven projects',
'Multi-org deployments',
'Mission-critical systems',
],
};
}
/**
* Present recommendation and get user confirmation
*/
async presentRecommendation(recommendation, complexity) {
console.log(chalk.yellow('\n\n๐ Step 2: Complexity Analysis Results\n'));
// Display complexity score
console.log(chalk.white(` Complexity Score: ${chalk.bold(complexity.score)}/100`));
console.log(chalk.white(` Category: ${chalk.bold(complexity.category)}\n`));
// Display contributing factors
console.log(chalk.gray(' Contributing factors:'));
complexity.factors.forEach((factor) => {
const scoreColor = factor.score > 15 ? 'red' : factor.score > 8 ? 'yellow' : 'green';
console.log(
chalk.gray(` โข ${factor.category}: `) +
chalk[scoreColor](`${factor.score} points `) +
chalk.gray(`(${factor.weight} weight)`)
);
});
// Display recommendation
console.log(chalk.cyan.bold('\n\n๐ฏ Step 3: Recommended Workflow\n'));
console.log(chalk.white.bold(` ${recommendation.name}`));
console.log(chalk.gray(` ${recommendation.description}\n`));
console.log(
chalk.white(' Estimated Time: ') + chalk.yellow.bold(recommendation.estimatedTime)
);
console.log(chalk.white(' Phases: ') + chalk.cyan(recommendation.phases.join(' โ ')));
console.log(chalk.white(' Agents Involved: ') + chalk.gray(recommendation.agents.length));
console.log(chalk.white('\n โจ Benefits:'));
recommendation.benefits.forEach((benefit) => {
console.log(chalk.gray(` โข ${benefit}`));
});
console.log(chalk.white('\n ๐ฏ Best For:'));
recommendation.bestFor.forEach((use) => {
console.log(chalk.gray(` โข ${use}`));
});
// Get user confirmation or allow override
const { confirmed, selectedTrack } = await inquirer.prompt([
{
type: 'confirm',
name: 'confirmed',
message: '\nUse recommended workflow?',
default: true,
},
{
type: 'list',
name: 'selectedTrack',
message: 'Select workflow track:',
when: (answers) => !answers.confirmed,
choices: [
{ name: 'โก Quick Flow (5-10 min)', value: 'quick' },
{ name: '๐ Balanced Flow (15-30 min)', value: 'balanced' },
{ name: '๐ข Enterprise Flow (30-60 min)', value: 'enterprise' },
],
},
]);
if (confirmed) {
return recommendation.track;
} else {
return selectedTrack;
}
}
/**
* Initialize the selected workflow
*/
async initializeWorkflow(track, projectInfo) {
const spinner = ora('Initializing workflow...').start();
try {
// Create workflow directory structure
const workflowDir = path.join(this.rootDir, 'docs', 'workflows', `current-${track}`);
await fs.ensureDir(workflowDir);
// Create workflow manifest
const manifest = {
track: track,
initialized: new Date().toISOString(),
projectInfo: projectInfo,
status: 'initialized',
currentPhase: null,
completedPhases: [],
agents: [],
artifacts: [],
};
await fs.writeJson(path.join(workflowDir, 'workflow-manifest.json'), manifest, { spaces: 2 });
// Create phase directories
const trackDefinitions = {
quick: ['implementation'],
balanced: ['planning', 'implementation', 'validation'],
enterprise: ['analysis', 'planning', 'solutioning', 'implementation', 'deployment'],
};
const phases = trackDefinitions[track] || ['planning', 'implementation'];
for (const phase of phases) {
await fs.ensureDir(path.join(workflowDir, phase));
}
spinner.succeed(chalk.green('Workflow initialized successfully'));
return true;
} catch (error) {
spinner.fail(chalk.red('Failed to initialize workflow'));
console.error(error);
return false;
}
}
/**
* Display success message with next steps
*/
displaySuccessMessage(track) {
console.log(chalk.green.bold('\n\nโ
Workflow Initialized Successfully!\n'));
const nextSteps = {
quick: [
'Start with /sf-developer-lean to implement your change',
'Run /sf-qa-lean to validate your implementation',
'Use /sf-devops-lead-lean to deploy when ready',
],
balanced: [
'Begin with /sf-business-analyst to document requirements',
'Continue with /sf-architect for solution design',
'Proceed to /sf-developer-lean for implementation',
'Validate with /sf-qa-lean',
'Deploy with /sf-devops-lead-lean',
],
enterprise: [
'Start analysis phase with /sf-product-manager',
'Document requirements with /sf-business-analyst',
'Design architecture with /sf-architect',
'Review security with /sf-security-architect',
'Implement with /sf-developer-lean',
'Complete testing with /sf-qa-lean',
'Manage release with /sf-release-manager',
],
};
console.log(chalk.white('๐ Next Steps:\n'));
const steps = nextSteps[track] || nextSteps.balanced;
steps.forEach((step, index) => {
console.log(chalk.gray(` ${index + 1}. ${step}`));
});
console.log(chalk.cyan.bold('\n\n๐ก Quick Commands:\n'));
console.log(chalk.gray(' sfa workflow:status - Check workflow status'));
console.log(chalk.gray(' sfa workflow:next - Get next recommended action'));
console.log(chalk.gray(' sfa agents:list - See all available agents'));
console.log(chalk.gray(' sfa phase <name> - Switch to different phase\n'));
}
/**
* Get current workflow status
*/
async getWorkflowStatus() {
try {
const workflowDirs = await fs.readdir(path.join(this.rootDir, 'docs', 'workflows'));
const currentWorkflow = workflowDirs.find((dir) => dir.startsWith('current-'));
if (!currentWorkflow) {
return {
initialized: false,
message: 'No active workflow. Run "sfa workflow:init" to get started.',
};
}
const manifestPath = path.join(
this.rootDir,
'docs',
'workflows',
currentWorkflow,
'workflow-manifest.json'
);
const manifest = await fs.readJson(manifestPath);
return {
initialized: true,
track: manifest.track,
status: manifest.status,
currentPhase: manifest.currentPhase,
completedPhases: manifest.completedPhases,
projectInfo: manifest.projectInfo,
startedAt: manifest.initialized,
};
} catch (error) {
return {
initialized: false,
error: error.message,
};
}
}
}
module.exports = WorkflowInitializer;