import { z } from "zod"; import { type ReferenceTreeEntry } from "../parsers/referenceTree.js"; import { type Verbosity } from "../parsers/shortenClassName.js"; import type { LeaksReport, NextCallSuggestion } from "../types.js"; export declare const analyzeMemgraphSchema: z.ZodObject<{ path: z.ZodString; fullChains: z.ZodDefault; verbosity: z.ZodDefault>; maxClassesInChain: z.ZodDefault; referenceTreeTopN: z.ZodDefault; outputFormat: z.ZodOptional>; }, "strip", z.ZodTypeAny, { path: string; fullChains: boolean; verbosity: "compact" | "normal" | "full"; maxClassesInChain: number; referenceTreeTopN: number; outputFormat?: "markdown" | "json" | "both" | "verify-fix-table" | undefined; }, { path: string; fullChains?: boolean | undefined; verbosity?: "compact" | "normal" | "full" | undefined; maxClassesInChain?: number | undefined; referenceTreeTopN?: number | undefined; outputFormat?: "markdown" | "json" | "both" | "verify-fix-table" | undefined; }>; export type AnalyzeMemgraphInput = z.infer; export interface CycleSummary { className: string; address: string; count?: number; size?: string; instanceSize?: number; /** Number of descendant nodes in the retain chain. */ chainLength: number; /** Top-ranked class names appearing in the chain (capped, app-level priority). */ classesInChain: string[]; /** Total unique class names found in the chain (the cap-aware count for context). */ classesInChainTotal: number; /** * Total instance size in bytes summed across every node reachable from * this cycle's root. Useful for prioritizing cycles: "breaking this one * frees X bytes" — bigger first. */ transitiveBytes: number; /** Total node count reachable from this root. Heavier than `chainLength` when the cycle has wide branches. */ transitiveInstanceCount: number; } export interface AnalyzeMemgraphResult { ok: boolean; path: string; process?: string; pid?: number; identifier?: string; platform?: string; totals: { leakCount: number; totalLeakedBytes: number; nodesMalloced?: number; }; /** Top-level ROOT CYCLE summaries. */ cycles: CycleSummary[]; /** Present only when `fullChains: true`. The full forest including standalone leaks. */ fullReport?: LeaksReport; /** Plain-English diagnosis (one liner). */ diagnosis: string; /** Pipeline hints. Chain `classifyCycle` next, then `reachableFromCycle` to scope blame. */ suggestedNextCalls?: NextCallSuggestion[]; /** * Top live classes by instance count from the heap reference tree. * Populated when `leakCount` is 0 and `referenceTreeTopN > 0`. Surfaces * the abandoned-memory shape that the standard `leaks` count misses: * objects that are technically reachable (so not "leaked" in the strict * sense) but whose growth across repeated workflows indicates a real * accumulation bug (KVO observers not invalidated, NotificationCenter * observers leaked, caches that never evict, etc.). These classes are * not formal leaks; they are reachable-but-suspicious and worth diffing * against a baseline via `analyzeAbandonedMemory(before, after)` for * the verdict. * * **Raw view.** Includes framework noise (NSMutableDictionary, CFString, * libMainThreadChecker bss, etc.) that grows with normal app activity * and is rarely the actionable leak. Useful for cache-bloat or * collection-explosion investigations. */ abandonedMemoryTop?: ReferenceTreeEntry[]; /** * Same top-N reference-tree analysis as `abandonedMemoryTop` but filtered * to actionable classes only. Foundation collection types (NSMutableDictionary, * CFString, ...), ObjC runtime metadata (Class.data, OBJC_METACLASS_), * Apple-framework static-data sections (__DATA __bss / __data / __common), * Stack of thread / non-object / VM region rows, and the `<>` * summary are all excluded. The remaining list surfaces AV*, KVO*, * SwiftUI app-level types, user-named classes, and other classes the * fix would actually live in. New in v1.10. * * Use this list for the "what should I worry about?" question; use * `abandonedMemoryTop` for "what's the full heap distribution?". */ abandonedMemorySuspects?: ReferenceTreeEntry[]; } /** * Pure function: take a `leaks` stdout string and a source path, produce a structured analysis. * Split out so it can be tested without spawning a subprocess. */ export declare function summarizeLeaks(leaksText: string, path: string, fullChains?: boolean, verbosity?: Verbosity, maxClassesInChain?: number): AnalyzeMemgraphResult; export declare function analyzeMemgraph(input: AnalyzeMemgraphInput): Promise;