claude-buddy
Version:
Your friendly AI development companion for Claude Code - supercharge Claude Code with intelligent workflows and safety features
242 lines (236 loc) • 9.65 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
class PersonaFlagParser {
availablePersonas;
flagPatterns;
constructor() {
this.availablePersonas = [
'architect', 'frontend', 'backend', 'security', 'performance',
'analyzer', 'qa', 'refactorer', 'devops', 'mentor', 'scribe'
];
this.flagPatterns = {
persona: /--persona-([a-z]+)/gi,
shortPersona: /--([a-z]+)/gi,
with: /--with-([a-z]+)/gi,
focus: /--focus\s+([a-z,\s]+)/gi,
comprehensive: /--comprehensive|--all|--multi-persona/gi,
singlePersona: /--single|--single-persona/gi,
noCollaboration: /--no-collab|--no-collaboration|--solo/gi,
learn: /--learn|--adaptive/gi,
noLearn: /--no-learn|--static/gi
};
}
parseInput(userInput) {
const originalInput = userInput;
let cleanedInput = userInput;
const parseResult = {
originalInput,
cleanedInput: '',
hasFlags: false,
personas: {
manual: [],
with: [],
focus: []
},
modes: {
comprehensive: false,
singlePersona: false,
noCollaboration: false,
learn: null
},
focusAreas: [],
confidence: {
override: null,
threshold: null
}
};
parseResult.personas.manual = this.extractPersonaFlags(userInput, 'persona');
parseResult.personas.with = this.extractPersonaFlags(userInput, 'with');
const focusMatch = userInput.match(this.flagPatterns.focus);
if (focusMatch) {
parseResult.focusAreas = focusMatch[0]
.replace(/--focus\s+/gi, '')
.split(',')
.map(area => area.trim().toLowerCase())
.filter(area => area.length > 0);
parseResult.hasFlags = true;
}
parseResult.modes.comprehensive = this.flagPatterns.comprehensive.test(userInput);
parseResult.modes.singlePersona = this.flagPatterns.singlePersona.test(userInput);
parseResult.modes.noCollaboration = this.flagPatterns.noCollaboration.test(userInput);
if (this.flagPatterns.learn.test(userInput)) {
parseResult.modes.learn = true;
}
else if (this.flagPatterns.noLearn.test(userInput)) {
parseResult.modes.learn = false;
}
parseResult.hasFlags = parseResult.hasFlags ||
parseResult.personas.manual.length > 0 ||
parseResult.personas.with.length > 0 ||
Object.values(parseResult.modes).some(mode => mode === true);
cleanedInput = this.removeFlags(userInput);
parseResult.cleanedInput = cleanedInput.trim();
return parseResult;
}
extractPersonaFlags(input, flagType) {
const personas = [];
const pattern = this.flagPatterns[flagType];
let match;
pattern.lastIndex = 0;
while ((match = pattern.exec(input)) !== null) {
const personaName = match[1].toLowerCase();
if (this.availablePersonas.includes(personaName)) {
if (!personas.includes(personaName)) {
personas.push(personaName);
}
}
}
return personas;
}
removeFlags(input) {
let cleaned = input;
for (const [, pattern] of Object.entries(this.flagPatterns)) {
cleaned = cleaned.replace(pattern, '');
}
cleaned = cleaned.replace(/\s+/g, ' ').trim();
return cleaned;
}
validateFlags(parseResult) {
const validation = {
isValid: true,
errors: [],
warnings: [],
suggestions: []
};
if (parseResult.modes.comprehensive && parseResult.modes.singlePersona) {
validation.errors.push('Cannot use --comprehensive and --single-persona flags together');
validation.isValid = false;
}
if (parseResult.modes.noCollaboration && parseResult.personas.with.length > 0) {
validation.warnings.push('--no-collaboration flag conflicts with --with-* flags');
}
if (parseResult.focusAreas.includes('')) {
validation.warnings.push('Empty focus areas detected, will be ignored');
}
const validFocusAreas = ['security', 'performance', 'quality', 'architecture', 'frontend', 'backend', 'testing', 'documentation'];
const unknownFocusAreas = parseResult.focusAreas.filter(area => !validFocusAreas.includes(area));
if (unknownFocusAreas.length > 0) {
validation.warnings.push(`Unknown focus areas: ${unknownFocusAreas.join(', ')}`);
}
if (parseResult.personas.manual.length > 3) {
validation.suggestions.push('Consider using --comprehensive instead of manually specifying many personas');
}
if (parseResult.personas.manual.length === 0 && parseResult.modes.singlePersona) {
validation.suggestions.push('--single-persona is more effective when combined with a specific --persona-* flag');
}
return validation;
}
generateActivationInstructions(parseResult, validation) {
if (!validation.isValid) {
return {
mode: 'error',
strategy: 'error',
personas: {
required: [],
preferred: [],
focus: []
},
collaboration: {
enabled: false,
comprehensive: false,
singleLeader: false
},
learning: {
enabled: null,
adaptive: false
},
validation,
errors: validation.errors,
fallback: 'automatic'
};
}
const instructions = {
mode: 'manual',
strategy: 'default',
personas: {
required: parseResult.personas.manual,
preferred: parseResult.personas.with,
focus: parseResult.focusAreas
},
collaboration: {
enabled: !parseResult.modes.noCollaboration,
comprehensive: parseResult.modes.comprehensive,
singleLeader: parseResult.modes.singlePersona
},
learning: {
enabled: parseResult.modes.learn,
adaptive: parseResult.modes.learn === true
},
validation: validation
};
if (parseResult.modes.comprehensive) {
instructions.strategy = 'comprehensive';
}
else if (parseResult.modes.singlePersona) {
instructions.strategy = 'single_leader';
}
else if (parseResult.modes.noCollaboration) {
instructions.strategy = 'isolated';
}
else if (parseResult.personas.with.length > 0) {
instructions.strategy = 'collaborative';
}
else if (parseResult.personas.manual.length > 0) {
instructions.strategy = 'manual_selection';
}
else {
instructions.strategy = 'focus_driven';
}
return instructions;
}
generateHelpText() {
const help = `
# Persona Flag Reference
## Manual Persona Selection
${this.availablePersonas.map(persona => `- \`--persona-${persona}\`: Activate ${persona} persona`).join('\n')}
## Collaboration Flags
${this.availablePersonas.map(persona => `- \`--with-${persona}\`: Include ${persona} as supporting expert`).join('\n')}
## Focus Areas
- \`--focus security,performance\`: Focus on specific areas (comma-separated)
- Available focus areas: security, performance, quality, architecture, frontend, backend, testing, documentation
## Mode Flags
- \`--comprehensive\`: Activate all relevant personas
- \`--single-persona\`: Use single persona leadership
- \`--no-collaboration\`: Disable persona collaboration
- \`--learn\`: Enable adaptive learning
- \`--no-learn\`: Disable learning for this session
## Example Usage
\`\`\`
/buddy:analyze --persona-security --with-backend --focus security,performance
/buddy:improve --comprehensive --learn
/buddy:architect --persona-architect --with-performance --with-security
\`\`\`
`;
return help;
}
hasPersonaFlags(input) {
return /--persona-|--with-|--focus|--comprehensive|--single|--no-collab/i.test(input);
}
extractCommand(input) {
const commandMatch = input.match(/^\/buddy:([a-z]+)/i);
return commandMatch ? commandMatch[1].toLowerCase() : null;
}
getCommandSuggestions(command) {
const suggestions = {
'analyze': ['--persona-analyzer', '--persona-security', '--focus security,performance'],
'improve': ['--persona-refactorer', '--persona-performance', '--comprehensive'],
'review': ['--persona-security', '--persona-qa', '--with-analyzer'],
'architect': ['--persona-architect', '--with-performance', '--with-security'],
'commit': ['--persona-scribe', '--persona-security'],
'docs': ['--persona-scribe', '--persona-mentor'],
'brainstorm': ['--comprehensive', '--with-architect']
};
return suggestions[command] || ['--comprehensive', '--persona-analyzer'];
}
}
exports.default = PersonaFlagParser;