export type ProfileSwitchDecision = { allowed: true; backendChanged: boolean; } | { allowed: false; reason: 'cross-backend-live-session'; }; /** * Pure switch policy shared by every surface (Slack / Feishu / Web). * * - No history (fresh session) → any switch is allowed, including across backends. `backendChanged` * reports whether the backend moved (the caller may want it for messaging), but nothing is blocked. * - Has history (live conversation) → only a same-backend switch is allowed. A cross-backend switch * is rejected because the running conversation cannot be resumed on a different backend; the user * must start a new session to change backend. * * NOTE: `claudeBackend` (print vs tui) is deliberately NOT part of the identity — those share * `backend: 'claude'` and count as the same backend (product decision), so switching between a * print and a tui claude profile mid-conversation is allowed. */ export declare function decideProfileSwitch(opts: { currentBackend: string; targetBackend: string; hasHistory: boolean; }): ProfileSwitchDecision; export type SwitchProfileFailure = 'unknown-profile' | 'cross-backend-live-session'; export interface SwitchProfileResult { ok: boolean; /** The requested profile name (echoed back). */ name: string; /** The channel's effective backend before the switch (empty when the profile was unknown). */ currentBackend: string; /** The target profile's backend (empty when the profile was unknown). */ targetBackend: string; /** True when the switch moved to a different backend (only possible on a fresh session). */ backendChanged: boolean; /** Present only when `ok` is false. */ reason?: SwitchProfileFailure; } /** Does the channel's session already carry conversation history? A fresh (just-created) session has * a ledger entry with zero turns; a live conversation has ≥1 turn. */ export declare function channelHasHistory(channel: string): Promise; /** * Switch the active profile for a channel/session under the shared rule. Validates the profile, * applies {@link decideProfileSwitch}, and on success sets the channel's active profile AND syncs the * session-registry record's `profileName` (so `!resume` and the Web session list reflect it). Never * resets the session — a same-backend switch keeps the conversation, the model changes on the next * turn. Returns a structured result; the caller maps it to a reply / tRPC error. */ export declare function switchChannelProfile(opts: { channel: string; name: string; }): Promise;