/** How many parent directories a local search climbs before giving up. */ export declare const DEFAULT_WALK_UP = 4; export interface ProjectRootInfo { root: string; evidence: string; confidence: "high" | "medium" | "low"; } export declare function detectProjectRoot(startDir: string): ProjectRootInfo; /** * Where the server will actually open its database for this project. * * Mirrors database.ts:106-114. `ideKey` is passed only for global installs on * IDEs without a workspace variable, which open a per-IDE shard so two IDEs on * one project do not contend for the same write lock (F7). */ export declare function resolveDbPath(projectRoot: string, ideKey?: string): string; /** The tier-6 fallback in findProjectRoot(): one shared DB for everything. */ export declare function globalFallbackDbPath(): string; export interface DiscoveredInstall { ideKey: string; ideName: string; scope: "local" | "global"; configPath: string; /** "?" when the entry predates version stamping. */ version: string; mode: "universal" | "classic" | "unknown"; /** Directories climbed from the search start. 0 = the directory searched. */ distanceUp: number; /** Present for local installs: the project this config belongs to. */ projectRoot?: string; dbPath?: string; } export interface DiscoveryProblem { configPath: string; ideName: string; reason: string; } export interface DiscoveryResult { installs: DiscoveredInstall[]; /** Config files that exist but could not be parsed. Never silently dropped. */ problems: DiscoveryProblem[]; /** Every path looked at, so "not found" can be shown as a search, not a claim. */ searched: string[]; } /** * Search for project-local installs from `startDir` upward. * * Stops at `maxUp` parents OR at the detected project root, whichever comes * first — climbing past the repo root reaches other people's projects and, on a * shallow directory, the home directory. Bounded on purpose. */ export declare function discoverLocal(startDir: string, maxUp?: number): DiscoveryResult; /** Search every known IDE's user-level config. This is the machine-wide sweep. */ export declare function discoverGlobal(): DiscoveryResult; /** * A version string a person can act on. * * "?" is what readEntry() stores when the entry predates version stamping. It * is an honest value and a terrible label: a user reading "v?" concludes the * installer is broken, when the fact is "installed before Engram recorded * versions, therefore older than every stamped release". */ export declare function formatVersion(version: string | undefined): string; /** * A path short enough to read, long enough to identify. * * The four Android Studio configs on a real machine differ only in their * second-to-last segment, so a formatter that truncates the TAIL makes them * indistinguishable — which is the opposite of the point. Home is collapsed to * `~`, and any middle is elided, but the last two segments always survive. */ export declare function abbreviatePath(configPath: string, cwd?: string): string; /** Every install on this machine that is visible from `cwd`, local and global. */ export declare function discoverEverywhere(cwd: string, walkUp?: number): DiscoveryResult; /** * Installs grouped by IDE key. * * The interactive installer assumed one IDE = one install and asked * resolveIdeInstallStatus for a single answer. On a machine with four Android * Studio channels that is not a summary, it is a coin toss — three real * installs go unmentioned and the one named is whichever the path list happened * to reach first. */ export declare function groupByIde(installs: DiscoveredInstall[]): Map; export interface LedgerEntry { configPath: string; ideKey: string; ideName: string; scope: "local" | "global"; mode: "universal" | "classic"; version: string; projectRoot?: string; dbPath?: string; installedAt: string; } export declare function ledgerPath(): string; export declare function readLedger(): LedgerEntry[]; /** Upsert by configPath. Returns false if the write failed — never throws. */ export declare function recordInstall(entry: LedgerEntry): boolean; export declare function forgetInstall(configPath: string): boolean; /** * Ledger entries whose config file no longer contains an Engram entry. * * The ledger records an intent; the config file is the fact. They diverge when * a user edits the config by hand or the host application rewrites it (D5 F11), * and reporting a stale ledger row as an install would be the register-kept-by- * discipline failure this project has already paid for twice. */ export declare function pruneLedger(): { kept: LedgerEntry[]; dropped: LedgerEntry[]; }; //# sourceMappingURL=discovery.d.ts.map