import type { AgentId, InstalledSubagent, SubagentFrontmatter } from './types.js';
/** A path an installed subagent occupies, tagged for removal/trash handling. */
export interface OccupiedEntry {
    path: string;
    kind: 'file' | 'dir';
}
/** Parsed metadata for one installed subagent (drives the rich listing). */
export interface SubagentMeta {
    frontmatter: SubagentFrontmatter;
    files: string[];
    /** Primary on-disk path for the listing's `path` field (a file or a dir, per layout). */
    path: string;
}
/**
 * The complete on-disk contract for one agent's subagents. Every operation is
 * expressed here so the engine below never branches on the agent id.
 */
export interface SubagentTarget {
    /** Absolute container dir under a home root (a version home or an agent home). */
    dir(home: string): string;
    /** Materialize central subagent `sub` into container `dir`. Throws on fs error. */
    write(dir: string, sub: {
        name: string;
        path: string;
    }): void;
    /** Installed subagent names in `dir` (detector + orphan diff). */
    names(dir: string): string[];
    /** On-disk paths subagent `name` occupies (for removal / soft-delete). */
    occupied(dir: string, name: string): OccupiedEntry[];
    /** Rich metadata for `name`; `null` skips it from the listing. */
    read(dir: string, name: string): SubagentMeta | null;
    /**
     * True when the installed subagent `sub` in `dir` byte-matches what `write`
     * would materialize from `sub.path` NOW — the content-drift check `agents
     * doctor` uses. Re-renders the CURRENT source through the same transform the
     * writer uses (never a stored hash), so a prompt-body edit to the source
     * surfaces as drift even though the filename is unchanged.
     */
    matches(dir: string, sub: {
        name: string;
        path: string;
    }): boolean;
}
/**
 * Copy every file in `src` into `dest` (created if missing), applying
 * `rename` (source filename -> target filename) on the way. Directories in
 * `src` are skipped -- subagents are flat file sets. Throws on fs error.
 */
export declare function copyDirWithRename(src: string, dest: string, rename?: Record<string, string>): void;
/**
 * Single source of truth for how each subagents-capable agent stores subagents.
 * The keys MUST match `capableAgents('subagents')` (the `subagents` flag in
 * `agents.ts`): the capability flag is the version gate, this table is the shape.
 */
export declare const SUBAGENT_TARGETS: Partial<Record<AgentId, SubagentTarget>>;
/** The registry entry for `agent`, or undefined if it stores no subagents. */
export declare function subagentTarget(agent: AgentId): SubagentTarget | undefined;
/**
 * Materialize central subagent `sub` into `home` for `agent`. Returns whether a
 * write happened (false when the agent has no registry entry). Throws only on
 * unexpected fs errors -- bulk callers wrap per-item.
 */
export declare function writeSubagentToHome(agent: AgentId, home: string, sub: {
    name: string;
    path: string;
}): boolean;
/** Installed subagent names for `agent` under `home` (detector + orphan diff). */
export declare function listInstalledSubagentNames(agent: AgentId, home: string): string[];
/**
 * True when subagent `name` installed for `agent` under `home` byte-matches what
 * the writer would produce NOW from `sourceDir` — the content-drift predicate
 * `agents doctor` uses. Returns false when the agent has no registry entry
 * (nothing could have been written) so an unexpected home copy reads as drift.
 */
export declare function subagentContentMatches(agent: AgentId, home: string, name: string, sourceDir: string): boolean;
/**
 * Rich listing of subagents installed for `agent` under `home`, with parsed
 * metadata. Enumerates names, then reads each -- entries whose metadata is
 * unreadable (per the target's reader) are dropped.
 */
export declare function listInstalledSubagentsRich(agent: AgentId, home: string): InstalledSubagent[];
/**
 * Remove subagent `name` for `agent` from `home` (hard delete). No-op success
 * when the agent has no registry entry or nothing is installed.
 */
export declare function removeSubagentFromHome(agent: AgentId, home: string, name: string): {
    success: boolean;
    error?: string;
};
/**
 * Soft-delete subagent `name` for `agent` from `home` into `trashDir`, stamping
 * each moved entry. Files land as `<basename>.<stamp>`, directories as
 * `<stamp>/`. No-op success when nothing is installed.
 */
export declare function trashSubagentFromHome(agent: AgentId, home: string, name: string, trashDir: string, stamp: string): {
    success: boolean;
    error?: string;
};
