/** * InputEditor — multiline text input with cursor, selection, word ops, and paste. * * Supports attachments: images, pasted text blocks, and file references are * tracked as virtual tags in the text (e.g. `[Image 1]`, `[Pasted 42 lines]`, * `[File: foo.ts]`). The actual data is stored separately and collected on submit. */ export { imageMimeTypeForPath, isImagePath, looksLikeFilePath, quoteFilePathForInput, readClipboardImage, type ClipboardImage } from "./input-editor-files.js"; export interface ImageContent { type: "image"; data: string; mimeType: string; } /** An attachment tracked alongside the text input. */ export type Attachment = { kind: "image"; tag: string; image: ImageContent; } | { kind: "pasted-text"; tag: string; text: string; lineCount: number; } | { kind: "file"; tag: string; path: string; content?: string; image?: ImageContent; }; /** A range of selected text (anchor = where selection started). */ export interface Selection { anchor: number; active: number; } /** One visual line produced by the editor for rendering. */ export interface VisualLine { text: string; /** true when this line was soft-wrapped from a longer logical line. */ wrapped: boolean; /** Attachment tag spans within this visual line, for distinct styling. */ tagSpans: Array<{ start: number; end: number; }>; /** Inline autocomplete suggestion spans within this visual line. */ suggestionSpans?: Array<{ start: number; end: number; }>; } export interface InputEditorDraftState { text: string; cursor: number; attachments?: readonly Attachment[]; } /** Full render-ready snapshot of the editor state. */ export interface RenderedEditor { visualLines: VisualLine[]; cursorVisualRow: number; cursorScreenCol: number; scrollOffset: number; cursorVisible: boolean; } export declare class InputEditor { private _text; private _cursor; private _selection; private _bracketedPasteDepth; private _scrollOffset; private readonly _attachments; private _imageCounter; private _pasteCounter; private readonly _undoStack; private readonly _redoStack; private _historyMutationDepth; private _restoringHistory; private _contentVersion; get text(): string; get cursor(): number; get selection(): Selection | undefined; get hasSelection(): boolean; get attachments(): readonly Attachment[]; get hasAttachments(): boolean; get canUndo(): boolean; get canRedo(): boolean; get contentVersion(): number; get draftState(): InputEditorDraftState; /** Get only image attachments. */ get images(): ImageContent[]; /** Get the text to submit — virtual attachment tags are expanded or removed. */ get expandedText(): string; /** * Get the text to send to the SDK. * * Like opencode, image attachments keep their virtual marker in the text * while the actual image is sent separately. That keeps image-only prompts * non-empty without showing the marker in our rendered user message. */ get promptText(): string; setText(text: string, cursor?: number): void; setDraftState(state: InputEditorDraftState): void; /** Restore a tab-owned draft without carrying undo or paste state across tabs. */ restoreDraftState(state: InputEditorDraftState): void; clear(): void; undo(): boolean; redo(): boolean; /** Insert text at the cursor, replacing any active selection. */ insert(text: string): void; deleteBackward(): void; deleteForward(): void; deleteToLineStart(): void; deleteToLineStartOrPreviousLineEnd(): void; deleteWordBackward(): void; deleteWordForward(): void; /** * Attach an image. Inserts a virtual tag `[Image N]` at the cursor. */ attachImage(data: string, mimeType: string): void; /** * Attach pasted multi-line text. Inserts a virtual tag `[Pasted ~N lines]` * at the cursor if the text exceeds the threshold; otherwise inserts inline. */ attachPastedText(text: string): void; /** * Attach a file. For images, creates an image attachment; for text, * creates a file reference. Inserts `[File: name]` tag. */ attachFile(filePath: string, content: string | Uint8Array, mimeType: string): void; /** * Remove the attachment whose tag is at or near the cursor. * Returns true if an attachment was removed. */ removeAttachmentAtCursor(): boolean; moveLeft(): void; moveRight(): void; moveUp(): void; moveDown(): void; moveToLineStart(): void; moveToLineEnd(): void; moveToStart(): void; moveToEnd(): void; moveWordLeft(): void; moveWordRight(): void; setCursor(offset: number, options?: { preserveScroll?: boolean; }): void; moveLeftExtend(): void; moveRightExtend(): void; moveUpExtend(): void; moveDownExtend(): void; moveToLineStartExtend(): void; moveToLineEndExtend(): void; getSelectedText(): string | undefined; deleteSelection(): void; clearSelection(): void; selectAll(): void; beginBracketedPaste(): void; endBracketedPaste(): void; get isInBracketedPaste(): boolean; render(width: number, maxRows: number, firstPrefix: string, continuationPrefix: string, suggestionSuffix?: string): RenderedEditor; scrollByVisualLines(delta: number, width: number, maxRows: number, firstPrefix: string, continuationPrefix: string): boolean; setVisualScrollOffset(offset: number, width: number, maxRows: number, firstPrefix: string, continuationPrefix: string): boolean; /** Convert a rendered visual row and 1-based terminal column into a text cursor offset. */ offsetAtVisualPosition(visualRow: number, screenColumn: number, width: number, firstPrefix: string, continuationPrefix: string): number; private recordEdit; private captureHistorySnapshot; private restoreHistorySnapshot; private didContentChangeFrom; private sameAttachmentRefs; private isRecordableHistorySnapshot; private clearHistory; private clearScrollOffset; private trimHistory; private totalHistoryTextChars; private totalHistoryAttachmentRefs; private historyTextChars; private historyAttachmentRefs; private clampCursor; private extendSelection; private syncSelectionActive; private orderedSelection; private removeAttachmentForBackwardDelete; private removeAttachmentForForwardDelete; private removeAttachmentRange; private attachmentTagRanges; private expandRangeToAttachmentBoundaries; private logicalLines; private findLineStart; private findLineEnd; private findWordStart; private findWordEnd; private offsetToRowCol; private rowColToOffset; /** Get regex patterns for all attachment tags in the text. */ private getTagPatterns; /** Find tag spans within a text string (offsets relative to the text). */ private findTagSpans; private pushVisualLines; private computeCursorVisualRow; private computeCursorScreenCol; private cursorAtExactWrapBoundary; }