import type { PrivateBlobHandle, PrivateBlobMetadata } from "./types.js"; export type AttachmentRef = string; export declare const ATTACHMENT_REF_PREFIX = "attachment:v1:"; /** * Slides minted its own descriptor before the ref moved to core. The payload * layout is the same, so the resolver still opens refs already stored in chat * threads and decks. Nothing mints this prefix any more. */ export declare const LEGACY_SLIDES_UPLOAD_REF_PREFIX = "slides-upload:v1:"; /** * Upper bound any prompt, context block or persisted field must allow for a * ref. A ref is opaque and unrecoverable once cut: a 2,000-character cap on a * 2,653-character legacy ref turned every follow-up turn into "invalid * reference". Truncate other strings; never truncate a ref. */ export declare const ATTACHMENT_REF_MAX_CHARS = 4096; export interface AttachmentScope { ownerEmail: string; /** * `undefined` reads the active request's org; `null` is the personal scope. */ orgId?: string | null; } export interface AttachmentFile { data: Buffer; filename: string; mimeType?: string; size: number; } /** Who can make a `storageUnavailable` outcome go away. */ export type StorageFixer = "workspace_admin" | "operator" | "self_resolving"; export type StorageUnavailableReason = "not_configured" | "misconfigured" | "encryption_key_unavailable" | "provider_unavailable"; export type AttachmentFailure = { status: "notFound"; reason: "blob_missing" | "file_missing"; filename?: string; } | { status: "forbiddenScope"; reason: "owner_mismatch" | "org_mismatch" | "path_outside_uploads"; } | { status: "expired"; reason: "undecryptable" | "retention"; filename?: string; } | { status: "malformed"; reason: "empty" | "unrecognized_scheme" | "invalid_shape"; } | { status: "storageUnavailable"; reason: StorageUnavailableReason; whoCanFix: StorageFixer; filename?: string; }; export type AttachmentResolution = { status: "ok"; file: AttachmentFile; } | AttachmentFailure; export type StorageUnavailable = Extract; export type MintAttachmentResult = { status: "ok"; ref: AttachmentRef; handle: PrivateBlobHandle; } | StorageUnavailable; export type DeleteAttachmentResult = { status: "ok"; deleted: boolean; } | AttachmentFailure; /** Same derivation Slides used for `ownerKey`, so legacy refs keep verifying. */ export declare function attachmentOwnerKey(email: string): string; export declare function isAttachmentRef(value: unknown): value is AttachmentRef; /** Retryable means the same ref can succeed later; nothing else qualifies. */ export declare function isRetryableAttachmentFailure(failure: AttachmentFailure): failure is StorageUnavailable; export declare function isAttachmentEncryptionKeyAvailable(): boolean; export declare function mintAttachmentRef(input: { data: Uint8Array | Buffer; filename: string; mimeType: string; ownerEmail: string; /** `undefined` uses the active request's org; `null` mints a personal ref. */ orgId?: string | null; metadata?: PrivateBlobMetadata; }): Promise; export declare function resolveAttachment(ref: AttachmentRef, scope: AttachmentScope): Promise; export declare function deleteAttachment(ref: AttachmentRef, scope: AttachmentScope): Promise;