github-mcp-auto-git
Version:
GitHub MCP Auto Git v3.0 - メモリ効率化・統合MCP・モジュール化完了の完全自動Git操作システム
318 lines • 13 kB
JavaScript
/**
* Interactive Configuration Manager Module
* Handles interactive setup and configuration following Constitutional AI principles
*/
import * as readline from 'readline';
export class InteractiveConfigManager {
constructor(config) {
this.config = { ...config };
}
/**
* Configure watch patterns interactively
* Fail Fast: Validate user input immediately
* Be Lazy: Reuse common pattern configurations
* TypeScript First: Complete type safety for configuration
*/
async configureWatchPatterns() {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
try {
console.log('\n🔧 監視設定');
console.log('現在の監視パターン:', this.config.paths.join(', '));
const answer = await this.askQuestion(rl, '\n📁 監視したいフォルダ/ファイルを指定してください:\n' +
' 1. 現在のまま (src/**/*)\n' +
' 2. プロジェクト全体 (**/*)\n' +
' 3. カスタム設定\n' +
'選択 (1-3): ');
const result = await this.processWatchPatternChoice(rl, answer);
rl.close();
return result;
}
catch (error) {
rl.close();
return {
success: false,
message: `Configuration failed: ${error}`
};
}
}
/**
* Configure subagent settings interactively
* TypeScript First: Strongly typed subagent configuration
*/
async configureSubagents() {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
try {
console.log('\n🤖 サブエージェント設定');
// Git Safety Analyzer configuration
const safetyEnabled = await this.askYesNo(rl, '🛡️ Git Safety Analyzer を有効にしますか? (機密情報・破壊的変更検出) [Y/n]: ');
let safetyThreshold = 0.85;
if (safetyEnabled) {
const thresholdAnswer = await this.askQuestion(rl, '🔒 安全性閾値を設定してください (0.0-1.0, デフォルト: 0.85): ');
const parsedThreshold = parseFloat(thresholdAnswer) || 0.85;
safetyThreshold = Math.max(0, Math.min(1, parsedThreshold));
}
// Commit Message Generator configuration
const commitEnabled = await this.askYesNo(rl, '📝 Commit Message Generator を有効にしますか? (非エンジニア向けメッセージ生成) [Y/n]: ');
let language = 'ja';
let style = 'friendly';
if (commitEnabled) {
const languageChoice = await this.askChoice(rl, '🌐 メッセージ言語を選択してください: ', ['ja (日本語)', 'en (English)'], 'ja');
language = languageChoice.split(' ')[0] || 'ja';
const styleChoice = await this.askChoice(rl, '💬 メッセージスタイルを選択してください: ', ['friendly (親しみやすい)', 'professional (プロフェッショナル)', 'technical (技術的)'], 'friendly');
style = styleChoice.split(' ')[0] || 'friendly';
}
// PR Management Agent configuration
const prEnabled = await this.askYesNo(rl, '🔀 PR Management Agent を有効にしますか? (自動マージ判定・PR管理) [Y/n]: ');
let autoMergeThreshold = 0.85;
if (prEnabled) {
const mergeAnswer = await this.askQuestion(rl, '🔄 自動マージ閾値を設定してください (0.0-1.0, デフォルト: 0.85): ');
const parsedMerge = parseFloat(mergeAnswer) || 0.85;
autoMergeThreshold = Math.max(0, Math.min(1, parsedMerge));
}
// Update configuration
this.config.subAgents = {
gitSafetyAnalyzer: {
enabled: safetyEnabled,
safetyThreshold
},
commitMessageGenerator: {
enabled: commitEnabled,
language,
style
},
prManagementAgent: {
enabled: prEnabled,
autoMergeThreshold
}
};
rl.close();
console.log('\n✅ サブエージェント設定が完了しました');
this.displaySubagentSummary();
return {
success: true,
config: this.config
};
}
catch (error) {
rl.close();
return {
success: false,
message: `Subagent configuration failed: ${error}`
};
}
}
/**
* Configure notification settings
* Be Lazy: Smart defaults with minimal user interaction
*/
async configureNotifications() {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
try {
console.log('\n🔔 通知設定');
const success = await this.askYesNo(rl, '✅ 成功時の通知を有効にしますか? [Y/n]: ');
const warnings = await this.askYesNo(rl, '⚠️ 警告時の通知を有効にしますか? [Y/n]: ');
const detailed = await this.askYesNo(rl, '📊 詳細結果の表示を有効にしますか? [y/N]: ', false);
this.config.notifications = {
success,
warnings,
detailed
};
rl.close();
console.log('\n✅ 通知設定が完了しました');
return {
success: true,
config: this.config
};
}
catch (error) {
rl.close();
return {
success: false,
message: `Notification configuration failed: ${error}`
};
}
}
/**
* Get the current configuration
* TypeScript First: Type-safe configuration access
*/
getConfiguration() {
return { ...this.config };
}
/**
* Process watch pattern choice
* Fail Fast: Immediate validation of pattern choices
*/
async processWatchPatternChoice(rl, choice) {
switch (choice.trim()) {
case '1':
// Keep current settings
console.log('✅ 現在の設定を維持します');
return {
success: true,
config: this.config
};
case '2':
this.config.paths = ['**/*', '!node_modules/**', '!.git/**', '!dist/**', '!build/**'];
console.log('✅ プロジェクト全体を監視対象に設定しました');
return {
success: true,
config: this.config
};
case '3':
return await this.configureCustomPatterns(rl);
default:
console.log('🔄 デフォルト設定を使用します');
return {
success: true,
config: this.config
};
}
}
/**
* Configure custom watch patterns
* Be Lazy: Smart validation and auto-completion
*/
async configureCustomPatterns(rl) {
try {
const customPath = await this.askQuestion(rl, 'カスタムパターンを入力してください (例: src/**/*,*.md): ');
if (!customPath.trim()) {
console.log('❌ 無効なパターンです。デフォルト設定を使用します');
return {
success: true,
config: this.config
};
}
const patterns = customPath.split(',')
.map(p => p.trim())
.filter(p => p.length > 0);
if (patterns.length === 0) {
console.log('❌ 有効なパターンがありません。デフォルト設定を使用します');
return {
success: true,
config: this.config
};
}
// Add common ignore patterns
this.config.paths = [...patterns, '!node_modules/**', '!.git/**'];
console.log('✅ カスタムパターンを設定しました:', patterns.join(', '));
return {
success: true,
config: this.config
};
}
catch (error) {
return {
success: false,
message: `Custom pattern configuration failed: ${error}`
};
}
}
/**
* Ask a question and wait for user input
* Fail Fast: Robust error handling for user input
*/
askQuestion(rl, question) {
return new Promise((resolve, reject) => {
let isCompleted = false;
const cleanup = () => {
if (!isCompleted) {
isCompleted = true;
}
};
const timeout = setTimeout(() => {
if (!isCompleted) {
cleanup();
reject(new Error('Input timeout'));
}
}, 30000); // 30 second timeout
rl.question(question, (answer) => {
if (!isCompleted) {
clearTimeout(timeout);
cleanup();
resolve(answer.trim());
}
});
rl.on('error', (error) => {
if (!isCompleted) {
clearTimeout(timeout);
cleanup();
reject(error);
}
});
});
}
/**
* Ask a yes/no question
* TypeScript First: Boolean return type with default handling
*/
async askYesNo(rl, question, defaultValue = true) {
try {
const answer = await this.askQuestion(rl, question);
const normalized = answer.toLowerCase();
if (normalized === '' || normalized === 'y' || normalized === 'yes') {
return defaultValue;
}
if (normalized === 'n' || normalized === 'no') {
return !defaultValue;
}
return defaultValue;
}
catch (error) {
console.warn('⚠️ 入力エラー、デフォルト値を使用します:', defaultValue);
return defaultValue;
}
}
/**
* Ask user to choose from multiple options
* Be Lazy: Simplified choice selection with smart defaults
*/
async askChoice(rl, question, choices, defaultChoice) {
try {
const choiceText = choices.map((choice, index) => ` ${index + 1}. ${choice}`).join('\n');
const fullQuestion = `${question}\n${choiceText}\n選択 (1-${choices.length}): `;
const answer = await this.askQuestion(rl, fullQuestion);
const choiceIndex = parseInt(answer) - 1;
if (choiceIndex >= 0 && choiceIndex < choices.length) {
return choices[choiceIndex] || defaultChoice;
}
console.log(`無効な選択です。デフォルト値を使用します: ${defaultChoice}`);
return defaultChoice;
}
catch (error) {
console.warn('⚠️ 選択エラー、デフォルト値を使用します:', defaultChoice);
return defaultChoice;
}
}
/**
* Display subagent configuration summary
* TypeScript First: Type-safe configuration display
*/
displaySubagentSummary() {
console.log('\n📋 サブエージェント設定サマリー:');
const { subAgents } = this.config;
console.log(` 🛡️ Git Safety Analyzer: ${subAgents.gitSafetyAnalyzer.enabled ? '✅' : '❌'}`);
if (subAgents.gitSafetyAnalyzer.enabled) {
console.log(` - 安全性閾値: ${subAgents.gitSafetyAnalyzer.safetyThreshold}`);
}
console.log(` 📝 Commit Message Generator: ${subAgents.commitMessageGenerator.enabled ? '✅' : '❌'}`);
if (subAgents.commitMessageGenerator.enabled) {
console.log(` - 言語: ${subAgents.commitMessageGenerator.language}`);
console.log(` - スタイル: ${subAgents.commitMessageGenerator.style}`);
}
console.log(` 🔀 PR Management Agent: ${subAgents.prManagementAgent.enabled ? '✅' : '❌'}`);
if (subAgents.prManagementAgent.enabled) {
console.log(` - 自動マージ閾値: ${subAgents.prManagementAgent.autoMergeThreshold}`);
}
}
}
//# sourceMappingURL=interactive-config-manager.js.map