import type { AgentId, Meta } from './types.js';
import { type AccountAuthKind } from './account-provider-registry.js';
export interface CredentialAccount {
    id: string;
    name: string;
    provider: string;
    auth: AccountAuthKind;
    secretRef: string;
    baseUrl?: string;
}
export interface AccountRegistryDocument {
    version: 2;
    accounts: Record<string, CredentialAccount>;
}
export interface ResolvedCredentialAccount {
    id: string;
    name: string;
    provider: string;
    auth: AccountAuthKind;
    env: Record<string, string>;
}
export interface NativeAccount {
    id: string;
    name: string;
    kind: 'native';
    agent: AgentId;
    identityKey: string;
    identityLabel?: string;
    scope: 'version' | 'device';
}
export type UnifiedAccount = (CredentialAccount & {
    kind: 'provider';
}) | NativeAccount;
export declare function accountRegistryPath(base?: string): string;
export declare function readAccountRegistry(base?: string): AccountRegistryDocument;
export declare function findAccount(name: string, doc?: AccountRegistryDocument): CredentialAccount | null;
/**
 * Effective native accounts: the fleet-shared central store (version-scoped
 * identities) merged with THIS box's own device doc (device-scoped identities).
 * A native login is machine-local — its home follows its scope (PHNX-3315), so
 * a `scope:'device'` identity is read from this box's device doc and never the
 * shared central agents.yaml (which is where its email/identityKey PII used to
 * accumulate). On an id collision the device slice wins.
 */
export declare function listNativeAccounts(meta: Pick<Meta, 'accounts' | 'deviceAccounts'>): NativeAccount[];
/**
 * Resolve one account by name or id across both stores, native first.
 *
 * `doc` is optional and read LAZILY: a native match returns without ever reading
 * the provider bundle registry — so a native view/attach/run never triggers a
 * bundle read, legacy-`accounts.yaml` migration, or a keychain decrypt (which
 * would surface a Touch ID prompt or crash on an undecryptable legacy item). A
 * default-evaluated `doc = readAccountRegistry()` argument would defeat this by
 * running before the body, so callers that only need a native lookup must be
 * able to omit it.
 */
export declare function findUnifiedAccount(nameOrId: string, meta: Pick<Meta, 'accounts' | 'deviceAccounts'>, doc?: AccountRegistryDocument, preferAgent?: AgentId): UnifiedAccount | null;
export declare function addNativeAccount(name: string, agent: AgentId, identityKey: string, identityLabel: string | undefined, scope: 'version' | 'device'): NativeAccount;
/** Create or replace the version-independent label for one native identity. */
export declare function labelNativeAccount(agent: AgentId, identityKey: string, identityLabel: string | undefined, label: string | undefined, scope: 'version' | 'device'): NativeAccount;
export declare function bindAccount(nameOrId: string, target: string, preferAgent?: AgentId): UnifiedAccount;
export declare function unbindAccount(nameOrId: string, target: string, preferAgent?: AgentId): void;
/** Every target bound to `accountId`: this box's device-doc bindings merged over
 * the fleet-shared central bindings (PHNX-3315). */
export declare function accountBindings(accountId: string, meta: Pick<Meta, 'accounts' | 'deviceAccounts'>): string[];
export interface AccountSelection {
    id: string;
    source: 'explicit' | 'binding' | 'default';
}
/** Explicit selection wins over a configured per-harness default. */
export declare function resolveAccountSelection(explicit: string | undefined, agent: AgentId, meta: Pick<Meta, 'accounts' | 'deviceAccounts'>, opts?: {
    useDefault?: boolean;
    target?: string;
}): AccountSelection | undefined;
export interface AddAccountOptions {
    baseUrl?: string;
}
export declare function addAccount(name: string, provider: string, auth: AccountAuthKind, secret: string, base?: string, opts?: AddAccountOptions): CredentialAccount;
export declare function setAccountSecret(name: string, secret: string, base?: string): void;
export declare function renameAccount(oldName: string, newName: string, base?: string): void;
export declare function removeAccount(name: string, base?: string): void;
export declare function inspectAccount(name: string, base?: string): CredentialAccount & {
    secretPresent: boolean;
    policy: 'never';
};
export declare function resolveCredentialAccount(name: string, host: AgentId, expectedProvider?: string, base?: string): ResolvedCredentialAccount;
/** The account a spawn should launch under, classified for the exec path. */
export type SpawnAccount = {
    kind: 'provider';
    id: string;
    name: string;
    agent: AgentId;
    env: Record<string, string>;
} | {
    kind: 'native';
    id: string;
    name: string;
    agent: AgentId;
    identityKey: string;
    scope: 'version' | 'device';
};
/**
 * Resolve the account a run should launch under, following the binding order
 * (explicit → exact `agent@version` → device-scoped `agent` → per-harness
 * default) and classifying the result:
 *
 * - **provider** → the injected env is resolved here (fails closed when the
 *   credential is absent or the provider cannot authenticate the host).
 * - **native** → returns the identity the caller must confirm is live on the
 *   execution device; **no secret or env is produced**, because a native login
 *   is owned by the harness and read from its own home. The caller validates the
 *   live fingerprint against the installed version before spawn.
 *
 * A native account bound to a different harness than the one being launched
 * fails loudly (EXEC-ACCOUNT-4). Returns null when nothing is selected.
 */
export declare function resolveSpawnAccount(explicit: string | undefined, agent: AgentId, version: string | undefined, meta: Pick<Meta, 'accounts' | 'deviceAccounts'>, opts?: {
    useDefault?: boolean;
    provider?: string;
    base?: string;
    target?: string;
}): SpawnAccount | null;
