/**
 * S3-backed cache storage.
 *
 * Stores cached items in S3 with custom metadata headers for TTL tracking.
 * Uses AWS SDK v3 modular imports -- only loaded when S3 storage is configured.
 *
 * Metadata storage:
 *   x-amz-meta-created-at      -- ISO timestamp of creation
 *   x-amz-meta-last-accessed-at -- ISO timestamp of last access
 *
 * TTL is enforced lazily: expired items are deleted on access.
 * Pre-signed URLs are generated for getUrl() with 15-minute expiry.
 */
import type { CacheStorage } from './types.js';
export interface S3CacheStorageOptions {
    bucket: string;
    prefix: string;
    ttlMs: number;
    region?: string;
    /** Custom endpoint URL for S3-compatible services (e.g., SeaweedFS, LocalStack) */
    endpoint?: string;
    /**
     * Separate endpoint for pre-signed URLs (upload and download).
     * When set, pre-signed URLs use this endpoint instead of `endpoint`.
     * Useful when the orchestrator accesses S3 on localhost but agents
     * need a container-routable address (e.g., container DNS name).
     */
    externalEndpoint?: string;
    /**
     * Separate endpoint for the host-facing (CLI) pre-signed upload URL.
     * The CLI running `kici run remote` is on the developer's host, which may
     * reach the bucket at a different address than the orchestrator's own
     * `endpoint` (e.g. an orchestrator in a container uses the compose DNS name
     * while the host CLI uses localhost). When unset, `getInternalUploadUrl`
     * falls back to the internal `endpoint` client (current behavior).
     */
    uploadEndpoint?: string;
    /** Use path-style access instead of virtual-hosted-style (required for most S3-compatible services) */
    forcePathStyle?: boolean;
}
export declare class S3CacheStorage implements CacheStorage {
    private readonly client;
    /** Separate client for pre-signed URL generation (uses externalEndpoint if configured). */
    private readonly presignClient;
    /** Separate client for the host CLI's pre-signed upload URL (uses uploadEndpoint if configured). */
    private readonly uploadPresignClient;
    private readonly bucket;
    private readonly prefix;
    private readonly ttlMs;
    constructor(options: S3CacheStorageOptions);
    /** Build the full S3 object key from a cache key. */
    private objectKey;
    /** Check if metadata indicates an expired item, honoring a per-op TTL override. */
    private isExpired;
    /**
     * Read metadata from an S3 object's custom headers.
     * Returns null if the object doesn't exist (NoSuchKey/NotFound).
     */
    private readMeta;
    /**
     * Update metadata on an S3 object by copying it to itself.
     * This is the standard S3 pattern for updating metadata without re-uploading data.
     */
    private updateMeta;
    /** Check if an error is a "not found" error (NoSuchKey, NotFound, 404). */
    private isNotFoundError;
    put(key: string, data: Buffer | string): Promise<void>;
    get(key: string, ttlMsOverride?: number): Promise<Buffer | null>;
    has(key: string, ttlMsOverride?: number): Promise<boolean>;
    delete(key: string): Promise<boolean>;
    touch(key: string): Promise<void>;
    getUrl(key: string, ttlMsOverride?: number): Promise<string | null>;
    getUploadUrl(key: string): Promise<string>;
    getInternalUploadUrl(key: string): Promise<string>;
    initMeta(key: string): Promise<void>;
    list(subPrefix: string): Promise<string[]>;
    copy(srcKey: string, destKey: string): Promise<void>;
    /** Delete an S3 object. Idempotent (doesn't error if missing). */
    private deleteObject;
}
//# sourceMappingURL=s3.d.ts.map