claude-code-company
Version:
Multi-agent tmux coordination system for Claude Code with perfect Unicode support
143 lines (120 loc) • 4.13 kB
JavaScript
// Color constants with extended palette
const colors = {
// Basic colors
red: '\x1b[0;31m',
green: '\x1b[0;32m',
blue: '\x1b[0;34m',
purple: '\x1b[0;35m',
yellow: '\x1b[1;33m',
nc: '\x1b[0m',
// Bright colors
brightYellow: '\x1b[1;33m',
brightCyan: '\x1b[1;36m',
// Additional colors
cyan: '\x1b[0;36m',
orange: '\x1b[38;5;208m',
lime: '\x1b[38;5;154m',
// Special effects
bold: '\x1b[1m',
dim: '\x1b[2m'
};
// Rate limiting configuration with environment variable support
const rateLimitConfig = {
delayBetweenCalls: parseInt(process.env.CCC_DELAY_BETWEEN_CALLS) || 2000, // 2秒間隔
setupDelay: parseInt(process.env.CCC_SETUP_DELAY) || 3000, // セットアップ時の間隔
chainDelay: parseInt(process.env.CCC_CHAIN_DELAY) || 4000, // チェインコマンド時の間隔
maxRetries: parseInt(process.env.CCC_MAX_RETRIES) || 3, // 最大リトライ回数
tmuxTimeout: parseInt(process.env.CCC_TMUX_TIMEOUT) || 10000 // tmuxコマンドタイムアウト
};
// Agent configuration - dynamic boss and worker count support
function createAgentConfig(workerCount = 3, bossCount = 1) {
// 入力値の検証と正規化
const normalizedWorkerCount = parseInt(workerCount) || 3;
const normalizedBossCount = parseInt(bossCount) || 1;
if (!Number.isInteger(normalizedWorkerCount) || normalizedWorkerCount < 1 || normalizedWorkerCount > 15) {
console.warn(`${colors.yellow}⚠️ Invalid worker count: ${workerCount}. Using default: 3${colors.nc}`);
workerCount = 3;
} else {
workerCount = normalizedWorkerCount;
}
if (!Number.isInteger(normalizedBossCount) || normalizedBossCount < 1 || normalizedBossCount > 5) {
console.warn(`${colors.yellow}⚠️ Invalid boss count: ${bossCount}. Using default: 1${colors.nc}`);
bossCount = 1;
} else {
bossCount = normalizedBossCount;
}
const agents = ['president'];
const panes = [1];
try {
for (let i = 1; i <= bossCount; i++) {
agents.push(`boss${i}`);
panes.push(i + 1);
}
for (let i = 1; i <= workerCount; i++) {
agents.push(`worker${i}`);
panes.push(i + bossCount + 1);
}
// 最大ペイン数チェック(tmuxの制限考慮)
const totalPanes = agents.length;
if (totalPanes > 20) {
throw new Error(`Too many panes (${totalPanes}). Maximum recommended: 20`);
}
return { agents, panes, bossCount, workerCount };
} catch (error) {
console.error(`${colors.red}❌ Agent config creation failed: ${error.message}${colors.nc}`);
console.warn(`${colors.yellow}⚠️ Using minimal fallback configuration${colors.nc}`);
return {
agents: ['president', 'boss1', 'worker1'],
panes: [1, 2, 3],
bossCount: 1,
workerCount: 1
};
}
}
// Default configuration - 実際のtmuxペイン番号に合わせて修正
let { agents, panes } = createAgentConfig(3, 1);
// 実際のペイン番号を設定
agents = ['president', 'boss1', 'worker1', 'worker2', 'worker3'];
panes = [1, 2, 3, 4, 5]; // 実際のtmuxペイン番号(pane 0はUI用)
// Get safe configuration with fallbacks
function getSafeConfig() {
return { agents, panes };
}
// UIペインチェック関数
function isUIPane(paneNumber) {
return paneNumber === 0;
}
// Window毎の設定を管理
const windowConfigs = new Map();
// 現在のwindow設定を取得
function getWindowConfig(windowId) {
if (!windowConfigs.has(windowId)) {
// デフォルト設定を作成
windowConfigs.set(windowId, {
agents: [...agents],
panes: [...panes],
setupComplete: false
});
}
return windowConfigs.get(windowId);
}
// Window設定を更新
function setWindowConfig(windowId, config) {
windowConfigs.set(windowId, config);
}
// Window設定をクリア
function clearWindowConfig(windowId) {
windowConfigs.delete(windowId);
}
module.exports = {
colors,
rateLimitConfig,
createAgentConfig,
agents,
panes,
getSafeConfig,
isUIPane,
getWindowConfig,
setWindowConfig,
clearWindowConfig
};