/**
 * SecretSync — cross-machine secret distribution (Multi-Machine Session Pool, Phase 4 /
 * `docs/specs/cross-machine-secret-sync-spec.md`, approved).
 *
 * A secret the user gives the agent on one machine should be usable by the same agent on
 * its other machines — without re-entry per machine, and without ever leaving the
 * encrypted vault in plaintext. The transport (mesh) is already TLS + Ed25519-signed +
 * recipient-bound + registered-peer-gated; the remaining requirement is APPLICATION-LAYER
 * confidentiality: each secret is encrypted to the recipient machine's X25519 key, so an
 * intermediary never reads it. That crypto already exists as `encryptForSync` /
 * `decryptFromSync` (forward-secret, ephemeral-key per payload) in SecretStore; this module
 * is the wiring over it.
 *
 * Two flows (judgment call per the spec's open questions, approved by Justin 2026-06-04):
 *   - PUSH-on-provision (primary): when a new secret arrives on machine A, A encrypts the
 *     secret set to each online registered peer's key and sends a `secret-share` command.
 *   - PULL-on-miss (fallback): a machine missing a `{secret:true}` value requests it.
 * v1 syncs ALL secret-marked fields; a rotation overwrites; a dedicated revoke verb is a
 * deliberate follow-up.
 *
 * Pure-ish + dependency-injected: the crypto, the peer list, the send transport, and the
 * store are all injected, so the logic is unit-tested with real keypairs (round-trip) and
 * no live mesh.
 */
import crypto from 'node:crypto';
import { type Secrets } from './SecretStore.js';
/** The `secret-share` mesh command payload (mirrors the MeshCommand variant). */
export interface SecretShareCommand {
    type: 'secret-share';
    /** JSON-serialized EncryptedSecretPayload (encrypted to the RECIPIENT's key). */
    encrypted: string;
}
export interface SecretSharePeer {
    machineId: string;
    /** Recipient machine's long-term X25519 public key (base64), from its MachineIdentity. */
    encryptionPublicKey: string;
}
/** Build the `secret-share` command for one recipient (encrypts the secret set to them). */
export declare function buildSecretShareCommand(secrets: Secrets, recipient: SecretSharePeer): SecretShareCommand;
/**
 * Flatten a (possibly nested) secrets map to its leaf dot-notation key-paths — NAMES ONLY,
 * never values. Used by the read-only `/secrets/sync-status` route so a caller can see WHICH
 * secrets a machine holds without the route ever touching a secret value. Mirrors the
 * dot-notation `set`/`get` the vault uses (e.g. `{ telegram: { token: 'x' } }` → `telegram.token`).
 */
export declare function secretKeyPaths(secrets: Secrets, prefix?: string): string[];
/**
 * The route-facing handle for secret-sync, plumbed through RouteContext. Exposes the
 * push-on-provision lever and read-only status WITHOUT ever exposing a secret value.
 */
export interface SecretSyncHandle {
    /** Whether secret-sync is enabled on this machine (receive path active). */
    enabled: boolean;
    /**
     * Whether OUTBOUND push is enabled. Defaults off: `enabled` alone is RECEIVE-ONLY so a
     * machine with a stale/divergent store can't clobber peers. Set on the authoritative machine.
     */
    pushEnabled: boolean;
    /** Push the current secret set to every online peer (no-op when pushEnabled is false). */
    provisionAll: () => Promise<{
        machineId: string;
        ok: boolean;
        reason?: string;
    }[]>;
    /** Leaf key-paths of secrets present in this machine's vault — NAMES only, never values. */
    localKeyPaths: () => string[];
    /** Vault readability — distinguishes a genuinely empty vault from a
     *  decrypt-failure (the 2026-06-05 masking: a key-bifurcated vault reported
     *  localKeyPaths: [] as if empty). 'decrypt-failed' carries the precise error. */
    vaultStatus?: () => {
        status: 'ok' | 'empty' | 'decrypt-failed';
        error?: string;
    };
    /** Online registered peers this machine would sync to (machineId + nickname). */
    syncTargets: () => {
        machineId: string;
        nickname?: string | null;
    }[];
}
/**
 * Provisioner (sender side). Encrypts the secret set PER-RECIPIENT and pushes it to each
 * online registered peer over the injected mesh transport. Returns a per-peer result; never
 * throws on a single peer's failure (best-effort fan-out).
 */
export declare class SecretProvisioner {
    private readonly deps;
    constructor(deps: {
        /** The set of secrets to sync (the user-entrusted `{secret:true}` fields). */
        secretsToSync: () => Secrets;
        /** Online, registered peers (excluding self) with their encryption public keys. */
        listPeers: () => SecretSharePeer[];
        /** Send a signed `secret-share` command to a peer over the mesh. */
        send: (machineId: string, command: SecretShareCommand) => Promise<{
            ok: boolean;
            reason?: string;
        }>;
        log?: (msg: string) => void;
    });
    /** Push the current secret set to every online peer. */
    provisionAll(): Promise<{
        machineId: string;
        ok: boolean;
        reason?: string;
    }[]>;
}
/**
 * Handler (receiver side). Decrypts an inbound `secret-share` with THIS machine's private
 * key and writes each secret into the local vault. The sender's authenticity + the
 * registered-peer gate are already enforced by the mesh acceptance layer BEFORE this runs;
 * confidentiality is enforced here (decryption fails for a payload not sealed to our key).
 */
export declare class SecretShareHandler {
    private readonly deps;
    constructor(deps: {
        /** This machine's X25519 private key (KeyObject) for decryption. */
        ownEncryptionPrivateKey: () => crypto.KeyObject;
        /** Persist a secret into the local encrypted vault. */
        store: {
            set: (keyPath: string, value: unknown) => void;
        };
        log?: (msg: string) => void;
    });
    /** Decrypt + store. Returns the keyPaths stored. Throws only on a malformed/foreign payload. */
    handle(command: SecretShareCommand, sender: string): {
        stored: string[];
    };
}
//# sourceMappingURL=SecretSync.d.ts.map