/** * Inline chip token grammar, shared by the editable input for chip rendering * and whole-token cursor deletion. Attachment shapes stay in sync with the * AttachmentStore placeholder regex in @wrongstack/core: * - seq-keyed `[pasted|image|file #N …]` (a cosmetic suffix after the seq, * e.g. `, 123 lines`, is tolerated; legacy `[file #N]` is included) * - path-keyed `[file:]` * `[VIBE]` is a protocol chip: it renders and deletes as a token, but it is * not an attachment and must stay in the prompt sent to the refiner/agent. */ /** Attachment placeholders only. Protocol tags must not be stripped as chips. */ export declare const ATTACHMENT_TOKEN_SRC = "\\[(?:pasted|image|file) #\\d+[^\\]]*\\]|\\[file:[^\\]]+\\]"; /** Protocol trigger rendered as a chip but kept in the prompt text. */ export declare const PROTOCOL_TOKEN_SRC = "\\[VIBE\\]"; export declare const INLINE_TOKEN_SRC = "\\[(?:pasted|image|file) #\\d+[^\\]]*\\]|\\[file:[^\\]]+\\]|\\[VIBE\\]"; /** * If a whole chip ends immediately before `cursor`, return the buffer and * cursor with that chip removed (so one backspace deletes the entire token, * anywhere in the line). Returns null when there's no chip there — the caller * falls back to a single-character delete. */ export declare function deleteTokenBackward(buffer: string, cursor: number): { buffer: string; cursor: number; } | null; /** * Length of a chip that starts exactly at `cursor`, or 0 if none — lets a * forward delete drop the whole token in one keystroke. */ export declare function tokenLengthForward(buffer: string, cursor: number): number; export declare function tokenSpanAt(buffer: string, cursor: number): { start: number; end: number; } | null; export interface ChipSpan { text: string; /** True for an attachment chip token, false for a plain run. */ chip: boolean; } /** Split a string into chip / plain spans for styled rendering. */ export declare function splitChips(text: string): ChipSpan[]; /** One rendered cell of the input row. Exactly one of chip/prompt/cursor may be true. */ export interface InputCell { ch: string; /** Inside an attachment chip token. */ chip: boolean; /** Part of the leading prompt (e.g. "› "). */ prompt: boolean; /** The single cursor cell (rendered inverse). */ cursor: boolean; } /** * Lay out `prompt + value` into wrapped rows of at most `width` columns, so the * input area can grow to exactly the number of visual lines its content needs. * Char-wrap (not word-wrap) keeps every cell index aligned with the buffer, so * the cursor lands on the right row/column. A cursor at end-of-buffer gets a * virtual trailing space cell (which may spill onto a fresh row, exactly like a * terminal). Newlines in `value` start a new row. */ export declare function layoutInputRows(prompt: string, value: string, cursor: number, width: number): InputCell[][]; /** * Inverse of {@link layoutInputRows}: given a pointer at visual * `(row, col)` (both 0-based; col is the column WITHIN the input area, i.e. the * prompt occupies the first columns of row 0), return the buffer cursor index * to place the caret. Mirrors layoutInputRows' wrapping exactly so the mapping * matches what's on screen. Clicking the prompt → start of buffer; clicking * past a row's last character → just after it; clicking below all rows → end of * buffer. Exported for the TUI input-click handler and unit tests. */ export declare function inputIndexAtRowCol(prompt: string, value: string, width: number, row: number, col: number): number; //# sourceMappingURL=input-tokens.d.ts.map