/**
 * In-memory notification queue for server→TUI push.
 * Replaces SQLite plugin_messages table.
 *
 * Also tracks whether a TUI client is actively connected (polling).
 * The server plugin cannot use `process.env.OPENCODE_CLIENT` to detect TUI
 * because the server runs in a separate process from the TUI client.
 */
export interface RpcNotification {
    id: number;
    type: string;
    payload: Record<string, unknown>;
    sessionId?: string;
}
/** Push a notification for TUI to pick up via polling. */
export declare function pushNotification(type: string, payload: Record<string, unknown>, sessionId?: string): void;
/** Return pending notifications after acking the client's last received id.
 *  Updates lastDrainAt so isTuiConnected() reflects recent activity.
 *
 *  Session scoping: when `sessionId` is provided, only notifications tagged for
 *  that session (or session-less/global ones) are returned and pruned — a
 *  notification tagged for a DIFFERENT session is never handed to this client
 *  and is never pruned by this client's ack. This matters because the in-memory
 *  queue is per-process but a TUI can end up draining a process that also serves
 *  OTHER sessions: e.g. opening OpenCode Desktop on the same project starts a
 *  newer RPC server that the TUI's port discovery (newest-pid-wins) then selects,
 *  so a Desktop-session upgrade-dialog action would otherwise surface in an
 *  unrelated TUI session. Each client also tracks its own `lastReceivedId`, so a
 *  global watermark prune would let session A's ack drop session B's still-unseen
 *  notification — scoping the prune to the acking session prevents that too.
 *
 *  Delivery is at-least-once (non-destructive return + prune-on-ack): a returned
 *  notification stays queued until a later call acks it via a higher
 *  `lastReceivedId`, so a lost poll response re-delivers on the next poll. */
export declare function drainNotifications(lastReceivedId?: number, sessionId?: string): RpcNotification[];
/** Whether a TUI client is actively polling for notifications.
 *  Returns true only if a TUI has drained within the last 3 seconds.
 *
 *  Pass `sessionId` (preferred) to ask whether a TUI is polling FOR THAT
 *  SESSION — this is what producers (`/ctx-status`, `/ctx-recomp`, the upgrade
 *  reminder) must use to decide dialog-vs-message, so a TUI on a different
 *  session in the same process does not misroute their delivery. Omit it only
 *  for legacy/global callers that genuinely have no session context; they fall
 *  back to "any session recently drained" (the pre-per-session behavior). */
export declare function isTuiConnected(sessionId?: string): boolean;
//# sourceMappingURL=rpc-notifications.d.ts.map