export interface ExternalSource {
    /** Unique short identifier, e.g. "@vendor-x". User-supplied or derived from the URL. */
    name: string;
    /** Full git URL (https://, git@, …). */
    url: string;
    /** Branch / tag / commit-ish to track. Defaults to `main`. */
    ref: string;
    /** ISO timestamp when first registered. */
    addedAt: string;
}
export interface ExternalSourcesFile {
    /** Schema version — bump if shape changes. */
    schema: 1;
    sources: ExternalSource[];
}
/**
 * Per-type active source selection. Only types reachable from more than
 * one source need an entry — single-source types have no ambiguity.
 *
 * Shape: { active: { "<type>": "<source-name>" } }
 */
export interface ProvidersActiveFile {
    schema: 1;
    active: Record<string, string>;
}
export declare function externalRoot(): string;
export declare function sourcesFilePath(): string;
export declare function activeFilePath(): string;
export declare function loadExternalSources(): ExternalSourcesFile;
export declare function saveExternalSources(file: ExternalSourcesFile): void;
export declare function loadProvidersActive(): ProvidersActiveFile;
export declare function saveProvidersActive(file: ProvidersActiveFile): void;
/**
 * Derive a short identifier from a git URL when the user didn't supply one.
 *   https://github.com/vendor/extra-providers.git → "@vendor-extra-providers"
 *   git@github.com:vendor/extra-providers       → "@vendor-extra-providers"
 *
 * Idempotent; safe to call before validation since it produces a string
 * regardless of input shape.
 */
export declare function deriveSourceName(url: string): string;
/**
 * Return the per-source category/type tree currently on disk under
 * ~/.adhdev/external/<source>/. Used by the conflict detector and by
 * list_provider_sources.
 */
export interface SourceInventoryEntry {
    sourceName: string;
    /** Map: category → list of provider types. */
    providers: Record<string, string[]>;
}
export declare function inventoryExternalSources(): SourceInventoryEntry[];
/**
 * For a given category+type, list every source that currently exposes it.
 * Returns source names in disk-walk order; callers can use the first one
 * when no explicit active selection exists.
 */
export declare function sourcesProviding(category: string, type: string): string[];
/**
 * Resolve which source should be active for a given category+type.
 *   - If exactly one source provides it → that source.
 *   - If multiple sources provide it → the one named in providers-active.json
 *     (when present) or null (ambiguous; loader should warn and pick
 *     the first deterministically so daemon doesn't refuse to boot).
 *   - If none → null.
 */
export declare function resolveActiveSource(category: string, type: string, activeFile?: ProvidersActiveFile): {
    source: string | null;
    ambiguous: boolean;
    candidates: string[];
};
