/**
 * artifacts/gcsArtifacts — the claim-check store in a Cloud Storage bucket.
 *
 * The same five verbs, the same laws, a different vendor's client. Read
 * `objectStore.ts` first for the laws both object adapters obey; read
 * `s3Artifacts.ts` beside this one to see what is genuinely per-vendor rather
 * than per-implementation. Three things really are different here, and each
 * one changes what an operator pays:
 *
 *   1. **A listing carries the metadata.** `bucket.getFiles()` hands back File
 *      objects with their metadata already populated — creation time, size AND
 *      the custom entry holding the ticket. So `list()` is ONE call per page
 *      and needs no per-row read, where the S3 adapter must HEAD each row it
 *      returns. Same port, same promise, cheaper here; said out loud because
 *      "the cloud adapters behave identically" is true of the CONTRACT and not
 *      of the bill.
 *   2. **A bigger metadata budget.** Custom metadata is capped at 8 KiB
 *      (keys and values together), against 2 KB on the other column. The
 *      ticket is checked against it at put and refused by name, so the cap is
 *      a stated limit and not a surprise from the service.
 *   3. **The client has no command objects.** Methods hang off a chain —
 *      `storage.bucket(b).file(k).save(...)` — which is why this column's pin
 *      test asserts a METHOD CHAIN rather than a set of command names.
 *
 * ── The object key ──────────────────────────────────────────────────────────
 * `[<prefix>/]<tenant>/<principal>/<conversation>/<ref>`, scope-partitioned by
 * `scopePath.ts` — the same percent-encoding law as the directory adapter, so
 * a tenant of literally `'..'` is a NAME here too. A ref alone opens nothing:
 * a wrong scope computes a different object name, the service answers 404, and
 * the caller reads `null`.
 *
 * ── What a 404 is allowed to mean here ──────────────────────────────────────
 * A missing object and a missing bucket look the SAME on this column
 * (`code: 404`, reason `notFound`, differing only in prose this adapter will
 * not parse). So the split is made by the call instead: only a read of one
 * named object may read a 404 as "not there". A 404 from a save or a listing
 * is not an answer to anything the caller asked — it goes through the
 * sanitizer, because nothing downstream converts it and the client's own text
 * for it carries the object name.
 *
 * ── Retention, and the operator's bulk tool ─────────────────────────────────
 * `ttlMs` stamps `expiresAt` AT MINT (stated, never sprung); expiry is
 * enforced on READ and the expired object is deleted on the way past; budgets
 * evict oldest-first (an object store has no cheap read-recency). A put SCANS
 * the scope only when a byte/count budget is configured — with no budget there
 * is nothing to plan, and a put stays a single upload.
 *
 * Reclaiming what nobody reads again is **Object Lifecycle Management**, the
 * operator's bulk tool. This adapter does not create rules: a lifecycle rule
 * is a cost and compliance decision that belongs to your infrastructure.
 * Align it like this:
 *
 * ```jsonc
 * // Delete objects 7 days after creation. Keep the rule LONGER than the
 * // store's ttlMs, never shorter: `expiresAt` is the promise printed on the
 * // ticket, and a lifecycle rule that deletes first makes a live ticket
 * // resolve to null BEFORE the time it stated. Longer, and lifecycle is what
 * // it should be — the backstop for what the store's own sweep never
 * // revisited.
 * { "lifecycle": { "rule": [
 *     { "action": { "type": "Delete" },
 *       "condition": { "age": 7, "matchesPrefix": ["artifacts/"] } }
 * ]}}
 * ```
 *
 * ── Lazy peer dependency ────────────────────────────────────────────────────
 * `@google-cloud/storage` is an OPTIONAL peer dependency, required at
 * CONSTRUCTION (the sqliteSessions law): importing the barrel costs a browser
 * bundle nothing, and a missing install refuses where the config was written.
 * Pass `storage` to share the client your app already built.
 *
 * ── What that peer's TREE carries, said out loud ────────────────────────────
 * Optional means it is your dependency and not this package's — nothing here
 * loads it unless you call `gcsArtifacts` — but you inherit its tree when you
 * do. Two independent audits (2026-08-13, 2026-08-14) reported the same five
 * MODERATE advisories, and they reproduce here:
 *
 *   `@google-cloud/storage` → `retry-request` → `teeny-request` → `gaxios` → `uuid`
 *
 * rooted in `uuid` (GHSA-w5hq-g745-h8pq — a missing buffer bounds check in
 * v3/v5/v6 when `buf` is provided). It is not a defect in this adapter and
 * there is no line here that would fix it: the chain is entirely inside
 * Google's client.
 *
 * **Do not take `npm audit fix --force`.** Its resolution installs
 * `@google-cloud/storage@5.18.3` — a major DOWNGRADE to a client from a
 * different era of the API. Trading a bounds check in a path this adapter does
 * not exercise for a client several majors behind the service is a different
 * outage, not a security improvement, and this package will never pin you to
 * it. Pin the newest 7.x yourself and watch the upstream chain.
 *
 * ── Status ──────────────────────────────────────────────────────────────────
 * **Field-validated** (was "awaiting field use" through 9.28.0). The method
 * chain it calls is pinned against the really-installed package by
 * `test/adapters/google/google-surface-pin.test.ts`, and the behaviour is
 * proved offline against an emulation double that speaks the same chain — but
 * the promotion rests on live evidence, not on those:
 *
 * An independent trial ran THIS adapter, unchanged since 9.25.0, against a real
 * Cloud Storage bucket (`@google-cloud/storage@7.22.0`, uniform bucket-level
 * access, public-access prevention on) and all nine checks passed: JSON
 * put/head/get with a verified SHA-256, scope isolation refusing another
 * tenant / principal / conversation, two distinct cursor pages, a byte-exact
 * native `putStream`/`getStream`, a TTL that expired and lazy-deleted, a
 * `maxCountPerScope` eviction reporting `max-count`, an oversize label refused
 * BEFORE upload against the 8 KiB metadata budget, a missing bucket answering
 * with the documented ambiguous `null` on read and a sanitized 404 on write
 * that leaked neither key nor scope, and an idempotent repeated delete.
 * (FINDINGS "Cloud Storage `gcsArtifacts()` — field PASS".)
 *
 * What that does NOT promote: the same evidence says nothing about a bucket
 * with soft delete or object versioning enabled — the trial's bucket had both
 * off, on purpose, so the evidence would be disposable.
 */
