/**
 * Execution Storage
 *
 * Database operations for agent_work table.
 */
import Database from 'better-sqlite3';
import { AgentWork, ExecutionStatus, ExecutorType, ExecutionEnvironment, DisplayMode, PermissionMode } from './types.js';
export declare class ExecutionStorage {
    private db;
    constructor(db: Database.Database);
    /**
     * Create a new execution record.
     * Uses UUID-based IDs to guarantee uniqueness without race conditions.
     */
    createExecution(params: {
        ticketId: string;
        agentName: string;
        executor: ExecutorType;
        environment: ExecutionEnvironment;
        displayMode: DisplayMode;
        permissionMode: PermissionMode;
        branch?: string;
        pid?: string;
        containerId?: string;
        sessionId?: string;
        host?: string;
        logPath?: string;
        externalSource?: string;
        externalKey?: string;
        externalId?: string;
        externalUrl?: string;
    }): AgentWork;
    /**
     * Get execution by ID
     */
    getExecution(id: string): AgentWork | null;
    /**
     * Update execution status
     */
    updateStatus(id: string, status: ExecutionStatus, exitCode?: number, errorMessage?: string): void;
    /**
     * Update execution with process info
     */
    updateProcessInfo(id: string, info: {
        pid?: string;
        containerId?: string;
        sessionId?: string;
        host?: string;
        logPath?: string;
    }): void;
    /**
     * List executions with optional filters
     */
    listExecutions(filter?: {
        status?: ExecutionStatus;
        agentName?: string;
        ticketId?: string;
        limit?: number;
    }): AgentWork[];
    /**
     * Get running execution for a ticket (if any)
     */
    getRunningExecution(ticketId: string): AgentWork | null;
    /**
     * Get all running executions for an agent
     */
    getAgentRunningExecutions(agentName: string): AgentWork[];
    /**
     * Check if agent is available (not running anything)
     */
    isAgentAvailable(agentName: string): boolean;
    /**
     * Clean up stale executions where the tmux session no longer exists.
     * This fixes the bug where agents appear "busy" after sessions terminate unexpectedly.
     * Returns the number of stale executions cleaned up.
     */
    cleanupStaleExecutions(): number;
    /**
     * Find container sessions using prefix matching.
     * Handles cases where the stored containerId format differs from docker ps output.
     */
    private findContainerSessionsByPrefix;
    /**
     * Get list of host tmux session names
     */
    private getHostTmuxSessionNames;
    /**
     * Get map of containerId -> tmux session names
     */
    private getContainerTmuxSessionMap;
    /**
     * Get total execution count for an agent (historical)
     * Used by least-busy agent selection strategy.
     */
    getAgentExecutionCount(agentName: string): number;
    /**
     * Delete execution record
     */
    deleteExecution(id: string): void;
}
export type ContainerStatus = 'running' | 'exited' | 'paused' | 'unknown' | 'removed';
export interface Container {
    id: string;
    agentName: string;
    dockerId: string;
    dockerName: string | null;
    image: string | null;
    status: ContainerStatus;
    currentExecutionId: string | null;
    createdAt: Date;
    lastSeenAt: Date;
}
export declare class ContainerStorage {
    private db;
    constructor(db: Database.Database);
    /**
     * Ensure containers table exists (for existing databases)
     */
    private ensureTable;
    /**
     * Upsert a container record (create or update by docker_id)
     */
    upsertContainer(params: {
        agentName: string;
        dockerId: string;
        dockerName?: string;
        image?: string;
        status?: ContainerStatus;
        currentExecutionId?: string;
    }): Container;
    /**
     * Get container by ID
     */
    getContainer(id: string): Container | null;
    /**
     * Get container by Docker ID (full or short)
     */
    getContainerByDockerId(dockerId: string): Container | null;
    /**
     * Get container for an agent (most recent)
     */
    getContainerForAgent(agentName: string): Container | null;
    /**
     * List all containers
     */
    listContainers(filter?: {
        agentName?: string;
        status?: ContainerStatus;
        limit?: number;
    }): Container[];
    /**
     * Update container status
     */
    updateStatus(dockerId: string, status: ContainerStatus): void;
    /**
     * Update container's current execution
     */
    setCurrentExecution(dockerId: string, executionId: string | null): void;
    /**
     * Mark container as removed
     */
    markRemoved(dockerId: string): void;
    /**
     * Delete container record
     */
    deleteContainer(id: string): void;
    /**
     * Sync container status from Docker
     * Updates status for all known containers based on Docker state
     * Wrapped in a transaction for consistency
     */
    syncFromDocker(dockerContainers: Array<{
        id: string;
        name: string;
        image: string;
        status: string;
        agentName: string;
    }>): {
        added: number;
        updated: number;
        removed: number;
    };
}
