/**
 * Local cache for trail JSON fetched from web-ade.
 *
 * Layout — `~/.principal/trails/<purl-namespace>/<purl-name>/<id>.json` when the
 * payload carries enough identity (single-repo `authoredAt`-style trails plus
 * `repos[0]` Purl in multi-repo trails), or `~/.principal/trails/by-id/<id>.json`
 * as a fallback for trails we can't anchor to a Purl.
 *
 * See `docs/TRAIL_VIEWER_MODES.md` for the design context.
 */
export interface CacheLocation {
    /** Absolute filesystem path to the cached JSON. */
    path: string;
    /** `<purl-namespace>/<purl-name>` style anchor, or `by-id` for the fallback. */
    anchor: string;
}
/**
 * Decide where a trail's JSON should live on disk.
 *
 * Prefers `<purl-namespace>/<purl-name>/<id>.json` when the payload's
 * `repos[0].id` parses; falls back to `by-id/<id>.json` otherwise. Only github,
 * gitlab, bitbucket, and generic Purls participate in the hierarchical layout —
 * other types fall through to `by-id` so we never write into surprising paths.
 */
export declare function locate(id: string, payload: unknown): CacheLocation;
/**
 * Write a trail's raw JSON body to its cache slot. The body is stored verbatim
 * — no re-serialization — so the cached file matches what the server returned.
 */
export declare function write(id: string, body: string, payload: unknown): CacheLocation;
/**
 * Read a cached trail by id. Returns `null` when the file is missing or older
 * than `maxAgeMs`. The caller is responsible for fetching + writing a fresh
 * copy when this returns null.
 */
export declare function read(id: string, maxAgeMs: number): {
    body: string;
    path: string;
} | null;
//# sourceMappingURL=trail-cache.d.ts.map