//#region src/cli/skills-install.d.ts /** * `pagesmith skills install` — write versioned-pointer skill stubs into a * consumer repo. * * Unlike the old full-copy installer, this never duplicates a skill body into * the repo. For every skill shipped by a resolvable `@pagesmith/*` package under * `node_modules/@pagesmith//skills//`, it writes a canonical pointer * stub at `.agents/skills//SKILL.md` plus thin mirrors under each * detected/requested harness dir (`.claude/skills`, `.cursor/skills`, * `.codex/skills`, `.continue/skills`). The stub bodies point back at the * version-pinned original in `node_modules`, so every agent reads exactly the * skill that matches the installed package. * * Stubs carry an HTML-comment marker so re-runs are idempotent (created / * updated / unchanged), version bumps are detected as drift, and orphaned stubs * (skills removed from a newer package, or a package that is no longer * installed) can be swept — but only within the managed `pagesmith-*` namespace, * and only stubs we actually generated. * * The mechanism is deliberately parallel to `diagramkit skills install`; the * only structural difference is that Pagesmith installs from several packages at * once, so the orphan baseline is the union of every resolvable package's skill * set (never just the packages selected for this run). */ type HarnessName = "claude" | "cursor" | "codex" | "continue"; /** Parent dir for each harness (mirrors live under `/skills/`). */ declare const HARNESS_PARENT_DIRS: Record; declare const ALL_HARNESSES: readonly HarnessName[]; /** HTML-comment marker token identifying a canonical Pagesmith pointer stub. */ declare const POINTER_MARKER_TOKEN = "pagesmith-skill-pointer"; /** HTML-comment marker token identifying a Pagesmith harness mirror stub. */ declare const MIRROR_MARKER_TOKEN = "pagesmith-skill-mirror"; /** * Shared substring present in both marker tokens. Retained for reference; orphan * detection deliberately does **not** key on this bare substring (it would match * a hand-authored skill that merely mentions the token in prose) — see * {@link hasManagedMarker}. */ declare const MANAGED_MARKER_SUBSTRING = "pagesmith-skill-"; /** True when `content` carries a generated Pagesmith pointer or mirror marker. */ declare function hasManagedMarker(content: string): boolean; /** Only skills in this namespace are ever created, swept, or reported. */ declare const MANAGED_SKILL_PREFIX = "pagesmith-"; /** Packages the umbrella installer considers by default. */ declare const DEFAULT_PACKAGES: readonly string[]; type StubStatus = "created" | "updated" | "unchanged" | "removed" | "missing" | "stale" | "orphaned"; interface SkillStubAction { /** Path relative to the target dir. */ path: string; skill: string; /** Owning package (undefined for orphan sweeps). */ pkg?: string; kind: "canonical" | "mirror" | "orphan"; harness?: HarnessName; status: StubStatus; } interface InstalledPackage { pkg: string; /** Installed version read from the resolved package.json. */ version: string; } interface InstallSkillsResult { cwd: string; mode: "install" | "check" | "dry-run"; /** Packages skills were installed from this run (resolved + selected). */ packages: InstalledPackage[]; /** Requested packages that could not be resolved from the consumer. */ unresolved: string[]; /** * Whether the caller named packages explicitly (`--package`). When `false` * the run used the default package set, so an unresolved default is expected * for a core-only consumer and is not surfaced as a `[skipped]` warning. */ requestedExplicit: boolean; /** Harness mirror dirs written this run (the `.agents` base is always written). */ harnesses: HarnessName[]; /** Skill names targeted this run. */ skills: string[]; actions: SkillStubAction[]; /** * `--check` disposition: `true` when nothing is missing/stale/orphaned. * Always `true` for install / dry-run. */ ok: boolean; } interface InstallSkillsOptions { /** Target repo directory (default: `process.cwd()`). */ cwd?: string; /** * Restrict installation to these packages. `undefined` = every default * package that resolves. Orphan detection always uses the full resolvable * set, so `--package` never sweeps stubs it merely chose not to reinstall. */ packages?: string[]; /** Explicit harness selection. `undefined` = auto-detect. */ harnesses?: HarnessName[]; /** Restrict to these skill names (with or without the `pagesmith-` prefix). */ only?: string[]; /** Verify-only: never write, exit nonzero on missing/stale/orphaned. */ check?: boolean; /** Show what would happen without writing. */ dryRun?: boolean; /** * Test hook: map of package name → package root. When a package is present * here its root is used verbatim, bypassing `import.meta.resolve`. */ packageRoots?: Record; } interface SkillFrontmatter { name?: string; description?: string; } /** Parse the leading YAML frontmatter block for `name` / `description`. */ declare function readFrontmatter(content: string): SkillFrontmatter; /** * Resolve a package root (the dir containing its `package.json`) as seen from * the consumer `cwd`. Returns `undefined` when the package is not installed. * * Resolution is anchored on `cwd` via `createRequire(/package.json)`. * `import.meta.resolve(spec, base)` must **not** be used here: on stable Node * (without `--experimental-import-meta-resolve`) the second `base`/parent * argument is silently ignored, so it resolves relative to *this* module — the * CLI's own install location — instead of the consumer `cwd`. That defeats the * whole point of `--dir`/`cwd` scoping (it would happily "find" a package the * consumer never installed). `createRequire` from the consumer's own * `package.json` walks the consumer's `node_modules` chain, matching Node's * runtime resolution for that directory. */ declare function resolvePackageRoot(pkg: string, cwd: string): string | undefined; interface DiscoveredSkill { name: string; description: string; sourcePath: string; } /** List every `skills//SKILL.md` shipped in a package root. */ declare function discoverSkills(packageRoot: string): DiscoveredSkill[]; /** A harness is auto-detected when its parent dir already exists in the repo. */ declare function detectHarnesses(cwd: string): HarnessName[]; declare function buildPointerMarker(pkg: string, version: string): string; declare function buildMirrorMarker(name: string): string; /** * Compute the POSIX relative link from a canonical stub's directory to the * `SKILL.md` shipped by the resolved package root. Using the *resolved* package * root (not a fixed `../../../node_modules/@pagesmith/` string) keeps the * pointer correct in hoisted monorepos, where the package lives at the repo-root * `node_modules` while the stub may sit several levels deep. */ declare function pointerToPackageSkill(stubDir: string, packageRoot: string, name: string): string; /** * Canonical stub written to `.agents/skills//SKILL.md`. Points at the * version-pinned original in the resolved package via relative links. */ declare function renderCanonicalStub(input: { name: string; description: string; pkg: string; version: string; pointerPath: string; referencesPath: string; packageReferencePath: string; }): string; /** * Mirror stub written to `/skills//SKILL.md`. Points back at the * canonical `.agents/skills/...` file. The `../../../` prefix resolves to the * repo root from three levels deep (`.claude/skills//`). */ declare function renderMirrorStub(name: string, description: string): string; declare function installPackageSkills(options?: InstallSkillsOptions): InstallSkillsResult; /** Human-readable summary for CLI output (non-JSON mode). */ declare function renderSkillsReport(result: InstallSkillsResult): string; /** Flatten a cac option that may be a string, comma list, or repeated array. */ declare function toList(input: string | string[] | undefined): string[]; interface SkillsCliOptions { cwd?: string; packages?: string[]; /** Raw harness tokens (validated here); empty = auto-detect. */ harnesses?: string[]; only?: string[]; check?: boolean; dryRun?: boolean; json?: boolean; /** One-line note printed to stderr before running (deprecated-alias path). */ deprecationNote?: string; /** Test hook forwarded to {@link installPackageSkills}. */ packageRoots?: Record; } /** * Parse normalized CLI inputs, run {@link installPackageSkills}, print a human * or JSON report, and return the process exit code (never throws, never exits). */ declare function runSkillsInstallCli(options: SkillsCliOptions): number; /** Resolve requested `--only` names that match nothing shipped (for warnings). */ declare function unknownOnlyNames(cwd: string, only: string[] | undefined, packageRoots?: Record): string[]; //#endregion export { ALL_HARNESSES, DEFAULT_PACKAGES, DiscoveredSkill, HARNESS_PARENT_DIRS, HarnessName, InstallSkillsOptions, InstallSkillsResult, InstalledPackage, MANAGED_MARKER_SUBSTRING, MANAGED_SKILL_PREFIX, MIRROR_MARKER_TOKEN, POINTER_MARKER_TOKEN, SkillFrontmatter, SkillStubAction, SkillsCliOptions, StubStatus, buildMirrorMarker, buildPointerMarker, detectHarnesses, discoverSkills, hasManagedMarker, installPackageSkills, pointerToPackageSkill, readFrontmatter, renderCanonicalStub, renderMirrorStub, renderSkillsReport, resolvePackageRoot, runSkillsInstallCli, toList, unknownOnlyNames }; //# sourceMappingURL=skills-install.d.mts.map