aiwf
Version:
AI Workflow Framework for Claude Code with multi-language support (Korean/English)
310 lines (269 loc) • 10.6 kB
JavaScript
/**
* AI 페르소나 명령어
* AI 행동 페르소나 관리 및 전환
*/
import { AIPersonaManager } from '../lib/ai-persona-manager.js';
import { ResourceLoader } from '../lib/resource-loader.js';
import path from 'path';
import chalk from 'chalk';
import { fileURLToPath } from 'url';
import { dirname } from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
class PersonaCommand {
constructor() {
this.personaManager = null;
this.resourceLoader = new ResourceLoader();
}
/**
* 페르소나 매니저 초기화
*/
async initPersonaManager() {
if (!this.personaManager) {
// 사용자 디렉토리 초기화
await this.resourceLoader.initUserDirectory();
this.personaManager = new AIPersonaManager({
personaConfigPath: path.join(process.cwd(), '.aiwf', 'personas'),
metricsPath: path.join(process.cwd(), '.aiwf', 'metrics'),
metricsEnabled: true,
autoDetectionEnabled: true,
resourceLoader: this.resourceLoader
});
await this.personaManager.init();
}
return this.personaManager;
}
/**
* 페르소나 상태 표시
*/
async showStatus() {
try {
// 파일에서 현재 페르소나 읽기
const fs = await import('fs/promises');
const path = await import('path');
const personaFile = path.join(process.cwd(), '.aiwf', 'personas', 'current.json');
try {
const content = await fs.readFile(personaFile, 'utf-8');
const currentPersona = JSON.parse(content);
console.log(chalk.cyan('🎭 현재 AI 페르소나 상태'));
console.log(chalk.gray('-'.repeat(50)));
console.log(`현재 페르소나: ${chalk.yellow(currentPersona.name)}`);
console.log(`설명: ${currentPersona.description}`);
console.log(`활성화 시간: ${new Date(currentPersona.activatedAt).toLocaleString('ko-KR')}`);
const behaviors = this.getKoreanBehaviors(currentPersona.name);
if (behaviors.length > 0) {
console.log('\n주요 동작:');
behaviors.forEach(behavior => {
console.log(` • ${behavior}`);
});
}
console.log(chalk.gray('\n' + '-'.repeat(50)));
console.log(chalk.green('✅ 페르소나가 활성화되어 있습니다.'));
} catch (fileError) {
console.log(chalk.yellow('⚠️ 현재 활성화된 페르소나가 없습니다.'));
console.log(chalk.gray('사용 가능한 페르소나 목록을 보려면: aiwf persona list'));
console.log(chalk.gray('페르소나를 설정하려면: aiwf persona set <페르소나명>'));
}
} catch (error) {
console.error(chalk.red('❌ 페르소나 상태 확인 중 오류가 발생했습니다:'), error.message);
console.error(error.stack);
}
}
/**
* 페르소나 목록 표시
*/
async listPersonas() {
try {
console.log(chalk.cyan('🎭 사용 가능한 AI 페르소나'));
console.log(chalk.gray('-'.repeat(50)));
// ResourceLoader를 사용하여 페르소나 목록 가져오기
try {
const personas = await this.resourceLoader.listPersonas();
for (const personaName of personas) {
try {
const persona = await this.resourceLoader.loadPersona(personaName);
const displayName = chalk.yellow(personaName);
const description = persona.description || '설명 없음';
console.log(` ${displayName} - ${description}`);
} catch (error) {
// 개별 페르소나 로드 실패 시 건너뛰기
console.log(` ${chalk.yellow(personaName)} - ${chalk.gray('(로드 실패)')}`);
}
}
} catch (error) {
// 페르소나 목록 가져오기 실패 시 기본 목록 표시
const defaultPersonas = [
{ name: 'architect', description: '시스템 설계 및 아키텍처 전문가' },
{ name: 'developer', description: '일반 개발자 (기본값)' },
{ name: 'reviewer', description: '코드 리뷰 및 품질 관리 전문가' },
{ name: 'analyst', description: '비즈니스 분석가' },
{ name: 'tester', description: '테스트 엔지니어' }
];
defaultPersonas.forEach(persona => {
const displayName = chalk.yellow(persona.name);
console.log(` ${displayName} - ${persona.description}`);
});
}
console.log(chalk.gray('\n' + '-'.repeat(50)));
console.log(chalk.gray('사용법: aiwf persona set <페르소나명>'));
} catch (error) {
console.error(chalk.red('❌ 페르소나 목록 조회 중 오류가 발생했습니다:'), error.message);
console.error(error.stack);
}
}
/**
* 페르소나 전환
*/
async setPersona(personaName) {
if (!personaName) {
console.error(chalk.red('❌ 페르소나 이름을 지정해주세요.'));
console.log(chalk.gray('사용법: aiwf persona set <페르소나명>'));
console.log(chalk.gray('사용 가능한 페르소나: aiwf persona list'));
return;
}
try {
// 유효한 페르소나인지 확인
const validPersonas = ['architect', 'developer', 'reviewer', 'debugger', 'optimizer', 'security', 'documenter'];
if (!validPersonas.includes(personaName)) {
console.error(chalk.red(`❌ 페르소나 '${personaName}'를 찾을 수 없습니다.`));
console.log(chalk.gray('사용 가능한 페르소나: aiwf persona list'));
return;
}
// 간단한 페르소나 설정 (파일 기반)
const fs = await import('fs/promises');
const path = await import('path');
const personaDir = path.join(process.cwd(), '.aiwf', 'personas');
// 디렉토리 생성
await fs.mkdir(personaDir, { recursive: true });
// 현재 페르소나 저장
const personaConfig = {
name: personaName,
description: this.getKoreanDescription(personaName),
activatedAt: new Date().toISOString()
};
await fs.writeFile(
path.join(personaDir, 'current.json'),
JSON.stringify(personaConfig, null, 2)
);
console.log(chalk.green('🎭 AI 페르소나 활성화 완료'));
console.log(chalk.gray('-'.repeat(50)));
console.log(`현재 페르소나: ${chalk.yellow(personaName)}`);
console.log(`전문 분야: ${this.getKoreanDescription(personaName)}`);
console.log(chalk.gray('-'.repeat(50)));
console.log(chalk.green('✅ 페르소나가 성공적으로 활성화되었습니다.'));
} catch (error) {
console.error(chalk.red('❌ 페르소나 전환 중 오류가 발생했습니다:'), error.message);
console.error(error.stack);
}
}
/**
* 페르소나 리셋
*/
async resetPersona() {
try {
// 기본 페르소나(developer)로 리셋
await this.setPersona('developer');
console.log(chalk.green('🔄 페르소나가 기본값(developer)으로 리셋되었습니다.'));
} catch (error) {
console.error(chalk.red('❌ 페르소나 리셋 중 오류가 발생했습니다:'), error.message);
console.error(error.stack);
}
}
/**
* 명령어 실행
*/
async execute(args) {
const [subcommand, ...restArgs] = args;
switch (subcommand) {
case 'status':
await this.showStatus();
break;
case 'list':
await this.listPersonas();
break;
case 'set':
await this.setPersona(restArgs[0]);
break;
case 'reset':
await this.resetPersona();
break;
default:
this.showHelp();
break;
}
}
/**
* 도움말 표시
*/
showHelp() {
console.log(chalk.cyan('🎭 AIWF 페르소나 관리'));
console.log(chalk.gray('-'.repeat(50)));
console.log('사용법: aiwf persona <명령어> [옵션]');
console.log('');
console.log('명령어:');
console.log(' status 현재 페르소나 상태 표시');
console.log(' list 사용 가능한 페르소나 목록');
console.log(' set <페르소나명> 특정 페르소나로 전환');
console.log(' reset 기본 페르소나로 리셋');
console.log('');
console.log('예시:');
console.log(' aiwf persona status');
console.log(' aiwf persona list');
console.log(' aiwf persona set architect');
console.log(' aiwf persona reset');
}
/**
* 한국어 설명 가져오기
*/
getKoreanDescription(persona) {
const descriptions = {
architect: '시스템 설계 및 아키텍처 전문가',
developer: '일반 개발자 (기본값)',
reviewer: '코드 리뷰 및 품질 관리 전문가',
debugger: '디버깅 및 문제 해결 전문가',
optimizer: '성능 최적화 전문가',
security: '보안 및 취약점 분석 전문가',
devops: 'DevOps 및 인프라 관리 전문가',
tester: '테스트 및 QA 전문가',
documenter: '문서화 및 기술 작성 전문가',
mentor: '멘토링 및 교육 전문가'
};
return descriptions[persona] || '설명 없음';
}
/**
* 한국어 동작 설명 가져오기
*/
getKoreanBehaviors(persona) {
const behaviors = {
architect: [
'큰 그림과 전체 시스템 구조에 집중',
'확장성과 유지보수성 우선시',
'디자인 패턴과 아키텍처 원칙 적용',
'통합 지점과 인터페이스 고려'
],
developer: [
'실용적이고 효율적인 코드 작성',
'베스트 프랙티스 적용',
'가독성과 유지보수성 중시'
],
reviewer: [
'코드 품질과 표준 준수 확인',
'잠재적 버그와 개선점 식별',
'성능과 보안 측면 검토'
],
debugger: [
'문제의 근본 원인 분석',
'체계적인 디버깅 접근',
'재현 가능한 테스트 케이스 생성'
],
optimizer: [
'성능 병목 지점 식별',
'메모리 사용량 최적화',
'알고리즘 효율성 개선'
]
};
return behaviors[persona] || ['기본 동작'];
}
}
export default PersonaCommand;