import { Session, SessionManager as ISessionManager, SessionState, DevcontainerConfig } from '../types/index.js'; import { EventEmitter } from 'events'; import { Effect } from 'effect'; import { ProcessError, ConfigError } from '../types/errors.js'; export interface SessionCounts { idle: number; busy: number; waiting_input: number; pending_auto_approval: number; total: number; backgroundTasks: number; teamMembers: number; } export declare class SessionManager extends EventEmitter implements ISessionManager { sessions: Map; private waitingWithBottomBorder; private busyTimers; private autoApprovalDisabledWorktrees; private restoringSessions; private bufferedRestoreData; private restoreRefreshTimers; private restoreRefreshDeadlines; private spawn; private resolvePreset; detectTerminalState(session: Session): SessionState; detectBackgroundTask(session: Session): number; detectTeamMembers(session: Session): number; private getTerminalContent; private handleAutoApproval; private cancelAutoApprovalVerification; /** * Update session state with automatic status hook execution. * This method ensures that executeStatusHook is always called when state changes. * * @param session - The session to update * @param newState - The new state to set * @param additionalUpdates - Optional additional state data updates */ private updateSessionState; constructor(); private createTerminal; private shouldResetRestoreScrollback; private getRestoreSnapshot; private scheduleRestoreRefresh; private armRestoreRefreshTimer; private cancelRestoreRefresh; private fireRestoreRefresh; private createSessionInternal; /** * Create session with command preset using Effect-based error handling * * @param {string} worktreePath - Path to the worktree * @param {string} [presetId] - Optional preset ID, uses default if not provided * @returns {Effect.Effect} Effect that may fail with ProcessError (spawn failure) or ConfigError (invalid preset) * * @example * ```typescript * // Use Effect.match for type-safe error handling * const result = await Effect.runPromise( * Effect.match(effect, { * onFailure: (error) => ({ type: 'error', message: error.message }), * onSuccess: (session) => ({ type: 'success', data: session }) * }) * ); * ``` */ createSessionWithPresetEffect(worktreePath: string, presetId?: string, initialPrompt?: string): Effect.Effect; private setupDataHandler; /** * Sets up exit handler for the session process. * When the process exits with code 1 and it's the primary command, * it will attempt a single retry using the configured command with fallback args. * If fallbackArgs are not configured, it retries the configured command with no args. */ private setupExitHandler; private setupBackgroundHandler; private cleanupSession; getSessionById(id: string): Session | undefined; getSessionsForWorktree(worktreePath: string): Session[]; setSessionActive(sessionId: string, active: boolean): void; cancelAutoApproval(sessionId: string, reason?: string): void; toggleAutoApprovalForWorktree(worktreePath: string): boolean; isAutoApprovalDisabledForWorktree(worktreePath: string): boolean; destroySession(sessionId: string): void; /** * Terminate session and cleanup resources using Effect-based error handling * * @param {string} sessionId - Session identifier * @returns {Effect.Effect} Effect that may fail with ProcessError if session does not exist or cleanup fails * * @example * ```typescript * // Terminate session with error handling * const result = await Effect.runPromise( * Effect.match(effect, { * onFailure: (error) => ({ type: 'error', message: error.message }), * onSuccess: () => ({ type: 'success' }) * }) * ); * ``` */ terminateSessionEffect(sessionId: string): Effect.Effect; getAllSessions(): Session[]; /** * Create session with devcontainer integration using Effect-based error handling * @returns Effect that may fail with ProcessError (container/spawn failure) or ConfigError (invalid preset) */ createSessionWithDevcontainerEffect(worktreePath: string, devcontainerConfig: DevcontainerConfig, presetId?: string, initialPrompt?: string, onLog?: (line: string) => void): Effect.Effect; destroy(): void; static getSessionCounts(sessions: Session[]): SessionCounts; static formatSessionCounts(counts: SessionCounts): string; }