source dump of claude code
at main 107 lines 3.3 kB view raw
1import type { AgentColorName } from '../../tools/AgentTool/agentColorManager.js' 2import { AGENT_COLORS } from '../../tools/AgentTool/agentColorManager.js' 3import { detectAndGetBackend } from './backends/registry.js' 4import type { PaneBackend } from './backends/types.js' 5 6// Track color assignments for teammates (persisted per session) 7const teammateColorAssignments = new Map<string, AgentColorName>() 8let colorIndex = 0 9 10/** 11 * Gets the appropriate backend for the current environment. 12 * detectAndGetBackend() caches internally — no need for a second cache here. 13 */ 14async function getBackend(): Promise<PaneBackend> { 15 return (await detectAndGetBackend()).backend 16} 17 18/** 19 * Assigns a unique color to a teammate from the available palette. 20 * Colors are assigned in round-robin order. 21 */ 22export function assignTeammateColor(teammateId: string): AgentColorName { 23 const existing = teammateColorAssignments.get(teammateId) 24 if (existing) { 25 return existing 26 } 27 28 const color = AGENT_COLORS[colorIndex % AGENT_COLORS.length]! 29 teammateColorAssignments.set(teammateId, color) 30 colorIndex++ 31 32 return color 33} 34 35/** 36 * Gets the assigned color for a teammate, if any. 37 */ 38export function getTeammateColor( 39 teammateId: string, 40): AgentColorName | undefined { 41 return teammateColorAssignments.get(teammateId) 42} 43 44/** 45 * Clears all teammate color assignments. 46 * Called during team cleanup to reset state for potential new teams. 47 */ 48export function clearTeammateColors(): void { 49 teammateColorAssignments.clear() 50 colorIndex = 0 51} 52 53/** 54 * Checks if we're currently running inside a tmux session. 55 * Uses the detection module directly for this check. 56 */ 57export async function isInsideTmux(): Promise<boolean> { 58 const { isInsideTmux: checkTmux } = await import('./backends/detection.js') 59 return checkTmux() 60} 61 62/** 63 * Creates a new teammate pane in the swarm view. 64 * Automatically selects the appropriate backend (tmux or iTerm2) based on environment. 65 * 66 * When running INSIDE tmux: 67 * - Uses TmuxBackend to split the current window 68 * - Leader stays on left (30%), teammates on right (70%) 69 * 70 * When running in iTerm2 (not in tmux) with it2 CLI: 71 * - Uses ITermBackend for native iTerm2 split panes 72 * 73 * When running OUTSIDE tmux/iTerm2: 74 * - Falls back to TmuxBackend with external claude-swarm session 75 */ 76export async function createTeammatePaneInSwarmView( 77 teammateName: string, 78 teammateColor: AgentColorName, 79): Promise<{ paneId: string; isFirstTeammate: boolean }> { 80 const backend = await getBackend() 81 return backend.createTeammatePaneInSwarmView(teammateName, teammateColor) 82} 83 84/** 85 * Enables pane border status for a window (shows pane titles). 86 * Delegates to the detected backend. 87 */ 88export async function enablePaneBorderStatus( 89 windowTarget?: string, 90 useSwarmSocket = false, 91): Promise<void> { 92 const backend = await getBackend() 93 return backend.enablePaneBorderStatus(windowTarget, useSwarmSocket) 94} 95 96/** 97 * Sends a command to a specific pane. 98 * Delegates to the detected backend. 99 */ 100export async function sendCommandToPane( 101 paneId: string, 102 command: string, 103 useSwarmSocket = false, 104): Promise<void> { 105 const backend = await getBackend() 106 return backend.sendCommandToPane(paneId, command, useSwarmSocket) 107}