import type { AttachSession } from './context.js'; export type TeardownReason = 'detach' | 'broker-gone' | 'signal' | 'node-done'; export type TeardownSession = Pick; export interface TeardownHooks { /** Stop everything this viewer runs locally — timers, the graph overlay, the * pane tag, the global key listener, the chat view's animations. Runs FIRST, * before the socket is told anything, so nothing can fire into a dead socket. */ stopLocal: () => void; /** The last socket-level error, so a broker-gone teardown can report the * precise reason (e.g. an oversized-frame overflow) instead of the generic * message. Read at teardown time, not captured at wiring time. */ lastSocketError: () => string | undefined; /** This viewer's tmux pane, as self-tagged at startup. Used only by the * node-done path to close our own pane. */ tagPane: () => string | undefined; } export interface AttachTeardown { /** Resolves when the session has ended — `runAttach` awaits this. */ readonly done: Promise; /** End the session. Idempotent: the first reason wins, later calls no-op. */ teardown: (reason: TeardownReason) => void; /** True once teardown has begun. Long-running loops must check this. */ isTornDown: () => boolean; /** Register SIGTERM/SIGHUP/SIGINT. Call only AFTER every collaborator * `stopLocal` touches exists, or a signal races a half-built session. * (Raw mode swallows ctrl+c as data, so SIGINT is unlikely — handled for * completeness.) */ installSignalHandlers: () => void; } export declare function createTeardown(s: TeardownSession, hooks: TeardownHooks): AttachTeardown;