/** * artifacts/fileArtifacts — the claim-check store in a directory. * * One machine, one directory, nothing to install: each artifact is one JSON * envelope at `////.json`, so an * incident can be inspected with `ls` and `cat` — a store you cannot read * with the tools already on the box is a store you debug by guessing. * * ── Scope-partitioned paths, structurally traversal-proof ────────────────── * The path is built from two kinds of segment and both are closed: * • the ref — MINTED (`art_` + base62), and `isArtifactRef` is asserted * before any ref touches a path anyway, because "cannot happen" is a * claim, not a defence; * • the scope tuple — caller strings, so each segment is percent-encoded * before it becomes a directory name: `..`, `/` and `\` arrive as data * and land as literals, never as navigation. That encoding is * `scopePath.ts`'s to own (9.25.0) — the object-store adapters partition * their keys with the identical law, and one traversal defence that lives * in two files is one that eventually differs in two files. * * ── Streaming (9.25.0) ───────────────────────────────────────────────────── * This adapter implements the port's OPTIONAL `putStream`/`getStream`, * because a directory can honestly do it: the bytes go to a sibling * `.bin` as they arrive and the envelope records `payload: { shape: * 'external' }`. The envelope is written LAST, so a crash mid-upload leaves an * orphan `.bin` nobody can see rather than a ticket pointing at a payload that * never finished. A streamed artifact reads back as a `Uint8Array` through * `get()`, and `delete`/retention remove both files. * * ── What this adapter does NOT know ──────────────────────────────────────── * A directory cannot cheaply know which artifact was READ last, so budget * evictions here are oldest-first (by mint time) rather than the in-memory * adapter's least-recently-used — stated here so nobody discovers it as a * surprise under pressure. TTL expiry behaves identically everywhere. * * Node-only (`node:fs` via lazy require, the sqliteSessions law) — importing * the barrel costs a browser bundle nothing; constructing one where there is * no filesystem refuses by name. */ import { type ArtifactRetention } from './retention.js'; import { type ArtifactStore } from './types.js'; /** Options for {@link fileArtifacts}. */ export interface FileArtifactsOptions { /** The root directory. Created if missing, parents included. */ readonly directory: string; /** Retention dials — all optional here: disk is a budget the operator * already owns. TTL is stamped at mint; budgets sweep oldest-first. */ readonly retention?: ArtifactRetention; /** @internal Test seam — the clock. Defaults to `Date.now`. */ readonly _now?: () => number; } /** * Raised when an artifact file EXISTS but this runtime cannot read it — a * different fact from "no artifact", and only one of them is safe to answer * with `null`. (The sqliteSessions law, per file.) */ export declare class UnreadableArtifactFileError extends Error { readonly code: "ERR_UNREADABLE_ARTIFACT_FILE"; readonly file: string; constructor(file: string, detail: string); } /** * A directory-backed artifact store — durable across restarts, legible to a * human, one file per artifact. * * @example * const store = fileArtifacts({ directory: './artifacts' }); * const agent = Agent.create({ provider, artifacts: store }); */ export declare function fileArtifacts(options: FileArtifactsOptions): ArtifactStore; //# sourceMappingURL=fileArtifacts.d.ts.map