/** * Session-scoped artifact storage for truncated tool outputs. * * Artifacts are stored in a directory alongside the session file, * accessible via artifact:// URLs. */ import { type ManagedSessionDescendantStore } from "./internal/managed-session-storage"; export interface ManagedOutputGeneration { outputFilename: string; metadataFilename: string; outputSizeBytes: number; outputSha256: string; metadataSizeBytes: number; metadataSha256: string; } export interface ArtifactSaveOptions { maxBytes?: number; } export type ArtifactPublishOutcome = { outcome: "saved"; handle: import("../tools/output-meta").EvictedToolOutputHandle; } | { outcome: "incomplete"; bytes: number; maxBytes: number; } | { outcome: "unavailable"; diagnostic: string; } | { outcome: "failed"; diagnostic: string; }; export interface ArtifactPublishOptions { /** Disable persistence explicitly; this fails closed without writing. */ persist?: boolean; maxBytes?: number; toolType?: string; } export interface ArtifactByteRange { start?: number; endExclusive?: number; } /** * Manages artifact storage for a session. * * Artifacts are stored with sequential IDs in the session's artifact directory. * The directory is created lazily on first write. * * Subagents do not own their own `ArtifactManager`. The parent's instance is * adopted via `SessionManager.adoptArtifactManager`, so the whole parent + * subagent tree shares one ID space and one directory. */ export declare class ArtifactManager { #private; /** * @param dir Directory that will hold artifact files. Created lazily on first save. */ constructor(target: string | ManagedSessionDescendantStore, options?: { readonly attemptId?: string; readonly stagingParentStore?: ManagedSessionDescendantStore; readonly stagingRelativePath?: string; }); /** * Artifact directory path. * Directory may not exist until first artifact is saved. */ get dir(): string; getManagedRootAuthority(): import("./internal/managed-session-storage").ManagedDirectoryRoot | undefined; getManagedSubtreeRootAuthority(): import("./internal/managed-session-storage").ManagedDirectoryRoot | undefined; getManagedStore(): ManagedSessionDescendantStore | undefined; assertManagedBinding(): void; replaceNamed(filename: string, content: string): Promise; replaceNamedBytes(filename: string, bytes: Uint8Array): Promise; publishManagedOutputGeneration(selectorFilename: string, outputFilenamePrefix: string, outputBytes: Uint8Array, metadataBytes: Uint8Array): Promise; publishNamedNoReplace(filename: string, bytes: Uint8Array): Promise; /** * Best-effort removal of a previously published named artifact. Used to roll * back staged publications when a transactional operation (e.g. gated * maintenance pruning) is rejected after publication succeeded. Returns false * when the artifact could not be removed so callers can log the failure * instead of silently treating the rollback as complete. */ removeNamedBestEffort(filename: string): Promise; /** * Atomically claim the next artifact ID after this manager has been initialized. * Prefer `allocatePath` or `save`; this synchronous seam exists for pruning callbacks. */ allocateId(): number; /** * Reserve an artifact ID without exposing a writable managed pathname. * * Streaming callers that only understand bare paths fail closed; use `save` * for terminally published artifact content. */ allocatePath(toolType: string): Promise<{ id: string; path?: string; }>; /** * Save content as an artifact and return the artifact ID. * Content is written to a private temporary inode, synced, and linked into * the artifact directory only after the complete terminal payload exists. */ save(content: string, toolType: string, options?: ArtifactSaveOptions): Promise; /** * Check if an artifact exists. * @param id Artifact ID (numeric string) */ exists(id: string): Promise; /** * List all artifact files in the directory. * Returns empty array if directory doesn't exist. */ listFiles(): Promise; getAttemptId(): string | undefined; getAllocatedIds(): readonly string[]; /** Create an isolated artifact manager rooted below this manager's staging area. */ createAttemptStaging(attemptId: string): ArtifactManager; /** Reserve and publish a candidate's staged artifacts with a contiguous parent ID block. */ commitAttemptStaging(staging: ArtifactManager, attemptId: string, options?: { beforePublish?: (mapping: ReadonlyMap) => Promise | void; }): Promise>; rollbackLastAttemptCommit(attemptId?: string): Promise; finalizeLastAttemptCommit(attemptId?: string): void; discardAttemptStaging(): Promise; /** Persist exact UTF-8 text for heap-eviction rehydration. */ publishExactText(text: string, options?: ArtifactPublishOptions): Promise; readRange(id: string, range?: ArtifactByteRange): Promise; openReadStream(id: string, range?: ArtifactByteRange): Promise>; /** * Get the full path to an artifact file. * Returns null if artifact doesn't exist. * * @param id Artifact ID (numeric string) */ getPath(id: string): Promise; }