/**
 * Identity Links
 *
 * OpenClaw-inspired cross-channel identity system.
 *
 * Collapses sessions from the same person across different channels
 * into one canonical identity. For example, if a user messages via
 * both Telegram and Discord, their sessions can be linked.
 *
 * Usage:
 * ```typescript
 * const identities = getIdentityLinker();
 *
 * // Link two channel identities
 * identities.link(
 *   { channelType: 'telegram', peerId: '12345' },
 *   { channelType: 'discord', peerId: 'user#6789' }
 * );
 *
 * // Resolve canonical identity
 * const canonical = identities.resolve({ channelType: 'telegram', peerId: '12345' });
 * // Returns the canonical identity that includes both telegram and discord
 * ```
 */
import { EventEmitter } from 'events';
import type { ChannelType } from './index.js';
/**
 * A channel-specific identity reference
 */
export interface ChannelIdentity {
    /** Channel type */
    channelType: ChannelType;
    /** Peer/user ID on that channel */
    peerId: string;
    /** Optional display name */
    displayName?: string;
    /** When this identity was first seen */
    firstSeen?: Date;
    /** When this identity was last seen */
    lastSeen?: Date;
}
/**
 * A canonical identity that may span multiple channels
 */
export interface CanonicalIdentity {
    /** Unique canonical identity ID */
    id: string;
    /** Display name for this identity */
    name: string;
    /** All linked channel identities */
    identities: ChannelIdentity[];
    /** When this canonical identity was created */
    createdAt: Date;
    /** Custom metadata */
    metadata?: Record<string, unknown>;
    /** Tags for categorization */
    tags?: string[];
}
/**
 * Identity linker configuration
 */
export interface IdentityLinkerConfig {
    /** Path to persist identity links */
    persistPath?: string;
    /** Auto-persist on changes */
    autoPersist: boolean;
    /** Maximum identities to track */
    maxIdentities: number;
}
export declare class IdentityLinker extends EventEmitter {
    private config;
    private canonicals;
    /** Maps "channelType:peerId" -> canonical ID */
    private lookupIndex;
    private idCounter;
    private dirty;
    constructor(config?: Partial<IdentityLinkerConfig>);
    /**
     * Resolve a channel identity to its canonical identity.
     * Returns null if no canonical identity exists for this peer.
     */
    resolve(identity: Pick<ChannelIdentity, 'channelType' | 'peerId'>): CanonicalIdentity | null;
    /**
     * Resolve or create a canonical identity for a channel identity.
     */
    resolveOrCreate(identity: ChannelIdentity): CanonicalIdentity;
    /**
     * Link two channel identities together.
     * If both already have canonical identities, they are merged.
     * If one has a canonical identity, the other is added to it.
     * If neither has one, a new canonical identity is created for both.
     */
    link(identity1: ChannelIdentity, identity2: ChannelIdentity, name?: string): CanonicalIdentity;
    /**
     * Unlink a channel identity from its canonical identity
     */
    unlink(identity: Pick<ChannelIdentity, 'channelType' | 'peerId'>): boolean;
    /**
     * Get all canonical identities
     */
    listAll(): CanonicalIdentity[];
    /**
     * Get canonical identity by ID
     */
    get(id: string): CanonicalIdentity | undefined;
    /**
     * Find identities by display name
     */
    findByName(name: string): CanonicalIdentity[];
    /**
     * Check if two channel identities are the same person
     */
    areSamePerson(identity1: Pick<ChannelIdentity, 'channelType' | 'peerId'>, identity2: Pick<ChannelIdentity, 'channelType' | 'peerId'>): boolean;
    /**
     * Get all channel identities for a peer (across channels)
     */
    getAllIdentitiesForPeer(identity: Pick<ChannelIdentity, 'channelType' | 'peerId'>): ChannelIdentity[];
    /**
     * Merge two canonical identities
     */
    private mergeCanonicals;
    /**
     * Add a channel identity to an existing canonical
     */
    private addToCanonical;
    /**
     * Make lookup key from channel type and peer ID
     */
    private makeKey;
    /**
     * Auto-persist if enabled
     */
    private autoPersist;
    /**
     * Persist identity links to disk
     */
    persist(): Promise<void>;
    /**
     * Load identity links from disk
     */
    load(): Promise<void>;
    getStats(): {
        totalCanonical: number;
        totalLinked: number;
        multiChannelCount: number;
        channelDistribution: Record<string, number>;
    };
    dispose(): void;
}
export declare function getIdentityLinker(config?: Partial<IdentityLinkerConfig>): IdentityLinker;
export declare function resetIdentityLinker(): void;
