Terminal session management with pooling, health monitoring, VSCode bridge, and multi-adapter support
The Terminal Manager provides terminal session management for agent execution in Claude Flow v2. It features a terminal pool for efficient resource management, multiple adapter support (native terminal and VSCode), session lifecycle management with health monitoring, command execution with timeout protection, and output streaming.
The main manager implementing ITerminalManager:
import { TerminalManager } from './terminal/manager';
const manager = new TerminalManager(
{
type: 'auto', // 'auto' | 'native' | 'vscode'
poolSize: 10, // Max terminals in pool
recycleAfter: 100, // Recycle terminal after N uses
commandTimeout: 30000, // 30-second command timeout
},
eventBus,
logger
);
await manager.initialize();
The manager auto-detects the environment for adapter selection:
| Adapter | When Selected |
|---|---|
vscode | TERM_PROGRAM === 'vscode' or VSCODE_PID exists |
native | All other environments |
auto | Auto-detects based on environment variables |
const terminalId = await manager.spawnTerminal({
id: 'agent-1',
type: 'worker',
metadata: {
workingDirectory: '/project',
initCommands: ['nvm use 20', 'export NODE_ENV=development'],
cleanupCommands: ['rm -f /tmp/agent-1-*'],
},
});
const output = await manager.executeCommand(terminalId, 'npm test');
// Executes with configured timeout
// Returns stdout output
// Throws TerminalCommandError on failure or timeout
await manager.terminateTerminal(terminalId);
// Runs cleanup commands
// Returns terminal to pool
// Removes session
const unsubscribe = await manager.streamOutput(terminalId, (output) => {
console.log('Terminal output:', output);
});
// Returns unsubscribe function to stop streaming
const health = await manager.getHealthStatus();
// {
// healthy: boolean,
// error?: string,
// metrics: {
// activeSessions: number,
// healthySessions: number,
// poolSize: number,
// availableTerminals: number,
// recycledTerminals: number,
// },
// }
await manager.performMaintenance();
// Cleans up dead sessions
// Performs pool maintenance
// Emits 'terminal:maintenance' event
const sessions = manager.getActiveSessions();
// Returns AgentSession[] with: id, agentId, terminalId, startTime, status, lastActivity
Each spawned terminal is wrapped in a TerminalSession:
class TerminalSession {
readonly id: string; // Unique session ID (session-*)
readonly startTime: Date;
readonly terminal: Terminal;
readonly profile: AgentProfile;
// Execute command with timeout protection
async executeCommand(command: string): Promise<string>;
// Check if session is healthy
isHealthy(): boolean;
// Get command history
getCommandHistory(): string[];
// Stream output
streamOutput(callback: (output: string) => void): () => void;
// Cleanup
async cleanup(): Promise<void>;
}
When a session initializes, it:
CLAUDE_FLOW_SESSION — Session IDCLAUDE_FLOW_AGENT — Agent IDCLAUDE_FLOW_AGENT_TYPE — Agent type[claude-flow]$ Sessions are considered unhealthy if:
Health check sends echo "HEALTH_CHECK_OK" with a 5-second timeout.
The TerminalPool manages terminal lifecycle and reuse:
class TerminalPool {
async initialize(): Promise<void>;
async acquire(): Promise<Terminal>; // Get terminal from pool
async release(terminal: Terminal): void; // Return terminal to pool
async shutdown(): Promise<void>;
async getHealthStatus(): Promise<PoolHealthStatus>;
async performMaintenance(): Promise<void>;
}
maxSizerecycleAfter usesThe VSCode bridge integrates with the VSCode extension API for terminal management:
import { initializeTerminalBridge } from './terminal/vscode-bridge';
// Initialize in VSCode extension context
initializeTerminalBridge(context);
terminal.sendText for command captureEventEmitter<string> for output streamingClaude-Flow Terminal {id}onDidCloseTerminalimport { createCapturedTerminal } from './terminal/vscode-bridge';
const { terminal, onData } = await createCapturedTerminal(
'Claude-Flow Terminal worker-1',
'/bin/bash',
['--login']
);
onData((data) => {
console.log('Output:', data);
});
import { executeTerminalCommand } from './terminal/vscode-bridge';
const output = await executeTerminalCommand(terminal, 'npm test', 30000);
// Uses completion markers for output boundary detection
// Times out after specified duration
interface ITerminalAdapter {
initialize(): Promise<void>;
shutdown(): Promise<void>;
createTerminal(): Promise<Terminal>;
destroyTerminal(terminal: Terminal): Promise<void>;
}
interface Terminal {
id: string;
isAlive(): boolean;
executeCommand(command: string): Promise<string>;
addOutputListener?(callback: (data: string) => void): void;
removeOutputListener?(callback: (data: string) => void): void;
}
Uses child processes for terminal management. Works in all environments.
Uses the VSCode extension API (vscode.window.createTerminal) with output capture hooks.
terminal:maintenance — Maintenance cycle completed (includes dead session count, pool status)