/** * `recordViaInstrumentsApp`: open Instruments.app, prompt the user to * record + save, watch a directory for the resulting `.trace` bundle. * v1.16 item G. * * The macOS 26.x escape hatch. `xcrun xctrace record` is broken on this * OS (the regression we documented in v1.14: `--time-limit` ignored, * wedge, partial bundle that fails template export). Instruments.app's * GUI still produces valid `.trace` bundles. Until Apple fixes the CLI, * the only automated path on macOS 26.x sims is "open Instruments, * pick a template, hit Record, Stop, Save" - and we wrap that. * * Why not full AppleScript automation? Instruments.app's AppleScript * surface is minimal (queries on the `document` class only, no verbs * for start/stop/select-template). Documented in the .sdef file at * `Xcode.app/Contents/Applications/Instruments.app/Contents/Resources/ * Instruments.sdef`. We can query open document file URLs but cannot * programmatically drive recording. The user-in-loop step stays. */ import { z } from "zod"; import { type InspectTraceResult } from "./inspectTrace.js"; export declare const recordViaInstrumentsAppSchema: z.ZodObject<{ template: z.ZodDefault; watchDir: z.ZodOptional; timeoutSec: z.ZodDefault; preexistingTraces: z.ZodOptional>; }, "strip", z.ZodTypeAny, { template: string; timeoutSec: number; watchDir?: string | undefined; preexistingTraces?: string[] | undefined; }, { template?: string | undefined; watchDir?: string | undefined; timeoutSec?: number | undefined; preexistingTraces?: string[] | undefined; }>; export type RecordViaInstrumentsAppInput = z.infer; export interface RecordViaInstrumentsAppResult { ok: boolean; /** Absolute path to the newly-saved `.trace` bundle. Empty when timed out. */ tracePath: string; watchDir: string; /** Step-by-step instructions to show the user before they interact with Instruments. */ instructions: string[]; /** True when the watcher gave up before finding a new `.trace`. */ timedOut?: boolean; /** * v1.17 B-01. True when the trace was detected via the Instruments.app * AppleScript document query, NOT via the filesystem watcher. Means * the user saved the .trace OUTSIDE the configured `watchDir`. The * `tracePath` still resolves correctly; this flag explains the * detection path so callers can suggest "next time save to " * or update their watcher config. */ savedOutsideWatchDir?: boolean; /** Wall-clock seconds the user spent recording (start of watcher to detection). */ elapsedSec: number; /** Chained inspectTrace summary when the recording was found AND was readable. */ inspection?: InspectTraceResult; /** Plain-English diagnosis (success vs timeout vs unreadable). */ diagnosis: string; } /** * Pure: snapshot the set of `.trace` bundle names currently in `dir`. * Used as the "existing files" baseline so the watcher only matches * NEW traces. Exported for testing. */ export declare function snapshotTracesInDir(dir: string): Set; /** * Pure: given the set of trace paths now in `dir` and the baseline * snapshot, return paths that are NEW (in current but not in baseline). * The order is alphabetical for determinism. Exported for testing. */ export declare function detectNewTraces(current: Set, baseline: Set): string[]; /** * Pure: given a candidate `.trace` bundle path and the current time * (in ms since epoch), decide whether the bundle has been "stable" for * at least `stableForMs` (the user has finished saving). Returns false * when the path does not exist or stat fails. Exported for testing. */ export declare function isStable(candidatePath: string, nowMs: number, stableForMs: number, statFn?: (p: string) => { mtimeMs: number; }): boolean; /** * Pure: build the step-by-step instruction text the response surfaces. * Exported for testing. */ export declare function buildInstructions(template: string, watchDir: string): string[]; /** * v1.17 B-01: query Instruments.app for the file paths of currently * open documents via AppleScript. Used as a cross-check during the * poll loop: if the user saves a `.trace` OUTSIDE `watchDir`, the * directory watcher misses it, but Instruments.app will have the new * document open and we can read its `file` property. * * Returns an array of absolute POSIX paths. Empty array when Instruments * is not running, has no documents open, or the AppleScript fails. * * Exported for testing. */ export declare function queryInstrumentsDocumentPaths(exec: (cmd: string, args: string[]) => Promise<{ code: number; stdout: string; }>): Promise; export declare function recordViaInstrumentsApp(input: RecordViaInstrumentsAppInput): Promise;