/** * Cross-harness skill collector (SMI-5392, umbrella SMI-5382). * * Walks every known harness skill directory (`CLIENT_NATIVE_PATHS`) and emits * one {@link InventorySkillEntry} per (harness, skill) observed on disk. This is * the shared scanner that both the CLI `inventory push` command (Wave 3) and the * MCP inventory tool call before handing the snapshot to {@link uploadInventory}. * * Design parity with the CLI scanner at * `packages/cli/src/utils/skills-directory.ts`: * - Uses the SAME {@link SkillParser} to resolve `skill_id` / `version`. * - Realpath-memoizes the expensive SKILL.md read/parse/hash ACROSS harnesses * (a symlinked alias is parsed only once), but does NOT drop the emitted * entry for it — one row is still emitted per harness, since the same skill * independently installed (or symlink-aliased) under two harnesses must * remain two distinct rows (the `device_skills` PK is `(harness, skill_id)`). * A shared `Set` here used to also skip the push whenever the * SAME realpath recurred under a DIFFERENT harness, collapsing legitimate * cross-harness membership (GH #1912 / SMI-5717). The fix keys the * memoization cache by realpath alone (safe — it's for parse-cost reuse * only) but keys emitted-row tracking by `(harness, realpath)` (so a * within-harness alias still collapses to one row, while a cross-harness * one does not). * * @module @skillsmith/core/sync/inventory-collector */ import type { InventorySkillEntry } from './inventory-types.js'; /** * Collect every harness-installed skill on this device as inventory entries. * * Scans each harness in {@link CLIENT_IDS} order. Repo-local `./.claude/skills` * is intentionally excluded — inventory tracks harness-installed skills only, and * `harness` is always a {@link ClientId}, never `'local'`. * * The result is NOT truncated to `INVENTORY_LIMITS.MAX_SKILLS`. Exceeding * the cap is a real condition the caller / edge function must enforce (returning * a `too_many_skills` 400) — silently dropping skills here would corrupt the * server-side reconcile by making present skills look absent. * * @returns One entry per (harness, skill). `readSkillFields()` is memoized by * realpath across harnesses to avoid redundant parsing, but every harness * that observes the skill still gets its own row (GH #1912 / SMI-5717). * @see SMI-5392 */ export declare function collectDeviceSkills(): Promise; //# sourceMappingURL=inventory-collector.d.ts.map