import { type AutocompleteProvider, type PasteOptions, type SlashCommand } from "@oh-my-pi/pi-tui"; import type { InteractiveModeContext, SubmittedUserInput } from "../../modes/types.js"; import { isClipboardTerminalLocal, readImageFromClipboard, readMacFileUrlsFromClipboard, readTextFromClipboard } from "../../utils/clipboard.js"; /** * Slash commands that may carry secrets in their arguments should never be * persisted to history. * * - /login accepts three callback forms (redirect URL, query string, raw auth * code) — all can contain OAuth code=/state= params. * - /join carries a 32-byte room key and optional write token. * - /mcp add --token carries a bearer token. * * The command name is extracted the same way as parseSlashCommand() — splitting * on the earliest whitespace or colon — so /login:?code=... is correctly matched. */ export declare function shouldSkipHistory(slashText: string): boolean; export declare class InputController { #private; private ctx; /** Injectable clipboard reads so tests can drive paste flows without a real clipboard. */ private clipboard; constructor(ctx: InteractiveModeContext, /** Injectable clipboard reads so tests can drive paste flows without a real clipboard. */ clipboard?: { readImage: typeof readImageFromClipboard; readText: typeof readTextFromClipboard; readMacFileUrls?: typeof readMacFileUrlsFromClipboard; /** False when the readable clipboard is not the terminal's (SSH); omitted means local. */ isTerminalLocal?: typeof isClipboardTerminalLocal; }); /** Prewarm only the local worker selected by the current tiny role. */ prewarmTinyTitleModel(): void; /** Return the last full editor snapshot delivered by its change contract. */ getDraftText(): string; setupKeyHandlers(): void; /** * Forget the last hovered target without repainting. Disabling mouse * capture clears the composer's band, but with reporting off no motion * event will ever refresh this cache — so a re-enable plus motion over * the same card would look unchanged and skip restoring the band. */ clearHoverHighlight(): void; setupEditorSubmitHandler(): void; handleCtrlC(): void; handleCtrlD(): void; handleCtrlZ(): void; handleDequeue(): void; handleRetry(): Promise; /** * Queue `/queue` input behind an active turn, or start it immediately when idle. * `detached` is a submission whose draft already left the editor: its * attachments are queued and its text is restored if queueing fails. Without * it, the live editor draft is the submission. */ handleQueueCommand(text: string, detached?: Pick): Promise; /** Send editor text as a follow-up message (queued behind current stream). */ handleFollowUp(): Promise; restoreQueuedMessagesToEditor(options?: { abort?: boolean; currentText?: string; }): number; /** * Hand a queued `/compact` and the input waiting in the compaction queue (follow-ups held behind * the request, or input typed while a compaction runs) back to the editor: the conversation it was * queued for is no longer the one that will receive it. */ restoreCompactionQueueToEditor(status?: string): void; /** A queued `/compact` whose conversation is gone (switch, tree move) goes back to the editor. */ releaseStaleYieldCompaction(): void; /** * Resolves once every submission (Enter or the follow-up key) reached the session (prompt or * custom-message admission, or the pending-submission hand-off) or finished dispatching locally. */ waitForSubmissionDispatches(): Promise; handleImagePathPaste(path: string): Promise; handleImagePaste(): Promise; handleClipboardTextRawPaste(): Promise; /** * Editor `onLargePaste` hook: gate a marker-sized paste behind the large-paste menu. Returns * `true` to intercept (the editor skips its default `[Paste]` marker) once the paste reaches the * configured `paste.largeMenuThreshold` line count; otherwise `false` for default collapse-to-marker * behavior. The async menu is fired and forgotten — the editor only needs the synchronous verdict. * A paste whose input burst already carries the submit key skips the menu: nobody can answer it * before the submit lands, so the paste is staged the way cancelling the menu would. */ handleLargePaste(text: string, lineCount: number, options?: PasteOptions): boolean; /** * Present the large-paste menu and apply the chosen action: wrap in `` tags (collapsed * to a `[Paste]` marker that expands on submit), save the text to a file and reference its path so * the agent can `read` it on demand, or paste inline. Cancelling (Esc) falls back to the default * inline paste marker, so the pasted content is never lost. */ presentLargePasteMenu(text: string, lineCount: number): Promise; createAutocompleteProvider(commands: SlashCommand[], basePath: string): AutocompleteProvider; /** Copy the current editor line to the system clipboard. */ handleCopyCurrentLine(): void; /** Copy current prompt text to system clipboard. */ handleCopyPrompt(): void; cycleThinkingLevel(): void; cycleRoleModel(direction?: "forward" | "backward"): Promise; toggleToolOutputExpansion(): void; toggleToolActivityVisibility(): void; setToolsExpanded(expanded: boolean): void; toggleThinkingBlockVisibility(): void; openExternalEditor(): Promise; /** Alt+G: the `/local` picker. `openLocalFileInEditor` refuses collab guests itself. */ openLocalFilePicker(): Promise; registerExtensionShortcuts(): void; }