export type TaskState = "todo" | "in-progress" | "blocked" | "complete" | "skipped";
export interface PersistedTask {
    id: string;
    goalId: string;
    parentTaskId?: string;
    title: string;
    type: string;
    state: TaskState;
    assignedSessionId?: string;
    spec?: string;
    createdAt: number;
    updatedAt: number;
    completedAt?: number;
    dependsOn?: string[];
    baseSha?: string;
    headSha?: string;
    branch?: string;
    resultSummary?: string;
    /** Workflow gate ID this task should produce (0 or 1). */
    workflowGateId?: string;
    /** Workflow gate IDs whose accepted content to inject when prompting the agent. */
    inputGateIds?: string[];
    /** Per-repo git handoff (multi-repo). Falls back to flat baseSha/headSha/branch for single-repo. */
    gitHandoff?: Record<string, {
        baseSha?: string;
        headSha?: string;
        branch?: string;
    }>;
}
/**
 * Read a task's git handoff for a specific repo, falling back to legacy flat
 * fields for single-repo tasks. Returns an empty object when neither is set.
 *
 * Callers should always go through this helper rather than reading flat fields
 * directly so single- and multi-repo tasks behave uniformly.
 */
export declare function readHandoff(task: PersistedTask, repo: string): {
    baseSha?: string;
    headSha?: string;
    branch?: string;
};
/**
 * Simple JSON file store for tasks.
 * Tasks persist across server restarts.
 */
export declare class TaskStore {
    private readonly storeDir;
    private readonly storeFile;
    private tasks;
    constructor(stateDir: string);
    private load;
    private save;
    put(task: PersistedTask): void;
    get(id: string): PersistedTask | undefined;
    remove(id: string): void;
    removeMany(ids: string[]): void;
    getAll(): PersistedTask[];
    getByGoalId(goalId: string): PersistedTask[];
    getBySessionId(sessionId: string): PersistedTask[];
    getByParentTaskId(parentTaskId: string): PersistedTask[];
}
//# sourceMappingURL=task-store.d.ts.map