/** * Owner- and session-scoped temp storage for tool output files. * * Every file a tool spills to the system temp directory (bash overflow logs, * `OutputAccumulator` spill files, and the in-memory-session tool-result fallback) * lands under: * * ```text * /-// * ``` * * The owner segment mirrors the upstream Claude Code `claude-{uid}` convention * (mehmoodosman/claude-code): a shared multi-user temp directory must never let * one account write into (or read) another account's tree. The session segment * makes the tree reapable as a unit by the age-based sweeper in * `session-temp-cleanup.ts` once the session is long gone. */ /** Directory mode for every directory this module creates (owner-only). */ export declare const SESSION_TEMP_DIR_MODE = 448; /** File mode for persisted tool-output files (owner-only). */ export declare const SESSION_TEMP_FILE_MODE = 384; /** * Reduce a value to a single safe path component. * * Disallowed characters collapse to `_`; leading `.`/`_` and trailing `.`/`_` * are stripped so the result can never be `.`, `..`, a hidden sweeper marker * file name, or anything that escapes the parent directory. Trimming uses a * linear scan rather than a `/^[._]+|[._]+$/` regex to avoid polynomial-time * backtracking on adversarial ids (CodeQL js/polynomial-redos). */ export declare function sanitizeTempPathComponent(value: string, fallback: string): string; /** * Derive the owner component for a named (non-uid) account. * * Sanitizing a name to a safe path component is lossy, and two distinct * accounts can reduce to the same component (`aliceé` and `aliceø` both yield * `alice_`). Where the system temp directory is machine-wide and * shared-accessible, that would put two accounts in one tree. Appending a short * digest of the raw identity keeps distinct accounts on distinct roots, with * the readable component in front so the directory stays recognizable. * * This prevents collision; it is not owner verification. Ownership is proven * separately by `verifyOwnedDirectory` — a uid check on POSIX, an owner-SID * and DACL check on Windows. * * Exported as a pure function so the collision property can be tested directly: * its only caller reaches this branch on Windows, which a POSIX test host * cannot enter. */ export declare function deriveOwnerComponent(rawIdentity: string): string; /** * Assemble the account identity used where there is no uid. * * `userInfo().username` returns the bare account name, so `CONTOSO\Alice` and * `FABRIKAM\Alice` would otherwise be one identity and share a tree. Exported * for tests: its caller only reaches this branch on Windows. */ export declare function windowsPrincipal(name: string | undefined): string; /** `/-` — the root every session temp tree lives under. */ export declare function getTempRootDir(): string; /** * The temp directory path for a session, without creating it. * * Falls back to the process-scoped component when no session id is available, * so a tool running outside a transcript session still writes inside the * owner-scoped root instead of directly into the system temp directory. */ export declare function resolveSessionTempDirPath(sessionId?: string): string; /** Raised when a temp directory cannot be created or trusted; callers degrade to no spill file. */ export declare class TempDirRefusedError extends Error { constructor(path: string, reason: string); } /** * Create `dir` with owner-only permissions, validating every component below the * system temp directory. * * Temp children always revalidate the canonical owner root and every later * component, even after a cache hit. A system temp reaper can delete a session * tree, and an attacker must not turn a memoized path into a symlink bypass. * Caller-owned paths outside the temp base may use the memo after confirming * the leaf is still a real directory. * * Throws {@link TempDirRefusedError} when a component cannot be trusted. Every * caller treats that as "no spill file", never as a fatal error: failing closed * loses a convenience artifact, while failing open writes tool output into a * directory someone else controls. */ export declare function ensureTempDir(dir: string): string; /** * Resolve and create the temp directory for a session. * * Pass an already-resolved directory to reuse a caller-provided path (still * created lazily with the same mode). */ export declare function getSessionTempDir(sessionId?: string): string; /** Create `explicitDir` when supplied, otherwise the active session's temp directory. */ export declare function ensureSessionTempDir(explicitDir?: string): string; /** A protection claim held by one owner; releasing twice is a no-op. */ export interface ProtectedPathLease { release(): void; } /** Protect `paths` until the returned lease is released. */ export declare function acquireProtectedPaths(paths: readonly string[]): ProtectedPathLease; /** * Make `sessionId` the default target for writers without a session handle. * * Deliberately separate from protection: a disposed session must stop protecting * its tree, but whichever session ran last still names where an unattached * writer spills. */ export declare function setActiveSessionTempId(sessionId: string): string; /** Directories this process must not reap: session temp trees and live tool-results. */ export declare function getProtectedSessionTempDirs(): ReadonlySet; /** Test seam: forget the process-level active/protected session state. */ export declare function resetSessionTempDirStateForTesting(): void; //# sourceMappingURL=session-temp-dir.d.ts.map