import type { Director } from '@wrongstack/core/coordination'; import type { Dispatch, MutableRefObject, SetStateAction } from 'react'; import type { Action } from './app-action-type.js'; import type { AppProps } from './app-props.js'; import type { State } from './app-state.js'; import { type KeyEvent } from './components/input.js'; import type { HistoryScrollController } from './components/scrollable-history.js'; import type { StatusBarClickMap } from './components/status-bar-types.js'; import { type StatuslineItem } from './components/statusline-picker.js'; import { type DOMElement } from './ink.js'; import { type PasteAccumState } from './paste-accumulator.js'; interface AppKeyHandlerOptions { state: State; dispatch: Dispatch; historyScrollRef: MutableRefObject; runInterruptLadder: () => void; enhanceCancelledRef: MutableRefObject; enhanceAbortRef: MutableRefObject; inputGateRef: MutableRefObject; lastEscAtRef: MutableRefObject; pasteAccumRef: MutableRefObject; pasteFlushTimerRef: MutableRefObject | null>; commitPaste: (full: string) => Promise; tryPickerKey: (input: string, key: KeyEvent, isEnter: boolean) => boolean; dismissedEscAtRef: MutableRefObject; streamingTextRef: MutableRefObject; confirmExitRef: MutableRefObject; activeCtrlRef: MutableRefObject; clearPendingConfirms: () => void; liveDirector: () => Director | null; openProjectPicker: () => Promise; loadLiveSessions: () => Promise; openStatuslinePicker: (field?: number) => void; statuslineHiddenItems: StatuslineItem[]; getSddRun: AppProps['getSddRun']; onSddLifecycle: AppProps['onSddLifecycle']; getSettings: AppProps['getSettings']; saveSettings: AppProps['saveSettings']; lastEnterAtRef: MutableRefObject; draftRef: MutableRefObject<{ buffer: string; cursor: number; }>; setDraft: (buffer: string, cursor: number) => void; submit: () => void; mouseMode: boolean; termRows: number; terminalColumns: number; terminalRows: number; /** Width of the main column (terminal width minus sidebar). When > 0, * scrollbar hit-tests use this instead of terminalColumns so the scrollbar * track is correctly positioned to the left of the sidebar. */ mainColumnWidth: number; /** * Whether a full-width overlay owns the screen. * * Passed in rather than derived. The old proxy — * `mainColumnWidth >= stdout.columns` — is true whenever the sidebar is * ZERO wide, and `computeSidebarWidth` returns 0 for any terminal under * `SIDEBAR_MIN_TERMINAL` (64 columns). So on a narrow terminal the flag was * permanently true with nothing open, and the whole `if (!overlayOpen)` * block below — wheel scrolling, scrollbar drag, drag-select, copy icons, * every status-bar chip click, PageUp/PageDown — silently stopped working, * along with Shift+Tab, `?` help, and (via `routeInputKey`) up/down input * history. `app.tsx` already hands the real value to `useMouseTracking`. */ overlayOpen: boolean; /** * Effective swarm-on-sidebar read: `panelPositions.fleet === 'sidebar'` * OR the legacy `showAgentSwarmPanel === 'sidebar'` flag from * `liveSettings`. The renderer at `app-view.tsx:897-899` reads * ONLY the legacy `showAgentSwarmPanel` field (not the panel- * position map) to decide whether to show the mission card; the * scroll-clamp reservation must match that source or a config-only * legacy 'sidebar' swarm mode (no recent picker open) will render * the mission card but the clamp will under-reserve, hiding the * bottom mission rows behind `RightSidebar`'s `overflowY="hidden"` * viewport. The OR with `panelPositions.fleet` is directionally * safe (over-reservation is harmless) and aligns with the field * that gates whether the swarm twin is mounted. See * {@link SidebarLayoutState.effectiveSwarmOnSidebar}. Threaded into * `sidebarScroll` dispatches so the reducer's mission-queue * reservation matches the actual render. */ effectiveSwarmOnSidebar: boolean; /** * Approximate row count for routed sidebar twin panels mounted above * `SidebarContent`. Subtracted from `viewportHeight` by the reducer's * scroll clamp so the user can't scroll past the end into blank space. * See {@link SidebarLayoutState.sidebarTwinRowCount}. */ sidebarTwinRowCount: number; statusBarWrapRef: MutableRefObject; belowStatusBarRef: MutableRefObject; /** Chip click map published by StatusBar on every render. */ statusBarClickMapRef: MutableRefObject; openModelPicker: () => Promise; nextStepsAutoSubmitTimerRef: MutableRefObject | undefined>; nextStepsAutoSubmitSuggestionRef: MutableRefObject; nextStepsAutoSubmitLabel: string | null; setNextStepsAutoSubmitCountdown: Dispatch>; setNextStepsAutoSubmitLabel: Dispatch>; cancelNextStepsCountdown: () => void; pasteClipboardText: () => Promise; pasteClipboardImage: () => Promise; slashRegistry: AppProps['slashRegistry']; agent: AppProps['agent']; /** * Called with the copied entry's id after a chat card's copy icon is clicked * and its content was successfully written to the clipboard. Lets the host * surface a transient "Copied" confirmation and flash that card's icon. Not * called when the click missed or the write failed. */ onHistoryCopy?: ((entryId: number) => void) | undefined; } /** Creates the terminal key host around focused overlay/input routers. */ export declare function createAppKeyHandler(options: AppKeyHandlerOptions): (input: string, key: KeyEvent) => Promise; export {}; //# sourceMappingURL=app-key-handler.d.ts.map