import type { IPty } from '../services/bunTerminal.js'; import type pkg from '@xterm/headless'; import type { SerializeAddon } from '@xterm/addon-serialize'; import { GitStatus } from '../utils/gitStatus.js'; import { Mutex, SessionStateData } from '../utils/mutex.js'; import type { StateDetector } from '../services/stateDetector/types.js'; export type Terminal = InstanceType; export type SessionState = 'idle' | 'busy' | 'waiting_input' | 'pending_auto_approval'; export type StateDetectionStrategy = 'claude' | 'gemini' | 'codex' | 'cursor' | 'github-copilot' | 'cline' | 'opencode' | 'kimi'; export interface Worktree { path: string; branch?: string; isMainWorktree: boolean; hasSession: boolean; gitStatus?: GitStatus; gitStatusError?: string; lastCommitDate?: Date; } export interface Session { id: string; worktreePath: string; sessionNumber: number; sessionName?: string; command: string; fallbackArgs?: string[]; lastAccessedAt: number; process: IPty; output: string[]; lastActivity: Date; isActive: boolean; terminal: Terminal; serializer: SerializeAddon; restoreScrollbackBaseLine: number; stateCheckInterval: NodeJS.Timeout | undefined; isPrimaryCommand: boolean; presetName: string | undefined; detectionStrategy: StateDetectionStrategy | undefined; devcontainerConfig: DevcontainerConfig | undefined; /** * Mutex-protected session state data. * Access via stateMutex.runExclusive() or stateMutex.update() to ensure thread-safe operations. * Contains: state, autoApprovalFailed, autoApprovalReason, autoApprovalAbortController, backgroundTaskCount, teamMemberCount */ stateMutex: Mutex; /** * State detector instance for this session. * Created once during session initialization based on detectionStrategy. */ stateDetector: StateDetector; } export interface AutoApprovalResponse { needsPermission: boolean; reason?: string; } export type MenuAction = { type: 'selectWorktree'; worktree: Worktree; session?: Session; } | { type: 'newWorktree'; } | { type: 'newSession'; worktreePath: string; } | { type: 'renameSession'; session: Session; } | { type: 'killSession'; sessionId: string; } | { type: 'sessionActions'; session: Session; worktreePath: string; } | { type: 'deleteWorktree'; } | { type: 'mergeWorktree'; } | { type: 'configuration'; scope: ConfigScope; } | { type: 'exit'; }; export interface SessionManager { sessions: Map; getSessionById(id: string): Session | undefined; getSessionsForWorktree(worktreePath: string): Session[]; destroySession(sessionId: string): void; getAllSessions(): Session[]; cancelAutoApproval(sessionId: string, reason?: string): void; } export interface ShortcutKey { ctrl?: boolean; alt?: boolean; shift?: boolean; key: string; } export interface ShortcutConfig { returnToMenu: ShortcutKey; cancel: ShortcutKey; } export declare const DEFAULT_SHORTCUTS: ShortcutConfig; export interface StatusHook { command: string; enabled: boolean; } export interface StatusHookConfig { idle?: StatusHook; busy?: StatusHook; waiting_input?: StatusHook; pending_auto_approval?: StatusHook; } export interface WorktreeHook { command: string; enabled: boolean; } export interface WorktreeHookConfig { pre_creation?: WorktreeHook; post_creation?: WorktreeHook; } export interface WorktreeConfig { autoDirectory: boolean; autoDirectoryPattern?: string; copySessionData?: boolean; sortByLastSession?: boolean; autoUseDefaultBranch?: boolean; includeRemoteBranches?: boolean; } export interface MergeConfig { mergeArgs?: string[]; rebaseArgs?: string[]; } export interface CommandPreset { id: string; name: string; command: string; args?: string[]; fallbackArgs?: string[]; detectionStrategy?: StateDetectionStrategy; } export interface CommandPresetsConfig { presets: CommandPreset[]; defaultPresetId: string; selectPresetOnStart?: boolean; } export interface DevcontainerConfig { upCommand: string; execCommand: string; } export interface ConfigurationData { shortcuts?: ShortcutConfig; statusHooks?: StatusHookConfig; worktreeHooks?: WorktreeHookConfig; worktree?: WorktreeConfig; commandPresets?: CommandPresetsConfig; mergeConfig?: MergeConfig; autoApproval?: { enabled: boolean; customCommand?: string; timeout?: number; }; } export type ConfigScope = 'project' | 'global'; export interface AutoApprovalConfig { enabled: boolean; customCommand?: string; timeout?: number; } export interface ProjectConfigurationData { shortcuts?: ShortcutConfig; statusHooks?: StatusHookConfig; worktreeHooks?: WorktreeHookConfig; worktree?: WorktreeConfig; commandPresets?: CommandPresetsConfig; mergeConfig?: MergeConfig; autoApproval?: AutoApprovalConfig; } /** * Common interface for configuration readers. * Provides read-only access to configuration values. * Implemented by ConfigReader, ConfigEditor, GlobalConfigManager, ProjectConfigManager. */ export interface IConfigReader { getShortcuts(): ShortcutConfig | undefined; getStatusHooks(): StatusHookConfig | undefined; getWorktreeHooks(): WorktreeHookConfig | undefined; getWorktreeConfig(): WorktreeConfig | undefined; getCommandPresets(): CommandPresetsConfig | undefined; getMergeConfig(): MergeConfig | undefined; getAutoApprovalConfig(): AutoApprovalConfig | undefined; reload(): void; } /** * Common interface for configuration editors. * Extends IConfigReader with write capabilities. * Implemented by ConfigEditor, GlobalConfigManager, ProjectConfigManager. */ export interface IConfigEditor extends IConfigReader { setShortcuts(value: ShortcutConfig): void; setStatusHooks(value: StatusHookConfig): void; setWorktreeHooks(value: WorktreeHookConfig): void; setWorktreeConfig(value: WorktreeConfig): void; setCommandPresets(value: CommandPresetsConfig): void; setMergeConfig(value: MergeConfig): void; setAutoApprovalConfig(value: AutoApprovalConfig): void; } export interface GitProject { name: string; path: string; relativePath: string; isValid: boolean; error?: string; } export interface MultiProjectConfig { enabled: boolean; projectsDir: string; rootMarker?: string; } export type MenuMode = 'normal' | 'multi-project'; export interface IMultiProjectService { discoverProjects(projectsDir: string): Promise; validateGitRepository(path: string): Promise; } export interface RecentProject { path: string; name: string; lastAccessed: number; } export interface IProjectManager { currentMode: MenuMode; currentProject?: GitProject; projects: GitProject[]; setMode(mode: MenuMode): void; selectProject(project: GitProject): void; getWorktreeService(projectPath?: string): IWorktreeService; getRecentProjects(limit?: number): RecentProject[]; addRecentProject(project: GitProject): void; clearRecentProjects(): void; validateGitRepository(path: string): Promise; } export interface RemoteBranchMatch { remote: string; branch: string; fullRef: string; } export declare class AmbiguousBranchError extends Error { branchName: string; matches: RemoteBranchMatch[]; constructor(branchName: string, matches: RemoteBranchMatch[]); } export interface IWorktreeService { getWorktreesEffect(): import('effect').Effect.Effect; getGitRootPath(): string; createWorktreeEffect(worktreePath: string, branch: string, baseBranch: string, copySessionData?: boolean, copyClaudeDirectory?: boolean): import('effect').Effect.Effect; deleteWorktreeEffect(worktreePath: string, options?: { deleteBranch?: boolean; }): import('effect').Effect.Effect; mergeWorktreeEffect(sourceBranch: string, targetBranch: string, operation?: 'merge' | 'rebase', mergeConfig?: MergeConfig): import('effect').Effect.Effect; }