import { type Task } from './taskStore';
export interface HeartbeatAction {
    name: string;
    run(projectDir: string): Promise<HeartbeatActionResult>;
}
export interface HeartbeatActionResult {
    ok: boolean;
    summary: string;
    details?: Record<string, unknown>;
}
export interface SelfLearningHeartbeatOptions {
    projectDir: string;
    /** Minutes between full heartbeat runs (default 15). */
    intervalMinutes?: number;
    /** Tick interval in ms (default 60_000). Tests override this. */
    tickMs?: number;
    /** Optional override of the default action set. */
    actions?: HeartbeatAction[];
    /** Returns true when the kill switch is engaged (skip everything). */
    isKillSwitchActive(): boolean;
    /** Returns true when the scheduler is enabled. */
    isEnabled(): boolean;
    /** Returns ms timestamp of the last full run. */
    getLastRunMs(): number;
    /** Persists the last full-run timestamp. */
    recordRunMs(timestamp: number): void;
}
export declare class SelfLearningHeartbeat {
    private opts;
    private timer;
    private running;
    private actions;
    constructor(opts: SelfLearningHeartbeatOptions);
    start(): void;
    stop(): void;
    /** Run one tick. Public for tests. */
    tick(now?: Date): Promise<{
        ranActions: boolean;
        reason?: string;
        results?: HeartbeatActionResult[];
    }>;
}
export declare function defaultHeartbeatActions(): HeartbeatAction[];
/** Runner that executes a task by delegating to the assigned agent. */
export type TaskAgentRunner = (input: {
    task: Task;
    agentId: string;
}) => Promise<string>;
/**
 * Factory: build a heartbeat action that picks up tasks whose assignee is a
 * known agent and runs them via the supplied runner. The runner returns a
 * summary string; the action records a check-in and marks the task done on
 * success or failed on throw. Designed so the server can wire it to
 * `runSubagent` without coupling this module to chat clients or tools.
 */
export interface WorkAssignedTasksOptions {
    /** Returns the set of agent ids the heartbeat is allowed to schedule. */
    knownAgentIds(): Promise<Set<string>>;
    runner: TaskAgentRunner;
    /** Maximum tasks to process per tick (default 3). */
    maxTasksPerTick?: number;
}
export declare function createWorkAssignedTasksAction(options: WorkAssignedTasksOptions): HeartbeatAction;
export interface IdentityGcActionOptions {
    /** Drop structured entries older than this many days. Defaults to 90. */
    maxAgeDays?: number;
}
/** Heartbeat action that runs identity garbage collection. */
export declare function createIdentityGcAction(options?: IdentityGcActionOptions): HeartbeatAction;
/**
 * Reflect on the most recent session: read the latest reflection from
 * `.harness/learning/reflections.jsonl` if present, summarize tool
 * success rate and high-signal insights, and surface them through the
 * heartbeat result so the Health tab / event store can show them.
 *
 * Deterministic and read-only: never invokes an LLM. The actual
 * reflection generation lives in `learning/engine.reflectOnSession()`
 * and is driven by the chat path; this action just snapshots whatever
 * was already produced.
 */
export declare function createReflectAndLearnAction(): HeartbeatAction;
export interface SkillEvolutionActionOptions {
    /** Stale-detector cutoff in days; defaults to 30. */
    staleAfterDays?: number;
    /** Max skills to flag per tick; defaults to 5. */
    maxFlagged?: number;
}
/**
 * Detect stale or unused skills in dry-run mode and surface them via the
 * heartbeat. Never archives in this action — archiving stays a curator
 * decision. Pure deterministic Phase 1 from `curator/curator.ts`.
 *
 * Additionally, when the curator's safety gate is enabled, we re-scan
 * every active skill against the safety rule library and surface any
 * blocking violations so they show up in heartbeat history before a
 * curator run silently skips them.
 */
export declare function createSkillEvolutionAction(options?: SkillEvolutionActionOptions): HeartbeatAction;
export interface CleanupAgentOutputsActionOptions {
    /** Files older than this age are removed. Defaults to 14 days. */
    maxAgeDays?: number;
    /** Override the directory name (relative to projectDir). Defaults to `agent-outputs`. */
    dirName?: string;
}
/**
 * Heartbeat action: prune scratch files the agent has written into
 * `agent-outputs/` past the configured age. The folder is the corral
 * for new bare-filename writes from `file_write` (see
 * `src/tools/pathResolution.ts`), so without this prune old reports
 * (e.g. a 2-day-old VW comparison) keep showing up in `grep` searches
 * and pollute later, unrelated tasks.
 *
 * Skips the corral root itself; only files (not subdirectories) are
 * removed so any deliberately curated subfolder under `agent-outputs/`
 * is preserved.
 */
export declare function createCleanupAgentOutputsAction(options?: CleanupAgentOutputsActionOptions): HeartbeatAction;
export interface HeartbeatRunRecord {
    timestamp: string;
    durationMs: number;
    actions: Array<{
        name: string;
        durationMs: number;
        ok: boolean;
        summary: string;
    }>;
}
export declare function writeHeartbeatHistory(projectDir: string, run: HeartbeatRunRecord): Promise<void>;
export declare function readHeartbeatHistory(projectDir: string, limit?: number): Promise<HeartbeatRunRecord[]>;
//# sourceMappingURL=selfLearningHeartbeat.d.ts.map