/**
 * TransferByNickname — the pure planner behind the headline "move this to
 * <nickname>" mid-conversation swap (Multi-Machine Session Pool §L4 "Topic
 * Placement Updates" + §L5). It turns a recognized NicknameCommand into a gated,
 * validated TransferPlan: resolve the nickname → machineId, enforce the rate limit,
 * the confirmation gate (offline target / mid-reply), and the already-there no-op.
 * Per "Structure > Willpower" a transfer is high-impact, so this is NOT free-text
 * inference — it operates on an ALREADY-recognized command + the registry state,
 * and an unknown/ambiguous nickname is REJECTED (listing valid nicknames), never
 * silently mis-routed.
 */
import type { NicknameCommand } from './NicknameCommand.js';
export interface TransferByNicknameState {
    /** Resolve a nickname → machineId (case-insensitive exact match), or null if unknown. */
    resolveNickname: (nickname: string) => string | null;
    /** The full set of valid nicknames (returned on an unknown-nickname rejection). */
    validNicknames: () => string[];
    isOnline: (machineId: string) => boolean;
    currentOwnerOf: (sessionKey: string) => string | null;
    /** Is the session mid-reply (a turn in flight)? Confirmation is required to interrupt it. */
    isMidReply: (sessionKey: string) => boolean;
    /**
     * The machine the topic is currently PINNED to (preferredMachine), or null if
     * unpinned. Optional for backward compatibility — when absent, only the
     * current-owner check can satisfy the already-there no-op.
     */
    currentPinOf?: (sessionKey: string) => string | null;
    /** When the topic last had a placement update (for the rate limit), or null. */
    lastPlacementUpdateAt: (sessionKey: string) => number | null;
    now: () => number;
    /** Minimum ms between placement updates per topic. Default 10000. */
    minUpdateIntervalMs?: number;
    /**
     * WS1.4 (MULTI-MACHINE-SEAMLESSNESS-SPEC): a LIVE autonomous run on this
     * topic on THIS machine, or null when none. Evaluated FIRST among the
     * consent gates (before offline/mid-reply) — moving a topic out from under
     * an in-flight autonomous run suspends real work, so it always requires
     * explicit confirmation. Optional for backward compatibility.
     */
    autonomousRunActive?: (sessionKey: string) => {
        goal: string | null;
        remainingMinutes: number | null;
    } | null;
}
export type TransferPlanAction = 'transfer' | 'noop' | 'confirm-required' | 'reject';
export interface TransferPlan {
    action: TransferPlanAction;
    sessionKey: string;
    /** Resolved target machine (present for transfer / confirm-required / noop). */
    targetMachine?: string;
    /** Set the topic's preferredMachine + pinned:true (a hard pin — §L4). */
    setPin?: boolean;
    /** Human-facing confirmation prompt (action === 'confirm-required'). */
    confirmationPrompt?: string;
    /** Rejection reason (action === 'reject'). */
    rejectReason?: 'unknown-machine-nickname' | 'rate-limited';
    /** On unknown-nickname: the valid nicknames to surface to the user. */
    validNicknames?: string[];
    detail?: string;
}
/**
 * Plan a transfer-by-nickname. Pure over (command, state). Both "move this to
 * <nick>" and "run this on <nick>" set a hard pin (pinned:true) per §L4; the only
 * intent difference is cosmetic. Confirmation is required when the target is offline,
 * or when it differs from the current owner AND the session is mid-reply (§L4 line 456).
 */
export declare function planTransferByNickname(command: NicknameCommand, state: TransferByNicknameState, sessionKey: string): TransferPlan;
//# sourceMappingURL=TransferByNickname.d.ts.map