/**
 * Recovery for LEGACY SYNCHRONIZABLE (iCloud Keychain) bundles.
 *
 * The pre-biometry helper era defaulted bundles to iCloud Keychain sync. The
 * device-local cutover (biometry ACL + kSecAttrSynchronizable false on every
 * query) orphaned those items: they still sync back via iCloud Keychain, but
 * neither `secrets list` nor `migrate-acl` can see them. This module powers
 * `agents secrets import --from icloud` — discover the orphaned bundles,
 * re-import them as normal device-local bundles, and optionally purge the
 * iCloud copies.
 *
 * The item-name scheme is the same one the modern store uses (see bundles.ts):
 * metadata under `agents-cli.bundles.<name>`, one value per key under
 * `agents-cli.secrets.<bundle>.<key>`. Legacy env keys never contained a dot,
 * so metadata-less synced secret services split at their LAST dot to recover
 * the bundle/key boundary even for dotted bundle names like `hetzner.com`.
 */
import { type SecretsBackend } from './bundles.js';
/** One orphaned iCloud bundle, as discovered from the synced item names. */
export interface SyncedBundleCandidate {
    /** Bundle name derived from the iCloud service names. */
    name: string;
    /** Env keys that have a per-key secret item in the iCloud keychain. */
    keys: string[];
    /** True when an `agents-cli.bundles.<name>` metadata item exists in iCloud. */
    hasMeta: boolean;
    /** Every iCloud service name belonging to this candidate (the purge set). */
    services: string[];
}
/**
 * Group raw synced service names into per-bundle candidates. Pure — separated
 * from discovery so the parsing rules are unit-testable without a keychain.
 *
 * A bundle can surface as metadata only (`agents-cli.bundles.<name>`), as
 * secret items only (`agents-cli.secrets.<bundle>.<KEY>` — metadata never
 * synced), or both; all three shapes appear in real iCloud strays, so every
 * one becomes a candidate.
 */
export declare function groupSyncedServices(services: string[]): SyncedBundleCandidate[];
/** Enumerate the iCloud keychain and return every orphaned bundle candidate. */
export declare function discoverSyncedBundles(): SyncedBundleCandidate[];
export interface ImportSyncedOptions {
    /** Overwrite keys that already exist in the local bundle. */
    force?: boolean;
    /** Store imported values as literals in the bundle metadata (no keychain items). */
    allPlaintext?: boolean;
    /** Backend for a newly created bundle (existing bundles keep theirs). */
    backend?: SecretsBackend;
    /** Delete the iCloud copies of successfully-read items after import. */
    purge?: boolean;
}
export interface ImportSyncedResult {
    name: string;
    added: number;
    skipped: number;
    /** Keys whose iCloud value could not be read (left in place, never purged). */
    missing: string[];
    /**
     * Keys the modern store refuses by policy (reserved env names like USER,
     * loader/interpreter vars like DYLD_*) — the pre-cutover store accepted
     * them. Left in iCloud, never purged: the iCloud item is the only copy.
     */
    unimportable: string[];
    purged: number;
}
/**
 * Import one discovered iCloud bundle into the local (device-local) store.
 *
 * Values come from the synced secret items; the synced metadata item, when
 * present, contributes the description, literal vars, and non-keychain refs
 * (env:/file:/exec: refs carry no stored secret, so copying the ref preserves
 * them exactly). Existing local keys are skipped unless `force`. Keys the
 * modern store refuses by policy (reserved / loader env names the pre-cutover
 * store accepted) are reported as `unimportable` instead of aborting the whole
 * bundle. With `purge`, only services whose value provably lives locally
 * (imported now, or skipped-because-present) are deleted from iCloud — an
 * unreadable or unimportable item is never destroyed.
 */
export declare function importSyncedBundle(candidate: SyncedBundleCandidate, opts?: ImportSyncedOptions): ImportSyncedResult;
