import * as _$_earendil_works_pi_tui0 from "@earendil-works/pi-tui"; import { Component, EditorTheme, ImageDimensions, ImageTheme, TUI } from "@earendil-works/pi-tui"; import { CustomEditor, ExtensionAPI, KeybindingsManager } from "@earendil-works/pi-coding-agent"; //#region src/config.d.ts type SubmittedPreviewStyle = "raw" | "collapsible"; interface ImageCompressionConfig { /** Enable the image compression slash command. */ enabled?: boolean; /** Slash command name without the leading slash. */ command?: string; /** Model passed to pi for image summarization. Pass an empty string to use pi's default model. */ model?: string; /** Prompt used to summarize each image. */ prompt?: string; /** pi executable used for summarization subprocesses. */ piCommand?: string; /** Per-image summarization timeout in milliseconds. */ timeoutMs?: number; /** Add a visible, collapsible UI report after compression. */ includeReport?: boolean; } interface ResolvedImageCompressionConfig { enabled: boolean; command: string; model: string; prompt: string; piCommand: string; timeoutMs: number; includeReport: boolean; } interface PasterConfig { /** How submitted attachment previews render in chat history. */ submittedPreviewStyle?: SubmittedPreviewStyle; /** Append local image paths to the submitted prompt so the agent can manipulate the source files. */ includeImagePathsInPrompt?: boolean; /** Configure the /image-compress command. */ imageCompression?: ImageCompressionConfig; customEditor?: { /** Replace pi's input editor to enable inline image UX features. */enabled?: boolean; /** Show an image preview above the input while the cursor is inside an image placeholder. */ showImagePreview?: boolean; /** Treat image placeholders as atomic blocks for backspace/delete. */ deletePlaceholderAsBlock?: boolean; }; } interface ResolvedPasterConfig { submittedPreviewStyle: SubmittedPreviewStyle; includeImagePathsInPrompt: boolean; imageCompression: ResolvedImageCompressionConfig; customEditor: { enabled: boolean; showImagePreview: boolean; deletePlaceholderAsBlock: boolean; }; } declare const DEFAULT_PASTER_CONFIG: ResolvedPasterConfig; declare function resolvePasterConfig(config?: PasterConfig): ResolvedPasterConfig; //#endregion //#region src/types.d.ts declare const EXTENSION_NAME = "paster"; declare const MAX_IMAGE_BYTES: number; declare const ANTHROPIC_MAX_DIMENSION = 8000; declare const ANTHROPIC_MAX_IMAGE_BYTES: number; type SupportedImageMimeType = "image/png" | "image/jpeg" | "image/webp" | "image/gif"; interface ImageAttachment { id: number; placeholder: string; originalPath: string; mimeType: SupportedImageMimeType; data: string; dimensions?: ImageDimensions; createdAt: number; /** True once optimizeImageBytes has run on this attachment. */ optimized?: boolean; /** Original (pre-optimization) base64 size in bytes — informational. */ originalBytes?: number; /** Final (post-optimization) base64 size in bytes — informational. */ finalBytes?: number; /** Human-readable trail of optimization actions applied, if any. */ optimizeActions?: string[]; } interface LoadedImage { originalPath: string; mimeType: SupportedImageMimeType; data: string; dimensions?: ImageDimensions; } interface PasterImageContent { type: "image"; mimeType: string; data: string; } type LoadImageResult = { ok: true; image: LoadedImage; } | { ok: false; reason: "missing" | "not-file" | "too-large" | "unsupported" | "read-error"; path: string; }; interface PasterPreviewDetails { placeholders: string[]; } interface ImageCompressionReportItem { index: number; summary: string; } interface ImageCompressionReportDetails { imageCount: number; summaryCount: number; items: ImageCompressionReportItem[]; } //#endregion //#region src/clipboard.d.ts type ClipboardImageResult = { ok: true; image: LoadedImage; } | { ok: false; reason: "empty" | "unsupported-platform" | "too-large" | "unsupported" | "read-error"; }; declare function readClipboardImage(maxBytes?: number): ClipboardImageResult; //#endregion //#region src/compress.d.ts declare const DEFAULT_IMAGE_SUMMARY_PROMPT = "Summarize this image in 2-4 concise sentences. Include important visible text, UI elements, errors, diagrams, and details that may matter for future coding or design work."; declare function registerImageCompressionCommand(pi: ExtensionAPI, config: ResolvedImageCompressionConfig): void; //#endregion //#region src/optimize-image.d.ts interface OptimizeResult { data: string; mimeType: SupportedImageMimeType; originalBytes: number; finalBytes: number; originalDim?: { width: number; height: number; }; finalDim?: { width: number; height: number; }; actions: string[]; changed: boolean; } declare function optimizeImageBytes(input: Buffer, mime: SupportedImageMimeType): Promise; //#endregion //#region src/store.d.ts declare class AttachmentStore { private nextId; private readonly attachments; clear(): void; list(): ImageAttachment[]; add(input: Omit): ImageAttachment; get(placeholder: string): ImageAttachment | undefined; matchingPlaceholders(text: string): ImageAttachment[]; } //#endregion //#region src/editor.d.ts declare const PASTE_START = "\u001B[200~"; declare const PASTE_END = "\u001B[201~"; declare function segmentTextWithAtomicImages(text: string, store: AttachmentStore, validPasteIds?: Set, segmenter?: Intl.Segmenter): Intl.SegmentData[]; declare class PasterEditor extends CustomEditor { private readonly pasterKeybindings; private readonly pasterOptions; private pasterPasteBuffer; private activePreviewPlaceholder; constructor(tui: TUI, theme: EditorTheme, pasterKeybindings: KeybindingsManager, pasterOptions: { cwd: string; store: AttachmentStore; notify: (message: string) => void; deletePlaceholderAsBlock: boolean; setCursorPreview: (attachment: ImageAttachment | undefined) => void; pasteClipboardImage?: () => Promise | ImageAttachment | undefined; }); insertTextAtCursor(text: string): void; handleInput(data: string): void; clearCursorPreview(): void; private installAtomicImageSegmentation; private handlePasteClipboardImage; private handleBracketedPaste; private handleAtomicPlaceholderNavigation; private handleAtomicPlaceholderDelete; private setCursor; private deleteLineRange; private transform; private updateCursorPreview; } //#endregion //#region src/image-utils.d.ts interface PathToken { raw: string; value: string; start: number; end: number; bare: boolean; } declare function detectImageMimeType(bytes: Uint8Array): SupportedImageMimeType | undefined; declare function isWindowsDrivePath(value: string): boolean; declare function isWindowsUncPath(value: string): boolean; declare function isWindowsLikePath(value: string): boolean; declare function isWsl(): boolean; declare function windowsToWslPath(windowsPath: string): string; declare function resolveImagePath(input: string, cwd: string): string; declare function shellUnescape(input: string): string; declare function tokenizePathLikeText(text: string): PathToken[]; declare function dimensionsForImage(data: string, mimeType: SupportedImageMimeType): _$_earendil_works_pi_tui0.ImageDimensions | undefined; declare function loadImageFromPath(inputPath: string, cwd: string, maxBytes?: number): LoadImageResult; declare function replaceImagePathsInText(text: string, options: { cwd: string; store: AttachmentStore; loadImage?: (path: string, cwd: string) => LoadImageResult; onReject?: (result: Exclude) => void; }): { text: string; replaced: number; accepted: ImageAttachment[]; }; declare function imagesForText(store: AttachmentStore, text: string, existing?: PasterImageContent[]): PasterImageContent[]; declare function appendImagePathContext(text: string, attachments: ImageAttachment[]): string; /** * Async variant of imagesForText that runs each attachment through the * Anthropic-aware image optimizer (resize to 8000px cap, JPEG ladder to stay * under the 5 MB / 32 MB request caps). Optimization is cached on the * attachment so the cost is paid once per image, not per submit. * * Used by paster's `input` handler; safe to await on the hot path because * sharp is only invoked when the image is actually over the limits. */ declare function imagesForTextOptimized(store: AttachmentStore, text: string, existing?: PasterImageContent[]): Promise; declare function describeReject(result: Exclude, notify?: (message: string) => void): void; //#endregion //#region src/preview.d.ts type ImagePreviewMessageStyle = "raw" | "collapsible"; interface ImagePreviewMessageTheme extends ImageTheme { background?: (text: string) => string; title?: (text: string) => string; muted?: (text: string) => string; } declare class ImagePreviewMessage implements Component { private readonly attachments; private readonly theme; private readonly options; private readonly images; constructor(attachments: ImageAttachment[], theme: ImagePreviewMessageTheme, options?: { expanded?: boolean; style?: ImagePreviewMessageStyle; }); invalidate(): void; render(width: number): string[]; private renderRaw; private renderCollapsible; } interface CompressionReportTheme { background?: (text: string) => string; title: (text: string) => string; muted: (text: string) => string; } declare class ImageCompressionReportMessage implements Component { private readonly details; private readonly theme; private readonly expanded; constructor(details: ImageCompressionReportDetails, theme: CompressionReportTheme, expanded?: boolean); render(width: number): string[]; invalidate(): void; } interface CursorPreviewTheme { title: (text: string) => string; muted: (text: string) => string; accent: (text: string) => string; } declare class CursorImagePreviewWidget implements Component { private attachment; private readonly theme; private image; constructor(attachment: ImageAttachment, theme: CursorPreviewTheme); render(width: number): string[]; invalidate(): void; private headerLine; private createImage; private constrainedImageWidth; } //#endregion //#region src/terminal-input.d.ts type TerminalInputResult = { consume?: boolean; data?: string; } | undefined; declare function createImagePasteTerminalInputHandler(options: { cwd: string; store: AttachmentStore; notify?: (message: string) => void; onAccept?: (attachments: ImageAttachment[]) => void; loadImage?: (path: string, cwd: string) => LoadImageResult; }): (data: string) => TerminalInputResult; //#endregion //#region src/index.d.ts declare function createPaster(config?: PasterConfig): (pi: ExtensionAPI) => void; declare function paster(pi: ExtensionAPI, config?: PasterConfig): void; //#endregion export { ANTHROPIC_MAX_DIMENSION, ANTHROPIC_MAX_IMAGE_BYTES, AttachmentStore, ClipboardImageResult, CursorImagePreviewWidget, DEFAULT_IMAGE_SUMMARY_PROMPT, DEFAULT_PASTER_CONFIG, EXTENSION_NAME, ImageAttachment, ImageCompressionConfig, ImageCompressionReportDetails, ImageCompressionReportItem, ImageCompressionReportMessage, ImagePreviewMessage, ImagePreviewMessageStyle, LoadImageResult, LoadedImage, MAX_IMAGE_BYTES, OptimizeResult, PASTE_END, PASTE_START, PasterConfig, PasterEditor, PasterImageContent, PasterPreviewDetails, ResolvedImageCompressionConfig, ResolvedPasterConfig, SubmittedPreviewStyle, SupportedImageMimeType, TerminalInputResult, appendImagePathContext, createImagePasteTerminalInputHandler, createPaster, paster as default, describeReject, detectImageMimeType, dimensionsForImage, imagesForText, imagesForTextOptimized, isWindowsDrivePath, isWindowsLikePath, isWindowsUncPath, isWsl, loadImageFromPath, optimizeImageBytes, readClipboardImage, registerImageCompressionCommand, replaceImagePathsInText, resolveImagePath, resolvePasterConfig, segmentTextWithAtomicImages, shellUnescape, tokenizePathLikeText, windowsToWslPath };