/** The marker file every MMA-installed skill directory carries. */ export declare const SKILL_OWNERSHIP_MARKER_FILE = ".mma-install.json"; /** * Thrown when a skill directory holds an entry that is neither a regular file nor * a directory — a symlink above all. * * Skipping such an entry (the obvious alternative) is precisely what makes it * dangerous: an excluded entry contributes nothing to the digest, so a directory * whose only file was swapped for a symlink still hashes to whatever the marker * records, passes as owned, and is then written through — truncating the symlink's * target somewhere else on disk entirely. Ownership must be unprovable here, not * merely unaffected. */ export declare class UnprovableSkillEntryError extends Error { readonly code: "unprovable_skill_entry"; readonly path: string; constructor(path: string); } /** * Whether — and how — a skill directory is MMA-owned. * * - `unowned`: nothing exists at this path yet. Safe to create fresh. * - `owned`: the marker is present, its recorded release matches the release being * installed, and its digest matches the current render. Safe to replace as a * no-op or identity write. * - `owned-stale`: the marker records an earlier release AND the directory's * contents still match the digest that install recorded. Safe to replace (upgrade). * - `modified-conflict`: the directory exists but ownership cannot be proven — the * marker is missing, unparseable, or its digest does not match the directory's * actual contents; or the directory holds an entry that is neither a regular file * nor a directory. Never replace or delete; preserve and report. */ type SkillOwnershipState = 'unowned' | 'owned' | 'owned-stale' | 'modified-conflict'; interface SkillOwnershipInspection { state: SkillOwnershipState; /** The digest computed from the `rendered` files passed in — i.e. what the * CURRENT release would write. Present regardless of state so callers can record * it into a fresh marker after a successful replace. */ digest: string; /** The marker's own fields, when a marker could be read and parsed. Absent for * `unowned` and for a `modified-conflict` caused by a missing/unparseable marker. */ recordedRelease?: string; recordedDigest?: string; /** Human-readable detail for `modified-conflict`, suitable for inventory reporting. */ reason?: string; } /** Regular-file bytes keyed by POSIX-relative path. Callers build this by walking a * render (in-memory skill output) or a real directory (via {@link isRegularFile} * filtering) — directories and symlinks are simply never entries in this map. */ export type RenderedFiles = ReadonlyMap; /** * The canonical digest of a rendered skill directory's regular files. * * Deterministic across processes and platforms: sorted by byte-wise POSIX-relative * path, each entry contributing `length-prefixed path + length-prefixed bytes` to a * single SHA-256. `.mma-install.json` is always excluded, even if present in `files`. */ export declare function computeSkillDigest(files: RenderedFiles): string; /** Read the directory's regular files, throwing {@link UnprovableSkillEntryError} * for any entry that is neither a regular file nor a directory. `lstat` (never * `stat`) is what makes that distinction possible: a symlink must be recognised as * a symlink, not silently resolved to whatever it points at. The marker is excluded * from the returned set because it cannot contain a hash of itself. Exported so * callers that need the SAME regular-file set this module's own ownership proof * uses -- e.g. a provisioning backup snapshot's digest -- never re-implement * directory walking (and risk disagreeing with it) themselves. */ export declare function readInstalledRegularFiles(root: string, current?: string): Promise>; /** * Inspect whether `dir` is MMA-owned for the given `installedRelease`, against the * current render `rendered` (what that release's skill content actually is). * * Never mutates the filesystem — this is the read-only proof step callers gate a * replace/remove decision on. */ export declare function inspectSkillOwnership(dir: string, rendered: RenderedFiles, installedRelease: string): Promise; /** * Inspect a directory whose skill this release no longer ships at all — a skill * retired between versions, still sitting in the user's skill root. * * There is no render to compare against, and there never will be again, so the * ONLY available proof is the one the marker already carries: an install recorded * its own digest, and content still matching that record was put there by MMA and * has not been touched since. That is exactly the rule {@link * inspectSkillOwnership} already applies to a superseded release, so this is the * same check with the render step removed rather than a second ownership notion. * * Returns `owned-stale` when the directory is provably MMA's and therefore safe to * remove; `modified-conflict` when it is not, in which case it must be left alone. */ export declare function inspectRetiredSkillOwnership(dir: string): Promise; export {}; //# sourceMappingURL=owned-files.d.ts.map