import { Buffer } from "buffer"; /** * Attachment object as returned by POST /api/v2/task/{task_id}/attachment. * ClickUp only renders an image inside a comment when the fragment carries this * whole object - a bare URL string renders as an empty placeholder tile. */ export interface ClickUpUploadedAttachment { id: string; name: string; title?: string; extension?: string; url: string; thumbnail_small?: string; thumbnail_medium?: string; thumbnail_large?: string; width?: number; height?: number; [key: string]: any; } /** Image bytes ready to be uploaded */ interface ResolvedBytes { kind: "bytes"; bytes: Buffer; mimeType: string; suggestedName: string; } /** Already an attachment on ClickUp's CDN - reuse it instead of uploading again */ interface ResolvedExisting { kind: "existing"; url: string; } export type ResolvedImageSource = ResolvedBytes | ResolvedExisting; /** * ClickUp serves attachments from *.clickup-attachments.com. Such a URL is * already uploaded, so it can be embedded directly. */ export declare function isClickUpAttachmentUrl(url: string): boolean; /** * Turn the `src` of a markdown image into something uploadable. * * Supported sources, in this order: * - a ClickUp attachment URL -> reused as-is, no upload * - a base64 data URI -> decoded * - any other http(s) URL -> downloaded * - anything else -> read from the local filesystem * * The local path case is the interesting one: this server runs next to the agent, * so a screenshot can be referenced by path instead of being inlined as base64, * which would otherwise cost a multiple of the file size in tokens. */ export declare function resolveImageSource(src: string, baseDir?: string): Promise; /** * Derive the upload filename from the markdown alt text. * * ClickUp shows the *attachment filename* underneath an image, not the fragment * text - so naming the upload after the caption is what makes a readable caption * appear in the ticket. */ export declare function captionToFilename(caption: string, fallbackName: string): string; /** * Upload a single image to a task and return the full attachment object. */ export declare function uploadTaskAttachment(taskId: string, filename: string, bytes: Buffer, mimeType: string): Promise; /** A markdown image whose source resolved to uploadable bytes or an existing attachment */ export interface ResolvedMarkdownImage { /** The original `src` as written in the markdown */ src: string; alt: string; resolved: ResolvedImageSource; } /** One markdown image reference that could not be used, and why */ export interface ImageFailure { src: string; error: string; } /** * Phase 1 of attaching images: resolve every source without writing anything. * * Reads local files, downloads http(s) URLs, decodes data URIs and validates * magic bytes and size. Failures are collected instead of thrown so the caller * can report every broken reference at once - and abort before anything is * posted to ClickUp. Identical sources are resolved once. */ export declare function resolveMarkdownImages(images: { src: string; alt: string; }[], baseDir?: string): Promise<{ resolved: ResolvedMarkdownImage[]; failures: ImageFailure[]; }>; /** A successfully uploaded (or reused) attachment for one markdown source */ export interface UploadedMarkdownImage { src: string; attachment: ClickUpUploadedAttachment; } /** * Phase 2: upload the resolved images to the task. * * Uploads run sequentially: a typical comment has a handful of screenshots, and * N uploads plus one write call stays well inside ClickUp's 100 calls/minute. * Stops at the first upload error - an API failure is unlikely to heal mid-batch, * and everything uploaded so far is returned so the caller can tell a retry to * reference those CDN URLs directly instead of uploading again. */ export declare function uploadResolvedImages(taskId: string, images: ResolvedMarkdownImage[]): Promise<{ uploaded: UploadedMarkdownImage[]; failure: ImageFailure | null; }>; /** Map from markdown `src` to the attachment that should be embedded for it. */ export declare function toAttachmentMap(uploaded: UploadedMarkdownImage[]): Map; export {}; //# sourceMappingURL=attachments.d.ts.map