/**
 * Workflow discovery — finds workflow definitions from disk.
 *
 * Workflows are discovered from:
 *   1. src/sdk/workflows/builtin/<name>/<agent>/index.ts (SDK-shipped builtins)
 *   2. .atomic/workflows/<name>/<agent>/index.ts (project-local)
 *   3. ~/.atomic/workflows/<name>/<agent>/index.ts (global)
 *
 * All three sources use the same scanning function (`discoverFromBaseDir`)
 * so registration is uniform. Builtin names are reserved — project-local
 * and global workflows with the same name are dropped during merge.
 */
import type { AgentType, WorkflowInput } from "../types.ts";
export interface DiscoveredWorkflow {
    name: string;
    agent: AgentType;
    path: string;
    source: "local" | "global" | "builtin";
}
export declare const AGENTS: AgentType[];
/**
 * Default `.gitignore` content for a workflows directory.
 * Auto-generated during install; regenerated by discovery if missing.
 */
export declare const WORKFLOWS_GITIGNORE: string;
/**
 * Discover all available workflows from built-in, global, and local sources.
 * Optionally filter by agent.
 *
 * **Merge precedence:** `builtin > local > global`.
 *
 * Builtin names are **strictly reserved** — a user-defined local or
 * global workflow whose name matches any built-in workflow is dropped
 * entirely from discovery. It will not be registered, returned from
 * `findWorkflow`, appear in the interactive picker, or show up in
 * `atomic workflow -l`. This protects SDK-shipped workflows (e.g.
 * `ralph`) from being silently overridden or even visibly "competing
 * with" a user's own definition, which would otherwise be confusing
 * when someone tries to run the canonical version.
 *
 * Reservation is by **name only**, across all agents: if a builtin
 * defines `ralph` for any agent, a local `ralph` for any other agent is
 * also dropped. Local still overrides global for every non-builtin
 * name, so project-scoped customisation of user-scoped workflows
 * continues to work.
 *
 * By default, the result is **merged by precedence** — if a workflow is
 * defined in both local and global sources, only the higher-precedence
 * entry is returned. This is the right shape for `findWorkflow`, which
 * needs the single resolved entry per (name, agent) pair.
 *
 * Pass `{ merge: false }` to get the **unmerged** result — local and
 * global contribute their entries independently, so `--list` can show
 * both a local and a global copy of the same workflow when they coexist
 * on disk. (Builtin reservation still applies in both modes.)
 */
export declare function discoverWorkflows(projectRoot?: string, agentFilter?: AgentType, options?: {
    merge?: boolean;
}): Promise<DiscoveredWorkflow[]>;
/**
 * Find a specific workflow by name and agent.
 */
export declare function findWorkflow(name: string, agent: AgentType, projectRoot?: string): Promise<DiscoveredWorkflow | null>;
/**
 * Load status for a {@link WorkflowWithMetadata} entry.
 *
 * - `ok`            — the workflow compiled cleanly and is ready to run.
 * - `incompatible`  — the workflow declared a `minSDKVersion` newer
 *                     than the bundled CLI. The CLI renders it with an
 *                     "update required" badge so users see the mismatch
 *                     rather than a silent disappearance.
 * - `error`         — any other load failure (syntax error, missing
 *                     `.compile()`, invalid default export, etc.).
 *                     Rendered with a "failed to load" badge plus the
 *                     underlying message.
 */
export type WorkflowMetadataStatus = {
    kind: "ok";
} | {
    kind: "incompatible";
    requiredVersion: string;
    currentVersion: string;
    message: string;
} | {
    kind: "error";
    stage: "resolve" | "validate" | "load";
    message: string;
};
/**
 * A discovered workflow enriched with the metadata the picker needs to
 * render it: the human description, the declared input schema, and the
 * load status.
 *
 * Populated by {@link loadWorkflowsMetadata}, which runs each discovered
 * workflow through {@link WorkflowLoader.loadWorkflow} and extracts the
 * display-relevant fields — the full compiled definition is discarded
 * after extraction so re-imports during execution are cheap.
 *
 * Broken entries still materialise with empty `description` / `inputs`
 * and a non-`ok` {@link status}, so the picker can render them as
 * visible "update required" / "failed to load" rows instead of
 * silently omitting them (the previous behaviour, which made user and
 * global workflows vanish whenever the base SDK shape drifted between
 * releases).
 */
export interface WorkflowWithMetadata extends DiscoveredWorkflow {
    /** Workflow description, empty string when none was declared or the workflow failed to load. */
    description: string;
    /** Picker-ready input schema; empty for free-form or failed-to-load workflows. */
    inputs: readonly WorkflowInput[];
    /** Load outcome — non-`ok` entries are rendered as visible diagnostics in the picker/list. */
    status: WorkflowMetadataStatus;
}
/**
 * Load metadata (description + picker-ready inputs + status) for a batch
 * of discovered workflows.
 *
 * **Failed workflows are kept in the returned list**, not dropped. Each
 * broken entry carries a {@link WorkflowMetadataStatus} explaining the
 * failure so the picker and `atomic workflow -l` can surface it as an
 * actionable diagnostic. This is the only way end users discover that a
 * workflow from an older SDK release has gone incompatible after an
 * `atomic` upgrade — silent filtering would leave them with a missing
 * entry and no breadcrumb.
 *
 * Callers that want to execute a workflow should still route through
 * {@link WorkflowLoader.loadWorkflow} — this function throws away the
 * compiled definition so re-running the loader on a confirmed pick is
 * unavoidable.
 */
export declare function loadWorkflowsMetadata(discovered: DiscoveredWorkflow[]): Promise<WorkflowWithMetadata[]>;
//# sourceMappingURL=discovery.d.ts.map