import { QQProfile, QQBuddy, QQGroup, QQMe, QQStatus, QQScriptStep } from '../../data/qq/types'; import { ChatProvider, ModerationProvider } from '../../providers/types'; export interface QQMessage { id: string; buddyId: string; from: 'me' | 'buddy'; text: string; /** HH:MM:SS */ time: string; } export interface RuntimeBuddy extends QQBuddy { /** Currently active status (can be rewritten by online timers / host). */ currentStatus: QQStatus; } export interface QQState { started: boolean; me: QQMe | null; groups: QQGroup[]; buddies: RuntimeBuddy[]; threads: Record; unread: Record; typing: Record; openGroups: Record; /** Buddy currently in focus (determines whether new messages need notification). */ focusedChat: string | null; } /** Side-effect channel, injected by the main-panel window (depends on useTray / useApp / event bus). */ export interface QQDriver { /** Buddy comes online: knock sound + tray blink + "上线了" balloon. */ onBuddyOnline?: (buddy: RuntimeBuddy) => void; /** Incoming unread message: message sound + taskbar/tray blink. */ onIncoming?: (buddy: RuntimeBuddy, message: QQMessage) => void; /** Dispatch events to the engine event bus. */ emit?: (event: import('../../events').XPEvent) => void; /** Host-supplied chat provider (#148). */ chatProvider?: ChatProvider; /** Host-supplied moderation provider (#148). */ moderationProvider?: ModerationProvider; /** Read current scenario flags for context assembly (#148). */ getFlags?: () => Record; /** Check a filesystem node's existence/locked state for context assembly (#148). */ getFileSummary?: (path: string[]) => { exists: boolean; locked?: boolean; name: string; } | null; /** Read recent events from the ring buffer for context assembly (#148). */ getRecentEvents?: () => Array<{ type: string; [k: string]: unknown; }>; } export declare const qqStore: { subscribe(listener: () => void): () => void; getState(): QQState; /** Inject the side-effect channel from the main-panel window; returns a cleanup function. */ setDriver(next: QQDriver): () => void; buddy(buddyId: string): RuntimeBuddy | undefined; /** * Start a session with a profile (called after login success). Idempotent: ignored if already started. * Schedules buddy online events and their post-online proactive scripts according to onlineDelayMs. */ start(profile: QQProfile): void; /** Bring a buddy online; optional knock hint and proactive script. */ bringOnline(buddyId: string, opts?: { announce?: boolean; runScript?: boolean; }): void; /** Play a script sequence in order (wait -> typing -> message appears). */ playScript(buddyId: string, steps: QQScriptStep[]): void; setTyping(buddyId: string, value: boolean): void; /** * A buddy sends a message (incoming). Host scripts / timers / auto-replies triggered * by player replies all go through here. Counts as unread and triggers notification * side effects when the chat is not focused. */ receiveMessage(buddyId: string, text: string): QQMessage | null; /** Player sends a message (outgoing), and triggers the buddy's scripted reply (if configured). */ sendFromMe(buddyId: string, text: string): void; /** Request a reply from the ChatProvider; fall back to scripted lines on failure. */ handleProviderReply(buddyId: string, buddy: RuntimeBuddy): void; /** Play a fallback line when the provider is absent or fails. */ playProviderFallback(buddyId: string, fallbackLines?: string[]): void; /** Mark a chat as focused (clear unread count). */ setFocusedChat(buddyId: string | null): void; markRead(buddyId: string): void; toggleGroup(groupId: string): void; /** Change "my" online status (online / invisible / away / busy), driving the banner and tray menu checkmark. */ setMeStatus(status: QQStatus): void; /** Total unread count (criterion for tray blinking). */ totalUnread(): number; /** Full reset (logout / host reset). */ reset(): void; };