/** * `cleanup_traces`: preview and delete `.trace` bundles generated by * `recordTimeProfile`. * * `.trace` bundles are directories that xctrace writes (typically tens * to hundreds of MB each). After a few profiling sessions the * `TRACE_ROOT` directory accumulates them quickly, and there is no * built-in clean-up in v1.8. This tool gives the agent a single call * to triage what is there and remove old runs once they are no longer * needed. * * Defaults err on the safe side: * * - `dryRun: true` by default. The agent has to explicitly pass * `dryRun: false` to actually delete. Operating with dry-run on by * default means an accidental call surfaces what would be deleted * rather than nuking the disk. * * - Scope is restricted to `MEMORYDETECTIVE_TRACE_ROOT` by default * (auto-discovered via `getSecurityFlags()`). To clean up traces in * an arbitrary directory, the caller passes `root: ` AND sets * `MEMORYDETECTIVE_ALLOW_EXTERNAL_CLEANUP=1` in the environment. * Without the env var, the tool returns `ok: false` with a clear * explanation and the requested path, but deletes nothing. * * - Only directories ending in `.trace` are considered. Files, * non-`.trace` directories, and symlinks are skipped without * recursion past the boundary so the tool cannot accidentally * remove anything outside its declared mandate. * * Returns `{ candidates, deleted, freedMB }`. Candidates are sorted by * `ageDays` descending (oldest first), so the agent can show the user * the most-stale traces at the top of the list. */ import { z } from "zod"; export declare const cleanupTracesShape: { readonly olderThanDays: z.ZodOptional; readonly dryRun: z.ZodDefault; readonly root: z.ZodOptional; readonly outputFormat: z.ZodOptional>; }; export declare const cleanupTracesSchema: z.ZodObject<{ readonly olderThanDays: z.ZodOptional; readonly dryRun: z.ZodDefault; readonly root: z.ZodOptional; readonly outputFormat: z.ZodOptional>; }, "strip", z.ZodTypeAny, { dryRun: boolean; outputFormat?: "markdown" | "json" | "both" | "verify-fix-table" | undefined; olderThanDays?: number | undefined; root?: string | undefined; }, { outputFormat?: "markdown" | "json" | "both" | "verify-fix-table" | undefined; olderThanDays?: number | undefined; dryRun?: boolean | undefined; root?: string | undefined; }>; export type CleanupTracesInput = z.infer; export interface CleanupCandidate { /** Absolute path to the `.trace` bundle. */ path: string; /** Total bundle size in MB (rounded to one decimal). */ sizeMB: number; /** Age in days since last modification (rounded to one decimal). */ ageDays: number; } export interface CleanupTracesResult { ok: boolean; dryRun: boolean; /** Absolute path actually scanned. Reflects the default when `root` was omitted. */ root: string; /** Total candidates discovered (independent of whether they were deleted). */ candidates: CleanupCandidate[]; /** Count of candidates actually deleted. 0 when `dryRun: true`. */ deleted: number; /** Total MB freed by deletions. 0 when `dryRun: true`. */ freedMB: number; /** Present when the call was rejected (e.g. external-root guard). */ failureReason?: string; } /** * Pure: build the path-prefix check that determines whether a target * lives under the trace-root boundary. Threaded as a helper for * testability and to keep the symlink-resolution logic in one place. */ export declare function isInsideTraceRoot(candidate: string, traceRoot: string): boolean; export declare function cleanupTraces(input: CleanupTracesInput): CleanupTracesResult;