/// <reference types="node" />
import { type ArtifactRetention } from './retention.js';
import { type ArtifactStore } from './types.js';
/** One object's metadata, as this adapter reads it. */
export interface GcsFileMetadataLike {
    readonly size?: string | number;
    readonly timeCreated?: string;
    readonly contentType?: string;
    /** The custom entries — where the ticket rides. */
    readonly metadata?: Record<string, unknown>;
}
/** One object handle, as this adapter calls it. */
export interface GcsFileLike {
    /** Populated by a listing; a File built by `bucket.file()` may not have it. */
    readonly name?: string;
    readonly metadata?: GcsFileMetadataLike;
    save(data: Uint8Array | string, options?: unknown): Promise<unknown>;
    download(options?: unknown): Promise<[Uint8Array]>;
    getMetadata(options?: unknown): Promise<[GcsFileMetadataLike, unknown?]>;
    delete(options?: unknown): Promise<unknown>;
    createReadStream(options?: unknown): NodeJS.ReadableStream;
    createWriteStream(options?: unknown): NodeJS.WritableStream;
}
/** One bucket handle, as this adapter calls it. */
export interface GcsBucketLike {
    file(name: string): GcsFileLike;
    getFiles(query?: unknown): Promise<[GcsFileLike[], unknown?, unknown?]>;
}
/** The client, as this adapter calls it. */
export interface GcsStorageLike {
    bucket(name: string): GcsBucketLike;
}
/** The module shape this adapter loads. */
export interface GcsSdkModule {
    readonly Storage?: new (config: Record<string, unknown>) => GcsStorageLike;
}
/** Options for {@link gcsArtifacts}. */
export interface GcsArtifactsOptions {
    /** The bucket. It must already exist — this library never creates one. */
    readonly bucket: string;
    /** Object-name prefix inside the bucket, so a bucket can be shared. */
    readonly prefix?: string;
    /** Project id for the client this factory builds. Ignored when `storage` is
     *  passed — that client's configuration is yours. */
    readonly projectId?: string;
    /** Your own pre-built client; configuration and credentials stay yours. */
    readonly storage?: GcsStorageLike;
    /** Retention dials. Budgets evict OLDEST-first (no cheap read-recency). */
    readonly retention?: ArtifactRetention;
    /** @internal Test seam — the SDK module, injected. */
    readonly _sdk?: GcsSdkModule;
    /** @internal Test seam — a client injected past the SDK entirely. */
    readonly _storage?: GcsStorageLike;
    /** @internal Test seam — the clock. Defaults to `Date.now`. */
    readonly _now?: () => number;
}
/**
 * An artifact store in a Cloud Storage bucket.
 *
 * @example
 *   const store = gcsArtifacts({ bucket: 'my-agent-artifacts', prefix: 'artifacts' });
 *   const agent = Agent.create({ provider, artifacts: store });
 */
export declare function gcsArtifacts(options: GcsArtifactsOptions): ArtifactStore;
