/** * @fileoverview `performUninstall` — manifest-aware skill removal, including * ADR-139 (SMI-6274 Wave 4)'s untracked-skill adoption. * @module @skillsmith/core/services/skill-installation.uninstall * * Split out of `skill-installation.helpers.ts` to stay under the 500-line * standard once ADR-139's adoption logic was added — mirrors the existing * `skill-installation.io.ts` sibling-split convention. Round 25 split its own * helpers out again, into `skill-installation.uninstall.helpers.ts`, for the * same reason. `performUninstall` * has exactly one internal consumer (`skill-installation.service.ts`) and * is not part of `@skillsmith/core`'s public export surface. */ import type { SkillDependencyRepository } from '../repositories/SkillDependencyRepository.js'; import type { ProgressCallback, UninstallResult } from './skill-installation.types.js'; import type { ManifestManager } from './skill-manifest.js'; import { type ClientId } from '../install/paths.js'; import type { SkillManifestEntry } from './skill-installation.types.js'; /** * ADR-139 (SMI-6274 Wave 4): build a manifest entry for a skill found on * disk with no manifest record — "adoption." Every field is reconstructed * from what is directly observable on disk; fields that genuinely cannot * be recovered this way (the originating registry version/source) are * recorded as `'unknown'` rather than guessed, so a later `update` sees * `'unknown'` and falls through to confidence-gated source recovery * instead of silently trusting a wrong version (ADR-139 point 1). * * Exported (not just used by {@link performUninstall}) so `update`'s own * adoption path (`packages/cli/src/commands/manage.update.ts`) reuses the * IDENTICAL reconstruction logic rather than a second, driftable copy — * GPT-5.6-Sol PR review, ADR-139 follow-up: `update` previously never * adopted an untracked skill at all, only `remove` did. */ export declare function buildAdoptedManifestEntry(skillName: string, installPath: string): Promise; /** * ADR-139 (SMI-6274 Wave 4) / GPT-5.6-Sol PR review round 4: adopt an * untracked skill (present on disk, no manifest entry) by writing a * reconstructed manifest entry — race-safe against a concurrent writer * (e.g. a real `install()`, or another concurrent `update()`) tracking the * SAME skill between the caller's own (unlocked) manifest read and this * call's lock-acquired write. * * Single shared implementation for BOTH adoption call sites — * {@link performUninstall} (this file, calls it directly) and * `getSkillDiff` (`packages/cli/src/commands/manage.update.ts`, via this * function's re-export at the `@skillsmith/core` package root). Round 3's * confirmation review found a CLI-package-local copy of this exact * race-safety logic (`manage.update.helpers.ts`'s now-removed * `adoptUntrackedSkill`) had drifted from `performUninstall`'s own * still-non-race-safe inline version — importing a CLI file into `core` * would be a layering violation, so the fix moves the ONE race-safe * implementation here, alongside {@link buildAdoptedManifestEntry}, instead * of maintaining two copies of the same logic. * * The `updateSafely()` callback checks `current.installedSkills[manifestKey]` * INSIDE the callback, against the FRESH, lock-acquired state it's handed — * never a caller's own stale, unlocked read: if a real entry is already * there by the time the lock is held, that entry wins and the guessed one * is discarded entirely (never written) — a concurrent legitimate * `install()` must never be clobbered by a same-tick adoption's guess. * * Returns the entry now in the manifest (freshly adopted, or a real one a * concurrent writer got there first with) plus whether OUR write happened, * or `{ adoptionError }` if the write itself failed — naming the skill, * path, and manifest (via `manifest.path`), per ADR-139 point 1's stated * failure contract. */ export declare function adoptUntrackedSkillEntry(skillName: string, skillDirName: string, installPath: string, manifestKey: string, manifest: ManifestManager): Promise<{ entry: SkillManifestEntry; adopted: boolean; } | { adoptionError: string; }>; /** Perform skill uninstall with manifest awareness and orphan fallback. */ export declare function performUninstall(params: { skillName: string; force: boolean; skillsDir: string; manifest: ManifestManager; skillDependencyRepo: SkillDependencyRepository; onProgress: ProgressCallback; /** SMI-5894 Wave 1 Step 3: defaults to the canonical client for callers * that don't yet resolve a client (preserves pre-existing behavior). */ client?: ClientId; }): Promise; //# sourceMappingURL=skill-installation.uninstall.d.ts.map