import type { Router } from "./router.js";
import { type SpawnJob, type JobEvent } from "./install-jobs.js";
import { type AgentInstallResult } from "../installer/multi-install.js";
import type { ParsedSkill } from "../installer/transformers/index.js";
type InstallScope = "project" | "user" | "global";
type MultiInstallScope = "project" | "user";
interface SkillJobMeta {
    skill: string;
    scope: InstallScope;
}
interface MultiInstallJob {
    id: string;
    done: boolean;
    subscribers: Set<(event: MultiInstallJobEvent, data: unknown) => void>;
    pastEvents: Array<{
        event: MultiInstallJobEvent;
        data: unknown;
    }>;
}
type MultiInstallJobEvent = JobEvent | "result";
declare function buildArgs(skill: string, scope: InstallScope): string[];
declare function normalizeInstallScope(scope: InstallScope): MultiInstallScope;
declare function isValidParsedSkill(s: unknown): s is ParsedSkill;
type FetchLike = typeof fetch;
interface ResolveSkillOptions {
    cwd?: string;
    home?: string;
    fetchImpl?: FetchLike;
    platformBaseUrl?: string;
    githubTokenProvider?: () => string | null;
}
declare function fetchSkillMdFromGitHub(opts: {
    repoUrl: string;
    skillPath: string;
    refs: string[];
    fetchImpl: FetchLike;
    token: string | null;
}): Promise<string | null>;
declare function resolveParsedSkillFromPlatform(identifier: string, opts?: ResolveSkillOptions): Promise<ParsedSkill | null>;
/**
 * Server-side fallback: when the frontend posts a multi-agent install
 * without `parsedSkill`, locate the skill on disk (project / personal /
 * plugin cache via {@link locateSkill}), read its SKILL.md, and build a
 * minimal {@link ParsedSkill}. Keeps the POST payload trivial — the
 * frontend doesn't need to fetch, parse, and re-marshal SKILL.md itself.
 *
 * Returns `null` when no on-disk skill matches the identifier (the route
 * surfaces this as a 404 so the caller can retry with an explicit
 * `parsedSkill`).
 */
export declare function resolveParsedSkillFromIdentifier(identifier: string, opts?: ResolveSkillOptions): Promise<ParsedSkill | null>;
declare function validateAgentIds(ids: unknown): {
    ok: true;
    ids: string[];
} | {
    ok: false;
    error: string;
};
declare function writeMultiInstallLockfile(opts: {
    identifier: string;
    skill: ParsedSkill;
    scope: "project" | "user";
    projectRoot: string;
    results: AgentInstallResult[];
}): void;
declare function runMultiInstallJob(opts: {
    identifier: string;
    skill: ParsedSkill;
    agentIds: string[];
    scope: "project" | "user";
    projectRoot: string;
}): Promise<MultiInstallJob>;
export declare function registerInstallSkillRoutes(router: Router, root?: string): void;
export declare const __test__: {
    JOBS: Map<string, SpawnJob<SkillJobMeta>>;
    MULTI_JOBS: Map<string, MultiInstallJob>;
    SAFE_NAME: RegExp;
    SAFE_AGENT_ID: RegExp;
    VALID_SCOPES: ReadonlySet<string>;
    INSTALL_TIMEOUT_MS: number;
    buildArgs: typeof buildArgs;
    normalizeInstallScope: typeof normalizeInstallScope;
    validateAgentIds: typeof validateAgentIds;
    isValidParsedSkill: typeof isValidParsedSkill;
    resolveParsedSkillFromIdentifier: typeof resolveParsedSkillFromIdentifier;
    resolveParsedSkillFromPlatform: typeof resolveParsedSkillFromPlatform;
    fetchSkillMdFromGitHub: typeof fetchSkillMdFromGitHub;
    runMultiInstallJob: typeof runMultiInstallJob;
    writeMultiInstallLockfile: typeof writeMultiInstallLockfile;
};
export {};
