UNPKG

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
"use strict"; 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;