export declare const TERMINAL_UPLOAD_MAX_FILES = 5;
export declare const TERMINAL_UPLOAD_MAX_BODY_BYTES: number;
/** Upload metadata returned only after bytes have been written inside the session upload directory. */
interface AcceptedUpload {
    originalName: string;
    savedName: string;
    savedAbsPath: string;
    savedRelPath: string;
    bytes: number;
}
/** Per-file rejection shown to the caller while other valid files in the same request may continue. */
interface RejectedUpload {
    originalName: string;
    reason: string;
}
/** Batch result that keeps accepted and rejected files separate for partial-success responses. */
interface UploadResult {
    accepted: AcceptedUpload[];
    rejected: RejectedUpload[];
}
/** Validated session upload directory plus the real target root used for containment checks. */
interface UploadDirectory {
    absPath: string;
    relPath: string;
    realRootPath: string;
}
/**
 * Strip directory components and unsafe characters from an upload filename.
 *
 * @param rawName Browser-provided filename, which may include fake path components.
 * @returns Safe basename plus an allowed extension, or an empty extension when unsupported.
 */
export declare function sanitizeUploadFilename(rawName: string): {
    base: string;
    ext: string;
};
/**
 * Detect image format by magic bytes because client MIME types and extensions are not trusted.
 *
 * @param bytes Decoded file bytes from the upload body.
 * @returns Canonical extension for supported image bytes, or null when the content is unsupported.
 */
export declare function detectImageExtension(bytes: Uint8Array): string | null;
/**
 * Compose the upload directory path for one terminal session.
 * Always under `<targetPath>/.goat-flow/logs/uploads/<sessionId>/` and asserted to remain inside
 * `targetPath` to prevent path traversal via the session id.
 *
 * @param targetPath Selected target project path that owns upload evidence.
 * @param sessionId Terminal session id used as the upload subdirectory.
 * @returns Absolute and relative upload paths plus the real target root.
 * @throws Error when the session id is not a simple path segment.
 */
export declare function uploadDirForSession(targetPath: string, sessionId: string): UploadDirectory;
/**
 * Validate one base64 image payload and decode it to bytes.
 *
 * @param rawName Browser-provided filename used for extension and saved-name hints.
 * @param base64 Base64 file body from the upload request.
 * @returns Decoded bytes with sanitized filename metadata, or a caller-safe rejection reason.
 */
export declare function decodeUploadFile(rawName: string, base64: string): {
    ok: true;
    bytes: Uint8Array;
    sanitized: {
        base: string;
        ext: string;
    };
} | {
    ok: false;
    reason: string;
};
/**
 * Persist accepted uploads to disk and return their saved metadata.
 * Caller is responsible for upstream session/path validation.
 *
 * @param uploadDir Validated session upload directory.
 * @param files Browser-provided file payloads from one upload request.
 * @param options Test seams for deterministic saved filenames.
 * @returns Accepted file metadata and per-file rejection reasons.
 * @throws Error when the created upload directory escapes the real target root.
 */
export declare function persistUploads(uploadDir: {
    absPath: string;
    relPath: string;
    realRootPath?: string;
}, files: Array<{
    name: string;
    data: string;
}>, options?: {
    now?: () => number;
}): UploadResult;
/**
 * Build the terminal-paste note that announces saved upload paths.
 * Callers paste this into the active PTY; it is plain text only.
 *
 * @param accepted Files that were saved for the active terminal session.
 * @returns Plain text note to paste into the PTY, or an empty string when nothing was accepted.
 */
export declare function buildAttachmentNote(accepted: AcceptedUpload[]): string;
export {};
//# sourceMappingURL=terminal-uploads.d.ts.map